⚠️ DISCLAIMER: USE AT YOUR OWN RISK This firmware is provided "as is", without warranty of any kind. You use this firmware entirely at your own risk. It is highly recommended to have an ST-Link programmer available to recover your device in case you encounter bugs, errors, or a failed firmware update.
This is a community fork of the Monstatek/M1 repository. Pre-compiled
.binand.hexfiles can be downloaded from the Releases section, or you can build the firmware yourself following the instructions below.
Firmware for the M1 NFC/RFID multi-protocol device, built on STM32H5.
The M1 firmware provides support for:
- NFC (13.56 MHz)
- LF RFID (125 kHz)
- Sub-GHz (315–915 MHz)
- Infrared (IR transmit/receive) — including Universal Remote (this fork)
- Battery monitoring
- Display (JHD12864-G386BTW, 128x64 pixels, SPI)
- USB (CDC, MSC)
- MCU: STM32H573VIT6 (32-bit, 2MB Flash, 100LQFP)
- Hardware revision: 2.x
See HARDWARE.md for more details.
- Build Tool (mbt) – Build with STM32CubeIDE or VS Code
- Stability Validation – Reproducible validation for Issues #22/#26/#27
- Architecture – Project structure
- Development – Development guidelines
- Changelog – Release history (see ARCHITECTURE.md for versioning logic)
- STM32CubeIDE 1.17+ (recommended), or
- VS Code with ARM GCC 14.2+, CMake Tools, Cortex-Debug, and Ninja
The CMakePresets.json expects the ARM toolchain at:
C:/Program Files (x86)/Arm/GNU Toolchain mingw-w64-i686-arm-none-eabi/bin/
Adjust the path in CMakePresets.json if your toolchain is installed elsewhere.
Quick Build (Recommended):
(Note: The
./buildconvenience script is exclusive to this fork and was not part of the upstream Monstatek release.)
./build # Build firmware and copy to distribution/
./build clean # Clean build artifacts and rebuildThis script automatically:
- Configures the build (if needed)
- Compiles the firmware
- Appends the required CRC32 checksum and image size metadata to
.bin - Generates
.hexfrom that post-processed.bin(not directly from.elf) - Copies all output files to
distribution/
Important for v0.8.5+ boot integrity checks:
- Always flash artifacts generated by the local
./buildscript (or CI release assets built the same way). - Do not generate your own
.hexfrom.elffor production flashing, because it will not contain the post-build CRC/image-size metadata required by early boot verification.
STM32CubeIDE:
Open the project and build in the IDE. Output: ./Release/MonstaTek_M1_v0809-UFO.elf
Manual CMake build:
cmake --preset gcc-14_2_build-release
cmake --build out/build/gcc-14_2_build-release --target M1_v0.8.11-UFOOutput files (in distribution/ or out/build/gcc-14_2_build-release/):
| File | Use |
|---|---|
M1_v0.8.11-UFO.bin |
STM32 firmware (includes CRC32) |
M1_v0.8.11-UFO.hex |
STM32CubeProgrammer / JLink |
M1_v0.8.11-UFO.elf |
Debug sessions |
For rapid development and debugging, use an ST-Link programmer connected to the M1's GPIO header pins. This avoids repeatedly opening the case to disconnect the battery.
Connect to the GPIO header (pins 1-18):
| ST-Link | M1 GPIO Pin | Function |
|---|---|---|
| VCC (3.3V) | Pin 9 (+3.3v) | Power |
| GND | Pin 8 or 18 (GND) | Ground |
| SWDIO | Pin 11 (PA13) | Data |
| SWCLK | Pin 10 (PA14) | Clock |
- Connect ST-Link to GPIO pins
- Connect USB for power and serial console
- Open serial terminal (PuTTY/Tera Term) at 9600 baud - keep open for logs
- Build firmware:
./build
- Flash with STM32CubeProgrammer:
- Click "Connect"
- Click "Open File" → Select
distribution/M1_v*.hex - Click "Program"
- Reset via ST-Link:
- Click "Reset" button in STM32CubeProgrammer
- OR use CLI command
rebootin serial terminal
Pro tip: Keep the serial terminal open during testing to see debug messages in real-time.
If the device does not boot after programming:
- Use Under Reset + Hardware reset connect mode in STM32CubeProgrammer.
- If PC reads near
0xFFFFFFFE, the mapped boot vector is invalid (often from flashing an image that does not match post-build CRC metadata). Rebuild with./build cleanand reflashdistribution/M1_v*.hex.
If you need to flash the firmware directly via USB using STM32CubeProgrammer (without an ST-Link), you must boot the device into DFU Mode using the hardware strap. The software menu option has been removed for reliability.
- Unplug the USB cable from the M1.
- Press and hold the UP button on the D-pad.
- While holding UP, plug the USB cable back in.
- You will hear a loud "tick" from the speaker. This confirms the hardware strap was detected and the device is now in DFU mode.
- In STM32CubeProgrammer, select USB from the dropdown menu and click Connect.
To exit DFU mode: Simply unplug the USB cable and plug it back in without holding any buttons to boot into normal firmware.
The M1 exposes a USB serial console for debugging and control.
Connection Settings:
- Port: COM3 (or whatever port the M1 appears as)
- Baud Rate: 9600
- Data Bits: 8
- Stop Bits: 1
- Parity: None
- Flow Control: None
Terminal Programs:
- Windows: PuTTY, Tera Term, or Arduino Serial Monitor
- Command Line:
screen /dev/ttyACM0 9600(Linux/Mac)
With USB connected and a terminal at 9600 baud, type help for available commands:
System Commands:
version- Show detailed firmware version (e.g., "0.8.11.0-UFO")status- System status, active bank, and build inforeboot- Software reset (no need to disconnect battery!)memory- Show RAM/Flash usage statisticslog- Display recent debug log messages
Hardware Status:
sdcard- SD card mount status and capacitywifi- ESP32 WiFi module statusbattery- Battery level and charging status
Utility:
cls- Clear the terminal screenmtest- Multi-purpose test commandhelp- List all available commands
Example Session:
cli> version
M1 Firmware Version:
0.8.11.0-UFO
cli> status
System Status:
Firmware: v0.8.11.0
Active Bank: 1
cli> reboot
Rebooting...
The serial console is invaluable for debugging firmware updates and other issues:
Debugging Firmware Update Failures:
- Keep the serial terminal open at 9600 baud
- Navigate to Settings → Firmware Update → Image file
- Select a .bin file
- Watch the debug output showing:
- Filename validation
- File size checks
- CRC validation
- Error messages if something fails
Common Debug Messages:
FW Update: File selected=1
Filename: 'M1_v0.8.2-ChrisUFO.bin' (len=22)
Dot found at index 18, ext len=4
Extension: '.bin'
File type OK
Full path: 0:/M1_v0.8.2-ChrisUFO.bin
File opened successfully
FW file size: 1047576 bytes
The M1 has two separate firmware components that can be updated:
This is the primary firmware that runs the M1 device.
File: MonstaTek_M1_v0802-ChrisUFO.bin (includes embedded CRC32 checksum)
- Copy the
.binfile to your SD card (any folder) - Insert the SD card into the M1
- Navigate to Settings → Firmware Update → Image file
- Browse to and select
MonstaTek_M1_v0802-ChrisUFO.bin - Confirm — the device validates the embedded CRC32, flashes the firmware, and reboots automatically
Note: The build system automatically appends a 4-byte CRC32 checksum to the end of the .bin file for validation during the update process.
You can also flash STM32 firmware over USB using the built-in STM32 ROM DFU bootloader.
On device:
- Open Settings -> Firmware update -> USB DFU mode
- Confirm entry (RIGHT/OK)
Quick checklist before entering DFU:
- CRITICAL: Physically disconnect any ST-Link debuggers. The STM32H5 BootROM will lock out USB enumeration if it detects active SWD lines. The ST-Link 3.3V supply will also mask the USB disconnect event from the host PC.
- Use a USB data cable (not charge-only)
- Power the board via the USB cable ONLY.
- Keep battery above 50%
- Close serial terminal apps that may hold the USB interface
CLI shortcut:
dfuOn host (example with dfu-util):
dfu-util -a 0 -D MonstaTek_M1_v0802-ChrisUFO.binIf dfu-util does not detect the device, use STM32CubeProgrammer in USB mode and verify USB cable/data support.
Troubleshooting and recovery:
- If DFU does not enumerate: unplug/replug USB, retry DFU entry, then use STM32CubeProgrammer USB connect flow
- If transfer fails mid-way: re-enter DFU and retry flashing; do not power off during transfer
- If app boot fails after a bad flash: recover over SWD (ST-Link + STM32CubeProgrammer) at
0x08000000
Automatic Exit (v0.8.10+): This fork includes a 32-second watchdog safety net. If you unplug the USB cable or lose connection while in DFU mode, the device will automatically reboot into normal firmware after 32 seconds.
Visual Indicator (v0.8.11+): A discrete LED (PD12/PD13) will turn on to confirm the device has entered DFU mode.
STM32CubeProgrammer Tip: To ensure the device boots into your new firmware immediately after flashing, check the "Run after programming" box in the "Erasing & Programming" tab before starting the transfer.
Tested matrix (current fork):
| Item | Tested |
|---|---|
| Device | M1 (STM32H573VIT6), HW rev 2.x |
| Host OS | Windows 11 |
| DFU host tools | dfu-util (CLI), STM32CubeProgrammer (GUI/CLI) |
| Entry methods | On-device menu entry, CLI dfu |
Known limitations:
- No dedicated hardware button-chord DFU entry is implemented yet
- If
arm-none-eabi-objcopyis not available in PATH, CMake still builds.elfbut skips.bin/.hexpost-build artifacts
This firmware is for the ESP32-C6 wireless module and uses a different update mechanism.
Files required:
esp32_firmware.bin(the ESP32 firmware image)esp32_firmware.md5(MD5 checksum file)
- Copy both files to your SD card under
/0:/esp32/ - Navigate to Settings → ESP32 Firmware Update
- Select the firmware file
- The device validates the MD5 checksum before flashing
Note: The ESP32 firmware requires both .bin and .md5 files with matching names.
The Universal Remote feature lets the M1 browse and transmit IR commands from
Flipper Zero-compatible .ir files
stored on the SD card.
Navigate to Infrared → Universal Remote on the device.
The feature starts with a Dashboard offering:
- Favorites: Quick access to pinned remotes.
- Recent: Last 10 used remotes.
- Search: Find remotes by name using the virtual keyboard.
- Browse Database: Traditional folder-based navigation.
Navigation:
- Use Up/Down to scroll through menus and lists.
- Press OK to select or transmit.
- Press Back to go up a level.
- Use Left/Right for fast scrolling in long lists.
The device expects .ir files organised as follows on the SD card:
SD card root:
IR/
<Category>/
<Brand>/
<Device>.ir
Example:
IR/
TV/
Samsung/
Samsung_BN59-01315J.ir
LG/
LG_AKB75095307.ir
Sony/
Sony_RMT-TX100D.ir
AC/
Daikin/
Daikin_ARC433B69.ir
Mitsubishi/
Mitsubishi_MSZ.ir
Projector/
Epson/
Epson_EH-TW.ir
The Flipper-IRDB project (MIT License)
provides a large community-maintained database of .ir files compatible with this
feature. Download the repository and copy the desired category folders into the
IR/ directory on your SD card.
git clone https://github.com/Lucaslhm/Flipper-IRDB
# Then copy e.g.:
cp -r Flipper-IRDB/TV /path/to/sdcard/IR/
cp -r Flipper-IRDB/AC /path/to/sdcard/IR/**The M1 supports virtually unlimited items per folder using Pagination. You can browse large categories (like the massive TV database) without issues.
NEC, NECext, NEC42, NEC16, RC5, RC5X, RC6, RC6A, Samsung32, Samsung48, SIRC, SIRC15, SIRC20, Kaseikyo, Denon, Sharp, JVC, Panasonic, LGAIR
This section documents every menu item in the firmware, its current implementation status, and — for stubs — the estimated effort and pen-testing value of completing it.
| Symbol | Meaning |
|---|---|
| ✅ | Fully functional |
| Stub / placeholder (shows "firmware update" screen or empty loop) | |
| 🚫 | Disabled — code exists but item is commented out of the menu |
| Menu Item | Status | Notes |
|---|---|---|
| Record | ✅ | Full pipeline: SI4463 capture → decode → save to SD card |
| Replay | ✅ | Browse SD card files, transmit saved signal |
| Frequency Reader | ✅ | Scans spectrum, shows strongest frequency |
| Regional Information | ✅ | Displays regional frequency band info |
| 🚫 | Function exists but not in menu — only 4 items in submenu |
Menu Structure: Sub-GHz → {Record, Replay, Frequency Reader, Regional Information}
Missing feature: Radio Settings — Function exists but is not included in the current menu. Adding it would enable custom modulation for rolling-code attacks. Low effort, High value.
| Menu Item | Status | Notes |
|---|---|---|
| Universal Remote | ✅ | Browse Flipper-IRDB .ir files on SD card, transmit commands (this fork) |
| Learn New Remote | ✅ | IRMP decode, displays protocol/address/command, saves to SD card |
| Saved Remotes | ✅ | Browse saved signals, replay last learned signal |
| Menu Item | Status | Notes |
|---|---|---|
| Read | ✅ | EM4100 and H10301 decode |
| Saved | ✅ | Emulate, write to T5577, edit, rename, delete, info |
| Add Manually | ✅ | Enter card data manually |
| 125 kHz Utilities | rfid_125khz_utilities() is an empty loop — no utility screens implemented |
Stub effort/value: 125 kHz Utilities — Medium effort (implement brute-force facility code scanner, raw read/write, T5577 config), High value (T5577 raw write and facility-code brute-force are core pen-testing primitives; Flipper Zero's lfrfid and lfrfid_worker are directly portable since the M1 already uses the same lfrfid library).
| Menu Item | Status | Notes |
|---|---|---|
| Read | ✅ | ISO14443A/B/F/V, Ultralight/NTAG, Mifare Classic |
| Saved | ✅ | Emulate, edit UID, rename, delete, info |
| NFC Tools | nfc_tools() calls m1_gui_let_update_fw() — no tools implemented |
Stub effort/value: NFC Tools — Medium effort (implement card-info dump, NDEF read, Mifare Classic sector auth brute-force), High value (Mifare Classic dictionary attack and NDEF inspection are the most-requested NFC pen-testing features; Flipper Zero's nfc app and nfc-laboratory are good references; the M1 already has the ST RFAL stack).
| Menu Item | Status | Notes |
|---|---|---|
| Scan AP | ✅ | ESP32-C6 scan — shows SSID, BSSID, RSSI, channel, auth type |
| WiFi Config | ✅ | Join network, manual hidden SSID entry, encrypted saved credentials, status view, disconnect |
Implemented: WiFi Config now supports AP scan selection, manual SSID entry, password entry with show/hide toggle, encrypted credential storage, saved-network management (delete + auto-connect toggle), and status/disconnect flow.
| Menu Item | Status | Notes |
|---|---|---|
| Scan | ✅ | BLE device scan, shows device name and RSSI |
| Advertise | ✅ | BLE advertisement broadcast |
| Bluetooth Config | bluetooth_config() calls m1_gui_let_update_fw() — no config UI |
Stub effort/value: Bluetooth Config — Low effort (expose advertisement name/interval/payload settings), Medium value (custom advertisement payloads enable BLE spoofing attacks; Apple/Samsung proximity spam is a popular pen-testing demo).
| Menu Item | Status | Notes |
|---|---|---|
| Manual Control | ✅ | Toggle individual GPIO pins |
| 3.3 V Power | ✅ | Enable/disable 3.3 V rail |
| 5 V Power | ✅ | Enable/disable 5 V rail |
| USB–UART Bridge | gpio_usb_uart_bridge() calls m1_gui_let_update_fw() — no bridge UI |
Stub effort/value: USB–UART Bridge — Low effort (route USB CDC ↔ UART peripheral; HAL plumbing already exists in m1_usb_cdc_msc.c), High value (UART bridge is essential for serial console access to target devices during hardware pen-testing).
| Menu Item | Status | Notes |
|---|---|---|
| Storage | ✅ | SD card management: About, Explore, Mount, Unmount, Format |
| Power | ✅ | Battery Info, Reboot, Power Off |
| LCD & Notifications | 🚫 | Menu entry commented out — placeholder only |
| System | 🚫 | Menu entry commented out — placeholder only |
| Firmware Update | ✅ | Browse SD card for .bin, flash via bank-swap updater, or enter ROM USB DFU mode |
| ESP32 Update | ✅ | ESP32-C6 WiFi/BT module firmware update via SD card |
| About | ✅ | Shows firmware version and device info |
Menu Structure: Settings → {Storage, Power, Firmware Update, ESP32 Update, About}
Disabled item effort/value:
- LCD & Notifications — Low effort (re-enable menu entry, implement brightness/contrast/notification LED controls), Medium value (quality-of-life; needed before shipping).
- System — Low effort (re-enable menu entry, implement device name, date/time, reset-to-defaults), Medium value (needed for a complete product experience).
Based on pen-testing value and implementation effort, here is the suggested priority:
| Priority | Feature | Effort | Value | Rationale |
|---|---|---|---|---|
| 1 | USB–UART Bridge | Low | High | HAL already wired; one-screen UI; critical for hardware hacking |
| 2 | Sub-GHz Radio Settings | Low | High | Unlocks custom modulation for rolling-code research |
| 3 | 125 kHz Utilities | Medium | High | T5577 raw write + facility-code brute-force; lfrfid lib already present |
| 4 | NFC Tools | Medium | High | Mifare Classic dict attack; ST RFAL stack already present |
| 5 | Settings: LCD & Notifications | Low | Medium | Re-enable + implement; needed for product completeness |
| 6 | Settings: System | Low | Medium | Re-enable + implement; needed for product completeness |
| 7 | Bluetooth Config | Low | Medium | BLE spoofing/spam payloads |
| 8 | WiFi Config | Low–Med | Medium | Network join via existing SPI-AT AT+CWJAP command |
| Feature | Reference |
|---|---|
| LF RFID utilities / T5577 | flipperdevices/flipperzero-firmware — lfrfid |
| NFC / Mifare Classic attack | flipperdevices/flipperzero-firmware — nfc |
| Sub-GHz modulation / RAW | flipperdevices/flipperzero-firmware — subghz |
| BLE advertisement spam | ECTO-1A/AppleJuice |
| NFC protocol analysis | josevcm/nfc-laboratory |
| IR database | Lucaslhm/Flipper-IRDB |
Contributions are welcome. See CONTRIBUTING.md and the Code of Conduct.
To contribute to the upstream project, please open pull requests against Monstatek/M1.
See LICENSE for details.