1#![no_main]
2#![no_std]
3#![deny(warnings)]
4#![warn(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)]
5#![feature(
6 const_convert,
7 const_trait_impl,
8 const_cmp,
9 const_index,
10 const_option_ops,
11 const_result_trait_fn,
12 optimize_attribute,
13 likely_unlikely
14)]
15#![expect(
16 clippy::blanket_clippy_restriction_lints,
17 clippy::future_not_send,
18 clippy::implicit_return,
19 clippy::separated_literal_suffix,
20 clippy::single_call_fn,
21 clippy::self_named_module_files,
22 clippy::pub_with_shorthand,
23 clippy::pub_use,
24 reason = "Implementation specific ignored lints"
25)]
26mod backlight;
28mod eeprom;
29mod flash_wrapper_async;
31mod keymap;
33mod matrix;
35mod vial;
37
38use crate::{
39 backlight::{init::backlight_runner, led_processor::LedIndicatorProcessor},
40 eeprom::Ft24c64,
41 flash_wrapper_async::Flash16K,
42 keymap::{COL, ROW},
43 matrix::{
44 analog_matrix::{AdcPart, AnalogHallMatrix, HallCfg},
45 encoder_switch,
46 hc164_cols::Hc164Cols,
47 layer_toggle::{LayerToggle, MatrixPos},
48 },
49 vial::VIAL_SERIAL,
50};
51use embassy_executor::{Spawner, main};
52use embassy_stm32::{
53 Config,
54 adc::{Adc, AdcChannel as _, AnyAdcChannel, SampleTime},
55 bind_interrupts,
56 dma,
57 exti::{self, ExtiInput},
58 flash,
59 flash::Flash,
60 gpio::{Flex, Input, Level, Output, Pull, Speed},
61 i2c,
62 i2c::I2c,
63 init,
64 interrupt::typelevel,
65 pac,
66 peripherals::{self, ADC1},
67 rcc::{
68 AHBPrescaler,
69 APBPrescaler,
70 Hse,
71 HseMode,
72 Pll,
73 PllMul,
74 PllPDiv,
75 PllPreDiv,
76 PllQDiv,
77 PllSource,
78 Sysclk,
79 mux::Clk48sel,
80 },
81 spi::{self},
82 time::Hertz,
83 usb::{self, Driver},
84};
85use encoder_switch::EncoderSwitch;
86use pac::SYSCFG;
87use rmk::{
88 KeymapData,
89 config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig},
90 futures::future::join4,
91 initialize_keymap_and_storage,
92 input_device::{Runnable as _, rotary_encoder::RotaryEncoder},
93 keyboard::Keyboard,
94 run_all,
95 run_rmk,
96};
97use static_cell::ConstStaticCell;
98use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID};
99
100bind_interrupts!(struct Irqs {
101 DMA2_STREAM0 => dma::InterruptHandler<peripherals::DMA2_CH0>;
102 DMA2_STREAM3 => dma::InterruptHandler<peripherals::DMA2_CH3>;
103 DMA2_STREAM2 => dma::InterruptHandler<peripherals::DMA2_CH2>;
104 DMA1_STREAM4 => dma::InterruptHandler<peripherals::DMA1_CH4>;
105 DMA1_STREAM2 => dma::InterruptHandler<peripherals::DMA1_CH2>;
106 EXTI3 => exti::InterruptHandler<typelevel::EXTI3>;
107 EXTI15_10 => exti::InterruptHandler<typelevel::EXTI15_10>;
108 FLASH => flash::InterruptHandler;
109 OTG_FS => usb::InterruptHandler<peripherals::USB_OTG_FS>;
110 I2C3_EV => i2c::EventInterruptHandler<peripherals::I2C3>;
111 I2C3_ER => i2c::ErrorInterruptHandler<peripherals::I2C3>;
112});
113
114#[main]
116async fn main(spawner: Spawner) {
117 let _: Spawner = spawner;
119 let mut peripheral = init({
121 let mut config = Config::default();
122 config.rcc.hse = Some(Hse { freq: Hertz(16_000_000), mode: HseMode::Oscillator });
123 config.rcc.hsi = false;
124 config.rcc.pll_src = PllSource::Hse;
125 config.rcc.pll = Some(Pll {
126 prediv: PllPreDiv::Div8, mul: PllMul::Mul168, divp: Some(PllPDiv::Div4), divq: Some(PllQDiv::Div7), divr: None,
131 });
132 config.rcc.ahb_pre = AHBPrescaler::Div1; config.rcc.apb1_pre = APBPrescaler::Div2; config.rcc.apb2_pre = APBPrescaler::Div1; config.rcc.sys = Sysclk::Pll1P;
136 config.rcc.mux.clk48sel = Clk48sel::Pll1Q;
137 config
138 });
139
140 static EP_OUT_BUFFER: ConstStaticCell<[u8; 1024]> = ConstStaticCell::new([0; 1024]);
142 let usb_config = {
143 let mut usb_config = usb::Config::default();
144 usb_config.vbus_detection = false;
145 usb_config
146 };
147 let driver = Driver::new_fs(
148 peripheral.USB_OTG_FS,
149 Irqs,
150 peripheral.PA12,
151 peripheral.PA11,
152 &mut EP_OUT_BUFFER.take()[..],
153 usb_config,
154 );
155
156 let storage_config = StorageConfig {
158 start_addr: 0x4000,
160 num_sectors: 2,
161 ..Default::default()
162 };
163 let flash = Flash16K(Flash::new(peripheral.FLASH, Irqs));
164
165 let rmk_config = RmkConfig {
167 vial_config: VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(0, 0), (4, 20)]),
168 device_config: DeviceConfig {
169 manufacturer: "Keychron",
170 product_name: "Q6 HE",
171 vid: 0x3434,
172 pid: 0x0B60,
173 serial_number: VIAL_SERIAL,
174 },
175 ..Default::default()
176 };
177 let _analog_matrix_power = Output::new(peripheral.PC13, Level::High, Speed::Low);
181 let _analog_matrix_wakeup = Input::new(peripheral.PC5, Pull::Down);
184
185 let ds = Output::new(peripheral.PB3, Level::Low, Speed::VeryHigh);
187 let cp = Output::new(peripheral.PB5, Level::Low, Speed::VeryHigh);
188 let mr = Output::new(peripheral.PD2, Level::Low, Speed::VeryHigh);
189 let cols = Hc164Cols::new(ds, cp, mr, HallCfg::default().shifter_delay_cycles);
190
191 let adc: Adc<'_, ADC1> = Adc::new(peripheral.ADC1);
193 SYSCFG.pmc().modify(|w| w.set_adc1dc2(true));
196 let row_channels: [AnyAdcChannel<'_, ADC1>; ROW] = [
197 peripheral.PC0.degrade_adc(),
198 peripheral.PC1.degrade_adc(),
199 peripheral.PC2.degrade_adc(),
200 peripheral.PC3.degrade_adc(),
201 peripheral.PA0.degrade_adc(),
202 peripheral.PA1.degrade_adc(),
203 ];
204
205 let i2c_config = {
206 let mut cfg = i2c::Config::default();
207 cfg.frequency = Hertz(850_000);
208 cfg
209 };
210 let i2c3 = I2c::new(
211 peripheral.I2C3,
212 peripheral.PA8, peripheral.PC9, peripheral.DMA1_CH4, peripheral.DMA1_CH2, Irqs,
217 i2c_config,
218 );
219 let eeprom_wp = Flex::new(peripheral.PB10);
220 let eeprom = Ft24c64::new(i2c3, eeprom_wp);
221 let adc_part = AdcPart::new(adc, row_channels, peripheral.DMA2_CH0, SampleTime::Cycles56);
222 let mut matrix = AnalogHallMatrix::<_, _, _, _, ROW, COL>::new(adc_part, Irqs, cols, HallCfg::default(), eeprom);
223 let pin_a = ExtiInput::new(peripheral.PB14, peripheral.EXTI14, Pull::None, Irqs);
225 let pin_b = ExtiInput::new(peripheral.PB15, peripheral.EXTI15, Pull::None, Irqs);
226 let mut encoder = RotaryEncoder::with_resolution(pin_a, pin_b, 4, true, 0);
227 let enc_sw_pin = ExtiInput::new(peripheral.PA3, peripheral.EXTI3, Pull::Up, Irqs);
228 let mut enc_switch = EncoderSwitch::new(enc_sw_pin, 0, 13);
229
230 let layer_toggle_pin = ExtiInput::new(peripheral.PB12, peripheral.EXTI12, Pull::Up, Irqs);
232 let mut layer_toggle = LayerToggle::new_with_default_debounce(
233 layer_toggle_pin,
234 MatrixPos { row: 5, col: 7 }, MatrixPos { row: 5, col: 8 }, );
237
238 let mut keymap_data = KeymapData::new_with_encoder(keymap::get_default_keymap(), keymap::get_default_encoder_map());
240 let mut behavior_config = BehaviorConfig::default();
241 let key_config = PositionalConfig::default();
242 let (keymap, mut storage) =
243 initialize_keymap_and_storage(&mut keymap_data, flash, &storage_config, &mut behavior_config, &key_config)
244 .await;
245
246 let mut keyboard = Keyboard::new(&keymap);
248
249 let spi_config = {
251 let mut spi_config = spi::Config::default();
252 spi_config.frequency = Hertz(3_500_000);
253 spi_config.mode = spi::MODE_0;
254 spi_config
255 };
256 let spi_backlight = spi::Spi::new(
257 peripheral.SPI1, peripheral.PA5, peripheral.PA7, peripheral.PA6, peripheral.DMA2_CH3, peripheral.DMA2_CH2, Irqs,
264 spi_config,
265 );
266 let cs0 = Output::new(peripheral.PB8, Level::High, Speed::VeryHigh);
267 let cs1 = Output::new(peripheral.PB9, Level::High, Speed::VeryHigh);
268 let sdb = Output::new(peripheral.PB7, Level::Low, Speed::VeryHigh);
269 let mut led_indicator = LedIndicatorProcessor::new();
270
271 join4(
273 run_all!(matrix, encoder, enc_switch, layer_toggle, led_indicator),
274 keyboard.run(),
275 run_rmk(&keymap, driver, &mut storage, rmk_config),
276 backlight_runner(spi_backlight, cs0, cs1, sdb),
277 )
278 .await;
279}