#include "esp_log.h" #include "esp_adc/adc_continuous.h" #include "esp_adc/adc_cali.h" #include "esp_adc/adc_cali_scheme.h" #include "hal/adc_types.h" #include "soc/soc_caps.h" #include "spinlock.h" #include "freertos/portmacro.h" #include "measure.h" #include #define TAG "Measure" static uint8_t channel_index[CONFIG_ADC_IN_PIN_NUM]; static uint32_t meas_res[CONFIG_ADC_IN_PIN_NUM]; static uint32_t meas_nb[CONFIG_ADC_IN_PIN_NUM]; spinlock_t adc_res_mutex; uint32_t meas_res_buff[CONFIG_ADC_IN_PIN_NUM]; uint32_t meas_nb_buff[CONFIG_ADC_IN_PIN_NUM]; adc_continuous_handle_t adc_handle; adc_cali_handle_t adc_cali_handles[CONFIG_ADC_IN_PIN_NUM]; static uint8_t* adc_pins; static bool IRAM_ATTR on_conv_done(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data){ adc_digi_output_data_t* res = (adc_digi_output_data_t*)edata->conv_frame_buffer; if(res->type2.channel < 0 || res->type2.channel >= CONFIG_ADC_IN_PIN_NUM) return false; //invalid channel int index = channel_index[res->type2.channel]; meas_res[index] += res->type2.data; meas_nb[index]++; return false; } void init_adc(uint8_t* _adc_pins){ adc_pins = _adc_pins; adc_continuous_handle_cfg_t adc_h_conf = { .conv_frame_size = SOC_ADC_DIGI_DATA_BYTES_PER_CONV, .max_store_buf_size = SOC_ADC_DIGI_DATA_BYTES_PER_CONV * CONFIG_ADC_IN_PIN_NUM, }; ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_h_conf, &adc_handle)); adc_digi_pattern_config_t adc_pattern[CONFIG_ADC_IN_PIN_NUM]; for(int i = 0; i < CONFIG_ADC_IN_PIN_NUM; i++){ adc_channel_t channel; adc_unit_t unit; adc_continuous_io_to_channel(adc_pins[i], &unit, &channel); if(unit != ADC_UNIT_1){ ESP_LOGE(TAG, "Wrong unit for one of the selected pins"); } channel_index[channel] = i; adc_pattern[i] = (adc_digi_pattern_config_t){ .atten = ADC_ATTEN_DB_0, .bit_width = ADC_BITWIDTH_12, .channel = channel, .unit = ADC_UNIT_1, }; } adc_continuous_config_t adc_conf = { .adc_pattern = adc_pattern, .pattern_num = CONFIG_ADC_IN_PIN_NUM, .conv_mode = ADC_CONV_SINGLE_UNIT_1, .format = ADC_DIGI_OUTPUT_FORMAT_TYPE2, .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, }; ESP_ERROR_CHECK(adc_continuous_config(adc_handle, &adc_conf)); adc_continuous_evt_cbs_t adc_event = { .on_conv_done = &on_conv_done, .on_pool_ovf = NULL, }; ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(adc_handle, &adc_event, NULL)); spinlock_initialize(&adc_res_mutex); } void init_adc_cali(){ for(int i = 0; i < CONFIG_ADC_IN_PIN_NUM; i++){ adc_cali_curve_fitting_config_t conf = { .atten = ADC_ATTEN_DB_0, .bitwidth = ADC_BITWIDTH_12, .unit_id = ADC_UNIT_1, }; ESP_ERROR_CHECK(adc_cali_create_scheme_curve_fitting(&conf, &adc_cali_handles[i])); } } void adc_start(){ ESP_ERROR_CHECK(adc_continuous_start(adc_handle)); } void fetch_measures(){ portENTER_CRITICAL(&adc_res_mutex); for(int i = 0; i < CONFIG_ADC_IN_PIN_NUM; i++){ meas_res_buff[i] = meas_res[i]; meas_nb_buff[i] = meas_nb[i]; meas_res[i] = 0; meas_nb[i] = 0; } portEXIT_CRITICAL(&adc_res_mutex); } void get_measures_raw_mV(uint32_t values[]){ for(int i = 0; i < CONFIG_ADC_IN_PIN_NUM; i++){ int mv; uint32_t val = meas_res_buff[i] / meas_nb_buff[i]; ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc_cali_handles[i], val, &mv)); values[i] = mv; } } void get_measures_calc(uint32_t values[]){ for(int i = 0; i < CONFIG_ADC_IN_PIN_NUM; i++){ int mv; uint32_t val = meas_res_buff[i] / meas_nb_buff[i]; ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc_cali_handles[i], val, &mv)); switch(adc_pins[i]){ case CONFIG_OUT_VOLT_PIN: values[i] = mv * 33; break; default: values[i] = mv * 10; } } }