Hardware details and information to build an open firmware for Bluetooth LED badges, compatible with Badge Magic app
Warning: Flashing this firmware on an unsupported badge can brick it permanently. The OEM firmware is read-protected and cannot be dumped, so there is no recovery path once overwritten. See #59 for a real example of this happening.
This firmware targets one specific badge variant:
- Chipset: WCH CH582M (RISC-V)
- Display: 11×44 LED matrix
- OEM BLE name often:
LSLED
After flashing this firmware, the default BLE device name is LED Badge Magic.
Many LED badges look identical on the outside and often ship with OEM firmware advertising the same BLE name (LSLED), but differ internally in chipset or LED grid size (e.g. 11×44 vs 11×55). Identical appearance and OEM BLE name do not guarantee compatibility.
To verify your badge before flashing:
- Open the badge and locate the chip marking on the PCB — it should read CH582M
- Count the LED columns — there should be 44 (not 48, 55 or any other number)
- If you are unsure, do not flash this firmware
For hardware photos and further identification help, see CH582.md.
Note: Compatibility with other badge variants (e.g. LeSun B1144 or other Alibaba sourced clones) is not established. Pinout reverse engineering for those boards is still in progress.
Install wchisp.
Download prebuilt binaries from release or the latest development builds.
Make the chip enter bootloader mode (ISP mode) by power cycling the chip while the boot pin is pulled down in one of two ways:
- Disconnect the battery, press and hold KEY2 (the button near the USB port) while plugging in the USB to enter the bootloader.
- Alternatively, connect the USB, press and hold KEY2, then short and release the C3 capacitor using metal tweezers or a wire.
See CH582.md for a technical explanation on why both the above methods work.
If the badge has successfully entered ISP mode, a single pixel roughly in the middle of the display will be lit. The badge will stay in ISP mode for approximately ten seconds before rebooting into normal mode.
On Linux, you can also check dmesg if the chip has entered the ISP mode with idVendor=4348 and idProduct=55e0.
Note: The photos shown below for option 2 show two different hardware revisions (Micro-USB and USB-C). C3 is in a different position on each board - Identify your revision before proceeding.
With the badge in ISP mode, run:
wchisp config reset
wchisp flash badgemagic-ch582.binOn Windows, you have the option to install and run wchisp studio instead of the wchisp CLI tool. Connect the badge via USB and enter bootloader mode, per the instructions above.
The device will automatically appear in the UI.
Select the badgemagic-ch582.bin file and click 'Download'.
Where badgemagic-ch582.bin is the binary downloaded above, the .elf file also works.
Once the open source firmware is installed, there is no further need to remove the battery or short-circuit C3 to enter ISP mode. Simply long-press KEY2 to enter ISP mode. Then, flash updated firmware with
wchisp config reset
wchisp flash badgemagic-ch582.binFor usual usages, please refer to badgemagic-app and led-name-badge-ls32.
See BadgeBLE.md.
From the device perspective, the data format is just the same as the BLE Data Format. The only difference is the data width. It's 64 bytes, while BLE, is only 16.
Located at Interface 0x00 and Endpoint 0x01. Interface Number and Enpoint Address might not be always fixed, any app using this should check them before using.
For more detail about USB HID, please refer to USB HID Device Class Definition.
Similar to USB HID, but more convenient. From the host's perspective, it appears as a serial device, which can be interacted directly without the additional library. e.g. A bitmap.bin file with a format just like the BLE Data Format can be transferred to the badge by:
stty -F /dev/ttyACM0 raw && cat bitmap.bin > /dev/ttyACM0For more detail about USB CDC ACM, see Class definitions for Communication Devices 1.2.
This firmware was implemented following the BLE Device Information standard. Any device with BLE-capable can easily get the version by reading the value of the Firmware Revision String Characteristic (0x2A26) in the Device Information Profile (0x18A).
The version can be read from USB by reading the USB Serial Number String.
While the badge is in charging state, it display a animation followed by a version repeatedly.
Set the toolchain location, e.g.:
export PREFIX=../MRS_Toolchain_Linux_x64_V1.92/RISC-V_Embedded_GCC/bin/riscv-none-embed-Simply run make to build the firmware for the second generation version (previously known as the USB-C version), with the output directed to the build/ directory. To build for the Micro USB version of the badge and specify a custom output directory:
BUILD_DIR=custom-dir HARDWARE_REV1=1 makeTo build for the third generation hardware, simply replace HARDWARE_REV1=1 with HARDWARE_REV3=1.
Note
Switching HARDWARE_REV* will require a clean build to make sure the new build
does not contain the previous build blob. To rebuild:
make clean allTo flash the firmware, enter the bootloader, then run:
BUILD_DIR=custom-dir-if-needed make ispThis firmware supports two independent build choices — you need to know both before building or downloading:
- Board revision — controlled by
HARDWARE_REV1/HARDWARE_REV3(see the Build section above for what each targets). - Button count — controlled by the new
KEY_COUNTflag:KEY_COUNT=4(default) orKEY_COUNT=2.
If you're not sure which board revision or button count your badge has, see CH582.md for identification help before flashing.
Set the toolchain location first, as described in Build:
export PREFIX=../MRS_Toolchain_Linux_x64_V1.92/RISC-V_Embedded_GCC/bin/riscv-none-embed-4-key badge, second-gen hardware (default):
make4-key badge, Micro USB (first-gen) hardware:
BUILD_DIR=custom-dir HARDWARE_REV1=1 make2-key badge, second-gen hardware:
BUILD_DIR=custom-dir KEY_COUNT=2 make2-key badge, Micro USB (first-gen) hardware:
BUILD_DIR=custom-dir HARDWARE_REV1=1 KEY_COUNT=2 makeNote
Switching KEY_COUNT, like switching HARDWARE_REV*, requires a clean
build so the new build doesn't contain the previous build's blob:
make clean allThis only matters if you're reusing the same BUILD_DIR for different
variants. Building each variant into its own BUILD_DIR avoids the need
for make clean between builds.
To flash directly after building, enter the bootloader (see Installation above), then:
BUILD_DIR=custom-dir-if-needed make ispDownload the binary matching your hardware from releases:
badgemagic-4key-<rev>.bin— 4-key badgesbadgemagic-2key-<rev>.bin— 2-key badges
Where <rev> matches your board revision, per CH582.md.
Then, same as any firmware update:
wchisp config reset
wchisp flash badgemagic-<variant>.binLong-press KEY2 to enter ISP mode first if the badge isn't already there.
Flashing the wrong KEY_COUNT variant won't damage the badge, but menu
navigation will be incomplete or stuck, since some button handlers expect
hardware that isn't present — reflash the correct variant to fix it.
Currently, only the UART1 with baudrate=921600 is used for debugging. To enable the log from UART, set the DEBUG=1 when building the project.
Any USB to UART dongle will work. Use your favorite terminal emulator to see the log, e.g.:
picocom -b921600 /dev/ttyUSB0 --imap lfcrlfThe badgemagic-hardware have this UART wired over USB-C. So it can be used without opening the case, but required an aditional hardware to split the serial lines from USB-C.
This is convenient as it doesn't require additional hardware, but it may not be useful for early logging when the USB is not yet initialized, and the user cannot open the serial port quickly enough.
Use cdc_tx_poll() to log to this serial channel.
This is a mystery.
To create a new custom data exchange channel, add a new BLE profile to the firmware
by duplicating /src/ble/profile/legacy.c and reconfig it. Rename
xxx_registerService() function. Call this function after peripheral_init() to
register your new profile.
For more detail of how to config a gatt service, see BLE GATT.
To add a new custom USB Composite Device (e.g., keyboard, mouse, speaker, etc.), duplicate src/usb/composite/hiddev.c. Rename and configure the file according to the Device Class you intend to implement, then call your device's xxx_init() function in usb_start() to initialize it. Each device class has specific specifications, so be sure to refer to them when implementing your new device.
BadgeMagic target hardware features a custom 11x44 LED matrix display, Bluetooth LE and low power consumption.
The design relies on a single MCU. MCU type has changed depending on manufacturer batches.
- ARM M0 variant based on MM32L062PF
- ARM M0 variant based on MM32W062
- RISC-V variant based on CH582M
See specific pages regarding each version of the hardware below
The custom 11x44 LED dot matrix displays using persistence of vision.
Bitmaps are drawn using 24 pins in charlieplexing technique.
Manufacturer firmware is closed source. Creating an open source compatible firmware is the goal of this project.
The badge stores bitmaps with preconfigured animation sequences. It uses 8 memory banks that can be used alternatively.
The 2 buttons configuration:
- Top button
- Switches device on or off (long press)
- Changes to Bluetooth upload mode (short press when on)
- Bottom button
- Switches to badge display instead of charging screen when plugged with USB
- Switches memory bank when displayed
- Changes brightness level (long press)
Previously, 2-key badges could only run the simple button scheme described above (power on/off, Bluetooth upload, brightness, bank switch). This release brings the full menu-driven firmware — until now only available on 4-key badges to 2-key hardware as well.
- Menu system — scroll and select between Animation, Bluetooth Pairing, Clock, Snake, and Off, instead of the old fixed on/off behaviour
- Clock mode with Stopwatch — a full clock submenu (Time / Stopwatch), previously exclusive to 4-key hardware.
- Snake — the game uses relative turning (turn left / turn right) rather than absolute directions, so it works identically on 2-key hardware with no loss of functionality.
- Everything else the 2-key firmware already had — animations, BLE pairing toggle, USB HID/CDC control
Every menu feature from the 4-key firmware is now fully available on 2-key hardware. Nothing is missing in this release.
The 4-key firmware uses two extra auxiliary buttons (KEY3/KEY4) for menu selection and returning to the menu. 2-key hardware doesn't have those buttons, so those actions are remapped onto long-presses of the two buttons you already have:
| Action | 4-key badges | 2-key badges |
|---|---|---|
| Scroll menu / clock submenu | KEY1/KEY2 short-press | KEY1/KEY2 short-press (unchanged) |
| Select menu item / enter clock submenu item | KEY3 short-press, or KEY1 long-press | KEY1 long-press |
| Return to menu (from Animation/BLE mode) | KEY4 short-press | KEY2 long-press |
| Return to menu / back (from Clock submenu) | KEY4 short-press | KEY2 long-press |
| Stopwatch start/stop, reset | KEY1 / KEY2 short-press | KEY1 / KEY2 short-press (unchanged) |
| Snake | KEY3/KEY4 for movement | Not available |
Menu scrolling, the clock submenu, and the stopwatch behave exactly the same either way — the only change is that KEY1 long-press and KEY2 long-press now do the job KEY3 and KEY4 used to do.
Here is some documentation on the BLE package format. There still are some unclear parts, but it seems to work.
See original led-name-badge-ls32 for USB update protocol reverse engineering
See Badge Magic app for Bluetooth update protocol
Address 38:3B:26:CC:03:C1
Name LSLED
Class 0x0
Appearance 0x0
Device UUID 0000fee0-0000-1000-8000-00805f9b34fb
or 0000fee1-0000-1000-8000-00805f9b34fb
Currently, only the RISC-V version is targeted as it seems the only one produced at the moment.
Please go to CH582 Badge Instructions and Reverse Engineering

