1#![feature(ascii_char)]
2#![feature(ascii_char_variants)]
3#![feature(trivial_bounds)]
4#![no_std]
5
6pub mod character_select;
7pub mod confirmation;
8pub mod console;
9pub mod grid;
10pub mod held_key;
11pub mod menu;
12pub mod multitap;
13pub mod test;
14pub mod textbox;
15pub mod time;
16
17use core::{ascii::Char, future::Future};
18
19use embassy_time::Duration;
20use embedded_graphics_core::{draw_target::DrawTarget, pixelcolor::BinaryColor};
21use enum_iterator::Sequence;
22use strum_macros::IntoStaticStr;
23use usbd_hid::descriptor::KeyboardUsage;
24
25pub trait Backlight {
26 fn on(&mut self);
27 fn off(&mut self);
28}
29
30pub trait VibrationMotor {
31 fn start_vibrating(&mut self);
32 fn stop_vibrating(&mut self);
33}
34
35pub trait Buzzer {
36 type Error: core::fmt::Debug;
37
38 fn set_frequency(&mut self, frequency: u16) -> Result<(), Self::Error>;
39 fn set_volume(&mut self, volume: u8);
40 fn mute_buzzer(&mut self) -> Result<(), Self::Error>;
41 fn unmute_buzzer(&mut self) -> Result<(), Self::Error>;
42}
43
44pub enum ButtonEvent {
45 Up,
46 Down,
47}
48
49pub trait PowerButton {
50 fn clear(&mut self);
51}
52
53pub trait Rtc {
54 type Error: core::fmt::Debug;
55
56 fn timestamp(&mut self) -> Result<i64, Self::Error>;
57 fn set_timestamp(&mut self, time: i64);
58}
59
60#[derive(Debug, Clone, IntoStaticStr, Sequence, PartialEq)]
61pub enum Key {
62 Select,
63 Cancel,
64 Up,
65 Down,
66 One,
67 Two,
68 Three,
69 Four,
70 Five,
71 Six,
72 Seven,
73 Eight,
74 Nine,
75 Asterisk,
76 Zero,
77 Hash,
78}
79
80impl From<Key> for Char {
81 fn from(k: Key) -> Char {
82 match k {
83 Key::Select => Char::CarriageReturn,
84 Key::Cancel => Char::Backspace,
85 Key::Up => Char::Digit1,
86 Key::Down => Char::Digit1,
87 Key::One => Char::Digit1,
88 Key::Two => Char::CapitalA,
89 Key::Three => Char::CapitalD,
90 Key::Four => Char::CapitalG,
91 Key::Five => Char::CapitalJ,
92 Key::Six => Char::CapitalM,
93 Key::Seven => Char::CapitalP,
94 Key::Eight => Char::CapitalT,
95 Key::Nine => Char::CapitalW,
96 Key::Asterisk => Char::Asterisk,
97 Key::Zero => Char::Space,
98 Key::Hash => Char::NumberSign,
99 }
100 }
101}
102
103#[derive(Clone, Debug, PartialEq)]
104pub enum KeyEvent {
105 Up(Key),
106 Down(Key),
107}
108
109pub trait Keypad {
110 fn event(&mut self) -> impl core::future::Future<Output = KeyEvent> + core::marker::Send;
111
112 fn last_pressed(&mut self) -> Option<embassy_time::Duration>;
113}
114
115pub trait Application {
116 fn run(&mut self, device: &mut impl Device) -> impl Future<Output = Result<(), ()>>;
117}
118
119pub trait Device:
120 VibrationMotor + Buzzer + Keypad + Rtc + Backlight + DrawTarget<Color = BinaryColor, Error = ()>
121{
122}
123
124pub fn build_report(c: Char) -> usbd_hid::descriptor::KeyboardReport {
125 let keycode = match c {
126 Char::Space => KeyboardUsage::KeyboardSpacebar,
127 Char::Digit0 => KeyboardUsage::Keyboard0CloseParens,
128 Char::Digit1 => KeyboardUsage::Keyboard1Exclamation,
129 Char::Digit2 => KeyboardUsage::Keyboard2At,
130 Char::Digit3 => KeyboardUsage::Keyboard3Hash,
131 Char::Digit4 => KeyboardUsage::Keyboard4Dollar,
132 Char::Digit5 => KeyboardUsage::Keyboard5Percent,
133 Char::Digit6 => KeyboardUsage::Keyboard6Caret,
134 Char::Digit7 => KeyboardUsage::Keyboard7Ampersand,
135 Char::Digit8 => KeyboardUsage::Keyboard8Asterisk,
136 Char::Digit9 => KeyboardUsage::Keyboard9OpenParens,
137 Char::CapitalA => KeyboardUsage::KeyboardAa,
138 Char::CapitalB => KeyboardUsage::KeyboardBb,
139 Char::CapitalC => KeyboardUsage::KeyboardCc,
140 Char::CapitalD => KeyboardUsage::KeyboardDd,
141 Char::CapitalE => KeyboardUsage::KeyboardEe,
142 Char::CapitalF => KeyboardUsage::KeyboardFf,
143 Char::CapitalG => KeyboardUsage::KeyboardGg,
144 Char::CapitalH => KeyboardUsage::KeyboardHh,
145 Char::CapitalI => KeyboardUsage::KeyboardIi,
146 Char::CapitalJ => KeyboardUsage::KeyboardJj,
147 Char::CapitalK => KeyboardUsage::KeyboardKk,
148 Char::CapitalL => KeyboardUsage::KeyboardLl,
149 Char::CapitalM => KeyboardUsage::KeyboardMm,
150 Char::CapitalN => KeyboardUsage::KeyboardNn,
151 Char::CapitalO => KeyboardUsage::KeyboardOo,
152 Char::CapitalP => KeyboardUsage::KeyboardPp,
153 Char::CapitalQ => KeyboardUsage::KeyboardQq,
154 Char::CapitalR => KeyboardUsage::KeyboardRr,
155 Char::CapitalS => KeyboardUsage::KeyboardSs,
156 Char::CapitalT => KeyboardUsage::KeyboardTt,
157 Char::CapitalU => KeyboardUsage::KeyboardUu,
158 Char::CapitalV => KeyboardUsage::KeyboardVv,
159 Char::CapitalW => KeyboardUsage::KeyboardWw,
160 Char::CapitalX => KeyboardUsage::KeyboardXx,
161 Char::CapitalY => KeyboardUsage::KeyboardYy,
162 Char::CapitalZ => KeyboardUsage::KeyboardZz,
163 Char::SmallA => KeyboardUsage::KeyboardAa,
164 Char::SmallB => KeyboardUsage::KeyboardBb,
165 Char::SmallC => KeyboardUsage::KeyboardCc,
166 Char::SmallD => KeyboardUsage::KeyboardDd,
167 Char::SmallE => KeyboardUsage::KeyboardEe,
168 Char::SmallF => KeyboardUsage::KeyboardFf,
169 Char::SmallG => KeyboardUsage::KeyboardGg,
170 Char::SmallH => KeyboardUsage::KeyboardHh,
171 Char::SmallI => KeyboardUsage::KeyboardIi,
172 Char::SmallJ => KeyboardUsage::KeyboardJj,
173 Char::SmallK => KeyboardUsage::KeyboardKk,
174 Char::SmallL => KeyboardUsage::KeyboardLl,
175 Char::SmallM => KeyboardUsage::KeyboardMm,
176 Char::SmallN => KeyboardUsage::KeyboardNn,
177 Char::SmallO => KeyboardUsage::KeyboardOo,
178 Char::SmallP => KeyboardUsage::KeyboardPp,
179 Char::SmallQ => KeyboardUsage::KeyboardQq,
180 Char::SmallR => KeyboardUsage::KeyboardRr,
181 Char::SmallS => KeyboardUsage::KeyboardSs,
182 Char::SmallT => KeyboardUsage::KeyboardTt,
183 Char::SmallU => KeyboardUsage::KeyboardUu,
184 Char::SmallV => KeyboardUsage::KeyboardVv,
185 Char::SmallW => KeyboardUsage::KeyboardWw,
186 Char::SmallX => KeyboardUsage::KeyboardXx,
187 Char::SmallY => KeyboardUsage::KeyboardYy,
188 Char::SmallZ => KeyboardUsage::KeyboardZz,
189 _ => KeyboardUsage::KeyboardZz,
190 };
191
192 usbd_hid::descriptor::KeyboardReport {
193 keycodes: [keycode as u8, 0, 0, 0, 0, 0],
194 leds: 0,
195 modifier: 0,
196 reserved: 0,
197 }
198}