Skip to content

Commit 92df79b

Browse files
committed
dma: added register_bitflields and usart base address
1 parent 1c82204 commit 92df79b

1 file changed

Lines changed: 144 additions & 29 deletions

File tree

chips/stm32u5xx/src/dma.rs

Lines changed: 144 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,117 @@
44

55
use core::cell::Cell;
66
use kernel::utilities::cells::OptionalCell;
7-
use kernel::utilities::registers::interfaces::{Readable, Writeable};
8-
use kernel::utilities::registers::{register_structs, ReadOnly, ReadWrite};
7+
use kernel::utilities::registers::interfaces::{ReadWriteable, Writeable};
8+
use kernel::utilities::registers::{
9+
register_bitfields, register_structs, Field, ReadOnly, ReadWrite,
10+
};
911
use kernel::utilities::StaticRef;
1012

13+
/// Base address for USART1 in Secure Alias mode.
14+
const USART1_BASE_ADDR: u32 = 0x50013800;
15+
/// USART1 Receive Data Register (RDR) address.
16+
const USART1_RDR: u32 = USART1_BASE_ADDR + 0x24;
17+
/// USART1 Transmit Data Register (TDR) address.
18+
const USART1_TDR: u32 = USART1_BASE_ADDR + 0x28;
19+
20+
register_bitfields! [
21+
u32,
22+
pub DmaChannelTR1 [
23+
/// Destination security
24+
DSEC OFFSET(31) NUMBITS(1) [],
25+
/// Destination allocated port
26+
DAP OFFSET(30) NUMBITS(1) [],
27+
/// Destination increment
28+
DINC OFFSET(19) NUMBITS(1) [],
29+
/// Source security
30+
SSEC OFFSET(15) NUMBITS(1) [],
31+
/// Source allocated port
32+
SAP OFFSET(14) NUMBITS(1) [],
33+
/// Source increment
34+
SINC OFFSET(3) NUMBITS(1) [],
35+
],
36+
pub DmaChannelTR2 [
37+
/// Destination request
38+
DREQ OFFSET(10) NUMBITS(1) [],
39+
/// Request selection
40+
REQSEL OFFSET(0) NUMBITS(7) [],
41+
],
42+
43+
pub DmaChannelCR [
44+
/// Transfer complete interrupt enable
45+
TCIE OFFSET(8) NUMBITS(1) [],
46+
/// Enable
47+
EN OFFSET(0) NUMBITS(1) [],
48+
],
49+
pub DmaChannelFCR [
50+
/// Completed suspension flag clear
51+
SUSPF OFFSET(13) NUMBITS(1) [],
52+
/// User setting error flag clear
53+
USEF OFFSET(12) NUMBITS(1) [],
54+
/// Update link error flag clear
55+
ULEF OFFSET(11) NUMBITS(1) [],
56+
/// Data transfer error flag clear
57+
DTEF OFFSET(10) NUMBITS(1) [],
58+
/// Half transfer flag clear
59+
HTF OFFSET(9) NUMBITS(1) [],
60+
/// Transfer complete flag clear
61+
TCF OFFSET(8) NUMBITS(1) [],
62+
],
63+
pub DmaChannelEnable [
64+
CH0 OFFSET(0) NUMBITS(1) [],
65+
CH1 OFFSET(1) NUMBITS(1) [],
66+
CH2 OFFSET(2) NUMBITS(1) [],
67+
CH3 OFFSET(3) NUMBITS(1) [],
68+
CH4 OFFSET(4) NUMBITS(1) [],
69+
CH5 OFFSET(5) NUMBITS(1) [],
70+
CH6 OFFSET(6) NUMBITS(1) [],
71+
CH7 OFFSET(7) NUMBITS(1) [],
72+
CH8 OFFSET(8) NUMBITS(1) [],
73+
CH9 OFFSET(9) NUMBITS(1) [],
74+
CH10 OFFSET(10) NUMBITS(1) [],
75+
CH11 OFFSET(11) NUMBITS(1) [],
76+
CH12 OFFSET(12) NUMBITS(1) [],
77+
CH13 OFFSET(13) NUMBITS(1) [],
78+
CH14 OFFSET(14) NUMBITS(1) [],
79+
CH15 OFFSET(15) NUMBITS(1) [],
80+
]
81+
];
82+
83+
const CH_FIELDS: [Field<u32, DmaChannelEnable::Register>; 16] = [
84+
DmaChannelEnable::CH0,
85+
DmaChannelEnable::CH1,
86+
DmaChannelEnable::CH2,
87+
DmaChannelEnable::CH3,
88+
DmaChannelEnable::CH4,
89+
DmaChannelEnable::CH5,
90+
DmaChannelEnable::CH6,
91+
DmaChannelEnable::CH7,
92+
DmaChannelEnable::CH8,
93+
DmaChannelEnable::CH9,
94+
DmaChannelEnable::CH10,
95+
DmaChannelEnable::CH11,
96+
DmaChannelEnable::CH12,
97+
DmaChannelEnable::CH13,
98+
DmaChannelEnable::CH14,
99+
DmaChannelEnable::CH15,
100+
];
101+
11102
register_structs! {
12103
pub DmaChannelRegisters {
13104
/// Channel x linked-list base address register (Relative 0x00)
14105
(0x000 => pub l_bar: ReadWrite<u32>),
15106
/// Channel x flag clear register (Relative 0x04)
16107
(0x004 => _reserved0: [u32; 2]),
17-
(0x00C => pub f_cr: ReadWrite<u32>),
108+
(0x00C => pub f_cr: ReadWrite<u32, DmaChannelFCR::Register>),
18109
/// Channel x status register (Relative 0x08)
19110
(0x010 => pub s_r: ReadOnly<u32>),
20111
/// Channel x control register (Relative 0x0C)
21-
(0x014 => pub c_r: ReadWrite<u32>),
112+
(0x014 => pub c_r: ReadWrite<u32, DmaChannelCR::Register>),
22113
(0x018 => _reserved1: [u32; 10]),
23114
/// Channel x transfer register 1 (Relative 0x40)
24-
(0x040 => pub t_r1: ReadWrite<u32>),
115+
(0x040 => pub t_r1: ReadWrite<u32, DmaChannelTR1::Register>),
25116
/// Channel x transfer register 2 (Relative 0x44)
26-
(0x044 => pub t_r2: ReadWrite<u32>),
117+
(0x044 => pub t_r2: ReadWrite<u32, DmaChannelTR2::Register>),
27118
/// Channel x block register 1 (Relative 0x48)
28119
(0x048 => pub b_r1: ReadWrite<u32>),
29120
/// Channel x source address register (Relative 0x4C)
@@ -40,9 +131,9 @@ register_structs! {
40131
register_structs! {
41132
pub DmaRegisters {
42133
/// GPDMA secure configuration register (0x00)
43-
(0x000 => pub seccfgr: ReadWrite<u32>),
134+
(0x000 => pub seccfgr: ReadWrite<u32, DmaChannelEnable::Register>),
44135
/// GPDMA privileged configuration register (0x04)
45-
(0x004 => pub privcfgr: ReadWrite<u32>),
136+
(0x004 => pub privcfgr: ReadWrite<u32, DmaChannelEnable::Register>),
46137
(0x008 => _reserved0: [u32; 1]),
47138
/// Masked interrupt status register (0x0C)
48139
(0x00C => pub misr: ReadOnly<u32>),
@@ -153,77 +244,101 @@ impl Dma {
153244
pub fn setup_usart1_tx(&self, channel: ChannelId, buffer_addr: u32, length: u32) {
154245
if let Some(channel_id) = self.match_channel(channel) {
155246
// 1. Mark channel as Secure AND Privileged
156-
let sec = self.registers.seccfgr.get();
157-
self.registers.seccfgr.set(sec | (1 << channel_id));
158-
let priv_reg = self.registers.privcfgr.get();
159-
self.registers.privcfgr.set(priv_reg | (1 << channel_id));
247+
self.registers.seccfgr.modify(CH_FIELDS[channel_id].val(1));
248+
self.registers.privcfgr.modify(CH_FIELDS[channel_id].val(1));
160249

161250
let ch = &self.registers.channels[channel_id];
162251

163252
// 2. Ensure channel is disabled
164-
ch.c_r.set(0);
253+
ch.c_r.write(DmaChannelCR::EN::CLEAR);
165254

166255
// 3. Clear all flags
167-
ch.f_cr.set(0x0000FFFF);
256+
ch.f_cr.write(
257+
DmaChannelFCR::SUSPF::SET
258+
+ DmaChannelFCR::USEF::SET
259+
+ DmaChannelFCR::ULEF::SET
260+
+ DmaChannelFCR::DTEF::SET
261+
+ DmaChannelFCR::HTF::SET
262+
+ DmaChannelFCR::TCF::SET,
263+
);
168264

169265
// 4. Configure Transfer Register 1 (TR1)
170266
// SINC (bit 3) = 1
171267
// SAP (bit 14) = 0 (Port 0)
172268
// DAP (bit 30) = 0 (Port 0 - Safer for U545)
173-
ch.t_r1.set(1 << 3);
269+
ch.t_r1.write(
270+
DmaChannelTR1::SINC::SET + DmaChannelTR1::SAP::CLEAR + DmaChannelTR1::DAP::CLEAR,
271+
);
174272

175273
// 5. Configure Transfer Register 2 (TR2)
176274
// REQSEL = 25 (USART1_TX on U545), DREQ = 1 (Destination request)
177-
ch.t_r2.set(25 | (1 << 10));
275+
ch.t_r2
276+
.write(DmaChannelTR2::REQSEL.val(25) + DmaChannelTR2::DREQ::SET);
178277

179278
// 6. Set Addresses
180279
ch.s_ar.set(buffer_addr);
181-
ch.d_ar.set(0x50013828); // USART1_TDR Secure Address
280+
ch.d_ar.set(USART1_TDR);
182281

183282
// 7. Set Block Register 1 (BR1)
184283
ch.b_r1.set(length & 0xFFFF);
185284

186285
// 8. Enable Transfer Complete Interrupt (bit 8) and Start (bit 0)
187-
ch.c_r.set((1 << 8) | 1);
286+
ch.c_r
287+
.write(DmaChannelCR::TCIE::SET + DmaChannelCR::EN::SET);
188288
}
189289
}
190290

191291
pub fn setup_usart1_rx(&self, channel: ChannelId, buffer_addr: u32, length: u32) {
192292
if let Some(channel_id) = self.match_channel(channel) {
193293
// Mark channel as Secure AND Privileged
194-
let sec = self.registers.seccfgr.get();
195-
self.registers.seccfgr.set(sec | (1 << channel_id));
196-
let priv_reg = self.registers.privcfgr.get();
197-
self.registers.privcfgr.set(priv_reg | (1 << channel_id));
294+
self.registers.seccfgr.modify(CH_FIELDS[channel_id].val(1));
295+
self.registers.privcfgr.modify(CH_FIELDS[channel_id].val(1));
198296

199297
let ch = &self.registers.channels[channel_id];
200298

201-
ch.c_r.set(0);
202-
ch.f_cr.set(0x0000FFFF);
299+
ch.c_r.write(DmaChannelCR::EN::CLEAR);
300+
ch.f_cr.write(
301+
DmaChannelFCR::SUSPF::SET
302+
+ DmaChannelFCR::USEF::SET
303+
+ DmaChannelFCR::ULEF::SET
304+
+ DmaChannelFCR::DTEF::SET
305+
+ DmaChannelFCR::HTF::SET
306+
+ DmaChannelFCR::TCF::SET,
307+
);
203308

204309
// Configure TR1 (Security + Direction)
205310
// DINC (19), SSEC (15), DSEC (31)
206-
ch.t_r1.set((1 << 19) | (1 << 15) | (1 << 31));
311+
ch.t_r1.write(
312+
DmaChannelTR1::DINC::SET + DmaChannelTR1::SSEC::SET + DmaChannelTR1::DSEC::SET,
313+
);
207314

208315
// Configure TR2 (Trigger Source) - REQSEL = 24
209-
ch.t_r2.set(24);
316+
ch.t_r2.write(DmaChannelTR2::REQSEL.val(24));
210317

211318
// 6. Set Addresses
212-
ch.s_ar.set(0x50013824);
319+
ch.s_ar.set(USART1_RDR);
213320
ch.d_ar.set(buffer_addr);
214321

215322
// 7. Set Block Register 1 (BR1)
216323
ch.b_r1.set(length & 0xFFFF);
217324

218325
// 8. Enable
219-
ch.c_r.set((1 << 8) | 1);
326+
ch.c_r
327+
.write(DmaChannelCR::TCIE::SET + DmaChannelCR::EN::SET);
220328
}
221329
}
222330

223331
pub fn clear_interrupt(&self, channel: ChannelId) {
224332
if let Some(channel_id) = self.match_channel(channel) {
225333
let ch = &self.registers.channels[channel_id];
226-
ch.f_cr.set(0x0000FFFF);
334+
ch.f_cr.write(
335+
DmaChannelFCR::SUSPF::SET
336+
+ DmaChannelFCR::USEF::SET
337+
+ DmaChannelFCR::ULEF::SET
338+
+ DmaChannelFCR::DTEF::SET
339+
+ DmaChannelFCR::HTF::SET
340+
+ DmaChannelFCR::TCF::SET,
341+
);
227342
}
228343
}
229344

0 commit comments

Comments
 (0)