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
|
#ifndef H__USART_
#define H__USART_
#include "common.h"
#include "rcc.h"
#include <stdint.h>
/*
* Possibel 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 conttrol register 1. */
union USART_CR1 {
__IO uint32_t r;
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:5;
bits_t deat:5;
bits_t rtoie:1;
bits_t eobie:1;
bits_t m1:1;
bits_t reserved:3;
} PACKED;
} __IO c1;
/* USART control register 2. */
union USART_CR2 {
__IO uint32_t r;
struct {
RESERVED(4);
bits_t addm7:1;
bits_t lbdl:1;
bits_t lbdie:1;
RESERVED(1);
bits_t lbcl:1;
bits_t cpha:1;
bits_t cpol:1;
bits_t clken:1;
bits_t stop:2;
bits_t linen:1;
bits_t swap:1;
bits_t rxinv:1;
bits_t txinv:1;
bits_t datainv:1;
bits_t msbfirst:1;
bits_t abren:1;
bits_t abrmod:2;
bits_t rtoen:1;
bits_t add:8;
} PACKED;
} __IO c2;
union USART_CR3 {
__IO uint32_t r;
struct {
bits_t eie:1;
bits_t iren:1;
bits_t irlp:1;
bits_t hdsel:1;
bits_t nack:1;
bits_t scen:1;
bits_t dmar:1;
bits_t dmat:1;
bits_t rtse:1;
bits_t ctse:1;
bits_t ctsie:1;
bits_t onebit:1;
bits_t ovrdis:1;
bits_t ddre:1;
bits_t dem:1;
bits_t dep:1;
RESERVED(1);
bits_t scarcnt:3;
bits_t wus:2;
bits_t wufie:1;
bits_t ucesm:1;
bits_t tcbgtie:1;
RESERVED(7);
} PACKED;
} __IO c3;
/* USART baud rate register. */
union USART_BRR {
__IO uint32_t r;
struct {
uint16_t v;
RESERVED(16);
} PACKED;
/* Structure to use when OVER8 is set in the control register
* USART_C1. */
struct {
bits_t low:3;
RESERVED(1);
bits_t high:12;
RESERVED(16);
} PACKED over8;
} __IO br;
uint32_t gtp_r;
uint32_t rto_r;
uint32_t rq_r;
uint32_t is_r;
uint32_t ic_r;
uint32_t rd_r;
uint32_t td_r;
} usart_t;
#define USART1 (* (__IO usart_t*) 0x40013800)
#define USART2 (* (__IO usart_t*) 0x40004400)
typedef enum {
OVERSAMPLE_8,
OVERSAMPLE_16
} oversampling_mode_t;
static inline void usart_set_divisor(
__IO usart_t* usart,
uint16_t usartdiv)
{
if (usart->c1.r & (1 << 15)) {
/* OVER8 is set. */
usart->br.over8.high = (usartdiv & ~7);
usart->br.over8.low = ((usartdiv & 7) >> 1);
} else {
/* OVER8 is not set. */
usart->br.v = usartdiv;
}
}
static inline void usart_set_oversampling_mode(
__IO usart_t* usart,
oversampling_mode_t mode)
{
usart->c1.over8 = mode == OVERSAMPLE_8;
}
typedef enum {
USART_PARITY_DISABLED = 0,
USART_PARITY_ODD = 1,
USART_PARITY_EVEN = 2,
} 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);
/*
* Send a byte on the usart, This command blocks until the data
* is fully sent.
*/
void usart_transmit_byte(__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(
__IO usart_t* usart, const uint8_t* bytes, uint32_t n);
void usart_transmit_str(__IO usart_t* usart, const char* str);
void usart_printf(__IO usart_t* usart, const char* fmt, ...);
/* Returns non-zero if usart2 is enabled. */
int is_usart2_enabled();
/* Enable the second USART. */
int enable_usart2(uint32_t baud);
#endif /* H__USART_ */
|