|
1 /** |
|
2 * @file task_adc.c |
|
3 * @brief The FreeRTOS task to query the pressure sensors on ADC inputs. |
|
4 * The task will update the ADC_State structure. |
|
5 */ |
|
6 |
|
7 |
|
8 #include "config.h" |
|
9 |
|
10 |
|
11 #define DEFAULT_VREF 1093 ///< Use adc2_vref_to_gpio() to obtain a better estimate |
|
12 #define NO_OF_SAMPLES 64 ///< Multisampling |
|
13 |
|
14 |
|
15 #define PRESSURE_1 (CONFIG_PRESSURE_1) |
|
16 #define PRESSURE_2 (CONFIG_PRESSURE_2) |
|
17 #define PRESSURE_3 (CONFIG_PRESSURE_3) |
|
18 #define BATT_CHANNEL (CONFIG_BATT_CHANNEL) |
|
19 #define BATT_ACTOR (CONFIG_BATT_ACTOR) |
|
20 |
|
21 |
|
22 static const char *TAG = "task_adc"; |
|
23 |
|
24 SemaphoreHandle_t xSemaphoreADC = NULL; ///< Semaphire ADC task |
|
25 EventGroupHandle_t xEventGroupADC; ///< Events ADC task |
|
26 ADC_State *adc_state; ///< Public state for other tasks |
|
27 |
|
28 const int TASK_ADC_REQUEST_PRESSURE = BIT0; ///< Request temperature measurements |
|
29 const int TASK_ADC_REQUEST_DONE = BIT1; ///< Request is completed |
|
30 |
|
31 |
|
32 |
|
33 void request_adc(void) |
|
34 { |
|
35 xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_DONE); |
|
36 xEventGroupSetBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE); |
|
37 } |
|
38 |
|
39 |
|
40 |
|
41 bool ready_adc(void) |
|
42 { |
|
43 if (xEventGroupGetBits(xEventGroupADC) & TASK_ADC_REQUEST_DONE) |
|
44 return true; |
|
45 return false; |
|
46 } |
|
47 |
|
48 |
|
49 /* |
|
50 static void print_char_val_type(esp_adc_cal_value_t val_type) |
|
51 { |
|
52 if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { |
|
53 ESP_LOGI(TAG, "Characterized using Two Point Value"); |
|
54 } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { |
|
55 ESP_LOGI(TAG, "Characterized using eFuse Vref"); |
|
56 } else { |
|
57 ESP_LOGI(TAG, "Characterized using Default Vref"); |
|
58 } |
|
59 } |
|
60 */ |
|
61 |
|
62 |
|
63 /* |
|
64 * Task to read pressure sensors and battery voltage on request. |
|
65 */ |
|
66 void task_adc(void *pvParameter) |
|
67 { |
|
68 int i, adc_reading; |
|
69 adc_atten_t atten = ADC_ATTEN_DB_0; |
|
70 |
|
71 ESP_LOGI(TAG, "Starting task ADC sensors"); |
|
72 // esp_log_level_set("task_adc", ESP_LOG_DEBUG); |
|
73 |
|
74 //Check TP is burned into eFuse |
|
75 // ESP_LOGI(TAG, "eFuse Two Point: %supported", (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) ? "S":"NOT s"); |
|
76 //Check Vref is burned into eFuse |
|
77 // ESP_LOGI(TAG, "eFuse Vref: %supported", (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) ? "S":"NOT s"); |
|
78 |
|
79 adc_state = malloc(sizeof(ADC_State)); |
|
80 for (i = 0; i < 3; i++) { |
|
81 adc_state->Pressure[i].valid = false; |
|
82 // adc_state->Pressure[i].atten = ADC_ATTEN_DB_2_5; // Optimal 100..1250 mV, max 1500 mV. max 4,5 bar. |
|
83 adc_state->Pressure[i].atten = ADC_ATTEN_DB_6; // Optimal 150..1750 mV, max 2200 mV, max 6,3 bar. |
|
84 adc_state->Pressure[i].voltage = 0; |
|
85 adc_state->Pressure[i].error = ADC_ERR_NONE; |
|
86 } |
|
87 adc_state->Pressure[0].channel = PRESSURE_1; |
|
88 adc_state->Pressure[1].channel = PRESSURE_2; |
|
89 adc_state->Pressure[2].channel = PRESSURE_3; |
|
90 adc_state->Batt_voltage = 0; |
|
91 adc_state->Batt_error = ADC_ERR_NONE; |
|
92 |
|
93 //Characterize ADC |
|
94 esp_adc_cal_characteristics_t *adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); |
|
95 // esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_6, ADC_WIDTH_BIT_11, DEFAULT_VREF, adc_chars); |
|
96 // print_char_val_type(val_type); |
|
97 |
|
98 /* event handler and event group for this task */ |
|
99 xEventGroupADC = xEventGroupCreate(); |
|
100 EventBits_t uxBits; |
|
101 |
|
102 /* |
|
103 * Task loop forever. |
|
104 */ |
|
105 while (1) { |
|
106 |
|
107 uxBits = xEventGroupWaitBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE, pdFALSE, pdFALSE, portMAX_DELAY ); |
|
108 |
|
109 if (uxBits & TASK_ADC_REQUEST_PRESSURE) { |
|
110 |
|
111 adc1_config_width(ADC_WIDTH_BIT_11); |
|
112 |
|
113 for (i = 0; i < 3; i++) { |
|
114 adc_reading = 0; |
|
115 atten = ADC_ATTEN_DB_0; |
|
116 |
|
117 /* |
|
118 * Autoranging the ADC conversion |
|
119 */ |
|
120 while (1) { |
|
121 esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_BIT_11, DEFAULT_VREF, adc_chars); |
|
122 adc1_config_channel_atten((adc1_channel_t)adc_state->Pressure[i].channel, atten); |
|
123 int raw = adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); |
|
124 // printf("raw: %d atten: %d\n", raw, atten); |
|
125 // if (raw < 3400) |
|
126 // break; |
|
127 |
|
128 if (atten == ADC_ATTEN_DB_0 && raw > 1850) |
|
129 atten = ADC_ATTEN_DB_2_5; |
|
130 else if (atten == ADC_ATTEN_DB_2_5 && raw > 1850) |
|
131 atten = ADC_ATTEN_DB_6; |
|
132 else if (atten == ADC_ATTEN_DB_6 && raw > 1850) |
|
133 atten = ADC_ATTEN_DB_11; |
|
134 else |
|
135 break; |
|
136 } |
|
137 |
|
138 /* |
|
139 * Now that he have the best attenuation, multisample the real value. |
|
140 */ |
|
141 for (int j = 0; j < NO_OF_SAMPLES; j++) { |
|
142 int tmp = adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); |
|
143 adc_reading += tmp; |
|
144 // printf("%4d ", tmp); |
|
145 //adc_reading += adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); |
|
146 } |
|
147 // printf("\n"); |
|
148 if (adc_reading < 0) { |
|
149 adc_state->Pressure[i].error = ADC_ERR_READ; |
|
150 adc_state->Pressure[i].voltage = 0; |
|
151 } else { |
|
152 adc_reading /= NO_OF_SAMPLES; |
|
153 if (xSemaphoreTake(xSemaphoreADC, 25) == pdTRUE) { |
|
154 adc_state->Pressure[i].voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); // voltage in mV |
|
155 adc_state->Pressure[i].error = ADC_ERR_NONE; |
|
156 xSemaphoreGive(xSemaphoreADC); |
|
157 } |
|
158 } |
|
159 ESP_LOGI(TAG, "Pressure %d raw: %4d, atten: %d, %.3f volt, error: %d", |
|
160 i, adc_reading, atten, adc_state->Pressure[i].voltage / 1000.0, adc_state->Pressure[i].error); |
|
161 } |
|
162 |
|
163 adc_reading = 0; |
|
164 atten = ADC_ATTEN_DB_6; // Don't use DB_11, it has a bad linearity. |
|
165 esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_BIT_11, DEFAULT_VREF, adc_chars); |
|
166 adc1_config_channel_atten((adc1_channel_t)BATT_CHANNEL, atten); |
|
167 for (int j = 0; j < NO_OF_SAMPLES; j++) { |
|
168 adc_reading += adc1_get_raw((adc1_channel_t)BATT_CHANNEL); |
|
169 } |
|
170 |
|
171 if (adc_reading < 0) { |
|
172 adc_state->Batt_voltage = 0; |
|
173 adc_state->Batt_error = ADC_ERR_READ; |
|
174 } else { |
|
175 adc_reading /= NO_OF_SAMPLES; |
|
176 if (xSemaphoreTake(xSemaphoreADC, 25) == pdTRUE) { |
|
177 adc_state->Batt_voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars) * 2; // Chip supply voltage in mV |
|
178 adc_state->Batt_error = ADC_ERR_NONE; |
|
179 xSemaphoreGive(xSemaphoreADC); |
|
180 } |
|
181 } |
|
182 |
|
183 xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE); |
|
184 xEventGroupSetBits(xEventGroupADC, TASK_ADC_REQUEST_DONE); |
|
185 #if 1 |
|
186 ESP_LOGI(TAG, "Battery raw: %4d, atten: %d %.3f volt, error: %d", adc_reading, atten, adc_state->Batt_voltage / 1000.0, adc_state->Batt_error); |
|
187 #endif |
|
188 } |
|
189 vTaskDelay( (TickType_t)10); |
|
190 } |
|
191 } |
|
192 |