#include #include #include #include "driver/adc_types_legacy.h" #include "driver/gpio.h" #include "esp_adc/adc_cali.h" #include "esp_adc/adc_continuous.h" #include "esp_adc/adc_oneshot.h" #include "esp_intr_alloc.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/portmacro.h" #include "hal/adc_types.h" #include "hal/gpio_types.h" #include "resistor_ranges.h" #include "measure.h" #include "soc/soc_caps.h" #define TAG "main" #define OVERRANGE_PIN 4 enum ranges {R1, R10, R100, R_NUM}; resistor_range ranges[] = { [R1] = { .pin = GPIO_NUM_6, .resistance = 1000, }, [R10] = { .pin = GPIO_NUM_7, .resistance = 10000, }, [R100] = { .pin = GPIO_NUM_NC, .resistance = 100000, }, }; enum inputs {X1, X10, X100, INPUTS_NUM}; measurement_input inputs[] = { [X1] = { .channel = ADC1_CHANNEL_3, .gain = 1, }, [X10] = { .channel = ADC1_CHANNEL_0, .gain = 10, }, [X100] = { .channel = ADC1_CHANNEL_1, .gain = 100, }, }; static spinlock_t adc_res_mutex; volatile uint32_t meas_res[INPUTS_NUM]; volatile uint32_t meas_nb[INPUTS_NUM]; uint32_t offsets[INPUTS_NUM]; unsigned int r_ind = 0; int get_input_index_from_channel(adc_channel_t channel){ switch(channel){ case ADC1_CHANNEL_3: return 0; case ADC1_CHANNEL_0: return 1; case ADC1_CHANNEL_1: return 2; default: return -1; } } 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; int index = get_input_index_from_channel(res->type2.channel); meas_res[index] += res->type2.data; meas_nb[index]++; return false; } char overrange_flag = 0; static void IRAM_ATTR overrange_handler(void* arg) { overrange_flag = 1; } void app_main(void){ gpio_config_t overrange_input = { .intr_type = GPIO_INTR_POSEDGE, .mode = GPIO_MODE_INPUT, .pin_bit_mask = 1ULL << OVERRANGE_PIN, .pull_down_en = 0, .pull_up_en = 0, }; gpio_config(&overrange_input); gpio_install_isr_service(0); gpio_isr_handler_add(OVERRANGE_PIN, overrange_handler, NULL); set_resistor_gpio(ranges, R100); activate_range(ranges, R100, R100); adc_continuous_handle_t adc_handle = init_measurement_inputs(inputs, INPUTS_NUM); spinlock_initialize(&adc_res_mutex); adc_cali_handle_t adc_conv_h[INPUTS_NUM]; init_conv_driver(inputs, INPUTS_NUM, adc_conv_h); 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)); ESP_ERROR_CHECK(adc_continuous_start(adc_handle)); while(1){ ESP_LOGI(TAG, "RANGE : %d", r_ind); int meas_res_buff[INPUTS_NUM]; int meas_nb_buff[INPUTS_NUM]; portENTER_CRITICAL(&adc_res_mutex); for(int i = 0; i < INPUTS_NUM; i++){ meas_res_buff[i] = meas_res[i]; meas_res[i] = 0; meas_nb_buff[i] = meas_nb[i]; meas_nb[i] = 0; } portEXIT_CRITICAL(&adc_res_mutex); for(int i = 0; i < INPUTS_NUM; i++){ int mv; uint32_t val = meas_res_buff[i]/meas_nb_buff[i]; val = (val >= offsets[i])?(val-offsets[i]):0; ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc_conv_h[i], val, &mv)); ESP_LOGI(TAG, "IN %d : %d mV (%d / %d)", i, mv, meas_res_buff[i], meas_nb_buff[i]); } ESP_LOGI(TAG, "overrange %d", overrange_flag); overrange_flag = 0; vTaskDelay(500 / portTICK_PERIOD_MS); r_ind = (r_ind + 1) % R_NUM; if(r_ind == 2) start_zero_cali(adc_handle, 1000, inputs, INPUTS_NUM, offsets); } }