MeshCore Ninja
← Meck-P4

Meck-P4 · Releases

from GitHub · updated 2026-06-21

12 releases

  1. v0.6.2-patch # Pre-release 7 days ago · 2026-06-14 19:48 UTC

    Meck P4 v0.6.2 Pre-release (Patch): Trace and notification fixes

    Point release on top of v0.6.1. Two bug fixes, no new features. Firmware identity is now 0.6.2.

    Bug Fixes

    Multi-byte trace path parsed as single-byte

    Running a path trace in 2-byte mode returned a wrong result. The response was parsed as if it were 1-byte, so it reported twice as many hops as actually existed, each one resolved to the wrong repeater. As an example, a two-hop 2-byte trace of 3601,2198 came back as four hops (36, 01, 21, 98) matched against unrelated repeaters.

    The cause was in the trace-response handler: the hop count and hash size were taken from the wrong source. The byte length handed up from the base layer was being read with the packet-header path encoding, which collapses to 1-byte mode for any short path. The real hash size is carried separately in the trace flags.

    The handler now reads the hash size from the trace flags and computes the hop count as the path byte length divided by bytes-per-hop. 1-byte traces were already correct and are unchanged. 2-byte traces now report the right hop count and resolve to the correct repeaters.

    Custom notification sounds not playing

    Custom per-channel notification tones stopped playing as of v0.6 (they worked in v0.5). A tone could be selected and would show as set, but nothing played when a message arrived on that channel.

    The cause was the v0.6 audio rework, which split file preparation from playback start. The notification trigger prepared the tone file but never issued the start, so it sat ready and silent.

    The notification path now starts playback after preparing. The same missing start also affected the tone-picker preview and voice-message playback, both fixed by the same change.

    Files Changed

    3 files changed (MeckMesh.h, MeckUI.cpp, meck.h).

    First-Time Flashing: Read This First

    Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting, channel message, DM, room post, and note is mirrored or stored on the card, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot, and the Reader, Notes, and notification sounds have no storage.

    Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash. correct port usage for flashing

    Flashing with the MeshCore Web Flasher (recommended)

    1. Go to https://flasher.meshcore.io/
    2. Scroll to the bottom and select Custom Firmware
    3. Select the meck-p4-0.6.2.bin file you downloaded
    4. Click OK on the merged-binary warning
    5. Click Flash, pick your device in the popup, and click Connect

    Flashing with esptool.py

    pip install esptool
    esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.6.2.bin
    

    (Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

    Upgrading from v0.6.1 or v0.6 does not require erase_flash. This patch changes program logic only and adds no new settings, so existing prefs carry over unchanged.


    For the full feature list see the README.

    Reporting Issues

    The Meck-P4 channel on the MeshCore Discord is the fastest path. GitHub Issues on the Meck-P4 repo also work for anything reproducible. Include the serial log if you can: Settings > Debug Logs > Start capt …

  2. v0.6.1-patch # Pre-release 11 days ago · 2026-06-10 03:42 UTC

    Point release on top of v0.6, adding a software LoRa antenna selector in Settings. No other functional changes. Firmware identity is now 0.6.1.

    Antenna Switch

    A new Antenna (tap to toggle) row at the top of Settings, switching the SX1262 between the two ports on the SKY13453 RF switch (XL9535 IO1 / VCTL).

    • Internal (RF1) is the default and corresponds to VCTL HIGH; External (RF2) is VCTL LOW. The internal antenna is the one in use when no external antenna is attached, so the device works out of the box without changing this.
    • The choice persists via prefs (NVS, mirrored to SD) and is re-applied at boot, so the selected port survives a reboot.
    • Tap applies live: the pin is driven immediately and the row label updates to show the active port.

    Bug Fixes

    None.

    Files Changed

    5 files changed.

    First-Time Flashing: Read This First

    Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting, channel message, DM, room post, and note is mirrored or stored on the card, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot, and the Reader, Notes, and notification sounds have no storage.

    Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash.

    Flashing with the MeshCore Web Flasher (recommended)

    1. Go to https://flasher.meshcore.io/
    2. Scroll to the bottom and select Custom Firmware
    3. Select the meck-p4-0.6.1.bin file you downloaded
    4. Click OK on the merged-binary warning
    5. Click Flash, pick your device in the popup, and click Connect

    Flashing with esptool.py

    pip install esptool
    esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.6.1.bin
    

    (Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

    Upgrading from v0.6 does not require erase_flash. The prefs loader tolerates the older layout, and the new antenna field comes up at its default (Internal).


    For the full feature list see the README.

    Reporting Issues

    The Meck-P4 channel on the MeshCore Discord is the fastest path. GitHub Issues on the Meck-P4 repo also work for anything reproducible. Include the serial log if you can: Settings > Debug Logs > Start captures it to SD if a serial monitor isn't practical.

    License

    MIT for Meck-specific code. The combined firmware binary links libraries with mixed licensing including GPL-3.0 and LGPL-2.1 (Codec2) and is effectively GPL-3.0 when distributed.

  3. v0.6 # Pre-release 12 days ago · 2026-06-09 22:14 UTC

    Feature release building on v0.5, adding a reader-mode web browser over the ESP32-C6, a Notes app, EPUB book support in the reader, a Cyrillic keyboard layout, optional M5Stack CardKB hardware-keyboard support, and a portrait/landscape orientation toggle, alongside several bug fixes. Firmware identity is now 0.6.

    Web Reader

    A lightweight reader-mode web browser on the new Web home tile, running over the onboard ESP32-C6. It drives the C6 directly over ESP-AT, building its HTTP and TLS requests by hand, so it shares the WiFi companion's C6 link but uses its own request path. The C6 must be connected to WiFi for it to fetch anything.

    • Landing menu with Enter URL, a DuckDuckGo Lite search, Bookmarks, and History.
    • Reader view: pages are parsed to readable text with a status line. Headings render in dark red; link markers show as a muted grey [N] and are followed from the Links panel.
    • HTTPS support, confirmed against DuckDuckGo Lite.
    • GET form fill: an orange Forms (N) button opens a picker (duplicate forms collapsed), then a fill modal with a labelled field per text or password input. Submitting builds the action?name=value&... query and loads it through the normal page path, so history and status stay correct.
    • Bookmarks (added from the reader view with a confirmation toast) and History.
    • This is a work in progress: an amber notice appears for a few seconds each time the Web tile is opened. See Known Limitations below and the README for the full list.

    EPUB Reading

    The reader now opens EPUB (.epub) files in addition to plain text. The file list shows folders, .txt, and .epub items.

    • Tapping an EPUB converts it to plain text the first time it is opened. A Converting ... to txt screen is shown while the book is decoded.
    • The result is cached as a .txt in a hidden .epub_cache subfolder, so re-opening the same EPUB later loads straight from the cache and the conversion only runs once.
    • You only ever see and tap the .epub itself; the cached text stays hidden from the browser.

    Notes

    A Notes app on the Notes home tile. Notes are plain UTF-8 .txt files stored under /sdcard/notes, so they live on the removable card, survive a reflash, and can be read or edited on a computer. The folder is created automatically on first run.

    • Browser modelled on the reader's: folder navigation, an up-one-level button, and a breadcrumb, rooted at /sdcard/notes. A green + New Note row sits at the top of every folder.
    • Create and edit with the on-screen keyboard (which honours the KB Theme and KB Layout settings). New notes are named by date and time when the clock is synced (note_YYYYMMDD_HHMM.txt), or sequentially (note_NNN.txt) otherwise.
    • Read view reuses the reader's paging: left third of the screen turns back, right two-thirds turns forward, with a progress percentage and a saved-position bookmark.
    • Long-press a note for an action menu with Rename, Delete (with confirmation), and Cancel.

    Cyrillic Keyboard

    A fourth on-screen keyboard layout, ЙЦУКЕН (Cyrillic), added to the Settings > KB Layout cycle alongside QWERTY, AZERTY, and QWERTZ.

    • Standard Russian arrangement, also commonly used by Bulgarian users. The top three rows carry twelve letters each, with ё on the third row.
    • The control keys keep their Latin labels (ABC / abc / 1#) so case and number switching still work.
    • Ukrainian and Serbian letter sets are not included. The Settings row shows "ЙЦУКЕН" when this layout is active.

    Physical Keyboard (M5Stack CardKB)

    Optional support for the M5Stack CardKB, a small I2C QWERTY keyboard, as an alternative to the on-screen keyboard for typing messages. Gated behind the MECK_CARDKB build flag (a build-from-source option).

    • Connects to the board's P1 connector (the 1x4 header) as a software-I2C bus on SDA = GPIO 48 and SCL = GPIO 47, at 10 kHz, address 0x5F. Probed for …
  4. v0.5 # Pre-release 23 days ago · 2026-05-29 09:24 UTC

    Feature release building on v0.4, adding a plain-text reader, inline colour emoji with a picker, over-the-mesh repeater administration from the companion app, audio player fixes, and draft message saving. Firmware identity is now 0.5.

    Text Reader

    • New plain-text (.txt) reader, opened from the home grid's Reader tile. Folder browser rooted at /sdcard/books with subfolder navigation, a breadcrumb, and an up-one-level button.
    • Windowed, page-at-a-time rendering: the reader never loads the whole book, so memory and layout cost stay fixed to one screen regardless of file size. LVGL's own layout finds each page boundary at a clean line break.
    • Per-book resume across reboots via a .pos sidecar, plus page-back through the pages visited in the current session.
    • Percentage progress through the file.
    • Reading-view taps: the left third turns back a page, the right two-thirds turns forward. Back returns to the browser; the browser's Back goes up a folder, or home at the /sdcard/books root.
    • Honours the Settings font-size preference.

    Inline Emoji

    IMG_3256 IMG_3255
    • Inline colour emoji across the UI. A per-size LVGL image-font (lv_imgfont) is attached as the fallback of each meck_montserrat_* font, so emoji codepoints the text font can't draw are rendered from baked-in Twemoji images instead of a missing-glyph box. Requires CONFIG_LV_USE_IMGFONT=y.
    • Emoji picker: a modal scrollable grid opened from the emoji key on the message-composer keyboards, inserting the chosen emoji as UTF-8. Dark-theme aware.
    • Expanded emoji set.
    • The emoji key moved to the right side of the space bar on the composer keyboards.
    • VS-16 presentation selector and the AU-flag regional indicators are handled so trailing combiners don't render as boxes.

    Repeater Admin (Companion App)

    Over-the-mesh repeater administration from the MeshCore app. The app's session state is kept separate from the on-device Repeater Admin screen, so the two can't capture each other's responses.

    • CMD_SEND_LOGIN (26): log in to a repeater from the app (force-flood for the login itself, out_path restored afterwards, sync_since reset for room contacts).
    • CMD_SEND_STATUS_REQ (27): request a repeater's status block; matched back to the app by tag.
    • CMD_HAS_CONNECTION (28): query whether a keep-alive session is active for a contact.
    • CMD_LOGOUT (29): end the keep-alive session for a contact.
    • CMD_SEND_BINARY_REQ (50): generic binary request (GET_NEIGHBOURS, ACL queries, owner info, and so on), forwarded verbatim and matched by tag. This is the path behind the app's neighbours command.
    • Push notifications: login success (0x85), login fail (0x86), status response (0x87), and binary response (0x8C). CLI text replies are queued to the app through the existing offline-message path (TXT_TYPE_CLI_DATA). Frame layouts mirror upstream byte-for-byte, so the app parses them with no protocol-version negotiation.
    • Pushes are delivered to both the BLE and WiFi companions.

    Audio Player

    • Track-skip fix: fixed a cascade where an entire album would skip through in under a second. The end-of-track flag was being set on every player IDLE event, including the internal stop that fires when advancing to the next track, so each advance immediately triggered another. The flag is now set only on a genuine track completion.
    • Bookmarks scoped to audiobooks: resume bookmarks are kept only for files under /sdcard/audio/audiobooks. Music and other audio always start from the beginning, so finishing a short track no longer leaves a near-end position that made it skip on reopen, and no stray bookmark files are written for music.
    • **Tappable now-playing ind …
  5. v0.4 # Pre-release 24 days ago · 2026-05-28 08:09 UTC

    Feature release building on v0.3.8, adding WiFi companion app support, companion protocol compatibility, power optimisation, and stability improvements.

    WiFi Companion Support

    • Full WiFi companion transport via ESP32-C6 AT commands over SDIO. Connect the MeshCore app to your T-Display P4 over your local WiFi network (TCP port 5000).
    • WiFi SSID and password configuration from the device Settings screen.
    • WiFi IP address displayed on the home screen and settings page with live refresh.
    • WiFi-aware sleep: when WiFi is active, the display dims to zero brightness instead of entering light sleep (which would kill the SDIO bus and TCP connection). Touch or boot button wakes the screen.

    Companion Protocol

    Extensive companion protocol implementation for MeshCore app compatibility:

    • CMD_DEVICE_QUERY (22): Full device info response including firmware version, build date, model, path hash mode.
    • CMD_APP_START (1): Identity, radio params, and position shared with the app on connection.
    • CMD_GET_CONTACTS (4): Full contact iteration with streaming and incremental sync (since timestamp).
    • CMD_SEND_CHANNEL_TXT_MSG (3): Send channel messages from the app, with own-echo detection so the app shows "Heard X Repeats".
    • CMD_SET_ADVERT_NAME (8): Set node name from the app.
    • CMD_SET_RADIO_PARAMS (11): Set frequency, bandwidth, spreading factor, coding rate (reboot to apply).
    • CMD_SET_RADIO_TX_POWER (12): Set TX power.
    • CMD_SET_ADVERT_LATLON (14): Set position for adverts.
    • CMD_REMOVE_CONTACT (15): Delete contacts from the app.
    • CMD_EXPORT_PRIVATE_KEY (23): Export identity for config backup.
    • CMD_IMPORT_PRIVATE_KEY (24): Import identity for config restore.
    • CMD_GET_CONTACT_BY_KEY (30): Look up contact by public key (required for app-side delete).
    • CMD_SET_CHANNEL (32): Import/update channel name and secret from the app.
    • CMD_SET_OTHER_PARAMS (38): Set manual add, advert location policy, multi-acks.
    • CMD_GET_CUSTOM_VARS (40): Returns GPS state, interval, latitude, longitude for the app's Position Settings page.
    • CMD_SET_CUSTOM_VAR (41): Toggle GPS on/off, set latitude/longitude from the app.
    • CMD_GET_ADVERT_PATH (42): Returns cached advert path hashes so the app can display route details with repeater names.
    • CMD_SET_FLOOD_SCOPE_KEY (54): Acknowledged (stub).
    • CMD_SET_PATH_HASH_MODE (61): Set path hash size (1-byte, 2-byte, or 3-byte) from the app's Experimental Settings.
    • CMD_SET_DEFAULT_FLOOD_SCOPE (63): Set/clear default region scope from the app.
    • CMD_GET_DEFAULT_FLOOD_SCOPE (64): Returns current scope name and key.
    • Push notifications: Channel messages, DM messages, send confirmations (acks), new adverts, and path updates are all pushed to the app in real time.

    Channel Expansion

    • Channel support expanded from 12 to 40 (MAX_GROUP_CHANNELS).
    • Channel notification preferences array expanded to match (41 slots: 40 channels + 1 DM).
    • Channel picker UI updated to support all 40 channels.
    • Stack-local channel record arrays moved to heap allocation to prevent stack overflow.

    Power Optimisation

    • ICM20948 IMU: Put to sleep after init (~3mA saved).
    • ES8311 audio codec: DAC, ADC, and PGA powered down after init. I2S channels disabled to release APB_FREQ_MAX PM locks. Woken on demand before playback, slept after stop (~5-10mA saved).
    • I2S PM lock management: Added disable_channels() / enable_channels() to Hardware_Iis class so I2S driver PM locks are only held during active audio playback.
    • DFS investigation: PM stats task added (enable via sdkconfig). Confirmed DSI display driver holds CPU_FREQ_MAX lock 97% of the time while screen is on, making CPU frequency reduction ineffective. ~172mA baseline is the hardware floor with display active.

    UI Improvements

    • Path display: Incoming message routes and outgoing heard-by lists reformatted as n …
  6. v0.3.8 # Pre-release 25 days ago · 2026-05-27 02:36 UTC

    Pre-release.

    Feature release building on v0.3.6, adding position adverts, share position, path view, private channels, and voice/picture over LoRa infrastructure (disabled pending final integration).


    What's New

    Position Adverts

    Your GPS position can now be encoded into outgoing adverts, allowing other nodes on the mesh to see your location on their Maps screen. Position is configured via a new Settings > Position sub-screen with three fields:

    • Latitude / Longitude (tap to edit) for manual entry in decimal degrees
    • Share Position (tap to cycle): Off / Manual / Auto-GPS

    In Auto-GPS mode, the L76K GPS snapshot is polled every 15 minutes and the stored position is updated automatically whenever the fix changes. A Copy Position button is also available on the sub-screen.

    Share Position

    The + button on the channel messages and DM compose screens now includes a Share Position option. Tapping it sends your current lat/lon as a message to the active channel or conversation.

    Path View and Message Actions

    Long-pressing an incoming message now opens Path View, which displays the routing path that message took through the mesh, showing each hop in the route.

    Long-pressing an outgoing message gives you the option to Retry Send if the message failed, or to see which repeaters acknowledged the message.

    Private Channels

    Channels can now be public or private:

    • Public channels start with # (e.g. #test). The secret is derived via SHA-256 from the name, matching the standard MeshCore convention.
    • Private channels have no # prefix. A random 16-byte secret is generated at creation, so only invited users can join.

    Sharing: open Settings > Channels, tap the channel, then tap Share Channel. This opens a contact picker and sends the channel name and secret as a DM invitation. Recipients see a pending invite they can accept (tap) or dismiss (long-press).


    Voice over LoRa Infrastructure (Not Yet Enabled)

    The full infrastructure for Codec2 1200bps voice messaging has been added to the firmware:

    • Codec2 ESP-IDF component (components/codec2/) wrapping drowe67/codec2 with only the core 1200bps mode compiled in
    • ES8311 microphone capture at native 44100 Hz I2S rate
    • VE3 protocol for chunked voice packet transfer
    • Recording buffer in PSRAM, staggered send timing
    • Voice UI: inbox with metadata persistence, record screen with Play/Discard/Send, previous recordings list, contact picker (favourites first), send status tracking
    • Playback at 85% volume via meck_audio_play_file

    Voice and Picture tiles are present on the home screen as placeholders but the features are disabled in this release pending final integration and testing.

    Picture over LoRa Infrastructure (Not Yet Enabled)

    Chunked image transfer protocol infrastructure has been added but is disabled in this release.

    UI Changes

    • Splash screen updated with new design and progress bar
    • Maps and Trace tile colours swapped so there are no longer two adjacent red tiles on the home screen
    • Home screen expanded from seven tiles to nine (Voice and Camera placeholders added)
    • MAX_GROUP_CHANNELS bumped from 8 to 12

    First-Time Flashing: Read This First

    Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot and notification sounds won't be available.

    Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash. <img width="377" height="284" alt="correct …

  7. v0.3.6 # Pre-release 27 days ago · 2026-05-24 23:38 UTC

    Pre-release.

    Feature release building on v0.3.5.1, adding custom radio parameters, region scope support, a Channels settings sub-screen, and per-channel notification sounds.


    What's New

    Custom Radio Parameters

    Frequency, Bandwidth, and Spreading Factor are now individually editable via text entry in Settings (tap the row, type the value, tap Confirm). Coding Rate cycles on tap (4/5 through 4/8). The Radio Preset row remains available and shows "Custom" whenever the current values don't match any of the 17 built-in presets. Selecting a preset populates all four fields; you can then tweak individual values without losing the rest.

    This is primarily useful for users in regions where the community presets don't cover the exact parameters in use, such as parts of Europe running SR 5/6 with 32.5 kHz bandwidth, or anyone wanting to customise the coding rate independently.

    Region Scope (MeshCore v1.15+ Compatibility)

    Regions limit how far your flood messages propagate through the mesh. When you set a region, outgoing messages are tagged with a transport code that repeaters use to decide whether to forward them. Messages sent without a region reach all repeaters via the default wildcard, same as always.

    Setting your device region:

    • Open Settings, tap Default Region, enter your region name (e.g. au-nsw), tap Confirm
    • Leave empty for unscoped (legacy behaviour, reaches all repeaters)

    Per-channel region: Open Settings > Channels, tap a channel, then tap Region Scope to set an override for that specific channel. Empty uses the device default.

    Finding your region name: Region names are determined by your local mesh community. Check with your local group, or browse the community region registry at regions.meshcore.nz for names already in use. Common patterns follow ISO 3166 codes (e.g. au for Australia, au-nsw, gb-eng, us-ca), but communities may also use custom names. Names must be lowercase alphanumeric characters and hyphens, max 30 characters. You can also create your own custom regions on repeaters you manage (see Repeater Admin below).

    Note: Region scoping requires repeaters in your area to be running MeshCore v1.10+ with the appropriate regions configured. If no repeaters have region filtering enabled, scoped and unscoped messages behave identically.

    Repeater Admin: Region Management via CLI

    Repeaters running MeshCore v1.10+ support full region management through the Cmd Line screen in Repeater Admin. Log in to a repeater, tap Cmd Line, and use the following commands:

    Command Description
    region put <name> [parent] Create a new region (optional parent for nesting)
    region remove <name> Remove a region (remove children first)
    region allowf <name> Allow flooding for a region
    region denyf <name> Block flooding for a region
    region get <name> Show info for a region
    region home / region home <name> View or set the repeater's home region
    region default / region default <name> View or set the repeater's default scope
    region save Persist region changes to the repeater's flash
    region list allowed / region list denied View regions (repeater firmware 1.12+)
    region load <name> [F] Single-line region load (append F to allow flooding)

    Not supported: The interactive multi-line region load (without parameters) requires a serial terminal and is not available on the P4, which does not currently support serial CLI commands. Use individual region put and region allowf commands instead.

    Quick start example (setting up a repeater for the au-nsw region):

    region put au-nsw
    region allowf au-nsw
    region home au-nsw
    region save
    

    For full documentation and nested region examples, see the [MeshCore CLI docs](https://docs.meshcore.io/cli_commands/#region-management-v1

  8. v0.3.5.1 # Pre-release 1 month ago · 2026-05-22 19:34 UTC

    Pre-release.

    Patch release on top of v0.3.5, fixing three bugs in the Contacts screen:

    • 200-row cap removed. The contacts list previously stopped rendering after 200 matched rows. With 200+ contacts this hid recently-added repeaters from the list entirely (including, in one reproducible case, a freshly-added Repeater that Discover claimed to have added but which was nowhere to be seen). The list now displays every matching contact.
    • Sorted by recency. Contacts now appear newest-first instead of in creation order. The sort key is local activity time (advert receipt, message send, or message receive), so the most recently active contacts sit at the top of the list regardless of which filter is active.
    • Sort key corrected. Initial attempt used last_advert_timestamp, which is the sender's claimed clock embedded in the advert payload rather than our reception time. That gave nonsense ordering: nodes with forward-dated clocks (stale build epoch, mis-set NTP, etc.) sat permanently at the top, and nodes whose clocks were stuck or behind had their adverts silently dropped by the upstream replay-attack guard and sank to the bottom. The fix sorts by lastmod (our local RTC time at last contact activity) with an override in onAdvertRecv so lastmod is updated on every advert receipt regardless of whether the upstream replay guard early-returned.

    No other behavioural changes from v0.3.5.

    First-Time Flashing: Read This First

    (Same as v0.3.5 — skip this section if you've already flashed v0.3.5; the contacts fixes carry over via the usual upgrade path.)

    Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.

    Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash. correct port usage for flashing

    Flashing with the MeshCore Web Flasher (recommended)

    1. Go to https://flasher.meshcore.io/
    2. Scroll to the bottom and select Custom Firmware
    3. Select the meck-p4-0.3.5.1-version-merged.bin file you downloaded
    4. Click OK on the merged-binary warning
    5. Click Flash, pick your device in the popup, and click Connect

    Flashing with esptool.py

    pip install esptool
    esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.5.1-version-merged.bin
    

    (Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

    Upgrading from v0.3.5 or v0.3.3 does not require erase_flash. The prefs loader continues to tolerate older shorter-blob layouts, so any new fields come up at default rather than wiping existing settings.

    ⚠️ AMOLED variant remains untested by the maintainer. The -amoled.bin is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.

    Known Limitations

    Carried over unchanged from v0.3.5:

    • Background audio playback has known issues — not recommended for general use yet. A blue >> glyph was added to the top bar to indicate when the audio player is actively playing, mirrored across every home tile and full screen. However, the broader background-playback experience has a number of unresolved bugs: tapping the Audio tile while a track is playing doesn't jump back to the Now Playing screen (so pausing requires navigating back to the file manually), and starting a second …
  9. v0.3.5 # Pre-release 1 month ago · 2026-05-21 09:56 UTC

    Direct messaging arrives in v0.3.5 — compose, send, receive, and persist DMs from any companion contact, with unread badges viewable in the channel list. Room server support and repeater admin land alongside, giving you logged-in access to room post history and the full status/CLI/settings interface for remote repeater management. A new map screen renders OSM slippy tiles from the SD card with a GPS dot, contact markers, and pan/zoom. Plus a per-contact path editor, a standalone trace route screen, a keyboard layout overhaul, a GPS time-sync fix, debug logs to SD, and config export to a MeshCore-app-compatible JSON file.

    ⚠️ Still a pre-release. ⚠️ Web browser, IRC, and the BLE/WiFi companion path are still not in this build. See What's Not Yet Implemented for the full pending list.

    First-Time Flashing: Read This First

    Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.

    Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash. correct port usage for flashing

    Flashing with the MeshCore Web Flasher (recommended)

    1. Go to https://flasher.meshcore.io/
    2. Scroll to the bottom and select Custom Firmware
    3. Select the meck-p4-0.3.5-version-merged.bin file you downloaded
    4. Click OK on the merged-binary warning
    5. Click Flash, pick your device in the popup, and click Connect

    Flashing with esptool.py

    pip install esptool
    esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.5-version-merged.bin
    

    (Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

    Upgrading from v0.3.3 does not require erase_flash. The prefs loader continues to tolerate older shorter-blob layouts, so any new fields come up at default rather than wiping existing settings.

    ⚠️ AMOLED variant remains untested by the maintainer. The -amoled.bin is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.

    What's New Since v0.3.3

    Direct Messaging

    Open a companion contact's detail screen (from the Contacts menu tile on the home screen) and tap the cyan Send DM button (stacked above the red Delete button) to compose. The DM conversation view uses the standard chat layout — keyboard on the bottom half, message bubbles scrolling above.

    • Per-contact 20-message ring buffers in PSRAM, lazy-allocated so unused contacts cost nothing
    • Per-contact DM history persisted to SD and reloaded on boot
    • DM Inbox row in the channel picker shows a per-contact unread badge, refreshed every tick
    • Send-side ACK tracking — outgoing bubbles update from "Sending..." through to "Delivered" or "Failed" as the ACK round-trip completes

    Room Server Support

    Tap a Room-type contact to open the same admin login flow as repeaters. On successful login, the room's post timeline appears as a scrollable bubble list, left-aligned, with the author name above each bubble and a timestamp and hop count footer below.

    • Post history persisted per-room to SD and loaded on boot, so you don't need to re-login to see what's already been received
    • Live re-render: posts arriving while you're sitting on the room view land in the bubble list without leaving the screen
    • Author resolution walks your contacts looking for a matc …
  10. v0.3.3 # Pre-release 1 month ago · 2026-05-18 02:47 UTC

    One-step config import from the MeshCore mobile app so existing users can move to a P4 without re-entering everything, a firmware-side fix for the BQ27220 fuel gauge calibration so the battery percentage matches reality, and substantial UI work on the home screen, Settings, and tile layouts. Plus a small power-savings pass that trims about 38 mA off idle draw.

    ⚠️ Still a pre-release. ⚠️ Direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, and the BLE companion path are still not in this build. See What's Not Yet Implemented for the full pending list.

    First-Time Flashing: Read This First

    Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.

    Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash.

    Flashing with the MeshCore Web Flasher (recommended)

    1. Go to https://flasher.meshcore.io/
    2. Scroll to the bottom and select Custom Firmware
    3. Select the meck-p4-0.3.3-version-merged.bin file you downloaded
    4. Click OK on the merged-binary warning
    5. Click Flash, pick your device in the popup, and click Connect

    Flashing with esptool.py

    pip install esptool
    esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.3-version-merged.bin
    

    (Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

    Upgrading from v0.3 does not require erase_flash. The prefs loader has been made tolerant of older shorter-blob layouts, so any new fields added in v0.3.3 (such as Font Size) come up at default rather than wiping existing settings.

    ⚠️ AMOLED variant remains untested by the maintainer. The -amoled.bin is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.

    What's New Since v0.3

    MeshCore App Config Import

    Drop your MeshCore mobile or desktop app config export onto the SD card, reboot, and your identity, channels, contacts, node name, and radio settings come across in one step. No more re-entering contacts or generating a fresh keypair when moving to the P4.

    How to use:

    1. In the MeshCore mobile or desktop app, export your config as JSON
    2. Rename to import.json and copy to /sdcard/meshcore/import.json on the P4's SD card
    3. Reboot the device

    On boot, Meck reads the file and applies it:

    Field Behaviour
    Identity (private + public key) Replaces _main.id atomically (tmp + rename). Existing identity is overwritten.
    Channels Merged by 16-byte secret. Existing channels kept; new ones appended to free slots; duplicates skipped.
    Contacts Merged by public key. Existing kept; new ones appended. Lat/lon converted from string-decimal to int32 e7. custom_name preferred over name.
    Node name Replaces prefs.node_name.
    Radio settings Replaces freq, BW, SF, CR, TX power on P4NodePrefs. Freq converted kHz to MHz, BW Hz to kHz.

    On success the file is moved to /sdcard/meshcore/import.history/import-<unix_epoch>.json so it doesn't re-apply on subsequent boots and leaves an audit trail. On parse failure (bad JSON, missing identity keys, wrong-length hex) a warning is logged and the file is left in place for inspection.

    Imported names (node, channels, contacts) are stripped to printable ASCII before being stored. Meck-P4's Montserrat fonts cover Latin-1 only, so emoji codepoints would otherwise render as tofu boxes. Leading an …

  11. v0.3 # Pre-release 1 month ago · 2026-05-16 03:53 UTC

    The third Meck-P4 pre-release. Audio playback from SD, active zero-hop neighbour discovery with one-tap contact add, and a substantially upgraded virtual keyboard with light/dark theme, three physical layouts, and long-press accent input for French and Czech. Plus per-message hop and ACK metadata, and a fix for the battery cell capacity (which had been wrong since v0.1).

    **⚠️ Still a pre-release.⚠️ ** Direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, and the BLE companion path are still not in this build. See What's Not Yet Implemented for the full pending list.


    First-Time Flashing -- Read This First

    Meck-P4 ships as a single merged binary (bootloader + partition table + application combined). One file, flash at offset 0x0.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.

    correct port usage for flashing

    Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash.

    Flashing with the MeshCore Web Flasher (recommended)

    1. Go to https://flasher.meshcore.io/
    2. Scroll to the bottom and select Custom Firmware
    3. Select the meck-p4-0.3-version-merged.bin file you downloaded
    4. Click OK on the merged-binary warning
    5. Click Flash, pick your device in the popup, and click Connect

    Flashing with esptool.py

    pip install esptool
    esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3-version-merged.bin
    

    (Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

    If you're upgrading from v0.1 and want to start with clean defaults, run esptool.py --chip esp32p4 -p PORT erase_flash before the write. Your contacts and prefs will be restored from the SD card mirror on first boot.

    ⚠️ AMOLED variant is untested. The -amoled.bin is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand and hasn't been able to flash or run it. Community members are currently testing it. If you have an AMOLED board, please report back via the MeshCore Discord or a GitHub issue with whether it boots, the display works, and touch works. The TFT variant is the tested and known-working build.


    What's New Since v0.1

    Audio Player

    MP3 playback directly from the SD card. Two top-level subtrees give the player different defaults so music and audiobooks behave appropriately:

    Subtree Defaults
    /sdcard/audio/music/ Standard playback. Resume bookmark off.
    /sdcard/audio/audiobooks/ Audiobook mode. Resume bookmark on, sleep timer available, position tracked through the playlist.

    How to use the audio player:

    1. Drop your music/ and audiobooks/ folders into /sdcard/audio/ on the SD card (the firmware creates the subtree automatically on first boot if it doesn't exist)
    2. Insert the card and power on
    3. Tap the Audio tile on the home grid to open the browser
    4. Navigate to a track and tap to play
    5. Use the transport row on the Now Playing screen for skip / play-pause / volume

    Read the audio player guide before copying files to your SD card. MP3s with large embedded album art can starve the IDLE task on first decode and trigger a watchdog reboot. The guide walks through the tools/mp3_clean.py script that strip …

  12. v0.1 # Pre-release 1 month ago · 2026-05-09 08:14 UTC

    The first publicly flashable Meck firmware for the LilyGo T-Display P4. One file, one offset, you're on the mesh.

    ⚠️ This is a pre-release, not a finished product. Many of the features people associate with Meck on the T-Deck Pro and T5S3 — direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, audio player — are not yet implemented on the P4. What's here is the foundation: a fully functional MeshCore node with channel messaging, contacts, persistent storage, GPS, and battery monitoring. See the full feature list and roadmap.


    Hardware

    ⚠️ LilyGo T-Display P4 (TFT version)⚠️ The AMOLED variant has not been tested but should be close — adjust the display init in main/examples/lvgl_9_ui/main.cpp if you want to try it.

    Flashing

    IMG_2838

    Ensure you use the right-usb C port, ie not the high-speed charger port to flash.

    The release file meck-p4-0.1-merged.bin is a merged binary containing the bootloader, partition table, and application combined into a single image — flash it at address 0x0.

    Using the MeshCore Flasher (web-based):

    1. Go to https://flasher.meshcore.io
    2. Scroll to the bottom and select Custom Firmware
    3. Select the meck-p4-0.1.bin file you downloaded
    4. Click OK for the warning about erase files because it's a merged binary.
    5. Click Flash, choose your device in the popup, and click Connect

    Using esptool.py:

    pip install esptool
    esptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.1.bin
    

    (Replace PORT with /dev/cu.usbmodemXXXX on macOS, /dev/ttyACM0 on Linux, or COM3 on Windows.)

    If you've previously had something else on the device, run esptool.py --chip esp32p4 -p PORT erase_flash first to clear NVS so Meck starts with clean defaults.

    An SD card is recommended. With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically. The device works without one but loses message history on reboot.


    What's Working

    📡 Mesh networking

    • Channel messaging — send and receive on Public, #test, #sydney
    • 17-preset radio picker (AU, US, EU, CN regions). Boots on Australia Narrow by default (916.575 MHz / SF7 / BW 62.5 kHz / CR 4/8)
    • Adverts go out automatically; received adverts populate Recent Heard and (subject to your auto-add policy) the contact list
    • Self-healing public-channel migration — earlier dev builds derived the Public channel secret from a hash, which didn't match the rest of the network. v0.1 detects this on every boot and repairs it automatically, without disturbing your custom channels

    📱 UI

    A horizontal seven-tile home layout. Swipe left/right to switch tiles.

    Tile What it shows
    0 Home Node name, freq/SF/RSSI/RX counters, six-button nav grid
    1 Recent Heard Live list of nodes whose adverts you've received
    2 Radio Details Current freq / BW / SF / CR / TX / sync word
    3 Advert Long-press to send a manual advert
    4 GPS Fix status, satellites, position, altitude, sentence rate
    5 Battery Voltage, charge%, current, chip temp, remaining mAh
    6 Shutdown Long-press to power down

    👥 Contacts

    • Filter chip bar at the top: All / Chat / Rptr / Room / Sens / Fav. Swipe left/right to cycle, or tap a chip directly
    • Per-row colour-coded type pill (C / R / RS / S) and 4-byte pubkey prefix for disambiguation
    • Long-press a contact to toggle favourite (a star appears, the contact rises to the top)
    • Tap a contact to open the detail screen, with a red Hold button that long-press-deletes (single tap is unbound to prevent accidents)
    • Auto-add policies in Settings → Contacts: Auto All / Custom (per-type toggles) / Manu …