#include "esp32-c3-uart-interface.h" static void init_uart_enable_clk(){ // enable the clock for UART RAM by setting SYSTEM_UART_MEM_CLK_EN to 1; // enable APB_CLK for UARTn by setting SYSTEM_UARTn_CLK_EN to 1; uint32_t perip_clk_en0_reg = *C3_SYSTEM_PERIP_CLK_EN0_REG; perip_clk_en0_reg |= 1<<24; perip_clk_en0_reg |= 1<<5; perip_clk_en0_reg |= 1<<2; *C3_SYSTEM_PERIP_CLK_EN0_REG = perip_clk_en0_reg; } static void init_uart_toggle_rst(){ // Detailed steps explained in 26.5.2.1 // for resetting and initilizing of uart // get current regestry values uint32_t rx_filt_reg = *C3_UART_RX_FILT_REG; uint32_t core_value = *C3_UART_CLK_CONF_REG; // clear UARTn_RST rx_filt_reg &= (uint32_t)~(1<<5); rx_filt_reg &= (uint32_t)~(1<<2); *C3_UART_RX_FILT_REG = rx_filt_reg; // set UART_RST_CORE core_value |= 1<<23; *C3_UART_CLK_CONF_REG = core_value; // set UARTn_RST rx_filt_reg |= 1<<5; rx_filt_reg |= 1<<2; *C3_UART_RX_FILT_REG = rx_filt_reg; // clear UARTn_RST rx_filt_reg &= (uint32_t)~(1<<5); rx_filt_reg &= (uint32_t)~(1<<2); *C3_UART_RX_FILT_REG = rx_filt_reg; // clear UART_RST_CORE core_value &= (uint32_t)~(1<<23); *C3_UART_CLK_CONF_REG = core_value; } static void init_uart_clear_update(){ // enable register synchronization by clearing UART_UPDATE_CTRL. uint32_t id_value = *C3_UART_ID_REG; id_value &= (uint32_t)~(1<<30); *C3_UART_ID_REG = id_value; } static void config_clock_freq(){ //freq = clock source rate / (UART_SCLK_DIV_NUM+UART_SCLK_DIV_A/UART_SCLK_DIV_B) // baud rate = freq / (UART_CLKDIV + UART_CLKDIV_FRAG / 16) // select the clock source via UART_SCLK_SEL; uint32_t clockSelect = *C3_UART_CLK_CONF_REG; // making sure we start with 0 clockSelect &= (uint32_t)~(1<<20); clockSelect &= (uint32_t)~(1<<21); // 01 is ABP_CLK with 80 MHz // 10 is RC_FAST_CLK with default of 17.5 MHz // 11 is XTAL_CLK with 40 MHz clockSelect |= 1<<20; *C3_UART_CLK_CONF_REG = clockSelect; // selected ABP_CLK with 80 MHz // dividing clock to 6 Mhz (divisor should be 13+1/3) // UART_SCLK_DIV_NUM clockSelect |= 1<<12; clockSelect |= 1<<14; clockSelect |= 1<<15; // UART_SCLK_DIV_A clockSelect |= 1<<6; // UART_SCLK_DIV_B clockSelect |= 1<<1; clockSelect |= 1<<0; *C3_UART_CLK_CONF_REG = clockSelect; // calculate Baud rate to be 9600 (6Mhz/625) uint32_t baudRateDivs = *C3_UART_CLKDIV_REG; baudRateDivs |= 1<<0; baudRateDivs |= 1<<4; baudRateDivs |= 1<<5; baudRateDivs |= 1<<6; baudRateDivs |= 1<<9; *C3_UART_CLKDIV_REG = baudRateDivs; } static void disable_parity(){ uint32_t uart_conf_reg = *C3_UART_CONF0_REG; uart_conf_reg &= (uint32_t)~(1<<0); uart_conf_reg &= (uint32_t)~(1<<1); *C3_UART_CONF0_REG = uart_conf_reg; } static void set_max_data_lenght(){ uint32_t uart_conf_reg = *C3_UART_CONF0_REG; uart_conf_reg |= (1<<2); uart_conf_reg |= (1<<3); *C3_UART_CONF0_REG = uart_conf_reg; } void config_uart(){ printf("Try to config %d\n", 1); // wait for UART_REG_UPDATE to become 0, which indicates the completion of the last synchronization; uint32_t reg_update = *C3_UART_ID_REG; if ((bool)(reg_update & (uint32_t)(1<<31))){ return; } printf("Ready to config %d\n", 1); // configure static registers (if any) following Section 26.5.1.2; // set clock freq to 6MHz // baud rate to 9600 config_clock_freq(); // configure data length via UART_BIT_NUM; set_max_data_lenght(); // configure odd or even parity check via UART_PARITY_EN and UART_PARITY; disable_parity(); // synchronize the configured values to the Core Clock domain by writing 1 to UART_REG_UPDATE. reg_update |= (uint32_t)(1<<31); *C3_UART_ID_REG = reg_update; } void enable_uart_transmitter(){ // configure TX FIFO’s empty threshold via UART_TXFIFO_EMPTY_THRHD; // disable UART_TXFIFO_EMPTY_INT interrupt by clearing UART_TXFIFO_EMPTY_INT_ENA; // write data to be sent to UART_RXFIFO_RD_BYTE; // clear UART_TXFIFO_EMPTY_INT interrupt by setting UART_TXFIFO_EMPTY_INT_CLR; // enable UART_TXFIFO_EMPTY_INT interrupt by setting UART_TXFIFO_EMPTY_INT_ENA; // detect UART_TXFIFO_EMPTY_INT and wait for the completion of data transmission. } void reset_uart(){ // 26.4.1 Clock and Reset init_uart_enable_clk(); init_uart_toggle_rst(); } void init_uart(){ // from technical reference manual 543 f init_uart_enable_clk(); init_uart_toggle_rst(); init_uart_clear_update(); }