Skip to content

Commit

Permalink
merge backlighting and underglow into a single lighting module
Browse files Browse the repository at this point in the history
- this also removes the `pub static` items like command channels, and instead replaces them with trait functions `get_command_channel`, `get_state`, `get_save_signal`, etc.
- these changes also enable different backlighting types to be used at the same time, instead of only being able to use one of simple-backlight, simple-backlight-matrix or rgb-backlight-matrix at a time.
- all lighting types use the same `lighting_task` and `lighting_storage_task`, using an `Animator` trait, which can be implemented by the user to allow for custom animators
- #[keyboard] macro usage for lighting has been updated accordingly to support the ability to have multiple lighting types share the same task as well.
- associated type items have been added to the `KeyboardLayout` trait and also a new `PeripheralDevice` trait, which can be used to control how the `layout_collect` and `peripheral_task` communicate with these lighting systems, respectively.
  • Loading branch information
Univa committed Mar 29, 2024
1 parent 4b7ac44 commit e9e09fb
Show file tree
Hide file tree
Showing 36 changed files with 3,709 additions and 3,064 deletions.
49 changes: 31 additions & 18 deletions docs/src/content/docs/features/feature-backlight.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,26 @@ Some drivers may not be able to support all backlight types.

## Required code

To set up backlighting, you must add `<backlight_type>(driver = "<driver>")` to your `#[keyboard]` macro invocation,
and your keyboard must implement the `BacklightDevice` trait.
To set up backlighting, you must add a new type to implement traits on.
Then, you can add `<backlight_type>(id = <type>, driver = "<driver>")` to your `#[keyboard]` macro
invocation, and your new type must implement the appropriate trait depending on the type of lighting you're using.

```rust ins={5-7,11-16}
```rust ins={5-8,13-18}
use rumcake::keyboard;

#[keyboard(
// somewhere in your keyboard macro invocation ...
simple_backlight_matrix( // TODO: Change this to `rgb_backlight_matrix` or `simple_backlight` if that's what you want.
id = MyKeyboardLighting,
driver = "is31fl3731", // TODO: change this to your desired backlight driver, and implement the appropriate trait (info below)
)
)]
struct MyKeyboard;

// Backlight configuration
use rumcake::backlight::BacklightDevice;
impl BacklightDevice for MyKeyboard {
use rumcake::lighting::simple_backlight_matrix::SimpleBacklightMatrixDevice;
struct MyKeyboardLighting; // New type to implement lighting traits on
impl SimpleBacklightMatrixDevice for MyKeyboardLighting {
// optionally, set FPS
const FPS: usize = 20;
}
Expand All @@ -57,12 +60,13 @@ hue, saturation, effect, etc.) will **NOT** be saved by default.

Optionally, you can add `use_storage`, and a `storage` driver to save backlight config data.

```rust ins={7,9}
```rust ins={8,10}
use rumcake::keyboard;

#[keyboard(
// somewhere in your keyboard macro invocation ...
simple_backlight_matrix( // TODO: Change this to `rgb_backlight_matrix` or `simple_backlight` if that's what you want.
id = MyKeyboardLighting,
driver = "is31fl3731", // TODO: change this to your desired backlight driver, and implement the appropriate trait (info below)
use_storage // Optional, if you want to save backlight configuration
),
Expand All @@ -77,26 +81,28 @@ For more information, see the docs for the [storage feature](../feature-storage/

If you're implementing a backlight matrix (either the `simple-backlight-matrix` or `rgb-backlight-matrix`), your keyboard must also implement the `BacklightMatrixDevice` trait:

```rust ins={18-37}
```rust ins={20-38}
use rumcake::keyboard;

#[keyboard(
// somewhere in your keyboard macro invocation ...
simple_backlight_matrix( // TODO: Change this to `rgb_backlight_matrix` or `simple_backlight` if that's what you want.
id = MyKeyboardLighting,
driver = "is31fl3731", // TODO: change this to your desired backlight driver, and implement the appropriate trait (info below)
)
)]
struct MyKeyboard;

// Backlight configuration
use rumcake::backlight::BacklightDevice;
impl BacklightDevice for MyKeyboard {
struct MyKeyboardLighting;
use rumcake::lighting::simple_backlight_matrix::SimpleBacklightMatrixDevice;
impl SimpleBacklightMatrixDevice for MyKeyboardLighting {
// optionally, set FPS
const FPS: usize = 20;
}

use rumcake::backlight::{BacklightMatrixDevice, setup_backlight_matrix};
impl BacklightMatrixDevice for MyKeyboard {
use rumcake::lighting::{BacklightMatrixDevice, setup_backlight_matrix};
impl BacklightMatrixDevice for MyKeyboardLighting {
setup_backlight_matrix! {
{ // LED layout
[ (0,0) (17,0) (34,0) (51,0) (68,0) (85,0) (102,0) (119,0) (136,0) (153,0) (170,0) (187,0) (204,0) (221,0) (238,0) (255,0) ]
Expand Down Expand Up @@ -132,11 +138,11 @@ For example, with `is31fl3731`, you must implement `IS31FL3731DriverSettings` an
// later in your file...

use rumcake::hw::mcu::setup_i2c;
use rumcake::drivers::is31fl3731::backlight::{
use rumcake::drivers::is31fl3731::{
get_led_from_matrix_coordinates, IS31FL3731BacklightDriver
};
// Note: The IS31FL3731DriverSettings trait does NOT come from the `rumcake` library. It is generated by the `keyboard` macro.
impl IS31FL3731DriverSettings for MyKeyboard {
impl IS31FL3731DriverSettings for MyKeyboardLighting {
const LED_DRIVER_ADDR: u8 = 0b1110100; // see https://github.com/qmk/qmk_firmware/blob/d9fa80c0b0044bb951694aead215d72e4a51807c/docs/feature_rgb_matrix.md#is31fl3731-idis31fl3731

setup_i2c! { // Note: The arguments of setup_i2c may change depending on platform. This assumes STM32.
Expand All @@ -149,7 +155,7 @@ impl IS31FL3731DriverSettings for MyKeyboard {
DMA1_CH6 // TX DMA Channel
}
}
impl IS31FL3731BacklightDriver for MyKeyboard {
impl IS31FL3731BacklightDriver for MyKeyboardLighting {
// This must have the same number of rows and columns as specified in your `BacklightMatrixDevice` implementation.
get_led_from_matrix_coordinates! {
[ C1_1 C1_2 C1_3 C1_4 C1_5 C1_6 C1_7 C1_8 C1_9 C1_10 C1_11 C1_12 C1_13 C1_14 C1_15 C2_15 ]
Expand Down Expand Up @@ -202,26 +208,33 @@ In your `keyberon` layout, you can use `{Custom(SimpleBacklight(<command>))}`,
`{Custom(SimpleBacklightMatrix(<command>))}`, `{Custom(RGBBacklightMatrix(<command>))}`,
depending on what type of backlight system you are using.

Additionally, you must choose the backlight system that the keycodes will correspond to by
implementing one of the associated types `SimpleBacklightDeviceType`, `SimpleBacklightMatrixDeviceType`,
`RGBBacklightDeviceType`.

Example of usage:

```rust
```rust ins={14}
use keyberon::action::Action::*;
use rumcake::backlight::animations::BacklightCommand::*;
use rumcake::lighting::simple_backlight_matrix::SimpleBacklightMatrixCommand::*;
use rumcake::keyboard::{build_layout, Keyboard, Keycode::*};

/* ... */
impl KeyboardLayout for MyKeyboard {
/* ... */

build_layout! {
{
[ Escape {Custom(SimpleBacklightMatrix(Toggle))} A B C]
}
}

type SimpleBacklightMatrixDeviceType = MyKeyboardLighting;
}
```

# To-do List

- [ ] RGB Backlight animations
- [ ] Allow different backlighting systems to be used at the same time

# Available Drivers

Expand Down
12 changes: 8 additions & 4 deletions docs/src/content/docs/features/feature-split.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,16 @@ If the split keyboard also uses extra features, then all the peripherals should
You must compile a binary with the following `rumcake` features:

- `split-peripheral`
- `drivers` (optional built-in drivers to your peripheral device to a central device)
- Feature flag for one of the [available split drivers](#available-drivers) that you would like to use

## Required code for peripheral device

To set up the peripheral device, you must add `split_peripheral(driver = "<driver>")` to your `#[keyboard]` macro invocation,
and your keyboard must implement the appropriate trait for the driver you're using. For example, with `ble` and an nRF5x chip
selected, you must implement `NRFBLEPeripheralDriverSettings`, and `BluetoothDevice`:
and your keyboard must implement the `PeripheralDevice` trait. Additionally, you must also implement the appropriate traits
for the driver you're using. For example, with `ble` and an nRF5x chip selected, you must implement `NRFBLEPeripheralDriverSettings`,
and `BluetoothDevice`:

```rust ins={6-8,12-24}
```rust ins={6-8,12-27}
// right.rs
use rumcake::keyboard;

Expand All @@ -143,6 +144,9 @@ impl BluetoothDevice for WingpairLeft {
}

// Split peripheral setup
use rumcake::split::peripheral::PeripheralDevice;
impl PeripheralDevice for WingpairRight {}

// Note: The NRFBLEPeripheralDriverSettings trait does NOT come from the `rumcake` library. It is generated by the `keyboard` macro.
impl NRFBLEPeripheralDriverSettings for MyKeyboardRightHalf {
// Must be valid "Random Static" bluetooth address.
Expand Down
29 changes: 20 additions & 9 deletions docs/src/content/docs/features/feature-underglow.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,27 @@ You must enable the following `rumcake` features:

## Required code

To set up underglow, you must add `underglow(driver = "<driver>")` to your `#[keyboard]` macro invocation,
and your keyboard must implement the `UnderglowDevice` trait. Optionally, you can add `use_storage` to the
To set up underglow, you must add a new type to implement traits on.
Then, you can add `underglow(id = <type>, driver = "<driver>")` to your `#[keyboard]` macro
invocation, and your keyboard must implement the `UnderglowDevice` trait. Optionally, you can add `use_storage` to the
macro invocation to use the specified storage driver to save underglow config data.

```rust ins={5-7,11-16}
```rust ins={5-7,13-18}
use rumcake::keyboard;

#[keyboard(
// somewhere in your keyboard macro invocation ...
underglow(
id = MyKeyboardUnderglow,
driver = "ws2812_bitbang", // TODO: change this to your desired underglow driver, and implement the appropriate trait (info below)
)
)]
struct MyKeyboard;

// Underglow configuration
use rumcake::underglow::UnderglowDevice;
impl UnderglowDevice for MyKeyboard {
use rumcake::lighting::underglow::UnderglowDevice;
struct MyKeyboardUnderglow; // New type to implement underglow traits on
impl UnderglowDevice for MyKeyboardUnderglow {
// Mandatory: set number of LEDs
const NUM_LEDS: usize = 20
}
Expand All @@ -48,12 +51,13 @@ hue, saturation, effect, etc.) will **NOT** be saved by default.

Optionally, you can add `use_storage`, and a `storage` driver to save underglow config data.

```rust ins={7,9}
```rust ins={8,10}
use rumcake::keyboard;

#[keyboard(
// somewhere in your keyboard macro invocation ...
underglow(
id = MyKeyboardUnderglow,
driver = "ws2812_bitbang", // TODO: change this to your desired underglow driver, and implement the appropriate trait (info below)
use_storage // Optional, if you want to save underglow configuration
)
Expand Down Expand Up @@ -108,20 +112,27 @@ SaveConfig, // normally called internally when the underglow config changes, onl
ResetTime, // normally used internally for syncing LEDs for split keyboards
```

In your `KeyboardLayout` implementation, you must choose the underglow system that the keycodes will
correspond to by implementing `UnderglowDeviceType`.

Example of usage:

```rust
```rust ins={14}
use keyberon::action::Action::*;
use rumcake::underglow::animations::UnderglowCommand::*;
use rumcake::lighting::underglow::UnderglowCommand::*;
use rumcake::keyboard::{build_layout, Keyboard, Keycode::*};

/* ... */
impl KeyboardLayout for MyKeyboard {
/* ... */

build_layout! {
{
[ Escape {Custom(Underglow(Toggle))} A B C]
}
}

type UnderglowDeviceType = MyKeyboardUnderglow;
}
```

# Available Drivers
Expand Down
10 changes: 5 additions & 5 deletions rumcake-macros/src/backlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ impl ToTokens for LEDFlags {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let flags = self.flags.iter();

quote! { #(::rumcake::backlight::LEDFlags::#flags)|* }.to_tokens(tokens)
quote! { #(::rumcake::lighting::LEDFlags::#flags)|* }.to_tokens(tokens)
}
}

pub fn led_flags(input: MatrixLike<OptionalItem<LEDFlags>>) -> TokenStream {
let flags = input.rows.iter().map(|row| {
let items = row.cols.iter().map(|col| match col {
OptionalItem::None => quote! {
::rumcake::backlight::LEDFlags::NONE
::rumcake::lighting::LEDFlags::NONE
},
OptionalItem::Some(ident) => quote! {
#ident
Expand Down Expand Up @@ -111,10 +111,10 @@ pub fn setup_backlight_matrix(input: BacklightMatrixMacroInput) -> TokenStream {
const LIGHTING_ROWS: usize = #row_count;

fn get_backlight_matrix(
) -> ::rumcake::backlight::BacklightMatrix<{ Self::LIGHTING_COLS }, { Self::LIGHTING_ROWS }>
) -> ::rumcake::lighting::BacklightMatrix<{ Self::LIGHTING_COLS }, { Self::LIGHTING_ROWS }>
{
const BACKLIGHT_MATRIX: ::rumcake::backlight::BacklightMatrix<#col_count, #row_count> =
::rumcake::backlight::BacklightMatrix::new(#led_layout, #led_flags);
const BACKLIGHT_MATRIX: ::rumcake::lighting::BacklightMatrix<#col_count, #row_count> =
::rumcake::lighting::BacklightMatrix::new(#led_layout, #led_flags);
BACKLIGHT_MATRIX
}
}
Expand Down
Loading

0 comments on commit e9e09fb

Please sign in to comment.