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}