From d30f3e7aa8fb60371925f21d4d7b8b794ec8669d Mon Sep 17 00:00:00 2001 From: michael Date: Wed, 13 Sep 2017 18:33:05 +0800 Subject: [PATCH] example(adc2): add example and test case for adc2. closes #461 --- components/driver/test/test_adc2.c | 115 ++++++++++++++++++ examples/peripherals/adc2/Makefile | 9 ++ examples/peripherals/adc2/README.md | 29 +++++ .../peripherals/adc2/main/Kconfig.projbuild | 61 ++++++++++ .../peripherals/adc2/main/adc2_example_main.c | 59 +++++++++ examples/peripherals/adc2/main/component.mk | 3 + 6 files changed, 276 insertions(+) create mode 100644 components/driver/test/test_adc2.c create mode 100644 examples/peripherals/adc2/Makefile create mode 100644 examples/peripherals/adc2/README.md create mode 100644 examples/peripherals/adc2/main/Kconfig.projbuild create mode 100644 examples/peripherals/adc2/main/adc2_example_main.c create mode 100644 examples/peripherals/adc2/main/component.mk diff --git a/components/driver/test/test_adc2.c b/components/driver/test/test_adc2.c new file mode 100644 index 0000000000..815f5c79a9 --- /dev/null +++ b/components/driver/test/test_adc2.c @@ -0,0 +1,115 @@ +/* + Tests for the adc2 device driver +*/ +#include "esp_system.h" +#include "driver/adc.h" +#include "driver/dac.h" +#include "unity.h" +#include "esp_system.h" +#include "esp_event_loop.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "nvs_flash.h" + +static const char* TAG = "test_adc2"; + +#define DEFAULT_SSID "TEST_SSID" +#define DEFAULT_PWD "TEST_PASS" + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + printf("ev_handle_called.\n"); + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); + //do not actually connect in test case + //; + break; + case SYSTEM_EVENT_STA_GOT_IP: + ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); + ESP_LOGI(TAG, "got ip:%s\n", + ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED"); + TEST_ESP_OK(esp_wifi_connect()); + break; + default: + break; + } + return ESP_OK; +} + +TEST_CASE("adc2 work with wifi","[adc]") +{ + int read_raw; + int target_value; + + //adc and dac init + TEST_ESP_OK( dac_output_enable( DAC_CHANNEL_1 )); + TEST_ESP_OK( dac_output_enable( DAC_CHANNEL_2 )); + TEST_ESP_OK( dac_output_voltage( DAC_CHANNEL_1, 30 )); + TEST_ESP_OK( dac_output_voltage( DAC_CHANNEL_2, 60 )); + TEST_ESP_OK( adc2_config_channel_atten( ADC2_CHANNEL_8, ADC_ATTEN_0db )); + TEST_ESP_OK( adc2_config_channel_atten( ADC2_CHANNEL_9, ADC_ATTEN_0db )); + + //init wifi + printf("nvs init\n"); + esp_err_t r = nvs_flash_init(); + if (r == ESP_ERR_NVS_NO_FREE_PAGES) { + printf("no free pages, erase..\n"); + TEST_ESP_OK(nvs_flash_erase()); + r = nvs_flash_init(); + } + TEST_ESP_OK( r); + tcpip_adapter_init(); + TEST_ESP_OK(esp_event_loop_init(event_handler, NULL)); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + TEST_ESP_OK(esp_wifi_init(&cfg)); + wifi_config_t wifi_config = { + .sta = { + .ssid = DEFAULT_SSID, + .password = DEFAULT_PWD + }, + }; + TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA)); + TEST_ESP_OK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + + //test read value + TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw )); + target_value = 30*4096*3/256; //3 = 3.3/1.1 + printf("dac set: %d, adc read: %d (target_value: %d)\n", 30, read_raw, target_value ); + TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); + TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw )); + target_value = 60*4096*3/256; + printf("dac set: %d, adc read: %d (target_value: %d)\n", 60, read_raw, target_value ); + TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); + + //now start wifi + printf("wifi start...\n"); + TEST_ESP_OK(esp_wifi_start()); + + //test reading during wifi on + TEST_ASSERT_EQUAL( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw ), ESP_ERR_TIMEOUT ); + TEST_ASSERT_EQUAL( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw ), ESP_ERR_TIMEOUT ); + + //wifi stop again + printf("wifi stop...\n"); + TEST_ESP_OK( esp_wifi_stop() ); + TEST_ESP_OK(esp_wifi_deinit()); + nvs_flash_deinit(); + + //test read value + TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_8, ADC_WIDTH_12Bit, &read_raw )); + target_value = 30*4096*3/256; //3 = 3.3/1.1 + printf("dac set: %d, adc read: %d (target_value: %d)\n", 30, read_raw, target_value ); + TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); + TEST_ESP_OK( adc2_get_raw( ADC2_CHANNEL_9, ADC_WIDTH_12Bit, &read_raw )); + target_value = 60*4096*3/256; + printf("dac set: %d, adc read: %d (target_value: %d)\n", 60, read_raw, target_value ); + TEST_ASSERT_INT_WITHIN( 600, target_value, read_raw ); + + printf("test passed...\n"); + + TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of tcpip_adapter and event_loop."); +} diff --git a/examples/peripherals/adc2/Makefile b/examples/peripherals/adc2/Makefile new file mode 100644 index 0000000000..2f322486e4 --- /dev/null +++ b/examples/peripherals/adc2/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := adc2 + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/peripherals/adc2/README.md b/examples/peripherals/adc2/README.md new file mode 100644 index 0000000000..7b8871878c --- /dev/null +++ b/examples/peripherals/adc2/README.md @@ -0,0 +1,29 @@ +# Example: ADC2 + +This test code shows how to configure ADC2 and read the voltage connected to GPIO pin. + + +### ADC2 functions: + +ADC1_CHANNEL_7: GPIO27, voltage range [0V..3.1V], the data range [0..4095], +saturates at about 1.1V. + +DAC_CHANNEL_1: GPIO25, output range [0V..3.3V] + + +### Test: + +Please choose the channel (GPIO) to output DAC signals and the channel to input +signals to ADC by menuconfig: + + make menuconfig + +Then connect two pins by a wire directly. + +E.g. Choose GPIO27 for ADC and GPIO 25 for DAC in menuconfig (default option). +Then connect them up. + +Connection of ADC and DAC to the same pin is also allowed. In this case, you don't +have to connect by a wire externally. E.g. choose GPIO 26 for both ADC and DAC in +menuconfig. + diff --git a/examples/peripherals/adc2/main/Kconfig.projbuild b/examples/peripherals/adc2/main/Kconfig.projbuild new file mode 100644 index 0000000000..4478e272dd --- /dev/null +++ b/examples/peripherals/adc2/main/Kconfig.projbuild @@ -0,0 +1,61 @@ +menu "Example Configuration" + +choice ADC2_EXAMPLE_CHANNEL + bool "ADC2 Channel Num" + default ADC2_EXAMPLE_CHANNEL_7 + help + The channel of ADC2 used in this example. + +config ADC2_EXAMPLE_CHANNEL_0 + bool "ADC2 Channel 0 (GPIO 4)" +config ADC2_EXAMPLE_CHANNEL_1 + bool "ADC2 Channel 1 (GPIO 0)" +config ADC2_EXAMPLE_CHANNEL_2 + bool "ADC2 Channel 2 (GPIO 2)" +config ADC2_EXAMPLE_CHANNEL_3 + bool "ADC2 Channel 3 (GPIO 15)" +config ADC2_EXAMPLE_CHANNEL_4 + bool "ADC2 Channel 4 (GPIO 13)" +config ADC2_EXAMPLE_CHANNEL_5 + bool "ADC2 Channel 5 (GPIO 12)" +config ADC2_EXAMPLE_CHANNEL_6 + bool "ADC2 Channel 6 (GPIO 14)" +config ADC2_EXAMPLE_CHANNEL_7 + bool "ADC2 Channel 7 (GPIO 27)" +config ADC2_EXAMPLE_CHANNEL_8 + bool "ADC2 Channel 8 (GPIO 25)" +config ADC2_EXAMPLE_CHANNEL_9 + bool "ADC2 Channel 9 (GPIO 26)" +endchoice + +config ADC2_EXAMPLE_CHANNEL + int + default 0 if ADC2_EXAMPLE_CHANNEL_0 + default 1 if ADC2_EXAMPLE_CHANNEL_1 + default 2 if ADC2_EXAMPLE_CHANNEL_2 + default 3 if ADC2_EXAMPLE_CHANNEL_3 + default 4 if ADC2_EXAMPLE_CHANNEL_4 + default 5 if ADC2_EXAMPLE_CHANNEL_5 + default 6 if ADC2_EXAMPLE_CHANNEL_6 + default 7 if ADC2_EXAMPLE_CHANNEL_7 + default 8 if ADC2_EXAMPLE_CHANNEL_8 + default 9 if ADC2_EXAMPLE_CHANNEL_9 + +choice DAC_EXAMPLE_CHANNEL + bool "DAC Channel Num" + default DAC_EXAMPLE_CHANNEL_1 + help + The channel of DAC used in this example. + +config DAC_EXAMPLE_CHANNEL_1 + bool "DAC Channel 1 (GPIO25)" +config DAC_EXAMPLE_CHANNEL_2 + bool "DAC Channel 2 (GPIO26)" +endchoice + +config DAC_EXAMPLE_CHANNEL + int + default 1 if DAC_EXAMPLE_CHANNEL_1 + default 2 if DAC_EXAMPLE_CHANNEL_2 + +endmenu diff --git a/examples/peripherals/adc2/main/adc2_example_main.c b/examples/peripherals/adc2/main/adc2_example_main.c new file mode 100644 index 0000000000..ed574be2ba --- /dev/null +++ b/examples/peripherals/adc2/main/adc2_example_main.c @@ -0,0 +1,59 @@ +/* ADC2 Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "driver/gpio.h" +#include "driver/adc.h" +#include "driver/dac.h" +#include "esp_system.h" +#include "esp_adc_cal.h" + +#define DAC_EXAMPLE_CHANNEL CONFIG_DAC_EXAMPLE_CHANNEL +#define ADC2_EXAMPLE_CHANNEL CONFIG_ADC2_EXAMPLE_CHANNEL + +void app_main(void) +{ + uint8_t output_data=0; + int read_raw; + esp_err_t r; + + gpio_num_t adc_gpio_num, dac_gpio_num; + + assert( adc2_pad_get_io_num( ADC2_EXAMPLE_CHANNEL, &adc_gpio_num ) == ESP_OK ); + assert( dac_pad_get_io_num( DAC_EXAMPLE_CHANNEL, &dac_gpio_num ) == ESP_OK ); + + printf("ADC channel %d @ GPIO %d, DAC channel %d @ GPIO %d.\n", ADC2_EXAMPLE_CHANNEL, adc_gpio_num, + DAC_EXAMPLE_CHANNEL, dac_gpio_num ); + + dac_output_enable( DAC_EXAMPLE_CHANNEL ); + + //be sure to do the init before using adc2. + printf("adc2_init...\n"); + adc2_config_channel_atten( ADC2_EXAMPLE_CHANNEL, ADC_ATTEN_0db ); + + vTaskDelay(2 * portTICK_PERIOD_MS); + + printf("start conversion.\n"); + while(1) { + dac_output_voltage( DAC_EXAMPLE_CHANNEL, output_data++ ); + r = adc2_get_raw( ADC2_EXAMPLE_CHANNEL, ADC_WIDTH_12Bit, &read_raw); + if ( r == ESP_OK ) { + printf("%d: %d\n", output_data, read_raw ); + } else if ( r == ESP_ERR_INVALID_STATE ) { + printf("ADC2 not initialized yet.\n"); + } else if ( r == ESP_ERR_TIMEOUT ) { + //This can not happen in this example. But if WiFi is in use, such error code could be returned. + printf("ADC2 is in use by Wi-Fi.\n"); + } + vTaskDelay( 2 * portTICK_PERIOD_MS ); + } +} diff --git a/examples/peripherals/adc2/main/component.mk b/examples/peripherals/adc2/main/component.mk new file mode 100644 index 0000000000..44bd2b5273 --- /dev/null +++ b/examples/peripherals/adc2/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile. +#