Skip to main content

How to Use NX40 with nRF Connect SDK and Zephyr

This guide introduces nRF Connect SDK and Zephyr RTOS for DEV-NX40, using UF2 firmware upload over USB. It follows the technical progression of Nordic Developer Academy: understand the SDK, build an application, describe hardware, configure software, and add peripherals and concurrent tasks.

Board support

NX40 board support is provided by NX-Zephyr-Samples. Use board target nx40/nrf52840 with nRF Connect SDK v3.3.1, the tested release.

NX40 nRF Connect SDK and Zephyr platform illustration

NX40 development platform illustration. Firmware is uploaded over USB through the UF2 bootloader.

Understand the platform​

nRF Connect SDK combines Nordic software with Zephyr's kernel, drivers, and hardware descriptions. Its workspace contains several repositories, including nrf, zephyr, nrfxlib, and MCUboot. Available features depend on the selected device and application configuration; the SDK-wide protocol list is not a feature list for NX40.

The build uses separate inputs:

Input or toolResponsibility
C applicationRuntime behavior
DevicetreeHardware instances, connections, and properties
KconfigSoftware features and their settings
CMakeBuild configuration
Ninja and compiler toolchainCompilation and linking
westWorkspace and build/programming commands

This separation lets application logic use board-defined devices without embedding connector pin numbers. See Nordic's SDK structure and content.

NX40 firmware build workflow

Application code, Kconfig, and board devicetree contribute to the firmware build, followed by UF2 programming over USB.

Supported host platforms​

Nordic provides its VS Code development workflow for Windows, macOS, and Linux. Check the host requirements for the SDK release selected by the NX40 board package.

Record the operating system, SDK version, toolchain version, board-package revision, and UF2 bootloader version with each validated setup.

Before you begin​

Required hardware​

ItemRequirement
Development boardDEV-NX40 with a matching Zephyr board definition
BootloaderKORLINX UF2 bootloader installed on the board
USB cableData-capable cable connected to the board's native USB interface for UF2 upload
Optional console connectionBoard-supported UART bridge or firmware-enabled USB CDC connection

A bare NX40 module additionally needs a carrier with power, native USB access, the UF2 bootloader, and the required application circuitry. See Dev Kit Hardware and the module pin map.

Required software​

  • Visual Studio Code and Nordic's nRF Connect for VS Code Extension Pack.
  • An nRF Connect SDK release and its matching toolchain.
  • NX40 board support compatible with that release.
  • Host USB support for the bootloader's mass-storage drive; serial drivers if using a UART console.

Install nRF Connect for VS Code​

  1. Install Visual Studio Code for your operating system.
  2. Open Extensions from the Activity Bar.
  3. Search for nRF Connect for VS Code and select the extension pack published by Nordic Semiconductor.
  4. Select Install, then reload VS Code if prompted.
  5. Open nRF Connect from the Activity Bar.

The pack provides these tools:

ExtensionPurpose
nRF ConnectSDK management, building, flashing, and debugging
nRF DeviceTreeHardware-description editing and visualization
nRF KconfigSoftware-configuration editing
nRF TerminalSerial and RTT terminal access

Follow Nordic's installation exercise for release-specific SDK prerequisites. The NX40 UF2 upload procedure uses the bootloader's USB drive.

Install the Nordic VS Code extension and select nRF Connect SDK

Install the Nordic extension, then select Install SDK and the Zephyr-based nRF Connect SDK option.

Install the SDK and toolchain​

  1. In the nRF Connect welcome view, select Install SDK.
  2. If prompted for SDK type, select nRF Connect SDK for the Zephyr-based workflow.
  3. Select the release supported by the NX40 board package and install its matching toolchain.
  4. Confirm installation in Manage SDKs and open a terminal associated with that SDK environment.

Installing the extension alone does not install the SDK. Install Toolchain is for toolchain-only setups, such as an existing west workspace. UI labels can vary by version.

SDK toolchain and NX40 board package compatibility

Match the SDK and toolchain to the board package. The tested release is nRF Connect SDK v3.3.1.

Select the NX40 hardware definition​

The NX40 board definition is provided as a Zephyr module by the NX-Zephyr-Samples repository. See Get the samples to install it. It defines:

Board settingNX40 board definition
Targetnx40/nrf52840, tested with nRF Connect SDK v3.3.1
LEDled0 is the red user LED on P0.11, active low
Clock sources32.768 kHz crystal for the low-frequency clock
ConsoleNative USB CDC ACM, started by the board at boot
Flash layoutApplication at 0x26000 (792 KB), after the SoftDevice region used by the KORLINX UF2 bootloader
UF2 outputEnabled by the board, family ID 0xADA52840
Module variantExternal flash (32 Mbit) enabled; disable its node with an overlay on a no-flash module

Do not substitute nrf52840dk/nrf52840 just to make compilation succeed. A build can succeed while using incompatible pins or flash settings.

Prepare the UF2 USB connection​

  1. Connect DEV-NX40 to the computer through its native USB interface using a data-capable cable.
  2. Enter UF2 bootloader mode using the reset-button sequence documented for the installed KORLINX bootloader.
  3. Confirm that a removable USB drive appears in the host file manager.
  4. Keep the board connected while preparing the UF2 application image.

Use the drive name reported by your board; it depends on the installed bootloader. The FTDI USB-to-UART bridge provides a serial console, while UF2 upload uses the native USB bootloader's mass-storage interface.

Bootloader-compatible firmware

Use the NX40 board package's application flash layout and UF2 settings. Generating a .uf2 file alone does not make an arbitrary Zephyr image compatible with the installed bootloader. Preserve the bootloader and its reserved flash regions.

Build your first application​

  1. In nRF Connect for VS Code, create an application by copying a sample.
  2. Select zephyr/samples/basic/blinky from the installed SDK.
  3. Save the copy as nx40_blinky outside the SDK's sample directory.
  4. Add a build configuration and select the installed SDK, matching toolchain, and exact NX40 board target.
  5. Apply only the overlays and configuration files required by the NX40 board package.

Nordic's first build exercise demonstrates the sample-copy and build-configuration workflow.

Blinky application and build configuration for NX40

Illustrative build configuration. Select the SDK, toolchain, and verified NX40 target supplied by the board package.

Upload over USB​

  1. Enter UF2 bootloader mode again if the removable drive is no longer visible.
  2. Copy the generated application .uf2 file to that drive using the host file manager.
  3. Wait for the copy to finish. The bootloader programs the application and normally restarts the board; its USB drive may disappear.
  4. If the board remains in bootloader mode, follow its documented reset procedure to start the application.
  5. Check the expected application behavior, such as the Blinky LED.

Repeat the build and copy steps after changing the application. Copy the generated UF2 artifact; renaming a .hex or .bin file to .uf2 does not convert it.

NX40 sample applications​

The NX-Zephyr-Samples repository contains the NX40 board definition and ready-to-build samples for the on-board peripherals and Bluetooth LE. The repository is a Zephyr module, so you can keep it outside your nRF Connect SDK workspace.

Get the samples​

Clone the repository next to your nRF Connect SDK workspace:

git clone https://github.com/KORLINX/NX-Zephyr-Samples

The commands below refer to the path of this clone as <repo>.

Build and upload a sample​

  1. Open a terminal in the nRF Connect SDK environment and change to the SDK workspace directory.

  2. Build the sample. Pass the repository as an extra Zephyr module so the build can find the NX40 board:

    west build -p always -b nx40/nrf52840 -d build/hello <repo>/samples/hello -- -DZEPHYR_EXTRA_MODULES=<repo>
  3. Upload build/hello/hello/zephyr/zephyr.uf2 as described in Upload over USB, or let west copy it to the bootloader drive:

    west flash -d build/hello -r uf2
  4. Open the DEV-NX40 USB serial port to see the output.

note

west flash -r uf2 can report a FileNotFoundError after the copy, because the bootloader resets as soon as it receives the image. The image is programmed when DEV-NX40 restarts and its USB serial port reappears.

tip

Samples built from this repository reboot into the bootloader when the USB serial port is opened at 1200 baud and closed, so you do not need to press reset for the next upload. On Linux: stty -F /dev/ttyACM0 1200.

Available samples​

SampleWhat it showsStatus on DEV-NX40
helloConsole output with printk and the logging subsystemVerified
uartInterrupt-driven UART receive and echo on the console portVerified
dmicPDM microphone capture with the DMIC APIVerified
qspi_flashErase, write and verify of the 32 Mbit external flash with the flash APIVerified
direct_test_modeBluetooth LE Direct Test Mode for RF testing over USB serialVerified
dht_pollingTemperature and humidity from the SHTC3 with the sensor APIValidation in progress
lsm6dsoAccelerometer and gyroscope data from the 6-axis IMUValidation in progress
gattBluetooth LE peripheral with a custom GATT service and notificationsValidation in progress
rssi_power_controlConnection RSSI and LE Power Control between two boards (central and peripheral)Validation in progress
nrf_dmDistance measurement between two boardsValidation in progress

Each sample folder contains a README.rst with its requirements, build command, and expected behavior.

caution

The qspi_flash sample erases the entire external flash. Do not run it on a board whose external flash contents you need to keep.

Onboard LED​

Zephyr's Blinky sample uses the led0 alias to select a physical LED. Use the verified NX40 board definition to configure that alias.

Build and run Blinky​

  1. Build and upload Blinky as described in Build your first application.
  2. Observe the user LED assigned to led0; it should alternate between on and off.
  3. Change SLEEP_TIME_MS in the sample, rebuild, and upload the new UF2 file. Confirm that the interval changes.

How the LED is selected​

The sample resolves an alias into a GPIO specification:

#define LED0_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

Trace led0 to the board's LED node. Its gpios property supplies the controller, pin number, and polarity. For an active-low LED, the devicetree flag makes the GPIO API interpret the active state correctly.

Expected result​

The red user LED (led0, P0.11, active low) blinks at the configured interval. Power and charging indicators do not verify Blinky.

Expected on and off behavior of the LED mapped to led0

Expected Blinky behavior, not a hardware test capture. On DEV-NX40 the LED mapped to led0 is the red user LED.

Describe hardware with devicetree​

A devicetree is a hierarchy of hardware nodes and properties. A node label identifies a node in source; an alias provides a name that portable application code can look up. Board files describe assembled hardware, while SoC include files describe the chip's peripherals. Read Nordic's Devicetree lesson.

Use the GPIO API​

Nordic's GPIO Generic API lesson introduces this sequence:

  1. Retrieve a gpio_dt_spec with GPIO_DT_SPEC_GET().
  2. Check the controller using gpio_is_ready_dt().
  3. Configure the pin with gpio_pin_configure_dt() and check its return value.
  4. Read or drive the pin using the GPIO API.

Logical active/inactive operations honor the devicetree polarity. An active-low LED therefore needs the correct flag in its hardware definition. After Blinky, apply the same approach to the NX40 user button with its verified input and pull configuration.

Resolve led0 through devicetree into a GPIO specification

The led0 alias resolves to an LED node whose GPIO properties define the controller, pin, and polarity.

Configure application features​

Understand the application files​

FilePurpose
src/main.cApplication logic
CMakeLists.txtBuild definition and source list
prj.confApplication Kconfig options
Board devicetree and overlaysHardware nodes, pin routing, and aliases

Zephyr separates application behavior from hardware description. See Application Development for configuration-file and overlay handling.

Arduino's LED_BUILTIN does not define Zephyr's led0 alias. See the Blinky sample requirements.

Kconfig and prj.conf​

Application configuration contains CONFIG_ assignments. For example, CONFIG_GPIO=y enables GPIO support. Board defaults and application settings contribute to the final configuration; dependencies determine which options can actually be enabled.

Inspect the generated .config for the application image when an option behaves unexpectedly. Change the source configuration and rebuild, rather than editing generated output. Nordic explains this in Configuration files.

Devicetree overlays​

Use application overlays for hardware changes specific to an example. An overlay changes selected nodes or properties without rewriting the shared board files. Enabling a node and enabling its driver are separate tasks: review both devicetree and Kconfig.

When rerouting a Nordic peripheral, check its pinctrl configuration, including applicable default and sleep states. Confirm the selected overlay in the build log and inspect the generated zephyr.dts. The output is inside the application's image build directory, which can be nested when using sysbuild.

See Nordic's overlays and build systems lesson.

Kconfig and devicetree configuration inputs and outputs

Software configuration produces .config; board devicetree and overlays produce the resolved zephyr.dts.

Console output and logging​

Copy zephyr/samples/hello_world into a separate application. Build and upload its UF2 firmware with the same board target and its documented console configuration.

Console pathHow to observe it
Hardware UARTOpen the connected bridge's serial port at the configured baud rate
RTT (optional debugging)Requires a separate debug probe and firmware configured for RTT; UF2 upload itself does not provide RTT
Native USB CDCDefault console of nx40/nrf52840; open the DEV-NX40 USB serial port

Reset the board after opening the viewer to capture startup output. Hello World should print a greeting identifying the configured board. Do not assume that an FTDI port receives native USB CDC output or that Arduino's serial settings carry over.

UART RTT and USB CDC console paths

Alternative console paths; select the backend enabled in your firmware. The displayed output is illustrative.

Choose a logging backend​

Use printk() for a simple console check. For ongoing diagnostics, Nordic teaches the logger module with severity levels, filtering, deferred processing, and multiple backends. Enable logging with CONFIG_LOG=y, register an application module, and select a backend supported by the board configuration.

A log message being compiled into firmware does not guarantee that it reaches a connected serial port. UART and RTT have different transport requirements. See the Logger module lesson.

Troubleshooting​

SymptomWhat to check
NX40 target is unavailableInstall the matching board package and check its board-root/module discovery instructions
led0 or GPIO build errorConfirm the alias, referenced LED node, and driver configuration
Build uses unexpected pinsInspect the generated devicetree and selected overlays; use a pristine build after changing targets
UF2 USB drive does not appearCheck the data cable, native USB connection, installed bootloader, and its documented entry sequence
No .uf2 file after buildingCheck CONFIG_BUILD_OUTPUT_UF2, the selected build directory, and any sysbuild image subdirectories
UF2 copy completes but application does not startCheck the board target, UF2 family ID, application start address, reserved flash regions, and bootloader compatibility
Flash succeeds but no LED togglesConfirm LED assignment, polarity, image layout, and reset behavior
No console outputCheck the selected backend, physical routing, port, and UART baud rate
Bootloader is missing or damagedFollow the KORLINX bootloader recovery procedure before resuming UF2 uploads

References​