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
130
#![cfg(feature = "semver-exempt")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum AltMode {
Gpio,
Alt1,
Alt2,
Alt3,
Alt4,
Alt5,
Alt6,
Alt7,
Alt8,
}
pub type Pin = (u8, u8);
pub trait GpioExt {
fn set_alt_mode(&self, pin: Pin, mode: AltMode) -> &Self;
fn set_output(&self, pin: Pin) -> &Self;
fn set_input(&self, pin: Pin) -> &Self;
}
unsafe fn set_bit16(reg: *mut u16, bit: u8) {
unsafe { reg.write_volatile(reg.read_volatile() | (1u16 << bit)) };
}
unsafe fn clear_bit16(reg: *mut u16, bit: u8) {
unsafe { reg.write_volatile(reg.read_volatile() & !(1u16 << bit)) };
}
#[inline]
fn panic_if_pin_is_invalid((n, m): Pin) {
assert!((1..12).contains(&n), "1 <= {n} < 12");
assert!(m < 16, "0 <= {m} < 16");
}
impl GpioExt for rza1::gpio::RegisterBlock {
#[inline]
fn set_alt_mode(&self, (n, m): Pin, mode: AltMode) -> &Self {
panic_if_pin_is_invalid((n, m));
let pmc = (&self.pmc1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
let pfcae = (&self.pfcae1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
let pfce = (&self.pfce1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
let pfc = (&self.pfc1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
unsafe {
match mode {
AltMode::Gpio => {
clear_bit16(pmc, m);
}
AltMode::Alt1 => {
set_bit16(pmc, m);
clear_bit16(pfcae, m);
clear_bit16(pfce, m);
clear_bit16(pfc, m);
}
AltMode::Alt2 => {
set_bit16(pmc, m);
clear_bit16(pfcae, m);
clear_bit16(pfce, m);
set_bit16(pfc, m);
}
AltMode::Alt3 => {
set_bit16(pmc, m);
clear_bit16(pfcae, m);
set_bit16(pfce, m);
clear_bit16(pfc, m);
}
AltMode::Alt4 => {
set_bit16(pmc, m);
clear_bit16(pfcae, m);
set_bit16(pfce, m);
set_bit16(pfc, m);
}
AltMode::Alt5 => {
set_bit16(pmc, m);
set_bit16(pfcae, m);
clear_bit16(pfce, m);
clear_bit16(pfc, m);
}
AltMode::Alt6 => {
set_bit16(pmc, m);
set_bit16(pfcae, m);
clear_bit16(pfce, m);
set_bit16(pfc, m);
}
AltMode::Alt7 => {
set_bit16(pmc, m);
set_bit16(pfcae, m);
set_bit16(pfce, m);
clear_bit16(pfc, m);
}
AltMode::Alt8 => {
set_bit16(pmc, m);
set_bit16(pfcae, m);
set_bit16(pfce, m);
set_bit16(pfc, m);
}
}
}
self
}
#[inline]
fn set_output(&self, (n, m): Pin) -> &Self {
panic_if_pin_is_invalid((n, m));
let pm = (&self.pm1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
unsafe { clear_bit16(pm, m) };
self
}
#[inline]
fn set_input(&self, (n, m): Pin) -> &Self {
panic_if_pin_is_invalid((n, m));
let pm = (&self.pm1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
unsafe { set_bit16(pm, m) };
self
}
}