stm32f303xc/
syscfg.rs
1use enum_primitive::cast::FromPrimitive;
6use enum_primitive::enum_from_primitive;
7use kernel::platform::chip::ClockInterface;
8use kernel::utilities::registers::interfaces::ReadWriteable;
9use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite};
10use kernel::utilities::StaticRef;
11
12use crate::gpio;
13use crate::rcc;
14
15#[repr(C)]
17struct SyscfgRegisters {
18 memrm: ReadWrite<u32, MEMRM::Register>,
20 pmc: ReadWrite<u32, PMC::Register>,
22 exticr1: ReadWrite<u32, EXTICR1::Register>,
24 exticr2: ReadWrite<u32, EXTICR2::Register>,
26 exticr3: ReadWrite<u32, EXTICR3::Register>,
28 exticr4: ReadWrite<u32, EXTICR4::Register>,
30 _reserved0: [u8; 8],
31 cmpcr: ReadOnly<u32, CMPCR::Register>,
33}
34
35register_bitfields![u32,
36 MEMRM [
37 MEM_MODE OFFSET(0) NUMBITS(3) [],
39 FB_MODE OFFSET(8) NUMBITS(1) [],
41 SWP_FMC OFFSET(10) NUMBITS(2) []
43 ],
44 PMC [
45 MII_RMII_SEL OFFSET(23) NUMBITS(1) [],
47 ADC1DC2 OFFSET(16) NUMBITS(1) [],
49 ADC2DC2 OFFSET(17) NUMBITS(1) [],
51 ADC3DC2 OFFSET(18) NUMBITS(1) []
53 ],
54 EXTICR1 [
55 EXTI3 OFFSET(12) NUMBITS(4) [],
57 EXTI2 OFFSET(8) NUMBITS(4) [],
59 EXTI1 OFFSET(4) NUMBITS(4) [],
61 EXTI0 OFFSET(0) NUMBITS(4) []
63 ],
64 EXTICR2 [
65 EXTI7 OFFSET(12) NUMBITS(4) [],
67 EXTI6 OFFSET(8) NUMBITS(4) [],
69 EXTI5 OFFSET(4) NUMBITS(4) [],
71 EXTI4 OFFSET(0) NUMBITS(4) []
73 ],
74 EXTICR3 [
75 EXTI11 OFFSET(12) NUMBITS(4) [],
77 EXTI10 OFFSET(8) NUMBITS(4) [],
79 EXTI9 OFFSET(4) NUMBITS(4) [],
81 EXTI8 OFFSET(0) NUMBITS(4) []
83 ],
84 EXTICR4 [
85 EXTI15 OFFSET(12) NUMBITS(4) [],
87 EXTI14 OFFSET(8) NUMBITS(4) [],
89 EXTI13 OFFSET(4) NUMBITS(4) [],
91 EXTI12 OFFSET(0) NUMBITS(4) []
93 ],
94 CMPCR [
95 READY OFFSET(8) NUMBITS(1) [],
97 CMP_PD OFFSET(0) NUMBITS(1) []
99 ]
100];
101
102const SYSCFG_BASE: StaticRef<SyscfgRegisters> =
103 unsafe { StaticRef::new(0x40010000 as *const SyscfgRegisters) };
104
105enum_from_primitive! {
106 #[repr(u32)]
107 enum ExtiCrId {
111 PA = 0b0000,
112 PB = 0b0001,
113 PC = 0b0010,
114 PD = 0b0011,
115 PE = 0b0100,
116 PF = 0b0101,
117 PG = 0b0110,
118 PH = 0b0111,
119 }
120}
121
122pub struct Syscfg<'a> {
123 registers: StaticRef<SyscfgRegisters>,
124 clock: SyscfgClock<'a>,
125}
126
127impl<'a> Syscfg<'a> {
128 pub const fn new(rcc: &'a rcc::Rcc) -> Self {
129 Self {
130 registers: SYSCFG_BASE,
131 clock: SyscfgClock(rcc::PeripheralClock::new(
132 rcc::PeripheralClockType::APB2(rcc::PCLK2::SYSCFG),
133 rcc,
134 )),
135 }
136 }
137
138 pub fn is_enabled_clock(&self) -> bool {
139 self.clock.is_enabled()
140 }
141
142 pub fn enable_clock(&self) {
143 self.clock.enable();
144 }
145
146 pub fn disable_clock(&self) {
147 self.clock.disable();
148 }
149
150 pub fn configure_interrupt(&self, pinid: gpio::PinId) {
152 let exticrid = self.get_exticrid_from_port_num(pinid.get_port_number());
153
154 let pin_num = pinid.get_pin_number();
155 match pin_num {
156 0b0000 => self
158 .registers
159 .exticr1
160 .modify(EXTICR1::EXTI0.val(exticrid as u32)),
161 0b0001 => self
162 .registers
163 .exticr1
164 .modify(EXTICR1::EXTI1.val(exticrid as u32)),
165 0b0010 => self
166 .registers
167 .exticr1
168 .modify(EXTICR1::EXTI2.val(exticrid as u32)),
169 0b0011 => self
170 .registers
171 .exticr1
172 .modify(EXTICR1::EXTI3.val(exticrid as u32)),
173 0b0100 => self
175 .registers
176 .exticr2
177 .modify(EXTICR2::EXTI4.val(exticrid as u32)),
178 0b0101 => self
179 .registers
180 .exticr2
181 .modify(EXTICR2::EXTI5.val(exticrid as u32)),
182 0b0110 => self
183 .registers
184 .exticr2
185 .modify(EXTICR2::EXTI6.val(exticrid as u32)),
186 0b0111 => self
187 .registers
188 .exticr2
189 .modify(EXTICR2::EXTI7.val(exticrid as u32)),
190 0b1000 => self
192 .registers
193 .exticr3
194 .modify(EXTICR3::EXTI8.val(exticrid as u32)),
195 0b1001 => self
196 .registers
197 .exticr3
198 .modify(EXTICR3::EXTI9.val(exticrid as u32)),
199 0b1010 => self
200 .registers
201 .exticr3
202 .modify(EXTICR3::EXTI10.val(exticrid as u32)),
203 0b1011 => self
204 .registers
205 .exticr3
206 .modify(EXTICR3::EXTI11.val(exticrid as u32)),
207 0b1100 => self
209 .registers
210 .exticr4
211 .modify(EXTICR4::EXTI12.val(exticrid as u32)),
212 0b1101 => self
213 .registers
214 .exticr4
215 .modify(EXTICR4::EXTI13.val(exticrid as u32)),
216 0b1110 => self
217 .registers
218 .exticr4
219 .modify(EXTICR4::EXTI14.val(exticrid as u32)),
220 0b1111 => self
221 .registers
222 .exticr4
223 .modify(EXTICR4::EXTI15.val(exticrid as u32)),
224 _ => {}
225 }
226 }
227
228 fn get_exticrid_from_port_num(&self, port_num: u8) -> ExtiCrId {
229 ExtiCrId::from_u32(u32::from(port_num)).unwrap()
230 }
231}
232
233struct SyscfgClock<'a>(rcc::PeripheralClock<'a>);
234
235impl ClockInterface for SyscfgClock<'_> {
236 fn is_enabled(&self) -> bool {
237 self.0.is_enabled()
238 }
239
240 fn enable(&self) {
241 self.0.enable();
242 }
243
244 fn disable(&self) {
245 self.0.disable();
246 }
247}