SearchA-ZF › Flipper Zero

Flipper Zero

2020 Open source On-board only Online

Flipper Zero is the open-source portable multi-tool emulated in the browser: the real FreeRTOS firmware, built from source, boots the playful dolphin desktop on an emulated STMicroelectronics STM32WB55 (an ARM Cortex-M4F). The 128x64 ST7565 LCD is rendered from the display byte stream, and the five-way pad and Back button drive the real inputs. Because the chip is ordinary JavaScript it plugs into this site's shared ARM debugger: single-step Thumb-2, read and write the registers, disassemble flash, and set breakpoints and write-watchpoints. This is honest from-source firmware, not the full official image, and the radio, SubGHz, NFC and USB peripherals are not emulated.

Runs on: Web browser

Flipper Zero Online Emulator

Play Flipper Zero using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
Flipper Desktop (FreeRTOS)Flipper ZeroFlipper ZeroopenOpen ⛶

Chips

Notes

Embedding

This is a two-layer stack: a real ARM CPU core underneath, and a from-scratch STM32WB55 + Flipper Zero board on top. It loads a real Cortex-M4F flash image and runs it on the actual on-chip peripherals — the real FreeRTOS 11 kernel (MIT) plus a Flipper-desktop GUI, built from source with the open arm-none-eabi-gcc toolchain. The RTOS runs on the emulated hardware; it is not a shim.

  • The CPU. cortex-m7.js executes Thumb-2. The real chip is a Cortex-M4F (ARMv7E-M + single-precision FPU); this core is ARMv7-M with an FPv5 single-precision VFP, a compatible superset, so it runs the M4 image unchanged. It implements the full exception model — NVIC, the 24-bit SysTick, SVC, PendSV, real exception entry/return — which is exactly what FreeRTOS needs to tick and context-switch.
  • Real reset. The image is a real STM32 flash image with the ARM vector table at 0x08000000: on reset the board loads SP from word 0 and PC from word 1, exactly like the silicon.
  • Real FreeRTOS. The firmware is the unmodified FreeRTOS-Kernel (V11.1.0, MIT) with the GCC ARM_CM4F port. vTaskStartScheduler arms SysTick, an SVC starts the first task, and every vTaskDelay/queue block triggers a PendSV context switch — all visible in the debugger.
  • The board, in JavaScript. flipper-board.js maps FLASH/SRAM/GPIO/SPI2/TIM16/RNG at their real STM32WB addresses, decodes the SPI2 byte stream into the ST7565 command/data protocol and 128x64 framebuffer, feeds the buttons in on their GPIO pins, and turns the TIM16 PWM into an audio tone.
PieceKindWhat it does
Flipper.create(canvas)factoryBuild the ARM core + the STM32WB memory map + peripherals.
load(bytes) / reset()methodCopy the image into FLASH; reset loads SP/PC from the vector table.
runFrame()methodStep ~300k instructions; SysTick fires several RTOS ticks per frame.
setKey(i,down)inputDrive a button GPIO level (0..5 = Up,Down,Right,Left,Ok,Back).
genAudio() / present()methodSquare-wave the speaker tone; draw the 128x64 LCD to the canvas.

Debugger integration

flipper-zero-debug.js reads window.EMU_BOOT and hands the shared debugger a genuine ARM Cortex-M4 machine — the same core the firmware runs on, exposed instruction-accurately.

  • Registers. registers() reads r0-r12, SP, LR, PC, xPSR, the APSR flags N/Z/C/V, and the VFP s0-s31 live each refresh; each has a set() that writes straight back into the core's register file.
  • Disassembly. FLASH is decoded with the shared cortex-m7 Thumb-2 disassembler, so the code window shows real ARM mnemonics at the real reset address 0x08000000.
  • Single-step. Step calls transport.stepInsn, advancing the core one Thumb instruction. You can watch a real exception entry on a SysTick tick (PC jumps to the handler, xPSR/IPSR changes, the frame is stacked) and the matching PendSV context switch (the scheduler saves one task's registers and restores another's), then the EXC_RETURN unstack.
  • Breakpoints & watchpoints. Execution breakpoints are a PC set the run-loop checks before each instruction; write watchpoints wrap the board's memory-write path and pause when a watched address is written. Both are real.
  • Memory map. Three chips read the real address space side-effect-free: FLASH (program, disassembled, 0x08000000), SRAM (0x20000000), and the GPIO block (0x48000000 — watch the button IDR and the display-control ODR change as you press keys and the GUI redraws).

Architecture

The Flipper Zero is a portable multi-tool built on an STMicro STM32WB55 — a dual-core wireless SoC whose application core is a 64 MHz ARM Cortex-M4F with 1 MB flash and 256 KB RAM (a second Cortex-M0+ runs the BLE/2.4 GHz radio stack). On board: a 128x64 monochrome ST7565R LCD, a 5-way navigation button + a Back button, and a piezo speaker. Its firmware is fully open-source (FreeRTOS-based).

  • Display — ST7565R over SPI2. 128x64, organised as 8 pages of 128 columns, each byte a vertical 8-pixel slice (LSB = top). The board decodes the real Flipper display-init sequence (0xE2 reset, 0xA2 bias, 0xA0/0xC8 SEG/COM direction, 0x24 ratio, 0x81+contrast, 0x2F power, 0xAF on) and the per-page 0xB0|page / 0x10|col≫4 / 0x00|col&0xF addressing, then streams the framebuffer. SPI pins: SCK PD1, MOSI PB15, CS PC11, DC PB1, RST PB0 — the real f7 wiring.
  • Buttons. Up PB10, Down PC6, Right PB12, Left PB11, Back PC13 are active-low with pull-ups; OK PH3 is active-high with a pull-down — exactly as in furi_hal_resources.c. The firmware's input task polls these from the GPIO IDR.
  • Speaker. A piezo on PB8 driven by TIM16 channel 1 PWM; the board reads the timer's prescaler/auto-reload/enable and synthesises the tone (freq = 64 MHz / ((PSC+1)(ARR+1))) through the shared audio sink.
  • FreeRTOS on real interrupts. The core's 24-bit SysTick drives the 1 kHz kernel tick; SVC starts the scheduler; PendSV performs every context switch; the NVIC priority masking (BASEPRI) protects critical sections. The firmware needs no other interrupt source — buttons are polled — so the board raises no external IRQs.
  • Second core — CPU2 over IPCC/SHCI. The STM32WB55 also carries a Cortex-M0+ that runs ST's BLE stack; the app core reaches it through the IPCC (0x58000C00) and a shared-memory mailbox. The board maps the full IPCC register set and High-Level-Emulates CPU2: it follows the reference table CPU1 publishes in SRAM2A, reads the SHCI/HCI command packets, and posts the responses back into the doubly-linked event queues over the real channel bits. On boot CPU2 posts its SHCI ready event (WIRELESS_FW_RUNNING), then answers SHCI_C2_BLE_Init and HCI_Reset, so the firmware's real BLE bring-up completes and reports the radio stack running. It is a faithful model of ST's transport-layer protocol, not a copy of ST's binary, and no CPU2 image is shipped.
  • Sub-GHz — a real CC1101 over SPI. The Flipper's sub-GHz radio is a TI CC1101 transceiver on the SPI_R bus (SPI1, SCK PA5, MISO PB4, MOSI PB5, chip-select PD0, GDO0 PA1 — the real f7 wiring). The board models the CC1101 on the far side of that bus: the datasheet header byte (R/W, burst, 6-bit address), the status-register burst convention, the command strobes (SRES/SCAL/SRX/SIDLE), the register file (FREQ2/1/0…), the chip-status byte and the FSM state. The firmware's Frequency Analyzer is the real furi_hal_subghz path: it resets the chip, reads VERSION (0x14) and PARTNUM (0x00), then sweeps the 433 MHz ISM band — programming the PLL, calibrating, entering RX and reading the RSSI status register at each step — and renders a live spectrum. There is no RF: the RSSI is answered from a synthetic on-board emitter (loopback) at 433.92 MHz, so the analyzer locks onto that test carrier. The SPI framing, chip-ID handshake, PLL programming and RSSI decode are real; the photons are not.
  • NFC — a real ST25R3916 over SPI. The Flipper's 13.56 MHz frontend is an ST ST25R3916 on the same SPI_R bus (SPI1, chip-select PE4, IRQ PA2 — the real f7 wiring). The board models the ST25R3916 on the far side: the datasheet SPI operation-mode byte (register write 0x00|addr, read 0x40|addr, FIFO load 0x80, FIFO read 0x9F, direct command 0xC0|cmd), the register file, the IC_IDENTITY (ic_type 5), the main IRQ status register (read-to-clear TXE/RXE), the 512-byte FIFO, and a synthetic Mifare Classic 1K tag. The firmware runs the real furi_hal_nfc / RFAL reader path: Set Default, read IC-identity, field on, then a real ISO14443A anticollision — Transmit REQA → ATQA, anticollision 0x93 0x20 → 4-byte UID + BCC (verified), SELECT 0x93 0x70 → SAK — and shows the card (UID 04 A1 B2 C3, ATQA 0004, SAK 08). Again there is no RF: the card is a synthetic on-board tag (loopback); the SPI framing, IC-identity read, direct commands, FIFO and the anticollision code path are real.
  • Infrared — real TIM capture + carrier. The Flipper's IR is a TSOP receiver on PA0 (TIM2_CH1 input capture) and an IR LED on PB9 driven by the TIM1 38 kHz carrier. Learn arms TIM2 input capture; the board's synthetic emitter feeds NEC edge timestamps, the firmware turns successive CCR1 captures into mark/space durations and decodes NEC (header + inverse-byte check), and the LCD shows the decoded address/command plus a capture waveform. Send encodes NEC and gates the TIM1 carrier (CR1.CEN) on/off for each mark/space using TIM2 as the microsecond time base; the board timestamps the carrier gating and decodes it back, so the frame round-trips. There is no IR light: the received frame is a loopback emitter and the transmitted carrier is decoded internally; the timing capture, NEC decode/encode and carrier gating are the real code path.
  • Larger HAL. On boot the firmware brings up the real clock tree (HSE + LSE + HSI48 + PLL, flash latency, SYSCLK switch), initialises the RTC calendar, and reads the battery through the ADC (VBAT) — all against the modelled RCC/PWR/FLASH/RTC/ADC registers.
  • Firmware. A purpose-built image (built from the real FreeRTOS-Kernel sources + an ST7565 driver mirroring Flipper's own st756x_flipper driver + the IPCC/SHCI bring-up mirroring ble_glue.c / ST's tl_mbox.c) that boots the RTOS, completes the dual-core BLE handshake, and renders the Flipper dolphin desktop, main menu and a Bluetooth status screen. It is not the full official flipperzero-firmware binary — that needs Flipper's whole build tree and a real CPU2 wireless binary. Honest limit: CPU2 is emulated only at the mailbox layer (no real Bluetooth controller, no 2.4 GHz RF, no advertising/connections/GATT). Sub-GHz drives a real CC1101, NFC a real ST25R3916, and Infrared a real TIM1/TIM2 capture+carrier path (analyzer + ISO14443A reader + NEC learn/send), but all with loopback RF/tag/IR sources, not photons; iButton/1-Wire and USB are still stubbed — no external media.

Sound

Pattern S (authored chip). The Flipper's only audio hardware is a piezo speaker on PB8 driven by a TIM16 PWM square wave. There is no PCM path — tone is pure frequency — so the board synthesises it directly from the timer registers. Each video frame genAudio() reads TIM16's CR1.CEN/CCER.CC1E enable, PSC and ARR, computes the output frequency as 64 MHz / ((PSC+1)(ARR+1)), and fills exactly round(EmuAudio.sampleRate/60) interleaved-stereo Int16 samples with a phase-continuous square wave (silence when the timer is off).

The GUI beeps on every key (a short ~70 ms tone at menu-click pitches), so navigating the menu is audible. Mute is the standard contract — transport.setMute/isMuted delegate to EmuAudio, and it starts muted until the on-page Sound button is clicked (browsers block audio before a gesture).