Skip to content

Commit bb5d69a

Browse files
authored
Merge pull request #17 from daystram/feat/oled-basic
Add basic OLED display peripheral
2 parents 5eb1a9e + 629b2d6 commit bb5d69a

File tree

9 files changed

+187
-5
lines changed

9 files changed

+187
-5
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ usb-device = "0.3.2"
2424
usbd-human-interface-device = "0.5.0"
2525
smart-leds = "0.3.0"
2626
ws2812-pio = "0.8.0"
27+
ssd1306 = "0.8.4"
2728

2829
serde = { version = "1.0.204", default-features = false, features = ["derive"] }
2930
postcard = { version = "1.0.8", features = ["alloc"] }

src/keyboard/default/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const ENABLE_RGB_MATRIX: bool = true;
2424
pub struct Keyboard {}
2525

2626
impl Configurator for Keyboard {
27+
const NAME: &str = "default";
28+
2729
const KEY_MATRIX_ROW_COUNT: usize = 2;
2830
const KEY_MATRIX_COL_COUNT: usize = 2;
2931

@@ -34,9 +36,11 @@ impl Configurator for Keyboard {
3436
mut slices: pwm::Slices,
3537
mut pio0: pio::PIO<pac::PIO0>,
3638
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
39+
_i2c1: pac::I2C1,
3740
_uart0: pac::UART0,
3841
_resets: &mut pac::RESETS,
3942
clock_freq: HertzU32,
43+
_system_clock: &hal::clocks::SystemClock,
4044
) -> (
4145
Configuration,
4246
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,
@@ -94,6 +98,7 @@ impl Configurator for Keyboard {
9498
rotary_encoder,
9599
heartbeat_led,
96100
rgb_matrix,
101+
oled_display: None,
97102
},
98103
None,
99104
)

src/keyboard/kb_dev/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const ENABLE_RGB_MATRIX: bool = true;
2424
pub struct Keyboard {}
2525

2626
impl Configurator for Keyboard {
27+
const NAME: &str = "kb_dev";
28+
2729
const KEY_MATRIX_ROW_COUNT: usize = 5;
2830
const KEY_MATRIX_COL_COUNT: usize = 15;
2931

@@ -34,9 +36,11 @@ impl Configurator for Keyboard {
3436
mut slices: pwm::Slices,
3537
mut pio0: pio::PIO<pac::PIO0>,
3638
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
39+
_i2c1: pac::I2C1,
3740
_uart0: pac::UART0,
3841
_resets: &mut pac::RESETS,
3942
clock_freq: HertzU32,
43+
_system_clock: &hal::clocks::SystemClock,
4044
) -> (
4145
Configuration,
4246
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,
@@ -110,6 +114,7 @@ impl Configurator for Keyboard {
110114
rotary_encoder,
111115
heartbeat_led,
112116
rgb_matrix,
117+
oled_display: None,
113118
},
114119
None,
115120
)

src/keyboard/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ use core::cell::RefCell;
33
use alloc::rc::Rc;
44
use hal::{fugit::HertzU32, gpio, pac, pio, pwm};
55
use rtic_sync::arbiter::Arbiter;
6+
use ssd1306::prelude::I2CInterface;
67
use ws2812_pio::Ws2812Direct;
78

89
use crate::{
910
heartbeat::HeartbeatLED,
1011
key::LayerIndex,
1112
matrix::{BasicVerticalSwitchMatrix, SplitSwitchMatrix},
13+
oled::OLEDDisplay,
1214
processor::{events::rgb::RGBMatrix, mapper::InputMap},
1315
remote::transport::uart::{UartReceiver, UartSender},
1416
rotary::RotaryEncoder,
@@ -58,6 +60,20 @@ pub struct Configuration {
5860
>,
5961
>,
6062
>,
63+
// TODO: configurable OLED display pinout
64+
pub oled_display: Option<
65+
OLEDDisplay<
66+
I2CInterface<
67+
hal::I2C<
68+
pac::I2C1,
69+
(
70+
gpio::Pin<gpio::bank0::Gpio26, gpio::FunctionI2c, gpio::PullUp>,
71+
gpio::Pin<gpio::bank0::Gpio27, gpio::FunctionI2c, gpio::PullUp>,
72+
),
73+
>,
74+
>,
75+
>,
76+
>,
6177
}
6278

6379
impl Configuration {
@@ -67,6 +83,8 @@ impl Configuration {
6783
}
6884

6985
pub trait Configurator {
86+
const NAME: &str;
87+
7088
const LAYER_COUNT: usize = selected_keyboard::layout::LAYER_COUNT;
7189
type Layer: LayerIndex = selected_keyboard::layout::Layer;
7290

@@ -80,9 +98,11 @@ pub trait Configurator {
8098
slices: pwm::Slices,
8199
pio0: pio::PIO<pac::PIO0>,
82100
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
101+
i2c1: pac::I2C1,
83102
uart0: pac::UART0,
84103
resets: &mut pac::RESETS,
85104
clock_freq: HertzU32,
105+
system_clock: &hal::clocks::SystemClock,
86106
) -> (
87107
Configuration,
88108
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,

src/keyboard/quadax_rift/mod.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,31 @@ use hal::{
88
gpio, pac, pio, pwm, uart,
99
};
1010
use rtic_sync::arbiter::Arbiter;
11+
use ssd1306::{prelude::*, size::DisplaySize128x32, I2CDisplayInterface, Ssd1306};
1112
use ws2812_pio::Ws2812Direct;
1213

1314
use crate::{
1415
heartbeat::HeartbeatLED,
1516
keyboard::{Configuration, Configurator},
1617
matrix::{BasicVerticalSwitchMatrix, SplitSwitchMatrix},
18+
oled::OLEDDisplay,
1719
processor::events::rgb::RGBMatrix,
1820
remote::transport::uart::{UartReceiver, UartSender},
1921
rotary::{Mode, RotaryEncoder},
20-
split::SideDetector,
22+
split::{self, SideDetector},
2123
};
2224

2325
const ENABLE_HEARTBEAT_LED: bool = true;
2426
const ENABLE_KEY_MATRIX: bool = true;
2527
const ENABLE_ROTARY_ENCODER: bool = true;
2628
const ENABLE_RGB_MATRIX: bool = true;
29+
const ENABLE_OLED_SCREEN: bool = true;
2730

2831
pub struct Keyboard {}
2932

3033
impl Configurator for Keyboard {
34+
const NAME: &str = "quadax-rift";
35+
3136
const KEY_MATRIX_ROW_COUNT: usize = 5;
3237
const KEY_MATRIX_COL_COUNT: usize = 14;
3338

@@ -38,13 +43,17 @@ impl Configurator for Keyboard {
3843
mut slices: pwm::Slices,
3944
mut pio0: pio::PIO<pac::PIO0>,
4045
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
46+
i2c1: pac::I2C1,
4147
uart0: pac::UART0,
4248
resets: &mut pac::RESETS,
4349
clock_freq: HertzU32,
50+
system_clock: &hal::clocks::SystemClock,
4451
) -> (
4552
Configuration,
4653
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,
4754
) {
55+
SideDetector::new(Box::new(pins.gpio2.into_pull_down_input())).detect();
56+
4857
#[rustfmt::skip]
4958
let key_matrix_split = if ENABLE_KEY_MATRIX {
5059
Some(SplitSwitchMatrix::new(BasicVerticalSwitchMatrix::new(
@@ -99,6 +108,23 @@ impl Configurator for Keyboard {
99108
None
100109
};
101110

111+
let oled_display = if ENABLE_OLED_SCREEN {
112+
let sda_pin: gpio::Pin<_, gpio::FunctionI2C, _> = pins.gpio26.reconfigure();
113+
let scl_pin: gpio::Pin<_, gpio::FunctionI2C, _> = pins.gpio27.reconfigure();
114+
let i2c = hal::I2C::i2c1(i2c1, sda_pin, scl_pin, 400.kHz(), resets, system_clock);
115+
116+
Some(OLEDDisplay::new(Ssd1306::new(
117+
I2CDisplayInterface::new(i2c),
118+
DisplaySize128x32,
119+
match split::get_self_side() {
120+
split::Side::Left => DisplayRotation::Rotate180,
121+
split::Side::Right => DisplayRotation::Rotate0,
122+
},
123+
)))
124+
} else {
125+
None
126+
};
127+
102128
let mut uart_peripheral = uart::UartPeripheral::new(
103129
uart0,
104130
(pins.gpio0.into_function(), pins.gpio1.into_function()),
@@ -120,15 +146,14 @@ impl Configurator for Keyboard {
120146
let uart_sender = Arbiter::new(Rc::new(RefCell::new(UartSender::new(uart_writer))));
121147
let uart_receiver = UartReceiver::new(uart_reader);
122148

123-
SideDetector::new(Box::new(pins.gpio2.into_pull_down_input())).detect();
124-
125149
(
126150
Configuration {
127151
key_matrix: None,
128152
key_matrix_split,
129153
rotary_encoder,
130154
heartbeat_led,
131155
rgb_matrix,
156+
oled_display,
132157
},
133158
Some((uart_sender, uart_receiver)),
134159
)

src/main.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod heartbeat;
1616
mod key;
1717
mod keyboard;
1818
mod matrix;
19+
mod oled;
1920
mod processor;
2021
mod remote;
2122
mod rotary;
@@ -45,7 +46,7 @@ mod kb {
4546
[core::mem::MaybeUninit::uninit(); HEAP_SIZE_BYTES];
4647

4748
use alloc::{boxed::Box, rc::Rc, vec::Vec};
48-
use core::cell::RefCell;
49+
use core::{cell::RefCell, fmt::Write};
4950
use hal::{
5051
clocks::init_clocks_and_plls,
5152
gpio, pac,
@@ -194,9 +195,11 @@ mod kb {
194195
pwm::Slices::new(ctx.device.PWM, &mut ctx.device.RESETS),
195196
pio0,
196197
sm0,
198+
ctx.device.I2C1,
197199
ctx.device.UART0,
198200
&mut ctx.device.RESETS,
199201
clocks.peripheral_clock.freq(),
202+
&clocks.system_clock,
200203
);
201204
assert!(
202205
!config.is_split() || transport.is_some(),
@@ -273,9 +276,12 @@ mod kb {
273276
frame_sender: Sender<'static, Box<dyn FrameIterator>, 1>,
274277
frame_receiver: Receiver<'static, Box<dyn FrameIterator>, 1>,
275278
seq_sender: Option<Receiver<'static, Sequence, { remote::REQUEST_SEQUENCE_QUEUE_SIZE }>>,
276-
config: Configuration,
279+
mut config: Configuration,
277280
) {
278281
defmt::info!("start_wait_usb()");
282+
if let Some(ref mut display) = config.oled_display {
283+
display.write_str("kb").unwrap();
284+
}
279285

280286
// Start USB tasks
281287
hid_usb_tick::spawn().ok();
@@ -297,6 +303,16 @@ mod kb {
297303
split::get_self_side()
298304
);
299305

306+
if let Some(ref mut display) = config.oled_display {
307+
display.clear();
308+
display
309+
.write_fmt(format_args!(
310+
"{}\n{}",
311+
<Keyboard as Configurator>::NAME,
312+
split::get_self_mode()
313+
))
314+
.unwrap();
315+
}
300316
match split::get_self_mode() {
301317
split::Mode::Master => {
302318
heartbeat::spawn(config.heartbeat_led, 500.millis()).ok();

0 commit comments

Comments
 (0)