aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/src/bin/dma_channel_link.rs88
-rw-r--r--examples/src/bin/dma_interleave_transfer.rs38
-rw-r--r--examples/src/bin/dma_mem_to_mem.rs12
-rw-r--r--examples/src/bin/dma_memset.rs37
-rw-r--r--examples/src/bin/dma_ping_pong_transfer.rs52
-rw-r--r--examples/src/bin/dma_scatter_gather.rs42
-rw-r--r--examples/src/bin/dma_scatter_gather_builder.rs17
-rw-r--r--examples/src/bin/dma_wrap_transfer.rs46
-rw-r--r--examples/src/bin/lpuart_dma.rs4
-rw-r--r--examples/src/bin/lpuart_ring_buffer.rs12
10 files changed, 201 insertions, 147 deletions
diff --git a/examples/src/bin/dma_channel_link.rs b/examples/src/bin/dma_channel_link.rs
index d541dc7f4..34162d931 100644
--- a/examples/src/bin/dma_channel_link.rs
+++ b/examples/src/bin/dma_channel_link.rs
@@ -18,10 +18,9 @@
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, DmaChannel, DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaCh2InterruptHandler}; 21use embassy_mcxa::dma::{self, DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaCh2InterruptHandler, DmaChannel};
22use embassy_mcxa::bind_interrupts;
23use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 22use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
24use embassy_mcxa::pac; 23use embassy_mcxa::{bind_interrupts, pac};
25use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 24use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
26 25
27// Buffers 26// Buffers
@@ -104,10 +103,14 @@ async fn main(_spawner: Spawner) {
104 103
105 // Clear Global Halt/Error state 104 // Clear Global Halt/Error state
106 dma0.mp_csr().modify(|_, w| { 105 dma0.mp_csr().modify(|_, w| {
107 w.halt().normal_operation() 106 w.halt()
108 .hae().normal_operation() 107 .normal_operation()
109 .ecx().normal_operation() 108 .hae()
110 .cx().normal_operation() 109 .normal_operation()
110 .ecx()
111 .normal_operation()
112 .cx()
113 .normal_operation()
111 }); 114 });
112 115
113 unsafe { 116 unsafe {
@@ -126,8 +129,7 @@ async fn main(_spawner: Spawner) {
126 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); 129 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap();
127 let (mut tx, _rx) = lpuart.split(); 130 let (mut tx, _rx) = lpuart.split();
128 131
129 tx.blocking_write(b"EDMA channel link example begin.\r\n\r\n") 132 tx.blocking_write(b"EDMA channel link example begin.\r\n\r\n").unwrap();
130 .unwrap();
131 133
132 // Initialize buffers 134 // Initialize buffers
133 unsafe { 135 unsafe {
@@ -180,11 +182,16 @@ async fn main(_spawner: Spawner) {
180 182
181 // Reset channel state 183 // Reset channel state
182 t.ch_csr().write(|w| { 184 t.ch_csr().write(|w| {
183 w.erq().disable() 185 w.erq()
184 .earq().disable() 186 .disable()
185 .eei().no_error() 187 .earq()
186 .ebw().disable() 188 .disable()
187 .done().clear_bit_by_one() 189 .eei()
190 .no_error()
191 .ebw()
192 .disable()
193 .done()
194 .clear_bit_by_one()
188 }); 195 });
189 t.ch_es().write(|w| w.bits(0)); 196 t.ch_es().write(|w| w.bits(0));
190 t.ch_int().write(|w| w.int().clear_bit_by_one()); 197 t.ch_int().write(|w| w.int().clear_bit_by_one());
@@ -211,8 +218,10 @@ async fn main(_spawner: Spawner) {
211 218
212 // Major loop: reset source address after major loop 219 // Major loop: reset source address after major loop
213 let total_bytes = nbytes * count as u32; 220 let total_bytes = nbytes * count as u32;
214 t.tcd_slast_sda().write(|w| w.slast_sda().bits(-(total_bytes as i32) as u32)); 221 t.tcd_slast_sda()
215 t.tcd_dlast_sga().write(|w| w.dlast_sga().bits(-(total_bytes as i32) as u32)); 222 .write(|w| w.slast_sda().bits(-(total_bytes as i32) as u32));
223 t.tcd_dlast_sga()
224 .write(|w| w.dlast_sga().bits(-(total_bytes as i32) as u32));
216 225
217 // Major loop count 226 // Major loop count
218 t.tcd_biter_elinkno().write(|w| w.biter().bits(count)); 227 t.tcd_biter_elinkno().write(|w| w.biter().bits(count));
@@ -229,7 +238,6 @@ async fn main(_spawner: Spawner) {
229 } 238 }
230 239
231 unsafe { 240 unsafe {
232
233 // Channel 0: Transfer 16 bytes total (8 bytes per minor loop, 2 major iterations) 241 // Channel 0: Transfer 16 bytes total (8 bytes per minor loop, 2 major iterations)
234 // Minor Link -> Channel 1 242 // Minor Link -> Channel 1
235 // Major Link -> Channel 2 243 // Major Link -> Channel 2
@@ -265,34 +273,44 @@ async fn main(_spawner: Spawner) {
265 core::ptr::addr_of!(SRC_BUFFER) as u32, 273 core::ptr::addr_of!(SRC_BUFFER) as u32,
266 core::ptr::addr_of_mut!(DEST_BUFFER2) as u32, 274 core::ptr::addr_of_mut!(DEST_BUFFER2) as u32,
267 4, 275 4,
268 16, // full buffer in one minor loop 276 16, // full buffer in one minor loop
269 1, // 1 major iteration 277 1, // 1 major iteration
270 true, // enable interrupt 278 true, // enable interrupt
271 ); 279 );
272 } 280 }
273 281
274 tx.blocking_write(b"Triggering Channel 0 (1st minor loop)...\r\n").unwrap(); 282 tx.blocking_write(b"Triggering Channel 0 (1st minor loop)...\r\n")
283 .unwrap();
275 284
276 // Trigger first minor loop of CH0 285 // Trigger first minor loop of CH0
277 unsafe { ch0.trigger_start(); } 286 unsafe {
287 ch0.trigger_start();
288 }
278 289
279 // Wait for CH1 to complete (triggered by CH0 minor link) 290 // Wait for CH1 to complete (triggered by CH0 minor link)
280 while !ch1.is_done() { 291 while !ch1.is_done() {
281 cortex_m::asm::nop(); 292 cortex_m::asm::nop();
282 } 293 }
283 unsafe { ch1.clear_done(); } 294 unsafe {
295 ch1.clear_done();
296 }
284 297
285 tx.blocking_write(b"CH1 done (via minor link).\r\n").unwrap(); 298 tx.blocking_write(b"CH1 done (via minor link).\r\n").unwrap();
286 tx.blocking_write(b"Triggering Channel 0 (2nd minor loop)...\r\n").unwrap(); 299 tx.blocking_write(b"Triggering Channel 0 (2nd minor loop)...\r\n")
300 .unwrap();
287 301
288 // Trigger second minor loop of CH0 302 // Trigger second minor loop of CH0
289 unsafe { ch0.trigger_start(); } 303 unsafe {
304 ch0.trigger_start();
305 }
290 306
291 // Wait for CH0 major loop to complete 307 // Wait for CH0 major loop to complete
292 while !ch0.is_done() { 308 while !ch0.is_done() {
293 cortex_m::asm::nop(); 309 cortex_m::asm::nop();
294 } 310 }
295 unsafe { ch0.clear_done(); } 311 unsafe {
312 ch0.clear_done();
313 }
296 314
297 tx.blocking_write(b"CH0 major loop done.\r\n").unwrap(); 315 tx.blocking_write(b"CH0 major loop done.\r\n").unwrap();
298 316
@@ -302,12 +320,13 @@ async fn main(_spawner: Spawner) {
302 while !ch2.is_done() { 320 while !ch2.is_done() {
303 cortex_m::asm::nop(); 321 cortex_m::asm::nop();
304 } 322 }
305 unsafe { ch2.clear_done(); } 323 unsafe {
324 ch2.clear_done();
325 }
306 326
307 tx.blocking_write(b"CH2 done (via major link).\r\n\r\n").unwrap(); 327 tx.blocking_write(b"CH2 done (via major link).\r\n\r\n").unwrap();
308 328
309 tx.blocking_write(b"EDMA channel link example finish.\r\n\r\n") 329 tx.blocking_write(b"EDMA channel link example finish.\r\n\r\n").unwrap();
310 .unwrap();
311 330
312 tx.blocking_write(b"DEST0 (after): ").unwrap(); 331 tx.blocking_write(b"DEST0 (after): ").unwrap();
313 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER0) as *const u32, 4); 332 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER0) as *const u32, 4);
@@ -330,9 +349,15 @@ async fn main(_spawner: Spawner) {
330 let dst2_ptr = core::ptr::addr_of!(DEST_BUFFER2) as *const u32; 349 let dst2_ptr = core::ptr::addr_of!(DEST_BUFFER2) as *const u32;
331 350
332 for i in 0..4 { 351 for i in 0..4 {
333 if *dst0_ptr.add(i) != *src_ptr.add(i) { success = false; } 352 if *dst0_ptr.add(i) != *src_ptr.add(i) {
334 if *dst1_ptr.add(i) != *src_ptr.add(i) { success = false; } 353 success = false;
335 if *dst2_ptr.add(i) != *src_ptr.add(i) { success = false; } 354 }
355 if *dst1_ptr.add(i) != *src_ptr.add(i) {
356 success = false;
357 }
358 if *dst2_ptr.add(i) != *src_ptr.add(i) {
359 success = false;
360 }
336 } 361 }
337 } 362 }
338 363
@@ -348,4 +373,3 @@ async fn main(_spawner: Spawner) {
348 cortex_m::asm::wfe(); 373 cortex_m::asm::wfe();
349 } 374 }
350} 375}
351
diff --git a/examples/src/bin/dma_interleave_transfer.rs b/examples/src/bin/dma_interleave_transfer.rs
index 949ea0605..c0ebb0a46 100644
--- a/examples/src/bin/dma_interleave_transfer.rs
+++ b/examples/src/bin/dma_interleave_transfer.rs
@@ -12,10 +12,9 @@
12 12
13use embassy_executor::Spawner; 13use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 14use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler}; 15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel};
16use embassy_mcxa::bind_interrupts;
17use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 16use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
18use embassy_mcxa::pac; 17use embassy_mcxa::{bind_interrupts, pac};
19use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
20 19
21// Bind DMA channel 0 interrupt using Embassy-style macro 20// Bind DMA channel 0 interrupt using Embassy-style macro
@@ -125,22 +124,29 @@ async fn main(_spawner: Spawner) {
125 124
126 // Reset channel state 125 // Reset channel state
127 t.ch_csr().write(|w| { 126 t.ch_csr().write(|w| {
128 w.erq().disable() 127 w.erq()
129 .earq().disable() 128 .disable()
130 .eei().no_error() 129 .earq()
131 .ebw().disable() 130 .disable()
132 .done().clear_bit_by_one() 131 .eei()
132 .no_error()
133 .ebw()
134 .disable()
135 .done()
136 .clear_bit_by_one()
133 }); 137 });
134 t.ch_es().write(|w| w.bits(0)); 138 t.ch_es().write(|w| w.bits(0));
135 t.ch_int().write(|w| w.int().clear_bit_by_one()); 139 t.ch_int().write(|w| w.int().clear_bit_by_one());
136 140
137 // Source/destination addresses 141 // Source/destination addresses
138 t.tcd_saddr().write(|w| w.saddr().bits(core::ptr::addr_of_mut!(SRC_BUFFER) as u32)); 142 t.tcd_saddr()
139 t.tcd_daddr().write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32)); 143 .write(|w| w.saddr().bits(core::ptr::addr_of_mut!(SRC_BUFFER) as u32));
144 t.tcd_daddr()
145 .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32));
140 146
141 // Custom offsets for interleaving 147 // Custom offsets for interleaving
142 t.tcd_soff().write(|w| w.soff().bits(4)); // src: +4 bytes per read 148 t.tcd_soff().write(|w| w.soff().bits(4)); // src: +4 bytes per read
143 t.tcd_doff().write(|w| w.doff().bits(8)); // dst: +8 bytes per write 149 t.tcd_doff().write(|w| w.doff().bits(8)); // dst: +8 bytes per write
144 150
145 // Attributes: 32-bit transfers (size = 2) 151 // Attributes: 32-bit transfers (size = 2)
146 t.tcd_attr().write(|w| w.ssize().bits(2).dsize().bits(2)); 152 t.tcd_attr().write(|w| w.ssize().bits(2).dsize().bits(2));
@@ -153,7 +159,8 @@ async fn main(_spawner: Spawner) {
153 t.tcd_slast_sda().write(|w| w.slast_sda().bits(-(nbytes as i32) as u32)); 159 t.tcd_slast_sda().write(|w| w.slast_sda().bits(-(nbytes as i32) as u32));
154 // Destination uses 2x offset, so adjust accordingly 160 // Destination uses 2x offset, so adjust accordingly
155 let dst_total = (HALF_BUFF_LENGTH * 8) as u32; 161 let dst_total = (HALF_BUFF_LENGTH * 8) as u32;
156 t.tcd_dlast_sga().write(|w| w.dlast_sga().bits(-(dst_total as i32) as u32)); 162 t.tcd_dlast_sga()
163 .write(|w| w.dlast_sga().bits(-(dst_total as i32) as u32));
157 164
158 // Major loop count = 1 165 // Major loop count = 1
159 t.tcd_biter_elinkno().write(|w| w.biter().bits(1)); 166 t.tcd_biter_elinkno().write(|w| w.biter().bits(1));
@@ -172,7 +179,9 @@ async fn main(_spawner: Spawner) {
172 while !dma_ch0.is_done() { 179 while !dma_ch0.is_done() {
173 cortex_m::asm::nop(); 180 cortex_m::asm::nop();
174 } 181 }
175 unsafe { dma_ch0.clear_done(); } 182 unsafe {
183 dma_ch0.clear_done();
184 }
176 185
177 tx.blocking_write(b"\r\nEDMA interleave transfer example finish.\r\n\r\n") 186 tx.blocking_write(b"\r\nEDMA interleave transfer example finish.\r\n\r\n")
178 .unwrap(); 187 .unwrap();
@@ -206,4 +215,3 @@ async fn main(_spawner: Spawner) {
206 cortex_m::asm::wfe(); 215 cortex_m::asm::wfe();
207 } 216 }
208} 217}
209
diff --git a/examples/src/bin/dma_mem_to_mem.rs b/examples/src/bin/dma_mem_to_mem.rs
index 01e5edb1e..72916384f 100644
--- a/examples/src/bin/dma_mem_to_mem.rs
+++ b/examples/src/bin/dma_mem_to_mem.rs
@@ -15,10 +15,9 @@
15 15
16use embassy_executor::Spawner; 16use embassy_executor::Spawner;
17use embassy_mcxa::clocks::config::Div8; 17use embassy_mcxa::clocks::config::Div8;
18use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler, TransferOptions}; 18use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, TransferOptions};
19use embassy_mcxa::bind_interrupts;
20use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 19use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
21use embassy_mcxa::pac; 20use embassy_mcxa::{bind_interrupts, pac};
22use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 21use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
23 22
24// Bind DMA channel 0 interrupt using Embassy-style macro 23// Bind DMA channel 0 interrupt using Embassy-style macro
@@ -147,8 +146,7 @@ async fn main(_spawner: Spawner) {
147 transfer.await; 146 transfer.await;
148 } 147 }
149 148
150 tx.blocking_write(b"DMA mem-to-mem transfer complete!\r\n\r\n") 149 tx.blocking_write(b"DMA mem-to-mem transfer complete!\r\n\r\n").unwrap();
151 .unwrap();
152 tx.blocking_write(b"Destination Buffer (after): ").unwrap(); 150 tx.blocking_write(b"Destination Buffer (after): ").unwrap();
153 print_buffer(&mut tx, &raw const DEST_BUFFER); 151 print_buffer(&mut tx, &raw const DEST_BUFFER);
154 tx.blocking_write(b"\r\n").unwrap(); 152 tx.blocking_write(b"\r\n").unwrap();
@@ -181,7 +179,8 @@ async fn main(_spawner: Spawner) {
181 // - Incrementing destination address 179 // - Incrementing destination address
182 // - Uses the same Transfer future pattern 180 // - Uses the same Transfer future pattern
183 181
184 tx.blocking_write(b"--- Demonstrating memset() feature ---\r\n\r\n").unwrap(); 182 tx.blocking_write(b"--- Demonstrating memset() feature ---\r\n\r\n")
183 .unwrap();
185 184
186 tx.blocking_write(b"Memset Buffer (before): ").unwrap(); 185 tx.blocking_write(b"Memset Buffer (before): ").unwrap();
187 print_buffer(&mut tx, &raw const MEMSET_BUFFER); 186 print_buffer(&mut tx, &raw const MEMSET_BUFFER);
@@ -230,4 +229,3 @@ async fn main(_spawner: Spawner) {
230 cortex_m::asm::wfe(); 229 cortex_m::asm::wfe();
231 } 230 }
232} 231}
233
diff --git a/examples/src/bin/dma_memset.rs b/examples/src/bin/dma_memset.rs
index 8a1636e57..9fbba85e9 100644
--- a/examples/src/bin/dma_memset.rs
+++ b/examples/src/bin/dma_memset.rs
@@ -12,10 +12,9 @@
12 12
13use embassy_executor::Spawner; 13use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 14use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler}; 15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel};
16use embassy_mcxa::bind_interrupts;
17use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 16use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
18use embassy_mcxa::pac; 17use embassy_mcxa::{bind_interrupts, pac};
19use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
20 19
21// Bind DMA channel 0 interrupt using Embassy-style macro 20// Bind DMA channel 0 interrupt using Embassy-style macro
@@ -92,8 +91,7 @@ async fn main(_spawner: Spawner) {
92 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); 91 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap();
93 let (mut tx, _rx) = lpuart.split(); 92 let (mut tx, _rx) = lpuart.split();
94 93
95 tx.blocking_write(b"EDMA memset example begin.\r\n\r\n") 94 tx.blocking_write(b"EDMA memset example begin.\r\n\r\n").unwrap();
96 .unwrap();
97 95
98 // Initialize buffers 96 // Initialize buffers
99 unsafe { 97 unsafe {
@@ -133,19 +131,26 @@ async fn main(_spawner: Spawner) {
133 131
134 // Reset channel state 132 // Reset channel state
135 t.ch_csr().write(|w| { 133 t.ch_csr().write(|w| {
136 w.erq().disable() 134 w.erq()
137 .earq().disable() 135 .disable()
138 .eei().no_error() 136 .earq()
139 .ebw().disable() 137 .disable()
140 .done().clear_bit_by_one() 138 .eei()
139 .no_error()
140 .ebw()
141 .disable()
142 .done()
143 .clear_bit_by_one()
141 }); 144 });
142 t.ch_es().write(|w| w.bits(0)); 145 t.ch_es().write(|w| w.bits(0));
143 t.ch_int().write(|w| w.int().clear_bit_by_one()); 146 t.ch_int().write(|w| w.int().clear_bit_by_one());
144 147
145 // Source address (pattern) - fixed 148 // Source address (pattern) - fixed
146 t.tcd_saddr().write(|w| w.saddr().bits(core::ptr::addr_of_mut!(PATTERN) as u32)); 149 t.tcd_saddr()
150 .write(|w| w.saddr().bits(core::ptr::addr_of_mut!(PATTERN) as u32));
147 // Destination address - increments 151 // Destination address - increments
148 t.tcd_daddr().write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32)); 152 t.tcd_daddr()
153 .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32));
149 154
150 // Source offset = 0 (stays fixed), Dest offset = 4 (increments) 155 // Source offset = 0 (stays fixed), Dest offset = 4 (increments)
151 t.tcd_soff().write(|w| w.soff().bits(0)); 156 t.tcd_soff().write(|w| w.soff().bits(0));
@@ -180,10 +185,11 @@ async fn main(_spawner: Spawner) {
180 while !dma_ch0.is_done() { 185 while !dma_ch0.is_done() {
181 cortex_m::asm::nop(); 186 cortex_m::asm::nop();
182 } 187 }
183 unsafe { dma_ch0.clear_done(); } 188 unsafe {
189 dma_ch0.clear_done();
190 }
184 191
185 tx.blocking_write(b"\r\nEDMA memset example finish.\r\n\r\n") 192 tx.blocking_write(b"\r\nEDMA memset example finish.\r\n\r\n").unwrap();
186 .unwrap();
187 tx.blocking_write(b"Destination Buffer (after): ").unwrap(); 193 tx.blocking_write(b"Destination Buffer (after): ").unwrap();
188 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH); 194 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH);
189 tx.blocking_write(b"\r\n\r\n").unwrap(); 195 tx.blocking_write(b"\r\n\r\n").unwrap();
@@ -212,4 +218,3 @@ async fn main(_spawner: Spawner) {
212 cortex_m::asm::wfe(); 218 cortex_m::asm::wfe();
213 } 219 }
214} 220}
215
diff --git a/examples/src/bin/dma_ping_pong_transfer.rs b/examples/src/bin/dma_ping_pong_transfer.rs
index d765ea575..692515441 100644
--- a/examples/src/bin/dma_ping_pong_transfer.rs
+++ b/examples/src/bin/dma_ping_pong_transfer.rs
@@ -24,12 +24,12 @@
24#![no_main] 24#![no_main]
25 25
26use core::sync::atomic::{AtomicBool, Ordering}; 26use core::sync::atomic::{AtomicBool, Ordering};
27
27use embassy_executor::Spawner; 28use embassy_executor::Spawner;
28use embassy_mcxa::clocks::config::Div8; 29use embassy_mcxa::clocks::config::Div8;
29use embassy_mcxa::dma::{self, DmaChannel, DmaCh1InterruptHandler, Tcd, TransferOptions}; 30use embassy_mcxa::dma::{self, DmaCh1InterruptHandler, DmaChannel, Tcd, TransferOptions};
30use embassy_mcxa::bind_interrupts;
31use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 31use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
32use embassy_mcxa::pac; 32use embassy_mcxa::{bind_interrupts, pac};
33use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 33use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
34 34
35// Source and destination buffers for Approach 1 (scatter/gather) 35// Source and destination buffers for Approach 1 (scatter/gather)
@@ -44,19 +44,21 @@ static mut DST2: [u32; 8] = [0; 8];
44#[repr(C, align(32))] 44#[repr(C, align(32))]
45struct TcdPool([Tcd; 2]); 45struct TcdPool([Tcd; 2]);
46 46
47static mut TCD_POOL: TcdPool = TcdPool([Tcd { 47static mut TCD_POOL: TcdPool = TcdPool(
48 saddr: 0, 48 [Tcd {
49 soff: 0, 49 saddr: 0,
50 attr: 0, 50 soff: 0,
51 nbytes: 0, 51 attr: 0,
52 slast: 0, 52 nbytes: 0,
53 daddr: 0, 53 slast: 0,
54 doff: 0, 54 daddr: 0,
55 citer: 0, 55 doff: 0,
56 dlast_sga: 0, 56 citer: 0,
57 csr: 0, 57 dlast_sga: 0,
58 biter: 0, 58 csr: 0,
59}; 2]); 59 biter: 0,
60 }; 2],
61);
60 62
61// AtomicBool to track scatter/gather completion 63// AtomicBool to track scatter/gather completion
62// Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads, 64// Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads,
@@ -289,7 +291,8 @@ async fn main(_spawner: Spawner) {
289 // - True async/await support 291 // - True async/await support
290 // - Good for streaming data processing 292 // - Good for streaming data processing
291 293
292 tx.blocking_write(b"--- Approach 2: wait_half() demo ---\r\n\r\n").unwrap(); 294 tx.blocking_write(b"--- Approach 2: wait_half() demo ---\r\n\r\n")
295 .unwrap();
293 296
294 // Enable DMA CH1 interrupt 297 // Enable DMA CH1 interrupt
295 unsafe { 298 unsafe {
@@ -310,10 +313,11 @@ async fn main(_spawner: Spawner) {
310 313
311 // Configure transfer with half-transfer interrupt enabled 314 // Configure transfer with half-transfer interrupt enabled
312 let mut options = TransferOptions::default(); 315 let mut options = TransferOptions::default();
313 options.half_transfer_interrupt = true; // Enable half-transfer interrupt 316 options.half_transfer_interrupt = true; // Enable half-transfer interrupt
314 options.complete_transfer_interrupt = true; 317 options.complete_transfer_interrupt = true;
315 318
316 tx.blocking_write(b"Starting transfer with half_transfer_interrupt...\r\n").unwrap(); 319 tx.blocking_write(b"Starting transfer with half_transfer_interrupt...\r\n")
320 .unwrap();
317 321
318 unsafe { 322 unsafe {
319 let src = &*core::ptr::addr_of!(SRC2); 323 let src = &*core::ptr::addr_of!(SRC2);
@@ -327,10 +331,12 @@ async fn main(_spawner: Spawner) {
327 let half_ok = transfer.wait_half().await; 331 let half_ok = transfer.wait_half().await;
328 332
329 if half_ok { 333 if half_ok {
330 tx.blocking_write(b"Half-transfer complete! First half of DST2: ").unwrap(); 334 tx.blocking_write(b"Half-transfer complete! First half of DST2: ")
335 .unwrap();
331 print_buffer(&mut tx, core::ptr::addr_of!(DST2) as *const u32, 4); 336 print_buffer(&mut tx, core::ptr::addr_of!(DST2) as *const u32, 4);
332 tx.blocking_write(b"\r\n").unwrap(); 337 tx.blocking_write(b"\r\n").unwrap();
333 tx.blocking_write(b"(Processing first half while second half transfers...)\r\n").unwrap(); 338 tx.blocking_write(b"(Processing first half while second half transfers...)\r\n")
339 .unwrap();
334 } 340 }
335 341
336 // Wait for complete transfer 342 // Wait for complete transfer
@@ -363,10 +369,10 @@ async fn main(_spawner: Spawner) {
363 defmt::info!("PASS: Approach 2 verified."); 369 defmt::info!("PASS: Approach 2 verified.");
364 } 370 }
365 371
366 tx.blocking_write(b"\r\n=== All ping-pong demos complete ===\r\n").unwrap(); 372 tx.blocking_write(b"\r\n=== All ping-pong demos complete ===\r\n")
373 .unwrap();
367 374
368 loop { 375 loop {
369 cortex_m::asm::wfe(); 376 cortex_m::asm::wfe();
370 } 377 }
371} 378}
372
diff --git a/examples/src/bin/dma_scatter_gather.rs b/examples/src/bin/dma_scatter_gather.rs
index d78605acc..b5ae00057 100644
--- a/examples/src/bin/dma_scatter_gather.rs
+++ b/examples/src/bin/dma_scatter_gather.rs
@@ -13,12 +13,12 @@
13#![no_main] 13#![no_main]
14 14
15use core::sync::atomic::{AtomicBool, Ordering}; 15use core::sync::atomic::{AtomicBool, Ordering};
16
16use embassy_executor::Spawner; 17use embassy_executor::Spawner;
17use embassy_mcxa::clocks::config::Div8; 18use embassy_mcxa::clocks::config::Div8;
18use embassy_mcxa::dma::{self, DmaChannel, Tcd}; 19use embassy_mcxa::dma::{self, DmaChannel, Tcd};
19use embassy_mcxa::bind_interrupts;
20use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 20use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
21use embassy_mcxa::pac; 21use embassy_mcxa::{bind_interrupts, pac};
22use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 22use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
23 23
24// Source and destination buffers 24// Source and destination buffers
@@ -29,19 +29,21 @@ static mut DST: [u32; 8] = [0; 8];
29#[repr(C, align(32))] 29#[repr(C, align(32))]
30struct TcdPool([Tcd; 2]); 30struct TcdPool([Tcd; 2]);
31 31
32static mut TCD_POOL: TcdPool = TcdPool([Tcd { 32static mut TCD_POOL: TcdPool = TcdPool(
33 saddr: 0, 33 [Tcd {
34 soff: 0, 34 saddr: 0,
35 attr: 0, 35 soff: 0,
36 nbytes: 0, 36 attr: 0,
37 slast: 0, 37 nbytes: 0,
38 daddr: 0, 38 slast: 0,
39 doff: 0, 39 daddr: 0,
40 citer: 0, 40 doff: 0,
41 dlast_sga: 0, 41 citer: 0,
42 csr: 0, 42 dlast_sga: 0,
43 biter: 0, 43 csr: 0,
44}; 2]); 44 biter: 0,
45 }; 2],
46);
45 47
46// AtomicBool to track scatter/gather completion 48// AtomicBool to track scatter/gather completion
47// Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads, 49// Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads,
@@ -53,7 +55,9 @@ static TRANSFER_DONE: AtomicBool = AtomicBool::new(false);
53// (delegates to HAL + sets a flag) and the main task does the actual processing 55// (delegates to HAL + sets a flag) and the main task does the actual processing
54pub struct ScatterGatherDmaHandler; 56pub struct ScatterGatherDmaHandler;
55 57
56impl embassy_mcxa::interrupt::typelevel::Handler<embassy_mcxa::interrupt::typelevel::DMA_CH0> for ScatterGatherDmaHandler { 58impl embassy_mcxa::interrupt::typelevel::Handler<embassy_mcxa::interrupt::typelevel::DMA_CH0>
59 for ScatterGatherDmaHandler
60{
57 unsafe fn on_interrupt() { 61 unsafe fn on_interrupt() {
58 // Delegate to HAL's on_interrupt() which clears INT flag and wakes wakers 62 // Delegate to HAL's on_interrupt() which clears INT flag and wakes wakers
59 dma::on_interrupt(0); 63 dma::on_interrupt(0);
@@ -161,10 +165,7 @@ async fn main(_spawner: Spawner) {
161 // TCD0 transfers first half (SRC[0..4] -> DST[0..4]), then loads TCD1. 165 // TCD0 transfers first half (SRC[0..4] -> DST[0..4]), then loads TCD1.
162 // TCD1 transfers second half (SRC[4..8] -> DST[4..8]), last TCD. 166 // TCD1 transfers second half (SRC[4..8] -> DST[4..8]), last TCD.
163 unsafe { 167 unsafe {
164 let tcds = core::slice::from_raw_parts_mut( 168 let tcds = core::slice::from_raw_parts_mut(core::ptr::addr_of_mut!(TCD_POOL.0) as *mut Tcd, 2);
165 core::ptr::addr_of_mut!(TCD_POOL.0) as *mut Tcd,
166 2,
167 );
168 let src_ptr = core::ptr::addr_of!(SRC) as *const u32; 169 let src_ptr = core::ptr::addr_of!(SRC) as *const u32;
169 let dst_ptr = core::ptr::addr_of_mut!(DST) as *mut u32; 170 let dst_ptr = core::ptr::addr_of_mut!(DST) as *mut u32;
170 171
@@ -262,4 +263,3 @@ async fn main(_spawner: Spawner) {
262 cortex_m::asm::wfe(); 263 cortex_m::asm::wfe();
263 } 264 }
264} 265}
265
diff --git a/examples/src/bin/dma_scatter_gather_builder.rs b/examples/src/bin/dma_scatter_gather_builder.rs
index 51bfbeb67..d42ff841e 100644
--- a/examples/src/bin/dma_scatter_gather_builder.rs
+++ b/examples/src/bin/dma_scatter_gather_builder.rs
@@ -22,10 +22,9 @@
22 22
23use embassy_executor::Spawner; 23use embassy_executor::Spawner;
24use embassy_mcxa::clocks::config::Div8; 24use embassy_mcxa::clocks::config::Div8;
25use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler, ScatterGatherBuilder}; 25use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, ScatterGatherBuilder};
26use embassy_mcxa::bind_interrupts;
27use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 26use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
28use embassy_mcxa::pac; 27use embassy_mcxa::{bind_interrupts, pac};
29use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 28use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
30 29
31// Bind DMA channel 0 interrupt 30// Bind DMA channel 0 interrupt
@@ -97,7 +96,8 @@ async fn main(_spawner: Spawner) {
97 let (mut tx, _rx) = lpuart.split(); 96 let (mut tx, _rx) = lpuart.split();
98 97
99 tx.blocking_write(b"DMA Scatter-Gather Builder Example\r\n").unwrap(); 98 tx.blocking_write(b"DMA Scatter-Gather Builder Example\r\n").unwrap();
100 tx.blocking_write(b"===================================\r\n\r\n").unwrap(); 99 tx.blocking_write(b"===================================\r\n\r\n")
100 .unwrap();
101 101
102 // Show source buffers 102 // Show source buffers
103 tx.blocking_write(b"Source buffers:\r\n").unwrap(); 103 tx.blocking_write(b"Source buffers:\r\n").unwrap();
@@ -125,7 +125,8 @@ async fn main(_spawner: Spawner) {
125 // Create DMA channel 125 // Create DMA channel
126 let dma_ch0 = DmaChannel::new(p.DMA_CH0); 126 let dma_ch0 = DmaChannel::new(p.DMA_CH0);
127 127
128 tx.blocking_write(b"Building scatter-gather chain with builder API...\r\n").unwrap(); 128 tx.blocking_write(b"Building scatter-gather chain with builder API...\r\n")
129 .unwrap();
129 130
130 // ========================================================================= 131 // =========================================================================
131 // ScatterGatherBuilder API demonstration 132 // ScatterGatherBuilder API demonstration
@@ -159,7 +160,8 @@ async fn main(_spawner: Spawner) {
159 } 160 }
160 161
161 tx.blocking_write(b"Added 3 transfer segments to chain.\r\n").unwrap(); 162 tx.blocking_write(b"Added 3 transfer segments to chain.\r\n").unwrap();
162 tx.blocking_write(b"Starting scatter-gather transfer with .await...\r\n\r\n").unwrap(); 163 tx.blocking_write(b"Starting scatter-gather transfer with .await...\r\n\r\n")
164 .unwrap();
163 165
164 // Build and execute the scatter-gather chain 166 // Build and execute the scatter-gather chain
165 // The build() method: 167 // The build() method:
@@ -222,7 +224,8 @@ async fn main(_spawner: Spawner) {
222 defmt::error!("FAIL: Mismatch detected!"); 224 defmt::error!("FAIL: Mismatch detected!");
223 } 225 }
224 226
225 tx.blocking_write(b"\r\n=== Scatter-Gather Builder example complete ===\r\n").unwrap(); 227 tx.blocking_write(b"\r\n=== Scatter-Gather Builder example complete ===\r\n")
228 .unwrap();
226 229
227 loop { 230 loop {
228 cortex_m::asm::wfe(); 231 cortex_m::asm::wfe();
diff --git a/examples/src/bin/dma_wrap_transfer.rs b/examples/src/bin/dma_wrap_transfer.rs
index 8e9aedbfb..0babf4c20 100644
--- a/examples/src/bin/dma_wrap_transfer.rs
+++ b/examples/src/bin/dma_wrap_transfer.rs
@@ -12,10 +12,9 @@
12 12
13use embassy_executor::Spawner; 13use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 14use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler}; 15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel};
16use embassy_mcxa::bind_interrupts;
17use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 16use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
18use embassy_mcxa::pac; 17use embassy_mcxa::{bind_interrupts, pac};
19use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
20 19
21// Bind DMA channel 0 interrupt using Embassy-style macro 20// Bind DMA channel 0 interrupt using Embassy-style macro
@@ -93,8 +92,7 @@ async fn main(_spawner: Spawner) {
93 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); 92 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap();
94 let (mut tx, _rx) = lpuart.split(); 93 let (mut tx, _rx) = lpuart.split();
95 94
96 tx.blocking_write(b"EDMA wrap transfer example begin.\r\n\r\n") 95 tx.blocking_write(b"EDMA wrap transfer example begin.\r\n\r\n").unwrap();
97 .unwrap();
98 96
99 // Initialize buffers 97 // Initialize buffers
100 unsafe { 98 unsafe {
@@ -127,18 +125,25 @@ async fn main(_spawner: Spawner) {
127 125
128 // Reset channel state 126 // Reset channel state
129 t.ch_csr().write(|w| { 127 t.ch_csr().write(|w| {
130 w.erq().disable() 128 w.erq()
131 .earq().disable() 129 .disable()
132 .eei().no_error() 130 .earq()
133 .ebw().disable() 131 .disable()
134 .done().clear_bit_by_one() 132 .eei()
133 .no_error()
134 .ebw()
135 .disable()
136 .done()
137 .clear_bit_by_one()
135 }); 138 });
136 t.ch_es().write(|w| w.bits(0)); 139 t.ch_es().write(|w| w.bits(0));
137 t.ch_int().write(|w| w.int().clear_bit_by_one()); 140 t.ch_int().write(|w| w.int().clear_bit_by_one());
138 141
139 // Source/destination addresses 142 // Source/destination addresses
140 t.tcd_saddr().write(|w| w.saddr().bits(core::ptr::addr_of!(SRC.0) as u32)); 143 t.tcd_saddr()
141 t.tcd_daddr().write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DST) as u32)); 144 .write(|w| w.saddr().bits(core::ptr::addr_of!(SRC.0) as u32));
145 t.tcd_daddr()
146 .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DST) as u32));
142 147
143 // Offsets: both increment by 4 bytes 148 // Offsets: both increment by 4 bytes
144 t.tcd_soff().write(|w| w.soff().bits(4)); 149 t.tcd_soff().write(|w| w.soff().bits(4));
@@ -147,10 +152,14 @@ async fn main(_spawner: Spawner) {
147 // Attributes: 32-bit transfers (size = 2) 152 // Attributes: 32-bit transfers (size = 2)
148 // SMOD = 4 (2^4 = 16 byte modulo for source), DMOD = 0 (disabled) 153 // SMOD = 4 (2^4 = 16 byte modulo for source), DMOD = 0 (disabled)
149 t.tcd_attr().write(|w| { 154 t.tcd_attr().write(|w| {
150 w.ssize().bits(2) 155 w.ssize()
151 .dsize().bits(2) 156 .bits(2)
152 .smod().bits(4) // Source modulo: 2^4 = 16 bytes 157 .dsize()
153 .dmod().bits(0) // Dest modulo: disabled 158 .bits(2)
159 .smod()
160 .bits(4) // Source modulo: 2^4 = 16 bytes
161 .dmod()
162 .bits(0) // Dest modulo: disabled
154 }); 163 });
155 164
156 // Transfer 32 bytes total in one minor loop 165 // Transfer 32 bytes total in one minor loop
@@ -179,7 +188,9 @@ async fn main(_spawner: Spawner) {
179 while !dma_ch0.is_done() { 188 while !dma_ch0.is_done() {
180 cortex_m::asm::nop(); 189 cortex_m::asm::nop();
181 } 190 }
182 unsafe { dma_ch0.clear_done(); } 191 unsafe {
192 dma_ch0.clear_done();
193 }
183 194
184 tx.blocking_write(b"\r\nEDMA wrap transfer example finish.\r\n\r\n") 195 tx.blocking_write(b"\r\nEDMA wrap transfer example finish.\r\n\r\n")
185 .unwrap(); 196 .unwrap();
@@ -211,4 +222,3 @@ async fn main(_spawner: Spawner) {
211 cortex_m::asm::wfe(); 222 cortex_m::asm::wfe();
212 } 223 }
213} 224}
214
diff --git a/examples/src/bin/lpuart_dma.rs b/examples/src/bin/lpuart_dma.rs
index 4e321b111..f4dfbcf39 100644
--- a/examples/src/bin/lpuart_dma.rs
+++ b/examples/src/bin/lpuart_dma.rs
@@ -48,8 +48,7 @@ async fn main(_spawner: Spawner) {
48 48
49 // Create UART instance with DMA channels 49 // Create UART instance with DMA channels
50 let mut lpuart = LpuartDma::new( 50 let mut lpuart = LpuartDma::new(
51 p.LPUART2, 51 p.LPUART2, p.P2_2, // TX pin
52 p.P2_2, // TX pin
53 p.P2_3, // RX pin 52 p.P2_3, // RX pin
54 p.DMA_CH0, // TX DMA channel 53 p.DMA_CH0, // TX DMA channel
55 p.DMA_CH1, // RX DMA channel 54 p.DMA_CH1, // RX DMA channel
@@ -82,4 +81,3 @@ async fn main(_spawner: Spawner) {
82 81
83 defmt::info!("Example complete"); 82 defmt::info!("Example complete");
84} 83}
85
diff --git a/examples/src/bin/lpuart_ring_buffer.rs b/examples/src/bin/lpuart_ring_buffer.rs
index d71876ade..6cc14f1c7 100644
--- a/examples/src/bin/lpuart_ring_buffer.rs
+++ b/examples/src/bin/lpuart_ring_buffer.rs
@@ -20,7 +20,7 @@
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::{DmaChannel, DmaCh0InterruptHandler, DmaCh1InterruptHandler, DMA_REQ_LPUART2_RX}; 23use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaChannel, DMA_REQ_LPUART2_RX};
24use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 24use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
25use embassy_mcxa::{bind_interrupts, pac}; 25use embassy_mcxa::{bind_interrupts, pac};
26use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 26use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
@@ -91,7 +91,8 @@ async fn main(_spawner: Spawner) {
91 dma_ch_rx.set_request_source(DMA_REQ_LPUART2_RX); 91 dma_ch_rx.set_request_source(DMA_REQ_LPUART2_RX);
92 } 92 }
93 93
94 tx.blocking_write(b"Setting up circular DMA for UART RX...\r\n").unwrap(); 94 tx.blocking_write(b"Setting up circular DMA for UART RX...\r\n")
95 .unwrap();
95 96
96 // Set up the ring buffer with circular DMA 97 // Set up the ring buffer with circular DMA
97 // This configures the DMA for continuous reception 98 // This configures the DMA for continuous reception
@@ -105,8 +106,10 @@ async fn main(_spawner: Spawner) {
105 dma_ch_rx.enable_request(); 106 dma_ch_rx.enable_request();
106 } 107 }
107 108
108 tx.blocking_write(b"Ring buffer ready! Type characters to see them echoed.\r\n").unwrap(); 109 tx.blocking_write(b"Ring buffer ready! Type characters to see them echoed.\r\n")
109 tx.blocking_write(b"The DMA continuously receives in the background.\r\n\r\n").unwrap(); 110 .unwrap();
111 tx.blocking_write(b"The DMA continuously receives in the background.\r\n\r\n")
112 .unwrap();
110 113
111 // Main loop: read from ring buffer and echo back 114 // Main loop: read from ring buffer and echo back
112 let mut read_buf = [0u8; 16]; 115 let mut read_buf = [0u8; 16];
@@ -144,4 +147,3 @@ async fn main(_spawner: Spawner) {
144 } 147 }
145 } 148 }
146} 149}
147