1use cortexm7::support::atomic;
30use enum_primitive::cast::FromPrimitive;
31use enum_primitive::enum_from_primitive;
32use kernel::hil;
33use kernel::platform::chip::ClockInterface;
34use kernel::utilities::cells::OptionalCell;
35use kernel::utilities::registers::interfaces::{Readable, Writeable};
36use kernel::utilities::registers::{ReadOnly, ReadWrite, WriteOnly};
37use kernel::utilities::StaticRef;
38
39use crate::ccm;
40
41#[repr(C)]
43struct GpioRegisters {
44 dr: ReadWrite<u32>,
46 gdir: ReadWrite<u32>,
48 psr: ReadOnly<u32>,
50 icr1: ReadWrite<u32>,
52 icr2: ReadWrite<u32>,
54 imr: ReadWrite<u32>,
56 isr: ReadWrite<u32>,
58 edge_sel: ReadWrite<u32>,
60 _reserved1: [u8; 100],
61 dr_set: WriteOnly<u32>,
63 dr_clear: WriteOnly<u32>,
65 dr_toggle: WriteOnly<u32>,
67}
68
69const GPIO1_BASE: StaticRef<GpioRegisters> =
70 unsafe { StaticRef::new(0x401B8000 as *const GpioRegisters) };
71
72const GPIO2_BASE: StaticRef<GpioRegisters> =
73 unsafe { StaticRef::new(0x401BC000 as *const GpioRegisters) };
74
75const GPIO3_BASE: StaticRef<GpioRegisters> =
76 unsafe { StaticRef::new(0x401C0000 as *const GpioRegisters) };
77
78const GPIO4_BASE: StaticRef<GpioRegisters> =
79 unsafe { StaticRef::new(0x401C4000 as *const GpioRegisters) };
80
81const GPIO5_BASE: StaticRef<GpioRegisters> =
82 unsafe { StaticRef::new(0x400C0000 as *const GpioRegisters) };
83
84enum_from_primitive! {
85 #[repr(u16)]
90 enum GpioPort {
91 GPIO1 = 0b000,
92 GPIO2 = 0b001,
93 GPIO3 = 0b010,
94 GPIO4 = 0b011,
95 GPIO5 = 0b100,
96 }
97}
98
99const fn gpio_id(port: GpioPort, offset: u16) -> u16 {
104 ((port as u16) << 6) | offset & 0x3F
105}
106
107#[repr(u16)]
109#[derive(Copy, Clone)]
110pub enum PinId {
111 AdB0_00 = gpio_id(GpioPort::GPIO1, 0),
113 AdB0_01 = gpio_id(GpioPort::GPIO1, 1),
114 AdB0_02 = gpio_id(GpioPort::GPIO1, 2),
115 AdB0_03 = gpio_id(GpioPort::GPIO1, 3),
116 AdB0_04 = gpio_id(GpioPort::GPIO1, 4),
117 AdB0_05 = gpio_id(GpioPort::GPIO1, 5),
118 AdB0_06 = gpio_id(GpioPort::GPIO1, 6),
119 AdB0_07 = gpio_id(GpioPort::GPIO1, 7),
120 AdB0_08 = gpio_id(GpioPort::GPIO1, 8),
121 AdB0_09 = gpio_id(GpioPort::GPIO1, 9),
122 AdB0_10 = gpio_id(GpioPort::GPIO1, 10),
123 AdB0_11 = gpio_id(GpioPort::GPIO1, 11),
124 AdB0_12 = gpio_id(GpioPort::GPIO1, 12),
125 AdB0_13 = gpio_id(GpioPort::GPIO1, 13),
126 AdB0_14 = gpio_id(GpioPort::GPIO1, 14),
127 AdB0_15 = gpio_id(GpioPort::GPIO1, 15),
128
129 AdB1_00 = gpio_id(GpioPort::GPIO1, 16),
130 AdB1_01 = gpio_id(GpioPort::GPIO1, 17),
131 AdB1_02 = gpio_id(GpioPort::GPIO1, 18),
132 AdB1_03 = gpio_id(GpioPort::GPIO1, 19),
133 AdB1_04 = gpio_id(GpioPort::GPIO1, 20),
134 AdB1_05 = gpio_id(GpioPort::GPIO1, 21),
135 AdB1_06 = gpio_id(GpioPort::GPIO1, 22),
136 AdB1_07 = gpio_id(GpioPort::GPIO1, 23),
137 AdB1_08 = gpio_id(GpioPort::GPIO1, 24),
138 AdB1_09 = gpio_id(GpioPort::GPIO1, 25),
139 AdB1_10 = gpio_id(GpioPort::GPIO1, 26),
140 AdB1_11 = gpio_id(GpioPort::GPIO1, 27),
141 AdB1_12 = gpio_id(GpioPort::GPIO1, 28),
142 AdB1_13 = gpio_id(GpioPort::GPIO1, 29),
143 AdB1_14 = gpio_id(GpioPort::GPIO1, 30),
144 AdB1_15 = gpio_id(GpioPort::GPIO1, 31),
145
146 B0_00 = gpio_id(GpioPort::GPIO2, 0),
148 B0_01 = gpio_id(GpioPort::GPIO2, 1),
149 B0_02 = gpio_id(GpioPort::GPIO2, 2),
150 B0_03 = gpio_id(GpioPort::GPIO2, 3),
151 B0_04 = gpio_id(GpioPort::GPIO2, 4),
152 B0_05 = gpio_id(GpioPort::GPIO2, 5),
153 B0_06 = gpio_id(GpioPort::GPIO2, 6),
154 B0_07 = gpio_id(GpioPort::GPIO2, 7),
155 B0_08 = gpio_id(GpioPort::GPIO2, 8),
156 B0_09 = gpio_id(GpioPort::GPIO2, 9),
157 B0_10 = gpio_id(GpioPort::GPIO2, 10),
158 B0_11 = gpio_id(GpioPort::GPIO2, 11),
159 B0_12 = gpio_id(GpioPort::GPIO2, 12),
160 B0_13 = gpio_id(GpioPort::GPIO2, 13),
161 B0_14 = gpio_id(GpioPort::GPIO2, 14),
162 B0_15 = gpio_id(GpioPort::GPIO2, 15),
163
164 B1_00 = gpio_id(GpioPort::GPIO2, 16),
165 B1_01 = gpio_id(GpioPort::GPIO2, 17),
166 B1_02 = gpio_id(GpioPort::GPIO2, 18),
167 B1_03 = gpio_id(GpioPort::GPIO2, 19),
168 B1_04 = gpio_id(GpioPort::GPIO2, 20),
169 B1_05 = gpio_id(GpioPort::GPIO2, 21),
170 B1_06 = gpio_id(GpioPort::GPIO2, 22),
171 B1_07 = gpio_id(GpioPort::GPIO2, 23),
172 B1_08 = gpio_id(GpioPort::GPIO2, 24),
173 B1_09 = gpio_id(GpioPort::GPIO2, 25),
174 B1_10 = gpio_id(GpioPort::GPIO2, 26),
175 B1_11 = gpio_id(GpioPort::GPIO2, 27),
176 B1_12 = gpio_id(GpioPort::GPIO2, 28),
177 B1_13 = gpio_id(GpioPort::GPIO2, 29),
178 B1_14 = gpio_id(GpioPort::GPIO2, 30),
179 B1_15 = gpio_id(GpioPort::GPIO2, 31),
180
181 SdB1_00 = gpio_id(GpioPort::GPIO3, 0),
183 SdB1_01 = gpio_id(GpioPort::GPIO3, 1),
184 SdB1_02 = gpio_id(GpioPort::GPIO3, 2),
185 SdB1_03 = gpio_id(GpioPort::GPIO3, 3),
186 SdB1_04 = gpio_id(GpioPort::GPIO3, 4),
187 SdB1_05 = gpio_id(GpioPort::GPIO3, 5),
188 SdB1_06 = gpio_id(GpioPort::GPIO3, 6),
189 SdB1_07 = gpio_id(GpioPort::GPIO3, 7),
190 SdB1_08 = gpio_id(GpioPort::GPIO3, 8),
191 SdB1_09 = gpio_id(GpioPort::GPIO3, 9),
192 SdB1_10 = gpio_id(GpioPort::GPIO3, 10),
193 SdB1_11 = gpio_id(GpioPort::GPIO3, 11),
194
195 SdB0_00 = gpio_id(GpioPort::GPIO3, 12),
196 SdB0_01 = gpio_id(GpioPort::GPIO3, 13),
197 SdB0_02 = gpio_id(GpioPort::GPIO3, 14),
198 SdB0_03 = gpio_id(GpioPort::GPIO3, 15),
199 SdB0_04 = gpio_id(GpioPort::GPIO3, 16),
200 SdB0_05 = gpio_id(GpioPort::GPIO3, 17),
201
202 Emc32 = gpio_id(GpioPort::GPIO3, 18),
203 Emc33 = gpio_id(GpioPort::GPIO3, 19),
204 Emc34 = gpio_id(GpioPort::GPIO3, 20),
205 Emc35 = gpio_id(GpioPort::GPIO3, 21),
206 Emc36 = gpio_id(GpioPort::GPIO3, 22),
207 Emc37 = gpio_id(GpioPort::GPIO3, 23),
208 Emc38 = gpio_id(GpioPort::GPIO3, 24),
209 Emc39 = gpio_id(GpioPort::GPIO3, 25),
210 Emc40 = gpio_id(GpioPort::GPIO3, 26),
211 Emc41 = gpio_id(GpioPort::GPIO3, 27),
212
213 Emc00 = gpio_id(GpioPort::GPIO4, 0),
215 Emc01 = gpio_id(GpioPort::GPIO4, 1),
216 Emc02 = gpio_id(GpioPort::GPIO4, 2),
217 Emc03 = gpio_id(GpioPort::GPIO4, 3),
218 Emc04 = gpio_id(GpioPort::GPIO4, 4),
219 Emc05 = gpio_id(GpioPort::GPIO4, 5),
220 Emc06 = gpio_id(GpioPort::GPIO4, 6),
221 Emc07 = gpio_id(GpioPort::GPIO4, 7),
222 Emc08 = gpio_id(GpioPort::GPIO4, 8),
223 Emc09 = gpio_id(GpioPort::GPIO4, 9),
224 Emc10 = gpio_id(GpioPort::GPIO4, 10),
225 Emc11 = gpio_id(GpioPort::GPIO4, 11),
226 Emc12 = gpio_id(GpioPort::GPIO4, 12),
227 Emc13 = gpio_id(GpioPort::GPIO4, 13),
228 Emc14 = gpio_id(GpioPort::GPIO4, 14),
229 Emc15 = gpio_id(GpioPort::GPIO4, 15),
230 Emc16 = gpio_id(GpioPort::GPIO4, 16),
231 Emc17 = gpio_id(GpioPort::GPIO4, 17),
232 Emc18 = gpio_id(GpioPort::GPIO4, 18),
233 Emc19 = gpio_id(GpioPort::GPIO4, 19),
234 Emc20 = gpio_id(GpioPort::GPIO4, 20),
235 Emc21 = gpio_id(GpioPort::GPIO4, 21),
236 Emc22 = gpio_id(GpioPort::GPIO4, 22),
237 Emc23 = gpio_id(GpioPort::GPIO4, 23),
238 Emc24 = gpio_id(GpioPort::GPIO4, 24),
239 Emc25 = gpio_id(GpioPort::GPIO4, 25),
240 Emc26 = gpio_id(GpioPort::GPIO4, 26),
241 Emc27 = gpio_id(GpioPort::GPIO4, 27),
242 Emc28 = gpio_id(GpioPort::GPIO4, 28),
243 Emc29 = gpio_id(GpioPort::GPIO4, 29),
244 Emc30 = gpio_id(GpioPort::GPIO4, 30),
245 Emc31 = gpio_id(GpioPort::GPIO4, 31),
246
247 Wakeup = gpio_id(GpioPort::GPIO5, 0),
249 PmicOnReq = gpio_id(GpioPort::GPIO5, 1),
250 PmicStbyReq = gpio_id(GpioPort::GPIO5, 2),
251}
252
253impl PinId {
254 fn port(self) -> GpioPort {
256 GpioPort::from_u16((self as u16) >> 6).unwrap()
257 }
258 const fn offset(self) -> usize {
260 (self as usize) & 0x3F
261 }
262}
263
264pub enum Mode {
277 Input = 0b00,
278 Output = 0b01,
279}
280
281pub struct Port<'a, const N: usize> {
286 registers: StaticRef<GpioRegisters>,
287 clock: PortClock<'a>,
288 pins: [Pin<'a>; N],
289}
290
291impl<'a, const N: usize> Port<'a, N> {
294 const fn new(
295 registers: StaticRef<GpioRegisters>,
296 clock: PortClock<'a>,
297 pins: [Pin<'a>; N],
298 ) -> Self {
299 Self {
300 registers,
301 clock,
302 pins,
303 }
304 }
305
306 pub fn is_enabled_clock(&self) -> bool {
307 self.clock.is_enabled()
308 }
309
310 pub fn enable_clock(&self) {
311 self.clock.enable();
312 }
313
314 pub fn disable_clock(&self) {
315 self.clock.disable();
316 }
317
318 pub const fn pin(&self, offset: usize) -> &Pin<'a> {
323 &self.pins[offset]
324 }
325
326 pub fn handle_interrupt(&self) {
327 let imr_val: u32 = self.registers.imr.get();
328
329 let isr_val = unsafe {
336 atomic(|| {
337 let isr_val = self.registers.isr.get();
338 self.registers.isr.set(isr_val);
339 isr_val
340 })
341 };
342
343 BitOffsets(isr_val)
344 .filter(|offset| imr_val & (1 << offset) != 0)
346 .filter_map(|offset| self.pins.get(offset as usize))
348 .for_each(|pin| {
350 pin.client.map(|client| client.fired());
351 });
352 }
353}
354
355type GPIO1<'a> = Port<'a, 32>;
356type GPIO2<'a> = Port<'a, 32>;
357type GPIO3<'a> = Port<'a, 28>;
358type GPIO4<'a> = Port<'a, 32>;
359type GPIO5<'a> = Port<'a, 3>;
360
361impl<'a> Port<'a, 32> {
362 const fn new_32(registers: StaticRef<GpioRegisters>, clock: PortClock<'a>) -> Self {
363 Self::new(
364 registers,
365 clock,
366 [
367 Pin::new(registers, 00),
368 Pin::new(registers, 01),
369 Pin::new(registers, 02),
370 Pin::new(registers, 03),
371 Pin::new(registers, 04),
372 Pin::new(registers, 05),
373 Pin::new(registers, 06),
374 Pin::new(registers, 07),
375 Pin::new(registers, 08),
376 Pin::new(registers, 09),
377 Pin::new(registers, 10),
378 Pin::new(registers, 11),
379 Pin::new(registers, 12),
380 Pin::new(registers, 13),
381 Pin::new(registers, 14),
382 Pin::new(registers, 15),
383 Pin::new(registers, 16),
384 Pin::new(registers, 17),
385 Pin::new(registers, 18),
386 Pin::new(registers, 19),
387 Pin::new(registers, 20),
388 Pin::new(registers, 21),
389 Pin::new(registers, 22),
390 Pin::new(registers, 23),
391 Pin::new(registers, 24),
392 Pin::new(registers, 25),
393 Pin::new(registers, 26),
394 Pin::new(registers, 27),
395 Pin::new(registers, 28),
396 Pin::new(registers, 29),
397 Pin::new(registers, 30),
398 Pin::new(registers, 31),
399 ],
400 )
401 }
402 const fn gpio1(ccm: &'a ccm::Ccm) -> GPIO1<'a> {
403 Self::new_32(
404 GPIO1_BASE,
405 PortClock(ccm::PeripheralClock::ccgr1(ccm, ccm::HCLK1::GPIO1)),
406 )
407 }
408 const fn gpio2(ccm: &'a ccm::Ccm) -> GPIO2<'a> {
409 Self::new_32(
410 GPIO2_BASE,
411 PortClock(ccm::PeripheralClock::ccgr0(ccm, ccm::HCLK0::GPIO2)),
412 )
413 }
414 const fn gpio4(ccm: &'a ccm::Ccm) -> GPIO4<'a> {
415 Self::new_32(
416 GPIO4_BASE,
417 PortClock(ccm::PeripheralClock::ccgr3(ccm, ccm::HCLK3::GPIO4)),
418 )
419 }
420}
421
422impl<'a> Port<'a, 28> {
423 const fn new_28(registers: StaticRef<GpioRegisters>, clock: PortClock<'a>) -> Self {
424 Self::new(
425 registers,
426 clock,
427 [
428 Pin::new(registers, 00),
429 Pin::new(registers, 01),
430 Pin::new(registers, 02),
431 Pin::new(registers, 03),
432 Pin::new(registers, 04),
433 Pin::new(registers, 05),
434 Pin::new(registers, 06),
435 Pin::new(registers, 07),
436 Pin::new(registers, 08),
437 Pin::new(registers, 09),
438 Pin::new(registers, 10),
439 Pin::new(registers, 11),
440 Pin::new(registers, 12),
441 Pin::new(registers, 13),
442 Pin::new(registers, 14),
443 Pin::new(registers, 15),
444 Pin::new(registers, 16),
445 Pin::new(registers, 17),
446 Pin::new(registers, 18),
447 Pin::new(registers, 19),
448 Pin::new(registers, 20),
449 Pin::new(registers, 21),
450 Pin::new(registers, 22),
451 Pin::new(registers, 23),
452 Pin::new(registers, 24),
453 Pin::new(registers, 25),
454 Pin::new(registers, 26),
455 Pin::new(registers, 27),
456 ],
457 )
458 }
459 const fn gpio3(ccm: &'a ccm::Ccm) -> GPIO3<'a> {
460 Self::new_28(
461 GPIO3_BASE,
462 PortClock(ccm::PeripheralClock::ccgr2(ccm, ccm::HCLK2::GPIO3)),
463 )
464 }
465}
466
467impl<'a> Port<'a, 3> {
468 const fn new_3(registers: StaticRef<GpioRegisters>, clock: PortClock<'a>) -> Self {
469 Self::new(
470 registers,
471 clock,
472 [
473 Pin::new(registers, 00),
474 Pin::new(registers, 01),
475 Pin::new(registers, 02),
476 ],
477 )
478 }
479 const fn gpio5(ccm: &'a ccm::Ccm) -> GPIO5<'a> {
480 Self::new_3(
481 GPIO5_BASE,
482 PortClock(ccm::PeripheralClock::ccgr1(ccm, ccm::HCLK1::GPIO5)),
483 )
484 }
485}
486
487#[non_exhaustive] pub struct Ports<'a> {
493 pub gpio1: GPIO1<'a>,
494 pub gpio2: GPIO2<'a>,
495 pub gpio3: GPIO3<'a>,
496 pub gpio4: GPIO4<'a>,
497 pub gpio5: GPIO5<'a>,
498}
499
500impl<'a> Ports<'a> {
501 pub const fn new(ccm: &'a ccm::Ccm) -> Self {
502 Self {
503 gpio1: GPIO1::gpio1(ccm),
504 gpio2: GPIO2::gpio2(ccm),
505 gpio3: GPIO3::gpio3(ccm),
506 gpio4: GPIO4::gpio4(ccm),
507 gpio5: GPIO5::gpio5(ccm),
508 }
509 }
510
511 pub fn pin(&self, pin: PinId) -> &Pin<'a> {
517 match pin.port() {
518 GpioPort::GPIO1 => &self.gpio1.pins[pin.offset()],
519 GpioPort::GPIO2 => &self.gpio2.pins[pin.offset()],
520 GpioPort::GPIO3 => &self.gpio3.pins[pin.offset()],
521 GpioPort::GPIO4 => &self.gpio4.pins[pin.offset()],
522 GpioPort::GPIO5 => &self.gpio5.pins[pin.offset()],
523 }
524 }
525}
526
527struct PortClock<'a>(ccm::PeripheralClock<'a>);
528
529impl ClockInterface for PortClock<'_> {
530 fn is_enabled(&self) -> bool {
531 self.0.is_enabled()
532 }
533
534 fn enable(&self) {
535 self.0.enable();
536 }
537
538 fn disable(&self) {
539 self.0.disable();
540 }
541}
542
543pub struct Pin<'a> {
550 registers: StaticRef<GpioRegisters>,
551 offset: usize,
552 client: OptionalCell<&'a dyn hil::gpio::Client>,
553}
554
555trait U32Ext {
556 fn set_bit(self, offset: usize) -> Self;
557 fn clear_bit(self, offset: usize) -> Self;
558 fn is_bit_set(&self, offset: usize) -> bool;
559}
560
561impl U32Ext for u32 {
562 #[inline(always)]
563 fn set_bit(self, offset: usize) -> u32 {
564 self | (1 << offset)
565 }
566 #[inline(always)]
567 fn clear_bit(self, offset: usize) -> u32 {
568 self & !(1 << offset)
569 }
570 #[inline(always)]
571 fn is_bit_set(&self, offset: usize) -> bool {
572 (self & (1 << offset)) != 0
573 }
574}
575
576impl Pin<'_> {
577 pub fn from_pin_id(pin_id: PinId) -> Self {
579 Self::new(
580 match pin_id.port() {
581 GpioPort::GPIO1 => GPIO1_BASE,
582 GpioPort::GPIO2 => GPIO2_BASE,
583 GpioPort::GPIO3 => GPIO3_BASE,
584 GpioPort::GPIO4 => GPIO4_BASE,
585 GpioPort::GPIO5 => GPIO5_BASE,
586 },
587 pin_id.offset(),
588 )
589 }
590 const fn new(registers: StaticRef<GpioRegisters>, offset: usize) -> Self {
591 Pin {
592 registers,
593 offset,
594 client: OptionalCell::empty(),
595 }
596 }
597
598 fn get_mode(&self) -> Mode {
599 if self.registers.gdir.get().is_bit_set(self.offset) {
600 Mode::Output
601 } else {
602 Mode::Input
603 }
604 }
605
606 fn set_mode(&self, mode: Mode) {
607 let gdir = self.registers.gdir.get();
608 let gdir = match mode {
609 Mode::Input => gdir.clear_bit(self.offset),
610 Mode::Output => gdir.set_bit(self.offset),
611 };
612 self.registers.gdir.set(gdir);
613 }
614
615 fn set_output_high(&self) {
616 self.registers.dr_set.set(1 << self.offset);
617 }
618
619 fn set_output_low(&self) {
620 self.registers.dr_clear.set(1 << self.offset);
621 }
622
623 fn is_output_high(&self) -> bool {
624 self.registers.dr.get().is_bit_set(self.offset)
625 }
626
627 fn toggle_output(&self) -> bool {
628 self.registers.dr_toggle.set(1 << self.offset);
629 self.is_output_high()
630 }
631
632 fn read_input(&self) -> bool {
633 self.registers.psr.get().is_bit_set(self.offset)
634 }
635
636 fn mask_interrupt(&self) {
637 let imr = self.registers.imr.get();
638 let imr = imr.clear_bit(self.offset);
639 self.registers.imr.set(imr);
640 }
641
642 fn unmask_interrupt(&self) {
643 let imr = self.registers.imr.get();
644 let imr = imr.set_bit(self.offset);
645 self.registers.imr.set(imr);
646 }
647
648 fn clear_pending(&self) {
649 self.registers.isr.set(1 << self.offset); }
651
652 fn set_edge_sensitive(&self, sensitive: hil::gpio::InterruptEdge) {
653 use hil::gpio::InterruptEdge::{EitherEdge, FallingEdge, RisingEdge};
654 const RISING_EDGE_SENSITIVE: u32 = 0b10;
655 const FALLING_EDGE_SENSITIVE: u32 = 0b11;
656
657 let edge_sel = self.registers.edge_sel.get();
658 let icr_offset = (self.offset % 16) * 2;
659
660 let sensitive = match sensitive {
661 EitherEdge => {
662 let edge_sel = edge_sel.set_bit(self.offset);
663 self.registers.edge_sel.set(edge_sel);
664 return;
666 }
667 RisingEdge => RISING_EDGE_SENSITIVE << icr_offset,
668 FallingEdge => FALLING_EDGE_SENSITIVE << icr_offset,
669 };
670
671 let edge_sel = edge_sel.clear_bit(self.offset);
672 self.registers.edge_sel.set(edge_sel);
673
674 let icr_mask = 0b11 << icr_offset;
675 if self.offset < 16 {
676 let icr1 = self.registers.icr1.get();
677 let icr1 = (icr1 & !icr_mask) | sensitive;
678 self.registers.icr1.set(icr1);
679 } else {
680 let icr2 = self.registers.icr2.get();
681 let icr2 = (icr2 & !icr_mask) | sensitive;
682 self.registers.icr2.set(icr2);
683 }
684 }
685}
686
687impl hil::gpio::Configure for Pin<'_> {
688 fn make_output(&self) -> hil::gpio::Configuration {
689 self.set_mode(Mode::Output);
690 hil::gpio::Configuration::Output
691 }
692
693 fn make_input(&self) -> hil::gpio::Configuration {
694 self.set_mode(Mode::Input);
695 hil::gpio::Configuration::Input
696 }
697
698 fn deactivate_to_low_power(&self) {
699 }
701
702 fn disable_output(&self) -> hil::gpio::Configuration {
703 hil::gpio::Configuration::LowPower
705 }
706
707 fn disable_input(&self) -> hil::gpio::Configuration {
708 hil::gpio::Configuration::LowPower
710 }
711
712 fn set_floating_state(&self, _mode: hil::gpio::FloatingState) {}
714
715 fn floating_state(&self) -> hil::gpio::FloatingState {
716 hil::gpio::FloatingState::PullNone
717 }
718
719 fn configuration(&self) -> hil::gpio::Configuration {
720 match self.get_mode() {
721 Mode::Input => hil::gpio::Configuration::Input,
722 Mode::Output => hil::gpio::Configuration::Output,
723 }
724 }
725}
726
727impl hil::gpio::Output for Pin<'_> {
728 fn set(&self) {
729 self.set_output_high();
730 }
731
732 fn clear(&self) {
733 self.set_output_low();
734 }
735
736 fn toggle(&self) -> bool {
737 self.toggle_output()
738 }
739}
740
741impl hil::gpio::Input for Pin<'_> {
742 fn read(&self) -> bool {
743 self.read_input()
744 }
745}
746
747impl<'a> hil::gpio::Interrupt<'a> for Pin<'a> {
748 fn enable_interrupts(&self, mode: hil::gpio::InterruptEdge) {
749 unsafe {
750 atomic(|| {
751 self.mask_interrupt();
753 self.clear_pending();
754 self.set_edge_sensitive(mode);
755
756 self.unmask_interrupt();
757 });
758 }
759 }
760
761 fn disable_interrupts(&self) {
762 unsafe {
763 atomic(|| {
764 self.mask_interrupt();
765 self.clear_pending();
766 });
767 }
768 }
769
770 fn set_client(&self, client: &'a dyn hil::gpio::Client) {
771 self.client.set(client);
772 }
773
774 fn is_pending(&self) -> bool {
775 self.registers.isr.get().is_bit_set(self.offset)
776 }
777}
778
779struct BitOffsets(u32);
784
785impl Iterator for BitOffsets {
786 type Item = u32;
787 fn next(&mut self) -> Option<Self::Item> {
788 if self.0 != 0 {
789 let offset = self.0.trailing_zeros();
790 self.0 &= self.0 - 1;
791 Some(offset)
792 } else {
793 None
794 }
795 }
796 fn size_hint(&self) -> (usize, Option<usize>) {
797 let popcnt = self.0.count_ones() as usize;
798 (popcnt, Some(popcnt))
799 }
800}
801
802impl ExactSizeIterator for BitOffsets {}
803
804#[cfg(test)]
805mod tests {
806 use super::BitOffsets;
807
808 #[test]
809 fn bit_offsets() {
810 fn check(word: u32, expected: impl ExactSizeIterator<Item = u32>) {
811 let offsets = BitOffsets(word);
812 assert_eq!(offsets.len(), expected.len());
813 assert!(
814 offsets.eq(expected),
815 "Incorrect bit offsets for word {:#b}",
816 word
817 );
818 }
819
820 check(0, core::iter::empty());
821 check(u32::max_value(), 0..32);
822 check(u32::max_value() >> 1, 0..31);
823 check(u32::max_value() << 1, 1..32);
824 check(0x5555_5555, (0..32).step_by(2));
825 check(0xAAAA_AAAA, (0..32).skip(1).step_by(2));
826 }
827}