blob: 7b3c06ffa2a92187cd3ccfed97ced5164a8ca00e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
//! DMA memset example for MCXA276.
//!
//! NOTE: this is a "raw dma" example! It exists as a proof of concept, as we don't have
//! a high-level and safe API for. It should not be taken as typical, recommended, or
//! stable usage!
//!
//! This example demonstrates using DMA to fill a buffer with a repeated pattern.
//! The source address stays fixed while the destination increments.
//!
//! # Embassy-style features demonstrated:
//! - `DmaChannel::is_done()` and `clear_done()` helper methods
//! - No need to pass register block around
#![no_std]
#![no_main]
use embassy_executor::Spawner;
use embassy_mcxa::clocks::config::Div8;
use embassy_mcxa::dma::DmaChannel;
use static_cell::ConstStaticCell;
use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
const BUFFER_LENGTH: usize = 4;
// Buffers in RAM
static PATTERN: u32 = 0xDEADBEEF;
static DEST_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]);
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
// Small delay to allow probe-rs to attach after reset
for _ in 0..100_000 {
cortex_m::asm::nop();
}
let mut cfg = hal::config::Config::default();
cfg.clock_cfg.sirc.fro_12m_enabled = true;
cfg.clock_cfg.sirc.fro_lf_div = Some(Div8::no_div());
let p = hal::init(cfg);
defmt::info!("DMA memset example starting...");
defmt::info!("EDMA memset example begin.");
// Initialize buffers
let pat = &PATTERN;
let dst = DEST_BUFFER.take();
defmt::info!("Pattern Value: {=u32}", pat);
defmt::info!("Destination Buffer (before): {=[?]}", dst.as_slice());
defmt::info!("Configuring DMA with Embassy-style API...");
// Create DMA channel using Embassy-style API
let dma_ch0 = DmaChannel::new(p.DMA_CH0);
// Configure memset transfer using direct TCD access:
// Source stays fixed (soff = 0, reads same pattern repeatedly)
// Destination increments (doff = 4)
unsafe {
let t = dma_ch0.tcd();
// Reset channel state
t.ch_csr().write(|w| {
w.erq()
.disable()
.earq()
.disable()
.eei()
.no_error()
.ebw()
.disable()
.done()
.clear_bit_by_one()
});
t.ch_es().write(|w| w.bits(0));
t.ch_int().write(|w| w.int().clear_bit_by_one());
// Source address (pattern) - fixed
t.tcd_saddr().write(|w| w.saddr().bits(pat as *const _ as u32));
// Destination address - increments
t.tcd_daddr().write(|w| w.daddr().bits(dst.as_mut_ptr() as u32));
// Source offset = 0 (stays fixed), Dest offset = 4 (increments)
t.tcd_soff().write(|w| w.soff().bits(0));
t.tcd_doff().write(|w| w.doff().bits(4));
// Attributes: 32-bit transfers (size = 2)
t.tcd_attr().write(|w| w.ssize().bits(2).dsize().bits(2));
// Transfer entire buffer in one minor loop
let nbytes = (BUFFER_LENGTH * 4) as u32;
t.tcd_nbytes_mloffno().write(|w| w.nbytes().bits(nbytes));
// Source doesn't need adjustment (stays fixed)
t.tcd_slast_sda().write(|w| w.slast_sda().bits(0));
// Reset dest address after major loop
t.tcd_dlast_sga().write(|w| w.dlast_sga().bits(-(nbytes as i32) as u32));
// Major loop count = 1
t.tcd_biter_elinkno().write(|w| w.biter().bits(1));
t.tcd_citer_elinkno().write(|w| w.citer().bits(1));
// Enable interrupt on major loop completion
t.tcd_csr().write(|w| w.intmajor().set_bit());
cortex_m::asm::dsb();
defmt::info!("Triggering transfer...");
dma_ch0.trigger_start();
}
// Wait for completion using channel helper method
while !dma_ch0.is_done() {
cortex_m::asm::nop();
}
unsafe {
dma_ch0.clear_done();
}
defmt::info!("EDMA memset example finish.");
defmt::info!("Destination Buffer (after): {=[?]}", dst.as_slice());
// Verify: All elements should equal PATTERN
let mismatch = dst.iter().any(|i| *i != *pat);
if mismatch {
defmt::error!("FAIL: Mismatch detected!");
} else {
defmt::info!("PASS: Data verified.");
}
}
|