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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
#ifndef H__USART_
#define H__USART_
#include <arch.h>
#include <stdint.h>
#include <stdarg.h>
#include "kern/common.h"
#include "arch/stm32l4xxx/peripherals/rcc.h"
#include <assert.h>
#define USART1 (* (usart_t*) USART1_BASE)
#define USART2 (* (usart_t*) USART2_BASE)
/*
* Possible USART clock sources.
*/
typedef enum {
USART_CLK_SRC_PLK = 0, /* Clock derived from the SysClk. */
USART_CLK_SRC_SYSCLK = 1, /* System clock. */
USART_CLK_SRC_HSI16 = 2, /* 16MHz oscillator. */
USART_CLK_SRC_LSE = 3 /* Low power 32kHz clock. */
} usart_clk_src_t;
typedef struct {
/* USART configuration registers 0x04 - 0x0c. */
#define usart_ue (1 << 0) /* UART enable */
#define usart_uesm (1 << 1) /* UART enabled in stop mode. */
#define usart_re (1 << 2) /* reciever enabled. */
#define usart_te (1 << 3) /* transmitter enabled. */
#define usart_idleie (1 << 4) /* Idle interrupt enabled. */
#define usart_rxneie (1 << 5) /* RXNEIE RXNE interrupt enable. */
#define usart_tcie (1 << 6)
#define usart_txeie (1 << 7)
#define usart_peie (1 << 8)
#define usart_ps (1 << 9)
#define usart_pce (1 << 10)
#define usart_wake (1 << 11)
#define usart_m0 (1 << 12)
#define usart_mme (1 << 13)
#define usart_cmie (1 << 14)
#define usart_over8 (1 << 15)
#define usart_dedt (0xF << 16)
#define usart_deat (0xF << 21)
#define usart_rtoie (1 << 26)
#define usart_eobie (1 << 27)
#define usart_m1 (1 << 28)
__IO uint32_t c_r1;
__IO uint32_t c_r2;
#define usart_eie (1 << 0) // Error interrupt enable.
#define usart_iren (1 << 1) // IrDA mode enabled
#define usart_irlp (1 << 2) // IrDA low power
#define usart_hdsel (1 << 3) // Half duplex selection
#define usart_nack (1 << 4) // Smartcard NACK enable
#define usart_scen (1 << 5) // Smartocard mode enable
#define usart_dmar (1 << 6) // DMA enable reciever
#define usart_dmat (1 << 7) // DMA enable transmitter
#define usart_rtse (1 << 8) // RTS enable
#define usart_ctse (1 << 9) // CTS enable
#define usart_ctsie (1 << 10) // CTS interrupt enable
#define usart_onebit (1 << 11) // One sample bit method enable
#define usart_ovrdis (1 << 12) // Overrun disable
#define usart_ddre (1 << 13) // DMA Disable on reception error
#define usart_dem (1 << 14) // Driver enable mode
#define usart_dep (1 << 15) // Driver enable polarity selection
#define usart_scarcnt0 (1 << 17)
#define usart_scarcnt1 (1 << 18)
#define usart_scarcnt2 (1 << 19)
#define usart_wus0 (1 << 20) // Wakeup from STOP mode interrept flag selection
#define usart_wus1 (1 << 21) // Wakeup from STOP mode interrept flag selection
#define usart_wufie (1 << 22) // Wakeup from STOP mode interrup enable
#define usart_ucesm (1 << 23) // USART clock enable in STOP mode.
#define usart_tcbgtie (1 << 24) // Transmission complete before guard time interrupt
__IO uint32_t c_r3;
/* USART baud rate register. */
uint32_t br_r;
uint32_t gtp_r;
uint32_t rto_r;
uint32_t rq_r;
/* USART ISR register. Offset = 0x1c*/
#define usart_pe (1 << 0) // Parity error
#define usart_fe (1 << 1) // Framing error
#define usart_nf (1 << 2) // START bit noise detection flag.
#define usart_ore (1 << 3) // Overrun error
#define usart_dlie (1 << 4) // Idle line detected
#define usart_rxne (1 << 5) // Read data register not empty
#define usart_tc (1 << 6) // Transmission complete
#define usart_txe (1 << 7) // Transmit data register empty
#define usart_lbdf (1 << 8) // LIN break detection flag
#define usart_ctsif (1 << 9) // CTS interrupt flag
#define usart_cts (1 << 10) // CTS flag.
#define usart_rtof (1 << 11) // Receiever timeout
#define usart_eobf (1 << 12) // End of block flag
#define usart_abre (1 << 14) // Auto baud rate error
#define usart_abrf (1 << 15) // Auto baud rate flag
#define usart_busy (1 << 16) // Busy flag
#define usart_cmf (1 << 17) // Character match flag
#define usart_sbkf (1 << 18) // send break flag
#define usart_rwu (1 << 19) // receiver wakeup frlom mute mode.
#define usart_wuf (1 << 20) // Wakeup from stop mode flag
#define usart_teack (1 << 21) // Transmit enable acknowledge flag.
#define usart_reack (1 << 22) // Receieve enable acknowledge flag.
#define usart_tcbgt (1 << 25) // Transmission completer before guard time completion.
__IO uint32_t is_r; /* Interrupt service register. */
#define usart_pecf (1 << 0) // Parity error clear flag
#define usart_fecf (1 << 1) // Framing error clear flag
#define usart_ncf (1 << 2) // Noise detected clear flag
#define usart_orecf (1 << 3) // Overrun error clear flag
#define usart_idlecf (1 << 4) // Idle line detected clear flag
#define usart_tccf (1 << 6) // Transmission complete clear flag
#define usart_tcbgtcf (1 << 7) // Transmission completed before guard time clear flag
#define usart_lbdcf (1 << 8) // LIN break detection clear flag
#define usart_ctscf (1 << 9) // CTS clear flag
#define usart_rtocf (1 << 11) // Receiver timeout clear flag
#define usart_eobcf (1 << 12) // End of block clear flag
#define usart_cmcf (1 << 17) // Character match clear flag
#define usart_wucf (1 << 20) // Wakeup from Stop mode clear flag.
__IO uint32_t ic_r;
uint32_t rd_r;
uint32_t td_r;
} usart_t;
static_assert(offsetof(usart_t, ic_r) == 0x20, "Offset assertion failed.");
static_assert(offsetof(usart_t, rd_r) == 0x24, "Offset assertion failed.");
typedef enum {
OVERSAMPLE_8,
OVERSAMPLE_16
} oversampling_mode_t;
static inline void usart_set_divisor(
__IO usart_t* usart,
uint32_t usartdiv)
{
if (usart->c_r1 & (1 << 15)) {
/* OVER8 is set. */
usart->br_r =
(usartdiv & ~7) |
((usartdiv & 7) >> 1);
} else {
/* OVER8 is not set. */
usart->br_r = usartdiv;
}
}
static inline void usart_set_oversampling_mode(
__IO usart_t* usart,
oversampling_mode_t mode)
{
if (mode == OVERSAMPLE_8) {
usart->c_r1 |= 1 << 15;
} else {
usart->c_r1 &= ~(1 << 15);
}
}
typedef enum {
USART_PARITY_DISABLED = 0,
USART_PARITY_EVEN = 2 << 9,
USART_PARITY_ODD = 3 << 9,
} usart_parity_t;
typedef enum {
USART_ENABLE_TX = 0x02,
USART_ENABLE_RX = 0x01,
USART_ENABLE_DISABLED = 0x00,
} usart_enable_t;
void usart_set_parity(__IO usart_t* usart, usart_parity_t parity);
void usart_set_enabled(__IO usart_t* usart, usart_enable_t enabled);
void usart_enable_dma(__IO usart_t* usart, usart_enable_t enabled);
/*
* Send a byte on the usart, This command blocks until the data
* is fully sent.
*/
void usart_transmit_byte_sync(__IO usart_t* usart, uint8_t byte);
void set_usart1_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src);
void set_usart1_clock_enabled(__IO rcc_t* rcc, bool enable);
void set_usart2_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src);
void set_usart2_clock_enabled(__IO rcc_t* rcc, bool enable);
void usart_transmit_bytes_sync(
__IO usart_t* usart, const uint8_t* bytes, uint32_t n);
void usart_transmit_str_sync(__IO usart_t* usart, const char* str);
void usart_printf(__IO usart_t* usart, const char* fmt, ...);
void usart_vprintf(__IO usart_t* usart, const char* fmt, va_list l);
#endif /* H__USART_ */
|