]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/din.c
Simplify DIN driver layer
[pes-rpp/rpp-lib.git] / rpp / src / drv / din.c
1 /*
2  * din.c
3  *
4  *  Created on: 17.12.2012
5  *      Author: Michal Horn
6  *
7  *  Refactored by: Martin Koubek
8  *      martin.koubek@porsche-engineering.com
9  *      18.9.2013
10  *
11  *  This file is written for 33972 Multiple Switch
12  *  http://www.freescale.com/files/analog/doc/data_sheet/MC33972.pdf
13  *
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
18  */
19
20
21 /******************************************************************************
22 *   Include Files
23 ******************************************************************************/
24 #include "drv/drv.h"
25
26
27
28 /******************************************************************************
29 *   Static Variable Definitions
30 ******************************************************************************/
31 /** Stored response from SPI */
32 static uint32_t din_spi_resp = 0;
33
34 /** Store commands in shadow registers */
35 static uint16_t shadow_reg_list[NUM_SPI_CMD];
36
37
38 const static uint32_t dsc_pin_map[8U] = {
39     PIN_DSC_DIN8,
40     PIN_DSC_DIN9,
41     PIN_DSC_DIN10,
42     PIN_DSC_DIN11,
43     PIN_DSC_DIN12,
44     PIN_DSC_DIN13,
45     PIN_DSC_DIN14,
46     PIN_DSC_DIN15
47 };
48
49
50 /******************************************************************************
51 *   Function Prototypes
52 ******************************************************************************/
53 /**
54  * Switch copy command, prepared by other functions, to shadow variable,
55  * convert command to MSB,
56  * transfer command to DIN
57  * store spi response
58  * return spi response
59  */
60 int din_spi_transfer_mst(const uint32_t din_spi_cmd);
61
62 /**
63  * This find an index in register list
64  * @param index
65  * @return command
66  */
67 uint32_t din_spi_get_command_from_enum(const uint8_t index);
68
69
70
71 /******************************************************************************
72 *   Close variable declaration sections
73 ******************************************************************************/
74 /* Private defines */
75 /* --------------- */
76 /** Options: */
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))
81
82
83 /* Public functions */
84 /* ---------------- */
85
86 uint16_t din_set_reg(
87                 enum SpiCmdTable spi_cmd_index, uint16_t clear_mask, uint16_t xor_mask)
88 {
89         if ((uint8_t)spi_cmd_index > NUM_SPI_CMD){
90                 return 0;
91         }
92         else{}
93
94         shadow_reg_list[spi_cmd_index] =
95                         shadow_reg_list[spi_cmd_index] & ~clear_mask ^ xor_mask;
96
97         uint32_t din_spi_cmd = din_spi_get_command_from_enum(spi_cmd_index) |
98                         shadow_reg_list[spi_cmd_index];
99
100         return din_spi_transfer_mst(din_spi_cmd);
101 }
102
103 int8_t drv_din_ref(uint16_t ref_a, uint16_t ref_b)
104 {
105
106     uint16_t cmd;
107
108     // Get descriptor
109     uint32_t commands[2];
110     port_desc_t* desc = hal_port_get_dsc(PORT_NAME_DACDREF, -1);
111
112     // Send command for DAC A
113     cmd = DACA_INIT_VAL | (ref_a & 0x0FFF);
114
115     commands[0] = (cmd & 0xFF00) >> 8;
116     commands[1] = (cmd & 0xFF);
117     desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
118
119     // Send command for DAC B
120     cmd = DACB_INIT_VAL | (ref_b & 0x0FFF);
121
122     commands[0] = (cmd & 0xFF00) >> 8;
123     commands[1] = (cmd & 0xFF);
124     desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
125
126     // Fixme: check SPI return value.
127     return SUCCESS;
128 }
129
130
131 int8_t drv_din_get_varthr(uint8_t pin) {
132
133     // Check range
134     if((pin < 8) || (pin > 15)) {
135         return FAILURE;
136     }
137
138     return hal_gpio_pin_get_value(dsc_pin_map[pin - 8]);
139 }
140
141 uint16_t din_get_val_word()
142 {
143     // How it should be.
144     //uint16_t sp = ((din_spi_resp >> 14) & 0x00FF);
145     //uint16_t sg = ((din_spi_resp << 8 ) & 0xFF00);
146
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]
150     //  x: Unknown.
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;
157     return word;
158 }
159
160
161 int din_spi_response() {
162     return din_spi_resp;
163 }
164
165
166 /* Private functions */
167 /* ----------------- */
168 /**
169  * Switch copy command, prepared by other functions, to shadow variable,
170  * convert command to MSB,
171  * transfer command to DIN
172  * store spi response
173  * return spi response
174  */
175 int din_spi_transfer_mst(const uint32_t din_spi_cmd) {
176     port_desc_t* desc;
177
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
183
184     din_spi_resp = desc->port_setfnc_ptr(desc->config, desc->numValues, \
185                 commands);
186     return din_spi_resp;
187 }
188 /**
189  * This find an index in register list
190  * @param command
191  * @return index
192  */
193 uint32_t din_spi_get_command_from_enum(const uint8_t index)
194 {
195         uint32_t command = 0x0;
196
197         if (index == DIN_RESET_CMD){
198                 return 0x0007F000;
199         }
200         else {}
201
202         command = index << 16;
203         return command;
204 }