aboutsummaryrefslogtreecommitdiff
path: root/src/lpuart/mod.rs
diff options
context:
space:
mode:
authorJanKomarekNXP <[email protected]>2025-12-01 18:07:58 +0100
committerGitHub <[email protected]>2025-12-01 18:07:58 +0100
commit717346f21a4cf4993c2a1f046e26b6bf647d89cb (patch)
tree81dcbf726769eac5726796b340542d661debe407 /src/lpuart/mod.rs
parent3b239cb6de22b7bb8c2d87defb3205294653be7a (diff)
Refactor LPUART driver constructors (#51)
* Refactor LPUART driver constructors - Add new_with_rtscts(), new_with_rts(), new_with_cts() methods - Store RTS/CTS pins in TX/RX structs - Remove enable_tx, enable_rx, enable_rx_rts, enable_tx_cts config fields - Fix typo: msb_firs -> msb_first - Fix write_byte() return type to Result<()> * Update hello example for LPUART driver changes * Refactor buffered LPUART initialization logic - Split new_inner() into init_common() and separate helpers for full-duplex, TX-only, and RX-only - Replace assert!() with proper Error::InvalidArgument returns for empty buffers - Simplify constructor implementations by removing expect() calls
Diffstat (limited to 'src/lpuart/mod.rs')
-rw-r--r--src/lpuart/mod.rs141
1 files changed, 96 insertions, 45 deletions
diff --git a/src/lpuart/mod.rs b/src/lpuart/mod.rs
index 317274a79..2d8308ec8 100644
--- a/src/lpuart/mod.rs
+++ b/src/lpuart/mod.rs
@@ -203,8 +203,8 @@ pub fn clear_all_status_flags(regs: Regs) {
203} 203}
204 204
205/// Configure hardware flow control if enabled 205/// Configure hardware flow control if enabled
206pub fn configure_flow_control(regs: Regs, config: &Config) { 206pub fn configure_flow_control(regs: Regs, enable_tx_cts: bool, enable_rx_rts: bool, config: &Config) {
207 if config.enable_rx_rts || config.enable_tx_cts { 207 if enable_rx_rts || enable_tx_cts {
208 regs.modir().modify(|_, w| { 208 regs.modir().modify(|_, w| {
209 let mut w = w; 209 let mut w = w;
210 210
@@ -212,13 +212,13 @@ pub fn configure_flow_control(regs: Regs, config: &Config) {
212 w = w.txctsc().variant(config.tx_cts_config); 212 w = w.txctsc().variant(config.tx_cts_config);
213 w = w.txctssrc().variant(config.tx_cts_source); 213 w = w.txctssrc().variant(config.tx_cts_source);
214 214
215 if config.enable_rx_rts { 215 if enable_rx_rts {
216 w = w.rxrtse().enabled(); 216 w = w.rxrtse().enabled();
217 } else { 217 } else {
218 w = w.rxrtse().disabled(); 218 w = w.rxrtse().disabled();
219 } 219 }
220 220
221 if config.enable_tx_cts { 221 if enable_tx_cts {
222 w = w.txctse().enabled(); 222 w = w.txctse().enabled();
223 } else { 223 } else {
224 w = w.txctse().disabled(); 224 w = w.txctse().disabled();
@@ -586,17 +586,13 @@ pub struct Config {
586 /// Number of data bits 586 /// Number of data bits
587 pub data_bits_count: DataBits, 587 pub data_bits_count: DataBits,
588 /// MSB First or LSB First configuration 588 /// MSB First or LSB First configuration
589 pub msb_firs: MsbFirst, 589 pub msb_first: MsbFirst,
590 /// Number of stop bits 590 /// Number of stop bits
591 pub stop_bits_count: StopBits, 591 pub stop_bits_count: StopBits,
592 /// TX FIFO watermark 592 /// TX FIFO watermark
593 pub tx_fifo_watermark: u8, 593 pub tx_fifo_watermark: u8,
594 /// RX FIFO watermark 594 /// RX FIFO watermark
595 pub rx_fifo_watermark: u8, 595 pub rx_fifo_watermark: u8,
596 /// RX RTS enable
597 pub enable_rx_rts: bool,
598 /// TX CTS enable
599 pub enable_tx_cts: bool,
600 /// TX CTS source 596 /// TX CTS source
601 pub tx_cts_source: TxCtsSource, 597 pub tx_cts_source: TxCtsSource,
602 /// TX CTS configure 598 /// TX CTS configure
@@ -605,10 +601,6 @@ pub struct Config {
605 pub rx_idle_type: IdleType, 601 pub rx_idle_type: IdleType,
606 /// RX IDLE configuration 602 /// RX IDLE configuration
607 pub rx_idle_config: IdleConfig, 603 pub rx_idle_config: IdleConfig,
608 /// Enable transmitter
609 pub enable_tx: bool,
610 /// Enable receiver
611 pub enable_rx: bool,
612 /// Swap TXD and RXD pins 604 /// Swap TXD and RXD pins
613 pub swap_txd_rxd: bool, 605 pub swap_txd_rxd: bool,
614} 606}
@@ -619,18 +611,14 @@ impl Default for Config {
619 baudrate_bps: 115_200u32, 611 baudrate_bps: 115_200u32,
620 parity_mode: None, 612 parity_mode: None,
621 data_bits_count: DataBits::Data8, 613 data_bits_count: DataBits::Data8,
622 msb_firs: MsbFirst::LsbFirst, 614 msb_first: MsbFirst::LsbFirst,
623 stop_bits_count: StopBits::One, 615 stop_bits_count: StopBits::One,
624 tx_fifo_watermark: 0, 616 tx_fifo_watermark: 0,
625 rx_fifo_watermark: 1, 617 rx_fifo_watermark: 1,
626 enable_rx_rts: false,
627 enable_tx_cts: false,
628 tx_cts_source: TxCtsSource::Cts, 618 tx_cts_source: TxCtsSource::Cts,
629 tx_cts_config: TxCtsConfig::Start, 619 tx_cts_config: TxCtsConfig::Start,
630 rx_idle_type: IdleType::FromStart, 620 rx_idle_type: IdleType::FromStart,
631 rx_idle_config: IdleConfig::Idle1, 621 rx_idle_config: IdleConfig::Idle1,
632 enable_tx: false,
633 enable_rx: false,
634 swap_txd_rxd: false, 622 swap_txd_rxd: false,
635 power: PoweredClock::NormalEnabledDeepSleepDisabled, 623 power: PoweredClock::NormalEnabledDeepSleepDisabled,
636 source: LpuartClockSel::FroLfDiv, 624 source: LpuartClockSel::FroLfDiv,
@@ -694,6 +682,7 @@ pub struct Lpuart<'a, M: Mode> {
694pub struct LpuartTx<'a, M: Mode> { 682pub struct LpuartTx<'a, M: Mode> {
695 info: Info, 683 info: Info,
696 _tx_pin: Peri<'a, AnyPin>, 684 _tx_pin: Peri<'a, AnyPin>,
685 _cts_pin: Option<Peri<'a, AnyPin>>,
697 _tx_dma: Option<Channel<'a>>, 686 _tx_dma: Option<Channel<'a>>,
698 mode: PhantomData<(&'a (), M)>, 687 mode: PhantomData<(&'a (), M)>,
699} 688}
@@ -702,6 +691,7 @@ pub struct LpuartTx<'a, M: Mode> {
702pub struct LpuartRx<'a, M: Mode> { 691pub struct LpuartRx<'a, M: Mode> {
703 info: Info, 692 info: Info,
704 _rx_pin: Peri<'a, AnyPin>, 693 _rx_pin: Peri<'a, AnyPin>,
694 _rts_pin: Option<Peri<'a, AnyPin>>,
705 _rx_dma: Option<Channel<'a>>, 695 _rx_dma: Option<Channel<'a>>,
706 mode: PhantomData<(&'a (), M)>, 696 mode: PhantomData<(&'a (), M)>,
707} 697}
@@ -712,10 +702,10 @@ pub struct LpuartRx<'a, M: Mode> {
712 702
713impl<'a, M: Mode> Lpuart<'a, M> { 703impl<'a, M: Mode> Lpuart<'a, M> {
714 fn init<T: Instance>( 704 fn init<T: Instance>(
715 _tx: Option<&Peri<'a, AnyPin>>, 705 enable_tx: bool,
716 _rx: Option<&Peri<'a, AnyPin>>, 706 enable_rx: bool,
717 _rts: Option<&Peri<'a, AnyPin>>, 707 enable_tx_cts: bool,
718 _cts: Option<&Peri<'a, AnyPin>>, 708 enable_rx_rts: bool,
719 config: Config, 709 config: Config,
720 ) -> Result<()> { 710 ) -> Result<()> {
721 let regs = T::info().regs; 711 let regs = T::info().regs;
@@ -737,9 +727,9 @@ impl<'a, M: Mode> Lpuart<'a, M> {
737 configure_control_settings(regs, &config); 727 configure_control_settings(regs, &config);
738 configure_fifo(regs, &config); 728 configure_fifo(regs, &config);
739 clear_all_status_flags(regs); 729 clear_all_status_flags(regs);
740 configure_flow_control(regs, &config); 730 configure_flow_control(regs, enable_tx_cts, enable_rx_rts, &config);
741 configure_bit_order(regs, config.msb_firs); 731 configure_bit_order(regs, config.msb_first);
742 enable_transceiver(regs, config.enable_tx, config.enable_rx); 732 enable_transceiver(regs, enable_rx, enable_tx);
743 733
744 Ok(()) 734 Ok(())
745 } 735 }
@@ -776,7 +766,7 @@ impl<'a, M: Mode> Lpuart<'a, M> {
776// ============================================================================ 766// ============================================================================
777 767
778impl<'a> Lpuart<'a, Blocking> { 768impl<'a> Lpuart<'a, Blocking> {
779 /// Create a new blocking LPUART instance with TX and RX pins. 769 /// Create a new blocking LPUART instance with RX/TX pins.
780 pub fn new_blocking<T: Instance>( 770 pub fn new_blocking<T: Instance>(
781 _inner: Peri<'a, T>, 771 _inner: Peri<'a, T>,
782 tx_pin: Peri<'a, impl TxPin<T>>, 772 tx_pin: Peri<'a, impl TxPin<T>>,
@@ -787,17 +777,38 @@ impl<'a> Lpuart<'a, Blocking> {
787 tx_pin.as_tx(); 777 tx_pin.as_tx();
788 rx_pin.as_rx(); 778 rx_pin.as_rx();
789 779
790 // Convert pins to AnyPin
791 let tx_pin: Peri<'a, AnyPin> = tx_pin.into();
792 let rx_pin: Peri<'a, AnyPin> = rx_pin.into();
793
794 // Initialize the peripheral 780 // Initialize the peripheral
795 Self::init::<T>(Some(&tx_pin), Some(&rx_pin), None, None, config)?; 781 Self::init::<T>(true, true, false, false, config)?;
796 782
797 Ok(Self { 783 Ok(Self {
798 info: T::info(), 784 info: T::info(),
799 tx: LpuartTx::new_inner(T::info(), tx_pin, None), 785 tx: LpuartTx::new_inner(T::info(), tx_pin.into(), None, None),
800 rx: LpuartRx::new_inner(T::info(), rx_pin, None), 786 rx: LpuartRx::new_inner(T::info(), rx_pin.into(), None, None),
787 })
788 }
789
790 /// Create a new blocking LPUART instance with RX, TX and RTS/CTS flow control pins
791 pub fn new_blocking_with_rtscts<T: Instance>(
792 _inner: Peri<'a, T>,
793 tx_pin: Peri<'a, impl TxPin<T>>,
794 rx_pin: Peri<'a, impl RxPin<T>>,
795 cts_pin: Peri<'a, impl CtsPin<T>>,
796 rts_pin: Peri<'a, impl RtsPin<T>>,
797 config: Config,
798 ) -> Result<Self> {
799 // Configure the pins for LPUART usage
800 rx_pin.as_rx();
801 tx_pin.as_tx();
802 rts_pin.as_rts();
803 cts_pin.as_cts();
804
805 // Initialize the peripheral with flow control
806 Self::init::<T>(true, true, true, true, config)?;
807
808 Ok(Self {
809 info: T::info(),
810 rx: LpuartRx::new_inner(T::info(), rx_pin.into(), Some(rts_pin.into()), None),
811 tx: LpuartTx::new_inner(T::info(), tx_pin.into(), Some(cts_pin.into()), None),
801 }) 812 })
802 } 813 }
803} 814}
@@ -807,10 +818,16 @@ impl<'a> Lpuart<'a, Blocking> {
807// ---------------------------------------------------------------------------- 818// ----------------------------------------------------------------------------
808 819
809impl<'a, M: Mode> LpuartTx<'a, M> { 820impl<'a, M: Mode> LpuartTx<'a, M> {
810 fn new_inner(info: Info, tx_pin: Peri<'a, AnyPin>, tx_dma: Option<Channel<'a>>) -> Self { 821 fn new_inner(
822 info: Info,
823 tx_pin: Peri<'a, AnyPin>,
824 cts_pin: Option<Peri<'a, AnyPin>>,
825 tx_dma: Option<Channel<'a>>,
826 ) -> Self {
811 Self { 827 Self {
812 info, 828 info,
813 _tx_pin: tx_pin, 829 _tx_pin: tx_pin,
830 _cts_pin: cts_pin,
814 _tx_dma: tx_dma, 831 _tx_dma: tx_dma,
815 mode: PhantomData, 832 mode: PhantomData,
816 } 833 }
@@ -818,19 +835,34 @@ impl<'a, M: Mode> LpuartTx<'a, M> {
818} 835}
819 836
820impl<'a> LpuartTx<'a, Blocking> { 837impl<'a> LpuartTx<'a, Blocking> {
821 /// Create a new blocking LPUART which can only send data. 838 /// Create a new blocking LPUART transmitter instance
822 pub fn new_blocking<T: Instance>( 839 pub fn new_blocking<T: Instance>(
823 _inner: Peri<'a, T>, 840 _inner: Peri<'a, T>,
824 tx_pin: Peri<'a, impl TxPin<T>>, 841 tx_pin: Peri<'a, impl TxPin<T>>,
825 config: Config, 842 config: Config,
826 ) -> Result<Self> { 843 ) -> Result<Self> {
844 // Configure the pins for LPUART usage
827 tx_pin.as_tx(); 845 tx_pin.as_tx();
828 846
829 let tx_pin: Peri<'a, AnyPin> = tx_pin.into(); 847 // Initialize the peripheral
848 Lpuart::<Blocking>::init::<T>(true, false, false, false, config)?;
849
850 Ok(Self::new_inner(T::info(), tx_pin.into(), None, None))
851 }
852
853 /// Create a new blocking LPUART transmitter instance with CTS flow control
854 pub fn new_blocking_with_cts<T: Instance>(
855 _inner: Peri<'a, T>,
856 tx_pin: Peri<'a, impl TxPin<T>>,
857 cts_pin: Peri<'a, impl CtsPin<T>>,
858 config: Config,
859 ) -> Result<Self> {
860 tx_pin.as_tx();
861 cts_pin.as_cts();
830 862
831 Lpuart::<Blocking>::init::<T>(Some(&tx_pin), None, None, None, config)?; 863 Lpuart::<Blocking>::init::<T>(true, false, true, false, config)?;
832 864
833 Ok(Self::new_inner(T::info(), tx_pin, None)) 865 Ok(Self::new_inner(T::info(), tx_pin.into(), Some(cts_pin.into()), None))
834 } 866 }
835 867
836 fn write_byte_internal(&mut self, byte: u8) -> Result<()> { 868 fn write_byte_internal(&mut self, byte: u8) -> Result<()> {
@@ -909,10 +941,16 @@ impl<'a> LpuartTx<'a, Blocking> {
909// ---------------------------------------------------------------------------- 941// ----------------------------------------------------------------------------
910 942
911impl<'a, M: Mode> LpuartRx<'a, M> { 943impl<'a, M: Mode> LpuartRx<'a, M> {
912 fn new_inner(info: Info, rx_pin: Peri<'a, AnyPin>, rx_dma: Option<Channel<'a>>) -> Self { 944 fn new_inner(
945 info: Info,
946 rx_pin: Peri<'a, AnyPin>,
947 rts_pin: Option<Peri<'a, AnyPin>>,
948 rx_dma: Option<Channel<'a>>,
949 ) -> Self {
913 Self { 950 Self {
914 info, 951 info,
915 _rx_pin: rx_pin, 952 _rx_pin: rx_pin,
953 _rts_pin: rts_pin,
916 _rx_dma: rx_dma, 954 _rx_dma: rx_dma,
917 mode: PhantomData, 955 mode: PhantomData,
918 } 956 }
@@ -920,7 +958,7 @@ impl<'a, M: Mode> LpuartRx<'a, M> {
920} 958}
921 959
922impl<'a> LpuartRx<'a, Blocking> { 960impl<'a> LpuartRx<'a, Blocking> {
923 /// Create a new blocking LPUART which can only receive data. 961 /// Create a new blocking LPUART Receiver instance
924 pub fn new_blocking<T: Instance>( 962 pub fn new_blocking<T: Instance>(
925 _inner: Peri<'a, T>, 963 _inner: Peri<'a, T>,
926 rx_pin: Peri<'a, impl RxPin<T>>, 964 rx_pin: Peri<'a, impl RxPin<T>>,
@@ -928,11 +966,24 @@ impl<'a> LpuartRx<'a, Blocking> {
928 ) -> Result<Self> { 966 ) -> Result<Self> {
929 rx_pin.as_rx(); 967 rx_pin.as_rx();
930 968
931 let rx_pin: Peri<'a, AnyPin> = rx_pin.into(); 969 Lpuart::<Blocking>::init::<T>(false, true, false, false, config)?;
970
971 Ok(Self::new_inner(T::info(), rx_pin.into(), None, None))
972 }
973
974 /// Create a new blocking LPUART Receiver instance with RTS flow control
975 pub fn new_blocking_with_rts<T: Instance>(
976 _inner: Peri<'a, T>,
977 rx_pin: Peri<'a, impl RxPin<T>>,
978 rts_pin: Peri<'a, impl RtsPin<T>>,
979 config: Config,
980 ) -> Result<Self> {
981 rx_pin.as_rx();
982 rts_pin.as_rts();
932 983
933 Lpuart::<Blocking>::init::<T>(None, Some(&rx_pin), None, None, config)?; 984 Lpuart::<Blocking>::init::<T>(false, true, false, true, config)?;
934 985
935 Ok(Self::new_inner(T::info(), rx_pin, None)) 986 Ok(Self::new_inner(T::info(), rx_pin.into(), Some(rts_pin.into()), None))
936 } 987 }
937 988
938 fn read_byte_internal(&mut self) -> Result<u8> { 989 fn read_byte_internal(&mut self) -> Result<u8> {
@@ -994,8 +1045,8 @@ impl<'a> Lpuart<'a, Blocking> {
994 self.tx.blocking_write(buf) 1045 self.tx.blocking_write(buf)
995 } 1046 }
996 1047
997 pub fn write_byte(&mut self, byte: u8) { 1048 pub fn write_byte(&mut self, byte: u8) -> Result<()> {
998 _ = self.tx.write_byte(byte); 1049 self.tx.write_byte(byte)
999 } 1050 }
1000 1051
1001 pub fn read_byte_blocking(&mut self) -> u8 { 1052 pub fn read_byte_blocking(&mut self) -> u8 {