]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/_tms570_rpp/adc.c
Update adc and spi to the new port interface
[pes-rpp/rpp-lib.git] / rpp / src / drv / _tms570_rpp / adc.c
1 /* Copyright (C) 2012-2013, 2015 Czech Technical University in Prague
2  *
3  * Authors:
4  *     - Michal Horn
5  *     - Carlos Jenkins <carlos@jenkins.co.cr>
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 : adc.c
13  * Abstract:
14  *     RPP driver implementation for ADC.
15  *
16  * References:
17  *     ti_drv_adc.c
18  */
19
20
21 #include "drv/drv.h"
22 #include "drv/port.h"
23
24 // Binary semaphore for ADC1 GRP1 conversion (AIN)
25 xSemaphoreHandle adcSemaphore_ADC1GRP1;
26 // Binary semaphore for ADC2 GRP1 conversion (HOUT-IFBK)
27 xSemaphoreHandle adcSemaphore_ADC2GRP1;
28
29 // Mutex for AIN read control
30 xSemaphoreHandle adcMutex_ADC;
31 // Mutex for HOUTIFBK control
32 xSemaphoreHandle adcMutex_HOUTIFBK;
33
34 void drv_adc_init()
35 {
36         // Create semaphores
37         vSemaphoreCreateBinary(adcSemaphore_ADC1GRP1);
38         xSemaphoreTake(adcSemaphore_ADC1GRP1, 0);
39         vSemaphoreCreateBinary(adcSemaphore_ADC2GRP1);
40         xSemaphoreTake(adcSemaphore_ADC2GRP1, 0);
41
42         adcMutex_ADC       = xSemaphoreCreateMutex();
43         adcMutex_HOUTIFBK  = xSemaphoreCreateMutex();
44
45         // Low level init
46         adcInit();
47 }
48
49
50 /**
51  * ADC notification called by ADC conversion finished ISR.
52  *
53  * This procedure will just give semaphore.
54  *
55  *   @param[in] adc Pointer to ADC module:
56  *              - adcREG1: ADC1 module pointer
57  *              - adcREG2: ADC2 module pointer
58  *   @param[in] group Hardware group of ADC module:
59  *              - adcGROUP0: ADC event group
60  *              - adcGROUP1: ADC group 1
61  *              - adcGROUP2: ADC group 2
62  */
63 void adcNotification(adcBASE_t *adc, uint32_t group)
64 {
65         if (adcIsConversionComplete(adc, group) == ADC_CONVERSION_IS_FINISHED) {
66
67                 // ADC1
68                 if (adc == adcREG1) {
69                         switch (group) {
70                         case adcGROUP0:
71                                 // Group0 is unused on RPP
72                                 break;
73                         case adcGROUP1:
74                                 // According to FreeRTOS documentation second parameter is
75                                 // optional (and can be set to NULL) from FreeRTOS
76                                 // V7.3.0. We are using 7.0.2. I confirmed this in the
77                                 // source code: src/os/queue.c line 821. - Carlos
78                         {
79                                 signed portBASE_TYPE dummy;
80                                 xSemaphoreGiveFromISR(adcSemaphore_ADC1GRP1, &dummy);
81                         }
82                         break;
83                         default:
84                                 // Group2 is unused on RPP
85                                 break;
86                         }
87                         // ADC2
88                 }
89                 else {
90                         switch (group) {
91                         case adcGROUP0:
92                                 // Group0 is unused on RPP
93                                 break;
94                         case adcGROUP1:
95                         {
96                                 signed portBASE_TYPE dummy;
97                                 xSemaphoreGiveFromISR(adcSemaphore_ADC2GRP1, &dummy);
98                         }
99                         break;
100                         default:
101                                 // Group2 is unused on RPP
102                                 break;
103                         }
104                 }
105         }
106 }
107
108
109 uint32_t drv_adc_generic_read(adcBASE_t *adc, uint32_t group,
110                                                           xSemaphoreHandle adcSemaphore, adcData_t *data)
111 {
112         // Calibrate
113         adcCalibration(adc);
114         adcMidPointCalibration(adc);
115
116         // Start conversion
117         adcEnableNotification(adc, group);
118         adcStartConversion(adc, group);
119
120         // Wait for conversion to complete
121         xSemaphoreTake(adcSemaphore, portMAX_DELAY);
122         adcDisableNotification(adc, group);
123
124         // Get data
125         uint32_t channels = adcGetData(adc, group, data);
126
127         // Check if memory overrun
128         if (adcIsFifoFull(adc, group) == ADC_FIFO_OVERFLOW)
129                 // FIXME Should report somehow.
130                 adcResetFiFo(adc, group);
131
132         return channels;
133 }
134
135
136 uint32_t drv_adc_read_adc(adcData_t *data)
137 {
138         xSemaphoreTake(adcMutex_ADC, portMAX_DELAY);
139         uint32_t result = drv_adc_generic_read(
140                 adcREG1,
141                 adcGROUP1,
142                 adcSemaphore_ADC1GRP1,
143                 data
144                 );
145         xSemaphoreGive(adcMutex_ADC);
146         return result;
147 }
148
149 uint32_t drv_adc_read_houtifbk(adcData_t *data)
150 {
151         xSemaphoreTake(adcMutex_HOUTIFBK, portMAX_DELAY);
152         uint32_t result = drv_adc_generic_read(
153                 adcREG2,
154                 adcGROUP1,
155                 adcSemaphore_ADC2GRP1,
156                 data
157                 );
158         xSemaphoreGive(adcMutex_HOUTIFBK);
159         return result;
160 }
161
162 #define MIN(a,b) ((a) < (b) ? (a) : (b))
163
164 int8_t port_adc_get(const struct port_desc *port, void *values, size_t size)
165 {
166         uint32_t i;
167         adcData_t data[ADC_MAX_CHANNELS];
168         int count = MIN(port->numchn, size/sizeof(uint16_t));
169         uint16_t *adcval = values;
170
171         assert(port->bpch == 16);
172         assert(size % sizeof(uint16_t) == 0);
173
174         drv_adc_generic_read(
175                 port->cfg.adc.reg,
176                 port->cfg.adc.group,
177                 (port->cfg.adc.sem == 1) ? adcSemaphore_ADC1GRP1 : adcSemaphore_ADC2GRP1,
178                 data
179                 );
180
181         for (i = 0; i < count; i++)
182                 adcval[i] = data[i].value;
183
184         return 0;
185 }