1#![no_main]
2#![no_std]
3#![deny(warnings)]
4#![warn(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)]
5#![feature(
6 const_trait_impl,
7 const_cmp,
8 const_option_ops,
9 const_index,
10 const_convert,
11 const_result_trait_fn,
12 optimize_attribute
13)]
14#![expect(
15 clippy::implicit_return,
16 clippy::blanket_clippy_restriction_lints,
17 clippy::separated_literal_suffix,
18 clippy::single_call_fn,
19 clippy::self_named_module_files,
20 clippy::future_not_send,
21 reason = "Implementation specific ignored lints"
22)]
23mod backlight;
25mod keymap;
27mod matrix;
29mod vial;
31
32use crate::{
33 backlight::{init::backlight_runner, lock_indicator::LedIndicatorProcessor},
34 matrix::{
35 layer_toggle::{LayerToggle, MatrixPos},
36 shiftreg_matrix::ShiftRegMatrixConfig,
37 },
38 vial::VIAL_SERIAL,
39};
40use embassy_executor::{Spawner, main};
41use embassy_stm32::{
42 Config,
43 bind_interrupts,
44 dma,
45 exti::{self, ExtiInput},
46 flash,
47 flash::Flash,
48 gpio::{Level, Output, Pull, Speed},
49 i2c,
50 init,
51 interrupt::typelevel,
52 peripherals::{self, USB},
53 rcc::{self},
54 time::Hertz,
55 usb::{self, Driver},
56};
57use embassy_time::Timer;
58use matrix::{hc595_cols::Hc595Cols, shiftreg_matrix::ShiftRegMatrix};
59use rmk::{
60 KeymapData,
61 config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig},
62 futures::future::join4,
63 initialize_keymap_and_storage,
64 input_device::{Runnable as _, rotary_encoder::RotaryEncoder},
65 keyboard::Keyboard,
66 run_all,
67 run_rmk,
68};
69use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID};
70
71bind_interrupts!(struct Irqs {
72 DMA1_CHANNEL6 => dma::InterruptHandler<peripherals::DMA1_CH6>;
73 DMA1_CHANNEL7 => dma::InterruptHandler<peripherals::DMA1_CH7>;
74 EXTI0 => exti::InterruptHandler<typelevel::EXTI0>;
75 EXTI3 => exti::InterruptHandler<typelevel::EXTI3>;
76 EXTI4 => exti::InterruptHandler<typelevel::EXTI4>;
77 EXTI9_5 => exti::InterruptHandler<typelevel::EXTI9_5>;
78 EXTI15_10 => exti::InterruptHandler<typelevel::EXTI15_10>;
79 FLASH => flash::InterruptHandler;
80 I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>;
81 I2C1_ER => i2c::ErrorInterruptHandler<peripherals::I2C1>;
82 USB => usb::InterruptHandler<USB>;
83});
84
85#[main]
86async fn main(spawner: Spawner) {
87 let _: Spawner = spawner;
89 let mut config = Config::default();
91
92 config.rcc.hsi = true;
93 config.rcc.hsi48 = Some(rcc::Hsi48Config {
94 sync_from_usb: true, });
96 config.rcc.pll = Some(rcc::Pll {
97 source: rcc::PllSource::Hsi,
98 prediv: rcc::PllPreDiv::Div1, mul: rcc::PllMul::Mul10, divp: None,
101 divq: None, divr: Some(rcc::PllRDiv::Div2), });
104
105 config.rcc.sys = rcc::Sysclk::Pll1R;
106 config.rcc.ahb_pre = rcc::AHBPrescaler::Div1; config.rcc.apb1_pre = rcc::APBPrescaler::Div1; config.rcc.apb2_pre = rcc::APBPrescaler::Div1; config.rcc.mux.clk48sel = rcc::mux::Clk48sel::Hsi48;
110
111 let peripheral = init(config);
113
114 let _led_driver_en = Output::new(peripheral.PC14, Level::High, Speed::Low);
116 Timer::after_millis(10).await;
117 let mut i2c_cfg_backlight = i2c::Config::default();
118 i2c_cfg_backlight.frequency = Hertz(400_000);
119 let i2c = i2c::I2c::new(
120 peripheral.I2C1,
121 peripheral.PB6, peripheral.PB7, peripheral.DMA1_CH6, peripheral.DMA1_CH7, Irqs,
126 i2c_cfg_backlight,
127 );
128
129 let driver = Driver::new(peripheral.USB, Irqs, peripheral.PA12, peripheral.PA11);
131
132 let flash = Flash::new(peripheral.FLASH, Irqs);
134
135 let rmk_config = RmkConfig {
137 vial_config: VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(5, 0), (3, 1)]),
138 device_config: DeviceConfig {
139 manufacturer: "Keychron",
140 product_name: "Q1 Pro",
141 vid: 0x3434,
142 pid: 0x0611,
143 serial_number: VIAL_SERIAL,
144 },
145 ..Default::default()
146 };
147
148 let data = Output::new(peripheral.PA7, Level::Low, Speed::VeryHigh); let clk = Output::new(peripheral.PA1, Level::Low, Speed::VeryHigh); let lat = Output::new(peripheral.PB0, Level::Low, Speed::VeryHigh); let cols = Hc595Cols::new(data, clk, lat, 1);
155
156 let rows = [
158 ExtiInput::new(peripheral.PB5, peripheral.EXTI5, Pull::Up, Irqs),
159 ExtiInput::new(peripheral.PB4, peripheral.EXTI4, Pull::Up, Irqs),
160 ExtiInput::new(peripheral.PB3, peripheral.EXTI3, Pull::Up, Irqs),
161 ExtiInput::new(peripheral.PA15, peripheral.EXTI15, Pull::Up, Irqs),
162 ExtiInput::new(peripheral.PA14, peripheral.EXTI14, Pull::Up, Irqs),
163 ExtiInput::new(peripheral.PA13, peripheral.EXTI13, Pull::Up, Irqs),
164 ];
165
166 let pin_a = ExtiInput::new(peripheral.PA10, peripheral.EXTI10, Pull::None, Irqs);
168 let pin_b = ExtiInput::new(peripheral.PA0, peripheral.EXTI0, Pull::None, Irqs);
169 let mut encoder = RotaryEncoder::with_resolution(pin_a, pin_b, 4, true, 0);
170
171 let layer_toggle_pin = ExtiInput::new(peripheral.PA8, peripheral.EXTI8, Pull::Up, Irqs);
173 let mut layer_toggle = LayerToggle::new_with_default_debounce(
174 layer_toggle_pin,
175 MatrixPos { row: 5, col: 7 }, MatrixPos { row: 5, col: 8 }, );
178
179 let mut keymap_data = KeymapData::new_with_encoder(keymap::get_default_keymap(), keymap::get_default_encoder_map());
181 let mut behavior_config = BehaviorConfig::default();
182 let storage_config = StorageConfig::default();
183 let key_config = PositionalConfig::default();
184 let (keymap, mut storage) =
185 initialize_keymap_and_storage(&mut keymap_data, flash, &storage_config, &mut behavior_config, &key_config)
186 .await;
187
188 let mut matrix = ShiftRegMatrix::<6, 16>::new(rows, cols, ShiftRegMatrixConfig::default());
190 let mut keyboard = Keyboard::new(&keymap);
191 let mut led_indicator = LedIndicatorProcessor::new();
192
193 join4(
195 run_all!(matrix, encoder, layer_toggle, led_indicator),
196 keyboard.run(),
197 run_rmk(&keymap, driver, &mut storage, rmk_config),
198 backlight_runner(i2c, 0x77, 0x74),
199 )
200 .await;
201}