aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/src/bin/dma_channel_link.rs5
-rw-r--r--examples/src/bin/dma_scatter_gather.rs3
-rw-r--r--examples/src/bin/lpuart_ring_buffer.rs57
3 files changed, 23 insertions, 42 deletions
diff --git a/examples/src/bin/dma_channel_link.rs b/examples/src/bin/dma_channel_link.rs
index 34162d931..361c9ebc7 100644
--- a/examples/src/bin/dma_channel_link.rs
+++ b/examples/src/bin/dma_channel_link.rs
@@ -18,7 +18,7 @@
18 18
19use embassy_executor::Spawner; 19use embassy_executor::Spawner;
20use embassy_mcxa::clocks::config::Div8; 20use embassy_mcxa::clocks::config::Div8;
21use embassy_mcxa::dma::{self, DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaCh2InterruptHandler, DmaChannel}; 21use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaCh2InterruptHandler, DmaChannel};
22use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 22use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
23use embassy_mcxa::{bind_interrupts, pac}; 23use embassy_mcxa::{bind_interrupts, pac};
24use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 24use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
@@ -85,8 +85,7 @@ async fn main(_spawner: Spawner) {
85 85
86 defmt::info!("DMA channel link example starting..."); 86 defmt::info!("DMA channel link example starting...");
87 87
88 // Ensure DMA is initialized (clock/reset/init handled automatically by HAL) 88 // DMA is initialized during hal::init() - no need to call ensure_init()
89 dma::ensure_init();
90 89
91 let pac_periphs = unsafe { pac::Peripherals::steal() }; 90 let pac_periphs = unsafe { pac::Peripherals::steal() };
92 let dma0 = &pac_periphs.dma0; 91 let dma0 = &pac_periphs.dma0;
diff --git a/examples/src/bin/dma_scatter_gather.rs b/examples/src/bin/dma_scatter_gather.rs
index b5ae00057..9844071b7 100644
--- a/examples/src/bin/dma_scatter_gather.rs
+++ b/examples/src/bin/dma_scatter_gather.rs
@@ -120,8 +120,7 @@ async fn main(_spawner: Spawner) {
120 120
121 defmt::info!("DMA scatter-gather transfer example starting..."); 121 defmt::info!("DMA scatter-gather transfer example starting...");
122 122
123 // Ensure DMA is initialized (clock/reset/init handled automatically by HAL) 123 // DMA is initialized during hal::init() - no need to call ensure_init()
124 dma::ensure_init();
125 124
126 // Enable DMA interrupt 125 // Enable DMA interrupt
127 unsafe { 126 unsafe {
diff --git a/examples/src/bin/lpuart_ring_buffer.rs b/examples/src/bin/lpuart_ring_buffer.rs
index 6cc14f1c7..0946bad03 100644
--- a/examples/src/bin/lpuart_ring_buffer.rs
+++ b/examples/src/bin/lpuart_ring_buffer.rs
@@ -1,18 +1,18 @@
1//! LPUART Ring Buffer DMA example for MCXA276. 1//! LPUART Ring Buffer DMA example for MCXA276.
2//! 2//!
3//! This example demonstrates using the new `RingBuffer` API for continuous 3//! This example demonstrates using the high-level `LpuartRxDma::setup_ring_buffer()`
4//! circular DMA reception from a UART peripheral. 4//! API for continuous circular DMA reception from a UART peripheral.
5//! 5//!
6//! # Features demonstrated: 6//! # Features demonstrated:
7//! - `setup_circular_read()` for continuous peripheral-to-memory DMA 7//! - `LpuartRxDma::setup_ring_buffer()` for continuous peripheral-to-memory DMA
8//! - `RingBuffer` for async reading of received data 8//! - `RingBuffer` for async reading of received data
9//! - Handling of potential overrun conditions 9//! - Handling of potential overrun conditions
10//! - Half-transfer and complete-transfer interrupts for timely wakeups 10//! - Half-transfer and complete-transfer interrupts for timely wakeups
11//! 11//!
12//! # How it works: 12//! # How it works:
13//! 1. Set up a circular DMA transfer from LPUART RX to a ring buffer 13//! 1. Create an `LpuartRxDma` driver with a DMA channel
14//! 2. DMA continuously writes received bytes into the buffer, wrapping around 14//! 2. Call `setup_ring_buffer()` which handles all low-level DMA configuration
15//! 3. Application asynchronously reads data as it arrives 15//! 3. Application asynchronously reads data as it arrives via `ring_buf.read()`
16//! 4. Both half-transfer and complete-transfer interrupts wake the reader 16//! 4. Both half-transfer and complete-transfer interrupts wake the reader
17 17
18#![no_std] 18#![no_std]
@@ -20,9 +20,9 @@
20 20
21use embassy_executor::Spawner; 21use embassy_executor::Spawner;
22use embassy_mcxa::clocks::config::Div8; 22use embassy_mcxa::clocks::config::Div8;
23use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaChannel, DMA_REQ_LPUART2_RX}; 23use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler};
24use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 24use embassy_mcxa::lpuart::{Config, LpuartDma, LpuartTxDma};
25use embassy_mcxa::{bind_interrupts, pac}; 25use embassy_mcxa::bind_interrupts;
26use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 26use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
27 27
28// Bind DMA channel interrupts 28// Bind DMA channel interrupts
@@ -35,7 +35,10 @@ bind_interrupts!(struct Irqs {
35static mut RX_RING_BUFFER: [u8; 64] = [0; 64]; 35static mut RX_RING_BUFFER: [u8; 64] = [0; 64];
36 36
37/// Helper to write a byte as hex to UART 37/// Helper to write a byte as hex to UART
38fn write_hex(tx: &mut LpuartTx<'_, Blocking>, byte: u8) { 38fn write_hex<T: embassy_mcxa::lpuart::Instance, C: embassy_mcxa::dma::Channel>(
39 tx: &mut LpuartTxDma<'_, T, C>,
40 byte: u8,
41) {
39 const HEX: &[u8; 16] = b"0123456789ABCDEF"; 42 const HEX: &[u8; 16] = b"0123456789ABCDEF";
40 let buf = [HEX[(byte >> 4) as usize], HEX[(byte & 0x0F) as usize]]; 43 let buf = [HEX[(byte >> 4) as usize], HEX[(byte & 0x0F) as usize]];
41 tx.blocking_write(&buf).ok(); 44 tx.blocking_write(&buf).ok();
@@ -55,12 +58,6 @@ async fn main(_spawner: Spawner) {
55 58
56 defmt::info!("LPUART Ring Buffer DMA example starting..."); 59 defmt::info!("LPUART Ring Buffer DMA example starting...");
57 60
58 // Enable DMA interrupts (DMA clock/reset/init is handled automatically by HAL)
59 unsafe {
60 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH0);
61 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH1);
62 }
63
64 // Create UART configuration 61 // Create UART configuration
65 let config = Config { 62 let config = Config {
66 baudrate_bps: 115_200, 63 baudrate_bps: 115_200,
@@ -69,41 +66,27 @@ async fn main(_spawner: Spawner) {
69 ..Default::default() 66 ..Default::default()
70 }; 67 };
71 68
72 // Create blocking UART for TX (we'll use DMA for RX only) 69 // Create LPUART with DMA support for both TX and RX, then split
73 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); 70 // This is the proper Embassy pattern - create once, split into TX and RX
74 let (mut tx, _rx) = lpuart.split(); 71 let lpuart = LpuartDma::new(p.LPUART2, p.P2_2, p.P2_3, p.DMA_CH1, p.DMA_CH0, config).unwrap();
72 let (mut tx, rx) = lpuart.split();
75 73
76 tx.blocking_write(b"LPUART Ring Buffer DMA Example\r\n").unwrap(); 74 tx.blocking_write(b"LPUART Ring Buffer DMA Example\r\n").unwrap();
77 tx.blocking_write(b"==============================\r\n\r\n").unwrap(); 75 tx.blocking_write(b"==============================\r\n\r\n").unwrap();
78 76
79 // Get LPUART2 RX data register address for DMA
80 let lpuart2 = unsafe { &*pac::Lpuart2::ptr() };
81 let rx_data_addr = lpuart2.data().as_ptr() as *const u8;
82
83 // Enable RX DMA request in LPUART
84 lpuart2.baud().modify(|_, w| w.rdmae().enabled());
85
86 // Create DMA channel for RX
87 let dma_ch_rx = DmaChannel::new(p.DMA_CH0);
88
89 // Configure the DMA mux for LPUART2 RX
90 unsafe {
91 dma_ch_rx.set_request_source(DMA_REQ_LPUART2_RX);
92 }
93
94 tx.blocking_write(b"Setting up circular DMA for UART RX...\r\n") 77 tx.blocking_write(b"Setting up circular DMA for UART RX...\r\n")
95 .unwrap(); 78 .unwrap();
96 79
97 // Set up the ring buffer with circular DMA 80 // Set up the ring buffer with circular DMA
98 // This configures the DMA for continuous reception 81 // The HAL handles: DMA request source, RDMAE enable, circular transfer config, NVIC enable
99 let ring_buf = unsafe { 82 let ring_buf = unsafe {
100 let buf = &mut *core::ptr::addr_of_mut!(RX_RING_BUFFER); 83 let buf = &mut *core::ptr::addr_of_mut!(RX_RING_BUFFER);
101 dma_ch_rx.setup_circular_read(rx_data_addr, buf) 84 rx.setup_ring_buffer(buf)
102 }; 85 };
103 86
104 // Enable DMA requests to start continuous reception 87 // Enable DMA requests to start continuous reception
105 unsafe { 88 unsafe {
106 dma_ch_rx.enable_request(); 89 rx.enable_dma_request();
107 } 90 }
108 91
109 tx.blocking_write(b"Ring buffer ready! Type characters to see them echoed.\r\n") 92 tx.blocking_write(b"Ring buffer ready! Type characters to see them echoed.\r\n")