From f5e4f9524940984c929bc48505b9435c1a89468e Mon Sep 17 00:00:00 2001 From: Jakob <Jakob.knitter@bettermarks.com> Date: Mon, 19 Jun 2023 15:44:05 +0200 Subject: [PATCH] feat: new simpler and working approach to initilize the uart --- src/simple-uart-transmit/Makefile | 3 + .../esp32-c3-uart-interface.c | 108 ++++++++ .../esp32-c3-uart-interface.h | 253 ++++++++++++++++++ src/simple-uart-transmit/main.c | 14 + 4 files changed, 378 insertions(+) create mode 100644 src/simple-uart-transmit/Makefile create mode 100644 src/simple-uart-transmit/esp32-c3-uart-interface.c create mode 100644 src/simple-uart-transmit/esp32-c3-uart-interface.h create mode 100644 src/simple-uart-transmit/main.c diff --git a/src/simple-uart-transmit/Makefile b/src/simple-uart-transmit/Makefile new file mode 100644 index 0000000..2171daa --- /dev/null +++ b/src/simple-uart-transmit/Makefile @@ -0,0 +1,3 @@ +SOURCES = main.c esp32-c3-uart-interface.c + +include $(MDK)/$(ARCH)/build.mk diff --git a/src/simple-uart-transmit/esp32-c3-uart-interface.c b/src/simple-uart-transmit/esp32-c3-uart-interface.c new file mode 100644 index 0000000..cac1024 --- /dev/null +++ b/src/simple-uart-transmit/esp32-c3-uart-interface.c @@ -0,0 +1,108 @@ +#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; +} \ No newline at end of file diff --git a/src/simple-uart-transmit/esp32-c3-uart-interface.h b/src/simple-uart-transmit/esp32-c3-uart-interface.h new file mode 100644 index 0000000..d34e5e2 --- /dev/null +++ b/src/simple-uart-transmit/esp32-c3-uart-interface.h @@ -0,0 +1,253 @@ +#ifndef ESP32_C3_REGISTER_INTERFACE_H +#define ESP32_C3_REGISTER_INTERFACE_H + +#include <stdint.h> + +#define C3_BASE_OFFSET_SYSTEM_REGISTERS ((uint32_t)0x600C0000) + +#define C3_UART_CONTROLLER_0_BASE ((uint32_t)0x60000000) +#define C3_UART_CONTROLLER_1_BASE ((uint32_t)0x60010000) +#define C3_UART_CONTROLLER_SELECT(base_select) ((uint32_t)((base_select == 1) ? C3_UART_CONTROLLER_1_BASE : C3_UART_CONTROLLER_0_BASE)) + +typedef volatile struct { + uint32_t rw_byte; +} uart_fifo_reg_t; + +typedef volatile struct { + uint32_t rxfifo_full: 1; + uint32_t txfifo_empty: 1; + uint32_t parity_err: 1; + uint32_t frm_err: 1; + uint32_t rxfifo_ovf: 1; + uint32_t dsr_chg: 1; + uint32_t cts_chg: 1; + uint32_t brk_det: 1; + uint32_t rxfifo_tout: 1; + uint32_t sw_xon: 1; + uint32_t sw_xoff: 1; + uint32_t glitch_det: 1; + uint32_t tx_brk_done: 1; + uint32_t tx_brk_idle_done: 1; + uint32_t tx_done: 1; + uint32_t rs485_parity_err: 1; + uint32_t rs485_frm_err: 1; + uint32_t rs485_clash: 1; + uint32_t at_cmd_char_det: 1; + uint32_t wakeup: 1; + uint32_t reserved: 12; +} uart_int_raw_t; + +typedef volatile struct { + uint32_t rxfifo_full_int_ena: 1; + uint32_t txfifo_empty_int_ena: 1; + uint32_t parity_err_int_ena: 1; + uint32_t frm_err_int_ena: 1; + uint32_t rxfifo_ovf_int_ena: 1; + uint32_t dsr_chg_int_ena: 1; + uint32_t cts_chg_int_ena: 1; + uint32_t brk_det_int_ena: 1; + uint32_t rxfifo_tout_int_ena: 1; + uint32_t sw_xon_int_ena: 1; + uint32_t sw_xoff_int_ena: 1; + uint32_t glitch_det_int_ena: 1; + uint32_t tx_brk_done_int_ena: 1; + uint32_t tx_brk_idle_done_int_ena: 1; + uint32_t tx_done_int_ena: 1; + uint32_t rs485_parity_err_int_ena: 1; + uint32_t rs485_frm_err_int_ena: 1; + uint32_t rs485_clash_int_ena: 1; + uint32_t at_cmd_char_det_int_ena: 1; + uint32_t wakeup_int_ena: 1; + uint32_t reserved: 12; +} uart_int_ena_reg_t; + +typedef volatile struct { + uint32_t rxfifo_full_int_clr: 1; + uint32_t txfifo_empty_int_clr: 1; + uint32_t parity_err_int_clr: 1; + uint32_t frm_err_int_clr: 1; + uint32_t rxfifo_ovf_int_clr: 1; + uint32_t dsr_chg_int_clr: 1; + uint32_t cts_chg_int_clr: 1; + uint32_t brk_det_int_clr: 1; + uint32_t rxfifo_tout_int_clr: 1; + uint32_t sw_xon_int_clr: 1; + uint32_t sw_xoff_int_clr: 1; + uint32_t glitch_det_int_clr: 1; + uint32_t tx_brk_done_int_clr: 1; + uint32_t tx_brk_idle_done_int_clr: 1; + uint32_t tx_done_int_clr: 1; + uint32_t rs485_parity_err_int_clr: 1; + uint32_t rs485_frm_err_int_clr: 1; + uint32_t rs485_clash_int_clr: 1; + uint32_t at_cmd_char_det_int_clr: 1; + uint32_t wakeup_int_clr: 1; + uint32_t reserved: 12; +} uart_int_clr_reg_t; + +typedef volatile struct { + uint32_t div_int: 12; + uint32_t reserved: 8; + uint32_t div_frag: 4; + uint32_t reserved1: 8; +} uart_clkdiv_reg_t; + +typedef volatile struct { + uint32_t glitch_filt: 8; + uint32_t glitch_filt_en: 1; + uint32_t reserved: 23; +} uart_rx_filt_reg_t; + +typedef volatile struct { + uint32_t parity: 1; + uint32_t parity_en: 1; + uint32_t bit_num: 2; + uint32_t stop_bit_num: 2; + uint32_t sw_rts: 1; + uint32_t sw_dtr: 1; + uint32_t txd_brk: 1; + uint32_t irda_dplx: 1; + uint32_t irda_tx_en: 1; + uint32_t irda_wctl: 1; + uint32_t irda_tx_inv: 1; + uint32_t irda_rx_inv: 1; + uint32_t loopback: 1; + uint32_t tx_flow_en: 1; + uint32_t irda_en: 1; + uint32_t rxfifo_rst: 1; + uint32_t txfifo_rst: 1; + uint32_t rxd_inv: 1; + uint32_t cts_inv: 1; + uint32_t dsr_inv: 1; + uint32_t txd_inv: 1; + uint32_t rts_inv: 1; + uint32_t dtr_inv: 1; + uint32_t clk_en: 1; + uint32_t err_wr_mask: 1; + uint32_t autobaud_en: 1; + uint32_t mem_clk_en: 1; + uint32_t reserved: 3; +} uart_conf0_reg_t; + +typedef volatile struct { + uint32_t rxfifo_full_thrhd: 9; + uint32_t txfifo_empty_thrhd: 9; + uint32_t dis_rx_dat_ovf: 1; + uint32_t rx_tout_flow_dis: 1; + uint32_t rx_flow_en: 1; + uint32_t rx_tout_en: 1; + uint32_t reserved: 10; +} uart_conf1_reg_t; + +typedef volatile struct { + uint32_t sclk_div_b: 6; + uint32_t sclk_div_a: 6; + uint32_t sclk_div_num: 8; + uint32_t sclk_sel: 2; + uint32_t sclk_en: 1; + uint32_t rst_core: 1; + uint32_t tx_sclk_en: 1; + uint32_t rx_sclk_en: 1; + uint32_t tx_rst_core: 1; + uint32_t rx_rst_core: 1; + uint32_t reserved: 4; +} uart_clk_conf_reg_t; + +typedef volatile struct { + uint32_t id :30; + uint32_t update_ctrl :1; + uint32_t reg_update :1; +} uart_id_reg_t; + +typedef volatile struct { + uint32_t timers_clk_en: 1; + uint32_t spi01_clk_en: 1; + uint32_t uart_clk_en: 1; + uint32_t reserved: 2; + uint32_t uart1_clk_en: 1; + uint32_t spi2_clk_en: 1; + uint32_t ext0_clk_en: 1; + uint32_t uhci0_clk_en: 1; + uint32_t rmt_clk_en: 1; + uint32_t reserved1: 1; + uint32_t ledc_clk_en: 1; + uint32_t reserved2: 1; + uint32_t timergroup_clk_en: 1; + uint32_t reserved3: 1; + uint32_t timergroup1_clk_en: 1; + uint32_t reserved4: 3; + uint32_t can_clk_en: 1; + uint32_t reserved5: 1; + uint32_t i2s1_clk_en: 1; + uint32_t reserved6: 1; + uint32_t usb_device_clk_en: 1; + uint32_t uart_mem_clk_en: 1; + uint32_t reserved7: 2; + uint32_t spi3_dma_clk_en: 1; + uint32_t apb_saradc_clk_en: 1; + uint32_t systimer_clk_en: 1; + uint32_t adc2_arb_clk_en: 1; + uint32_t reserved8: 1; +} system_perip_clk_en0_reg_t; + +typedef volatile struct { + uint32_t timers_rst: 1; + uint32_t spi01_rst: 1; + uint32_t uart_rst: 1; + uint32_t reserved: 2; + uint32_t uart1_rst: 1; + uint32_t spi2_rst: 1; + uint32_t ext0_rst: 1; + uint32_t uhci0_rst: 1; + uint32_t rmt_rst: 1; + uint32_t reserved1: 1; + uint32_t ledc_rst: 1; + uint32_t reserved2: 1; + uint32_t timergroup_rst: 1; + uint32_t reserved3: 1; + uint32_t timergroup1_rst: 1; + uint32_t reserved4: 3; + uint32_t can_rst: 1; + uint32_t reserved5: 1; + uint32_t i2s1_rst: 1; + uint32_t reserved6: 1; + uint32_t usb_device_rst: 1; + uint32_t uart_mem_rst: 1; + uint32_t reserved7: 2; + uint32_t spi3_dma_rst: 1; + uint32_t apb_saradc_rst: 1; + uint32_t systimer_rst: 1; + uint32_t adc2_arb_rst: 1; + uint32_t reserved8: 1; +} system_perip_rst_en0_reg_t; + + +#define UART_FIFO_REG(base_select) ((uart_fifo_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0000)) + +#define UART_INT_RAW(base_select) ((uart_int_raw_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0004)) + +#define UART_INT_ENA_REG(base_select) ((uart_int_ena_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x000C)) + +#define UART_INT_CLR_REG(base_select) ((uart_int_clr_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0010)) + +#define UART_CLKDIV_REG(base_select) ((uart_clkdiv_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0014)) + +#define UART_RX_FILT_REG(base_select) ((uart_rx_filt_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0018)) + +#define UART_CONF0_REG(base_select) ((uart_conf0_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0020)) + +#define UART_CONF1_REG(base_select) ((uart_conf1_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0024)) + +#define UART_CLK_CONF_REG(base_select) ((uart_clk_conf_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0078)) + +#define UART_ID_REG(base_select) ((uart_id_reg_t *)(C3_UART_CONTROLLER_SELECT((base_select)) + 0x0080)) + +#define SYSTEM_PERIP_CLK_EN0_REG ((system_perip_clk_en0_reg_t *)(C3_BASE_OFFSET_SYSTEM_REGISTERS+0x0010)) + +#define SYSTEM_PERIP_RST_EN0_REG ((system_perip_rst_en0_reg_t *)(C3_BASE_OFFSET_SYSTEM_REGISTERS+0x0018)) + +void config_uart(); +void init_uart(); +void enable_uart_transmitter(); + +#endif \ No newline at end of file diff --git a/src/simple-uart-transmit/main.c b/src/simple-uart-transmit/main.c new file mode 100644 index 0000000..1cdad6f --- /dev/null +++ b/src/simple-uart-transmit/main.c @@ -0,0 +1,14 @@ +// All rights reserved + +#include <mdk.h> +#include "esp32-c3-uart-interface.h" + +int main(void) { + wdt_disable(); + + init_uart(); + config_uart(); + enable_uart_transmitter(); + + return 0; +} \ No newline at end of file -- GitLab