diff -r 000000000000 -r 88d965579617 main/task_adc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/task_adc.c Tue Oct 08 12:00:31 2019 +0200 @@ -0,0 +1,192 @@ +/** + * @file task_adc.c + * @brief The FreeRTOS task to query the pressure sensors on ADC inputs. + * The task will update the ADC_State structure. + */ + + +#include "config.h" + + +#define DEFAULT_VREF 1093 ///< Use adc2_vref_to_gpio() to obtain a better estimate +#define NO_OF_SAMPLES 64 ///< Multisampling + + +#define PRESSURE_1 (CONFIG_PRESSURE_1) +#define PRESSURE_2 (CONFIG_PRESSURE_2) +#define PRESSURE_3 (CONFIG_PRESSURE_3) +#define BATT_CHANNEL (CONFIG_BATT_CHANNEL) +#define BATT_ACTOR (CONFIG_BATT_ACTOR) + + +static const char *TAG = "task_adc"; + +SemaphoreHandle_t xSemaphoreADC = NULL; ///< Semaphire ADC task +EventGroupHandle_t xEventGroupADC; ///< Events ADC task +ADC_State *adc_state; ///< Public state for other tasks + +const int TASK_ADC_REQUEST_PRESSURE = BIT0; ///< Request temperature measurements +const int TASK_ADC_REQUEST_DONE = BIT1; ///< Request is completed + + + +void request_adc(void) +{ + xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_DONE); + xEventGroupSetBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE); +} + + + +bool ready_adc(void) +{ + if (xEventGroupGetBits(xEventGroupADC) & TASK_ADC_REQUEST_DONE) + return true; + return false; +} + + +/* +static void print_char_val_type(esp_adc_cal_value_t val_type) +{ + if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { + ESP_LOGI(TAG, "Characterized using Two Point Value"); + } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { + ESP_LOGI(TAG, "Characterized using eFuse Vref"); + } else { + ESP_LOGI(TAG, "Characterized using Default Vref"); + } +} +*/ + + +/* + * Task to read pressure sensors and battery voltage on request. + */ +void task_adc(void *pvParameter) +{ + int i, adc_reading; + adc_atten_t atten = ADC_ATTEN_DB_0; + + ESP_LOGI(TAG, "Starting task ADC sensors"); +// esp_log_level_set("task_adc", ESP_LOG_DEBUG); + + //Check TP is burned into eFuse +// ESP_LOGI(TAG, "eFuse Two Point: %supported", (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) ? "S":"NOT s"); + //Check Vref is burned into eFuse +// ESP_LOGI(TAG, "eFuse Vref: %supported", (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) ? "S":"NOT s"); + + adc_state = malloc(sizeof(ADC_State)); + for (i = 0; i < 3; i++) { + adc_state->Pressure[i].valid = false; +// adc_state->Pressure[i].atten = ADC_ATTEN_DB_2_5; // Optimal 100..1250 mV, max 1500 mV. max 4,5 bar. + adc_state->Pressure[i].atten = ADC_ATTEN_DB_6; // Optimal 150..1750 mV, max 2200 mV, max 6,3 bar. + adc_state->Pressure[i].voltage = 0; + adc_state->Pressure[i].error = ADC_ERR_NONE; + } + adc_state->Pressure[0].channel = PRESSURE_1; + adc_state->Pressure[1].channel = PRESSURE_2; + adc_state->Pressure[2].channel = PRESSURE_3; + adc_state->Batt_voltage = 0; + adc_state->Batt_error = ADC_ERR_NONE; + + //Characterize ADC + esp_adc_cal_characteristics_t *adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); +// 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); +// print_char_val_type(val_type); + + /* event handler and event group for this task */ + xEventGroupADC = xEventGroupCreate(); + EventBits_t uxBits; + + /* + * Task loop forever. + */ + while (1) { + + uxBits = xEventGroupWaitBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE, pdFALSE, pdFALSE, portMAX_DELAY ); + + if (uxBits & TASK_ADC_REQUEST_PRESSURE) { + + adc1_config_width(ADC_WIDTH_BIT_11); + + for (i = 0; i < 3; i++) { + adc_reading = 0; + atten = ADC_ATTEN_DB_0; + + /* + * Autoranging the ADC conversion + */ + while (1) { + esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_BIT_11, DEFAULT_VREF, adc_chars); + adc1_config_channel_atten((adc1_channel_t)adc_state->Pressure[i].channel, atten); + int raw = adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); +// printf("raw: %d atten: %d\n", raw, atten); +// if (raw < 3400) +// break; + + if (atten == ADC_ATTEN_DB_0 && raw > 1850) + atten = ADC_ATTEN_DB_2_5; + else if (atten == ADC_ATTEN_DB_2_5 && raw > 1850) + atten = ADC_ATTEN_DB_6; + else if (atten == ADC_ATTEN_DB_6 && raw > 1850) + atten = ADC_ATTEN_DB_11; + else + break; + } + + /* + * Now that he have the best attenuation, multisample the real value. + */ + for (int j = 0; j < NO_OF_SAMPLES; j++) { + int tmp = adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); + adc_reading += tmp; +// printf("%4d ", tmp); + //adc_reading += adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); + } +// printf("\n"); + if (adc_reading < 0) { + adc_state->Pressure[i].error = ADC_ERR_READ; + adc_state->Pressure[i].voltage = 0; + } else { + adc_reading /= NO_OF_SAMPLES; + if (xSemaphoreTake(xSemaphoreADC, 25) == pdTRUE) { + adc_state->Pressure[i].voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); // voltage in mV + adc_state->Pressure[i].error = ADC_ERR_NONE; + xSemaphoreGive(xSemaphoreADC); + } + } + ESP_LOGI(TAG, "Pressure %d raw: %4d, atten: %d, %.3f volt, error: %d", + i, adc_reading, atten, adc_state->Pressure[i].voltage / 1000.0, adc_state->Pressure[i].error); + } + + adc_reading = 0; + atten = ADC_ATTEN_DB_6; // Don't use DB_11, it has a bad linearity. + esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_BIT_11, DEFAULT_VREF, adc_chars); + adc1_config_channel_atten((adc1_channel_t)BATT_CHANNEL, atten); + for (int j = 0; j < NO_OF_SAMPLES; j++) { + adc_reading += adc1_get_raw((adc1_channel_t)BATT_CHANNEL); + } + + if (adc_reading < 0) { + adc_state->Batt_voltage = 0; + adc_state->Batt_error = ADC_ERR_READ; + } else { + adc_reading /= NO_OF_SAMPLES; + if (xSemaphoreTake(xSemaphoreADC, 25) == pdTRUE) { + adc_state->Batt_voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars) * 2; // Chip supply voltage in mV + adc_state->Batt_error = ADC_ERR_NONE; + xSemaphoreGive(xSemaphoreADC); + } + } + + xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE); + xEventGroupSetBits(xEventGroupADC, TASK_ADC_REQUEST_DONE); +#if 1 + 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); +#endif + } + vTaskDelay( (TickType_t)10); + } +} +