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