44
55use core:: cell:: Cell ;
66use 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+ } ;
911use 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+
11102register_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! {
40131register_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