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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
#ifndef H__USART_
#define H__USART_
#include <arch.h>
#include <stdint.h>
#include "common.h"
#include "rcc.h"
#include <assert.h>
#define USART1 (* (__IO usart_t*) USART1_BASE)
#define USART2 (* (__IO 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. */
union {
__IO uint32_t c_r1;
struct {
bits_t ue:1; /* UART enable */
bits_t uesm:1; /* UART enabled in stop mode. */
bits_t re:1; /* reciever enabled. */
bits_t te:1; /* transmitter enabled. */
bits_t idleie:1; /* Idle interrupt enabled. */
bits_t rxneie:1; /* RXNEIE RXNE interrupt enable. */
bits_t tcie:1;
bits_t txeie:1;
bits_t peie:1;
bits_t ps:1;
bits_t pce:1;
bits_t wake:1;
bits_t m0:1;
bits_t mme:1;
bits_t cmie:1;
bits_t over8:1;
bits_t dedt:4;
bits_t deat:4;
bits_t rtoie:1;
bits_t eobie:1;
bits_t m1:1;
bits_t reserved:3;
} PACKED c1_bf; /* c1_bf = c1 bit field */
}; /* USART Control Register 1. */
__IO uint32_t c_r2;
union {
__IO uint32_t c_r3;
struct {
bits_t eie:1; // Error interrupt enable.
bits_t iren:1; // IrDA mode enabled
bits_t irlp:1; // IrDA low power
bits_t hdsel:1; // Half duplex selection
bits_t nack:1; // Smartcard NACK enable
bits_t scen:1; // Smartocard mode enable
bits_t dmar:1; // DMA enable reciever
bits_t dmat:1; // DMA enable transmitter
bits_t rtse:1; // RTS enable
bits_t ctse:1; // CTS enable
bits_t ctsie:1; // CTS interrupt enable
bits_t onebit:1; // One sample bit method enable
bits_t ovrdis:1; // Overrun disable
bits_t ddre:1; // DMA Disable on reception error
bits_t dem:1; // Driver enable mode
bits_t dep:1; // Driver enable polarity selection
bits_t reserved0:1;
bits_t scarcnt:3; // Smartcard auto-retry count.
bits_t wus:2; // Wakeup from STOP mode interrept flag selection
bits_t wufie:1; // Wakeup from STOP mode interrup enable
bits_t ucesm:1; // USART clock enable in STOP mode.
bits_t tcbgtie:1; // Transmission complete before guard time interrupt
bits_t reserved1:7;
} PACKED c3_bf;
};
/* 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*/
union {
__IO uint32_t is_r; /* Interrupt service register. */
struct {
bits_t pe:1; // Parity error
bits_t fe:1; // Framing error
bits_t nf:1; // START bit noise detection flag.
bits_t ore:1; // Overrun error
bits_t dlie:1; // Idle line detected
bits_t rxne:1; // Read data register not empty
bits_t tc:1; // Transmission complete
bits_t txe:1; // Transmit data register empty
bits_t lbdf:1; // LIN break detection flag
bits_t ctsif:1; // CTS interrupt flag
bits_t cts:1; // CTS flag.
bits_t rtof:1; // Receiever timeout
bits_t eobf:1; // End of block flag
bits_t reserved0:1;
bits_t abre:1; // Auto baud rate error
bits_t abrf:1; // Auto baud rate flag
bits_t busy:1; // Busy flag
bits_t cmf:1; // Character match flag
bits_t sbkf:1; // send break flag
bits_t rwu:1; // receiver wakeup frlom mute mode.
bits_t wuf:1; // Wakeup from stop mode flag
bits_t teack:1; // Transmit enable acknowledge flag.
bits_t reack:1; // Receieve enable acknowledge flag.
bits_t reserved1:2;
bits_t tcbgt:1; // Transmission completer before guard time completion.
bits_t reserved2:6;
} PACKED is_bf; /* Interrupt servite bit field. */
};
union {
__IO uint32_t ic_r;
struct {
bits_t pecf:1; // Parity error clear flag
bits_t fecf:1; // Framing error clear flag
bits_t ncf:1; // Noise detected clear flag
bits_t orecf:1; // Overrun error clear flag
bits_t idlecf:1; // Idle line detected clear flag
bits_t reserved0:1;
bits_t tccf:1; // Transmission complete clear flag
bits_t tcbgtcf:1; // Transmission completed before guard time clear flag
bits_t lbdcf:1; // LIN break detection clear flag
bits_t ctscf:1; // CTS clear flag
bits_t reserved1:1;
bits_t rtocf:1; // Receiver timeout clear flag
bits_t eobcf:1; // End of block clear flag
bits_t reserved2:4;
bits_t cmcf:1; // Character match clear flag
bits_t reserved3:2; // Character match clear flag
bits_t wucf:1; // Wakeup from Stop mode clear flag.
bits_t reserved4:11;
} PACKED ic_bf;
};
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, ...);
#endif /* H__USART_ */
|