adc_digi: add dma drivers

This commit is contained in:
Armando
2020-12-08 14:50:32 +08:00
committed by bot
parent 76bb9565af
commit b38f4646de
13 changed files with 656 additions and 124 deletions

View File

@@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(adc)

View File

@@ -0,0 +1,55 @@
| Supported Targets | ESP32-C3 |
| ----------------- | -------- |
# ADC DMA Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example shows how to use DMA to read voltage from a GPIO pin via ADC controller.
## How to use example
### Hardware Required
* A development board with ESP32C3 SoC
* A USB cable for power supply and programming
In this example, we use `ADC_UNIT_1` by default, we need to connect a voltage source (0 ~ 3.3v) to GPIO1. If another ADC unit is selected in your application, you need to change the GPIO pin (please refer to the `ESP32C3 Technical Reference Manual`).
### Configure the project
```
idf.py menuconfig
```
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
Running this example, you will see the following log output on the serial monitor:
[unit_channel_data](<all the data you read from the ADC>)
```
[0_1_54e](4e 25 00 00)
[0_1_548](48 25 00 00)
[0_1_556](56 25 00 00)
```
## Troubleshooting
* program upload failure
* Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs.
* The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again.
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "adc_dma_example_main.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,117 @@
#include <string.h>
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/adc.h"
#define TIMES 256
#define DMA_CHANNEL 0
static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num)
{
esp_err_t ret = ESP_OK;
assert(ret == ESP_OK);
adc_digi_init_config_t adc_dma_config = {
.max_store_buf_size = 1024,
.conv_num_each_intr = 256,
.dma_chan = SOC_GDMA_ADC_DMA_CHANNEL,
.adc1_chan_mask = adc1_chan_mask,
.adc2_chan_mask = adc2_chan_mask,
};
ret = adc_digi_initialize(&adc_dma_config);
assert(ret == ESP_OK);
adc_digi_pattern_table_t adc_pattern[10];
adc_digi_config_t dig_cfg = {
.conv_limit_en = 0,
.conv_limit_num = 250,
.interval = 40,
.dig_clk.use_apll = 0,
.dig_clk.div_num = 15,
.dig_clk.div_a = 0,
.dig_clk.div_b = 1,
};
dig_cfg.adc_pattern_len = channel_num;
for (int i = 0; i < channel_num; i++) {
uint8_t unit = ((channel[i] >> 3) & 0x1);
uint8_t ch = channel[i] & 0x7;
adc_pattern[i].atten = ADC_ATTEN_DB_0;
adc_pattern[i].channel = ch;
adc_pattern[i].unit = unit;
}
dig_cfg.adc_pattern = adc_pattern;
ret = adc_digi_controller_config(&dig_cfg);
assert(ret == ESP_OK);
}
static void continuous_read_demo(void *arg)
{
esp_err_t ret;
uint32_t ret_num = 0;
uint8_t result[TIMES] = {0};
memset(result, 0xcc, TIMES);
uint16_t adc1_chan_mask = BIT(ADC1_CHANNEL_0) | BIT(ADC1_CHANNEL_1);
uint16_t adc2_chan_mask = BIT(ADC2_CHANNEL_0);
adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1, (ADC2_CHANNEL_0 | 1 << 3)};
continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t));
adc_digi_start();
int n = 20;
while(n--) {
ret = adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY);
for (int i = 0; i < ret_num; i+=4) {
uint32_t temp = (result[i+3] << 24) | (result[i+2] << 16) | (result[i+1] << 8) | (result[i+0]);
adc_digi_output_data_t *p = (void*)&temp;
printf("[%d_%d_%x](%02x %02x %02x %02x) \n", p->type2.unit, p->type2.channel, p->type2.data,
result[i],
result[i + 1],
result[i + 2],
result[i + 3]);
}
// If you see task WDT in this task, it means the conversion is too fast for the task to handle
}
adc_digi_stop();
ret = adc_digi_deinitialize();
assert(ret == ESP_OK);
}
static void single_read_demo(void *arg)
{
esp_err_t ret;
int adc1_reading[3] = {0xcc};
int adc2_reading[1] = {0xcc};
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_2, ADC_ATTEN_DB_0);
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6);
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0);
adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0);
int n = 20;
while (n--) {
adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_2);
adc1_reading[1] = adc1_get_raw(ADC1_CHANNEL_3);
adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4);
for (int i = 0; i < 3; i++) {
printf("[%x]\n", adc1_reading[i]);
}
ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]);
assert(ret == ESP_OK);
printf("[%x]\n", adc2_reading[0]);
}
}
void app_main()
{
single_read_demo(NULL);
continuous_read_demo(NULL);
}