From d28f54587c4db5778ff63ce7b0dc4f70eaa71e6f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 1 Apr 2026 13:36:16 -0700 Subject: [PATCH] Add Zephyr build for the Feather nrf52840 Sense --- .../autogen_board_info.toml | 120 ++++++++++++++++++ .../circuitpython.toml | 4 + .../autogen_board_info.toml | 2 +- .../circuitpython.toml | 1 + ...t_feather_nrf52840_nrf52840_sense_uf2.conf | 10 ++ ...eather_nrf52840_nrf52840_sense_uf2.overlay | 46 +++++++ ports/zephyr-cp/boards/board_aliases.cmake | 1 + .../zephyr-cp/cptools/build_circuitpython.py | 21 +-- ports/zephyr-cp/cptools/zephyr2cp.py | 4 +- 9 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml create mode 100644 ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/circuitpython.toml create mode 100644 ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.conf create mode 100644 ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.overlay diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml new file mode 100644 index 0000000000000..cfcae40090624 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml @@ -0,0 +1,120 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Adafruit Industries LLC Feather Bluefruit Sense" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = false +adafruit_pixelbuf = false +aesio = false +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilters = false +audiofreeverb = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = false +gifio = false +gnss = false +hashlib = false +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = false +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = false +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = false +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_cdc = true +usb_hid = false +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = false diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/circuitpython.toml new file mode 100644 index 0000000000000..eacb0f9607df9 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/circuitpython.toml @@ -0,0 +1,4 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] +USB_VID=0x239A +USB_PID=0x8088 +NAME="Feather Bluefruit Sense" diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml index 7b1fb9a0d6f55..4f56f4d203e1e 100644 --- a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml @@ -1,5 +1,5 @@ # This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. -name = "Adafruit Industries LLC Feather nRF52840 (Express, Sense)" +name = "Adafruit Industries LLC Feather nRF52840 Express" [modules] __future__ = true diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/circuitpython.toml index e1a16cb74aa46..c4d1099a77e1d 100644 --- a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/circuitpython.toml +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/circuitpython.toml @@ -1,3 +1,4 @@ CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] USB_VID=0x239A USB_PID=0x802A +NAME="Feather nRF52840 Express" diff --git a/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.conf b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.conf new file mode 100644 index 0000000000000..20176b34be052 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.conf @@ -0,0 +1,10 @@ +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_BROADCASTER=y +CONFIG_BT_OBSERVER=y +CONFIG_BT_EXT_ADV=y + +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n diff --git a/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.overlay b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.overlay new file mode 100644 index 0000000000000..e01ebd6df1f51 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.overlay @@ -0,0 +1,46 @@ +/ { + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + }; +}; + +&zephyr_udc0 { + /delete-node/ board_cdc_acm_uart; +}; + + +&gd25q16 { + /delete-node/ partitions; +}; + +/delete-node/ &storage_partition; +/delete-node/ &code_partition; + +&flash0 { + partitions { + code_partition: partition@26000 { + label = "Application"; + reg = <0x00026000 0x000c4000>; + }; + + storage_partition: partition@ea000 { + label = "storage"; + reg = <0x000ea000 0x00008000>; + }; + + nvm_partition: partition@f2000 { + label = "nvm"; + reg = <0x000f2000 0x00002000>; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/board_aliases.cmake b/ports/zephyr-cp/boards/board_aliases.cmake index e973eac72d4a5..e20a7b0cc62d7 100644 --- a/ports/zephyr-cp/boards/board_aliases.cmake +++ b/ports/zephyr-cp/boards/board_aliases.cmake @@ -28,6 +28,7 @@ endmacro() cp_board_alias(pca10056 nrf52840dk/nrf52840) cp_board_alias(adafruit_feather_nrf52840_zephyr adafruit_feather_nrf52840/nrf52840/uf2) +cp_board_alias(adafruit_feather_nrf52840_sense_zephyr adafruit_feather_nrf52840/nrf52840/sense/uf2) cp_board_alias(renesas_ek_ra6m5 ek_ra6m5) cp_board_alias(renesas_ek_ra8d1 ek_ra8d1) cp_board_alias(renesas_da14695_dk_usb da14695_dk_usb) diff --git a/ports/zephyr-cp/cptools/build_circuitpython.py b/ports/zephyr-cp/cptools/build_circuitpython.py index 63a2ed9635142..772c805a50143 100644 --- a/ports/zephyr-cp/cptools/build_circuitpython.py +++ b/ports/zephyr-cp/cptools/build_circuitpython.py @@ -362,6 +362,11 @@ async def build_circuitpython(): genhdr = builddir / "genhdr" genhdr.mkdir(exist_ok=True, parents=True) version_header = genhdr / "mpversion.h" + mpconfigboard_fn = board_tools.find_mpconfigboard(portdir, board) + mpconfigboard = {"USB_VID": 0x1209, "USB_PID": 0x000C, "USB_INTERFACE_NAME": "CircuitPython"} + if mpconfigboard_fn is not None and mpconfigboard_fn.exists(): + with mpconfigboard_fn.open("rb") as f: + mpconfigboard.update(tomllib.load(f)) async with asyncio.TaskGroup() as tg: tg.create_task( cpbuild.run_command( @@ -379,11 +384,9 @@ async def build_circuitpython(): ) board_autogen_task = tg.create_task( - zephyr_dts_to_cp_board(zephyr_board, portdir, builddir, zephyrbuilddir) + zephyr_dts_to_cp_board(zephyr_board, portdir, builddir, zephyrbuilddir, mpconfigboard) ) board_info = board_autogen_task.result() - mpconfigboard_fn = board_tools.find_mpconfigboard(portdir, board) - mpconfigboard = {"USB_VID": 0x1209, "USB_PID": 0x000C, "USB_INTERFACE_NAME": "CircuitPython"} if mpconfigboard_fn is None: mpconfigboard_fn = ( portdir / "boards" / board_info["vendor_id"] / board / "circuitpython.toml" @@ -391,9 +394,6 @@ async def build_circuitpython(): logging.warning( f"Could not find board config at: boards/{board_info['vendor_id']}/{board}" ) - elif mpconfigboard_fn.exists(): - with mpconfigboard_fn.open("rb") as f: - mpconfigboard.update(tomllib.load(f)) autogen_board_info_fn = mpconfigboard_fn.parent / "autogen_board_info.toml" @@ -402,6 +402,9 @@ async def build_circuitpython(): circuitpython_flags.append(f"-DCIRCUITPY_CREATOR_ID=0x{creator_id:08x}") circuitpython_flags.append(f"-DCIRCUITPY_CREATION_ID=0x{creation_id:08x}") + vendor = mpconfigboard.get("VENDOR", board_info["vendor"]) + name = mpconfigboard.get("NAME", board_info["name"]) + enabled_modules, module_reasons = determine_enabled_modules(board_info, portdir, srcdir) web_workflow_enabled = board_info.get("wifi", False) or board_info.get("hostnetwork", False) @@ -459,8 +462,8 @@ async def build_circuitpython(): f"-DUSB_INTERFACE_NAME='\"{mpconfigboard['USB_INTERFACE_NAME']}\"'" ) for macro, limit, value in ( - ("USB_PRODUCT", 16, board_info["name"]), - ("USB_MANUFACTURER", 8, board_info["vendor"]), + ("USB_PRODUCT", 16, name), + ("USB_MANUFACTURER", 8, vendor), ): circuitpython_flags.append(f"-D{macro}='\"{value}\"'") circuitpython_flags.append(f"-D{macro}_{limit}='\"{value[:limit]}\"'") @@ -512,7 +515,7 @@ async def build_circuitpython(): "This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info." ) ) - autogen_board_info.add("name", board_info["vendor"] + " " + board_info["name"]) + autogen_board_info.add("name", vendor + " " + name) autogen_modules = tomlkit.table() autogen_board_info.add("modules", autogen_modules) for module in sorted( diff --git a/ports/zephyr-cp/cptools/zephyr2cp.py b/ports/zephyr-cp/cptools/zephyr2cp.py index 08a16da0cf6fa..d40501f1d1d00 100644 --- a/ports/zephyr-cp/cptools/zephyr2cp.py +++ b/ports/zephyr-cp/cptools/zephyr2cp.py @@ -433,7 +433,7 @@ def find_ram_regions(device_tree): @cpbuild.run_in_thread -def zephyr_dts_to_cp_board(board_id, portdir, builddir, zephyrbuilddir): # noqa: C901 +def zephyr_dts_to_cp_board(board_id, portdir, builddir, zephyrbuilddir, mpconfigboard=None): # noqa: C901 board_dir = builddir / "board" # Auto generate board files from device tree. @@ -486,6 +486,8 @@ def zephyr_dts_to_cp_board(board_id, portdir, builddir, zephyrbuilddir): # noqa soc_name = board_yaml["socs"][0]["name"] board_info["soc"] = soc_name board_name = board_yaml["full_name"] + if mpconfigboard and "NAME" in mpconfigboard: + board_name = mpconfigboard["NAME"] board_info["name"] = board_name # board_id_yaml = zephyr_board_dir / (zephyr_board_dir.name + ".yaml") # board_id_yaml = yaml.safe_load(board_id_yaml.read_text())