Skip to content

Commit 931a00a

Browse files
committed
keyboard: Implement reading of arrow keys
Prints to USB serial Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent ecdadfb commit 931a00a

File tree

3 files changed

+237
-36
lines changed

3 files changed

+237
-36
lines changed

Cargo.lock

Lines changed: 2 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ members = [
2020
# target. But we set the default target to thumbv6m-none-eabi
2121
default-members = ["fl16-inputmodules"]
2222

23+
[patch.crates-io]
24+
rp2040-hal = { git = "https://github.com/FrameworkComputer/rp-hal", branch = "adc-pull-down-up" }
25+
2326
[workspace.dependencies]
2427
cortex-m = "0.7"
2528
cortex-m-rt = "0.7.3"

keyboard/src/main.rs

Lines changed: 232 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,24 @@
77
//use cortex_m::delay::Delay;
88
//use defmt::*;
99
use defmt_rtt as _;
10+
use embedded_hal::adc::OneShot;
1011
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
11-
12-
use rp2040_hal::Timer;
12+
use rp2040_hal::gpio::bank0::Gpio28;
13+
use rp2040_hal::gpio::{Input, PullUp};
14+
15+
use core::fmt::Display;
16+
use core::fmt::{self, Formatter};
17+
18+
use rp2040_hal::{
19+
gpio::{
20+
bank0::{
21+
Gpio1, Gpio10, Gpio11, Gpio12, Gpio13, Gpio14, Gpio15, Gpio16, Gpio17, Gpio18, Gpio19,
22+
Gpio2, Gpio20, Gpio21, Gpio22, Gpio23, Gpio3, Gpio8, Gpio9,
23+
},
24+
Output, Pin, PinState, PushPull,
25+
},
26+
Adc, Timer,
27+
};
1328
//#[cfg(debug_assertions)]
1429
//use panic_probe as _;
1530
use rp2040_panic_usb_boot as _;
@@ -44,6 +59,151 @@ use heapless::String;
4459

4560
use fl16_inputmodules::serialnum::device_release;
4661

62+
const MATRIX_COLS: usize = 16;
63+
const MATRIX_ROWS: usize = 8;
64+
const ADC_THRESHOLD: usize = 2900;
65+
66+
struct Mux {
67+
a: Pin<Gpio1, Output<PushPull>>,
68+
b: Pin<Gpio2, Output<PushPull>>,
69+
c: Pin<Gpio3, Output<PushPull>>,
70+
// TODO
71+
// x: Pin<Gpio3, Output<PushPull>>,
72+
}
73+
impl Mux {
74+
pub fn select_row(&mut self, row: usize) {
75+
let index = match row {
76+
0 => 2,
77+
1 => 0,
78+
2 => 1,
79+
_ => row,
80+
};
81+
self.a.set_state(PinState::from(index & 0x01 != 0)).unwrap();
82+
self.b.set_state(PinState::from(index & 0x02 != 0)).unwrap();
83+
self.c.set_state(PinState::from(index & 0x04 != 0)).unwrap();
84+
}
85+
}
86+
87+
#[derive(Debug, PartialEq, Eq, Clone, Default)]
88+
pub struct Col(u8);
89+
#[derive(Debug, PartialEq, Eq, Clone, Default)]
90+
struct Matrix([Col; MATRIX_COLS]);
91+
92+
impl Matrix {
93+
pub fn set(&mut self, row: usize, col: usize, val: bool) {
94+
let mask = 1 << row;
95+
96+
self.0[col].0 = if val {
97+
self.0[col].0 | mask
98+
} else {
99+
self.0[col].0 & !mask
100+
};
101+
}
102+
}
103+
104+
impl Display for Col {
105+
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
106+
for row in 0..MATRIX_ROWS {
107+
let val = (self.0 & (1 << row)) >> row;
108+
write!(f, "{:b}", val)?
109+
}
110+
Ok(())
111+
}
112+
}
113+
114+
type Kso = (
115+
Pin<Gpio8, Output<PushPull>>,
116+
Pin<Gpio9, Output<PushPull>>,
117+
Pin<Gpio10, Output<PushPull>>,
118+
Pin<Gpio11, Output<PushPull>>,
119+
Pin<Gpio12, Output<PushPull>>,
120+
Pin<Gpio13, Output<PushPull>>,
121+
Pin<Gpio14, Output<PushPull>>,
122+
Pin<Gpio15, Output<PushPull>>,
123+
Pin<Gpio21, Output<PushPull>>,
124+
Pin<Gpio20, Output<PushPull>>,
125+
Pin<Gpio19, Output<PushPull>>,
126+
Pin<Gpio18, Output<PushPull>>,
127+
Pin<Gpio17, Output<PushPull>>,
128+
Pin<Gpio16, Output<PushPull>>,
129+
Pin<Gpio23, Output<PushPull>>,
130+
Pin<Gpio22, Output<PushPull>>,
131+
);
132+
133+
struct Scanner {
134+
kso: Kso,
135+
mux: Mux,
136+
adc: (Adc, Pin<Gpio28, Input<PullUp>>),
137+
}
138+
impl Scanner {
139+
fn drive_col(&mut self, col: usize, state: PinState) {
140+
match col {
141+
0 => self.kso.0.set_state(state).unwrap(),
142+
1 => self.kso.1.set_state(state).unwrap(),
143+
2 => self.kso.2.set_state(state).unwrap(),
144+
3 => self.kso.3.set_state(state).unwrap(),
145+
4 => self.kso.4.set_state(state).unwrap(),
146+
5 => self.kso.5.set_state(state).unwrap(),
147+
6 => self.kso.6.set_state(state).unwrap(),
148+
7 => self.kso.7.set_state(state).unwrap(),
149+
8 => self.kso.8.set_state(state).unwrap(),
150+
9 => self.kso.9.set_state(state).unwrap(),
151+
10 => self.kso.10.set_state(state).unwrap(),
152+
11 => self.kso.11.set_state(state).unwrap(),
153+
12 => self.kso.12.set_state(state).unwrap(),
154+
13 => self.kso.13.set_state(state).unwrap(),
155+
14 => self.kso.14.set_state(state).unwrap(),
156+
15 => self.kso.15.set_state(state).unwrap(),
157+
_ => unreachable!(),
158+
}
159+
}
160+
fn read_voltage(&mut self) -> usize {
161+
let _adc_read: u16 = self.adc.0.read(&mut self.adc.1).unwrap();
162+
33000
163+
}
164+
pub fn measure_key(&mut self, row: usize, col: usize) -> (usize, usize) {
165+
for col in 0..MATRIX_COLS {
166+
self.drive_col(col, PinState::High);
167+
}
168+
self.drive_col(col, PinState::Low);
169+
170+
self.mux.select_row(row);
171+
cortex_m::asm::delay(2000);
172+
let adc_read: u16 = self.adc.0.read(&mut self.adc.1).unwrap();
173+
174+
self.drive_col(col, PinState::High);
175+
176+
let voltage_10k = ((adc_read as usize) * 3300) / 4096;
177+
(voltage_10k / 1_000, voltage_10k % 1_000)
178+
}
179+
pub fn scan(&mut self) -> Matrix {
180+
let mut matrix = Matrix::default();
181+
182+
// Initialize all cols as high
183+
for col in 0..MATRIX_COLS {
184+
self.drive_col(col, PinState::High);
185+
}
186+
187+
for col in 0..MATRIX_COLS {
188+
self.drive_col(col, PinState::Low);
189+
190+
for row in 0..MATRIX_ROWS {
191+
self.mux.select_row(row);
192+
193+
if self.read_voltage() < ADC_THRESHOLD {
194+
matrix.set(row, col, true);
195+
}
196+
}
197+
198+
self.drive_col(col, PinState::High);
199+
}
200+
201+
matrix.set(3, 4, true);
202+
matrix.set(0, 4, true);
203+
matrix
204+
}
205+
}
206+
47207
#[entry]
48208
fn main() -> ! {
49209
let mut pac = pac::Peripherals::take().unwrap();
@@ -121,7 +281,7 @@ fn main() -> ! {
121281

122282
// Disable bootloader circuitry
123283
let mut boot_done = pins.boot_done.into_push_pull_output();
124-
boot_done.set_high().unwrap();
284+
boot_done.set_low().unwrap();
125285

126286
// pins.gp26 // SDA
127287
// pins.gp27 // SCL
@@ -133,28 +293,28 @@ fn main() -> ! {
133293
// Pull low to enable mux
134294
let mut mux_enable = pins.mux_enable.into_push_pull_output();
135295
mux_enable.set_low().unwrap();
136-
let mut _mux_a = pins.mux_a.into_push_pull_output();
137-
let mut _mux_b = pins.mux_b.into_push_pull_output();
138-
let mut _mux_c = pins.mux_c.into_push_pull_output();
296+
let mux_a = pins.mux_a.into_push_pull_output();
297+
let mux_b = pins.mux_b.into_push_pull_output();
298+
let mux_c = pins.mux_c.into_push_pull_output();
139299

140300
// KS0 - KSO7 for Keyboard and Numpad
141-
let mut _kso0 = pins.kso0.into_push_pull_output();
142-
let mut _kso1 = pins.kso1.into_push_pull_output();
143-
let mut _kso2 = pins.kso2.into_push_pull_output();
144-
let mut _kso3 = pins.kso3.into_push_pull_output();
145-
let mut _kso4 = pins.kso4.into_push_pull_output();
146-
let mut _kso5 = pins.kso5.into_push_pull_output();
147-
let mut _kso6 = pins.kso6.into_push_pull_output();
148-
let mut _kso7 = pins.kso7.into_push_pull_output();
301+
let kso0 = pins.kso0.into_push_pull_output();
302+
let kso1 = pins.kso1.into_push_pull_output();
303+
let kso2 = pins.kso2.into_push_pull_output();
304+
let kso3 = pins.kso3.into_push_pull_output();
305+
let kso4 = pins.kso4.into_push_pull_output();
306+
let kso5 = pins.kso5.into_push_pull_output();
307+
let kso6 = pins.kso6.into_push_pull_output();
308+
let kso7 = pins.kso7.into_push_pull_output();
149309
// KS08 - KS015 for Keyboard only
150-
let mut _kso8 = pins.kso8.into_push_pull_output();
151-
let mut _kso9 = pins.kso9.into_push_pull_output();
152-
let mut _kso10 = pins.kso10.into_push_pull_output();
153-
let mut _kso11 = pins.kso11.into_push_pull_output();
154-
let mut _kso12 = pins.kso12.into_push_pull_output();
155-
let mut _kso13 = pins.kso13.into_push_pull_output();
156-
let mut _kso14 = pins.kso14.into_push_pull_output();
157-
let mut _kso15 = pins.kso15.into_push_pull_output();
310+
let kso8 = pins.kso8.into_push_pull_output();
311+
let kso9 = pins.kso9.into_push_pull_output();
312+
let kso10 = pins.kso10.into_push_pull_output();
313+
let kso11 = pins.kso11.into_push_pull_output();
314+
let kso12 = pins.kso12.into_push_pull_output();
315+
let kso13 = pins.kso13.into_push_pull_output();
316+
let kso14 = pins.kso14.into_push_pull_output();
317+
let kso15 = pins.kso15.into_push_pull_output();
158318
// Set unused pins to input to avoid interfering. They're hooked up to rows 5 and 6
159319
let _ = pins.ksi5_reserved.into_floating_input();
160320
let _ = pins.ksi6_reserved.into_floating_input();
@@ -191,6 +351,22 @@ fn main() -> ! {
191351
let mut animation_timer = timer.get_counter().ticks();
192352
caps_led.set_high().unwrap();
193353

354+
let adc = Adc::new(pac.ADC, &mut pac.RESETS);
355+
let adc_x = pins.analog_in.into_pull_up_input();
356+
357+
let mut scanner = Scanner {
358+
kso: (
359+
kso0, kso1, kso2, kso3, kso4, kso5, kso6, kso7, kso8, kso9, kso10, kso11, kso12, kso13,
360+
kso14, kso15,
361+
),
362+
mux: Mux {
363+
a: mux_a,
364+
b: mux_b,
365+
c: mux_c,
366+
},
367+
adc: (adc, adc_x),
368+
};
369+
194370
let mut usb_initialized;
195371
let mut usb_suspended = false;
196372
loop {
@@ -214,6 +390,23 @@ fn main() -> ! {
214390
animation_timer = timer.get_counter().ticks();
215391
}
216392

393+
if timer.get_counter().ticks() > animation_timer + 500_000 {
394+
let left = scanner.measure_key(6, 11);
395+
let up = scanner.measure_key(1, 13);
396+
let down = scanner.measure_key(1, 8);
397+
let right = scanner.measure_key(2, 15);
398+
let mut text: String<64> = String::new();
399+
write!(
400+
&mut text,
401+
"L:{}.{:0>4}V, R:{}.{:0>4}V, U:{}.{:0>4}V, D:{}.{:0>4}V\r\n",
402+
left.0, left.1, right.0, right.1, up.0, up.1, down.0, down.1
403+
)
404+
.unwrap();
405+
let _ = serial.write(text.as_bytes());
406+
407+
animation_timer = timer.get_counter().ticks();
408+
}
409+
217410
// Check for new data
218411
if usb_dev.poll(&mut [&mut serial]) {
219412
match usb_dev.state() {
@@ -239,6 +432,9 @@ fn main() -> ! {
239432
let _ = usb_initialized;
240433
let _ = usb_suspended;
241434

435+
let kb = Matrix::default();
436+
let kb = scanner.scan();
437+
242438
let mut buf = [0u8; 64];
243439
match serial.read(&mut buf) {
244440
Err(_e) => {
@@ -247,15 +443,20 @@ fn main() -> ! {
247443
Ok(0) => {
248444
// Do nothing
249445
}
250-
Ok(count) => {
251-
let mut text: String<64> = String::new();
252-
write!(
253-
&mut text,
254-
"Hello World: Usb Suspended: {}. C: {}\r\n",
255-
usb_suspended, count
256-
)
257-
.unwrap();
258-
let _ = serial.write(text.as_bytes());
446+
Ok(_count) => {
447+
match buf[0] {
448+
b'r' => rp2040_hal::rom_data::reset_to_usb_boot(0, 0),
449+
_ => (),
450+
}
451+
//let mut text: String<64> = String::new();
452+
//write!(&mut text, " 01234567\r\n").unwrap();
453+
//let _ = serial.write(text.as_bytes());
454+
455+
//for col in 0..MATRIX_COLS {
456+
// let mut text: String<64> = String::new();
457+
// write!(&mut text, "{:2}: {}\r\n", col, kb.0[col]).unwrap();
458+
// let _ = serial.write(text.as_bytes());
459+
//}
259460
}
260461
}
261462
} else {

0 commit comments

Comments
 (0)