-
Notifications
You must be signed in to change notification settings - Fork 1
/
Uart.hpp
241 lines (172 loc) · 5 KB
/
Uart.hpp
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#pragma once
#include <cstdint>
#include "Pins.hpp"
#include "Reg.hpp"
#include "Sprintf.hpp"
#include "Osc.hpp"
//UART 1/2/3
struct Uart : private Reg, private Sprintf<> {
//instantiate Uart with uart number, optionally baud rate-
//(pins setup manually)
//(use this for UART1- has fixed pins, so cannot use pps)
// UARTn, [, baud ]
// Uart u(UART1); //tx+rx, default baud 115200
// Uart u(UART1TX, 230400); //tx only, 230400 baud
//or uart number and tx/rx pin info (tx or rx only), optionally baud rate-
// UARTnTX|RX, tx|rx pin [, baud ]
// Uart u(UART2TX, Pins::A0); //tx, 115200 default baud
// Uart u(UART2TX, Pins::A0, 19200); //tx, 19200 baud
// Uart u(UART2RX, Pins::A0, 230400); //rx, 230400 baud
//or uart number and both tx/rx pins info, optionally set baud rate
// UARTn, tx pin, rx pin [, baud ]
// Uart u(UART2, Pins::A0, Pins::B0);
// Uart u(UART2, Pins::A0, Pins::B0, 230400);
enum
UARTX {
UART1 = 0, UART4 = 1, UART3 = 2,
UART6 = 3, UART2 = 4, UART5 = 5,
};
Uart (UARTX, uint32_t = 0);
//==== UxMODE ====
//uart on/off
auto
on (bool) -> void;
//uart stop in idle
auto
stop_idle (bool) -> void;
//irda on/off
auto
irda (bool) -> void;
enum
RTSMODE { FLOW, SIMPLEX };
//rts mode
auto
rts_mode (RTSMODE) -> void;
enum
UEN {
BCLK, CTS_RTS, RTS, TX_RX
};
//enable uart pins
auto
uen (UEN) -> void;
//wake on start bit
auto
wake (bool) -> void;
//loopback on/off
auto
loopback (bool) -> void;
//autobaud on/off
auto
autobaud (bool) -> void;
enum
RXPOL { IDLEHIGH, IDLELOW };
//rx polarity
auto
rx_pol (RXPOL) -> void;
enum
MODESEL {
MODE8N1 = 0, MODE8E1 = 2, MODE8O1 = 4, MODE9N1 = 6,
MODE8N2 = 1, MODE8E2 = 3, MODE8O2 = 5, MODE9N2 = 7
};
//parity, data, stop
auto
mode (MODESEL) -> void;
//==== UxSTA ====
//address mask
auto
rx_mask (bool) -> void;
//address
auto
rx_addr (uint8_t) -> void;
enum
UTXISEL : uint8_t { TFREE, TDONE, TEMPTY };
//tx irq select
auto
tx_irq (UTXISEL) -> void;
//tx polarity
auto
tx_pol (RXPOL) -> void;
//rx enable
auto
rx_on (bool) -> void;
//send break
auto
tx_break () -> void;
//tx enable
auto
tx_on (bool) -> void;
//tx buf is full?
auto
tx_full () -> bool;
//all tx bits are out
auto
tx_done () -> bool;
enum
URXISEL : uint8_t { RANY, RHALF, RMOST };
//rx irq select
auto
rx_irq (URXISEL) -> void;
//rx addr detect on
auto
rx_addren (bool) -> void;
//rx busy? (not idle)
auto
rx_busy () -> bool;
//rx parity, framing, or overrun err?
//return low byte which will contain these masked flags
auto
rx_err () -> uint8_t;
//clear rx overrun err
auto
rx_errclr () -> void;
//rx is empty?
auto
rx_empty () -> bool;
//==== UxTXREG ====
//put in tx register
auto
write (uint16_t) -> void;
//==== UxRXREG ====
//get from rx register
auto
read () -> uint16_t;
//==== UxBRG ====
//set baud to value
auto
baud_set (uint32_t) -> void;
//recalc baud, or set to default
auto
baud_set () -> void;
//get uart clock freq
auto
baud_clk () -> uint32_t;
//misc
//blocking functions
auto
putc (const char) -> void;
auto
puts (const char*) -> void;
auto
printf (char const *fmt, ...) -> void;
auto
printf (char const *fmt, va_list) -> void;
// -1 = none
auto
getc () -> int;
private:
//baud_set will take care of-
//if normal speed error >2%, then hispeed
//true=4x=hispeed false=16x
auto
hispeed (bool) -> void;
volatile uint32_t* m_uartx_base;
volatile uint32_t& m_uartx_tx; //use reference
volatile uint32_t& m_uartx_rx; //use reference
uint32_t m_uartx_baud; //desired baud
};
//=============================================================================
inline auto Uart::
baud_clk () -> uint32_t
{
return Osc::pbclk(); //pb/sys are the same
}