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