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