From 02f4efb8e883c9200308af163b8f3b15492b5013 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sat, 5 Oct 2024 10:53:17 +0300 Subject: [PATCH] simplify serialdma macro --- src/serial.rs | 339 ++++++++++++++++++++++++++------------------------ 1 file changed, 174 insertions(+), 165 deletions(-) diff --git a/src/serial.rs b/src/serial.rs index cd2384d8..5930c28e 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -660,197 +660,206 @@ pub type Tx3 = Tx; use crate::dma::{Receive, TransferPayload, Transmit}; macro_rules! serialdma { - ($( - $USARTX:ident: ( - $rxdma:ident, - $txdma:ident, - $dmarxch:ty, - $dmatxch:ty, - ), - )+) => { - $( - pub type $rxdma = RxDma, $dmarxch>; - pub type $txdma = TxDma, $dmatxch>; + ( + $USARTX:ident, + $rxdma:ident, + $txdma:ident, + $dmarxch:ty, + $dmatxch:ty + ) => { + pub type $rxdma = RxDma, $dmarxch>; + pub type $txdma = TxDma, $dmatxch>; + + impl Receive for $rxdma { + type RxChannel = $dmarxch; + type TransmittedWord = u8; + } - impl Receive for $rxdma { - type RxChannel = $dmarxch; - type TransmittedWord = u8; - } + impl Transmit for $txdma { + type TxChannel = $dmatxch; + type ReceivedWord = u8; + } - impl Transmit for $txdma { - type TxChannel = $dmatxch; - type ReceivedWord = u8; + impl TransferPayload for $rxdma { + fn start(&mut self) { + self.channel.start(); } + fn stop(&mut self) { + self.channel.stop(); + } + } - impl TransferPayload for $rxdma { - fn start(&mut self) { - self.channel.start(); - } - fn stop(&mut self) { - self.channel.stop(); - } + impl TransferPayload for $txdma { + fn start(&mut self) { + self.channel.start(); } + fn stop(&mut self) { + self.channel.stop(); + } + } - impl TransferPayload for $txdma { - fn start(&mut self) { - self.channel.start(); + impl Rx<$USARTX> { + pub fn with_dma(self, channel: $dmarxch) -> $rxdma { + unsafe { + (*$USARTX::ptr()).cr3.modify(|_, w| w.dmar().set_bit()); } - fn stop(&mut self) { - self.channel.stop(); + RxDma { + payload: self, + channel, } } + } - impl Rx<$USARTX> { - pub fn with_dma(self, channel: $dmarxch) -> $rxdma { - unsafe { (*$USARTX::ptr()).cr3.modify(|_, w| w.dmar().set_bit()); } - RxDma { - payload: self, - channel, - } + impl Tx<$USARTX> { + pub fn with_dma(self, channel: $dmatxch) -> $txdma { + unsafe { + (*$USARTX::ptr()).cr3.modify(|_, w| w.dmat().set_bit()); } - } - - impl Tx<$USARTX> { - pub fn with_dma(self, channel: $dmatxch) -> $txdma { - unsafe { (*$USARTX::ptr()).cr3.modify(|_, w| w.dmat().set_bit()); } - TxDma { - payload: self, - channel, - } + TxDma { + payload: self, + channel, } } + } - impl $rxdma { - pub fn release(mut self) -> (Rx<$USARTX>, $dmarxch) { - self.stop(); - unsafe { (*$USARTX::ptr()).cr3.modify(|_, w| w.dmar().clear_bit()); } - let RxDma {payload, channel} = self; - ( - payload, - channel - ) + impl $rxdma { + pub fn release(mut self) -> (Rx<$USARTX>, $dmarxch) { + self.stop(); + unsafe { + (*$USARTX::ptr()).cr3.modify(|_, w| w.dmar().clear_bit()); } + let RxDma { payload, channel } = self; + (payload, channel) } + } - impl $txdma { - pub fn release(mut self) -> (Tx<$USARTX>, $dmatxch) { - self.stop(); - unsafe { (*$USARTX::ptr()).cr3.modify(|_, w| w.dmat().clear_bit()); } - let TxDma {payload, channel} = self; - ( - payload, - channel, - ) + impl $txdma { + pub fn release(mut self) -> (Tx<$USARTX>, $dmatxch) { + self.stop(); + unsafe { + (*$USARTX::ptr()).cr3.modify(|_, w| w.dmat().clear_bit()); } + let TxDma { payload, channel } = self; + (payload, channel) } + } - impl crate::dma::CircReadDma for $rxdma - where - &'static mut [B; 2]: WriteBuffer, - B: 'static, - { - fn circ_read(mut self, mut buffer: &'static mut [B; 2]) -> CircBuffer { - // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it - // until the end of the transfer. - let (ptr, len) = unsafe { buffer.write_buffer() }; - self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false); - self.channel.set_memory_address(ptr as u32, true); - self.channel.set_transfer_length(len); - - atomic::compiler_fence(Ordering::Release); - - self.channel.ch().cr.modify(|_, w| { - w.mem2mem().clear_bit(); - w.pl().medium(); - w.msize().bits8(); - w.psize().bits8(); - w.circ().set_bit(); - w.dir().clear_bit() - }); - - self.start(); - - CircBuffer::new(buffer, self) - } + impl crate::dma::CircReadDma for $rxdma + where + &'static mut [B; 2]: WriteBuffer, + B: 'static, + { + fn circ_read(mut self, mut buffer: &'static mut [B; 2]) -> CircBuffer { + // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it + // until the end of the transfer. + let (ptr, len) = unsafe { buffer.write_buffer() }; + self.channel.set_peripheral_address( + unsafe { &(*$USARTX::ptr()).dr as *const _ as u32 }, + false, + ); + self.channel.set_memory_address(ptr as u32, true); + self.channel.set_transfer_length(len); + + atomic::compiler_fence(Ordering::Release); + + self.channel.ch().cr.modify(|_, w| { + w.mem2mem().clear_bit(); + w.pl().medium(); + w.msize().bits8(); + w.psize().bits8(); + w.circ().set_bit(); + w.dir().clear_bit() + }); + + self.start(); + + CircBuffer::new(buffer, self) } + } - impl crate::dma::ReadDma for $rxdma - where - B: WriteBuffer, - { - fn read(mut self, mut buffer: B) -> Transfer { - // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it - // until the end of the transfer. - let (ptr, len) = unsafe { buffer.write_buffer() }; - self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false); - self.channel.set_memory_address(ptr as u32, true); - self.channel.set_transfer_length(len); - - atomic::compiler_fence(Ordering::Release); - self.channel.ch().cr.modify(|_, w| { - w.mem2mem().clear_bit(); - w.pl().medium(); - w.msize().bits8(); - w.psize().bits8(); - w.circ().clear_bit(); - w.dir().clear_bit() - }); - self.start(); - - Transfer::w(buffer, self) - } + impl crate::dma::ReadDma for $rxdma + where + B: WriteBuffer, + { + fn read(mut self, mut buffer: B) -> Transfer { + // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it + // until the end of the transfer. + let (ptr, len) = unsafe { buffer.write_buffer() }; + self.channel.set_peripheral_address( + unsafe { &(*$USARTX::ptr()).dr as *const _ as u32 }, + false, + ); + self.channel.set_memory_address(ptr as u32, true); + self.channel.set_transfer_length(len); + + atomic::compiler_fence(Ordering::Release); + self.channel.ch().cr.modify(|_, w| { + w.mem2mem().clear_bit(); + w.pl().medium(); + w.msize().bits8(); + w.psize().bits8(); + w.circ().clear_bit(); + w.dir().clear_bit() + }); + self.start(); + + Transfer::w(buffer, self) } + } - impl crate::dma::WriteDma for $txdma - where - B: ReadBuffer, - { - fn write(mut self, buffer: B) -> Transfer { - // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it - // until the end of the transfer. - let (ptr, len) = unsafe { buffer.read_buffer() }; - - self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false); - - self.channel.set_memory_address(ptr as u32, true); - self.channel.set_transfer_length(len); - - atomic::compiler_fence(Ordering::Release); - - self.channel.ch().cr.modify(|_, w| { - w.mem2mem().clear_bit(); - w.pl().medium(); - w.msize().bits8(); - w.psize().bits8(); - w.circ().clear_bit(); - w.dir().set_bit() - }); - self.start(); - - Transfer::r(buffer, self) - } + impl crate::dma::WriteDma for $txdma + where + B: ReadBuffer, + { + fn write(mut self, buffer: B) -> Transfer { + // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it + // until the end of the transfer. + let (ptr, len) = unsafe { buffer.read_buffer() }; + + self.channel.set_peripheral_address( + unsafe { &(*$USARTX::ptr()).dr as *const _ as u32 }, + false, + ); + + self.channel.set_memory_address(ptr as u32, true); + self.channel.set_transfer_length(len); + + atomic::compiler_fence(Ordering::Release); + + self.channel.ch().cr.modify(|_, w| { + w.mem2mem().clear_bit(); + w.pl().medium(); + w.msize().bits8(); + w.psize().bits8(); + w.circ().clear_bit(); + w.dir().set_bit() + }); + self.start(); + + Transfer::r(buffer, self) } - )+ - } + } + }; } serialdma! { - USART1: ( - RxDma1, - TxDma1, - dma1::C5, - dma1::C4, - ), - USART2: ( - RxDma2, - TxDma2, - dma1::C6, - dma1::C7, - ), - USART3: ( - RxDma3, - TxDma3, - dma1::C3, - dma1::C2, - ), + USART1, + RxDma1, + TxDma1, + dma1::C5, + dma1::C4 +} +serialdma! { + USART2, + RxDma2, + TxDma2, + dma1::C6, + dma1::C7 +} +serialdma! { + USART3, + RxDma3, + TxDma3, + dma1::C3, + dma1::C2 }