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.
23 #include "os/portmacro.h"
25 // Binary semaphores for finish notifications
26 static xSemaphoreHandle sem[2][2];
29 xSemaphoreHandle mutex[2];
35 for (adc = 0; adc < 2; adc++) {
36 for (grp = 0; grp < 2; grp++) {
37 vSemaphoreCreateBinary(sem[adc][grp]);
38 xSemaphoreTake(sem[adc][grp], 0);
40 mutex[adc] = xSemaphoreCreateMutex();
48 * ADC notification called by ADC conversion finished ISR.
50 * This procedure will just give semaphore.
52 * @param[in] adc Pointer to ADC module:
53 * - adcREG1: ADC1 module pointer
54 * - adcREG2: ADC2 module pointer
55 * @param[in] group Hardware group of ADC module:
56 * - adcGROUP0: ADC event group
57 * - adcGROUP1: ADC group 1
58 * - adcGROUP2: ADC group 2
60 void adcNotification(adcBASE_t *adc, uint32_t group, portBASE_TYPE* xHigherPriorityTaskWoken)
62 if (adcIsConversionComplete(adc, group) == ADC_CONVERSION_IS_FINISHED) {
63 int adc_idx = (adc == adcREG1) ? 0 : 1;
64 int grp_idx = (group == adcGROUP1) ? 0 : 1;
65 xSemaphoreGiveFromISR(sem[adc_idx][grp_idx], xHigherPriorityTaskWoken);
70 uint32_t drv_adc_generic_read(adcBASE_t *adc, uint32_t group,
73 int adc_idx = (adc == adcREG1) ? 0 : 1;
74 int grp_idx = (group == adcGROUP1) ? 0 : 1;
76 xSemaphoreTake(mutex[adc_idx], portMAX_DELAY);
80 adcMidPointCalibration(adc);
83 adcEnableNotification(adc, group);
84 adcStartConversion(adc, group);
86 // Wait for conversion to complete
87 xSemaphoreTake(sem[adc_idx][grp_idx], portMAX_DELAY);
88 adcDisableNotification(adc, group);
91 uint32_t channels = adcGetData(adc, group, data);
93 // Check if memory overrun
94 if (adcIsFifoFull(adc, group) == ADC_FIFO_OVERFLOW)
95 // FIXME Should report somehow.
96 adcResetFiFo(adc, group);
98 xSemaphoreGive(mutex[adc_idx]);
103 #define MIN(a,b) ((a) < (b) ? (a) : (b))
105 int8_t port_adc_get(const struct port_desc *port, void *values, size_t size)
108 adcData_t data[ADC_MAX_CHANNELS];
109 int count = MIN(port->numchn, size/sizeof(uint16_t));
110 uint16_t *adcval = values;
112 assert(port->bpch == 16);
113 assert(size % sizeof(uint16_t) == 0);
115 drv_adc_generic_read(
121 for (i = 0; i < count; i++)
122 adcval[i] = data[i].value;