diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 2a10402..c6ff117 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "power_profiler.c" "resistor_ranges.c" +idf_component_register(SRCS "power_profiler.c" "resistor_ranges.c" "measure.c" INCLUDE_DIRS "." - REQUIRES "driver") + REQUIRES "driver" "esp_adc") \ No newline at end of file diff --git a/main/measure.c b/main/measure.c new file mode 100644 index 0000000..42d7261 --- /dev/null +++ b/main/measure.c @@ -0,0 +1,54 @@ +#include "esp_adc/adc_cali.h" +#include "esp_adc/adc_continuous.h" +#include "esp_adc/adc_cali_scheme.h" +#include "esp_err.h" + +#include "hal/adc_types.h" +#include "measure.h" +#include "soc/soc_caps.h" + +adc_continuous_handle_t init_measurement_inputs(measurement_input inputs[], int inputs_num){ + adc_continuous_handle_cfg_t adc_h_conf = { + .conv_frame_size = SOC_ADC_DIGI_DATA_BYTES_PER_CONV, // One sample per interrupt for now + .max_store_buf_size = SOC_ADC_DIGI_DATA_BYTES_PER_CONV * inputs_num * 100, // TODO: averaging nb + }; + + adc_continuous_handle_t handle; + ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_h_conf, &handle)); + + adc_digi_pattern_config_t adc_patt[inputs_num]; + + for(int i = 0; i < inputs_num; i++){ + adc_digi_pattern_config_t patt = { + .atten = ADC_ATTEN_DB_0, + .bit_width = ADC_BITWIDTH_12, + .channel = inputs[i].channel, + .unit = ADC_UNIT_1, + }; + + adc_patt[i] = patt; + } + + adc_continuous_config_t adc_conf = { + .adc_pattern = adc_patt, + .pattern_num = inputs_num, + .conv_mode = ADC_CONV_SINGLE_UNIT_1, + .format = ADC_DIGI_OUTPUT_FORMAT_TYPE2, + .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_LOW, + }; + + ESP_ERROR_CHECK(adc_continuous_config(handle, &adc_conf)); + + return handle; +} + +void init_conv_driver(measurement_input inputs[], int inputs_num, adc_cali_handle_t* out){ + for(int i = 0; i < inputs_num; i++){ + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = ADC_UNIT_1, + .atten = ADC_ATTEN_DB_0, + .bitwidth = ADC_BITWIDTH_12, + }; + ESP_ERROR_CHECK(adc_cali_create_scheme_curve_fitting(&cali_config, &out[i])); + } +} \ No newline at end of file diff --git a/main/measure.h b/main/measure.h new file mode 100644 index 0000000..1d03581 --- /dev/null +++ b/main/measure.h @@ -0,0 +1,7 @@ +typedef struct { + unsigned int channel; + unsigned int gain; // x1000 +} measurement_input; + +adc_continuous_handle_t init_measurement_inputs(measurement_input inputs[], int inputs_num); +void init_conv_driver(measurement_input inputs[], int inputs_num, adc_cali_handle_t* out); \ No newline at end of file diff --git a/main/power_profiler.c b/main/power_profiler.c index 8325acd..4e77521 100644 --- a/main/power_profiler.c +++ b/main/power_profiler.c @@ -1,12 +1,21 @@ +#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_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/portmacro.h" +#include "hal/adc_types.h" #include "resistor_ranges.h" +#include "measure.h" +#include "soc/soc_caps.h" #define TAG "main" @@ -15,26 +24,105 @@ enum ranges {R1, R10, R100, R_NUM}; resistor_range ranges[] = { [R1] = { .pin = GPIO_NUM_6, - .resistance = 1, + .resistance = 1000, }, [R10] = { .pin = GPIO_NUM_7, - .resistance = 10, + .resistance = 10000, }, [R100] = { .pin = GPIO_NUM_NC, - .resistance = 100, + .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 unsigned long conv_done_cpt = 0; +volatile int meas_res[INPUTS_NUM]; + +char buff[64]; + 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){ + conv_done_cpt = edata->size; + + 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; + + return false; +} + void app_main(void){ 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, + }; + 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); - activate_range(ranges, r_ind, R100); + + int meas_res_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; + } + portEXIT_CRITICAL(&adc_res_mutex); + + for(int i = 0; i < INPUTS_NUM; i++){ + int mv; + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc_conv_h[i], meas_res_buff[i], &mv)); + ESP_LOGI(TAG, "IN %d : %d mV", i, meas_res_buff[i]); + } + + //activate_range(ranges, r_ind, R100); vTaskDelay(5000 / portTICK_PERIOD_MS); r_ind = (r_ind + 1) % R_NUM; } diff --git a/main/resistor_ranges.c b/main/resistor_ranges.c index 0d03b61..7efaead 100644 --- a/main/resistor_ranges.c +++ b/main/resistor_ranges.c @@ -25,7 +25,6 @@ void set_resistor_gpio(resistor_range ranges[], int range_num){ void activate_range(resistor_range ranges[], int index, int range_num){ for(int i = 0; i < range_num; i++){ - ESP_LOGI("RES_RANGE", "%d %d", ranges[i].pin, i==index); ESP_ERROR_CHECK(gpio_set_level(ranges[i].pin, i == index)); } } \ No newline at end of file