Unofficial, community port of the Blockstream Jade hardware-wallet firmware onto the M5Stack StickS3 (SKU K150, ESP32-S3-PICO-1-N8R8).
Working and verified on real hardware: the LCD renders the Jade UI, the board is detected and works over USB (Blockstream Green and Sparrow Wallet) and over BLE (e.g. Blockstream Green on iOS/Android).
This is an experimental board port. It is not a supported Blockstream Jade target and is not affiliated with Blockstream. Use at your own risk.
DO NOT build/flash this firmware onto official Blockstream Jade hardware. Official units can only be updated via a supported companion app or the Firmware Update Instructions.
| Item | Value |
|---|---|
| Board | M5Stack StickS3 (K150, ESP32-S3-PICO-1-N8R8) |
| Flash | 8 MB (QIO) |
| PSRAM | 8 MB octal (OPI) - CONFIG_SPIRAM_MODE_OCT required |
| Display | ST7789P3, 135x240, driven as 240x135 landscape |
| PMIC | M5PM1 on I2C 0x6E (NOT an AXP192/IP5306) |
| Buttons | KEY1 (middle, active-low), KEY2 (right, active-low) |
| Battery | 250 mAh LiPo (readouts not yet wired up) |
| Function | ESP32-S3 GPIO |
|---|---|
| LCD MOSI | 39 |
| LCD SCK | 40 |
| LCD RS/DC | 45 |
| LCD CS | 41 |
| LCD RST | 21 |
| LCD BL | 38 |
| M5PM1 SDA | 47 |
| M5PM1 SCL | 48 |
| KEY1 | 11 |
| KEY2 | 12 |
main/power/m5pm1.inc— small M5PM1 PMU driver (see "The M5PM1 gotcha").main/power.c— selectsm5pm1.incwhenCONFIG_HAS_M5PM1is set.main/Kconfig.projbuild— newHAS_M5PM1option (visible under the custom board menus).configs/sdkconfig_display_m5sticks3.defaults— complete StickS3 device config (board=custom, 8 MB flash/partitions, display pins + orientation, buttons, I2C SDA=47/SCL=48,HAS_M5PM1=y, PSRAM/octal, USB CDС+TinyUSB).partitionss3.csv— existing 8 MB S3 partition table (two 4024K OTA slots).
CONFIG_BOARD_TYPE_CUSTOM=y is required so the custom I2C/input/display pin
menus are available. The reported OTA BOARD_TYPE stays UNKNOWN for this
target (cosmetic; does not affect wallet detection).
The M5PM1 powers the ESP32 from its L0/L1/L2 rails automatically. The
L3B rail (LCD backlight / MIC / speaker) is gated by the PMIC's
PYG2/GPIO2 output, which is an ACTIVE-HIGH enable: output HIGH powers the
rail. The GPIO_OUT register defaults to all-high on reset, so stock M5
firmware never touches PYG2 and the rail is simply on. Writing GPIO_OUT low
actively disables L3B - this is what kept the screen black in earlier ports.
Verified against uiflow-micropython m5stack/boards/M5STACK_StickS3/board_init.c
(which never configures PYG2) and by hardware test (writing 0x04 = PYG2 HIGH
restores the backlight).
The M5PM1 driver also:
- Disables the PMIC I2C idle-sleep timeout (reg
0x09) so it never drops rails once the app stops talking to it. - Disables the PMIC watchdog (reg
0x0A). - Keeps core rails asserted (reg
0x06) and holds LDO/BOOST/PYG2 state across soft resets (reg0x07). - Configures PYG2 push-pull HIGH → L3B on, and PYG3 LOW to keep the speaker amplifier off during bring-up.
Register map used (regs 0x00, 0x06, 0x07, 0x09, 0x0A, 0x10, 0x11,
0x13, 0x16); see the [M5PM1 datasheet] and the [M5PM1 Arduino library].
- ESP-IDF v5.5.x (to match Jade
master). See the upstream DIY guide and the Espressif install guide. - System
cmakeandninjaon PATH:sudo apt install cmake ninja-build(orbrew install cmake ninja). - Python 3.11+ for the ESP-IDF Python env.
- Clone submodules:
git submodule update --init --recursive.
cd ~/JadeSticks3
# ensure the StickS3 config is active
cp configs/sdkconfig_display_m5sticks3.defaults sdkconfig.defaults
export IDF_PATH=~/esp/esp-idf # your ESP-IDF v5.5 checkout
source "$IDF_PATH/export.sh"
idf.py fullclean && idf.py build # artifact: build/jade.binEnvironment notes:
- ESP-IDF pins a Python env at configure time. If you build with a different
Python version than the one used to configure
build/, runidf.py fullcleanfirst - it will refuse to reusebuild/otherwise. - To switch configs, delete any stale root
sdkconfig(andsdkconfig.old) in addition toidf.py fullclean;fullcleandoes not regeneratesdkconfigfromsdkconfig.defaults.
On a real (non-sandboxed) terminal, board in download mode (hold the side reset button while plugging in USB-C until the green LED flashes):
cd ~/JadeSticks3
source ~/esp/esp-idf/export.sh
idf.py -p /dev/ttyACM0 -b 460800 flashIf the board is already running Jade over USB-CDC, flashing over that same port usually works without download mode.
- USB: plug in via USB-C. Blockstream Green and Sparrow Wallet both detect and talk to the device over the USB serial (CDC) interface.
- BLE: enable Bluetooth; pair/connect from a companion app (tested with Blockstream Green on iOS).
- Serial log over USB-CDC:
idf.py -p /dev/ttyACM0 monitor. - Firmware logs default to
NONEin the release config. For diagnostics, setCONFIG_LOG_DEFAULT_LEVEL_INFO=y(and optionallyDEBUG) insdkconfig.defaults, then rebuild. - If the display is black, check in order:
- L3B rail on? — PYG2 must be driven HIGH; the M5PM1 readback in the boot
log should show
m5pm1: reg 0x11 = 0x04(PYG2 high → L3B on). - Backlight — BL GPIO38; if it glows but the panel is blank, the issue is panel init/SPI.
- PMIC alive? — M5PM1 answers at
0x6Eon SDA=47/SCL=48 (shared bus with BMI2700x68).
- L3B rail on? — PYG2 must be driven HIGH; the M5PM1 readback in the boot
log should show
- For plain-text boot logs over USB-Serial-JTAG (rather than USB-CDC), enable
CONFIG_JADE_USE_USB_JTAG_SERIAL=y+CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=yCONFIG_TINYUSB_CDC_ENABLED=n+ LF line endings. Note this disables the USB-CDC used by wallets, so it is only for diagnostics.
- Board boots, PSRAM/octal, USB-CDC (Green + Sparrow) and BLE work
- ST7789P3 display pin map + orientation/offsets
- M5PM1 L3B rail (PYG2 active-high), watchdog/idle-sleep disabled
- Battery level/charging readout via M5PM1 ADC (
power_get_vbatetc. are stubs) - Camera and IMU (BMI270) not used by Jade
- OTA board id / provisioning for the custom target (
ota_defines.h)
- StickS3 docs/pinmap: https://docs.m5stack.com/en/core/StickS3
- StickS3 M5PM1 tutorial: https://docs.m5stack.com/en/arduino/m5sticks3/m5pm1
- M5PM1 datasheet: https://m5stack-doc.oss-cn-shenzhen.aliyuncs.com/1207/M5PM1_Datasheet_EN.pdf
- M5PM1 Arduino library: https://github.com/m5stack/M5PM1
- M5Unified (StickS3 board init): https://github.com/m5stack/M5Unified
- Blockstream Jade firmware: https://github.com/Blockstream/Jade
- Upstream Jade DIY guide: ./diy/