Krolyxon
Commit f34f8a0

Branches

Tags

Refs →

orion-rfsrcdriversbuttons.rs

75 lines · 2.1 KB · Rust

1//! Six momentary buttons, active-low with internal pull-ups.
2//!
3//! Parity reference: `src-arduino/utils/buttons.cpp`. Arduino uses
4//! `pinMode(INPUT_PULLUP)` and reports pressed as `!digitalRead(pin)`, i.e. a
5//! pressed button reads LOW. We mirror that: `get_level() == Level::Low`.
6//!
7//! Debounce (the Arduino `delay(150)` after each handled press) lives at the
8//! call site via [`debounce`], matching the original per-action delays.
9
10use esp_idf_hal::delay::FreeRtos;
11use esp_idf_hal::gpio::{AnyIOPin, Input, Level, PinDriver, Pull};
12
13/// The ~150ms debounce the Arduino firmware applies after each handled press.
14pub const DEBOUNCE_MS: u32 = 150;
15
16/// Block for the standard debounce interval after acting on a press.
17pub fn debounce() {
18 FreeRtos::delay_ms(DEBOUNCE_MS);
19}
20
21type Btn = PinDriver<'static, Input>;
22
23pub struct Buttons {
24 up: Btn,
25 down: Btn,
26 select: Btn,
27 back: Btn,
28 right: Btn,
29 left: Btn,
30}
31
32impl Buttons {
33 /// Configure the six pins as pulled-up inputs. Order matches the physical
34 /// labels, not GPIO numbers (see `board::pins`).
35 pub fn new(
36 up: AnyIOPin<'static>,
37 down: AnyIOPin<'static>,
38 select: AnyIOPin<'static>,
39 back: AnyIOPin<'static>,
40 right: AnyIOPin<'static>,
41 left: AnyIOPin<'static>,
42 ) -> Self {
43 Self {
44 up: Self::input(up),
45 down: Self::input(down),
46 select: Self::input(select),
47 back: Self::input(back),
48 right: Self::input(right),
49 left: Self::input(left),
50 }
51 }
52
53 fn input(pin: AnyIOPin<'static>) -> Btn {
54 PinDriver::input(pin, Pull::Up).expect("button input")
55 }
56
57 pub fn up(&self) -> bool {
58 self.up.get_level() == Level::Low
59 }
60 pub fn down(&self) -> bool {
61 self.down.get_level() == Level::Low
62 }
63 pub fn select(&self) -> bool {
64 self.select.get_level() == Level::Low
65 }
66 pub fn back(&self) -> bool {
67 self.back.get_level() == Level::Low
68 }
69 pub fn right(&self) -> bool {
70 self.right.get_level() == Level::Low
71 }
72 pub fn left(&self) -> bool {
73 self.left.get_level() == Level::Low
74 }
75}