Skip to content

feat(boards): add AkidaTag hardware revision 2 as a build target - #97

Merged
nikunj95 merged 7 commits into
mainfrom
fm/akt-rev2-board-support
Sep 27, 2026
Merged

nikunj95 merged 7 commits into
mainfrom
fm/akt-rev2-board-support

Conversation

@nikunj95

@nikunj95 nikunj95 commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

What this does

AkidaTag hardware revision 2 becomes a build target next to revision 1:

./scripts/run.sh -d -b --app demo_apps           # revision 1, the default, unchanged
./scripts/run.sh -d -b --rev 2 --app demo_apps   # revision 2

To get there, the AkidaTag board stops being "the nRF5340 DK plus an overlay" and becomes a Zephyr board definition, src/boards/brainchip/akidatag/, with revisions 1 and 2. Revision 1 stays the default in board.yml, and release and CI builds are unchanged: nothing under .github/workflows/ is touched.

Revision 2 is not the default or the release target yet. That switch waits until the firmware has been tested on a real revision 2 board.

Why Zephyr board revisions

nRF Connect SDK v3.1.1 uses Zephyr's hardware model v2. HWMv2 handles hardware revisions as board revisions:

  • board.yml declares them (revision: with format: number, default: "1", exact: true).
  • The build selects one as akidatag@2/nrf5340/cpuapp.
  • Files named <board>_<qualifiers>_<revision>.overlay (and _defconfig) are picked up for the selected revision.
  • BOARD_REVISION is set in CMake and Kconfig.
  • Sysbuild passes the revision on to every image, so MCUboot and the network core are built for the same revision as the application.

This PR uses that one mechanism and nothing alongside it:

  • The revision 1 and revision 2 differences are the two revision overlays.
  • MCUboot's own adjustments sit in src/sysbuild/mcuboot/boards/ under the same revision file names. Sysbuild discovers them there.
  • The one Kconfig default that depends on the board, the INA190 variant, tests BOARD_REVISION.
  • run.sh --rev N only appends @N to the board target.

Alternatives considered:

  • Board revisions on the old overlay setup. Not possible: the old build targeted nrf5340dk, which has no revisions. A board extension can add variants to it, but not revisions.
  • Board variants. Zephyr uses variants for different SoC or CPU configurations, such as ns, not for different PCB revisions.
  • A Kconfig switch, or run.sh choosing overlay files. Either would be a second selection mechanism outside Zephyr's, and it would not reach MCUboot or the network core consistently.

The move to sysbuild's MCUboot configuration directory has one cost. That directory replaces MCUboot's own configuration directory, so src/sysbuild/mcuboot/prj.conf restates MCUboot's prj.conf from NCS v3.1.1 unchanged. src/sysbuild/mcuboot.conf still carries the project's settings.

Revision 2 differences

I checked the full nRF5340 pin map against the revision 2 schematic, netlist and bill of materials, not only the known list. The pins below differ from revision 1. Every other pin matches revision 1: UART, I2C, PDM, the AKD1500 host SPI, the rail enables, charger status, fuel gauge and IMU interrupts, and the ADC inputs.

Revision 1 (default) Revision 2
Camera SPI SPIM3, shared with flash IC1: P0.17, P0.13, P0.14; chip select P0.25 SPIM2 on its own: SCK P0.06, MOSI P0.07, MISO P0.26; chip select P0.25
Camera level shifter enable, P1.15 Active high Active low (SN74AXC2T245 OE)
Camera supply None cam_pwr_enb on P1.06, switched on just before the level shifters
User button P0.26; the MCUboot button on P1.01 P1.01 for the application and MCUboot
LEDs Red P0.28, green P0.27 Red P1.14, green P0.27; blue P1.13 and white P0.28 are described but not driven
akdreset P1.13 Removed; P1.13 is the blue LED
Flash IC1 Micron MT25QU128ABA, SPIM3 chip select 1 Winbond W25Q128JW, JEDEC ID EF 60 18, SPIM3 chip select 0
Flash IC2, behind the AKD1500 Micron Winbond W25Q128JW
INA190 default A1, 25 V/V A3, 100 V/V
MCUboot flash access SPIM4 on the SPIM3 pins, as before The board's SPIM3 flash node; SPIM2 and SPIM4 stay off

The Winbond deep power-down timings come from the W25Q128JW datasheet: 3 µs to enter, 30 µs to exit.

The firmware now reads these properties from the board description instead of hard-coding them:

  • The camera driver uses the camera node's bus rather than spi3.
  • akidatag_peripherals_power_enable() switches on the camera supply when the board has one.
  • The AKD1500 flash routines skip the Micron flag status commands when the flash is not a Micron part. On the Winbond part, 0x50 is Volatile SR Write Enable and 0x70 is not a defined command, so the old erase and write checks would have read an undefined response.

Revision 1 behaviour is unchanged

I built revision 1 from main and from this branch in the same container and compared the images:

  • Network core (hci_ipc): byte-identical.

  • MCUboot: only the pin control function differs. It lost the PWM case, which came from the DK's PWM LED node, and gained the PDM case for the board's microphone. MCUboot configures only UART and SPIM pins, so no executed path changes. As a check, a throwaway build with those two nodes swapped back produced an MCUboot identical to main.

  • Application: three differences, all from DK devicetree content that the old overlay approach inherited:

    • The device metadata no longer includes the DK's arduino_i2c and arduino_spi labels.
    • The BLE disconnect handler no longer calls dk_set_led_off(). On main that call went through the DK's LED table and cleared the output latch of P0.29. That pin is the console UART's TX, which the UART owns while it runs. With the DK table gone, the call would have logged an error at every disconnect instead. It is now guarded by CONFIG_DK_BOARD, like every other DK LED call (the first commit).
    • An assert in gpio.c reports a different line number.

    With the DK LED table and labels put back in a throwaway build, the application was identical to main except for that line number.

  • Devicetree: every enabled node that remains has the same pins and properties. The nodes that went away are DK leftovers with no driver in this firmware: the Arduino connectors, the PWM LED, USBD, NFCT, IEEE 802.15.4 and the boot-mode retention area.

  • DK build: MCUboot and the network core are byte-identical to main. The application differs only by the guarded LED call.

Builds and checks

CI builds two targets today: the AkidaTag release build in release.yml and the DK build in hardware.yml. The DK has no hardware revisions, so the full matrix is revision 1, revision 2 and the DK, each built from the head of this branch.

On the toolchain image: CI uses ghcr.io/brainchip-inc/akidatag-ncs:v3.1.1-py3.12, but pulling it from this machine failed twice on the same layer. All builds below therefore ran in akidatag-ncs:v3.1.1-py3.12, built locally from the same docker/Dockerfile with NCS v3.1.1 and Python 3.12. The only toolchain-side change since that image was built is the host Python requirements.

Build Command Result
Revision 1, the release build ./scripts/run.sh -d --release -b --app demo_apps Passed. Images match the revision 1 analysis above.
Revision 2 ./scripts/run.sh -d --release -b --rev 2 --app demo_apps Passed. The build reports CONFIG_BOARD_REVISION="2" and INA190_VARIANT_A3 in the application, MCUboot and network core images.
DK ./scripts/run.sh -d --release -b --dk --app demo_apps Passed. MCUboot and network core are identical to main.
Revision 1 at the board definition commit alone as the first row Passed. The network core and MCUboot are identical to the final revision 1 build.
main, revision 1 and DK as the first and third rows Passed. Baselines for the comparisons above.
Revision 1 and revision 2 after merging main (the published docs trim) as the first two rows Passed, with the same board targets and INA190 defaults. The merge changed only docs and the site.
Docs site npm run build in site/ Passed. All 13 pages build, and every internal link, anchor and repository link in the output resolves.

Checks:

  • clang-format 23.1.0 check on the five changed C and C++ files: passed. akd_spi_flash.cpp keeps its CRLF line endings.
  • shellcheck 0.11.0 on scripts/run.sh: passed.
  • No Python changed. All commit subjects pass .github/ci-gates/check-subject.sh.
  • --rev 2 --dk is rejected with an error.

No board was flashed or connected for this PR.

To test on the first revision 2 board

  • Boot, BLE advertising, and a model transfer and inference.
  • Camera capture at both resolutions. This covers the camera supply, the level shifter enable polarity and the SPIM2 pins.
  • The user button in the application, and holding it through reset to enter MCUboot serial recovery. The red LED should show recovery mode.
  • LittleFS and a firmware update over BLE and over USB-C, both on the Winbond flash IC1.
  • Writing a model to the AKD1500's Winbond flash IC2, with a read back.
  • power read with the A3 default against a meter.
  • The fuel gauge current sign while charging. Both revisions keep the same sign correction, and the datasheet now says so.

Other changes

  • NOTICE records that the board definition is adapted from Zephyr's nRF5340 DK board. Those files keep the upstream copyright and SPDX lines.

  • The docs changes are limited to two kinds:

    • The --rev 2 build and flash commands, documented wherever build options are documented: docs/setup.md, docs/developer-guide.md, README.md, src/README.md, AGENTS.md and the run.sh help. The published pages under docs/ mention only the AkidaTag board. The DK appears only in firmware code, scripts, AGENTS.md and src/README.md.
    • In docs/hardware/, the passages saying the firmware does not match revision 2. They now describe a revision 2 build.

    I also updated the file references in those docs that named the removed overlay files. After main gained the published docs trim, the developer guide's statement that the AkidaTag builds as nrf5340dk/nrf5340/cpuapp became the board definition wording.

Noticed, not changed

  • 32 kHz crystal load capacitance. The board definition keeps the DK's LFXO setting of 7 pF internal load capacitance. The revision 2 bill of materials fits 6 pF external capacitors (C2, C4) for a 6 pF crystal. This applies to both revisions, so it is left for a separate change.
  • Network core console pins. The network core keeps the DK's UART pins. The application core never hands those pins to the network core, so the console has no output. Kept for identity.
  • docs/BOARD_OVERLAY_CHANGES.md still describes the removed overlay.
  • The revision 2 bill of materials swaps the SW1 and SW2 designators relative to the schematic.
  • Devicetree warning. The revision 1 IC1 node keeps its flash@0 name, because the device name is part of the image. Its reg = <1> triggers a devicetree unit-address warning.

The disconnect handler called dk_set_led_off() on every board, while every
other DK LED call is guarded by CONFIG_DK_BOARD. On the AkidaTag board the
DK library's LED table came from the nRF5340 DK devicetree, so the call
cleared the output latch of P0.29, the console UART's TX pin, which the
UART owns while it runs. Without the DK devicetree the table is empty and
the call would log an error at every disconnect instead.
…ition

The AkidaTag board was built as the nRF5340 DK with an application overlay
and an MCUboot overlay on top. Zephyr can only attach hardware revisions to
a board of its own, and the nRF5340 DK has none, so the board now has a
board definition in src/boards/brainchip/akidatag/, adapted from the DK's.
Its devicetree is split into what every revision shares and a revision 1
overlay, and board.yml declares revision 1 as the default.

MCUboot's changes move into the sysbuild configuration directory
src/sysbuild/mcuboot/, whose boards/ overlays sysbuild finds by board and
revision name. MCUboot then no longer reads its own prj.conf, so the
directory restates it; the project's settings stay in mcuboot.conf.

run.sh builds akidatag/nrf5340/cpuapp with src as the board root, and
names the DK target explicitly instead of reading it from the environment.

The revision 1 network core image is byte-identical to the one built from
the overlays. MCUboot and the application differ only where the DK
devicetree used to leak in: MCUboot no longer carries pin control code for
the DK's PWM LED, and the application no longer carries the DK's LED table
or its Arduino node labels.
Revision 2 is a Zephyr board revision of the AkidaTag board, selected with
run.sh --rev 2 (akidatag@2/nrf5340/cpuapp). Revision 1 stays the default.

The revision 2 overlay follows the revision 2 schematic, netlist and bill
of materials: the camera on SPIM2 (P0.06, P0.07, P0.26, chip select
P0.25), the camera supply switch on P1.06, the camera level shifter enable
on P1.15 as active low, the user button on P1.01, the red, green, blue and
white LEDs on P1.14, P0.27, P1.13 and P0.28, no akdreset line, and Winbond
W25Q128JW flash in both positions. MCUboot on revision 2 uses the board's
flash node directly.

The firmware follows the description rather than fixed names: the camera
driver takes the camera node's bus, the power-up sequence switches on the
camera supply when the board has one, and the AKD1500 flash routines skip
the Micron flag status commands when the flash is not a Micron part, since
Winbond parts use those opcodes for other commands. The INA190 variant
defaults to A3 on revision 2.
Describe --rev 2 wherever the build options are documented, and replace
the statements that both boards build as the nRF5340 DK with the board
definition and its revisions.
The datasheet described the firmware on main as not matching revision 2.
Its pin table, flash, camera, power and current-sense notes now describe a
revision 2 build and how to make one, and list where the default revision 1
build differs. The fuel gauge note states that both revisions share the
same current-sign handling, which is checked on the first revision 2
board. Source references point at the board definition that replaces the
removed overlays.
Main now keeps the published pages to the AkidaTag board. The developer
guide's build section takes this branch's board definition and revision 2
wording without the DK build lines.
@nikunj95
nikunj95 merged commit 099af26 into main Sep 27, 2026
3 checks passed
@nikunj95
nikunj95 deleted the fm/akt-rev2-board-support branch September 27, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant