2022-07-15 00:52:44 -04:00
/*
2023-05-05 07:56:44 -04:00
* SPDX - FileCopyrightText : 2022 - 2023 Espressif Systems ( Shanghai ) CO LTD
2022-07-15 00:52:44 -04:00
*
* SPDX - License - Identifier : Apache - 2.0
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include "esp_log.h"
# include "soc/adc_periph.h"
# include "esp_adc/adc_oneshot.h"
# include "driver/gpio.h"
# include "driver/rtc_io.h"
# include "test_common_adc.h"
2023-11-14 01:46:29 -05:00
# include "esp_rom_sys.h"
2022-07-15 00:52:44 -04:00
const __attribute__ ( ( unused ) ) static char * TAG = " TEST_ADC " ;
/*---------------------------------------------------------------
ADC General Macros
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//ADC Channels
# if CONFIG_IDF_TARGET_ESP32
# define ADC1_TEST_CHAN0 ADC_CHANNEL_4
# define ADC1_TEST_CHAN1 ADC_CHANNEL_5
# define ADC2_TEST_CHAN0 ADC_CHANNEL_0
static const char * TAG_CH [ 2 ] [ 10 ] = { { " ADC1_CH4 " , " ADC1_CH5 " } , { " ADC2_CH0 " } } ;
# else
# define ADC1_TEST_CHAN0 ADC_CHANNEL_2
# define ADC1_TEST_CHAN1 ADC_CHANNEL_3
# define ADC2_TEST_CHAN0 ADC_CHANNEL_0
static const char * TAG_CH [ 2 ] [ 10 ] = { { " ADC1_CH2 " , " ADC1_CH3 " } , { " ADC2_CH0 " } } ;
# endif
/*---------------------------------------------------------------
ADC Oneshot High / Low test
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2022-12-11 22:01:22 -05:00
//ESP32C3 ADC2 oneshot mode is not supported anymore
# define ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2 ((SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3)
2022-07-15 00:52:44 -04:00
TEST_CASE ( " ADC oneshot high/low test " , " [adc_oneshot] " )
{
static int adc_raw [ 2 ] [ 10 ] ;
//-------------ADC1 Init---------------//
adc_oneshot_unit_handle_t adc1_handle ;
adc_oneshot_unit_init_cfg_t init_config1 = {
. unit_id = ADC_UNIT_1 ,
2022-08-21 23:00:10 -04:00
. ulp_mode = ADC_ULP_MODE_DISABLE ,
2022-07-15 00:52:44 -04:00
} ;
TEST_ESP_OK ( adc_oneshot_new_unit ( & init_config1 , & adc1_handle ) ) ;
2022-12-11 22:01:22 -05:00
# if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
//-------------ADC2 Init---------------//
adc_oneshot_unit_handle_t adc2_handle ;
adc_oneshot_unit_init_cfg_t init_config2 = {
. unit_id = ADC_UNIT_2 ,
2022-08-21 23:00:10 -04:00
. ulp_mode = ADC_ULP_MODE_DISABLE ,
2022-07-15 00:52:44 -04:00
} ;
TEST_ESP_OK ( adc_oneshot_new_unit ( & init_config2 , & adc2_handle ) ) ;
2022-12-11 22:01:22 -05:00
# endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
//-------------ADC1 TEST Channel 0 Config---------------//
adc_oneshot_chan_cfg_t config = {
. bitwidth = ADC_BITWIDTH_DEFAULT ,
2023-10-13 04:02:45 -04:00
. atten = ADC_ATTEN_DB_12 ,
2022-07-15 00:52:44 -04:00
} ;
TEST_ESP_OK ( adc_oneshot_config_channel ( adc1_handle , ADC1_TEST_CHAN0 , & config ) ) ;
//-------------ADC1 TEST Channel 1 Config---------------//
TEST_ESP_OK ( adc_oneshot_config_channel ( adc1_handle , ADC1_TEST_CHAN1 , & config ) ) ;
2022-12-11 22:01:22 -05:00
# if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
//-------------ADC2 TEST Channel 0 Config---------------//
TEST_ESP_OK ( adc_oneshot_config_channel ( adc2_handle , ADC2_TEST_CHAN0 , & config ) ) ;
2022-12-11 22:01:22 -05:00
# endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
test_adc_set_io_level ( ADC_UNIT_1 , ADC1_TEST_CHAN0 , 0 ) ;
TEST_ESP_OK ( adc_oneshot_read ( adc1_handle , ADC1_TEST_CHAN0 , & adc_raw [ 0 ] [ 0 ] ) ) ;
ESP_LOGI ( TAG_CH [ 0 ] [ 0 ] , " raw data: %d " , adc_raw [ 0 ] [ 0 ] ) ;
TEST_ASSERT_INT_WITHIN ( ADC_TEST_LOW_THRESH , ADC_TEST_LOW_VAL , adc_raw [ 0 ] [ 0 ] ) ;
test_adc_set_io_level ( ADC_UNIT_1 , ADC1_TEST_CHAN1 , 1 ) ;
TEST_ESP_OK ( adc_oneshot_read ( adc1_handle , ADC1_TEST_CHAN1 , & adc_raw [ 0 ] [ 1 ] ) ) ;
ESP_LOGI ( TAG_CH [ 0 ] [ 1 ] , " raw data: %d " , adc_raw [ 0 ] [ 1 ] ) ;
TEST_ASSERT_INT_WITHIN ( ADC_TEST_HIGH_THRESH , ADC_TEST_HIGH_VAL , adc_raw [ 0 ] [ 1 ] ) ;
2022-12-11 22:01:22 -05:00
# if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
test_adc_set_io_level ( ADC_UNIT_2 , ADC2_TEST_CHAN0 , 0 ) ;
TEST_ESP_OK ( adc_oneshot_read ( adc2_handle , ADC2_TEST_CHAN0 , & adc_raw [ 1 ] [ 0 ] ) ) ;
ESP_LOGI ( TAG_CH [ 1 ] [ 0 ] , " raw data: %d " , adc_raw [ 1 ] [ 0 ] ) ;
TEST_ASSERT_INT_WITHIN ( ADC_TEST_LOW_THRESH , ADC_TEST_LOW_VAL , adc_raw [ 1 ] [ 0 ] ) ;
2022-12-11 22:01:22 -05:00
# endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
test_adc_set_io_level ( ADC_UNIT_1 , ADC1_TEST_CHAN0 , 1 ) ;
TEST_ESP_OK ( adc_oneshot_read ( adc1_handle , ADC1_TEST_CHAN0 , & adc_raw [ 0 ] [ 0 ] ) ) ;
ESP_LOGI ( TAG_CH [ 0 ] [ 0 ] , " raw data: %d " , adc_raw [ 0 ] [ 0 ] ) ;
TEST_ASSERT_INT_WITHIN ( ADC_TEST_HIGH_THRESH , ADC_TEST_HIGH_VAL , adc_raw [ 0 ] [ 0 ] ) ;
test_adc_set_io_level ( ADC_UNIT_1 , ADC1_TEST_CHAN1 , 0 ) ;
TEST_ESP_OK ( adc_oneshot_read ( adc1_handle , ADC1_TEST_CHAN1 , & adc_raw [ 0 ] [ 1 ] ) ) ;
ESP_LOGI ( TAG_CH [ 0 ] [ 1 ] , " raw data: %d " , adc_raw [ 0 ] [ 1 ] ) ;
TEST_ASSERT_INT_WITHIN ( ADC_TEST_LOW_THRESH , ADC_TEST_LOW_VAL , adc_raw [ 0 ] [ 1 ] ) ;
2022-12-11 22:01:22 -05:00
# if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
test_adc_set_io_level ( ADC_UNIT_2 , ADC2_TEST_CHAN0 , 1 ) ;
TEST_ESP_OK ( adc_oneshot_read ( adc2_handle , ADC2_TEST_CHAN0 , & adc_raw [ 1 ] [ 0 ] ) ) ;
ESP_LOGI ( TAG_CH [ 1 ] [ 0 ] , " raw data: %d " , adc_raw [ 1 ] [ 0 ] ) ;
TEST_ASSERT_INT_WITHIN ( ADC_TEST_HIGH_THRESH , ADC_TEST_HIGH_VAL , adc_raw [ 1 ] [ 0 ] ) ;
2022-12-11 22:01:22 -05:00
# endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
TEST_ESP_OK ( adc_oneshot_del_unit ( adc1_handle ) ) ;
2022-12-11 22:01:22 -05:00
# if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
TEST_ESP_OK ( adc_oneshot_del_unit ( adc2_handle ) ) ;
2022-12-11 22:01:22 -05:00
# endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2
2022-07-15 00:52:44 -04:00
}
2023-11-14 01:46:29 -05:00
TEST_CASE ( " ADC oneshot stress test that get zero even if convent done " , " [adc_oneshot] " )
{
//There is a hardware limitation. After ADC get DONE signal, it still need a delay to synchronize ADC raw data or it may get zero even if getting DONE signal.
int test_num = 100 ;
adc_channel_t channel = ADC1_TEST_CHAN1 ;
adc_atten_t atten = ADC_ATTEN_DB_12 ;
adc_unit_t unit_id = ADC_UNIT_1 ;
adc_oneshot_unit_handle_t adc1_handle ;
adc_oneshot_unit_init_cfg_t init_config1 = {
. unit_id = unit_id ,
. ulp_mode = ADC_ULP_MODE_DISABLE ,
} ;
adc_oneshot_chan_cfg_t config = {
. bitwidth = SOC_ADC_RTC_MAX_BITWIDTH ,
. atten = atten ,
} ;
int raw_data = 0 ;
srand ( 199 ) ;
for ( int i = 0 ; i < test_num ; i + + ) {
test_adc_set_io_level ( unit_id , ADC1_TEST_CHAN1 , 1 ) ;
2022-07-15 00:52:44 -04:00
2023-11-14 01:46:29 -05:00
TEST_ESP_OK ( adc_oneshot_new_unit ( & init_config1 , & adc1_handle ) ) ;
TEST_ESP_OK ( adc_oneshot_config_channel ( adc1_handle , channel , & config ) ) ;
TEST_ESP_OK ( adc_oneshot_read ( adc1_handle , channel , & raw_data ) ) ;
TEST_ASSERT_NOT_EQUAL ( 0 , raw_data ) ;
TEST_ESP_OK ( adc_oneshot_del_unit ( adc1_handle ) ) ;
esp_rom_delay_us ( rand ( ) % 512 ) ;
}
}
2022-07-15 00:52:44 -04:00
# if SOC_ADC_CALIBRATION_V1_SUPPORTED
/*---------------------------------------------------------------
ADC Oneshot with Light Sleep
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
# include <inttypes.h>
# include "esp_sleep.h"
# include "esp_private/regi2c_ctrl.h"
# include "soc/regi2c_saradc.h"
# define TEST_REGI2C_ANA_CALI_BYTE_NUM 8
static void s_adc_oneshot_with_sleep ( adc_unit_t unit_id , adc_channel_t channel )
{
//-------------ADC Init---------------//
adc_oneshot_unit_handle_t adc_handle ;
adc_oneshot_unit_init_cfg_t init_config = {
. unit_id = unit_id ,
2022-08-21 23:00:10 -04:00
. ulp_mode = ADC_ULP_MODE_DISABLE ,
2022-07-15 00:52:44 -04:00
} ;
TEST_ESP_OK ( adc_oneshot_new_unit ( & init_config , & adc_handle ) ) ;
//-------------ADC Channel Config---------------//
adc_oneshot_chan_cfg_t config = {
. bitwidth = SOC_ADC_RTC_MAX_BITWIDTH ,
} ;
//-------------ADC Calibration Init---------------//
bool do_calibration = false ;
2022-09-08 07:20:52 -04:00
adc_cali_handle_t cali_handle [ TEST_ATTEN_NUMS ] = { } ;
for ( int i = 0 ; i < TEST_ATTEN_NUMS ; i + + ) {
2023-05-05 07:56:44 -04:00
do_calibration = test_adc_calibration_init ( unit_id , channel , g_test_atten [ i ] , SOC_ADC_RTC_MAX_BITWIDTH , & cali_handle [ i ] ) ;
2022-07-15 00:52:44 -04:00
}
if ( ! do_calibration ) {
ESP_LOGW ( TAG , " No efuse bits burnt, only test the regi2c analog register values " ) ;
}
2022-09-08 07:20:52 -04:00
for ( int i = 0 ; i < TEST_ATTEN_NUMS ; i + + ) {
2022-07-15 00:52:44 -04:00
//-------------ADC Channel Config---------------//
2022-09-08 07:20:52 -04:00
config . atten = g_test_atten [ i ] ;
2022-07-15 00:52:44 -04:00
TEST_ESP_OK ( adc_oneshot_config_channel ( adc_handle , channel , & config ) ) ;
2022-09-08 07:20:52 -04:00
printf ( " Test with atten: %d \n " , g_test_atten [ i ] ) ;
2022-07-15 00:52:44 -04:00
//---------------------------------Before Sleep-----------------------------------//
printf ( " Before Light Sleep \n " ) ;
int raw_expected = 0 ;
int cali_expected = 0 ;
uint8_t regi2c_cali_val_before [ TEST_REGI2C_ANA_CALI_BYTE_NUM ] = { } ;
//Read
TEST_ESP_OK ( adc_oneshot_read ( adc_handle , channel , & raw_expected ) ) ;
if ( do_calibration ) {
TEST_ESP_OK ( adc_cali_raw_to_voltage ( cali_handle [ i ] , raw_expected , & cali_expected ) ) ;
}
//Print regi2c
printf ( " regi2c cali val is: " ) ;
for ( int j = 0 ; j < TEST_REGI2C_ANA_CALI_BYTE_NUM ; j + + ) {
regi2c_cali_val_before [ j ] = regi2c_ctrl_read_reg ( I2C_SAR_ADC , I2C_SAR_ADC_HOSTID , j ) ;
printf ( " 0x%x " , regi2c_cali_val_before [ j ] ) ;
}
printf ( " \n " ) ;
//Print result
ESP_LOGI ( TAG , " ADC%d Chan%d: raw data: %d " , unit_id + 1 , channel , raw_expected ) ;
ESP_LOGI ( TAG , " ADC%d Chan%d: cali data: %d " , unit_id + 1 , channel , cali_expected ) ;
//---------------------------------Sleep-----------------------------------//
esp_sleep_enable_timer_wakeup ( 30 * 1000 ) ;
esp_light_sleep_start ( ) ;
//---------------------------------After Sleep-----------------------------------//
printf ( " After Light Sleep \n " ) ;
int raw_after_sleep = 0 ;
int cali_after_sleep = 0 ;
uint8_t regi2c_cali_val_after [ TEST_REGI2C_ANA_CALI_BYTE_NUM ] = { } ;
//Print regi2c
printf ( " regi2c cali val is: " ) ;
for ( int i = 0 ; i < TEST_REGI2C_ANA_CALI_BYTE_NUM ; i + + ) {
regi2c_cali_val_after [ i ] = regi2c_ctrl_read_reg ( I2C_SAR_ADC , I2C_SAR_ADC_HOSTID , i ) ;
printf ( " 0x%x " , regi2c_cali_val_after [ i ] ) ;
}
printf ( " \n " ) ;
//Read
TEST_ESP_OK ( adc_oneshot_read ( adc_handle , channel , & raw_after_sleep ) ) ;
if ( do_calibration ) {
TEST_ESP_OK ( adc_cali_raw_to_voltage ( cali_handle [ i ] , raw_after_sleep , & cali_after_sleep ) ) ;
}
//Print result
ESP_LOGI ( TAG , " ADC%d Chan%d: raw data: %d " , unit_id + 1 , channel , raw_after_sleep ) ;
if ( do_calibration ) {
ESP_LOGI ( TAG , " ADC%d Chan%d: cali data: %d " , unit_id + 1 , channel , cali_after_sleep ) ;
}
//Compare
int32_t raw_diff = raw_expected - raw_after_sleep ;
2022-08-25 23:28:01 -04:00
ESP_LOGI ( TAG , " ADC%d Chan%d: raw difference: % " PRId32 , unit_id + 1 , channel , raw_diff ) ;
2022-07-15 00:52:44 -04:00
if ( do_calibration ) {
int32_t cali_diff = cali_expected - cali_after_sleep ;
2022-08-25 23:28:01 -04:00
ESP_LOGI ( TAG , " ADC%d Chan%d: cali difference: % " PRId32 , unit_id + 1 , channel , cali_diff ) ;
2022-07-15 00:52:44 -04:00
}
//Test Calibration registers
for ( int i = 0 ; i < TEST_REGI2C_ANA_CALI_BYTE_NUM ; i + + ) {
TEST_ASSERT_EQUAL ( regi2c_cali_val_before [ i ] , regi2c_cali_val_after [ i ] ) ;
}
ESP_LOGI ( TAG , " Cali register settings unchanged \n " ) ;
}
TEST_ESP_OK ( adc_oneshot_del_unit ( adc_handle ) ) ;
2022-09-08 07:20:52 -04:00
for ( int i = 0 ; i < TEST_ATTEN_NUMS ; i + + ) {
2022-07-15 00:52:44 -04:00
if ( cali_handle [ i ] ) {
test_adc_calibration_deinit ( cali_handle [ i ] ) ;
}
}
}
//ADC Channels
# if CONFIG_IDF_TARGET_ESP32
# define ADC1_SLEEP_TEST_CHAN ADC_CHANNEL_6
# define ADC2_SLEEP_TEST_CHAN ADC_CHANNEL_0
# else
# define ADC1_SLEEP_TEST_CHAN ADC_CHANNEL_2
# define ADC2_SLEEP_TEST_CHAN ADC_CHANNEL_0
# endif
TEST_CASE ( " test ADC1 Single Read with Light Sleep " , " [adc][manul][ignore] " )
{
s_adc_oneshot_with_sleep ( ADC_UNIT_1 , ADC1_SLEEP_TEST_CHAN ) ;
}
2022-12-11 22:01:22 -05:00
# if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
//ESP32C3 ADC2 oneshot mode is not supported anymore
2022-07-15 00:52:44 -04:00
TEST_CASE ( " test ADC2 Single Read with Light Sleep " , " [adc][manul][ignore] " )
{
s_adc_oneshot_with_sleep ( ADC_UNIT_2 , ADC2_SLEEP_TEST_CHAN ) ;
}
2022-12-11 22:01:22 -05:00
# endif //#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3
2022-09-08 07:20:52 -04:00
2022-07-15 00:52:44 -04:00
# endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED