stm32_rust_template/mcu/stm32f407/
gpio.rs

1// GPIO (General Purpose Input/Output) peripheral definitions
2// Generated from STM32F407 SVD file
3
4use super::{
5    GPIOA_BASEADDR, GPIOB_BASEADDR, GPIOC_BASEADDR, GPIOD_BASEADDR, GPIOE_BASEADDR,
6    PeripheralAccess,
7};
8
9// GPIO Register Block
10#[repr(C)]
11pub struct RegisterBlock {
12    pub moder: u32,   // RW: GPIO port mode register
13    pub otyper: u32,  // RW: GPIO port output type register
14    pub ospeedr: u32, // RW: GPIO port output speed register
15    pub pupdr: u32,   // RW: GPIO port pull-up/pull-down register
16    pub idr: u32,     // RO: GPIO port input data register
17    pub odr: u32,     // RW: GPIO port output data register
18    pub bsrr: u32,    // WO: GPIO port bit set/reset register
19    pub lckr: u32,    // RW: GPIO port configuration lock register
20    pub afrl: u32,    // RW: GPIO alternate function low register
21    pub afrh: u32,    // RW: GPIO alternate function high register
22}
23
24// GPIO peripheral instances
25pub struct GPIOA;
26pub struct GPIOB;
27pub struct GPIOC;
28pub struct GPIOD;
29pub struct GPIOE;
30
31impl PeripheralAccess for GPIOA {
32    const BASE_ADDRESS: u32 = GPIOA_BASEADDR;
33    type RegisterBlock = RegisterBlock;
34}
35
36impl PeripheralAccess for GPIOB {
37    const BASE_ADDRESS: u32 = GPIOB_BASEADDR;
38    type RegisterBlock = RegisterBlock;
39}
40
41impl PeripheralAccess for GPIOC {
42    const BASE_ADDRESS: u32 = GPIOC_BASEADDR;
43    type RegisterBlock = RegisterBlock;
44}
45
46impl PeripheralAccess for GPIOD {
47    const BASE_ADDRESS: u32 = GPIOD_BASEADDR;
48    type RegisterBlock = RegisterBlock;
49}
50
51impl PeripheralAccess for GPIOE {
52    const BASE_ADDRESS: u32 = GPIOE_BASEADDR;
53    type RegisterBlock = RegisterBlock;
54}
55
56// GPIO Register Field Definitions
57
58// MODER register fields
59pub const MODER_MODER15_POS: u32 = 30;
60pub const MODER_MODER15_WIDTH: u32 = 2;
61pub const MODER_MODER15_MASK: u32 = 0x3 << 30;
62
63pub const MODER_MODER14_POS: u32 = 28;
64pub const MODER_MODER14_WIDTH: u32 = 2;
65pub const MODER_MODER14_MASK: u32 = 0x3 << 28;
66
67pub const MODER_MODER13_POS: u32 = 26;
68pub const MODER_MODER13_WIDTH: u32 = 2;
69pub const MODER_MODER13_MASK: u32 = 0x3 << 26;
70
71pub const MODER_MODER12_POS: u32 = 24;
72pub const MODER_MODER12_WIDTH: u32 = 2;
73pub const MODER_MODER12_MASK: u32 = 0x3 << 24;
74
75pub const MODER_MODER11_POS: u32 = 22;
76pub const MODER_MODER11_WIDTH: u32 = 2;
77pub const MODER_MODER11_MASK: u32 = 0x3 << 22;
78
79pub const MODER_MODER10_POS: u32 = 20;
80pub const MODER_MODER10_WIDTH: u32 = 2;
81pub const MODER_MODER10_MASK: u32 = 0x3 << 20;
82
83pub const MODER_MODER9_POS: u32 = 18;
84pub const MODER_MODER9_WIDTH: u32 = 2;
85pub const MODER_MODER9_MASK: u32 = 0x3 << 18;
86
87pub const MODER_MODER8_POS: u32 = 16;
88pub const MODER_MODER8_WIDTH: u32 = 2;
89pub const MODER_MODER8_MASK: u32 = 0x3 << 16;
90
91pub const MODER_MODER7_POS: u32 = 14;
92pub const MODER_MODER7_WIDTH: u32 = 2;
93pub const MODER_MODER7_MASK: u32 = 0x3 << 14;
94
95pub const MODER_MODER6_POS: u32 = 12;
96pub const MODER_MODER6_WIDTH: u32 = 2;
97pub const MODER_MODER6_MASK: u32 = 0x3 << 12;
98
99pub const MODER_MODER5_POS: u32 = 10;
100pub const MODER_MODER5_WIDTH: u32 = 2;
101pub const MODER_MODER5_MASK: u32 = 0x3 << 10;
102
103pub const MODER_MODER4_POS: u32 = 8;
104pub const MODER_MODER4_WIDTH: u32 = 2;
105pub const MODER_MODER4_MASK: u32 = 0x3 << 8;
106
107pub const MODER_MODER3_POS: u32 = 6;
108pub const MODER_MODER3_WIDTH: u32 = 2;
109pub const MODER_MODER3_MASK: u32 = 0x3 << 6;
110
111pub const MODER_MODER2_POS: u32 = 4;
112pub const MODER_MODER2_WIDTH: u32 = 2;
113pub const MODER_MODER2_MASK: u32 = 0x3 << 4;
114
115pub const MODER_MODER1_POS: u32 = 2;
116pub const MODER_MODER1_WIDTH: u32 = 2;
117pub const MODER_MODER1_MASK: u32 = 0x3 << 2;
118
119pub const MODER_MODER0_POS: u32 = 0;
120pub const MODER_MODER0_WIDTH: u32 = 2;
121pub const MODER_MODER0_MASK: u32 = 0x3 << 0;
122// MODER0 enumerated values (same for all pins)
123pub const MODER_INPUT: u32 = 0;
124pub const MODER_OUTPUT: u32 = 1;
125pub const MODER_ALTERNATE: u32 = 2;
126pub const MODER_ANALOG: u32 = 3;
127
128// OTYPER register fields
129pub const OTYPER_OT15_POS: u32 = 15;
130pub const OTYPER_OT15_WIDTH: u32 = 1;
131pub const OTYPER_OT15_MASK: u32 = 0x1 << 15;
132
133pub const OTYPER_OT14_POS: u32 = 14;
134pub const OTYPER_OT14_WIDTH: u32 = 1;
135pub const OTYPER_OT14_MASK: u32 = 0x1 << 14;
136
137pub const OTYPER_OT13_POS: u32 = 13;
138pub const OTYPER_OT13_WIDTH: u32 = 1;
139pub const OTYPER_OT13_MASK: u32 = 0x1 << 13;
140
141pub const OTYPER_OT12_POS: u32 = 12;
142pub const OTYPER_OT12_WIDTH: u32 = 1;
143pub const OTYPER_OT12_MASK: u32 = 0x1 << 12;
144
145pub const OTYPER_OT11_POS: u32 = 11;
146pub const OTYPER_OT11_WIDTH: u32 = 1;
147pub const OTYPER_OT11_MASK: u32 = 0x1 << 11;
148
149pub const OTYPER_OT10_POS: u32 = 10;
150pub const OTYPER_OT10_WIDTH: u32 = 1;
151pub const OTYPER_OT10_MASK: u32 = 0x1 << 10;
152
153pub const OTYPER_OT9_POS: u32 = 9;
154pub const OTYPER_OT9_WIDTH: u32 = 1;
155pub const OTYPER_OT9_MASK: u32 = 0x1 << 9;
156
157pub const OTYPER_OT8_POS: u32 = 8;
158pub const OTYPER_OT8_WIDTH: u32 = 1;
159pub const OTYPER_OT8_MASK: u32 = 0x1 << 8;
160
161pub const OTYPER_OT7_POS: u32 = 7;
162pub const OTYPER_OT7_WIDTH: u32 = 1;
163pub const OTYPER_OT7_MASK: u32 = 0x1 << 7;
164
165pub const OTYPER_OT6_POS: u32 = 6;
166pub const OTYPER_OT6_WIDTH: u32 = 1;
167pub const OTYPER_OT6_MASK: u32 = 0x1 << 6;
168
169pub const OTYPER_OT5_POS: u32 = 5;
170pub const OTYPER_OT5_WIDTH: u32 = 1;
171pub const OTYPER_OT5_MASK: u32 = 0x1 << 5;
172
173pub const OTYPER_OT4_POS: u32 = 4;
174pub const OTYPER_OT4_WIDTH: u32 = 1;
175pub const OTYPER_OT4_MASK: u32 = 0x1 << 4;
176
177pub const OTYPER_OT3_POS: u32 = 3;
178pub const OTYPER_OT3_WIDTH: u32 = 1;
179pub const OTYPER_OT3_MASK: u32 = 0x1 << 3;
180
181pub const OTYPER_OT2_POS: u32 = 2;
182pub const OTYPER_OT2_WIDTH: u32 = 1;
183pub const OTYPER_OT2_MASK: u32 = 0x1 << 2;
184
185pub const OTYPER_OT1_POS: u32 = 1;
186pub const OTYPER_OT1_WIDTH: u32 = 1;
187pub const OTYPER_OT1_MASK: u32 = 0x1 << 1;
188
189pub const OTYPER_OT0_POS: u32 = 0;
190pub const OTYPER_OT0_WIDTH: u32 = 1;
191pub const OTYPER_OT0_MASK: u32 = 0x1 << 0;
192// OTYPER enumerated values (same for all pins)
193pub const OTYPER_PUSHPULL: u32 = 0;
194pub const OTYPER_OPENDRAIN: u32 = 1;
195
196// OSPEEDR register fields
197pub const OSPEEDR_OSPEEDR15_POS: u32 = 30;
198pub const OSPEEDR_OSPEEDR15_WIDTH: u32 = 2;
199pub const OSPEEDR_OSPEEDR15_MASK: u32 = 0x3 << 30;
200
201pub const OSPEEDR_OSPEEDR14_POS: u32 = 28;
202pub const OSPEEDR_OSPEEDR14_WIDTH: u32 = 2;
203pub const OSPEEDR_OSPEEDR14_MASK: u32 = 0x3 << 28;
204
205pub const OSPEEDR_OSPEEDR13_POS: u32 = 26;
206pub const OSPEEDR_OSPEEDR13_WIDTH: u32 = 2;
207pub const OSPEEDR_OSPEEDR13_MASK: u32 = 0x3 << 26;
208
209pub const OSPEEDR_OSPEEDR12_POS: u32 = 24;
210pub const OSPEEDR_OSPEEDR12_WIDTH: u32 = 2;
211pub const OSPEEDR_OSPEEDR12_MASK: u32 = 0x3 << 24;
212
213pub const OSPEEDR_OSPEEDR11_POS: u32 = 22;
214pub const OSPEEDR_OSPEEDR11_WIDTH: u32 = 2;
215pub const OSPEEDR_OSPEEDR11_MASK: u32 = 0x3 << 22;
216
217pub const OSPEEDR_OSPEEDR10_POS: u32 = 20;
218pub const OSPEEDR_OSPEEDR10_WIDTH: u32 = 2;
219pub const OSPEEDR_OSPEEDR10_MASK: u32 = 0x3 << 20;
220
221pub const OSPEEDR_OSPEEDR9_POS: u32 = 18;
222pub const OSPEEDR_OSPEEDR9_WIDTH: u32 = 2;
223pub const OSPEEDR_OSPEEDR9_MASK: u32 = 0x3 << 18;
224
225pub const OSPEEDR_OSPEEDR8_POS: u32 = 16;
226pub const OSPEEDR_OSPEEDR8_WIDTH: u32 = 2;
227pub const OSPEEDR_OSPEEDR8_MASK: u32 = 0x3 << 16;
228
229pub const OSPEEDR_OSPEEDR7_POS: u32 = 14;
230pub const OSPEEDR_OSPEEDR7_WIDTH: u32 = 2;
231pub const OSPEEDR_OSPEEDR7_MASK: u32 = 0x3 << 14;
232
233pub const OSPEEDR_OSPEEDR6_POS: u32 = 12;
234pub const OSPEEDR_OSPEEDR6_WIDTH: u32 = 2;
235pub const OSPEEDR_OSPEEDR6_MASK: u32 = 0x3 << 12;
236
237pub const OSPEEDR_OSPEEDR5_POS: u32 = 10;
238pub const OSPEEDR_OSPEEDR5_WIDTH: u32 = 2;
239pub const OSPEEDR_OSPEEDR5_MASK: u32 = 0x3 << 10;
240
241pub const OSPEEDR_OSPEEDR4_POS: u32 = 8;
242pub const OSPEEDR_OSPEEDR4_WIDTH: u32 = 2;
243pub const OSPEEDR_OSPEEDR4_MASK: u32 = 0x3 << 8;
244
245pub const OSPEEDR_OSPEEDR3_POS: u32 = 6;
246pub const OSPEEDR_OSPEEDR3_WIDTH: u32 = 2;
247pub const OSPEEDR_OSPEEDR3_MASK: u32 = 0x3 << 6;
248
249pub const OSPEEDR_OSPEEDR2_POS: u32 = 4;
250pub const OSPEEDR_OSPEEDR2_WIDTH: u32 = 2;
251pub const OSPEEDR_OSPEEDR2_MASK: u32 = 0x3 << 4;
252
253pub const OSPEEDR_OSPEEDR1_POS: u32 = 2;
254pub const OSPEEDR_OSPEEDR1_WIDTH: u32 = 2;
255pub const OSPEEDR_OSPEEDR1_MASK: u32 = 0x3 << 2;
256
257pub const OSPEEDR_OSPEEDR0_POS: u32 = 0;
258pub const OSPEEDR_OSPEEDR0_WIDTH: u32 = 2;
259pub const OSPEEDR_OSPEEDR0_MASK: u32 = 0x3 << 0;
260// OSPEEDR enumerated values (same for all pins)
261pub const OSPEEDR_LOWSPEED: u32 = 0;
262pub const OSPEEDR_MEDIUMSPEED: u32 = 1;
263pub const OSPEEDR_HIGHSPEED: u32 = 2;
264pub const OSPEEDR_VERYHIGHSPEED: u32 = 3;
265
266// PUPDR register fields
267pub const PUPDR_PUPDR15_POS: u32 = 30;
268pub const PUPDR_PUPDR15_WIDTH: u32 = 2;
269pub const PUPDR_PUPDR15_MASK: u32 = 0x3 << 30;
270
271pub const PUPDR_PUPDR14_POS: u32 = 28;
272pub const PUPDR_PUPDR14_WIDTH: u32 = 2;
273pub const PUPDR_PUPDR14_MASK: u32 = 0x3 << 28;
274
275pub const PUPDR_PUPDR13_POS: u32 = 26;
276pub const PUPDR_PUPDR13_WIDTH: u32 = 2;
277pub const PUPDR_PUPDR13_MASK: u32 = 0x3 << 26;
278
279pub const PUPDR_PUPDR12_POS: u32 = 24;
280pub const PUPDR_PUPDR12_WIDTH: u32 = 2;
281pub const PUPDR_PUPDR12_MASK: u32 = 0x3 << 24;
282
283pub const PUPDR_PUPDR11_POS: u32 = 22;
284pub const PUPDR_PUPDR11_WIDTH: u32 = 2;
285pub const PUPDR_PUPDR11_MASK: u32 = 0x3 << 22;
286
287pub const PUPDR_PUPDR10_POS: u32 = 20;
288pub const PUPDR_PUPDR10_WIDTH: u32 = 2;
289pub const PUPDR_PUPDR10_MASK: u32 = 0x3 << 20;
290
291pub const PUPDR_PUPDR9_POS: u32 = 18;
292pub const PUPDR_PUPDR9_WIDTH: u32 = 2;
293pub const PUPDR_PUPDR9_MASK: u32 = 0x3 << 18;
294
295pub const PUPDR_PUPDR8_POS: u32 = 16;
296pub const PUPDR_PUPDR8_WIDTH: u32 = 2;
297pub const PUPDR_PUPDR8_MASK: u32 = 0x3 << 16;
298
299pub const PUPDR_PUPDR7_POS: u32 = 14;
300pub const PUPDR_PUPDR7_WIDTH: u32 = 2;
301pub const PUPDR_PUPDR7_MASK: u32 = 0x3 << 14;
302
303pub const PUPDR_PUPDR6_POS: u32 = 12;
304pub const PUPDR_PUPDR6_WIDTH: u32 = 2;
305pub const PUPDR_PUPDR6_MASK: u32 = 0x3 << 12;
306
307pub const PUPDR_PUPDR5_POS: u32 = 10;
308pub const PUPDR_PUPDR5_WIDTH: u32 = 2;
309pub const PUPDR_PUPDR5_MASK: u32 = 0x3 << 10;
310
311pub const PUPDR_PUPDR4_POS: u32 = 8;
312pub const PUPDR_PUPDR4_WIDTH: u32 = 2;
313pub const PUPDR_PUPDR4_MASK: u32 = 0x3 << 8;
314
315pub const PUPDR_PUPDR3_POS: u32 = 6;
316pub const PUPDR_PUPDR3_WIDTH: u32 = 2;
317pub const PUPDR_PUPDR3_MASK: u32 = 0x3 << 6;
318
319pub const PUPDR_PUPDR2_POS: u32 = 4;
320pub const PUPDR_PUPDR2_WIDTH: u32 = 2;
321pub const PUPDR_PUPDR2_MASK: u32 = 0x3 << 4;
322
323pub const PUPDR_PUPDR1_POS: u32 = 2;
324pub const PUPDR_PUPDR1_WIDTH: u32 = 2;
325pub const PUPDR_PUPDR1_MASK: u32 = 0x3 << 2;
326
327pub const PUPDR_PUPDR0_POS: u32 = 0;
328pub const PUPDR_PUPDR0_WIDTH: u32 = 2;
329pub const PUPDR_PUPDR0_MASK: u32 = 0x3 << 0;
330// PUPDR enumerated values (same for all pins)
331pub const PUPDR_FLOATING: u32 = 0;
332pub const PUPDR_PULLUP: u32 = 1;
333pub const PUPDR_PULLDOWN: u32 = 2;
334
335// IDR register fields (individual pins for input data)
336pub const IDR_IDR15_POS: u32 = 15;
337pub const IDR_IDR15_WIDTH: u32 = 1;
338pub const IDR_IDR15_MASK: u32 = 0x1 << 15;
339
340pub const IDR_IDR14_POS: u32 = 14;
341pub const IDR_IDR14_WIDTH: u32 = 1;
342pub const IDR_IDR14_MASK: u32 = 0x1 << 14;
343
344pub const IDR_IDR13_POS: u32 = 13;
345pub const IDR_IDR13_WIDTH: u32 = 1;
346pub const IDR_IDR13_MASK: u32 = 0x1 << 13;
347
348pub const IDR_IDR12_POS: u32 = 12;
349pub const IDR_IDR12_WIDTH: u32 = 1;
350pub const IDR_IDR12_MASK: u32 = 0x1 << 12;
351
352pub const IDR_IDR11_POS: u32 = 11;
353pub const IDR_IDR11_WIDTH: u32 = 1;
354pub const IDR_IDR11_MASK: u32 = 0x1 << 11;
355
356pub const IDR_IDR10_POS: u32 = 10;
357pub const IDR_IDR10_WIDTH: u32 = 1;
358pub const IDR_IDR10_MASK: u32 = 0x1 << 10;
359
360pub const IDR_IDR9_POS: u32 = 9;
361pub const IDR_IDR9_WIDTH: u32 = 1;
362pub const IDR_IDR9_MASK: u32 = 0x1 << 9;
363
364pub const IDR_IDR8_POS: u32 = 8;
365pub const IDR_IDR8_WIDTH: u32 = 1;
366pub const IDR_IDR8_MASK: u32 = 0x1 << 8;
367
368pub const IDR_IDR7_POS: u32 = 7;
369pub const IDR_IDR7_WIDTH: u32 = 1;
370pub const IDR_IDR7_MASK: u32 = 0x1 << 7;
371
372pub const IDR_IDR6_POS: u32 = 6;
373pub const IDR_IDR6_WIDTH: u32 = 1;
374pub const IDR_IDR6_MASK: u32 = 0x1 << 6;
375
376pub const IDR_IDR5_POS: u32 = 5;
377pub const IDR_IDR5_WIDTH: u32 = 1;
378pub const IDR_IDR5_MASK: u32 = 0x1 << 5;
379
380pub const IDR_IDR4_POS: u32 = 4;
381pub const IDR_IDR4_WIDTH: u32 = 1;
382pub const IDR_IDR4_MASK: u32 = 0x1 << 4;
383
384pub const IDR_IDR3_POS: u32 = 3;
385pub const IDR_IDR3_WIDTH: u32 = 1;
386pub const IDR_IDR3_MASK: u32 = 0x1 << 3;
387
388pub const IDR_IDR2_POS: u32 = 2;
389pub const IDR_IDR2_WIDTH: u32 = 1;
390pub const IDR_IDR2_MASK: u32 = 0x1 << 2;
391
392pub const IDR_IDR1_POS: u32 = 1;
393pub const IDR_IDR1_WIDTH: u32 = 1;
394pub const IDR_IDR1_MASK: u32 = 0x1 << 1;
395
396pub const IDR_IDR0_POS: u32 = 0;
397pub const IDR_IDR0_WIDTH: u32 = 1;
398pub const IDR_IDR0_MASK: u32 = 0x1 << 0;
399
400// ODR register fields (individual pins for output data)
401pub const ODR_ODR15_POS: u32 = 15;
402pub const ODR_ODR15_WIDTH: u32 = 1;
403pub const ODR_ODR15_MASK: u32 = 0x1 << 15;
404
405pub const ODR_ODR14_POS: u32 = 14;
406pub const ODR_ODR14_WIDTH: u32 = 1;
407pub const ODR_ODR14_MASK: u32 = 0x1 << 14;
408
409pub const ODR_ODR13_POS: u32 = 13;
410pub const ODR_ODR13_WIDTH: u32 = 1;
411pub const ODR_ODR13_MASK: u32 = 0x1 << 13;
412
413pub const ODR_ODR12_POS: u32 = 12;
414pub const ODR_ODR12_WIDTH: u32 = 1;
415pub const ODR_ODR12_MASK: u32 = 0x1 << 12;
416
417pub const ODR_ODR11_POS: u32 = 11;
418pub const ODR_ODR11_WIDTH: u32 = 1;
419pub const ODR_ODR11_MASK: u32 = 0x1 << 11;
420
421pub const ODR_ODR10_POS: u32 = 10;
422pub const ODR_ODR10_WIDTH: u32 = 1;
423pub const ODR_ODR10_MASK: u32 = 0x1 << 10;
424
425pub const ODR_ODR9_POS: u32 = 9;
426pub const ODR_ODR9_WIDTH: u32 = 1;
427pub const ODR_ODR9_MASK: u32 = 0x1 << 9;
428
429pub const ODR_ODR8_POS: u32 = 8;
430pub const ODR_ODR8_WIDTH: u32 = 1;
431pub const ODR_ODR8_MASK: u32 = 0x1 << 8;
432
433pub const ODR_ODR7_POS: u32 = 7;
434pub const ODR_ODR7_WIDTH: u32 = 1;
435pub const ODR_ODR7_MASK: u32 = 0x1 << 7;
436
437pub const ODR_ODR6_POS: u32 = 6;
438pub const ODR_ODR6_WIDTH: u32 = 1;
439pub const ODR_ODR6_MASK: u32 = 0x1 << 6;
440
441pub const ODR_ODR5_POS: u32 = 5;
442pub const ODR_ODR5_WIDTH: u32 = 1;
443pub const ODR_ODR5_MASK: u32 = 0x1 << 5;
444
445pub const ODR_ODR4_POS: u32 = 4;
446pub const ODR_ODR4_WIDTH: u32 = 1;
447pub const ODR_ODR4_MASK: u32 = 0x1 << 4;
448
449pub const ODR_ODR3_POS: u32 = 3;
450pub const ODR_ODR3_WIDTH: u32 = 1;
451pub const ODR_ODR3_MASK: u32 = 0x1 << 3;
452
453pub const ODR_ODR2_POS: u32 = 2;
454pub const ODR_ODR2_WIDTH: u32 = 1;
455pub const ODR_ODR2_MASK: u32 = 0x1 << 2;
456
457pub const ODR_ODR1_POS: u32 = 1;
458pub const ODR_ODR1_WIDTH: u32 = 1;
459pub const ODR_ODR1_MASK: u32 = 0x1 << 1;
460
461pub const ODR_ODR0_POS: u32 = 0;
462pub const ODR_ODR0_WIDTH: u32 = 1;
463pub const ODR_ODR0_MASK: u32 = 0x1 << 0;
464
465// GPIO Mode enumeration
466#[derive(Copy, Clone, Debug, PartialEq)]
467pub enum GpioMode {
468    Input = 0,
469    Output = 1,
470    Alternate = 2,
471    Analog = 3,
472}
473
474// GPIO Output Type enumeration
475#[derive(Copy, Clone, Debug, PartialEq)]
476pub enum GpioOutputType {
477    PushPull = 0,
478    OpenDrain = 1,
479}
480
481// GPIO Speed enumeration
482#[derive(Copy, Clone, Debug, PartialEq)]
483pub enum GpioSpeed {
484    Low = 0,
485    Medium = 1,
486    High = 2,
487    VeryHigh = 3,
488}
489
490// GPIO Pull-up/Pull-down enumeration
491#[derive(Copy, Clone, Debug, PartialEq)]
492pub enum GpioPull {
493    None = 0,
494    PullUp = 1,
495    PullDown = 2,
496}
497
498// Helper functions for GPIO configuration
499impl RegisterBlock {
500    /// Configure a pin mode
501    pub fn set_pin_mode(&mut self, pin: u8, mode: GpioMode) {
502        if pin < 16 {
503            let shift = pin * 2;
504            let mask = 0x3 << shift;
505            self.moder = (self.moder & !mask) | ((mode as u32) << shift);
506        }
507    }
508
509    /// Set pin output type
510    pub fn set_pin_output_type(&mut self, pin: u8, output_type: GpioOutputType) {
511        if pin < 16 {
512            if output_type == GpioOutputType::OpenDrain {
513                self.otyper |= 1 << pin;
514            } else {
515                self.otyper &= !(1 << pin);
516            }
517        }
518    }
519
520    /// Set pin speed
521    pub fn set_pin_speed(&mut self, pin: u8, speed: GpioSpeed) {
522        if pin < 16 {
523            let shift = pin * 2;
524            let mask = 0x3 << shift;
525            self.ospeedr = (self.ospeedr & !mask) | ((speed as u32) << shift);
526        }
527    }
528
529    /// Set pin pull-up/pull-down
530    pub fn set_pin_pull(&mut self, pin: u8, pull: GpioPull) {
531        if pin < 16 {
532            let shift = pin * 2;
533            let mask = 0x3 << shift;
534            self.pupdr = (self.pupdr & !mask) | ((pull as u32) << shift);
535        }
536    }
537
538    /// Set pin output value
539    pub fn set_pin(&mut self, pin: u8, value: bool) {
540        if pin < 16 {
541            if value {
542                self.bsrr = 1 << pin; // Set bit
543            } else {
544                self.bsrr = 1 << (pin + 16); // Reset bit
545            }
546        }
547    }
548
549    /// Get pin input value
550    pub fn get_pin(&self, pin: u8) -> bool {
551        if pin < 16 {
552            (self.idr & (1 << pin)) != 0
553        } else {
554            false
555        }
556    }
557
558    /// Toggle pin output value
559    pub fn toggle_pin(&mut self, pin: u8) {
560        if pin < 16 {
561            let current_value = (self.odr & (1 << pin)) != 0;
562            self.set_pin(pin, !current_value);
563        }
564    }
565}