]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/din.c
Merge branches 'master' and 'rm48/master'
[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 const static uint32_t dsc_pin_map[8U] = {
43         PIN_DSC_DIN8,
44         PIN_DSC_DIN9,
45         PIN_DSC_DIN10,
46         PIN_DSC_DIN11,
47         PIN_DSC_DIN12,
48         PIN_DSC_DIN13,
49         PIN_DSC_DIN14,
50         PIN_DSC_DIN15
51 };
52
53
54 /******************************************************************************
55 *   Function Prototypes
56 ******************************************************************************/
57 /**
58  * Switch copy command, prepared by other functions, to shadow variable,
59  * convert command to MSB,
60  * transfer command to DIN
61  * store spi response
62  * return spi response
63  */
64 int din_spi_transfer_mst(const uint32_t din_spi_cmd);
65
66 /******************************************************************************
67 *   Close variable declaration sections
68 ******************************************************************************/
69 /* Private defines */
70 /* --------------- */
71 /** Options: */
72 /**   Bit 13: Output Gain Selection bit set = 1x (VOUT = VREF * D/4096)   */
73 /**   Bit 15: DACA (0) or DACB (1) Selection bit.  */
74 #define DACA_INIT_VAL   (_BV(13) | _BV(12)          )
75 #define DACB_INIT_VAL   (_BV(13) | _BV(12) | _BV(15))
76
77 /**
78  * This find an index in register list
79  * @param command
80  * @return index
81  */
82 static uint32_t enum2cmd(const enum SpiCmdTable index)
83 {
84         if (index == DIN_RESET_CMD)
85                 return 0x007F0000;
86         else
87                 return index << 16;
88 }
89
90 /* Public functions */
91 /* ---------------- */
92
93 uint16_t din_set_reg(
94         enum SpiCmdTable spi_cmd_index, uint16_t clear_mask, uint16_t xor_mask)
95 {
96         if (spi_cmd_index >= DIN_NUM_SPI_CMD)
97                 return 0;
98
99         shadow_reg_list[spi_cmd_index] =
100                 shadow_reg_list[spi_cmd_index] & ~clear_mask ^ xor_mask;
101
102         uint32_t din_spi_cmd = enum2cmd(spi_cmd_index) | shadow_reg_list[spi_cmd_index];
103
104         return din_spi_transfer_mst(din_spi_cmd);
105 }
106
107 int8_t drv_din_ref(uint16_t ref_a, uint16_t ref_b)
108 {
109
110         uint16_t cmd;
111
112         // Get descriptor
113         uint32_t commands[2];
114         port_desc_t *desc = hal_port_get_dsc(PORT_NAME_DACDREF, -1);
115
116         // Send command for DAC A
117         cmd = DACA_INIT_VAL | (ref_a & 0x0FFF);
118
119         commands[0] = (cmd & 0xFF00) >> 8;
120         commands[1] = (cmd & 0xFF);
121         desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
122
123         // Send command for DAC B
124         cmd = DACB_INIT_VAL | (ref_b & 0x0FFF);
125
126         commands[0] = (cmd & 0xFF00) >> 8;
127         commands[1] = (cmd & 0xFF);
128         desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
129
130         // Fixme: check SPI return value.
131         return SUCCESS;
132 }
133
134
135 int8_t drv_din_get_varthr(uint8_t pin)
136 {
137
138         // Check range
139         if ((pin < 8) || (pin > 15))
140                 return FAILURE;
141
142         return hal_gpio_pin_get_value(dsc_pin_map[pin - 8]);
143 }
144
145 uint16_t din_get_val_word()
146 {
147         // How it should be.
148         //uint16_t sp = ((din_spi_resp >> 14) & 0x00FF);
149         //uint16_t sg = ((din_spi_resp << 8 ) & 0xFF00);
150
151         // How it actually is.
152         // Ignore datasheet, this is the actual response from the SPI driver:
153         // [xxxx xxxx][SG7-SG0][SP1 SP0 yy yyyy][zz SP7-SP2]
154         //  x: Unknown.
155         //  y: Maybe SG13-SG8, but untested.
156         //  z: Maybe therm flag and int flag.
157         // For SP: First get SP7-SP2 right, then add SP1 and SP0
158         uint16_t sp = ((din_spi_resp << 2) & 0x00FF) | ((din_spi_resp >> 14) & 0x3);
159         uint16_t sg = ((din_spi_resp >> 8) & 0xFF00);
160         uint16_t word = sg | sp;
161
162         return word;
163 }
164
165
166 int din_spi_response()
167 {
168         return din_spi_resp;
169 }
170
171
172 /* Private functions */
173 /* ----------------- */
174 /**
175  * Switch copy command, prepared by other functions, to shadow variable,
176  * convert command to MSB,
177  * transfer command to DIN
178  * store spi response
179  * return spi response
180  */
181 int din_spi_transfer_mst(const uint32_t din_spi_cmd)
182 {
183         port_desc_t *desc;
184
185         desc = hal_port_get_dsc(PORT_NAME_DINSPI, -1);
186         uint32_t commands[3];
187         commands[0] = (din_spi_cmd & 0xFF0000) >> 16;   // command
188         commands[1] = (din_spi_cmd & 0xFF00) >> 8;      // 1.st B of data
189         commands[2] = (din_spi_cmd & 0xFF);             // 2.nd B of data
190
191         din_spi_resp = desc->port_setfnc_ptr(desc->config, desc->numValues,     \
192                                                                                  commands);
193         return din_spi_resp;
194 }