1use core::cell::Cell;
8use core::marker::PhantomData;
9use kernel::hil::gpio;
10use kernel::utilities::cells::OptionalCell;
11use kernel::utilities::registers::interfaces::{Readable, Writeable};
12use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
13use kernel::utilities::StaticRef;
14
15const GPIO_BASES: [StaticRef<GpioRegisters>; 6] = [
16 unsafe { StaticRef::new(0x4000_4C00u32 as *const GpioRegisters) }, unsafe { StaticRef::new(0x4000_4C20u32 as *const GpioRegisters) }, unsafe { StaticRef::new(0x4000_4C40u32 as *const GpioRegisters) }, unsafe { StaticRef::new(0x4000_4C60u32 as *const GpioRegisters) }, unsafe { StaticRef::new(0x4000_4C80u32 as *const GpioRegisters) }, unsafe { StaticRef::new(0x4000_4D20u32 as *const GpioRegisters) }, ];
23
24const PINS_PER_PORT: u8 = 8;
25
26register_structs! {
27 GpioRegisters {
28 (0x00 => input: [ReadOnly<u8, PxIN::Register>; 2]),
29 (0x02 => out: [ReadWrite<u8, PxOUT::Register>; 2]),
30 (0x04 => dir: [ReadWrite<u8, PxDIR::Register>; 2]),
31 (0x06 => ren: [ReadWrite<u8, PxREN::Register>; 2]),
32 (0x08 => ds: [ReadWrite<u8, PxDS::Register>; 2]),
33 (0x0A => sel0: [ReadWrite<u8, PxSEL0::Register>; 2]),
34 (0x0C => sel1: [ReadWrite<u8, PxSEL1::Register>; 2]),
35 (0x0E => iv1: ReadWrite<u16, PxIV::Register>),
36 (0x10 => _reserved),
37 (0x16 => selc: [ReadWrite<u8, PxSELC::Register>; 2]),
38 (0x18 => ies: [ReadWrite<u8, PxIES::Register>; 2]),
39 (0x1A => ie: [ReadWrite<u8, PxIE::Register>; 2]),
40 (0x1C => ifg: [ReadWrite<u8, PxIFG::Register>; 2]),
41 (0x1E => iv2: ReadWrite<u16, PxIV::Register>),
42 (0x20 => @END),
43 }
44}
45
46register_bitfields! [u8,
47 PxIN [
49 PIN0 OFFSET(0) NUMBITS(1),
50 PIN1 OFFSET(1) NUMBITS(1),
51 PIN2 OFFSET(2) NUMBITS(1),
52 PIN3 OFFSET(3) NUMBITS(1),
53 PIN4 OFFSET(4) NUMBITS(1),
54 PIN5 OFFSET(5) NUMBITS(1),
55 PIN6 OFFSET(6) NUMBITS(1),
56 PIN7 OFFSET(7) NUMBITS(1)
57 ],
58 PxOUT [
60 PIN0 OFFSET(0) NUMBITS(1),
61 PIN1 OFFSET(1) NUMBITS(1),
62 PIN2 OFFSET(2) NUMBITS(1),
63 PIN3 OFFSET(3) NUMBITS(1),
64 PIN4 OFFSET(4) NUMBITS(1),
65 PIN5 OFFSET(5) NUMBITS(1),
66 PIN6 OFFSET(6) NUMBITS(1),
67 PIN7 OFFSET(7) NUMBITS(1)
68 ],
69 PxDIR [
71 PIN0 OFFSET(0) NUMBITS(1),
72 PIN1 OFFSET(1) NUMBITS(1),
73 PIN2 OFFSET(2) NUMBITS(1),
74 PIN3 OFFSET(3) NUMBITS(1),
75 PIN4 OFFSET(4) NUMBITS(1),
76 PIN5 OFFSET(5) NUMBITS(1),
77 PIN6 OFFSET(6) NUMBITS(1),
78 PIN7 OFFSET(7) NUMBITS(1)
79 ],
80 PxREN [
82 PIN0 OFFSET(0) NUMBITS(1),
83 PIN1 OFFSET(1) NUMBITS(1),
84 PIN2 OFFSET(2) NUMBITS(1),
85 PIN3 OFFSET(3) NUMBITS(1),
86 PIN4 OFFSET(4) NUMBITS(1),
87 PIN5 OFFSET(5) NUMBITS(1),
88 PIN6 OFFSET(6) NUMBITS(1),
89 PIN7 OFFSET(7) NUMBITS(1)
90 ],
91 PxDS [
93 PIN0 OFFSET(0) NUMBITS(1),
94 PIN1 OFFSET(1) NUMBITS(1),
95 PIN2 OFFSET(2) NUMBITS(1),
96 PIN3 OFFSET(3) NUMBITS(1),
97 PIN4 OFFSET(4) NUMBITS(1),
98 PIN5 OFFSET(5) NUMBITS(1),
99 PIN6 OFFSET(6) NUMBITS(1),
100 PIN7 OFFSET(7) NUMBITS(1)
101 ],
102 PxSEL0 [
105 PIN0 OFFSET(0) NUMBITS(1),
106 PIN1 OFFSET(1) NUMBITS(1),
107 PIN2 OFFSET(2) NUMBITS(1),
108 PIN3 OFFSET(3) NUMBITS(1),
109 PIN4 OFFSET(4) NUMBITS(1),
110 PIN5 OFFSET(5) NUMBITS(1),
111 PIN6 OFFSET(6) NUMBITS(1),
112 PIN7 OFFSET(7) NUMBITS(1)
113 ],
114 PxSEL1 [
117 PIN0 OFFSET(0) NUMBITS(1),
118 PIN1 OFFSET(1) NUMBITS(1),
119 PIN2 OFFSET(2) NUMBITS(1),
120 PIN3 OFFSET(3) NUMBITS(1),
121 PIN4 OFFSET(4) NUMBITS(1),
122 PIN5 OFFSET(5) NUMBITS(1),
123 PIN6 OFFSET(6) NUMBITS(1),
124 PIN7 OFFSET(7) NUMBITS(1)
125 ],
126 PxSELC [
128 PIN0 OFFSET(0) NUMBITS(1),
129 PIN1 OFFSET(1) NUMBITS(1),
130 PIN2 OFFSET(2) NUMBITS(1),
131 PIN3 OFFSET(3) NUMBITS(1),
132 PIN4 OFFSET(4) NUMBITS(1),
133 PIN5 OFFSET(5) NUMBITS(1),
134 PIN6 OFFSET(6) NUMBITS(1),
135 PIN7 OFFSET(7) NUMBITS(1)
136 ],
137 PxIES [
139 PIN0 OFFSET(0) NUMBITS(1),
140 PIN1 OFFSET(1) NUMBITS(1),
141 PIN2 OFFSET(2) NUMBITS(1),
142 PIN3 OFFSET(3) NUMBITS(1),
143 PIN4 OFFSET(4) NUMBITS(1),
144 PIN5 OFFSET(5) NUMBITS(1),
145 PIN6 OFFSET(6) NUMBITS(1),
146 PIN7 OFFSET(7) NUMBITS(1)
147 ],
148 PxIE [
150 PIN0 OFFSET(0) NUMBITS(1),
151 PIN1 OFFSET(1) NUMBITS(1),
152 PIN2 OFFSET(2) NUMBITS(1),
153 PIN3 OFFSET(3) NUMBITS(1),
154 PIN4 OFFSET(4) NUMBITS(1),
155 PIN5 OFFSET(5) NUMBITS(1),
156 PIN6 OFFSET(6) NUMBITS(1),
157 PIN7 OFFSET(7) NUMBITS(1)
158 ],
159 PxIFG [
161 PIN0 OFFSET(0) NUMBITS(1),
162 PIN1 OFFSET(1) NUMBITS(1),
163 PIN2 OFFSET(2) NUMBITS(1),
164 PIN3 OFFSET(3) NUMBITS(1),
165 PIN4 OFFSET(4) NUMBITS(1),
166 PIN5 OFFSET(5) NUMBITS(1),
167 PIN6 OFFSET(6) NUMBITS(1),
168 PIN7 OFFSET(7) NUMBITS(1)
169 ]
170];
171
172register_bitfields! [u16,
173 PxIV [
175 IV OFFSET(0) NUMBITS(16)
176 ]
177];
178
179#[rustfmt::skip]
180#[repr(u8)]
181#[derive(Copy, Clone)]
182pub enum IntPinNr {
183 P01_0, P01_1, P01_2, P01_3, P01_4, P01_5, P01_6, P01_7,
184 P02_0, P02_1, P02_2, P02_3, P02_4, P02_5, P02_6, P02_7,
185 P03_0, P03_1, P03_2, P03_3, P03_4, P03_5, P03_6, P03_7,
186 P04_0, P04_1, P04_2, P04_3, P04_4, P04_5, P04_6, P04_7,
187 P05_0, P05_1, P05_2, P05_3, P05_4, P05_5, P05_6, P05_7,
188 P06_0, P06_1, P06_2, P06_3, P06_4, P06_5, P06_6, P06_7,
189}
190
191#[rustfmt::skip]
192#[allow(non_camel_case_types)]
193#[repr(u8)]
194#[derive(Copy, Clone)]
195pub enum PinNr {
196 P07_0, P07_1, P07_2, P07_3, P07_4, P07_5, P07_6, P07_7,
197 P08_0, P08_1, P08_2, P08_3, P08_4, P08_5, P08_6, P08_7,
198 P09_0, P09_1, P09_2, P09_3, P09_4, P09_5, P09_6, P09_7,
199 P10_0, P10_1, P10_2, P10_3, P10_4, P10_5, P10_6, P10_7,
200 PJ_0, PJ_1, PJ_2, PJ_3, PJ_4, PJ_5, PJ_6, PJ_7,
201}
202
203#[derive(Clone, Copy, Debug, PartialEq)]
204enum ModuleFunction {
205 Gpio,
206 Primary,
207 Secondary,
208 Tertiary,
209}
210
211pub struct GpioManager<'a> {
212 pub int_pins: [IntPin<'a>; 48],
213 pub pins: [Pin<'a>; 40],
214}
215
216impl GpioManager<'_> {
217 pub fn new() -> Self {
218 Self {
219 int_pins: [
220 IntPin::new(IntPinNr::P01_0),
221 IntPin::new(IntPinNr::P01_1),
222 IntPin::new(IntPinNr::P01_2),
223 IntPin::new(IntPinNr::P01_3),
224 IntPin::new(IntPinNr::P01_4),
225 IntPin::new(IntPinNr::P01_5),
226 IntPin::new(IntPinNr::P01_6),
227 IntPin::new(IntPinNr::P01_7),
228 IntPin::new(IntPinNr::P02_0),
229 IntPin::new(IntPinNr::P02_1),
230 IntPin::new(IntPinNr::P02_2),
231 IntPin::new(IntPinNr::P02_3),
232 IntPin::new(IntPinNr::P02_4),
233 IntPin::new(IntPinNr::P02_5),
234 IntPin::new(IntPinNr::P02_6),
235 IntPin::new(IntPinNr::P02_7),
236 IntPin::new(IntPinNr::P03_0),
237 IntPin::new(IntPinNr::P03_1),
238 IntPin::new(IntPinNr::P03_2),
239 IntPin::new(IntPinNr::P03_3),
240 IntPin::new(IntPinNr::P03_4),
241 IntPin::new(IntPinNr::P03_5),
242 IntPin::new(IntPinNr::P03_6),
243 IntPin::new(IntPinNr::P03_7),
244 IntPin::new(IntPinNr::P04_0),
245 IntPin::new(IntPinNr::P04_1),
246 IntPin::new(IntPinNr::P04_2),
247 IntPin::new(IntPinNr::P04_3),
248 IntPin::new(IntPinNr::P04_4),
249 IntPin::new(IntPinNr::P04_5),
250 IntPin::new(IntPinNr::P04_6),
251 IntPin::new(IntPinNr::P04_7),
252 IntPin::new(IntPinNr::P05_0),
253 IntPin::new(IntPinNr::P05_1),
254 IntPin::new(IntPinNr::P05_2),
255 IntPin::new(IntPinNr::P05_3),
256 IntPin::new(IntPinNr::P05_4),
257 IntPin::new(IntPinNr::P05_5),
258 IntPin::new(IntPinNr::P05_6),
259 IntPin::new(IntPinNr::P05_7),
260 IntPin::new(IntPinNr::P06_0),
261 IntPin::new(IntPinNr::P06_1),
262 IntPin::new(IntPinNr::P06_2),
263 IntPin::new(IntPinNr::P06_3),
264 IntPin::new(IntPinNr::P06_4),
265 IntPin::new(IntPinNr::P06_5),
266 IntPin::new(IntPinNr::P06_6),
267 IntPin::new(IntPinNr::P06_7),
268 ],
269 pins: [
270 Pin::new(PinNr::P07_0),
271 Pin::new(PinNr::P07_1),
272 Pin::new(PinNr::P07_2),
273 Pin::new(PinNr::P07_3),
274 Pin::new(PinNr::P07_4),
275 Pin::new(PinNr::P07_5),
276 Pin::new(PinNr::P07_6),
277 Pin::new(PinNr::P07_7),
278 Pin::new(PinNr::P08_0),
279 Pin::new(PinNr::P08_1),
280 Pin::new(PinNr::P08_2),
281 Pin::new(PinNr::P08_3),
282 Pin::new(PinNr::P08_4),
283 Pin::new(PinNr::P08_5),
284 Pin::new(PinNr::P08_6),
285 Pin::new(PinNr::P08_7),
286 Pin::new(PinNr::P09_0),
287 Pin::new(PinNr::P09_1),
288 Pin::new(PinNr::P09_2),
289 Pin::new(PinNr::P09_3),
290 Pin::new(PinNr::P09_4),
291 Pin::new(PinNr::P09_5),
292 Pin::new(PinNr::P09_6),
293 Pin::new(PinNr::P09_7),
294 Pin::new(PinNr::P10_0),
295 Pin::new(PinNr::P10_1),
296 Pin::new(PinNr::P10_2),
297 Pin::new(PinNr::P10_3),
298 Pin::new(PinNr::P10_4),
299 Pin::new(PinNr::P10_5),
300 Pin::new(PinNr::P10_6),
301 Pin::new(PinNr::P10_7),
302 Pin::new(PinNr::PJ_0),
303 Pin::new(PinNr::PJ_1),
304 Pin::new(PinNr::PJ_2),
305 Pin::new(PinNr::PJ_3),
306 Pin::new(PinNr::PJ_4),
307 Pin::new(PinNr::PJ_5),
308 Pin::new(PinNr::PJ_6),
309 Pin::new(PinNr::PJ_7),
310 ],
311 }
312 }
313}
314
315pub struct IntPin<'a> {
317 pin: u8,
318 registers: StaticRef<GpioRegisters>,
319 reg_idx: usize,
320 detect_both_edges: Cell<bool>,
321 client: OptionalCell<&'a dyn gpio::Client>,
322}
323
324pub struct Pin<'a> {
326 pin: u8,
327 registers: StaticRef<GpioRegisters>,
328 reg_idx: usize,
329 phantom: PhantomData<&'a ()>,
332}
333
334impl<'a> Pin<'a> {
335 const fn new(pin: PinNr) -> Pin<'a> {
336 let pin_nr = (pin as u8) % PINS_PER_PORT;
337 let p = (pin as u8) / PINS_PER_PORT;
338 Pin {
339 pin: pin_nr,
340 registers: GPIO_BASES[3 + ((p / 2) as usize)],
341 reg_idx: (p % 2) as usize,
342 phantom: PhantomData,
343 }
344 }
345}
346
347impl<'a> IntPin<'a> {
348 pub const fn new(pin: IntPinNr) -> IntPin<'a> {
349 let pin_nr = (pin as u8) % PINS_PER_PORT;
350 let p = (pin as u8) / PINS_PER_PORT;
351 IntPin {
352 pin: pin_nr,
353 registers: GPIO_BASES[(p / 2) as usize],
354 reg_idx: (p % 2) as usize,
355 detect_both_edges: Cell::new(false),
356 client: OptionalCell::empty(),
357 }
358 }
359
360 fn switch_detecting_edge(&self) {
361 let mut edge = self.registers.ies[self.reg_idx].get();
366 if self.read_level() {
367 edge |= 1 << self.pin;
369 } else {
370 edge &= !(1 << self.pin);
372 }
373 self.registers.ies[self.reg_idx].set(edge);
374 }
375
376 fn handle_interrupt(&self) {
377 self.client.map(|client| client.fired());
378
379 if self.detect_both_edges.get() {
380 self.switch_detecting_edge();
381 }
382 }
383}
384
385macro_rules! pin_implementation {
386 ($pin_type:ident) => {
387 impl<'a> $pin_type<'a> {
388 fn read_level(&self) -> bool {
389 (self.registers.input[self.reg_idx].get() & (1 << self.pin)) > 0
390 }
391
392 fn enable_module_function(&self, mode: ModuleFunction) {
393 let mut sel0 = self.registers.sel0[self.reg_idx].get();
394 let mut sel1 = self.registers.sel1[self.reg_idx].get();
395
396 match mode {
397 ModuleFunction::Gpio => {
398 sel0 &= !(1 << self.pin);
399 sel1 &= !(1 << self.pin);
400 }
401 ModuleFunction::Primary => {
402 sel0 |= 1 << self.pin;
403 sel1 &= !(1 << self.pin);
404 }
405 ModuleFunction::Secondary => {
406 sel0 &= !(1 << self.pin);
407 sel1 |= 1 << self.pin;
408 }
409 ModuleFunction::Tertiary => {
410 sel0 |= 1 << self.pin;
411 sel1 |= 1 << self.pin;
412 }
413 }
414
415 self.registers.sel0[self.reg_idx].set(sel0);
416 self.registers.sel1[self.reg_idx].set(sel1);
417 }
418
419 pub fn enable_primary_function(&self) {
420 self.enable_module_function(ModuleFunction::Primary);
421 }
422
423 pub fn enable_secondary_function(&self) {
424 self.enable_module_function(ModuleFunction::Secondary);
425 }
426
427 pub fn enable_tertiary_function(&self) {
428 self.enable_module_function(ModuleFunction::Tertiary);
429 }
430 }
431
432 impl<'a> gpio::Input for $pin_type<'a> {
433 fn read(&self) -> bool {
434 self.read_level()
435 }
436 }
437
438 impl<'a> gpio::Output for $pin_type<'a> {
439 fn set(&self) {
440 let mut val = self.registers.out[self.reg_idx].get();
441 val |= 1 << self.pin;
442 self.registers.out[self.reg_idx].set(val);
443 }
444
445 fn clear(&self) {
446 let mut val = self.registers.out[self.reg_idx].get();
447 val &= !(1 << self.pin);
448 self.registers.out[self.reg_idx].set(val);
449 }
450
451 fn toggle(&self) -> bool {
452 let mut val = self.registers.out[self.reg_idx].get();
453 val ^= 1 << self.pin;
454 self.registers.out[self.reg_idx].set(val);
455 (val & (1 << self.pin)) > 0
456 }
457 }
458
459 impl<'a> gpio::Configure for $pin_type<'a> {
460 fn configuration(&self) -> gpio::Configuration {
461 let regs = self.registers;
462 let dir = regs.dir[self.reg_idx].get();
463 let mut sel = ((regs.sel0[self.reg_idx].get() & (1 << self.pin)) > 0) as u8;
464 sel |= (((regs.sel1[self.reg_idx].get() & (1 << self.pin)) > 0) as u8) << 1;
465
466 if sel > 0 {
467 gpio::Configuration::Function
468 } else {
469 if (dir & (1 << self.pin)) > 0 {
470 gpio::Configuration::Output
471 } else {
472 gpio::Configuration::Input
473 }
474 }
475 }
476
477 fn make_output(&self) -> gpio::Configuration {
478 use gpio::Output;
479 self.enable_module_function(ModuleFunction::Gpio);
480
481 let mut val = self.registers.dir[self.reg_idx].get();
482 val |= 1 << self.pin;
483 self.registers.dir[self.reg_idx].set(val);
484
485 self.clear();
487 gpio::Configuration::Output
488 }
489
490 fn disable_output(&self) -> gpio::Configuration {
491 self.make_input()
492 }
493
494 fn make_input(&self) -> gpio::Configuration {
495 self.enable_module_function(ModuleFunction::Gpio);
496
497 let mut val = self.registers.dir[self.reg_idx].get();
498 val &= !(1 << self.pin);
499 self.registers.dir[self.reg_idx].set(val);
500 gpio::Configuration::Input
501 }
502
503 fn disable_input(&self) -> gpio::Configuration {
504 self.configuration()
507 }
508
509 fn deactivate_to_low_power(&self) {
510 self.make_input();
513 self.set_floating_state(gpio::FloatingState::PullUp);
514 }
515
516 fn set_floating_state(&self, state: gpio::FloatingState) {
517 let regs = self.registers;
518 let mut ren = regs.ren[self.reg_idx].get();
519 let mut out = regs.out[self.reg_idx].get();
520 match state {
521 gpio::FloatingState::PullDown => {
522 ren |= 1 << self.pin;
523 out &= !(1 << self.pin);
524 }
525 gpio::FloatingState::PullUp => {
526 ren |= 1 << self.pin;
527 out |= 1 << self.pin;
528 }
529 gpio::FloatingState::PullNone => {
530 ren &= !(1 << self.pin);
531 }
532 }
533 regs.ren[self.reg_idx].set(ren);
534 regs.out[self.reg_idx].set(out);
535 }
536
537 fn floating_state(&self) -> gpio::FloatingState {
538 let ren = self.registers.ren[self.reg_idx].get();
539 let out = self.registers.out[self.reg_idx].get();
540
541 if (ren & (1 << self.pin)) > 0 {
542 if (out & (1 << self.pin)) > 0 {
543 gpio::FloatingState::PullUp
544 } else {
545 gpio::FloatingState::PullDown
546 }
547 } else {
548 gpio::FloatingState::PullNone
549 }
550 }
551 }
552 };
553}
554
555pin_implementation!(IntPin);
556pin_implementation!(Pin);
557
558impl<'a> gpio::Interrupt<'a> for IntPin<'a> {
559 fn set_client(&self, client: &'a dyn gpio::Client) {
560 self.client.set(client);
561 }
562
563 fn enable_interrupts(&self, mode: gpio::InterruptEdge) {
564 self.disable_interrupts();
567
568 let mut edge = self.registers.ies[self.reg_idx].get();
569 match mode {
570 gpio::InterruptEdge::FallingEdge => {
571 self.detect_both_edges.set(false);
572 edge |= 1 << self.pin;
573 }
574 gpio::InterruptEdge::RisingEdge => {
575 self.detect_both_edges.set(false);
576 edge &= !(1 << self.pin);
577 }
578 gpio::InterruptEdge::EitherEdge => {
579 self.detect_both_edges.set(true);
582 if self.read_level() {
583 edge |= 1 << self.pin;
585 } else {
586 edge &= !(1 << self.pin);
588 }
589 }
590 }
591
592 self.registers.ies[self.reg_idx].set(edge);
594 self.registers.ifg[self.reg_idx]
596 .set(self.registers.ifg[self.reg_idx].get() & !(1 << self.pin));
597 self.registers.ie[self.reg_idx]
599 .set(self.registers.ie[self.reg_idx].get() | (1 << self.pin));
600 }
601
602 fn disable_interrupts(&self) {
603 let mut enable = self.registers.ie[self.reg_idx].get();
604 enable &= !(1 << self.pin);
605 self.registers.ie[self.reg_idx].set(enable);
606 }
607
608 fn is_pending(&self) -> bool {
609 (self.registers.ifg[self.reg_idx].get() & (1 << self.pin)) > 0
610 }
611}
612
613impl GpioManager<'_> {
614 pub fn handle_interrupt(&self, port_idx: usize) {
615 let regs: StaticRef<GpioRegisters> = GPIO_BASES[port_idx / 2];
616 let ifgs: [u8; 2] = [regs.ifg[0].get(), regs.ifg[1].get()];
617
618 let handle_int = |ifg_idx: usize, i: usize| {
619 let bit = 1 << i;
620 if (ifgs[ifg_idx] & bit) > 0 {
621 self.int_pins[(port_idx * 8) + i].handle_interrupt();
622 regs.ifg[ifg_idx].set(regs.ifg[ifg_idx].get() & !bit);
625 }
626 };
627
628 for i in 0..8 {
629 handle_int(0, i);
630 handle_int(1, i);
631 }
632 }
633}