Skip to content

Commit

Permalink
add CentralDevice trait to replace MESSAGE_TO_PERIPHERALS channel
Browse files Browse the repository at this point in the history
  • Loading branch information
Univa committed Mar 30, 2024
1 parent 063ccad commit 28946c2
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 104 deletions.
2 changes: 1 addition & 1 deletion rumcake-macros/src/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ pub(crate) fn keyboard_main(
SplitSettings::Central(&args),
);
spawning.extend(quote! {
spawner.spawn(::rumcake::central_task!(split_central_driver)).unwrap();
spawner.spawn(::rumcake::central_task!(#kb_name, split_central_driver)).unwrap();
});
}
}
Expand Down
47 changes: 27 additions & 20 deletions rumcake/src/lighting/rgb_backlight_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ pub trait RGBBacklightMatrixDevice: BacklightMatrixDevice {
&RGB_BACKLIGHT_MATRIX_SAVE_SIGNAL
}

#[cfg(feature = "split-central")]
type CentralDevice: crate::split::central::private::MaybeCentralDevice =
crate::split::central::private::EmptyCentralDevice;

rgb_backlight_matrix_effect_items!();
}

Expand Down Expand Up @@ -703,26 +707,29 @@ where
// Send commands to be consumed by the split peripherals
#[cfg(feature = "split-central")]
{
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::ResetTime,
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::SetEffect(self.config.effect),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::SetValue(self.config.val),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::SetSpeed(self.config.speed),
))
.await;
use crate::split::central::private::MaybeCentralDevice;
if let Some(channel) = D::CentralDevice::get_message_to_peripheral_channel() {
channel
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::ResetTime,
))
.await;
channel
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::SetEffect(self.config.effect),
))
.await;
channel
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::SetValue(self.config.val),
))
.await;
channel
.send(crate::split::MessageToPeripheral::RGBBacklightMatrix(
RGBBacklightMatrixCommand::SetSpeed(self.config.speed),
))
.await;
}
}
}

Expand Down
47 changes: 27 additions & 20 deletions rumcake/src/lighting/simple_backlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ pub trait SimpleBacklightDevice {
&SIMPLE_BACKLIGHT_SAVE_SIGNAL
}

#[cfg(feature = "split-central")]
type CentralDevice: crate::split::central::private::MaybeCentralDevice =
crate::split::central::private::EmptyCentralDevice;

simple_backlight_effect_items!();
}

Expand Down Expand Up @@ -414,26 +418,29 @@ impl<D: SimpleBacklightDevice, R: SimpleBacklightDriver<D>> Animator
// Send commands to be consumed by the split peripherals
#[cfg(feature = "split-central")]
{
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::ResetTime,
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::SetEffect(self.config.effect),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::SetValue(self.config.val),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::SetSpeed(self.config.speed),
))
.await;
use crate::split::central::private::MaybeCentralDevice;
if let Some(channel) = D::CentralDevice::get_message_to_peripheral_channel() {
channel
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::ResetTime,
))
.await;
channel
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::SetEffect(self.config.effect),
))
.await;
channel
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::SetValue(self.config.val),
))
.await;
channel
.send(crate::split::MessageToPeripheral::SimpleBacklight(
SimpleBacklightCommand::SetSpeed(self.config.speed),
))
.await;
}
}
}

Expand Down
47 changes: 27 additions & 20 deletions rumcake/src/lighting/simple_backlight_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ pub trait SimpleBacklightMatrixDevice: BacklightMatrixDevice {
&SIMPLE_BACKLIGHT_MATRIX_SAVE_SIGNAL
}

#[cfg(feature = "split-central")]
type CentralDevice: crate::split::central::private::MaybeCentralDevice =
crate::split::central::private::EmptyCentralDevice;

simple_backlight_matrix_effect_items!();
}

Expand Down Expand Up @@ -846,26 +850,29 @@ where
// Send commands to be consumed by the split peripherals
#[cfg(feature = "split-central")]
{
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::ResetTime,
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::SetEffect(self.config.effect),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::SetValue(self.config.val),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::SetSpeed(self.config.speed),
))
.await;
use crate::split::central::private::MaybeCentralDevice;
if let Some(channel) = D::CentralDevice::get_message_to_peripheral_channel() {
channel
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::ResetTime,
))
.await;
channel
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::SetEffect(self.config.effect),
))
.await;
channel
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::SetValue(self.config.val),
))
.await;
channel
.send(crate::split::MessageToPeripheral::SimpleBacklightMatrix(
SimpleBacklightMatrixCommand::SetSpeed(self.config.speed),
))
.await;
}
}
}

Expand Down
67 changes: 37 additions & 30 deletions rumcake/src/lighting/underglow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ pub trait UnderglowDevice {
&UNDERGLOW_SAVE_SIGNAL
}

#[cfg(feature = "split-central")]
type CentralDevice: crate::split::central::private::MaybeCentralDevice =
crate::split::central::private::EmptyCentralDevice;

// Effect settings
underglow_effect_items!();
}
Expand Down Expand Up @@ -729,36 +733,39 @@ where
// Send commands to be consumed by the split peripherals
#[cfg(feature = "split-central")]
{
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::ResetTime,
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetEffect(self.config.effect),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetHue(self.config.hue),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetSaturation(self.config.sat),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetValue(self.config.val),
))
.await;
crate::split::central::MESSAGE_TO_PERIPHERALS
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetSpeed(self.config.speed),
))
.await;
use crate::split::central::private::MaybeCentralDevice;
if let Some(channel) = D::CentralDevice::get_message_to_peripheral_channel() {
channel
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::ResetTime,
))
.await;
channel
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetEffect(self.config.effect),
))
.await;
channel
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetHue(self.config.hue),
))
.await;
channel
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetSaturation(self.config.sat),
))
.await;
channel
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetValue(self.config.val),
))
.await;
channel
.send(crate::split::MessageToPeripheral::Underglow(
UnderglowCommand::SetSpeed(self.config.speed),
))
.await;
}
}
}

Expand Down
54 changes: 41 additions & 13 deletions rumcake/src/split/central.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,50 @@ use crate::split::MessageToCentral;
use super::drivers::CentralDeviceDriver;
use super::MessageToPeripheral;

/// Channel for sending messages to peripherals.
///
/// Channel messages should be consumed by the central task, so user-level code should
/// **not** attempt to receive messages from the channel, otherwise commands may not be processed
/// appropriately. You should only send to this channel.
pub static MESSAGE_TO_PERIPHERALS: Channel<RawMutex, MessageToPeripheral, 4> = Channel::new();
pub trait CentralDevice {
/// Get a reference to a channel that can receive messages from other tasks to be sent to
/// peripherals.
fn get_message_to_peripheral_channel() -> &'static Channel<RawMutex, MessageToPeripheral, 4> {
static MESSAGE_TO_PERIPHERALS: Channel<RawMutex, MessageToPeripheral, 4> = Channel::new();

&MESSAGE_TO_PERIPHERALS
}
}

pub(crate) mod private {
use embassy_sync::channel::Channel;

use crate::hw::platform::RawMutex;
use crate::split::MessageToPeripheral;

use super::CentralDevice;

pub struct EmptyCentralDevice;
impl MaybeCentralDevice for EmptyCentralDevice {}

pub trait MaybeCentralDevice {
#[inline(always)]
fn get_message_to_peripheral_channel(
) -> Option<&'static Channel<RawMutex, MessageToPeripheral, 4>> {
None
}
}

impl<T: CentralDevice> MaybeCentralDevice for T {
#[inline(always)]
fn get_message_to_peripheral_channel(
) -> Option<&'static Channel<RawMutex, MessageToPeripheral, 4>> {
Some(T::get_message_to_peripheral_channel())
}
}
}

#[rumcake_macros::task]
pub async fn central_task(mut driver: impl CentralDeviceDriver) {
pub async fn central_task<K: CentralDevice>(_k: K, mut driver: impl CentralDeviceDriver) {
let channel = K::get_message_to_peripheral_channel();

loop {
match select(
driver.receive_message_from_peripherals(),
MESSAGE_TO_PERIPHERALS.receive(),
)
.await
{
match select(driver.receive_message_from_peripherals(), channel.receive()).await {
Either::First(message) => match message {
Ok(event) => match event {
MessageToCentral::KeyPress(_, _) | MessageToCentral::KeyRelease(_, _) => {
Expand Down

0 comments on commit 28946c2

Please sign in to comment.