Skip to content

Commit

Permalink
fix(split): sync connection state periodically when using serial
Browse files Browse the repository at this point in the history
Signed-off-by: Haobo Gu <[email protected]>
  • Loading branch information
HaoboGu committed Dec 19, 2024
1 parent 3ec02de commit ce2a11d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 19 deletions.
2 changes: 1 addition & 1 deletion rmk/src/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
keyboard::{key_event_channel, KeyEvent},
CONNECTION_STATE,
};
use defmt::{error, info, Format};
use defmt::{info, Format};

Check warning on line 6 in rmk/src/matrix.rs

View workflow job for this annotation

GitHub Actions / binary-size

unused import: `error`
use embassy_time::{Instant, Timer};
use embedded_hal::digital::{InputPin, OutputPin};
#[cfg(feature = "async_matrix")]
Expand Down
26 changes: 11 additions & 15 deletions rmk/src/split/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub(crate) trait SplitWriter {
///
/// The `ROW` and `COL` are the number of rows and columns of the corresponding peripheral's keyboard matrix.
/// The `ROW_OFFSET` and `COL_OFFSET` are the offset of the peripheral's matrix in the keyboard's matrix.
/// TODO: Rename `PeripheralMatrixMonitor`
pub(crate) struct PeripheralMatrixMonitor<
const ROW: usize,
const COL: usize,
Expand Down Expand Up @@ -73,7 +74,7 @@ impl<
error!("SplitDriver write error: {}", e);
}
loop {
match select(self.receiver.read(), embassy_time::Timer::after_millis(200)).await {
match select(self.receiver.read(), embassy_time::Timer::after_millis(500)).await {
embassy_futures::select::Either::First(read_result) => match read_result {
Ok(received_message) => {
debug!("Received peripheral message: {}", received_message);
Expand Down Expand Up @@ -101,20 +102,15 @@ impl<
Err(e) => error!("Peripheral message read error: {:?}", e),
},
embassy_futures::select::Either::Second(_) => {
// Check ConnectionState every 200ms
// Current, only ConnectionState will be notified to peripheral
let current_conn_state = CONNECTION_STATE.load(Ordering::Acquire);
if conn_state != current_conn_state {
// ConnectionState changed, notify peripheral
conn_state = current_conn_state;
if let Err(e) = self
.receiver
.write(&SplitMessage::ConnectionState(conn_state))
.await
{
error!("SplitDriver write error: {}", e);
};
}
// Sync ConnectionState every 500ms
conn_state = CONNECTION_STATE.load(Ordering::Acquire);
if let Err(e) = self
.receiver
.write(&SplitMessage::ConnectionState(conn_state))
.await
{
error!("SplitDriver write error: {}", e);
};
}
}
}
Expand Down
20 changes: 17 additions & 3 deletions rmk/src/split/nrf/central.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ use embassy_sync::{
};
use nrf_softdevice::ble::{central, gatt_client, Address, AddressType};

use crate::split::{
driver::{PeripheralMatrixMonitor, SplitDriverError, SplitReader, SplitWriter},
SplitMessage, SPLIT_MESSAGE_MAX_SIZE,
use crate::{
split::{
driver::{PeripheralMatrixMonitor, SplitDriverError, SplitReader, SplitWriter},
SplitMessage, SPLIT_MESSAGE_MAX_SIZE,
},
CONNECTION_STATE,
};

/// Gatt client used in split central to receive split message from peripherals
Expand Down Expand Up @@ -46,6 +49,7 @@ pub(crate) async fn run_ble_peripheral_monitor<
let split_ble_driver = BleSplitCentralDriver {
receiver: receive_receiver,
sender: notify_sender,
connection_state: CONNECTION_STATE.load(Ordering::Acquire),
};

let peripheral =
Expand Down Expand Up @@ -169,6 +173,8 @@ pub(crate) struct BleSplitCentralDriver<'a> {
pub(crate) receiver: Receiver<'a, CriticalSectionRawMutex, SplitMessage, 8>,
// Sender that send message to peripherals
pub(crate) sender: Sender<'a, CriticalSectionRawMutex, SplitMessage, 8>,
// Cached connection state
connection_state: bool,
}

impl<'a> SplitReader for BleSplitCentralDriver<'a> {
Expand All @@ -179,6 +185,14 @@ impl<'a> SplitReader for BleSplitCentralDriver<'a> {

impl SplitWriter for BleSplitCentralDriver<'_> {
async fn write(&mut self, message: &SplitMessage) -> Result<usize, SplitDriverError> {
if let SplitMessage::ConnectionState(state) = message {
// Check if the connection state is changed
if self.connection_state == *state {
return Ok(SPLIT_MESSAGE_MAX_SIZE);
}
// ConnectionState changed, update cached state and notify peripheral
self.connection_state = *state;
}
self.sender.send(message.clone()).await;
Ok(SPLIT_MESSAGE_MAX_SIZE)
}
Expand Down
3 changes: 3 additions & 0 deletions rmk/src/split/serial/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::sync::atomic::Ordering;

Check warning on line 1 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split

unused import: `core::sync::atomic::Ordering`

Check warning on line 1 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split

unused import: `core::sync::atomic::Ordering`

Check warning on line 1 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split_with_config

unused import: `core::sync::atomic::Ordering`

Check warning on line 1 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split_with_config

unused import: `core::sync::atomic::Ordering`

use defmt::{error, info};
use embedded_io_async::{Read, Write};

Expand All @@ -8,6 +10,7 @@ use crate::{
peripheral::SplitPeripheral,
SplitMessage, SPLIT_MESSAGE_MAX_SIZE,
},
CONNECTION_STATE,

Check warning on line 13 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split

unused import: `CONNECTION_STATE`

Check warning on line 13 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split

unused import: `CONNECTION_STATE`

Check warning on line 13 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split_with_config

unused import: `CONNECTION_STATE`

Check warning on line 13 in rmk/src/split/serial/mod.rs

View workflow job for this annotation

GitHub Actions / build_rp2040_split_with_config

unused import: `CONNECTION_STATE`
};

use super::driver::SplitDriverError;
Expand Down

0 comments on commit ce2a11d

Please sign in to comment.