Skip to content

Commit 5b9a63c

Browse files
committed
Moved DMA setup to when the DMA object is made
As it is a one-time setup, it does not make sense to re-setup the entire DMA engine, when it's enough to setup the buffer's address and length.
1 parent fc59268 commit 5b9a63c

File tree

1 file changed

+135
-128
lines changed

1 file changed

+135
-128
lines changed

src/spi.rs

Lines changed: 135 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -400,22 +400,147 @@ macro_rules! spi_dma {
400400
}
401401

402402
impl<PINS> Spi<$SPIX, PINS> {
403-
pub fn with_rx_dma(self, channel: $RX_CH) -> SpiRxDma<$SPIX, PINS, $RX_CH> {
403+
pub fn with_rx_dma(self, mut channel: $RX_CH) -> SpiRxDma<$SPIX, PINS, $RX_CH> {
404404
let payload = SpiPayload { spi: self };
405+
406+
// Perform one-time setup actions to keep the work minimal when using the driver.
407+
408+
channel.set_peripheral_address(
409+
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
410+
false,
411+
);
412+
channel.cselr().modify(|_, w| w.$RX_CHX().$RX_MAPX());
413+
channel.ccr().modify(|_, w| {
414+
w
415+
// memory to memory mode disabled
416+
.mem2mem()
417+
.clear_bit()
418+
// medium channel priority level
419+
.pl()
420+
.medium()
421+
// 8-bit memory size
422+
.msize()
423+
.bits8()
424+
// 8-bit peripheral size
425+
.psize()
426+
.bits8()
427+
// circular mode disabled
428+
.circ()
429+
.clear_bit()
430+
// write to memory
431+
.dir()
432+
.clear_bit()
433+
});
434+
405435
SpiRxDma { payload, channel }
406436
}
407437

408-
pub fn with_tx_dma(self, channel: $TX_CH) -> SpiTxDma<$SPIX, PINS, $TX_CH> {
438+
pub fn with_tx_dma(self, mut channel: $TX_CH) -> SpiTxDma<$SPIX, PINS, $TX_CH> {
409439
let payload = SpiPayload { spi: self };
440+
441+
// Perform one-time setup actions to keep the work minimal when using the driver.
442+
443+
channel.set_peripheral_address(
444+
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
445+
false,
446+
);
447+
channel.cselr().modify(|_, w| w.$TX_CHX().$TX_MAPX());
448+
channel.ccr().modify(|_, w| {
449+
w
450+
// memory to memory mode disabled
451+
.mem2mem()
452+
.clear_bit()
453+
// medium channel priority level
454+
.pl()
455+
.medium()
456+
// 8-bit memory size
457+
.msize()
458+
.bits8()
459+
// 8-bit peripheral size
460+
.psize()
461+
.bits8()
462+
// circular mode disabled
463+
.circ()
464+
.clear_bit()
465+
// write to peripheral
466+
.dir()
467+
.set_bit()
468+
});
469+
410470
SpiTxDma { payload, channel }
411471
}
412472

413473
pub fn with_rxtx_dma(
414474
self,
415-
rx_channel: $RX_CH,
416-
tx_channel: $TX_CH,
475+
mut rx_channel: $RX_CH,
476+
mut tx_channel: $TX_CH,
417477
) -> SpiRxTxDma<$SPIX, PINS, $RX_CH, $TX_CH> {
418478
let payload = SpiPayload { spi: self };
479+
480+
// Perform one-time setup actions to keep the work minimal when using the driver.
481+
482+
//
483+
// Setup RX channel
484+
//
485+
rx_channel.set_peripheral_address(
486+
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
487+
false,
488+
);
489+
rx_channel.cselr().modify(|_, w| w.$RX_CHX().$RX_MAPX());
490+
491+
rx_channel.ccr().modify(|_, w| {
492+
w
493+
// memory to memory mode disabled
494+
.mem2mem()
495+
.clear_bit()
496+
// medium channel priority level
497+
.pl()
498+
.medium()
499+
// 8-bit memory size
500+
.msize()
501+
.bits8()
502+
// 8-bit peripheral size
503+
.psize()
504+
.bits8()
505+
// circular mode disabled
506+
.circ()
507+
.clear_bit()
508+
// write to memory
509+
.dir()
510+
.clear_bit()
511+
});
512+
513+
//
514+
// Setup TX channel
515+
//
516+
tx_channel.set_peripheral_address(
517+
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
518+
false,
519+
);
520+
tx_channel.cselr().modify(|_, w| w.$TX_CHX().$TX_MAPX());
521+
522+
tx_channel.ccr().modify(|_, w| {
523+
w
524+
// memory to memory mode disabled
525+
.mem2mem()
526+
.clear_bit()
527+
// medium channel priority level
528+
.pl()
529+
.medium()
530+
// 8-bit memory size
531+
.msize()
532+
.bits8()
533+
// 8-bit peripheral size
534+
.psize()
535+
.bits8()
536+
// circular mode disabled
537+
.circ()
538+
.clear_bit()
539+
// write to peripheral
540+
.dir()
541+
.set_bit()
542+
});
543+
419544
SpiRxTxDma {
420545
payload,
421546
rx_channel,
@@ -515,37 +640,12 @@ macro_rules! spi_dma {
515640
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
516641
// until the end of the transfer.
517642
let (ptr, len) = unsafe { buffer.static_write_buffer() };
518-
self.channel.set_peripheral_address(
519-
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
520-
false,
521-
);
643+
644+
// Setup RX channel
522645
self.channel.set_memory_address(ptr as u32, true);
523646
self.channel.set_transfer_length(len as u16);
524647

525-
self.channel.cselr().modify(|_, w| w.$RX_CHX().$RX_MAPX());
526-
527-
atomic::compiler_fence(Ordering::Release);
528-
self.channel.ccr().modify(|_, w| {
529-
w
530-
// memory to memory mode disabled
531-
.mem2mem()
532-
.clear_bit()
533-
// medium channel priority level
534-
.pl()
535-
.medium()
536-
// 8-bit memory size
537-
.msize()
538-
.bits8()
539-
// 8-bit peripheral size
540-
.psize()
541-
.bits8()
542-
// circular mode disabled
543-
.circ()
544-
.clear_bit()
545-
// write to memory
546-
.dir()
547-
.clear_bit()
548-
});
648+
// Fences and start
549649
atomic::compiler_fence(Ordering::Release);
550650
self.start();
551651

@@ -561,37 +661,12 @@ macro_rules! spi_dma {
561661
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
562662
// until the end of the transfer.
563663
let (ptr, len) = unsafe { buffer.static_read_buffer() };
564-
self.channel.set_peripheral_address(
565-
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
566-
false,
567-
);
664+
665+
// Setup TX channel
568666
self.channel.set_memory_address(ptr as u32, true);
569667
self.channel.set_transfer_length(len as u16);
570668

571-
self.channel.cselr().modify(|_, w| w.$TX_CHX().$TX_MAPX());
572-
573-
atomic::compiler_fence(Ordering::Release);
574-
self.channel.ccr().modify(|_, w| {
575-
w
576-
// memory to memory mode disabled
577-
.mem2mem()
578-
.clear_bit()
579-
// medium channel priority level
580-
.pl()
581-
.medium()
582-
// 8-bit memory size
583-
.msize()
584-
.bits8()
585-
// 8-bit peripheral size
586-
.psize()
587-
.bits8()
588-
// circular mode disabled
589-
.circ()
590-
.clear_bit()
591-
// write to peripheral
592-
.dir()
593-
.set_bit()
594-
});
669+
// Fences and start
595670
atomic::compiler_fence(Ordering::Release);
596671
self.start();
597672

@@ -610,83 +685,15 @@ macro_rules! spi_dma {
610685
// until the end of the transfer.
611686
let (ptr, len) = unsafe { buffer.static_write_buffer() };
612687

613-
//
614688
// Setup RX channel
615-
//
616-
self.rx_channel.set_peripheral_address(
617-
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
618-
false,
619-
);
620689
self.rx_channel.set_memory_address(ptr as u32, true);
621690
self.rx_channel.set_transfer_length(len as u16);
622691

623-
self.rx_channel
624-
.cselr()
625-
.modify(|_, w| w.$RX_CHX().$RX_MAPX());
626-
627-
atomic::compiler_fence(Ordering::Release);
628-
self.rx_channel.ccr().modify(|_, w| {
629-
w
630-
// memory to memory mode disabled
631-
.mem2mem()
632-
.clear_bit()
633-
// medium channel priority level
634-
.pl()
635-
.medium()
636-
// 8-bit memory size
637-
.msize()
638-
.bits8()
639-
// 8-bit peripheral size
640-
.psize()
641-
.bits8()
642-
// circular mode disabled
643-
.circ()
644-
.clear_bit()
645-
// write to memory
646-
.dir()
647-
.clear_bit()
648-
});
649-
650-
//
651692
// Setup TX channel
652-
//
653-
self.tx_channel.set_peripheral_address(
654-
unsafe { &(*$SPIX::ptr()).dr as *const _ as u32 },
655-
false,
656-
);
657693
self.tx_channel.set_memory_address(ptr as u32, true);
658694
self.tx_channel.set_transfer_length(len as u16);
659695

660-
self.tx_channel
661-
.cselr()
662-
.modify(|_, w| w.$TX_CHX().$TX_MAPX());
663-
664-
atomic::compiler_fence(Ordering::Release);
665-
self.tx_channel.ccr().modify(|_, w| {
666-
w
667-
// memory to memory mode disabled
668-
.mem2mem()
669-
.clear_bit()
670-
// medium channel priority level
671-
.pl()
672-
.medium()
673-
// 8-bit memory size
674-
.msize()
675-
.bits8()
676-
// 8-bit peripheral size
677-
.psize()
678-
.bits8()
679-
// circular mode disabled
680-
.circ()
681-
.clear_bit()
682-
// write to peripheral
683-
.dir()
684-
.set_bit()
685-
});
686-
687-
//
688696
// Fences and start
689-
//
690697
atomic::compiler_fence(Ordering::Release);
691698
self.start();
692699

0 commit comments

Comments
 (0)