1use crate::iomuxc::{consts, sai};
24use crate::ral;
25use core::marker::PhantomData;
26
27#[derive(Clone, Copy, Default, Eq, PartialEq)]
29pub enum ByteOrder {
30 #[default]
32 LSB = 0,
33 MSB = 1,
35}
36
37#[derive(Clone, Copy, Default, Eq, PartialEq)]
39pub enum Mode {
40 #[default]
42 Master = 0,
43 Slave = 1,
45 BclkMasterFrameSyncSlave = 2,
47 BclkSlaveFrameSyncMaster = 3,
49}
50
51#[derive(Clone, Copy, Default, Eq, PartialEq)]
53pub enum ClockPolarity {
54 #[default]
56 ActiveHigh = 0,
57 ActiveLow = 1,
59}
60
61#[allow(non_upper_case_globals)]
62impl ClockPolarity {
63 pub const SampleOnRising: ClockPolarity = ClockPolarity::ActiveLow;
65 pub const SampleOnFalling: ClockPolarity = ClockPolarity::ActiveHigh;
67}
68
69#[derive(Clone, Copy, Default, Eq, PartialEq)]
71pub enum MclkSource {
72 #[default]
74 Sysclk = 0,
75 Select1 = 1,
77 Select2 = 2,
79 Select3 = 3,
81}
82
83#[derive(Clone, Copy, Default, Eq, PartialEq)]
85pub enum SyncMode {
86 #[default]
88 Async = 0,
89 TxFollowRx = 1,
91 RxFollowTx = 2,
93}
94
95#[derive(Clone, Copy, Default, Eq, PartialEq)]
97pub enum SyncWidth {
98 #[default]
100 WordSize,
101}
102
103#[derive(Clone, Copy, Default, Eq, PartialEq)]
105pub enum BclkSource {
106 #[default]
108 Bus = 0,
109 Opt1 = 1,
111 Opt2 = 2,
113 Opt3 = 3,
115}
116
117bitflags::bitflags! {
118 pub struct Interrupts : u32 {
122 const WORD_START = 1 << 12;
124 const SYNC_ERROR = 1 << 11;
126 const FIFO_ERROR = 1 << 10;
128 const FIFO_WARNING = 1 << 9;
130 const FIFO_REQUEST = 1 << 8;
132 }
133}
134
135bitflags::bitflags! {
136 pub struct Status : u32 {
138 const WORD_START = 1 << 20;
142 const SYNC_ERROR = 1 << 19;
146 const FIFO_ERROR = 1 << 18;
152 const FIFO_WARNING = 1 << 17;
158 const FIFO_REQUEST = 1 << 16;
164 }
165}
166
167impl Status {
168 const W1C: Self = Self::from_bits_truncate(
169 Self::WORD_START.bits() | Self::SYNC_ERROR.bits() | Self::FIFO_ERROR.bits(),
170 );
171}
172
173mod private {
174 pub trait Sealed {}
175}
176
177pub trait Packing<const WORD_SIZE: u8>: private::Sealed {
179 const FPACK: u32;
181}
182
183pub struct PackingNone;
185
186pub struct Packing8bit;
188
189pub struct Packing16bit;
191
192impl<const WORD_SIZE: u8> Packing<WORD_SIZE> for PackingNone {
193 const FPACK: u32 = 0b00;
194}
195
196impl private::Sealed for PackingNone {}
197
198impl Packing<8> for Packing8bit {
199 const FPACK: u32 = 0b01;
200}
201
202impl private::Sealed for Packing8bit {}
203
204impl Packing<16> for Packing16bit {
205 const FPACK: u32 = 0b10;
206}
207
208impl private::Sealed for Packing16bit {}
209
210#[allow(non_upper_case_globals)]
211impl BclkSource {
212 pub const MclkDiv: BclkSource = BclkSource::Opt1;
214}
215
216fn reset_tx(regs: &ral::sai::RegisterBlock) {
217 ral::write_reg!(ral::sai, regs, TCSR, SR: 1, FR: 1);
218 ral::modify_reg!(ral::sai, regs, TCSR, SR: 0);
219}
220
221fn reset_rx(regs: &ral::sai::RegisterBlock) {
222 ral::write_reg!(ral::sai, regs, RCSR, SR: 1, FR: 1);
223 ral::modify_reg!(ral::sai, regs, RCSR, SR: 0);
224}
225
226fn reset(regs: &ral::sai::RegisterBlock) {
227 reset_tx(regs);
228 reset_rx(regs);
229}
230
231pub struct Pins<Sync, Bclk, Data> {
235 pub sync: Sync,
237 pub bclk: Bclk,
239 pub data: Data,
241}
242
243#[derive(Default)]
245pub struct SaiConfig {
246 pub mclk_source: MclkSource,
248 pub tx_fifo_wm: u32,
250 pub tx_stop_en: bool,
252 pub tx_debug_en: bool,
254 pub tx_bclk_div: u32,
256 pub rx_fifo_wm: u32,
258 pub rx_stop_en: bool,
260 pub rx_debug_en: bool,
262 pub rx_bclk_div: u32,
264 pub byte_order: ByteOrder,
266 pub mode: Mode,
268 pub sync_width: SyncWidth,
270 pub sync_early: bool,
272 pub sync_polarity: ClockPolarity,
274 pub sync_mode: SyncMode,
276 pub bclk_src_swap: bool,
278 pub bclk_input_delay: bool,
280 pub bclk_polarity: ClockPolarity,
282}
283
284const MIN_BCLK_DIV: u32 = 2;
285const MAX_BCLK_DIV: u32 = 512;
286
287pub fn bclk_div(bclk_div: u32) -> u32 {
289 bclk_div.clamp(MIN_BCLK_DIV, MAX_BCLK_DIV).div_ceil(2) - 1
290}
291
292impl SaiConfig {
293 pub const fn i2s(bclk_div: u32) -> Self {
295 Self {
298 mclk_source: MclkSource::Sysclk,
299 tx_fifo_wm: 16,
300 tx_stop_en: false,
301 tx_debug_en: false,
302 tx_bclk_div: bclk_div,
303 rx_fifo_wm: 16,
304 rx_stop_en: false,
305 rx_debug_en: false,
306 rx_bclk_div: bclk_div,
307 byte_order: ByteOrder::MSB,
308 mode: Mode::Master,
309 sync_early: true,
310 sync_width: SyncWidth::WordSize,
311 sync_polarity: ClockPolarity::ActiveLow,
312 sync_mode: SyncMode::Async,
313 bclk_src_swap: false,
314 bclk_input_delay: false,
315 bclk_polarity: ClockPolarity::SampleOnRising,
316 }
317 }
318}
319
320pub struct Sai<const N: u8, MclkPin, TxPins, RxPins> {
322 pub(super) sai: ral::sai::Instance<N>,
323 _mclk_pin: MclkPin,
324 tx_pins: Option<TxPins>,
325 rx_pins: Option<RxPins>,
326 tx_chan_mask: u32,
327 rx_chan_mask: u32,
328}
329
330impl<const N: u8, Chan, Mclk, TxSync, TxBclk, TxData, RxSync, RxBclk, RxData>
331 Sai<N, Mclk, Pins<TxSync, TxBclk, TxData>, Pins<RxSync, RxBclk, RxData>>
332where
333 Mclk: sai::Pin<consts::Const<N>, Signal = sai::Mclk>,
334 TxSync: sai::Pin<consts::Const<N>, Signal = sai::TxSync>,
335 TxBclk: sai::Pin<consts::Const<N>, Signal = sai::TxBclk>,
336 TxData: sai::Pin<consts::Const<N>>,
337 RxSync: sai::Pin<consts::Const<N>, Signal = sai::RxSync>,
338 RxBclk: sai::Pin<consts::Const<N>, Signal = sai::RxBclk>,
339 RxData: sai::Pin<consts::Const<N>>,
340 Chan: consts::Unsigned,
341 <TxData as sai::Pin<consts::Const<N>>>::Signal: sai::TxDataSignal<Index = Chan>,
342 <RxData as sai::Pin<consts::Const<N>>>::Signal: sai::RxDataSignal<Index = Chan>,
343{
344 pub fn new(
346 sai: ral::sai::Instance<N>,
347 mut mclk_pin: Mclk,
348 mut tx_pins: Pins<TxSync, TxBclk, TxData>,
349 mut rx_pins: Pins<RxSync, RxBclk, RxData>,
350 ) -> Self {
351 reset(&sai);
352
353 sai::prepare(&mut mclk_pin);
354 sai::prepare(&mut tx_pins.sync);
355 sai::prepare(&mut tx_pins.bclk);
356 sai::prepare(&mut tx_pins.data);
357 sai::prepare(&mut rx_pins.sync);
358 sai::prepare(&mut rx_pins.bclk);
359 sai::prepare(&mut rx_pins.data);
360
361 Self {
362 sai,
363 _mclk_pin: mclk_pin,
364 tx_pins: Some(tx_pins),
365 rx_pins: Some(rx_pins),
366 tx_chan_mask: 1 << Chan::to_usize(),
367 rx_chan_mask: 1 << Chan::to_usize(),
368 }
369 }
370}
371
372pub struct Tx<
374 const N: u8,
375 const WORD_SIZE: u8,
376 const FRAME_SIZE: usize,
377 PACKING: Packing<WORD_SIZE>,
378> {
379 sai: ral::sai::Instance<N>,
380 _packing: PhantomData<PACKING>,
381}
382
383impl<const N: u8, const WORD_SIZE: u8, const FRAME_SIZE: usize, PACKING: Packing<WORD_SIZE>>
384 Tx<N, WORD_SIZE, FRAME_SIZE, PACKING>
385{
386 pub fn set_enable(&mut self, en: bool) {
388 let mut tcsr = ral::read_reg!(ral::sai, self.sai, TCSR) & !Status::W1C.bits();
389 if en {
390 tcsr |= ral::sai::TCSR::TE::mask
391 } else {
392 tcsr &= !ral::sai::TCSR::TE::mask
393 }
394 ral::write_reg!(ral::sai, self.sai, TCSR, tcsr);
395 self.clear_status(Status::W1C);
396 }
397
398 pub fn interrupts(&self) -> Interrupts {
402 let tcsr = ral::read_reg!(ral::sai, self.sai, TCSR);
403 Interrupts::from_bits_truncate(tcsr)
404 }
405
406 pub fn set_interrupts(&mut self, interrutps: Interrupts) {
408 ral::modify_reg!(ral::sai, self.sai, TCSR, |tcsr| {
409 let tcsr = tcsr & !Interrupts::all().bits();
410 tcsr | interrutps.bits()
411 })
412 }
413
414 pub fn status(&mut self) -> Status {
417 let tcsr = ral::read_reg!(ral::sai, self.sai, TCSR);
418 Status::from_bits_truncate(tcsr)
419 }
420
421 pub fn clear_status(&mut self, flags: Status) {
423 let flags = flags & Status::W1C;
424 ral::modify_reg!(ral::sai, self.sai, TCSR, |tcsr| { tcsr | flags.bits() });
425 }
426
427 pub fn reg_dump(&mut self) -> [u32; 6] {
429 [
430 ral::read_reg!(ral::sai, self.sai, TCR1),
431 ral::read_reg!(ral::sai, self.sai, TCR2),
432 ral::read_reg!(ral::sai, self.sai, TCR3),
433 ral::read_reg!(ral::sai, self.sai, TCR4),
434 ral::read_reg!(ral::sai, self.sai, TCR5),
435 ral::read_reg!(ral::sai, self.sai, TCSR),
436 ]
437 }
438
439 pub fn fifo_position(&mut self, chan: usize) -> (u32, u32) {
450 ral::read_reg!(ral::sai, self.sai, TFR[chan], WFP, RFP)
451 }
452}
453
454impl<const N: u8, const FRAME_SIZE: usize> Tx<N, 32, FRAME_SIZE, PackingNone> {
455 pub fn write_frame(&mut self, chan: usize, frame: [u32; FRAME_SIZE]) {
457 for sample in frame {
458 ral::write_reg!(ral::sai, self.sai, TDR[chan], sample);
459 }
460 }
461}
462
463impl<const N: u8, const FRAME_SIZE: usize> Tx<N, 16, FRAME_SIZE, PackingNone> {
464 pub fn write_frame(&mut self, chan: usize, frame: [u16; FRAME_SIZE]) {
466 for sample in frame {
467 ral::write_reg!(ral::sai, self.sai, TDR[chan], sample as u32);
468 }
469 }
470}
471
472impl<const N: u8, const FRAME_SIZE: usize> Tx<N, 8, FRAME_SIZE, PackingNone> {
473 pub fn write_frame(&mut self, chan: usize, frame: [u8; FRAME_SIZE]) {
475 for sample in frame {
476 ral::write_reg!(ral::sai, self.sai, TDR[chan], sample as u32);
477 }
478 }
479}
480
481pub struct Rx<
483 const N: u8,
484 const WORD_SIZE: u8,
485 const FRAME_SIZE: usize,
486 PACKING: Packing<WORD_SIZE>,
487> {
488 sai: ral::sai::Instance<N>,
489 _packing: PhantomData<PACKING>,
490}
491
492impl<const N: u8, const WORD_SIZE: u8, const FRAME_SIZE: usize, PACKING: Packing<WORD_SIZE>>
493 Rx<N, WORD_SIZE, FRAME_SIZE, PACKING>
494{
495 pub fn set_enable(&mut self, en: bool) {
497 let mut rcsr = ral::read_reg!(ral::sai, self.sai, RCSR) & !Status::W1C.bits();
498 if en {
499 rcsr |= ral::sai::RCSR::RE::mask
500 } else {
501 rcsr &= !ral::sai::RCSR::RE::mask
502 }
503 ral::write_reg!(ral::sai, self.sai, RCSR, rcsr);
504 self.clear_status(Status::W1C);
505 }
506
507 pub fn interrupts(&self) -> Interrupts {
511 let rcsr = ral::read_reg!(ral::sai, self.sai, RCSR);
512 Interrupts::from_bits_truncate(rcsr)
513 }
514
515 pub fn set_interrupts(&mut self, interrutps: Interrupts) {
517 ral::modify_reg!(ral::sai, self.sai, RCSR, |rcsr| {
518 let rcsr = rcsr & !Interrupts::all().bits();
519 rcsr | interrutps.bits()
520 })
521 }
522
523 pub fn status(&mut self) -> Status {
526 let rcsr = ral::read_reg!(ral::sai, self.sai, RCSR);
527 Status::from_bits_truncate(rcsr)
528 }
529
530 pub fn clear_status(&mut self, flags: Status) {
532 let flags = flags & Status::W1C;
533 ral::modify_reg!(ral::sai, self.sai, RCSR, |rcsr| { rcsr | flags.bits() });
534 }
535
536 pub fn reg_dump(&mut self) -> [u32; 6] {
538 [
539 ral::read_reg!(ral::sai, self.sai, RCR1),
540 ral::read_reg!(ral::sai, self.sai, RCR2),
541 ral::read_reg!(ral::sai, self.sai, RCR3),
542 ral::read_reg!(ral::sai, self.sai, RCR4),
543 ral::read_reg!(ral::sai, self.sai, RCR5),
544 ral::read_reg!(ral::sai, self.sai, RCSR),
545 ]
546 }
547
548 pub fn fifo_position(&mut self, chan: usize) -> (u32, u32) {
559 ral::read_reg!(ral::sai, self.sai, RFR[chan], WFP, RFP)
560 }
561}
562
563impl<const N: u8, const FRAME_SIZE: usize> Rx<N, 32, FRAME_SIZE, PackingNone> {
564 pub fn read_frame(&mut self, chan: usize, frame: &mut [u32; FRAME_SIZE]) {
566 for sample in frame {
567 *sample = ral::read_reg!(ral::sai, self.sai, RDR[chan]);
568 }
569 }
570}
571
572impl<const N: u8, const FRAME_SIZE: usize> Rx<N, 16, FRAME_SIZE, PackingNone> {
573 pub fn read_frame(&mut self, chan: usize, frame: &mut [u16; FRAME_SIZE]) {
575 for sample in frame {
576 *sample = ral::read_reg!(ral::sai, self.sai, RDR[chan]) as u16;
577 }
578 }
579}
580
581impl<const N: u8, const FRAME_SIZE: usize> Rx<N, 8, FRAME_SIZE, PackingNone> {
582 pub fn read_frame(&mut self, chan: usize, frame: &mut [u8; FRAME_SIZE]) {
584 for sample in frame {
585 *sample = ral::read_reg!(ral::sai, self.sai, RDR[chan]) as u8;
586 }
587 }
588}
589
590impl<const N: u8, Chan, Mclk, TxSync, TxBclk, TxData> Sai<N, Mclk, Pins<TxSync, TxBclk, TxData>, ()>
591where
592 Mclk: sai::Pin<consts::Const<N>, Signal = sai::Mclk>,
593 TxSync: sai::Pin<consts::Const<N>, Signal = sai::TxSync>,
594 TxBclk: sai::Pin<consts::Const<N>, Signal = sai::TxBclk>,
595 TxData: sai::Pin<consts::Const<N>>,
596 Chan: consts::Unsigned,
597 <TxData as sai::Pin<consts::Const<N>>>::Signal: sai::TxDataSignal<Index = Chan>,
598{
599 pub const N: u8 = N;
601
602 pub fn from_tx(
604 sai: ral::sai::Instance<N>,
605 mut mclk_pin: Mclk,
606 mut tx_pins: Pins<TxSync, TxBclk, TxData>,
607 ) -> Self {
608 reset(&sai);
609
610 sai::prepare(&mut mclk_pin);
611 sai::prepare(&mut tx_pins.sync);
612 sai::prepare(&mut tx_pins.bclk);
613 sai::prepare(&mut tx_pins.data);
614
615 Sai {
616 sai,
617 _mclk_pin: mclk_pin,
618 tx_pins: Some(tx_pins),
619 rx_pins: None,
620 tx_chan_mask: 1 << Chan::to_usize(),
621 rx_chan_mask: 0,
622 }
623 }
624}
625
626impl<const N: u8, Chan, Mclk, RxSync, RxBclk, RxData> Sai<N, Mclk, (), Pins<RxSync, RxBclk, RxData>>
627where
628 Mclk: sai::Pin<consts::Const<N>, Signal = sai::Mclk>,
629 RxSync: sai::Pin<consts::Const<N>, Signal = sai::RxSync>,
630 RxBclk: sai::Pin<consts::Const<N>, Signal = sai::RxBclk>,
631 RxData: sai::Pin<consts::Const<N>>,
632 Chan: consts::Unsigned,
633 <RxData as sai::Pin<consts::Const<N>>>::Signal: sai::RxDataSignal<Index = Chan>,
634{
635 pub fn from_rx(
637 sai: ral::sai::Instance<N>,
638 mut mclk_pin: Mclk,
639 mut rx_pins: Pins<RxSync, RxBclk, RxData>,
640 ) -> Self {
641 reset(&sai);
642
643 sai::prepare(&mut mclk_pin);
644 sai::prepare(&mut rx_pins.sync);
645 sai::prepare(&mut rx_pins.bclk);
646 sai::prepare(&mut rx_pins.data);
647
648 Sai {
649 sai,
650 _mclk_pin: mclk_pin,
651 tx_pins: None,
652 rx_pins: Some(rx_pins),
653 tx_chan_mask: 0,
654 rx_chan_mask: 1 << Chan::to_usize(),
655 }
656 }
657}
658
659impl<const N: u8> Sai<N, (), (), ()> {
660 pub fn without_pins(sai: ral::sai::Instance<N>, tx_chan_mask: u32, rx_chan_mask: u32) -> Self {
666 Sai {
667 sai,
668 _mclk_pin: (),
669 tx_pins: None,
670 rx_pins: None,
671 tx_chan_mask,
672 rx_chan_mask,
673 }
674 }
675}
676
677impl<const N: u8, Mclk, TxPins, RxPins> Sai<N, Mclk, TxPins, RxPins> {
678 pub fn split<const WORD_SIZE: u8, const FRAME_SIZE: usize, PACKING: Packing<WORD_SIZE>>(
680 self,
681 cfg: &SaiConfig,
682 ) -> (
683 Option<Tx<N, WORD_SIZE, FRAME_SIZE, PACKING>>,
684 Option<Rx<N, WORD_SIZE, FRAME_SIZE, PACKING>>,
685 ) {
686 let tx = self.tx_pins.map(|_| Tx {
687 sai: unsafe { ral::sai::Instance::<N>::new(&*self.sai) },
689 _packing: PhantomData::<PACKING>,
690 });
691
692 let rx = self.rx_pins.map(|_| Rx {
693 sai: unsafe { ral::sai::Instance::<N>::new(&*self.sai) },
695 _packing: PhantomData::<PACKING>,
696 });
697
698 let frame_sync_dir = match cfg.mode {
699 Mode::Master => 1,
700 Mode::BclkSlaveFrameSyncMaster => 1,
701 _ => 0,
702 };
703
704 let bclk_dir = match cfg.mode {
705 Mode::Master => 1,
706 Mode::BclkMasterFrameSyncSlave => 1,
707 _ => 0,
708 };
709
710 let (tx_sync_mode, rx_sync_mode) = match cfg.sync_mode {
711 SyncMode::Async => (0b00, 0b00),
712 SyncMode::TxFollowRx => (0b01, 0b00),
713 SyncMode::RxFollowTx => (0b00, 0b01),
714 };
715
716 let sync_width = match cfg.sync_width {
717 SyncWidth::WordSize => WORD_SIZE as u32,
718 };
719
720 if tx.is_some() {
721 ral::write_reg!(ral::sai, self.sai, TCR1, TFW: cfg.tx_fifo_wm);
722 if cfg.mode == Mode::Master || cfg.mode == Mode::BclkMasterFrameSyncSlave {
723 ral::write_reg!(ral::sai, self.sai, TCR2, SYNC: tx_sync_mode,
724 BCS: cfg.bclk_src_swap as u32, BCI: cfg.bclk_input_delay as u32,
725 MSEL: 0x11_u32, BCP: cfg.bclk_polarity as u32, BCD: bclk_dir,
726 DIV: cfg.tx_bclk_div);
727 } else {
728 ral::modify_reg!(ral::sai, self.sai, TCR2, BCP: cfg.bclk_polarity as u32);
729 }
730 ral::modify_reg!(ral::sai, self.sai, TCR3, TCE: self.tx_chan_mask, WDFL: 0_u32);
731 ral::write_reg!(ral::sai, self.sai, TCR4, FRSZ: ((FRAME_SIZE - 1) as u32),
732 FPACK: 0_u32, SYWD: (sync_width - 1), MF: cfg.byte_order as u32,
733 FSE: cfg.sync_early as u32, FSP: cfg.sync_polarity as u32, FSD: frame_sync_dir);
734 ral::write_reg!(ral::sai, self.sai, TCR5, W0W: ((WORD_SIZE - 1) as u32), WNW: ((WORD_SIZE - 1) as u32), FBT: (WORD_SIZE - 1) as u32);
735 ral::write_reg!(ral::sai, self.sai, TCSR, TE: 0, STOPE: cfg.tx_stop_en as u32,
736 DBGE: cfg.tx_debug_en as u32, BCE: 1, WSF: 1, SEF: 1, FEF: 1, FWF: 0, FRF: 0,
737 WSIE: 0, SEIE: 0, FEIE: 0, FWIE: 0, FWDE: 0, FRDE: 0);
738 }
739
740 if rx.is_some() {
741 ral::write_reg!(ral::sai, self.sai, RCR1, RFW: cfg.rx_fifo_wm);
742 if cfg.mode == Mode::Master || cfg.mode == Mode::BclkMasterFrameSyncSlave {
743 ral::write_reg!(ral::sai, self.sai, RCR2, SYNC: rx_sync_mode,
744 BCS: cfg.bclk_src_swap as u32, BCI: cfg.bclk_input_delay as u32,
745 MSEL: cfg.mclk_source as u32, BCP: cfg.bclk_polarity as u32, BCD: bclk_dir,
746 DIV: cfg.rx_bclk_div);
747 } else {
748 ral::modify_reg!(ral::sai, self.sai, RCR2, BCP: cfg.bclk_polarity as u32);
749 }
750 ral::modify_reg!(ral::sai, self.sai, RCR3, RCE: self.rx_chan_mask);
751 ral::write_reg!(ral::sai, self.sai, RCR4, FRSZ: ((FRAME_SIZE - 1) as u32),
752 FPACK: PACKING::FPACK, SYWD: (sync_width - 1), MF: cfg.byte_order as u32,
753 FSE: cfg.sync_early as u32, FSP: cfg.sync_polarity as u32, FSD: frame_sync_dir);
754 ral::write_reg!(ral::sai, self.sai, RCR5, W0W: ((WORD_SIZE - 1) as u32), WNW: ((WORD_SIZE - 1) as u32), FBT: (WORD_SIZE - 1) as u32);
755 ral::write_reg!(ral::sai, self.sai, RCSR, RE: 0, STOPE: cfg.rx_stop_en as u32,
756 DBGE: cfg.rx_debug_en as u32, BCE: 1, WSF: 1, SEF: 1, FEF: 1, FWF: 0, FRF: 0,
757 WSIE: 0, SEIE: 0, FEIE: 0, FWIE: 0, FWDE: 0, FRDE: 0);
758 }
759
760 (tx, rx)
761 }
762}