1 /* Copyright (C) 2012-2013, 2015 Czech Technical University in Prague
5 * - Carlos Jenkins <carlos@jenkins.co.cr>
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.
14 * RPP driver implementation for ADC.
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;
29 // Mutex for AIN read control
30 xSemaphoreHandle adcMutex_ADC;
31 // Mutex for HOUTIFBK control
32 xSemaphoreHandle adcMutex_HOUTIFBK;
37 vSemaphoreCreateBinary(adcSemaphore_ADC1GRP1);
38 xSemaphoreTake(adcSemaphore_ADC1GRP1, 0);
39 vSemaphoreCreateBinary(adcSemaphore_ADC2GRP1);
40 xSemaphoreTake(adcSemaphore_ADC2GRP1, 0);
42 adcMutex_ADC = xSemaphoreCreateMutex();
43 adcMutex_HOUTIFBK = xSemaphoreCreateMutex();
51 * ADC notification called by ADC conversion finished ISR.
53 * This procedure will just give semaphore.
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
63 void adcNotification(adcBASE_t *adc, uint32_t group)
65 if (adcIsConversionComplete(adc, group) == ADC_CONVERSION_IS_FINISHED) {
71 // Group0 is unused on RPP
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
79 signed portBASE_TYPE dummy;
80 xSemaphoreGiveFromISR(adcSemaphore_ADC1GRP1, &dummy);
84 // Group2 is unused on RPP
92 // Group0 is unused on RPP
96 signed portBASE_TYPE dummy;
97 xSemaphoreGiveFromISR(adcSemaphore_ADC2GRP1, &dummy);
101 // Group2 is unused on RPP
109 uint32_t drv_adc_generic_read(adcBASE_t *adc, uint32_t group,
110 xSemaphoreHandle adcSemaphore, adcData_t *data)
114 adcMidPointCalibration(adc);
117 adcEnableNotification(adc, group);
118 adcStartConversion(adc, group);
120 // Wait for conversion to complete
121 xSemaphoreTake(adcSemaphore, portMAX_DELAY);
122 adcDisableNotification(adc, group);
125 uint32_t channels = adcGetData(adc, group, data);
127 // Check if memory overrun
128 if (adcIsFifoFull(adc, group) == ADC_FIFO_OVERFLOW)
129 // FIXME Should report somehow.
130 adcResetFiFo(adc, group);
136 uint32_t drv_adc_read_adc(adcData_t *data)
138 xSemaphoreTake(adcMutex_ADC, portMAX_DELAY);
139 uint32_t result = drv_adc_generic_read(
142 adcSemaphore_ADC1GRP1,
145 xSemaphoreGive(adcMutex_ADC);
149 uint32_t drv_adc_read_houtifbk(adcData_t *data)
151 xSemaphoreTake(adcMutex_HOUTIFBK, portMAX_DELAY);
152 uint32_t result = drv_adc_generic_read(
155 adcSemaphore_ADC2GRP1,
158 xSemaphoreGive(adcMutex_HOUTIFBK);
162 #define MIN(a,b) ((a) < (b) ? (a) : (b))
164 int8_t port_adc_get(const struct port_desc *port, void *values, size_t size)
167 adcData_t data[ADC_MAX_CHANNELS];
168 int count = MIN(port->numchn, size/sizeof(uint16_t));
169 uint16_t *adcval = values;
171 assert(port->bpch == 16);
172 assert(size % sizeof(uint16_t) == 0);
174 drv_adc_generic_read(
177 (port->cfg.adc.sem == 1) ? adcSemaphore_ADC1GRP1 : adcSemaphore_ADC2GRP1,
181 for (i = 0; i < count; i++)
182 adcval[i] = data[i].value;