# AT32F403A/407 MCU Documentation Repository ## Introduction This project provides comprehensive technical documentation and firmware driver resources for the Artery AT32F403A/407 ARM Cortex-M4 microcontroller series, designed as a primary reference source for Context7 and embedded systems development. The repository includes 26 detailed peripheral documentation files covering all major subsystems (CAN, Flash, PWC, ADC, I2C, SPI, TMR, USART, USB, GPIO, DMA, EMAC, and more), a complete firmware library v2.2.1 with peripheral drivers and CMSIS support, and an intelligent taxonomy system with 5 YAML files for semantic search. Each peripheral guide provides complete API references, initialization code examples, GPIO pin mappings, best practices, and troubleshooting guidance, making this a comprehensive resource for firmware development and Context7 AI integration. The repository serves as both a critical reference for production firmware development and a Context7-optimized knowledge source with structured metadata and searchable content. With 26 peripheral documentation files totaling over 25,000 lines of technical content, complete peripheral driver implementations (26 headers + 25 source files), CMSIS ARM Cortex-M4 core support, and 5 YAML taxonomy files for intelligent search, developers have immediate access to working code examples and comprehensive API documentation. The markdown format ensures GitHub-native rendering with interactive tables, code syntax highlighting, cross-references, and full-text search across all technical documentation. For device errata and silicon limitations, users should download the official ES0002 errata sheet from Artery Technology's website, which documents 41 known issues with detailed workarounds for critical areas like Flash operations, CAN communication, and power management. ## API Reference and Code Examples ### CAN Controller Initialization Initialize CAN controller with proper baudrate configuration and filter setup ```c #include "at32f403a_407_can.h" void can_configuration(void) { can_base_type can_base_struct; can_baudrate_type can_baudrate_struct; can_filter_init_type can_filter_init_struct; // Enable CAN1 and GPIO clocks crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); // Configure GPIO pins (PA11=RX, PA12=TX) gpio_init_type gpio_init_struct; gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = GPIO_PINS_11 | GPIO_PINS_12; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); // CAN base configuration can_default_para_init(&can_base_struct); can_base_struct.mode_selection = CAN_MODE_COMMUNICATE; can_base_struct.ttc_enable = FALSE; can_base_struct.aebo_enable = TRUE; can_base_struct.aed_enable = TRUE; can_base_struct.prsf_enable = FALSE; can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED; can_base_struct.mmssr_enable = TRUE; can_base_init(CAN1, &can_base_struct); // Baudrate configuration for 500 kbps (assuming APB1 = 120 MHz) can_baudrate_struct.baudrate_div = 20; can_baudrate_struct.rsaw_size = CAN_RSAW_3TQ; can_baudrate_struct.bts1_size = CAN_BTS1_8TQ; can_baudrate_struct.bts2_size = CAN_BTS2_3TQ; can_baudrate_set(CAN1, &can_baudrate_struct); // Configure filter to accept all messages can_filter_init_struct.filter_activate_enable = TRUE; can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0; can_filter_init_struct.filter_number = 0; can_filter_init_struct.filter_bit = CAN_FILTER_32BIT; can_filter_init_struct.filter_id_high = 0x0000; can_filter_init_struct.filter_id_low = 0x0000; can_filter_init_struct.filter_mask_high = 0x0000; can_filter_init_struct.filter_mask_low = 0x0000; can_filter_init(CAN1, &can_filter_init_struct); } ``` ### CAN Message Transmission Transmit CAN message with standard 11-bit identifier ```c void can_transmit_message(uint32_t std_id, uint8_t *data, uint8_t length) { can_tx_message_type tx_message; tx_message.standard_id = std_id; tx_message.extended_id = 0; tx_message.id_type = CAN_ID_STANDARD; tx_message.frame_type = CAN_TFT_DATA; tx_message.dlc = length; for(uint8_t i = 0; i < length; i++) { tx_message.data[i] = data[i]; } can_message_transmit(CAN1, &tx_message); } ``` ### CAN Message Reception with Interrupt Configure CAN reception interrupt and handler ```c void can_nvic_configuration(void) { nvic_irq_enable(CAN1_RX0_IRQn, 0, 0); can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE); } void CAN1_RX0_IRQHandler(void) { can_rx_message_type rx_message; if(can_flag_get(CAN1, CAN_RF0MN_FLAG) != RESET) { can_message_receive(CAN1, CAN_RX_FIFO0, &rx_message); // Process received message if(rx_message.frame_type == CAN_TFT_DATA) { process_can_data(rx_message.standard_id, rx_message.data, rx_message.dlc); } } } ``` ### Flash Memory Programming Program flash memory with proper unlock/lock sequence ```c #include "at32f403a_407_flash.h" flash_status_type flash_write_data(uint32_t address, uint32_t *data, uint32_t length) { flash_status_type status = FLASH_OPERATE_DONE; uint32_t i; // Unlock flash flash_unlock(); // Write data word by word for(i = 0; i < length; i++) { status = flash_word_program(address + (i * 4), data[i]); if(status != FLASH_OPERATE_DONE) { break; } } // Lock flash flash_lock(); return status; } ``` ### Flash Sector Erase Erase a flash sector before programming ```c flash_status_type flash_erase_sector(uint32_t sector_address) { flash_status_type status; // Unlock flash flash_unlock(); // Erase sector status = flash_sector_erase(sector_address); // Wait for operation to complete status = flash_operation_wait_for(ERASE_TIMEOUT); // Lock flash flash_lock(); return status; } ``` ### ADC Single Channel Conversion Initialize ADC for single channel conversion ```c #include "at32f403a_407_adc.h" void adc_single_channel_init(void) { adc_base_config_type adc_base_struct; // Enable ADC and GPIO clocks crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); // Configure ADC clock (max 14 MHz for 12-bit mode) crm_adc_clock_div_set(CRM_ADC_DIV_6); // Configure GPIO pin as analog input (PA0) gpio_init_type gpio_init_struct; gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_0; gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG; gpio_init(GPIOA, &gpio_init_struct); // ADC base configuration adc_base_default_para_init(&adc_base_struct); adc_base_struct.sequence_mode = FALSE; adc_base_struct.repeat_mode = FALSE; adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT; adc_base_struct.ordinary_channel_length = 1; adc_base_config(ADC1, &adc_base_struct); // Configure channel adc_ordinary_channel_set(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_239_5); // Enable ADC adc_enable(ADC1, TRUE); // Calibrate ADC adc_calibration_init(ADC1); while(adc_calibration_init_status_get(ADC1)); adc_calibration_start(ADC1); while(adc_calibration_status_get(ADC1)); } uint16_t adc_read_channel(void) { // Start conversion adc_ordinary_software_trigger_enable(ADC1, TRUE); // Wait for conversion to complete while(adc_flag_get(ADC1, ADC_OCCE_FLAG) == RESET); // Return conversion result return adc_ordinary_conversion_data_get(ADC1); } ``` ### ADC DMA Mode Configuration Configure ADC with DMA for continuous conversion ```c void adc_dma_mode_init(uint16_t *adc_buffer, uint32_t buffer_size) { adc_base_config_type adc_base_struct; dma_init_type dma_init_struct; // Enable clocks crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE); // Configure DMA dma_reset(DMA1_CHANNEL1); dma_default_para_init(&dma_init_struct); dma_init_struct.buffer_size = buffer_size; dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; dma_init_struct.memory_base_addr = (uint32_t)adc_buffer; dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD; dma_init_struct.memory_inc_enable = TRUE; dma_init_struct.peripheral_base_addr = (uint32_t)&(ADC1->odt); dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD; dma_init_struct.peripheral_inc_enable = FALSE; dma_init_struct.priority = DMA_PRIORITY_HIGH; dma_init_struct.loop_mode_enable = TRUE; dma_init(DMA1_CHANNEL1, &dma_init_struct); dma_channel_enable(DMA1_CHANNEL1, TRUE); // Configure ADC adc_base_default_para_init(&adc_base_struct); adc_base_struct.sequence_mode = FALSE; adc_base_struct.repeat_mode = TRUE; adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT; adc_base_struct.ordinary_channel_length = 1; adc_base_config(ADC1, &adc_base_struct); adc_ordinary_channel_set(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_239_5); adc_dma_mode_enable(ADC1, TRUE); adc_enable(ADC1, TRUE); // Calibrate adc_calibration_init(ADC1); while(adc_calibration_init_status_get(ADC1)); adc_calibration_start(ADC1); while(adc_calibration_status_get(ADC1)); // Start conversion adc_ordinary_software_trigger_enable(ADC1, TRUE); } ``` ### I2C Master Transmit Send data via I2C as master device ```c #include "at32f403a_407_i2c.h" void i2c_master_init(void) { i2c_init_type i2c_init_struct; gpio_init_type gpio_init_struct; // Enable clocks crm_periph_clock_enable(CRM_I2C1_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); // Configure GPIO (PB6=SCL, PB7=SDA) gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = GPIO_PINS_6 | GPIO_PINS_7; gpio_init_struct.gpio_pull = GPIO_PULL_UP; gpio_init(GPIOB, &gpio_init_struct); // I2C configuration i2c_init_struct.i2c_mode = I2C_MODE_I2CMODE; i2c_init_struct.speed = I2C_SPEED_FAST; i2c_init_struct.duty_cycle = I2C_DUTYCYCLE_2; i2c_init_struct.own_address1 = 0x00; i2c_init_struct.ack_enable = I2C_ACK_ENABLE; i2c_init_struct.address_mode = I2C_ADDRESS_MODE_7BIT; i2c_init(I2C1, &i2c_init_struct); i2c_enable(I2C1, TRUE); } void i2c_master_transmit(uint8_t slave_addr, uint8_t *data, uint16_t length) { uint16_t i; // Generate start condition i2c_start_generate(I2C1, TRUE); while(!i2c_flag_get(I2C1, I2C_STARTF_FLAG)); // Send slave address i2c_7bit_address_send(I2C1, slave_addr, I2C_DIRECTION_TRANSMIT); while(!i2c_flag_get(I2C1, I2C_ADDRF_FLAG)); i2c_flag_clear(I2C1, I2C_ADDRF_FLAG); // Transmit data for(i = 0; i < length; i++) { i2c_data_send(I2C1, data[i]); while(!i2c_flag_get(I2C1, I2C_TDBE_FLAG)); } // Generate stop condition i2c_stop_generate(I2C1, TRUE); } ``` ### SPI Master Configuration Initialize SPI as master device ```c #include "at32f403a_407_spi.h" void spi_master_init(void) { spi_init_type spi_init_struct; gpio_init_type gpio_init_struct; // Enable clocks crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); // Configure GPIO (PA5=SCK, PA6=MISO, PA7=MOSI) gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = GPIO_PINS_5 | GPIO_PINS_7; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_6; gpio_init(GPIOA, &gpio_init_struct); // SPI configuration spi_default_para_init(&spi_init_struct); spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX; spi_init_struct.master_slave_mode = SPI_MODE_MASTER; spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_8; spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB; spi_init_struct.frame_bit_num = SPI_FRAME_8BIT; spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_LOW; spi_init_struct.clock_phase = SPI_CLOCK_PHASE_1EDGE; spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE; spi_init(SPI1, &spi_init_struct); spi_enable(SPI1, TRUE); } uint8_t spi_transfer_byte(uint8_t data) { // Wait until transmit buffer is empty while(spi_i2s_flag_get(SPI1, SPI_I2S_TDBE_FLAG) == RESET); spi_i2s_data_transmit(SPI1, data); // Wait until receive buffer is not empty while(spi_i2s_flag_get(SPI1, SPI_I2S_RDBF_FLAG) == RESET); return spi_i2s_data_receive(SPI1); } ``` ### USART Configuration and Communication Initialize USART for serial communication ```c #include "at32f403a_407_usart.h" void usart_init_config(void) { gpio_init_type gpio_init_struct; // Enable clocks crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); // Configure GPIO (PA9=TX, PA10=RX) gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = GPIO_PINS_9; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOA, &gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_10; gpio_init(GPIOA, &gpio_init_struct); // USART configuration usart_init(USART1, 115200, USART_DATA_8BITS, USART_STOP_1_BIT); usart_transmitter_enable(USART1, TRUE); usart_receiver_enable(USART1, TRUE); usart_enable(USART1, TRUE); } void usart_send_byte(uint8_t data) { while(usart_flag_get(USART1, USART_TDBE_FLAG) == RESET); usart_data_transmit(USART1, data); } uint8_t usart_receive_byte(void) { while(usart_flag_get(USART1, USART_RDBF_FLAG) == RESET); return usart_data_receive(USART1); } void usart_send_string(char *str) { while(*str) { usart_send_byte(*str++); } } ``` ### Timer PWM Generation Configure timer for PWM output ```c #include "at32f403a_407_tmr.h" void tmr_pwm_init(void) { tmr_output_config_type tmr_output_struct; gpio_init_type gpio_init_struct; // Enable clocks crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); // Configure GPIO (PA0=TMR2_CH1) gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_0; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init(GPIOA, &gpio_init_struct); // Timer base configuration (1 kHz PWM) tmr_base_init(TMR2, 999, 119); // Period=1000, Prescaler=120 tmr_cnt_dir_set(TMR2, TMR_COUNT_UP); // PWM mode configuration tmr_output_default_para_init(&tmr_output_struct); tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; tmr_output_struct.oc_output_state = TRUE; tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; tmr_output_struct.oc_idle_state = FALSE; tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_1, &tmr_output_struct); // Set duty cycle (50%) tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_1, 500); // Enable timer tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_1, TRUE); tmr_counter_enable(TMR2, TRUE); } void tmr_set_duty_cycle(uint16_t duty) { tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_1, duty); } ``` ### DMA Memory to Peripheral Transfer Configure DMA for memory to peripheral transfer ```c #include "at32f403a_407_dma.h" void dma_config_mem_to_periph(uint32_t *src_buffer, uint32_t periph_addr, uint32_t length) { dma_init_type dma_init_struct; // Enable DMA clock crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); // Reset DMA channel dma_reset(DMA1_CHANNEL1); // Configure DMA dma_default_para_init(&dma_init_struct); dma_init_struct.buffer_size = length; dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; dma_init_struct.memory_base_addr = (uint32_t)src_buffer; dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD; dma_init_struct.memory_inc_enable = TRUE; dma_init_struct.peripheral_base_addr = periph_addr; dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD; dma_init_struct.peripheral_inc_enable = FALSE; dma_init_struct.priority = DMA_PRIORITY_MEDIUM; dma_init_struct.loop_mode_enable = FALSE; dma_init(DMA1_CHANNEL1, &dma_init_struct); // Enable DMA channel dma_channel_enable(DMA1_CHANNEL1, TRUE); } ``` ### GPIO Configuration Configure GPIO pins for various modes ```c #include "at32f403a_407_gpio.h" #include "at32f403a_407_crm.h" void gpio_output_init(void) { gpio_init_type gpio_init_struct; // Enable GPIO clock crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE); // Configure PC13 as output (LED pin) gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_13; gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init(GPIOC, &gpio_init_struct); } void gpio_input_init(void) { gpio_init_type gpio_init_struct; // Enable GPIO clock crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); // Configure PA0 as input with pull-down (button pin) gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_0; gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; gpio_init_struct.gpio_pull = GPIO_PULL_DOWN; gpio_init(GPIOA, &gpio_init_struct); } void gpio_toggle_led(void) { gpio_bits_write(GPIOC, GPIO_PINS_13, !gpio_output_data_bit_read(GPIOC, GPIO_PINS_13)); } uint8_t gpio_read_button(void) { return gpio_input_data_bit_read(GPIOA, GPIO_PINS_0); } ``` ### External Interrupt Configuration Configure external interrupt on GPIO pin ```c #include "at32f403a_407_exint.h" void exint_config(void) { exint_init_type exint_init_struct; gpio_init_type gpio_init_struct; // Enable clocks crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE); // Configure PA0 as input gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_pins = GPIO_PINS_0; gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; gpio_init_struct.gpio_pull = GPIO_PULL_DOWN; gpio_init(GPIOA, &gpio_init_struct); // Connect EXINT line to GPIO pin gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE0); // Configure EXINT exint_default_para_init(&exint_init_struct); exint_init_struct.line_enable = TRUE; exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT; exint_init_struct.line_select = EXINT_LINE_0; exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE; exint_init(&exint_init_struct); // Enable NVIC nvic_irq_enable(EXINT0_IRQn, 0, 0); } void EXINT0_IRQHandler(void) { if(exint_flag_get(EXINT_LINE_0) != RESET) { // Handle interrupt handle_button_press(); // Clear flag exint_flag_clear(EXINT_LINE_0); } } ``` ### RTC Configuration Initialize Real-Time Clock ```c #include "at32f403a_407_rtc.h" #include "at32f403a_407_pwc.h" #include "at32f403a_407_bpr.h" void rtc_config(void) { // Enable PWC and BPR clocks crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE); // Enable access to backup domain pwc_battery_powered_domain_access(TRUE); // Reset backup domain crm_battery_powered_domain_reset(TRUE); crm_battery_powered_domain_reset(FALSE); // Enable LEXT (32.768 kHz external crystal) crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE); while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET); // Select LEXT as RTC clock source crm_rtc_clock_select(CRM_RTC_CLOCK_LEXT); crm_rtc_clock_enable(TRUE); // Wait for RTC registers synchronization rtc_wait_for_synchro(); // Wait for RTC register access rtc_wait_config_finish(); // Set RTC divider (32768 - 1) rtc_divider_set(32767); // Wait for configuration to finish rtc_wait_config_finish(); } void rtc_set_time(uint32_t timestamp) { rtc_wait_config_finish(); rtc_counter_set(timestamp); rtc_wait_config_finish(); } uint32_t rtc_get_time(void) { return rtc_counter_get(); } ``` ### Watchdog Timer Configuration Configure independent watchdog timer ```c #include "at32f403a_407_wdt.h" void wdt_init(uint16_t timeout_ms) { // Enable write access to WDT registers wdt_enable(); wdt_register_write_enable(TRUE); // Configure divider and reload value // LICK = 40 kHz, timeout = (4 * 2^div * reload) / 40000 wdt_divider_set(WDT_CLK_DIV_32); // 32 divider wdt_reload_value_set((timeout_ms * 40) / 128); // Calculate reload value // Reload counter wdt_counter_reload(); // Disable write access wdt_register_write_enable(FALSE); } void wdt_feed(void) { wdt_counter_reload(); } ``` ### Power Management - Sleep Mode Enter sleep mode with wake-up configuration ```c #include "at32f403a_407_pwc.h" void enter_sleep_mode(void) { // Configure wake-up sources (e.g., EXINT, RTC) // ... (configure interrupts as needed) // Enter sleep mode using WFI instruction pwc_sleep_mode_enter(PWC_SLEEP_ENTER_WFI); // CPU wakes up here when interrupt occurs } void enter_deepsleep_mode(void) { // Save power by disabling unnecessary peripherals // ... (disable unused clocks) // Configure voltage regulator pwc_voltage_regulate_set(PWC_REGULATOR_LOW_POWER); // Enter deepsleep mode pwc_deep_sleep_mode_enter(PWC_DEEP_SLEEP_ENTER_WFI); // CPU wakes up here and restores clocks } ``` ### USB Device Configuration Initialize USB device peripheral ```c #include "at32f403a_407_usb.h" void usb_device_init(void) { // Enable USB clock crm_periph_clock_enable(CRM_USB_PERIPH_CLOCK, TRUE); crm_usb_clock_div_set(CRM_USB_DIV_2_5); // 120MHz / 2.5 = 48MHz // Enable USB interrupts nvic_irq_enable(OTGFS1_IRQn, 0, 0); // Initialize USB peripheral usb_global_init(); // Configure device mode usb_device_init(); } ``` ## Integration and Usage Summary This comprehensive MCU documentation repository enables developers to successfully deploy AT32F403A/407 microcontrollers in production systems through multiple integrated resources: (1) 26 detailed peripheral documentation files covering all major subsystems with complete API references, code examples, and best practices, (2) complete firmware library v2.2.1 with 26 peripheral driver headers and 25 implementation files providing production-ready driver code, (3) CMSIS ARM Cortex-M4 core support for standard embedded development workflows, (4) intelligent taxonomy system with 5 YAML files enabling Context7 semantic search for natural language queries, and (5) comprehensive technical content totaling over 25,000 lines of documentation. Primary use cases include firmware development with documented API references, peripheral initialization using provided code examples, driver integration leveraging the firmware library, Context7 AI integration for intelligent MCU queries, and hardware debugging with detailed peripheral behavior documentation. Integration patterns follow a multi-layered approach: developers start by exploring the peripheral documentation files in the docs/ folder to understand initialization sequences and API usage patterns, then leverage the firmware library drivers (at32f403a_407_*.h/c files) for production-grade peripheral implementations, and finally use the taxonomy system for semantic search of specific functionality. The repository provides detailed peripheral guides for critical subsystems including CAN (Controller Area Network with dual controllers, 14 filters, and 1 Mbps support), Flash (dual-bank architecture with SPIM external flash and security library protection), ADC (3x 12-bit ADCs with DMA support and 2 MSPS sampling), USART (5 controllers with DMA, LIN, IrDA, and SmartCard support), TMR (10 timers with advanced PWM, encoder, and input capture), I2C (2 controllers with 400 kHz Fast Mode and SMBus support), SPI (4 controllers up to 60 Mbps), USB (USB 2.0 Full Speed device/host/OTG), DMA (12 channels with flexible request routing), and GPIO (up to 144 I/O pins with alternate function mapping). Context7 users benefit from YAML-structured metadata enabling intelligent queries like "show me SPI DMA initialization code" or "how to configure CAN filters" with direct navigation to relevant documentation and code examples. For device errata and silicon limitations, developers should download the official ES0002 errata sheet from Artery Technology's website, which documents 41 known issues with detailed workarounds for critical areas affecting Flash operations, CAN communication, and power management functionality.