sparkle-fw16 is an alternative Framework Laptop 16 LED matrix module firmware.
I didn't like a few things about the original firmware:
- Has too many useless features.
- It's written in Rust and my eyes just cannot stand that shit. Call it a skill issue, I don't give a fuck.
- It handles display interaction in a weird way that breaks my brain.
- Download CMake and Ninja build tools. I'll let you figure this one out yourself.
- Download RP2040 Pico SDK, install it.
When that's done, set your
PICO_SDK_PATHandPICO_TOOLCHAIN_PATHenvironmental variables accordingly. - After setting up your environment, just navigate to this directory and execute:
cmake . -B build/ -G ninja -DCMAKE_BUILD_TYPE=<build_type>
cd build/
ninja
Where <build_type> is one of the following: Release, RelWithDebInfo, Debug.
The artifact that's been built should be a .uf2 located somewhere in the build
directory.
- Take your input module(s) out of the input deck.
- Switch the input module(s) into BOOTSEL mode by toggling the DIP-switch pin 2 into ON position.
- Place the module(s) back into the input deck. A mass storage device will appear in your system.
- Move the file
.uf2file into the newly appeared mass storage device. RP2040 should pick it up and flash it after a few seconds. - Refresh your file manager and you'll find the file magically vanished - that's how it confirms the flashing process has completed.
- Take the input module(s) out again and toggle the DIP-switch pin 2 into OFF position.
- Replace the input module(s). Congratulations, you're running
sparkle-fw16.
When Sparkle starts up it initializes 3 interfaces:
- USB CDC interface for debugging purposes. All messages are logged there.
- USB HID interface for control purposes. API requests are sent there.
- RP2040 Reset interface for easy flashing. The modified Sparkle Picotool makes use of this.
The Glitter Protocol is how Sparkle talks to your Framework Laptop 16 and vice-versa.
It's implemented on top of the USB HID stack and exposes 3 HID reports.
Returns the current device information defined by the structure specified below.
NOTE
This report only accepts GET_REPORT control transfer. SET_REPORT requests with this ID will be ignored.
typedef struct glitter_device_info
{
uint8_t sleep_pin; /* 1 = on, 0 = off */
uint8_t dip1_pin; /* 1 = on, 0 = off */
uint8_t intb_pin; /* 1 = on, 0 = off */
uint8_t state_flags; /* see firmware/kernel.h for details */
uint8_t id_reg; /* see IS31FL3741A datasheet for details */
uint8_t config_reg;
uint8_t global_brightness;
uint8_t display_width; /* 9 for the official LED matrix module */
uint8_t display_height; /* 34 for the official LED matrix module */
} glitter_device_info_t;
Executes a user-accessible firmware subroutine. First byte specifies command ID, while subsequent bytes are used as command arguments where applicable.
0x00-GLITTER_CMD_REBOOT(target: uint8_t)
Reboots the microcontroller into the specified target state.
target:0x00to reboot into BOOTSEL mode,0x01to reboot the firmware. Undefined reboot targets will be treated as if they were requests to reboot into firmware.
0x01-GLITTER_CMD_SLEEP(enter: uint8_t)
Tells the firmware to enter or exit sleep mode.
enter:0x00to initiate a wake-up,0x01to enter user-induced sleep. This will set the sleep state flag to theKERNEL_SLEEPSTATE_COMMAND (0x03)value.
0x02-GLITTER_CMD_WAKE_ON_COMMAND(enable: uint8_t)
Toggles the integrated wake-on-command mechanism. When wake-on-command is enabled, any draw commands or grid control reports received will automaticall wake the LED matrix module up. Otherwise, they will be ignored untilGLITTER_CMD_SLEEP(false)request is issued.
enable:0x00to disable the wake-on-command mechanism,0x01to enable it.
0x03-GLITTER_CMD_SET_SLEEP_TIMEOUT(timeout_ms: int32_t)
Sets the time, in milliseconds, since last received display draw command that needs to pass in order to put the LED matrix is put to sleep.
timeout_ms: Set to0to disable the timeout mechanism, set to-1to ignore any sleep requests received (including user-induced sleep and the EC sleep pin).
0x04-GLITTER_CMD_SET_GLOBAL_BRIGHTNESS(brightness: uint8_t)
Sets the global LED brightness multiplier.
brightness: A new global brightness multiplier to be applied.
0x05-GLITTER_CMD_DRAW_PIXEL(x: uint8_t, y: uint8_t, brightness: uint8_t)
Sets a single pixel.
x: The horizontal axis coordinate identifying the LED to be set.
y: The vertical axis coordinate identifying the LED to be set.
brightness: The brightness value the selected LED is going to be set to.NOTE
Coordinate system starts (point [0, 0]) at the top-right LED, like with classic 2D computer graphics engines and frameworks.
0x06-GLITTER_CMD_DRAW_LINE(x1y1: uint16_t, x2y2: uint16_t, brightness: uint8_t)
Draws a line.
x1y1: Coordinate pair at which the line drawn starts.
x2y2: Coordinate pair at which the line drawn ends.
brightness: The brightness value of the line drawn.NOTE
The coordinates are encoded in the following way:x = x1y1 >> 8; y = x1y1 & 0xFF;
This report takes a sequence of 306 bytes representing the entire pixel grid's brightness values.
NOTE
If the wake-on-command mechanism is disabled, any requests for this report ID are ignored by the firmware.
This report takes a sequence of 306 bytes representing the DC scale values for every pixel in the grid. Please consult the included IS31FL3741A datasheet for more details on what this means.