Skip to content
Snippets Groups Projects
Commit c57f5085 authored by Jakob's avatar Jakob
Browse files

chore: split uart interface from main source file

parent 47e2dd08
No related branches found
No related tags found
1 merge request!1copied and adapted example from mdk, added init and config uart
#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
#ifndef ESP32_C3_UART_INTERFACE_H
#define ESP32_C3_UART_INTERFACE_H
#define C3_SYSTEM_PERIP_CLK_EN0_REG ((volatile uint32_t *)0x0010)
// SYSTEM_UART_MEM_CLK_EN is on 24
// SYSTEM_UARTn_CLK_EN n=0 is on 2, n=1 is on 5
#define C3_UART_CLKDIV_REG ((volatile uint32_t *)0x0014)
// UART_CLKDIV - integer part of baud rate calculator devisor - 0 to 11
// UART_CLKDIV_FRAG - numerator of devisor in baud rate calculator devisor
#define C3_UART_RX_FILT_REG ((volatile uint32_t *)0x0018)
// SYSTEM_UARTn_RST n=0 is on 2, n=1 is on 5
#define C3_UART_CONF0_REG ((volatile uint32_t *)0x0020)
// UART_PARITY is on 0
// UART_PARITY_EN is on 1
// UART_BIT_NUM is on 2 and 3
#define C3_UART_CLK_CONF_REG ((volatile uint32_t *)0x0078)
// UART_RST_CORE is on 23
// UART_SCLK_SEL is on 20 and 21 (2 bits), selcetion is between 1 and 3
// UART_SCLK_DIV_NUM - The integral part of the frequency divisor - 12 to 19
// UART_SCLK_DIV_A - The numerator of the frequency divisor - 6 to 11
// UART_SCLK_DIV_B - The denominator of the frequency divisor - 0 to 5
#define C3_UART_ID_REG ((volatile uint32_t *)0x0080)
// UART_UPDATE_CTRL is on 30
// UART_REG_UPDATE is on 31
void config_uart();
void init_uart();
void reset_uart();
void enable_uart_transmitter();
#endif
\ No newline at end of file
......@@ -3,183 +3,9 @@
#include <mdk.h>
#define C3_SYSTEM_PERIP_CLK_EN0_REG ((volatile uint32_t *)0x0010)
// SYSTEM_UART_MEM_CLK_EN is on 24
// SYSTEM_UARTn_CLK_EN n=0 is on 2, n=1 is on 5
#define C3_UART_CLKDIV_REG ((volatile uint32_t *)0x0014)
// UART_CLKDIV - integer part of baud rate calculator devisor - 0 to 11
// UART_CLKDIV_FRAG - numerator of devisor in baud rate calculator devisor
#define C3_UART_RX_FILT_REG ((volatile uint32_t *)0x0018)
// SYSTEM_UARTn_RST n=0 is on 2, n=1 is on 5
#define C3_UART_CONF0_REG ((volatile uint32_t *)0x0020)
// UART_PARITY is on 0
// UART_PARITY_EN is on 1
// UART_BIT_NUM is on 2 and 3
#define C3_UART_CLK_CONF_REG ((volatile uint32_t *)0x0078)
// UART_RST_CORE is on 23
// UART_SCLK_SEL is on 20 and 21 (2 bits), selcetion is between 1 and 3
// UART_SCLK_DIV_NUM - The integral part of the frequency divisor - 12 to 19
// UART_SCLK_DIV_A - The numerator of the frequency divisor - 6 to 11
// UART_SCLK_DIV_B - The denominator of the frequency divisor - 0 to 5
#define C3_UART_ID_REG ((volatile uint32_t *)0x0080)
// UART_UPDATE_CTRL is on 30
// UART_REG_UPDATE is on 31
// On the ESP32C3 dev boards, the WS2812 LED is connected to GPIO 8
static int ws_2812_pin = 8;
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;
}
static 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;
}
static 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.
}
//static void reset_uart(){
// 26.4.1 Clock and Reset
// init_uart_enable_clk();
// init_uart_toggle_rst();
//}
static void init_uart(){
// from technical reference manual 543 f
init_uart_enable_clk();
init_uart_toggle_rst();
init_uart_clear_update();
}
// Simple hue function for generation of smooth rainbow.
static uint8_t hueval(int value) {
value = value % 1536;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment