Skip to content

Commit

Permalink
add: basic oled peripheral
Browse files Browse the repository at this point in the history
  • Loading branch information
daystram committed Sep 5, 2024
1 parent 5eb1a9e commit 629b2d6
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 5 deletions.
63 changes: 63 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ usb-device = "0.3.2"
usbd-human-interface-device = "0.5.0"
smart-leds = "0.3.0"
ws2812-pio = "0.8.0"
ssd1306 = "0.8.4"

serde = { version = "1.0.204", default-features = false, features = ["derive"] }
postcard = { version = "1.0.8", features = ["alloc"] }
Expand Down
5 changes: 5 additions & 0 deletions src/keyboard/default/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const ENABLE_RGB_MATRIX: bool = true;
pub struct Keyboard {}

impl Configurator for Keyboard {
const NAME: &str = "default";

const KEY_MATRIX_ROW_COUNT: usize = 2;
const KEY_MATRIX_COL_COUNT: usize = 2;

Expand All @@ -34,9 +36,11 @@ impl Configurator for Keyboard {
mut slices: pwm::Slices,
mut pio0: pio::PIO<pac::PIO0>,
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
_i2c1: pac::I2C1,
_uart0: pac::UART0,
_resets: &mut pac::RESETS,
clock_freq: HertzU32,
_system_clock: &hal::clocks::SystemClock,
) -> (
Configuration,
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,
Expand Down Expand Up @@ -94,6 +98,7 @@ impl Configurator for Keyboard {
rotary_encoder,
heartbeat_led,
rgb_matrix,
oled_display: None,
},
None,
)
Expand Down
5 changes: 5 additions & 0 deletions src/keyboard/kb_dev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const ENABLE_RGB_MATRIX: bool = true;
pub struct Keyboard {}

impl Configurator for Keyboard {
const NAME: &str = "kb_dev";

const KEY_MATRIX_ROW_COUNT: usize = 5;
const KEY_MATRIX_COL_COUNT: usize = 15;

Expand All @@ -34,9 +36,11 @@ impl Configurator for Keyboard {
mut slices: pwm::Slices,
mut pio0: pio::PIO<pac::PIO0>,
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
_i2c1: pac::I2C1,
_uart0: pac::UART0,
_resets: &mut pac::RESETS,
clock_freq: HertzU32,
_system_clock: &hal::clocks::SystemClock,
) -> (
Configuration,
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,
Expand Down Expand Up @@ -110,6 +114,7 @@ impl Configurator for Keyboard {
rotary_encoder,
heartbeat_led,
rgb_matrix,
oled_display: None,
},
None,
)
Expand Down
20 changes: 20 additions & 0 deletions src/keyboard/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ use core::cell::RefCell;
use alloc::rc::Rc;
use hal::{fugit::HertzU32, gpio, pac, pio, pwm};
use rtic_sync::arbiter::Arbiter;
use ssd1306::prelude::I2CInterface;
use ws2812_pio::Ws2812Direct;

use crate::{
heartbeat::HeartbeatLED,
key::LayerIndex,
matrix::{BasicVerticalSwitchMatrix, SplitSwitchMatrix},
oled::OLEDDisplay,
processor::{events::rgb::RGBMatrix, mapper::InputMap},
remote::transport::uart::{UartReceiver, UartSender},
rotary::RotaryEncoder,
Expand Down Expand Up @@ -58,6 +60,20 @@ pub struct Configuration {
>,
>,
>,
// TODO: configurable OLED display pinout
pub oled_display: Option<
OLEDDisplay<
I2CInterface<
hal::I2C<
pac::I2C1,
(
gpio::Pin<gpio::bank0::Gpio26, gpio::FunctionI2c, gpio::PullUp>,
gpio::Pin<gpio::bank0::Gpio27, gpio::FunctionI2c, gpio::PullUp>,
),
>,
>,
>,
>,
}

impl Configuration {
Expand All @@ -67,6 +83,8 @@ impl Configuration {
}

pub trait Configurator {
const NAME: &str;

const LAYER_COUNT: usize = selected_keyboard::layout::LAYER_COUNT;
type Layer: LayerIndex = selected_keyboard::layout::Layer;

Expand All @@ -80,9 +98,11 @@ pub trait Configurator {
slices: pwm::Slices,
pio0: pio::PIO<pac::PIO0>,
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
i2c1: pac::I2C1,
uart0: pac::UART0,
resets: &mut pac::RESETS,
clock_freq: HertzU32,
system_clock: &hal::clocks::SystemClock,
) -> (
Configuration,
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,
Expand Down
31 changes: 28 additions & 3 deletions src/keyboard/quadax_rift/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,31 @@ use hal::{
gpio, pac, pio, pwm, uart,
};
use rtic_sync::arbiter::Arbiter;
use ssd1306::{prelude::*, size::DisplaySize128x32, I2CDisplayInterface, Ssd1306};
use ws2812_pio::Ws2812Direct;

use crate::{
heartbeat::HeartbeatLED,
keyboard::{Configuration, Configurator},
matrix::{BasicVerticalSwitchMatrix, SplitSwitchMatrix},
oled::OLEDDisplay,
processor::events::rgb::RGBMatrix,
remote::transport::uart::{UartReceiver, UartSender},
rotary::{Mode, RotaryEncoder},
split::SideDetector,
split::{self, SideDetector},
};

const ENABLE_HEARTBEAT_LED: bool = true;
const ENABLE_KEY_MATRIX: bool = true;
const ENABLE_ROTARY_ENCODER: bool = true;
const ENABLE_RGB_MATRIX: bool = true;
const ENABLE_OLED_SCREEN: bool = true;

pub struct Keyboard {}

impl Configurator for Keyboard {
const NAME: &str = "quadax-rift";

const KEY_MATRIX_ROW_COUNT: usize = 5;
const KEY_MATRIX_COL_COUNT: usize = 14;

Expand All @@ -38,13 +43,17 @@ impl Configurator for Keyboard {
mut slices: pwm::Slices,
mut pio0: pio::PIO<pac::PIO0>,
sm0: pio::UninitStateMachine<(pac::PIO0, pio::SM0)>,
i2c1: pac::I2C1,
uart0: pac::UART0,
resets: &mut pac::RESETS,
clock_freq: HertzU32,
system_clock: &hal::clocks::SystemClock,
) -> (
Configuration,
Option<(Arbiter<Rc<RefCell<UartSender>>>, UartReceiver)>,
) {
SideDetector::new(Box::new(pins.gpio2.into_pull_down_input())).detect();

#[rustfmt::skip]
let key_matrix_split = if ENABLE_KEY_MATRIX {
Some(SplitSwitchMatrix::new(BasicVerticalSwitchMatrix::new(
Expand Down Expand Up @@ -99,6 +108,23 @@ impl Configurator for Keyboard {
None
};

let oled_display = if ENABLE_OLED_SCREEN {
let sda_pin: gpio::Pin<_, gpio::FunctionI2C, _> = pins.gpio26.reconfigure();
let scl_pin: gpio::Pin<_, gpio::FunctionI2C, _> = pins.gpio27.reconfigure();
let i2c = hal::I2C::i2c1(i2c1, sda_pin, scl_pin, 400.kHz(), resets, system_clock);

Some(OLEDDisplay::new(Ssd1306::new(
I2CDisplayInterface::new(i2c),
DisplaySize128x32,
match split::get_self_side() {
split::Side::Left => DisplayRotation::Rotate180,
split::Side::Right => DisplayRotation::Rotate0,
},
)))
} else {
None
};

let mut uart_peripheral = uart::UartPeripheral::new(
uart0,
(pins.gpio0.into_function(), pins.gpio1.into_function()),
Expand All @@ -120,15 +146,14 @@ impl Configurator for Keyboard {
let uart_sender = Arbiter::new(Rc::new(RefCell::new(UartSender::new(uart_writer))));
let uart_receiver = UartReceiver::new(uart_reader);

SideDetector::new(Box::new(pins.gpio2.into_pull_down_input())).detect();

(
Configuration {
key_matrix: None,
key_matrix_split,
rotary_encoder,
heartbeat_led,
rgb_matrix,
oled_display,
},
Some((uart_sender, uart_receiver)),
)
Expand Down
20 changes: 18 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod heartbeat;
mod key;
mod keyboard;
mod matrix;
mod oled;
mod processor;
mod remote;
mod rotary;
Expand Down Expand Up @@ -45,7 +46,7 @@ mod kb {
[core::mem::MaybeUninit::uninit(); HEAP_SIZE_BYTES];

use alloc::{boxed::Box, rc::Rc, vec::Vec};
use core::cell::RefCell;
use core::{cell::RefCell, fmt::Write};
use hal::{
clocks::init_clocks_and_plls,
gpio, pac,
Expand Down Expand Up @@ -194,9 +195,11 @@ mod kb {
pwm::Slices::new(ctx.device.PWM, &mut ctx.device.RESETS),
pio0,
sm0,
ctx.device.I2C1,
ctx.device.UART0,
&mut ctx.device.RESETS,
clocks.peripheral_clock.freq(),
&clocks.system_clock,
);
assert!(
!config.is_split() || transport.is_some(),
Expand Down Expand Up @@ -273,9 +276,12 @@ mod kb {
frame_sender: Sender<'static, Box<dyn FrameIterator>, 1>,
frame_receiver: Receiver<'static, Box<dyn FrameIterator>, 1>,
seq_sender: Option<Receiver<'static, Sequence, { remote::REQUEST_SEQUENCE_QUEUE_SIZE }>>,
config: Configuration,
mut config: Configuration,
) {
defmt::info!("start_wait_usb()");
if let Some(ref mut display) = config.oled_display {
display.write_str("kb").unwrap();
}

// Start USB tasks
hid_usb_tick::spawn().ok();
Expand All @@ -297,6 +303,16 @@ mod kb {
split::get_self_side()
);

if let Some(ref mut display) = config.oled_display {
display.clear();
display
.write_fmt(format_args!(
"{}\n{}",
<Keyboard as Configurator>::NAME,
split::get_self_mode()
))
.unwrap();
}
match split::get_self_mode() {
split::Mode::Master => {
heartbeat::spawn(config.heartbeat_led, 500.millis()).ok();
Expand Down
Loading

0 comments on commit 629b2d6

Please sign in to comment.