@@ -5,6 +5,7 @@ use core::marker::PhantomData;
5
5
use volatile_register:: RW ;
6
6
7
7
/// The `PINMUX` pad multiplexer peripheral.
8
+ #[ repr( C ) ]
8
9
pub struct PinMux {
9
10
/// Pad function multiplexer registers for all the pads.
10
11
pub fmux : FMux ,
@@ -21,32 +22,74 @@ impl AsRef<FMux> for PinMux {
21
22
}
22
23
23
24
/// Pad function multiplexer registers for all the pads.
25
+ #[ repr( C ) ]
24
26
pub struct FMux {
25
- _reserved0 : [ u8 ; 0xAC ] ,
27
+ _reserved0 : [ u8 ; 0x40 ] ,
28
+ /// UART-0 TX pad function.
29
+ pub uart0_tx : RW < u32 > ,
30
+ /// UART-0 RX pad function.
31
+ pub uart0_rx : RW < u32 > ,
32
+ _reserved1 : [ u8 ; 0x28 ] ,
33
+ /// I2C-0 Serial Clock (SCL) pad function.
34
+ pub i2c0_scl : RW < u32 > ,
35
+ /// I2C-0 Serial Data (SDA) pad function.
36
+ pub i2c0_sda : RW < u32 > ,
37
+ _reserved2 : [ u8 ; 0x34 ] ,
26
38
/// Power (RTC) domain GPIO-2 pad function.
27
39
pub pwr_gpio2 : RW < u32 > ,
28
40
// TODO other fields and padding
41
+ _reserved3 : [ u8 ; 0x1750 ] ,
29
42
}
30
43
31
44
impl FMux {
32
45
/// Gets the pad function multiplexer register for the given pad number `N`.
33
46
#[ inline]
34
47
pub fn fmux < const N : usize > ( & self ) -> & RW < u32 > {
35
48
match N {
49
+ 18 => & self . uart0_tx ,
50
+ 19 => & self . uart0_rx ,
51
+ 28 => & self . i2c0_scl ,
52
+ 29 => & self . i2c0_sda ,
36
53
49 => & self . pwr_gpio2 ,
37
54
_ => todo ! ( ) ,
38
55
}
39
56
}
40
57
}
41
58
42
59
/// Non-RTC domain pad configurations.
60
+ #[ repr( C ) ]
43
61
pub struct PadConfigs {
44
- // TODO
62
+ _reserved0 : [ u8 ; 0x10C ] ,
63
+ /// Non-RTC domain UART-0 TX pad configurations.
64
+ pub uart0_tx : RW < PadConfig > ,
65
+ /// Non-RTC domain UART-0 RX pad configurations.
66
+ pub uart0_rx : RW < PadConfig > ,
67
+ _reserved1 : [ u8 ; 0x28 ] ,
68
+ /// Non-RTC domain i2c-0 SCL pad configurations.
69
+ pub i2c0_scl : RW < PadConfig > ,
70
+ /// Non-RTC domain i2c-0 SDA pad configurations.
71
+ pub i2c0_sda : RW < PadConfig > ,
45
72
}
46
73
47
- // TODO fn pad_config in impl PadConfigs
74
+ impl PadConfigs {
75
+ /// Gets the pad configuration register for the given pad number `N`.
76
+ ///
77
+ /// `N` must be number of a pad in the non-RTC domain.
78
+ #[ inline]
79
+ const fn pad_config < const N : usize > ( & self ) -> & RW < PadConfig > {
80
+ match N {
81
+ 18 => & self . uart0_tx ,
82
+ 19 => & self . uart0_rx ,
83
+ 28 => & self . i2c0_scl ,
84
+ 29 => & self . i2c0_sda ,
85
+ // if not a non-RTC pad, return unimplemented!()
86
+ _ => todo ! ( ) ,
87
+ }
88
+ }
89
+ }
48
90
49
91
/// Power (RTC) domain pad configurations.
92
+ #[ repr( C ) ]
50
93
pub struct PwrPadConfigs {
51
94
_reserved0 : [ u8 ; 0x34 ] ,
52
95
/// Power (RTC) domain GPIO-2 pad configuration.
@@ -138,11 +181,14 @@ impl<A: BaseAddress, const N: usize, F> Pad<A, N, F> {
138
181
}
139
182
}
140
183
#[ inline]
141
- fn pad_config ( & self ) -> & RW < PadConfig > {
184
+ pub fn pad_config ( & self ) -> & RW < PadConfig > {
142
185
match N {
143
186
// TODO in range of power pads ...
144
187
49 => unsafe { & * ( self . base . ptr ( ) as * const PwrPadConfigs ) } . pad_config :: < N > ( ) ,
145
188
// TODO in range of conventional pads ...
189
+ 18 ..=19 | 28 ..=29 => {
190
+ unsafe { & * ( self . base . ptr ( ) as * const PadConfigs ) } . pad_config :: < N > ( )
191
+ }
146
192
// .. => { ... }
147
193
_ => todo ! ( ) ,
148
194
}
@@ -174,6 +220,9 @@ pub struct PullUp;
174
220
/// Floating as pull mode (type state).
175
221
pub struct Floating ;
176
222
223
+ /// UART function (type state).
224
+ pub struct UartFunc < const I : usize > ;
225
+
177
226
/// Trait for all valid pad functions.
178
227
pub trait Function {
179
228
/// Pull direction associated with this pad function.
@@ -214,6 +263,32 @@ const fn gpio_fmux<const N: usize>() -> u32 {
214
263
}
215
264
}
216
265
266
+ impl < const I : usize > Function for UartFunc < I > {
267
+ const PULL : Pull = Pull :: Up ;
268
+ #[ inline]
269
+ fn fmux < const N : usize > ( ) -> u32 {
270
+ uart_fmux :: < N , I > ( )
271
+ }
272
+ }
273
+
274
+ const fn uart_fmux < const N : usize , const I : usize > ( ) -> u32 {
275
+ match I {
276
+ 0 => match N {
277
+ 18 ..=19 => 0 ,
278
+ _ => unimplemented ! ( ) ,
279
+ } ,
280
+ 1 => match N {
281
+ 28 ..=29 => 1 ,
282
+ _ => unimplemented ! ( ) ,
283
+ } ,
284
+ 2 => match N {
285
+ 28 ..=29 => 2 ,
286
+ _ => unimplemented ! ( ) ,
287
+ } ,
288
+ _ => unimplemented ! ( ) ,
289
+ }
290
+ }
291
+
217
292
/// Pad internal pull direction values.
218
293
#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
219
294
#[ repr( u8 ) ]
@@ -225,3 +300,32 @@ pub enum Pull {
225
300
/// Internally pulled down.
226
301
Down = 2 ,
227
302
}
303
+
304
+ #[ cfg( test) ]
305
+ mod tests {
306
+ use super :: { FMux , PadConfigs , PinMux } ;
307
+ use memoffset:: offset_of;
308
+
309
+ #[ test]
310
+ fn struct_pinmux_offset ( ) {
311
+ assert_eq ! ( offset_of!( PinMux , fmux) , 0x00 ) ;
312
+ assert_eq ! ( offset_of!( PinMux , config) , 0x1800 ) ;
313
+ }
314
+
315
+ #[ test]
316
+ fn struct_fmux_offset ( ) {
317
+ assert_eq ! ( offset_of!( FMux , uart0_tx) , 0x40 ) ;
318
+ assert_eq ! ( offset_of!( FMux , uart0_rx) , 0x44 ) ;
319
+ assert_eq ! ( offset_of!( FMux , i2c0_scl) , 0x70 ) ;
320
+ assert_eq ! ( offset_of!( FMux , i2c0_sda) , 0x74 ) ;
321
+ assert_eq ! ( offset_of!( FMux , pwr_gpio2) , 0xAC ) ;
322
+ }
323
+
324
+ #[ test]
325
+ fn struct_pad_configs_offset ( ) {
326
+ assert_eq ! ( offset_of!( PadConfigs , uart0_tx) , 0x190C - 0x1800 ) ;
327
+ assert_eq ! ( offset_of!( PadConfigs , uart0_rx) , 0x1910 - 0x1800 ) ;
328
+ assert_eq ! ( offset_of!( PadConfigs , i2c0_scl) , 0x193C - 0x1800 ) ;
329
+ assert_eq ! ( offset_of!( PadConfigs , i2c0_sda) , 0x1940 - 0x1800 ) ;
330
+ }
331
+ }
0 commit comments