1 /*
2 * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 /*
7 Tests for the dac device driver
8 */
9 #include "esp_system.h"
10
11 #include "driver/adc.h"
12 #include "unity.h"
13 #include "esp_system.h"
14 #include "esp_event.h"
15 #include "esp_wifi.h"
16 #include "esp_log.h"
17 #include "nvs_flash.h"
18 #include "test_utils.h"
19 #include "driver/i2s.h"
20 #include "soc/soc_caps.h"
21
22 #if SOC_DAC_SUPPORTED
23 #include "driver/dac.h"
24 #include "esp_adc_cal.h"
25
26 static const char *TAG = "test_dac";
27
28 #ifdef CONFIG_IDF_TARGET_ESP32
29 #define ADC_TEST_WIDTH ADC_WIDTH_BIT_12
30 #elif defined CONFIG_IDF_TARGET_ESP32S2
31 #define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width
32 #endif
33 #define ADC_TEST_ATTEN ADC_ATTEN_DB_11
34
35 #if CONFIG_IDF_TARGET_ESP32
36 #define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_8 // GPIO25
37 #define DAC_TEST_CHANNEL_NUM DAC_CHANNEL_1 // GPIO25
38 #elif CONFIG_IDF_TARGET_ESP32S2
39 #define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_6 // GPIO17
40 #define DAC_TEST_CHANNEL_NUM DAC_CHANNEL_1 // GPIO17
41 #endif
42
43 #define DAC_OUT_MAX (200)
44 #define DAC_OUT_TIMES (10)
45 #define DAC_OUT_STEP (DAC_OUT_MAX / DAC_OUT_TIMES)
46
47 #define DAC_TEST_TIMES (100)
48
49 TEST_CASE("DAC output (RTC) check by adc", "[dac]")
50 {
51 gpio_num_t adc_gpio_num, dac_gpio_num;
52
53 TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) );
54 TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) );
55
56 printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
57 DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num );
58
59 TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) );
60
61 //be sure to do the init before using adc2.
62 printf("adc2_init...\n");
63 TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN ) );
64
65 vTaskDelay(2 * portTICK_RATE_MS);
66
67 printf("start conversion.\n");
68 int output_data = 0;
69 int read_raw = 0, read_old = 0;
70 for (int i = 0; i < DAC_OUT_TIMES; i++) {
71 TEST_ESP_OK( dac_output_voltage( DAC_TEST_CHANNEL_NUM, output_data ) );
72 output_data += DAC_OUT_STEP;
73 vTaskDelay(2 * portTICK_RATE_MS);
74 TEST_ESP_OK( adc2_get_raw( ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw) );
75 ESP_LOGI(TAG, "DAC%d - ADC%d", output_data, read_raw);
76 if (read_old != 0) {
77 TEST_ASSERT_GREATER_THAN(read_old, read_raw);
78 }
79 read_old = read_raw;
80 }
81 TEST_ESP_OK( dac_output_disable( DAC_TEST_CHANNEL_NUM ) );
82 }
83
84 TEST_CASE("DAC cw generator output (RTC) check by adc", "[dac]")
85 {
86 gpio_num_t adc_gpio_num, dac_gpio_num;
87
88 TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) );
89 TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) );
90
91 printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
92 DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num );
93
94 dac_cw_config_t cw = {
95 .en_ch = DAC_TEST_CHANNEL_NUM,
96 .scale = DAC_CW_SCALE_2,
97 .phase = DAC_CW_PHASE_0,
98 .freq = 1000,
99 #if CONFIG_IDF_TARGET_ESP32
100 .offset = 64,
101 #elif CONFIG_IDF_TARGET_ESP32S2
102 .offset = 16,
103 #endif
104 };
105 TEST_ESP_OK( dac_cw_generator_config(&cw) );
106 TEST_ESP_OK( dac_cw_generator_enable() );
107 TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) );
108
109 //be sure to do the init before using adc2.
110 printf("adc2_init...\n");
111 TEST_ESP_OK( adc2_config_channel_atten( ADC_TEST_CHANNEL_NUM, ADC_TEST_ATTEN ) );
112
113 vTaskDelay(2 * portTICK_RATE_MS);
114
115 printf("start conversion.\n");
116 int read_raw[3] = {0};
117 for (int i = 0; i < DAC_TEST_TIMES; i++) {
118 vTaskDelay(10 * portTICK_RATE_MS);
119 TEST_ESP_OK( adc2_get_raw( ADC_TEST_CHANNEL_NUM, ADC_TEST_WIDTH, &read_raw[0]) );
120 ESP_LOGI(TAG, "ADC: %d", read_raw[0]);
121 /* Should open after dac cali. */
122 // if (read_raw[0] == read_raw[1]) {
123 // TEST_ASSERT_NOT_EQUAL(read_raw[1], read_raw[2]);
124 // }
125 read_raw[2] = read_raw[1];
126 read_raw[1] = read_raw[0];
127 }
128
129 TEST_ESP_OK( dac_cw_generator_disable() );
130 TEST_ESP_OK( dac_output_disable( DAC_TEST_CHANNEL_NUM ) );
131 }
132
133 #if CONFIG_IDF_TARGET_ESP32S2
helper_calc_dac_output(int mV)134 static int helper_calc_dac_output(int mV)
135 {
136 return mV * 0.07722;
137 }
subtest_adc_dac(int mV_ref,esp_adc_cal_characteristics_t * chars)138 static bool subtest_adc_dac(int mV_ref, esp_adc_cal_characteristics_t * chars)
139 {
140 dac_output_voltage(DAC_TEST_CHANNEL_NUM, helper_calc_dac_output(mV_ref));
141 vTaskDelay(pdMS_TO_TICKS(80));
142 int raw;
143 adc2_get_raw((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_WIDTH_BIT_13, &raw);
144 uint32_t voltage = esp_adc_cal_raw_to_voltage(raw, chars);
145 TEST_ASSERT_INT_WITHIN( 200, mV_ref, voltage ); // 200 mV error allowance, because both DAC and ADC have error
146 return true;
147 }
148
149 TEST_CASE("esp32s2 adc2-dac with adc2 calibration", "[adc-dac]")
150 {
151 gpio_num_t adc_gpio_num, dac_gpio_num;
152 if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) != ESP_OK) {
153 TEST_IGNORE_MESSAGE("Warning: This esp32s2 board does not support calibration. This test will be skipped.\n");
154 }
155 TEST_ESP_OK( adc2_pad_get_io_num( ADC_TEST_CHANNEL_NUM, &adc_gpio_num ) );
156 TEST_ESP_OK( dac_pad_get_io_num( DAC_TEST_CHANNEL_NUM, &dac_gpio_num ) );
157 printf("Please connect ADC2 CH%d-GPIO%d <--> DAC CH%d-GPIO%d.\n", ADC_TEST_CHANNEL_NUM, adc_gpio_num,
158 DAC_TEST_CHANNEL_NUM + 1, dac_gpio_num );
159 TEST_ESP_OK( dac_output_enable( DAC_TEST_CHANNEL_NUM ) );
160
161 esp_adc_cal_characteristics_t chars;
162
163 printf("Test 0dB atten...\n");
164 adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_0);
165 esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_13, 0, &chars);
166 printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
167 subtest_adc_dac(750, &chars);
168
169 printf("Test 2.5dB atten...\n");
170 adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_2_5);
171 esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_2_5, ADC_WIDTH_BIT_13, 0, &chars);
172 printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
173 subtest_adc_dac(1100, &chars);
174
175 printf("Test 6dB atten...\n");
176 adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_6);
177 esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_6, ADC_WIDTH_BIT_13, 0, &chars);
178 printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
179 subtest_adc_dac(800, &chars);
180 subtest_adc_dac(1250, &chars);
181
182 printf("Test 11dB atten...\n");
183 adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_11);
184 esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_13, 0, &chars);
185 printf("a %d, b %d\n", chars.coeff_a, chars.coeff_b);
186 subtest_adc_dac(1500, &chars);
187 subtest_adc_dac(2500, &chars);
188 }
189 #endif
190
191 #endif // SOC_DAC_SUPPORTED
192