1use core::fmt;
2use core::marker::PhantomData;
3use core::ptr;
4
5use crate::gpio::gpioa::{PA10, PA2, PA3, PA9};
6use crate::gpio::gpiob::{PB10, PB11};
7use crate::gpio::{AltMode, Floating, Input};
8use crate::rcc::Rcc;
9use crate::stm32::{USART1, USART2, USART3};
10use hal;
11use hal::prelude::*;
12use nb::block;
13
14#[derive(Debug)]
16pub enum Error {
17 Framing,
19 Noise,
21 Overrun,
23 Parity,
25 #[doc(hidden)]
26 _Extensible,
27}
28
29pub enum Event {
31 Rxne,
33 Txe,
35 Idle,
37}
38
39use crate::time::Bps;
40use crate::time::U32Ext;
41
42pub enum WordLength {
43 DataBits8,
44 DataBits9,
45}
46
47pub enum Parity {
48 ParityNone,
49 ParityEven,
50 ParityOdd,
51}
52
53pub enum StopBits {
54 #[doc = "1 stop bit"]
55 STOP1,
56 #[doc = "0.5 stop bits"]
57 STOP0P5,
58 #[doc = "2 stop bits"]
59 STOP2,
60 #[doc = "1.5 stop bits"]
61 STOP1P5,
62}
63
64pub struct Config {
65 pub baudrate: Bps,
66 pub wordlength: WordLength,
67 pub parity: Parity,
68 pub stopbits: StopBits,
69}
70
71impl Config {
72 pub fn baudrate(mut self, baudrate: Bps) -> Self {
73 self.baudrate = baudrate;
74 self
75 }
76
77 pub fn parity_none(mut self) -> Self {
78 self.parity = Parity::ParityNone;
79 self
80 }
81
82 pub fn parity_even(mut self) -> Self {
83 self.parity = Parity::ParityEven;
84 self
85 }
86
87 pub fn parity_odd(mut self) -> Self {
88 self.parity = Parity::ParityOdd;
89 self
90 }
91
92 pub fn wordlength_8(mut self) -> Self {
93 self.wordlength = WordLength::DataBits8;
94 self
95 }
96
97 pub fn wordlength_9(mut self) -> Self {
98 self.wordlength = WordLength::DataBits9;
99 self
100 }
101
102 pub fn stopbits(mut self, stopbits: StopBits) -> Self {
103 self.stopbits = stopbits;
104 self
105 }
106}
107
108#[derive(Debug)]
109pub struct InvalidConfig;
110
111impl Default for Config {
112 fn default() -> Config {
113 let baudrate = 19_200_u32.bps();
114 Config {
115 baudrate,
116 wordlength: WordLength::DataBits8,
117 parity: Parity::ParityNone,
118 stopbits: StopBits::STOP1,
119 }
120 }
121}
122
123pub trait Pins<USART> {
124 fn setup(&self);
125}
126
127impl Pins<USART1> for (PA9<Input<Floating>>, PA10<Input<Floating>>) {
128 fn setup(&self) {
129 self.0.set_alt_mode(AltMode::USART1_3);
130 self.1.set_alt_mode(AltMode::USART1_3);
131 }
132}
133
134impl Pins<USART2> for (PA2<Input<Floating>>, PA3<Input<Floating>>) {
135 fn setup(&self) {
136 self.0.set_alt_mode(AltMode::USART1_3);
137 self.1.set_alt_mode(AltMode::USART1_3);
138 }
139}
140
141impl Pins<USART3> for (PB10<Input<Floating>>, PB11<Input<Floating>>) {
142 fn setup(&self) {
143 self.0.set_alt_mode(AltMode::USART1_3);
144 self.1.set_alt_mode(AltMode::USART1_3);
145 }
146}
147
148pub struct Serial<USART> {
150 usart: USART,
151 rx: Rx<USART>,
152 tx: Tx<USART>,
153}
154
155pub struct Rx<USART> {
157 _usart: PhantomData<USART>,
158}
159
160pub struct Tx<USART> {
162 _usart: PhantomData<USART>,
163}
164
165pub trait SerialExt<USART, PINS> {
166 fn usart(
167 self,
168 pins: PINS,
169 config: Config,
170 rcc: &mut Rcc,
171 ) -> Result<Serial<USART>, InvalidConfig>;
172}
173
174macro_rules! usart {
175 ($(
176 $USARTX:ident: ($usartX:ident, $apbXenr:ident, $usartXen:ident, $pclkX:ident, $SerialExt:ident),
177 )+) => {
178 $(
179 impl<PINS> SerialExt<$USARTX, PINS> for $USARTX
180 where
181 PINS: Pins<$USARTX>,
182 {
183 fn usart(self, pins: PINS, config: Config, rcc: &mut Rcc) -> Result<Serial<$USARTX>, InvalidConfig> {
184 Serial::$usartX(self, pins, config, rcc)
185 }
186 }
187
188 impl Serial<$USARTX> {
189 pub fn $usartX<PINS>(
190 usart: $USARTX,
191 pins: PINS,
192 config: Config,
193 rcc: &mut Rcc,
194 ) -> Result<Self, InvalidConfig>
195 where
196 PINS: Pins<$USARTX>,
197 {
198 pins.setup();
199
200 rcc.rb.$apbXenr.modify(|_, w| w.$usartXen().set_bit());
202
203 let div = (rcc.clocks.$pclkX().0 * 25) / (4 * config.baudrate.0);
205 let mantissa = div / 100;
206 let fraction = ((div - mantissa * 100) * 16 + 50) / 100;
207 usart
208 .brr
209 .write(|w| unsafe { w.bits(mantissa << 4 | fraction) });
210
211 usart.cr2.reset();
213 usart.cr3.reset();
214
215 usart.cr1.write(|w| {
218 w.ue()
219 .set_bit()
220 .te()
221 .set_bit()
222 .re()
223 .set_bit()
224 .m()
225 .bit(match config.wordlength {
226 WordLength::DataBits8 => false,
227 WordLength::DataBits9 => true,
228 }).pce()
229 .bit(match config.parity {
230 Parity::ParityNone => false,
231 _ => true,
232 }).ps()
233 .bit(match config.parity {
234 Parity::ParityOdd => true,
235 _ => false,
236 })
237 });
238
239 usart.cr2.write(|w| unsafe {
240 w.stop().bits(match config.stopbits {
241 StopBits::STOP1 => 0b00,
242 StopBits::STOP0P5 => 0b01,
243 StopBits::STOP2 => 0b10,
244 StopBits::STOP1P5 => 0b11,
245 })
246 });
247 Ok(Serial {
248 usart,
249 tx: Tx { _usart: PhantomData },
250 rx: Rx { _usart: PhantomData },
251 })
252 }
253
254 pub fn listen(&mut self, event: Event) {
256 match event {
257 Event::Rxne => {
258 self.usart.cr1.modify(|_, w| w.rxneie().set_bit())
259 },
260 Event::Txe => {
261 self.usart.cr1.modify(|_, w| w.txeie().set_bit())
262 },
263 Event::Idle => {
264 self.usart.cr1.modify(|_, w| w.idleie().set_bit())
265 },
266 }
267 }
268
269 pub fn unlisten(&mut self, event: Event) {
271 match event {
272 Event::Rxne => {
273 self.usart.cr1.modify(|_, w| w.rxneie().clear_bit())
274 },
275 Event::Txe => {
276 self.usart.cr1.modify(|_, w| w.txeie().clear_bit())
277 },
278 Event::Idle => {
279 self.usart.cr1.modify(|_, w| w.idleie().clear_bit())
280 },
281 }
282 }
283
284 pub fn clear_irq(&mut self, event: Event) {
286 if let Event::Rxne = event {
287 self.usart.sr.modify(|_, w| w.rxne().clear_bit())
288 }
289 }
290
291 pub fn split(self) -> (Tx<$USARTX>, Rx<$USARTX>) {
292 (self.tx, self.rx)
293 }
294
295 pub fn release(self) -> $USARTX {
296 self.usart
297 }
298 }
299
300 impl hal::serial::Read<u8> for Serial<$USARTX> {
301 type Error = Error;
302
303 fn read(&mut self) -> nb::Result<u8, Error> {
304 self.rx.read()
305 }
306 }
307
308 impl hal::serial::Write<u8> for Serial<$USARTX> {
309 type Error = Error;
310
311 fn flush(&mut self) -> nb::Result<(), Self::Error> {
312 self.tx.flush()
313 }
314
315 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
316 self.tx.write(byte)
317 }
318 }
319
320 impl hal::serial::Read<u8> for Rx<$USARTX> {
321 type Error = Error;
322
323 fn read(&mut self) -> nb::Result<u8, Error> {
324 let sr = unsafe { (*$USARTX::ptr()).sr.read() };
326
327 Err(if sr.pe().bit_is_set() {
328 nb::Error::Other(Error::Parity)
329 } else if sr.fe().bit_is_set() {
330 nb::Error::Other(Error::Framing)
331 } else if sr.nf().bit_is_set() {
332 nb::Error::Other(Error::Noise)
333 } else if sr.ore().bit_is_set() {
334 nb::Error::Other(Error::Overrun)
335 } else if sr.rxne().bit_is_set() {
336 return Ok(unsafe { ptr::read_volatile(&(*$USARTX::ptr()).dr as *const _ as *const _) });
338 } else {
339 nb::Error::WouldBlock
340 })
341 }
342 }
343
344 impl hal::serial::Write<u8> for Tx<$USARTX> {
345 type Error = Error;
346
347 fn flush(&mut self) -> nb::Result<(), Self::Error> {
348 let sr = unsafe { (*$USARTX::ptr()).sr.read() };
350
351 if sr.tc().bit_is_set() {
352 Ok(())
353 } else {
354 Err(nb::Error::WouldBlock)
355 }
356 }
357
358 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
359 let sr = unsafe { (*$USARTX::ptr()).sr.read() };
361
362 if sr.txe().bit_is_set() {
363 unsafe { ptr::write_volatile(&(*$USARTX::ptr()).dr as *const _ as *mut _, byte) }
366 Ok(())
367 } else {
368 Err(nb::Error::WouldBlock)
369 }
370 }
371 }
372 )+
373 }
374}
375
376usart! {
377 USART1: (usart1, apb2enr, usart1en, apb2_clk, Serial1Ext),
378 USART2: (usart2, apb1enr, usart2en, apb1_clk, Serial2Ext),
379 USART3: (usart3, apb1enr, usart3en, apb1_clk, Serial3Ext),
380}
381
382impl<USART> fmt::Write for Serial<USART>
383where
384 Serial<USART>: hal::serial::Write<u8>,
385{
386 fn write_str(&mut self, s: &str) -> fmt::Result {
387 let _ = s
388 .as_bytes()
389 .into_iter()
390 .map(|c| block!(self.write(*c)))
391 .last();
392 Ok(())
393 }
394}
395
396impl<USART> fmt::Write for Tx<USART>
397where
398 Tx<USART>: hal::serial::Write<u8>,
399{
400 fn write_str(&mut self, s: &str) -> fmt::Result {
401 let _ = s
402 .as_bytes()
403 .into_iter()
404 .map(|c| block!(self.write(*c)))
405 .last();
406 Ok(())
407 }
408}