]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/din.c
ccdafb23548e3248503fe90a8fc5ef4d06f9d760
[pes-rpp/rpp-lib.git] / rpp / src / drv / din.c
1 /* Copyright (C) 2012-2013 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Michal Horn <hornmich@fel.cvut.cz>
5  *     - Martin Koubek <martin.koubek@porsche-engineering.com>
6  *
7  * This document contains proprietary information belonging to Czech
8  * Technical University in Prague. Passing on and copying of this
9  * document, and communication of its contents is not permitted
10  * without prior written authorization.
11  *
12  * File : din.c
13
14  * Abstract:
15  *         This file is written for 33972 Multiple Switch
16  *         http://www.freescale.com/files/analog/doc/data_sheet/MC33972.pdf
17  *
18  *         This file contains functions to control DIN
19  *         Voltage on each pin can be set
20  *         switch to ground or to battery on programable pins can be set
21  *         interrupts on each pins can be disabled and enabled
22  */
23
24
25 /******************************************************************************
26 *   Include Files
27 ******************************************************************************/
28 #include "drv/drv.h"
29
30
31
32 /******************************************************************************
33 *   Static Variable Definitions
34 ******************************************************************************/
35 /** Stored response from SPI */
36 static uint32_t din_spi_resp = 0;
37
38 /** Store commands in shadow registers */
39 static uint16_t shadow_reg_list[DIN_NUM_SPI_CMD];
40
41 /******************************************************************************
42 *   Function Prototypes
43 ******************************************************************************/
44 /**
45  * Switch copy command, prepared by other functions, to shadow variable,
46  * convert command to MSB,
47  * transfer command to DIN
48  * store spi response
49  * return spi response
50  */
51 int din_spi_transfer_mst(const uint32_t din_spi_cmd);
52
53 /******************************************************************************
54 *   Close variable declaration sections
55 ******************************************************************************/
56 /* Private defines */
57 /* --------------- */
58 /** Options: */
59 /**   Bit 13: Output Gain Selection bit set = 1x (VOUT = VREF * D/4096)   */
60 /**   Bit 15: DACA (0) or DACB (1) Selection bit.  */
61 #define DACA_INIT_VAL   (_BV(13) | _BV(12)          )
62 #define DACB_INIT_VAL   (_BV(13) | _BV(12) | _BV(15))
63
64 /**
65  * This find an index in register list
66  * @param command
67  * @return index
68  */
69 static uint32_t enum2cmd(const enum SpiCmdTable index)
70 {
71         if (index == DIN_RESET_CMD)
72                 return 0x007F0000;
73         else
74                 return index << 16;
75 }
76
77 /* Public functions */
78 /* ---------------- */
79
80 uint16_t din_set_reg(
81         enum SpiCmdTable spi_cmd_index, uint16_t clear_mask, uint16_t xor_mask)
82 {
83         if (spi_cmd_index >= DIN_NUM_SPI_CMD)
84                 return 0;
85
86         shadow_reg_list[spi_cmd_index] =
87                 shadow_reg_list[spi_cmd_index] & ~clear_mask ^ xor_mask;
88
89         uint32_t din_spi_cmd = enum2cmd(spi_cmd_index) | shadow_reg_list[spi_cmd_index];
90
91         return din_spi_transfer_mst(din_spi_cmd);
92 }
93
94 int8_t drv_din_ref(uint16_t ref_a, uint16_t ref_b)
95 {
96
97         uint16_t cmd;
98
99         // Get descriptor
100         uint32_t commands[2];
101         dio_port_desc_t *desc = dio_port_get_dsc(DIO_PORT_NAME_DACDREF, -1);
102
103         // Send command for DAC A
104         cmd = DACA_INIT_VAL | (ref_a & 0x0FFF);
105
106         commands[0] = (cmd & 0xFF00) >> 8;
107         commands[1] = (cmd & 0xFF);
108         desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
109
110         // Send command for DAC B
111         cmd = DACB_INIT_VAL | (ref_b & 0x0FFF);
112
113         commands[0] = (cmd & 0xFF00) >> 8;
114         commands[1] = (cmd & 0xFF);
115         desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
116
117         // Fixme: check SPI return value.
118         return SUCCESS;
119 }
120
121
122 int8_t drv_din_get_varthr(uint8_t pin)
123 {
124
125         // Check range
126         if ((pin < 8) || (pin > 15))
127                 return FAILURE;
128
129         dio_port_desc_t* port = dio_port_get_dsc(DIO_PORT_NAME_DINMCU, -1);
130         if (pin-8 >= port->numValues)
131                 return FAILURE;
132
133         return dio_gpio_pin_get_value(port->config[pin - 8]);
134 }
135
136 uint16_t din_get_val_word()
137 {
138         // How it should be.
139         //uint16_t sp = ((din_spi_resp >> 14) & 0x00FF);
140         //uint16_t sg = ((din_spi_resp << 8 ) & 0xFF00);
141
142         // How it actually is.
143         // Ignore datasheet, this is the actual response from the SPI driver:
144         // [xxxx xxxx][SG7-SG0][SP1 SP0 yy yyyy][zz SP7-SP2]
145         //  x: Unknown.
146         //  y: Maybe SG13-SG8, but untested.
147         //  z: Maybe therm flag and int flag.
148         // For SP: First get SP7-SP2 right, then add SP1 and SP0
149         uint16_t sp = ((din_spi_resp << 2) & 0x00FF) | ((din_spi_resp >> 14) & 0x3);
150         uint16_t sg = ((din_spi_resp >> 8) & 0xFF00);
151         uint16_t word = sg | sp;
152
153         return word;
154 }
155
156
157 int din_spi_response()
158 {
159         return din_spi_resp;
160 }
161
162
163 /* Private functions */
164 /* ----------------- */
165 /**
166  * Switch copy command, prepared by other functions, to shadow variable,
167  * convert command to MSB,
168  * transfer command to DIN
169  * store spi response
170  * return spi response
171  */
172 int din_spi_transfer_mst(const uint32_t din_spi_cmd)
173 {
174         dio_port_desc_t *desc;
175
176         desc = dio_port_get_dsc(DIO_PORT_NAME_DINSPI, -1);
177         uint32_t commands[3];
178         commands[0] = (din_spi_cmd & 0xFF0000) >> 16;   // command
179         commands[1] = (din_spi_cmd & 0xFF00) >> 8;      // 1.st B of data
180         commands[2] = (din_spi_cmd & 0xFF);             // 2.nd B of data
181
182         din_spi_resp = desc->port_setfnc_ptr(desc->config, desc->numValues,     \
183                                                                                  commands);
184         return din_spi_resp;
185 }