1#![doc = crate::before_snippet!()]
18#![doc = crate::before_snippet!()]
75use core::{
127 mem::ManuallyDrop,
128 ops::{Deref, DerefMut},
129};
130
131use enumset::{EnumSet, EnumSetType};
132use private::*;
133
134use crate::{
135 Async,
136 Blocking,
137 DriverMode,
138 dma::{
139 Channel,
140 ChannelRx,
141 ChannelTx,
142 DmaChannelFor,
143 DmaError,
144 DmaPeripheral,
145 DmaRxBuffer,
146 DmaTxBuffer,
147 PeripheralRxChannel,
148 PeripheralTxChannel,
149 },
150 gpio::{
151 self,
152 InputSignal,
153 NoPin,
154 OutputSignal,
155 interconnect::{self, PeripheralInput, PeripheralOutput},
156 },
157 interrupt::InterruptHandler,
158 parl_io::asynch::interrupt_handler,
159 peripherals::{Interrupt, PARL_IO, PCR},
160 system::{self, GenericPeripheralGuard},
161 time::Rate,
162};
163
164const MAX_DMA_SIZE: usize = 65535;
165
166#[derive(Debug, EnumSetType)]
168#[cfg_attr(feature = "defmt", derive(defmt::Format))]
169pub enum ParlIoInterrupt {
170 TxFifoReEmpty,
173 RxFifoWOvf,
176 TxEof,
178}
179
180#[derive(Debug, Clone, Copy, PartialEq)]
182#[cfg_attr(feature = "defmt", derive(defmt::Format))]
183#[allow(clippy::enum_variant_names, reason = "peripheral is unstable")]
184pub enum Error {
185 DmaError(DmaError),
187 MaxDmaTransferSizeExceeded,
189}
190
191impl From<DmaError> for Error {
192 fn from(value: DmaError) -> Self {
193 Error::DmaError(value)
194 }
195}
196
197#[derive(Debug, Clone, Copy, PartialEq)]
199#[cfg_attr(feature = "defmt", derive(defmt::Format))]
200pub enum SampleEdge {
201 Normal = 0,
203 Invert = 1,
205}
206
207#[derive(Debug, Clone, Copy, PartialEq)]
209#[cfg_attr(feature = "defmt", derive(defmt::Format))]
210pub enum BitPackOrder {
211 Msb = 0,
213 Lsb = 1,
215}
216
217#[cfg(esp32c6)]
218#[derive(Debug, Clone, Copy, PartialEq)]
220#[cfg_attr(feature = "defmt", derive(defmt::Format))]
221pub enum EnableMode {
222 HighLevel,
224 LowLevel,
226 PulseMode1,
229 PulseMode2,
232 PulseMode3,
235 PulseMode4,
238 PulseMode5,
240 PulseMode6,
242 PulseMode7,
245 PulseMode8,
248 PulseMode9,
251 PulseMode10,
254 PulseMode11,
256 PulseMode12,
258}
259
260#[cfg(esp32c6)]
261impl EnableMode {
262 fn pulse_submode_sel(&self) -> Option<u8> {
263 match self {
264 EnableMode::PulseMode1 => Some(0),
265 EnableMode::PulseMode2 => Some(1),
266 EnableMode::PulseMode3 => Some(2),
267 EnableMode::PulseMode4 => Some(3),
268 EnableMode::PulseMode5 => Some(4),
269 EnableMode::PulseMode6 => Some(5),
270 EnableMode::PulseMode7 => Some(6),
271 EnableMode::PulseMode8 => Some(7),
272 EnableMode::PulseMode9 => Some(8),
273 EnableMode::PulseMode10 => Some(9),
274 EnableMode::PulseMode11 => Some(10),
275 EnableMode::PulseMode12 => Some(11),
276 _ => None,
277 }
278 }
279
280 fn level_submode_sel(&self) -> Option<u8> {
281 match self {
282 EnableMode::HighLevel => Some(0),
283 EnableMode::LowLevel => Some(1),
284 _ => None,
285 }
286 }
287
288 fn smp_model_sel(&self) -> Option<self::private::SampleMode> {
289 match self {
290 EnableMode::HighLevel => Some(self::private::SampleMode::ExternalLevel),
291 EnableMode::LowLevel => Some(self::private::SampleMode::ExternalLevel),
292 _ => Some(self::private::SampleMode::ExternalPulse),
293 }
294 }
295}
296
297#[cfg(esp32h2)]
298#[derive(Debug, Clone, Copy, PartialEq)]
300#[cfg_attr(feature = "defmt", derive(defmt::Format))]
301pub enum EnableMode {
302 HighLevel,
304 PulseMode1,
307 PulseMode2,
310 PulseMode3,
313 PulseMode4,
316 PulseMode5,
318 PulseMode6,
320}
321
322#[cfg(esp32h2)]
323impl EnableMode {
324 fn pulse_submode_sel(&self) -> Option<u8> {
325 match self {
326 EnableMode::PulseMode1 => Some(0),
327 EnableMode::PulseMode2 => Some(1),
328 EnableMode::PulseMode3 => Some(2),
329 EnableMode::PulseMode4 => Some(3),
330 EnableMode::PulseMode5 => Some(4),
331 EnableMode::PulseMode6 => Some(5),
332 _ => None,
333 }
334 }
335
336 fn level_submode_sel(&self) -> Option<u8> {
337 match self {
338 EnableMode::HighLevel => Some(0),
339 _ => None,
340 }
341 }
342
343 fn smp_model_sel(&self) -> Option<self::private::SampleMode> {
344 match self {
345 EnableMode::HighLevel => Some(self::private::SampleMode::ExternalLevel),
346 _ => Some(self::private::SampleMode::ExternalPulse),
347 }
348 }
349}
350
351#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
353#[cfg_attr(feature = "defmt", derive(defmt::Format))]
354#[non_exhaustive]
355pub struct RxConfig {
356 frequency: Rate,
358
359 bit_order: BitPackOrder,
362
363 timeout_ticks: Option<u16>,
370}
371
372impl Default for RxConfig {
373 fn default() -> Self {
374 Self {
375 frequency: Rate::from_khz(100),
376 bit_order: BitPackOrder::Msb,
377 timeout_ticks: None,
378 }
379 }
380}
381
382#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
384#[cfg_attr(feature = "defmt", derive(defmt::Format))]
385#[non_exhaustive]
386pub struct TxConfig {
387 frequency: Rate,
389
390 idle_value: u16,
392
393 sample_edge: SampleEdge,
395
396 bit_order: BitPackOrder,
399}
400
401impl Default for TxConfig {
402 fn default() -> Self {
403 Self {
404 frequency: Rate::from_khz(100),
405 idle_value: 0,
406 sample_edge: SampleEdge::Normal,
407 bit_order: BitPackOrder::Msb,
408 }
409 }
410}
411
412#[non_exhaustive]
414#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
415#[cfg_attr(feature = "defmt", derive(defmt::Format))]
416pub enum ConfigError {
417 UnreachableClockRate,
419}
420
421impl core::error::Error for ConfigError {}
422
423impl core::fmt::Display for ConfigError {
424 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
425 match self {
426 ConfigError::UnreachableClockRate => {
427 write!(f, "The requested frequency is not supported")
428 }
429 }
430 }
431}
432
433impl TxClkPin for NoPin {
435 fn configure(&mut self) {
436 OutputSignal::PARL_TX_CLK.connect_to(self);
437 }
438}
439impl RxClkPin for NoPin {
440 fn configure(&mut self) {
441 InputSignal::PARL_RX_CLK.connect_to(self);
442 }
443}
444
445pub struct ClkOutPin<'d> {
447 pin: interconnect::OutputSignal<'d>,
448}
449impl<'d> ClkOutPin<'d> {
450 pub fn new(pin: impl PeripheralOutput<'d>) -> Self {
452 Self { pin: pin.into() }
453 }
454}
455impl TxClkPin for ClkOutPin<'_> {
456 fn configure(&mut self) {
457 self.pin.apply_output_config(&gpio::OutputConfig::default());
458 self.pin.set_output_enable(true);
459
460 OutputSignal::PARL_TX_CLK.connect_to(&self.pin);
461 }
462}
463
464pub struct ClkInPin<'d> {
466 pin: interconnect::InputSignal<'d>,
467}
468impl<'d> ClkInPin<'d> {
469 pub fn new(pin: impl PeripheralInput<'d>) -> Self {
471 Self { pin: pin.into() }
472 }
473}
474impl TxClkPin for ClkInPin<'_> {
475 fn configure(&mut self) {
476 let pcr = PCR::regs();
477 pcr.parl_clk_tx_conf()
478 .modify(|_, w| unsafe { w.parl_clk_tx_sel().bits(3).parl_clk_tx_div_num().bits(0) }); self.pin.apply_input_config(&gpio::InputConfig::default());
481 self.pin.set_input_enable(true);
482 InputSignal::PARL_TX_CLK.connect_to(&self.pin);
483 }
484}
485
486pub struct RxClkInPin<'d> {
488 pin: interconnect::InputSignal<'d>,
489 sample_edge: SampleEdge,
490}
491impl<'d> RxClkInPin<'d> {
492 pub fn new(pin: impl PeripheralInput<'d>, sample_edge: SampleEdge) -> Self {
494 Self {
495 pin: pin.into(),
496 sample_edge,
497 }
498 }
499}
500impl RxClkPin for RxClkInPin<'_> {
501 fn configure(&mut self) {
502 let pcr = PCR::regs();
503 pcr.parl_clk_rx_conf()
504 .modify(|_, w| unsafe { w.parl_clk_rx_sel().bits(3).parl_clk_rx_div_num().bits(0) }); self.pin.apply_input_config(&gpio::InputConfig::default());
507 self.pin.set_input_enable(true);
508
509 InputSignal::PARL_RX_CLK.connect_to(&self.pin);
510
511 Instance::set_rx_clk_edge_sel(self.sample_edge);
512 }
513}
514
515pub struct TxPinConfigWithValidPin<'d, P>
517where
518 P: NotContainsValidSignalPin + TxPins + ConfigurePins + 'd,
519{
520 tx_pins: P,
521 valid_pin: interconnect::OutputSignal<'d>,
522}
523
524impl<'d, P> TxPinConfigWithValidPin<'d, P>
525where
526 P: NotContainsValidSignalPin + TxPins + ConfigurePins + 'd,
527{
528 pub fn new(tx_pins: P, valid_pin: impl PeripheralOutput<'d>) -> Self {
530 Self {
531 tx_pins,
532 valid_pin: valid_pin.into(),
533 }
534 }
535}
536
537impl<'d, P> TxPins for TxPinConfigWithValidPin<'d, P> where
538 P: NotContainsValidSignalPin + TxPins + ConfigurePins + 'd
539{
540}
541
542impl<'d, P> ConfigurePins for TxPinConfigWithValidPin<'d, P>
543where
544 P: NotContainsValidSignalPin + TxPins + ConfigurePins + 'd,
545{
546 fn configure(&mut self) {
547 self.tx_pins.configure();
548
549 self.valid_pin
550 .apply_output_config(&gpio::OutputConfig::default());
551 self.valid_pin.set_output_enable(true);
552
553 Instance::tx_valid_pin_signal().connect_to(&self.valid_pin);
554 Instance::set_tx_hw_valid_en(true);
555 }
556}
557
558pub struct TxPinConfigIncludingValidPin<P>
560where
561 P: ContainsValidSignalPin + TxPins + ConfigurePins,
562{
563 tx_pins: P,
564}
565
566impl<P> TxPinConfigIncludingValidPin<P>
567where
568 P: ContainsValidSignalPin + TxPins + ConfigurePins,
569{
570 pub fn new(tx_pins: P) -> Self {
572 Self { tx_pins }
573 }
574}
575
576impl<P> TxPins for TxPinConfigIncludingValidPin<P> where
577 P: ContainsValidSignalPin + TxPins + ConfigurePins
578{
579}
580
581impl<P> ConfigurePins for TxPinConfigIncludingValidPin<P>
582where
583 P: ContainsValidSignalPin + TxPins + ConfigurePins,
584{
585 fn configure(&mut self) {
586 self.tx_pins.configure();
587 Instance::set_tx_hw_valid_en(true);
588 }
589}
590
591macro_rules! tx_pins {
592 ($name:ident, $width:literal, $($pin:ident = $signal:ident),+ ) => {
593 paste::paste! {
594 #[doc = "Data pin configuration for "]
595 #[doc = stringify!($width)]
596 #[doc = "bit output mode"]
597 pub struct $name<'d> {
598 $(
599 [< pin_ $pin:lower >] : interconnect::OutputSignal<'d>,
600 )+
601 }
602
603 impl<'d> $name<'d>
604 {
605 #[allow(clippy::too_many_arguments)]
607 pub fn new(
608 $(
609 [< pin_ $pin:lower >] : impl PeripheralOutput<'d>,
610 )+
611 ) -> Self {
612 Self { $( [< pin_ $pin:lower >]: [< pin_ $pin:lower >].into() ),+ }
613 }
614 }
615
616 impl ConfigurePins for $name<'_>
617 {
618 fn configure(&mut self) {
619 $(
620 self.[< pin_ $pin:lower >].apply_output_config(&gpio::OutputConfig::default());
621 self.[< pin_ $pin:lower >].set_output_enable(true);
622
623 OutputSignal::$signal.connect_to(&mut self.[< pin_ $pin:lower >]);
624 )+
625
626 private::Instance::set_tx_bit_width( private::WidSel::[< Bits $width >]);
627 }
628 }
629
630 impl TxPins for $name<'_> {}
631 }
632 };
633}
634
635tx_pins!(TxOneBit, 1, P0 = PARL_TX_DATA0);
636tx_pins!(TxTwoBits, 2, P0 = PARL_TX_DATA0, P1 = PARL_TX_DATA1);
637tx_pins!(
638 TxFourBits,
639 4,
640 P0 = PARL_TX_DATA0,
641 P1 = PARL_TX_DATA1,
642 P2 = PARL_TX_DATA2,
643 P3 = PARL_TX_DATA3
644);
645tx_pins!(
646 TxEightBits,
647 8,
648 P0 = PARL_TX_DATA0,
649 P1 = PARL_TX_DATA1,
650 P2 = PARL_TX_DATA2,
651 P3 = PARL_TX_DATA3,
652 P4 = PARL_TX_DATA4,
653 P5 = PARL_TX_DATA5,
654 P6 = PARL_TX_DATA6,
655 P7 = PARL_TX_DATA7
656);
657#[cfg(esp32c6)]
658tx_pins!(
659 TxSixteenBits,
660 16,
661 P0 = PARL_TX_DATA0,
662 P1 = PARL_TX_DATA1,
663 P2 = PARL_TX_DATA2,
664 P3 = PARL_TX_DATA3,
665 P4 = PARL_TX_DATA4,
666 P5 = PARL_TX_DATA5,
667 P6 = PARL_TX_DATA6,
668 P7 = PARL_TX_DATA7,
669 P8 = PARL_TX_DATA8,
670 P9 = PARL_TX_DATA9,
671 P10 = PARL_TX_DATA10,
672 P11 = PARL_TX_DATA11,
673 P12 = PARL_TX_DATA12,
674 P13 = PARL_TX_DATA13,
675 P14 = PARL_TX_DATA14,
676 P15 = PARL_TX_DATA15
677);
678
679impl NotContainsValidSignalPin for TxOneBit<'_> {}
680impl NotContainsValidSignalPin for TxTwoBits<'_> {}
681impl NotContainsValidSignalPin for TxFourBits<'_> {}
682
683#[cfg(esp32c6)]
684impl NotContainsValidSignalPin for TxEightBits<'_> {}
685
686#[cfg(esp32h2)]
687impl ContainsValidSignalPin for TxEightBits<'_> {}
688
689#[cfg(esp32c6)]
690impl ContainsValidSignalPin for TxSixteenBits<'_> {}
691
692pub struct RxPinConfigWithValidPin<'d, P>
694where
695 P: NotContainsValidSignalPin + RxPins + ConfigurePins,
696{
697 rx_pins: P,
698 valid_pin: interconnect::InputSignal<'d>,
699 enable_mode: EnableMode,
700}
701
702impl<'d, P> RxPinConfigWithValidPin<'d, P>
703where
704 P: NotContainsValidSignalPin + RxPins + ConfigurePins,
705{
706 pub fn new(rx_pins: P, valid_pin: impl PeripheralInput<'d>, enable_mode: EnableMode) -> Self {
708 Self {
709 rx_pins,
710 valid_pin: valid_pin.into(),
711 enable_mode,
712 }
713 }
714}
715
716impl<P> RxPins for RxPinConfigWithValidPin<'_, P> where
717 P: NotContainsValidSignalPin + RxPins + ConfigurePins
718{
719}
720
721impl<P> ConfigurePins for RxPinConfigWithValidPin<'_, P>
722where
723 P: NotContainsValidSignalPin + RxPins + ConfigurePins,
724{
725 fn configure(&mut self) {
726 self.rx_pins.configure();
727
728 self.valid_pin
729 .apply_input_config(&gpio::InputConfig::default());
730 self.valid_pin.set_input_enable(true);
731
732 Instance::rx_valid_pin_signal().connect_to(&self.valid_pin);
733 Instance::set_rx_sw_en(false);
734 if let Some(sel) = self.enable_mode.pulse_submode_sel() {
735 Instance::set_rx_pulse_submode_sel(sel);
736 }
737 if let Some(sel) = self.enable_mode.level_submode_sel() {
738 Instance::set_rx_level_submode_sel(sel);
739 }
740 if let Some(sel) = self.enable_mode.smp_model_sel() {
741 Instance::set_rx_sample_mode(sel);
742 }
743 }
744}
745
746pub struct RxPinConfigIncludingValidPin<P>
748where
749 P: ContainsValidSignalPin + RxPins + ConfigurePins,
750{
751 rx_pins: P,
752 enable_mode: EnableMode,
753}
754
755impl<P> RxPinConfigIncludingValidPin<P>
756where
757 P: ContainsValidSignalPin + RxPins + ConfigurePins,
758{
759 pub fn new(rx_pins: P, enable_mode: EnableMode) -> Self {
761 Self {
762 rx_pins,
763 enable_mode,
764 }
765 }
766}
767
768impl<P> RxPins for RxPinConfigIncludingValidPin<P> where
769 P: ContainsValidSignalPin + RxPins + ConfigurePins
770{
771}
772
773impl<P> ConfigurePins for RxPinConfigIncludingValidPin<P>
774where
775 P: ContainsValidSignalPin + RxPins + ConfigurePins,
776{
777 fn configure(&mut self) {
778 self.rx_pins.configure();
779 Instance::set_rx_sw_en(false);
780 if let Some(sel) = self.enable_mode.pulse_submode_sel() {
781 Instance::set_rx_pulse_submode_sel(sel);
782 }
783 if let Some(sel) = self.enable_mode.level_submode_sel() {
784 Instance::set_rx_level_submode_sel(sel);
785 }
786 if let Some(sel) = self.enable_mode.smp_model_sel() {
787 Instance::set_rx_sample_mode(sel);
788 }
789 }
790}
791
792macro_rules! rx_pins {
793 ($name:ident, $width:literal, $($pin:ident = $signal:ident),+ ) => {
794 paste::paste! {
795 #[doc = "Data pin configuration for "]
796 #[doc = stringify!($width)]
797 #[doc = "bit input mode"]
798 pub struct $name<'d> {
799 $(
800 [< pin_ $pin:lower >] : interconnect::InputSignal<'d>,
801 )+
802 }
803
804 impl<'d> $name<'d>
805 {
806 #[allow(clippy::too_many_arguments)]
808 pub fn new(
809 $(
810 [< pin_ $pin:lower >] : impl PeripheralInput<'d>,
811 )+
812 ) -> Self {
813 Self { $( [< pin_ $pin:lower >]: [< pin_ $pin:lower >].into() ),+ }
814 }
815 }
816
817 impl ConfigurePins for $name<'_>
818 {
819 fn configure(&mut self) {
820 $(
821 self.[< pin_ $pin:lower >].apply_input_config(&gpio::InputConfig::default());
822 self.[< pin_ $pin:lower >].set_input_enable(true);
823 InputSignal::$signal.connect_to(&self.[< pin_ $pin:lower >]);
824 )+
825
826 private::Instance::set_rx_bit_width( private::WidSel::[< Bits $width >]);
827 }
828 }
829
830 impl RxPins for $name<'_> {}
831 }
832 };
833}
834
835rx_pins!(RxOneBit, 1, P0 = PARL_RX_DATA0);
836rx_pins!(RxTwoBits, 2, P0 = PARL_RX_DATA0, P1 = PARL_RX_DATA1);
837rx_pins!(
838 RxFourBits,
839 4,
840 P0 = PARL_RX_DATA0,
841 P1 = PARL_RX_DATA1,
842 P2 = PARL_RX_DATA2,
843 P3 = PARL_RX_DATA3
844);
845rx_pins!(
846 RxEightBits,
847 8,
848 P0 = PARL_RX_DATA0,
849 P1 = PARL_RX_DATA1,
850 P2 = PARL_RX_DATA2,
851 P3 = PARL_RX_DATA3,
852 P4 = PARL_RX_DATA4,
853 P5 = PARL_RX_DATA5,
854 P6 = PARL_RX_DATA6,
855 P7 = PARL_RX_DATA7
856);
857#[cfg(esp32c6)]
858rx_pins!(
859 RxSixteenBits,
860 16,
861 P0 = PARL_RX_DATA0,
862 P1 = PARL_RX_DATA1,
863 P2 = PARL_RX_DATA2,
864 P3 = PARL_RX_DATA3,
865 P4 = PARL_RX_DATA4,
866 P5 = PARL_RX_DATA5,
867 P6 = PARL_RX_DATA6,
868 P7 = PARL_RX_DATA7,
869 P8 = PARL_RX_DATA8,
870 P9 = PARL_RX_DATA9,
871 P10 = PARL_RX_DATA10,
872 P11 = PARL_RX_DATA11,
873 P12 = PARL_RX_DATA12,
874 P13 = PARL_RX_DATA13,
875 P14 = PARL_RX_DATA14,
876 P15 = PARL_RX_DATA15
877);
878
879impl NotContainsValidSignalPin for RxOneBit<'_> {}
880impl NotContainsValidSignalPin for RxTwoBits<'_> {}
881impl NotContainsValidSignalPin for RxFourBits<'_> {}
882
883#[cfg(esp32c6)]
884impl NotContainsValidSignalPin for RxEightBits<'_> {}
885
886#[cfg(esp32h2)]
887impl ContainsValidSignalPin for RxEightBits<'_> {}
888
889#[cfg(esp32c6)]
890impl ContainsValidSignalPin for RxSixteenBits<'_> {}
891
892impl<'d, Dm> TxCreator<'d, Dm>
893where
894 Dm: DriverMode,
895{
896 pub fn with_config<P, CP>(
898 self,
899 mut tx_pins: P,
900 mut clk_pin: CP,
901 config: TxConfig,
902 ) -> Result<ParlIoTx<'d, Dm>, ConfigError>
903 where
904 P: TxPins + ConfigurePins + 'd,
905 CP: TxClkPin + 'd,
906 {
907 tx_pins.configure();
908 clk_pin.configure();
909
910 let mut this = ParlIoTx {
911 tx_channel: self.tx_channel,
912 _guard: self._guard,
913 };
914 this.apply_config(&config)?;
915
916 Ok(this)
917 }
918}
919
920#[instability::unstable]
922pub struct ParlIoTx<'d, Dm>
923where
924 Dm: DriverMode,
925{
926 tx_channel: ChannelTx<Dm, PeripheralTxChannel<PARL_IO<'d>>>,
927 _guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
928}
929
930impl<Dm> core::fmt::Debug for ParlIoTx<'_, Dm>
931where
932 Dm: DriverMode,
933{
934 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
935 f.debug_struct("ParlIoTx").finish()
936 }
937}
938
939impl<'d, Dm> RxCreator<'d, Dm>
940where
941 Dm: DriverMode,
942{
943 pub fn with_config<P, CP>(
945 self,
946 mut rx_pins: P,
947 mut clk_pin: CP,
948 config: RxConfig,
949 ) -> Result<ParlIoRx<'d, Dm>, ConfigError>
950 where
951 P: RxPins + ConfigurePins + 'd,
952 CP: RxClkPin + 'd,
953 {
954 Instance::set_rx_sw_en(true);
955 Instance::set_rx_sample_mode(SampleMode::InternalSoftwareEnable);
956
957 rx_pins.configure();
958 clk_pin.configure();
959
960 let mut this = ParlIoRx {
961 rx_channel: self.rx_channel,
962 _guard: self._guard,
963 };
964 this.apply_config(&config)?;
965
966 Ok(this)
967 }
968}
969
970#[instability::unstable]
972pub struct ParlIoRx<'d, Dm>
973where
974 Dm: DriverMode,
975{
976 rx_channel: ChannelRx<Dm, PeripheralRxChannel<PARL_IO<'d>>>,
977 _guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
978}
979
980impl<Dm> core::fmt::Debug for ParlIoRx<'_, Dm>
981where
982 Dm: DriverMode,
983{
984 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
985 f.debug_struct("ParlIoTx").finish()
986 }
987}
988
989fn internal_set_interrupt_handler(handler: InterruptHandler) {
990 let mut peri = unsafe { PARL_IO::steal() };
991 #[cfg(esp32c6)]
992 {
993 for core in crate::system::Cpu::other() {
994 crate::interrupt::disable(core, Interrupt::PARL_IO);
995 }
996 internal_listen(EnumSet::all(), false);
997 internal_clear_interrupts(EnumSet::all());
998 peri.bind_parl_io_interrupt(handler.handler());
999
1000 unwrap!(crate::interrupt::enable(
1001 Interrupt::PARL_IO,
1002 handler.priority()
1003 ));
1004 }
1005 #[cfg(esp32h2)]
1006 {
1007 for core in crate::system::Cpu::other() {
1008 crate::interrupt::disable(core, Interrupt::PARL_IO_RX);
1009 crate::interrupt::disable(core, Interrupt::PARL_IO_TX);
1010 }
1011 internal_listen(EnumSet::all(), false);
1012 internal_clear_interrupts(EnumSet::all());
1013 peri.bind_parl_io_tx_interrupt(handler.handler());
1014 peri.bind_parl_io_rx_interrupt(handler.handler());
1015
1016 unwrap!(crate::interrupt::enable(
1017 Interrupt::PARL_IO_TX,
1018 handler.priority(),
1019 ));
1020 unwrap!(crate::interrupt::enable(
1021 Interrupt::PARL_IO_RX,
1022 handler.priority(),
1023 ));
1024 }
1025}
1026
1027fn internal_listen(interrupts: EnumSet<ParlIoInterrupt>, enable: bool) {
1028 PARL_IO::regs().int_ena().write(|w| {
1029 for interrupt in interrupts {
1030 match interrupt {
1031 ParlIoInterrupt::TxFifoReEmpty => w.tx_fifo_rempty().bit(enable),
1032 ParlIoInterrupt::RxFifoWOvf => w.rx_fifo_wovf().bit(enable),
1033 ParlIoInterrupt::TxEof => w.tx_eof().bit(enable),
1034 };
1035 }
1036 w
1037 });
1038}
1039
1040fn internal_interrupts() -> EnumSet<ParlIoInterrupt> {
1041 let mut res = EnumSet::new();
1042 let parl_io = PARL_IO::regs();
1043 let ints = parl_io.int_st().read();
1044 if ints.tx_fifo_rempty().bit() {
1045 res.insert(ParlIoInterrupt::TxFifoReEmpty);
1046 }
1047 if ints.rx_fifo_wovf().bit() {
1048 res.insert(ParlIoInterrupt::RxFifoWOvf);
1049 }
1050 if ints.tx_eof().bit() {
1051 res.insert(ParlIoInterrupt::TxEof);
1052 }
1053
1054 res
1055}
1056
1057fn internal_clear_interrupts(interrupts: EnumSet<ParlIoInterrupt>) {
1058 let parl_io = PARL_IO::regs();
1059 parl_io.int_clr().write(|w| {
1060 for interrupt in interrupts {
1061 match interrupt {
1062 ParlIoInterrupt::TxFifoReEmpty => w.tx_fifo_rempty().clear_bit_by_one(),
1063 ParlIoInterrupt::RxFifoWOvf => w.rx_fifo_wovf().clear_bit_by_one(),
1064 ParlIoInterrupt::TxEof => w.tx_eof().clear_bit_by_one(),
1065 };
1066 }
1067 w
1068 });
1069}
1070
1071pub struct ParlIo<'d, Dm>
1073where
1074 Dm: DriverMode,
1075{
1076 pub tx: TxCreator<'d, Dm>,
1079 pub rx: RxCreator<'d, Dm>,
1082}
1083
1084impl<'d> ParlIo<'d, Blocking> {
1085 pub fn new(
1087 _parl_io: PARL_IO<'d>,
1088 dma_channel: impl DmaChannelFor<PARL_IO<'d>>,
1089 ) -> Result<Self, Error> {
1090 let tx_guard = GenericPeripheralGuard::new();
1091 let rx_guard = GenericPeripheralGuard::new();
1092 let dma_channel = Channel::new(dma_channel.degrade());
1093
1094 Ok(Self {
1095 tx: TxCreator {
1096 tx_channel: dma_channel.tx,
1097 _guard: tx_guard,
1098 },
1099 rx: RxCreator {
1100 rx_channel: dma_channel.rx,
1101 _guard: rx_guard,
1102 },
1103 })
1104 }
1105
1106 pub fn into_async(self) -> ParlIo<'d, Async> {
1108 for core in crate::system::Cpu::other() {
1109 #[cfg(esp32c6)]
1110 {
1111 crate::interrupt::disable(core, Interrupt::PARL_IO);
1112 }
1113 #[cfg(esp32h2)]
1114 {
1115 crate::interrupt::disable(core, Interrupt::PARL_IO_RX);
1116 crate::interrupt::disable(core, Interrupt::PARL_IO_TX);
1117 }
1118 }
1119
1120 #[cfg(esp32c6)]
1121 {
1122 unsafe {
1123 crate::interrupt::bind_interrupt(Interrupt::PARL_IO, interrupt_handler.handler());
1124 }
1125 unwrap!(crate::interrupt::enable(
1126 Interrupt::PARL_IO,
1127 interrupt_handler.priority()
1128 ));
1129 }
1130 #[cfg(esp32h2)]
1131 {
1132 unsafe {
1133 crate::interrupt::bind_interrupt(
1134 Interrupt::PARL_IO_TX,
1135 interrupt_handler.handler(),
1136 );
1137 }
1138 unwrap!(crate::interrupt::enable(
1139 Interrupt::PARL_IO_TX,
1140 interrupt_handler.priority()
1141 ));
1142 }
1143
1144 ParlIo {
1145 tx: TxCreator {
1146 tx_channel: self.tx.tx_channel.into_async(),
1147 _guard: self.tx._guard,
1148 },
1149 rx: RxCreator {
1150 rx_channel: self.rx.rx_channel.into_async(),
1151 _guard: self.rx._guard,
1152 },
1153 }
1154 }
1155
1156 #[instability::unstable]
1161 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1162 internal_set_interrupt_handler(handler);
1163 }
1164
1165 pub fn listen(&mut self, interrupts: impl Into<EnumSet<ParlIoInterrupt>>) {
1167 internal_listen(interrupts.into(), true);
1168 }
1169
1170 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<ParlIoInterrupt>>) {
1172 internal_listen(interrupts.into(), false);
1173 }
1174
1175 pub fn interrupts(&mut self) -> EnumSet<ParlIoInterrupt> {
1177 internal_interrupts()
1178 }
1179
1180 pub fn clear_interrupts(&mut self, interrupts: EnumSet<ParlIoInterrupt>) {
1182 internal_clear_interrupts(interrupts);
1183 }
1184}
1185
1186impl crate::private::Sealed for ParlIo<'_, Blocking> {}
1187
1188#[instability::unstable]
1189impl crate::interrupt::InterruptConfigurable for ParlIo<'_, Blocking> {
1190 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
1191 ParlIo::set_interrupt_handler(self, handler);
1192 }
1193}
1194
1195impl<'d> ParlIo<'d, Async> {
1196 pub fn into_blocking(self) -> ParlIo<'d, Blocking> {
1198 ParlIo {
1199 tx: TxCreator {
1200 tx_channel: self.tx.tx_channel.into_blocking(),
1201 _guard: self.tx._guard,
1202 },
1203 rx: RxCreator {
1204 rx_channel: self.rx.rx_channel.into_blocking(),
1205 _guard: self.rx._guard,
1206 },
1207 }
1208 }
1209}
1210
1211impl<'d, Dm> ParlIoTx<'d, Dm>
1212where
1213 Dm: DriverMode,
1214{
1215 pub fn write<BUF>(
1221 mut self,
1222 number_of_bytes: usize,
1223 mut buffer: BUF,
1224 ) -> Result<ParlIoTxTransfer<'d, BUF, Dm>, (Error, Self, BUF)>
1225 where
1226 BUF: DmaTxBuffer,
1227 {
1228 if number_of_bytes > MAX_DMA_SIZE {
1229 return Err((Error::MaxDmaTransferSizeExceeded, self, buffer));
1230 }
1231
1232 PCR::regs()
1233 .parl_clk_tx_conf()
1234 .modify(|_, w| w.parl_tx_rst_en().set_bit());
1235
1236 Instance::clear_tx_interrupts();
1237 Instance::set_tx_bytes(number_of_bytes as u16);
1238
1239 let result = unsafe {
1240 self.tx_channel
1241 .prepare_transfer(DmaPeripheral::ParlIo, &mut buffer)
1242 .and_then(|_| self.tx_channel.start_transfer())
1243 };
1244 if let Err(err) = result {
1245 return Err((Error::DmaError(err), self, buffer));
1246 }
1247
1248 while !Instance::is_tx_ready() {}
1249
1250 Instance::set_tx_start(true);
1251
1252 PCR::regs()
1253 .parl_clk_tx_conf()
1254 .modify(|_, w| w.parl_tx_rst_en().clear_bit());
1255
1256 Ok(ParlIoTxTransfer {
1257 parl_io: ManuallyDrop::new(self),
1258 buf_view: ManuallyDrop::new(buffer.into_view()),
1259 })
1260 }
1261
1262 pub fn apply_config(&mut self, config: &TxConfig) -> Result<(), ConfigError> {
1264 if config.frequency.as_hz() > 40_000_000 {
1265 return Err(ConfigError::UnreachableClockRate);
1266 }
1267
1268 let divider = crate::soc::constants::PARL_IO_SCLK / config.frequency.as_hz();
1269 if divider > 0xFFFF {
1270 return Err(ConfigError::UnreachableClockRate);
1271 }
1272 let divider = divider as u16;
1273
1274 PCR::regs().parl_clk_tx_conf().modify(|_, w| unsafe {
1275 w.parl_clk_tx_en().set_bit();
1276 w.parl_clk_tx_sel().bits(1); w.parl_clk_tx_div_num().bits(divider)
1278 });
1279
1280 Instance::set_tx_idle_value(config.idle_value);
1281 Instance::set_tx_sample_edge(config.sample_edge);
1282 Instance::set_tx_bit_order(config.bit_order);
1283
1284 Ok(())
1285 }
1286}
1287
1288pub struct ParlIoTxTransfer<'d, BUF: DmaTxBuffer, Dm: DriverMode> {
1291 parl_io: ManuallyDrop<ParlIoTx<'d, Dm>>,
1292 buf_view: ManuallyDrop<BUF::View>,
1293}
1294
1295impl<'d, BUF: DmaTxBuffer, Dm: DriverMode> ParlIoTxTransfer<'d, BUF, Dm> {
1296 pub fn is_done(&self) -> bool {
1298 Instance::is_tx_eof()
1299 }
1300
1301 pub fn wait(mut self) -> (Result<(), DmaError>, ParlIoTx<'d, Dm>, BUF) {
1303 while !self.is_done() {}
1304
1305 Instance::set_tx_start(false);
1306 Instance::clear_is_tx_done();
1307
1308 self.parl_io.tx_channel.stop_transfer();
1310
1311 let (parl_io, view) = self.release();
1312
1313 let result = if parl_io.tx_channel.has_error() {
1314 Err(DmaError::DescriptorError)
1315 } else {
1316 Ok(())
1317 };
1318
1319 (result, parl_io, BUF::from_view(view))
1320 }
1321
1322 fn release(mut self) -> (ParlIoTx<'d, Dm>, BUF::View) {
1323 let (parl_io, view) = unsafe {
1324 (
1325 ManuallyDrop::take(&mut self.parl_io),
1326 ManuallyDrop::take(&mut self.buf_view),
1327 )
1328 };
1329 core::mem::forget(self);
1330 (parl_io, view)
1331 }
1332}
1333
1334impl<BUF: DmaTxBuffer, Dm: DriverMode> Deref for ParlIoTxTransfer<'_, BUF, Dm> {
1335 type Target = BUF::View;
1336
1337 fn deref(&self) -> &Self::Target {
1338 &self.buf_view
1339 }
1340}
1341
1342impl<BUF: DmaTxBuffer, Dm: DriverMode> DerefMut for ParlIoTxTransfer<'_, BUF, Dm> {
1343 fn deref_mut(&mut self) -> &mut Self::Target {
1344 &mut self.buf_view
1345 }
1346}
1347
1348impl<BUF: DmaTxBuffer, Dm: DriverMode> Drop for ParlIoTxTransfer<'_, BUF, Dm> {
1349 fn drop(&mut self) {
1350 self.parl_io.tx_channel.stop_transfer();
1353
1354 let view = unsafe {
1357 ManuallyDrop::drop(&mut self.parl_io);
1358 ManuallyDrop::take(&mut self.buf_view)
1359 };
1360 let _ = BUF::from_view(view);
1361 }
1362}
1363
1364impl<'d, Dm> ParlIoRx<'d, Dm>
1365where
1366 Dm: DriverMode,
1367{
1368 pub fn read<BUF>(
1380 mut self,
1381 number_of_bytes: Option<usize>,
1382 mut buffer: BUF,
1383 ) -> Result<ParlIoRxTransfer<'d, BUF, Dm>, (Error, Self, BUF)>
1384 where
1385 BUF: DmaRxBuffer,
1386 {
1387 PCR::regs()
1388 .parl_clk_rx_conf()
1389 .modify(|_, w| w.parl_rx_rst_en().set_bit());
1390 PCR::regs()
1391 .parl_clk_rx_conf()
1392 .modify(|_, w| w.parl_rx_rst_en().clear_bit());
1393
1394 Instance::clear_rx_interrupts();
1395 if let Some(number_of_bytes) = number_of_bytes {
1396 if number_of_bytes > MAX_DMA_SIZE {
1397 return Err((Error::MaxDmaTransferSizeExceeded, self, buffer));
1398 }
1399 Instance::set_rx_bytes(number_of_bytes as u16);
1400 Instance::set_eof_gen_sel(EofMode::ByteLen);
1401 } else {
1402 Instance::set_eof_gen_sel(EofMode::EnableSignal);
1403 }
1404
1405 let result = unsafe {
1406 self.rx_channel
1407 .prepare_transfer(DmaPeripheral::ParlIo, &mut buffer)
1408 .and_then(|_| self.rx_channel.start_transfer())
1409 };
1410 if let Err(err) = result {
1411 return Err((Error::DmaError(err), self, buffer));
1412 }
1413
1414 Instance::set_rx_reg_update();
1415
1416 Instance::set_rx_start(true);
1417
1418 Ok(ParlIoRxTransfer {
1419 parl_io: ManuallyDrop::new(self),
1420 buf_view: ManuallyDrop::new(buffer.into_view()),
1421 dma_result: None,
1422 })
1423 }
1424
1425 pub fn apply_config(&mut self, config: &RxConfig) -> Result<(), ConfigError> {
1427 if config.frequency.as_hz() > 40_000_000 {
1428 return Err(ConfigError::UnreachableClockRate);
1429 }
1430
1431 let divider = crate::soc::constants::PARL_IO_SCLK / config.frequency.as_hz();
1432 if divider > 0xffff {
1433 return Err(ConfigError::UnreachableClockRate);
1434 }
1435 let divider = divider as u16;
1436
1437 PCR::regs().parl_clk_rx_conf().modify(|_, w| unsafe {
1438 w.parl_clk_rx_en().set_bit();
1439 w.parl_clk_rx_sel().bits(1); w.parl_clk_rx_div_num().bits(divider)
1441 });
1442
1443 Instance::set_rx_bit_order(config.bit_order);
1444 Instance::set_rx_timeout_ticks(config.timeout_ticks);
1445
1446 Ok(())
1447 }
1448}
1449
1450pub struct ParlIoRxTransfer<'d, BUF: DmaRxBuffer, Dm: DriverMode> {
1453 parl_io: ManuallyDrop<ParlIoRx<'d, Dm>>,
1454 buf_view: ManuallyDrop<BUF::View>,
1455 dma_result: Option<Result<(), DmaError>>,
1457}
1458
1459impl<'d, BUF: DmaRxBuffer, Dm: DriverMode> ParlIoRxTransfer<'d, BUF, Dm> {
1460 pub fn is_done(&self) -> bool {
1462 if self.dma_result.is_some() {
1463 return true;
1464 }
1465 let ch = &self.parl_io.rx_channel;
1466 ch.is_done() || ch.has_eof_error() || ch.has_dscr_empty_error()
1467 }
1468
1469 pub fn wait(mut self) -> (Result<(), DmaError>, ParlIoRx<'d, Dm>, BUF) {
1471 while !self.is_done() {}
1472
1473 Instance::set_rx_start(false);
1474
1475 self.parl_io.rx_channel.stop_transfer();
1477
1478 let dma_result = self.dma_result.take();
1479 let (parl_io, view) = self.release();
1480
1481 let result = if parl_io.rx_channel.has_error() {
1482 Err(DmaError::DescriptorError)
1483 } else {
1484 dma_result.unwrap_or(Ok(()))
1485 };
1486
1487 (result, parl_io, BUF::from_view(view))
1488 }
1489
1490 fn release(mut self) -> (ParlIoRx<'d, Dm>, BUF::View) {
1491 let (parl_io, view) = unsafe {
1492 (
1493 ManuallyDrop::take(&mut self.parl_io),
1494 ManuallyDrop::take(&mut self.buf_view),
1495 )
1496 };
1497 core::mem::forget(self);
1498 (parl_io, view)
1499 }
1500}
1501
1502impl<BUF: DmaRxBuffer, Dm: DriverMode> Deref for ParlIoRxTransfer<'_, BUF, Dm> {
1503 type Target = BUF::View;
1504
1505 fn deref(&self) -> &Self::Target {
1506 &self.buf_view
1507 }
1508}
1509
1510impl<BUF: DmaRxBuffer, Dm: DriverMode> DerefMut for ParlIoRxTransfer<'_, BUF, Dm> {
1511 fn deref_mut(&mut self) -> &mut Self::Target {
1512 &mut self.buf_view
1513 }
1514}
1515
1516impl<BUF: DmaRxBuffer, Dm: DriverMode> Drop for ParlIoRxTransfer<'_, BUF, Dm> {
1517 fn drop(&mut self) {
1518 self.parl_io.rx_channel.stop_transfer();
1521
1522 let view = unsafe {
1525 ManuallyDrop::drop(&mut self.parl_io);
1526 ManuallyDrop::take(&mut self.buf_view)
1527 };
1528 let _ = BUF::from_view(view);
1529 }
1530}
1531
1532pub struct TxCreator<'d, Dm>
1534where
1535 Dm: DriverMode,
1536{
1537 tx_channel: ChannelTx<Dm, PeripheralTxChannel<PARL_IO<'d>>>,
1538 _guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
1539}
1540
1541pub struct RxCreator<'d, Dm>
1543where
1544 Dm: DriverMode,
1545{
1546 rx_channel: ChannelRx<Dm, PeripheralRxChannel<PARL_IO<'d>>>,
1547 _guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
1548}
1549
1550#[doc(hidden)]
1554pub trait TxPins {}
1555#[doc(hidden)]
1556pub trait RxPins {}
1557#[doc(hidden)]
1558pub trait ConfigurePins {
1559 fn configure(&mut self);
1560}
1561
1562#[doc(hidden)]
1563pub mod asynch {
1564 use core::task::Poll;
1565
1566 use procmacros::handler;
1567
1568 use super::{ParlIoRxTransfer, ParlIoTxTransfer, private::Instance};
1569 use crate::{
1570 asynch::AtomicWaker,
1571 dma::{DmaRxBuffer, DmaTxBuffer, asynch::DmaRxFuture},
1572 };
1573
1574 static TX_WAKER: AtomicWaker = AtomicWaker::new();
1575
1576 #[must_use = "futures do nothing unless you `.await` or poll them"]
1577 struct TxDoneFuture {}
1578
1579 impl TxDoneFuture {
1580 pub fn new() -> Self {
1581 Self {}
1582 }
1583 }
1584
1585 impl core::future::Future for TxDoneFuture {
1586 type Output = ();
1587
1588 fn poll(
1589 self: core::pin::Pin<&mut Self>,
1590 cx: &mut core::task::Context<'_>,
1591 ) -> Poll<Self::Output> {
1592 if Instance::is_tx_done_set() {
1593 Poll::Ready(())
1594 } else {
1595 TX_WAKER.register(cx.waker());
1596 Instance::listen_tx_done();
1597 Poll::Pending
1598 }
1599 }
1600 }
1601
1602 impl Drop for TxDoneFuture {
1603 fn drop(&mut self) {
1604 Instance::unlisten_tx_done();
1605 }
1606 }
1607
1608 #[handler]
1609 pub(super) fn interrupt_handler() {
1610 if Instance::is_tx_done_set() {
1611 Instance::unlisten_tx_done();
1612 TX_WAKER.wake()
1613 }
1614 }
1615
1616 impl<BUF: DmaTxBuffer> ParlIoTxTransfer<'_, BUF, crate::Async> {
1617 pub async fn wait_for_done(&mut self) {
1619 let future = TxDoneFuture::new();
1620 future.await;
1621 }
1622 }
1623
1624 impl<BUF: DmaRxBuffer> ParlIoRxTransfer<'_, BUF, crate::Async> {
1625 pub async fn wait_for_done(&mut self) {
1627 if self.dma_result.is_some() {
1628 return;
1629 }
1630 let future = DmaRxFuture::new(&mut self.parl_io.rx_channel);
1631 self.dma_result = Some(future.await);
1632 }
1633 }
1634}
1635
1636mod private {
1637 use super::{BitPackOrder, SampleEdge};
1638 use crate::{
1639 gpio::{InputSignal, OutputSignal},
1640 peripherals::PARL_IO,
1641 };
1642
1643 pub trait NotContainsValidSignalPin {}
1644
1645 pub trait ContainsValidSignalPin {}
1646
1647 pub trait TxClkPin {
1648 fn configure(&mut self);
1649 }
1650
1651 pub trait RxClkPin {
1652 fn configure(&mut self);
1653 }
1654
1655 #[cfg(esp32c6)]
1656 pub(super) enum WidSel {
1657 Bits16 = 0,
1658 Bits8 = 1,
1659 Bits4 = 2,
1660 Bits2 = 3,
1661 Bits1 = 4,
1662 }
1663
1664 #[cfg(esp32h2)]
1665 pub(super) enum WidSel {
1666 Bits8 = 3,
1667 Bits4 = 2,
1668 Bits2 = 1,
1669 Bits1 = 0,
1670 }
1671
1672 pub(super) enum SampleMode {
1673 ExternalLevel = 0,
1674 ExternalPulse = 1,
1675 InternalSoftwareEnable = 2,
1676 }
1677
1678 pub(super) enum EofMode {
1680 ByteLen,
1682 EnableSignal,
1684 }
1685
1686 pub(super) struct Instance;
1687
1688 #[cfg(esp32c6)]
1689 impl Instance {
1690 pub fn set_tx_bit_width(width: WidSel) {
1691 let reg_block = PARL_IO::regs();
1692
1693 reg_block
1694 .tx_cfg0()
1695 .modify(|_, w| unsafe { w.tx_bus_wid_sel().bits(width as u8) });
1696 }
1697
1698 pub fn set_tx_idle_value(value: u16) {
1699 let reg_block = PARL_IO::regs();
1700 reg_block
1701 .tx_cfg1()
1702 .modify(|_, w| unsafe { w.tx_idle_value().bits(value) });
1703 }
1704
1705 pub fn set_tx_sample_edge(value: SampleEdge) {
1706 let reg_block = PARL_IO::regs();
1707 reg_block
1708 .tx_cfg0()
1709 .modify(|_, w| w.tx_smp_edge_sel().bit(value as u8 == 1));
1710 }
1711
1712 pub fn set_tx_bit_order(value: BitPackOrder) {
1713 let reg_block = PARL_IO::regs();
1714 reg_block
1715 .tx_cfg0()
1716 .modify(|_, w| w.tx_bit_unpack_order().bit(value as u8 == 1));
1717 }
1718
1719 pub fn clear_tx_interrupts() {
1720 let reg_block = PARL_IO::regs();
1721
1722 reg_block.int_clr().write(|w| {
1723 w.tx_fifo_rempty()
1724 .clear_bit_by_one()
1725 .tx_eof()
1726 .clear_bit_by_one()
1727 });
1728 }
1729
1730 pub fn set_tx_bytes(len: u16) {
1731 let reg_block = PARL_IO::regs();
1732
1733 reg_block
1734 .tx_cfg0()
1735 .modify(|_, w| unsafe { w.tx_bytelen().bits(len) });
1736 }
1737
1738 pub fn is_tx_ready() -> bool {
1739 let reg_block = PARL_IO::regs();
1740
1741 reg_block.st().read().tx_ready().bit_is_set()
1742 }
1743
1744 pub fn set_tx_start(value: bool) {
1745 let reg_block = PARL_IO::regs();
1746
1747 reg_block.tx_cfg0().modify(|_, w| w.tx_start().bit(value));
1748 }
1749
1750 pub fn is_tx_eof() -> bool {
1751 let reg_block = PARL_IO::regs();
1752
1753 reg_block.int_raw().read().tx_eof().bit_is_set()
1754 }
1755
1756 pub fn tx_valid_pin_signal() -> OutputSignal {
1757 OutputSignal::PARL_TX_DATA15
1758 }
1759
1760 pub fn set_tx_hw_valid_en(value: bool) {
1761 let reg_block = PARL_IO::regs();
1762
1763 reg_block
1764 .tx_cfg0()
1765 .modify(|_, w| w.tx_hw_valid_en().bit(value));
1766 }
1767
1768 pub fn set_rx_bit_width(width: WidSel) {
1769 let reg_block = PARL_IO::regs();
1770
1771 reg_block
1772 .rx_cfg0()
1773 .modify(|_, w| unsafe { w.rx_bus_wid_sel().bits(width as u8) });
1774 }
1775
1776 pub fn rx_valid_pin_signal() -> InputSignal {
1777 InputSignal::PARL_RX_DATA15
1778 }
1779
1780 pub fn set_rx_sw_en(value: bool) {
1781 let reg_block = PARL_IO::regs();
1782
1783 reg_block.rx_cfg0().modify(|_, w| w.rx_sw_en().bit(value));
1784 }
1785
1786 pub fn clear_rx_interrupts() {
1787 let reg_block = PARL_IO::regs();
1788
1789 reg_block
1790 .int_clr()
1791 .write(|w| w.rx_fifo_wovf().clear_bit_by_one());
1792 }
1793
1794 pub fn set_rx_bytes(len: u16) {
1795 let reg_block = PARL_IO::regs();
1796
1797 reg_block
1798 .rx_cfg0()
1799 .modify(|_, w| unsafe { w.rx_data_bytelen().bits(len) });
1800 }
1801
1802 pub fn set_rx_sample_mode(sample_mode: SampleMode) {
1803 let reg_block = PARL_IO::regs();
1804
1805 reg_block
1806 .rx_cfg0()
1807 .modify(|_, w| unsafe { w.rx_smp_mode_sel().bits(sample_mode as u8) });
1808 }
1809
1810 pub fn set_eof_gen_sel(mode: EofMode) {
1811 let reg_block = PARL_IO::regs();
1812
1813 reg_block.rx_cfg0().modify(|_, w| {
1814 w.rx_eof_gen_sel()
1815 .bit(matches!(mode, EofMode::EnableSignal))
1816 });
1817 }
1818
1819 pub fn set_rx_pulse_submode_sel(sel: u8) {
1820 let reg_block = PARL_IO::regs();
1821
1822 reg_block
1823 .rx_cfg0()
1824 .modify(|_, w| unsafe { w.rx_pulse_submode_sel().bits(sel) });
1825 }
1826
1827 pub fn set_rx_level_submode_sel(sel: u8) {
1828 let reg_block = PARL_IO::regs();
1829
1830 reg_block
1831 .rx_cfg0()
1832 .modify(|_, w| w.rx_level_submode_sel().bit(sel == 1));
1833 }
1834
1835 pub fn set_rx_clk_edge_sel(edge: SampleEdge) {
1836 let reg_block = PARL_IO::regs();
1837
1838 reg_block
1839 .rx_cfg0()
1840 .modify(|_, w| w.rx_clk_edge_sel().bit(edge as u8 == 1));
1841 }
1842
1843 pub fn set_rx_start(value: bool) {
1844 let reg_block = PARL_IO::regs();
1845
1846 reg_block.rx_cfg0().modify(|_, w| w.rx_start().bit(value));
1847 }
1848
1849 pub fn set_rx_reg_update() {
1850 let reg_block = PARL_IO::regs();
1851
1852 reg_block
1853 .rx_cfg1()
1854 .modify(|_, w| w.rx_reg_update().bit(true));
1855 }
1856
1857 pub fn set_rx_bit_order(value: BitPackOrder) {
1858 let reg_block = PARL_IO::regs();
1859 reg_block
1860 .rx_cfg0()
1861 .modify(|_, w| w.rx_bit_pack_order().bit(value as u8 == 1));
1862 }
1863
1864 pub fn set_rx_timeout_ticks(value: Option<u16>) {
1865 let reg_block = PARL_IO::regs();
1866 reg_block.rx_cfg1().modify(|_, w| unsafe {
1867 w.rx_timeout_en()
1868 .bit(value.is_some())
1869 .rx_timeout_threshold()
1870 .bits(value.unwrap_or(0xfff))
1871 });
1872 }
1873
1874 pub fn listen_tx_done() {
1875 let reg_block = PARL_IO::regs();
1876
1877 reg_block.int_ena().modify(|_, w| w.tx_eof().set_bit());
1878 }
1879
1880 pub fn unlisten_tx_done() {
1881 let reg_block = PARL_IO::regs();
1882
1883 reg_block.int_ena().modify(|_, w| w.tx_eof().clear_bit());
1884 }
1885
1886 pub fn is_tx_done_set() -> bool {
1887 let reg_block = PARL_IO::regs();
1888
1889 reg_block.int_raw().read().tx_eof().bit()
1890 }
1891
1892 pub fn clear_is_tx_done() {
1893 let reg_block = PARL_IO::regs();
1894
1895 reg_block.int_clr().write(|w| w.tx_eof().clear_bit_by_one());
1896 }
1897 }
1898
1899 #[cfg(esp32h2)]
1900 impl Instance {
1901 pub fn set_tx_bit_width(width: WidSel) {
1902 let reg_block = PARL_IO::regs();
1903
1904 reg_block
1905 .tx_data_cfg()
1906 .modify(|_, w| unsafe { w.tx_bus_wid_sel().bits(width as u8) });
1907 }
1908
1909 pub fn set_tx_idle_value(value: u16) {
1910 let reg_block = PARL_IO::regs();
1911 reg_block
1912 .tx_genrl_cfg()
1913 .modify(|_, w| unsafe { w.tx_idle_value().bits(value) });
1914 }
1915
1916 pub fn set_tx_sample_edge(value: SampleEdge) {
1917 let reg_block = PARL_IO::regs();
1918 reg_block.tx_clk_cfg().modify(|_, w| {
1919 w.tx_clk_i_inv()
1920 .bit(value == SampleEdge::Invert)
1921 .tx_clk_o_inv()
1922 .bit(value == SampleEdge::Invert)
1923 });
1924 }
1925
1926 pub fn set_tx_bit_order(value: BitPackOrder) {
1927 let reg_block = PARL_IO::regs();
1928 reg_block
1929 .tx_data_cfg()
1930 .modify(|_, w| w.tx_data_order_inv().bit(value as u8 == 1));
1931 }
1932
1933 pub fn clear_tx_interrupts() {
1934 let reg_block = PARL_IO::regs();
1935
1936 reg_block.int_clr().write(|w| {
1937 w.tx_fifo_rempty()
1938 .clear_bit_by_one()
1939 .tx_eof()
1940 .clear_bit_by_one()
1941 });
1942 }
1943
1944 pub fn set_tx_bytes(len: u16) {
1945 let reg_block = PARL_IO::regs();
1946
1947 reg_block
1948 .tx_data_cfg()
1949 .modify(|_, w| unsafe { w.tx_bitlen().bits((len as u32) * 8) });
1950 }
1951
1952 pub fn is_tx_ready() -> bool {
1953 let reg_block = PARL_IO::regs();
1954
1955 reg_block.st().read().tx_ready().bit_is_set()
1956 }
1957
1958 pub fn set_tx_start(value: bool) {
1959 let reg_block = PARL_IO::regs();
1960
1961 reg_block
1962 .tx_start_cfg()
1963 .modify(|_, w| w.tx_start().bit(value));
1964 }
1965
1966 pub fn is_tx_eof() -> bool {
1967 let reg_block = PARL_IO::regs();
1968
1969 reg_block.int_raw().read().tx_eof().bit_is_set()
1970 }
1971
1972 pub fn tx_valid_pin_signal() -> OutputSignal {
1973 OutputSignal::PARL_TX_DATA7
1974 }
1975
1976 pub fn set_tx_hw_valid_en(value: bool) {
1977 let reg_block = PARL_IO::regs();
1978
1979 reg_block
1980 .tx_genrl_cfg()
1981 .modify(|_, w| w.tx_valid_output_en().bit(value));
1982 }
1983
1984 pub fn set_rx_bit_width(width: WidSel) {
1985 let reg_block = PARL_IO::regs();
1986
1987 reg_block
1988 .rx_data_cfg()
1989 .modify(|_, w| unsafe { w.rx_bus_wid_sel().bits(width as u8) });
1990 }
1991
1992 pub fn rx_valid_pin_signal() -> InputSignal {
1993 InputSignal::PARL_RX_DATA7
1994 }
1995
1996 pub fn set_rx_sw_en(value: bool) {
1997 let reg_block = PARL_IO::regs();
1998
1999 reg_block
2000 .rx_mode_cfg()
2001 .modify(|_, w| w.rx_sw_en().bit(value));
2002 }
2003
2004 pub fn clear_rx_interrupts() {
2005 let reg_block = PARL_IO::regs();
2006
2007 reg_block
2008 .int_clr()
2009 .write(|w| w.rx_fifo_wovf().clear_bit_by_one());
2010 }
2011
2012 pub fn set_rx_bytes(len: u16) {
2013 let reg_block = PARL_IO::regs();
2014
2015 reg_block
2016 .rx_data_cfg()
2017 .modify(|_, w| unsafe { w.rx_bitlen().bits((len as u32) * 8) });
2018 }
2019
2020 pub fn set_rx_sample_mode(sample_mode: SampleMode) {
2021 let reg_block = PARL_IO::regs();
2022
2023 reg_block
2024 .rx_mode_cfg()
2025 .modify(|_, w| unsafe { w.rx_smp_mode_sel().bits(sample_mode as u8) });
2026 }
2027
2028 pub fn set_eof_gen_sel(mode: EofMode) {
2029 let reg_block = PARL_IO::regs();
2030
2031 reg_block.rx_genrl_cfg().modify(|_, w| {
2032 w.rx_eof_gen_sel()
2033 .bit(matches!(mode, EofMode::EnableSignal))
2034 });
2035 }
2036
2037 pub fn set_rx_pulse_submode_sel(sel: u8) {
2038 let reg_block = PARL_IO::regs();
2039
2040 reg_block
2041 .rx_mode_cfg()
2042 .modify(|_, w| unsafe { w.rx_pulse_submode_sel().bits(sel) });
2043 }
2044
2045 pub fn set_rx_level_submode_sel(_sel: u8) {
2046 }
2048
2049 pub fn set_rx_clk_edge_sel(value: SampleEdge) {
2050 let reg_block = PARL_IO::regs();
2051
2052 reg_block.rx_clk_cfg().modify(|_, w| {
2053 w.rx_clk_i_inv()
2054 .bit(value == SampleEdge::Invert)
2055 .rx_clk_o_inv()
2056 .bit(value == SampleEdge::Invert)
2057 });
2058 }
2059
2060 pub fn set_rx_start(value: bool) {
2061 let reg_block = PARL_IO::regs();
2062
2063 reg_block
2064 .rx_start_cfg()
2065 .modify(|_, w| w.rx_start().bit(value));
2066 }
2067
2068 pub fn set_rx_reg_update() {
2069 let reg_block = PARL_IO::regs();
2070
2071 reg_block
2072 .reg_update()
2073 .write(|w| w.rx_reg_update().bit(true));
2074 }
2075
2076 pub fn set_rx_bit_order(value: BitPackOrder) {
2077 let reg_block = PARL_IO::regs();
2078 reg_block
2079 .rx_data_cfg()
2080 .modify(|_, w| w.rx_data_order_inv().bit(value as u8 == 1));
2081 }
2082
2083 pub fn set_rx_timeout_ticks(value: Option<u16>) {
2084 let reg_block = PARL_IO::regs();
2085 reg_block.rx_genrl_cfg().modify(|_, w| unsafe {
2086 w.rx_timeout_en()
2087 .bit(value.is_some())
2088 .rx_timeout_thres()
2089 .bits(value.unwrap_or(0xfff))
2090 });
2091 }
2092
2093 pub fn listen_tx_done() {
2094 let reg_block = PARL_IO::regs();
2095
2096 reg_block.int_ena().modify(|_, w| w.tx_eof().set_bit());
2097 }
2098
2099 pub fn unlisten_tx_done() {
2100 let reg_block = PARL_IO::regs();
2101
2102 reg_block.int_ena().modify(|_, w| w.tx_eof().clear_bit());
2103 }
2104
2105 pub fn is_tx_done_set() -> bool {
2106 let reg_block = PARL_IO::regs();
2107
2108 reg_block.int_raw().read().tx_eof().bit()
2109 }
2110
2111 pub fn clear_is_tx_done() {
2112 let reg_block = PARL_IO::regs();
2113
2114 reg_block.int_clr().write(|w| w.tx_eof().clear_bit_by_one());
2115 }
2116 }
2117}