1use core::fmt;
3use core::marker::PhantomData;
4use core::ptr;
5
6use embedded_hal::serial;
7use embedded_hal::prelude::*;
8use nb::block;
9
10use crate::hal::serial::Write;
11
12use crate::stm32::{RCC, UART4, UART5, USART1, USART2, USART3, USART6, UART7, UART8};
13
14use crate::gpio::gpioa::{PA0, PA1, PA2, PA3, PA8, PA9, PA10, PA11, PA12, PA15};
15use crate::gpio::gpiob::{PB3, PB4, PB10, PB11, PB12, PB13, PB5, PB6, PB7, PB8, PB9};
16use crate::gpio::gpioc::{PC5, PC10, PC11, PC12, PC6, PC7};
17use crate::gpio::gpiod::{PD0, PD1, PD2, PD5, PD6, PD8, PD9, PD10};
18use crate::gpio::gpioe::{PE0, PE1, PE7, PE8};
19use crate::gpio::gpiof::{PF6, PF7, PF8, PF9};
20use crate::gpio::gpiog::{PG0, PG1, PG11, PG12, PG14, PG9};
21use crate::gpio::gpioh::{PH13, PH14};
22use crate::gpio::{Alternate, AF7, AF8, AF11};
23use crate::rcc::Clocks;
24use crate::time::Bps;
25
26#[derive(Debug)]
28pub enum Error {
29 Framing,
31 Noise,
33 Overrun,
35 Parity,
37 #[doc(hidden)]
38 _Extensible,
39}
40
41pub enum Event {
43 Rxne,
45 Txe,
47 Idle,
49}
50
51pub mod config {
52 use crate::time::Bps;
53 use crate::time::U32Ext;
54
55 pub enum WordLength {
56 DataBits8,
57 DataBits9,
58 }
59
60 pub enum Parity {
61 ParityNone,
62 ParityEven,
63 ParityOdd,
64 }
65
66 pub enum StopBits {
67 #[doc = "1 stop bit"]
68 STOP1,
69 #[doc = "0.5 stop bits"]
70 STOP0P5,
71 #[doc = "2 stop bits"]
72 STOP2,
73 #[doc = "1.5 stop bits"]
74 STOP1P5,
75 }
76
77 pub struct Config {
78 pub baudrate: Bps,
79 pub wordlength: WordLength,
80 pub parity: Parity,
81 pub stopbits: StopBits,
82 }
83
84 impl Config {
85 pub fn baudrate(mut self, baudrate: Bps) -> Self {
86 self.baudrate = baudrate;
87 self
88 }
89
90 pub fn parity_none(mut self) -> Self {
91 self.parity = Parity::ParityNone;
92 self
93 }
94
95 pub fn parity_even(mut self) -> Self {
96 self.parity = Parity::ParityEven;
97 self
98 }
99
100 pub fn parity_odd(mut self) -> Self {
101 self.parity = Parity::ParityOdd;
102 self
103 }
104
105 pub fn wordlength_8(mut self) -> Self {
106 self.wordlength = WordLength::DataBits8;
107 self
108 }
109
110 pub fn wordlength_9(mut self) -> Self {
111 self.wordlength = WordLength::DataBits9;
112 self
113 }
114
115 pub fn stopbits(mut self, stopbits: StopBits) -> Self {
116 self.stopbits = stopbits;
117 self
118 }
119 }
120
121 #[derive(Debug)]
122 pub struct InvalidConfig;
123
124 impl Default for Config {
125 fn default() -> Config {
126 let baudrate = 19_200_u32.bps();
127 Config {
128 baudrate,
129 wordlength: WordLength::DataBits8,
130 parity: Parity::ParityNone,
131 stopbits: StopBits::STOP1,
132 }
133 }
134 }
135}
136
137pub trait Pins<USART> {}
138pub trait PinTx<USART> {}
139pub trait PinRx<USART> {}
140
141impl<USART, TX, RX> Pins<USART> for (TX, RX)
142where
143 TX: PinTx<USART>,
144 RX: PinRx<USART>,
145{}
146
147pub struct NoTx;
149pub struct NoRx;
151
152impl PinTx<USART1> for NoTx {}
153impl PinRx<USART1> for NoRx {}
154
155impl PinTx<USART1> for PA9<Alternate<AF7>> {}
156impl PinRx<USART1> for PA10<Alternate<AF7>> {}
157impl PinTx<USART1> for PA15<Alternate<AF7>> {}
158impl PinRx<USART1> for PB3<Alternate<AF7>> {}
159impl PinTx<USART1> for PB6<Alternate<AF7>> {}
160impl PinRx<USART1> for PB7<Alternate<AF7>> {}
161
162impl PinTx<USART2> for NoTx {}
163impl PinRx<USART2> for NoRx {}
164
165impl PinTx<USART2> for PA2<Alternate<AF7>> {}
166impl PinRx<USART2> for PA3<Alternate<AF7>> {}
167impl PinTx<USART2> for PD5<Alternate<AF7>> {}
168impl PinRx<USART2> for PD6<Alternate<AF7>> {}
169
170impl PinTx<USART3> for NoTx {}
171impl PinRx<USART3> for NoRx {}
172
173impl PinTx<USART3> for PB10<Alternate<AF7>> {}
174impl PinRx<USART3> for PB11<Alternate<AF7>> {}
175impl PinRx<USART3> for PC5<Alternate<AF7>> {}
176impl PinTx<USART3> for PC10<Alternate<AF7>> {}
177impl PinRx<USART3> for PC11<Alternate<AF7>> {}
178impl PinTx<USART3> for PD8<Alternate<AF7>> {}
179impl PinRx<USART3> for PD9<Alternate<AF7>> {}
180
181impl PinTx<UART4> for NoTx {}
182impl PinRx<UART4> for NoRx {}
183
184impl PinTx<UART4> for PA0<Alternate<AF8>> {}
185impl PinRx<UART4> for PA1<Alternate<AF8>> {}
186impl PinTx<UART4> for PA12<Alternate<AF11>> {}
187impl PinRx<UART4> for PA11<Alternate<AF11>> {}
188impl PinTx<UART4> for PC10<Alternate<AF8>> {}
189impl PinRx<UART4> for PC11<Alternate<AF8>> {}
190impl PinTx<UART4> for PD1<Alternate<AF11>> {}
191impl PinRx<UART4> for PD0<Alternate<AF11>> {}
192impl PinTx<UART4> for PD10<Alternate<AF8>> {}
193
194impl PinTx<UART5> for NoTx {}
195impl PinRx<UART5> for NoRx {}
196
197impl PinTx<UART5> for PB6<Alternate<AF11>> {}
198impl PinRx<UART5> for PB5<Alternate<AF11>> {}
199impl PinTx<UART5> for PB9<Alternate<AF11>> {}
200impl PinRx<UART5> for PB8<Alternate<AF11>> {}
201impl PinTx<UART5> for PB13<Alternate<AF11>> {}
202impl PinRx<UART5> for PB12<Alternate<AF11>> {}
203impl PinTx<UART5> for PC12<Alternate<AF8>> {}
204impl PinRx<UART5> for PD2<Alternate<AF8>> {}
205impl PinTx<UART5> for PE8<Alternate<AF8>> {}
206impl PinRx<UART5> for PE7<Alternate<AF8>> {}
207
208impl PinTx<USART6> for NoTx {}
209impl PinRx<USART6> for NoRx {}
210
211impl PinTx<USART6> for PA11<Alternate<AF8>> {}
212impl PinRx<USART6> for PA12<Alternate<AF8>> {}
213impl PinTx<USART6> for PC6<Alternate<AF8>> {}
214impl PinRx<USART6> for PC7<Alternate<AF8>> {}
215impl PinTx<USART6> for PG14<Alternate<AF8>> {}
216impl PinRx<USART6> for PG9<Alternate<AF8>> {}
217
218impl PinTx<UART7> for NoTx {}
219impl PinRx<UART7> for NoRx {}
220
221impl PinTx<UART7> for PA15<Alternate<AF8>> {}
222impl PinRx<UART7> for PA8<Alternate<AF8>> {}
223impl PinTx<UART7> for PB4<Alternate<AF8>> {}
224impl PinRx<UART7> for PB3<Alternate<AF8>> {}
225impl PinTx<UART7> for PE8<Alternate<AF8>> {}
226impl PinRx<UART7> for PE7<Alternate<AF8>> {}
227impl PinTx<UART7> for PF7<Alternate<AF8>> {}
228impl PinRx<UART7> for PF6<Alternate<AF8>> {}
229
230impl PinTx<UART8> for NoTx {}
231impl PinRx<UART8> for NoRx {}
232
233impl PinTx<UART8> for PE1<Alternate<AF8>> {}
234impl PinRx<UART8> for PE0<Alternate<AF8>> {}
235impl PinTx<UART8> for PF9<Alternate<AF8>> {}
236impl PinRx<UART8> for PF8<Alternate<AF8>> {}
237
238pub struct Serial<USART, PINS> {
240 usart: USART,
241 pins: PINS,
242}
243
244pub struct Rx<USART> {
246 _usart: PhantomData<USART>,
247}
248
249pub struct Tx<USART> {
251 _usart: PhantomData<USART>,
252}
253
254macro_rules! halUsartImpl {
255 ($(
256 $USARTX:ident: ($usartX:ident, $apbXenr:ident, $usartXen:ident, $pclkX:ident),
257 )+) => {
258 $(
259 impl<PINS> Serial<$USARTX, PINS> {
260 pub fn $usartX(
261 usart: $USARTX,
262 pins: PINS,
263 config: config::Config,
264 clocks: Clocks,
265 ) -> Result<Self, config::InvalidConfig>
266 where
267 PINS: Pins<$USARTX>,
268 {
269 use self::config::*;
270
271 let rcc = unsafe { &(*RCC::ptr()) };
273
274 rcc.$apbXenr.modify(|_, w| w.$usartXen().set_bit());
276
277 let div = (clocks.$pclkX().0 + config.baudrate.0 / 2)
279 / config.baudrate.0;
280 usart.brr.write(|w| unsafe { w.bits(div) });
281
282 usart.cr2.reset();
284 usart.cr3.reset();
285
286 usart.cr1.write(|w| {
289 w.ue()
290 .set_bit()
291 .te()
292 .set_bit()
293 .re()
294 .set_bit()
295 .m0()
296 .bit(match config.wordlength {
297 WordLength::DataBits8 => false,
298 WordLength::DataBits9 => true,
299 }).pce()
300 .bit(match config.parity {
301 Parity::ParityNone => false,
302 _ => true,
303 }).ps()
304 .bit(match config.parity {
305 Parity::ParityOdd => true,
306 _ => false,
307 })
308 });
309
310 Ok(Serial { usart, pins }.config_stop(config))
311 }
312
313 pub fn listen(&mut self, event: Event) {
315 match event {
316 Event::Rxne => {
317 self.usart.cr1.modify(|_, w| w.rxneie().set_bit())
318 },
319 Event::Txe => {
320 self.usart.cr1.modify(|_, w| w.txeie().set_bit())
321 },
322 Event::Idle => {
323 self.usart.cr1.modify(|_, w| w.idleie().set_bit())
324 },
325 }
326 }
327
328 pub fn unlisten(&mut self, event: Event) {
330 match event {
331 Event::Rxne => {
332 self.usart.cr1.modify(|_, w| w.rxneie().clear_bit())
333 },
334 Event::Txe => {
335 self.usart.cr1.modify(|_, w| w.txeie().clear_bit())
336 },
337 Event::Idle => {
338 self.usart.cr1.modify(|_, w| w.idleie().clear_bit())
339 },
340 }
341 }
342
343 pub fn is_idle(& self) -> bool {
345 unsafe { (*$USARTX::ptr()).isr.read().idle().bit_is_set() }
346 }
347
348 pub fn is_txe(& self) -> bool {
350 unsafe { (*$USARTX::ptr()).isr.read().txe().bit_is_set() }
351 }
352
353 pub fn is_rxne(& self) -> bool {
355 unsafe { (*$USARTX::ptr()).isr.read().rxne().bit_is_set() }
356 }
357
358 pub fn split(self) -> (Tx<$USARTX>, Rx<$USARTX>) {
359 (
360 Tx {
361 _usart: PhantomData,
362 },
363 Rx {
364 _usart: PhantomData,
365 },
366 )
367 }
368 pub fn release(self) -> ($USARTX, PINS) {
369 (self.usart, self.pins)
370 }
371 }
372
373 impl<PINS> serial::Read<u8> for Serial<$USARTX, PINS> {
374 type Error = Error;
375
376 fn read(&mut self) -> nb::Result<u8, Error> {
377 let mut rx: Rx<$USARTX> = Rx {
378 _usart: PhantomData,
379 };
380 rx.read()
381 }
382 }
383
384 impl serial::Read<u8> for Rx<$USARTX> {
385 type Error = Error;
386
387 fn read(&mut self) -> nb::Result<u8, Error> {
388 let sr = unsafe { (*$USARTX::ptr()).isr.read() };
390
391 if sr.pe().bit_is_set()
393 || sr.fe().bit_is_set()
394 || sr.nf().bit_is_set()
395 || sr.ore().bit_is_set()
396 {
397 unsafe { (*$USARTX::ptr()).rdr.read() };
398 }
399
400 Err(if sr.pe().bit_is_set() {
401 nb::Error::Other(Error::Parity)
402 } else if sr.fe().bit_is_set() {
403 nb::Error::Other(Error::Framing)
404 } else if sr.nf().bit_is_set() {
405 nb::Error::Other(Error::Noise)
406 } else if sr.ore().bit_is_set() {
407 nb::Error::Other(Error::Overrun)
408 } else if sr.rxne().bit_is_set() {
409 return Ok(unsafe { ptr::read_volatile(&(*$USARTX::ptr()).rdr as *const _ as *const _) });
411 } else {
412 nb::Error::WouldBlock
413 })
414 }
415 }
416
417 impl<PINS> serial::Write<u8> for Serial<$USARTX, PINS> {
418 type Error = Error;
419
420 fn flush(&mut self) -> nb::Result<(), Self::Error> {
421 let mut tx: Tx<$USARTX> = Tx {
422 _usart: PhantomData,
423 };
424 tx.flush()
425 }
426
427 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
428 let mut tx: Tx<$USARTX> = Tx {
429 _usart: PhantomData,
430 };
431 tx.write(byte)
432 }
433 }
434
435 impl serial::Write<u8> for Tx<$USARTX> {
436 type Error = Error;
437
438 fn flush(&mut self) -> nb::Result<(), Self::Error> {
439 let sr = unsafe { (*$USARTX::ptr()).isr.read() };
441
442 if sr.tc().bit_is_set() {
443 Ok(())
444 } else {
445 Err(nb::Error::WouldBlock)
446 }
447 }
448
449 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
450 let sr = unsafe { (*$USARTX::ptr()).isr.read() };
452
453 if sr.txe().bit_is_set() {
454 unsafe { ptr::write_volatile(&(*$USARTX::ptr()).tdr as *const _ as *mut _, byte) }
457 Ok(())
458 } else {
459 Err(nb::Error::WouldBlock)
460 }
461 }
462 }
463 )+
464 }
465}
466
467macro_rules! halUsart {
468 ($(
469 $USARTX:ident: ($usartX:ident, $apbXenr:ident, $usartXen:ident, $pclkX:ident),
470 )+) => {
471 $(
472 impl<PINS> Serial<$USARTX, PINS> {
473 fn config_stop(self, config: config::Config) -> Self {
474 use crate::stm32::usart1::cr2::STOPW;
475 use self::config::*;
476
477 self.usart.cr2.write(|w| {
478 w.stop().variant(match config.stopbits {
479 StopBits::STOP0P5 => STOPW::STOP0P5,
480 StopBits::STOP1 => STOPW::STOP1,
481 StopBits::STOP1P5 => STOPW::STOP1P5,
482 StopBits::STOP2 => STOPW::STOP2,
483 })
484 });
485 self
486 }
487 }
488 )+
489
490 halUsartImpl! {
491 $( $USARTX: ($usartX, $apbXenr, $usartXen, $pclkX), )+
492 }
493 }
494}
495
496macro_rules! halUart {
497 ($(
498 $USARTX:ident: ($usartX:ident, $apbXenr:ident, $usartXen:ident, $pclkX:ident),
499 )+) => {
500 $(
501 impl<PINS> Serial<$USARTX, PINS> {
502 fn config_stop(self, config: config::Config) -> Self {
503 use crate::stm32::usart1::cr2::STOPW;
504 use self::config::*;
505
506 self.usart.cr2.write(|w| {
507 w.stop().variant(match config.stopbits {
508 StopBits::STOP0P5 => STOPW::STOP0P5,
509 StopBits::STOP1 => STOPW::STOP1,
510 StopBits::STOP1P5 => STOPW::STOP1P5,
511 StopBits::STOP2 => STOPW::STOP2,
512 })
513 });
514 self
515 }
516 }
517 )+
518
519 halUsartImpl! {
520 $( $USARTX: ($usartX, $apbXenr, $usartXen, $pclkX), )+
521 }
522 }
523}
524
525halUsart! {
526 USART1: (usart1, apb2enr, usart1en, pclk2),
527 USART2: (usart2, apb1enr, usart2en, pclk1),
528 USART6: (usart6, apb2enr, usart6en, pclk2),
529}
530
531
532halUsart! {
533 USART3: (usart3, apb1enr, usart3en, pclk1),
534}
535
536halUart! {
537 UART4: (uart4, apb1enr, uart4en, pclk1),
538 UART5: (uart5, apb1enr, uart5en, pclk1),
539}
540
541halUsart! {
542 UART7: (uart7, apb1enr, uart7en, pclk1),
543 UART8: (uart8, apb1enr, uart8en, pclk1),
544}
545
546
547impl<USART> fmt::Write for Tx<USART>
548where
549 Tx<USART>: serial::Write<u8>,
550{
551 fn write_str(&mut self, s: &str) -> fmt::Result {
552 let _ = s
553 .as_bytes()
554 .iter()
555 .map(|c| block!(self.write(*c)))
556 .last();
557 Ok(())
558 }
559}
560