1use core::fmt;
2use core::marker::PhantomData;
3
4use crate::dma;
5use crate::dmamux::DmaMuxIndex;
6use crate::gpio::{AltFunction, *};
7use crate::prelude::*;
8use crate::rcc::*;
9use crate::serial::config::*;
10use crate::stm32::*;
11
12use cortex_m::interrupt;
13use nb::block;
14
15#[derive(Debug)]
17pub enum Error {
18 Framing,
20 Noise,
22 Overrun,
24 Parity,
26}
27
28pub enum Event {
30 TXFT = 1 << 27,
32 RXFT = 1 << 26,
34
35 RXFF = 1 << 24,
37 TXFE = 1 << 23,
39
40 BUSY = 1 << 16,
42
43 RTOF = 1 << 11,
46 Txe = 1 << 7,
48
49 TC = 1 << 6,
51 Rxne = 1 << 5,
53 Idle = 1 << 4,
55
56 ORE = 1 << 3,
58
59 NE = 1 << 2,
61
62 FE = 1 << 1,
64
65 PE = 1 << 0,
67}
68
69impl Event {
70 fn val(self) -> u32 {
71 self as u32
72 }
73}
74
75pub struct Rx<USART, Config> {
77 _usart: PhantomData<USART>,
78 _config: PhantomData<Config>,
79}
80
81pub struct Tx<USART, Config> {
83 _usart: PhantomData<USART>,
84 _config: PhantomData<Config>,
85}
86
87pub struct Serial<USART, Config> {
89 tx: Tx<USART, Config>,
90 rx: Rx<USART, Config>,
91 usart: USART,
92 _config: PhantomData<Config>,
93}
94
95pub trait TxPin<USART> {
97 fn setup(&self);
98 fn release(self) -> Self;
99}
100
101pub trait RxPin<USART> {
103 fn setup(&self);
104 fn release(self) -> Self;
105}
106
107pub struct NoTx;
108
109impl<USART> TxPin<USART> for NoTx {
110 fn setup(&self) {}
111
112 fn release(self) -> Self {
113 self
114 }
115}
116pub struct NoRx;
117
118impl<USART> RxPin<USART> for NoRx {
119 fn setup(&self) {}
120
121 fn release(self) -> Self {
122 self
123 }
124}
125
126pub trait DriverEnablePin<USART> {
128 fn setup(&self);
129 fn release(self) -> Self;
130}
131
132pub trait Pins<USART> {
134 const DRIVER_ENABLE: bool;
135
136 fn setup(&self);
137 fn release(self) -> Self;
138}
139
140impl<USART, TX, RX> Pins<USART> for (TX, RX)
142where
143 TX: TxPin<USART>,
144 RX: RxPin<USART>,
145{
146 const DRIVER_ENABLE: bool = false;
147
148 fn setup(&self) {
149 self.0.setup();
150 self.1.setup();
151 }
152
153 fn release(self) -> Self {
154 (self.0.release(), self.1.release())
155 }
156}
157
158impl<USART, TX, RX, DE> Pins<USART> for (TX, RX, DE)
160where
161 TX: TxPin<USART>,
162 RX: RxPin<USART>,
163 DE: DriverEnablePin<USART>,
164{
165 const DRIVER_ENABLE: bool = true;
166
167 fn setup(&self) {
168 self.0.setup();
169 self.1.setup();
170 self.2.setup();
171 }
172
173 fn release(self) -> Self {
174 (self.0.release(), self.1.release(), self.2.release())
175 }
176}
177
178pub trait SerialExt<USART, Config> {
179 fn usart<PINS: Pins<USART>>(
180 self,
181 pins: PINS,
182 config: Config,
183 rcc: &mut Rcc,
184 ) -> Result<Serial<USART, Config>, InvalidConfig>;
185}
186
187impl<USART, Config> fmt::Write for Serial<USART, Config>
188where
189 Serial<USART, Config>: hal::serial::Write<u8>,
190{
191 fn write_str(&mut self, s: &str) -> fmt::Result {
192 let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last();
193 Ok(())
194 }
195}
196
197impl<USART, Config> fmt::Write for Tx<USART, Config>
198where
199 Tx<USART, Config>: hal::serial::Write<u8>,
200{
201 fn write_str(&mut self, s: &str) -> fmt::Result {
202 let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last();
203 Ok(())
204 }
205}
206
207macro_rules! uart_shared {
208 ($USARTX:ident, $dmamux_rx:ident, $dmamux_tx:ident,
209 tx: [ $(($PTX:ident, $TAF:expr),)+ ],
210 rx: [ $(($PRX:ident, $RAF:expr),)+ ],
211 de: [ $(($PDE:ident, $DAF:expr),)+ ]) => {
212
213 $(
214 impl<MODE> TxPin<$USARTX> for $PTX<MODE> {
215 fn setup(&self) {
216 self.set_alt_mode($TAF)
217 }
218
219 fn release(self) -> Self {
220 self
221 }
222 }
223 )+
224
225 $(
226 impl<MODE> RxPin<$USARTX> for $PRX<MODE> {
227 fn setup(&self) {
228 self.set_alt_mode($RAF)
229 }
230
231 fn release(self) -> Self {
232 self
233 }
234 }
235 )+
236
237 $(
238 impl<MODE> DriverEnablePin<$USARTX> for $PDE<MODE> {
239 fn setup(&self) {
240 self.set_alt_mode($DAF)
241 }
242
243 fn release(self) -> Self {
244 self
245 }
246 }
247 )+
248
249 impl<Config> Rx<$USARTX, Config> {
250 pub fn listen(&mut self) {
252 let usart = unsafe { &(*$USARTX::ptr()) };
253 usart.cr1.modify(|_, w| w.rxneie().set_bit());
254 }
255
256 pub fn unlisten(&mut self) {
258 let usart = unsafe { &(*$USARTX::ptr()) };
259 usart.cr1.modify(|_, w| w.rxneie().clear_bit());
260 }
261
262 pub fn is_rxne(&self) -> bool {
264 let usart = unsafe { &(*$USARTX::ptr()) };
265 usart.isr.read().rxne().bit_is_set()
266 }
267
268 pub fn listen_idle(&mut self) {
270 let usart = unsafe { &(*$USARTX::ptr()) };
271 usart.cr1.modify(|_, w| w.idleie().set_bit());
272 }
273
274 pub fn unlisten_idle(&mut self) {
276 let usart = unsafe { &(*$USARTX::ptr()) };
277 usart.cr1.modify(|_, w| w.idleie().clear_bit());
278 }
279
280 pub fn is_idle(&self) -> bool {
282 let usart = unsafe { &(*$USARTX::ptr()) };
283 usart.isr.read().idle().bit_is_set()
284 }
285
286 pub fn clear_idle(&mut self) {
288 let usart = unsafe { &(*$USARTX::ptr()) };
289 usart.icr.write(|w| w.idlecf().set_bit());
290 }
291 }
292
293 impl<Config> hal::serial::Read<u8> for Rx<$USARTX, Config> {
294 type Error = Error;
295
296 fn read(&mut self) -> nb::Result<u8, Error> {
297 let usart = unsafe { &(*$USARTX::ptr()) };
298 let isr = usart.isr.read();
299 Err(
300 if isr.pe().bit_is_set() {
301 usart.icr.write(|w| w.pecf().set_bit());
302 nb::Error::Other(Error::Parity)
303 } else if isr.fe().bit_is_set() {
304 usart.icr.write(|w| w.fecf().set_bit());
305 nb::Error::Other(Error::Framing)
306 } else if isr.nf().bit_is_set() {
307 usart.icr.write(|w| w.ncf().set_bit());
308 nb::Error::Other(Error::Noise)
309 } else if isr.ore().bit_is_set() {
310 usart.icr.write(|w| w.orecf().set_bit());
311 nb::Error::Other(Error::Overrun)
312 } else if isr.rxne().bit_is_set() {
313 return Ok(usart.rdr.read().bits() as u8)
314 } else {
315 nb::Error::WouldBlock
316 }
317 )
318 }
319 }
320
321 impl<Config> hal::serial::Read<u8> for Serial<$USARTX, Config> {
322 type Error = Error;
323
324 fn read(&mut self) -> nb::Result<u8, Error> {
325 self.rx.read()
326 }
327 }
328
329 impl<Config> Tx<$USARTX, Config> {
330
331 pub fn listen(&mut self) {
333 let usart = unsafe { &(*$USARTX::ptr()) };
334 usart.cr1.modify(|_, w| w.txeie().set_bit());
335 }
336
337 pub fn unlisten(&mut self) {
339 let usart = unsafe { &(*$USARTX::ptr()) };
340 usart.cr1.modify(|_, w| w.txeie().clear_bit());
341 }
342
343 pub fn is_txe(&self) -> bool {
345 let usart = unsafe { &(*$USARTX::ptr()) };
346 usart.isr.read().txe().bit_is_set()
347 }
348
349 }
350
351 impl<Config> hal::serial::Write<u8> for Tx<$USARTX, Config> {
352 type Error = Error;
353
354 fn flush(&mut self) -> nb::Result<(), Self::Error> {
355 let usart = unsafe { &(*$USARTX::ptr()) };
356 if usart.isr.read().tc().bit_is_set() {
357 Ok(())
358 } else {
359 Err(nb::Error::WouldBlock)
360 }
361 }
362
363 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
364 let usart = unsafe { &(*$USARTX::ptr()) };
365 if usart.isr.read().txe().bit_is_set() {
366 usart.tdr.write(|w| unsafe { w.bits(byte as u32) });
367 Ok(())
368 } else {
369 Err(nb::Error::WouldBlock)
370 }
371 }
372 }
373
374 impl<Config> hal::serial::Write<u8> for Serial<$USARTX, Config> {
375 type Error = Error;
376
377 fn flush(&mut self) -> nb::Result<(), Self::Error> {
378 self.tx.flush()
379 }
380
381 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
382 self.tx.write(byte)
383 }
384 }
385
386
387 impl<Config> Serial<$USARTX, Config> {
388
389 pub fn split(self) -> (Tx<$USARTX, Config>, Rx<$USARTX, Config>) {
392 (self.tx, self.rx)
393 }
394
395 }
396
397 impl<Config> dma::Target for Rx<$USARTX, Config> {
398
399 fn dmamux(&self) -> DmaMuxIndex {
400 DmaMuxIndex::$dmamux_rx
401 }
402
403 fn enable_dma(&mut self) {
404 interrupt::free(|_| unsafe {
406 let cr3 = &(*$USARTX::ptr()).cr3;
407 cr3.modify(|_, w| w.dmar().set_bit());
408 });
409 }
410
411 fn disable_dma(&mut self) {
412 interrupt::free(|_| unsafe {
414 let cr3 = &(*$USARTX::ptr()).cr3;
415 cr3.modify(|_, w| w.dmar().clear_bit());
416 });
417 }
418 }
419
420 impl<Config> dma::Target for Tx<$USARTX, Config> {
421
422 fn dmamux(&self) -> DmaMuxIndex {
423 DmaMuxIndex::$dmamux_tx
424 }
425
426 fn enable_dma(&mut self) {
427 interrupt::free(|_| unsafe {
429 let cr3 = &(*$USARTX::ptr()).cr3;
430 cr3.modify(|_, w| w.dmat().set_bit());
431 });
432 }
433
434 fn disable_dma(&mut self) {
435 interrupt::free(|_| unsafe {
437 let cr3 = &(*$USARTX::ptr()).cr3;
438 cr3.modify(|_, w| w.dmat().clear_bit());
439 });
440 }
441 }
442 }
443}
444
445macro_rules! uart_basic {
446 ($USARTX:ident,
447 $usartX:ident, $clk_mul:expr
448 ) => {
449 impl SerialExt<$USARTX, BasicConfig> for $USARTX {
450 fn usart<PINS: Pins<$USARTX>>(
451 self,
452 pins: PINS,
453 config: BasicConfig,
454 rcc: &mut Rcc,
455 ) -> Result<Serial<$USARTX, BasicConfig>, InvalidConfig> {
456 Serial::$usartX(self, pins, config, rcc)
457 }
458 }
459
460 impl Serial<$USARTX, BasicConfig> {
461 pub fn $usartX<PINS: Pins<$USARTX>>(
462 usart: $USARTX,
463 pins: PINS,
464 config: BasicConfig,
465 rcc: &mut Rcc,
466 ) -> Result<Self, InvalidConfig> {
467 $USARTX::enable(rcc);
469
470 let clk = rcc.clocks.apb_clk.raw() as u64;
471 let bdr = config.baudrate.0 as u64;
472 let div = ($clk_mul * clk) / bdr;
473 usart.brr.write(|w| unsafe { w.bits(div as u32) });
474 usart.cr2.reset();
476 usart.cr3.reset();
477
478 usart.cr1.modify(|_, w| w.ue().clear_bit());
480
481 usart.cr1.write(|w| {
483 w.te()
484 .set_bit()
485 .re()
486 .set_bit()
487 .m0()
488 .bit(config.wordlength == WordLength::DataBits9)
489 .m1()
490 .bit(config.wordlength == WordLength::DataBits7)
491 .pce()
492 .bit(config.parity != Parity::ParityNone)
493 .ps()
494 .bit(config.parity == Parity::ParityOdd)
495 });
496 usart.cr2.write(|w| unsafe {
497 w.stop()
498 .bits(match config.stopbits {
499 StopBits::STOP1 => 0b00,
500 StopBits::STOP0P5 => 0b01,
501 StopBits::STOP2 => 0b10,
502 StopBits::STOP1P5 => 0b11,
503 })
504 .txinv()
505 .bit(config.inverted_tx)
506 .rxinv()
507 .bit(config.inverted_rx)
508 .swap()
509 .bit(config.swap)
510 });
511
512 usart.cr3.write(|w| w.dem().bit(PINS::DRIVER_ENABLE));
513
514 pins.setup();
516
517 usart.cr1.modify(|_, w| w.ue().set_bit());
519
520 Ok(Serial {
521 tx: Tx {
522 _usart: PhantomData,
523 _config: PhantomData,
524 },
525 rx: Rx {
526 _usart: PhantomData,
527 _config: PhantomData,
528 },
529 usart,
530 _config: PhantomData,
531 })
532 }
533
534 pub fn listen(&mut self, event: Event) {
536 match event {
537 Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
538 Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
539 Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()),
540 _ => {}
541 }
542 }
543
544 pub fn unlisten(&mut self, event: Event) {
546 match event {
547 Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
548 Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
549 Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
550 _ => {}
551 }
552 }
553
554 pub fn is_pending(&mut self, event: Event) -> bool {
556 (self.usart.isr.read().bits() & event.val()) != 0
557 }
558
559 pub fn unpend(&mut self, event: Event) {
561 let mask: u32 = 0x123BFF;
563 self.usart
564 .icr
565 .write(|w| unsafe { w.bits(event.val() & mask) });
566 }
567 }
568 };
569}
570
571macro_rules! uart_full {
572 ($USARTX:ident,
573 $usartX:ident, $clk_mul:expr
574 ) => {
575 impl SerialExt<$USARTX, FullConfig> for $USARTX {
576 fn usart<PINS: Pins<$USARTX>>(
577 self,
578 pins: PINS,
579 config: FullConfig,
580 rcc: &mut Rcc,
581 ) -> Result<Serial<$USARTX, FullConfig>, InvalidConfig> {
582 Serial::$usartX(self, pins, config, rcc)
583 }
584 }
585
586 impl Serial<$USARTX, FullConfig> {
587 pub fn $usartX<PINS: Pins<$USARTX>>(
588 usart: $USARTX,
589 pins: PINS,
590 config: FullConfig,
591 rcc: &mut Rcc,
592 ) -> Result<Self, InvalidConfig> {
593 $USARTX::enable(rcc);
595
596 let clk = rcc.clocks.apb_clk.raw() as u64;
597 let bdr = config.baudrate.0 as u64;
598 let clk_mul = 1;
599 let div = (clk_mul * clk) / bdr;
600 usart.brr.write(|w| unsafe { w.bits(div as u32) });
601
602 usart.cr1.reset();
603 usart.cr2.reset();
604 usart.cr3.reset();
605
606 usart.cr2.write(|w| unsafe {
607 w.stop()
608 .bits(config.stopbits.bits())
609 .txinv()
610 .bit(config.inverted_tx)
611 .rxinv()
612 .bit(config.inverted_rx)
613 .swap()
614 .bit(config.swap)
615 });
616
617 if let Some(timeout) = config.receiver_timeout {
618 usart.cr1.write(|w| w.rtoie().set_bit());
619 usart.cr2.modify(|_, w| w.rtoen().set_bit());
620 usart.rtor.write(|w| unsafe { w.rto().bits(timeout) });
621 }
622
623 usart.cr3.write(|w| unsafe {
624 w.txftcfg()
625 .bits(config.tx_fifo_threshold.bits())
626 .rxftcfg()
627 .bits(config.rx_fifo_threshold.bits())
628 .txftie()
629 .bit(config.tx_fifo_interrupt)
630 .rxftie()
631 .bit(config.rx_fifo_interrupt)
632 .dem()
633 .bit(PINS::DRIVER_ENABLE)
634 });
635
636 usart.cr1.modify(|_, w| {
637 w.ue()
638 .set_bit()
639 .te()
640 .set_bit()
641 .re()
642 .set_bit()
643 .m0()
644 .bit(config.wordlength == WordLength::DataBits7)
645 .m1()
646 .bit(config.wordlength == WordLength::DataBits9)
647 .pce()
648 .bit(config.parity != Parity::ParityNone)
649 .ps()
650 .bit(config.parity == Parity::ParityOdd)
651 .fifoen()
652 .bit(config.fifo_enable)
653 });
654
655 pins.setup();
657
658 Ok(Serial {
659 tx: Tx {
660 _usart: PhantomData,
661 _config: PhantomData,
662 },
663 rx: Rx {
664 _usart: PhantomData,
665 _config: PhantomData,
666 },
667 usart,
668 _config: PhantomData,
669 })
670 }
671
672 pub fn listen(&mut self, event: Event) {
674 match event {
675 Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
676 Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
677 Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()),
678 _ => {}
679 }
680 }
681
682 pub fn unlisten(&mut self, event: Event) {
684 match event {
685 Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
686 Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
687 Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
688 _ => {}
689 }
690 }
691
692 pub fn is_pending(&mut self, event: Event) -> bool {
694 (self.usart.isr.read().bits() & event.val()) != 0
695 }
696
697 pub fn unpend(&mut self, event: Event) {
699 let mask: u32 = 0x123BFF;
701 self.usart
702 .icr
703 .write(|w| unsafe { w.bits(event.val() & mask) });
704 }
705 }
706 impl Tx<$USARTX, FullConfig> {
707 pub fn fifo_threshold_reached(&self) -> bool {
709 let usart = unsafe { &(*$USARTX::ptr()) };
710 usart.isr.read().txft().bit_is_set()
711 }
712 }
713
714 impl Rx<$USARTX, FullConfig> {
715 pub fn timeout_lapsed(&self) -> bool {
718 let usart = unsafe { &(*$USARTX::ptr()) };
719 usart.isr.read().rtof().bit_is_set()
720 }
721
722 pub fn clear_timeout(&mut self) {
724 let usart = unsafe { &(*$USARTX::ptr()) };
725 usart.icr.write(|w| w.rtocf().set_bit());
726 }
727
728 pub fn fifo_threshold_reached(&self) -> bool {
730 let usart = unsafe { &(*$USARTX::ptr()) };
731 usart.isr.read().rxft().bit_is_set()
732 }
733 }
734 };
735}
736
737uart_shared!(USART1, USART1_RX, USART1_TX,
738 tx: [
739 (PA9, AltFunction::AF1),
740 (PB6, AltFunction::AF0),
741 (PC4, AltFunction::AF1),
742 ],
743 rx: [
744 (PA10, AltFunction::AF1),
745 (PB7, AltFunction::AF0),
746 (PC5, AltFunction::AF1),
747 ],
748 de: [
749 (PA12, AltFunction::AF1),
750 (PB3, AltFunction::AF4),
751 ]
752);
753
754uart_shared!(USART2, USART2_RX, USART2_TX,
755 tx: [
756 (PA2, AltFunction::AF1),
757 (PA14, AltFunction::AF1),
758 (PD5, AltFunction::AF0),
759 ],
760 rx: [
761 (PA3, AltFunction::AF1),
762 (PA15, AltFunction::AF1),
763 (PD6, AltFunction::AF0),
764 ],
765 de: [
766 (PA1, AltFunction::AF1),
767 (PD4, AltFunction::AF0),
768 ]
769);
770
771#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
772uart_shared!(USART3, USART3_RX, USART3_TX,
773 tx: [
774 (PA5, AltFunction::AF4),
775 (PB2, AltFunction::AF4),
776 (PB8, AltFunction::AF4),
777 (PB10, AltFunction::AF4),
778 (PC4, AltFunction::AF1),
779 (PC10, AltFunction::AF1),
780 (PD8, AltFunction::AF1),
781 ],
782 rx: [
783 (PB0, AltFunction::AF4),
784 (PB9, AltFunction::AF4),
785 (PB11, AltFunction::AF4),
786 (PC5, AltFunction::AF1),
787 (PC11, AltFunction::AF1),
788 (PD9, AltFunction::AF1),
789 ],
790 de: [
791 (PA15, AltFunction::AF5),
792 (PB1, AltFunction::AF4),
793 (PB14, AltFunction::AF4),
794 (PD2, AltFunction::AF0),
795 (PD12, AltFunction::AF0),
796 ]
797);
798
799#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
800uart_shared!(USART4, USART4_RX, USART4_TX,
801 tx: [
802 (PA0, AltFunction::AF4),
803 (PC10, AltFunction::AF1),
804 ],
805 rx: [
806 (PC11, AltFunction::AF1),
807 (PA1, AltFunction::AF4),
808 ],
809 de: [
810 (PA15, AltFunction::AF4),
811 ]
812);
813
814#[cfg(feature = "stm32g0x1")]
815uart_shared!(LPUART, LPUART_RX, LPUART_TX,
816 tx: [
817 (PA2, AltFunction::AF6),
818 (PB11, AltFunction::AF1),
819 (PC1, AltFunction::AF1),
820 ],
821 rx: [
822 (PA3, AltFunction::AF6),
823 (PB10, AltFunction::AF1),
824 (PC0, AltFunction::AF1),
825 ],
826 de: [
827 (PB1, AltFunction::AF6),
828 (PB12, AltFunction::AF1),
829 ]
830);
831
832uart_full!(USART1, usart1, 1);
833
834#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
835uart_full!(USART2, usart2, 1);
836
837#[cfg(any(feature = "stm32g030", feature = "stm32g031", feature = "stm32g041"))]
838uart_basic!(USART2, usart2, 1);
839
840#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
841uart_basic!(USART3, usart3, 1);
842
843#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
844uart_basic!(USART4, usart4, 1);
845
846#[cfg(feature = "stm32g0x1")]
850uart_basic!(LPUART, lpuart, 256);