Skip to content

Commit

Permalink
feat(ble): update nrf ble tasks
Browse files Browse the repository at this point in the history
Signed-off-by: Haobo Gu <[email protected]>
  • Loading branch information
HaoboGu committed May 28, 2024
1 parent fcb2a11 commit e60e816
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 36 deletions.
49 changes: 32 additions & 17 deletions rmk/src/ble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,26 @@ pub mod esp;
#[cfg(feature = "_nrf_ble")]
pub mod nrf;

use defmt::error;
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Receiver};
use embassy_time::Timer;
use embedded_hal::digital::{InputPin, OutputPin};
#[cfg(feature = "nrf52840_ble")]
pub use nrf::SOFTWARE_VBUS;

use crate::{hid::HidWriterWrapper, Keyboard};
use crate::{
hid::HidWriterWrapper, keyboard::{write_other_report_to_host, KeyboardReportMessage},
usb::descriptor::CompositeReportType,
};

/// BLE keyboard task, run the keyboard with the ble server
pub(crate) async fn keyboard_ble_task<
/// BLE communication task, send reports to host via BLE.
pub(crate) async fn ble_task<
'a,
W: HidWriterWrapper,
W2: HidWriterWrapper,
W3: HidWriterWrapper,
W4: HidWriterWrapper,
In: InputPin,
Out: OutputPin,
const ROW: usize,
const COL: usize,
const NUM_LAYER: usize,
>(
keyboard: &mut Keyboard<'a, In, Out, ROW, COL, NUM_LAYER>,
keyboard_report_receiver: &mut Receiver<'a, CriticalSectionRawMutex, KeyboardReportMessage, 8>,
ble_keyboard_writer: &mut W,
ble_media_writer: &mut W2,
ble_system_control_writer: &mut W3,
Expand All @@ -35,12 +34,28 @@ pub(crate) async fn keyboard_ble_task<
// Wait 1 seconds, ensure that gatt server has been started
Timer::after_secs(1).await;
loop {
let _ = keyboard.scan_matrix().await;
keyboard.send_keyboard_report(ble_keyboard_writer).await;
keyboard.send_media_report(ble_media_writer).await;
keyboard
.send_system_control_report(ble_system_control_writer)
.await;
keyboard.send_mouse_report(ble_mouse_writer).await;
match keyboard_report_receiver.receive().await {
KeyboardReportMessage::KeyboardReport(report) => {
match ble_keyboard_writer.write_serialize(&report).await {
Ok(()) => {}
Err(e) => error!("Send keyboard report error: {}", e),
};
}
KeyboardReportMessage::CompositeReport(report, report_type) => {
match report_type {
CompositeReportType::Media => {
write_other_report_to_host(report, report_type, ble_media_writer).await
}
CompositeReportType::Mouse => {
write_other_report_to_host(report, report_type, ble_mouse_writer).await
}
CompositeReportType::System => {
write_other_report_to_host(report, report_type, ble_system_control_writer)
.await
}
CompositeReportType::None => (),
};
}
}
}
}
51 changes: 32 additions & 19 deletions rmk/src/ble/nrf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ pub(crate) mod spec;
// TODO: Conditional imports should be compatible with more nRF chip models
use self::server::BleServer;
use crate::{
ble::{
keyboard_ble_task,
nrf::{
advertise::{create_advertisement_data, SCAN_DATA},
bonder::{BondInfo, Bonder},
server::BleHidWriter,
},
},
keyboard::Keyboard,
ble::{ble_task, nrf::{
advertise::{create_advertisement_data, SCAN_DATA},
bonder::{BondInfo, Bonder},
server::BleHidWriter,
}},
keyboard::{keyboard_task, Keyboard, KeyboardReportMessage},
storage::{get_bond_info_key, Storage, StorageData},
KeyAction, KeyMap, RmkConfig,
};
Expand All @@ -33,18 +30,22 @@ use core::{cell::RefCell, mem};
use defmt::*;
use embassy_executor::Spawner;
#[cfg(not(feature = "nrf52832_ble"))]
use embassy_futures::select::{select, Either};
use embassy_futures::select::{select4, Either4};
use embassy_futures::select::Either;
use embassy_futures::select::{select, select4, Either4};
#[cfg(not(feature = "nrf52832_ble"))]
use embassy_nrf::usb::vbus_detect::SoftwareVbusDetect;
use embassy_sync::{
blocking_mutex::raw::CriticalSectionRawMutex,
channel::{Channel, Receiver, Sender},
};
use embassy_time::Timer;
#[cfg(not(feature = "nrf52832_ble"))]
use embassy_usb::driver::Driver;
use embedded_hal::digital::{InputPin, OutputPin};
use embedded_storage_async::nor_flash::NorFlash as AsyncNorFlash;
use heapless::FnvIndexMap;
use nrf_softdevice::{
ble::{gatt_server, Connection, peripheral, security::SecurityHandler as _},
ble::{gatt_server, peripheral, security::SecurityHandler as _, Connection},
raw, Config, Flash, Softdevice,
};
#[cfg(not(feature = "nrf52832_ble"))]
Expand Down Expand Up @@ -205,6 +206,11 @@ pub async fn initialize_nrf_ble_keyboard_with_config_and_run<
LightService::from_config(keyboard_config.light_config),
);

static keyboard_channel: Channel<CriticalSectionRawMutex, KeyboardReportMessage, 8> =
Channel::new();
let mut keyboard_report_sender = keyboard_channel.sender();
let mut keyboard_report_receiver = keyboard_channel.receiver();

// Main loop
loop {
// Init BLE advertising data
Expand All @@ -228,6 +234,8 @@ pub async fn initialize_nrf_ble_keyboard_with_config_and_run<
&mut storage,
&mut light_service,
&mut vial_service,
&mut keyboard_report_receiver,
&mut keyboard_report_sender,
);
info!("Running USB keyboard!");
select(usb_fut, wait_for_usb_suspend()).await;
Expand All @@ -243,10 +251,6 @@ pub async fn initialize_nrf_ble_keyboard_with_config_and_run<
Either::First(re) => match re {
Ok(conn) => {
info!("Connected to BLE");
// let mut buf = [0_u8; 64];
// let l = get_sys_attrs(&conn, &mut buf).unwrap();
// set_sys_attrs(&conn, Some(&buf[0..l])).unwrap();
// bonder.save_sys_attrs(&conn);
bonder.load_sys_attrs(&conn);
let usb_configured = wait_for_usb_configured();
let usb_fut = usb_device.device.run();
Expand All @@ -257,6 +261,8 @@ pub async fn initialize_nrf_ble_keyboard_with_config_and_run<
&mut keyboard,
&mut storage,
&mut keyboard_config.ble_battery_config,
&mut keyboard_report_receiver,
&mut keyboard_report_sender,
),
select(usb_fut, usb_configured),
)
Expand Down Expand Up @@ -287,6 +293,8 @@ pub async fn initialize_nrf_ble_keyboard_with_config_and_run<
&mut keyboard,
&mut storage,
&mut keyboard_config.ble_battery_config,
&mut keyboard_report_receiver,
&mut keyboard_report_sender,
)
.await
}
Expand All @@ -303,6 +311,8 @@ pub async fn initialize_nrf_ble_keyboard_with_config_and_run<
&mut keyboard,
&mut storage,
&mut keyboard_config.ble_battery_config,
&mut keyboard_report_receiver,
&mut keyboard_report_sender,
)
.await
}
Expand All @@ -329,6 +339,8 @@ async fn run_ble_keyboard<
keyboard: &mut Keyboard<'a, In, Out, ROW, COL, NUM_LAYER>,
storage: &mut Storage<F>,
battery_config: &mut BleBatteryConfig<'b>,
keyboard_report_receiver: &mut Receiver<'a, CriticalSectionRawMutex, KeyboardReportMessage, 8>,
keyboard_report_sender: &mut Sender<'a, CriticalSectionRawMutex, KeyboardReportMessage, 8>,
) {
info!("Starting GATT server 200 ms later");
Timer::after_millis(200).await;
Expand All @@ -342,8 +354,9 @@ async fn run_ble_keyboard<

// Run the GATT server on the connection. This returns when the connection gets disconnected.
let ble_fut = gatt_server::run(&conn, ble_server, |_| {});
let keyboard_fut = keyboard_ble_task(
keyboard,
let keyboard_fut = keyboard_task(keyboard, keyboard_report_sender);
let ble_task = ble_task(
keyboard_report_receiver,
&mut ble_keyboard_writer,
&mut ble_media_writer,
&mut ble_system_control_writer,
Expand All @@ -352,7 +365,7 @@ async fn run_ble_keyboard<
let storage_fut = storage.run::<ROW, COL, NUM_LAYER>();

// Exit if anyone of three futures exits
match select4(ble_fut, keyboard_fut, battery_fut, storage_fut).await {
match select4(ble_fut, select(ble_task, keyboard_fut), battery_fut, storage_fut).await {
Either4::First(disconnected_error) => error!(
"BLE gatt_server run exited with error: {:?}",
disconnected_error
Expand Down

0 comments on commit e60e816

Please sign in to comment.