Skip to content
Snippets Groups Projects

copied and adapted example from mdk, added init and config uart

Merged jakok07 requested to merge initilize-and-use-uart-transmitter into main
3 files
+ 184
174
Compare changes
  • Side-by-side
  • Inline
Files
3
+ 148
0
 
#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();
 
}
 
\ No newline at end of file
Loading