]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/adc.c
Fixed includes in rpp and sys libs.
[pes-rpp/rpp-lib.git] / rpp / src / drv / adc.c
1 /*
2  * adc.c
3  *
4  *  Created on: 23.11.2012
5  *      Author: Michal Horn
6  *
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.
9  */
10 #include "drv_adc.h"
11
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 */
15 MyAdcData_t adcData;
16 /**     Place to store converted data **/
17 static adcData_t adc_data_origin[ADC_MAX_CHANNELS_COUNT*2];
18
19
20 /**
21  * @brief Function called by ADC interrupt handler, stores data from ADC
22  *
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.
25  *
26  *  @param[in]  adc     Pointer to ADC registers
27  *  @param[in]  group   Identificator of the ADC group, whic caused the interrupt
28  */
29 void adcNotification(adcBASE_t *adc, uint32_t group)
30 {
31         /* FIXME Move this implementation and header somewhere else
32         // Group selected by group selector has been read
33         if (adc->GxINTFLG[group] & 8) {
34                 uint32_t ch_count;
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);
38         }
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;
44         }
45         */
46 }
47
48 /**
49  * @brief       Master function for AD conversion
50  *
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
53  *
54  * @param[in]   adc     Pointer to ADC registers
55  * @param[in]   group   ADC group identificator
56  *
57  * @return      0 when success, 1 when error
58  */
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
62                 return 1;
63         }
64         adcDataConverted = xSemaphoreCreateCounting(1, 0);
65         adcEnableNotification(adc, group);
66     adcCalibration(adc);
67     adcMidPointCalibration(adc);
68
69         adcStartConversion(adc, group);
70         xSemaphoreTake(adcDataConverted, portMAX_DELAY);                // Wait the measurement to complete
71
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);
77         return 1;
78     }
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;
82     }
83         adcDisableNotification(adc, group);
84         vSemaphoreDelete(adcDataConverted);
85     return 0;
86     */
87         return 0;
88 }
89
90 /**
91  * @brief       High level general function for AD conversion
92  *
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
97  */
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;
102
103     if (read_adc(adc, group) == 1)
104         return 1;
105     return 0;
106 }
107
108 /**
109  * @brief       High level function fot data conversion from AD port on the board
110  *
111  * @param[in]   Pointer to ADC registers
112  * @param[in]   Number of channels to be converted
113  * @param[out]  Converted values
114  *
115  * @return 0 when success, 1 when error
116  */
117 uint32_t adc_get_port_val(uint32_t* config, uint32_t num_channels, uint32_t* values) {
118         uint32_t i;
119         adcBASE_t* adcReg = (adcBASE_t *)config[0];
120         uint32_t adcGroup = config[1];
121
122     adcData.adc_data = adc_data_origin;
123     adcData.ch_count = num_channels;
124     if (read_adc(adcReg, adcGroup) == 1)
125         return 1;
126
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;
130     }
131     adcData.adc_data = NULL;
132         return 0;
133 }