4 * Created on: 23.11.2012
7 * This file contains low level and high level functions for reading from ADC.
8 * One function for reading from ADC port on the board is also defined.
12 /** @brief Semaphore blocking task when it waits for interrupt signaling end of the conversion */
13 //xSemaphoreHandle adcDataConverted;
14 /** @brief Data structure containing converted data from ADC */
16 /** Place to store converted data **/
17 static adcData_t adc_data_origin[ADC_MAX_CHANNELS_COUNT*2];
21 * @brief Function called by ADC interrupt handler, stores data from ADC
23 * If conversion has finished on ADC, store measured data and detect weather right number of channels was measured.
24 * If memory overrun was detected, set appropriate flag, reset ADC FIFO to be allow future measurement.
26 * @param[in] adc Pointer to ADC registers
27 * @param[in] group Identificator of the ADC group, whic caused the interrupt
29 void adcNotification(adcBASE_t *adc, uint32_t group)
31 /* FIXME Move this implementation and header somewhere else
32 // Group selected by group selector has been read
33 if (adc->GxINTFLG[group] & 8) {
35 ch_count = adcGetData(adc, group, &adcData.adc_data[0]);
36 adcData.flags |= (ch_count == adcData.ch_count) ? 0 : BAD_CHANNELS_COUNT;
37 xSemaphoreGiveFromISR(adcDataConverted, NULL);
39 // Memory overrun detected - set flag
40 if (adc->GxINTFLG[group] & 2) {
41 print((uint8_t *)"Warning: ADC overrun detected!\r\n");
42 adcData.flags |= MEM_OVERRUN;
43 adc->GxFIFORESETCR[1] = 1;
49 * @brief Master function for AD conversion
51 * This function expects adcData.adc_data to be initialized to proper size (ADC_NUM_CHANNELS*2)
52 * Function waits until conversion completes (by semaphore, which is released in ADC ISR
54 * @param[in] adc Pointer to ADC registers
55 * @param[in] group ADC group identificator
57 * @return 0 when success, 1 when error
59 int read_adc(adcBASE_t* adc, uint32_t group) {
60 /* FIXME Move this implementation and header somewhere else
61 if (adcData.adc_data == NULL) { // ADC data structure was not initialized
64 adcDataConverted = xSemaphoreCreateCounting(1, 0);
65 adcEnableNotification(adc, group);
67 adcMidPointCalibration(adc);
69 adcStartConversion(adc, group);
70 xSemaphoreTake(adcDataConverted, portMAX_DELAY); // Wait the measurement to complete
72 if (adcData.flags & BAD_CHANNELS_COUNT) {
73 print((uint8_t *)"\r\nERROR: Bad count of channels was read! Can not proceed.");
74 adcData.flags &= ~BAD_CHANNELS_COUNT;
75 adcDisableNotification(adc, group);
76 vSemaphoreDelete(adcDataConverted);
79 if (adcData.flags & MEM_OVERRUN) {
80 print((uint8_t *)"\r\nWARNING: ADC Memory overrun detected. Values can be imprecise.");
81 adcData.flags &= ~MEM_OVERRUN;
83 adcDisableNotification(adc, group);
84 vSemaphoreDelete(adcDataConverted);
91 * @brief High level general function for AD conversion
93 * @param[out] adc_data_origin Pointer to adc data array, where converted data will be stored
94 * @param[in] adc_num_channels Number of channels to be converted
95 * @param[in] adc Pointer to ADC registers
96 * @param[in] group ADC group identificator
98 int adc_read_values(adcData_t* adc_data_origin, uint32_t adc_num_channels, adcBASE_t* adc, uint32_t group) {
99 /* ADCData structure initialization */
100 adcData.adc_data = adc_data_origin;
101 adcData.ch_count = adc_num_channels;
103 if (read_adc(adc, group) == 1)
109 * @brief High level function fot data conversion from AD port on the board
111 * @param[in] Pointer to ADC registers
112 * @param[in] Number of channels to be converted
113 * @param[out] Converted values
115 * @return 0 when success, 1 when error
117 uint32_t adc_get_port_val(uint32_t* config, uint32_t num_channels, uint32_t* values) {
119 adcBASE_t* adcReg = (adcBASE_t *)config[0];
120 uint32_t adcGroup = config[1];
122 adcData.adc_data = adc_data_origin;
123 adcData.ch_count = num_channels;
124 if (read_adc(adcReg, adcGroup) == 1)
127 for (i = 0; i < num_channels; i++) {
128 values[i] = adcData.adc_data[i].value;
129 values[i+num_channels] = adcData.adc_data[i].id;
131 adcData.adc_data = NULL;