๐Ÿ”“ OPEN
๐Ÿ”Œ CONNECT
๐Ÿ“ฅ DUMP
๐ŸŽจ MOD
๐Ÿ“ค FLASH

๐Ÿ”ฌ Vape Pimp Speedrun

SMOK Novo 6 / Raz TN9000 / Kraze HD7K N32G031 ARM Cortex-M0 ยท 48MHz ยท 64KB Flash

๐Ÿšจ SAFETY

๐Ÿ”‹ Battery FIRST ๐Ÿงค Gloves ALWAYS โšก 3.3V ONLY ๐Ÿ”ฅ MOSFET = fire risk

1. Pry bottom cap Plastic spudger only

CC1 โ†’ SWDIO CC2 โ†’ SWCLK

openocd -f stlink.cfg -f n32g031.cfg

PNG โ†’ RGB565 80ร—160 big-endian

SPI: TL866 / CH341A Desolder + SSOP adapter

2. Disconnect battery FIRST โ€” puncture = ๐Ÿ”ฅ

GND โ†’ GND 3.3V logic ONLY โšก

dump_image fw.bin 0x08000000 0x10000

Python + Pillow struct.pack('>H',...)

SWD: flash write_image Or flashrom via RPi

3. Clean PCB 99% IPA + nitrile gloves ๐Ÿงค

USB-C breakout

  • 5.1kฮฉ pull-downs

0xFFFFFFFF? โ†’ FMC ๐Ÿ”’ Chip-erase or ISP

MADCTL 0x36 Bit3: RGBโ†”BGR swap

N32G031-based vape โ†’ pocket console. Novo 6 ยท Raz TN9000 ยท Kraze HD7K & clones.


graph LR
    A["๐Ÿ”“ OPEN<br>Teardown + clean<br><i>spudger, IPA+gloves</i>"]
    B["๐Ÿ”Œ CONNECT<br>USB-C SWD tap<br><i>CC1=SWDIO, CC2=SWCLK<br>3.3V ONLY!</i>"]
    C["๐Ÿ“ฅ DUMP<br>OpenOCD flash<br><i>0x08000000<br>64KB MCU, 1MB SPI NOR</i>"]
    D["๐ŸŽจ MOD<br>RGB565 bitmaps<br><i>80ร—160 px, big-endian<br>Pillow</i>"]
    E["๐Ÿ“ค FLASH<br>SPI/SWD write<br><i>TL866 / CH341A<br>flashrom</i>"]

    A -->|"โฑ๏ธ"| B -->|"โฑ๏ธ"| C -->|"โฑ๏ธ"| D -->|"โฑ๏ธ"| E

    style A fill:#4a9,color:#fff
    style B fill:#49a,color:#fff
    style C fill:#69c,color:#fff
    style D fill:#e9973f,color:#fff
    style E fill:#a882ff,color:#fff

๐Ÿงค GLOVES MANDATORY ยท ๐Ÿ”‹ DISCONNECT BATTERY FIRST


๐Ÿง  HW Overview

graph TD
    HW["๐Ÿ“‹ HW SPECS"]
    MCU["๐Ÿง  MCU<br>N32G031K8Q7<br>ARM Cortex-M0 ยท 48MHz<br>64KB Flash ยท 8KB SRAM"]
    SCR["๐Ÿ“บ Screen<br>0.96โ€ณ 80ร—160 IPS TFT<br>ST7735S or GC9107<br>4-wire SPI"]
    FLS["๐Ÿ’พ Flash<br>GT25Q80A 8Mbit (1MB)<br>bitmaps, puff counters, config"]
    CEL["๐Ÿ”‹ Cell<br>13450 Li-ion ~1700mAh<br>UNPROTECTED ยท puncture = ๐Ÿ”ฅ"]
    COI["โšก Coil<br>N-ch MOSFET driver<br>latch HIGH = fire hazard โ˜ ๏ธ"]

    HW --- MCU
    HW --- SCR
    HW --- FLS
    HW --- CEL
    HW --- COI

    style HW fill:#69c,color:#fff,stroke:#357,stroke-width:2px
    style CEL fill:#f44,color:#fff,stroke:#a00,stroke-width:2px
    style COI fill:#f80,color:#fff,stroke:#a50,stroke-width:2px

1. ๐Ÿ› ๏ธ Teardown

#Doโš ๏ธ
1Pry bottom cap โ†’ slide sled outPlastic spudger only
2Disconnect battery lead FIRSTPuncture = thermal runaway ๐Ÿ”ฅ
3Clean PCB: 99% IPA + nitrile gloves ๐ŸงคNicotine absorbs through skin
4ID chip markings (QFN32/LQFP32)Varies between production runs

๐Ÿ”ฅ PULL GENTLY: Do NOT puncture the 13450-size 1700mAh lithium-ion battery! Puncture = Thermal runaway = fire.

๐Ÿงค E-liquid has nicotine (toxic and absorbs through skin!). Use 99% Isopropyl Alcohol to clean the logic board and wear nitrile gloves!


2. ๐Ÿ”Œ SWD Tap

The USB-C SWD Hack: Hardware engineers often wire the SWDIO and SWCLK debug lines directly to the unused CC1/CC2 pins on the USB-C port!

graph LR
    subgraph USB["๐Ÿ”Œ USB-C Port"]
        CC1["CC1"]
        CC2["CC2"]
        GND_U["GND"]
        VBUS["VBUS 5V"]
    end
    subgraph PRB["๐Ÿ”ฌ Debug Probe"]
        SWDIO["SWDIO"]
        SWCLK["SWCLK"]
        PGND["GND"]
    end
    subgraph MCU["๐Ÿง  N32G031"]
        PA13["PA13"]
        PA14["PA14"]
    end

    CC1 -->|"data"| SWDIO -->|"debug"| PA13
    CC2 -->|"clock"| SWCLK -->|"debug"| PA14
    GND_U -->|"common"| PGND
    VBUS -.->|"LETHAL"| PA13

    style VBUS fill:#f44,color:#fff,stroke:#a00,stroke-width:3px
    style CC1 fill:#4a9,color:#fff
    style CC2 fill:#49a,color:#fff
    style PA13 fill:#6a6,color:#fff
    style PA14 fill:#6a6,color:#fff
    style SWDIO fill:#4a9,color:#fff
    style SWCLK fill:#49a,color:#fff
# USB-C Debug Accessory Mode: CC1โ†’SWDIO | CC2โ†’SWCLK | GNDโ†’GND
# โš ๏ธ 3.3V ONLY โ€” 5V probe = dead MCU | Need breakout + 5.1kฮฉ pull-downs
openocd -f interface/stlink.cfg -f target/n32g031.cfg \
  -c "init; halt; dump_image fw.bin 0x08000000 0x10000; exit"
# Got 0xFFFFFFFF? โ†’ FMC read-protection ON ๐Ÿ”’ โ†’ chip-erase (loses factory FW)
# Alt: SRAM injection via ISP (BOOT0 pin) or UART bootloader
ToolUse
ST-Link V2 / J-Link / CMSIS-DAPSWD debug โ€” 3.3V logic
Custom USB-C breakoutExpose CC1/CC2 + 5.1kฮฉ pull-downs
OpenOCD / pyOCDhalt โ†’ dump_image โ†’ flash write_image

3. ๐Ÿ“ฅ FW Extraction

flowchart TD
    A(["๐Ÿ”ฌ Connect SWD"]) --> B{"halt + dump?"}
    B -->|"got data"| C["๐Ÿ“Š Ghidra/IDA"]
    B -->|"0xFF..."| D{"๐Ÿ”’ FMC Locked"}
    D -->|"nuke it"| E["๐Ÿ’ฃ Chip Erase"]
    D -->|"bypass"| F["๐Ÿ’‰ SRAM Inject"]
    D -->|"alt"| G["๐Ÿ“ก UART Boot"]
    E --> H["โš ๏ธ Factory FW Gone"]
    H --> I(["๐Ÿ“ค Flash Custom"])
    F --> J["๐Ÿ”“ RAM Bypass"]
    G --> J
    J --> C
    C --> K["๐Ÿ—บ๏ธ Locate Bitmaps"]

    style A fill:#4a9,color:#fff
    style D fill:#f44,color:#fff,stroke:#a00,stroke-width:3px
    style H fill:#f80,color:#fff
    style E fill:#fa0,color:#000
    style I fill:#4c9,color:#fff
    style K fill:#69c,color:#fff

๐Ÿ”’ FMC Lock? If the memory dump gives you endless 0xFFFFFFFF, the Flash Memory Controller (FMC) is locked. Youโ€™ll need SRAM injection via ISP mode or a Whole Chip Erase (destroys factory firmware forever).


4. ๐ŸŽจ Display Mod

Pixel Format: RGB565 โ€” 16-bit color (5 bits Red, 6 bits Green, 5 bits Blue) stored in big-endian layout. ๐ŸŒˆ

flowchart LR
    A(["๐Ÿ–ผ๏ธ PNG"]) -->|"Pillow"| B["๐Ÿ“ 80x160"]
    B -->|"convert"| C["๐ŸŽจ RGB565"]
    C -->|"pack BE"| D["๐Ÿ“ฆ out.bin"]
    D -->|"desolder"| E["๐Ÿ”ง SSOP Adapt"]
    E -->|"program"| F["๐Ÿ’พ TL866/CH341A"]
    F -->|"resolder"| G(["โœ… Custom LCD"])

    style A fill:#69c,color:#fff
    style C fill:#e9973f,color:#fff
    style D fill:#a882ff,color:#fff
    style G fill:#4c9,color:#fff
# PNG โ†’ RGB565 binary (big-endian!) โ€” flash to GT25Q80A via TL866/CH341A/flashrom
from PIL import Image; import struct
img = Image.open('custom.png').convert('RGB').resize((80,160))
open('out.bin','wb').write(b''.join(
    struct.pack('>H',((r>>3)<<11)|((g>>2)<<5)|(b>>3))
    for y in range(160) for x in range(80) for r,g,b in [img.getpixel((x,y))]))
ProgrammerInterfaceNotes
MiniPro TL866SPI NORDesolder chip, SSOPโ†’DIP adapter
CH341ASPI NORCheapest option, clip or desolder
flashromCLIflashrom -p ch341a_spi -r dump.bin

5. ๐Ÿ–ฅ๏ธ LCD Init

sequenceDiagram
    participant MCU as MCU
    participant LCD as LCD

    rect rgb(68, 207, 110, 0.1)
        Note over MCU,LCD: Reset Phase
        MCU->>LCD: SWRESET 0x01
        Note over LCD: 150ms wait
        MCU->>LCD: SLPOUT 0x11
        Note over LCD: 500ms wait
    end

    rect rgb(83, 223, 221, 0.1)
        Note over MCU,LCD: Config Phase
        MCU->>LCD: COLMOD 0x3A 0x05 (RGB565)
        MCU->>LCD: MADCTL 0x36 (orientation)
        Note right of MCU: Bit3 = RGB/BGR swap
        MCU->>LCD: CASET 0x2A (col range)
        MCU->>LCD: RASET 0x2B (row range)
    end

    rect rgb(168, 130, 255, 0.1)
        Note over MCU,LCD: Activate Phase
        MCU->>LCD: DISPON 0x29
        MCU->>LCD: RAMWR 0x2C + pixels
    end
SWRESET(0x01) โ†’ SLPOUT(0x11) โ†’ COLMOD(0x3A,0x05=RGB565) โ†’ MADCTL(0x36) โ†’ DISPON(0x29)
  • ๐Ÿ”„ Red/blue swapped? XOR MADCTL with 0x08 (bit 3 toggles RGBโ†”BGR). Donโ€™t rewire.
  • โฌ› Black border/offset? Set CASET(0x2A)/RASET(0x2B) โ€” try _colstart=0x01 or 0x1A.
  • ๐Ÿ”ฒ GC9107 blank? Must send unlock 0xFFโ†’0xA5 before any command. Init may start 0xFE/0xEF/0xEB.

6. ๐Ÿ‘พ Custom FW

graph TD
    subgraph SDK["๐Ÿ“š Community SDKs"]
        A["ColorLCDVape-RE"] -->|"memory maps"| C["โšก Custom FW"]
        B["Vaporware SDK"] -->|"display API"| C
        D["RAZ-RE"] -->|"HW pinouts"| C
    end

    C -->|"compile"| E["๐Ÿ”ง arm-gcc"]
    E -->|"flash"| F["๐Ÿ“ค SWD Write"]
    F --> G(["๐ŸŽฎ Pocket Console"])

    subgraph SAFE["๐Ÿšจ Safety Critical"]
        C -->|"must have"| H["โฑ๏ธ Timer ISR"]
        H -->|"kills"| I["๐Ÿ”Œ MOSFET Off"]
        C -->|"must have"| J["๐Ÿ“Š ADC Watch"]
        J -->|"triggers"| K["๐Ÿ”‹ LVC Cutoff"]
    end

    style H fill:#f44,color:#fff,stroke:#a00,stroke-width:3px
    style J fill:#fa0,color:#000,stroke:#a50,stroke-width:2px
    style G fill:#4c9,color:#fff
    style I fill:#f44,color:#fff
    style K fill:#fa0,color:#000

โš ๏ธ THE COIL OF DEATH: If you write your own C code and your MOSFET pin latches HIGH by accident, your coil will melt, the pod will catch fire, and the battery will vent. ALWAYS code a strict hardware-timer-backed thermal cutoff limit! โฑ๏ธ๐Ÿšจ

๐Ÿ›ก๏ธ Safety Pattern

// MANDATORY: hardware-timer-backed coil cutoff โ€” main loop bugs CANNOT override
#define MAX_FIRE_MS 10000   // 10s hard ceiling
#define MIN_VBAT_MV 3000    // 3.0V low-voltage cutoff
 
void init_safety(void) {
    GPIO_ResetBits(GPIOA, COIL_PIN);              // default: coil OFF
    TIM_SetAutoReload(TIM3, MAX_FIRE_MS);          // ISR kills MOSFET
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
    ADC_AnalogWatchdogThresholdsConfig(ADC1, 0xFFF, MIN_VBAT_MV);
}

๐Ÿ“ฆ Deps & Tools

CategoryItemNotes
๐Ÿ”ง ProbeST-Link V2 / J-Link / CMSIS-DAPSWD debug โ€” 3.3V logic
๐Ÿ’พ ProgrammerMiniPro TL866 / CH341A / flashromSPI NOR read/write (desolder chip)
๐Ÿ–ฅ๏ธ DebugOpenOCD / pyOCDhalt โ†’ dump_image โ†’ flash write_image
๐Ÿ”ฌ REGhidra / IDA FreeARM Cortex-M0 disassembly
๐Ÿ ConvertPython + PillowPNGโ†’RGB565
โš™๏ธ Compilearm-none-eabi-gccCustom firmware cross-compile
๐Ÿ“š ColorLCDVape-REginbot86Memory maps, re-theming docs
๐Ÿ“š RAZ-RExbenkozxHW revision pinouts
๐Ÿ“š Vaporware SDKImoverEngineeringMinimal C SDK โ€” display only, no coil code

๐Ÿšจ Gotchas

TrapFix
๐Ÿ”ฅMOSFET latch-of-death โ€” GPIO HIGH on crash = coil melts โ†’ fire โ†’ battery ventHardware timer ISR kills MOSFET; never trust main loop
๐Ÿ”’FMC/ROP โ€” 0xFFFFFFFF dump = read-protectedChip-erase unlocks but destroys factory FW forever
โšก5V probe on 3.3V MCU = instant deathLevel-shift or use 3.3V probe
๐ŸงชNicotine residue on PCB absorbs through skinNitrile gloves + 99% IPA clean
๐Ÿ”„Same model โ‰  same chips โ€” HW revisions swap MCU/display/flashVerify markings every unit
๐Ÿ“RGB565 byte order โ€” 16-bit big-endian (5R/6G/5B)Garbled colors = wrong endianness
๐Ÿ“ฑUSB-C DAM โ€” standard cables donโ€™t expose CC1/CC2Custom breakout + 5.1kฮฉ pull-downs
๐ŸงŠSWD locked? โ†’ ISP via UART BOOT0 pinCheck N32G031 datasheet ยง3.4

๐Ÿ—๏ธ Full Architecture

graph TB
    subgraph L1["๐Ÿ”“ Physical"]
        A["๐Ÿ“ฆ Device"] -->|"pry open"| B["๐Ÿ”ง Teardown"]
        B -->|"99% IPA"| C["๐Ÿงน Clean"]
    end

    subgraph L2["๐Ÿ”Œ Debug"]
        C -->|"expose CC"| D["๐Ÿ”Œ USB-C Break"]
        D -->|"3.3V"| E["๐Ÿ”ฌ SWD Probe"]
        E -->|"connect"| F["๐Ÿ’ป OpenOCD"]
    end

    subgraph L3["๐Ÿ“ฅ Extract"]
        F -->|"halt"| G{"๐Ÿ”’ FMC?"}
        G -->|"unlocked"| H["๐Ÿ’พ MCU 64KB"]
        G -->|"locked"| I["๐Ÿ’ฃ Erase"]
        I -->|"blank MCU"| J["๐Ÿ†• Fresh"]
        F -->|"SPI read"| K["๐Ÿ’พ Flash 1MB"]
    end

    subgraph L4["๐ŸŽจ Mod"]
        H -->|"disasm"| L["๐Ÿ”ฌ Ghidra"]
        K -->|"extract"| M["๐Ÿ–ผ๏ธ Bitmaps"]
        M -->|"Pillow"| N["๐ŸŽจ RGB565"]
        N -->|"program"| O["๐Ÿ“ค Flash SPI"]
    end

    subgraph L5["๐Ÿ‘พ Custom OS"]
        L -->|"understand"| P["๐Ÿ“ Write FW"]
        P -->|"safety!"| Q["๐Ÿšจ ISR Guard"]
        Q -->|"deploy"| R(["โœ… Done"])
    end

    style I fill:#f44,color:#fff,stroke:#a00,stroke-width:2px
    style Q fill:#f80,color:#fff,stroke:#a50,stroke-width:2px
    style A fill:#69c,color:#fff
    style R fill:#4c9,color:#fff
    style G fill:#f44,color:#fff

๐Ÿ—บ๏ธ Visual workflow map: NovoModCanvas โ†’

startread firstfull docsreference