Full Code of paradajz/OpenDeck for AI

master 2de8b05714d5 cached
654 files
39.1 MB
10.3M tokens
488 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (41,159K chars total). Download the full file to get everything.
Repository: paradajz/OpenDeck
Branch: master
Commit: 2de8b05714d5
Files: 654
Total size: 39.1 MB

Directory structure:
gitextract_h4wb0_nf/

├── .codechecker.yml
├── .codex
├── .devcontainer/
│   ├── Dockerfile
│   └── devcontainer.json
├── .gitattributes
├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── .gitignore
├── .vscode/
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
├── LICENSE
├── Makefile
├── README.md
├── agents.md
├── app/
│   ├── CMakeLists.txt
│   ├── Kconfig
│   ├── boards/
│   │   ├── README.md
│   │   ├── opendeck/
│   │   │   ├── bergamot/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── blackpill411/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── discovery/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── dubfocus16t/
│   │   │   │   └── opendeck.overlay
│   │   │   ├── nrf52840dk/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── nrf54h20dk/
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck2/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck21/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck22/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck31/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── pico/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── pico2/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── rooibos/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── teensy4/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── teensy41/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   └── ws_core405r/
│   │   │       ├── firmware.overlay
│   │   │       └── opendeck.overlay
│   │   └── zephyr/
│   │       ├── blackpill_f411ce_stm32f411xe/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── nrf52840dk_nrf52840/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── nrf54h20dk_nrf54h20_cpuapp/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   ├── sysbuild.cmake
│   │       │   └── test.overlay
│   │       ├── rpi_pico2_rp2350a_m33/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── rpi_pico_rp2040/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── stm32f4_disco_stm32f407xx/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── teensy40_mimxrt1062/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── teensy41_mimxrt1062/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       └── weact_stm32f405_core_stm32f405xx/
│   │           ├── bootloader.conf
│   │           ├── bootloader.overlay
│   │           ├── firmware.conf
│   │           ├── firmware.overlay
│   │           ├── partitions.overlay
│   │           └── test.overlay
│   ├── bootloader/
│   │   ├── CMakeLists.txt
│   │   ├── bootloader.conf
│   │   └── src/
│   │       ├── fw_selector/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── common.h
│   │       │   ├── deps.h
│   │       │   ├── fw_selector.cpp
│   │       │   ├── fw_selector.h
│   │       │   └── hwa_hw.h
│   │       ├── indicators/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── indicators.cpp
│   │       │   └── indicators.h
│   │       ├── main.cpp
│   │       ├── updater/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── builder.h
│   │       │   ├── builder_hw.h
│   │       │   ├── builder_test.h
│   │       │   ├── common.h
│   │       │   ├── deps.h
│   │       │   ├── hwa_hw.h
│   │       │   ├── hwa_test.h
│   │       │   ├── updater.cpp
│   │       │   └── updater.h
│   │       └── webusb/
│   │           ├── transport.cpp
│   │           └── transport.h
│   ├── common/
│   │   ├── metadata/
│   │   │   └── CMakeLists.txt
│   │   └── retained/
│   │       ├── common.h
│   │       └── retained.h
│   ├── common.conf
│   ├── debug.conf
│   ├── dts/
│   │   └── bindings/
│   │       ├── opendeck/
│   │       │   ├── opendeck-analog.yaml
│   │       │   ├── opendeck-bootloader.yaml
│   │       │   ├── opendeck-bulk-build.yaml
│   │       │   ├── opendeck-buttons.yaml
│   │       │   ├── opendeck-display-i2c.yaml
│   │       │   ├── opendeck-leds.yaml
│   │       │   ├── opendeck-metadata.yaml
│   │       │   ├── opendeck-midi-indicators.yaml
│   │       │   ├── opendeck-midi-uart.yaml
│   │       │   ├── opendeck-tests.yaml
│   │       │   └── opendeck-touchscreen.yaml
│   │       └── vendor-prefixes.txt
│   ├── firmware/
│   │   ├── CMakeLists.txt
│   │   ├── Kconfig
│   │   ├── firmware.conf
│   │   └── src/
│   │       ├── Kconfig
│   │       ├── atomic_compat.cpp
│   │       ├── database/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── builder.h
│   │       │   ├── builder_hw.h
│   │       │   ├── builder_test.h
│   │       │   ├── config.h
│   │       │   ├── custom_init.cpp
│   │       │   ├── database.cpp
│   │       │   ├── database.h
│   │       │   ├── deps.h
│   │       │   ├── hwa_hw.h
│   │       │   ├── hwa_test.h
│   │       │   └── layout.h
│   │       ├── global/
│   │       │   ├── bpm.h
│   │       │   └── midi_program.h
│   │       ├── io/
│   │       │   ├── Kconfig
│   │       │   ├── analog/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── analog.cpp
│   │       │   │   ├── analog.h
│   │       │   │   ├── analog_stub.h
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── common.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── drivers/
│   │       │   │   │   ├── count.h
│   │       │   │   │   ├── driver.h
│   │       │   │   │   ├── driver_base.h
│   │       │   │   │   ├── multiplexer/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── multiplexer_driver.h
│   │       │   │   │   ├── mux_on_mux/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── mux_on_mux_driver.h
│   │       │   │   │   ├── native/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── native_driver.h
│   │       │   │   │   └── scan_driver_base.h
│   │       │   │   ├── filter_hw.h
│   │       │   │   ├── filter_stub.h
│   │       │   │   ├── filter_test.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   └── remap.h
│   │       │   ├── base.h
│   │       │   ├── common/
│   │       │   │   └── common.h
│   │       │   ├── digital/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── buttons/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── builder.h
│   │       │   │   │   ├── builder_hw.h
│   │       │   │   │   ├── builder_stub.h
│   │       │   │   │   ├── builder_test.h
│   │       │   │   │   ├── buttons.cpp
│   │       │   │   │   ├── buttons.h
│   │       │   │   │   ├── buttons_stub.h
│   │       │   │   │   ├── common.h
│   │       │   │   │   ├── deps.h
│   │       │   │   │   ├── filter_hw.h
│   │       │   │   │   ├── filter_stub.h
│   │       │   │   │   ├── filter_test.h
│   │       │   │   │   ├── hwa_hw.h
│   │       │   │   │   ├── hwa_stub.h
│   │       │   │   │   └── hwa_test.h
│   │       │   │   ├── digital.cpp
│   │       │   │   ├── digital.h
│   │       │   │   ├── drivers/
│   │       │   │   │   ├── count.h
│   │       │   │   │   ├── driver.h
│   │       │   │   │   ├── driver_base.h
│   │       │   │   │   ├── matrix_native_rows/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── matrix_native_rows_driver.h
│   │       │   │   │   ├── matrix_shift_register_rows/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── matrix_shift_register_rows_driver.h
│   │       │   │   │   ├── native/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── native_driver.h
│   │       │   │   │   └── shift_register/
│   │       │   │   │       ├── count.h
│   │       │   │   │       └── shift_register_driver.h
│   │       │   │   ├── encoders/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── builder.h
│   │       │   │   │   ├── builder_hw.h
│   │       │   │   │   ├── builder_stub.h
│   │       │   │   │   ├── builder_test.h
│   │       │   │   │   ├── common.h
│   │       │   │   │   ├── deps.h
│   │       │   │   │   ├── encoders.cpp
│   │       │   │   │   ├── encoders.h
│   │       │   │   │   ├── encoders_stub.h
│   │       │   │   │   ├── filter_hw.h
│   │       │   │   │   ├── filter_stub.h
│   │       │   │   │   ├── filter_test.h
│   │       │   │   │   ├── hwa_hw.h
│   │       │   │   │   ├── hwa_stub.h
│   │       │   │   │   └── hwa_test.h
│   │       │   │   ├── frame_store.h
│   │       │   │   └── remap.h
│   │       │   ├── i2c/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   ├── i2c.cpp
│   │       │   │   ├── i2c.h
│   │       │   │   ├── i2c_stub.h
│   │       │   │   └── peripherals/
│   │       │   │       ├── builder.h
│   │       │   │       ├── builder_hw.h
│   │       │   │       └── display/
│   │       │   │           ├── common.h
│   │       │   │           ├── deps.h
│   │       │   │           ├── display.cpp
│   │       │   │           ├── display.h
│   │       │   │           ├── element.h
│   │       │   │           ├── elements.cpp
│   │       │   │           └── strings.h
│   │       │   ├── indicators/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── common.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   ├── indicators.cpp
│   │       │   │   └── indicators.h
│   │       │   ├── leds/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── common.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── drivers/
│   │       │   │   │   ├── count.h
│   │       │   │   │   ├── driver.h
│   │       │   │   │   ├── driver_base.h
│   │       │   │   │   ├── matrix_native_rows/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── matrix_native_rows_driver.h
│   │       │   │   │   ├── max7219/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── max7219_driver.h
│   │       │   │   │   ├── native/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── native_driver.h
│   │       │   │   │   ├── shift_register/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── shift_register_driver.h
│   │       │   │   │   └── stub/
│   │       │   │   │       └── stub_driver.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   ├── leds.cpp
│   │       │   │   ├── leds.h
│   │       │   │   ├── leds_stub.h
│   │       │   │   └── remap.h
│   │       │   └── touchscreen/
│   │       │       ├── CMakeLists.txt
│   │       │       ├── builder.h
│   │       │       ├── builder_hw.h
│   │       │       ├── builder_stub.h
│   │       │       ├── builder_test.h
│   │       │       ├── common.h
│   │       │       ├── count.h
│   │       │       ├── deps.h
│   │       │       ├── hwa_hw.h
│   │       │       ├── hwa_stub.h
│   │       │       ├── hwa_test.h
│   │       │       ├── models/
│   │       │       │   ├── builder.h
│   │       │       │   ├── builder_hw.h
│   │       │       │   └── nextion/
│   │       │       │       ├── nextion.cpp
│   │       │       │       └── nextion.h
│   │       │       ├── touchscreen.cpp
│   │       │       ├── touchscreen.h
│   │       │       └── touchscreen_stub.h
│   │       ├── main.cpp
│   │       ├── messaging/
│   │       │   └── messaging.h
│   │       ├── protocol/
│   │       │   ├── base.h
│   │       │   └── midi/
│   │       │       ├── CMakeLists.txt
│   │       │       ├── ble_service.cpp
│   │       │       ├── ble_service.h
│   │       │       ├── builder.h
│   │       │       ├── builder_hw.h
│   │       │       ├── builder_test.h
│   │       │       ├── common.h
│   │       │       ├── deps.h
│   │       │       ├── hwa_hw.h
│   │       │       ├── hwa_test.h
│   │       │       ├── midi.cpp
│   │       │       └── midi.h
│   │       ├── system/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── builder.h
│   │       │   ├── builder_hw.h
│   │       │   ├── builder_test.h
│   │       │   ├── common.h
│   │       │   ├── config.h
│   │       │   ├── custom_ids.h
│   │       │   ├── deps.h
│   │       │   ├── hwa_hw.h
│   │       │   ├── hwa_test.h
│   │       │   ├── layout.h
│   │       │   ├── system.cpp
│   │       │   └── system.h
│   │       ├── threads.h
│   │       └── util/
│   │           ├── cinfo/
│   │           │   ├── CMakeLists.txt
│   │           │   ├── cinfo.cpp
│   │           │   └── cinfo.h
│   │           ├── configurable/
│   │           │   ├── CMakeLists.txt
│   │           │   ├── configurable.cpp
│   │           │   └── configurable.h
│   │           ├── conversion/
│   │           │   └── conversion.h
│   │           ├── incdec/
│   │           │   └── inc_dec.h
│   │           └── thread_sleep.h
│   ├── presets.yml
│   ├── release.conf
│   └── sysbuild.cmake
├── bin/
│   └── touchscreen/
│       └── design/
│           ├── corel/
│           │   ├── bergamot.cdr
│           │   └── cardamom.cdr
│           └── nextion-gui/
│               └── rooibos.hmi
├── cmake/
│   ├── bluetooth_device_name.conf.in
│   ├── dfu_bin.cmake
│   ├── helpers.cmake
│   ├── opendeck_library.cmake
│   ├── opendeck_test_suite.cmake
│   ├── opendeck_test_target.cmake
│   ├── usb_midi_label.overlay.in
│   └── usb_product.conf.in
├── sch/
│   ├── bergamot/
│   │   ├── MBO/
│   │   │   ├── MBO.brd
│   │   │   └── MBO.sch
│   │   ├── Pots/
│   │   │   ├── Pots.brd
│   │   │   └── Pots.sch
│   │   └── USB/
│   │       ├── USB.brd
│   │       └── USB.sch
│   ├── dmx/
│   │   └── DMX.sch
│   ├── dubfocus/
│   │   ├── 12sr/
│   │   │   ├── ButtonsLEDs/
│   │   │   │   ├── ButtonsLEDs.brd
│   │   │   │   └── ButtonsLEDs.sch
│   │   │   ├── MBO/
│   │   │   │   ├── MBO.brd
│   │   │   │   └── MBO.sch
│   │   │   ├── Pots/
│   │   │   │   ├── Pots.brd
│   │   │   │   └── Pots.sch
│   │   │   └── USB/
│   │   │       ├── USB.brd
│   │   │       └── USB.sch
│   │   ├── 16c/
│   │   │   ├── ButtonsLEDs/
│   │   │   │   ├── ButtonsLEDs.brd
│   │   │   │   └── ButtonsLEDs.sch
│   │   │   ├── MBO/
│   │   │   │   ├── MBO.brd
│   │   │   │   └── MBO.sch
│   │   │   ├── Pots/
│   │   │   │   ├── Pots.brd
│   │   │   │   └── Pots.sch
│   │   │   └── USB/
│   │   │       ├── USB.brd
│   │   │       └── USB.sch
│   │   └── 16t/
│   │       ├── ButtonsLEDs/
│   │       │   ├── Buttons.kicad_sch
│   │       │   ├── ButtonsLEDs.kicad_pcb
│   │       │   ├── ButtonsLEDs.kicad_pro
│   │       │   ├── ButtonsLEDs.kicad_sch
│   │       │   ├── LEDs.kicad_sch
│   │       │   └── prod/
│   │       │       ├── ButtonsLEDs-BOM.csv
│   │       │       ├── ButtonsLEDs-all-pos.csv
│   │       │       └── gerbers/
│   │       │           ├── ButtonsLEDs-B_Cu.gbl
│   │       │           ├── ButtonsLEDs-B_Mask.gbs
│   │       │           ├── ButtonsLEDs-B_Paste.gbp
│   │       │           ├── ButtonsLEDs-B_Silkscreen.gbo
│   │       │           ├── ButtonsLEDs-Edge_Cuts.gm1
│   │       │           ├── ButtonsLEDs-F_Cu.gtl
│   │       │           ├── ButtonsLEDs-F_Mask.gts
│   │       │           ├── ButtonsLEDs-F_Paste.gtp
│   │       │           ├── ButtonsLEDs-F_Silkscreen.gto
│   │       │           ├── ButtonsLEDs-NPTH-drl_map.gbr
│   │       │           ├── ButtonsLEDs-NPTH.drl
│   │       │           ├── ButtonsLEDs-PTH-drl_map.gbr
│   │       │           └── ButtonsLEDs-PTH.drl
│   │       ├── MBO/
│   │       │   ├── Connections.kicad_sch
│   │       │   ├── MBO.kicad_dru
│   │       │   ├── MBO.kicad_pcb
│   │       │   ├── MBO.kicad_pro
│   │       │   ├── MBO.kicad_sch
│   │       │   ├── MCU.kicad_sch
│   │       │   ├── Pots.kicad_sch
│   │       │   ├── Power.kicad_sch
│   │       │   └── prod/
│   │       │       ├── MBO-BOM.csv
│   │       │       ├── MBO-all-pos.csv
│   │       │       └── gerbers/
│   │       │           ├── MBO-B_Cu.gbl
│   │       │           ├── MBO-B_Mask.gbs
│   │       │           ├── MBO-B_Paste.gbp
│   │       │           ├── MBO-B_Silkscreen.gbo
│   │       │           ├── MBO-Edge_Cuts.gm1
│   │       │           ├── MBO-F_Cu.gtl
│   │       │           ├── MBO-F_Mask.gts
│   │       │           ├── MBO-F_Paste.gtp
│   │       │           ├── MBO-F_Silkscreen.gto
│   │       │           ├── MBO-NPTH-drl_map.gbr
│   │       │           ├── MBO-NPTH.drl
│   │       │           ├── MBO-PTH-drl_map.gbr
│   │       │           └── MBO-PTH.drl
│   │       ├── Pots/
│   │       │   ├── Mux.kicad_sch
│   │       │   ├── Pots.kicad_pcb
│   │       │   ├── Pots.kicad_pro
│   │       │   ├── Pots.kicad_sch
│   │       │   └── prod/
│   │       │       ├── Pots-BOM.csv
│   │       │       ├── Pots-all-pos.csv
│   │       │       └── gerbers/
│   │       │           ├── Pots-B_Cu.gbl
│   │       │           ├── Pots-B_Mask.gbs
│   │       │           ├── Pots-B_Paste.gbp
│   │       │           ├── Pots-B_Silkscreen.gbo
│   │       │           ├── Pots-Edge_Cuts.gm1
│   │       │           ├── Pots-F_Cu.gtl
│   │       │           ├── Pots-F_Mask.gts
│   │       │           ├── Pots-F_Paste.gtp
│   │       │           ├── Pots-F_Silkscreen.gto
│   │       │           ├── Pots-NPTH-drl_map.gbr
│   │       │           ├── Pots-NPTH.drl
│   │       │           ├── Pots-PTH-drl_map.gbr
│   │       │           └── Pots-PTH.drl
│   │       └── USB/
│   │           ├── USB.kicad_pcb
│   │           ├── USB.kicad_pro
│   │           ├── USB.kicad_sch
│   │           └── prod/
│   │               ├── USB-BOM.csv
│   │               ├── USB-all-pos.csv
│   │               └── gerbers/
│   │                   ├── USB-B_Cu.gbl
│   │                   ├── USB-B_Mask.gbs
│   │                   ├── USB-B_Paste.gbp
│   │                   ├── USB-B_Silkscreen.gbo
│   │                   ├── USB-Edge_Cuts.gm1
│   │                   ├── USB-F_Cu.gtl
│   │                   ├── USB-F_Mask.gts
│   │                   ├── USB-F_Paste.gtp
│   │                   ├── USB-F_Silkscreen.gto
│   │                   ├── USB-NPTH-drl_map.gbr
│   │                   ├── USB-NPTH.drl
│   │                   ├── USB-PTH-drl_map.gbr
│   │                   └── USB-PTH.drl
│   ├── opendeck/
│   │   ├── v1.2.2/
│   │   │   ├── OpenDeck-r1.2.2-BOM.csv
│   │   │   ├── OpenDeck-r1.2.2.brd
│   │   │   └── OpenDeck-r1.2.2.sch
│   │   ├── v2.0.1/
│   │   │   ├── OpenDeck-r2.0.1-BOM.csv
│   │   │   ├── OpenDeck-r2.0.1.brd
│   │   │   └── OpenDeck-r2.0.1.sch
│   │   ├── v2.1.0/
│   │   │   ├── OpenDeck-r2.1.0.brd
│   │   │   ├── OpenDeck-r2.1.0.sch
│   │   │   └── prod/
│   │   │       ├── OpenDeck-r2.1.0-BOM.csv
│   │   │       ├── OpenDeck-r2.1.0-top-pos.csv
│   │   │       └── gerbers/
│   │   │           ├── OpenDeck-r2.1.0.GBL
│   │   │           ├── OpenDeck-r2.1.0.GBO
│   │   │           ├── OpenDeck-r2.1.0.GBS
│   │   │           ├── OpenDeck-r2.1.0.GKO
│   │   │           ├── OpenDeck-r2.1.0.GTL
│   │   │           ├── OpenDeck-r2.1.0.GTO
│   │   │           ├── OpenDeck-r2.1.0.GTS
│   │   │           └── OpenDeck-r2.1.0.TXT
│   │   ├── v2.2.1/
│   │   │   ├── Analog.kicad_sch
│   │   │   ├── Buttons.kicad_sch
│   │   │   ├── DIN_MIDI.kicad_sch
│   │   │   ├── Indicators.kicad_sch
│   │   │   ├── LEDs.kicad_sch
│   │   │   ├── OpenDeck-r2.2.1.kicad_pcb
│   │   │   ├── OpenDeck-r2.2.1.kicad_pro
│   │   │   ├── OpenDeck-r2.2.1.kicad_sch
│   │   │   └── prod/
│   │   │       ├── OpenDeck-r2.2.1-BOM.csv
│   │   │       ├── OpenDeck-r2.2.1-top-pos.csv
│   │   │       └── gerbers/
│   │   │           ├── OpenDeck-r2.2.1-B_Cu.gbl
│   │   │           ├── OpenDeck-r2.2.1-B_Mask.gbs
│   │   │           ├── OpenDeck-r2.2.1-B_Paste.gbp
│   │   │           ├── OpenDeck-r2.2.1-B_Silkscreen.gbo
│   │   │           ├── OpenDeck-r2.2.1-Edge_Cuts.gm1
│   │   │           ├── OpenDeck-r2.2.1-F_Cu.gtl
│   │   │           ├── OpenDeck-r2.2.1-F_Mask.gts
│   │   │           ├── OpenDeck-r2.2.1-F_Paste.gtp
│   │   │           ├── OpenDeck-r2.2.1-F_Silkscreen.gto
│   │   │           ├── OpenDeck-r2.2.1-NPTH-drl_map.gbr
│   │   │           ├── OpenDeck-r2.2.1-NPTH.drl
│   │   │           ├── OpenDeck-r2.2.1-PTH-drl_map.gbr
│   │   │           └── OpenDeck-r2.2.1-PTH.drl
│   │   ├── v3.0.1/
│   │   │   ├── Analog.kicad_sch
│   │   │   ├── Analog_Multiplexer.kicad_sch
│   │   │   ├── Buttons.kicad_sch
│   │   │   ├── Buttons_Rows.kicad_sch
│   │   │   ├── DIN_MIDI.kicad_sch
│   │   │   ├── DMX.kicad_sch
│   │   │   ├── Indicators.kicad_sch
│   │   │   ├── LEDs.kicad_sch
│   │   │   ├── OpenDeck-r3.0.1.kicad_pcb
│   │   │   ├── OpenDeck-r3.0.1.kicad_pro
│   │   │   ├── OpenDeck-r3.0.1.kicad_sch
│   │   │   ├── Touchscreen.kicad_sch
│   │   │   └── prod/
│   │   │       ├── OpenDeck-r3.0.1-BOM.csv
│   │   │       ├── OpenDeck-r3.0.1-top-pos.csv
│   │   │       └── gerbers/
│   │   │           ├── OpenDeck-r3.0.1-B_Cu.gbl
│   │   │           ├── OpenDeck-r3.0.1-B_Mask.gbs
│   │   │           ├── OpenDeck-r3.0.1-B_Paste.gbp
│   │   │           ├── OpenDeck-r3.0.1-B_Silkscreen.gbo
│   │   │           ├── OpenDeck-r3.0.1-Edge_Cuts.gm1
│   │   │           ├── OpenDeck-r3.0.1-F_Cu.gtl
│   │   │           ├── OpenDeck-r3.0.1-F_Mask.gts
│   │   │           ├── OpenDeck-r3.0.1-F_Paste.gtp
│   │   │           ├── OpenDeck-r3.0.1-F_Silkscreen.gto
│   │   │           ├── OpenDeck-r3.0.1-NPTH-drl_map.gbr
│   │   │           ├── OpenDeck-r3.0.1-NPTH.drl
│   │   │           ├── OpenDeck-r3.0.1-PTH-drl_map.gbr
│   │   │           └── OpenDeck-r3.0.1-PTH.drl
│   │   └── v3.1.x/
│   │       ├── Analog.kicad_sch
│   │       ├── Analog_Multiplexer.kicad_sch
│   │       ├── Buttons.kicad_sch
│   │       ├── Buttons_Rows.kicad_sch
│   │       ├── DIN_MIDI.kicad_sch
│   │       ├── DMX.kicad_sch
│   │       ├── Indicators.kicad_sch
│   │       ├── LEDs.kicad_sch
│   │       ├── OpenDeck-r3.1.2.kicad_pcb
│   │       ├── OpenDeck-r3.1.2.kicad_pro
│   │       ├── OpenDeck-r3.1.2.kicad_sch
│   │       ├── Touchscreen.kicad_sch
│   │       └── prod/
│   │           ├── OpenDeck-r3.1.2-BOM.csv
│   │           ├── OpenDeck-r3.1.2-top-pos.csv
│   │           └── gerbers/
│   │               ├── OpenDeck-r3.1.2-B_Cu.gbl
│   │               ├── OpenDeck-r3.1.2-B_Mask.gbs
│   │               ├── OpenDeck-r3.1.2-B_Paste.gbp
│   │               ├── OpenDeck-r3.1.2-B_Silkscreen.gbo
│   │               ├── OpenDeck-r3.1.2-Edge_Cuts.gm1
│   │               ├── OpenDeck-r3.1.2-F_Cu.gtl
│   │               ├── OpenDeck-r3.1.2-F_Mask.gts
│   │               ├── OpenDeck-r3.1.2-F_Paste.gtp
│   │               ├── OpenDeck-r3.1.2-F_Silkscreen.gto
│   │               ├── OpenDeck-r3.1.2-NPTH-drl_map.gbr
│   │               ├── OpenDeck-r3.1.2-NPTH.drl
│   │               ├── OpenDeck-r3.1.2-PTH-drl_map.gbr
│   │               ├── OpenDeck-r3.1.2-PTH.drl
│   │               └── OpenDeck-r3.1.2-bottom-pos.csv
│   ├── opendeck_mini/
│   │   ├── opendeck_mini.brd
│   │   └── opendeck_mini.sch
│   └── rooibos/
│       ├── MBO/
│       │   ├── MBO.brd
│       │   └── MBO.sch
│       ├── Pots/
│       │   ├── Pots.brd
│       │   └── Pots.sch
│       ├── SingleFader/
│       │   ├── SingleFader.brd
│       │   └── SingleFader.sch
│       └── USB/
│           ├── USBboard.brd
│           └── USBboard.sch
├── scripts/
│   ├── bulk_build.sh
│   ├── code_format.sh
│   ├── copy_release_binaries.sh
│   ├── gen/
│   │   └── gen_fw_uid.sh
│   └── query_test_metadata.sh
├── tests/
│   ├── global.conf
│   ├── include/
│   │   └── tests/
│   │       ├── common.h
│   │       └── helpers/
│   │           ├── database.h
│   │           ├── midi.h
│   │           └── misc.h
│   └── src/
│       ├── bootloader/
│       │   ├── CMakeLists.txt
│       │   ├── Kconfig
│       │   ├── bootloader_test.cpp
│       │   ├── prj.conf
│       │   └── testcase.yaml
│       ├── database/
│       │   ├── CMakeLists.txt
│       │   ├── Kconfig
│       │   ├── database_test.cpp
│       │   ├── prj.conf
│       │   └── testcase.yaml
│       ├── hw/
│       │   ├── CMakeLists.txt
│       │   ├── Kconfig
│       │   ├── hw_test.cpp
│       │   ├── prj.conf
│       │   └── testcase.yaml
│       ├── io/
│       │   ├── analog/
│       │   │   ├── CMakeLists.txt
│       │   │   ├── Kconfig
│       │   │   ├── analog_test.cpp
│       │   │   ├── prj.conf
│       │   │   └── testcase.yaml
│       │   ├── analog_filter/
│       │   │   ├── CMakeLists.txt
│       │   │   ├── Kconfig
│       │   │   ├── analog_filter_test.cpp
│       │   │   ├── prj.conf
│       │   │   └── testcase.yaml
│       │   ├── digital/
│       │   │   ├── CMakeLists.txt
│       │   │   ├── Kconfig
│       │   │   ├── digital_buttons_test.cpp
│       │   │   ├── digital_encoders_test.cpp
│       │   │   ├── prj.conf
│       │   │   └── testcase.yaml
│       │   └── leds/
│       │       ├── CMakeLists.txt
│       │       ├── Kconfig
│       │       ├── leds_test.cpp
│       │       ├── prj.conf
│       │       └── testcase.yaml
│       ├── protocol/
│       │   └── midi/
│       │       ├── CMakeLists.txt
│       │       ├── Kconfig
│       │       ├── midi_test.cpp
│       │       ├── prj.conf
│       │       └── testcase.yaml
│       └── system/
│           ├── CMakeLists.txt
│           ├── Kconfig
│           ├── prj.conf
│           ├── system_test.cpp
│           └── testcase.yaml
├── west.yml
└── zephyr/
    └── patch/
        ├── README.md
        └── zephyr/
            ├── adc_rp2xx0_01_polled_read.patch
            ├── adc_rp2xx0_02_configurable_clkdiv.patch
            ├── adc_stm32_polled_read.patch
            ├── blackpill411_dfu_util_with_sysbuild.patch
            ├── dfu_util_reset_cap.patch
            ├── teensy_loader_reset_cap.patch
            ├── usb_midi2_01_configurable_buffer_size.patch
            ├── usb_midi2_02_ump_burst.patch
            └── west_runner_handle_no_flash_load_offset.patch

================================================
FILE CONTENTS
================================================

================================================
FILE: .codechecker.yml
================================================
analyzer:
  - --enable=sensitive
  - --enable=bugprone-use-after-move
  - --enable=bugprone-dangling-handle
  - --disable=bugprone-dynamic-static-initializers
  - --enable=clang-analyzer-cplusplus.NewDeleteLeaks
  - --enable=bugprone-incorrect-roundings
  - --enable=modernize-use-nullptr
  - --enable=modernize-use-override
  - --enable=cppcoreguidelines-pro-type-member-init
  - --enable=readability-magic-numbers
  - --disable=performance-enum-size
  - --disable=clang-diagnostic-reserved-identifier
  - --disable=clang-diagnostic-missing-field-initializers
  - --disable=clang-diagnostic-format-nonliteral
  - --disable=cppcoreguidelines-special-member-functions
  - --disable=cppcoreguidelines-avoid-const-or-ref-data-members
  - --disable=google-build-using-namespace
  - --enable=readability-braces-around-statements
  - --enable=readability-else-after-return
  - --enable=readability-inconsistent-declaration-parameter-name
  - --enable=readability-static-accessed-through-instance
  - --enable=readability-identifier-naming
  - --enable=modernize-use-equals-default
  - --enable=modernize-use-using
  - --enable=modernize-redundant-void-arg
  - --enable=modernize-concat-nested-namespaces
  - --enable=misc-redundant-expression
  - --enable=performance-inefficient-vector-operation
  - --checker-config=clang-tidy:readability-braces-around-statements:ShortStatementLines=0
  - --checker-config=clang-tidy:readability-identifier-naming:ClassCase=CamelCase
  - --checker-config=clang-tidy:readability-identifier-naming:ClassMemberCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:ClassMethodCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:ConstexprFunctionCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:ConstexprVariableCase=UPPER_CASE
  - --checker-config=clang-tidy:readability-identifier-naming:EnumConstantCase=CamelCase
  - --checker-config=clang-tidy:readability-identifier-naming:FunctionCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:GlobalConstantCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:GlobalPointerCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:GlobalVariableCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:LocalConstantCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:LocalConstantPointerCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:LocalVariableCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:MemberCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:NamespaceCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:PrivateMemberCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:PrivateMemberPrefix=_
  - --checker-config=clang-tidy:readability-identifier-naming:ProtectedMemberCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:ProtectedMemberPrefix=_
  - --checker-config=clang-tidy:readability-identifier-naming:StaticConstantCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:StaticVariableCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:StructCase=CamelCase
  - --checker-config=clang-tidy:readability-identifier-naming:PublicMemberCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:TemplateParameterCase=CamelCase
  - --checker-config=clang-tidy:readability-identifier-naming:VirtualMethodCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:ParameterCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:ConstantParameterCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:ConstantPointerParameterCase=lower_case
  - --checker-config=clang-tidy:readability-identifier-naming:PointerParameterCase=lower_case
  - --checker-config=clang-tidy:readability-inconsistent-declaration-parameter-name:Strict=true
  - --checker-config=clang-tidy:readability-identifier-naming:TypeAliasCase=CamelCase
  - --ignore=$ZEPHYR_WS/zenv/codechecker/skip.txt
  - --clean
  - --no-missing-checker-error

parse:
  - --ignore=$ZEPHYR_WS/zenv/codechecker/skip.txt


================================================
FILE: .codex
================================================


================================================
FILE: .devcontainer/Dockerfile
================================================
FROM ghcr.io/paradajz/zenv:aa66c31a11cb6ff9efa6a82c37c2cf6779a8f975

ARG jlink_version=V926

RUN \
echo '#!/bin/bash\necho not running udevadm "$@"' | sudo tee -a /usr/bin/udevadm && \
sudo chmod +x /usr/bin/udevadm && \
sudo apt-get update && \
sudo apt-get -y --no-install-recommends install \
build-essential \
libasound2-dev \
libfontconfig1 \
libfreetype6 \
libice6 \
libsm6 \
libssl-dev \
libtool \
libusb-dev \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render0 \
libxcb-render-util0 \
libxcb-shape0 \
libxcb-shm0 \
libxcb-sync1 \
libxcb-xfixes0 \
libxext6 \
libxkbcommon0 \
libxkbcommon-x11-0 \
libxrender1 \
pkg-config

RUN \
cd /tmp && \
git clone https://github.com/gbevin/SendMIDI.git && \
cd SendMIDI/Builds/LinuxMakefile && \
make && \
sudo mv build/sendmidi /usr/local/bin

RUN \
cd /tmp && \
git clone https://github.com/gbevin/ReceiveMIDI.git && \
cd ReceiveMIDI/Builds/LinuxMakefile && \
make && \
sudo mv build/receivemidi /usr/local/bin

RUN \
cd /tmp && \
git clone https://github.com/PaulStoffregen/teensy_loader_cli.git && \
cd teensy_loader_cli && \
make && \
sudo mv teensy_loader_cli /usr/local/bin

RUN \
ARCH=$(uname -m); \
if [ "$ARCH" = "x86_64" ]; then \
PACKAGE_VARIANT="x86_64"; \
elif [ "$ARCH" = "aarch64" ]; then \
PACKAGE_VARIANT="arm64"; \
fi; \
wget --post-data="accept_license_agreement=accepted&submit=Download+software" https://www.segger.com/downloads/jlink/JLink_Linux_${jlink_version}_${PACKAGE_VARIANT}.deb -O jlink.deb && \
sudo dpkg -i jlink.deb && \
rm -f jlink.deb

RUN \
ARCH="$(dpkg --print-architecture)" && \
if [ "$ARCH" = "amd64" ]; then \
PACKAGE_VARIANT="x86_64"; \
elif [ "$ARCH" = "arm64" ]; then \
PACKAGE_VARIANT="aarch64"; \
else echo "Unsupported architecture"; false; \
fi; \
cd && \
wget ${wget_args} \
-O nrfutil \
"https://files.nordicsemi.com/artifactory/swtools/external/nrfutil/executables/${PACKAGE_VARIANT}-unknown-linux-gnu/nrfutil" && \
chmod +x nrfutil && \
sudo mv nrfutil /usr/bin/

RUN nrfutil self-upgrade
RUN nrfutil install device


================================================
FILE: .devcontainer/devcontainer.json
================================================
{
    "name": "${localWorkspaceFolderBasename}",
    "build": {
        "dockerfile": "Dockerfile"
    },
    "workspaceMount": "src=${localWorkspaceFolder},dst=/home/ubuntu/zephyr_ws/project,type=bind",
    "workspaceFolder": "/home/ubuntu/zephyr_ws/project",
    "mounts": [
        {
            "source": "/dev",
            "target": "/dev",
            "type": "bind"
        },
        {
            "source": "${localEnv:HOME}/.gitconfig",
            "target": "/etc/gitconfig",
            "type": "bind"
        }
    ],
    "containerUser": "ubuntu",
    "privileged": true,
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-vscode.cpptools",
                "xaver.clang-format",
                "timonwong.shellcheck",
                "marus25.cortex-debug"
            ]
        }
    },
    "onCreateCommand": "/home/ubuntu/zephyr_ws/zenv/scripts/cleanup.sh"
}


================================================
FILE: .gitattributes
================================================
#text files
*.md    text
*.x     text
*.mk    text
*.json  text
*.c     text
*.cpp   text
*.h     text
*.txt   text
*.map   text
*.py    text
*.tsi   text eol=crlf
*.bat   text eol=crlf
*.sh    text eol=lf
#binary files
*.bin   binary
*.elf   binary
*.hex   binary
*.o     binary
*.jpg   binary
*.png   binary
*.bmp filter=lfs diff=lfs merge=lfs -text
*.HMI filter=lfs diff=lfs merge=lfs -text
*.cdr filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.pdf   binary
*.cdr   binary


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  push:
    branches:
      - '**'
    tags-ignore:
      - '**'

jobs:
  build:
    name: Build/Test
    runs-on: ubuntu-latest
    steps:
      - name: Pull the repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - name: Restore ccache
        uses: actions/cache/restore@v4
        with:
          path: ccache
          key: ccache-
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup missing directories and files on the runner
        run: |
          touch ~/.gitconfig
      - name: Prepare container
        uses: devcontainers/ci@v0.3
        with:
          imageName: opendeck # Local name only
          imageTag: latest # Local tag only
          push: never
      - name: Build and test presets
        uses: devcontainers/ci@v0.3
        with:
          imageName: opendeck
          imageTag: latest
          push: never
          runCmd: |
            git fetch --tags
            ./scripts/bulk_build.sh --type=host-test
            ./scripts/bulk_build.sh --type=app
            ./scripts/copy_release_binaries.sh --build-dir=build --copy-dir=release
      - name: Upload firmware artifacts
        uses: actions/upload-artifact@v7
        with:
          name: binaries
          path: release/*
      - name: Save ccache
        uses: actions/cache/save@v4
        if: always()
        with:
          path: ccache
          key: "ccache-${{ github.run_id }}"
  format:
    name: Code formatting
    runs-on: ubuntu-latest
    steps:
      - name: Pull the repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup missing directories and files on the runner
        run: |
          mkdir -p ~/.ssh
          touch ~/.gitconfig
      - name: Prepare container
        uses: devcontainers/ci@v0.3
        with:
          imageName: opendeck # Local name only
          imageTag: latest # Local tag only
          push: never
      - name: Check formatting
        uses: devcontainers/ci@v0.3
        with:
          imageName: opendeck
          imageTag: latest
          push: never
          runCmd: |
            make format


================================================
FILE: .github/workflows/release.yml
================================================
name: Deploy

on:
  release:
    types: [created]

jobs:
  build:
    name: Attach firmware to release
    runs-on: ubuntu-latest
    steps:
      - name: Pull the repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup missing directories and files on the runner
        run: |
          touch ~/.gitconfig
      - name: Prepare container
        uses: devcontainers/ci@v0.3
        with:
          imageName: opendeck # Local name only
          imageTag: latest # Local tag only
          push: never
          env: |
            GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
      - name: Build and upload
        uses: devcontainers/ci@v0.3
        with:
          imageName: opendeck
          imageTag: latest
          push: never
          runCmd: |
            git fetch --tags
            ./scripts/bulk_build.sh --type=app
            ./scripts/copy_release_binaries.sh --build-dir=build --copy-dir=release
      - name: Upload firmware artifacts
        uses: actions/upload-artifact@v7
        with:
          name: binaries
          path: release/*
      -
        name: Upload binaries to Github Release
        uses: ncipollo/release-action@v1
        with:
          artifacts: release/*
          allowUpdates: true
          omitBody: false


================================================
FILE: .gitignore
================================================
**/generated/*
*-backups
*-bak
*.cortex-debug*
*.kicad_prl
*compile_commands.json
*fp-info-cache
.DS_Store
build/
ccache/*
release/*
.west-updated
*.cache


================================================
FILE: .vscode/launch.json
================================================
{
    "configurations": [
        {
            "name": "Test",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/tests/test_vscode.exe",
            "args": [],
            "stopAtEntry": true,
            "environment": [],
            "externalConsole": false,
            "cwd": "${workspaceFolder}",
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "[Tests] Build"
        },
        {
            "name": "Launch/app",
            "type": "cortex-debug",
            "request": "launch",
            "servertype": "jlink",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceFolder}/build/app/nrf54h20/debug/app/zephyr/zephyr.elf",
            "interface": "swd",
            "device": "nRF52840_xxAA",
            "runToEntryPoint": "main",
            "preLaunchTask": "[Flash] [debug] nrf54h20",
            "gdbPath": "${env:ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb",
            "showDevDebugOutput": "both",
        },
    ]
}


================================================
FILE: .vscode/settings.json
================================================
{
    "files.exclude": {
        "bin/": true,
        "**/ipch*": true,
        "**/*cortex-debug*": true,
        "**/*profraw": true,
        "**/*ccache": true,
    },
    "files.insertFinalNewline": true,
    "files.trimFinalNewlines": true,
    "C_Cpp.intelliSenseEngine": "disabled",
    "C_Cpp.autocomplete": "disabled",
    "C_Cpp.autoAddFileAssociations": false,
    "C_Cpp.configurationWarnings": "disabled",
    "C_Cpp.errorSquiggles": "disabled",
    "diffEditor.ignoreTrimWhitespace": false,
    "editor.defaultFormatter": "xaver.clang-format",
    "editor.formatOnSave": true,
    "editor.inlayHints.enabled": "off",
    "editor.mouseWheelZoom": true,
    "editor.renderWhitespace": "all",
    "explorer.compactFolders": false,
    "extensions.ignoreRecommendations": true,
    "git.detectSubmodules": false,
    "git.mergeEditor": false,
    "clang-format.style": "file:/home/ubuntu/zephyr_ws/zenv/clang-format/.clang-format",
}


================================================
FILE: .vscode/tasks.json
================================================
{
    "tasks": [
        {
            "label": "[Flash] [debug] nrf54h20",
            "command": "make PRESET=nrf54h20 DEBUG=1 flash",
            "type": "shell",
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
        },
        {
            "label": "[Tests] Build",
            "command": "make tests TEST=${input:test} TARGET=${input:target}",
            "type": "shell",
            "problemMatcher": [
                "$gcc"
            ]
        }
    ],
    "inputs": [
        {
            "id": "target",
            "type": "pickString",
            "default": "bergamot",
            "description": "Select test:",
            "options": [
                "bergamot",
                "blackpill411",
                "discovery",
                "dubfocus16t",
                "nrf52840dk",
                "nrf54h20dk",
                "opendeck2",
                "opendeck21",
                "opendeck22",
                "opendeck31",
                "pico",
                "pico2",
                "rooibos",
                "ws_core405r",
                "ws_core407i"
            ]
        },
        {
            "id": "test",
            "type": "pickString",
            "default": "system",
            "description": "Select test:",
            "options": [
                "analog",
                "bootloader",
                "database",
                "digital",
                "hw",
                "leds",
                "midi",
                "system",
            ]
        },
    ]
}


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Makefile
================================================
include $(ZEPHYR_WS)/zenv/make/Makefile

PROJECT_PRESETS_FILE := $(ZEPHYR_PROJECT)/app/presets.yml
NON_TARGET_GOALS     := clean clean-all format print-%
OPENDECK_OVERLAYS    := $(sort $(wildcard $(ZEPHYR_PROJECT)/app/boards/opendeck/*/opendeck.overlay))
OPENDECK_TARGET_DIRS := $(patsubst %/,%,$(dir $(OPENDECK_OVERLAYS)))
OPENDECK_TARGETS     := $(notdir $(OPENDECK_TARGET_DIRS))
TARGET               := $(firstword $(OPENDECK_TARGETS))

ifeq ($(strip $(TARGET)),)
    $(error No OpenDeck targets found under $(ZEPHYR_PROJECT)/app/boards/opendeck)
endif

ifneq ($(filter $(TARGET),$(OPENDECK_TARGETS)),$(TARGET))
    $(error Unknown TARGET '$(TARGET)'. Available targets: $(OPENDECK_TARGETS))
endif

export TARGET

OPENDECK_OVERLAY := $(ZEPHYR_PROJECT)/app/boards/opendeck/$(TARGET)/opendeck.overlay
BUILD_DIR_APP    := $(BUILD_DIR_APP)/$(TARGET)
BUILD_DIR_TESTS  := $(BUILD_DIR_TESTS)/$(TARGET)
BOARD            := $(shell sed -n 's/.*zephyr-board[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' $(OPENDECK_OVERLAY) 2>/dev/null | head -n 1)


================================================
FILE: README.md
================================================
# OpenDeck MIDI Platform

OpenDeck is a platform for building MIDI controllers designed to solve two problems when building a MIDI controller:

* Coding - there is no need to code anything in order to make changes to the controller or to make it work
* Making the controller behave the way you want it to - the firmware supports a huge number of configurable parameters, all configurable in a Web browser

Solving these two goals means you can forget about implementation details and focus on having your custom controller built as fast as possible.

*Click the image below for a demo video of the [OpenDeck configurator](https://config.shanteacontrols.com)*

[![Watch the video](https://img.youtube.com/vi/7X2LC0JMfAU/maxresdefault.jpg)](https://youtu.be/7X2LC0JMfAU)

Configurator is available either [online](https://config.shanteacontrols.com) or [offline](https://github.com/shanteacontrols/OpenDeckUI/releases).

*Some of the controllers built with OpenDeck*

![](bin/img/readme/gallery.png)

## Features

The following components are supported:

* Buttons
* Encoders
* LEDs (single color or RGB)
* Potentiometers
* FSRs (force-sensitive resistors)
* LCD/OLED displays
* Touchscreen displays (Nextion)

OpenDeck supports sending of both 7-bit and 14-bit Non-Registered Parameter Numbers (NRPN), latching messages on buttons, various encoding modes for quadrature encoders, LED control using MIDI In, configurable MIDI channels for each component individually, Bluetooth MIDI etc. Full list of supported features can be found [here](https://github.com/shanteacontrols/OpenDeck/wiki/Configurable-features).

If the feature you want isn't supported yet, don't feel discouraged. Open up a [discussion thread](https://github.com/shanteacontrols/OpenDeck/discussions) and let's talk about it.

## Official boards

Currently, there are two official boards: M and L variants. "M" stands for "middle" and "L" for "large". M board is currently out of production, but the L board is available on [Lectronz store](https://lectronz.com/products/opendeck-l/).

### M board

![](https://github.com/shanteacontrols/OpenDeck/wiki/img/opendeck2.webp)

This board is based on Raspberry Pi RP2040 microcontroller and features the following:

* 64 digital inputs
* 48 digital outputs
* 32 analog inputs
* DIN MIDI
* USB MIDI (USB C)
* Connector for touchscreen
* Connector for I2C OLED display

### L board

![](https://raw.githubusercontent.com/shanteacontrols/website/master/images/opendeck3-header.png)

This board is based on Raspberry Pi RP2040 microcontroller and features the following:

* 128 digital inputs
* 64 digital outputs
* 64 analog inputs
* DIN MIDI
* USB MIDI (USB C)
* Connector for touchscreen
* Connector for I2C OLED display
* Additional connectors with 3V+GND and 5V+GND connections

## Supported boards

The firmware supports various other boards, both small and large:

* [nRF52840 DK](https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dk)
* [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/)
* [Raspberry Pi Pico 2](https://www.raspberrypi.com/products/raspberry-pi-pico-2/)
* [STM32F411 Black Pill](https://stm32-base.org/boards/STM32F411CEU6-WeAct-Black-Pill-V2.0) ([Adafruit](https://www.adafruit.com/product/4877))
* [STM32F4 Discovery](https://www.st.com/en/evaluation-tools/stm32f4discovery.html) ([Mouser](https://hr.mouser.com/ProductDetail/STMicroelectronics/STM32F407G-DISC1?qs=%2Fha2pyFadugMvYxi1ftRWf5mGCRgIpVnZzkmnZLph%2FPbqHgeIRafES4CiZOiJh1y) / [Digikey](https://www.digikey.com/en/products/detail/stmicroelectronics/STM32F407G-DISC1/5824404?s=N4IgTCBcDaIMoBUCyBmMAxALABgOwHEBaAEQEk4BhARhAF0BfIA))
* [Teensy 4.0](https://www.pjrc.com/store/teensy40.html)
* [Teensy 4.1](https://www.pjrc.com/store/teensy41.html)
* [Waveshare Core405R](https://www.waveshare.com/core405r.htm)

For more details on supported boards, check the [wiki page](https://github.com/shanteacontrols/OpenDeck/wiki). A page with [instructions on how to flash OpenDeck firmware](https://github.com/shanteacontrols/OpenDeck/wiki/Flashing-the-OpenDeck-firmware) to supported boards is also available. Support for custom boards can be added with the current Zephyr-based target model using [OpenDeck target overlays and matching board layers](https://github.com/shanteacontrols/OpenDeck/wiki/Creating-custom-board-variant).

## Documentation

Available on dedicated [Wiki section](https://github.com/shanteacontrols/OpenDeck/wiki/).

## Discussion

Need help? Want to show off your OpenDeck-based builds? Head over to [Discussions](https://github.com/shanteacontrols/OpenDeck/discussions)!

## License

OpenDeck source code is available under Apache License v2.0. Zephyr RTOS, which OpenDeck is built on top of, is also licensed under Apache License v2.0.

Third-party components with different licenses:

* `zlibs`: MIT
* `u8g2`: Two-clause BSD


================================================
FILE: agents.md
================================================
# Session Helper

This repo is now fully Zephyr-based. Board support is split into:

- `app/boards/zephyr/`
- `app/boards/opendeck/`

Use [app/boards/README.md](/home/ubuntu/zephyr_ws/project/app/boards/README.md) as the source of truth for how that split works.

## Board Support State

OpenDeck boards are selected with `TARGET`, not `PRESET`.

Current targets can be inferred from `app/boards/opendeck/`:

- `discovery`
- `nrf52840dk`
- `nrf54h20dk`
- `pico`

Useful verification commands:

- `make TARGET=nrf54h20dk`
- `make TARGET=pico`
- `make TARGET=discovery`
- `make TARGET=nrf52840dk`

Notes:

- `app/presets.yml` is now just a generic build preset file.
- It currently contains a single preset, `default`.
- Shared build-mode config comes from:
  - `app/common.conf`
  - `app/release.conf`
  - `app/debug.conf`

## Testing

Testing uses Twister from Zephyr wrapped inside `make tests`.

`tests` accepts:

- `TEST=<test>`: build or run one specific test
- `TAG=<tag>`: filter by Twister tag
- `RUN=<0/1>`: run the tests instead of build-only

Examples:

- `make tests TAG=host`
- `make tests TEST=digital TAG=host`
- `make tests TEST=analog TAG=host`
- `make tests TEST=bootloader TAG=host`
- `make tests RUN=1 TAG=host`

Guidelines:

- Always add `TAG=host` unless you are intentionally working with hardware-tagged tests.
- If Twister behaves oddly, run `make clean` and retry before changing code.
- When fixing failing tests, start with logs in the relevant firmware path instead of introducing timing workarounds.

## CodeChecker

Do not remove, trim, or "fix" rules in `.codechecker.yml` just because the local `CodeChecker` or `clang-tidy` reports invalid checker-option messages.

Those messages usually mean the local tool version does not match the project's expected checker-option set. They do not by themselves mean the repo config is wrong.

## Things To Check First In New Sessions

1. If board or image composition looks wrong, inspect [app/sysbuild.cmake](/home/ubuntu/zephyr_ws/project/app/sysbuild.cmake).
2. If a target is being selected incorrectly, inspect [Makefile](/home/ubuntu/zephyr_ws/project/Makefile).
3. If board metadata or layering is unclear, inspect [app/boards/README.md](/home/ubuntu/zephyr_ws/project/app/boards/README.md).


================================================
FILE: app/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.27.0)
list(APPEND BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND DTS_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
set(KCONFIG_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/Kconfig)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
zephyr_get(PRESET_NAME MERGE SYSBUILD GLOBAL)

project(project)

if(NOT DEFINED ENV{TARGET} OR "$ENV{TARGET}" STREQUAL "")
    message(FATAL_ERROR "OpenDeck application requires TARGET to be exported by the makefile")
endif()

set(TARGET "$ENV{TARGET}")

zephyr_compile_options(-Wno-psabi)
zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-threadsafe-statics>)
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/bootloader/src)
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common)
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/firmware/src)

add_subdirectory(firmware)

set(ZEPHYR_BIN_FILE ${CMAKE_CURRENT_BINARY_DIR}/zephyr/zephyr.bin)
set(DFU_OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/dfu.bin)

add_custom_target(firmware_dfu ALL
    COMMAND
    ${CMAKE_COMMAND}
    -DINPUT_FILE=${ZEPHYR_BIN_FILE}
    -DOUTPUT_FILE=${DFU_OUTPUT_FILE}
    -DTARGET_UID=${OPENDECK_TARGET_UID}
    -DFORMAT_VERSION=${OPENDECK_DFU_FORMAT_VERSION}
    -DBEGIN_MAGIC=${OPENDECK_DFU_BEGIN_MAGIC}
    -DEND_MAGIC=${OPENDECK_DFU_END_MAGIC}
    -P $ENV{ZEPHYR_PROJECT}/cmake/dfu_bin.cmake
    DEPENDS app ${ZEPHYR_BIN_FILE}
    COMMENT "Generating wrapped DFU binary"
    VERBATIM
)


================================================
FILE: app/Kconfig
================================================
mainmenu "Project-specific configuration"

module = OPENDECK
module-str = OpenDeck
source "subsys/logging/Kconfig.template.log_config"

source "Kconfig.zephyr"
rsource "firmware/Kconfig"


================================================
FILE: app/boards/README.md
================================================
# Boards

OpenDeck board support is split into two layers:

- `app/boards/opendeck/`
- `app/boards/zephyr/`

They describe different things.

- `app/boards/opendeck/` describes the actual OpenDeck hardware topology.
- `app/boards/zephyr/` adapts an upstream Zephyr board so it can host that OpenDeck target.

## What Each Layer Contains

`app/boards/opendeck/` is the user-facing hardware description.

This layer defines things like:

- buttons
- analog inputs
- LEDs
- displays
- touchscreens
- DIN MIDI
- bus connections between those features
- target metadata used by build and test helpers
- target-specific OpenDeck resource aliases in `firmware.overlay`, when needed

`app/boards/zephyr/` is the Zephyr board adaptation layer.

This layer defines things like:

- partition layout
- low-level board-specific peripheral setup
- bootloader-specific overlay and config
- firmware-specific overlay and config
- test-only overlay data
- optional board-specific sysbuild adjustments

## How Target Selection Works

OpenDeck targets are selected with `TARGET`.

Example:

```sh
make TARGET=pico
```

The build system loads:

- `app/boards/opendeck/<target>/opendeck.overlay`

and reads the upstream Zephyr board identity from that file.

## Required Metadata

Each `app/boards/opendeck/<target>/opendeck.overlay` must contain:

```dts
opendeck_metadata: opendeck-metadata {
    compatible = "opendeck,metadata";
    zephyr-board = "rpi_pico/rp2040";
};
```

This tells the build system which upstream Zephyr board should be used as the base for the target.

The `zephyr-board` value must map to a board layer under `app/boards/zephyr/`, with `/` replaced by `_`.

The metadata node can also define:

```dts
board-name = "My Custom Board";
```

When present, `board-name` overrides the runtime-facing `TARGET` name used for:

- USB MIDI product and label naming
- BLE MIDI device naming
- DFU / bootloader USB product naming

Examples:

- `rpi_pico/rp2040` -> `app/boards/zephyr/rpi_pico_rp2040/`
- `nrf54h20dk/nrf54h20/cpuapp` -> `app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/`

## Optional Helper Metadata

Targets can also define helper-only metadata nodes.

Test capability node:

```dts
opendeck_tests: opendeck-tests {
    compatible = "opendeck,tests";
    host;
    hw;
};
```

This describes whether the target supports:

- host tests
- hardware-backed tests

Bulk helper node:

```dts
opendeck_bulk_build: opendeck-bulk-build {
    compatible = "opendeck,bulk-build";
    app;
    host-test;
    hw-test;
    lint;
};
```

This controls whether helper scripts such as `scripts/bulk_build.sh` include the target in:

- bulk app builds
- bulk host test runs
- bulk hardware test runs
- bulk lint runs

## Testcase Tags

Test suites under `tests/src/**/testcase.yaml` can also control how bulk helpers schedule them.

- `host` or `hw` selects the test mode.
- `preset` tells `scripts/bulk_build.sh` to run that suite once per eligible target.

If `preset` is omitted, bulk helpers run the suite once using the first eligible target as the
representative target. This is useful for tests whose behavior does not actually vary by target.

## File Layout

For a target named `pico`, the layout looks like this:

```text
app/boards/
├── opendeck/
│   └── pico/
│       ├── opendeck.overlay
│       ├── firmware.overlay
└── zephyr/
    └── rpi_pico_rp2040/
        ├── partitions.overlay
        ├── firmware.overlay
        ├── firmware.conf
        ├── bootloader.overlay
        ├── bootloader.conf
        ├── test.overlay
        └── sysbuild.cmake
```

`sysbuild.cmake` in the board layer is optional. Target-level `firmware.overlay` and
`firmware.conf` are also optional and only needed when the target has extra OpenDeck-specific
wiring or config on top of the shared Zephyr board layer.

When a target only needs abstract OpenDeck UART/I2C labels for bootloader or host-test DTS
parsing, those alias lines are generated automatically from the target `firmware.overlay`.
Only targets with real bootloader- or test-specific DTS changes need dedicated board-layer
`bootloader.overlay` or `test.overlay` files under `app/boards/zephyr/<board>/`.

## Presets File

`app/presets.yml` is the build-preset file used by `zenv`, the Zephyr-oriented
build wrapper used by this project. When `make` runs, `zenv` parses that file
and turns the selected preset into the final build configuration inputs for
`west build`.

The project currently defines only one build preset, `default`. In
`app/presets.yml`, that preset groups config files into:

- `common`
  - always included
  - currently: `common.conf`
- `release`
  - used for normal OpenDeck builds
  - currently: `release.conf`
- `debug`
  - used instead of `release` when passing `DEBUG=1` to `make`
  - currently: `debug.conf`
  - enables console and UART logging support

## Overlay Merge Order

Firmware image overlay order:

1. upstream Zephyr board DTS
2. `app/boards/zephyr/<board>/partitions.overlay`
3. `app/boards/zephyr/<board>/firmware.overlay`
4. `app/boards/opendeck/<target>/opendeck.overlay`
5. generated firmware USB MIDI label overlay
6. `app/boards/opendeck/<target>/firmware.overlay`, if the file exists

Bootloader image overlay order:

1. upstream Zephyr board DTS
2. `app/boards/zephyr/<board>/partitions.overlay`
3. `app/boards/zephyr/<board>/bootloader.overlay`
4. `app/boards/opendeck/<target>/opendeck.overlay`
5. generated bootloader alias overlay from `app/boards/opendeck/<target>/firmware.overlay`, if needed

Host-test overlay order:

1. native test board DTS, usually `native_sim`
2. `app/boards/zephyr/<board>/test.overlay`, if the file exists
3. generated test alias overlay from `app/boards/opendeck/<target>/firmware.overlay`, if needed
4. `app/boards/opendeck/<target>/opendeck.overlay`

## Config Merge Order

Firmware config order:

1. shared build config from `app/presets.yml`
2. `app/firmware/firmware.conf`
3. `app/boards/zephyr/<board>/firmware.conf`
4. generated firmware USB product config
5. generated firmware BLE device-name config, when BLE peripheral support is enabled
6. `app/boards/opendeck/<target>/firmware.conf`, if the file exists

Bootloader config order:

1. shared build config from `app/presets.yml`
2. `app/bootloader/bootloader.conf`
3. `app/boards/zephyr/<board>/bootloader.conf`
4. generated bootloader USB product config
5. `app/boards/opendeck/<target>/bootloader.conf`, if the file exists

## Index Remapping

If logical component ordering differs from the physical scan order, these nodes can define:

- `index-remap`

This is currently supported on:

- `opendeck-buttons`
- `opendeck-analog`
- `opendeck-leds`

Use it only when a target needs a physical-to-logical reorder table.

## Adding A New Board

To add a new target:

1. Pick an upstream Zephyr board that matches your MCU or module.
2. Create the board layer under `app/boards/zephyr/<board>/`.
3. Add the normal board-layer files:
   - `partitions.overlay`
   - `firmware.overlay`
   - `firmware.conf`
   - `bootloader.conf`
   - `bootloader.overlay`, only if the bootloader image needs real DTS changes beyond generated alias labels
   - `test.overlay`, only if host tests need shared emulated devices or partition labels for that board family
4. Add `app/boards/opendeck/<target>/opendeck.overlay`.
5. Add `app/boards/opendeck/<target>/firmware.overlay` only if the target needs extra OpenDeck-specific bus aliases or target-local DTS tweaks.
6. Add the required `opendeck,metadata` node with the correct `zephyr-board` value.
7. Describe the actual OpenDeck hardware in `opendeck.overlay`.
8. Add optional `opendeck,tests` and `opendeck,bulk-build` nodes if the target should participate in test or helper-script flows.

In practice:

- `app/boards/opendeck/<target>/opendeck.overlay` should own all `opendeck_*` hardware nodes
- `app/boards/zephyr/<board>/firmware.overlay` should own low-level peripheral enablement and common board setup
- `app/boards/opendeck/<target>/firmware.overlay` should usually contain target-specific OpenDeck wiring on top of that shared board layer, most often abstract alias lines such as `opendeck_uart_din_midi: &uart1 {};`, `opendeck_uart_touchscreen: &uart2 {};`, or `opendeck_i2c_display: &i2c1 {};`
- custom targets can also use `app/boards/opendeck/<target>/firmware.overlay` to remap those OpenDeck resources to different UART or I2C instances than the shared board-layer default when the carrier wiring differs
- dedicated target `bootloader.overlay` files are usually unnecessary unless the target truly needs image-specific DTS changes

For a fuller walkthrough, see the wiki page on creating a custom board variant:
https://github.com/shanteacontrols/OpenDeck/wiki/Creating-custom-board-variant


================================================
FILE: app/boards/opendeck/bergamot/firmware.overlay
================================================
opendeck_uart_touchscreen: &usart1 {};


================================================
FILE: app/boards/opendeck/bergamot/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "weact_stm32f405_core/stm32f405xx";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        host-test;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpiob 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "4067";
        io-channels = <&adc1 15>;
        multiplexers = <1>;
        index-remap = <10 11 12 13 8 9 14 15 7 6 1 0 5 4 3 2>;
        selector-s0-gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>;
        selector-s1-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
        selector-s2-gpios = <&gpioa 7 GPIO_ACTIVE_HIGH>;
        selector-s3-gpios = <&gpioa 6 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/blackpill411/firmware.overlay
================================================
opendeck_uart_din_midi: &usart1 {};

opendeck_uart_touchscreen: &usart1 {};

opendeck_i2c_display: &i2c1 {};


================================================
FILE: app/boards/opendeck/blackpill411/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "blackpill_f411ce/stm32f411xe";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        lint;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        native-gpios =
            <&gpioa 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioa 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc1 1>,
            <&adc1 2>,
            <&adc1 3>,
            <&adc1 4>,
            <&adc1 5>,
            <&adc1 6>,
            <&adc1 7>,
            <&adc1 9>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        native-gpios =
            <&gpioa 15 GPIO_ACTIVE_HIGH>,
            <&gpiob 3 GPIO_ACTIVE_HIGH>,
            <&gpiob 4 GPIO_ACTIVE_HIGH>,
            <&gpiob 5 GPIO_ACTIVE_HIGH>,
            <&gpiob 8 GPIO_ACTIVE_HIGH>,
            <&gpiob 9 GPIO_ACTIVE_HIGH>,
            <&gpioc 14 GPIO_ACTIVE_HIGH>,
            <&gpioc 15 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
        usb-out-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
        din-in-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
        din-out-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpioa 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/discovery/firmware.overlay
================================================
opendeck_uart_din_midi: &usart6 {};

opendeck_uart_touchscreen: &usart6 {};

opendeck_i2c_display: &i2c2 {};


================================================
FILE: app/boards/opendeck/discovery/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "stm32f4_disco/stm32f407xx";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        host-test;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpioc 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiod 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiod 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioe 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiod 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioa 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc1 2>,
            <&adc1 3>,
            <&adc1 8>,
            <&adc1 9>,
            <&adc1 11>,
            <&adc1 12>,
            <&adc1 14>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpioe 6 GPIO_ACTIVE_HIGH>,
            <&gpioe 4 GPIO_ACTIVE_HIGH>,
            <&gpioe 2 GPIO_ACTIVE_HIGH>,
            <&gpioe 0 GPIO_ACTIVE_HIGH>,
            <&gpiob 8 GPIO_ACTIVE_HIGH>,
            <&gpiob 4 GPIO_ACTIVE_HIGH>,
            <&gpiod 7 GPIO_ACTIVE_HIGH>,
            <&gpiod 3 GPIO_ACTIVE_HIGH>,
            <&gpiod 1 GPIO_ACTIVE_HIGH>,
            <&gpioc 13 GPIO_ACTIVE_HIGH>,
            <&gpioe 5 GPIO_ACTIVE_HIGH>,
            <&gpiob 9 GPIO_ACTIVE_HIGH>,
            <&gpiob 5 GPIO_ACTIVE_HIGH>,
            <&gpiod 6 GPIO_ACTIVE_HIGH>,
            <&gpiod 2 GPIO_ACTIVE_HIGH>,
            <&gpiod 0 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpiod 14 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpiod 12 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpiod 15 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/dubfocus16t/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "weact_stm32f405_core/stm32f405xx";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        lint;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpioc 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "shift-register";
        shift-registers = <4>;
        index-remap = <29 26 28 27 30 25 31 24 21 18 20 19 22 17 23 16
                     13 10 12 11 14 9 15 8 5 2 4 3 6 1 7 0>;
        data-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>;
        clock-gpios = <&gpiob 13 GPIO_ACTIVE_HIGH>;
        latch-gpios = <&gpiob 14 GPIO_ACTIVE_HIGH>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "4067";
        io-channels =
            <&adc1 3>,
            <&adc1 4>,
            <&adc1 5>,
            <&adc1 6>,
            <&adc1 7>;
        multiplexers = <5>;
        index-remap = <10 11 12 13 72 8 9 14 15 73 7 6 1 0 74
                     5 4 3 2 75 26 27 28 29 76 24 25 30 31 77
                     23 22 17 16 78 21 20 19 18 79 42 43 44 45 64
                     40 41 46 47 65 39 38 33 32 66 37 36 35 34 67
                     58 59 60 61 68 56 57 62 63 69 55 54 49 48 70
                     53 52 51 50 71>;
        selector-s0-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>;
        selector-s1-gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>;
        selector-s2-gpios = <&gpioc 9 GPIO_ACTIVE_HIGH>;
        selector-s3-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "max7219";
        drivers = <1>;
        index-remap = <7 3 47 43 15 11 55 51 39 35 23 19 63 59 31 27
                     30 26 62 58 22 18 38 34 54 50 14 10 46 42 6 2>;
        data-gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>;
        clock-gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>;
        latch-gpios = <&gpiob 15 GPIO_ACTIVE_HIGH>;
    };
};


================================================
FILE: app/boards/opendeck/nrf52840dk/firmware.overlay
================================================
opendeck_uart_din_midi: &uart1 {};

opendeck_uart_touchscreen: &uart1 {};

opendeck_i2c_display: &i2c0 {};


================================================
FILE: app/boards/opendeck/nrf52840dk/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "nrf52840dk/nrf52840";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
        hw;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        lint;
        hw-test;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 25 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio1 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio1 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio1 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio1 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio1 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio1 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc 1>,
            <&adc 2>,
            <&adc 4>,
            <&adc 5>,
            <&adc 6>,
            <&adc 7>,
            <&adc 3>,
            <&adc 0>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpio0 17 GPIO_ACTIVE_HIGH>,
            <&gpio0 19 GPIO_ACTIVE_HIGH>,
            <&gpio0 20 GPIO_ACTIVE_HIGH>,
            <&gpio0 21 GPIO_ACTIVE_HIGH>,
            <&gpio0 22 GPIO_ACTIVE_HIGH>,
            <&gpio0 23 GPIO_ACTIVE_HIGH>,
            <&gpio1 7 GPIO_ACTIVE_HIGH>,
            <&gpio1 8 GPIO_ACTIVE_HIGH>,
            <&gpio1 9 GPIO_ACTIVE_HIGH>,
            <&gpio1 10 GPIO_ACTIVE_HIGH>,
            <&gpio1 11 GPIO_ACTIVE_HIGH>,
            <&gpio1 12 GPIO_ACTIVE_HIGH>,
            <&gpio1 13 GPIO_ACTIVE_HIGH>,
            <&gpio1 14 GPIO_ACTIVE_HIGH>,
            <&gpio1 15 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
        usb-out-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
        din-in-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
        din-out-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
        ble-in-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
        ble-out-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/nrf54h20dk/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "nrf54h20dk/nrf54h20/cpuapp";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
        hw;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        hw-test;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        native-gpios =
            <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc 0>,
            <&adc 1>,
            <&adc 2>,
            <&adc 3>,
            <&adc 4>,
            <&adc 5>,
            <&adc 6>,
            <&adc 7>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        native-gpios =
            <&gpio9 0 GPIO_ACTIVE_HIGH>,
            <&gpio9 1 GPIO_ACTIVE_HIGH>,
            <&gpio9 2 GPIO_ACTIVE_HIGH>,
            <&gpio9 3 GPIO_ACTIVE_HIGH>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio9 0 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>;
        ble-in-gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>;
        ble-out-gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/opendeck2/firmware.overlay
================================================
opendeck_uart_din_midi: &usart1 {};

opendeck_uart_touchscreen: &usart1 {};

opendeck_i2c_display: &i2c1 {};


================================================
FILE: app/boards/opendeck/opendeck2/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "weact_stm32f405_core/stm32f405xx";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        lint;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpiob 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "matrix";
        touchscreen-components = <64>;
        row-mode = "native";
        rows = <8>;
        columns = <8>;
        index-remap = <0 7 2 1 4 3 5 6 8 15 10 9 12 11 13 14
                     16 23 18 17 20 19 21 22 24 31 26 25 28 27 29 30
                     56 63 58 57 60 59 61 62 48 55 50 49 52 51 53 54
                     40 47 42 41 44 43 45 46 32 39 34 33 36 35 37 38>;
        row-gpios =
            <&gpioa 4 GPIO_ACTIVE_LOW>,
            <&gpioa 5 GPIO_ACTIVE_LOW>,
            <&gpioc 4 GPIO_ACTIVE_LOW>,
            <&gpioc 5 GPIO_ACTIVE_LOW>,
            <&gpiob 11 GPIO_ACTIVE_LOW>,
            <&gpiob 10 GPIO_ACTIVE_LOW>,
            <&gpiob 2 GPIO_ACTIVE_LOW>,
            <&gpiob 1 GPIO_ACTIVE_LOW>;
        column-mode = "decoder";
        decoder-a0-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>;
        decoder-a1-gpios = <&gpioc 9 GPIO_ACTIVE_HIGH>;
        decoder-a2-gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "4067";
        io-channels =
            <&adc1 12>,
            <&adc1 11>;
        multiplexers = <2>;
        index-remap = <8 9 10 11 12 13 14 15 7 6 5 4 3 2 1 0
                     24 25 26 27 28 29 30 31 23 22 21 20 19 18 17 16>;
        selector-s0-gpios = <&gpiob 14 GPIO_ACTIVE_HIGH>;
        selector-s1-gpios = <&gpiob 15 GPIO_ACTIVE_HIGH>;
        selector-s2-gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>;
        selector-s3-gpios = <&gpiob 13 GPIO_ACTIVE_HIGH>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "matrix";
        touchscreen-components = <64>;
        rows = <6>;
        columns = <8>;
        index-remap = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
                     32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
                     16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
        row-gpios =
            <&gpiob 9 GPIO_ACTIVE_HIGH>,
            <&gpiob 8 GPIO_ACTIVE_HIGH>,
            <&gpioa 3 GPIO_ACTIVE_HIGH>,
            <&gpioa 6 GPIO_ACTIVE_HIGH>,
            <&gpioa 7 GPIO_ACTIVE_HIGH>,
            <&gpiob 0 GPIO_ACTIVE_HIGH>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };
};


================================================
FILE: app/boards/opendeck/opendeck21/firmware.overlay
================================================
opendeck_uart_din_midi: &usart1 {};

opendeck_uart_touchscreen: &usart1 {};

opendeck_i2c_display: &i2c1 {};


================================================
FILE: app/boards/opendeck/opendeck21/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "weact_stm32f405_core/stm32f405xx";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpiob 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "matrix";
        touchscreen-components = <64>;
        row-mode = "native";
        rows = <8>;
        columns = <8>;
        index-remap = <0 7 2 1 4 3 5 6 8 15 10 9 12 11 13 14
                     16 23 18 17 20 19 21 22 24 31 26 25 28 27 29 30
                     56 63 58 57 60 59 61 62 48 55 50 49 52 51 53 54
                     40 47 42 41 44 43 45 46 32 39 34 33 36 35 37 38>;
        row-gpios =
            <&gpioa 4 GPIO_ACTIVE_LOW>,
            <&gpioa 5 GPIO_ACTIVE_LOW>,
            <&gpioc 4 GPIO_ACTIVE_LOW>,
            <&gpioc 5 GPIO_ACTIVE_LOW>,
            <&gpiob 11 GPIO_ACTIVE_LOW>,
            <&gpiob 10 GPIO_ACTIVE_LOW>,
            <&gpiob 2 GPIO_ACTIVE_LOW>,
            <&gpiob 1 GPIO_ACTIVE_LOW>;
        column-mode = "decoder";
        decoder-a0-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>;
        decoder-a1-gpios = <&gpioc 9 GPIO_ACTIVE_HIGH>;
        decoder-a2-gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "4067";
        io-channels =
            <&adc1 12>,
            <&adc1 11>;
        multiplexers = <2>;
        index-remap = <8 9 10 11 12 13 14 15 7 6 5 4 3 2 1 0
                     24 25 26 27 28 29 30 31 23 22 21 20 19 18 17 16>;
        selector-s0-gpios = <&gpiob 14 GPIO_ACTIVE_HIGH>;
        selector-s1-gpios = <&gpiob 15 GPIO_ACTIVE_HIGH>;
        selector-s2-gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>;
        selector-s3-gpios = <&gpiob 13 GPIO_ACTIVE_HIGH>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "max7219";
        touchscreen-components = <64>;
        drivers = <1>;
        index-remap = <24 28 30 26 27 31 29 25 56 60 62 58 59 63 61 57
                     16 20 22 18 19 23 21 17 32 36 38 34 35 39 37 33
                     0 4 6 2 3 7 5 1 40 44 46 42 43 47 45 41>;
        data-gpios = <&gpioa 2 GPIO_ACTIVE_HIGH>;
        clock-gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>;
        latch-gpios = <&gpioa 1 GPIO_ACTIVE_HIGH>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };
};


================================================
FILE: app/boards/opendeck/opendeck22/firmware.overlay
================================================
#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>

&pinctrl {
    uart1_touchscreen_8_9: uart1_touchscreen_8_9 {
        group1 {
            pinmux = <UART1_TX_P8>;
        };

        group2 {
            pinmux = <UART1_RX_P9>;
            input-enable;
        };
    };

    i2c1_display_10_11: i2c1_display_10_11 {
        group1 {
            pinmux = <I2C1_SDA_P10>, <I2C1_SCL_P11>;
            input-enable;
            input-schmitt-enable;
        };
    };
};

&uart1 {
    current-speed = <115200>;
    status = "okay";
    pinctrl-0 = <&uart1_touchscreen_8_9>;
    pinctrl-names = "default";
};

&i2c1 {
    status = "okay";
    pinctrl-0 = <&i2c1_display_10_11>;
    pinctrl-names = "default";
};

opendeck_uart_din_midi: &uart0 {};

opendeck_uart_touchscreen: &uart1 {};

opendeck_i2c_display: &i2c1 {};


================================================
FILE: app/boards/opendeck/opendeck22/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "rpi_pico/rp2040";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpio0 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "matrix";
        touchscreen-components = <64>;
        row-mode = "shift-register";
        rows = <8>;
        columns = <8>;
        index-remap = <59 60 62 61 63 56 57 58 51 52 54 53 55 48 49 50
                     43 44 46 45 47 40 41 42 35 36 38 37 39 32 33 34
                     3 4 6 5 7 0 1 2 11 12 14 13 15 8 9 10
                     19 20 22 21 23 16 17 18 27 28 30 29 31 24 25 26>;
        data-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
        clock-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
        latch-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
        column-mode = "decoder";
        decoder-a0-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
        decoder-a1-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
        decoder-a2-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "4067";
        io-channels =
            <&adc 1>,
            <&adc 0>;
        multiplexers = <2>;
        index-remap = <8 9 10 11 12 13 14 15 7 6 5 4 3 2 1 0
                     24 25 26 27 28 29 30 31 23 22 21 20 19 18 17 16>;
        selector-s0-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
        selector-s1-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
        selector-s2-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
        selector-s3-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "max7219";
        touchscreen-components = <64>;
        drivers = <1>;
        index-remap = <24 28 30 26 27 31 29 25 56 60 62 58 59 63 61 57
                     16 20 22 18 19 23 21 17 32 36 38 34 35 39 37 33
                     0 4 6 2 3 7 5 1 40 44 46 42 43 47 45 41>;
        data-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
        clock-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
        latch-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };
};


================================================
FILE: app/boards/opendeck/opendeck31/firmware.overlay
================================================
#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>

&pinctrl {
    i2c1_display_2_3: i2c1_display_2_3 {
        group1 {
            pinmux = <I2C1_SDA_P2>, <I2C1_SCL_P3>;
            input-enable;
            input-schmitt-enable;
        };
    };
};

&i2c1 {
    status = "okay";
    pinctrl-0 = <&i2c1_display_2_3>;
    pinctrl-names = "default";
};

opendeck_uart_din_midi: &uart0 {};

opendeck_uart_touchscreen: &uart1 {};

opendeck_i2c_display: &i2c1 {};


================================================
FILE: app/boards/opendeck/opendeck31/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "rpi_pico/rp2040";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        lint;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpio0 18 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "matrix";
        touchscreen-components = <64>;
        row-mode = "shift-register";
        rows = <16>;
        columns = <8>;
        index-remap = <95 88 89 90 91 92 93 94 87 80 81 82 83 84 85 86
                     79 72 73 74 75 76 77 78 71 64 65 66 67 68 69 70
                     103 96 97 98 99 100 101 102 111 104 105 106 107 108 109 110
                     119 112 113 114 115 116 117 118 127 120 121 122 123 124 125 126
                     31 24 25 26 27 28 29 30 23 16 17 18 19 20 21 22
                     15 8 9 10 11 12 13 14 7 0 1 2 3 4 5 6
                     39 32 33 34 35 36 37 38 47 40 41 42 43 44 45 46
                     55 48 49 50 51 52 53 54 63 56 57 58 59 60 61 62>;
        data-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
        clock-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
        latch-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
        column-mode = "decoder";
        decoder-a0-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
        decoder-a1-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
        decoder-a2-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "muxonmux";
        io-channels = <&adc 2>;
        index-remap = <63 62 61 60 59 58 57 56 48 49 50 51 52 53 54 55
                     15 14 13 12 11 10 9 8 0 1 2 3 4 5 6 7
                     31 30 29 28 27 26 25 24 16 17 18 19 20 21 22 23
                     47 46 45 44 43 42 41 40 32 33 34 35 36 37 38 39>;
        controller-s0-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
        controller-s1-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
        node-s0-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
        node-s1-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        node-s2-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
        node-s3-gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "max7219";
        touchscreen-components = <64>;
        drivers = <1>;
        index-remap = <48 8 40 0 32 16 56 24 52 12 44 4 36 20 60 28
                     54 14 46 6 38 22 62 30 50 10 42 2 34 18 58 26
                     51 11 43 3 35 19 59 27 55 15 47 7 39 23 63 31
                     53 13 45 5 37 21 61 29 49 9 41 1 33 17 57 25>;
        data-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
        clock-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
        latch-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };
};


================================================
FILE: app/boards/opendeck/pico/firmware.overlay
================================================
opendeck_uart_din_midi: &uart0 {};

opendeck_uart_touchscreen: &uart1 {};

opendeck_i2c_display: &i2c0 {};


================================================
FILE: app/boards/opendeck/pico/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "rpi_pico/rp2040";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        host-test;
        lint;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 23 GPIO_ACTIVE_HIGH>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc 0>,
            <&adc 1>,
            <&adc 2>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpio0 14 GPIO_ACTIVE_HIGH>,
            <&gpio0 15 GPIO_ACTIVE_HIGH>,
            <&gpio0 22 GPIO_ACTIVE_HIGH>,
            <&gpio0 21 GPIO_ACTIVE_HIGH>,
            <&gpio0 20 GPIO_ACTIVE_HIGH>,
            <&gpio0 19 GPIO_ACTIVE_HIGH>,
            <&gpio0 18 GPIO_ACTIVE_HIGH>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        ble-in-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        ble-out-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        button-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/pico2/firmware.overlay
================================================
opendeck_uart_din_midi: &uart0 {};

opendeck_uart_touchscreen: &uart1 {};

opendeck_i2c_display: &i2c0 {};


================================================
FILE: app/boards/opendeck/pico2/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "rpi_pico2/rp2350a/m33";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpio0 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc 0>,
            <&adc 1>,
            <&adc 2>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpio0 14 GPIO_ACTIVE_HIGH>,
            <&gpio0 15 GPIO_ACTIVE_HIGH>,
            <&gpio0 22 GPIO_ACTIVE_HIGH>,
            <&gpio0 21 GPIO_ACTIVE_HIGH>,
            <&gpio0 20 GPIO_ACTIVE_HIGH>,
            <&gpio0 19 GPIO_ACTIVE_HIGH>,
            <&gpio0 18 GPIO_ACTIVE_HIGH>;
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        ble-in-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
        ble-out-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/rooibos/firmware.overlay
================================================
opendeck_uart_touchscreen: &usart1 {};


================================================
FILE: app/boards/opendeck/rooibos/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "weact_stm32f405_core/stm32f405xx";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpiob 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "4067";
        io-channels =
            <&adc1 15>,
            <&adc1 14>;
        multiplexers = <2>;
        index-remap = <10 11 12 13 8 9 14 15 7 6 1 0 5 4 3 2
                     23 16>;
        selector-s0-gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>;
        selector-s1-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
        selector-s2-gpios = <&gpioa 7 GPIO_ACTIVE_HIGH>;
        selector-s3-gpios = <&gpioa 6 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/teensy4/firmware.overlay
================================================
opendeck_uart_din_midi: &lpuart4 {};       /* Teensy pins 8 (TX4) / 7 (RX4) */

opendeck_uart_touchscreen: &lpuart4 {};    /* Teensy pins 8 (TX4) / 7 (RX4) */

opendeck_i2c_display: &lpi2c4 {};          /* Teensy pins 24 (SCL2) / 25 (SDA2) */


================================================
FILE: app/boards/opendeck/teensy4/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "teensy40/mimxrt1062";
        board-name = "Teensy 4.0";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
        hw;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        hw-test;
        lint;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        native-gpios =
            <&gpio4 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 2 */
            <&gpio4 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 3 */
            <&gpio4 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 4 */
            <&gpio4 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 5 */
            <&gpio2 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,  /* pin 6 */
            <&gpio2 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,  /* pin 9 */
            <&gpio2 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 10 */
            <&gpio2 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 11 */
            <&gpio2 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 12 */
            <&gpio3 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,  /* pin 36, bottom pad CLK */
            <&gpio3 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;  /* pin 37, bottom pad DAT3 */
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc1 7>,   /* A0 = pin 14 */
            <&adc1 8>,   /* A1 = pin 15 */
            <&adc1 12>,  /* A2 = pin 16 */
            <&adc1 11>,  /* A3 = pin 17 */
            <&adc1 6>,   /* A4 = pin 18 */
            <&adc1 5>,   /* A5 = pin 19 */
            <&adc1 15>,  /* A6 = pin 20 */
            <&adc1 0>,   /* A7 = pin 21 */
            <&adc1 13>,  /* A8 = pin 22 */
            <&adc1 14>;  /* A9 = pin 23 */
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        native-gpios =
            <&gpio1 30 GPIO_ACTIVE_HIGH>,  /* pin 26 */
            <&gpio1 31 GPIO_ACTIVE_HIGH>,  /* pin 27 */
            <&gpio3 18 GPIO_ACTIVE_HIGH>,  /* pin 28 */
            <&gpio4 31 GPIO_ACTIVE_HIGH>,  /* pin 29 */
            <&gpio3 23 GPIO_ACTIVE_HIGH>,  /* pin 30 */
            <&gpio3 22 GPIO_ACTIVE_HIGH>,  /* pin 31 */
            <&gpio2 12 GPIO_ACTIVE_HIGH>,  /* pin 32 */
            <&gpio4 7 GPIO_ACTIVE_HIGH>,   /* pin 33 */
            <&gpio3 15 GPIO_ACTIVE_HIGH>,  /* pin 34, bottom pad DAT0 */
            <&gpio3 14 GPIO_ACTIVE_HIGH>,  /* pin 35, bottom pad CMD */
            <&gpio3 17 GPIO_ACTIVE_HIGH>;  /* pin 38, bottom pad DAT2 */
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/teensy41/firmware.overlay
================================================
opendeck_uart_din_midi: &lpuart4 {};       /* Teensy pins 8 (TX4) / 7 (RX4) */

opendeck_uart_touchscreen: &lpuart4 {};    /* Teensy pins 8 (TX4) / 7 (RX4) */

opendeck_i2c_display: &lpi2c4 {};          /* Teensy pins 24 (SCL2) / 25 (SDA2) */


================================================
FILE: app/boards/opendeck/teensy41/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "teensy41/mimxrt1062";
        board-name = "Teensy 4.1";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
        hw;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
        host-test;
        hw-test;
        lint;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        native-gpios =
            <&gpio4 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 2 */
            <&gpio4 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 3 */
            <&gpio4 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 4 */
            <&gpio4 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 5 */
            <&gpio2 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,  /* pin 6 */
            <&gpio2 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,  /* pin 9 */
            <&gpio2 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 10 */
            <&gpio2 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,   /* pin 11 */
            <&gpio2 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;   /* pin 12 */
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc1 7>,   /* A0 = pin 14 */
            <&adc1 8>,   /* A1 = pin 15 */
            <&adc1 12>,  /* A2 = pin 16 */
            <&adc1 11>,  /* A3 = pin 17 */
            <&adc1 6>,   /* A4 = pin 18 */
            <&adc1 5>,   /* A5 = pin 19 */
            <&adc1 15>,  /* A6 = pin 20 */
            <&adc1 0>,   /* A7 = pin 21 */
            <&adc1 13>,  /* A8 = pin 22 */
            <&adc1 14>,  /* A9 = pin 23 */
            <&adc2 3>,   /* A12 = pin 26 */
            <&adc2 4>,   /* A13 = pin 27 */
            <&adc2 1>,   /* A14 = pin 38 */
            <&adc2 2>,   /* A15 = pin 39 */
            <&adc1 9>,   /* A16 = pin 40 */
            <&adc1 10>;  /* A17 = pin 41 */
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        native-gpios =
            <&gpio3 18 GPIO_ACTIVE_HIGH>,  /* pin 28 */
            <&gpio4 31 GPIO_ACTIVE_HIGH>,  /* pin 29 */
            <&gpio3 23 GPIO_ACTIVE_HIGH>,  /* pin 30 */
            <&gpio3 22 GPIO_ACTIVE_HIGH>,  /* pin 31 */
            <&gpio2 12 GPIO_ACTIVE_HIGH>,  /* pin 32 */
            <&gpio4 7 GPIO_ACTIVE_HIGH>,   /* pin 33 */
            <&gpio2 29 GPIO_ACTIVE_HIGH>,  /* pin 34 */
            <&gpio2 28 GPIO_ACTIVE_HIGH>,  /* pin 35 */
            <&gpio2 18 GPIO_ACTIVE_HIGH>,  /* pin 36 */
            <&gpio2 19 GPIO_ACTIVE_HIGH>;  /* pin 37 */
    };

    opendeck_midi_indicators: opendeck-midi-indicators {
        compatible = "opendeck,midi-indicators";
        usb-in-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
        usb-out-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
        din-in-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
        din-out-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/opendeck/ws_core405r/firmware.overlay
================================================
opendeck_uart_din_midi: &usart1 {};

opendeck_uart_touchscreen: &usart1 {};

opendeck_i2c_display: &i2c1 {};


================================================
FILE: app/boards/opendeck/ws_core405r/opendeck.overlay
================================================
/ {
    opendeck_metadata: opendeck-metadata {
        compatible = "opendeck,metadata";
        zephyr-board = "weact_stm32f405_core/stm32f405xx";
    };

    opendeck_tests: opendeck-tests {
        compatible = "opendeck,tests";
        host;
    };

    opendeck_bulk_build: opendeck-bulk-build {
        compatible = "opendeck,bulk-build";
        app;
    };

    opendeck_buttons: opendeck-buttons {
        compatible = "opendeck,buttons";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpiob 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioa 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioa 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioa 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioa 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpioc 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiod 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>,
            <&gpiob 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    };

    opendeck_analog: opendeck-analog {
        compatible = "opendeck,analog";
        mode = "native";
        io-channels =
            <&adc1 0>,
            <&adc1 1>,
            <&adc1 2>,
            <&adc1 3>,
            <&adc1 4>,
            <&adc1 5>,
            <&adc1 6>,
            <&adc1 7>,
            <&adc1 8>,
            <&adc1 9>,
            <&adc1 10>,
            <&adc1 11>,
            <&adc1 12>,
            <&adc1 13>,
            <&adc1 14>,
            <&adc1 15>;
    };

    opendeck_leds: opendeck-leds {
        compatible = "opendeck,leds";
        mode = "native";
        touchscreen-components = <64>;
        native-gpios =
            <&gpiob 5 GPIO_ACTIVE_HIGH>,
            <&gpiob 8 GPIO_ACTIVE_HIGH>,
            <&gpiob 9 GPIO_ACTIVE_HIGH>,
            <&gpiob 11 GPIO_ACTIVE_HIGH>,
            <&gpiob 2 GPIO_ACTIVE_HIGH>,
            <&gpioc 15 GPIO_ACTIVE_HIGH>,
            <&gpioc 13 GPIO_ACTIVE_HIGH>,
            <&gpioc 10 GPIO_ACTIVE_HIGH>,
            <&gpioc 14 GPIO_ACTIVE_HIGH>;
    };

    opendeck_touchscreen: opendeck-touchscreen {
        compatible = "opendeck,touchscreen";
        component-count = <64>;
        uart = <&opendeck_uart_touchscreen>;
    };

    opendeck_din_midi: opendeck-din-midi {
        compatible = "opendeck,midi-uart";
        uart = <&opendeck_uart_din_midi>;
    };

    opendeck_display: opendeck-display {
        compatible = "opendeck,display-i2c";
        i2c = <&opendeck_i2c_display>;
    };

    opendeck_bootloader: opendeck-bootloader {
        compatible = "opendeck,bootloader";
        boot-partition = <&opendeck_partition_boot>;
        app-partition = <&opendeck_partition_app>;
    };
};


================================================
FILE: app/boards/zephyr/blackpill_f411ce_stm32f411xe/bootloader.conf
================================================


================================================
FILE: app/boards/zephyr/blackpill_f411ce_stm32f411xe/bootloader.overlay
================================================
/ {
    chosen {
        /delete-property/ zephyr,console;
        /delete-property/ zephyr,shell-uart;
        zephyr,code-partition = &boot_partition;
    };
};


================================================
FILE: app/boards/zephyr/blackpill_f411ce_stm32f411xe/firmware.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=16384


================================================
FILE: app/boards/zephyr/blackpill_f411ce_stm32f411xe/firmware.overlay
================================================
/ {
    chosen {
        /delete-property/ zephyr,console;
        /delete-property/ zephyr,shell-uart;
    };

    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&usart1 {
    current-speed = <115200>;
    pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
    pinctrl-names = "default";
    status = "okay";
};

&i2c1 {
    clock-frequency = <I2C_BITRATE_FAST>;
    pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>;
    pinctrl-names = "default";
    status = "okay";
};

&adc1 {
    pinctrl-0 = <&adc1_in1_pa1
                 &adc1_in2_pa2
                 &adc1_in3_pa3
                 &adc1_in4_pa4
                 &adc1_in5_pa5
                 &adc1_in6_pa6
                 &adc1_in7_pa7
                 &adc1_in9_pb1>;
    pinctrl-names = "default";
    st,adc-prescaler = <4>;
    status = "okay";

    #address-cells = <1>;
    #size-cells = <0>;

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@4 {
        reg = <4>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@5 {
        reg = <5>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@6 {
        reg = <6>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@7 {
        reg = <7>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@9 {
        reg = <9>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };
};

&{/leds} {
    status = "disabled";
};

&{/gpio_keys} {
    status = "disabled";
};


================================================
FILE: app/boards/zephyr/blackpill_f411ce_stm32f411xe/partitions.overlay
================================================
&flash0 {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x08000000 0x00080000>;

    partitions {
        compatible = "fixed-partitions";
        ranges;
        #address-cells = <1>;
        #size-cells = <1>;

        /delete-node/ partition@0;
        /delete-node/ partition@20000;
        /delete-node/ partition@40000;
        /delete-node/ partition@60000;

        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x0000c000>;
            read-only;
        };

        factory_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x0000c000 0x00004000>;
            read-only;
        };

        code_partition: partition@10000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00010000 0x00030000>;
            read-only;
        };

        emueeprom_page1_partition: partition@40000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x00040000 0x00020000>;
        };

        emueeprom_page2_partition: partition@60000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x00060000 0x00020000>;
        };
    };
};

&sram0 {
    reg = <0x20000000 DT_SIZE_K(124)>;
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@2001f000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x2001f000 DT_SIZE_K(4)>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/blackpill_f411ce_stm32f411xe/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpioa: gpioa {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpiob: gpiob {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpioc: gpioc {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    adc1: adc1 {
        compatible = "zephyr,adc-emul";
        nchannels = <16>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    usart1: usart1 {
        compatible = "zephyr,uart-emul";
        current-speed = <115200>;
        status = "okay";
    };

    usart2: usart2 {
        compatible = "zephyr,uart-emul";
        current-speed = <115200>;
        status = "okay";
    };

    i2c1: i2c1@500 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x500 4>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x0000c000>;
        };

        code_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x0000c000 0x00069000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/nrf52840dk_nrf52840/bootloader.conf
================================================



================================================
FILE: app/boards/zephyr/nrf52840dk_nrf52840/bootloader.overlay
================================================
/ {
    chosen {
        zephyr,code-partition = &boot_partition;
    };
};


================================================
FILE: app/boards/zephyr/nrf52840dk_nrf52840/firmware.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_RX_SIZE=251


================================================
FILE: app/boards/zephyr/nrf52840dk_nrf52840/firmware.overlay
================================================
/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&uart0 {
    current-speed = <115200>;
};

&uart1 {
    status = "okay";
};

&qspi {
    status = "disabled";
};

&spi3 {
    status = "disabled";
};

&pwm0 {
    status = "disabled";
};

&adc {
    status = "okay";
    #address-cells = <1>;
    #size-cells = <0>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN0>;
    };

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN1>;
    };

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN2>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN3>;
    };

    channel@4 {
        reg = <4>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN4>;
    };

    channel@5 {
        reg = <5>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN5>;
    };

    channel@6 {
        reg = <6>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN6>;
    };

    channel@7 {
        reg = <7>;
        zephyr,gain = "ADC_GAIN_1_5";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN7>;
    };
};

&{/buttons} {
    status = "disabled";
};

&{/leds} {
    status = "disabled";
};

&{/pwmleds} {
    status = "disabled";
};


================================================
FILE: app/boards/zephyr/nrf52840dk_nrf52840/partitions.overlay
================================================
&flash0 {
    partitions {
        ranges;
        /delete-node/ boot_partition;
        /delete-node/ slot0_partition;
        /delete-node/ slot1_partition;
        /delete-node/ storage_partition;

        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x00018000>;
            read-only;
        };

        code_partition: partition@18000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00018000 0x00040000>;
            read-only;
        };

        factory_partition: partition@58000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x00058000 0x00002000>;
        };

        emueeprom_page1_partition: partition@5a000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x0005a000 0x00002000>;
        };

        emueeprom_page2_partition: partition@5c000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x0005c000 0x00002000>;
        };
    };
};

&sram0 {
    reg = <0x20000000 DT_SIZE_K(252)>;
    ranges = <0x0 0x20000000 DT_SIZE_K(252)>;
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@2003f000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x2003f000 DT_SIZE_K(4)>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/nrf52840dk_nrf52840/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpio1: gpio1 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    arduino_adc: adc {
        compatible = "zephyr,adc-emul";
        nchannels = <8>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    arduino_i2c: arduino_i2c@500 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x500 4>;
        status = "okay";
    };

    uart1: uart1 {
        compatible = "zephyr,uart-emul";
        current-speed = <115200>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x0000c000>;
        };

        code_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x0000c000 0x00069000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/bootloader.conf
================================================
CONFIG_POWEROFF=y
CONFIG_NRF_FORCE_RAM_ON_REBOOT=y
CONFIG_NRF_ENABLE_ICACHE=n
CONFIG_NRF_RTC_TIMER=n


================================================
FILE: app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/bootloader.overlay
================================================
/ {
    chosen {
        zephyr,code-partition = &cpuapp_boot_partition;
    };
};


================================================
FILE: app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/firmware.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=y
# CONFIG_BT=y
# CONFIG_BT_PERIPHERAL=y
# CONFIG_BT_L2CAP_TX_MTU=247
# CONFIG_BT_BUF_ACL_TX_SIZE=251
# CONFIG_BT_BUF_ACL_RX_SIZE=251


================================================
FILE: app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/firmware.overlay
================================================
/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&can120 {
    status = "disabled";
};

&adc {
    #address-cells = <1>;
    #size-cells = <0>;
    status = "okay";
    memory-regions = <&cpuapp_dma_region>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN0>;
    };

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN1>;
    };

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN2>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN3>;
    };

    channel@4 {
        reg = <4>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN4>;
    };

    channel@5 {
        reg = <5>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN5>;
    };

    channel@6 {
        reg = <6>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN6>;
    };

    channel@7 {
        reg = <7>;
        zephyr,gain = "ADC_GAIN_1_2";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 5)>;
        zephyr,resolution = <12>;
        zephyr,input-positive = <NRF_SAADC_AIN7>;
    };
};

&{/buttons} {
    status = "disabled";
};


================================================
FILE: app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/partitions.overlay
================================================
&cpuapp_boot_partition {
    compatible = "zephyr,mapped-partition";
    reg = <0x30000 DT_SIZE_K(96)>;
};

&mram1x {
    partitions {
        ranges;
        /delete-node/ partition@40000;

        cpuapp_slot0_partition: partition@48000 {
            compatible = "zephyr,mapped-partition";
            reg = <0x48000 DT_SIZE_K(296)>;
        };

        factory_partition: partition@1f3000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x1f3000 DT_SIZE_K(8)>;
        };

        emueeprom_page1_partition: partition@1f5000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x1f5000 DT_SIZE_K(8)>;
        };

        emueeprom_page2_partition: partition@1f7000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x1f7000 DT_SIZE_K(8)>;
        };
    };
};

&cpuapp_data {
    reg = <0x2f000000 0x000bd000>;
};

/ {
    opendeck_retained_mem: memory@2f0bd000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x2f0bd000 DT_SIZE_K(4)>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &cpuapp_boot_partition {};

opendeck_partition_app: &cpuapp_slot0_partition {};


================================================
FILE: app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/sysbuild.cmake
================================================
set(uicr_EXTRA_DTC_OVERLAY_FILE ${opendeck_board_partitions_overlay} CACHE INTERNAL "")


================================================
FILE: app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    buttons {
        compatible = "gpio-keys";
        status = "okay";
    };

    adc: adc {
        compatible = "zephyr,adc-emul";
        nchannels = <8>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    gpio9: gpio9 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        cpuapp_boot_partition: partition@0 {
            label = "boot";
            reg = <0x00000000 0x0000c000>;
        };

        cpuapp_slot0_partition: code_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x0000c000 0x00069000>;
        };
    };
};

opendeck_partition_boot: &cpuapp_boot_partition {};

opendeck_partition_app: &cpuapp_slot0_partition {};


================================================
FILE: app/boards/zephyr/rpi_pico2_rp2350a_m33/bootloader.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=n
CONFIG_FLASH_LOAD_OFFSET=0x0
CONFIG_FLASH_LOAD_SIZE=0x18000


================================================
FILE: app/boards/zephyr/rpi_pico2_rp2350a_m33/bootloader.overlay
================================================
&led0 {
    status = "disabled";
};

&pwm_led0 {
    status = "disabled";
};


================================================
FILE: app/boards/zephyr/rpi_pico2_rp2350a_m33/firmware.conf
================================================


================================================
FILE: app/boards/zephyr/rpi_pico2_rp2350a_m33/firmware.overlay
================================================
#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2350a-pinctrl.h>
/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&led0 {
    status = "disabled";
};

&pwm_led0 {
    status = "disabled";
};

&pinctrl {
    uart1_touchscreen_default: uart1_touchscreen_default {
        group1 {
            pinmux = <UART1_TX_P4>;
        };

        group2 {
            pinmux = <UART1_RX_P5>;
            input-enable;
        };
    };

    i2c0_display_default: i2c0_display_default {
        group1 {
            pinmux = <I2C0_SDA_P16>, <I2C0_SCL_P17>;
            input-enable;
            input-schmitt-enable;
        };
    };
};

&uart1 {
    current-speed = <115200>;
    status = "okay";
    pinctrl-0 = <&uart1_touchscreen_default>;
    pinctrl-names = "default";
};

&i2c0 {
    status = "okay";
    pinctrl-0 = <&i2c0_display_default>;
    pinctrl-names = "default";
};

&adc {
    raspberrypi,adc-clkdiv = <2>;
    #address-cells = <1>;
    #size-cells = <0>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };
};


================================================
FILE: app/boards/zephyr/rpi_pico2_rp2350a_m33/partitions.overlay
================================================
&flash0 {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x10000000 DT_SIZE_M(4)>;

    /delete-node/ partitions;

    partitions {
        compatible = "fixed-partitions";
        ranges;
        #address-cells = <1>;
        #size-cells = <1>;

        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x00018000>;
            read-only;
        };

        code_partition: partition@18000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00018000 0x00328000>;
            read-only;
        };

        factory_partition: partition@340000 {
            label = "factory";
            reg = <0x00340000 0x00008000>;
        };

        emueeprom_page1_partition: partition@380000 {
            label = "emueeprom-page1";
            reg = <0x00380000 0x00008000>;
        };

        emueeprom_page2_partition: partition@3c0000 {
            label = "emueeprom-page2";
            reg = <0x003c0000 0x00008000>;
        };
    };
};

/delete-node/ &sram0;

&{/soc} {
    sram0: memory@20000100 {
        compatible = "mmio-sram";
        reg = <0x20000100 ((DT_SIZE_K(520)) - 0x100)>;
    };
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@20000000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x20000000 0x100>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/rpi_pico2_rp2350a_m33/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpio1: gpio1 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    adc: adc {
        compatible = "zephyr,adc-emul";
        nchannels = <8>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    i2c1: i2c1@600 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x600 4>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x0000c000>;
        };

        code_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x0000c000 0x00069000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/rpi_pico_rp2040/bootloader.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=n
# RP2040 bootloader image placement must match `boot_partition` in
# `partitions.overlay`; the explicit Kconfig values are required so Zephyr
# keeps the RP2040 second-stage boot block at flash offset 0x0.
CONFIG_FLASH_LOAD_OFFSET=0x100
CONFIG_FLASH_LOAD_SIZE=0x17F00


================================================
FILE: app/boards/zephyr/rpi_pico_rp2040/bootloader.overlay
================================================
&led0 {
    status = "disabled";
};

&pwm_led0 {
    status = "disabled";
};


================================================
FILE: app/boards/zephyr/rpi_pico_rp2040/firmware.conf
================================================


================================================
FILE: app/boards/zephyr/rpi_pico_rp2040/firmware.overlay
================================================
#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>
/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&led0 {
    status = "disabled";
};

&pwm_led0 {
    status = "disabled";
};

&pinctrl {
    uart1_touchscreen_default: uart1_touchscreen_default {
        group1 {
            pinmux = <UART1_TX_P4>;
        };

        group2 {
            pinmux = <UART1_RX_P5>;
            input-enable;
        };
    };

    i2c0_display_default: i2c0_display_default {
        group1 {
            pinmux = <I2C0_SDA_P16>, <I2C0_SCL_P17>;
            input-enable;
            input-schmitt-enable;
        };
    };
};

&uart1 {
    current-speed = <115200>;
    status = "okay";
    pinctrl-0 = <&uart1_touchscreen_default>;
    pinctrl-names = "default";
};

&i2c0 {
    status = "okay";
    pinctrl-0 = <&i2c0_display_default>;
    pinctrl-names = "default";
};

&adc {
    raspberrypi,adc-clkdiv = <2>;
    #address-cells = <1>;
    #size-cells = <0>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };
};


================================================
FILE: app/boards/zephyr/rpi_pico_rp2040/partitions.overlay
================================================
&flash0 {
    /delete-node/ partitions;

    partitions {
        compatible = "fixed-partitions";
        ranges;
        #address-cells = <1>;
        #size-cells = <1>;

        second_stage_bootloader: partition@0 {
            label = "second_stage_bootloader";
            reg = <0x00000000 0x00000100>;
            read-only;
        };

        boot_partition: partition@100 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000100 0x00017f00>;
            read-only;
        };

        code_partition: partition@18000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00018000 0x00128000>;
            read-only;
        };

        factory_partition: partition@140000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x00140000 0x00008000>;
        };

        emueeprom_page1_partition: partition@180000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x00180000 0x00008000>;
        };

        emueeprom_page2_partition: partition@1c0000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x001c0000 0x00008000>;
        };
    };
};

/delete-node/ &sram0;

&{/soc} {
    sram0: memory@20000100 {
        compatible = "mmio-sram";
        reg = <0x20000100 ((DT_SIZE_K(264)) - 0x100)>;
    };
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@20000000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x20000000 0x100>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/rpi_pico_rp2040/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpio1: gpio1 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    adc: adc {
        compatible = "zephyr,adc-emul";
        nchannels = <8>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    i2c1: i2c1@600 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x600 4>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x0000c000>;
        };

        code_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x0000c000 0x00069000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/stm32f4_disco_stm32f407xx/bootloader.conf
================================================


================================================
FILE: app/boards/zephyr/stm32f4_disco_stm32f407xx/bootloader.overlay
================================================
/ {
    chosen {
        zephyr,code-partition = &boot_partition;
    };
};


================================================
FILE: app/boards/zephyr/stm32f4_disco_stm32f407xx/firmware.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=16384


================================================
FILE: app/boards/zephyr/stm32f4_disco_stm32f407xx/firmware.overlay
================================================
/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&usart6 {
    current-speed = <115200>;
    pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>;
    pinctrl-names = "default";
    status = "okay";
};

&i2c2 {
    clock-frequency = <I2C_BITRATE_FAST>;
    pinctrl-0 = <&i2c2_scl_pb10 &i2c2_sda_pb11>;
    pinctrl-names = "default";
    status = "okay";
};

&adc1 {
    pinctrl-0 = <&adc1_in2_pa2
                 &adc1_in3_pa3
                 &adc1_in8_pb0
                 &adc1_in9_pb1
                 &adc1_in11_pc1
                 &adc1_in12_pc2
                 &adc1_in14_pc4>;
    pinctrl-names = "default";
    st,adc-prescaler = <4>;
    status = "okay";

    #address-cells = <1>;
    #size-cells = <0>;

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@8 {
        reg = <8>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@9 {
        reg = <9>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@b {
        reg = <11>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@c {
        reg = <12>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@e {
        reg = <14>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };
};


================================================
FILE: app/boards/zephyr/stm32f4_disco_stm32f407xx/partitions.overlay
================================================
&flash0 {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x08000000 0x00100000>;

    partitions {
        compatible = "fixed-partitions";
        ranges;
        #address-cells = <1>;
        #size-cells = <1>;

        /delete-node/ partition@0;
        /delete-node/ partition@8000;

        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x00010000>;
            read-only;
        };

        code_partition: partition@10000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00010000 0x00050000>;
            read-only;
        };

        emueeprom_page1_partition: partition@60000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x00060000 0x00020000>;
        };

        emueeprom_page2_partition: partition@80000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x00080000 0x00020000>;
        };

        factory_partition: partition@a0000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x000a0000 0x00020000>;
            read-only;
        };
    };
};

&sram0 {
    reg = <0x20000000 DT_SIZE_K(124)>;
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@2001f000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x2001f000 DT_SIZE_K(4)>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/stm32f4_disco_stm32f407xx/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpioa: gpioa {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpiob: gpiob {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpioc: gpioc {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpiod: gpiod {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpioe: gpioe {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    adc1: adc1 {
        compatible = "zephyr,adc-emul";
        nchannels = <16>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    usart6: usart6 {
        compatible = "zephyr,uart-emul";
        current-speed = <115200>;
        status = "okay";
    };

    i2c2: i2c2@600 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x600 4>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x0000c000>;
        };

        code_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x0000c000 0x00069000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/teensy40_mimxrt1062/bootloader.conf
================================================



================================================
FILE: app/boards/zephyr/teensy40_mimxrt1062/bootloader.overlay
================================================
/ {
    chosen {
        zephyr,code-partition = &boot_partition;
    };
};


================================================
FILE: app/boards/zephyr/teensy40_mimxrt1062/firmware.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=32768


================================================
FILE: app/boards/zephyr/teensy40_mimxrt1062/firmware.overlay
================================================
#include <zephyr/dt-bindings/adc/adc.h>

/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&{/leds} {
    status = "disabled";
};

&pinctrl {
    adc1_opendeck_default: adc1_opendeck_default {
        group1 {
            pinmux = <&iomuxc_gpio_ad_b1_02_adc1_in7>,
                     <&iomuxc_gpio_ad_b1_03_adc1_in8>,
                     <&iomuxc_gpio_ad_b1_07_adc1_in12>,
                     <&iomuxc_gpio_ad_b1_06_adc1_in11>,
                     <&iomuxc_gpio_ad_b1_01_adc1_in6>,
                     <&iomuxc_gpio_ad_b1_00_adc1_in5>,
                     <&iomuxc_gpio_ad_b1_10_adc1_in15>,
                     <&iomuxc_gpio_ad_b1_11_adc1_in0>,
                     <&iomuxc_gpio_ad_b1_08_adc1_in13>,
                     <&iomuxc_gpio_ad_b1_09_adc1_in14>;
            bias-disable;
            drive-strength = "r0-6";
            slew-rate = "slow";
            nxp,speed = "100-mhz";
        };
    };
};

&lpuart4 {
    /* Teensy pins 8 (TX) / 7 (RX) */
    current-speed = <115200>;
    status = "okay";
};

&lpi2c4 {
    /* Teensy pins 24 (SCL) / 25 (SDA) */
    clock-frequency = <I2C_BITRATE_FAST>;
    status = "okay";
};

&adc1 {
    status = "okay";
    pinctrl-0 = <&adc1_opendeck_default>;
    pinctrl-names = "default";
    #address-cells = <1>;
    #size-cells = <0>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@5 {
        reg = <5>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@6 {
        reg = <6>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@7 {
        reg = <7>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@8 {
        reg = <8>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@b {
        reg = <11>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@c {
        reg = <12>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@d {
        reg = <13>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@e {
        reg = <14>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@f {
        reg = <15>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };
};


================================================
FILE: app/boards/zephyr/teensy40_mimxrt1062/partitions.overlay
================================================
&w25q16jvuxim {
    partitions {
        compatible = "fixed-partitions";
        #address-cells = <1>;
        #size-cells = <1>;

        boot_partition: partition@0 {
            label = "boot";
            reg = <0x00000000 0x00020000>;
            read-only;
        };

        code_partition: partition@20000 {
            label = "code-partition";
            reg = <0x00020000 0x001c8000>;
            read-only;
        };

        factory_partition: partition@1e8000 {
            label = "factory";
            reg = <0x001e8000 0x00008000>;
        };

        emueeprom_page1_partition: partition@1f0000 {
            label = "emueeprom-page1";
            reg = <0x001f0000 0x00008000>;
        };

        emueeprom_page2_partition: partition@1f8000 {
            label = "emueeprom-page2";
            reg = <0x001f8000 0x00008000>;
        };
    };
};

&flexram {
    /delete-node/ ocram@20280000;

    ocram: ocram@20200000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x20200000 DT_SIZE_K(252)>;
        zephyr,memory-region = "OCRAM";
    };
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@2023f000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x2023f000 DT_SIZE_K(4)>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/teensy40_mimxrt1062/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpio1: gpio1 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpio2: gpio2 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpio3: gpio3 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpio4: gpio4 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    adc1: adc1 {
        compatible = "zephyr,adc-emul";
        nchannels = <16>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    lpuart4: lpuart4 {
        compatible = "zephyr,uart-emul";
        current-speed = <115200>;
        status = "okay";
    };

    lpi2c4: lpi2c4@500 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x500 4>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x00020000>;
        };

        code_partition: partition@20000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00020000 0x001c8000>;
        };

        factory_partition: partition@1e8000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x001e8000 0x00008000>;
        };

        emueeprom_page1_partition: partition@1f0000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x001f0000 0x00008000>;
        };

        emueeprom_page2_partition: partition@1f8000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x001f8000 0x00008000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/teensy41_mimxrt1062/bootloader.conf
================================================



================================================
FILE: app/boards/zephyr/teensy41_mimxrt1062/bootloader.overlay
================================================
/ {
    chosen {
        zephyr,code-partition = &boot_partition;
    };
};


================================================
FILE: app/boards/zephyr/teensy41_mimxrt1062/firmware.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=32768


================================================
FILE: app/boards/zephyr/teensy41_mimxrt1062/firmware.overlay
================================================
#include <zephyr/dt-bindings/adc/adc.h>

/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&{/leds} {
    status = "disabled";
};

&enet_mac {
    status = "disabled";
};

&enet_mdio {
    status = "disabled";
};

&lpspi3 {
    status = "disabled";
};

&usdhc1 {
    status = "disabled";
};

&pinctrl {
    adc1_opendeck_default: adc1_opendeck_default {
        group1 {
            pinmux = <&iomuxc_gpio_ad_b1_11_adc1_in0>,
                     <&iomuxc_gpio_ad_b1_00_adc1_in5>,
                     <&iomuxc_gpio_ad_b1_01_adc1_in6>,
                     <&iomuxc_gpio_ad_b1_02_adc1_in7>,
                     <&iomuxc_gpio_ad_b1_03_adc1_in8>,
                     <&iomuxc_gpio_ad_b1_04_adc1_in9>,
                     <&iomuxc_gpio_ad_b1_05_adc1_in10>,
                     <&iomuxc_gpio_ad_b1_06_adc1_in11>,
                     <&iomuxc_gpio_ad_b1_07_adc1_in12>,
                     <&iomuxc_gpio_ad_b1_08_adc1_in13>,
                     <&iomuxc_gpio_ad_b1_09_adc1_in14>,
                     <&iomuxc_gpio_ad_b1_10_adc1_in15>;
            bias-disable;
            drive-strength = "r0-6";
            slew-rate = "slow";
            nxp,speed = "100-mhz";
        };
    };

    adc2_opendeck_default: adc2_opendeck_default {
        group1 {
            pinmux = <&iomuxc_gpio_ad_b1_12_adc2_in1>,
                     <&iomuxc_gpio_ad_b1_13_adc2_in2>,
                     <&iomuxc_gpio_ad_b1_14_adc2_in3>,
                     <&iomuxc_gpio_ad_b1_15_adc2_in4>;
            bias-disable;
            drive-strength = "r0-6";
            slew-rate = "slow";
            nxp,speed = "100-mhz";
        };
    };
};

&lpuart4 {
    /* Teensy pins 8 (TX4) / 7 (RX4) */
    current-speed = <115200>;
    status = "okay";
};

&lpi2c4 {
    /* Teensy pins 24 (SCL2) / 25 (SDA2) */
    clock-frequency = <I2C_BITRATE_FAST>;
    status = "okay";
};

&adc1 {
    status = "okay";
    pinctrl-0 = <&adc1_opendeck_default>;
    pinctrl-names = "default";
    #address-cells = <1>;
    #size-cells = <0>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@5 {
        reg = <5>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@6 {
        reg = <6>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@7 {
        reg = <7>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@8 {
        reg = <8>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@9 {
        reg = <9>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@a {
        reg = <10>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@b {
        reg = <11>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@c {
        reg = <12>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@d {
        reg = <13>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@e {
        reg = <14>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@f {
        reg = <15>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };
};

&adc2 {
    status = "okay";
    pinctrl-0 = <&adc2_opendeck_default>;
    pinctrl-names = "default";
    #address-cells = <1>;
    #size-cells = <0>;

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };

    channel@4 {
        reg = <4>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,resolution = <12>;
    };
};


================================================
FILE: app/boards/zephyr/teensy41_mimxrt1062/partitions.overlay
================================================
&w25q64jvxgim {
    partitions {
        compatible = "fixed-partitions";
        #address-cells = <1>;
        #size-cells = <1>;

        boot_partition: partition@0 {
            label = "boot";
            reg = <0x00000000 0x00020000>;
            read-only;
        };

        code_partition: partition@20000 {
            label = "code-partition";
            reg = <0x00020000 0x007c8000>;
            read-only;
        };

        factory_partition: partition@7e8000 {
            label = "factory";
            reg = <0x007e8000 0x00008000>;
        };

        emueeprom_page1_partition: partition@7f0000 {
            label = "emueeprom-page1";
            reg = <0x007f0000 0x00008000>;
        };

        emueeprom_page2_partition: partition@7f8000 {
            label = "emueeprom-page2";
            reg = <0x007f8000 0x00008000>;
        };
    };
};

&flexram {
    /delete-node/ ocram@20280000;

    ocram: ocram@20200000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x20200000 DT_SIZE_K(252)>;
        zephyr,memory-region = "OCRAM";
    };
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@2023f000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x2023f000 DT_SIZE_K(4)>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/teensy41_mimxrt1062/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpio1: gpio1 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpio2: gpio2 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpio3: gpio3 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpio4: gpio4 {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    adc1: adc1 {
        compatible = "zephyr,adc-emul";
        nchannels = <16>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    adc2: adc2 {
        compatible = "zephyr,adc-emul";
        nchannels = <16>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    lpuart4: lpuart4 {
        compatible = "zephyr,uart-emul";
        current-speed = <115200>;
        status = "okay";
    };

    lpi2c4: lpi2c4@500 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x500 4>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x00020000>;
        };

        code_partition: partition@20000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00020000 0x007c8000>;
        };

        factory_partition: partition@7e8000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x007e8000 0x00008000>;
        };

        emueeprom_page1_partition: partition@7f0000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x007f0000 0x00008000>;
        };

        emueeprom_page2_partition: partition@7f8000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x007f8000 0x00008000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/weact_stm32f405_core_stm32f405xx/bootloader.conf
================================================


================================================
FILE: app/boards/zephyr/weact_stm32f405_core_stm32f405xx/bootloader.overlay
================================================
/ {
    chosen {
        zephyr,code-partition = &boot_partition;
    };
};


================================================
FILE: app/boards/zephyr/weact_stm32f405_core_stm32f405xx/firmware.conf
================================================
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=16384


================================================
FILE: app/boards/zephyr/weact_stm32f405_core_stm32f405xx/firmware.overlay
================================================
/ {
    usb_midi: usb_midi {
        compatible = "zephyr,midi2-device";
        status = "okay";
        #address-cells = <1>;
        #size-cells = <1>;

        midi_in_out@0 {
            reg = <0 1>;
            protocol = "midi1-up-to-128b";
        };
    };
};

&usart1 {
    current-speed = <115200>;
    pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
    pinctrl-names = "default";
    status = "okay";
};

&i2c1 {
    clock-frequency = <I2C_BITRATE_FAST>;
    pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>;
    pinctrl-names = "default";
    status = "okay";
};

&adc1 {
    pinctrl-0 = <&adc1_in0_pa0
                 &adc1_in1_pa1
                 &adc1_in2_pa2
                 &adc1_in3_pa3
                 &adc1_in4_pa4
                 &adc1_in5_pa5
                 &adc1_in6_pa6
                 &adc1_in7_pa7
                 &adc1_in8_pb0
                 &adc1_in9_pb1
                 &adc1_in10_pc0
                 &adc1_in11_pc1
                 &adc1_in12_pc2
                 &adc1_in13_pc3
                 &adc1_in14_pc4
                 &adc1_in15_pc5>;
    pinctrl-names = "default";
    st,adc-prescaler = <4>;
    status = "okay";

    #address-cells = <1>;
    #size-cells = <0>;

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@1 {
        reg = <1>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@2 {
        reg = <2>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@3 {
        reg = <3>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@4 {
        reg = <4>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@5 {
        reg = <5>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@6 {
        reg = <6>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@7 {
        reg = <7>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@8 {
        reg = <8>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@9 {
        reg = <9>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@a {
        reg = <10>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@b {
        reg = <11>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@c {
        reg = <12>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@d {
        reg = <13>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@e {
        reg = <14>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };

    channel@f {
        reg = <15>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS, 112)>;
        zephyr,resolution = <12>;
    };
};

&{/leds} {
    status = "disabled";
};

&{/gpio_keys} {
    status = "disabled";
};


================================================
FILE: app/boards/zephyr/weact_stm32f405_core_stm32f405xx/partitions.overlay
================================================
&flash0 {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges = <0x0 0x08000000 0x00100000>;

    partitions {
        compatible = "fixed-partitions";
        ranges;
        #address-cells = <1>;
        #size-cells = <1>;

        /delete-node/ partition@0;
        /delete-node/ partition@8000;

        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x00010000>;
            read-only;
        };

        code_partition: partition@10000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x00010000 0x00050000>;
            read-only;
        };

        emueeprom_page1_partition: partition@60000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page1";
            reg = <0x00060000 0x00020000>;
        };

        emueeprom_page2_partition: partition@80000 {
            compatible = "zephyr,mapped-partition";
            label = "emueeprom-page2";
            reg = <0x00080000 0x00020000>;
        };

        factory_partition: partition@a0000 {
            compatible = "zephyr,mapped-partition";
            label = "factory";
            reg = <0x000a0000 0x00020000>;
            read-only;
        };
    };
};

&sram0 {
    reg = <0x20000000 DT_SIZE_K(124)>;
};

/ {
    chosen {
        zephyr,code-partition = &code_partition;
    };

    opendeck_retained_mem: memory@2001f000 {
        compatible = "zephyr,memory-region", "mmio-sram";
        reg = <0x2001f000 DT_SIZE_K(4)>;
        zephyr,memory-region = "RetainedMem";
        status = "okay";

        retainedmem {
            compatible = "zephyr,retained-ram";
            status = "okay";
            #address-cells = <1>;
            #size-cells = <1>;

            opendeck_retained: boot_mode@0 {
                compatible = "zephyr,retention";
                status = "okay";
                reg = <0x0 0x100>;
                prefix = [00 53 43];
                checksum = <1>;
            };
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/boards/zephyr/weact_stm32f405_core_stm32f405xx/test.overlay
================================================
/ {
    opendeck_retained: opendeck-retained {
    };

    gpioa: gpioa {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpiob: gpiob {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpioc: gpioc {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    gpiod: gpiod {
        compatible = "zephyr,gpio-emul";
        rising-edge;
        falling-edge;
        high-level;
        low-level;
        gpio-controller;
        #gpio-cells = <2>;
        status = "okay";
    };

    adc1: adc1 {
        compatible = "zephyr,adc-emul";
        nchannels = <16>;
        #io-channel-cells = <1>;
        status = "okay";
    };

    usart1: usart1 {
        compatible = "zephyr,uart-emul";
        current-speed = <115200>;
        status = "okay";
    };

    i2c1: i2c1@500 {
        compatible = "zephyr,i2c-emul-controller";
        #address-cells = <1>;
        #size-cells = <0>;
        #forward-cells = <1>;
        clock-frequency = <100000>;
        reg = <0x500 4>;
        status = "okay";
    };
};

&flash0 {
    partitions {
        boot_partition: partition@0 {
            compatible = "zephyr,mapped-partition";
            label = "boot";
            reg = <0x00000000 0x0000c000>;
        };

        code_partition: partition@c000 {
            compatible = "zephyr,mapped-partition";
            label = "code-partition";
            reg = <0x0000c000 0x00069000>;
        };
    };
};

opendeck_partition_boot: &boot_partition {};

opendeck_partition_app: &code_partition {};


================================================
FILE: app/bootloader/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.27.0)
list(APPEND DTS_ROOT ${CMAKE_CURRENT_LIST_DIR}/..)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(opendeck_bootloader)

add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common/metadata ${CMAKE_CURRENT_BINARY_DIR}/metadata)
add_subdirectory(src/fw_selector)
add_subdirectory(src/indicators)
add_subdirectory(src/updater)

target_include_directories(app
    PRIVATE
    ${CMAKE_CURRENT_LIST_DIR}/src
    ${CMAKE_CURRENT_LIST_DIR}/src/fw_selector
    ${CMAKE_CURRENT_LIST_DIR}/src/indicators
    ${CMAKE_CURRENT_LIST_DIR}/src/updater
    ${CMAKE_CURRENT_LIST_DIR}/src/webusb
    ${CMAKE_CURRENT_LIST_DIR}/../common
    ${CMAKE_CURRENT_LIST_DIR}/../firmware/src
)

target_link_libraries(app
    PRIVATE
    metadata
    opendeck_bootloader_fw_selector
    opendeck_bootloader_indicators
    opendeck_bootloader_updater
    zlibs-drivers-usb_hw
)

target_sources(app
    PRIVATE
    src/main.cpp
    src/webusb/transport.cpp
)


================================================
FILE: app/bootloader/bootloader.conf
================================================
# Zephyr
CONFIG_GPIO=y
CONFIG_USE_DT_CODE_PARTITION=y
CONFIG_POLL=y
CONFIG_USB_DEVICE_STACK_NEXT=y
CONFIG_NET_BUF=y
CONFIG_ASSERT=n
CONFIG_BOOT_BANNER=n
CONFIG_ERRNO=n
CONFIG_NO_RUNTIME_CHECKS=y
CONFIG_PRINTK=n
CONFIG_CONSOLE=n
CONFIG_SERIAL=n
CONFIG_UART_CONSOLE=n
CONFIG_UART_INTERRUPT_DRIVEN=n
CONFIG_PICOLIBC_IO_LONG_LONG=n

# zlibs
CONFIG_ZLIBS_DRIVERS_USB_20_EXTENSION_DESC=y
CONFIG_ZLIBS_DRIVERS_USB_PID=0x8474


================================================
FILE: app/bootloader/src/fw_selector/CMakeLists.txt
================================================
include($ENV{ZEPHYR_PROJECT}/cmake/opendeck_library.cmake)

opendeck_library_named(opendeck_bootloader_fw_selector)

target_sources(opendeck_bootloader_fw_selector PRIVATE
    fw_selector.cpp
)

target_include_directories(opendeck_bootloader_fw_selector
    PRIVATE
    ${CMAKE_CURRENT_LIST_DIR}
    ${CMAKE_CURRENT_LIST_DIR}/../../src
    ${CMAKE_CURRENT_LIST_DIR}/../../../firmware/src
)


================================================
FILE: app/bootloader/src/fw_selector/common.h
================================================
/*
 * Copyright (c) 2026 Igor Petrovic
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#include <stdint.h>

namespace fw_selector
{
    /**
     * @brief Identifies which firmware image should be started.
     */
    enum class FwType : uint32_t
    {
        Application = 0xFFFFFFFF,
        Bootloader  = 0x47474747
    };

    /**
     * @brief Identifies why a particular firmware image was selected.
     */
    enum class Trigger : uint8_t
    {
        Software,
        Hardware,
        InvalidApp,
        None
    };

    /**
     * @brief Describes the firmware-selection outcome.
     */
    struct Selection
    {
        FwType  firmware = FwType::Bootloader;
        Trigger trigger  = Trigger::None;
    };
}    // namespace fw_selector


================================================
FILE: app/bootloader/src/fw_selector/deps.h
================================================
/*
 * Copyright (c) 2026 Igor Petrovic
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#include "common.h"

namespace fw_selector
{
    /**
     * @brief Hardware abstraction used to choose and load a firmware image.
     */
    class Hwa
    {
        public:
        virtual ~Hwa() = default;

        /**
         * @brief Returns whether the hardware boot trigger is active.
         *
         * @return `true` when a hardware trigger requests alternate firmware, otherwise `false`.
         */
        virtual bool is_hw_trigger_active() = 0;

        /**
         * @brief Returns whether the software boot trigger is active.
         *
         * @return `true` when a software trigger requests alternate firmware, otherwise `false`.
         */
        virtual bool is_sw_trigger_active() = 0;

        /**
         * @brief Returns whether the application image is valid.
         *
         * @return `true` when the application image can be started, otherwise `false`.
         */
        virtual bool is_app_valid() = 0;

        /**
         * @brief Transfers control to the selected firmware image.
         *
         * @param type Firmware image to load.
         */
        virtual void load(FwType type) = 0;
    };
}    // namespace fw_selector


================================================
FILE: app/bootloader/src/fw_selector/fw_selector.cpp
================================================
/*
 * Copyright (c) 2026 Igor Petrovic
 * SPDX-License-Identifier: Apache-2.0
 */

#include "fw_selector.h"

fw_selector::Selection fw_selector::FwSelector::select()
{
    Selection selection = {};

    if (_hwa.is_hw_trigger_active())
    {
        selection.firmware = FwType::Bootloader;
        selection.trigger  = Trigger::Hardware;

        return selection;
    }

    if (_hwa.is_sw_trigger_active())
    {
        selection.firmware = FwType::Bootloader;
        selection.trigger  = Trigger::Software;

        return selection;
    }

    if (_hwa.is_app_valid())
    {
        selection.firmware = FwType::Application;
        selection.trigger  = Trigger::None;

        return selection;
    }

    selection.firmware = FwType::Bootloader;
    selection.trigger  = Trigger::InvalidApp;

    return selection;
}


================================================
FILE: app/bootloader/src/fw_selector/fw_selector.h
================================================
/*
 * Copyright (c) 2026 Igor Petrovic
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#include "common.h"
#include "deps.h"

namespace fw_selector
{
    /**
     * @brief Chooses which firmware image should be started.
     */
    class FwSelector
    {
        public:
        /**
         * @brief Constructs the selector around one hardware-abstraction instance.
         *
         * @param hwa Hardware abstraction used to inspect triggers and image validity.
         */
        explicit FwSelector(Hwa& hwa)
            : _hwa(hwa)
        {}

        /**
         * @brief Selects the firmware image and trigger reason to use.
         *
         * @return Firmware-selection result.
         */
        Selection select();

        private:
        Hwa& _hwa;
    };
}    // namespace fw_selector


================================================
FILE: app/bootloader/src/fw_selector/hwa_hw.h
================================================
/*
 * Copyright (c) 2026 Igor Petrovic
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#include "fw_selector.h"
#include "retained/retained.h"

#include <zephyr/devicetree.h>
#include <zephyr/devicetree/fixed-partitions.h>
#include <zephyr/devicetree/partitions.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/storage/flash_map.h>

#include <cmsis_core.h>
#include <array>
#include <bit>
#include <cstdint>

#define OPENDECK_BOOTLOADER_NODE DT_NODELABEL(opendeck_bootloader)
#define BOOT_SLOT_NODE           DT_PHANDLE(OPENDECK_BOOTLOADER_NODE, boot_partition)
#define APP_SLOT_NODE            DT_PHANDLE(OPENDECK_BOOTLOADER_NODE, app_partition)
#define BOOT_SLOT_START          DT_PARTITION_ADDR(BOOT_SLOT_NODE)
#define APP_SLOT_START           DT_PARTITION_ADDR(APP_SLOT_NODE)
#define APP_SLOT_SIZE            DT_REG_SIZE(APP_SLOT_NODE)
#define APP_SLOT_END             (APP_SLOT_START + APP_SLOT_SIZE)
#define APP_VECTOR_TABLE_START   (APP_SLOT_START + CONFIG_ROM_START_OFFSET)
#define OPENDECK_SRAM_START      DT_REG_ADDR(DT_CHOSEN(zephyr_sram))
#define OPENDECK_SRAM_SIZE       DT_REG_SIZE(DT_CHOSEN(zephyr_sram))
#define OPENDECK_SRAM_END        (OPENDECK_SRAM_START + OPENDECK_SRAM_SIZE)

#if !DT_NODE_EXISTS(OPENDECK_BOOTLOADER_NODE)
#error "Node label 'opendeck_bootloader' is required for bootloader image."
#endif

#if !DT_NODE_HAS_PROP(OPENDECK_BOOTLOADER_NODE, app_partition)
#error "opendeck-bootloader must define app-partition."
#endif

#if !DT_NODE_EXISTS(APP_SLOT_NODE)
#error "opendeck-bootloader app-partition phandle must reference a valid fixed partition."
#endif

#if !DT_NODE_HAS_PROP(OPENDECK_BOOTLOADER_NODE, boot_partition)
#error "opendeck-bootloader must define boot-partition."
#endif

namespace fw_selector
{
    /**
     * @brief Hardware-backed firmware-selection backend.
     */
    class HwaHw : public Hwa
    {
        public:
        /**
         * @brief Delay applied before jumping to the application image.
         */
        static constexpr uint32_t APP_STARTUP_DELAY_MS = 20;

        /**
         * @brief Thumb-state bit required in Cortex-M reset vectors.
         */
        static constexpr uint32_t THUMB_BIT_MASK = 0x01;

        /**
         * @brief Constructs the hardware-backed firmware selector and validates the application image.
         */
        HwaHw()
        {
            _is_app_valid = init_app_info();
        }

        /**
         * @brief Returns whether the optional bootloader button is currently asserted.
         *
         * @return `true` when the hardware bootloader trigger is active, otherwise `false`.
         */
        bool is_hw_trigger_active() override
        {
#if !DT_NODE_HAS_PROP(OPENDECK_BOOTLOADER_NODE, button_gpios)
            return false;
#else
            if (!gpio_is_ready_dt(&_bootloader_button))
            {
                return false;
            }

            auto ret = gpio_pin_configure_dt(&_bootloader_button, GPIO_INPUT);

            if (ret != 0)
            {
                return false;
            }

            ret = gpio_pin_get_dt(&_bootloader_button);

            if (ret < 0)
            {
                return false;
            }

            return ret > 0;
#endif
        }

        /**
         * @brief Returns whether software requested a boot into the bootloader.
         *
         * @return `true` when the retained boot mode targets the bootloader, otherwise `false`.
         */
        bool is_sw_trigger_active() override
        {
            const bool bootloader_requested =
                retained::data.boot_mode.data() == static_cast<uint32_t>(FwType::Bootloader);

            retained::data.boot_mode.set(static_cast<uint32_t>(FwType::Application));

            return bootloader_requested;
        }

        /**
         * @brief Returns whether the application vector table passed validation.
         *
         * @return `true` if the application image can be jumped to, otherwise `false`.
         */
        bool is_app_valid() override
        {
            return _is_app_valid;
        }

        /**
         * @brief Transfers control to the selected firmware image when supported.
         *
         * @param type Firmware image to load.
         */
        void load(FwType type) override
        {
            switch (type)
            {
            case FwType::Application:
            {
                if (_is_app_valid)
                {
                    jump(_app_info.stack_pointer, _app_info.reset_vector);
                }
            }
            break;

            case FwType::Bootloader:
            default:
                break;
            }
        }

        private:
        /**
         * @brief Captures the application vector-table entry points used for validation and jumping.
         */
        struct AppInfo
        {
            uint32_t stack_pointer = 0;
            uint32_t reset_vector  = 0;
        };

        static constexpr uint32_t VALIDATION_SP_ALIGNMENT_BYTES = 4;

        /**
         * @brief Reads and validates the application vector table.
         *
         * @return `true` if the application stack pointer and reset vector are valid, otherwise `false`.
         */
        bool init_app_info()
        {
            static constexpr uint8_t APP_SLOT_AREA_ID = DT_PARTITION_ID(APP_SLOT_NODE);
            const struct flash_area* app_flash_area   = nullptr;
            std::array<uint32_t, 2>  vector_table     = {};

            if (flash_area_open(APP_SLOT_AREA_ID, &app_flash_area) != 0)
            {
                return false;
            }

            // Read the vector table through the flash-map API instead of
            // dereferencing a computed memory address. Some targets, such as
            // i.MX RT XIP images, place boot headers ahead of the actual
            // Cortex-M vector table, so read from the configured ROM start
            // offset within the application slot rather than assuming the
            // first bytes of the partition are SP/Reset.
            auto ret = flash_area_read(app_flash_area,
                                       CONFIG_ROM_START_OFFSET,
                                       vector_table.data(),
                                       sizeof(vector_table));
            flash_area_close(app_flash_area);

            if (ret != 0)
            {
                return false;
            }

            _app_info.stack_pointer = vector_table[0];
            _app_info.reset_vector  = vector_table[1];

            if (!is_aligned(_app_info.stack_pointer, VALIDATION_SP_ALIGNMENT_BYTES))
            {
                return false;
            }

            if (!is_in_range(_app_info.stack_pointer, OPENDECK_SRAM_START, OPENDECK_SRAM_END))
            {
                return false;
            }

            if ((_app_info.reset_vector & THUMB_BIT_MASK) == 0U)
            {
                return false;
            }

            if (!is_in_range(_app_info.reset_vector & ~THUMB_BIT_MASK, APP_SLOT_START, APP_SLOT_END))
            {
                return false;
            }

            return true;
        }

        /**
         * @brief Returns whether a value is aligned to the requested byte boundary.
         *
         * @param value Value to validate.
         * @param alignment Required byte alignment.
         *
         * @return `true` if `value` is aligned, otherwise `false`.
         */
        static bool is_aligned(uint32_t value, uint32_t alignment)
        {
            return (value % alignment) == 0U;
        }

        /**
         * @brief Returns whether a value falls within a half-open address range.
         *
         * @param value Address to validate.
         * @param start Inclusive range start.
         * @param end Exclusive range end.
         *
         * @return `true` if `value` is inside `[start, end)`, otherwise `false`.
         */
        static bool is_in_range(uint32_t value, uint32_t start, uint32_t end)
        {
            return (value >= start) && (value < end);
        }

        /**
         * @brief Transfers execution to the application image using a reset-like CPU handoff.
         *
         * This is a chain-load, not a hardware reset. The bootloader has already
         * executed Zephyr startup, enabled interrupts, configured SysTick and, on
         * some targets, enabled MPU and configurable fault handlers. Entering the
         * application with that state still active can make the app fault before
         * its own reset path has a chance to run.
         *
         * The sequence below therefore tries to leave the core in a state that is
         * as close as practical to power-on reset:
         * - stop periodic exception sources inherited from the bootloader
         * - clear pending IRQ and fault state
         * - drop bootloader-specific MPU/fault configuration
         * - restore privileged thread mode on MSP
         * - repoint VTOR at the application's vector table
         * - clear CPU interrupt masks before branching to the app reset handler
         *
         * @param stack_pointer Initial application stack pointer read from the
         *                      first word of the app vector table.
         * @param reset_vector Application reset handler address read from the
         *                     second word of the app vector table.
         */
        static void jump(uint32_t stack_pointer, uint32_t reset_vector)
        {
            using AppResetHandler = void (*)();

            auto                          reset_handler = std::bit_cast<AppResetHandler>(static_cast<uintptr_t>(reset_vector));
            [[maybe_unused]] unsigned int key;
            k_msleep(APP_STARTUP_DELAY_MS);

            // Stop Zephyr bootloader execution from scheduling anything else
            // while we dismantle its runtime state. We intentionally do not
            // call irq_unlock(key) later; interrupt masks are cleared manually
            // once the NVIC and system exception state is sanitized.
            key = irq_lock();
            __disable_irq();

            // SysTick continues running across a plain branch. Disable and
            // clear it so the application does not inherit a pending tick
            // interrupt that belongs to the bootloader's scheduling context.
            SysTick->CTRL = 0U;
            SysTick->LOAD = 0U;
            SysTick->VAL  = 0U;

            // Clear pending system exceptions and any sticky fault status
            // latched while the bootloader was active. All Cortex-M variants
            // have ICSR, but the more detailed fault status registers only
            // exist on ARMv7-M / ARMv8-M Mainline cores.
            SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk | SCB_ICSR_PENDSVCLR_Msk;    // ICSR  - Interrupt Control and State Register

#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
            SCB->CFSR = SCB->CFSR;    // CFSR  - Configurable Fault Status Register
            SCB->HFSR = SCB->HFSR;    // HFSR  - HardFault Status Register
            SCB->DFSR = SCB->DFSR;    // DFSR  - Debug Fault Status Register
#endif

            // NVIC ICER/ICPR are 32 IRQs per register, rounded up
            constexpr size_t   NVIC_REG_COUNT    = (CONFIG_NUM_IRQS + 31) / 32;
            constexpr uint32_t ALL_NVIC_IRQ_BITS = 0xFFFFFFFFU;

            // Disable every external interrupt source and drop any pending
            // state so enabling interrupts for the application cannot service
            // a stale bootloader IRQ.
            for (size_t i = 0; i < NVIC_REG_COUNT; i++)
            {
                NVIC->ICER[i] = ALL_NVIC_IRQ_BITS;    // ICER - Interrupt Clear-Enable Register
                NVIC->ICPR[i] = ALL_NVIC_IRQ_BITS;    // ICPR - Interrupt Clear-Pending Register
            }

            // Zephyr enables the MPU (Memory Protection Unit) and fault
            // handlers in the bootloader. The app expects to start from reset
            // state and will reconfigure them during its own startup.
#if defined(__MPU_PRESENT) && (__MPU_PRESENT == 1U)
            MPU->CTRL = 0U;
            __DSB();    // DSB - Data Synchronization Barrier: wait until the MPU disable write has taken effect
            __ISB();    // ISB - Instruction Synchronization Barrier: flush prefetched instructions so execution uses the updated MPU state
#endif

            // Disable configurable fault handlers that may have been enabled by
            // the bootloader. These handler-enable bits exist only on
            // ARMv7-M / ARMv8-M Mainline cores; ARMv6-M / v8-M Baseline do
            // not expose them.
#if defined(CONFI
Download .txt
gitextract_h4wb0_nf/

├── .codechecker.yml
├── .codex
├── .devcontainer/
│   ├── Dockerfile
│   └── devcontainer.json
├── .gitattributes
├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── .gitignore
├── .vscode/
│   ├── launch.json
│   ├── settings.json
│   └── tasks.json
├── LICENSE
├── Makefile
├── README.md
├── agents.md
├── app/
│   ├── CMakeLists.txt
│   ├── Kconfig
│   ├── boards/
│   │   ├── README.md
│   │   ├── opendeck/
│   │   │   ├── bergamot/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── blackpill411/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── discovery/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── dubfocus16t/
│   │   │   │   └── opendeck.overlay
│   │   │   ├── nrf52840dk/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── nrf54h20dk/
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck2/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck21/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck22/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── opendeck31/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── pico/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── pico2/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── rooibos/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── teensy4/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   ├── teensy41/
│   │   │   │   ├── firmware.overlay
│   │   │   │   └── opendeck.overlay
│   │   │   └── ws_core405r/
│   │   │       ├── firmware.overlay
│   │   │       └── opendeck.overlay
│   │   └── zephyr/
│   │       ├── blackpill_f411ce_stm32f411xe/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── nrf52840dk_nrf52840/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── nrf54h20dk_nrf54h20_cpuapp/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   ├── sysbuild.cmake
│   │       │   └── test.overlay
│   │       ├── rpi_pico2_rp2350a_m33/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── rpi_pico_rp2040/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── stm32f4_disco_stm32f407xx/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── teensy40_mimxrt1062/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       ├── teensy41_mimxrt1062/
│   │       │   ├── bootloader.conf
│   │       │   ├── bootloader.overlay
│   │       │   ├── firmware.conf
│   │       │   ├── firmware.overlay
│   │       │   ├── partitions.overlay
│   │       │   └── test.overlay
│   │       └── weact_stm32f405_core_stm32f405xx/
│   │           ├── bootloader.conf
│   │           ├── bootloader.overlay
│   │           ├── firmware.conf
│   │           ├── firmware.overlay
│   │           ├── partitions.overlay
│   │           └── test.overlay
│   ├── bootloader/
│   │   ├── CMakeLists.txt
│   │   ├── bootloader.conf
│   │   └── src/
│   │       ├── fw_selector/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── common.h
│   │       │   ├── deps.h
│   │       │   ├── fw_selector.cpp
│   │       │   ├── fw_selector.h
│   │       │   └── hwa_hw.h
│   │       ├── indicators/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── indicators.cpp
│   │       │   └── indicators.h
│   │       ├── main.cpp
│   │       ├── updater/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── builder.h
│   │       │   ├── builder_hw.h
│   │       │   ├── builder_test.h
│   │       │   ├── common.h
│   │       │   ├── deps.h
│   │       │   ├── hwa_hw.h
│   │       │   ├── hwa_test.h
│   │       │   ├── updater.cpp
│   │       │   └── updater.h
│   │       └── webusb/
│   │           ├── transport.cpp
│   │           └── transport.h
│   ├── common/
│   │   ├── metadata/
│   │   │   └── CMakeLists.txt
│   │   └── retained/
│   │       ├── common.h
│   │       └── retained.h
│   ├── common.conf
│   ├── debug.conf
│   ├── dts/
│   │   └── bindings/
│   │       ├── opendeck/
│   │       │   ├── opendeck-analog.yaml
│   │       │   ├── opendeck-bootloader.yaml
│   │       │   ├── opendeck-bulk-build.yaml
│   │       │   ├── opendeck-buttons.yaml
│   │       │   ├── opendeck-display-i2c.yaml
│   │       │   ├── opendeck-leds.yaml
│   │       │   ├── opendeck-metadata.yaml
│   │       │   ├── opendeck-midi-indicators.yaml
│   │       │   ├── opendeck-midi-uart.yaml
│   │       │   ├── opendeck-tests.yaml
│   │       │   └── opendeck-touchscreen.yaml
│   │       └── vendor-prefixes.txt
│   ├── firmware/
│   │   ├── CMakeLists.txt
│   │   ├── Kconfig
│   │   ├── firmware.conf
│   │   └── src/
│   │       ├── Kconfig
│   │       ├── atomic_compat.cpp
│   │       ├── database/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── builder.h
│   │       │   ├── builder_hw.h
│   │       │   ├── builder_test.h
│   │       │   ├── config.h
│   │       │   ├── custom_init.cpp
│   │       │   ├── database.cpp
│   │       │   ├── database.h
│   │       │   ├── deps.h
│   │       │   ├── hwa_hw.h
│   │       │   ├── hwa_test.h
│   │       │   └── layout.h
│   │       ├── global/
│   │       │   ├── bpm.h
│   │       │   └── midi_program.h
│   │       ├── io/
│   │       │   ├── Kconfig
│   │       │   ├── analog/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── analog.cpp
│   │       │   │   ├── analog.h
│   │       │   │   ├── analog_stub.h
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── common.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── drivers/
│   │       │   │   │   ├── count.h
│   │       │   │   │   ├── driver.h
│   │       │   │   │   ├── driver_base.h
│   │       │   │   │   ├── multiplexer/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── multiplexer_driver.h
│   │       │   │   │   ├── mux_on_mux/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── mux_on_mux_driver.h
│   │       │   │   │   ├── native/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── native_driver.h
│   │       │   │   │   └── scan_driver_base.h
│   │       │   │   ├── filter_hw.h
│   │       │   │   ├── filter_stub.h
│   │       │   │   ├── filter_test.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   └── remap.h
│   │       │   ├── base.h
│   │       │   ├── common/
│   │       │   │   └── common.h
│   │       │   ├── digital/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── buttons/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── builder.h
│   │       │   │   │   ├── builder_hw.h
│   │       │   │   │   ├── builder_stub.h
│   │       │   │   │   ├── builder_test.h
│   │       │   │   │   ├── buttons.cpp
│   │       │   │   │   ├── buttons.h
│   │       │   │   │   ├── buttons_stub.h
│   │       │   │   │   ├── common.h
│   │       │   │   │   ├── deps.h
│   │       │   │   │   ├── filter_hw.h
│   │       │   │   │   ├── filter_stub.h
│   │       │   │   │   ├── filter_test.h
│   │       │   │   │   ├── hwa_hw.h
│   │       │   │   │   ├── hwa_stub.h
│   │       │   │   │   └── hwa_test.h
│   │       │   │   ├── digital.cpp
│   │       │   │   ├── digital.h
│   │       │   │   ├── drivers/
│   │       │   │   │   ├── count.h
│   │       │   │   │   ├── driver.h
│   │       │   │   │   ├── driver_base.h
│   │       │   │   │   ├── matrix_native_rows/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── matrix_native_rows_driver.h
│   │       │   │   │   ├── matrix_shift_register_rows/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── matrix_shift_register_rows_driver.h
│   │       │   │   │   ├── native/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── native_driver.h
│   │       │   │   │   └── shift_register/
│   │       │   │   │       ├── count.h
│   │       │   │   │       └── shift_register_driver.h
│   │       │   │   ├── encoders/
│   │       │   │   │   ├── CMakeLists.txt
│   │       │   │   │   ├── builder.h
│   │       │   │   │   ├── builder_hw.h
│   │       │   │   │   ├── builder_stub.h
│   │       │   │   │   ├── builder_test.h
│   │       │   │   │   ├── common.h
│   │       │   │   │   ├── deps.h
│   │       │   │   │   ├── encoders.cpp
│   │       │   │   │   ├── encoders.h
│   │       │   │   │   ├── encoders_stub.h
│   │       │   │   │   ├── filter_hw.h
│   │       │   │   │   ├── filter_stub.h
│   │       │   │   │   ├── filter_test.h
│   │       │   │   │   ├── hwa_hw.h
│   │       │   │   │   ├── hwa_stub.h
│   │       │   │   │   └── hwa_test.h
│   │       │   │   ├── frame_store.h
│   │       │   │   └── remap.h
│   │       │   ├── i2c/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   ├── i2c.cpp
│   │       │   │   ├── i2c.h
│   │       │   │   ├── i2c_stub.h
│   │       │   │   └── peripherals/
│   │       │   │       ├── builder.h
│   │       │   │       ├── builder_hw.h
│   │       │   │       └── display/
│   │       │   │           ├── common.h
│   │       │   │           ├── deps.h
│   │       │   │           ├── display.cpp
│   │       │   │           ├── display.h
│   │       │   │           ├── element.h
│   │       │   │           ├── elements.cpp
│   │       │   │           └── strings.h
│   │       │   ├── indicators/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── common.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   ├── indicators.cpp
│   │       │   │   └── indicators.h
│   │       │   ├── leds/
│   │       │   │   ├── CMakeLists.txt
│   │       │   │   ├── Kconfig
│   │       │   │   ├── builder.h
│   │       │   │   ├── builder_hw.h
│   │       │   │   ├── builder_stub.h
│   │       │   │   ├── builder_test.h
│   │       │   │   ├── common.h
│   │       │   │   ├── deps.h
│   │       │   │   ├── drivers/
│   │       │   │   │   ├── count.h
│   │       │   │   │   ├── driver.h
│   │       │   │   │   ├── driver_base.h
│   │       │   │   │   ├── matrix_native_rows/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── matrix_native_rows_driver.h
│   │       │   │   │   ├── max7219/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── max7219_driver.h
│   │       │   │   │   ├── native/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── native_driver.h
│   │       │   │   │   ├── shift_register/
│   │       │   │   │   │   ├── count.h
│   │       │   │   │   │   └── shift_register_driver.h
│   │       │   │   │   └── stub/
│   │       │   │   │       └── stub_driver.h
│   │       │   │   ├── hwa_hw.h
│   │       │   │   ├── hwa_stub.h
│   │       │   │   ├── hwa_test.h
│   │       │   │   ├── leds.cpp
│   │       │   │   ├── leds.h
│   │       │   │   ├── leds_stub.h
│   │       │   │   └── remap.h
│   │       │   └── touchscreen/
│   │       │       ├── CMakeLists.txt
│   │       │       ├── builder.h
│   │       │       ├── builder_hw.h
│   │       │       ├── builder_stub.h
│   │       │       ├── builder_test.h
│   │       │       ├── common.h
│   │       │       ├── count.h
│   │       │       ├── deps.h
│   │       │       ├── hwa_hw.h
│   │       │       ├── hwa_stub.h
│   │       │       ├── hwa_test.h
│   │       │       ├── models/
│   │       │       │   ├── builder.h
│   │       │       │   ├── builder_hw.h
│   │       │       │   └── nextion/
│   │       │       │       ├── nextion.cpp
│   │       │       │       └── nextion.h
│   │       │       ├── touchscreen.cpp
│   │       │       ├── touchscreen.h
│   │       │       └── touchscreen_stub.h
│   │       ├── main.cpp
│   │       ├── messaging/
│   │       │   └── messaging.h
│   │       ├── protocol/
│   │       │   ├── base.h
│   │       │   └── midi/
│   │       │       ├── CMakeLists.txt
│   │       │       ├── ble_service.cpp
│   │       │       ├── ble_service.h
│   │       │       ├── builder.h
│   │       │       ├── builder_hw.h
│   │       │       ├── builder_test.h
│   │       │       ├── common.h
│   │       │       ├── deps.h
│   │       │       ├── hwa_hw.h
│   │       │       ├── hwa_test.h
│   │       │       ├── midi.cpp
│   │       │       └── midi.h
│   │       ├── system/
│   │       │   ├── CMakeLists.txt
│   │       │   ├── builder.h
│   │       │   ├── builder_hw.h
│   │       │   ├── builder_test.h
│   │       │   ├── common.h
│   │       │   ├── config.h
│   │       │   ├── custom_ids.h
│   │       │   ├── deps.h
│   │       │   ├── hwa_hw.h
│   │       │   ├── hwa_test.h
│   │       │   ├── layout.h
│   │       │   ├── system.cpp
│   │       │   └── system.h
│   │       ├── threads.h
│   │       └── util/
│   │           ├── cinfo/
│   │           │   ├── CMakeLists.txt
│   │           │   ├── cinfo.cpp
│   │           │   └── cinfo.h
│   │           ├── configurable/
│   │           │   ├── CMakeLists.txt
│   │           │   ├── configurable.cpp
│   │           │   └── configurable.h
│   │           ├── conversion/
│   │           │   └── conversion.h
│   │           ├── incdec/
│   │           │   └── inc_dec.h
│   │           └── thread_sleep.h
│   ├── presets.yml
│   ├── release.conf
│   └── sysbuild.cmake
├── bin/
│   └── touchscreen/
│       └── design/
│           ├── corel/
│           │   ├── bergamot.cdr
│           │   └── cardamom.cdr
│           └── nextion-gui/
│               └── rooibos.hmi
├── cmake/
│   ├── bluetooth_device_name.conf.in
│   ├── dfu_bin.cmake
│   ├── helpers.cmake
│   ├── opendeck_library.cmake
│   ├── opendeck_test_suite.cmake
│   ├── opendeck_test_target.cmake
│   ├── usb_midi_label.overlay.in
│   └── usb_product.conf.in
├── sch/
│   ├── bergamot/
│   │   ├── MBO/
│   │   │   ├── MBO.brd
│   │   │   └── MBO.sch
│   │   ├── Pots/
│   │   │   ├── Pots.brd
│   │   │   └── Pots.sch
│   │   └── USB/
│   │       ├── USB.brd
│   │       └── USB.sch
│   ├── dmx/
│   │   └── DMX.sch
│   ├── dubfocus/
│   │   ├── 12sr/
│   │   │   ├── ButtonsLEDs/
│   │   │   │   ├── ButtonsLEDs.brd
│   │   │   │   └── ButtonsLEDs.sch
│   │   │   ├── MBO/
│   │   │   │   ├── MBO.brd
│   │   │   │   └── MBO.sch
│   │   │   ├── Pots/
│   │   │   │   ├── Pots.brd
│   │   │   │   └── Pots.sch
│   │   │   └── USB/
│   │   │       ├── USB.brd
│   │   │       └── USB.sch
│   │   ├── 16c/
│   │   │   ├── ButtonsLEDs/
│   │   │   │   ├── ButtonsLEDs.brd
│   │   │   │   └── ButtonsLEDs.sch
│   │   │   ├── MBO/
│   │   │   │   ├── MBO.brd
│   │   │   │   └── MBO.sch
│   │   │   ├── Pots/
│   │   │   │   ├── Pots.brd
│   │   │   │   └── Pots.sch
│   │   │   └── USB/
│   │   │       ├── USB.brd
│   │   │       └── USB.sch
│   │   └── 16t/
│   │       ├── ButtonsLEDs/
│   │       │   ├── Buttons.kicad_sch
│   │       │   ├── ButtonsLEDs.kicad_pcb
│   │       │   ├── ButtonsLEDs.kicad_pro
│   │       │   ├── ButtonsLEDs.kicad_sch
│   │       │   ├── LEDs.kicad_sch
│   │       │   └── prod/
│   │       │       ├── ButtonsLEDs-BOM.csv
│   │       │       ├── ButtonsLEDs-all-pos.csv
│   │       │       └── gerbers/
│   │       │           ├── ButtonsLEDs-B_Cu.gbl
│   │       │           ├── ButtonsLEDs-B_Mask.gbs
│   │       │           ├── ButtonsLEDs-B_Paste.gbp
│   │       │           ├── ButtonsLEDs-B_Silkscreen.gbo
│   │       │           ├── ButtonsLEDs-Edge_Cuts.gm1
│   │       │           ├── ButtonsLEDs-F_Cu.gtl
│   │       │           ├── ButtonsLEDs-F_Mask.gts
│   │       │           ├── ButtonsLEDs-F_Paste.gtp
│   │       │           ├── ButtonsLEDs-F_Silkscreen.gto
│   │       │           ├── ButtonsLEDs-NPTH-drl_map.gbr
│   │       │           ├── ButtonsLEDs-NPTH.drl
│   │       │           ├── ButtonsLEDs-PTH-drl_map.gbr
│   │       │           └── ButtonsLEDs-PTH.drl
│   │       ├── MBO/
│   │       │   ├── Connections.kicad_sch
│   │       │   ├── MBO.kicad_dru
│   │       │   ├── MBO.kicad_pcb
│   │       │   ├── MBO.kicad_pro
│   │       │   ├── MBO.kicad_sch
│   │       │   ├── MCU.kicad_sch
│   │       │   ├── Pots.kicad_sch
│   │       │   ├── Power.kicad_sch
│   │       │   └── prod/
│   │       │       ├── MBO-BOM.csv
│   │       │       ├── MBO-all-pos.csv
│   │       │       └── gerbers/
│   │       │           ├── MBO-B_Cu.gbl
│   │       │           ├── MBO-B_Mask.gbs
│   │       │           ├── MBO-B_Paste.gbp
│   │       │           ├── MBO-B_Silkscreen.gbo
│   │       │           ├── MBO-Edge_Cuts.gm1
│   │       │           ├── MBO-F_Cu.gtl
│   │       │           ├── MBO-F_Mask.gts
│   │       │           ├── MBO-F_Paste.gtp
│   │       │           ├── MBO-F_Silkscreen.gto
│   │       │           ├── MBO-NPTH-drl_map.gbr
│   │       │           ├── MBO-NPTH.drl
│   │       │           ├── MBO-PTH-drl_map.gbr
│   │       │           └── MBO-PTH.drl
│   │       ├── Pots/
│   │       │   ├── Mux.kicad_sch
│   │       │   ├── Pots.kicad_pcb
│   │       │   ├── Pots.kicad_pro
│   │       │   ├── Pots.kicad_sch
│   │       │   └── prod/
│   │       │       ├── Pots-BOM.csv
│   │       │       ├── Pots-all-pos.csv
│   │       │       └── gerbers/
│   │       │           ├── Pots-B_Cu.gbl
│   │       │           ├── Pots-B_Mask.gbs
│   │       │           ├── Pots-B_Paste.gbp
│   │       │           ├── Pots-B_Silkscreen.gbo
│   │       │           ├── Pots-Edge_Cuts.gm1
│   │       │           ├── Pots-F_Cu.gtl
│   │       │           ├── Pots-F_Mask.gts
│   │       │           ├── Pots-F_Paste.gtp
│   │       │           ├── Pots-F_Silkscreen.gto
│   │       │           ├── Pots-NPTH-drl_map.gbr
│   │       │           ├── Pots-NPTH.drl
│   │       │           ├── Pots-PTH-drl_map.gbr
│   │       │           └── Pots-PTH.drl
│   │       └── USB/
│   │           ├── USB.kicad_pcb
│   │           ├── USB.kicad_pro
│   │           ├── USB.kicad_sch
│   │           └── prod/
│   │               ├── USB-BOM.csv
│   │               ├── USB-all-pos.csv
│   │               └── gerbers/
│   │                   ├── USB-B_Cu.gbl
│   │                   ├── USB-B_Mask.gbs
│   │                   ├── USB-B_Paste.gbp
│   │                   ├── USB-B_Silkscreen.gbo
│   │                   ├── USB-Edge_Cuts.gm1
│   │                   ├── USB-F_Cu.gtl
│   │                   ├── USB-F_Mask.gts
│   │                   ├── USB-F_Paste.gtp
│   │                   ├── USB-F_Silkscreen.gto
│   │                   ├── USB-NPTH-drl_map.gbr
│   │                   ├── USB-NPTH.drl
│   │                   ├── USB-PTH-drl_map.gbr
│   │                   └── USB-PTH.drl
│   ├── opendeck/
│   │   ├── v1.2.2/
│   │   │   ├── OpenDeck-r1.2.2-BOM.csv
│   │   │   ├── OpenDeck-r1.2.2.brd
│   │   │   └── OpenDeck-r1.2.2.sch
│   │   ├── v2.0.1/
│   │   │   ├── OpenDeck-r2.0.1-BOM.csv
│   │   │   ├── OpenDeck-r2.0.1.brd
│   │   │   └── OpenDeck-r2.0.1.sch
│   │   ├── v2.1.0/
│   │   │   ├── OpenDeck-r2.1.0.brd
│   │   │   ├── OpenDeck-r2.1.0.sch
│   │   │   └── prod/
│   │   │       ├── OpenDeck-r2.1.0-BOM.csv
│   │   │       ├── OpenDeck-r2.1.0-top-pos.csv
│   │   │       └── gerbers/
│   │   │           ├── OpenDeck-r2.1.0.GBL
│   │   │           ├── OpenDeck-r2.1.0.GBO
│   │   │           ├── OpenDeck-r2.1.0.GBS
│   │   │           ├── OpenDeck-r2.1.0.GKO
│   │   │           ├── OpenDeck-r2.1.0.GTL
│   │   │           ├── OpenDeck-r2.1.0.GTO
│   │   │           ├── OpenDeck-r2.1.0.GTS
│   │   │           └── OpenDeck-r2.1.0.TXT
│   │   ├── v2.2.1/
│   │   │   ├── Analog.kicad_sch
│   │   │   ├── Buttons.kicad_sch
│   │   │   ├── DIN_MIDI.kicad_sch
│   │   │   ├── Indicators.kicad_sch
│   │   │   ├── LEDs.kicad_sch
│   │   │   ├── OpenDeck-r2.2.1.kicad_pcb
│   │   │   ├── OpenDeck-r2.2.1.kicad_pro
│   │   │   ├── OpenDeck-r2.2.1.kicad_sch
│   │   │   └── prod/
│   │   │       ├── OpenDeck-r2.2.1-BOM.csv
│   │   │       ├── OpenDeck-r2.2.1-top-pos.csv
│   │   │       └── gerbers/
│   │   │           ├── OpenDeck-r2.2.1-B_Cu.gbl
│   │   │           ├── OpenDeck-r2.2.1-B_Mask.gbs
│   │   │           ├── OpenDeck-r2.2.1-B_Paste.gbp
│   │   │           ├── OpenDeck-r2.2.1-B_Silkscreen.gbo
│   │   │           ├── OpenDeck-r2.2.1-Edge_Cuts.gm1
│   │   │           ├── OpenDeck-r2.2.1-F_Cu.gtl
│   │   │           ├── OpenDeck-r2.2.1-F_Mask.gts
│   │   │           ├── OpenDeck-r2.2.1-F_Paste.gtp
│   │   │           ├── OpenDeck-r2.2.1-F_Silkscreen.gto
│   │   │           ├── OpenDeck-r2.2.1-NPTH-drl_map.gbr
│   │   │           ├── OpenDeck-r2.2.1-NPTH.drl
│   │   │           ├── OpenDeck-r2.2.1-PTH-drl_map.gbr
│   │   │           └── OpenDeck-r2.2.1-PTH.drl
│   │   ├── v3.0.1/
│   │   │   ├── Analog.kicad_sch
│   │   │   ├── Analog_Multiplexer.kicad_sch
│   │   │   ├── Buttons.kicad_sch
│   │   │   ├── Buttons_Rows.kicad_sch
│   │   │   ├── DIN_MIDI.kicad_sch
│   │   │   ├── DMX.kicad_sch
│   │   │   ├── Indicators.kicad_sch
│   │   │   ├── LEDs.kicad_sch
│   │   │   ├── OpenDeck-r3.0.1.kicad_pcb
│   │   │   ├── OpenDeck-r3.0.1.kicad_pro
│   │   │   ├── OpenDeck-r3.0.1.kicad_sch
│   │   │   ├── Touchscreen.kicad_sch
│   │   │   └── prod/
│   │   │       ├── OpenDeck-r3.0.1-BOM.csv
│   │   │       ├── OpenDeck-r3.0.1-top-pos.csv
│   │   │       └── gerbers/
│   │   │           ├── OpenDeck-r3.0.1-B_Cu.gbl
│   │   │           ├── OpenDeck-r3.0.1-B_Mask.gbs
│   │   │           ├── OpenDeck-r3.0.1-B_Paste.gbp
│   │   │           ├── OpenDeck-r3.0.1-B_Silkscreen.gbo
│   │   │           ├── OpenDeck-r3.0.1-Edge_Cuts.gm1
│   │   │           ├── OpenDeck-r3.0.1-F_Cu.gtl
│   │   │           ├── OpenDeck-r3.0.1-F_Mask.gts
│   │   │           ├── OpenDeck-r3.0.1-F_Paste.gtp
│   │   │           ├── OpenDeck-r3.0.1-F_Silkscreen.gto
│   │   │           ├── OpenDeck-r3.0.1-NPTH-drl_map.gbr
│   │   │           ├── OpenDeck-r3.0.1-NPTH.drl
│   │   │           ├── OpenDeck-r3.0.1-PTH-drl_map.gbr
│   │   │           └── OpenDeck-r3.0.1-PTH.drl
│   │   └── v3.1.x/
│   │       ├── Analog.kicad_sch
│   │       ├── Analog_Multiplexer.kicad_sch
│   │       ├── Buttons.kicad_sch
│   │       ├── Buttons_Rows.kicad_sch
│   │       ├── DIN_MIDI.kicad_sch
│   │       ├── DMX.kicad_sch
│   │       ├── Indicators.kicad_sch
│   │       ├── LEDs.kicad_sch
│   │       ├── OpenDeck-r3.1.2.kicad_pcb
│   │       ├── OpenDeck-r3.1.2.kicad_pro
│   │       ├── OpenDeck-r3.1.2.kicad_sch
│   │       ├── Touchscreen.kicad_sch
│   │       └── prod/
│   │           ├── OpenDeck-r3.1.2-BOM.csv
│   │           ├── OpenDeck-r3.1.2-top-pos.csv
│   │           └── gerbers/
│   │               ├── OpenDeck-r3.1.2-B_Cu.gbl
│   │               ├── OpenDeck-r3.1.2-B_Mask.gbs
│   │               ├── OpenDeck-r3.1.2-B_Paste.gbp
│   │               ├── OpenDeck-r3.1.2-B_Silkscreen.gbo
│   │               ├── OpenDeck-r3.1.2-Edge_Cuts.gm1
│   │               ├── OpenDeck-r3.1.2-F_Cu.gtl
│   │               ├── OpenDeck-r3.1.2-F_Mask.gts
│   │               ├── OpenDeck-r3.1.2-F_Paste.gtp
│   │               ├── OpenDeck-r3.1.2-F_Silkscreen.gto
│   │               ├── OpenDeck-r3.1.2-NPTH-drl_map.gbr
│   │               ├── OpenDeck-r3.1.2-NPTH.drl
│   │               ├── OpenDeck-r3.1.2-PTH-drl_map.gbr
│   │               ├── OpenDeck-r3.1.2-PTH.drl
│   │               └── OpenDeck-r3.1.2-bottom-pos.csv
│   ├── opendeck_mini/
│   │   ├── opendeck_mini.brd
│   │   └── opendeck_mini.sch
│   └── rooibos/
│       ├── MBO/
│       │   ├── MBO.brd
│       │   └── MBO.sch
│       ├── Pots/
│       │   ├── Pots.brd
│       │   └── Pots.sch
│       ├── SingleFader/
│       │   ├── SingleFader.brd
│       │   └── SingleFader.sch
│       └── USB/
│           ├── USBboard.brd
│           └── USBboard.sch
├── scripts/
│   ├── bulk_build.sh
│   ├── code_format.sh
│   ├── copy_release_binaries.sh
│   ├── gen/
│   │   └── gen_fw_uid.sh
│   └── query_test_metadata.sh
├── tests/
│   ├── global.conf
│   ├── include/
│   │   └── tests/
│   │       ├── common.h
│   │       └── helpers/
│   │           ├── database.h
│   │           ├── midi.h
│   │           └── misc.h
│   └── src/
│       ├── bootloader/
│       │   ├── CMakeLists.txt
│       │   ├── Kconfig
│       │   ├── bootloader_test.cpp
│       │   ├── prj.conf
│       │   └── testcase.yaml
│       ├── database/
│       │   ├── CMakeLists.txt
│       │   ├── Kconfig
│       │   ├── database_test.cpp
│       │   ├── prj.conf
│       │   └── testcase.yaml
│       ├── hw/
│       │   ├── CMakeLists.txt
│       │   ├── Kconfig
│       │   ├── hw_test.cpp
│       │   ├── prj.conf
│       │   └── testcase.yaml
│       ├── io/
│       │   ├── analog/
│       │   │   ├── CMakeLists.txt
│       │   │   ├── Kconfig
│       │   │   ├── analog_test.cpp
│       │   │   ├── prj.conf
│       │   │   └── testcase.yaml
│       │   ├── analog_filter/
│       │   │   ├── CMakeLists.txt
│       │   │   ├── Kconfig
│       │   │   ├── analog_filter_test.cpp
│       │   │   ├── prj.conf
│       │   │   └── testcase.yaml
│       │   ├── digital/
│       │   │   ├── CMakeLists.txt
│       │   │   ├── Kconfig
│       │   │   ├── digital_buttons_test.cpp
│       │   │   ├── digital_encoders_test.cpp
│       │   │   ├── prj.conf
│       │   │   └── testcase.yaml
│       │   └── leds/
│       │       ├── CMakeLists.txt
│       │       ├── Kconfig
│       │       ├── leds_test.cpp
│       │       ├── prj.conf
│       │       └── testcase.yaml
│       ├── protocol/
│       │   └── midi/
│       │       ├── CMakeLists.txt
│       │       ├── Kconfig
│       │       ├── midi_test.cpp
│       │       ├── prj.conf
│       │       └── testcase.yaml
│       └── system/
│           ├── CMakeLists.txt
│           ├── Kconfig
│           ├── prj.conf
│           ├── system_test.cpp
│           └── testcase.yaml
├── west.yml
└── zephyr/
    └── patch/
        ├── README.md
        └── zephyr/
            ├── adc_rp2xx0_01_polled_read.patch
            ├── adc_rp2xx0_02_configurable_clkdiv.patch
            ├── adc_stm32_polled_read.patch
            ├── blackpill411_dfu_util_with_sysbuild.patch
            ├── dfu_util_reset_cap.patch
            ├── teensy_loader_reset_cap.patch
            ├── usb_midi2_01_configurable_buffer_size.patch
            ├── usb_midi2_02_ump_burst.patch
            └── west_runner_handle_no_flash_load_offset.patch
Download .txt
SYMBOL INDEX (488 symbols across 188 files)

FILE: app/bootloader/src/fw_selector/common.h
  type class (line 15) | enum class
  function Trigger (line 24) | enum class Trigger : uint8_t

FILE: app/bootloader/src/fw_selector/deps.h
  function namespace (line 10) | namespace fw_selector

FILE: app/bootloader/src/fw_selector/fw_selector.h
  function namespace (line 11) | namespace fw_selector

FILE: app/bootloader/src/fw_selector/hwa_hw.h
  function namespace (line 51) | namespace fw_selector

FILE: app/bootloader/src/indicators/indicators.cpp
  function blink_handler (line 23) | void blink_handler()

FILE: app/bootloader/src/indicators/indicators.h
  function namespace (line 8) | namespace indicators

FILE: app/bootloader/src/main.cpp
  function main (line 20) | int main()

FILE: app/bootloader/src/updater/builder_hw.h
  function namespace (line 11) | namespace updater

FILE: app/bootloader/src/updater/builder_test.h
  function namespace (line 11) | namespace updater

FILE: app/bootloader/src/updater/common.h
  function namespace (line 10) | namespace updater

FILE: app/bootloader/src/updater/deps.h
  function namespace (line 11) | namespace updater

FILE: app/bootloader/src/updater/hwa_hw.h
  function namespace (line 26) | namespace updater

FILE: app/bootloader/src/updater/hwa_test.h
  function namespace (line 13) | namespace updater

FILE: app/bootloader/src/updater/updater.h
  type class (line 42) | enum class
  function ProcessStatus (line 54) | enum class ProcessStatus : uint8_t

FILE: app/bootloader/src/webusb/transport.cpp
  function cleanup_callback (line 43) | void cleanup_callback()
  type UsbBosWebusbDesc (line 50) | struct UsbBosWebusbDesc
  function webusb_to_host_cb (line 108) | static int webusb_to_host_cb(const usbd_context* const,
  type FunctionDesc (line 154) | struct FunctionDesc
  type FunctionData (line 164) | struct FunctionData
  type k_work (line 246) | struct k_work
  function flush_status_queue (line 250) | void flush_status_queue(struct k_work*)
  function clear_status_queue (line 292) | void clear_status_queue()
  function bulk_out_ep (line 301) | uint8_t bulk_out_ep(usbd_class_data* const class_data)
  function bulk_in_ep (line 313) | uint8_t bulk_in_ep(usbd_class_data* const class_data)
  function net_buf (line 325) | net_buf* buffer_alloc(usbd_class_data* const class_data)
  function request_handler (line 342) | int request_handler(usbd_class_data* class_data, net_buf* buffer, int err)
  function enable (line 393) | void enable(usbd_class_data* const class_data)
  function disable (line 421) | void disable(usbd_class_data* const)
  function init_class (line 430) | int init_class(usbd_class_data*)
  function usb_msg_cb (line 445) | void usb_msg_cb(usbd_context* const context, const usbd_msg* const message)

FILE: app/bootloader/src/webusb/transport.h
  function namespace (line 8) | namespace webusb

FILE: app/common/retained/common.h
  function namespace (line 17) | namespace retained

FILE: app/common/retained/retained.h
  function namespace (line 12) | namespace retained

FILE: app/firmware/src/atomic_compat.cpp
  function __atomic_exchange_1 (line 27) | uint8_t __atomic_exchange_1(volatile void*       target_ptr,

FILE: app/firmware/src/database/builder_hw.h
  function namespace (line 12) | namespace database

FILE: app/firmware/src/database/builder_test.h
  function namespace (line 12) | namespace database

FILE: app/firmware/src/database/config.h
  type class (line 33) | enum class
  type class (line 59) | enum class
  type class (line 68) | enum class
  type class (line 77) | enum class
  type class (line 90) | enum class
  type class (line 110) | enum class
  type class (line 127) | enum class
  function I2c (line 141) | enum class I2c : uint8_t

FILE: app/firmware/src/database/database.h
  function Config (line 219) | static constexpr Config::Block block([[maybe_unused]] Config::Section::G...
  function Config (line 231) | static constexpr Config::Block block([[maybe_unused]] Config::Section::B...
  function Config (line 243) | static constexpr Config::Block block([[maybe_unused]] Config::Section::E...
  function Config (line 255) | static constexpr Config::Block block([[maybe_unused]] Config::Section::A...
  function Config (line 267) | static constexpr Config::Block block([[maybe_unused]] Config::Section::L...
  function Config (line 279) | static constexpr Config::Block block([[maybe_unused]] Config::Section::I...
  function Config (line 291) | static constexpr Config::Block block([[maybe_unused]] Config::Section::T...
  type class (line 300) | enum class
  function signature (line 388) | uint16_t signature() const;

FILE: app/firmware/src/database/deps.h
  function namespace (line 10) | namespace database

FILE: app/firmware/src/database/hwa_hw.h
  function namespace (line 26) | namespace database

FILE: app/firmware/src/database/hwa_test.h
  function namespace (line 18) | namespace database

FILE: app/firmware/src/database/layout.h
  function override (line 34) | const override
  function override (line 44) | const override
  function common_layout_size (line 54) | constexpr uint32_t common_layout_size() const override
  function I2C_SECTIONS (line 320) | inline static constexpr auto I2C_SECTIONS = zlibs::utils::lessdb::make_b...

FILE: app/firmware/src/global/bpm.h
  function namespace (line 11) | namespace global

FILE: app/firmware/src/global/midi_program.h
  function namespace (line 11) | namespace global

FILE: app/firmware/src/io/analog/analog.h
  function namespace (line 19) | namespace io::analog

FILE: app/firmware/src/io/analog/analog_stub.h
  function namespace (line 11) | namespace io::analog

FILE: app/firmware/src/io/analog/builder_hw.h
  function namespace (line 14) | namespace io::analog

FILE: app/firmware/src/io/analog/builder_stub.h
  function namespace (line 13) | namespace io::analog

FILE: app/firmware/src/io/analog/builder_test.h
  function namespace (line 13) | namespace io::analog

FILE: app/firmware/src/io/analog/common.h
  function class (line 26) | class Collection : public io::common::BaseCollection<OPENDECK_ANALOG_LOG...
  type class (line 46) | enum class
  type class (line 63) | enum class
  type AdcConfig10Bit (line 92) | struct AdcConfig10Bit
  type AdcConfig12Bit (line 106) | struct AdcConfig12Bit
  function ADC_RESOLUTION_10_BIT (line 134) | struct AdcConfigFor<ADC_RESOLUTION_10_BIT>
  function ADC_RESOLUTION_12_BIT (line 140) | struct AdcConfigFor<ADC_RESOLUTION_12_BIT>

FILE: app/firmware/src/io/analog/deps.h
  function namespace (line 17) | namespace io::analog

FILE: app/firmware/src/io/analog/drivers/driver_base.h
  function namespace (line 15) | namespace io::analog

FILE: app/firmware/src/io/analog/drivers/multiplexer/multiplexer_driver.h
  function namespace (line 15) | namespace io::analog

FILE: app/firmware/src/io/analog/drivers/mux_on_mux/mux_on_mux_driver.h
  function namespace (line 13) | namespace io::analog

FILE: app/firmware/src/io/analog/drivers/native/native_driver.h
  function select_input (line 64) | void select_input(size_t index)
  function read_sample (line 76) | bool read_sample(uint16_t& sample)

FILE: app/firmware/src/io/analog/drivers/scan_driver_base.h
  function namespace (line 12) | namespace io::analog::drivers

FILE: app/firmware/src/io/analog/filter_hw.h
  function namespace (line 17) | namespace io::analog

FILE: app/firmware/src/io/analog/filter_stub.h
  function namespace (line 10) | namespace io::analog

FILE: app/firmware/src/io/analog/filter_test.h
  function namespace (line 10) | namespace io::analog

FILE: app/firmware/src/io/analog/hwa_hw.h
  function namespace (line 11) | namespace io::analog

FILE: app/firmware/src/io/analog/hwa_stub.h
  function namespace (line 10) | namespace io::analog

FILE: app/firmware/src/io/analog/hwa_test.h
  function namespace (line 15) | namespace io::analog

FILE: app/firmware/src/io/analog/remap.h
  function namespace (line 14) | namespace io::analog

FILE: app/firmware/src/io/base.h
  function namespace (line 15) | namespace io

FILE: app/firmware/src/io/common/common.h
  type BitStorageLocation (line 16) | struct BitStorageLocation
  function BitStorageLocation (line 31) | constexpr BitStorageLocation bit_storage_location(size_t index)
  type class (line 42) | enum class
  function groups (line 68) | static constexpr size_t groups()
  function size (line 78) | static constexpr size_t size()
  function size (line 90) | static constexpr size_t size(size_t group)
  function start_index (line 103) | static constexpr size_t start_index(size_t group)
  function class (line 119) | class Allocatable

FILE: app/firmware/src/io/digital/builder_hw.h
  function namespace (line 19) | namespace io::digital

FILE: app/firmware/src/io/digital/builder_stub.h
  function namespace (line 11) | namespace io::digital

FILE: app/firmware/src/io/digital/builder_test.h
  function namespace (line 13) | namespace io::digital

FILE: app/firmware/src/io/digital/buttons/builder_hw.h
  function namespace (line 14) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/builder_stub.h
  function namespace (line 13) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/builder_test.h
  function namespace (line 13) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/buttons.h
  function namespace (line 16) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/buttons_stub.h
  function namespace (line 11) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/common.h
  function namespace (line 13) | namespace io::buttons
  function Type (line 45) | enum class Type : uint8_t

FILE: app/firmware/src/io/digital/buttons/deps.h
  function namespace (line 14) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/filter_hw.h
  function namespace (line 10) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/filter_stub.h
  function namespace (line 10) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/filter_test.h
  function namespace (line 10) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/hwa_hw.h
  function namespace (line 11) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/hwa_stub.h
  function namespace (line 10) | namespace io::buttons

FILE: app/firmware/src/io/digital/buttons/hwa_test.h
  function namespace (line 12) | namespace io::buttons

FILE: app/firmware/src/io/digital/digital.h
  function namespace (line 15) | namespace io::digital

FILE: app/firmware/src/io/digital/drivers/driver.h
  function namespace (line 19) | namespace io::digital::drivers

FILE: app/firmware/src/io/digital/drivers/driver_base.h
  function namespace (line 15) | namespace io::digital::drivers

FILE: app/firmware/src/io/digital/drivers/matrix_native_rows/matrix_native_rows_driver.h
  function class (line 16) | class Driver : public DriverBase
  function button_to_encoder_index (line 74) | size_t button_to_encoder_index(size_t index) override
  function encoder_component_from_encoder (line 90) | size_t encoder_component_from_encoder(size_t index, EncoderComponent com...
  function init_columns (line 128) | bool init_columns()
  function select_column (line 160) | void select_column(size_t column)
  function Frame (line 177) | Frame scan()

FILE: app/firmware/src/io/digital/drivers/matrix_shift_register_rows/matrix_shift_register_rows_driver.h
  function button_to_encoder_index (line 73) | size_t button_to_encoder_index(size_t index) override
  function encoder_component_from_encoder (line 89) | size_t encoder_component_from_encoder(size_t index, EncoderComponent com...
  function init_columns (line 128) | bool init_columns()
  function select_column (line 160) | void select_column(size_t column)
  function Frame (line 177) | Frame scan()

FILE: app/firmware/src/io/digital/drivers/native/native_driver.h
  function button_to_encoder_index (line 71) | size_t button_to_encoder_index(size_t index) override
  function encoder_component_from_encoder (line 84) | size_t encoder_component_from_encoder(size_t index, EncoderComponent com...

FILE: app/firmware/src/io/digital/drivers/shift_register/shift_register_driver.h
  function namespace (line 11) | namespace io::digital::drivers

FILE: app/firmware/src/io/digital/encoders/builder_hw.h
  function namespace (line 14) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/builder_stub.h
  function namespace (line 14) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/builder_test.h
  function namespace (line 14) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/common.h
  function class (line 16) | class Collection : public io::common::BaseCollection<OPENDECK_ENCODER_CO...
  type class (line 28) | enum class
  type class (line 51) | enum class
  function Acceleration (line 61) | enum class Acceleration : uint8_t

FILE: app/firmware/src/io/digital/encoders/deps.h
  function namespace (line 15) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/encoders.cpp
  function Position (line 463) | Position Encoders::read(size_t index, uint8_t pair_state)

FILE: app/firmware/src/io/digital/encoders/encoders.h
  function namespace (line 17) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/encoders_stub.h
  function namespace (line 10) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/filter_hw.h
  function namespace (line 12) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/filter_stub.h
  function namespace (line 10) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/filter_test.h
  function namespace (line 10) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/hwa_hw.h
  function namespace (line 11) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/hwa_stub.h
  function namespace (line 10) | namespace io::encoders

FILE: app/firmware/src/io/digital/encoders/hwa_test.h
  function namespace (line 12) | namespace io::encoders

FILE: app/firmware/src/io/digital/frame_store.h
  function namespace (line 13) | namespace io::digital

FILE: app/firmware/src/io/digital/remap.h
  function namespace (line 14) | namespace io::digital

FILE: app/firmware/src/io/i2c/builder_hw.h
  function namespace (line 12) | namespace io::i2c

FILE: app/firmware/src/io/i2c/builder_stub.h
  function namespace (line 11) | namespace io::i2c

FILE: app/firmware/src/io/i2c/builder_test.h
  function namespace (line 12) | namespace io::i2c

FILE: app/firmware/src/io/i2c/deps.h
  function namespace (line 11) | namespace io::i2c

FILE: app/firmware/src/io/i2c/hwa_hw.h
  function namespace (line 14) | namespace io::i2c

FILE: app/firmware/src/io/i2c/hwa_stub.h
  function namespace (line 10) | namespace io::i2c

FILE: app/firmware/src/io/i2c/hwa_test.h
  function namespace (line 10) | namespace io::i2c

FILE: app/firmware/src/io/i2c/i2c.h
  function namespace (line 16) | namespace io::i2c

FILE: app/firmware/src/io/i2c/i2c_stub.h
  function namespace (line 11) | namespace io::i2c

FILE: app/firmware/src/io/i2c/peripherals/builder_hw.h
  function namespace (line 11) | namespace io::i2c

FILE: app/firmware/src/io/i2c/peripherals/display/common.h
  type class (line 15) | enum class
  function DisplayController (line 30) | enum class DisplayController : uint8_t

FILE: app/firmware/src/io/i2c/peripherals/display/deps.h
  function namespace (line 12) | namespace io::i2c::display

FILE: app/firmware/src/io/i2c/peripherals/display/display.h
  function namespace (line 19) | namespace io::i2c::display

FILE: app/firmware/src/io/i2c/peripherals/display/element.h
  function namespace (line 17) | namespace io::i2c::display

FILE: app/firmware/src/io/i2c/peripherals/display/strings.h
  function namespace (line 10) | namespace io::i2c::display

FILE: app/firmware/src/io/indicators/builder_hw.h
  function namespace (line 11) | namespace io::indicators

FILE: app/firmware/src/io/indicators/builder_stub.h
  function namespace (line 11) | namespace io::indicators

FILE: app/firmware/src/io/indicators/builder_test.h
  function namespace (line 11) | namespace io::indicators

FILE: app/firmware/src/io/indicators/common.h
  function namespace (line 10) | namespace io::indicators

FILE: app/firmware/src/io/indicators/deps.h
  function namespace (line 10) | namespace io::indicators

FILE: app/firmware/src/io/indicators/hwa_hw.h
  function namespace (line 13) | namespace io::indicators

FILE: app/firmware/src/io/indicators/hwa_stub.h
  function namespace (line 10) | namespace io::indicators

FILE: app/firmware/src/io/indicators/hwa_test.h
  function namespace (line 10) | namespace io::indicators

FILE: app/firmware/src/io/indicators/indicators.cpp
  function Type (line 160) | Type Indicators::indicator_type(messaging::MidiTransport transport, mess...

FILE: app/firmware/src/io/indicators/indicators.h
  function namespace (line 14) | namespace io::indicators

FILE: app/firmware/src/io/leds/builder_hw.h
  function namespace (line 13) | namespace io::leds

FILE: app/firmware/src/io/leds/builder_stub.h
  function namespace (line 12) | namespace io::leds

FILE: app/firmware/src/io/leds/builder_test.h
  function namespace (line 12) | namespace io::leds

FILE: app/firmware/src/io/leds/common.h
  type class (line 39) | enum class
  type class (line 49) | enum class
  type class (line 65) | enum class
  type class (line 77) | enum class
  type class (line 96) | enum class
  type class (line 107) | enum class
  function Brightness (line 116) | enum class Brightness : uint8_t

FILE: app/firmware/src/io/leds/deps.h
  function namespace (line 12) | namespace io::leds

FILE: app/firmware/src/io/leds/drivers/driver_base.h
  function namespace (line 13) | namespace io::leds

FILE: app/firmware/src/io/leds/drivers/matrix_native_rows/matrix_native_rows_driver.h
  function namespace (line 11) | namespace io::leds

FILE: app/firmware/src/io/leds/drivers/max7219/max7219_driver.h
  function namespace (line 17) | namespace io::leds

FILE: app/firmware/src/io/leds/drivers/native/native_driver.h
  function namespace (line 17) | namespace io::leds
  function update (line 42) | void update() override
  function set_state (line 52) | void set_state(size_t index, Brightness brightness) override
  function rgb_from_output (line 69) | size_t rgb_from_output(size_t index) override
  function rgb_component_from_rgb (line 83) | size_t rgb_component_from_rgb(size_t index, RgbComponent component) over...
  function rgb_led_count (line 98) | static constexpr size_t rgb_led_count()

FILE: app/firmware/src/io/leds/drivers/shift_register/shift_register_driver.h
  function namespace (line 17) | namespace io::leds

FILE: app/firmware/src/io/leds/drivers/stub/stub_driver.h
  function namespace (line 10) | namespace io::leds

FILE: app/firmware/src/io/leds/hwa_hw.h
  function namespace (line 12) | namespace io::leds

FILE: app/firmware/src/io/leds/hwa_stub.h
  function namespace (line 10) | namespace io::leds

FILE: app/firmware/src/io/leds/hwa_test.h
  function namespace (line 12) | namespace io::leds

FILE: app/firmware/src/io/leds/leds.cpp
  function Color (line 408) | Color Leds::value_to_color(uint8_t value)
  function BlinkSpeed (line 414) | BlinkSpeed Leds::value_to_blink_speed(uint8_t value)
  function Brightness (line 425) | Brightness Leds::value_to_brightness(uint8_t value)
  function BlinkSpeed (line 851) | BlinkSpeed Leds::blink_speed(uint8_t index)
  function Color (line 905) | Color Leds::color(uint8_t index)

FILE: app/firmware/src/io/leds/leds.h
  function init (line 51) | bool init() override;

FILE: app/firmware/src/io/leds/leds_stub.h
  function namespace (line 11) | namespace io::leds

FILE: app/firmware/src/io/leds/remap.h
  function namespace (line 14) | namespace io::leds

FILE: app/firmware/src/io/touchscreen/builder_hw.h
  function namespace (line 13) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/builder_stub.h
  function namespace (line 12) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/builder_test.h
  function namespace (line 12) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/common.h
  function class (line 16) | class Collection : public io::common::BaseCollection<OPENDECK_TOUCHSCREE...
  type class (line 28) | enum class
  type class (line 41) | enum class
  type class (line 50) | enum class
  type class (line 60) | enum class
  function ModelType (line 74) | enum class ModelType : uint8_t

FILE: app/firmware/src/io/touchscreen/deps.h
  function namespace (line 15) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/hwa_hw.h
  function namespace (line 24) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/hwa_stub.h
  function namespace (line 10) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/hwa_test.h
  function namespace (line 10) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/models/builder_hw.h
  function namespace (line 12) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/models/nextion/nextion.cpp
  function TsEvent (line 68) | TsEvent Nextion::update(Data& data)
  function TsEvent (line 145) | TsEvent Nextion::response(Data& data)

FILE: app/firmware/src/io/touchscreen/models/nextion/nextion.h
  function namespace (line 14) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/touchscreen.cpp
  function Model (line 360) | Model* Touchscreen::model_instance(ModelType model)

FILE: app/firmware/src/io/touchscreen/touchscreen.h
  function namespace (line 20) | namespace io::touchscreen

FILE: app/firmware/src/io/touchscreen/touchscreen_stub.h
  function namespace (line 10) | namespace io::touchscreen

FILE: app/firmware/src/main.cpp
  function main (line 16) | int main()

FILE: app/firmware/src/messaging/messaging.h
  function namespace (line 16) | namespace messaging

FILE: app/firmware/src/protocol/base.h
  function namespace (line 13) | namespace protocol

FILE: app/firmware/src/protocol/midi/ble_service.cpp
  function publish_ready_state (line 49) | void publish_ready_state()
  function midi_read_cb (line 67) | ssize_t midi_read_cb([[maybe_unused]] struct bt_conn*            conn,
  function midi_write_cb (line 76) | ssize_t midi_write_cb([[maybe_unused]] struct bt_conn*            conn,
  function midi_ccc_cfg_changed (line 94) | void midi_ccc_cfg_changed([[maybe_unused]] const struct bt_gatt_attr* at...
  function on_notify_done (line 114) | void on_notify_done([[maybe_unused]] struct bt_conn* conn, [[maybe_unuse...
  function on_mtu_changed (line 118) | void on_mtu_changed(struct bt_conn* conn, uint16_t mtu_size)
  function att_mtu_updated_cb (line 124) | void att_mtu_updated_cb(struct bt_conn* conn, uint16_t tx, uint16_t rx)
  function le_param_updated (line 130) | void le_param_updated(struct bt_conn* conn, uint16_t interval, uint16_t ...
  function on_connected (line 139) | void on_connected([[maybe_unused]] struct bt_conn* conn, uint8_t err)
  function on_disconnected (line 176) | void on_disconnected([[maybe_unused]] struct bt_conn* conn, [[maybe_unus...

FILE: app/firmware/src/protocol/midi/ble_service.h
  function namespace (line 10) | namespace protocol::midi::ble_service

FILE: app/firmware/src/protocol/midi/builder_hw.h
  function namespace (line 12) | namespace protocol::midi

FILE: app/firmware/src/protocol/midi/builder_test.h
  function namespace (line 12) | namespace protocol::midi

FILE: app/firmware/src/protocol/midi/common.h
  type UsbPacket (line 32) | struct UsbPacket
  type SerialPacket (line 40) | struct SerialPacket
  type class (line 48) | enum class
  type class (line 57) | enum class
  type Message (line 112) | struct Message
  function Note (line 146) | constexpr inline Note note_to_tonic(int8_t note)
  function note_to_octave (line 158) | constexpr inline uint8_t note_to_octave(int8_t note)
  function is_channel_message (line 170) | constexpr inline bool is_channel_message(MessageType type)
  function MessageType (line 198) | inline MessageType decode_type(const midi_ump& packet)
  function Message (line 238) | inline Message decode_message(const midi_ump& packet)
  function Setting (line 269) | enum class Setting : uint8_t

FILE: app/firmware/src/protocol/midi/deps.h
  function namespace (line 16) | namespace protocol::midi
  function class (line 117) | class HwaBle : public zlibs::utils::midi::ble::Hwa

FILE: app/firmware/src/protocol/midi/hwa_hw.h
  function namespace (line 41) | namespace protocol::midi

FILE: app/firmware/src/protocol/midi/hwa_test.h
  function namespace (line 12) | namespace protocol::midi
  function class (line 90) | class HwaUsbTest : public HwaUsb
  function class (line 214) | class HwaSerialTest : public HwaSerial
  function class (line 319) | class HwaBleTest : public HwaBle

FILE: app/firmware/src/protocol/midi/midi.cpp
  function to_zero_based_channel (line 28) | uint8_t to_zero_based_channel(uint8_t channel)

FILE: app/firmware/src/protocol/midi/midi.h
  function namespace (line 19) | namespace protocol::midi

FILE: app/firmware/src/system/builder_hw.h
  function namespace (line 19) | namespace sys

FILE: app/firmware/src/system/builder_test.h
  function namespace (line 19) | namespace sys

FILE: app/firmware/src/system/common.h
  function namespace (line 11) | namespace sys

FILE: app/firmware/src/system/config.h
  type class (line 43) | enum class
  type class (line 69) | enum class
  type class (line 80) | enum class
  type class (line 93) | enum class
  type class (line 114) | enum class
  type class (line 134) | enum class
  function I2c (line 150) | enum class I2c : uint8_t

FILE: app/firmware/src/system/deps.h
  function namespace (line 16) | namespace sys

FILE: app/firmware/src/system/hwa_hw.h
  function namespace (line 21) | namespace sys

FILE: app/firmware/src/system/hwa_test.h
  function namespace (line 18) | namespace sys

FILE: app/firmware/src/system/layout.h
  function sections (line 391) | constexpr size_t sections(size_t block) const

FILE: app/firmware/src/system/system.h
  type class (line 45) | enum class
  type class (line 55) | enum class
  type BackupSession (line 69) | struct BackupSession
  type ForcedRefreshSession (line 82) | struct ForcedRefreshSession
  function class (line 93) | class SysExDataHandler : public zlibs::utils::sysex_conf::DataHandler

FILE: app/firmware/src/threads.h
  function namespace (line 10) | namespace threads

FILE: app/firmware/src/util/cinfo/cinfo.h
  function namespace (line 12) | namespace util

FILE: app/firmware/src/util/configurable/configurable.h
  function namespace (line 13) | namespace util

FILE: app/firmware/src/util/conversion/conversion.h
  function namespace (line 13) | namespace util

FILE: app/firmware/src/util/incdec/inc_dec.h
  function namespace (line 13) | namespace util

FILE: app/firmware/src/util/thread_sleep.h
  function namespace (line 10) | namespace util

FILE: tests/include/tests/common.h
  function namespace (line 22) | namespace tests

FILE: tests/include/tests/helpers/database.h
  function namespace (line 10) | namespace tests

FILE: tests/include/tests/helpers/midi.h
  function namespace (line 34) | namespace test
  function capture_sysex_responses (line 314) | static bool capture_sysex_responses(const std::vector<uint8_t>&        r...
  function flush (line 384) | static void flush()
  function std (line 807) | static std::string send_midi_payload(const std::vector<uint8_t>& request)
  function std (line 832) | static std::string temporary_file_path(const std::string& tag)
  function std (line 844) | static std::string trim(const std::string& input)
  function std (line 864) | static std::string read_file(const std::string& path)
  function send_midi (line 885) | static bool send_midi(const std::string& payload)
  function stop_receive_midi (line 926) | static void stop_receive_midi(int pid)
  function wait_for_receive_midi_ready (line 941) | static bool wait_for_receive_midi_ready(const std::string& output_file)
  function std (line 968) | static std::vector<uint8_t> parse_receive_midi_output_line(const std::st...
  function std (line 1002) | static std::vector<std::vector<uint8_t>> parse_receive_midi_outputs(cons...
  function std (line 1024) | static std::vector<uint8_t> wait_for_receive_midi_response(const std::st...
  function std (line 1038) | static std::vector<uint8_t> wait_for_receive_midi_response(const std::st...

FILE: tests/include/tests/helpers/misc.h
  function namespace (line 17) | namespace test

FILE: tests/src/bootloader/bootloader_test.cpp
  function read_binary_file (line 19) | std::vector<uint8_t> read_binary_file(const char* path)
  type webusb (line 30) | namespace webusb
    function status (line 32) | void status(const char*)
  function TEST (line 37) | TEST(Bootloader, FwUpdate)

FILE: tests/src/database/database_test.cpp
  class CountingHandlers (line 20) | class CountingHandlers : public database::Handlers
    method preset_change (line 23) | void preset_change(uint8_t) override
    method factory_reset_start (line 26) | void factory_reset_start() override
    method factory_reset_done (line 31) | void factory_reset_done() override
    method initialized (line 36) | void initialized() override
  class DatabaseTest (line 46) | class DatabaseTest : public ::testing::Test
    method SetUp (line 49) | void SetUp() override
    method TearDown (line 56) | void TearDown() override
  function TEST_F (line 85) | TEST_F(DatabaseTest, ReadInitialValues)
  function TEST (line 433) | TEST(DatabaseRegressionTest, InitWithMissingFactorySnapshotFallsBackToFa...
  function TEST_F (line 454) | TEST_F(DatabaseTest, Presets)
  function TEST_F (line 494) | TEST_F(DatabaseTest, FactoryReset)
  function TEST_F (line 533) | TEST_F(DatabaseTest, LEDs)

FILE: tests/src/hw/hw_test.cpp
  class HWTest (line 38) | class HWTest : public ::testing::Test
    method SetUpTestSuite (line 41) | static void SetUpTestSuite()
    method TearDownTestSuite (line 47) | static void TearDownTestSuite()
    method SetUp (line 51) | void SetUp()
    method TearDown (line 63) | void TearDown()
    type PowerCycleType (line 89) | enum class PowerCycleType : uint8_t
    type SoftRebootType (line 96) | enum class SoftRebootType : uint8_t
    method handshake (line 103) | static bool handshake()
    method reboot (line 136) | void reboot(SoftRebootType type = SoftRebootType::Standard)
    method factory_reset (line 219) | void factory_reset()
    method bootloader (line 224) | void bootloader()
    method flash (line 229) | static bool flash()
  function TEST_F (line 281) | TEST_F(HWTest, DatabaseInitialValues)
  function TEST_F (line 464) | TEST_F(HWTest, BackupAndRestore)
  function TEST_F (line 643) | TEST_F(HWTest, USBMIDIData)

FILE: tests/src/io/analog/analog_test.cpp
  function make_frame (line 72) | analog::Frame make_frame(uint16_t value)
  class FakeScanDriver (line 79) | class FakeScanDriver : public analog::drivers::ScanDriverBase<FakeScanDr...
    method init_driver (line 84) | bool init_driver()
    method physical_input_count (line 89) | size_t physical_input_count() const
    method select_input (line 94) | void select_input(size_t index)
    method settle (line 100) | void settle() const
    method read_sample (line 104) | bool read_sample(uint16_t& sample)
  class MidiSignalCollector (line 123) | class MidiSignalCollector
    method push (line 126) | void push(const messaging::MidiSignal& signal)
    method clear (line 132) | void clear()
    method size (line 138) | size_t size() const
    method snapshot (line 144) | std::vector<messaging::MidiSignal> snapshot() const
  class AnalogTest (line 155) | class AnalogTest : public ::testing::Test
    method reset_analog (line 158) | void reset_analog(size_t index)
    method SetUp (line 169) | void SetUp() override
    method TearDown (line 213) | void TearDown() override
    method state_change_register (line 220) | void state_change_register(uint16_t value)
    method state_change_register (line 225) | void state_change_register(const std::vector<uint16_t>& values)
    method clear_messages (line 233) | void clear_messages()
    method wait_for_signals (line 240) | void wait_for_signals()
  function TEST (line 274) | TEST(AnalogDriverBufferTest, KeepsNewestEightFrames)
  function TEST (line 297) | TEST(AnalogDriverScanTest, PublishesFullFrames)
  function TEST_F (line 324) | TEST_F(AnalogTest, CC)
  function TEST_F (line 391) | TEST_F(AnalogTest, NRPN7bit)
  function TEST_F (line 419) | TEST_F(AnalogTest, NRPN14bit)
  function TEST_F (line 447) | TEST_F(AnalogTest, PitchBendTest)
  function TEST_F (line 503) | TEST_F(AnalogTest, Inversion)
  function TEST_F (line 599) | TEST_F(AnalogTest, Scaling)
  function TEST_F (line 684) | TEST_F(AnalogTest, ButtonForwarding)
  function TEST_F (line 757) | TEST_F(AnalogTest, DrainsMultipleQueuedFramesInSingleUpdate)
  function TEST_F (line 773) | TEST_F(AnalogTest, ForceRefreshUsesLastValueWithoutNewFrames)
  function TEST (line 796) | TEST(AnalogTest, SkippedWhenPresetDoesNotSupportAdc)

FILE: tests/src/io/analog_filter/analog_filter_test.cpp
  class AnalogFilterTest (line 26) | class AnalogFilterTest : public ::testing::Test
    method descriptor (line 43) | analog::Filter::Descriptor descriptor(uint16_t value,
    method button_descriptor (line 57) | analog::Filter::Descriptor button_descriptor(uint16_t value) const
    method fsr_descriptor (line 68) | analog::Filter::Descriptor fsr_descriptor(uint16_t value,
    method configured_lower_offset_raw (line 80) | uint16_t configured_lower_offset_raw(uint8_t percentage) const
    method configured_upper_offset_raw (line 93) | uint16_t configured_upper_offset_raw(uint8_t percentage) const
    method adc_value_for_output (line 106) | uint16_t adc_value_for_output(uint16_t output_value,
    method adc_value_for_fsr_output (line 143) | uint16_t adc_value_for_fsr_output(uint16_t output_value,
    method sample (line 176) | std::optional<uint16_t> sample(uint16_t value,
    method sample_button (line 191) | std::optional<uint16_t> sample_button(uint16_t value)
    method sample_fsr (line 203) | std::optional<uint16_t> sample_fsr(uint16_t value,
    method sample_sequence (line 216) | std::vector<uint16_t> sample_sequence(std::initializer_list<uint16_t> ...
    method sample_midi_sequence (line 233) | std::vector<uint16_t> sample_midi_sequence(std::initializer_list<uint1...
    method sample_timed_midi_sequence (line 250) | std::vector<uint16_t> sample_timed_midi_sequence(std::initializer_list...
    method sample_midi_repeated (line 272) | std::vector<uint16_t> sample_midi_repeated(uint16_t midi_value,
    method sample_midi_for (line 291) | std::vector<uint16_t> sample_midi_for(uint16_t midi_value,
    method prime (line 316) | uint16_t prime(uint16_t value        = MID_VALUE,
    method settle_to_raw (line 338) | uint16_t settle_to_raw(uint16_t value,
    method prime_midi (line 371) | uint16_t prime_midi(uint16_t value     = DEFAULT_MIDI_OUT,
    method prime_fsr_midi (line 402) | uint16_t prime_fsr_midi(uint16_t value     = DEFAULT_MIDI_OUT,
    method settle_to_midi (line 433) | uint16_t settle_to_midi(uint16_t value,
    method reset_filter (line 443) | void reset_filter()
  function TEST_F (line 452) | TEST_F(AnalogFilterTest, StableInputPublishesOnlyOnce)
  function TEST_F (line 459) | TEST_F(AnalogFilterTest, SubDeadbandSamplesAreSuppressed)
  function TEST_F (line 467) | TEST_F(AnalogFilterTest, LowerOffsetClampsToConfiguredLowerBound)
  function TEST_F (line 485) | TEST_F(AnalogFilterTest, UpperOffsetClampsToConfiguredUpperBound)
  function TEST_F (line 503) | TEST_F(AnalogFilterTest, ButtonPathUsesHysteresisAndEmitsOnTransitions)
  function TEST_F (line 521) | TEST_F(AnalogFilterTest, ButtonPathPublishesPressedStateOnStartup)
  function TEST_F (line 530) | TEST_F(AnalogFilterTest, IdlePotDriftRequiresRepeatConfirmation)
  function TEST_F (line 544) | TEST_F(AnalogFilterTest, FastModeRequiresRepeatedLargeDeltasToEnter)
  function TEST_F (line 556) | TEST_F(AnalogFilterTest, FastModeThresholdScalesWithOutputResolution)
  function TEST_F (line 575) | TEST_F(AnalogFilterTest, FastModeExpiresWhileContinuousIdleSamplesArrive)
  function TEST_F (line 591) | TEST_F(AnalogFilterTest, TimedIdleDriftTraceNeedsRepeatedIdleSamples)
  function TEST_F (line 612) | TEST_F(AnalogFilterTest, ActivePotMovementPublishesWithoutIdleRepeat)
  function TEST_F (line 622) | TEST_F(AnalogFilterTest, FsrIdleDriftRequiresRepeatConfirmation)
  function TEST_F (line 636) | TEST_F(AnalogFilterTest, ActiveFsrMovementPublishesWithoutIdleRepeat)

FILE: tests/src/io/digital/digital_buttons_test.cpp
  type TestEvent (line 23) | struct TestEvent
  class Listener (line 33) | class Listener
    method push (line 36) | void push(const messaging::MidiSignal& signal)
    method push (line 49) | void push(const messaging::SystemSignal& signal)
    method clear (line 63) | void clear()
    method size (line 69) | size_t size() const
    method TestEvent (line 75) | TestEvent at(size_t index) const
    method snapshot (line 81) | std::vector<TestEvent> snapshot() const
  class DigitalButtonsTest (line 94) | class DigitalButtonsTest : public ::testing::Test
    method SetUp (line 97) | void SetUp() override
    method TearDown (line 133) | void TearDown() override
    method state_change_register_all (line 140) | void state_change_register_all(bool state)
    method state_change_register_single (line 154) | void state_change_register_single(size_t index, bool state)
    method wait_for_signals (line 175) | void wait_for_signals()
    method digital_button_count (line 203) | static size_t digital_button_count()
  function TEST (line 216) | TEST(ButtonsBufferTest, PreservesOrderAndDrains)
  function TEST (line 246) | TEST(ButtonsBufferTest, OverwritesOldestUnreadSampleWhenFull)
  function TEST_F (line 267) | TEST_F(DigitalButtonsTest, Note)
  function TEST_F (line 351) | TEST_F(DigitalButtonsTest, ProgramChange)
  function TEST_F (line 588) | TEST_F(DigitalButtonsTest, ProgramChangeWithOffset)
  function TEST_F (line 703) | TEST_F(DigitalButtonsTest, ControlChange)
  function TEST_F (line 814) | TEST_F(DigitalButtonsTest, NoMessages)
  function TEST_F (line 854) | TEST_F(DigitalButtonsTest, PresetChange)
  function TEST_F (line 884) | TEST_F(DigitalButtonsTest, MMCStartStop)
  function TEST (line 915) | TEST(DigitalButtonsTest, SkippedWhenPresetDoesNotSupportButtons)

FILE: tests/src/io/digital/digital_encoders_test.cpp
  type TestEvent (line 20) | struct TestEvent
  class Listener (line 30) | class Listener
    method push (line 33) | void push(const messaging::MidiSignal& signal)
    method push (line 46) | void push(const messaging::SystemSignal& signal)
    method clear (line 55) | void clear()
    method size (line 61) | size_t size() const
    method TestEvent (line 67) | TestEvent at(size_t index) const
  class DigitalEncodersTest (line 80) | class DigitalEncodersTest : public ::testing::Test
    method SetUp (line 83) | void SetUp() override
    method TearDown (line 119) | void TearDown() override
    method state_change_register (line 126) | void state_change_register(uint8_t state)
    method wait_for_signals (line 141) | void wait_for_signals()
  function TEST_F (line 181) | TEST_F(DigitalEncodersTest, StateDecoding)
  function TEST_F (line 389) | TEST_F(DigitalEncodersTest, Messages)
  function TEST (line 480) | TEST(DigitalEncodersTest, SkippedWhenPresetDoesNotSupportEncoders)

FILE: tests/src/io/leds/leds_test.cpp
  class TouchscreenListener (line 20) | class TouchscreenListener
    method on_message (line 23) | void on_message(const messaging::TouchscreenLedSignal& event)
  class LEDsTest (line 31) | class LEDsTest : public ::testing::Test
    method SetUp (line 34) | void SetUp() override
    method TearDown (line 52) | void TearDown() override
    method wait_for_signal_dispatch (line 58) | void wait_for_signal_dispatch()
    method subscribe_touchscreen_listener (line 63) | void subscribe_touchscreen_listener()
    method wait_for_touchscreen_led_events (line 75) | void wait_for_touchscreen_led_events(size_t expected_count)
    method expected_brightness (line 93) | static leds::Brightness expected_brightness(uint8_t value)
    method expected_blink_speed (line 103) | static leds::BlinkSpeed expected_blink_speed(uint8_t value)
    method notify_midi_in (line 113) | void notify_midi_in(midi::MessageType message, uint8_t channel, uint16...
    method notify_local (line 158) | void notify_local(messaging::MidiSource source,
    method notify_program (line 176) | void notify_program(uint8_t channel, uint16_t program)
  function TEST_F (line 464) | TEST_F(LEDsTest, MultiValue)
  function TEST_F (line 613) | TEST_F(LEDsTest, SingleValue)
  function TEST_F (line 741) | TEST_F(LEDsTest, SingleLEDstate)
  function TEST_F (line 785) | TEST_F(LEDsTest, ProgramChangeWithOffset)
  function TEST_F (line 864) | TEST_F(LEDsTest, StaticLEDsOnInitially)
  function TEST_F (line 903) | TEST_F(LEDsTest, GlobalChannel)
  function TEST (line 961) | TEST(LedsTest, SkippedWhenPresetDoesNotSupportLeds)

FILE: tests/src/protocol/midi/midi_test.cpp
  class MIDITest (line 16) | class MIDITest : public ::testing::Test
    method SetUp (line 19) | void SetUp() override
    method TearDown (line 25) | void TearDown() override
    method wait_for_signal_dispatch (line 31) | void wait_for_signal_dispatch()
    method set_midi_setting (line 36) | uint8_t set_midi_setting(midi::Setting setting, uint16_t value)
  function TEST_F (line 51) | TEST_F(MIDITest, OmniChannel)
  function TEST_F (line 90) | TEST_F(MIDITest, BleEnabledSupportMatchesBuild)
  function TEST_F (line 103) | TEST_F(MIDITest, BleTxIsSkippedUntilReady)
  function TEST_F (line 128) | TEST_F(MIDITest, UsbThruBleSupportMatchesBuild)
  function TEST_F (line 148) | TEST_F(MIDITest, BleThruUsbSupportMatchesBuild)
  function TEST_F (line 174) | TEST_F(MIDITest, DinAndBleThruRoutesAreApplied)

FILE: tests/src/system/system_test.cpp
  class SystemTest (line 22) | class SystemTest : public ::testing::Test
    method SetUp (line 25) | void SetUp() override
    method TearDown (line 29) | void TearDown() override
    method supported_presets (line 40) | int supported_presets()
    method handshake (line 56) | void handshake()
  function TEST_F (line 69) | TEST_F(SystemTest, ForcedResendOnPresetChange)
  function TEST_F (line 149) | TEST_F(SystemTest, ProgramIndicatedOnStartup)
  function TEST_F (line 167) | TEST_F(SystemTest, UsbThruDin)
Copy disabled (too large) Download .json
Condensed preview — 654 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (44,107K chars).
[
  {
    "path": ".codechecker.yml",
    "chars": 4340,
    "preview": "analyzer:\n  - --enable=sensitive\n  - --enable=bugprone-use-after-move\n  - --enable=bugprone-dangling-handle\n  - --disabl"
  },
  {
    "path": ".codex",
    "chars": 0,
    "preview": ""
  },
  {
    "path": ".devcontainer/Dockerfile",
    "chars": 2078,
    "preview": "FROM ghcr.io/paradajz/zenv:aa66c31a11cb6ff9efa6a82c37c2cf6779a8f975\n\nARG jlink_version=V926\n\nRUN \\\necho '#!/bin/bash\\nec"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 919,
    "preview": "{\n    \"name\": \"${localWorkspaceFolderBasename}\",\n    \"build\": {\n        \"dockerfile\": \"Dockerfile\"\n    },\n    \"workspace"
  },
  {
    "path": ".gitattributes",
    "chars": 508,
    "preview": "#text files\n*.md    text\n*.x     text\n*.mk    text\n*.json  text\n*.c     text\n*.cpp   text\n*.h     text\n*.txt   text\n*.ma"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 2572,
    "preview": "name: CI\n\non:\n  push:\n    branches:\n      - '**'\n    tags-ignore:\n      - '**'\n\njobs:\n  build:\n    name: Build/Test\n    "
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1532,
    "preview": "name: Deploy\n\non:\n  release:\n    types: [created]\n\njobs:\n  build:\n    name: Attach firmware to release\n    runs-on: ubun"
  },
  {
    "path": ".gitignore",
    "chars": 155,
    "preview": "**/generated/*\n*-backups\n*-bak\n*.cortex-debug*\n*.kicad_prl\n*compile_commands.json\n*fp-info-cache\n.DS_Store\nbuild/\nccache"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 1307,
    "preview": "{\n    \"configurations\": [\n        {\n            \"name\": \"Test\",\n            \"type\": \"cppdbg\",\n            \"request\": \"la"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 945,
    "preview": "{\n    \"files.exclude\": {\n        \"bin/\": true,\n        \"**/ipch*\": true,\n        \"**/*cortex-debug*\": true,\n        \"**/"
  },
  {
    "path": ".vscode/tasks.json",
    "chars": 1657,
    "preview": "{\n    \"tasks\": [\n        {\n            \"label\": \"[Flash] [debug] nrf54h20\",\n            \"command\": \"make PRESET=nrf54h20"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Makefile",
    "chars": 1040,
    "preview": "include $(ZEPHYR_WS)/zenv/make/Makefile\n\nPROJECT_PRESETS_FILE := $(ZEPHYR_PROJECT)/app/presets.yml\nNON_TARGET_GOALS     "
  },
  {
    "path": "README.md",
    "chars": 4880,
    "preview": "# OpenDeck MIDI Platform\n\nOpenDeck is a platform for building MIDI controllers designed to solve two problems when build"
  },
  {
    "path": "agents.md",
    "chars": 2272,
    "preview": "# Session Helper\n\nThis repo is now fully Zephyr-based. Board support is split into:\n\n- `app/boards/zephyr/`\n- `app/board"
  },
  {
    "path": "app/CMakeLists.txt",
    "chars": 1434,
    "preview": "cmake_minimum_required(VERSION 3.27.0)\nlist(APPEND BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR})\nlist(APPEND DTS_ROOT ${CMAKE_"
  },
  {
    "path": "app/Kconfig",
    "chars": 187,
    "preview": "mainmenu \"Project-specific configuration\"\n\nmodule = OPENDECK\nmodule-str = OpenDeck\nsource \"subsys/logging/Kconfig.templa"
  },
  {
    "path": "app/boards/README.md",
    "chars": 8727,
    "preview": "# Boards\n\nOpenDeck board support is split into two layers:\n\n- `app/boards/opendeck/`\n- `app/boards/zephyr/`\n\nThey descri"
  },
  {
    "path": "app/boards/opendeck/bergamot/firmware.overlay",
    "chars": 39,
    "preview": "opendeck_uart_touchscreen: &usart1 {};\n"
  },
  {
    "path": "app/boards/opendeck/bergamot/opendeck.overlay",
    "chars": 1867,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"weact_s"
  },
  {
    "path": "app/boards/opendeck/blackpill411/firmware.overlay",
    "chars": 109,
    "preview": "opendeck_uart_din_midi: &usart1 {};\n\nopendeck_uart_touchscreen: &usart1 {};\n\nopendeck_i2c_display: &i2c1 {};\n"
  },
  {
    "path": "app/boards/opendeck/blackpill411/opendeck.overlay",
    "chars": 2798,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"blackpi"
  },
  {
    "path": "app/boards/opendeck/discovery/firmware.overlay",
    "chars": 109,
    "preview": "opendeck_uart_din_midi: &usart6 {};\n\nopendeck_uart_touchscreen: &usart6 {};\n\nopendeck_i2c_display: &i2c2 {};\n"
  },
  {
    "path": "app/boards/opendeck/discovery/opendeck.overlay",
    "chars": 3696,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"stm32f4"
  },
  {
    "path": "app/boards/opendeck/dubfocus16t/opendeck.overlay",
    "chars": 2378,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"weact_s"
  },
  {
    "path": "app/boards/opendeck/nrf52840dk/firmware.overlay",
    "chars": 107,
    "preview": "opendeck_uart_din_midi: &uart1 {};\n\nopendeck_uart_touchscreen: &uart1 {};\n\nopendeck_i2c_display: &i2c0 {};\n"
  },
  {
    "path": "app/boards/opendeck/nrf52840dk/opendeck.overlay",
    "chars": 3403,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"nrf5284"
  },
  {
    "path": "app/boards/opendeck/nrf54h20dk/opendeck.overlay",
    "chars": 2062,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"nrf54h2"
  },
  {
    "path": "app/boards/opendeck/opendeck2/firmware.overlay",
    "chars": 109,
    "preview": "opendeck_uart_din_midi: &usart1 {};\n\nopendeck_uart_touchscreen: &usart1 {};\n\nopendeck_i2c_display: &i2c1 {};\n"
  },
  {
    "path": "app/boards/opendeck/opendeck2/opendeck.overlay",
    "chars": 3696,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"weact_s"
  },
  {
    "path": "app/boards/opendeck/opendeck21/firmware.overlay",
    "chars": 109,
    "preview": "opendeck_uart_din_midi: &usart1 {};\n\nopendeck_uart_touchscreen: &usart1 {};\n\nopendeck_i2c_display: &i2c1 {};\n"
  },
  {
    "path": "app/boards/opendeck/opendeck21/opendeck.overlay",
    "chars": 3548,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"weact_s"
  },
  {
    "path": "app/boards/opendeck/opendeck22/firmware.overlay",
    "chars": 834,
    "preview": "#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>\n\n&pinctrl {\n    uart1_touchscreen_8_9: uart1_touchscreen"
  },
  {
    "path": "app/boards/opendeck/opendeck22/opendeck.overlay",
    "chars": 3350,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"rpi_pic"
  },
  {
    "path": "app/boards/opendeck/opendeck31/firmware.overlay",
    "chars": 475,
    "preview": "#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>\n\n&pinctrl {\n    i2c1_display_2_3: i2c1_display_2_3 {\n   "
  },
  {
    "path": "app/boards/opendeck/opendeck31/opendeck.overlay",
    "chars": 3922,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"rpi_pic"
  },
  {
    "path": "app/boards/opendeck/pico/firmware.overlay",
    "chars": 107,
    "preview": "opendeck_uart_din_midi: &uart0 {};\n\nopendeck_uart_touchscreen: &uart1 {};\n\nopendeck_i2c_display: &i2c0 {};\n"
  },
  {
    "path": "app/boards/opendeck/pico/opendeck.overlay",
    "chars": 2978,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"rpi_pic"
  },
  {
    "path": "app/boards/opendeck/pico2/firmware.overlay",
    "chars": 107,
    "preview": "opendeck_uart_din_midi: &uart0 {};\n\nopendeck_uart_touchscreen: &uart1 {};\n\nopendeck_i2c_display: &i2c0 {};\n"
  },
  {
    "path": "app/boards/opendeck/pico2/opendeck.overlay",
    "chars": 2856,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"rpi_pic"
  },
  {
    "path": "app/boards/opendeck/rooibos/firmware.overlay",
    "chars": 39,
    "preview": "opendeck_uart_touchscreen: &usart1 {};\n"
  },
  {
    "path": "app/boards/opendeck/rooibos/opendeck.overlay",
    "chars": 2027,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"weact_s"
  },
  {
    "path": "app/boards/opendeck/teensy4/firmware.overlay",
    "chars": 243,
    "preview": "opendeck_uart_din_midi: &lpuart4 {};       /* Teensy pins 8 (TX4) / 7 (RX4) */\n\nopendeck_uart_touchscreen: &lpuart4 {}; "
  },
  {
    "path": "app/boards/opendeck/teensy4/opendeck.overlay",
    "chars": 3724,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"teensy4"
  },
  {
    "path": "app/boards/opendeck/teensy41/firmware.overlay",
    "chars": 243,
    "preview": "opendeck_uart_din_midi: &lpuart4 {};       /* Teensy pins 8 (TX4) / 7 (RX4) */\n\nopendeck_uart_touchscreen: &lpuart4 {}; "
  },
  {
    "path": "app/boards/opendeck/teensy41/opendeck.overlay",
    "chars": 3724,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"teensy4"
  },
  {
    "path": "app/boards/opendeck/ws_core405r/firmware.overlay",
    "chars": 109,
    "preview": "opendeck_uart_din_midi: &usart1 {};\n\nopendeck_uart_touchscreen: &usart1 {};\n\nopendeck_i2c_display: &i2c1 {};\n"
  },
  {
    "path": "app/boards/opendeck/ws_core405r/opendeck.overlay",
    "chars": 3168,
    "preview": "/ {\n    opendeck_metadata: opendeck-metadata {\n        compatible = \"opendeck,metadata\";\n        zephyr-board = \"weact_s"
  },
  {
    "path": "app/boards/zephyr/blackpill_f411ce_stm32f411xe/bootloader.conf",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/boards/zephyr/blackpill_f411ce_stm32f411xe/bootloader.overlay",
    "chars": 163,
    "preview": "/ {\n    chosen {\n        /delete-property/ zephyr,console;\n        /delete-property/ zephyr,shell-uart;\n        zephyr,c"
  },
  {
    "path": "app/boards/zephyr/blackpill_f411ce_stm32f411xe/firmware.conf",
    "chars": 76,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=y\nCONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=16384\n"
  },
  {
    "path": "app/boards/zephyr/blackpill_f411ce_stm32f411xe/firmware.overlay",
    "chars": 3033,
    "preview": "/ {\n    chosen {\n        /delete-property/ zephyr,console;\n        /delete-property/ zephyr,shell-uart;\n    };\n\n    usb_"
  },
  {
    "path": "app/boards/zephyr/blackpill_f411ce_stm32f411xe/partitions.overlay",
    "chars": 2271,
    "preview": "&flash0 {\n    #address-cells = <1>;\n    #size-cells = <1>;\n    ranges = <0x0 0x08000000 0x00080000>;\n\n    partitions {\n "
  },
  {
    "path": "app/boards/zephyr/blackpill_f411ce_stm32f411xe/test.overlay",
    "chars": 1885,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpioa: gpioa {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/boards/zephyr/nrf52840dk_nrf52840/bootloader.conf",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "app/boards/zephyr/nrf52840dk_nrf52840/bootloader.overlay",
    "chars": 76,
    "preview": "/ {\n    chosen {\n        zephyr,code-partition = &boot_partition;\n    };\n};\n"
  },
  {
    "path": "app/boards/zephyr/nrf52840dk_nrf52840/firmware.conf",
    "chars": 153,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=y\nCONFIG_BT=y\nCONFIG_BT_PERIPHERAL=y\nCONFIG_BT_L2CAP_TX_MTU=247\nCONFIG_BT_BUF_ACL_TX_SIZE=2"
  },
  {
    "path": "app/boards/zephyr/nrf52840dk_nrf52840/firmware.overlay",
    "chars": 3000,
    "preview": "/ {\n    usb_midi: usb_midi {\n        compatible = \"zephyr,midi2-device\";\n        status = \"okay\";\n        #address-cells"
  },
  {
    "path": "app/boards/zephyr/nrf52840dk_nrf52840/partitions.overlay",
    "chars": 2109,
    "preview": "&flash0 {\n    partitions {\n        ranges;\n        /delete-node/ boot_partition;\n        /delete-node/ slot0_partition;\n"
  },
  {
    "path": "app/boards/zephyr/nrf52840dk_nrf52840/test.overlay",
    "chars": 1319,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpio1: gpio1 {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/bootloader.conf",
    "chars": 101,
    "preview": "CONFIG_POWEROFF=y\nCONFIG_NRF_FORCE_RAM_ON_REBOOT=y\nCONFIG_NRF_ENABLE_ICACHE=n\nCONFIG_NRF_RTC_TIMER=n\n"
  },
  {
    "path": "app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/bootloader.overlay",
    "chars": 83,
    "preview": "/ {\n    chosen {\n        zephyr,code-partition = &cpuapp_boot_partition;\n    };\n};\n"
  },
  {
    "path": "app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/firmware.conf",
    "chars": 163,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=y\n# CONFIG_BT=y\n# CONFIG_BT_PERIPHERAL=y\n# CONFIG_BT_L2CAP_TX_MTU=247\n# CONFIG_BT_BUF_ACL_T"
  },
  {
    "path": "app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/firmware.overlay",
    "chars": 2811,
    "preview": "/ {\n    usb_midi: usb_midi {\n        compatible = \"zephyr,midi2-device\";\n        status = \"okay\";\n        #address-cells"
  },
  {
    "path": "app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/partitions.overlay",
    "chars": 1755,
    "preview": "&cpuapp_boot_partition {\n    compatible = \"zephyr,mapped-partition\";\n    reg = <0x30000 DT_SIZE_K(96)>;\n};\n\n&mram1x {\n  "
  },
  {
    "path": "app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/sysbuild.cmake",
    "chars": 88,
    "preview": "set(uicr_EXTRA_DTC_OVERLAY_FILE ${opendeck_board_partitions_overlay} CACHE INTERNAL \"\")\n"
  },
  {
    "path": "app/boards/zephyr/nrf54h20dk_nrf54h20_cpuapp/test.overlay",
    "chars": 992,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    buttons {\n        compatible = \"gpio-keys\";\n        status = "
  },
  {
    "path": "app/boards/zephyr/rpi_pico2_rp2350a_m33/bootloader.conf",
    "chars": 91,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=n\nCONFIG_FLASH_LOAD_OFFSET=0x0\nCONFIG_FLASH_LOAD_SIZE=0x18000\n"
  },
  {
    "path": "app/boards/zephyr/rpi_pico2_rp2350a_m33/bootloader.overlay",
    "chars": 77,
    "preview": "&led0 {\n    status = \"disabled\";\n};\n\n&pwm_led0 {\n    status = \"disabled\";\n};\n"
  },
  {
    "path": "app/boards/zephyr/rpi_pico2_rp2350a_m33/firmware.conf",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/boards/zephyr/rpi_pico2_rp2350a_m33/firmware.overlay",
    "chars": 2058,
    "preview": "#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2350a-pinctrl.h>\n/ {\n    usb_midi: usb_midi {\n        compatible = \"zeph"
  },
  {
    "path": "app/boards/zephyr/rpi_pico2_rp2350a_m33/partitions.overlay",
    "chars": 2079,
    "preview": "&flash0 {\n    #address-cells = <1>;\n    #size-cells = <1>;\n    ranges = <0x0 0x10000000 DT_SIZE_M(4)>;\n\n    /delete-node"
  },
  {
    "path": "app/boards/zephyr/rpi_pico2_rp2350a_m33/test.overlay",
    "chars": 1170,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpio1: gpio1 {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/boards/zephyr/rpi_pico_rp2040/bootloader.conf",
    "chars": 299,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=n\n# RP2040 bootloader image placement must match `boot_partition` in\n# `partitions.overlay`"
  },
  {
    "path": "app/boards/zephyr/rpi_pico_rp2040/bootloader.overlay",
    "chars": 77,
    "preview": "&led0 {\n    status = \"disabled\";\n};\n\n&pwm_led0 {\n    status = \"disabled\";\n};\n"
  },
  {
    "path": "app/boards/zephyr/rpi_pico_rp2040/firmware.conf",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/boards/zephyr/rpi_pico_rp2040/firmware.overlay",
    "chars": 2057,
    "preview": "#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2040-pinctrl.h>\n/ {\n    usb_midi: usb_midi {\n        compatible = \"zephy"
  },
  {
    "path": "app/boards/zephyr/rpi_pico_rp2040/partitions.overlay",
    "chars": 2315,
    "preview": "&flash0 {\n    /delete-node/ partitions;\n\n    partitions {\n        compatible = \"fixed-partitions\";\n        ranges;\n     "
  },
  {
    "path": "app/boards/zephyr/rpi_pico_rp2040/test.overlay",
    "chars": 1170,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpio1: gpio1 {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/boards/zephyr/stm32f4_disco_stm32f407xx/bootloader.conf",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/boards/zephyr/stm32f4_disco_stm32f407xx/bootloader.overlay",
    "chars": 76,
    "preview": "/ {\n    chosen {\n        zephyr,code-partition = &boot_partition;\n    };\n};\n"
  },
  {
    "path": "app/boards/zephyr/stm32f4_disco_stm32f407xx/firmware.conf",
    "chars": 76,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=y\nCONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=16384\n"
  },
  {
    "path": "app/boards/zephyr/stm32f4_disco_stm32f407xx/firmware.overlay",
    "chars": 2581,
    "preview": "/ {\n    usb_midi: usb_midi {\n        compatible = \"zephyr,midi2-device\";\n        status = \"okay\";\n        #address-cells"
  },
  {
    "path": "app/boards/zephyr/stm32f4_disco_stm32f407xx/partitions.overlay",
    "chars": 2193,
    "preview": "&flash0 {\n    #address-cells = <1>;\n    #size-cells = <1>;\n    ranges = <0x0 0x08000000 0x00100000>;\n\n    partitions {\n "
  },
  {
    "path": "app/boards/zephyr/stm32f4_disco_stm32f407xx/test.overlay",
    "chars": 2210,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpioa: gpioa {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/boards/zephyr/teensy40_mimxrt1062/bootloader.conf",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "app/boards/zephyr/teensy40_mimxrt1062/bootloader.overlay",
    "chars": 76,
    "preview": "/ {\n    chosen {\n        zephyr,code-partition = &boot_partition;\n    };\n};\n"
  },
  {
    "path": "app/boards/zephyr/teensy40_mimxrt1062/firmware.conf",
    "chars": 76,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=y\nCONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=32768\n"
  },
  {
    "path": "app/boards/zephyr/teensy40_mimxrt1062/firmware.overlay",
    "chars": 3699,
    "preview": "#include <zephyr/dt-bindings/adc/adc.h>\n\n/ {\n    usb_midi: usb_midi {\n        compatible = \"zephyr,midi2-device\";\n      "
  },
  {
    "path": "app/boards/zephyr/teensy40_mimxrt1062/partitions.overlay",
    "chars": 1911,
    "preview": "&w25q16jvuxim {\n    partitions {\n        compatible = \"fixed-partitions\";\n        #address-cells = <1>;\n        #size-ce"
  },
  {
    "path": "app/boards/zephyr/teensy40_mimxrt1062/test.overlay",
    "chars": 2574,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpio1: gpio1 {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/boards/zephyr/teensy41_mimxrt1062/bootloader.conf",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "app/boards/zephyr/teensy41_mimxrt1062/bootloader.overlay",
    "chars": 76,
    "preview": "/ {\n    chosen {\n        zephyr,code-partition = &boot_partition;\n    };\n};\n"
  },
  {
    "path": "app/boards/zephyr/teensy41_mimxrt1062/firmware.conf",
    "chars": 76,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=y\nCONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=32768\n"
  },
  {
    "path": "app/boards/zephyr/teensy41_mimxrt1062/firmware.overlay",
    "chars": 5876,
    "preview": "#include <zephyr/dt-bindings/adc/adc.h>\n\n/ {\n    usb_midi: usb_midi {\n        compatible = \"zephyr,midi2-device\";\n      "
  },
  {
    "path": "app/boards/zephyr/teensy41_mimxrt1062/partitions.overlay",
    "chars": 1911,
    "preview": "&w25q64jvxgim {\n    partitions {\n        compatible = \"fixed-partitions\";\n        #address-cells = <1>;\n        #size-ce"
  },
  {
    "path": "app/boards/zephyr/teensy41_mimxrt1062/test.overlay",
    "chars": 2723,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpio1: gpio1 {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/boards/zephyr/weact_stm32f405_core_stm32f405xx/bootloader.conf",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "app/boards/zephyr/weact_stm32f405_core_stm32f405xx/bootloader.overlay",
    "chars": 76,
    "preview": "/ {\n    chosen {\n        zephyr,code-partition = &boot_partition;\n    };\n};\n"
  },
  {
    "path": "app/boards/zephyr/weact_stm32f405_core_stm32f405xx/firmware.conf",
    "chars": 76,
    "preview": "CONFIG_USE_DT_CODE_PARTITION=y\nCONFIG_ZLIBS_UTILS_EMUEEPROM_PAGE_SIZE=16384\n"
  },
  {
    "path": "app/boards/zephyr/weact_stm32f405_core_stm32f405xx/firmware.overlay",
    "chars": 5065,
    "preview": "/ {\n    usb_midi: usb_midi {\n        compatible = \"zephyr,midi2-device\";\n        status = \"okay\";\n        #address-cells"
  },
  {
    "path": "app/boards/zephyr/weact_stm32f405_core_stm32f405xx/partitions.overlay",
    "chars": 2193,
    "preview": "&flash0 {\n    #address-cells = <1>;\n    #size-cells = <1>;\n    ranges = <0x0 0x08000000 0x00100000>;\n\n    partitions {\n "
  },
  {
    "path": "app/boards/zephyr/weact_stm32f405_core_stm32f405xx/test.overlay",
    "chars": 1983,
    "preview": "/ {\n    opendeck_retained: opendeck-retained {\n    };\n\n    gpioa: gpioa {\n        compatible = \"zephyr,gpio-emul\";\n     "
  },
  {
    "path": "app/bootloader/CMakeLists.txt",
    "chars": 973,
    "preview": "cmake_minimum_required(VERSION 3.27.0)\nlist(APPEND DTS_ROOT ${CMAKE_CURRENT_LIST_DIR}/..)\nfind_package(Zephyr REQUIRED H"
  },
  {
    "path": "app/bootloader/bootloader.conf",
    "chars": 418,
    "preview": "# Zephyr\nCONFIG_GPIO=y\nCONFIG_USE_DT_CODE_PARTITION=y\nCONFIG_POLL=y\nCONFIG_USB_DEVICE_STACK_NEXT=y\nCONFIG_NET_BUF=y\nCONF"
  },
  {
    "path": "app/bootloader/src/fw_selector/CMakeLists.txt",
    "chars": 390,
    "preview": "include($ENV{ZEPHYR_PROJECT}/cmake/opendeck_library.cmake)\n\nopendeck_library_named(opendeck_bootloader_fw_selector)\n\ntar"
  },
  {
    "path": "app/bootloader/src/fw_selector/common.h",
    "chars": 765,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <stdint.h>\n\nna"
  },
  {
    "path": "app/bootloader/src/fw_selector/deps.h",
    "chars": 1276,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"common.h\"\n\nna"
  },
  {
    "path": "app/bootloader/src/fw_selector/fw_selector.cpp",
    "chars": 826,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include \"fw_selector.h\"\n\nfw_selector"
  },
  {
    "path": "app/bootloader/src/fw_selector/fw_selector.h",
    "chars": 817,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"common.h\"\n#in"
  },
  {
    "path": "app/bootloader/src/fw_selector/hwa_hw.h",
    "chars": 14926,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"fw_selector.h"
  },
  {
    "path": "app/bootloader/src/indicators/CMakeLists.txt",
    "chars": 386,
    "preview": "include($ENV{ZEPHYR_PROJECT}/cmake/opendeck_library.cmake)\n\nopendeck_library_named(opendeck_bootloader_indicators)\n\ntarg"
  },
  {
    "path": "app/bootloader/src/indicators/indicators.cpp",
    "chars": 1181,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include \"indicators.h\"\n\n#include \"io"
  },
  {
    "path": "app/bootloader/src/indicators/indicators.h",
    "chars": 197,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\nnamespace indicators\n{\n"
  },
  {
    "path": "app/bootloader/src/main.cpp",
    "chars": 1410,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include \"fw_selector/fw_selector.h\"\n"
  },
  {
    "path": "app/bootloader/src/updater/CMakeLists.txt",
    "chars": 473,
    "preview": "include($ENV{ZEPHYR_PROJECT}/cmake/opendeck_library.cmake)\n\nopendeck_library_named(opendeck_bootloader_updater)\n\ntarget_"
  },
  {
    "path": "app/bootloader/src/updater/builder.h",
    "chars": 197,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#ifdef OPENDECK_TEST\n#i"
  },
  {
    "path": "app/bootloader/src/updater/builder_hw.h",
    "chars": 915,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"hwa_hw.h\"\n#in"
  },
  {
    "path": "app/bootloader/src/updater/builder_test.h",
    "chars": 750,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"hwa_test.h\"\n#"
  },
  {
    "path": "app/bootloader/src/updater/common.h",
    "chars": 635,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <stdint.h>\n\nna"
  },
  {
    "path": "app/bootloader/src/updater/deps.h",
    "chars": 1960,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <stddef.h>\n#in"
  },
  {
    "path": "app/bootloader/src/updater/hwa_hw.h",
    "chars": 9680,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n#incl"
  },
  {
    "path": "app/bootloader/src/updater/hwa_test.h",
    "chars": 2600,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n\n#inc"
  },
  {
    "path": "app/bootloader/src/updater/updater.cpp",
    "chars": 5634,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include \"updater.h\"\n#include \"webusb"
  },
  {
    "path": "app/bootloader/src/updater/updater.h",
    "chars": 3946,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"common.h\"\n#in"
  },
  {
    "path": "app/bootloader/src/webusb/transport.cpp",
    "chars": 15194,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include \"transport.h\"\n\n#include \"upd"
  },
  {
    "path": "app/bootloader/src/webusb/transport.h",
    "chars": 1032,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\nnamespace webusb\n{\n    "
  },
  {
    "path": "app/common/metadata/CMakeLists.txt",
    "chars": 2342,
    "preview": "add_library(metadata INTERFACE)\n\nif(NOT DEFINED ENV{TARGET} OR \"$ENV{TARGET}\" STREQUAL \"\")\n    message(FATAL_ERROR \"Meta"
  },
  {
    "path": "app/common/retained/common.h",
    "chars": 2035,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <zephyr/device"
  },
  {
    "path": "app/common/retained/retained.h",
    "chars": 689,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"common.h\"\n\n#i"
  },
  {
    "path": "app/common.conf",
    "chars": 508,
    "preview": "# Zephyr\nCONFIG_CPP=y\nCONFIG_STD_CPP20=y\nCONFIG_REQUIRES_FULL_LIBCPP=y\nCONFIG_GLIBCXX_LIBCPP=y\nCONFIG_FLASH=y\nCONFIG_FLA"
  },
  {
    "path": "app/debug.conf",
    "chars": 298,
    "preview": "CONFIG_LOG=y\nCONFIG_BOOT_BANNER=y\nCONFIG_PRINTK=y\nCONFIG_CONSOLE=y\nCONFIG_UART_CONSOLE=y\nCONFIG_LOG_BACKEND_UART=y\nCONFI"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-analog.yaml",
    "chars": 2582,
    "preview": "description: OpenDeck analog input inventory and topology\n\ncompatible: \"opendeck,analog\"\n\nproperties:\n  disabled:\n    ty"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-bootloader.yaml",
    "chars": 627,
    "preview": "description: OpenDeck bootloader trigger configuration\n\ncompatible: \"opendeck,bootloader\"\n\nproperties:\n  disabled:\n    t"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-bulk-build.yaml",
    "chars": 650,
    "preview": "description: OpenDeck bulk helper script configuration\n\ncompatible: \"opendeck,bulk-build\"\n\nproperties:\n  app:\n    type: "
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-buttons.yaml",
    "chars": 2746,
    "preview": "description: OpenDeck button inventory and topology\n\ncompatible: \"opendeck,buttons\"\n\nproperties:\n  disabled:\n    type: b"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-display-i2c.yaml",
    "chars": 370,
    "preview": "description: OpenDeck display I2C configuration\n\ncompatible: \"opendeck,display-i2c\"\n\nproperties:\n  disabled:\n    type: b"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-leds.yaml",
    "chars": 1992,
    "preview": "description: OpenDeck LED inventory and topology\n\ncompatible: \"opendeck,leds\"\n\nproperties:\n  disabled:\n    type: boolean"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-metadata.yaml",
    "chars": 389,
    "preview": "description: OpenDeck target metadata\n\ncompatible: \"opendeck,metadata\"\n\nproperties:\n  zephyr-board:\n    type: string\n   "
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-midi-indicators.yaml",
    "chars": 1019,
    "preview": "description: OpenDeck MIDI traffic indicator LEDs\n\ncompatible: \"opendeck,midi-indicators\"\n\nproperties:\n  disabled:\n    t"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-midi-uart.yaml",
    "chars": 362,
    "preview": "description: OpenDeck DIN MIDI UART configuration\n\ncompatible: \"opendeck,midi-uart\"\n\nproperties:\n  disabled:\n    type: b"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-tests.yaml",
    "chars": 324,
    "preview": "description: OpenDeck test capability configuration\n\ncompatible: \"opendeck,tests\"\n\nproperties:\n  host:\n    type: boolean"
  },
  {
    "path": "app/dts/bindings/opendeck/opendeck-touchscreen.yaml",
    "chars": 524,
    "preview": "description: OpenDeck touchscreen inventory\n\ncompatible: \"opendeck,touchscreen\"\n\nproperties:\n  disabled:\n    type: boole"
  },
  {
    "path": "app/dts/bindings/vendor-prefixes.txt",
    "chars": 18,
    "preview": "opendeck\tOpenDeck\n"
  },
  {
    "path": "app/firmware/CMakeLists.txt",
    "chars": 893,
    "preview": "add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common/metadata ${CMAKE_CURRENT_BINARY_DIR}/metadata)\nadd_subdirectory(src"
  },
  {
    "path": "app/firmware/Kconfig",
    "chars": 10910,
    "preview": "OPENDECK_BUTTONS_NODE := $(dt_nodelabel_path,opendeck_buttons)\nOPENDECK_ANALOG_NODE := $(dt_nodelabel_path,opendeck_anal"
  },
  {
    "path": "app/firmware/firmware.conf",
    "chars": 734,
    "preview": "# Zephyr\nCONFIG_MPU_ALLOW_FLASH_WRITE=y\nCONFIG_ADC=y\nCONFIG_POLL=y\nCONFIG_I2C=y\nCONFIG_USBD_MIDI2_CLASS=y\nCONFIG_USBD_MI"
  },
  {
    "path": "app/firmware/src/Kconfig",
    "chars": 21,
    "preview": "rsource \"io/Kconfig\"\n"
  },
  {
    "path": "app/firmware/src/atomic_compat.cpp",
    "chars": 1350,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include <zephyr/irq.h>\n\n#include <cs"
  },
  {
    "path": "app/firmware/src/database/CMakeLists.txt",
    "chars": 429,
    "preview": "include($ENV{ZEPHYR_PROJECT}/cmake/opendeck_library.cmake)\nopendeck_library_named(database)\n\ntarget_include_directories("
  },
  {
    "path": "app/firmware/src/database/builder.h",
    "chars": 199,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#ifdef OPENDECK_TEST\n#i"
  },
  {
    "path": "app/firmware/src/database/builder_hw.h",
    "chars": 762,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"database.h\"\n#"
  },
  {
    "path": "app/firmware/src/database/builder_test.h",
    "chars": 721,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"database.h\"\n#"
  },
  {
    "path": "app/firmware/src/database/config.h",
    "chars": 4504,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <inttypes.h>\n#"
  },
  {
    "path": "app/firmware/src/database/custom_init.cpp",
    "chars": 1737,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include \"database/database.h\"\n#inclu"
  },
  {
    "path": "app/firmware/src/database/database.cpp",
    "chars": 10834,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#include \"util/conversion/conversion."
  },
  {
    "path": "app/firmware/src/database/database.h",
    "chars": 20633,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"config.h\"\n#in"
  },
  {
    "path": "app/firmware/src/database/deps.h",
    "chars": 3445,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"zlibs/utils/l"
  },
  {
    "path": "app/firmware/src/database/hwa_hw.h",
    "chars": 14467,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n#incl"
  },
  {
    "path": "app/firmware/src/database/hwa_test.h",
    "chars": 9417,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n\n#inc"
  },
  {
    "path": "app/firmware/src/database/layout.h",
    "chars": 15290,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n#incl"
  },
  {
    "path": "app/firmware/src/global/bpm.h",
    "chars": 3518,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"util/incdec/i"
  },
  {
    "path": "app/firmware/src/global/midi_program.h",
    "chars": 6568,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"util/incdec/i"
  },
  {
    "path": "app/firmware/src/io/Kconfig",
    "chars": 96,
    "preview": "rsource \"analog/Kconfig\"\nrsource \"digital/Kconfig\"\nrsource \"i2c/Kconfig\"\nrsource \"leds/Kconfig\"\n"
  },
  {
    "path": "app/firmware/src/io/analog/CMakeLists.txt",
    "chars": 321,
    "preview": "include($ENV{ZEPHYR_PROJECT}/cmake/opendeck_library.cmake)\nopendeck_library_named(analog)\n\ntarget_include_directories(an"
  },
  {
    "path": "app/firmware/src/io/analog/Kconfig",
    "chars": 295,
    "preview": "config ANALOG_THREAD_SLEEP_MS\n    int \"Analog thread loop sleep in milliseconds\"\n    range 0 1000\n    default 1\n    help"
  },
  {
    "path": "app/firmware/src/io/analog/analog.cpp",
    "chars": 13023,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#ifdef CONFIG_PROJECT_TARGET_SUPPORT_"
  },
  {
    "path": "app/firmware/src/io/analog/analog.h",
    "chars": 7959,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n#incl"
  },
  {
    "path": "app/firmware/src/io/analog/analog_stub.h",
    "chars": 1058,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n#incl"
  },
  {
    "path": "app/firmware/src/io/analog/builder.h",
    "chars": 381,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#ifdef OPENDECK_TEST\n#i"
  },
  {
    "path": "app/firmware/src/io/analog/builder_hw.h",
    "chars": 1309,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"analog.h\"\n#in"
  },
  {
    "path": "app/firmware/src/io/analog/builder_stub.h",
    "chars": 1117,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"analog_stub.h"
  },
  {
    "path": "app/firmware/src/io/analog/builder_test.h",
    "chars": 1090,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"analog.h\"\n#in"
  },
  {
    "path": "app/firmware/src/io/analog/common.h",
    "chars": 4253,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"io/common/com"
  },
  {
    "path": "app/firmware/src/io/analog/deps.h",
    "chars": 2363,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"common.h\"\n\n#i"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/count.h",
    "chars": 517,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#if defined(CONFIG_PROJ"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/driver.h",
    "chars": 898,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <zephyr/driver"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/driver_base.h",
    "chars": 1006,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <zephyr/driver"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/multiplexer/count.h",
    "chars": 765,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <zephyr/device"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/multiplexer/multiplexer_driver.h",
    "chars": 5466,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"../scan_drive"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/mux_on_mux/count.h",
    "chars": 952,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <zephyr/device"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/mux_on_mux/mux_on_mux_driver.h",
    "chars": 9489,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"../scan_drive"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/native/count.h",
    "chars": 758,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <zephyr/device"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/native/native_driver.h",
    "chars": 2930,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"../scan_drive"
  },
  {
    "path": "app/firmware/src/io/analog/drivers/scan_driver_base.h",
    "chars": 2730,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"driver_base.h"
  },
  {
    "path": "app/firmware/src/io/analog/filter_hw.h",
    "chars": 49772,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n\n#inc"
  },
  {
    "path": "app/firmware/src/io/analog/filter_stub.h",
    "chars": 953,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n\nname"
  },
  {
    "path": "app/firmware/src/io/analog/filter_test.h",
    "chars": 957,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n\nname"
  },
  {
    "path": "app/firmware/src/io/analog/hwa_hw.h",
    "chars": 1363,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n#incl"
  },
  {
    "path": "app/firmware/src/io/analog/hwa_stub.h",
    "chars": 909,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n\nname"
  },
  {
    "path": "app/firmware/src/io/analog/hwa_test.h",
    "chars": 2284,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"deps.h\"\n\n#inc"
  },
  {
    "path": "app/firmware/src/io/analog/remap.h",
    "chars": 1787,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"drivers/count"
  },
  {
    "path": "app/firmware/src/io/base.h",
    "chars": 3504,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <inttypes.h>\n#"
  },
  {
    "path": "app/firmware/src/io/common/common.h",
    "chars": 3676,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include <inttypes.h>\n#"
  },
  {
    "path": "app/firmware/src/io/digital/CMakeLists.txt",
    "chars": 344,
    "preview": "include($ENV{ZEPHYR_PROJECT}/cmake/opendeck_library.cmake)\nopendeck_library_named(digital)\n\ntarget_include_directories(d"
  },
  {
    "path": "app/firmware/src/io/digital/Kconfig",
    "chars": 298,
    "preview": "config DIGITAL_THREAD_SLEEP_MS\n    int \"Digital thread loop sleep in milliseconds\"\n    range 0 1000\n    default 1\n    he"
  },
  {
    "path": "app/firmware/src/io/digital/builder.h",
    "chars": 407,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#ifdef OPENDECK_TEST\n#i"
  },
  {
    "path": "app/firmware/src/io/digital/builder_hw.h",
    "chars": 2093,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"digital.h\"\n#i"
  },
  {
    "path": "app/firmware/src/io/digital/builder_stub.h",
    "chars": 1422,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"io/base.h\"\n#i"
  },
  {
    "path": "app/firmware/src/io/digital/builder_test.h",
    "chars": 3099,
    "preview": "/*\n * Copyright (c) 2026 Igor Petrovic\n * SPDX-License-Identifier: Apache-2.0\n */\n\n#pragma once\n\n#include \"io/base.h\"\n#i"
  }
]

// ... and 454 more files (download for full content)

About this extraction

This page contains the full source code of the paradajz/OpenDeck GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 654 files (39.1 MB), approximately 10.3M tokens, and a symbol index with 488 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!