diff --git a/CMakeLists.txt b/CMakeLists.txt index 68425e7..2a1dd0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ set(TARGET_SOURCES "SDK/middlewares/i2c_application_library/i2c_application.c" "board/at32f435_437_board.c" "board/at32f435_437_clock.c" + "src/app_adc.c" "src/app_ate_impl.c" "src/main.c" ) diff --git a/include/app_adc.h b/include/app_adc.h new file mode 100644 index 0000000..d04444e --- /dev/null +++ b/include/app_adc.h @@ -0,0 +1,9 @@ +#ifndef APP_ADC_H +#define APP_ADC_H + +#include + +void app_adc_init(void); +uint16_t app_adc_read(void); + +#endif // APP_ADC_H diff --git a/src/app_adc.c b/src/app_adc.c new file mode 100644 index 0000000..f118c63 --- /dev/null +++ b/src/app_adc.c @@ -0,0 +1,69 @@ +#include "at32f435_437_board.h" + +/* App */ +#include "app_adc.h" + +void app_adc_init(void) { + crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE); + + gpio_init_type pin_cfg = { + .gpio_pins = GPIO_PINS_0, + .gpio_mode = GPIO_MODE_ANALOG, + .gpio_out_type = GPIO_OUTPUT_PUSH_PULL, + .gpio_pull = GPIO_PULL_NONE, + .gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER, + }; + + gpio_init(GPIOB, &pin_cfg); + + adc_common_config_type adc_cfg = { + .combine_mode = ADC_INDEPENDENT_MODE, + .div = ADC_HCLK_DIV_4, + .common_dma_mode = ADC_COMMON_DMAMODE_DISABLE, + .common_dma_request_repeat_state = FALSE, + .sampling_interval = ADC_SAMPLING_INTERVAL_5CYCLES, + .tempervintrv_state = FALSE, + .vbat_state = FALSE, + }; + + adc_common_config(&adc_cfg); + + adc_base_config_type base_cfg = { + .sequence_mode = FALSE, + .repeat_mode = FALSE, + .data_align = ADC_RIGHT_ALIGNMENT, + .ordinary_channel_length = 1, + }; + + adc_base_config(ADC1, &base_cfg); + + adc_resolution_set(ADC1, ADC_RESOLUTION_12B); + + adc_ordinary_channel_set(ADC1, ADC_CHANNEL_8, 1, ADC_SAMPLETIME_640_5); + + adc_enable(ADC1, TRUE); + + while (adc_flag_get(ADC1, ADC_RDY_FLAG) == RESET) { + /* -- */ + } + + adc_calibration_init(ADC1); + while (adc_calibration_init_status_get(ADC1)) { + /* -- */ + } + + adc_calibration_start(ADC1); + while (adc_calibration_status_get(ADC1)) { + /* -- */ + } +} + +uint16_t app_adc_read(void) { + adc_ordinary_software_trigger_enable(ADC1, TRUE); + while (adc_flag_get(ADC1, ADC_OCCE_FLAG) == RESET) { + /* -- */ + } + + return adc_ordinary_conversion_data_get(ADC1); +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 17c55b5..fdb289c 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include "at32f435_437_i2c.h" /* ATE */ +#include "app_adc.h" #include "app_ate_impl.h" static ate_t s_ate = { @@ -17,11 +18,14 @@ static ate_t s_ate = { }, }; +static int app_ad_da_test(void); + int main(void) { system_clock_config(); at32_board_init(); uart_print_init(115200); + app_adc_init(); ate_impl_i2c_init(); if (ate_init(&s_ate) != ATE_RET_SUCCESS) { @@ -32,73 +36,64 @@ int main(void) { printf("ATE initialized.\r\n"); - bool pin_value = false; + at32_led_on(LED3); - if (ate_gpio_read(&s_ate, 0, &pin_value) != ATE_RET_SUCCESS) { - printf("Failed to read GPIO value\r\n"); - - goto dead_loop; + if (app_ad_da_test() < 0) { + goto fail_exit; } - if (ate_gpio_write(&s_ate, 0, 1) != ATE_RET_SUCCESS) { - printf("Failed to write pin.\r\n"); - - goto dead_loop; - } - - if (ate_gpio_init(&s_ate, 0, ATE_GPIO_MODE_OUTPUT_PP) != ATE_RET_SUCCESS) { - printf("Failed to config pin."); - - goto dead_loop; - } - - if (ate_gpio_read(&s_ate, 0, &pin_value) != ATE_RET_SUCCESS) { - printf("Failed to read GPIO value\r\n"); - - goto dead_loop; - } - - printf("GPIO value: %d\r\n", pin_value); - - if (ate_adc_configure(&s_ate, true, ATE_ADC_CH_IOREF_MASK) != ATE_RET_SUCCESS) { - printf("Failed to enable ATE ADC.\r\n"); - - goto dead_loop; - } - - uint16_t ioref_val; - uint16_t da_value = 0; + at32_led_off(LED3); + at32_led_on(LED4); + ate_led_set(&s_ate, ATE_LED_G, true); for (;;) { /* -- */ - ate_led_set(&s_ate, ATE_LED_G, true); - delay_ms(500); - ate_led_set(&s_ate, ATE_LED_G, false); - delay_ms(500); - - ate_ret_t ret = ate_adc_read(&s_ate, ATE_ADC_CH_IOREF, &ioref_val); - if (ret == ATE_RET_NOT_READY) { - printf("ADC result is not ready.\r\n"); - - continue; - } else if (ret != ATE_RET_SUCCESS) { - printf("Failed to read ADC value.\r\n"); - - goto dead_loop; - } - - printf("IOREF: %ld mV\r\n", ((uint32_t)ioref_val * 3300 * 2 / 4095)); - - ate_dac_set(&s_ate, da_value); - printf("DAC set to %dmV\r\n", (da_value * 3300 / 1023)); - da_value += 32; - if (da_value > 1023) { - da_value = 0U; - } } +fail_exit: + at32_led_off(LED3); + at32_led_on(LED2); + ate_led_set(&s_ate, ATE_LED_R, true); + dead_loop: for (;;) { /* -- */ } } + +static int app_ad_da_test(void) { + printf("[ADDA] Test started.\r\n"); + + for (uint16_t i = 0; i < 1024; i += 16) { + ate_led_set(&s_ate, ATE_LED_B, true); + + ate_dac_set(&s_ate, i); + + delay_ms(10); + + uint16_t ad_result = app_adc_read(); + uint16_t ad_voltage = ad_result * 3300 / 4096; + uint16_t da_voltage = i * 3300 / 1024; + int delta_voltage = ad_voltage - da_voltage; + + printf("[ADDA] AD voltage: %5dmV, set: %5dmV, delta: %5dmV\r\n", ad_voltage, da_voltage, delta_voltage); + + if (ad_voltage > da_voltage) { + if (ad_voltage - da_voltage > 100) { + return -1; + } + } else if (da_voltage > ad_voltage) { + if (da_voltage - ad_voltage > 100) { + return -1; + } + } + + ate_led_set(&s_ate, ATE_LED_B, false); + + delay_ms(10); + } + + printf("[ADDA] Test completed.\r\n"); + + return 0; +} \ No newline at end of file