#include "esp32-c3-uart-interface.h" #include <stdbool.h> static void config_clock_freq_and_baud_rate(){ //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) uart_clk_conf_reg_t *clk_config = UART_CLK_CONF_REG(1); uart_clkdiv_reg_t *clk_div = UART_CLKDIV_REG(1); // select the clock source via UART_SCLK_SEL; // 1 is ABP_CLK with 80 MHz // 2 is RC_FAST_CLK with default of 17.5 MHz // 3 is XTAL_CLK with 40 MHz clk_config->sclk_sel = 1; // dividing clock to 6 Mhz (divisor should be 13+1/3) // UART_SCLK_DIV_NUM clk_config->sclk_div_num=13; clk_config->sclk_div_a=1; clk_config->sclk_div_b=3; // calculate Baud rate to be 9600 (6Mhz/625) clk_div->div_int=625; } void config_uart(){ // wait for UART_REG(1)_UPDATE to become 0, which indicates the completion of the last synchronization; uart_id_reg_t *id = UART_ID_REG(1); uart_conf0_reg_t *conf0 = UART_CONF0_REG(1); while((bool)(id->reg_update)){ __asm__("ADDI x0, x0, 0"); } // configure static registers (if any) following Section 26.5.1.2; // set clock freq to 6MHz // baud rate to 9600 config_clock_freq_and_baud_rate(); // configure data length via UART_BIT_NUM; conf0->bit_num=3; // configure odd or even parity check via UART_PARITY_EN and UART_PARITY; conf0->parity=0; conf0->parity_en=0; // synchronize the configured values to the Core Clock domain by writing 1 to UART_REG_UPDATE. id->reg_update=1; } void enable_uart_transmitter(){ uart_conf1_reg_t *uart_conf1 = UART_CONF1_REG(1); uart_fifo_reg_t *fifo = UART_FIFO_REG(1); uart_int_clr_reg_t *int_clr = UART_INT_CLR_REG(1); uart_int_ena_reg_t *int_ena = UART_INT_ENA_REG(1); // configure TX FIFO’s empty threshold via UART_TXFIFO_EMPTY_THRHD; uart_conf1->txfifo_empty_thrhd=4; // disable UART_TXFIFO_EMPTY_INT interrupt by clearing UART_TXFIFO_EMPTY_INT_ENA; int_ena->txfifo_empty_int_ena=0; // write data to be sent to UART_RXFIFO_RD_BYTE; fifo->rw_byte=63; // clear UART_TXFIFO_EMPTY_INT interrupt by setting UART_TXFIFO_EMPTY_INT_CLR; int_clr->txfifo_empty_int_clr=1; // enable UART_TXFIFO_EMPTY_INT interrupt by setting UART_TXFIFO_EMPTY_INT_ENA; int_ena->txfifo_empty_int_ena=1; // detect UART_TXFIFO_EMPTY_INT and wait for the completion of data transmission. } void init_uart(){ // from technical reference manual 543 f uart_id_reg_t *id = UART_ID_REG(1); uart_clk_conf_reg_t *clk_config = UART_CLK_CONF_REG(1); system_perip_clk_en0_reg_t *perip_clk_en0 = SYSTEM_PERIP_CLK_EN0_REG; system_perip_rst_en0_reg_t *perip_rst_en0 = SYSTEM_PERIP_RST_EN0_REG; // enable the clock for UART RAM by setting SYSTEM_UART_MEM_CLK_EN to 1; perip_clk_en0->uart_mem_clk_en = 1; // enable APB_CLK for UARTn by setting SYSTEM_UARTn_CLK_EN to 1; perip_clk_en0->uart1_clk_en = 1; // clear SYSTEM_UARTn_RST; perip_rst_en0->uart1_rst = 0; // write 1 to UART_RST_CORE; clk_config->rst_core = 1; // write 1 to SYSTEM_UARTn_RST; perip_rst_en0->uart1_rst = 1; // clear SYSTEM_UARTn_RST; perip_rst_en0->uart1_rst = 0; // clear UART_RST_CORE; clk_config->rst_core = 0; // enable register synchronization by clearing UART_UPDATE_CTRL id->update_ctrl = 0; }