forked from HaoboGu/rmk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.rs
More file actions
180 lines (155 loc) · 6.01 KB
/
Copy pathmain.rs
File metadata and controls
180 lines (155 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#![no_std]
#![no_main]
#[macro_use]
mod keymap;
#[macro_use]
mod macros;
mod vial;
use bt_hci::controller::ExternalController;
use cyw43::aligned_bytes;
use cyw43_pio::PioSpi;
use defmt_rtt as _;
use embassy_executor::Spawner;
use embassy_rp::bind_interrupts;
use embassy_rp::clocks::RoscRng;
use embassy_rp::flash::{Async, Flash};
use embassy_rp::gpio::{Input, Level, Output};
use embassy_rp::peripherals::{DMA_CH0, DMA_CH1, PIO0, USB};
use embassy_rp::pio::{self, Pio};
use embassy_rp::usb::{self, Driver};
use embassy_time as _;
use keymap::{COL, ROW};
use panic_probe as _;
use rand::SeedableRng;
use rmk::ble::{BleTransport, build_ble_stack};
use rmk::config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig};
use rmk::debounce::default_debouncer::DefaultDebouncer;
use rmk::host::HostService;
use rmk::keyboard::Keyboard;
use rmk::matrix::Matrix;
use rmk::processor::builtin::wpm::WpmProcessor;
use rmk::usb::UsbTransport;
use rmk::watchdog::Rp2040Watchdog;
use rmk::{HostResources, KeymapData, initialize_keymap_and_storage, run_all};
use static_cell::StaticCell;
use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID};
bind_interrupts!(struct Irqs {
USBCTRL_IRQ => usb::InterruptHandler<USB>;
PIO0_IRQ_0 => pio::InterruptHandler<PIO0>;
DMA_IRQ_0 => embassy_rp::dma::InterruptHandler<DMA_CH0>, embassy_rp::dma::InterruptHandler<DMA_CH1>;
});
#[embassy_executor::task]
async fn cyw43_task(runner: cyw43::Runner<'static, cyw43::SpiBus<Output<'static>, PioSpi<'static, PIO0, 0>>>) -> ! {
runner.run().await
}
const FLASH_SIZE: usize = 2 * 1024 * 1024;
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let p = embassy_rp::init(Default::default());
#[cfg(feature = "skip-cyw43-firmware")]
let (fw, clm, btfw, nvram) = {
static EMPTY: &cyw43::Aligned<cyw43::A4, [u8]> = &cyw43::Aligned([0u8; 0]);
(EMPTY, &[] as &[u8], EMPTY, EMPTY)
};
#[cfg(not(feature = "skip-cyw43-firmware"))]
let (fw, clm, btfw, nvram) = {
// IMPORTANT
//
// Download and make sure these files from https://github.com/embassy-rs/embassy/tree/main/cyw43-firmware
// are available in `./examples/rp-pico-w`. (should be automatic)
//
// IMPORTANT
let fw = aligned_bytes!("../cyw43-firmware/43439A0.bin");
let clm = aligned_bytes!("../cyw43-firmware/43439A0_clm.bin");
let btfw = aligned_bytes!("../cyw43-firmware/43439A0_btfw.bin");
let nvram = aligned_bytes!("../cyw43-firmware/nvram_rp2040.bin");
(fw, clm, btfw, nvram)
};
let pwr = Output::new(p.PIN_23, Level::Low);
let cs = Output::new(p.PIN_25, Level::High);
let mut pio = Pio::new(p.PIO0, Irqs);
let spi = PioSpi::new(
&mut pio.common,
pio.sm0,
cyw43_pio::DEFAULT_CLOCK_DIVIDER,
pio.irq0,
cs,
p.PIN_24,
p.PIN_29,
embassy_rp::dma::Channel::new(p.DMA_CH0, Irqs),
);
static STATE: StaticCell<cyw43::State> = StaticCell::new();
let state = STATE.init(cyw43::State::new());
let (_net_device, bt_device, mut control, runner) =
cyw43::new_with_bluetooth(state, pwr, spi, fw, btfw, nvram).await;
spawner.spawn(cyw43_task(runner).unwrap());
control.init(clm).await;
let controller: ExternalController<_, 10> = ExternalController::new(bt_device);
// Create the usb driver, from the HAL
let driver = Driver::new(p.USB, Irqs);
// Pin config
let (row_pins, col_pins) =
config_matrix_pins_rp!(peripherals: p, input: [PIN_6, PIN_7, PIN_8, PIN_9], output: [PIN_19, PIN_20, PIN_21]);
// Use internal flash to emulate eeprom
// Both blocking and async flash are support, use different API
// let flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(p.FLASH);
let flash = Flash::<_, Async, FLASH_SIZE>::new(p.FLASH, p.DMA_CH1, Irqs);
let keyboard_device_config = DeviceConfig {
vid: 0x4c4c,
pid: 0x464c,
manufacturer: "Haobo",
product_name: "RMK PicoW",
serial_number: "vial:f64c2b3c:000001",
};
let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(0, 0), (1, 1)]);
let storage_config = StorageConfig {
start_addr: 0x100000, // Start from 1M
num_sectors: 32,
..Default::default()
};
let rmk_config = RmkConfig {
device_config: keyboard_device_config,
vial_config,
storage_config,
..Default::default()
};
// Initialize the storage and keymap
let mut keymap_data = KeymapData::new(keymap::get_default_keymap());
let mut behavior_config = BehaviorConfig::default();
let per_key_config = PositionalConfig::default();
let (keymap, mut storage) = initialize_keymap_and_storage(
&mut keymap_data,
flash,
&storage_config,
&mut behavior_config,
&per_key_config,
)
.await;
// Initialize the matrix + keyboard
let debouncer = DefaultDebouncer::new();
let mut matrix = Matrix::<_, _, _, ROW, COL, true>::new(row_pins, col_pins, debouncer);
let mut keyboard = Keyboard::new(&keymap);
let host_ctx = rmk::host::KeyboardContext::new(&keymap);
let mut host_service = HostService::new(&host_ctx, &rmk_config);
let ble_addr = [0x18, 0xe2, 0x21, 0x88, 0xc0, 0xc7];
let mut host_resources = HostResources::new();
let mut rosc_rng = RoscRng {};
let mut rng = rand_chacha::ChaCha12Rng::from_rng(&mut rosc_rng).unwrap();
let stack = build_ble_stack(controller, ble_addr, &mut rng, &mut host_resources).await;
let mut usb_transport = UsbTransport::new(driver, rmk_config.device_config);
let mut ble_transport = BleTransport::new(&stack, rmk_config).await;
let mut wpm_processor = WpmProcessor::new();
let mut watchdog_runner = Rp2040Watchdog::default_runner(embassy_rp::watchdog::Watchdog::new(p.WATCHDOG));
// Start
run_all!(
matrix,
storage,
usb_transport,
ble_transport,
wpm_processor,
keyboard,
host_service,
watchdog_runner
)
.await;
}