1use core::{
62 convert::Infallible,
63 fmt::{Result, Write},
64 ops::Deref,
65};
66
67use embedded_hal::prelude::*;
68
69use crate::{gpio::*, rcc::Rcc, time::Bps};
70
71use core::marker::PhantomData;
72
73#[non_exhaustive]
75#[derive(Debug)]
76pub enum Error {
77 Framing,
79 Noise,
81 Overrun,
83 Parity,
85}
86
87pub enum Event {
89 Rxne,
91 Txe,
93 Idle,
95}
96
97pub trait TxPin<USART> {}
98pub trait RxPin<USART> {}
99
100macro_rules! usart_pins {
101 ($($USART:ident => {
102 tx => [$($tx:ty),+ $(,)*],
103 rx => [$($rx:ty),+ $(,)*],
104 })+) => {
105 $(
106 $(
107 impl TxPin<crate::pac::$USART> for $tx {}
108 )+
109 $(
110 impl RxPin<crate::pac::$USART> for $rx {}
111 )+
112 )+
113 }
114}
115
116#[cfg(any(
117 feature = "stm32f030",
118 feature = "stm32f031",
119 feature = "stm32f038",
120 feature = "stm32f042",
121 feature = "stm32f048",
122 feature = "stm32f051",
123 feature = "stm32f058",
124 feature = "stm32f070",
125 feature = "stm32f071",
126 feature = "stm32f072",
127 feature = "stm32f078",
128 feature = "stm32f091",
129 feature = "stm32f098",
130))]
131usart_pins! {
132 USART1 => {
133 tx => [gpioa::PA9<Alternate<AF1>>, gpiob::PB6<Alternate<AF0>>],
134 rx => [gpioa::PA10<Alternate<AF1>>, gpiob::PB7<Alternate<AF0>>],
135 }
136}
137#[cfg(any(
138 feature = "stm32f030x4",
139 feature = "stm32f030x6",
140 feature = "stm32f031",
141 feature = "stm32f038",
142))]
143usart_pins! {
144 USART1 => {
145 tx => [gpioa::PA2<Alternate<AF1>>, gpioa::PA14<Alternate<AF1>>],
146 rx => [gpioa::PA3<Alternate<AF1>>, gpioa::PA15<Alternate<AF1>>],
147 }
148}
149
150#[cfg(any(
151 feature = "stm32f030x8",
152 feature = "stm32f030xc",
153 feature = "stm32f042",
154 feature = "stm32f048",
155 feature = "stm32f051",
156 feature = "stm32f058",
157 feature = "stm32f070",
158 feature = "stm32f071",
159 feature = "stm32f072",
160 feature = "stm32f078",
161 feature = "stm32f091",
162 feature = "stm32f098",
163))]
164usart_pins! {
165 USART2 => {
166 tx => [gpioa::PA2<Alternate<AF1>>, gpioa::PA14<Alternate<AF1>>],
167 rx => [gpioa::PA3<Alternate<AF1>>, gpioa::PA15<Alternate<AF1>>],
168 }
169}
170#[cfg(any(
171 feature = "stm32f071",
172 feature = "stm32f072",
173 feature = "stm32f078",
174 feature = "stm32f091",
175 feature = "stm32f098",
176))]
177usart_pins! {
178 USART2 => {
179 tx => [gpiod::PD5<Alternate<AF0>>],
180 rx => [gpiod::PD6<Alternate<AF0>>],
181 }
182}
183
184#[cfg(any(
185 feature = "stm32f030xc",
186 feature = "stm32f070xb",
187 feature = "stm32f071",
188 feature = "stm32f072",
189 feature = "stm32f078",
190 feature = "stm32f091",
191 feature = "stm32f098",
192))]
193usart_pins! {
194 USART3 => {
195 tx => [gpiob::PB10<Alternate<AF4>>, gpioc::PC4<Alternate<AF1>>, gpioc::PC10<Alternate<AF1>>],
197 rx => [gpiob::PB11<Alternate<AF4>>, gpioc::PC5<Alternate<AF1>>, gpioc::PC11<Alternate<AF1>>],
198 }
199 USART4 => {
200 tx => [gpioa::PA0<Alternate<AF4>>, gpioc::PC10<Alternate<AF0>>],
201 rx => [gpioa::PA1<Alternate<AF4>>, gpioc::PC11<Alternate<AF0>>],
202 }
203}
204#[cfg(any(
205 feature = "stm32f071",
206 feature = "stm32f072",
207 feature = "stm32f078",
208 feature = "stm32f091",
209 feature = "stm32f098",
210))]
211usart_pins! {
212 USART3 => {
213 tx => [gpiod::PD8<Alternate<AF0>>],
214 rx => [gpiod::PD9<Alternate<AF0>>],
215 }
216}
217#[cfg(any(feature = "stm32f030xc", feature = "stm32f091", feature = "stm32f098"))]
228usart_pins! {
229 USART5 => {
230 tx => [gpioc::PC12<Alternate<AF2>>],
231 rx => [gpiod::PD2<Alternate<AF2>>],
232 }
233 USART6 => {
234 tx => [gpioa::PA4<Alternate<AF5>>, gpioc::PC0<Alternate<AF2>>],
235 rx => [gpioa::PA5<Alternate<AF5>>, gpioc::PC1<Alternate<AF2>>],
236 }
237}
238#[cfg(any(feature = "stm32f030xc", feature = "stm32f091"))]
239usart_pins! {
240 USART5 => {
241 tx => [gpiob::PB3<Alternate<AF4>>],
242 rx => [gpiob::PB4<Alternate<AF4>>],
243 }
244}
245#[cfg(any(feature = "stm32f091", feature = "stm32f098"))]
248usart_pins! {
249 USART6 => {
254 tx => [gpiof::PF9<Alternate<AF1>>],
255 rx => [gpiof::PF10<Alternate<AF1>>],
256 }
257}
258
259pub struct Serial<USART, TXPIN, RXPIN> {
261 usart: USART,
262 pins: (TXPIN, RXPIN),
263}
264
265type SerialRegisterBlock = crate::pac::usart1::RegisterBlock;
267
268pub struct Rx<USART> {
270 usart: *const SerialRegisterBlock,
271 _instance: PhantomData<USART>,
272}
273
274unsafe impl<USART> Send for Rx<USART> {}
276
277pub struct Tx<USART> {
279 usart: *const SerialRegisterBlock,
280 _instance: PhantomData<USART>,
281}
282
283unsafe impl<USART> Send for Tx<USART> {}
285
286macro_rules! usart {
287 ($($USART:ident: ($usart:ident, $usarttx:ident, $usartrx:ident, $usartXen:ident, $apbenr:ident),)+) => {
288 $(
289 use crate::pac::$USART;
290 impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN>
291 where
292 TXPIN: TxPin<$USART>,
293 RXPIN: RxPin<$USART>,
294 {
295 pub fn $usart(usart: $USART, pins: (TXPIN, RXPIN), baud_rate: Bps, rcc: &mut Rcc) -> Self
297 {
298 let mut serial = Serial { usart, pins };
299 serial.configure(baud_rate, rcc);
300 serial.usart.cr1.modify(|_, w| w.te().set_bit().re().set_bit().ue().set_bit());
302 serial
303 }
304 }
305
306 impl<TXPIN> Serial<$USART, TXPIN, ()>
307 where
308 TXPIN: TxPin<$USART>,
309 {
310 pub fn $usarttx(usart: $USART, txpin: TXPIN, baud_rate: Bps, rcc: &mut Rcc) -> Self
312 {
313 let rxpin = ();
314 let mut serial = Serial { usart, pins: (txpin, rxpin) };
315 serial.configure(baud_rate, rcc);
316 serial.usart.cr1.modify(|_, w| w.te().set_bit().ue().set_bit());
318 serial
319 }
320 }
321
322 impl<RXPIN> Serial<$USART, (), RXPIN>
323 where
324 RXPIN: RxPin<$USART>,
325 {
326 pub fn $usartrx(usart: $USART, rxpin: RXPIN, baud_rate: Bps, rcc: &mut Rcc) -> Self
328 {
329 let txpin = ();
330 let mut serial = Serial { usart, pins: (txpin, rxpin) };
331 serial.configure(baud_rate, rcc);
332 serial.usart.cr1.modify(|_, w| w.re().set_bit().ue().set_bit());
334 serial
335 }
336 }
337
338 impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN> {
339 fn configure(&mut self, baud_rate: Bps, rcc: &mut Rcc) {
340 rcc.regs.$apbenr.modify(|_, w| w.$usartXen().set_bit());
342
343 let brr = rcc.clocks.pclk().0 / baud_rate.0;
345 self.usart.brr.write(|w| unsafe { w.bits(brr) });
346
347 self.usart.cr2.reset();
349 self.usart.cr3.reset();
350 }
351
352 pub fn listen(&mut self, event: Event) {
354 match event {
355 Event::Rxne => {
356 self.usart.cr1.modify(|_, w| w.rxneie().set_bit())
357 },
358 Event::Txe => {
359 self.usart.cr1.modify(|_, w| w.txeie().set_bit())
360 },
361 Event::Idle => {
362 self.usart.cr1.modify(|_, w| w.idleie().set_bit())
363 },
364 }
365 }
366
367 pub fn unlisten(&mut self, event: Event) {
369 match event {
370 Event::Rxne => {
371 self.usart.cr1.modify(|_, w| w.rxneie().clear_bit())
372 },
373 Event::Txe => {
374 self.usart.cr1.modify(|_, w| w.txeie().clear_bit())
375 },
376 Event::Idle => {
377 self.usart.cr1.modify(|_, w| w.idleie().clear_bit())
378 },
379 }
380 }
381 }
382 )+
383 }
384}
385
386usart! {
387 USART1: (usart1, usart1tx, usart1rx, usart1en, apb2enr),
388}
389#[cfg(any(
390 feature = "stm32f030x8",
391 feature = "stm32f030xc",
392 feature = "stm32f042",
393 feature = "stm32f048",
394 feature = "stm32f051",
395 feature = "stm32f058",
396 feature = "stm32f070",
397 feature = "stm32f071",
398 feature = "stm32f072",
399 feature = "stm32f078",
400 feature = "stm32f091",
401 feature = "stm32f098",
402))]
403usart! {
404 USART2: (usart2, usart2tx, usart2rx,usart2en, apb1enr),
405}
406#[cfg(any(
407 feature = "stm32f030xc",
408 feature = "stm32f070xb",
409 feature = "stm32f071",
410 feature = "stm32f072",
411 feature = "stm32f078",
412 feature = "stm32f091",
413 feature = "stm32f098",
414))]
415usart! {
416 USART3: (usart3, usart3tx, usart3rx,usart3en, apb1enr),
417 USART4: (usart4, usart4tx, usart4rx,usart4en, apb1enr),
418}
419#[cfg(any(feature = "stm32f030xc", feature = "stm32f091", feature = "stm32f098"))]
420usart! {
421 USART5: (usart5, usart5tx, usart5rx,usart5en, apb1enr),
422 USART6: (usart6, usart6tx, usart6rx,usart6en, apb2enr),
423}
424
425impl<USART> embedded_hal::serial::Read<u8> for Rx<USART>
426where
427 USART: Deref<Target = SerialRegisterBlock>,
428{
429 type Error = Error;
430
431 fn read(&mut self) -> nb::Result<u8, Error> {
433 read(self.usart)
434 }
435}
436
437impl<USART, TXPIN, RXPIN> embedded_hal::serial::Read<u8> for Serial<USART, TXPIN, RXPIN>
438where
439 USART: Deref<Target = SerialRegisterBlock>,
440 RXPIN: RxPin<USART>,
441{
442 type Error = Error;
443
444 fn read(&mut self) -> nb::Result<u8, Error> {
446 read(&*self.usart)
447 }
448}
449
450impl<USART> embedded_hal::serial::Write<u8> for Tx<USART>
451where
452 USART: Deref<Target = SerialRegisterBlock>,
453{
454 type Error = Infallible;
455
456 fn flush(&mut self) -> nb::Result<(), Self::Error> {
458 flush(self.usart)
459 }
460
461 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
464 write(self.usart, byte)
465 }
466}
467
468impl<USART, TXPIN, RXPIN> embedded_hal::serial::Write<u8> for Serial<USART, TXPIN, RXPIN>
469where
470 USART: Deref<Target = SerialRegisterBlock>,
471 TXPIN: TxPin<USART>,
472{
473 type Error = Infallible;
474
475 fn flush(&mut self) -> nb::Result<(), Self::Error> {
477 flush(&*self.usart)
478 }
479
480 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
483 write(&*self.usart, byte)
484 }
485}
486
487impl<USART, TXPIN, RXPIN> Serial<USART, TXPIN, RXPIN>
488where
489 USART: Deref<Target = SerialRegisterBlock>,
490{
491 pub fn split(self) -> (Tx<USART>, Rx<USART>)
494 where
495 TXPIN: TxPin<USART>,
496 RXPIN: RxPin<USART>,
497 {
498 (
499 Tx {
500 usart: &*self.usart,
501 _instance: PhantomData,
502 },
503 Rx {
504 usart: &*self.usart,
505 _instance: PhantomData,
506 },
507 )
508 }
509
510 pub fn release(self) -> (USART, (TXPIN, RXPIN)) {
511 (self.usart, self.pins)
512 }
513}
514
515impl<USART> Write for Tx<USART>
516where
517 Tx<USART>: embedded_hal::serial::Write<u8>,
518{
519 fn write_str(&mut self, s: &str) -> Result {
520 s.as_bytes()
521 .iter()
522 .try_for_each(|c| nb::block!(self.write(*c)))
523 .map_err(|_| core::fmt::Error)
524 }
525}
526
527impl<USART, TXPIN, RXPIN> Write for Serial<USART, TXPIN, RXPIN>
528where
529 USART: Deref<Target = SerialRegisterBlock>,
530 TXPIN: TxPin<USART>,
531{
532 fn write_str(&mut self, s: &str) -> Result {
533 s.as_bytes()
534 .iter()
535 .try_for_each(|c| nb::block!(self.write(*c)))
536 .map_err(|_| core::fmt::Error)
537 }
538}
539
540fn flush(usart: *const SerialRegisterBlock) -> nb::Result<(), Infallible> {
542 let isr = unsafe { (*usart).isr.read() };
544
545 if isr.tc().bit_is_set() {
546 Ok(())
547 } else {
548 Err(nb::Error::WouldBlock)
549 }
550}
551
552fn write(usart: *const SerialRegisterBlock, byte: u8) -> nb::Result<(), Infallible> {
555 let isr = unsafe { (*usart).isr.read() };
557
558 if isr.txe().bit_is_set() {
559 unsafe { (*usart).tdr.write(|w| w.tdr().bits(byte as u16)) }
561 Ok(())
562 } else {
563 Err(nb::Error::WouldBlock)
564 }
565}
566
567fn read(usart: *const SerialRegisterBlock) -> nb::Result<u8, Error> {
569 let isr = unsafe { (*usart).isr.read() };
571
572 let icr = unsafe { &(*usart).icr };
574
575 if isr.pe().bit_is_set() {
576 icr.write(|w| w.pecf().set_bit());
577 Err(nb::Error::Other(Error::Parity))
578 } else if isr.fe().bit_is_set() {
579 icr.write(|w| w.fecf().set_bit());
580 Err(nb::Error::Other(Error::Framing))
581 } else if isr.nf().bit_is_set() {
582 icr.write(|w| w.ncf().set_bit());
583 Err(nb::Error::Other(Error::Noise))
584 } else if isr.ore().bit_is_set() {
585 icr.write(|w| w.orecf().set_bit());
586 Err(nb::Error::Other(Error::Overrun))
587 } else if isr.rxne().bit_is_set() {
588 Ok(unsafe { (*usart).rdr.read().rdr().bits() as u8 })
589 } else {
590 Err(nb::Error::WouldBlock)
591 }
592}