aboutsummaryrefslogtreecommitdiff
path: root/examples/mcxa
diff options
context:
space:
mode:
Diffstat (limited to 'examples/mcxa')
-rw-r--r--examples/mcxa/src/bin/dma_scatter_gather_builder.rs168
1 files changed, 57 insertions, 111 deletions
diff --git a/examples/mcxa/src/bin/dma_scatter_gather_builder.rs b/examples/mcxa/src/bin/dma_scatter_gather_builder.rs
index d0f9ae9c4..ba8682cee 100644
--- a/examples/mcxa/src/bin/dma_scatter_gather_builder.rs
+++ b/examples/mcxa/src/bin/dma_scatter_gather_builder.rs
@@ -25,23 +25,18 @@ use core::fmt::Write as _;
25use embassy_executor::Spawner; 25use embassy_executor::Spawner;
26use embassy_mcxa::clocks::config::Div8; 26use embassy_mcxa::clocks::config::Div8;
27use embassy_mcxa::dma::{DmaChannel, ScatterGatherBuilder}; 27use embassy_mcxa::dma::{DmaChannel, ScatterGatherBuilder};
28use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 28use static_cell::ConstStaticCell;
29use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 29use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
30 30
31// Source buffers (multiple segments) 31// Source buffers (multiple segments)
32static mut SRC1: [u32; 4] = [0x11111111, 0x22222222, 0x33333333, 0x44444444]; 32static SRC1: ConstStaticCell<[u32; 4]> = ConstStaticCell::new([0x11111111, 0x22222222, 0x33333333, 0x44444444]);
33static mut SRC2: [u32; 4] = [0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD]; 33static SRC2: ConstStaticCell<[u32; 4]> = ConstStaticCell::new([0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD]);
34static mut SRC3: [u32; 4] = [0x12345678, 0x9ABCDEF0, 0xFEDCBA98, 0x76543210]; 34static SRC3: ConstStaticCell<[u32; 4]> = ConstStaticCell::new([0x12345678, 0x9ABCDEF0, 0xFEDCBA98, 0x76543210]);
35 35
36// Destination buffers (one per segment) 36// Destination buffers (one per segment)
37static mut DST1: [u32; 4] = [0; 4]; 37static DST1: ConstStaticCell<[u32; 4]> = ConstStaticCell::new([0; 4]);
38static mut DST2: [u32; 4] = [0; 4]; 38static DST2: ConstStaticCell<[u32; 4]> = ConstStaticCell::new([0; 4]);
39static mut DST3: [u32; 4] = [0; 4]; 39static DST3: ConstStaticCell<[u32; 4]> = ConstStaticCell::new([0; 4]);
40
41/// Helper to print a buffer to UART
42fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) {
43 write!(tx, "{:08X?}", unsafe { core::slice::from_raw_parts(buf_ptr, len) }).ok();
44}
45 40
46#[embassy_executor::main] 41#[embassy_executor::main]
47async fn main(_spawner: Spawner) { 42async fn main(_spawner: Spawner) {
@@ -57,47 +52,30 @@ async fn main(_spawner: Spawner) {
57 52
58 defmt::info!("DMA Scatter-Gather Builder example starting..."); 53 defmt::info!("DMA Scatter-Gather Builder example starting...");
59 54
60 // Create UART for debug output 55 defmt::info!("DMA Scatter-Gather Builder Example");
61 let config = Config { 56 defmt::info!("===================================");
62 baudrate_bps: 115_200, 57 let src1 = SRC1.take();
63 ..Default::default() 58 let src2 = SRC2.take();
64 }; 59 let src3 = SRC3.take();
65 60 let dst1 = DST1.take();
66 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); 61 let dst2 = DST2.take();
67 let (mut tx, _rx) = lpuart.split(); 62 let dst3 = DST3.take();
68
69 tx.blocking_write(b"DMA Scatter-Gather Builder Example\r\n").unwrap();
70 tx.blocking_write(b"===================================\r\n\r\n")
71 .unwrap();
72 63
73 // Show source buffers 64 // Show source buffers
74 tx.blocking_write(b"Source buffers:\r\n").unwrap(); 65 defmt::info!("Source buffers:");
75 tx.blocking_write(b" SRC1: ").unwrap(); 66 defmt::info!(" SRC1: {=[?]}", src1.as_slice());
76 print_buffer(&mut tx, core::ptr::addr_of!(SRC1) as *const u32, 4); 67 defmt::info!(" SRC2: {=[?]}", src2.as_slice());
77 tx.blocking_write(b"\r\n").unwrap(); 68 defmt::info!(" SRC3: {=[?]}", src3.as_slice());
78 tx.blocking_write(b" SRC2: ").unwrap(); 69
79 print_buffer(&mut tx, core::ptr::addr_of!(SRC2) as *const u32, 4); 70 defmt::info!("Destination buffers (before):");
80 tx.blocking_write(b"\r\n").unwrap(); 71 defmt::info!(" DST1: {=[?]}", dst1.as_slice());
81 tx.blocking_write(b" SRC3: ").unwrap(); 72 defmt::info!(" DST2: {=[?]}", dst2.as_slice());
82 print_buffer(&mut tx, core::ptr::addr_of!(SRC3) as *const u32, 4); 73 defmt::info!(" DST3: {=[?]}", dst3.as_slice());
83 tx.blocking_write(b"\r\n\r\n").unwrap();
84
85 tx.blocking_write(b"Destination buffers (before):\r\n").unwrap();
86 tx.blocking_write(b" DST1: ").unwrap();
87 print_buffer(&mut tx, core::ptr::addr_of!(DST1) as *const u32, 4);
88 tx.blocking_write(b"\r\n").unwrap();
89 tx.blocking_write(b" DST2: ").unwrap();
90 print_buffer(&mut tx, core::ptr::addr_of!(DST2) as *const u32, 4);
91 tx.blocking_write(b"\r\n").unwrap();
92 tx.blocking_write(b" DST3: ").unwrap();
93 print_buffer(&mut tx, core::ptr::addr_of!(DST3) as *const u32, 4);
94 tx.blocking_write(b"\r\n\r\n").unwrap();
95 74
96 // Create DMA channel 75 // Create DMA channel
97 let dma_ch0 = DmaChannel::new(p.DMA_CH0); 76 let dma_ch0 = DmaChannel::new(p.DMA_CH0);
98 77
99 tx.blocking_write(b"Building scatter-gather chain with builder API...\r\n") 78 defmt::info!("Building scatter-gather chain with builder API...");
100 .unwrap();
101 79
102 // ========================================================================= 80 // =========================================================================
103 // ScatterGatherBuilder API demonstration 81 // ScatterGatherBuilder API demonstration
@@ -112,27 +90,24 @@ async fn main(_spawner: Spawner) {
112 let mut builder = ScatterGatherBuilder::<u32>::new(); 90 let mut builder = ScatterGatherBuilder::<u32>::new();
113 91
114 // Add three transfer segments - the builder handles TCD linking automatically 92 // Add three transfer segments - the builder handles TCD linking automatically
115 unsafe { 93 builder.add_transfer(src1, dst1);
116 let src1 = &*core::ptr::addr_of!(SRC1); 94 builder.add_transfer(src2, dst2);
117 let dst1 = &mut *core::ptr::addr_of_mut!(DST1); 95 builder.add_transfer(src3, dst3);
118 builder.add_transfer(src1, dst1); 96
119 } 97 defmt::info!("Added 3 transfer segments to chain.");
120 98 defmt::info!("Starting scatter-gather transfer with .await...");
121 unsafe { 99
122 let src2 = &*core::ptr::addr_of!(SRC2); 100 // TODO START
123 let dst2 = &mut *core::ptr::addr_of_mut!(DST2); 101 defmt::info!("Destination buffers (after):");
124 builder.add_transfer(src2, dst2); 102 defmt::info!(" DST1: {=[?]}", dst1.as_slice());
125 } 103 defmt::info!(" DST2: {=[?]}", dst2.as_slice());
126 104 defmt::info!(" DST3: {=[?]}", dst3.as_slice());
127 unsafe { 105 // TODO: If we want to make the `builder.build()` below safe, the above prints SHOULD NOT
128 let src3 = &*core::ptr::addr_of!(SRC3); 106 // compile. We need to make sure that the lifetime of the builder reflects that it is
129 let dst3 = &mut *core::ptr::addr_of_mut!(DST3); 107 // "consuming" the slices until the builder is dropped, since we can access them to print here,
130 builder.add_transfer(src3, dst3); 108 // that means that the borrow checker isn't enforcing that yet.
131 } 109 todo!("ABOVE CODE SHOULDN'T COMPILE");
132 110 // TODO END
133 tx.blocking_write(b"Added 3 transfer segments to chain.\r\n").unwrap();
134 tx.blocking_write(b"Starting scatter-gather transfer with .await...\r\n\r\n")
135 .unwrap();
136 111
137 // Build and execute the scatter-gather chain 112 // Build and execute the scatter-gather chain
138 // The build() method: 113 // The build() method:
@@ -145,60 +120,31 @@ async fn main(_spawner: Spawner) {
145 transfer.blocking_wait(); 120 transfer.blocking_wait();
146 } 121 }
147 122
148 tx.blocking_write(b"Scatter-gather transfer complete!\r\n\r\n").unwrap(); 123 defmt::info!("Scatter-gather transfer complete!");
149 124
150 // Show results 125 // Show results
151 tx.blocking_write(b"Destination buffers (after):\r\n").unwrap(); 126 defmt::info!("Destination buffers (after):");
152 tx.blocking_write(b" DST1: ").unwrap(); 127 defmt::info!(" DST1: {=[?]}", dst1.as_slice());
153 print_buffer(&mut tx, core::ptr::addr_of!(DST1) as *const u32, 4); 128 defmt::info!(" DST2: {=[?]}", dst2.as_slice());
154 tx.blocking_write(b"\r\n").unwrap(); 129 defmt::info!(" DST3: {=[?]}", dst3.as_slice());
155 tx.blocking_write(b" DST2: ").unwrap(); 130
156 print_buffer(&mut tx, core::ptr::addr_of!(DST2) as *const u32, 4); 131 let comps = [
157 tx.blocking_write(b"\r\n").unwrap(); 132 (src1, dst1),
158 tx.blocking_write(b" DST3: ").unwrap(); 133 (src2, dst2),
159 print_buffer(&mut tx, core::ptr::addr_of!(DST3) as *const u32, 4); 134 (src3, dst3),
160 tx.blocking_write(b"\r\n\r\n").unwrap(); 135 ];
161 136
162 // Verify all three segments 137 // Verify all three segments
163 let mut all_ok = true; 138 let mut all_ok = true;
164 unsafe { 139 for (src, dst) in comps {
165 let src1 = core::ptr::addr_of!(SRC1) as *const u32; 140 all_ok &= src == dst;
166 let dst1 = core::ptr::addr_of!(DST1) as *const u32;
167 for i in 0..4 {
168 if *src1.add(i) != *dst1.add(i) {
169 all_ok = false;
170 }
171 }
172
173 let src2 = core::ptr::addr_of!(SRC2) as *const u32;
174 let dst2 = core::ptr::addr_of!(DST2) as *const u32;
175 for i in 0..4 {
176 if *src2.add(i) != *dst2.add(i) {
177 all_ok = false;
178 }
179 }
180
181 let src3 = core::ptr::addr_of!(SRC3) as *const u32;
182 let dst3 = core::ptr::addr_of!(DST3) as *const u32;
183 for i in 0..4 {
184 if *src3.add(i) != *dst3.add(i) {
185 all_ok = false;
186 }
187 }
188 } 141 }
189 142
190 if all_ok { 143 if all_ok {
191 tx.blocking_write(b"PASS: All segments verified!\r\n").unwrap();
192 defmt::info!("PASS: All segments verified!"); 144 defmt::info!("PASS: All segments verified!");
193 } else { 145 } else {
194 tx.blocking_write(b"FAIL: Mismatch detected!\r\n").unwrap();
195 defmt::error!("FAIL: Mismatch detected!"); 146 defmt::error!("FAIL: Mismatch detected!");
196 } 147 }
197 148
198 tx.blocking_write(b"\r\n=== Scatter-Gather Builder example complete ===\r\n") 149 defmt::info!("=== Scatter-Gather Builder example complete ===");
199 .unwrap();
200
201 loop {
202 cortex_m::asm::wfe();
203 }
204} 150}