[MCXA] dma: Peripheral Paced Scatter-Gather - #6686
Conversation
|
This pull request is a draft, so it isn't in the review queue yet. Mark it as ready for review when you'd like someone to look at it. |
| // Run TX gather and RX scatter concurrently. | ||
| let rx_fut = async { | ||
| defmt::info!("RX: scatter chain armed"); | ||
| let t = rx_sg.build_borrowed(&mut rx_ch).unwrap(); | ||
| let res = t.await; | ||
| defmt::info!("RX: transfer done, result ok={}", res.is_ok()); | ||
| res | ||
| }; | ||
|
|
||
| let tx_fut = async { | ||
| defmt::info!("TX: gather chain starting"); | ||
| let t = tx_sg.build_borrowed(&mut tx_ch).unwrap(); | ||
| let res = t.await; | ||
| defmt::info!("TX: transfer done, result ok={}", res.is_ok()); | ||
| res | ||
| }; | ||
|
|
||
| let (rx_res, tx_res) = join(rx_fut, tx_fut).await; |
There was a problem hiding this comment.
Run something like this in a loop. We need to know that this API remains robust even after running for many days.
| // Build both scatter-gather chains. | ||
| let mut rx_sg = ScatterGatherBuilder::<u8, PeripheralPaced>::new(); | ||
| rx_sg | ||
| .add_transfer_segment(PeripheralSegment::peripheral_to_memory(data_rx, &mut rx1)) | ||
| .unwrap() | ||
| .add_transfer_segment(PeripheralSegment::peripheral_to_memory(data_rx, &mut rx2)) | ||
| .unwrap() | ||
| .add_transfer_segment(PeripheralSegment::peripheral_to_memory(data_rx, &mut rx3)) | ||
| .unwrap(); | ||
|
|
||
| let mut tx_sg = ScatterGatherBuilder::<u8, PeripheralPaced>::new(); | ||
| tx_sg | ||
| .add_transfer_segment(PeripheralSegment::memory_to_peripheral(&PAYLOAD1, data_tx)) | ||
| .unwrap() | ||
| .add_transfer_segment(PeripheralSegment::memory_to_peripheral(&PAYLOAD2, data_tx)) | ||
| .unwrap() | ||
| .add_transfer_segment(PeripheralSegment::memory_to_peripheral(&PAYLOAD3, data_tx)) | ||
| .unwrap(); | ||
|
|
||
| defmt::info!( | ||
| "TX chain: {} segments, RX chain: {} segments", | ||
| tx_sg.segment_count(), | ||
| rx_sg.segment_count() | ||
| ); | ||
|
|
||
| // Enable LPUART2 DMA request lines directly via PAC — the HAL does not | ||
| // yet provide a method for this on `Lpuart`. This is only used for the purpose of this example. | ||
| hal::pac::LPUART2.baud().modify(|w| { | ||
| w.set_tdmae(true); | ||
| w.set_rdmae(true); | ||
| }); |
There was a problem hiding this comment.
I don't think this will survive for long if we put all the onus on the users. How about an API where the user passes a slice of slices and the driver ensures safe use of the DMA block?
There was a problem hiding this comment.
I was following the existing ScatterGather pattern but with peripheral paced transfers enabled. Is what you are suggesting akin to having something like read_from_peripheral_scatter and write_to_peripheral_gather as methods under DmaChannel which takes in slices?
Extend the
ScatterGatherBuilderDMA API to support peripheral paced mode, alongside aLPUART2loopback example that exercises it.