4 * Created on: 17.12.2012
7 * Refactored by: Martin Koubek
8 * martin.koubek@porsche-engineering.com
11 * This file is written for 33972 Multiple Switch
12 * http://www.freescale.com/files/analog/doc/data_sheet/MC33972.pdf
14 * This file contains functions to control DIN
15 * Voltage on each pin can be set
16 * switch to ground or to battery on programable pins can be set
17 * interrupts on each pins can be disabled and enabled
21 /******************************************************************************
23 ******************************************************************************/
28 /******************************************************************************
29 * Static Variable Definitions
30 ******************************************************************************/
31 /** Stored response from SPI */
32 static uint32_t din_spi_resp = 0;
34 /** Store commands in shadow registers */
35 static uint16_t shadow_reg_list[NUM_SPI_CMD];
38 const static uint32_t dsc_pin_map[8U] = {
50 /******************************************************************************
52 ******************************************************************************/
54 * Switch copy command, prepared by other functions, to shadow variable,
55 * convert command to MSB,
56 * transfer command to DIN
60 int din_spi_transfer_mst(const uint32_t din_spi_cmd);
63 * This find an index in register list
67 uint32_t din_spi_get_command_from_enum(const uint8_t index);
71 /******************************************************************************
72 * Close variable declaration sections
73 ******************************************************************************/
77 /** Bit 13: Output Gain Selection bit set = 1x (VOUT = VREF * D/4096) */
78 /** Bit 15: DACA (0) or DACB (1) Selection bit. */
79 #define DACA_INIT_VAL (_BV(13) | _BV(12) )
80 #define DACB_INIT_VAL (_BV(13) | _BV(12) | _BV(15))
83 /* Public functions */
84 /* ---------------- */
87 enum SpiCmdTable spi_cmd_index, uint16_t clear_mask, uint16_t xor_mask)
89 if ((uint8_t)spi_cmd_index > NUM_SPI_CMD){
94 shadow_reg_list[spi_cmd_index] =
95 shadow_reg_list[spi_cmd_index] & ~clear_mask ^ xor_mask;
97 uint32_t din_spi_cmd = din_spi_get_command_from_enum(spi_cmd_index) |
98 shadow_reg_list[spi_cmd_index];
100 return din_spi_transfer_mst(din_spi_cmd);
103 int8_t drv_din_ref(uint16_t ref_a, uint16_t ref_b)
109 uint32_t commands[2];
110 port_desc_t* desc = hal_port_get_dsc(PORT_NAME_DACDREF, -1);
112 // Send command for DAC A
113 cmd = DACA_INIT_VAL | (ref_a & 0x0FFF);
115 commands[0] = (cmd & 0xFF00) >> 8;
116 commands[1] = (cmd & 0xFF);
117 desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
119 // Send command for DAC B
120 cmd = DACB_INIT_VAL | (ref_b & 0x0FFF);
122 commands[0] = (cmd & 0xFF00) >> 8;
123 commands[1] = (cmd & 0xFF);
124 desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
126 // Fixme: check SPI return value.
131 int8_t drv_din_get_varthr(uint8_t pin) {
134 if((pin < 8) || (pin > 15)) {
138 return hal_gpio_pin_get_value(dsc_pin_map[pin - 8]);
141 uint16_t din_get_val_word()
144 //uint16_t sp = ((din_spi_resp >> 14) & 0x00FF);
145 //uint16_t sg = ((din_spi_resp << 8 ) & 0xFF00);
147 // How it actually is.
148 // Ignore datasheet, this is the actual response from the SPI driver:
149 // [xxxx xxxx][SG7-SG0][SP1 SP0 yy yyyy][zz SP7-SP2]
151 // y: Maybe SG13-SG8, but untested.
152 // z: Maybe therm flag and int flag.
153 // For SP: First get SP7-SP2 right, then add SP1 and SP0
154 uint16_t sp = ((din_spi_resp << 2) & 0x00FF) | ((din_spi_resp >> 14) & 0x3);
155 uint16_t sg = ((din_spi_resp >> 8) & 0xFF00);
156 uint16_t word = sg | sp;
161 int din_spi_response() {
166 /* Private functions */
167 /* ----------------- */
169 * Switch copy command, prepared by other functions, to shadow variable,
170 * convert command to MSB,
171 * transfer command to DIN
173 * return spi response
175 int din_spi_transfer_mst(const uint32_t din_spi_cmd) {
178 desc = hal_port_get_dsc(PORT_NAME_DINSPI, -1);
179 uint32_t commands[3];
180 commands[0] = (din_spi_cmd & 0xFF0000) >> 16; // command
181 commands[1] = (din_spi_cmd & 0xFF00) >> 8; // 1.st B of data
182 commands[2] = (din_spi_cmd & 0xFF); // 2.nd B of data
184 din_spi_resp = desc->port_setfnc_ptr(desc->config, desc->numValues, \
189 * This find an index in register list
193 uint32_t din_spi_get_command_from_enum(const uint8_t index)
195 uint32_t command = 0x0;
197 if (index == DIN_RESET_CMD){
202 command = index << 16;