Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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;
}