125 lines
3.7 KiB
C
125 lines
3.7 KiB
C
#include "esp_adc/adc_cali.h"
|
|
#include "esp_adc/adc_continuous.h"
|
|
#include "esp_adc/adc_cali_scheme.h"
|
|
#include "esp_err.h"
|
|
#include "esp_log.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/portmacro.h"
|
|
#include "freertos/task.h"
|
|
#include "math.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 * ADC_STORE_BUFFER_SIZE,
|
|
};
|
|
|
|
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_HIGH,
|
|
};
|
|
|
|
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]));
|
|
}
|
|
}
|
|
|
|
void cali_get_one_chunk_avg(adc_continuous_handle_t handle, unsigned nb_samples, measurement_input inputs[], int nb_inputs, uint32_t meas[], uint32_t meas_nb[]){
|
|
|
|
uint32_t samples_size = nb_samples * SOC_ADC_DIGI_DATA_BYTES_PER_CONV;
|
|
|
|
uint8_t res_r[samples_size];
|
|
uint32_t ret_num;
|
|
|
|
ESP_ERROR_CHECK(adc_continuous_read(handle, res_r, samples_size, &ret_num, 100));
|
|
if(ret_num != samples_size)
|
|
ESP_LOGW("ZERO calibration", "Zero calibration : number of samples received not equal to requested %lu / %lu", ret_num, samples_size);
|
|
|
|
uint32_t ret_nb = ret_num / SOC_ADC_DIGI_DATA_BYTES_PER_CONV;
|
|
|
|
for(int i = 0; i < ret_nb; i++){
|
|
adc_digi_output_data_t* res = (adc_digi_output_data_t*)(&res_r[i*sizeof(adc_digi_output_data_t)]);
|
|
int index = -1;
|
|
|
|
index = get_input_index_from_channel(res->type2.channel);
|
|
|
|
if(index == -1)
|
|
continue;
|
|
|
|
meas[index] += res->type2.data;
|
|
meas_nb[index]++;
|
|
}
|
|
}
|
|
|
|
void start_zero_cali(measurements_ctxt* ctxt, unsigned int nb_samples, uint32_t offsets[]){
|
|
uint32_t meas[ctxt->nb_inputs];
|
|
uint32_t meas_nb[ctxt->nb_inputs];
|
|
for(int i = 0; i < ctxt->nb_inputs; i++){
|
|
meas[i] = 0;
|
|
meas_nb[i] = 0;
|
|
}
|
|
|
|
for(int i = 0; i < nb_samples / ADC_STORE_BUFFER_SIZE; i++){
|
|
unsigned int nsamp = fmin(nb_samples - (i * ADC_STORE_BUFFER_SIZE), ADC_STORE_BUFFER_SIZE);
|
|
cali_get_one_chunk_avg(ctxt->handle, nsamp, ctxt->inputs, ctxt->nb_inputs, meas, meas_nb);
|
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
|
}
|
|
|
|
ESP_LOGI("ZERO cali", "%lu %lu %lu", meas[0], meas[1], meas[2]);
|
|
ESP_LOGI("ZERO cali", "%lu %lu %lu", meas_nb[0], meas_nb[1], meas_nb[2]);
|
|
ESP_LOGI("ZERO cali", "%lu %lu %lu", meas[0]/meas_nb[0], meas[1]/meas_nb[1], meas[2]/meas_nb[2]);
|
|
|
|
for(int i = 0; i < ctxt->nb_inputs; i++){
|
|
offsets[i] = meas[i] / meas_nb[i];
|
|
}
|
|
}
|
|
|
|
int get_input_index_from_channel(adc_channel_t channel){
|
|
switch(channel){
|
|
case ADC_CHANNEL_3:
|
|
return 0;
|
|
case ADC_CHANNEL_0:
|
|
return 1;
|
|
case ADC_CHANNEL_1:
|
|
return 2;
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|