Skip to content

Firmware Update

The LC29H module contains a Broadcom BCM4775 GNSS SoC with SPI flash storing the firmware image. The lc29h firmware commands communicate with the BCM4775’s ROM bootloader to read, write, and verify flash contents. All operations except firmware info require a bootloader.pkg file that establishes the bootloader session and configures the flash interface.

See Firmware Internals for protocol details, bootloader package structure, and the reverse-engineered FlashUpdater analysis.

  • bootloader.pkg — included with the Waveshare wiki downloads and the LC29H_EVB package. Set the LC29H_BOOTLOADER environment variable to its path, or place the file in your current working directory:
Terminal window
export LC29H_BOOTLOADER=/path/to/bootloader.pkg
  • Exclusive serial access — the module enters bootloader mode during backup, update, and verify operations, which interrupts NMEA output. Close any other program using the serial port (monitor sessions, MCP server, gpsd) before proceeding.

  • Stable power supply — the module must not lose power during flash erase or write operations. If running from a Raspberry Pi, use a quality power supply rated for the full board draw plus peripherals.

Safe, read-only query using standard NMEA/proprietary sentences. Returns the same version data as lc29h info but organized under the firmware subcommand group. No bootloader entry, no bootloader.pkg required.

Terminal window
lc29h firmware info
Model: LC29HDAANR11A01S
Firmware: LC29HDANR11A01S_RSA
Built: 2024/02/23 17:58:32
Chip: Airoha AG3335A
Chip FW: AXN_5.8.3_LLAC29H

Enters the BCM4775 bootloader, reads the entire SPI flash, and writes it to a local binary file. A progress bar tracks the read operation.

Terminal window
# Default filename: FlashBackup_YYYYMMDD-HHMMSS.bin
lc29h firmware backup
# Custom output path
lc29h firmware backup -o my_backup.bin
Entering bootloader...
Reading flash: [####################] 100% 2048 KB
Saved to FlashBackup_20260227-143012.bin

The backup file is a raw byte-for-byte copy of the flash contents. Keep it somewhere safe — this is your recovery path if an update goes wrong.


Erases the SPI flash and writes a new firmware image. This is the most dangerous operation in the toolchain. The --yes flag is mandatory to confirm you understand the risks.

Terminal window
# Standard update (auto-backup first)
lc29h firmware update firmware.bin --yes
# Skip the automatic pre-update backup
lc29h firmware update firmware.bin --yes --skip-backup
# Write at a specific flash offset (must be 4 KB aligned)
lc29h firmware update firmware.bin --yes --offset 0x1000
# Specify bootloader path explicitly
lc29h firmware update firmware.bin --yes --bootloader /path/to/bootloader.pkg
OptionDescription
--yesRequired. Confirms destructive operation. Without this flag, the command refuses to run.
--skip-backupSkip the automatic flash backup before erasing. Saves time but removes your safety net.
--offset HEXFlash write offset in hex. Must be 4 KB (0x1000) aligned. Default is 0x0.
--bootloader PATHExplicit path to bootloader.pkg. Overrides LC29H_BOOTLOADER env var and working directory search.
Entering bootloader...
Backing up current flash...
Reading flash: [####################] 100% 2048 KB
Saved to FlashBackup_20260227-143012.bin
Erasing flash...
Writing firmware: [####################] 100% 1847 KB
Verifying write: [####################] 100% 1847 KB
CRC OK — firmware update complete
Module rebooting...

Exit codes:

CodeMeaning
0Success
1General error (serial failure, file not found, etc.)
2Chip ID mismatch — the bootloader.pkg does not match the connected module revision
3CRC verification failed after write
4User abort (Ctrl+C during safe phase, before erase begins)

Read-only CRC comparison between a firmware image file and the current flash contents. Enters the bootloader to read flash but does not modify anything.

Terminal window
lc29h firmware verify firmware.bin
Entering bootloader...
Reading flash: [####################] 100% 1847 KB
Comparing CRC... OK
Flash contents match firmware.bin

If the CRC does not match, the command prints the expected and actual values and exits with code 3.

  1. Check current firmware version

    Start with firmware info to see what is currently running. This is safe and fast — no bootloader involved.

    Terminal window
    lc29h firmware info
  2. Backup existing flash

    Read the full flash contents to a local file. This is your rollback path.

    Terminal window
    lc29h firmware backup -o before_update.bin
  3. Update with new firmware

    Write the new image. The command will perform an automatic backup (unless --skip-backup is passed), erase, write, and verify in sequence.

    Terminal window
    lc29h firmware update new_firmware.bin --yes
  4. Verify the write

    Confirm the flash contents match the source image. This is a separate read pass with independent CRC calculation.

    Terminal window
    lc29h firmware verify new_firmware.bin

    After verification, the module reboots automatically. Run lc29h firmware info again to confirm the new version string.

The same firmware operations are available as MCP tools through the lc29h-mcp server. The MCP server automatically pauses its NMEA monitor during bootloader operations and resumes afterward.

MCP ToolCLI EquivalentNotes
firmware_infolc29h firmware infoSafe, NMEA-only query
firmware_backuplc29h firmware backupReturns backup file path
firmware_updatelc29h firmware updateRequires confirm=True parameter (equivalent to --yes)
firmware_verifylc29h firmware verifyReturns CRC match result
You: Back up the current firmware and tell me what version is running.
Claude: I'll query the module info and start a backup.
[Calls firmware_info]
[Calls firmware_backup]
The module is running LC29HDANR11A01S_RSA, built 2024-02-23.
Flash backup saved to FlashBackup_20260227-151200.bin (2048 KB).

The firmware commands search for bootloader.pkg in this order:

  1. --bootloader flag (CLI) or bootloader_path parameter (MCP)
  2. LC29H_BOOTLOADER environment variable
  3. bootloader.pkg in the current working directory

Set the environment variable in your shell profile to avoid repeating the path:

Terminal window
echo 'export LC29H_BOOTLOADER=/opt/lc29h/bootloader.pkg' >> ~/.bashrc
source ~/.bashrc

The bootloader package contains a chip identifier that must match the connected module’s BCM4775 revision. This error means you have the wrong bootloader.pkg for your hardware. Check the Waveshare wiki downloads for a version matching your specific module variant (AA, BA, CA, DA, BS).

The post-write CRC check did not match. Possible causes:

  • Marginal serial connection — check cable and connections, try a lower baud rate
  • Flash wear — unlikely on a new module but possible on heavily cycled hardware
  • Corrupted firmware image — re-download and verify the source file checksum

Retry the update. If CRC failures persist across retries, the flash may have bad sectors.

The module takes up to 30 seconds to boot after a flash write. If it does not respond after 30 seconds:

  1. Power cycle the module (disconnect and reconnect power, or toggle the HAT’s power pin)
  2. Wait 30 seconds for the full boot sequence
  3. Try lc29h firmware info at the default 115200 baud

If the module still does not respond, it may need recovery via the backup image:

Terminal window
lc29h firmware update before_update.bin --yes --skip-backup

Close all programs that might hold the serial port open — lc29h monitor, lc29h-mcp, gpsd, screen, minicom. The bootloader requires exclusive serial access. On Linux, check what has the port open:

Terminal window
fuser /dev/ttyS0