#include <string.h>
#include <stdio.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/adc.h"
#define TIMES 256
#define GET_UNIT(x) ((x >> 3) & 0x1)
#define ADC_RESULT_BYTE 4
#define ADC_CONV_LIMIT_EN 0
#define ADC_CONV_MODE ADC_CONV_ALTER_UNIT
#define ADC_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
static uint16_t adc1_chan_mask = BIT(2) | BIT(3) | BIT(4);
static uint16_t adc2_chan_mask = BIT(0);
static adc_channel_t channel[4] = {ADC1_CHANNEL_2, ADC1_CHANNEL_3, ADC1_CHANNEL_4, (ADC2_CHANNEL_0 | 1 << 3)};
static const char *TAG = "ADC DMA";
int value_channel_2[1100] = {0};
int value_channel_3[1100] = {0};
int value_channel_4[1100] = {0};
int index_channel_2 = 0;
int index_channel_3 = 0;
int index_channel_4 = 0;
int sum_temp = 0;
int countNum = 0;
static void
continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num)
{
adc_digi_init_config_t adc_dma_config = {
.max_store_buf_size = 1024,
.conv_num_each_intr = TIMES,
.adc1_chan_mask = adc1_chan_mask,
.adc2_chan_mask = adc2_chan_mask,
};
ESP_ERROR_CHECK(adc_digi_initialize(&adc_dma_config));
adc_digi_configuration_t dig_cfg = {
.conv_limit_en = ADC_CONV_LIMIT_EN,
.conv_limit_num = 250,
.sample_freq_hz = 10 * 1000,
.conv_mode = ADC_CONV_MODE,
.format = ADC_OUTPUT_TYPE,
};
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
dig_cfg.pattern_num = channel_num;
for (int i = 0; i < channel_num; i++)
{
uint8_t unit = GET_UNIT(channel[i]);
uint8_t ch = channel[i] & 0x7;
adc_pattern[i].atten = ADC_ATTEN_DB_11;
adc_pattern[i].channel = ch;
adc_pattern[i].unit = unit;
adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
ESP_LOGI(TAG, "adc_pattern[%d].atten is :%x", i, adc_pattern[i].atten);
ESP_LOGI(TAG, "adc_pattern[%d].channel is :%x", i, adc_pattern[i].channel);
ESP_LOGI(TAG, "adc_pattern[%d].unit is :%x", i, adc_pattern[i].unit);
}
dig_cfg.adc_pattern = adc_pattern;
ESP_ERROR_CHECK(adc_digi_controller_configure(&dig_cfg));
}
#if !CONFIG_IDF_TARGET_ESP32
static bool check_valid_data(const adc_digi_output_data_t *data)
{
const unsigned int unit = data->type2.unit;
if (unit > 2)
return false;
if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit))
return false;
return true;
}
#endif
void LOG_ADV_VALUE(int index_channel, const int *value_channel, char * LOG_TAG)
{
// for (int i = 0; i < index_channel; ++i)
// { sum_temp += value_channel[i]; }
// ESP_LOGI(LOG_TAG, "%d", (int)(sum_temp / index_channel));
ESP_LOGI(LOG_TAG, "%d", value_channel[1]);
sum_temp = 0;
}
void clearTask(void *param)
{
while (1)
{
vTaskDelay(250 / portTICK_PERIOD_MS);
LOG_ADV_VALUE(index_channel_2, value_channel_2,"channel 2 adv value");
LOG_ADV_VALUE(index_channel_3, value_channel_3,"channel 3 adv value");
LOG_ADV_VALUE(index_channel_4, value_channel_4,"channel 4 adv value");
index_channel_2 = 0;
index_channel_3 = 0;
index_channel_4 = 0;
}
}
void countTask(void *param)
{
while (1)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
printf("count=%d\n", countNum);
countNum = 0;
}
}
void app_main(void)
{
xTaskCreate(clearTask, "clearTask", 1024 * 5, NULL, 1, NULL);
xTaskCreate(countTask, "countTask", 1024 * 5, NULL, 2, NULL);
continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t));
adc_digi_start();
uint32_t ret_num = 0;
uint8_t result[TIMES] = {0};
memset(result, 0xcc, TIMES);
while (1)
{
adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY);
for (int i = 0; i < ret_num; i += ADC_RESULT_BYTE)
{
adc_digi_output_data_t *p = (void *)&result[i];
if (check_valid_data(p))
{
if (((p->type2.unit + 1) == 1) || (p->type2.channel >= 2) || (p->type2.channel <= 4))
{
// ESP_LOGI(TAG, "Unit: %d,_Channel: %d, Value: %d", p->type2.unit + 1, p->type2.channel,
// p->type2.data);
countNum++;
switch (p->type2.channel)
{
case 2:
value_channel_2[index_channel_2] = p->type2.data;
index_channel_2++;
break;
case 3:
value_channel_3[index_channel_3] = p->type2.data;
index_channel_3++;
break;
case 4:
value_channel_4[index_channel_4] = p->type2.data;
index_channel_4++;
break;
}
}
}
}
vTaskDelay(1);
}
}