55use crate :: dma:: { ChannelId , Dma , DmaPeripheral } ;
66use core:: cell:: Cell ;
77use cortexm33:: dma_fence:: CortexMDmaFence ;
8+ use kernel:: deferred_call:: { DeferredCall , DeferredCallClient } ;
89use kernel:: hil:: uart:: { self } ;
910use kernel:: platform:: chip:: PanicWriter ;
1011use kernel:: utilities:: cells:: MapCell ;
@@ -166,10 +167,13 @@ pub struct Usart<'a> {
166167 rx_dma_buf : MapCell < DmaSubSliceMut < ' static , u8 > > ,
167168 tx_len : Cell < usize > ,
168169 rx_len : Cell < usize > ,
170+ deferred_call : DeferredCall ,
171+ tx_deferred : Cell < bool > ,
172+ rx_deferred : Cell < bool > ,
169173}
170174
171175impl < ' a > Usart < ' a > {
172- pub const fn new ( base : StaticRef < UsartRegisters > ) -> Self {
176+ pub fn new ( base : StaticRef < UsartRegisters > ) -> Self {
173177 Self {
174178 registers : base,
175179 dma : OptionalCell :: empty ( ) ,
@@ -181,6 +185,9 @@ impl<'a> Usart<'a> {
181185 rx_dma_buf : MapCell :: empty ( ) ,
182186 tx_len : Cell :: new ( 0 ) ,
183187 rx_len : Cell :: new ( 0 ) ,
188+ deferred_call : DeferredCall :: new ( ) ,
189+ tx_deferred : Cell :: new ( false ) ,
190+ rx_deferred : Cell :: new ( false ) ,
184191 }
185192 }
186193
@@ -225,6 +232,7 @@ impl<'a> Usart<'a> {
225232 }
226233 } ) ;
227234 self . registers . cr3 . modify ( CR3 :: DMAT :: CLEAR ) ;
235+ self . tx_deferred . set ( false ) ;
228236 if let Some ( dma_slice) = self . tx_dma_buf . take ( ) {
229237 let fence = unsafe { CortexMDmaFence :: new ( ) } ;
230238 let mut subslice = unsafe { dma_slice. take ( fence) } ;
@@ -242,6 +250,7 @@ impl<'a> Usart<'a> {
242250 }
243251 } ) ;
244252 self . registers . cr3 . modify ( CR3 :: DMAR :: CLEAR ) ;
253+ self . rx_deferred . set ( false ) ;
245254 if let Some ( dma_slice) = self . rx_dma_buf . take ( ) {
246255 let fence = unsafe { CortexMDmaFence :: new ( ) } ;
247256 let mut subslice = unsafe { dma_slice. take ( fence) } ;
@@ -281,6 +290,42 @@ impl<'a> Usart<'a> {
281290 }
282291}
283292
293+ impl DeferredCallClient for Usart < ' _ > {
294+ fn register ( & ' static self ) {
295+ self . deferred_call . register ( self ) ;
296+ }
297+
298+ fn handle_deferred_call ( & self ) {
299+ if self . tx_deferred . get ( ) {
300+ self . tx_deferred . set ( false ) ;
301+ self . tx_client . map ( move |client| {
302+ let dma_slice = self . tx_dma_buf . take ( ) . unwrap ( ) ;
303+ let fence = unsafe { CortexMDmaFence :: new ( ) } ;
304+ let mut subslice = unsafe { dma_slice. take ( fence) } ;
305+ subslice. reset ( ) ;
306+ let buf = subslice. take ( ) ;
307+ client. transmitted_buffer ( buf, 0 , Err ( kernel:: ErrorCode :: CANCEL ) ) ;
308+ } ) ;
309+ }
310+ if self . rx_deferred . get ( ) {
311+ self . rx_deferred . set ( false ) ;
312+ self . rx_client . map ( move |client| {
313+ let dma_slice = self . rx_dma_buf . take ( ) . unwrap ( ) ;
314+ let fence = unsafe { CortexMDmaFence :: new ( ) } ;
315+ let mut subslice = unsafe { dma_slice. take ( fence) } ;
316+ subslice. reset ( ) ;
317+ let buf = subslice. take ( ) ;
318+ client. received_buffer (
319+ buf,
320+ 0 ,
321+ Err ( kernel:: ErrorCode :: CANCEL ) ,
322+ uart:: Error :: Aborted ,
323+ ) ;
324+ } ) ;
325+ }
326+ }
327+ }
328+
284329impl crate :: dma:: DmaClient for Usart < ' _ > {
285330 fn transfer_done ( & self , channel : ChannelId ) {
286331 if let Some ( tx_ch) = self . dma_channel_tx . get ( ) {
@@ -352,16 +397,9 @@ impl<'a> uart::Transmit<'a> for Usart<'a> {
352397
353398 fn transmit_abort ( & self ) -> Result < ( ) , kernel:: ErrorCode > {
354399 self . registers . cr3 . modify ( CR3 :: DMAT :: CLEAR ) ;
355- if let Some ( dma_slice) = self . tx_dma_buf . take ( ) {
356- let fence = unsafe { CortexMDmaFence :: new ( ) } ;
357-
358- let mut subslice = unsafe { dma_slice. take ( fence) } ;
359- subslice. reset ( ) ;
360- let buf = subslice. take ( ) ;
361-
362- self . tx_client . map ( move |client| {
363- client. transmitted_buffer ( buf, 0 , Err ( kernel:: ErrorCode :: CANCEL ) ) ;
364- } ) ;
400+ if self . tx_dma_buf . is_some ( ) {
401+ self . tx_deferred . set ( true ) ;
402+ self . deferred_call . set ( ) ;
365403 Err ( kernel:: ErrorCode :: BUSY )
366404 } else {
367405 Ok ( ( ) )
@@ -438,19 +476,9 @@ impl<'a> uart::Receive<'a> for Usart<'a> {
438476
439477 fn receive_abort ( & self ) -> Result < ( ) , kernel:: ErrorCode > {
440478 self . registers . cr3 . modify ( CR3 :: DMAR :: CLEAR ) ;
441- if let Some ( dma_slice) = self . rx_dma_buf . take ( ) {
442- let fence = unsafe { CortexMDmaFence :: new ( ) } ;
443- let mut subslice = unsafe { dma_slice. take ( fence) } ;
444- subslice. reset ( ) ;
445- let buf = subslice. take ( ) ;
446- self . rx_client . map ( move |client| {
447- client. received_buffer (
448- buf,
449- 0 ,
450- Err ( kernel:: ErrorCode :: CANCEL ) ,
451- uart:: Error :: Aborted ,
452- ) ;
453- } ) ;
479+ if self . rx_dma_buf . is_some ( ) {
480+ self . rx_deferred . set ( true ) ;
481+ self . deferred_call . set ( ) ;
454482 Err ( kernel:: ErrorCode :: BUSY )
455483 } else {
456484 Ok ( ( ) )
0 commit comments