157 lines
4.2 KiB
C
157 lines
4.2 KiB
C
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#include "esp_attr.h"
|
|
#include "esp_err.h"
|
|
#include "esp_log.h"
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/projdefs.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/portmacro.h"
|
|
#include "spinlock.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 "nvs_flash.h"
|
|
|
|
#include "sdkconfig.h"
|
|
|
|
#include "BLEh.h"
|
|
|
|
#include "BLE.h"
|
|
|
|
#define TAG "Main"
|
|
|
|
#define ADC_IN_PIN_NUM 5
|
|
|
|
static uint8_t channel_index[ADC_IN_PIN_NUM];
|
|
static uint32_t meas_res[ADC_IN_PIN_NUM];
|
|
static uint32_t meas_nb[ADC_IN_PIN_NUM];
|
|
|
|
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 >= 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 app_main(void){
|
|
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 * ADC_IN_PIN_NUM,
|
|
};
|
|
|
|
adc_continuous_handle_t adc_handle;
|
|
ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_h_conf, &adc_handle));
|
|
|
|
uint8_t adc_pins[] = {CONFIG_OUT_VOLT_PIN, CONFIG_OUT_CURR_PIN, CONFIG_PHASE1_CURR_PIN, CONFIG_PHASE2_CURR_PIN, CONFIG_PHASE3_CURR_PIN};
|
|
|
|
adc_digi_pattern_config_t adc_pattern[ADC_IN_PIN_NUM];
|
|
for(int i = 0; i < 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 = 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_cali_handle_t adc_cali_handles[ADC_IN_PIN_NUM];
|
|
|
|
for(int i = 0; i < 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]));
|
|
}
|
|
|
|
spinlock_t adc_res_mutex;
|
|
spinlock_initialize(&adc_res_mutex);
|
|
|
|
adc_continuous_evt_cbs_t adc_event = {
|
|
.on_conv_done = &on_conv_done,
|
|
.on_pool_ovf = NULL,
|
|
};
|
|
|
|
nvs_flash_init();
|
|
|
|
set_gatt_services(gatt_svcs, SVCS_NUM);
|
|
initBLE("ALIM");
|
|
|
|
ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(adc_handle, &adc_event, NULL));
|
|
ESP_ERROR_CHECK(adc_continuous_start(adc_handle));
|
|
|
|
while(1){
|
|
uint32_t meas_res_buff[ADC_IN_PIN_NUM];
|
|
uint32_t meas_nb_buff[ADC_IN_PIN_NUM];
|
|
|
|
portENTER_CRITICAL(&adc_res_mutex);
|
|
for(int i = 0; i < 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);
|
|
|
|
for(int i = 0; i < 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:
|
|
ESP_LOGI(TAG, "Output voltage %lu mV", val);
|
|
break;
|
|
case CONFIG_OUT_CURR_PIN:
|
|
ESP_LOGI(TAG, "Output current %lu mV", val);
|
|
break;
|
|
case CONFIG_PHASE1_CURR_PIN:
|
|
ESP_LOGI(TAG, "Phase 1 current %lu mV", val);
|
|
break;
|
|
case CONFIG_PHASE2_CURR_PIN:
|
|
ESP_LOGI(TAG, "Phase 2 current %lu mV", val);
|
|
break;
|
|
case CONFIG_PHASE3_CURR_PIN:
|
|
ESP_LOGI(TAG, "Phase 3 current %lu mV", val);
|
|
break;
|
|
}
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(CONFIG_UPD_DELAY));
|
|
}
|
|
}
|