1use core::ops::Deref;
11
12use cfg_if::cfg_if;
13
14#[cfg(not(any(feature = "f4", feature = "l552", feature = "h5")))]
15use crate::dma::{self, ChannelCfg, DmaChannel};
16#[cfg(any(feature = "c0", feature = "h5"))]
17use crate::pac::DMA as DMA1;
18#[cfg(not(any(feature = "h5", feature = "c0")))]
19use crate::pac::DMA1;
20use crate::{
22 clocks::Clocks,
23 error::{Error, Result},
24 pac::{self, RCC},
25 util::{BaudPeriph, RccPeriph, bounded_loop, cr1, isr},
26};
27
28#[non_exhaustive]
32#[derive(Debug, Clone, Copy, Eq, PartialEq, defmt::Format)]
33pub enum UsartError {
34 Framing,
36 Noise,
38 Overrun,
40 Parity,
42}
43
44#[derive(Clone, Copy)]
45#[repr(u8)]
46pub enum StopBits {
48 S1 = 0b00,
49 S0_5 = 0b01,
50 S2 = 0b10,
51 S1_5 = 0b11,
52}
53
54#[derive(Clone, Copy, PartialEq)]
55pub enum Parity {
57 EnabledEven,
58 EnabledOdd,
59 Disabled,
60}
61
62#[derive(Clone, Copy)]
63pub enum WordLen {
65 W8,
66 W9,
67 W7,
68}
69
70impl WordLen {
71 pub fn bits(&self) -> (u8, u8) {
74 match self {
75 Self::W8 => (0, 0),
76 Self::W9 => (0, 1),
77 Self::W7 => (1, 0),
78 }
79 }
80}
81
82#[derive(Clone, Copy)]
83#[repr(u8)]
84pub enum OverSampling {
86 O16 = 0,
87 O8 = 1,
88}
89
90#[derive(Clone, Copy, PartialEq)]
91pub enum IrdaMode {
92 None,
94 Normal,
96 LowPower,
98}
99
100#[cfg(not(feature = "f4"))]
101#[derive(Clone, Copy)]
102pub enum UsartInterrupt {
104 CharDetect(Option<u8>),
108 Cts,
109 EndOfBlock,
110 Idle,
111 FramingError,
112 LineBreak,
113 Overrun,
114 ParityError,
115 ReadNotEmpty,
116 ReceiverTimeout,
117 #[cfg(not(any(feature = "f3", feature = "l4")))] Tcbgt,
119 TransmissionComplete,
120 TransmitEmpty,
121}
122
123pub struct UsartConfig {
125 pub word_len: WordLen,
127 pub stop_bits: StopBits,
129 pub oversampling: OverSampling,
131 pub parity: Parity,
133 pub irda_mode: IrdaMode,
136 #[cfg(any(feature = "g4", feature = "h7"))]
137 pub fifo_enabled: bool,
139 #[cfg(not(feature = "f4"))]
140 pub overrun_disabled: bool,
142}
143
144impl Default for UsartConfig {
145 fn default() -> Self {
146 Self {
147 word_len: WordLen::W8,
148 stop_bits: StopBits::S1,
149 oversampling: OverSampling::O16,
150 parity: Parity::Disabled,
151 irda_mode: IrdaMode::None,
152 #[cfg(any(feature = "g4", feature = "h7"))]
153 fifo_enabled: true,
154 #[cfg(not(feature = "f4"))]
155 overrun_disabled: false,
156 }
157 }
158}
159
160pub struct Usart<R> {
167 pub regs: R,
168 baud: u32,
169 config: UsartConfig,
170}
171
172impl<R> Usart<R>
173where
174 R: Deref<Target = pac::usart1::RegisterBlock> + RccPeriph + BaudPeriph,
175{
176 pub fn new(regs: R, baud: u32, config: UsartConfig, clock_cfg: &Clocks) -> Result<Self> {
179 let rcc = unsafe { &(*RCC::ptr()) };
180 R::en_reset(rcc);
181
182 let mut usart = Self { regs, baud, config };
183
184 usart.disable()?;
188
189 let word_len_bits = usart.config.word_len.bits();
193 cr1!(usart.regs).modify(|_, w| {
194 w.over8().bit(usart.config.oversampling as u8 != 0);
195 w.pce().bit(usart.config.parity != Parity::Disabled);
196 cfg_if! {
197 if #[cfg(not(any(feature = "f", feature = "wl")))] {
198 w.m1().bit(word_len_bits.0 != 0);
199 w.m0().bit(word_len_bits.1 != 0);
200 return w.ps().bit(usart.config.parity == Parity::EnabledOdd);
201 } else if #[cfg(feature = "f")] {
202 w.m().bit(word_len_bits.0 != 0);
204 return w.ps().bit(usart.config.parity == Parity::EnabledOdd);
205 } else {
206 return w.ps().bit(usart.config.parity == Parity::EnabledOdd);
207 }
208 }
209 });
210
211 #[cfg(not(feature = "f4"))]
212 usart
213 .regs
214 .cr3()
215 .modify(|_, w| w.ovrdis().bit(usart.config.overrun_disabled));
216
217 #[cfg(any(feature = "g4", feature = "h7"))]
219 usart
220 .regs
221 .cr1()
222 .modify(|_, w| w.fifoen().bit(usart.config.fifo_enabled));
223
224 usart.set_baud(baud, clock_cfg).ok();
226 usart
228 .regs
229 .cr2()
230 .modify(|_, w| unsafe { w.stop().bits(usart.config.stop_bits as u8) });
231 usart.enable()?;
233
234 cr1!(usart.regs).modify(|_, w| {
242 w.te().bit(true);
243 w.re().bit(true)
244 });
245
246 match usart.config.irda_mode {
247 IrdaMode::None => (),
252 _ => {
253 usart.regs.cr2().modify(|_, w| unsafe {
254 w.linen().clear_bit();
255 w.stop().bits(0);
256 w.clken().clear_bit()
257 });
258
259 usart.regs.cr3().modify(|_, w| {
261 w.scen().clear_bit();
262 w.hdsel().clear_bit();
263 w.irlp().bit(usart.config.irda_mode == IrdaMode::LowPower);
264 w.iren().bit(true)
265 });
266 }
267 }
268
269 Ok(usart)
270 }
271}
272
273impl<R> Usart<R>
274where
275 R: Deref<Target = pac::usart1::RegisterBlock> + BaudPeriph,
276{
277 pub fn set_baud(&mut self, baud: u32, clock_cfg: &Clocks) -> Result<()> {
280 let originally_enabled = cr1!(self.regs).read().ue().bit_is_set();
281
282 if originally_enabled {
283 cr1!(self.regs).modify(|_, w| w.ue().clear_bit());
284 bounded_loop!(
285 cr1!(self.regs).read().ue().bit_is_set(),
286 Error::RegisterUnchanged
287 );
288 }
289
290 let fclk = R::baud(clock_cfg);
295
296 let usart_div = match self.config.oversampling {
297 OverSampling::O16 => fclk / baud,
298 OverSampling::O8 => 2 * fclk / baud,
299 };
300
301 #[cfg(feature = "f4")]
310 let div = usart_div as u16;
311 #[cfg(not(feature = "f4"))]
312 let div = usart_div;
314
315 self.regs.brr().write(|w| unsafe { w.bits(div) });
316
317 self.baud = baud;
318
319 if originally_enabled {
320 cr1!(self.regs).modify(|_, w| w.ue().bit(true));
321 }
322
323 Ok(())
324 }
325}
326
327impl<R> Usart<R>
328where
329 R: Deref<Target = pac::usart1::RegisterBlock> + RccPeriph,
330{
331 pub fn enable(&mut self) -> Result<()> {
333 cr1!(self.regs).modify(|_, w| w.ue().bit(true));
334 bounded_loop!(
335 cr1!(self.regs).read().ue().bit_is_clear(),
336 Error::RegisterUnchanged
337 );
338
339 Ok(())
340 }
341
342 pub fn disable(&mut self) -> Result<()> {
344 cr1!(self.regs).modify(|_, w| w.ue().clear_bit());
345 bounded_loop!(
346 cr1!(self.regs).read().ue().bit_is_set(),
347 Error::RegisterUnchanged
348 );
349 Ok(())
350 }
351
352 pub fn write(&mut self, data: &[u8]) -> Result<()> {
354 for word in data {
361 cfg_if! {
362 if #[cfg(any(
363 feature = "h5",
364 feature = "c0",
365 feature = "g050", feature = "g051", feature = "g061", feature = "g0b0", feature = "g0b1", feature = "g0c1")
366 )] {
367 bounded_loop!(
368 isr!(self.regs).read().txfe().bit_is_clear(),
369 Error::RegisterUnchanged
370 );
371 } else if #[cfg(feature = "f4")] {
372 bounded_loop!(
373 isr!(self.regs).read().tc().bit_is_clear(),
374 Error::RegisterUnchanged
375 );
376 bounded_loop!(
377 isr!(self.regs).read().txe().bit_is_clear(),
378 Error::RegisterUnchanged
379 );
380 } else {
381 bounded_loop!(
382 isr!(self.regs).read().txe().bit_is_clear(),
383 Error::RegisterUnchanged
384 );
385 }
386 }
387
388 cfg_if! {
393 if #[cfg(feature = "f4")] {
394 self.regs
395 .dr()
396 .modify(|_, w| unsafe { w.dr().bits(*word as u16) });
397 bounded_loop!(
398 self.regs.sr().read().tc().bit_is_clear(),
399 Error::RegisterUnchanged
400 );
401 } else {
402 self.regs
405 .tdr()
406 .modify(|_, w| unsafe { w.tdr().bits(*word as u16) });
407 }
408 }
409 }
410
411 Ok(())
412 }
413
414 pub fn write_one(&mut self, word: u8) {
417 cfg_if! {
420 if #[cfg(not(feature = "f4"))] {
421 self.regs
422 .tdr()
423 .modify(|_, w| unsafe { w.tdr().bits(word as u16) });
424 } else {
425 self.regs
426 .dr()
427 .modify(|_, w| unsafe { w.dr().bits(word as u16) });
428 }
429 }
430 }
431
432 pub fn read(&mut self, buf: &mut [u8]) -> Result<()> {
434 for i in 0..buf.len() {
435 cfg_if! {
438 if #[cfg(any(
439 feature = "h5",
440 feature = "c0",
441 feature = "g050", feature = "g051", feature = "g061", feature = "g0b0", feature = "g0b1", feature = "g0c1")
442 )] {
443 bounded_loop!(
444 isr!(self.regs).read().rxfne().bit_is_clear(),
445 Error::RegisterUnchanged
446 );
447 } else {
448 bounded_loop!(
449 isr!(self.regs).read().rxne().bit_is_clear(),
450 Error::RegisterUnchanged
451 );
452 }
453 }
454
455 #[cfg(not(feature = "f4"))]
456 {
457 buf[i] = self.regs.rdr().read().rdr().bits() as u8;
458 }
459 #[cfg(feature = "f4")]
460 {
461 buf[i] = self.regs.dr().read().dr().bits() as u8;
462 }
463 }
464
465 Ok(())
480 }
481
482 pub fn read_one(&mut self) -> u8 {
485 cfg_if! {
486 if #[cfg(not(feature = "f4"))] {
487 self.regs.rdr().read().rdr().bits() as u8
488 } else {
489 self.regs.dr().read().dr().bits() as u8
490 }
491 }
492 }
493
494 #[cfg(not(any(feature = "f4", feature = "l552", feature = "h5")))]
495 pub unsafe fn write_dma(
499 &mut self,
500 buf: &[u8],
501 channel: DmaChannel,
502 channel_cfg: ChannelCfg,
503 dma_periph: dma::DmaPeriph,
504 ) -> Result<()> {
505 let (ptr, len) = (buf.as_ptr(), buf.len());
506
507 #[cfg(any(feature = "f3", feature = "l4"))]
511 let channel = R::write_chan();
512 #[cfg(feature = "l4")]
513 let mut dma_regs = unsafe { &(*DMA1::ptr()) }; #[cfg(feature = "l4")]
515 R::write_sel(&mut dma_regs);
516
517 let num_data = len as u32;
518
519 self.regs.cr3().modify(|_, w| w.dmat().bit(true));
524
525 self.regs.icr().write(|w| w.tccf().bit(true));
528
529 match dma_periph {
530 dma::DmaPeriph::Dma1 => {
531 let mut regs = unsafe { &(*DMA1::ptr()) };
532 dma::cfg_channel(
533 &mut regs,
534 channel,
535 self.regs.tdr().as_ptr() as u32,
539 ptr as u32,
543 num_data,
545 dma::Direction::ReadFromMem,
546 dma::DataSize::S8,
549 dma::DataSize::S8,
550 channel_cfg,
551 )
552 }
553 #[cfg(dma2)]
554 dma::DmaPeriph::Dma2 => {
555 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
556 dma::cfg_channel(
557 &mut regs,
558 channel,
559 self.regs.tdr().as_ptr() as u32,
560 ptr as u32,
561 num_data,
562 dma::Direction::ReadFromMem,
563 dma::DataSize::S8,
564 dma::DataSize::S8,
565 channel_cfg,
566 )
567 }
568 }
569
570 }
586
587 #[cfg(not(any(feature = "f4", feature = "l552", feature = "h5")))]
588 pub unsafe fn read_dma(
592 &mut self,
593 buf: &mut [u8],
594 channel: DmaChannel,
595 channel_cfg: ChannelCfg,
596 dma_periph: dma::DmaPeriph,
597 ) -> Result<()> {
598 let (ptr, len) = (buf.as_mut_ptr(), buf.len());
599
600 #[cfg(any(feature = "f3", feature = "l4"))]
601 let channel = R::read_chan();
602 #[cfg(feature = "l4")]
603 let mut dma_regs = unsafe { &(*DMA1::ptr()) }; #[cfg(feature = "l4")]
605 R::write_sel(&mut dma_regs);
606
607 let num_data = len as u32;
608
609 self.regs.cr3().modify(|_, w| w.dmar().bit(true));
611
612 match dma_periph {
613 dma::DmaPeriph::Dma1 => {
614 let mut regs = unsafe { &(*DMA1::ptr()) };
615 dma::cfg_channel(
616 &mut regs,
617 channel,
618 self.regs.rdr().as_ptr() as u32,
622 ptr as u32,
626 num_data,
628 dma::Direction::ReadFromPeriph,
629 dma::DataSize::S8,
630 dma::DataSize::S8,
631 channel_cfg,
632 )
633 }
634 #[cfg(dma2)]
635 dma::DmaPeriph::Dma2 => {
636 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
637 dma::cfg_channel(
638 &mut regs,
639 channel,
640 self.regs.rdr().as_ptr() as u32,
641 ptr as u32,
642 num_data,
643 dma::Direction::ReadFromPeriph,
644 dma::DataSize::S8,
645 dma::DataSize::S8,
646 channel_cfg,
647 )
648 }
649 }
650
651 }
665
666 #[cfg(not(feature = "f4"))]
675 pub fn enable_interrupt(&mut self, interrupt: UsartInterrupt) -> Result<()> {
679 match interrupt {
680 UsartInterrupt::CharDetect(char_wrapper) => {
681 if let Some(char) = char_wrapper {
682 cr1!(self.regs).modify(|_, w| w.ue().clear_bit());
684 bounded_loop!(
685 cr1!(self.regs).read().ue().bit_is_set(),
686 Error::RegisterUnchanged
687 );
688
689 cr1!(self.regs).modify(|_, w| w.cmie().bit(true));
691
692 self.regs.cr2().modify(|_, w| unsafe {
694 w.addm7().bit(true);
695 w.add().bits(char)
697 });
698
699 cr1!(self.regs).modify(|_, w| w.ue().bit(true));
700 bounded_loop!(
701 cr1!(self.regs).read().ue().bit_is_clear(),
702 Error::RegisterUnchanged
703 );
704 }
705
706 cr1!(self.regs).modify(|_, w| w.cmie().bit(true));
707 }
708 UsartInterrupt::Cts => {
709 self.regs.cr3().modify(|_, w| w.ctsie().bit(true));
710 }
711 UsartInterrupt::EndOfBlock => {
712 cr1!(self.regs).modify(|_, w| w.eobie().bit(true));
713 }
714 UsartInterrupt::Idle => {
715 cr1!(self.regs).modify(|_, w| w.idleie().bit(true));
716 }
717 UsartInterrupt::FramingError => {
718 self.regs.cr3().modify(|_, w| w.eie().bit(true));
719 }
720 UsartInterrupt::LineBreak => {
721 self.regs.cr2().modify(|_, w| w.lbdie().bit(true));
722 }
723 UsartInterrupt::Overrun => {
724 self.regs.cr3().modify(|_, w| w.eie().bit(true));
725 }
726 UsartInterrupt::ParityError => {
727 cr1!(self.regs).modify(|_, w| w.peie().bit(true));
728 }
729 UsartInterrupt::ReadNotEmpty => {
730 #[cfg(feature = "h5")]
731 cr1!(self.regs).modify(|_, w| w.rxfneie().bit(true));
732 #[cfg(not(feature = "h5"))]
733 cr1!(self.regs).modify(|_, w| w.rxneie().bit(true));
734 }
735 UsartInterrupt::ReceiverTimeout => {
736 cr1!(self.regs).modify(|_, w| w.rtoie().bit(true));
737 }
738 #[cfg(not(any(feature = "f3", feature = "l4")))]
739 UsartInterrupt::Tcbgt => {
740 self.regs.cr3().modify(|_, w| w.tcbgtie().bit(true));
741 self.regs.cr3().modify(|_, w| w.tcbgtie().bit(true));
742 }
743 UsartInterrupt::TransmissionComplete => {
744 cr1!(self.regs).modify(|_, w| w.tcie().bit(true));
745 }
746 UsartInterrupt::TransmitEmpty => {
747 #[cfg(feature = "h5")]
748 cr1!(self.regs).modify(|_, w| w.txfeie().bit(true));
749 #[cfg(not(feature = "h5"))]
750 cr1!(self.regs).modify(|_, w| w.txeie().bit(true));
751 }
752 }
753 Ok(())
754 }
755
756 #[cfg(not(feature = "f4"))]
757 pub fn disable_interrupt(&mut self, interrupt: UsartInterrupt) {
760 match interrupt {
761 UsartInterrupt::CharDetect(_) => {
762 cr1!(self.regs).modify(|_, w| w.cmie().clear_bit());
763 }
764 UsartInterrupt::Cts => {
765 self.regs.cr3().modify(|_, w| w.ctsie().clear_bit());
766 }
767 UsartInterrupt::EndOfBlock => {
768 cr1!(self.regs).modify(|_, w| w.eobie().clear_bit());
769 }
770 UsartInterrupt::Idle => {
771 cr1!(self.regs).modify(|_, w| w.idleie().clear_bit());
772 }
773 UsartInterrupt::FramingError => {
774 self.regs.cr3().modify(|_, w| w.eie().clear_bit());
775 }
776 UsartInterrupt::LineBreak => {
777 self.regs.cr2().modify(|_, w| w.lbdie().clear_bit());
778 }
779 UsartInterrupt::Overrun => {
780 self.regs.cr3().modify(|_, w| w.eie().clear_bit());
781 }
782 UsartInterrupt::ParityError => {
783 cr1!(self.regs).modify(|_, w| w.peie().clear_bit());
784 }
785 UsartInterrupt::ReadNotEmpty => {
786 #[cfg(feature = "h5")]
787 cr1!(self.regs).modify(|_, w| w.rxfneie().clear_bit());
788 #[cfg(not(feature = "h5"))]
789 cr1!(self.regs).modify(|_, w| w.rxneie().clear_bit());
790 }
791 UsartInterrupt::ReceiverTimeout => {
792 cr1!(self.regs).modify(|_, w| w.rtoie().clear_bit());
793 }
794 #[cfg(not(any(feature = "f3", feature = "l4")))]
795 UsartInterrupt::Tcbgt => {
796 self.regs.cr3().modify(|_, w| w.tcbgtie().clear_bit());
797 self.regs.cr3().modify(|_, w| w.tcbgtie().clear_bit());
798 }
799 UsartInterrupt::TransmissionComplete => {
800 cr1!(self.regs).modify(|_, w| w.tcie().clear_bit());
801 }
802 UsartInterrupt::TransmitEmpty => {
803 #[cfg(feature = "h5")]
804 cr1!(self.regs).modify(|_, w| w.txfeie().clear_bit());
805 #[cfg(not(feature = "h5"))]
806 cr1!(self.regs).modify(|_, w| w.txeie().clear_bit());
807 }
808 }
809 }
810
811 #[cfg(not(feature = "f4"))]
812 pub fn read_status(&self) -> u32 {
814 unsafe { isr!(self.regs).read().bits() }
815 }
816
817 #[cfg(not(feature = "f4"))]
818 pub fn clear_interrupt(&mut self, interrupt: UsartInterrupt) {
823 match interrupt {
824 UsartInterrupt::CharDetect(_) => self.regs.icr().write(|w| w.cmcf().bit(true)),
825 UsartInterrupt::Cts => self.regs.icr().write(|w| w.ctscf().bit(true)),
826 UsartInterrupt::EndOfBlock => self.regs.icr().write(|w| w.eobcf().bit(true)),
827 UsartInterrupt::Idle => self.regs.icr().write(|w| w.idlecf().bit(true)),
828 UsartInterrupt::FramingError => self.regs.icr().write(|w| w.fecf().bit(true)),
829 UsartInterrupt::LineBreak => self.regs.icr().write(|w| w.lbdcf().bit(true)),
830 UsartInterrupt::Overrun => self.regs.icr().write(|w| w.orecf().bit(true)),
831 UsartInterrupt::ParityError => self.regs.icr().write(|w| w.pecf().bit(true)),
832 UsartInterrupt::ReadNotEmpty => self.regs.rqr().write(|w| w.rxfrq().bit(true)),
833 UsartInterrupt::ReceiverTimeout => self.regs.icr().write(|w| w.rtocf().bit(true)),
834 #[cfg(not(any(feature = "f3", feature = "l4", feature = "h7")))]
835 UsartInterrupt::Tcbgt => self.regs.icr().write(|w| w.tcbgtcf().bit(true)),
836 #[cfg(feature = "h7")]
837 UsartInterrupt::Tcbgt => self.regs.icr().write(|w| w.tcbgtcf().bit(true)),
838 UsartInterrupt::TransmissionComplete => self.regs.icr().write(|w| w.tccf().bit(true)),
839 UsartInterrupt::TransmitEmpty => self.regs.rqr().write(|w| w.txfrq().bit(true)),
840 };
841 }
842
843 #[cfg(not(feature = "f4"))]
844 pub fn check_status_flag(&mut self, flag: UsartInterrupt) -> bool {
847 let status = isr!(self.regs).read();
848
849 match flag {
850 UsartInterrupt::CharDetect(_) => status.cmf().bit_is_set(),
851 UsartInterrupt::Cts => status.cts().bit_is_set(),
852 UsartInterrupt::EndOfBlock => status.eobf().bit_is_set(),
853 UsartInterrupt::Idle => status.idle().bit_is_set(),
854 UsartInterrupt::FramingError => status.fe().bit_is_set(),
855 UsartInterrupt::LineBreak => status.lbdf().bit_is_set(),
856 UsartInterrupt::Overrun => status.ore().bit_is_set(),
857 UsartInterrupt::ParityError => status.pe().bit_is_set(),
858 #[cfg(any(
859 feature = "h5",
860 feature = "c0",
861 feature = "g050",
862 feature = "g051",
863 feature = "g061",
864 feature = "g0b0",
865 feature = "g0b1",
866 feature = "g0c1"
867 ))]
868 UsartInterrupt::ReadNotEmpty => status.rxfne().bit_is_set(),
869 #[cfg(not(any(
870 feature = "h5",
871 feature = "c0",
872 feature = "g050",
873 feature = "g051",
874 feature = "g061",
875 feature = "g0b0",
876 feature = "g0b1",
877 feature = "g0c1"
878 )))]
879 UsartInterrupt::ReadNotEmpty => status.rxne().bit_is_set(),
880 UsartInterrupt::ReceiverTimeout => status.rtof().bit_is_set(),
881 #[cfg(not(any(feature = "f3", feature = "l4")))]
882 UsartInterrupt::Tcbgt => status.tcbgt().bit_is_set(),
883 UsartInterrupt::TransmissionComplete => status.tc().bit_is_set(),
884 #[cfg(any(
885 feature = "h5",
886 feature = "c0",
887 feature = "g050",
888 feature = "g051",
889 feature = "g061",
890 feature = "g0b0",
891 feature = "g0b1",
892 feature = "g0c1"
893 ))]
894 UsartInterrupt::TransmitEmpty => status.txfe().bit_is_set(),
895 #[cfg(not(any(
896 feature = "h5",
897 feature = "c0",
898 feature = "g050",
899 feature = "g051",
900 feature = "g061",
901 feature = "g0b0",
902 feature = "g0b1",
903 feature = "g0c1"
904 )))]
905 UsartInterrupt::TransmitEmpty => status.txe().bit_is_set(),
906 }
907 }
908
909 fn check_status(&mut self) -> core::result::Result<(), UsartError> {
910 cfg_if! {
911 if #[cfg(feature = "f4")] {
912 let status = self.regs.sr().read();
913 } else {
914 let status = self.regs.isr().read();
915 }
916 }
917 let mut result = if status.pe().bit_is_set() {
918 Err(UsartError::Parity)
919 } else if status.fe().bit_is_set() {
920 Err(UsartError::Framing)
921 } else if status.ore().bit_is_set() {
922 Err(UsartError::Overrun)
923 } else {
924 Ok(())
925 };
926
927 #[cfg(not(any(
928 feature = "wl",
929 feature = "c0",
930 feature = "g050",
931 feature = "g051",
932 feature = "g061",
933 feature = "g0b0",
934 feature = "g0b1",
935 feature = "g0c1"
936 )))]
937 if status.nf().bit_is_set() {
938 result = Err(UsartError::Noise);
939 }
940
941 #[cfg(any(
942 feature = "c0",
943 feature = "g050",
944 feature = "g051",
945 feature = "g061",
946 feature = "g0b0",
947 feature = "g0b1",
948 feature = "g0c1"
949 ))]
950 if status.ne().bit_is_set() {
951 result = Err(UsartError::Noise);
952 }
953
954 if result.is_err() {
955 cfg_if! {
958 if #[cfg(feature = "f4")] {
959 let _ = self.regs.dr().read();
960 } else {
961 self.regs.icr().write(|w| {
962 w.pecf().bit(true);
963 w.fecf().bit(true);
964 #[cfg(not(any(feature = "c0", feature = "g050", feature = "g051", feature = "g061", feature = "g0b0", feature = "g0b1", feature = "g0c1")))]
965 w.ncf().bit(true);
966 #[cfg(any(feature = "c0", feature = "g050", feature = "g051", feature = "g061", feature = "g0b0", feature = "g0b1", feature = "g0c1"))]
967 w.necf().bit(true);
968 w.orecf().bit(true)
969 });
970 let _ = self.regs.rdr().read();
971 }
972 }
973 }
974 result
975 }
976}
977
978#[cfg(feature = "embedded_hal")]
979mod embedded_io_impl {
980 use embedded_io::{ErrorType, Read, ReadReady, Write, WriteReady};
981
982 use super::*;
983
984 impl<R> ErrorType for Usart<R> {
985 type Error = crate::error::Error;
986 }
987
988 impl<R> Read for Usart<R>
989 where
990 R: Deref<Target = pac::usart1::RegisterBlock> + RccPeriph + BaudPeriph,
991 Usart<R>: ReadReady,
992 {
993 fn read(&mut self, mut buf: &mut [u8]) -> core::result::Result<usize, Self::Error> {
994 while !self.read_ready()? {
996 cortex_m::asm::nop();
997 }
998
999 let buf_len = buf.len();
1000 while !buf.is_empty() && self.read_ready()? {
1001 let (first, remaining) = buf.split_first_mut().unwrap();
1002 *first = self.read_one();
1003 buf = remaining;
1004 }
1005 Ok(buf_len - buf.len())
1006 }
1007 }
1008
1009 impl<R> ReadReady for Usart<R>
1010 where
1011 R: Deref<Target = pac::usart1::RegisterBlock> + RccPeriph + BaudPeriph,
1012 {
1013 fn read_ready(&mut self) -> core::result::Result<bool, Self::Error> {
1014 self.check_status()?;
1015 cfg_if! {
1016 if #[cfg(any(
1017 feature = "h5",
1018 feature = "c0",
1019 feature = "g050", feature = "g051", feature = "g061", feature = "g0b0", feature = "g0b1", feature = "g0c1")
1020 )] {
1021 let ready = self.regs.isr().read().rxfne().bit_is_set();
1022 } else if #[cfg(feature = "f4")] {
1023 let ready = self.regs.sr().read().rxne().bit_is_set();
1024 } else {
1025 let ready = self.regs.isr().read().rxne().bit_is_set();
1026 }
1027 };
1028 Ok(ready)
1029 }
1030 }
1031
1032 impl<R> Write for Usart<R>
1033 where
1034 R: Deref<Target = pac::usart1::RegisterBlock> + RccPeriph + BaudPeriph,
1035 {
1036 fn write(&mut self, mut buf: &[u8]) -> core::result::Result<usize, Self::Error> {
1037 while !self.write_ready()? {
1039 cortex_m::asm::nop();
1040 }
1041
1042 let buf_len = buf.len();
1043 while !buf.is_empty() && self.write_ready()? {
1044 let (byte, remaining) = buf.split_first().unwrap();
1045 self.write_one(*byte);
1046 buf = remaining;
1047 }
1048 Ok(buf_len - buf.len())
1049 }
1050
1051 fn flush(&mut self) -> core::result::Result<(), Self::Error> {
1052 #[cfg(not(feature = "f4"))]
1053 while isr!(self.regs).read().tc().bit_is_clear() {}
1054 #[cfg(feature = "f4")]
1055 while self.regs.sr().read().tc().bit_is_clear() {}
1056 Ok(())
1057 }
1058 }
1059
1060 impl<R> WriteReady for Usart<R>
1061 where
1062 R: Deref<Target = pac::usart1::RegisterBlock> + RccPeriph + BaudPeriph,
1063 {
1064 fn write_ready(&mut self) -> core::result::Result<bool, Self::Error> {
1065 cfg_if! {
1066 if #[cfg(any(
1067 feature = "h5",
1068 feature = "c0",
1069 feature = "g050", feature = "g051", feature = "g061", feature = "g0b0", feature = "g0b1", feature = "g0c1")
1070 )] {
1071 let ready = self.regs.isr().read().txfe().bit_is_set();
1072 } else if #[cfg(feature = "f4")] {
1073 let ready = self.regs.sr().read().txe().bit_is_set();
1074 } else {
1075 let ready = self.regs.isr().read().txe().bit_is_set();
1076 }
1077 };
1078 Ok(ready)
1079 }
1080 }
1081}