-
Notifications
You must be signed in to change notification settings - Fork 3
04 ‐ Programming
This page covers how to program the two programmable targets on the LinkIt V4 board:
| Target | Connector | Probe | Methods |
|---|---|---|---|
| LinkIt Core (nRF52840) | J1 | TC2030 pogo-pin | J-Link (SWD) or DFU (BLE) |
| SMD Module (Argos/Kineis) | J12 | TC2030 pogo-pin | J-Link (SWD) or DFU (SPI/UART) |
The SMD module is only present on boards built with ARGOS_SMD=ON (LinkIt V4 SMD, RSPB).
Connect a J-Link debug probe to the J1 TC2030 pogo-pin connector on the board.
The merged hex contains bootloader + SoftDevice + application in a single file:
nrfjprog --recover
nrfjprog -f nrf52 --program <merged_hex_file> --sectorerase
nrfjprog -f nrf52 --reset| Board | Build Dir | Merged Hex File |
|---|---|---|
| KIM | build/LINKIT/ |
LinkIt_board_merged-*.hex |
| SMD | build/LINKIT_SMD/ |
LinkIt_board_merged-*.hex |
| LoRa | build/LINKIT_LORA/ |
LinkIt_board_merged-*.hex |
| RSPB | build/RSPB/ |
LinkIt_RSPB_board_merged-*.hex |
All paths are relative to ports/nrf52840/.
Note: The merged hex is only generated if the bootloader has been built first. See Developer Quick Start - Build the Bootloader.
When the bootloader and SoftDevice are already on the device, flash only the application + settings for faster iteration. Use the *_app_settings-*.hex file (not the raw app hex), because the bootloader requires an updated settings page to validate the new application (ECDSA signature).
nrfjprog -f nrf52 --program <app_settings_hex_file> --sectorerase --verify --resetWarning: Flashing the raw
*_board-*.hex(without settings) will cause the bootloader to reject the application — the device will stay in bootloader mode (yellow LED).
For debugging without the bootloader (SoftDevice + application only):
nrfjprog --recover
nrfjprog -f nrf52 --program ports/nrf52840/drivers/nRF5_SDK_17.0.2/components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex --sectorerase
nrfjprog -f nrf52 --program <app_hex_file> --sectorerase
nrfjprog -f nrf52 --resetThe firmware can be updated over Bluetooth using pylinkit (CLI) or the LinkIt GUI tool. The bootloader must already be on the device.
The device must be powered on and advertising via BLE. Scan for available devices first:
pylinkit --scanThis will list all nearby LinkIt devices with their BLE addresses (e.g., xx:xx:xx:xx:xx:xx).
pylinkit --device xx:xx:xx:xx:xx:xx --fw firmware.zipThe .zip DFU package is generated automatically by the build scripts:
| Board | DFU Package |
|---|---|
| KIM | build/LINKIT/LinkIt_board_dfu-*.zip |
| SMD | build/LINKIT_SMD/LinkIt_board_dfu-*.zip |
| LoRa | build/LINKIT_LORA/LinkIt_board_dfu-*.zip |
| RSPB | build/RSPB/LinkIt_RSPB_board_dfu-*.zip |
Warning: The firmware update takes several minutes. Do not reset the device or disconnect during the transfer. Ensure the battery is not critically low.
The graphical interface provides the same firmware update functionality with a visual progress indicator. Select the DFU package (.zip) and the target device from the GUI.
The SMD satellite module has its own MCU and firmware. It can be updated independently from the LinkIt Core, either via the J12 debug connector or via DFU over SPI/UART.
Connect a J-Link debug probe to the J12 TC2030 pogo-pin connector (dedicated to the SMD module).
Important: The SMD module must be powered on before flashing. The nRF52840 controls power to the satellite module, so the LinkIt Core must be running and the satellite power rail must be enabled.
Power on the satellite module first:
Via pylinkit (BLE)
pylinkit --device xx:xx:xx:xx:xx:xx --pwron satellite
Via DTE command (serial terminal)
$PWRON#001;3Once the satellite power rail is active, flash the SMD firmware with the J-Link probe connected to J12:
Flash SMD firmware via J12
nrfjprog --program <smd_firmware.hex> --sectorerase
nrfjprog --resetNote: The J12 probe targets the SMD module's MCU, not the nRF52840. Make sure the correct J-Link target is selected.
The SMD firmware can also be updated through the LinkIt Core, which forwards the firmware to the SMD module over SPI or UART. This does not require a J-Link probe.
The device must be powered on and discoverable via BLE (see pylinkit --scan).
DFU via SPI (recommended)
pylinkit --device xx:xx:xx:xx:xx:xx --smdfw <smd_firmware.bin> --smdfw_mode spi
DFU via UART
pylinkit --device xx:xx:xx:xx:xx:xx --smdfw <smd_firmware.bin> --smdfw_mode uartThe SPI DFU process can take up to 3 minutes. pylinkit will wait for the device to confirm completion.
The graphical interface supports SMD firmware updates with visual progress tracking. Select the SMD firmware binary and the DFU mode (SPI or UART).
For manual control of the SMD DFU process via a serial terminal:
| Command | Description |
|---|---|
$SMDDFU#001;5 |
Check SMD firmware version |
$SMDDFU#001;0 |
Enter DFU mode |
$SMDDFU#001;2 |
Check DFU status |
$SMDDFU#001;4 |
Get bootloader info |
$SMDDFU#001;1 |
Exit DFU mode |
The debug output is a read-only log stream (trace, warnings, errors). It is separate from the DTE command interface.
The log output interface is configured via DEBUG_OUTPUT_MODE (DTE key: DBP01):
| Value | Mode | Interface | Default For |
|---|---|---|---|
| 0 | UART | J3 connector (UART 460800 baud, requires USB-to-UART adapter) | RSPB |
| 1 | USB_CDC | USB connector (virtual serial port) | LinkIt V4 (KIM, SMD, LoRa) |
| 2 | BLE_NUS | Bluetooth Low Energy Nordic UART Service | - |
| 3 | NONE | No debug output (recommended for field deployment) |
Release builds (CMAKE_BUILD_TYPE=Release / NDEBUG defined) — every board |
Build-time default: Release builds force NONE at startup regardless of board — USB CDC is not enumerated, UART debug TX stays idle, BLE NUS debug stream is empty (DTE responses still work). Debug builds keep their board-default (USB_CDC on LinkIt, UART on RSPB). See Building § Release build behaviour.
Power note: Mode NONE reduces idle power from ~1.9mA to ~10µA by not initializing any debug peripheral. The internal
system.log(filesystem) continues recording all INFO/WARN/ERROR messages, retrievable via BLE in configuration mode.Runtime override:
PARMW,DBP01,<mode>switches at runtime on a Release device too — useful for short diagnostic windows on a deployed unit (it persists in flash, so remember to revert before sealing).
LinkIt V4 (KIM, SMD, LoRa) — USB CDC (default):
Connect the USB cable and open a serial terminal at 115200 baud, 8N1:
minicom -D /dev/ttyACM0 -b 115200
or
screen /dev/ttyACM0 115200RSPB — UART via J3 connector:
The RSPB has no USB interface for debug. Connect a USB-to-UART adapter to the J3 header, then use the same serial terminal commands on the adapter's port (e.g., /dev/ttyUSB0).
BLE NUS (all boards):
Set DBP01=2 first, then use the nRF Connect app (iOS/Android) or any BLE terminal supporting the Nordic UART Service.
pylinkit log viewer (BLE):
pylinkit --device xx:xx:xx:xx:xx:xx --logSet at compile time via DEBUG_LEVEL in CMake:
| Level | Output |
|---|---|
| 0 | Off |
| 1 | Errors only |
| 2 | Errors + Warnings |
| 3 | Errors + Warnings + Info |
| 4 | Errors + Warnings + Info + Trace |
cmake ... -DDEBUG_LEVEL=4 ...The DTE (Data Terminal Equipment) protocol is used for device configuration and control (read/write parameters, trigger actions, firmware updates). DTE commands are sent over BLE using pylinkit or the LinkIt GUI tool.
The device must be powered on and discoverable via BLE:
Scan for devices
pylinkit --scan
Read all parameters to a file
pylinkit --device xx:xx:xx:xx:xx:xx --parmr params.cfg
Write parameters from a file
pylinkit --device xx:xx:xx:xx:xx:xx --parmw params.cfg
Factory reset
pylinkit --device xx:xx:xx:xx:xx:xx --factw
Software reset
pylinkit --device xx:xx:xx:xx:xx:xx --rstbwThe graphical interface provides the same DTE functionality: parameter read/write, device control, log viewing, and firmware updates.
DTE commands follow this format:
$COMMAND#LEN;ARGS\r
Example commands:
$PARML#000; # List all parameter keys
$PARMR#000; # Read all parameters
$PARMR#00A;GNP01,ARP01 # Read specific parameters
$PARMW#010;GNP01=1 # Write a parameter
$PWRON#001;3 # Power on satellite module
See DTE Commands Reference for the full protocol specification and command set.
| Parameter | DTE Key | Description |
|---|---|---|
LED_MODE |
LDP01 |
Internal RGB LED behavior |
Note:
EXT_LED_MODE(LDP02) is deprecated (slot reserved, hidden from DTE). The external LED was an Icoteq Horizon / Artic-R2 era feature not wired on LinkIt V4 or RSPB. See Parameters § LED.
| Value | Mode | Behavior |
|---|---|---|
| 0 | OFF | LED disabled |
| 1 | HRS_24 | LED active for the first 24 hours after boot |
| 3 | ALWAYS | LED always active |
Boot by holding a magnet against the reed switch for ~3 seconds. The device enters deep sleep when idle and wakes on accelerometer activity or scheduled events.
The RSPB uses a TPL5111 external timer for ultra-low-power duty cycling (0 current draw between cycles).
| Parameter | DTE Key | Description |
|---|---|---|
SHUTDOWN_TIMER |
PWP01 |
Max awake time per cycle in seconds (0 = no limit) |
BOOT_COUNTER |
PWP02 |
Current boot count (read-only) |
BOOT_COUNTER_MODULO |
PWP03 |
Run every Nth boot (min: 2) |
WAKEUP_PERIOD |
PWP04 |
TPL5111 wakeup interval in seconds (read-only, hardware) |
Effective duty cycle = WAKEUP_PERIOD x BOOT_COUNTER_MODULO. Default: 3600s x 2 = 2 hours.
The device runs when BOOT_COUNTER % BOOT_COUNTER_MODULO == 0, and powers down immediately on other boots. Applying a magnet during a modulo-skip overrides the skip (useful for configuration access).
- Check power: Reed switch engaged (LinkIt V4) or TPL5111 cycling (RSPB)?
-
Check BLE:
pylinkit --scan— if the device does not appear, it may be in deep sleep or not powered -
Recover via J-Link:
nrfjprog --recovererases and unlocks the chip
nrfjprog --recover
nrfjprog -f nrf52 --program <merged_hex_file> --sectorerase
nrfjprog -f nrf52 --reset--recover performs a full erase including UICR and flash protection bits.
- Ensure the bootloader is on the device (flash a merged hex first via J-Link)
- Check that the DFU package (
.zip) matches the board variant - Verify the device is discoverable:
pylinkit --scan
- Ensure satellite power is on:
pylinkit --device xx:xx:xx:xx:xx:xx --pwron satelliteor$PWRON#001;3 - Run SMD SPI test:
pylinkit --device xx:xx:xx:xx:xx:xx --smdtstor$SMDTST#000; - Check SMD firmware version:
pylinkit --device xx:xx:xx:xx:xx:xx --smddfu versionor$SMDDFU#001;5
- Verify
DEBUG_LEVEL> 0 at compile time - Check
DBP01matches your interface (1 = USB CDC for LinkIt V4, 0 = UART/J3 for RSPB) - For RSPB: debug log is on the J3 UART connector, not USB — requires a USB-to-UART adapter
- Board Variants — Hardware specs, parameters, and configuration per board
- DTE Commands Reference — Full protocol and command documentation
- Architecture Overview — Firmware design and service model
- Underwater & Behavioral Modes — UW detection, SWS algorithm, cooldown, HAULED