Skip to content

[MCXA] dma: Peripheral Paced Scatter-Gather - #6686

Open
ayodejiige wants to merge 5 commits into
embassy-rs:mainfrom
ayodejiige:dma/scatter-gather-peripheral-paced
Open

[MCXA] dma: Peripheral Paced Scatter-Gather#6686
ayodejiige wants to merge 5 commits into
embassy-rs:mainfrom
ayodejiige:dma/scatter-gather-peripheral-paced

Conversation

@ayodejiige

Copy link
Copy Markdown

Extend the ScatterGatherBuilder DMA API to support peripheral paced mode, alongside a LPUART2 loopback example that exercises it.

@embassy-bot

embassy-bot Bot commented Aug 1, 2026

Copy link
Copy Markdown

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.

@ayodejiige
ayodejiige marked this pull request as ready for review August 2, 2026 00:08
@leftger leftger added the e-mcxa Issues for the NXP MCX-A family of chips label Aug 2, 2026
Comment on lines +105 to +122
// 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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run something like this in a loop. We need to know that this API remains robust even after running for many days.

Comment on lines +73 to +103
// 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);
});

@felipebalbi felipebalbi Aug 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@felipebalbi felipebalbi changed the title Mcxa: Peripheral Paced Scatter-Gather [MCXA] dma: Peripheral Paced Scatter-Gather Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e-mcxa Issues for the NXP MCX-A family of chips

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants