1use core::convert::Infallible;
16pub mod regs;
17#[cfg(feature = "vor1x")]
18use crate::InterruptConfig;
19use crate::{FunctionSelect, gpio::IoPeriphPin, pins::AnyPin, sealed::Sealed};
20use arbitrary_int::{prelude::*, u6, u18};
21use fugit::RateExtU32;
22use regs::{ClockScale, Control, Data, Enable, FifoClear, InterruptClear, MmioUart};
23
24use crate::{PeripheralSelect, enable_nvic_interrupt, enable_peripheral_clock, time::Hertz};
25use embedded_hal_nb::serial::Read;
26pub use regs::{Bank, Stopbits, WordSize};
27
28#[cfg(feature = "vor1x")]
29mod pins_vor1x;
30#[cfg(feature = "vor4x")]
31mod pins_vor4x;
32
33#[cfg(feature = "vor4x")]
34use crate::clock::Clocks;
35#[cfg(feature = "vor1x")]
36use va108xx as pac;
37#[cfg(feature = "vor4x")]
38use va416xx as pac;
39
40pub mod tx_asynch;
41pub use tx_asynch::*;
42
43pub mod rx_asynch;
44pub use rx_asynch::*;
45
46pub trait TxPin: AnyPin {
51 const BANK: Bank;
52 const FUN_SEL: FunctionSelect;
53}
54pub trait RxPin: AnyPin {
55 const BANK: Bank;
56 const FUN_SEL: FunctionSelect;
57}
58
59#[derive(Debug, PartialEq, Eq, thiserror::Error)]
64#[cfg_attr(feature = "defmt", derive(defmt::Format))]
65#[error("no interrupt ID was set")]
66pub struct NoInterruptIdWasSet;
67
68#[derive(Debug, PartialEq, Eq, thiserror::Error)]
69#[cfg_attr(feature = "defmt", derive(defmt::Format))]
70#[error("transer is pending")]
71pub struct TransferPendingError;
72
73#[derive(Debug, PartialEq, Eq, Copy, Clone)]
74#[cfg_attr(feature = "defmt", derive(defmt::Format))]
75pub enum Event {
76 RxFifoHalfFull,
80 RxError,
82 RxTimeout,
85
86 TxFifoHalfFull,
90 TxError,
92 TxEmpty,
94 TxCts,
96}
97
98#[derive(Debug, Copy, Clone, PartialEq, Eq)]
99#[cfg_attr(feature = "defmt", derive(defmt::Format))]
100pub enum Parity {
101 None,
102 Odd,
103 Even,
104}
105
106#[derive(Debug, Copy, Clone, PartialEq, Eq)]
107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
108pub struct Config {
109 pub baudrate: Hertz,
110 pub parity: Parity,
111 pub stopbits: Stopbits,
112 pub baud8: bool,
114 pub wordsize: WordSize,
115 pub enable_tx: bool,
116 pub enable_rx: bool,
117}
118
119impl Config {
120 pub fn baudrate(mut self, baudrate: Hertz) -> Self {
121 self.baudrate = baudrate;
122 self
123 }
124
125 pub fn parity_none(mut self) -> Self {
126 self.parity = Parity::None;
127 self
128 }
129
130 pub fn parity_even(mut self) -> Self {
131 self.parity = Parity::Even;
132 self
133 }
134
135 pub fn parity_odd(mut self) -> Self {
136 self.parity = Parity::Odd;
137 self
138 }
139
140 pub fn stopbits(mut self, stopbits: Stopbits) -> Self {
141 self.stopbits = stopbits;
142 self
143 }
144
145 pub fn wordsize(mut self, wordsize: WordSize) -> Self {
146 self.wordsize = wordsize;
147 self
148 }
149
150 pub fn baud8(mut self, baud: bool) -> Self {
151 self.baud8 = baud;
152 self
153 }
154}
155
156impl Default for Config {
157 fn default() -> Config {
158 let baudrate = 115_200_u32.Hz();
159 Config {
160 baudrate,
161 parity: Parity::None,
162 stopbits: Stopbits::One,
163 baud8: false,
164 wordsize: WordSize::Eight,
165 enable_tx: true,
166 enable_rx: true,
167 }
168 }
169}
170
171impl From<Hertz> for Config {
172 fn from(baud: Hertz) -> Self {
173 Config::default().baudrate(baud)
174 }
175}
176
177#[derive(Debug, Copy, Clone)]
182#[cfg_attr(feature = "defmt", derive(defmt::Format))]
183pub struct InterruptContextTimeoutOrMaxSize {
184 rx_idx: usize,
185 mode: InterruptReceptionMode,
186 pub max_len: usize,
187}
188
189impl InterruptContextTimeoutOrMaxSize {
190 pub fn new(max_len: usize) -> Self {
191 InterruptContextTimeoutOrMaxSize {
192 rx_idx: 0,
193 max_len,
194 mode: InterruptReceptionMode::Idle,
195 }
196 }
197}
198
199impl InterruptContextTimeoutOrMaxSize {
200 pub fn reset(&mut self) {
201 self.rx_idx = 0;
202 self.mode = InterruptReceptionMode::Idle;
203 }
204}
205
206#[derive(Debug, Default)]
208#[cfg_attr(feature = "defmt", derive(defmt::Format))]
209pub struct InterruptResult {
210 pub bytes_read: usize,
211 pub errors: Option<UartErrors>,
212}
213
214#[derive(Debug, Default)]
216#[cfg_attr(feature = "defmt", derive(defmt::Format))]
217pub struct InterruptResultMaxSizeOrTimeout {
218 complete: bool,
219 timeout: bool,
220 pub errors: Option<UartErrors>,
221 pub bytes_read: usize,
222}
223
224impl InterruptResultMaxSizeOrTimeout {
225 pub fn new() -> Self {
226 InterruptResultMaxSizeOrTimeout {
227 complete: false,
228 timeout: false,
229 errors: None,
230 bytes_read: 0,
231 }
232 }
233}
234impl InterruptResultMaxSizeOrTimeout {
235 #[inline]
236 pub fn has_errors(&self) -> bool {
237 self.errors.is_some()
238 }
239
240 #[inline]
241 pub fn overflow_error(&self) -> bool {
242 self.errors.is_some_and(|e| e.overflow)
243 }
244
245 #[inline]
246 pub fn framing_error(&self) -> bool {
247 self.errors.is_some_and(|e| e.framing)
248 }
249
250 #[inline]
251 pub fn parity_error(&self) -> bool {
252 self.errors.is_some_and(|e| e.parity)
253 }
254
255 #[inline]
256 pub fn timeout(&self) -> bool {
257 self.timeout
258 }
259
260 #[inline]
261 pub fn complete(&self) -> bool {
262 self.complete
263 }
264}
265
266#[derive(Debug, PartialEq, Copy, Clone)]
267#[cfg_attr(feature = "defmt", derive(defmt::Format))]
268enum InterruptReceptionMode {
269 Idle,
270 Pending,
271}
272
273#[derive(Default, Debug, Copy, Clone)]
274#[cfg_attr(feature = "defmt", derive(defmt::Format))]
275pub struct UartErrors {
276 overflow: bool,
277 framing: bool,
278 parity: bool,
279 other: bool,
280}
281
282impl UartErrors {
283 #[inline(always)]
284 pub fn overflow(&self) -> bool {
285 self.overflow
286 }
287
288 #[inline(always)]
289 pub fn framing(&self) -> bool {
290 self.framing
291 }
292
293 #[inline(always)]
294 pub fn parity(&self) -> bool {
295 self.parity
296 }
297
298 #[inline(always)]
299 pub fn other(&self) -> bool {
300 self.other
301 }
302}
303
304impl UartErrors {
305 #[inline(always)]
306 pub fn error(&self) -> bool {
307 self.overflow || self.framing || self.parity || self.other
308 }
309}
310
311#[derive(Debug, PartialEq, Eq)]
312#[cfg_attr(feature = "defmt", derive(defmt::Format))]
313pub struct BufferTooShortError {
314 found: usize,
315 expected: usize,
316}
317
318pub trait UartInstance: Sealed {
323 const ID: Bank;
324 const PERIPH_SEL: PeripheralSelect;
325}
326
327#[cfg(feature = "vor1x")]
328pub type Uart0 = pac::Uarta;
329#[cfg(feature = "vor4x")]
330pub type Uart0 = pac::Uart0;
331
332impl UartInstance for Uart0 {
333 const ID: Bank = Bank::Uart0;
334 const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart0;
335}
336impl Sealed for Uart0 {}
337
338#[cfg(feature = "vor1x")]
339pub type Uart1 = pac::Uartb;
340#[cfg(feature = "vor4x")]
341pub type Uart1 = pac::Uart1;
342
343impl UartInstance for Uart1 {
344 const ID: Bank = Bank::Uart1;
345 const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart1;
346}
347impl Sealed for Uart1 {}
348
349#[cfg(feature = "vor4x")]
350impl UartInstance for pac::Uart2 {
351 const ID: Bank = Bank::Uart2;
352 const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart2;
353}
354#[cfg(feature = "vor4x")]
355impl Sealed for pac::Uart2 {}
356
357#[derive(Debug, thiserror::Error)]
358#[cfg_attr(feature = "defmt", derive(defmt::Format))]
359#[error("UART ID missmatch between peripheral and pins.")]
360pub struct UartIdMissmatchError;
361
362pub struct Uart {
368 tx: Tx,
369 rx: Rx,
370}
371
372impl Uart {
373 cfg_if::cfg_if! {
374 if #[cfg(feature = "vor1x")] {
375 pub fn new_with_interrupt<UartPeriph: UartInstance, Tx: TxPin, Rx: RxPin>(
377 uart: UartPeriph,
378 tx_pin: Tx,
379 rx_pin: Rx,
380 sys_clk: Hertz,
381 config: Config,
382 irq_cfg: InterruptConfig,
383 ) -> Result<Self, UartIdMissmatchError> {
384 Self::new(uart, tx_pin, rx_pin, sys_clk, config, Some(irq_cfg))
385 }
386
387 pub fn new_without_interrupt<UartPeriph: UartInstance, Tx: TxPin, Rx: RxPin>(
389 uart: UartPeriph,
390 tx_pin: Tx,
391 rx_pin: Rx,
392 sys_clk: Hertz,
393 config: Config,
394 ) -> Result<Self, UartIdMissmatchError> {
395 Self::new(uart, tx_pin, rx_pin, sys_clk, config, None)
396 }
397
398 pub fn new<UartPeriph: UartInstance, Tx: TxPin, Rx: RxPin>(
411 uart: UartPeriph,
412 tx_pin: Tx,
413 rx_pin: Rx,
414 sys_clk: Hertz,
415 config: Config,
416 opt_irq_cfg: Option<InterruptConfig>,
417 ) -> Result<Self, UartIdMissmatchError> {
418 Self::new_internal(uart, (tx_pin, rx_pin), sys_clk, config, opt_irq_cfg)
419 }
420 } else if #[cfg(feature = "vor4x")] {
421 pub fn new<UartI: UartInstance, Tx: TxPin, Rx: RxPin>(
430 uart: UartI,
431 tx_pin: Tx,
432 rx_pin: Rx,
433 clks: &Clocks,
434 config: Config,
435 ) -> Result<Self, UartIdMissmatchError> {
436 if UartI::ID == Bank::Uart2 {
437 Self::new_internal(uart, (tx_pin, rx_pin), clks.apb1(), config)
438 } else {
439 Self::new_internal(uart, (tx_pin, rx_pin), clks.apb2(), config)
440 }
441 }
442
443 pub fn new_with_ref_clk<Uart: UartInstance, Tx: TxPin, Rx: RxPin>(
452 uart: Uart,
453 tx_pin: Tx,
454 rx_pin: Rx,
455 ref_clk: Hertz,
456 config: Config,
457 ) -> Result<Self, UartIdMissmatchError> {
458 Self::new_internal(uart,(tx_pin, rx_pin),ref_clk, config)
459 }
460 }
461 }
462
463 fn new_internal<UartI: UartInstance, TxPinI: TxPin, RxPinI: RxPin>(
464 _uart: UartI,
465 _pins: (TxPinI, RxPinI),
466 ref_clk: Hertz,
467 config: Config,
468 #[cfg(feature = "vor1x")] opt_irq_cfg: Option<InterruptConfig>,
469 ) -> Result<Self, UartIdMissmatchError> {
470 if UartI::ID != TxPinI::BANK || UartI::ID != RxPinI::BANK {
471 return Err(UartIdMissmatchError);
472 }
473 IoPeriphPin::new(TxPinI::ID, TxPinI::FUN_SEL, None);
474 IoPeriphPin::new(RxPinI::ID, TxPinI::FUN_SEL, None);
475 enable_peripheral_clock(UartI::PERIPH_SEL);
476
477 let mut reg_block = regs::Uart::new_mmio(UartI::ID);
478 let baud_multiplier = match config.baud8 {
479 false => 16,
480 true => 8,
481 };
482
483 let frac = ((ref_clk.raw() % (config.baudrate.raw() * 16)) * 64
486 + (config.baudrate.raw() * 8))
487 / (config.baudrate.raw() * 16);
488 let x = ref_clk.raw() as f32 / (config.baudrate.raw() * baud_multiplier) as f32;
490 let integer_part = x as u32;
491 reg_block.write_clkscale(
492 ClockScale::builder()
493 .with_int(u18::new(integer_part))
494 .with_frac(u6::new(frac as u8))
495 .build(),
496 );
497
498 let (paren, pareven) = match config.parity {
499 Parity::None => (false, false),
500 Parity::Odd => (true, false),
501 Parity::Even => (true, true),
502 };
503 reg_block.write_ctrl(
504 Control::builder()
505 .with_baud8(config.baud8)
506 .with_auto_rts(false)
507 .with_def_rts(false)
508 .with_auto_cts(false)
509 .with_loopback_block(false)
510 .with_loopback(false)
511 .with_wordsize(config.wordsize)
512 .with_stopbits(config.stopbits)
513 .with_parity_manual(false)
514 .with_parity_even(pareven)
515 .with_parity_enable(paren)
516 .build(),
517 );
518 reg_block.write_fifo_clr(FifoClear::builder().with_tx(true).with_rx(true).build());
520 reg_block.write_enable(
521 Enable::builder()
522 .with_tx(config.enable_tx)
523 .with_rx(config.enable_rx)
524 .build(),
525 );
526
527 #[cfg(feature = "vor1x")]
528 if let Some(irq_cfg) = opt_irq_cfg {
529 if irq_cfg.route {
530 enable_peripheral_clock(PeripheralSelect::Irqsel);
531 unsafe { va108xx::Irqsel::steal() }
532 .uart(UartI::ID as usize)
533 .write(|w| unsafe { w.bits(irq_cfg.id as u32) });
534 }
535 if irq_cfg.enable_in_nvic {
536 unsafe { enable_nvic_interrupt(irq_cfg.id) };
538 }
539 }
540
541 Ok(Uart {
542 tx: Tx::new(UartI::ID),
543 rx: Rx::new(UartI::ID),
544 })
545 }
546
547 #[inline]
548 pub fn peripheral_id(&self) -> u32 {
549 self.tx.perid()
550 }
551
552 #[inline]
553 pub fn enable_rx(&mut self) {
554 self.rx.enable();
555 }
556
557 #[inline]
558 pub fn disable_rx(&mut self) {
559 self.rx.disable();
560 }
561
562 #[inline]
563 pub fn enable_tx(&mut self) {
564 self.tx.enable();
565 }
566
567 #[inline]
568 pub fn disable_tx(&mut self) {
569 self.tx.disable();
570 }
571
572 #[inline]
574 pub fn clear_rx_fifo(&mut self) {
575 self.rx.clear_fifo();
576 }
577
578 #[inline]
580 pub fn clear_tx_fifo(&mut self) {
581 self.tx.clear_fifo();
582 }
583
584 pub fn listen(&mut self, event: Event) {
585 self.tx.regs.modify_irq_enabled(|mut value| {
586 match event {
587 Event::RxError => value.set_rx_status(true),
588 Event::RxFifoHalfFull => value.set_rx(true),
589 Event::RxTimeout => value.set_rx_timeout(true),
590 Event::TxEmpty => value.set_tx_empty(true),
591 Event::TxError => value.set_tx_status(true),
592 Event::TxFifoHalfFull => value.set_tx(true),
593 Event::TxCts => value.set_tx_cts(true),
594 }
595 value
596 });
597 }
598
599 pub fn unlisten(&mut self, event: Event) {
600 self.tx.regs.modify_irq_enabled(|mut value| {
601 match event {
602 Event::RxError => value.set_rx_status(false),
603 Event::RxFifoHalfFull => value.set_rx(false),
604 Event::RxTimeout => value.set_rx_timeout(false),
605 Event::TxEmpty => value.set_tx_empty(false),
606 Event::TxError => value.set_tx_status(false),
607 Event::TxFifoHalfFull => value.set_tx(false),
608 Event::TxCts => value.set_tx_cts(false),
609 }
610 value
611 });
612 }
613
614 pub fn poll_rx_errors(&self) -> Option<UartErrors> {
616 self.rx.poll_errors()
617 }
618
619 pub fn split(self) -> (Tx, Rx) {
620 (self.tx, self.rx)
621 }
622}
623
624impl embedded_io::ErrorType for Uart {
625 type Error = Infallible;
626}
627
628impl embedded_hal_nb::serial::ErrorType for Uart {
629 type Error = Infallible;
630}
631
632impl embedded_hal_nb::serial::Read<u8> for Uart {
633 fn read(&mut self) -> nb::Result<u8, Self::Error> {
634 self.rx.read()
635 }
636}
637
638impl embedded_hal_nb::serial::Write<u8> for Uart {
639 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
640 self.tx.write(word).map_err(|e| {
641 if let nb::Error::Other(_) = e {
642 unreachable!()
643 }
644 nb::Error::WouldBlock
645 })
646 }
647
648 fn flush(&mut self) -> nb::Result<(), Self::Error> {
649 self.tx.flush().map_err(|e| {
650 if let nb::Error::Other(_) = e {
651 unreachable!()
652 }
653 nb::Error::WouldBlock
654 })
655 }
656}
657
658#[inline(always)]
659pub fn enable_rx(uart: &mut MmioUart<'static>) {
660 uart.modify_enable(|mut value| {
661 value.set_rx(true);
662 value
663 });
664}
665
666#[inline(always)]
667pub fn disable_rx(uart: &mut MmioUart<'static>) {
668 uart.modify_enable(|mut value| {
669 value.set_rx(false);
670 value
671 });
672}
673
674#[inline(always)]
675pub fn enable_rx_interrupts(uart: &mut MmioUart<'static>, timeout: bool) {
676 uart.modify_irq_enabled(|mut value| {
677 value.set_rx_status(true);
678 value.set_rx(true);
679 if timeout {
680 value.set_rx_timeout(true);
681 }
682 value
683 });
684}
685
686#[inline(always)]
687pub fn disable_rx_interrupts(uart: &mut MmioUart<'static>) {
688 uart.modify_irq_enabled(|mut value| {
689 value.set_rx_status(false);
690 value.set_rx(false);
691 value.set_rx_timeout(false);
692 value
693 });
694}
695
696pub struct Rx {
700 id: Bank,
701 regs: regs::MmioUart<'static>,
702}
703
704impl Rx {
705 #[inline(always)]
711 pub unsafe fn steal(id: Bank) -> Self {
712 Self::new(id)
713 }
714
715 #[inline(always)]
716 fn new(id: Bank) -> Self {
717 Self {
718 id,
719 regs: regs::Uart::new_mmio(id),
720 }
721 }
722
723 pub fn poll_errors(&self) -> Option<UartErrors> {
724 let mut errors = UartErrors::default();
725
726 let status = self.regs.read_rx_status();
727 if status.overrun_error() {
728 errors.overflow = true;
729 } else if status.framing_error() {
730 errors.framing = true;
731 } else if status.parity_error() {
732 errors.parity = true;
733 } else {
734 return None;
735 };
736 Some(errors)
737 }
738
739 #[inline]
740 pub fn perid(&self) -> u32 {
741 self.regs.read_perid()
742 }
743
744 #[inline]
745 pub fn clear_fifo(&mut self) {
746 self.regs
747 .write_fifo_clr(FifoClear::builder().with_tx(false).with_rx(true).build());
748 }
749
750 #[inline]
751 pub fn disable_interrupts(&mut self) {
752 disable_rx_interrupts(&mut self.regs);
753 }
754
755 #[inline]
756 pub fn enable_interrupts(
757 &mut self,
758 #[cfg(feature = "vor4x")] enable_in_nvic: bool,
759 timeout: bool,
760 ) {
761 #[cfg(feature = "vor4x")]
762 if enable_in_nvic {
763 unsafe {
764 enable_nvic_interrupt(self.id.interrupt_id_rx());
765 }
766 }
767 enable_rx_interrupts(&mut self.regs, timeout);
768 }
769
770 #[inline]
771 pub fn enable(&mut self) {
772 enable_rx(&mut self.regs);
773 }
774
775 #[inline]
776 pub fn disable(&mut self) {
777 disable_rx(&mut self.regs);
778 }
779
780 #[inline(always)]
787 pub fn read_fifo(&mut self) -> nb::Result<u32, Infallible> {
788 if !self.regs.read_rx_status().data_available() {
789 return Err(nb::Error::WouldBlock);
790 }
791 Ok(self.read_fifo_unchecked())
792 }
793
794 #[inline(always)]
803 pub fn read_fifo_unchecked(&mut self) -> u32 {
804 self.regs.read_data().raw_value()
805 }
806
807 pub fn into_rx_with_irq(self) -> RxWithInterrupt {
808 RxWithInterrupt::new(self)
809 }
810}
811
812impl embedded_io::ErrorType for Rx {
813 type Error = Infallible;
814}
815
816impl embedded_hal_nb::serial::ErrorType for Rx {
817 type Error = Infallible;
818}
819
820impl embedded_hal_nb::serial::Read<u8> for Rx {
821 fn read(&mut self) -> nb::Result<u8, Self::Error> {
822 self.read_fifo().map(|val| (val & 0xff) as u8).map_err(|e| {
823 if let nb::Error::Other(_) = e {
824 unreachable!()
825 }
826 nb::Error::WouldBlock
827 })
828 }
829}
830
831impl embedded_io::Read for Rx {
832 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
833 if buf.is_empty() {
834 return Ok(0);
835 }
836 let mut read = 0;
837 loop {
838 if self.regs.read_rx_status().data_available() {
839 break;
840 }
841 }
842 for byte in buf.iter_mut() {
843 match <Self as embedded_hal_nb::serial::Read<u8>>::read(self) {
844 Ok(w) => {
845 *byte = w;
846 read += 1;
847 }
848 Err(nb::Error::WouldBlock) => break,
849 }
850 }
851
852 Ok(read)
853 }
854}
855
856#[inline(always)]
857pub fn enable_tx(uart: &mut MmioUart<'static>) {
858 uart.modify_enable(|mut value| {
859 value.set_tx(true);
860 value
861 });
862}
863
864#[inline(always)]
865pub fn disable_tx(uart: &mut MmioUart<'static>) {
866 uart.modify_enable(|mut value| {
867 value.set_tx(false);
868 value
869 });
870}
871
872#[inline(always)]
873pub fn enable_tx_interrupts(uart: &mut MmioUart<'static>) {
874 uart.modify_irq_enabled(|mut value| {
875 value.set_tx(true);
876 value.set_tx_empty(true);
877 value.set_tx_status(true);
878 value
879 });
880}
881
882#[inline(always)]
883pub fn disable_tx_interrupts(uart: &mut MmioUart<'static>) {
884 uart.modify_irq_enabled(|mut value| {
885 value.set_tx(false);
886 value.set_tx_empty(false);
887 value.set_tx_status(false);
888 value
889 });
890}
891
892pub struct Tx {
896 id: Bank,
897 regs: regs::MmioUart<'static>,
898}
899
900impl Tx {
901 #[inline(always)]
907 pub unsafe fn steal(id: Bank) -> Self {
908 Self::new(id)
909 }
910
911 #[inline(always)]
912 fn new(id: Bank) -> Self {
913 Self {
914 id,
915 regs: regs::Uart::new_mmio(id),
916 }
917 }
918
919 #[inline]
920 pub fn perid(&self) -> u32 {
921 self.regs.read_perid()
922 }
923
924 #[inline]
925 pub fn clear_fifo(&mut self) {
926 self.regs
927 .write_fifo_clr(FifoClear::builder().with_tx(true).with_rx(false).build());
928 }
929
930 #[inline]
931 pub fn enable(&mut self) {
932 self.regs.modify_enable(|mut value| {
933 value.set_tx(true);
934 value
935 });
936 }
937
938 #[inline]
939 pub fn disable(&mut self) {
940 self.regs.modify_enable(|mut value| {
941 value.set_tx(false);
942 value
943 });
944 }
945
946 #[inline]
953 pub fn enable_interrupts(&mut self, #[cfg(feature = "vor4x")] enable_in_nvic: bool) {
954 #[cfg(feature = "vor4x")]
955 if enable_in_nvic {
956 unsafe { enable_nvic_interrupt(self.id.interrupt_id_tx()) };
957 }
958 enable_tx_interrupts(&mut self.regs);
960 }
961
962 #[inline]
966 pub fn disable_interrupts(&mut self) {
967 disable_tx_interrupts(&mut self.regs);
969 }
970
971 #[inline(always)]
978 pub fn write_fifo(&mut self, data: u32) -> nb::Result<(), Infallible> {
979 if !self.regs.read_tx_status().ready() {
980 return Err(nb::Error::WouldBlock);
981 }
982 self.write_fifo_unchecked(data);
983 Ok(())
984 }
985
986 #[inline(always)]
993 pub fn write_fifo_unchecked(&mut self, data: u32) {
994 self.regs.write_data(Data::new_with_raw_value(data));
995 }
996
997 pub fn into_async(self) -> TxAsync {
998 TxAsync::new(self)
999 }
1000}
1001
1002impl embedded_io::ErrorType for Tx {
1003 type Error = Infallible;
1004}
1005
1006impl embedded_hal_nb::serial::ErrorType for Tx {
1007 type Error = Infallible;
1008}
1009
1010impl embedded_hal_nb::serial::Write<u8> for Tx {
1011 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
1012 self.write_fifo(word as u32)
1013 }
1014
1015 fn flush(&mut self) -> nb::Result<(), Self::Error> {
1016 if self.regs.read_tx_status().write_busy() {
1018 return Err(nb::Error::WouldBlock);
1019 }
1020 Ok(())
1021 }
1022}
1023
1024impl embedded_io::Write for Tx {
1025 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1026 if buf.is_empty() {
1027 return Ok(0);
1028 }
1029 loop {
1030 if self.regs.read_tx_status().ready() {
1031 break;
1032 }
1033 }
1034 let mut written = 0;
1035 for byte in buf.iter() {
1036 match <Self as embedded_hal_nb::serial::Write<u8>>::write(self, *byte) {
1037 Ok(_) => written += 1,
1038 Err(nb::Error::WouldBlock) => return Ok(written),
1039 }
1040 }
1041
1042 Ok(written)
1043 }
1044
1045 fn flush(&mut self) -> Result<(), Self::Error> {
1046 nb::block!(<Self as embedded_hal_nb::serial::Write<u8>>::flush(self))
1047 }
1048}
1049
1050pub struct RxWithInterrupt(Rx);
1067
1068impl RxWithInterrupt {
1069 pub fn new(rx: Rx) -> Self {
1070 Self(rx)
1071 }
1072
1073 pub fn start(&mut self) {
1076 #[cfg(feature = "vor4x")]
1077 self.enable_interrupts(true, true);
1078 #[cfg(feature = "vor1x")]
1079 self.enable_interrupts(true);
1080 self.0.enable();
1081 }
1082
1083 #[inline(always)]
1084 pub fn rx(&self) -> &Rx {
1085 &self.0
1086 }
1087
1088 pub fn read_fixed_len_or_timeout_based_using_irq(
1097 &mut self,
1098 context: &mut InterruptContextTimeoutOrMaxSize,
1099 ) -> Result<(), TransferPendingError> {
1100 if context.mode != InterruptReceptionMode::Idle {
1101 return Err(TransferPendingError);
1102 }
1103 context.mode = InterruptReceptionMode::Pending;
1104 context.rx_idx = 0;
1105 self.start();
1106 Ok(())
1107 }
1108
1109 #[inline]
1110 fn enable_interrupts(&mut self, #[cfg(feature = "vor4x")] enable_in_nvic: bool, timeout: bool) {
1111 #[cfg(feature = "vor4x")]
1112 self.0.enable_interrupts(enable_in_nvic, timeout);
1113 #[cfg(feature = "vor1x")]
1114 self.0.enable_interrupts(timeout);
1115 }
1116
1117 #[inline]
1118 fn disable_interrupts(&mut self) {
1119 self.0.disable_interrupts();
1120 }
1121
1122 pub fn cancel_transfer(&mut self) {
1123 self.disable_interrupts();
1124 self.0.clear_fifo();
1125 }
1126
1127 pub fn on_interrupt(&mut self, buf: &mut [u8; 16]) -> InterruptResult {
1136 let mut result = InterruptResult::default();
1137
1138 let irq_status = self.0.regs.read_irq_status();
1139 let irq_enabled = self.0.regs.read_irq_enabled();
1140 let rx_enabled = irq_enabled.rx();
1141
1142 if irq_status.rx() {
1144 let available_bytes = self.0.regs.read_rx_fifo_trigger().level().as_usize();
1145
1146 for _ in 0..available_bytes {
1149 buf[result.bytes_read] = (self.0.read_fifo_unchecked() & 0xff) as u8;
1150 result.bytes_read += 1;
1151 }
1152 }
1153
1154 if irq_status.rx_timeout() {
1156 while let Ok(byte) = self.0.read_fifo() {
1158 buf[result.bytes_read] = byte as u8;
1159 result.bytes_read += 1;
1160 }
1161 }
1162
1163 if rx_enabled {
1165 self.check_for_errors(&mut result.errors);
1166 }
1167
1168 self.0.regs.write_irq_clr(
1170 InterruptClear::builder()
1171 .with_rx_overrun(true)
1172 .with_tx_overrun(false)
1173 .build(),
1174 );
1175 result
1176 }
1177
1178 pub fn on_interrupt_max_size_or_timeout_based(
1191 &mut self,
1192 context: &mut InterruptContextTimeoutOrMaxSize,
1193 buf: &mut [u8],
1194 ) -> Result<InterruptResultMaxSizeOrTimeout, BufferTooShortError> {
1195 if buf.len() < context.max_len {
1196 return Err(BufferTooShortError {
1197 found: buf.len(),
1198 expected: context.max_len,
1199 });
1200 }
1201 let mut result = InterruptResultMaxSizeOrTimeout::default();
1202
1203 let irq_status = self.0.regs.read_irq_status();
1204 let rx_enabled = self.0.regs.read_enable().rx();
1205
1206 if irq_status.rx() {
1208 let available_bytes = self.0.regs.read_rx_fifo_trigger().level().as_usize();
1213
1214 let bytes_to_read = core::cmp::min(
1215 available_bytes.saturating_sub(1),
1216 context.max_len - context.rx_idx,
1217 );
1218
1219 for _ in 0..bytes_to_read {
1222 buf[context.rx_idx] = (self.0.read_fifo_unchecked() & 0xff) as u8;
1223 context.rx_idx += 1;
1224 }
1225
1226 }
1231 if irq_status.rx_timeout() {
1233 loop {
1235 if context.rx_idx == context.max_len {
1236 break;
1237 }
1238 match self.0.read() {
1240 Ok(byte) => {
1241 buf[context.rx_idx] = byte;
1242 context.rx_idx += 1;
1243 }
1244 Err(_) => break,
1245 }
1246 }
1247 self.irq_completion_handler_max_size_timeout(&mut result, context);
1248 return Ok(result);
1249 }
1250
1251 if (context.rx_idx < context.max_len) && rx_enabled {
1253 self.check_for_errors(&mut result.errors);
1254 }
1255
1256 self.0.regs.write_irq_clr(
1258 InterruptClear::builder()
1259 .with_rx_overrun(true)
1260 .with_tx_overrun(false)
1261 .build(),
1262 );
1263 Ok(result)
1264 }
1265
1266 fn check_for_errors(&self, errors: &mut Option<UartErrors>) {
1267 let rx_status = self.0.regs.read_rx_status();
1268
1269 if rx_status.overrun_error() || rx_status.framing_error() || rx_status.parity_error() {
1270 let err = errors.get_or_insert(UartErrors::default());
1271
1272 if rx_status.overrun_error() {
1273 err.overflow = true;
1274 }
1275 if rx_status.framing_error() {
1276 err.framing = true;
1277 }
1278 if rx_status.parity_error() {
1279 err.parity = true;
1280 }
1281 }
1282 }
1283
1284 fn irq_completion_handler_max_size_timeout(
1285 &mut self,
1286 res: &mut InterruptResultMaxSizeOrTimeout,
1287 context: &mut InterruptContextTimeoutOrMaxSize,
1288 ) {
1289 self.disable_interrupts();
1290 self.0.disable();
1291 res.bytes_read = context.rx_idx;
1292 res.complete = true;
1293 context.mode = InterruptReceptionMode::Idle;
1294 context.rx_idx = 0;
1295 }
1296
1297 pub unsafe fn release(mut self) -> Rx {
1303 self.disable_interrupts();
1304 self.0
1305 }
1306}