├── .gitignore ├── VERSION ├── boards ├── nordic │ ├── promicro_uf2 │ │ ├── CMakeLists.txt │ │ ├── Kconfig.promicro_uf2 │ │ ├── promicro_uf2_i2c.dts │ │ ├── promicro_uf2_spi.dts │ │ ├── promicro_uf2.yaml │ │ ├── promicro_uf2_i2c.yaml │ │ ├── promicro_uf2_spi.yaml │ │ ├── promicro_uf2_chrysalis.yaml │ │ ├── board.cmake │ │ ├── board.yml │ │ ├── promicro_uf2_defconfig │ │ ├── promicro_uf2_i2c_defconfig │ │ ├── promicro_uf2_spi_defconfig │ │ ├── promicro_uf2_smspi.yaml │ │ ├── promicro_uf2_chrysalis_defconfig │ │ ├── promicro_uf2_smspi_defconfig │ │ ├── promicro_uf2_smspi.dts │ │ ├── board.c │ │ └── promicro_uf2_chrysalis.dts │ ├── test54l │ │ ├── board.yml │ │ ├── pre_dt_board.cmake │ │ ├── Kconfig.defconfig │ │ ├── Kconfig.test54l │ │ ├── test54l_nrf54l15_cpuapp.yaml │ │ ├── test54l_nrf54l15_cpuapp_defconfig │ │ ├── board.cmake │ │ └── test54l-pinctrl.dtsi │ └── test805 │ │ ├── Kconfig.test805 │ │ ├── test805_defconfig │ │ ├── board.yml │ │ ├── board.cmake │ │ └── test805.dts ├── nrf21540dk_nrf52840.conf ├── nrf52840dk_nrf52840.conf ├── mocha-elec │ └── mochi │ │ ├── Kconfig.mochi_uf2 │ │ ├── board.yml │ │ ├── mochi_uf2.yaml │ │ ├── board.cmake │ │ └── mochi_uf2_defconfig ├── sctanf │ ├── slimenrf_r3 │ │ ├── slimenrf_r3_nrf52840_uf2.dts │ │ ├── Kconfig.slimenrf_r3 │ │ ├── board.yml │ │ ├── slimenrf_r3.yaml │ │ ├── slimenrf_r3_nrf52840_uf2.yaml │ │ ├── slimenrf_r3_defconfig │ │ ├── board.cmake │ │ ├── slimenrf_r3_nrf52840_uf2_defconfig │ │ └── slimenrf_r3.dts │ ├── slimenrf_r1 │ │ ├── Kconfig.slimenrf_r1 │ │ ├── board.yml │ │ ├── slimenrf_r1_defconfig │ │ ├── slimenrf_r1.yaml │ │ ├── board.cmake │ │ └── slimenrf_r1.dts │ └── slimenrf_r2 │ │ ├── Kconfig.slimenrf_r2 │ │ ├── board.yml │ │ ├── slimenrf_r2_defconfig │ │ ├── slimenrf_r2.yaml │ │ ├── board.cmake │ │ └── slimenrf_r2.dts ├── nrf5340dk_nrf5340_cpuapp.conf ├── slimevr │ ├── microslime │ │ ├── Kconfig.microslime_uf2 │ │ ├── board.yml │ │ ├── microslime_uf2.yaml │ │ ├── board.cmake │ │ ├── microslime_uf2_defconfig │ │ └── microslime_uf2.dts │ ├── slimevrmini_p1_uf2 │ │ ├── Kconfig.slimevrmini_p1_uf2 │ │ ├── board.yml │ │ ├── slimevrmini_p1_uf2.yaml │ │ ├── board.cmake │ │ ├── slimevrmini_p1_uf2_defconfig │ │ └── slimevrmini_p1_uf2.dts │ ├── slimevrmini_p2_uf2 │ │ ├── Kconfig.slimevrmini_p2_uf2 │ │ ├── board.yml │ │ ├── slimevrmini_p2_uf2.yaml │ │ ├── board.cmake │ │ ├── slimevrmini_p2_uf2_defconfig │ │ └── slimevrmini_p2_uf2.dts │ ├── slimevrmini_p4_uf2 │ │ ├── Kconfig.slimevrmini_p4_uf2 │ │ ├── board.yml │ │ ├── slimevrmini_p4_uf2.yaml │ │ ├── board.cmake │ │ └── slimevrmini_p4_uf2_defconfig │ ├── slimevrmini_p3r6_uf2 │ │ ├── Kconfig.slimevrmini_p3r6_uf2 │ │ ├── board.yml │ │ ├── slimevrmini_p3r6_uf2.yaml │ │ ├── board.cmake │ │ ├── slimevrmini_p3r6_uf2_defconfig │ │ └── slimevrmini_p3r6_uf2.dts │ ├── slimevrmini_p3r7_uf2 │ │ ├── Kconfig.slimevrmini_p3r7_uf2 │ │ ├── board.yml │ │ ├── slimevrmini_p3r7_uf2.yaml │ │ ├── board.cmake │ │ ├── slimevrmini_p3r7_uf2_defconfig │ │ └── slimevrmini_p3r7_uf2.dts │ └── slimevrmini_p4r9_uf2 │ │ ├── Kconfig.slimevrmini_p4r9_uf2 │ │ ├── board.yml │ │ ├── slimevrmini_p4r9_uf2.yaml │ │ ├── board.cmake │ │ └── slimevrmini_p4r9_uf2_defconfig ├── nrf52840dongle_nrf52840.conf ├── xiao_ble.conf ├── xiao_ble_nrf52840_sense.conf ├── nrf52840dongle_nrf52840.overlay ├── nrf52dk_nrf52832.overlay ├── nrf54l15dk_nrf54l15_cpuapp.overlay ├── nrf5340dk_nrf5340_cpuapp.overlay ├── nrf52840dk_nrf52840.overlay ├── nrf21540dk_nrf52840.overlay ├── xiao_ble_nrf52840_sense.overlay └── xiao_ble.overlay ├── pm_static_nrf52840dongle_nrf52840.yml ├── src ├── console.h ├── sensor │ ├── magneto │ │ ├── magneto1_4.h │ │ └── mymathlib_matrix.h │ ├── mag │ │ ├── QMC6309.h │ │ ├── IST8308.h │ │ ├── LIS2MDL.h │ │ ├── BMM150.h │ │ ├── IST8306.h │ │ ├── BMM350.h │ │ ├── LIS3MDL.h │ │ ├── AK09940.h │ │ └── MMC5983MA.h │ ├── fusion │ │ ├── xiofusion │ │ │ ├── xioFusionOffset2.h │ │ │ ├── xiofusion.h │ │ │ └── xioFusionOffset2.c │ │ ├── fusions.h │ │ ├── vqf │ │ │ └── vqf.h │ │ └── motionsense │ │ │ ├── motionsense.h │ │ │ └── motionsense.c │ ├── scan_spi.h │ ├── scan.h │ ├── scan_ext.h │ ├── calibration.h │ ├── sensor_none.h │ ├── imu │ │ ├── BMI270.h │ │ ├── LSM6DSM.h │ │ └── LSM6DSO.h │ ├── interface.h │ └── scan_spi.c ├── system │ ├── power.h │ ├── rtt_console.h │ ├── status.h │ ├── system.h │ ├── battery_tracker.h │ ├── battery.h │ ├── status.c │ └── led.h ├── thread_priority.h ├── connection │ ├── timer.h │ ├── connection.h │ ├── esb.h │ └── timer.c ├── hid.h ├── parse_args.h ├── usb.c ├── retained.c ├── retained.h ├── parse_args.c ├── util.h └── globals.h ├── .vscode ├── extensions.json └── settings.json ├── west.yml ├── pm_static_mochi_uf2_nrf52833.yml ├── pm_static_microslime_uf2_nrf52833.yml ├── pm_static_promicro_uf2_nrf52840.yml ├── pm_static_xiao_ble_nrf52840.yml ├── pm_static_promicro_uf2_nrf52840_i2c.yml ├── pm_static_promicro_uf2_nrf52840_smspi.yml ├── pm_static_promicro_uf2_nrf52840_spi.yml ├── pm_static_slimenrf_r3_nrf52840_uf2.yml ├── pm_static_slimevrmini_p1_uf2_nrf52833.yml ├── pm_static_slimevrmini_p2_uf2_nrf52833.yml ├── pm_static_slimevrmini_p4_uf2_nrf52833.yml ├── pm_static_xiao_ble_nrf52840_sense.yml ├── pm_static_promicro_uf2_nrf52840_chrysalis.yml ├── pm_static_slimevrmini_p3r6_uf2_nrf52833.yml ├── pm_static_slimevrmini_p3r7_uf2_nrf52833.yml ├── pm_static_slimevrmini_p4r9_uf2_nrf52833.yml ├── .gitmodules ├── sample.yaml ├── socs ├── nrf52805.overlay ├── nrf52810.overlay ├── nrf52811.overlay ├── nrf52820.overlay ├── nrf52832.overlay ├── nrf5340_cpuapp.overlay ├── nrf54l15_cpuapp.overlay ├── nrf52833.overlay ├── nrf52840.overlay ├── nrf52840_i2c.overlay ├── nrf52840_spi.overlay ├── nrf52840_uf2.overlay ├── nrf52840_chrysalis.overlay ├── nrf52840_sense.overlay └── nrf52840_smspi.overlay ├── .clang-format ├── README.md ├── CMakeLists.txt ├── LICENSE-MIT └── prj.conf /.gitignore: -------------------------------------------------------------------------------- 1 | # editors 2 | *.swp 3 | *~ 4 | 5 | # build 6 | /build*/ 7 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | VERSION_MAJOR = 0 2 | VERSION_MINOR = 6 3 | PATCHLEVEL = 9 4 | VERSION_TWEAK = 0 5 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | zephyr_library() 4 | zephyr_library_sources(board.c) 5 | -------------------------------------------------------------------------------- /pm_static_nrf52840dongle_nrf52840.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0xe0000 3 | end_address: 0x100000 4 | region: flash_primary 5 | size: 0x20000 6 | -------------------------------------------------------------------------------- /src/console.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIMENRF_CONSOLE 2 | #define SLIMENRF_CONSOLE 3 | 4 | void console_thread_create(void); 5 | void console_thread_abort(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "nordic-semiconductor.nrf-connect-extension-pack", 4 | "nordic-semiconductor.nrf-connect" 5 | ] 6 | } -------------------------------------------------------------------------------- /boards/nordic/test54l/board.yml: -------------------------------------------------------------------------------- 1 | board: 2 | name: test54l 3 | vendor: nordic 4 | socs: 5 | - name: nrf54l15 6 | variants: 7 | - name: xip 8 | cpucluster: cpuflpr -------------------------------------------------------------------------------- /boards/nordic/test54l/pre_dt_board.cmake: -------------------------------------------------------------------------------- 1 | # Suppress "unique_unit_address_if_enabled" to handle some overlaps 2 | list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") 3 | -------------------------------------------------------------------------------- /boards/nrf21540dk_nrf52840.conf: -------------------------------------------------------------------------------- 1 | CONFIG_USB_DEVICE_STACK=y 2 | CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" 3 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker nRF21540 DK" 4 | -------------------------------------------------------------------------------- /boards/nrf52840dk_nrf52840.conf: -------------------------------------------------------------------------------- 1 | CONFIG_USB_DEVICE_STACK=y 2 | CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" 3 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker nRF52840 DK" 4 | -------------------------------------------------------------------------------- /boards/nordic/test805/Kconfig.test805: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_TEST805 5 | select SOC_NRF52805_CAAA 6 | -------------------------------------------------------------------------------- /boards/nordic/test805/test805_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | -------------------------------------------------------------------------------- /boards/mocha-elec/mochi/Kconfig.mochi_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_MOCHI_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/slimenrf_r3_nrf52840_uf2.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include "slimenrf_r3.dts" 6 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r1/Kconfig.slimenrf_r1: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMENRF_R1 5 | select SOC_NRF52840_QIAA 6 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r2/Kconfig.slimenrf_r2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMENRF_R2 5 | select SOC_NRF52832_CIAA 6 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/Kconfig.slimenrf_r3: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMENRF_R3 5 | select SOC_NRF52840_QIAA 6 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/Kconfig.promicro_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_PROMICRO_UF2 5 | select SOC_NRF52840_QIAA 6 | -------------------------------------------------------------------------------- /boards/nrf5340dk_nrf5340_cpuapp.conf: -------------------------------------------------------------------------------- 1 | CONFIG_USB_DEVICE_STACK=y 2 | CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" 3 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker nRF5340 DK" 4 | 5 | CONFIG_ESB=n 6 | -------------------------------------------------------------------------------- /boards/slimevr/microslime/Kconfig.microslime_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_MICROSLIME_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/nordic/test805/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: test805 6 | vendor: nordic 7 | socs: 8 | - name: nrf52805 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.h": "c" 4 | }, 5 | "nrf-connect.toolchain.path": "${nrf-connect.toolchain:2.9.0}", 6 | "nrf-connect.topdir": "${nrf-connect.sdk:2.9.0}" 7 | } -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_i2c.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include "promicro_uf2.dts" 6 | 7 | /delete-node/ &spi3; 8 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_spi.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include "promicro_uf2.dts" 6 | 7 | /delete-node/ &i2c0; 8 | -------------------------------------------------------------------------------- /boards/nrf52840dongle_nrf52840.conf: -------------------------------------------------------------------------------- 1 | CONFIG_USB_DEVICE_STACK=y 2 | CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor" 3 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker nRF52840 Dongle" 4 | 5 | CONFIG_LED_RGB_COLOR=y 6 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p1_uf2/Kconfig.slimevrmini_p1_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMEVRMINI_P1_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p2_uf2/Kconfig.slimevrmini_p2_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMEVRMINI_P2_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4_uf2/Kconfig.slimevrmini_p4_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMEVRMINI_P4_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r1/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimenrf_r1 6 | vendor: sctanf 7 | socs: 8 | - name: nrf52840 9 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimenrf_r2 6 | vendor: sctanf 7 | socs: 8 | - name: nrf52832 9 | -------------------------------------------------------------------------------- /boards/xiao_ble.conf: -------------------------------------------------------------------------------- 1 | CONFIG_USB_DEVICE_STACK=y 2 | CONFIG_USB_DEVICE_MANUFACTURER="Seeed Studio" 3 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker XIAO" 4 | 5 | CONFIG_BATTERY_USE_REG_LDO_MAPPING=y 6 | CONFIG_LED_RGB_COLOR=y 7 | -------------------------------------------------------------------------------- /boards/nordic/test54l/Kconfig.defconfig: -------------------------------------------------------------------------------- 1 | if BOARD_TEST54L_NRF54L15_CPUAPP 2 | 3 | config BT_CTLR 4 | default BT 5 | 6 | config ROM_START_OFFSET 7 | default 0x800 if BOOTLOADER_MCUBOOT 8 | 9 | endif # BOARD_TEST54L_NRF54L15_CPUAPP -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r6_uf2/Kconfig.slimevrmini_p3r6_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMEVRMINI_P3R6_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r7_uf2/Kconfig.slimevrmini_p3r7_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMEVRMINI_P3R7_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4r9_uf2/Kconfig.slimevrmini_p4r9_uf2: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_SLIMEVRMINI_P4R9_UF2 5 | select SOC_NRF52833_QIAA 6 | -------------------------------------------------------------------------------- /boards/mocha-elec/mochi/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: mochi_uf2 6 | vendor: mocha-elec 7 | socs: 8 | - name: nrf52833 9 | 10 | -------------------------------------------------------------------------------- /boards/nordic/test54l/Kconfig.test54l: -------------------------------------------------------------------------------- 1 | config BOARD_TEST54L 2 | select SOC_NRF54L15_CPUAPP if BOARD_TEST54L_NRF54L15_CPUAPP 3 | select SOC_NRF54L15_CPUFLPR if \ 4 | BOARD_TEST54L_NRF54L15_CPUFLPR || \ 5 | BOARD_TEST54L_NRF54L15_CPUFLPR_XIP -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p1_uf2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimevrmini_p1_uf2 6 | vendor: slimevr 7 | socs: 8 | - name: nrf52833 9 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p2_uf2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimevrmini_p2_uf2 6 | vendor: slimevr 7 | socs: 8 | - name: nrf52833 9 | -------------------------------------------------------------------------------- /src/sensor/magneto/magneto1_4.h: -------------------------------------------------------------------------------- 1 | void magneto_sample(double x, double y, double z, double* ata, double* norm_sum, double* sample_count); 2 | void magneto_current_calibration(float BAinv[4][3], double* ata, double norm_sum, double sample_count); -------------------------------------------------------------------------------- /boards/slimevr/microslime/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: microslime_uf2 6 | vendor: slimevr 7 | socs: 8 | - name: nrf52833 9 | 10 | -------------------------------------------------------------------------------- /boards/xiao_ble_nrf52840_sense.conf: -------------------------------------------------------------------------------- 1 | CONFIG_USB_DEVICE_STACK=y 2 | CONFIG_USB_DEVICE_MANUFACTURER="Seeed Studio" 3 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker XIAO Sense" 4 | 5 | CONFIG_BATTERY_USE_REG_LDO_MAPPING=y 6 | CONFIG_LED_RGB_COLOR=y 7 | -------------------------------------------------------------------------------- /west.yml: -------------------------------------------------------------------------------- 1 | manifest: 2 | version: "1.2" 3 | projects: 4 | 5 | # nRF-Connect SDK 6 | - name: sdk-nrf 7 | path: nrf 8 | url: https://github.com/nrfconnect/sdk-nrf.git 9 | revision: v3.1-branch 10 | import: true -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4_uf2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimevrmini_p4_uf2 6 | vendor: slimevr 7 | socs: 8 | - name: nrf52833 9 | 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r6_uf2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimevrmini_p3r6_uf2 6 | vendor: slimevr 7 | socs: 8 | - name: nrf52833 9 | 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r7_uf2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimevrmini_p3r7_uf2 6 | vendor: slimevr 7 | socs: 8 | - name: nrf52833 9 | 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4r9_uf2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimevrmini_p4r9_uf2 6 | vendor: slimevr 7 | socs: 8 | - name: nrf52833 9 | 10 | -------------------------------------------------------------------------------- /pm_static_mochi_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_microslime_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_promicro_uf2_nrf52840.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_xiao_ble_nrf52840.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x27000 4 | region: flash_primary 5 | size: 0x27000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_promicro_uf2_nrf52840_i2c.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_promicro_uf2_nrf52840_smspi.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_promicro_uf2_nrf52840_spi.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_slimenrf_r3_nrf52840_uf2.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_slimevrmini_p1_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_slimevrmini_p2_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_slimevrmini_p4_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_xiao_ble_nrf52840_sense.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x27000 4 | region: flash_primary 5 | size: 0x27000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board: 5 | name: slimenrf_r3 6 | vendor: sctanf 7 | socs: 8 | - name: nrf52840 9 | variants: 10 | - name: 'uf2' 11 | -------------------------------------------------------------------------------- /pm_static_promicro_uf2_nrf52840_chrysalis.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0xf4000 8 | end_address: 0x100000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_slimevrmini_p3r6_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_slimevrmini_p3r7_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /pm_static_slimevrmini_p4r9_uf2_nrf52833.yml: -------------------------------------------------------------------------------- 1 | bootloader: 2 | address: 0x0 3 | end_address: 0x1000 4 | region: flash_primary 5 | size: 0x1000 6 | uf2_bootloader: 7 | address: 0x74000 8 | end_address: 0x80000 9 | region: flash_primary 10 | size: 0xc000 11 | -------------------------------------------------------------------------------- /boards/nordic/test54l/test54l_nrf54l15_cpuapp.yaml: -------------------------------------------------------------------------------- 1 | identifier: test54l/nrf54l15/cpuapp 2 | name: Custom Board auto generated by nRF Connect for VS Code 3 | vendor: nordic 4 | arch: arm 5 | toolchain: 6 | - zephyr 7 | sysbuild: true 8 | ram: 188 9 | flash: 324 10 | supported: [] -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r1/slimenrf_r1_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=n 8 | 9 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 10 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r2/slimenrf_r2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=n 8 | 9 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 10 | -------------------------------------------------------------------------------- /boards/nordic/test54l/test54l_nrf54l15_cpuapp_defconfig: -------------------------------------------------------------------------------- 1 | CONFIG_ARM_MPU=y 2 | CONFIG_HW_STACK_PROTECTION=y 3 | 4 | CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y 5 | 6 | CONFIG_CACHE_MANAGEMENT=y 7 | CONFIG_EXTERNAL_CACHE=y 8 | 9 | CONFIG_NRF_GRTC_START_SYSCOUNTER=y 10 | 11 | CONFIG_REGULATOR=y 12 | -------------------------------------------------------------------------------- /boards/mocha-elec/mochi/mochi_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: mochi_uf2 5 | name: mochi_uf2 6 | vendor: mocha-elec 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vqf-c"] 2 | path = vqf-c 3 | url = https://github.com/sctanf/vqf-c/ 4 | [submodule "Fusion"] 5 | path = Fusion 6 | url = https://github.com/xioTechnologies/Fusion 7 | [submodule "NXP-ISSDK-SensorFusion"] 8 | path = NXP-ISSDK-SensorFusion 9 | url = https://github.com/sctanf/NXP-ISSDK-SensorFusion/ 10 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r1/slimenrf_r1.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimenrf_r1 5 | name: slimenrf_r1 6 | vendor: sctanf 7 | type: mcu 8 | arch: arm 9 | ram: 256 10 | flash: 1024 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r2/slimenrf_r2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimenrf_r2 5 | name: slimenrf_r2 6 | vendor: sctanf 7 | type: mcu 8 | arch: arm 9 | ram: 64 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/slimenrf_r3.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimenrf_r3 5 | name: slimenrf_r3 6 | vendor: sctanf 7 | type: mcu 8 | arch: arm 9 | ram: 256 10 | flash: 1024 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: promicro_uf2 5 | name: promicro_uf2 6 | vendor: nordic 7 | type: mcu 8 | arch: arm 9 | ram: 256 10 | flash: 1024 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /src/system/power.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIMENRF_SYSTEM_POWER 2 | #define SLIMENRF_SYSTEM_POWER 3 | 4 | void sys_interface_suspend(void); 5 | void sys_interface_resume(void); 6 | 7 | void sys_request_WOM(bool, bool); 8 | void sys_request_system_off(bool); 9 | void sys_request_system_reboot(bool); 10 | 11 | bool vin_read(void); 12 | 13 | #endif -------------------------------------------------------------------------------- /boards/slimevr/microslime/microslime_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: microslime_uf2 5 | name: microslime_uf2 6 | vendor: slimevr 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_i2c.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: promicro_uf2/nrf52840/i2c 5 | name: promicro_uf2_i2c 6 | vendor: nordic 7 | type: mcu 8 | arch: arm 9 | ram: 256 10 | flash: 1024 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_spi.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: promicro_uf2/nrf52840/spi 5 | name: promicro_uf2_spi 6 | vendor: nordic 7 | type: mcu 8 | arch: arm 9 | ram: 256 10 | flash: 1024 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/slimenrf_r3_nrf52840_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimenrf_r3/nrf52840/uf2 5 | name: slimenrf_r3_uf2 6 | vendor: sctanf 7 | type: mcu 8 | arch: arm 9 | ram: 256 10 | flash: 1024 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p1_uf2/slimevrmini_p1_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimevrmini_p1_uf2 5 | name: slimevrmini_p1_uf2 6 | vendor: slimevr 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p2_uf2/slimevrmini_p2_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimevrmini_p2_uf2 5 | name: slimevrmini_p2_uf2 6 | vendor: slimevr 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4_uf2/slimevrmini_p4_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimevrmini_p4_uf2 5 | name: slimevrmini_p4_uf2 6 | vendor: slimevr 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r6_uf2/slimevrmini_p3r6_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimevrmini_p3r6_uf2 5 | name: slimevrmini_p3r6_uf2 6 | vendor: slimevr 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r7_uf2/slimevrmini_p3r7_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimevrmini_p3r7_uf2 5 | name: slimevrmini_p3r7_uf2 6 | vendor: slimevr 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4r9_uf2/slimevrmini_p4r9_uf2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: slimevrmini_p4r9_uf2 5 | name: slimevrmini_p4r9_uf2 6 | vendor: slimevr 7 | type: mcu 8 | arch: arm 9 | ram: 128 10 | flash: 512 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_chrysalis.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | identifier: promicro_uf2/nrf52840/chrysalis 5 | name: promicro_uf2_chrysalis 6 | vendor: nordic 7 | type: mcu 8 | arch: arm 9 | ram: 256 10 | flash: 1024 11 | toolchain: 12 | - zephyr 13 | - gnuarmemb 14 | - xtools 15 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/slimenrf_r3_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="sctanf" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker R3" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | -------------------------------------------------------------------------------- /sample.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | common: 3 | platform_allow: 4 | - nrf21540dk/nrf52840 5 | - nrf52840dk/nrf52840 6 | - nrf52840dongle/nrf52840 7 | - nrf52dk/nrf52832 8 | - nrf5340dk/nrf5340/cpuapp 9 | - nrf5340dk/nrf5340/cpunet 10 | - nrf54l15dk/nrf54l15/cpuapp 11 | - xiao_ble/nrf52840 12 | - xiao_ble/nrf52840/sense 13 | sysbuild: true 14 | -------------------------------------------------------------------------------- /boards/nordic/test54l/board.cmake: -------------------------------------------------------------------------------- 1 | if (CONFIG_SOC_NRF54L15_CPUAPP) 2 | board_runner_args(jlink "--device=cortex-m33" "--speed=4000") 3 | elseif (CONFIG_SOC_NRF54L15_CPUFLPR) 4 | board_runner_args(jlink "--speed=4000") 5 | endif() 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) -------------------------------------------------------------------------------- /boards/nordic/test805/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nrf52805_xxaa" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52805" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r1/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nrf52" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nrf52" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52832" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/mocha-elec/mochi/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nrf52840_xxaa" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nrf52840_xxaa" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/slimevr/microslime/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /src/sensor/mag/QMC6309.h: -------------------------------------------------------------------------------- 1 | #ifndef QMC6309_h 2 | #define QMC6309_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | int qmc_init(float time, float *actual_time); 7 | void qmc_shutdown(void); 8 | 9 | int qmc_update_odr(float time, float *actual_time); 10 | 11 | void qmc_mag_oneshot(void); 12 | void qmc_mag_read(float m[3]); 13 | 14 | void qmc_mag_process(uint8_t *raw_m, float m[3]); 15 | 16 | extern const sensor_mag_t sensor_mag_qmc6309; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p1_uf2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p2_uf2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r6_uf2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r7_uf2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4_uf2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4r9_uf2/board.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | board_runner_args(jlink "--device=nRF52833_xxAA" "--speed=4000") 5 | board_runner_args(pyocd "--target=nrf52833" "--frequency=4000000") 6 | 7 | include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 8 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 9 | include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 10 | -------------------------------------------------------------------------------- /src/system/rtt_console.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static uint8_t line[64]; 5 | 6 | static uint8_t* rtt_console_getline(void) 7 | { 8 | uint8_t len = 0; 9 | do { 10 | while (SEGGER_RTT_HasKey() == 0) 11 | k_usleep(1); 12 | line[len] = SEGGER_RTT_GetKey(); 13 | printk("%c", line[len]); 14 | len++; 15 | } while (len < sizeof(line) && line[len - 1] != '\n' && line[len - 1] != '\r'); 16 | line[len - 1] = 0; 17 | return line; 18 | } 19 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/board.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # The 'smspi' board variant is targeted promico stack with the SM-ICM45686-AK09940A 5 | # where ICM is on SPI, AK is on I2C, external clock disabled. 6 | 7 | board: 8 | name: promicro_uf2 9 | vendor: nordic 10 | socs: 11 | - name: nrf52840 12 | variants: 13 | - name: 'i2c' 14 | - name: 'spi' 15 | - name: 'smspi' 16 | - name: 'chrysalis' -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker ProMicro" 10 | 11 | CONFIG_BATTERY_USE_REG_LDO_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_i2c_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker ProMicro" 10 | 11 | CONFIG_BATTERY_USE_REG_LDO_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_spi_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker ProMicro" 10 | 11 | CONFIG_BATTERY_USE_REG_LDO_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/slimenrf_r3_nrf52840_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="sctanf" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker R3" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_smspi.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # This board variant is targeted promico stack with the SM-ICM45686-AK09940A 5 | # where ICM is on SPI, AK is on I2C, external clock disabled 6 | 7 | identifier: promicro_uf2/nrf52840/smspi 8 | name: promicro_uf2_smspi 9 | vendor: nordic 10 | type: mcu 11 | arch: arm 12 | ram: 256 13 | flash: 1024 14 | toolchain: 15 | - zephyr 16 | - gnuarmemb 17 | - xtools 18 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r6_uf2/slimevrmini_p3r6_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeVR smol P3R6" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r7_uf2/slimevrmini_p3r7_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeVR smol P3R7" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/mocha-elec/mochi/mochi_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="Mocha-Elec" 9 | CONFIG_USB_DEVICE_PRODUCT="Mochi" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | 13 | CONFIG_LED_RGB_COLOR=y 14 | 15 | #generate for adafruit uf2 bootloader flashing 16 | CONFIG_BUILD_OUTPUT_UF2=y 17 | CONFIG_FLASH_LOAD_OFFSET=0x1000 18 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p1_uf2/slimevrmini_p1_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeVR Mini Tracker P1" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p2_uf2/slimevrmini_p2_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeVR Mini Tracker P2" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | 13 | #generate for adafruit uf2 bootloader flashing 14 | CONFIG_BUILD_OUTPUT_UF2=y 15 | CONFIG_FLASH_LOAD_OFFSET=0x1000 16 | -------------------------------------------------------------------------------- /boards/slimevr/microslime/microslime_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="Microslime" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | 13 | CONFIG_LED_RGB_COLOR=n 14 | 15 | #generate for adafruit uf2 bootloader flashing 16 | CONFIG_BUILD_OUTPUT_UF2=y 17 | CONFIG_FLASH_LOAD_OFFSET=0x1000 18 | -------------------------------------------------------------------------------- /src/system/status.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIMENRF_SYSTEM_STATUS 2 | #define SLIMENRF_SYSTEM_STATUS 3 | 4 | enum sys_status { 5 | SYS_STATUS_SENSOR_ERROR = 1, 6 | SYS_STATUS_CONNECTION_ERROR = 2, 7 | SYS_STATUS_SYSTEM_ERROR = 4, 8 | SYS_STATUS_USB_CONNECTED = 8, 9 | SYS_STATUS_PLUGGED = 16, 10 | SYS_STATUS_CALIBRATION_RUNNING = 32, 11 | SYS_STATUS_BUTTON_PRESSED = 64, 12 | }; 13 | 14 | void set_status(enum sys_status status, bool set); 15 | 16 | bool get_status(enum sys_status status); 17 | 18 | bool status_ready(void); 19 | 20 | #endif -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_chrysalis_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker ProMicro" 10 | 11 | CONFIG_BATTERY_USE_REG_LDO_MAPPING=y 12 | 13 | CONFIG_LED_RGB_COLOR=y 14 | 15 | #generate for adafruit uf2 bootloader flashing 16 | CONFIG_BUILD_OUTPUT_UF2=y 17 | CONFIG_FLASH_LOAD_OFFSET=0x1000 18 | -------------------------------------------------------------------------------- /socs/nrf52805.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@20005c00 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x20005c00 DT_SIZE_K(1)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | aliases { 15 | retainedmemdevice = &retainedmem0; 16 | }; 17 | }; 18 | 19 | &sram0 { 20 | /* Shrink SRAM size to avoid overlap with retained memory region */ 21 | reg = <0x20000000 DT_SIZE_K(23)>; 22 | }; -------------------------------------------------------------------------------- /socs/nrf52810.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@20005c00 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x20005c00 DT_SIZE_K(1)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | aliases { 15 | retainedmemdevice = &retainedmem0; 16 | }; 17 | }; 18 | 19 | &sram0 { 20 | /* Shrink SRAM size to avoid overlap with retained memory region */ 21 | reg = <0x20000000 DT_SIZE_K(23)>; 22 | }; -------------------------------------------------------------------------------- /socs/nrf52811.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@20005c00 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x20005c00 DT_SIZE_K(1)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | aliases { 15 | retainedmemdevice = &retainedmem0; 16 | }; 17 | }; 18 | 19 | &sram0 { 20 | /* Shrink SRAM size to avoid overlap with retained memory region */ 21 | reg = <0x20000000 DT_SIZE_K(23)>; 22 | }; -------------------------------------------------------------------------------- /socs/nrf52820.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@20007000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x20007000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | aliases { 15 | retainedmemdevice = &retainedmem0; 16 | }; 17 | }; 18 | 19 | &sram0 { 20 | /* Shrink SRAM size to avoid overlap with retained memory region */ 21 | reg = <0x20000000 DT_SIZE_K(28)>; 22 | }; -------------------------------------------------------------------------------- /socs/nrf52832.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@20007000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x20007000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | aliases { 15 | retainedmemdevice = &retainedmem0; 16 | }; 17 | }; 18 | 19 | &sram0 { 20 | /* Shrink SRAM size to avoid overlap with retained memory region */ 21 | reg = <0x20000000 DT_SIZE_K(28)>; 22 | }; -------------------------------------------------------------------------------- /socs/nrf5340_cpuapp.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2007f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2007f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | aliases { 15 | retainedmemdevice = &retainedmem0; 16 | }; 17 | }; 18 | 19 | &sram0 { 20 | /* Shrink SRAM size to avoid overlap with retained memory region */ 21 | reg = <0x20000000 DT_SIZE_K(508)>; 22 | }; -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4_uf2/slimevrmini_p4_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="SlimeVR Butterfly P4" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | CONFIG_LED_RGB_COLOR=y 13 | 14 | #generate for adafruit uf2 bootloader flashing 15 | CONFIG_BUILD_OUTPUT_UF2=y 16 | CONFIG_FLASH_LOAD_OFFSET=0x1000 17 | 18 | CONFIG_SENSOR_USE_MAG=n -------------------------------------------------------------------------------- /socs/nrf54l15_cpuapp.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | cpuapp_sram@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | aliases { 15 | retainedmemdevice = &retainedmem0; 16 | }; 17 | }; 18 | 19 | &cpuapp_sram { 20 | /* Shrink SRAM size to avoid overlap with retained memory region */ 21 | reg = <0x20000000 DT_SIZE_K(252)>; 22 | }; -------------------------------------------------------------------------------- /src/sensor/mag/IST8308.h: -------------------------------------------------------------------------------- 1 | #ifndef IST8308_h 2 | #define IST8308_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | #define IST8308_CNTL4 0x33 7 | 8 | #define DR_500 0b00 9 | #define DR_200 0b1 10 | 11 | int ist8308_init(float time, float *actual_time); 12 | void ist8308_shutdown(void); 13 | 14 | int ist8308_update_odr(float time, float *actual_time); 15 | 16 | void ist8308_mag_oneshot(void); 17 | void ist8308_mag_read(float m[3]); 18 | 19 | void ist8308_mag_process(uint8_t *raw_m, float m[3]); 20 | 21 | extern const sensor_mag_t sensor_mag_ist8308; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p4r9_uf2/slimevrmini_p4r9_uf2_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | CONFIG_ARM_MPU=y 5 | CONFIG_HW_STACK_PROTECTION=y 6 | 7 | CONFIG_USB_DEVICE_STACK=y 8 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 9 | CONFIG_USB_DEVICE_PRODUCT="Butterfly P4R9" 10 | 11 | CONFIG_BATTERY_USE_REG_BUCK_MAPPING=y 12 | CONFIG_LED_RGB_COLOR=y 13 | 14 | #generate for adafruit uf2 bootloader flashing 15 | CONFIG_BUILD_OUTPUT_UF2=y 16 | CONFIG_FLASH_LOAD_OFFSET=0x1000 17 | 18 | # MAG on aux I2C yet not supported #77 19 | CONFIG_SENSOR_USE_MAG=n -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_smspi_defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # This board variant is targeted promico stack with the SM-ICM45686-AK09940A 5 | # where ICM is on SPI, AK is on I2C, external clock disabled 6 | 7 | CONFIG_ARM_MPU=y 8 | CONFIG_HW_STACK_PROTECTION=y 9 | 10 | CONFIG_USB_DEVICE_STACK=y 11 | CONFIG_USB_DEVICE_MANUFACTURER="SlimeVR" 12 | CONFIG_USB_DEVICE_PRODUCT="SlimeNRF Tracker ProMicro" 13 | 14 | CONFIG_BATTERY_USE_REG_LDO_MAPPING=y 15 | 16 | #generate for adafruit uf2 bootloader flashing 17 | CONFIG_BUILD_OUTPUT_UF2=y 18 | CONFIG_FLASH_LOAD_OFFSET=0x1000 19 | 20 | # Disable external clock 21 | CONFIG_USE_SENSOR_CLOCK=n 22 | -------------------------------------------------------------------------------- /src/thread_priority.h: -------------------------------------------------------------------------------- 1 | /* Negative priority is cooperative 2 | Non-negative priority is preemptible (such as during any k_sleep) 3 | Higher value is lower priority 4 | */ 5 | #define CONSOLE_THREAD_PRIORITY 6 6 | #define HID_THREAD_PRIORITY 6 7 | #define USB_INIT_THREAD_PRIORITY 6 8 | #define CONNECTION_THREAD_PRIORITY 8 9 | #define ESB_THREAD_PRIORITY 6 10 | #define CLOCKS_START_THREAD_PRIORITY 5 11 | #define CLOCKS_STOP_THREAD_PRIORITY 5 12 | #define CALIBRATION_THREAD_PRIORITY 6 13 | #define SENSOR_REQUEST_SCAN_THREAD_PRIORITY 7 14 | #define SENSOR_SCAN_THREAD_PRIORITY 7 15 | #define SENSOR_LOOP_THREAD_PRIORITY 7 16 | #define LED_THREAD_PRIORITY 6 17 | #define DISABLE_DFU_THREAD_PRIORITY 6 18 | #define POWER_THREAD_PRIORITY 6 19 | #define STATUS_THREAD_PRIORITY 6 20 | #define BUTTON_THREAD_PRIORITY 6 21 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Google 3 | AccessModifierOffset: -4 4 | AlignAfterOpenBracket: BlockIndent 5 | AlignOperands: AlignAfterOperator 6 | AlignTrailingComments: false 7 | AllowAllArgumentsOnNextLine: false 8 | AllowAllConstructorInitializersOnNextLine: false 9 | AllowAllParametersOfDeclarationOnNextLine: false 10 | AllowShortIfStatementsOnASingleLine: Never 11 | AllowShortLoopsOnASingleLine: false 12 | BinPackArguments: false 13 | BinPackParameters: false 14 | BreakBeforeBinaryOperators: All 15 | BreakConstructorInitializers: BeforeComma 16 | BreakInheritanceList: BeforeComma 17 | ColumnLimit: 88 18 | DerivePointerAlignment: false 19 | IndentWidth: 4 20 | InsertBraces: true 21 | InsertTrailingCommas: Wrapped 22 | PackConstructorInitializers: Never 23 | TabWidth: 4 24 | UseTab: ForContinuationAndIndentation 25 | -------------------------------------------------------------------------------- /boards/nordic/test54l/test54l-pinctrl.dtsi: -------------------------------------------------------------------------------- 1 | &pinctrl { 2 | i2c0_default: i2c0_default { 3 | group1 { 4 | psels = , 5 | ; 6 | bias-disable; 7 | }; 8 | }; 9 | 10 | i2c0_sleep: i2c0_sleep { 11 | group1 { 12 | psels = , 13 | ; 14 | low-power-enable; 15 | bias-disable; 16 | }; 17 | }; 18 | 19 | spi00_default: spi00_default { 20 | group1 { 21 | psels = , 22 | , 23 | ; 24 | }; 25 | }; 26 | 27 | spi00_sleep: spi00_sleep { 28 | group1 { 29 | psels = , 30 | , 31 | ; 32 | low-power-enable; 33 | }; 34 | }; 35 | 36 | }; 37 | -------------------------------------------------------------------------------- /socs/nrf52833.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2001f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2001f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(124)>; 34 | }; -------------------------------------------------------------------------------- /socs/nrf52840.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(252)>; 34 | }; -------------------------------------------------------------------------------- /socs/nrf52840_i2c.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(252)>; 34 | }; -------------------------------------------------------------------------------- /socs/nrf52840_spi.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(252)>; 34 | }; -------------------------------------------------------------------------------- /socs/nrf52840_uf2.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(252)>; 34 | }; -------------------------------------------------------------------------------- /socs/nrf52840_chrysalis.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(252)>; 34 | }; -------------------------------------------------------------------------------- /socs/nrf52840_sense.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(252)>; 34 | }; -------------------------------------------------------------------------------- /socs/nrf52840_smspi.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | sram0@2003f000 { 3 | compatible = "zephyr,memory-region", "mmio-sram"; 4 | reg = <0x2003f000 DT_SIZE_K(4)>; 5 | zephyr,memory-region = "RETAINED_MEM"; 6 | status = "okay"; 7 | 8 | retainedmem0: retainedmem { 9 | compatible = "zephyr,retained-ram"; 10 | status = "okay"; 11 | }; 12 | }; 13 | 14 | sram0@20007f7c { 15 | compatible = "zephyr,memory-region", "mmio-sram"; 16 | reg = <0x20007f7c 4>; 17 | zephyr,memory-region = "DFU_DBL_RESET_MEM"; 18 | status = "okay"; 19 | 20 | retainedmem { 21 | compatible = "zephyr,retained-ram"; 22 | status = "okay"; 23 | }; 24 | }; 25 | 26 | aliases { 27 | retainedmemdevice = &retainedmem0; 28 | }; 29 | }; 30 | 31 | &sram0 { 32 | /* Shrink SRAM size to avoid overlap with retained memory region */ 33 | reg = <0x20000000 DT_SIZE_K(252)>; 34 | }; -------------------------------------------------------------------------------- /src/sensor/fusion/xiofusion/xioFusionOffset2.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file FusionOffset.h 3 | * @author Seb Madgwick 4 | * @brief Gyroscope offset correction algorithm for run-time calibration of the 5 | * gyroscope offset. 6 | */ 7 | 8 | #ifndef FUSION_OFFSET2_H 9 | #define FUSION_OFFSET2_H 10 | 11 | //------------------------------------------------------------------------------ 12 | // Includes 13 | 14 | #include "FusionOffset.h" 15 | 16 | //------------------------------------------------------------------------------ 17 | // Function declarations 18 | 19 | void FusionOffsetInitialise2(FusionOffset* const offset, const unsigned int sampleRate); 20 | 21 | FusionVector FusionOffsetUpdate2(FusionOffset* const offset, FusionVector gyroscope); 22 | 23 | #endif 24 | 25 | //------------------------------------------------------------------------------ 26 | // End of file 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tracker firmware for SlimeNRF 2 | Firmware for Nordic nRF52 / nRF54L Series SoC. 3 | 4 | Please see https://docs.slimevr.dev/smol-slimes for more information and usage. 5 | 6 | ## Hardware 7 | - https://github.com/SlimeVR/SlimeVR-Tracker-nRF-PCB 8 | - https://oshwlab.com/sctanf/slimenrf3 9 | 10 | ## License 11 | Unless otherwise specified, all code in this repository is dual-licensed under either: 12 | 13 | - MIT License ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/license/mit/) 14 | - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or https://opensource.org/license/apache-2-0/) 15 | 16 | at your option. This means you can select the license you prefer! 17 | 18 | Unless you explicitly state otherwise, any contribution intentionally submitted for 19 | inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual 20 | licensed as above, without any additional terms or conditions. 21 | -------------------------------------------------------------------------------- /src/sensor/mag/LIS2MDL.h: -------------------------------------------------------------------------------- 1 | #ifndef LIS2MDL_h 2 | #define LIS2MDL_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | // https://www.st.com/resource/en/datasheet/lis2mdl.pdf 7 | #define LIS2MDL_CFG_REG_A 0x60 8 | 9 | #define LIS2MDL_OUTX_L_REG 0x68 10 | 11 | #define LIS2MDL_TEMP_OUT_L_REG 0x6E 12 | 13 | #define ODR_10Hz 0x00 14 | #define ODR_20Hz 0x01 15 | #define ODR_50Hz 0x02 16 | #define ODR_100Hz 0x03 17 | 18 | #define MD_CONTINUOUS 0x00 19 | #define MD_SINGLE 0x01 // Performs oneshot, then switches to idle 20 | #define MD_IDLE 0x03 21 | 22 | int lis2_init(float time, float *actual_time); 23 | void lis2_shutdown(void); 24 | 25 | int lis2_update_odr(float time, float *actual_time); 26 | 27 | void lis2_mag_oneshot(void); 28 | void lis2_mag_read(float m[3]); 29 | float lis2_temp_read(float bias[3]); 30 | 31 | void lis2_mag_process(uint8_t *raw_m, float m[3]); 32 | 33 | extern const sensor_mag_t sensor_mag_lis2mdl; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_smspi.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include "promicro_uf2.dts" 6 | 7 | &i2c0_default { 8 | group1 { 9 | psels = , ; 10 | bias-disable; 11 | }; 12 | }; 13 | 14 | &i2c0_sleep { 15 | group1 { 16 | psels = , ; 17 | bias-disable; 18 | low-power-enable; 19 | }; 20 | }; 21 | 22 | &spi3_default { 23 | group1 { 24 | psels = , 25 | , 26 | ; 27 | }; 28 | }; 29 | 30 | &spi3_sleep { 31 | group1 { 32 | psels = , 33 | , 34 | ; 35 | low-power-enable; 36 | }; 37 | }; 38 | 39 | / { 40 | zephyr,user { 41 | int0-gpios = <&gpio1 0 0>; 42 | /delete-property/ clk-gpios; 43 | }; 44 | }; 45 | 46 | &spi3 { 47 | cs-gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; 48 | }; 49 | -------------------------------------------------------------------------------- /src/system/system.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIMENRF_SYSTEM 2 | #define SLIMENRF_SYSTEM 3 | 4 | #include "led.h" 5 | #include "power.h" 6 | #include "status.h" 7 | 8 | #define RBT_CNT_ID 1 9 | #define PAIRED_ID 2 10 | #define MAIN_SENSOR_DATA_ID 8 11 | #define MAIN_ACCEL_BIAS_ID 3 12 | #define MAIN_GYRO_BIAS_ID 4 13 | #define MAIN_MAG_BIAS_ID 5 14 | #define MAIN_ACC_6_BIAS_ID 7 15 | 16 | #define BATT_STATS_LAST_RUN_ID 8 17 | #define BATT_STATS_INTERVAL_0 9 // ID 9 to 28 18 | #define BATT_STATS_CURVE_ID 29 19 | 20 | #define SETTINGS_ID 30 21 | 22 | void configure_sense_pins(void); 23 | 24 | uint8_t reboot_counter_read(void); 25 | void reboot_counter_write(uint8_t reboot_counter); 26 | 27 | void sys_write(uint16_t id, void *ptr, const void *data, size_t len); 28 | void sys_read(uint16_t id, void *data, size_t len); 29 | void sys_clear(void); 30 | 31 | int set_sensor_clock(bool enable, float rate, float* actual_rate); 32 | 33 | bool button_read(void); 34 | 35 | bool dock_read(void); 36 | bool chg_read(void); 37 | bool stby_read(void); 38 | 39 | int sys_user_shutdown(void); 40 | void sys_reset_mode(uint8_t mode); 41 | 42 | #endif -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2023 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | cmake_minimum_required(VERSION 3.20.0) 7 | 8 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 9 | project(NONE) 10 | 11 | # NORDIC SDK APP START 12 | FILE(GLOB_RECURSE app_sources src/*.c) 13 | target_sources(app PRIVATE ${app_sources}) 14 | 15 | # NORDIC SDK APP END 16 | 17 | FILE(GLOB_RECURSE files Fusion/Fusion/*.c) 18 | target_sources(app PRIVATE ${files}) 19 | 20 | #FILE(GLOB_RECURSE files NXP-ISSDK-SensorFusion/sources/*.c) 21 | #target_sources(app PRIVATE ${files}) 22 | 23 | FILE(GLOB_RECURSE files vqf-c/src/*.c) 24 | target_sources(app PRIVATE ${files}) 25 | 26 | target_include_directories(app PRIVATE src) 27 | target_include_directories(app PRIVATE Fusion/Fusion) 28 | #target_include_directories(app PRIVATE NXP-ISSDK-SensorFusion/sources) 29 | target_include_directories(app PRIVATE vqf-c/src) 30 | 31 | # Force recompile for updated build timestamp 32 | add_custom_target(touch_util_h ALL 33 | COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/src/build_defines.h 34 | ) 35 | -------------------------------------------------------------------------------- /src/system/battery_tracker.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIMENRF_SYSTEM_BATTERY_TRACKER 2 | #define SLIMENRF_SYSTEM_BATTERY_TRACKER 3 | 4 | void sys_update_battery_tracker_voltage(int mV, bool plugged); 5 | void sys_update_battery_tracker(int16_t pptt, bool plugged); 6 | 7 | int16_t sys_get_calibrated_battery_pptt(int16_t pptt); 8 | 9 | int sys_get_battery_mV(void); 10 | int sys_get_valid_battery_mV(void); 11 | int16_t sys_get_valid_battery_pptt(void); 12 | uint64_t sys_get_last_unplugged_time(void); 13 | 14 | uint64_t sys_get_battery_runtime_estimate(void); 15 | uint64_t sys_get_battery_runtime_min_estimate(void); 16 | uint64_t sys_get_battery_runtime_max_estimate(void); 17 | uint64_t sys_get_battery_remaining_time_estimate(void); 18 | uint32_t sys_get_battery_cycles(void); 19 | 20 | uint8_t sys_get_battery_calibration_coverage(void); 21 | int16_t sys_get_calibrated_battery_range_min_pptt(void); 22 | int16_t sys_get_calibrated_battery_range_max_pptt(void); 23 | 24 | int16_t sys_get_last_cycle_min_pptt(void); 25 | int16_t sys_get_last_cycle_max_pptt(void); 26 | uint64_t sys_get_last_cycle_runtime(void); 27 | 28 | void sys_reset_battery_tracker(void); 29 | 30 | #endif -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 sctanf and SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /boards/nrf52840dongle_nrf52840.overlay: -------------------------------------------------------------------------------- 1 | &red_pwm_led { 2 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 3 | }; 4 | &green_pwm_led { 5 | pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 6 | }; 7 | &blue_pwm_led { 8 | pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 9 | }; 10 | 11 | / { 12 | battery-divider { 13 | compatible = "voltage-divider"; 14 | status = "okay"; 15 | io-channels = <&adc 12>; // Measure VDDHDIV5 16 | output-ohms = <1>; 17 | full-ohms = <2>; 18 | }; 19 | }; 20 | 21 | &i2c0 { 22 | compatible = "nordic,nrf-twim"; 23 | zephyr,concat-buf-size = <1023>; 24 | zephyr,flash-buf-max-size = <1023>; 25 | clock-frequency = ; 26 | 27 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 28 | compatible = "i2c-device"; 29 | label = "imu"; 30 | reg = <0>; 31 | }; 32 | 33 | mag: mag@0 { 34 | compatible = "i2c-device"; 35 | label = "mag"; 36 | reg = <0>; 37 | }; 38 | 39 | }; 40 | 41 | arduino_spi: &spi3 { 42 | imu_spi: imu_spi@0 { 43 | compatible = "vnd,spi-device"; 44 | spi-max-frequency = ; 45 | label = "imu-spi"; 46 | reg = <0>; 47 | }; 48 | }; 49 | -------------------------------------------------------------------------------- /src/sensor/mag/BMM150.h: -------------------------------------------------------------------------------- 1 | #ifndef BMM150_h 2 | #define BMM150_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | // https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmm150-ds001.pdf 7 | #define BMM150_DATAX_LSB 0x42 8 | 9 | #define BMM150_RHALL_LSB 0x48 10 | 11 | #define BMM150_POWER_CTRL 0x4B 12 | #define BMM150_OP_CTRL 0x4C 13 | 14 | #define BMM150_REP_XY 0x51 // 1+2(REP_XY) 15 | #define BMM150_REP_Z 0x52 // 1+REP_Z 16 | 17 | // taken from boschsensortec BMM150_SensorAPI 18 | #define BMM150_DIG_X1 0x5D 19 | #define BMM150_DIG_Z4_LSB 0x62 20 | #define BMM150_DIG_Z2_LSB 0x68 21 | 22 | #define DR_ODR_10Hz 0x00 23 | #define DR_ODR_2Hz 0x01 24 | #define DR_ODR_6Hz 0x02 25 | #define DR_ODR_8Hz 0x03 26 | #define DR_ODR_15Hz 0x04 27 | #define DR_ODR_20Hz 0x05 28 | #define DR_ODR_25Hz 0x06 29 | #define DR_ODR_30Hz 0x07 30 | 31 | #define OPMODE_NORMAL 0x00 32 | #define OPMODE_FORCED 0x01 33 | #define OPMODE_SLEEP 0x03 34 | 35 | int bmm1_init(float time, float *actual_time); 36 | void bmm1_shutdown(void); 37 | 38 | int bmm1_update_odr(float time, float *actual_time); 39 | 40 | void bmm1_mag_oneshot(void); 41 | void bmm1_mag_read(float m[3]); 42 | 43 | void bmm1_mag_process(uint8_t *raw_m, float m[3]); 44 | 45 | extern const sensor_mag_t sensor_mag_bmm150; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/sensor/mag/IST8306.h: -------------------------------------------------------------------------------- 1 | #ifndef IST8306_h 2 | #define IST8306_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | #define IST8306_STAT 0x10 7 | 8 | #define IST8306_DATAXL 0x11 9 | 10 | #define IST8306_ACTR 0x20 11 | #define IST8306_CNTL1 0x30 12 | #define IST8306_CNTL2 0x31 13 | #define IST8306_CNTL3 0x32 14 | #define IST8306_OSRCNTL 0x41 15 | 16 | #define NSF_Disable 0b00 17 | #define NSF_Low 0b01 18 | #define NSF_Medium 0b10 19 | #define NSF_High 0b11 20 | 21 | #define MODE_STANDBY 0x00 22 | #define MODE_SINGLE 0x01 23 | #define MODE_CMM_10Hz 0x02 24 | #define MODE_CMM_20Hz 0x04 25 | #define MODE_CMM_50Hz 0x06 26 | #define MODE_CMM_100Hz 0x08 27 | #define MODE_CMM_200Hz 0x0A 28 | #define MODE_CMM_8Hz 0x0B 29 | #define MODE_CMM_1Hz 0x0C 30 | #define MODE_CMM_0_5Hz 0x0D 31 | 32 | #define OSR_1 0b000000 33 | #define OSR_2 0b001001 34 | #define OSR_4 0b010010 35 | #define OSR_8 0b011011 36 | #define OSR_16 0b100100 37 | #define OSR_32 0b101101 38 | 39 | int ist8306_init(float time, float *actual_time); 40 | void ist8306_shutdown(void); 41 | 42 | int ist8306_update_odr(float time, float *actual_time); 43 | 44 | void ist8306_mag_oneshot(void); 45 | void ist8306_mag_read(float m[3]); 46 | 47 | void ist8306_mag_process(uint8_t *raw_m, float m[3]); 48 | 49 | extern const sensor_mag_t sensor_mag_ist8306; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/board.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nordic Semiconductor ASA. 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define ZEPHYR_USER_NODE DT_PATH(zephyr_user) 12 | 13 | #define VCC_GPIO_PIN DT_GPIO_PIN(ZEPHYR_USER_NODE, vcc_gpios) 14 | #define VCC_GPIO_PORT_NUM DT_PROP(DT_GPIO_CTLR(ZEPHYR_USER_NODE, vcc_gpios), port) 15 | 16 | static int board_promicro_init(void) 17 | { 18 | /* using vcc-gpios for sensor power defined in promicro_uf2.dts 19 | */ 20 | nrf_gpio_cfg(NRF_GPIO_PIN_MAP(VCC_GPIO_PORT_NUM, VCC_GPIO_PIN), NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_D0H1, NRF_GPIO_PIN_NOSENSE); 21 | nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(VCC_GPIO_PORT_NUM, VCC_GPIO_PIN)); 22 | /* pull down on P0.13, disables external 3V3 regulator 23 | */ 24 | nrf_gpio_cfg(NRF_GPIO_PIN_MAP(0, 13), NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE); 25 | /* if external 3V3 regulator is needed, use PULLUP instead of PULLDOWN: nrf_gpio_cfg(NRF_GPIO_PIN_MAP(0, 13), NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE); 26 | */ 27 | return 0; 28 | } 29 | 30 | SYS_INIT(board_promicro_init, PRE_KERNEL_1, 31 | CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); -------------------------------------------------------------------------------- /src/connection/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_TIMER 24 | #define SLIMENRF_TIMER 25 | 26 | #include 27 | 28 | void timer_handler(nrf_timer_event_t event_type, void* p_context); 29 | void timer_init(void); 30 | 31 | #endif -------------------------------------------------------------------------------- /src/hid.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_HID 24 | #define SLIMENRF_HID 25 | 26 | #include 27 | 28 | void hid_thread_create(void); 29 | void hid_thread_abort(void); 30 | 31 | void hid_int_in_ready(void); 32 | 33 | void hid_write_packet_n(uint8_t* data); 34 | 35 | #endif -------------------------------------------------------------------------------- /src/sensor/mag/BMM350.h: -------------------------------------------------------------------------------- 1 | #ifndef BMM350_h 2 | #define BMM350_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | // https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmm350-ds00.pdf 7 | #define BMM350_PMU_CMD_AGGR_SET 0x04 8 | #define BMM350_PMU_CMD 0x06 9 | #define BMM350_PMU_CMD_STATUS_0 0x07 10 | 11 | #define BMM350_MAG_X_XLSB 0x31 12 | 13 | #define BMM350_TEMP_XLSB 0x3A 14 | 15 | #define BMM350_OTP_CMD_REG 0x50 16 | #define BMM350_CMD 0x7E 17 | 18 | #define AGGR_ODR_400Hz 0x02 19 | #define AGGR_ODR_200Hz 0x03 20 | #define AGGR_ODR_100Hz 0x04 21 | #define AGGR_ODR_50Hz 0x05 22 | #define AGGR_ODR_25Hz 0x06 23 | #define AGGR_ODR_12_5Hz 0x07 24 | #define AGGR_ODR_6_25Hz 0x08 25 | #define AGGR_ODR_3_125Hz 0x09 26 | #define AGGR_ODR_1_5625Hz 0x0A 27 | 28 | #define AGGR_NO_AVG 0x00 29 | #define AGGR_AVG_2 0x01 30 | #define AGGR_AVG_4 0x02 31 | #define AGGR_AVG_8 0x03 32 | 33 | #define PMU_CMD_SUS 0x00 34 | #define PMU_CMD_NM 0x01 35 | #define PMU_CMD_UPD_OAE 0x02 36 | #define PMU_CMD_FM 0x03 37 | #define PMU_CMD_FM_FAST 0x04 38 | 39 | int bmm3_init(float time, float *actual_time); 40 | void bmm3_shutdown(void); 41 | 42 | int bmm3_update_odr(float time, float *actual_time); 43 | 44 | void bmm3_mag_oneshot(void); 45 | void bmm3_mag_read(float m[3]); 46 | float bmm3_temp_read(float bias[3]); 47 | 48 | void bmm3_mag_process(uint8_t *raw_m, float m[3]); 49 | 50 | extern const sensor_mag_t sensor_mag_bmm350; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/sensor/scan_spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSOR_SCAN_SPI 24 | #define SLIMENRF_SENSOR_SCAN_SPI 25 | 26 | #include 27 | 28 | int sensor_scan_spi(struct spi_dt_spec *bus, uint8_t *spi_dev_reg, int dev_addr_count, const uint8_t dev_reg[], const uint8_t dev_id[], const int dev_ids[]); 29 | 30 | #endif -------------------------------------------------------------------------------- /src/sensor/scan.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSOR_SCAN 24 | #define SLIMENRF_SENSOR_SCAN 25 | 26 | #include 27 | 28 | int sensor_scan_i2c(struct i2c_dt_spec *i2c_dev, uint8_t *i2c_dev_reg, int dev_addr_count, const uint8_t dev_addr[], const uint8_t dev_reg[], const uint8_t dev_id[], const int dev_ids[]); 29 | 30 | #endif -------------------------------------------------------------------------------- /src/sensor/mag/LIS3MDL.h: -------------------------------------------------------------------------------- 1 | #ifndef LIS3MDL_h 2 | #define LIS3MDL_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | // https://www.st.com/resource/en/datasheet/lis3mdl.pdf 7 | #define LIS3MDL_CTRL_REG1 0x20 8 | #define LIS3MDL_CTRL_REG2 0x21 9 | #define LIS3MDL_CTRL_REG3 0x22 10 | #define LIS3MDL_CTRL_REG4 0x23 11 | 12 | #define LIS3MDL_OUT_X_L 0x28 13 | 14 | #define LIS3MDL_TEMP_OUT_L 0x2E 15 | 16 | // X/Y and Z (OMZ) 17 | #define OM_LP 0x00 // Low power, 1000Hz with FAST_ODR 18 | #define OM_MP 0x01 // Medium performance, 560Hz with FAST_ODR 19 | #define OM_HP 0x02 // High performance, 300Hz with FAST_ODR 20 | #define OM_UHP 0x03 // Ultrahigh performance, 155Hz with FAST_ODR 21 | 22 | #define DO_0_625Hz 0x00 23 | #define DO_1_25Hz 0x01 24 | #define DO_2_5Hz 0x02 25 | #define DO_5Hz 0x03 26 | #define DO_10Hz 0x04 27 | #define DO_20Hz 0x05 28 | #define DO_40Hz 0x06 29 | #define DO_80Hz 0x07 30 | 31 | #define FS_4G 0x00 32 | #define FS_8G 0x01 33 | #define FS_12G 0x02 34 | #define FS_16G 0x03 35 | 36 | #define MD_CONTINUOUS_CONV 0x00 37 | #define MD_SINGLE_CONV 0x01 // <= 80Hz only 38 | #define MD_POWER_DOWN 0x03 39 | 40 | int lis3_init(float time, float *actual_time); 41 | void lis3_shutdown(void); 42 | 43 | int lis3_update_odr(float time, float *actual_time); 44 | 45 | void lis3_mag_oneshot(void); 46 | void lis3_mag_read(float m[3]); 47 | float lis3_temp_read(float bias[3]); 48 | 49 | void lis3_mag_process(uint8_t *raw_m, float m[3]); 50 | 51 | extern const sensor_mag_t sensor_mag_lis3mdl; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/sensor/scan_ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSOR_SCAN_EXT 24 | #define SLIMENRF_SENSOR_SCAN_EXT 25 | 26 | #include "interface.h" 27 | 28 | int sensor_scan_ext(const sensor_ext_ssi_t *ext_ssi, uint16_t *ext_dev_addr, uint8_t *ext_dev_reg, int dev_addr_count, const uint8_t dev_addr[], const uint8_t dev_reg[], const uint8_t dev_id[], const int dev_ids[]); 29 | 30 | #endif -------------------------------------------------------------------------------- /src/parse_args.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_PARSE_ARGS 24 | #define SLIMENRF_PARSE_ARGS 25 | 26 | #include 27 | #include 28 | 29 | size_t parse_args(char *str, char *argv[], size_t size); 30 | int32_t parse_i32(const char *ptr, uint8_t base); 31 | uint32_t parse_u32(const char *ptr, uint8_t base); 32 | uint64_t parse_u64(const char *ptr, uint8_t base); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/sensor/mag/AK09940.h: -------------------------------------------------------------------------------- 1 | #ifndef AK09940_h 2 | #define AK09940_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | // https://www.akm.com/content/dam/documents/products/tri-axis-magnetic-sensor/ak09940a/ak09940a-en-datasheet-myakm.pdf 7 | #define AK09940_ST 0x0F 8 | 9 | #define AK09940_ST1 0x10 10 | 11 | #define AK09940_HXL 0x11 12 | 13 | #define AK09940_TMPS 0x1A 14 | 15 | #define AK09940_ST2 0x1B 16 | 17 | #define AK09940_CNTL1 0x30 18 | #define AK09940_CNTL3 0x32 19 | #define AK09940_CNTL4 0x33 20 | 21 | #define MODE_PDM 0b00000 // Power-down mode 22 | #define MODE_SMM 0b00001 // Single measurement mode 23 | #define MODE_CMM1_10Hz 0b00010 // Continuous measurement modes 24 | #define MODE_CMM2_20Hz 0b00100 25 | #define MODE_CMM3_50Hz 0b00110 26 | #define MODE_CMM4_100Hz 0b01000 27 | #define MODE_CMM5_200Hz 0b01010 28 | // Low power drive 1, 2, or Ultra low power drive 29 | #define MODE_CMM6_400Hz 0b01100 30 | // Low power drive 1, or Ultra low power drive 31 | #define MODE_CMM7_1000Hz 0b01110 32 | // Ultra low power drive 33 | #define MODE_CMM8_2500Hz 0b01111 34 | 35 | #define MT_LPD1 0b00 // Low power drive 1 36 | #define MT_LPD2 0b01 // Low power drive 2 37 | #define MT_LND1 0b10 // Low noise drive 1 38 | #define MT_LND2 0b11 // Low noise drive 2 39 | 40 | int ak_init(float time, float *actual_time); 41 | void ak_shutdown(void); 42 | 43 | int ak_update_odr(float time, float *actual_time); 44 | 45 | void ak_mag_oneshot(void); 46 | void ak_mag_read(float m[3]); 47 | float ak_temp_read(float bias[3]); 48 | 49 | void ak_mag_process(uint8_t *raw_m, float m[3]); 50 | 51 | extern const sensor_mag_t sensor_mag_ak09940; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /boards/nrf52dk_nrf52832.overlay: -------------------------------------------------------------------------------- 1 | &pwm0_default { 2 | group1 { 3 | psels = , 4 | , 5 | ; 6 | nordic,drive-mode = ; 7 | nordic,invert; 8 | }; 9 | }; 10 | 11 | &pwm0_sleep { 12 | group1 { 13 | psels = , 14 | , 15 | ; 16 | }; 17 | }; 18 | 19 | / { 20 | pwmleds { 21 | pwm_led1: pwm_led_1 { 22 | pwms = <&pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 23 | }; 24 | pwm_led2: pwm_led_2 { 25 | pwms = <&pwm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 26 | }; 27 | }; 28 | 29 | battery-divider { 30 | compatible = "voltage-divider"; 31 | status = "okay"; 32 | io-channels = <&adc 12>; // Measure VDDHDIV5 33 | output-ohms = <1>; 34 | full-ohms = <2>; 35 | }; 36 | 37 | aliases { 38 | pwm-led1 = &pwm_led1; 39 | pwm-led2 = &pwm_led2; 40 | }; 41 | }; 42 | 43 | &i2c0 { 44 | compatible = "nordic,nrf-twim"; 45 | zephyr,concat-buf-size = <255>; // MAXCNT 46 | zephyr,flash-buf-max-size = <255>; 47 | clock-frequency = ; 48 | 49 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 50 | compatible = "i2c-device"; 51 | label = "imu"; 52 | reg = <0>; 53 | }; 54 | 55 | mag: mag@0 { 56 | compatible = "i2c-device"; 57 | label = "mag"; 58 | reg = <0>; 59 | }; 60 | 61 | }; 62 | 63 | arduino_spi: &spi2 { 64 | imu_spi: imu_spi@0 { 65 | compatible = "vnd,spi-device"; 66 | spi-max-frequency = ; 67 | label = "imu-spi"; 68 | reg = <0>; 69 | }; 70 | }; 71 | -------------------------------------------------------------------------------- /boards/nrf54l15dk_nrf54l15_cpuapp.overlay: -------------------------------------------------------------------------------- 1 | &pinctrl { 2 | i2c0_default: i2c0_default { 3 | group1 { 4 | psels = , 5 | ; 6 | }; 7 | }; 8 | 9 | i2c0_sleep: i2c0_sleep { 10 | group1 { 11 | psels = , 12 | ; 13 | low-power-enable; 14 | }; 15 | }; 16 | 17 | }; 18 | 19 | &pwm20_default { 20 | group1 { 21 | psels = , 22 | ; 23 | }; 24 | }; 25 | 26 | &pwm20_sleep { 27 | group1 { 28 | psels = , 29 | ; 30 | }; 31 | }; 32 | 33 | / { 34 | pwmleds { 35 | pwm_led0: pwm_led_0 { 36 | pwms = <&pwm20 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; 37 | }; 38 | }; 39 | 40 | battery-divider { 41 | compatible = "voltage-divider"; 42 | status = "okay"; 43 | io-channels = <&adc 12>; // Measure VDDHDIV5 44 | output-ohms = <1>; 45 | full-ohms = <2>; 46 | }; 47 | }; 48 | 49 | &i2c20 { 50 | compatible = "nordic,nrf-twim"; 51 | status = "okay"; 52 | zephyr,concat-buf-size = <1023>; 53 | zephyr,flash-buf-max-size = <1023>; 54 | clock-frequency = ; 55 | pinctrl-0 = <&i2c0_default>; 56 | pinctrl-1 = <&i2c0_sleep>; 57 | pinctrl-names = "default", "sleep"; 58 | 59 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 60 | compatible = "i2c-device"; 61 | label = "imu"; 62 | reg = <0>; 63 | }; 64 | 65 | mag: mag@0 { 66 | compatible = "i2c-device"; 67 | label = "mag"; 68 | reg = <0>; 69 | }; 70 | 71 | }; 72 | 73 | &uart20 { 74 | status = "disabled"; 75 | }; 76 | -------------------------------------------------------------------------------- /src/system/battery.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018-2019 Peter Bigot Consulting, LLC 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #ifndef APPLICATION_BATTERY_H_ 8 | #define APPLICATION_BATTERY_H_ 9 | 10 | /** Enable or disable measurement of the battery voltage. 11 | * 12 | * @param enable true to enable, false to disable 13 | * 14 | * @return zero on success, or a negative error code. 15 | */ 16 | int battery_measure_enable(bool enable); 17 | 18 | /** Measure the battery voltage. 19 | * 20 | * @return the battery voltage in millivolts, or a negative error 21 | * code. 22 | */ 23 | int battery_sample(void); 24 | 25 | /** A point in a battery discharge curve sequence. 26 | * 27 | * A discharge curve is defined as a sequence of these points, where 28 | * the first point has #lvl_pptt set to 10000 and the last point has 29 | * #lvl_pptt set to zero. Both #lvl_pptt and #lvl_mV should be 30 | * monotonic decreasing within the sequence. 31 | */ 32 | struct battery_level_point { 33 | /** Remaining life at #lvl_mV. */ 34 | uint16_t lvl_pptt; 35 | 36 | /** Battery voltage at #lvl_pptt remaining life. */ 37 | uint16_t lvl_mV; 38 | }; 39 | 40 | /** Calculate the estimated battery level based on a measured voltage. 41 | * 42 | * @param batt_mV a measured battery voltage level. 43 | * 44 | * @param curve the discharge curve for the type of battery installed 45 | * on the system. 46 | * 47 | * @return the estimated remaining capacity in parts per ten 48 | * thousand. 49 | */ 50 | unsigned int 51 | battery_level_pptt(unsigned int batt_mV, const struct battery_level_point* curve); 52 | 53 | unsigned int read_batt(void); 54 | 55 | unsigned int read_batt_mV(int* out); 56 | 57 | #endif /* APPLICATION_BATTERY_H_ */ 58 | -------------------------------------------------------------------------------- /boards/nordic/promicro_uf2/promicro_uf2_chrysalis.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include "promicro_uf2.dts" 6 | 7 | &pwm0_default { 8 | group1 { 9 | psels = , // Red 10 | , // Green 11 | ; // Blue 12 | nordic,drive-mode = ; 13 | nordic,invert; 14 | }; 15 | }; 16 | 17 | &pwm0_sleep { 18 | group1 { 19 | psels = , // Red 20 | , // Green 21 | ; // Blue 22 | low-power-enable; 23 | }; 24 | }; 25 | 26 | / { 27 | pwmleds { 28 | /delete-node/ pwm_led_0; 29 | pwm_led0: pwm_led_0 { 30 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; // Red 31 | }; 32 | pwm_led1: pwm_led_1 { 33 | pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_INVERTED>; // Green 34 | }; 35 | pwm_led2: pwm_led_2 { 36 | pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_INVERTED>; // Blue 37 | }; 38 | }; 39 | 40 | leds { 41 | compatible = "gpio-leds"; 42 | led0: led_0 { 43 | gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; // Red 44 | }; 45 | led1: led_1 { 46 | gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; // Green 47 | }; 48 | led2: led_2 { 49 | gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; // Blue 50 | }; 51 | }; 52 | 53 | aliases { 54 | sw0 = &button0; 55 | pwm-led0 = &pwm_led0; // Red 56 | pwm-led1 = &pwm_led1; // Green 57 | pwm-led2 = &pwm_led2; // Blue 58 | led0 = &led0; // Red 59 | led1 = &led1; // Green 60 | led2 = &led2; // Blue 61 | }; 62 | 63 | zephyr,user { 64 | clk-gpios = <&gpio0 20 GPIO_OPEN_DRAIN>; 65 | /delete-property/ led-gpios; 66 | }; 67 | }; 68 | 69 | /delete-node/ &i2c0; -------------------------------------------------------------------------------- /src/sensor/fusion/fusions.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSOR_FUSIONS 24 | #define SLIMENRF_SENSOR_FUSIONS 25 | 26 | #include "motionsense/motionsense.h" 27 | #include "xiofusion/xiofusion.h" 28 | #include "vqf/vqf.h" 29 | 30 | enum fusion { 31 | FUSION_NONE, 32 | FUSION_FUSION, 33 | FUSION_MOTIONSENSE, 34 | FUSION_VQF 35 | }; 36 | 37 | const char *fusion_names[] = { 38 | "None", 39 | "x-io Technologies Fusion", 40 | "NXP SensorFusion", 41 | "VQF" 42 | }; 43 | const sensor_fusion_t *sensor_fusions[] = { 44 | NULL, 45 | &sensor_fusion_fusion, 46 | &sensor_fusion_motionsense, 47 | &sensor_fusion_vqf 48 | }; 49 | 50 | #endif -------------------------------------------------------------------------------- /boards/nordic/test805/test805.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | &pinctrl { 8 | i2c0_default: i2c0_default { 9 | group1 { 10 | psels = , ; 11 | bias-disable; 12 | }; 13 | }; 14 | 15 | i2c0_sleep: i2c0_sleep { 16 | group1 { 17 | psels = , ; 18 | bias-disable; 19 | low-power-enable; 20 | }; 21 | }; 22 | }; 23 | 24 | / { 25 | model = "test805"; 26 | compatible = "test805"; 27 | 28 | chosen { 29 | zephyr,sram = &sram0; 30 | zephyr,flash = &flash0; 31 | }; 32 | 33 | battery-divider { 34 | compatible = "voltage-divider"; 35 | status = "okay"; 36 | io-channels = <&adc 12>; // Measure VDDHDIV5 37 | output-ohms = <1>; 38 | full-ohms = <2>; 39 | }; 40 | 41 | zephyr,user { 42 | int0-gpios = <&gpio0 0 0>; 43 | }; 44 | }; 45 | 46 | ® { 47 | regulator-initial-mode = ; 48 | }; 49 | 50 | &adc { 51 | status = "okay"; 52 | }; 53 | 54 | &i2c0 { 55 | compatible = "nordic,nrf-twim"; 56 | status = "okay"; 57 | zephyr,concat-buf-size = <1023>; 58 | zephyr,flash-buf-max-size = <1023>; 59 | clock-frequency = ; 60 | pinctrl-0 = <&i2c0_default>; 61 | pinctrl-1 = <&i2c0_sleep>; 62 | pinctrl-names = "default", "sleep"; 63 | 64 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 65 | compatible = "i2c-device"; 66 | label = "imu"; 67 | reg = <0>; 68 | }; 69 | 70 | mag: mag@0 { 71 | compatible = "i2c-device"; 72 | label = "mag"; 73 | reg = <0>; 74 | }; 75 | 76 | }; 77 | 78 | &gpio0 { 79 | status = "okay"; 80 | }; 81 | 82 | &gpiote { 83 | status = "okay"; 84 | }; 85 | -------------------------------------------------------------------------------- /boards/nrf5340dk_nrf5340_cpuapp.overlay: -------------------------------------------------------------------------------- 1 | &pwm0_default { 2 | group1 { 3 | psels = , 4 | , 5 | ; 6 | nordic,drive-mode = ; 7 | nordic,invert; 8 | }; 9 | }; 10 | 11 | &pwm0_sleep { 12 | group1 { 13 | psels = , 14 | , 15 | ; 16 | }; 17 | }; 18 | 19 | / { 20 | chosen { 21 | zephyr,console = &cdc_acm_uart0; 22 | zephyr,shell-uart = &cdc_acm_uart0; 23 | }; 24 | 25 | pwmleds { 26 | pwm_led1: pwm_led_1 { 27 | pwms = <&pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 28 | }; 29 | pwm_led2: pwm_led_2 { 30 | pwms = <&pwm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 31 | }; 32 | }; 33 | 34 | battery-divider { 35 | compatible = "voltage-divider"; 36 | status = "okay"; 37 | io-channels = <&adc 12>; // Measure VDDHDIV5 38 | output-ohms = <1>; 39 | full-ohms = <2>; 40 | }; 41 | 42 | aliases { 43 | pwm-led1 = &pwm_led1; 44 | pwm-led2 = &pwm_led2; 45 | }; 46 | }; 47 | 48 | &i2c0 { 49 | compatible = "nordic,nrf-twim"; 50 | zephyr,concat-buf-size = <1023>; 51 | zephyr,flash-buf-max-size = <1023>; 52 | clock-frequency = ; 53 | 54 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 55 | compatible = "i2c-device"; 56 | label = "imu"; 57 | reg = <0>; 58 | }; 59 | 60 | mag: mag@0 { 61 | compatible = "i2c-device"; 62 | label = "mag"; 63 | reg = <0>; 64 | }; 65 | 66 | }; 67 | 68 | arduino_spi: &spi3 { 69 | imu_spi: imu_spi@0 { 70 | compatible = "vnd,spi-device"; 71 | spi-max-frequency = ; 72 | label = "imu-spi"; 73 | reg = <0>; 74 | }; 75 | }; 76 | 77 | zephyr_udc0: &usbd { 78 | cdc_acm_uart0: cdc_acm_uart0 { 79 | compatible = "zephyr,cdc-acm-uart"; 80 | }; 81 | }; 82 | -------------------------------------------------------------------------------- /src/sensor/fusion/xiofusion/xiofusion.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_FUSION 24 | #define SLIMENRF_FUSION 25 | 26 | #include "sensor/sensor.h" 27 | 28 | void fusion_init(float g_time, float a_time, float m_time); 29 | void fusion_load(const void* data); 30 | void fusion_save(void* data); 31 | 32 | void fusion_update_gyro(float* g, float time); 33 | void fusion_update_accel(float* a, float time); 34 | void fusion_update_mag(float* m, float time); 35 | void fusion_update(float* g, float* a, float* m, float time); 36 | 37 | void fusion_get_gyro_bias(float* g_off); 38 | void fusion_set_gyro_bias(float* g_off); 39 | 40 | void fusion_update_gyro_sanity(float* g, float* m); 41 | int fusion_get_gyro_sanity(void); 42 | 43 | void fusion_get_lin_a(float* lin_a); 44 | void fusion_get_quat(float* q); 45 | 46 | extern const sensor_fusion_t sensor_fusion_fusion; 47 | 48 | #endif -------------------------------------------------------------------------------- /boards/nrf52840dk_nrf52840.overlay: -------------------------------------------------------------------------------- 1 | &pwm0_default { 2 | group1 { 3 | psels = , 4 | , 5 | ; 6 | nordic,drive-mode = ; 7 | nordic,invert; 8 | }; 9 | }; 10 | 11 | &pwm0_sleep { 12 | group1 { 13 | psels = , 14 | , 15 | ; 16 | }; 17 | }; 18 | 19 | &i2c0_default { 20 | group1 { 21 | bias-disable; 22 | }; 23 | }; 24 | 25 | &i2c0_sleep { 26 | group1 { 27 | bias-disable; 28 | }; 29 | }; 30 | 31 | / { 32 | chosen { 33 | zephyr,console = &cdc_acm_uart0; 34 | zephyr,shell-uart = &cdc_acm_uart0; 35 | }; 36 | 37 | pwmleds { 38 | pwm_led1: pwm_led_1 { 39 | pwms = <&pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 40 | }; 41 | pwm_led2: pwm_led_2 { 42 | pwms = <&pwm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 43 | }; 44 | }; 45 | 46 | battery-divider { 47 | compatible = "voltage-divider"; 48 | status = "okay"; 49 | io-channels = <&adc 12>; // Measure VDDHDIV5 50 | output-ohms = <1>; 51 | full-ohms = <2>; 52 | }; 53 | 54 | aliases { 55 | pwm-led1 = &pwm_led1; 56 | pwm-led2 = &pwm_led2; 57 | }; 58 | }; 59 | 60 | &i2c0 { 61 | compatible = "nordic,nrf-twim"; 62 | zephyr,concat-buf-size = <1023>; 63 | zephyr,flash-buf-max-size = <1023>; 64 | clock-frequency = ; 65 | 66 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 67 | compatible = "i2c-device"; 68 | label = "imu"; 69 | reg = <0>; 70 | }; 71 | 72 | mag: mag@0 { 73 | compatible = "i2c-device"; 74 | label = "mag"; 75 | reg = <0>; 76 | }; 77 | 78 | }; 79 | 80 | &spi3 { 81 | imu_spi: imu_spi@0 { 82 | compatible = "vnd,spi-device"; 83 | spi-max-frequency = ; 84 | label = "imu-spi"; 85 | reg = <0>; 86 | }; 87 | }; 88 | 89 | &usbd { 90 | cdc_acm_uart0: cdc_acm_uart0 { 91 | compatible = "zephyr,cdc-acm-uart"; 92 | }; 93 | }; 94 | -------------------------------------------------------------------------------- /src/sensor/mag/MMC5983MA.h: -------------------------------------------------------------------------------- 1 | /* 06/14/2020 Copyright Tlera Corporation 2 | 3 | Created by Kris Winer 4 | 5 | This sketch uses SDA/SCL on pins 21/20 (Ladybug default), respectively, and it uses the Ladybug STM32L432 Breakout Board. 6 | The MMC5983MA is a low power magnetometer, here used as 3 DoF in a 9 DoF absolute orientation solution. 7 | 8 | Library may be used freely and without limit with attribution. 9 | 10 | */ 11 | 12 | #ifndef MMC5983MA_h 13 | #define MMC5983MA_h 14 | 15 | #include "sensor/sensor.h" 16 | 17 | // http://www.memsic.com/userfiles/files/DataSheets/Magnetic-Sensors-Datasheets/MMC5983MA_Datasheet.pdf 18 | #define MMC5983MA_XOUT_0 0x00 19 | #define MMC5983MA_TOUT 0x07 20 | 21 | #define MMC5983MA_STATUS 0x08 22 | #define MMC5983MA_CONTROL_0 0x09 23 | #define MMC5983MA_CONTROL_1 0x0A 24 | #define MMC5983MA_CONTROL_2 0x0B 25 | 26 | // Sample rates 27 | #define MODR_ONESHOT 0x00 28 | #define MODR_1Hz 0x01 29 | #define MODR_10Hz 0x02 30 | #define MODR_20Hz 0x03 31 | #define MODR_50Hz 0x04 32 | #define MODR_100Hz 0x05 33 | #define MODR_200Hz 0x06 // BW = 0x01 only 34 | #define MODR_1000Hz 0x07 // BW = 0x11 only 35 | 36 | //Bandwidths 37 | #define MBW_100Hz 0x00 // 8 ms measurement time 38 | #define MBW_200Hz 0x01 // 4 ms 39 | #define MBW_400Hz 0x02 // 2 ms 40 | #define MBW_800Hz 0x03 // 0.5 ms 41 | 42 | // Set/Reset as a function of measurements 43 | #define MSET_1 0x00 // Set/Reset each data measurement 44 | #define MSET_25 0x01 // each 25 data measurements 45 | #define MSET_75 0x02 46 | #define MSET_100 0x03 47 | #define MSET_250 0x04 48 | #define MSET_500 0x05 49 | #define MSET_1000 0x06 50 | #define MSET_2000 0x07 51 | 52 | int mmc_init(float time, float *actual_time); 53 | void mmc_shutdown(void); 54 | 55 | int mmc_update_odr(float time, float *actual_time); 56 | 57 | void mmc_mag_oneshot(void); 58 | void mmc_mag_read(float m[3]); 59 | float mmc_temp_read(float bias[3]); 60 | 61 | void mmc_mag_process(uint8_t *raw_m, float m[3]); 62 | 63 | extern const sensor_mag_t sensor_mag_mmc5983ma; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /boards/nrf21540dk_nrf52840.overlay: -------------------------------------------------------------------------------- 1 | &pwm0_default { 2 | group1 { 3 | psels = , 4 | , 5 | ; 6 | nordic,drive-mode = ; 7 | nordic,invert; 8 | }; 9 | }; 10 | 11 | &pwm0_sleep { 12 | group1 { 13 | psels = , 14 | , 15 | ; 16 | }; 17 | }; 18 | 19 | &i2c0_default { 20 | group1 { 21 | bias-disable; 22 | }; 23 | }; 24 | 25 | &i2c0_sleep { 26 | group1 { 27 | bias-disable; 28 | }; 29 | }; 30 | 31 | / { 32 | chosen { 33 | zephyr,console = &cdc_acm_uart0; 34 | zephyr,shell-uart = &cdc_acm_uart0; 35 | }; 36 | 37 | pwmleds { 38 | pwm_led1: pwm_led_1 { 39 | pwms = <&pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 40 | }; 41 | pwm_led2: pwm_led_2 { 42 | pwms = <&pwm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; 43 | }; 44 | }; 45 | 46 | battery-divider { 47 | compatible = "voltage-divider"; 48 | status = "okay"; 49 | io-channels = <&adc 12>; // Measure VDDHDIV5 50 | output-ohms = <1>; 51 | full-ohms = <2>; 52 | }; 53 | 54 | aliases { 55 | pwm-led1 = &pwm_led1; 56 | pwm-led2 = &pwm_led2; 57 | }; 58 | }; 59 | 60 | &i2c0 { 61 | compatible = "nordic,nrf-twim"; 62 | zephyr,concat-buf-size = <1023>; 63 | zephyr,flash-buf-max-size = <1023>; 64 | clock-frequency = ; 65 | 66 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 67 | compatible = "i2c-device"; 68 | label = "imu"; 69 | reg = <0>; 70 | }; 71 | 72 | mag: mag@0 { 73 | compatible = "i2c-device"; 74 | label = "mag"; 75 | reg = <0>; 76 | }; 77 | 78 | }; 79 | 80 | &spi3 { 81 | cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ 82 | imu_spi: imu_spi@0 { 83 | compatible = "vnd,spi-device"; 84 | spi-max-frequency = ; 85 | label = "imu-spi"; 86 | reg = <0>; 87 | }; 88 | }; 89 | 90 | &usbd { 91 | cdc_acm_uart0: cdc_acm_uart0 { 92 | compatible = "zephyr,cdc-acm-uart"; 93 | }; 94 | }; 95 | -------------------------------------------------------------------------------- /src/sensor/fusion/vqf/vqf.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_VQF 24 | #define SLIMENRF_VQF 25 | 26 | #include "sensor/sensor.h" 27 | 28 | void vqf_update_sensor_ids(int imu); 29 | 30 | void vqf_init(float g_time, float a_time, float m_time); 31 | void vqf_load(const void *data); 32 | void vqf_save(void *data); 33 | 34 | void vqf_update_gyro(float *g, float time); 35 | void vqf_update_accel(float *a, float time); 36 | void vqf_update_mag(float *m, float time); 37 | void vqf_update(float *g, float *a, float *m, float time); 38 | 39 | void vqf_get_gyro_bias(float *g_off); 40 | void vqf_set_gyro_bias(float *g_off); 41 | 42 | void vqf_update_gyro_sanity(float *g, float *m); 43 | int vqf_get_gyro_sanity(void); 44 | 45 | void vqf_get_lin_a(float *lin_a); 46 | void vqf_get_quat(float *q); 47 | 48 | bool vqf_get_rest_detected(void); 49 | void vqf_get_relative_rest_deviations(float *out); 50 | 51 | extern const sensor_fusion_t sensor_fusion_vqf; 52 | 53 | #endif -------------------------------------------------------------------------------- /src/sensor/fusion/motionsense/motionsense.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSORFUSION 24 | #define SLIMENRF_SENSORFUSION 25 | 26 | #include "sensor/sensor.h" 27 | 28 | void sensorfusion_init(float g_time, float a_time, float m_time); 29 | void sensorfusion_load(const void* data); 30 | void sensorfusion_save(void* data); 31 | 32 | void sensorfusion_update_gyro(float* g, float time); 33 | void sensorfusion_update_accel(float* a, float time); 34 | void sensorfusion_update_mag(float* m, float time); 35 | void sensorfusion_update(float* g, float* a, float* m, float time); 36 | 37 | void sensorfusion_get_gyro_bias(float* g_off); 38 | void sensorfusion_set_gyro_bias(float* g_off); 39 | 40 | void sensorfusion_update_gyro_sanity(float* g, float* m); 41 | int sensorfusion_get_gyro_sanity(void); 42 | 43 | void sensorfusion_get_lin_a(float* lin_a); 44 | void sensorfusion_get_quat(float* q); 45 | 46 | extern const sensor_fusion_t sensor_fusion_motionsense; 47 | 48 | #endif -------------------------------------------------------------------------------- /src/connection/connection.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_CONNECTION 24 | #define SLIMENRF_CONNECTION 25 | 26 | void connection_clocks_request_start(void); 27 | void connection_clocks_request_start_delay_us(uint32_t delay_us); 28 | void connection_clocks_request_stop(void); 29 | void connection_clocks_request_stop_delay_us(uint32_t delay_us); 30 | 31 | uint8_t connection_get_id(void); 32 | void connection_set_id(uint8_t id); 33 | 34 | void connection_update_sensor_ids(int imu_id, int mag_id); 35 | void connection_update_sensor_data(float *q, float *a, int64_t data_time); // ticks 36 | void connection_update_sensor_mag(float *m); 37 | void connection_update_sensor_temp(float temp); 38 | void connection_update_battery( 39 | bool battery_available, 40 | bool plugged, 41 | uint32_t battery_pptt, 42 | int battery_mV 43 | ); 44 | void connection_update_status(int status); 45 | 46 | void connection_write_packet_0(); 47 | void connection_write_packet_1(); 48 | void connection_write_packet_2(); 49 | void connection_write_packet_3(); 50 | void connection_write_packet_4(); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/connection/esb.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_ESB 24 | #define SLIMENRF_ESB 25 | 26 | #include 27 | #include 28 | 29 | // TODO: timer? 30 | #define LAST_RESET_LIMIT 10 31 | extern uint8_t last_reset; 32 | // TODO: move to esb/timer 33 | // extern const nrfx_timer_t m_timer; 34 | extern bool esb_state; 35 | extern bool timer_state; 36 | extern bool send_data; 37 | // TODO: esb/sensor? 38 | extern uint16_t led_clock; 39 | extern uint32_t led_clock_offset; 40 | 41 | void event_handler(struct esb_evt const* event); 42 | int clocks_start(void); 43 | void clocks_stop(void); 44 | void clocks_request_start(uint32_t delay_us); 45 | void clocks_request_stop(uint32_t delay_us); 46 | int esb_initialize(bool); 47 | void esb_deinitialize(void); 48 | 49 | void esb_set_addr_discovery(void); 50 | void esb_set_addr_paired(void); 51 | 52 | void esb_set_pair(uint64_t addr); 53 | 54 | void esb_pair(void); 55 | void esb_reset_pair(void); 56 | void esb_clear_pair(void); 57 | 58 | void esb_write(uint8_t* data); // TODO: give packets some names 59 | 60 | bool esb_ready(void); 61 | 62 | #endif -------------------------------------------------------------------------------- /src/usb.c: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "console.h" 3 | #include "hid.h" 4 | #include "system/status.h" 5 | 6 | #if CONFIG_USB_DEVICE_STACK 7 | #define USB DT_NODELABEL(usbd) 8 | #define USB_EXISTS (DT_NODE_HAS_STATUS(USB, okay) && CONFIG_UART_CONSOLE) 9 | #endif 10 | 11 | #if USB_EXISTS 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | static bool configured; 18 | 19 | LOG_MODULE_REGISTER(usb, LOG_LEVEL_INF); 20 | 21 | static void usb_init_thread(void); 22 | K_THREAD_DEFINE(usb_init_thread_id, 256, usb_init_thread, NULL, NULL, NULL, USB_INIT_THREAD_PRIORITY, 0, 500); // Wait before enabling USB 23 | 24 | static void status_cb(enum usb_dc_status_code status, const uint8_t *param) 25 | { 26 | const struct log_backend *backend = log_backend_get_by_name("log_backend_uart"); 27 | const struct device *const cons = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); 28 | switch (status) 29 | { 30 | case USB_DC_RESET: 31 | configured = false; 32 | break; 33 | case USB_DC_CONNECTED: 34 | set_status(SYS_STATUS_USB_CONNECTED, true); 35 | pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME); 36 | log_backend_enable(backend, backend->cb->ctx, CONFIG_LOG_MAX_LEVEL); 37 | console_thread_create(); 38 | #if CONFIG_CONNECTION_OVER_HID 39 | hid_thread_create(); 40 | #endif 41 | break; 42 | #if CONFIG_CONNECTION_OVER_HID 43 | case USB_DC_CONFIGURED: 44 | int configurationIndex = *param; 45 | if (configurationIndex == 0) 46 | { 47 | // from usb_device.c: A configuration index of 0 unconfigures the device. 48 | configured = false; 49 | } 50 | else 51 | { 52 | if (!configured) 53 | { 54 | hid_int_in_ready(); 55 | configured = true; 56 | } 57 | } 58 | break; 59 | #endif 60 | case USB_DC_DISCONNECTED: 61 | set_status(SYS_STATUS_USB_CONNECTED, false); 62 | #if CONFIG_CONNECTION_OVER_HID 63 | hid_thread_abort(); 64 | #endif 65 | console_thread_abort(); 66 | log_backend_disable(backend); 67 | pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND); 68 | break; 69 | case USB_DC_SOF: 70 | break; 71 | default: 72 | LOG_DBG("status %u unhandled", status); 73 | break; 74 | } 75 | } 76 | 77 | static void usb_init_thread(void) 78 | { 79 | usb_enable(status_cb); 80 | } 81 | 82 | #endif -------------------------------------------------------------------------------- /src/sensor/calibration.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSOR_CALIBRATION 24 | #define SLIMENRF_SENSOR_CALIBRATION 25 | 26 | /* Sensor feeds data to calibration */ 27 | void sensor_calibration_process_accel(float a[3]); 28 | void sensor_calibration_process_gyro(float g[3]); 29 | void sensor_calibration_process_mag(float m[3]); 30 | 31 | void sensor_calibration_update_sensor_ids(int imu); 32 | uint8_t *sensor_calibration_get_sensor_data(); 33 | 34 | void sensor_calibration_read(void); 35 | 36 | int sensor_calibration_validate(float *a_bias, float *g_bias, bool write); 37 | #if CONFIG_SENSOR_USE_6_SIDE_CALIBRATION 38 | int sensor_calibration_validate_6_side(float a_inv[][3], bool write); 39 | #endif 40 | int sensor_calibration_validate_mag(float m_inv[][3], bool write); 41 | 42 | void sensor_calibration_clear(float *a_bias, float *g_bias, bool write); 43 | #if CONFIG_SENSOR_USE_6_SIDE_CALIBRATION 44 | void sensor_calibration_clear_6_side(float a_inv[][3], bool write); 45 | #endif 46 | void sensor_calibration_clear_mag(float m_inv[][3], bool write); // "request" mag cal 47 | 48 | void sensor_request_calibration(void); 49 | void sensor_request_calibration_6_side(void); 50 | void sensor_request_calibration_mag(void); 51 | 52 | #endif -------------------------------------------------------------------------------- /src/sensor/sensor_none.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSOR_NONE 24 | #define SLIMENRF_SENSOR_NONE 25 | 26 | #include "sensor.h" 27 | 28 | int imu_none_init(float clock_rate, float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 29 | void imu_none_shutdown(void); 30 | 31 | int imu_none_update_odr(float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 32 | 33 | uint16_t imu_none_fifo_read(uint8_t *data, uint16_t len); 34 | int imu_none_fifo_process(uint16_t index, uint8_t *data, float a[3], float g[3]); 35 | void imu_none_accel_read(float a[3]); 36 | void imu_none_gyro_read(float g[3]); 37 | float imu_none_temp_read(void); 38 | 39 | uint8_t imu_none_setup_WOM(void); 40 | 41 | int imu_none_ext_setup(void); 42 | int imu_none_ext_passthrough(bool passthrough); 43 | 44 | extern const sensor_imu_t sensor_imu_none; 45 | 46 | int mag_none_init(float time, float *actual_time); 47 | void mag_none_shutdown(void); 48 | 49 | int mag_none_update_odr(float time, float *actual_time); 50 | 51 | void mag_none_mag_oneshot(void); 52 | void mag_none_mag_read(float m[3]); 53 | float mag_none_temp_read(float bias[3]); 54 | 55 | void mag_none_mag_process(uint8_t *raw_m, float m[3]); 56 | 57 | extern const sensor_mag_t sensor_mag_none; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/system/status.c: -------------------------------------------------------------------------------- 1 | #include "globals.h" 2 | #include "connection/connection.h" 3 | 4 | #include 5 | 6 | #include "status.h" 7 | #include "led.h" 8 | 9 | static int status_state = 0; 10 | 11 | LOG_MODULE_REGISTER(status, LOG_LEVEL_INF); 12 | 13 | static void status_thread(void); 14 | K_THREAD_DEFINE(status_thread_id, 256, status_thread, NULL, NULL, NULL, STATUS_THREAD_PRIORITY, 0, 0); 15 | 16 | void set_status(enum sys_status status, bool set) { 17 | if (set) { 18 | status_state |= status; 19 | switch (status) 20 | { 21 | case SYS_STATUS_SENSOR_ERROR: 22 | LOG_ERR("Sensor communication error"); 23 | break; 24 | case SYS_STATUS_CONNECTION_ERROR: 25 | LOG_WRN("Connection error"); 26 | break; 27 | case SYS_STATUS_SYSTEM_ERROR: 28 | LOG_ERR("General error"); 29 | break; 30 | case SYS_STATUS_USB_CONNECTED: 31 | LOG_INF("USB connected"); 32 | break; 33 | case SYS_STATUS_PLUGGED: 34 | LOG_INF("Charger plugged"); 35 | break; 36 | case SYS_STATUS_CALIBRATION_RUNNING: 37 | LOG_INF("Calibration running"); 38 | break; 39 | case SYS_STATUS_BUTTON_PRESSED: 40 | LOG_INF("Button pressed"); 41 | break; 42 | default: 43 | break; 44 | } 45 | } else { 46 | status_state &= ~status; 47 | LOG_INF("Cleared status: %d", status); 48 | } 49 | connection_update_status(status_state); 50 | LOG_INF("Status: %d", status_state); 51 | } 52 | 53 | bool get_status(enum sys_status status) 54 | { 55 | return status_state & status; 56 | } 57 | 58 | static void status_thread(void) 59 | { 60 | while (1) // cycle through errors 61 | { 62 | int status = status_state 63 | & (SYS_STATUS_SENSOR_ERROR | SYS_STATUS_CONNECTION_ERROR 64 | | SYS_STATUS_SYSTEM_ERROR); 65 | if (status & SYS_STATUS_SENSOR_ERROR) { 66 | set_led(SYS_LED_PATTERN_ERROR_A, SYS_LED_PRIORITY_STATUS); 67 | k_msleep(5000); 68 | } 69 | if (status & SYS_STATUS_CONNECTION_ERROR) { 70 | set_led(SYS_LED_PATTERN_ERROR_B, SYS_LED_PRIORITY_STATUS); 71 | k_msleep(5000); 72 | } 73 | if (status & SYS_STATUS_SYSTEM_ERROR) { 74 | set_led(SYS_LED_PATTERN_ERROR_C, SYS_LED_PRIORITY_STATUS); 75 | k_msleep(5000); 76 | } 77 | if (!status) { 78 | set_led(SYS_LED_PATTERN_OFF, SYS_LED_PRIORITY_STATUS); 79 | k_msleep(100); 80 | } 81 | } 82 | } 83 | 84 | bool status_ready(void) // true if no important statuses are active 85 | { 86 | return (status_state & ~SYS_STATUS_CONNECTION_ERROR) 87 | == 0; // connection error is temporary, not critical 88 | } 89 | -------------------------------------------------------------------------------- /boards/xiao_ble_nrf52840_sense.overlay: -------------------------------------------------------------------------------- 1 | &i2c0_default { 2 | group1 { 3 | bias-disable; 4 | }; 5 | }; 6 | 7 | &i2c0_sleep { 8 | group1 { 9 | bias-disable; 10 | }; 11 | }; 12 | 13 | &pwm0_default { 14 | group1 { 15 | psels = , 16 | , 17 | ; 18 | nordic,drive-mode = ; 19 | nordic,invert; 20 | }; 21 | }; 22 | 23 | &pwm0_sleep { 24 | group1 { 25 | psels = , 26 | , 27 | ; 28 | }; 29 | }; 30 | 31 | / { 32 | pwmleds { 33 | pwm_led0: pwm_led_0 { 34 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 35 | }; 36 | pwm_led1: pwm_led_1 { 37 | pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 38 | }; 39 | pwm_led2: pwm_led_2 { 40 | pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 41 | }; 42 | }; 43 | 44 | lsm6ds3tr-c-en { 45 | startup-delay-us = <0>; 46 | }; 47 | 48 | buttons { 49 | compatible = "gpio-keys"; 50 | button0: button_0 { 51 | gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 52 | label = "Push button switch 0"; 53 | }; 54 | }; 55 | 56 | aliases { 57 | // sw0 = &button0; // Uncomment to Enable SW0 58 | pwm-led1 = &pwm_led1; 59 | pwm-led2 = &pwm_led2; 60 | }; 61 | 62 | battery-divider { 63 | compatible = "voltage-divider"; 64 | status = "okay"; 65 | io-channels = <&adc 7>; 66 | output-ohms = <510000>; 67 | full-ohms = <(1000000+510000)>; 68 | power-gpios = <&gpio0 14 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 69 | }; 70 | 71 | zephyr,user { 72 | int0-gpios = <&gpio0 11 0>; 73 | led-gpios = <&gpio0 17 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 74 | }; 75 | 76 | }; 77 | 78 | /delete-node/ &uart0; 79 | 80 | &i2c0 { 81 | zephyr,concat-buf-size = <1023>; 82 | zephyr,flash-buf-max-size = <1023>; 83 | 84 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 85 | compatible = "i2c-device"; 86 | label = "imu"; 87 | reg = <0>; 88 | }; 89 | 90 | }; 91 | 92 | /delete-node/ &i2c1; 93 | /delete-node/ &spi2; 94 | /delete-node/ &qspi; 95 | 96 | &cryptocell { 97 | status = "disabled"; 98 | }; 99 | 100 | &nfct { 101 | status = "disabled"; 102 | }; 103 | 104 | &lsm6ds3tr_c { 105 | status = "disabled"; 106 | /delete-property/ irq-gpios; 107 | }; 108 | -------------------------------------------------------------------------------- /src/system/led.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIMENRF_SYSTEM_LED 2 | #define SLIMENRF_SYSTEM_LED 3 | 4 | /* 5 | LED priorities (0 is highest) 6 | 0: boot/power 7 | 1: sensor 8 | 2: connection (esb) 9 | 3: status 10 | 4: system (persist) 11 | */ 12 | 13 | #define SYS_LED_PRIORITY_HIGHEST 0 14 | #define SYS_LED_PRIORITY_BOOT 0 15 | #define SYS_LED_PRIORITY_SENSOR 1 16 | #define SYS_LED_PRIORITY_CONNECTION 2 17 | #define SYS_LED_PRIORITY_STATUS 3 18 | #define SYS_LED_PRIORITY_SYSTEM 4 19 | #define SYS_LED_PATTERN_DEPTH 5 20 | 21 | // RGB 22 | // Red, Green, Blue 23 | 24 | // Tri-color 25 | // Red/Amber, Green, YellowGreen/White 26 | 27 | // RG 28 | // Red, Green 29 | 30 | // Dual color 31 | // Red/Amber, YellowGreen/White 32 | 33 | // TODO: these patterns are kinda funky 34 | enum sys_led_pattern { 35 | SYS_LED_PATTERN_OFF_FORCE, // ignores lower priority patterns 36 | 37 | SYS_LED_PATTERN_OFF, // yield to lower priority patterns 38 | SYS_LED_PATTERN_ON, // Default | indicates busy 39 | SYS_LED_PATTERN_SHORT, // 100ms on 900ms off // Pairing | indicates waiting (pairing) 40 | SYS_LED_PATTERN_LONG, // 500ms on 500ms off // Default | indicates waiting 41 | SYS_LED_PATTERN_FLASH, // 200ms on 200ms off // Default | indicates readiness 42 | 43 | SYS_LED_PATTERN_ONESHOT_POWERON, // 200ms on 200ms off, 3 times // Default 44 | SYS_LED_PATTERN_ONESHOT_POWEROFF, // 250ms off, 1000ms fade to off // Default 45 | SYS_LED_PATTERN_ONESHOT_PROGRESS, // 200ms on 200ms off, 2 times // Success 46 | SYS_LED_PATTERN_ONESHOT_COMPLETE, // 200ms on 200ms off, 4 times // Success 47 | 48 | SYS_LED_PATTERN_ON_PERSIST, // 20% duty cycle // Success | indicates charged 49 | SYS_LED_PATTERN_LONG_PERSIST, // 20% duty cycle, 500ms on 500ms off // Charging| indicates low battery 50 | SYS_LED_PATTERN_PULSE_PERSIST, // 5000ms pulsing // Charging| indicates charging 51 | SYS_LED_PATTERN_ACTIVE_PERSIST, // 300ms on 9700ms off // Default | indicates normal operation 52 | 53 | SYS_LED_PATTERN_ERROR_A, // 500ms on 500ms off, 2 times, every 5000ms // Error 54 | SYS_LED_PATTERN_ERROR_B, // 500ms on 500ms off, 3 times, every 5000ms // Error 55 | SYS_LED_PATTERN_ERROR_C, // 500ms on 500ms off, 4 times, every 5000ms // Error 56 | SYS_LED_PATTERN_ERROR_D, // 500ms on 500ms off (same as SYS_LED_PATTERN_LONG) // Error 57 | }; 58 | 59 | enum sys_led_color { 60 | SYS_LED_COLOR_DEFAULT, 61 | SYS_LED_COLOR_SUCCESS, 62 | SYS_LED_COLOR_ERROR, 63 | SYS_LED_COLOR_CHARGING, 64 | SYS_LED_COLOR_PAIRING, 65 | }; 66 | 67 | void set_led(enum sys_led_pattern led_pattern, int priority); 68 | 69 | #endif -------------------------------------------------------------------------------- /src/sensor/fusion/motionsense/motionsense.c: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #include "globals.h" 24 | #include "util.h" 25 | 26 | //#include 27 | 28 | #include "motionsense.h" 29 | 30 | LOG_MODULE_REGISTER(sensorfusion, LOG_LEVEL_INF); 31 | 32 | void sensorfusion_init(float g_time, float a_time, float m_time) {} 33 | 34 | void sensorfusion_load(const void* data) {} 35 | 36 | void sensorfusion_save(void* data) {} 37 | 38 | void sensorfusion_update_gyro(float* g, float time) {} 39 | 40 | void sensorfusion_update_accel(float* a, float time) {} 41 | 42 | void sensorfusion_update_mag(float* m, float time) {} 43 | 44 | void sensorfusion_update(float* g, float* a, float* m, float time) {} 45 | 46 | void sensorfusion_get_gyro_bias(float* g_off) {} 47 | 48 | void sensorfusion_set_gyro_bias(float* g_off) {} 49 | 50 | void sensorfusion_update_gyro_sanity(float* g, float* m) {} 51 | 52 | int sensorfusion_get_gyro_sanity(void) { return -1; } 53 | 54 | void sensorfusion_get_lin_a(float* lin_a) {} 55 | 56 | void sensorfusion_get_quat(float* q) {} 57 | 58 | const sensor_fusion_t sensor_fusion_motionsense 59 | = {*sensorfusion_init, 60 | *sensorfusion_load, 61 | *sensorfusion_save, 62 | 63 | *sensorfusion_update_gyro, 64 | *sensorfusion_update_accel, 65 | *sensorfusion_update_mag, 66 | *sensorfusion_update, 67 | 68 | *sensorfusion_get_gyro_bias, 69 | *sensorfusion_set_gyro_bias, 70 | 71 | *sensorfusion_update_gyro_sanity, 72 | *sensorfusion_get_gyro_sanity, 73 | 74 | *sensorfusion_get_lin_a, 75 | *sensorfusion_get_quat}; 76 | -------------------------------------------------------------------------------- /src/retained.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "retained.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "build_defines.h" 19 | 20 | #if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(retainedmemdevice)) 21 | #define MEMORY_REGION DT_PARENT(DT_ALIAS(retainedmemdevice)) 22 | #else 23 | #error "retained_mem region not defined" 24 | #endif 25 | 26 | struct retained_data *retained = (struct retained_data *)DT_REG_ADDR(MEMORY_REGION); 27 | 28 | #define RETAINED_CRC_OFFSET offsetof(struct retained_data, crc) 29 | #define RETAINED_CHECKED_SIZE (RETAINED_CRC_OFFSET + sizeof(retained->crc)) 30 | 31 | static uint64_t init_time; 32 | 33 | static int retained_init(void) 34 | { 35 | init_time = k_uptime_ticks(); // Get current uptime in ticks as soon as possible 36 | return 0; 37 | } 38 | 39 | // TODO: priority? 40 | SYS_INIT(retained_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); 41 | 42 | bool retained_validate(void) 43 | { 44 | NRF_STATIC_ASSERT((RETAINED_CHECKED_SIZE <= 1024), "Retained data size exceeds 1 KB limit"); 45 | 46 | uint64_t now = init_time; 47 | // uint64_t now = k_uptime_ticks(); // Get current uptime in ticks as soon as possible 48 | 49 | /* The residue of a CRC is what you get from the CRC over the 50 | * message catenated with its CRC. This is the post-final-xor 51 | * residue for CRC-32 (CRC-32/ISO-HDLC) which Zephyr calls 52 | * crc32_ieee. 53 | */ 54 | const uint32_t residue = 0x2144df1c; 55 | uint32_t crc = crc32_ieee((const uint8_t *)retained, 56 | RETAINED_CHECKED_SIZE); 57 | bool valid = (crc == residue); 58 | 59 | /* Check the build timestamp of the firmware that last updated 60 | * the retained data. 61 | */ 62 | valid &= (retained->build_timestamp == BUILD_TIMESTAMP); 63 | 64 | /* If the CRC isn't valid or the build timestamp is different 65 | * from the current build timestamp, reset the retained data. 66 | */ 67 | if (!valid) { 68 | memset(retained, 0, sizeof(struct retained_data)); 69 | retained->build_timestamp = BUILD_TIMESTAMP; 70 | } 71 | 72 | /* Reset to accrue runtime from this session. */ 73 | retained->uptime_latest = now; 74 | retained->battery_uptime_latest = now; 75 | 76 | return valid; 77 | } 78 | 79 | void retained_update(void) 80 | { 81 | uint64_t now = k_uptime_ticks(); 82 | 83 | retained->uptime_sum += (now - retained->uptime_latest); 84 | retained->uptime_latest = now; 85 | 86 | uint32_t crc = crc32_ieee((const uint8_t *)retained, 87 | RETAINED_CRC_OFFSET); 88 | 89 | retained->crc = sys_cpu_to_le32(crc); 90 | } 91 | -------------------------------------------------------------------------------- /src/sensor/imu/BMI270.h: -------------------------------------------------------------------------------- 1 | #ifndef BMI270_h 2 | #define BMI270_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | #define BMI270_INTERNAL_STATUS 0x21 7 | 8 | #define BMI270_DATA_8 0x0C // accel 9 | #define BMI270_DATA_14 0x12 // gyro 10 | #define BMI270_TEMPERATURE_0 0x22 11 | 12 | #define BMI270_FIFO_LENGTH_0 0x24 13 | #define BMI270_FIFO_DATA 0x26 14 | 15 | #define BMI270_FEAT_PAGE 0x2F 16 | // page 0 17 | #define BMI270_GYR_GAIN_STATUS 0x38 18 | #define BMI270_GYR_CAS 0x3C 19 | // page 1 20 | #define BMI270_G_TRIG_1 0x32 21 | #define BMI270_ANYMO_1 0x3C 22 | #define BMI270_ANYMO_2 0x3E 23 | 24 | #define BMI270_ACC_CONF 0x40 25 | #define BMI270_ACC_RANGE 0x41 26 | #define BMI270_GYR_CONF 0x42 27 | #define BMI270_GYR_RANGE 0x43 28 | 29 | #define BMI270_FIFO_WTM_0 0x46 30 | #define BMI270_FIFO_CONFIG_0 0x48 31 | #define BMI270_FIFO_CONFIG_1 0x49 32 | 33 | #define BMI270_INT1_IO_CTRL 0x53 34 | #define BMI270_INT1_MAP_FEAT 0x56 35 | #define BMI270_INT_MAP_DATA 0x58 36 | 37 | #define BMI270_INIT_CTRL 0x59 38 | #define BMI270_INIT_ADDR_0 0x5B 39 | #define BMI270_INIT_ADDR_1 0x5C 40 | #define BMI270_INIT_DATA 0x5E 41 | 42 | #define BMI270_GYR_CRT_CONF 0x69 43 | #define BMI270_OFFSET_6 0x77 44 | #define BMI270_GYR_USR_GAIN 0x78 45 | 46 | #define BMI270_PWR_CONF 0x7C 47 | #define BMI270_PWR_CTRL 0x7D 48 | #define BMI270_CMD 0x7E 49 | 50 | // accel only 51 | #define ODR_0p78 0x01 52 | #define ODR_1p5 0x02 53 | #define ODR_3p1 0x03 54 | #define ODR_6p25 0x04 55 | #define ODR_12p5 0x05 56 | // accel and gyro 57 | #define ODR_25 0x06 58 | #define ODR_50 0x07 59 | #define ODR_100 0x08 60 | #define ODR_200 0x09 61 | #define ODR_400 0x0a 62 | #define ODR_800 0x0b 63 | #define ODR_1k6 0x0c 64 | // gyro only 65 | #define ODR_3k2 0x0d 66 | 67 | #define RANGE_2G 0x00 68 | #define RANGE_4G 0x01 69 | #define RANGE_8G 0x02 70 | #define RANGE_16G 0x03 71 | 72 | #define RANGE_2000 0x00 73 | #define RANGE_1000 0x01 74 | #define RANGE_500 0x02 75 | #define RANGE_250 0x03 76 | #define RANGE_125 0x04 77 | 78 | int bmi_init(float clock_rate, float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 79 | void bmi_shutdown(void); 80 | 81 | void bmi_update_fs(float accel_range, float gyro_range, float *accel_actual_range, float *gyro_actual_range); 82 | int bmi_update_odr(float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 83 | 84 | uint16_t bmi_fifo_read(uint8_t *data, uint16_t len); 85 | int bmi_fifo_process(uint16_t index, uint8_t *data, float a[3], float g[3]); 86 | void bmi_accel_read(float a[3]); 87 | void bmi_gyro_read(float g[3]); 88 | float bmi_temp_read(void); 89 | 90 | uint8_t bmi_setup_DRDY(uint16_t threshold); 91 | uint8_t bmi_setup_WOM(void); 92 | 93 | int bmi_crt(uint8_t *data); 94 | void bmi_gain_apply(uint8_t *data); 95 | 96 | extern const sensor_imu_t sensor_imu_bmi270; 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/retained.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #ifndef RETAINED_H_ 8 | #define RETAINED_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct retained_data { 15 | /* The build version of the firmware that last updated the 16 | * retained data. 17 | */ 18 | uint32_t build_timestamp; 19 | 20 | /* The uptime from the current session the last time the 21 | * retained data was updated. 22 | */ 23 | uint64_t uptime_latest; 24 | 25 | /* Cumulative uptime from all previous sessions up through 26 | * uptime_latest of this session. 27 | */ 28 | uint64_t uptime_sum; 29 | 30 | /* Battery statistics. Tracking for discharge curve only begins 31 | * after ~3% discharged. If battery_pptt has changed significantly 32 | * compared to min_battery_pptt since the last update, 33 | * the statistics are cleared and may be saved to NVS. 34 | */ 35 | int16_t max_battery_pptt; 36 | int16_t min_battery_pptt; 37 | 38 | /* Battery uptime from last retained update */ 39 | uint64_t battery_uptime_latest; 40 | 41 | /* Cumulative runtime */ 42 | uint64_t battery_runtime_sum; 43 | 44 | /* Last interval stored in NVS */ 45 | int16_t battery_pptt_saved; 46 | uint64_t battery_runtime_saved; 47 | 48 | /* Calibrated discharge curve */ 49 | int16_t battery_pptt_curve[18]; 50 | 51 | uint8_t reboot_counter; 52 | uint8_t paired_addr[8]; 53 | 54 | uint8_t sensor_data[128]; 55 | 56 | float accelBias[3]; 57 | float gyroBias[3]; 58 | float magBias[3]; 59 | float magBAinv[4][3]; 60 | float accBAinv[4][3]; 61 | 62 | uint8_t fusion_id; // fusion_data_stored 63 | uint8_t fusion_data[512]; 64 | 65 | uint16_t imu_addr; 66 | uint16_t mag_addr; 67 | 68 | uint8_t imu_reg; 69 | uint8_t mag_reg; 70 | 71 | uint8_t settings[128]; 72 | 73 | /* CRC used to validate the retained data. This must be 74 | * stored little-endian, and covers everything up to but not 75 | * including this field. 76 | */ 77 | uint32_t crc; 78 | }; 79 | 80 | /* Up to 1 KB of retained data allowed right now. 81 | */ 82 | #define RETAINED_SIZE (sizeof(struct retained_data)) 83 | 84 | /* For simplicity in the sample just allow anybody to see and 85 | * manipulate the retained state. 86 | */ 87 | extern struct retained_data *retained; 88 | 89 | /* Check whether the retained data is valid, and if not reset it. 90 | * 91 | * @return true if and only if the data was valid and reflects state 92 | * from previous sessions. 93 | */ 94 | bool retained_validate(void); 95 | 96 | /* Update any generic retained state and recalculate its checksum so 97 | * subsequent boots can verify the retained state. 98 | */ 99 | void retained_update(void); 100 | 101 | #endif /* RETAINED_H_ */ -------------------------------------------------------------------------------- /src/sensor/imu/LSM6DSM.h: -------------------------------------------------------------------------------- 1 | #ifndef LSM6DSM_h 2 | #define LSM6DSM_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | // https://www.st.com/resource/en/datasheet/lsm6dsm.pdf 7 | #define LSM6DSM_FIFO_CTRL1 0x06 8 | #define LSM6DSM_FIFO_CTRL3 0x08 9 | #define LSM6DSM_FIFO_CTRL5 0x0A 10 | 11 | #define LSM6DSM_INT1_CTRL 0x0D 12 | 13 | #define LSM6DSM_CTRL1 0x10 14 | #define LSM6DSM_CTRL2 0x11 15 | #define LSM6DSM_CTRL3 0x12 16 | #define LSM6DSM_CTRL4 0x13 17 | #define LSM6DSM_CTRL6 0x15 18 | #define LSM6DSM_CTRL7 0x16 19 | #define LSM6DSM_CTRL8 0x17 20 | 21 | #define LSM6DSM_FIFO_STATUS1 0x3A 22 | #define LSM6DSM_FIFO_STATUS3 0x3C 23 | 24 | #define LSM6DSM_FIFO_DATA_OUT_L 0x3E 25 | 26 | #define LSM6DSM_TAP_CFG 0x58 27 | #define LSM6DSM_WAKE_UP_THS 0x5B 28 | #define LSM6DSM_MD1_CFG 0x5E 29 | 30 | #define DSM_FS_G_250DPS 0x00 //0bxxxx0000 31 | #define DSM_FS_G_500DPS 0x04 //0bxxxx0100 32 | #define DSM_FS_G_1000DPS 0x08 //0bxxxx1000 33 | #define DSM_FS_G_2000DPS 0x0C //0bxxxx1100 34 | 35 | #define DSM_FS_XL_2G 0x00 // 0bxxxx0000 36 | #define DSM_FS_XL_4G 0x08 // 0bxxxx1000 37 | #define DSM_FS_XL_8G 0x0C // 0bxxxx1100 38 | #define DSM_FS_XL_16G 0x04 // 0bxxxx0100 39 | 40 | // Same for XL and G 41 | #define DSM_ODR_OFF 0b00000000 42 | #define DSM_ODR_12_5Hz 0b00010000 43 | #define DSM_ODR_26Hz 0b00100000 44 | #define DSM_ODR_52Hz 0b00110000 45 | #define DSM_ODR_104Hz 0b01000000 46 | #define DSM_ODR_208Hz 0b01010000 47 | #define DSM_ODR_416Hz 0b01100000 48 | #define DSM_ODR_833Hz 0b01110000 49 | #define DSM_ODR_1_66kHz 0b10000000 50 | #define DSM_ODR_3_33kHz 0b10010000 51 | #define DSM_ODR_6_66kHz 0b10100000 52 | 53 | #define DSM_OP_MODE_XL_HP 0x00 // High Performance 54 | #define DSM_OP_MODE_XL_NP 0x10 // Low Power 55 | 56 | #define DSM_OP_MODE_G_HP 0x00 // High Performance 57 | #define DSM_OP_MODE_G_NP 0x80 // Low Power 58 | 59 | #define DSM_OP_MODE_G_AWAKE 0x00 // Gyro active 60 | #define DSM_OP_MODE_G_SLEEP 0x40 // Gyro sleep 61 | 62 | int lsm6dsm_init(float clock_rate, float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 63 | 64 | void lsm6dsm_update_fs(float accel_range, float gyro_range, float *accel_actual_range, float *gyro_actual_range); 65 | int lsm6dsm_update_odr(float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 66 | 67 | uint16_t lsm6dsm_fifo_read(uint8_t *data, uint16_t len); 68 | uint16_t lsm6dsm_fifo_read(uint8_t *data, uint16_t len); 69 | 70 | uint8_t lsm6dsm_setup_DRDY(uint16_t threshold); 71 | uint8_t lsm6dsm_setup_WOM(void); 72 | 73 | extern const sensor_imu_t sensor_imu_lsm6dsm; 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/parse_args.c: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #include "parse_args.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | // Parse the command line to find its arguments. 33 | // Original string is modified to terminate the arguments substrings. 34 | // Returns the number of found arguments or zero. 35 | size_t parse_args(char *str, char *argv[], size_t size) 36 | { 37 | size_t argc = 0; 38 | if (!strlen(str)) { 39 | return 0; 40 | } 41 | while (*str && *str == ' ') { 42 | str++; 43 | } 44 | if (!*str) { 45 | return 0; 46 | } 47 | argv[argc++] = str; 48 | while ((str = strchr(str, ' '))) { 49 | *str++ = '\0'; 50 | while (*str && *str == ' ') 51 | str++; 52 | if (!*str) break; 53 | argv[argc++] = str; 54 | if (argc == size) { 55 | printk("Too many parameters (max %u)\n", size); 56 | return 0; 57 | } 58 | } 59 | // keep it POSIX style where argv[argc] is required to be NULL 60 | argv[argc] = NULL; 61 | return argc; 62 | } 63 | 64 | int32_t parse_i32(const char *str, uint8_t base) 65 | { 66 | long long res = strtoll(str, NULL, base); 67 | if(res < INT32_MIN) { 68 | res = INT32_MIN; 69 | errno = ERANGE; 70 | } 71 | if(res > INT32_MAX) { 72 | res = INT32_MAX; 73 | errno = ERANGE; 74 | } 75 | return (int32_t) res; 76 | } 77 | 78 | uint32_t parse_u32(const char *str, uint8_t base) 79 | { 80 | unsigned long long res = strtoull(str, NULL, base); 81 | if(res > UINT32_MAX) { 82 | res = UINT32_MAX; 83 | errno = ERANGE; 84 | } 85 | return (uint32_t) res; 86 | } 87 | 88 | uint64_t parse_u64(const char *str, uint8_t base) 89 | { 90 | return strtoull(str, NULL, base); 91 | } 92 | -------------------------------------------------------------------------------- /src/sensor/fusion/xiofusion/xioFusionOffset2.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file FusionOffset.c 3 | * @author Seb Madgwick 4 | * @brief Gyroscope offset correction algorithm for run-time calibration of the 5 | * gyroscope offset. 6 | */ 7 | 8 | //------------------------------------------------------------------------------ 9 | // Includes 10 | 11 | #include "xioFusionOffset2.h" 12 | 13 | #include // fabsf 14 | 15 | //------------------------------------------------------------------------------ 16 | // Definitions 17 | 18 | /** 19 | * @brief Cutoff frequency in Hz. 20 | */ 21 | #define CUTOFF_FREQUENCY (0.02f) 22 | 23 | /** 24 | * @brief Timeout in seconds. 25 | */ 26 | #define TIMEOUT (2) 27 | 28 | /** 29 | * @brief Threshold in degrees per second. 30 | */ 31 | #define THRESHOLD (3.0f) 32 | 33 | //------------------------------------------------------------------------------ 34 | // Functions 35 | 36 | /** 37 | * @brief Initialises the gyroscope offset algorithm. 38 | * @param offset Gyroscope offset algorithm structure. 39 | * @param sampleRate Sample rate in Hz. 40 | */ 41 | void FusionOffsetInitialise2( 42 | FusionOffset* const offset, 43 | const unsigned int sampleRate 44 | ) { 45 | offset->filterCoefficient 46 | = 2.0f * (float)M_PI * CUTOFF_FREQUENCY * (1.0f / (float)sampleRate); 47 | offset->timeout = TIMEOUT * sampleRate; 48 | offset->timer = 0; 49 | offset->gyroscopeOffset = FUSION_VECTOR_ZERO; 50 | } 51 | 52 | /** 53 | * @brief Updates the gyroscope offset algorithm and returns the corrected 54 | * gyroscope measurement. 55 | * @param offset Gyroscope offset algorithm structure. 56 | * @param gyroscope Gyroscope measurement in degrees per second. 57 | * @return Corrected gyroscope measurement in degrees per second. 58 | */ 59 | FusionVector FusionOffsetUpdate2(FusionOffset* const offset, FusionVector gyroscope) { 60 | // Subtract offset from gyroscope measurement 61 | gyroscope = FusionVectorSubtract(gyroscope, offset->gyroscopeOffset); 62 | 63 | // Reset timer if gyroscope not stationary 64 | if ((fabsf(gyroscope.axis.x) > THRESHOLD) || (fabsf(gyroscope.axis.y) > THRESHOLD) 65 | || (fabsf(gyroscope.axis.z) > THRESHOLD)) { 66 | offset->timer = 0; 67 | return gyroscope; 68 | } 69 | 70 | // Increment timer while gyroscope stationary 71 | if (offset->timer < offset->timeout) { 72 | offset->timer++; 73 | return gyroscope; 74 | } 75 | 76 | // Adjust offset if timer has elapsed 77 | if (offset->gyroscopeOffset.axis.x == 0 && offset->gyroscopeOffset.axis.y == 0 78 | && offset->gyroscopeOffset.axis.z == 0) { 79 | offset->gyroscopeOffset = gyroscope; 80 | } else { 81 | offset->gyroscopeOffset = FusionVectorAdd( 82 | offset->gyroscopeOffset, 83 | FusionVectorMultiplyScalar(gyroscope, offset->filterCoefficient) 84 | ); 85 | } 86 | return gyroscope; 87 | } 88 | 89 | //------------------------------------------------------------------------------ 90 | // End of file 91 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r2/slimenrf_r2.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | i2c0_default: i2c0_default { 10 | group1 { 11 | psels = , 12 | ; 13 | bias-disable; 14 | }; 15 | }; 16 | 17 | i2c0_sleep: i2c0_sleep { 18 | group1 { 19 | psels = , 20 | ; 21 | bias-disable; 22 | low-power-enable; 23 | }; 24 | }; 25 | 26 | pwm0_default: pwm0_default { 27 | group1 { 28 | psels = ; 29 | nordic,drive-mode = ; 30 | nordic,invert; 31 | }; 32 | }; 33 | 34 | pwm0_sleep: pwm0_sleep { 35 | group1 { 36 | psels = ; 37 | low-power-enable; 38 | }; 39 | }; 40 | 41 | }; 42 | //end 43 | 44 | / { 45 | model = "slimenrf_r2"; 46 | compatible = "slimenrf_r2"; 47 | 48 | chosen { 49 | zephyr,sram = &sram0; 50 | zephyr,flash = &flash0; 51 | }; 52 | 53 | pwmleds { 54 | compatible = "pwm-leds"; 55 | pwm_led0: pwm_led_0 { 56 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 57 | }; 58 | }; 59 | 60 | aliases { 61 | pwm-led0 = &pwm_led0; 62 | }; 63 | 64 | battery-divider { 65 | compatible = "voltage-divider"; 66 | status = "okay"; 67 | io-channels = <&adc 1>; 68 | output-ohms = <510000>; 69 | full-ohms = <(1000000+510000)>; 70 | power-gpios = <&gpio0 2 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 71 | }; 72 | 73 | zephyr,user { 74 | dock-gpios = <&gpio0 8 (GPIO_PULL_UP|GPIO_ACTIVE_LOW)>; 75 | chgstat-gpios = <&gpio0 6 (GPIO_PULL_UP|GPIO_ACTIVE_LOW)>; 76 | int0-gpios = <&gpio0 11 0>; 77 | led-gpios = <&gpio0 25 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 78 | }; 79 | 80 | }; 81 | 82 | ® { 83 | regulator-initial-mode = ; 84 | }; 85 | 86 | &adc { 87 | status = "okay"; 88 | }; 89 | 90 | &gpiote { 91 | status = "okay"; 92 | }; 93 | 94 | &gpio0 { 95 | status = "okay"; 96 | }; 97 | 98 | &i2c0 { 99 | compatible = "nordic,nrf-twim"; 100 | status = "okay"; 101 | zephyr,concat-buf-size = <255>; // MAXCNT 102 | zephyr,flash-buf-max-size = <255>; 103 | clock-frequency = ; 104 | pinctrl-0 = <&i2c0_default>; 105 | pinctrl-1 = <&i2c0_sleep>; 106 | pinctrl-names = "default", "sleep"; 107 | 108 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 109 | compatible = "i2c-device"; 110 | label = "imu"; 111 | reg = <0>; 112 | }; 113 | 114 | mag: mag@0 { 115 | compatible = "i2c-device"; 116 | label = "mag"; 117 | reg = <0>; 118 | }; 119 | 120 | }; 121 | 122 | &pwm0 { 123 | status = "okay"; 124 | pinctrl-0 = <&pwm0_default>; 125 | pinctrl-1 = <&pwm0_sleep>; 126 | pinctrl-names = "default", "sleep"; 127 | }; 128 | 129 | &nfct { 130 | status = "disabled"; 131 | }; 132 | -------------------------------------------------------------------------------- /boards/xiao_ble.overlay: -------------------------------------------------------------------------------- 1 | &i2c1_default { 2 | group1 { 3 | bias-disable; 4 | }; 5 | }; 6 | 7 | &i2c1_sleep { 8 | group1 { 9 | bias-disable; 10 | }; 11 | }; 12 | 13 | &pwm0_default { 14 | group1 { 15 | psels = , 16 | , 17 | ; 18 | nordic,drive-mode = ; 19 | nordic,invert; 20 | }; 21 | }; 22 | 23 | &pwm0_sleep { 24 | group1 { 25 | psels = , 26 | , 27 | ; 28 | }; 29 | }; 30 | 31 | / { 32 | pwmleds { 33 | pwm_led0: pwm_led_0 { 34 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 35 | }; 36 | pwm_led1: pwm_led_1 { 37 | pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 38 | }; 39 | pwm_led2: pwm_led_2 { 40 | pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 41 | }; 42 | }; 43 | 44 | buttons { 45 | compatible = "gpio-keys"; 46 | button0: button_0 { 47 | gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 48 | label = "Push button switch 0"; 49 | }; 50 | }; 51 | 52 | aliases { 53 | // sw0 = &button0; // Uncomment to Enable SW0 54 | pwm-led1 = &pwm_led1; 55 | pwm-led2 = &pwm_led2; 56 | }; 57 | 58 | battery-divider { 59 | compatible = "voltage-divider"; 60 | status = "okay"; 61 | io-channels = <&adc 7>; 62 | output-ohms = <510000>; 63 | full-ohms = <(1000000+510000)>; 64 | power-gpios = <&gpio0 14 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 65 | }; 66 | 67 | zephyr,user { 68 | int0-gpios = <&gpio0 3 0>; 69 | led-gpios = <&gpio0 17 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 70 | // clk-gpios = <&gpio0 28 GPIO_OPEN_DRAIN>; // Uncomment and set to correct pin if using an external clock (crystal oscillator) 71 | }; 72 | 73 | }; 74 | 75 | /delete-node/ &uart0; 76 | 77 | &i2c1 { 78 | compatible = "nordic,nrf-twim"; 79 | zephyr,concat-buf-size = <1023>; 80 | zephyr,flash-buf-max-size = <1023>; 81 | clock-frequency = ; 82 | 83 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 84 | compatible = "i2c-device"; 85 | label = "imu"; 86 | reg = <0>; 87 | }; 88 | 89 | mag: mag@0 { 90 | compatible = "i2c-device"; 91 | label = "mag"; 92 | reg = <0>; 93 | }; 94 | 95 | }; 96 | 97 | /delete-node/ &spi2; 98 | /delete-node/ &qspi; 99 | 100 | &spi3 { 101 | compatible = "nordic,nrf-spim"; 102 | status = "okay"; 103 | max-frequency = ; 104 | pinctrl-0 = <&spi2_default>; 105 | pinctrl-1 = <&spi2_sleep>; 106 | pinctrl-names = "default", "sleep"; 107 | cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; 108 | 109 | imu_spi: imu_spi@0 { 110 | compatible = "vnd,spi-device"; 111 | spi-max-frequency = ; 112 | label = "imu-spi"; 113 | reg = <0>; 114 | }; 115 | }; 116 | 117 | &cryptocell { 118 | status = "disabled"; 119 | }; 120 | 121 | &nfct { 122 | status = "disabled"; 123 | }; 124 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_UTILS 24 | #define SLIMENRF_UTILS 25 | 26 | #ifndef M_PI 27 | #define M_PI 3.141592653589793238462643383279502884f 28 | #endif 29 | 30 | #ifndef EPS 31 | #define EPS 1e-6f 32 | #endif 33 | 34 | // Saturate int to 16 bits 35 | // Optimized to a single ARM assembler instruction 36 | #define SATURATE_INT16(x) ((x) > 32767 ? 32767 : ((x) < -32768 ? -32768 : (x))) 37 | 38 | #define SATURATE_UINT11(x) ((x) > 2047 ? 2047 : ((x) < 0 ? 0 : (x))) 39 | #define SATURATE_UINT10(x) ((x) > 1023 ? 1023 : ((x) < 0 ? 0 : (x))) 40 | 41 | #define TO_FIXED_15(x) ((int16_t)SATURATE_INT16((x) * (1 << 15))) 42 | #define TO_FIXED_11(x) ((int16_t)SATURATE_INT16((x) * (1 << 11))) 43 | #define TO_FIXED_10(x) ((int16_t)SATURATE_INT16((x) * (1 << 10))) 44 | #define TO_FIXED_7(x) ((int16_t)SATURATE_INT16((x) * (1 << 7))) 45 | #define FIXED_15_TO_DOUBLE(x) (((double)(x)) / (1 << 15)) 46 | #define FIXED_11_TO_DOUBLE(x) (((double)(x)) / (1 << 11)) 47 | #define FIXED_10_TO_DOUBLE(x) (((double)(x)) / (1 << 10)) 48 | #define FIXED_7_TO_DOUBLE(x) (((double)(x)) / (1 << 7)) 49 | 50 | #define CONST_EARTH_GRAVITY 9.80665f 51 | 52 | void q_normalize(const float* q, float* out); 53 | void q_multiply(const float* x, const float* y, float* out); 54 | void q_conj(const float* q, float* out); 55 | void q_negate(const float* q, float* out); 56 | float q_diff_mag(const float* x, const float* y); 57 | void v_rotate(const float* v, const float* q, float* out); 58 | float v_avg(const float* a); 59 | float v_diff_mag(const float* a, const float* b); 60 | bool q_epsilon(const float* x, const float* y, float eps); 61 | bool v_epsilon(const float* a, const float* b, float eps); 62 | 63 | // TODO: does this need to be moved? 64 | void apply_BAinv(float xyz[3], float BAinv[4][3]); 65 | 66 | void a_to_lin_a(const float *q, const float *a, float *lin_a); 67 | 68 | void q_fem(const float *q, float *out); 69 | void q_iem(const float *v, float *out); 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/sensor/imu/LSM6DSO.h: -------------------------------------------------------------------------------- 1 | #ifndef LSM6DSO_h 2 | #define LSM6DSO_h 3 | 4 | #include "sensor/sensor.h" 5 | 6 | // https://www.st.com/resource/en/datasheet/lsm6dso.pdf 7 | #define LSM6DSO_FIFO_CTRL3 0x09 8 | #define LSM6DSO_FIFO_CTRL4 0x0A 9 | #define LSM6DSO_COUNTER_BDR_REG1 0x0B 10 | 11 | #define LSM6DSO_INT1_CTRL 0x0D 12 | 13 | #define LSM6DSO_CTRL1 0x10 14 | #define LSM6DSO_CTRL2 0x11 15 | #define LSM6DSO_CTRL3 0x12 16 | #define LSM6DSO_CTRL4 0x13 17 | #define LSM6DSO_CTRL5 0x14 18 | #define LSM6DSO_CTRL6 0x15 19 | #define LSM6DSO_CTRL7 0x16 20 | #define LSM6DSO_CTRL8 0x17 21 | 22 | #define LSM6DSO_STATUS_MASTER_MAINPAGE 0x39 23 | #define LSM6DSO_FIFO_STATUS1 0x3A 24 | 25 | #define LSM6DSO_TAP_CFG0 0x56 26 | #define LSM6DSO_TAP_CFG2 0x58 27 | #define LSM6DSO_WAKE_UP_THS 0x5B 28 | #define LSM6DSO_MD1_CFG 0x5E 29 | 30 | #define LSM6DSO_INTERNAL_FREQ_FINE 0x63 31 | 32 | #define LSM6DSO_FIFO_DATA_OUT_TAG 0x78 33 | 34 | #define DSO_FS_G_250DPS 0x00 //0bxxxx0000 35 | #define DSO_FS_G_500DPS 0x04 //0bxxxx0100 36 | #define DSO_FS_G_1000DPS 0x08 //0bxxxx1000 37 | #define DSO_FS_G_2000DPS 0x0C //0bxxxx1100 38 | 39 | #define DSO_FS_XL_2G 0x00 // 0bxxxx0000 40 | #define DSO_FS_XL_4G 0x08 // 0bxxxx1000 41 | #define DSO_FS_XL_8G 0x0C // 0bxxxx1100 42 | #define DSO_FS_XL_16G 0x04 // 0bxxxx0100 43 | 44 | // Same for XL and G 45 | #define DSO_ODR_OFF 0b00000000 46 | #define DSO_ODR_12_5Hz 0b00010000 47 | #define DSO_ODR_26Hz 0b00100000 48 | #define DSO_ODR_52Hz 0b00110000 49 | #define DSO_ODR_104Hz 0b01000000 50 | #define DSO_ODR_208Hz 0b01010000 51 | #define DSO_ODR_416Hz 0b01100000 52 | #define DSO_ODR_833Hz 0b01110000 53 | #define DSO_ODR_1_66kHz 0b10000000 54 | #define DSO_ODR_3_33kHz 0b10010000 55 | #define DSO_ODR_6_66kHz 0b10100000 56 | 57 | #define DSO_OP_MODE_XL_HP 0x00 // High Performance 58 | #define DSO_OP_MODE_XL_NP 0x10 // Low Power 59 | 60 | #define DSO_OP_MODE_G_HP 0x00 // High Performance 61 | #define DSO_OP_MODE_G_NP 0x80 // Low Power 62 | 63 | #define DSO_OP_MODE_G_AWAKE 0x00 // Gyro active 64 | #define DSO_OP_MODE_G_SLEEP 0x40 // Gyro sleep 65 | 66 | int lsm6dso_init(float clock_rate, float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 67 | 68 | void lsm6dso_update_fs(float accel_range, float gyro_range, float *accel_actual_range, float *gyro_actual_range); 69 | int lsm6dso_update_odr(float accel_time, float gyro_time, float *accel_actual_time, float *gyro_actual_time); 70 | 71 | uint16_t lsm6dso_fifo_read(uint8_t *data, uint16_t len); 72 | 73 | uint8_t lsm6dso_setup_WOM(void); 74 | 75 | int lsm6dso_ext_setup(void); 76 | int lsm6dso_ext_passthrough(bool passthrough); 77 | 78 | int lsm6dso_ext_write(const uint8_t addr, const uint8_t *buf, uint32_t num_bytes); 79 | int lsm6dso_ext_write_read(const uint8_t addr, const void *write_buf, size_t num_write, void *read_buf, size_t num_read); 80 | 81 | extern const sensor_imu_t sensor_imu_lsm6dso; 82 | extern const sensor_ext_ssi_t sensor_ext_lsm6dso; 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/globals.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_GLOBALS 24 | #define SLIMENRF_GLOBALS 25 | 26 | #include 27 | 28 | #include "retained.h" 29 | #include "thread_priority.h" 30 | 31 | #define USER_SHUTDOWN_ENABLED CONFIG_USER_SHUTDOWN // Allow user to use reset or sw0 to shutdown 32 | #define MAG_ENABLED CONFIG_SENSOR_USE_MAG // Use magnetometer if it is present 33 | #define IGNORE_RESET CONFIG_IGNORE_RESET // If sw0 available, don't change any reset behavior 34 | #define WOM_USE_DCDC CONFIG_WOM_USE_DCDC // Use DCDC instead of LDO for WOM if it is more efficient 35 | 36 | /* Sensor gyroscope, accelerometer, and magnetometer axes should align to the IMU body axes 37 | * SENSOR_QUATERNION_CORRECTION should align the sensor to the device following Android convention 38 | * On flat surface / face up: 39 | * Left from the perspective of the device / right from your perspective is +X 40 | * Front side (facing up) is +Z 41 | * Mounted on body / standing up: 42 | * Top side of the device is +Y 43 | * Front side (facing out) is +Z 44 | */ 45 | 46 | // TODO: not matching anymore 47 | #if defined(CONFIG_BOARD_SLIMEVRMINI_P1_UF2) || defined(CONFIG_BOARD_SLIMEVRMINI_P2_UF2) 48 | #define SENSOR_MAGNETOMETER_AXES_ALIGNMENT -mx, mz, -my 49 | #define SENSOR_QUATERNION_CORRECTION 0.7071f, 0.7071f, 0.0f, 0.0f 50 | #endif 51 | #if defined(CONFIG_BOARD_SLIMEVRMINI_P4_UF2) 52 | #define SENSOR_GYROSCOPE_AXES_ALIGNMENT gx, gy, gz 53 | #define SENSOR_ACCELEROMETER_AXES_ALIGNMENT ax, ay, az 54 | #define SENSOR_MAGNETOMETER_AXES_ALIGNMENT my, -mx, -mz 55 | #define SENSOR_QUATERNION_CORRECTION 0.7071f, 0.0f, 0.0f, 0.7071f 56 | #endif 57 | 58 | #if defined(CONFIG_BOARD_SLIMENRF_R1) || defined(CONFIG_BOARD_SLIMENRF_R2) || defined(CONFIG_BOARD_SLIMENRF_R3) 59 | #define SENSOR_QUATERNION_CORRECTION 0.0f, 0.7071f, 0.7071f, 0.0f 60 | #endif 61 | 62 | #ifndef SENSOR_MAGNETOMETER_AXES_ALIGNMENT 63 | #define SENSOR_MAGNETOMETER_AXES_ALIGNMENT my, -mx, -mz // mag axes alignment to sensor body 64 | #endif 65 | #ifndef SENSOR_QUATERNION_CORRECTION 66 | #define SENSOR_QUATERNION_CORRECTION 1.0f, 0.0f, 0.0f, 0.0f // correction quat for sensor to mounting orientation 67 | #endif 68 | 69 | #endif -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r1/slimenrf_r1.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | i2c0_default: i2c0_default { 10 | group1 { 11 | psels = , 12 | ; 13 | bias-disable; 14 | }; 15 | }; 16 | 17 | i2c0_sleep: i2c0_sleep { 18 | group1 { 19 | psels = , 20 | ; 21 | bias-disable; 22 | low-power-enable; 23 | }; 24 | }; 25 | 26 | pwm0_default: pwm0_default { 27 | group1 { 28 | psels = ; 29 | nordic,drive-mode = ; 30 | }; 31 | }; 32 | 33 | pwm0_sleep: pwm0_sleep { 34 | group1 { 35 | psels = ; 36 | low-power-enable; 37 | }; 38 | }; 39 | 40 | }; 41 | //end 42 | 43 | / { 44 | model = "slimenrf_r1"; 45 | compatible = "slimenrf_r1"; 46 | 47 | chosen { 48 | zephyr,sram = &sram0; 49 | zephyr,flash = &flash0; 50 | }; 51 | 52 | pwmleds { 53 | compatible = "pwm-leds"; 54 | pwm_led0: pwm_led_0 { 55 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_NORMAL>; 56 | }; 57 | }; 58 | 59 | aliases { 60 | pwm-led0 = &pwm_led0; 61 | }; 62 | 63 | battery-divider { 64 | compatible = "voltage-divider"; 65 | status = "okay"; 66 | io-channels = <&adc 1>; 67 | output-ohms = <510000>; 68 | full-ohms = <(1000000+510000)>; 69 | power-gpios = <&gpio0 2 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 70 | }; 71 | 72 | zephyr,user { 73 | dock-gpios = <&gpio0 8 (GPIO_PULL_UP|GPIO_ACTIVE_LOW)>; 74 | chgstat-gpios = <&gpio0 6 (GPIO_PULL_UP|GPIO_ACTIVE_LOW)>; 75 | int0-gpios = <&gpio0 11 0>; 76 | led-gpios = <&gpio0 25 (GPIO_OPEN_SOURCE | (1 << 9))>; 77 | }; 78 | 79 | }; 80 | 81 | ®1 { 82 | regulator-initial-mode = ; 83 | }; 84 | 85 | &adc { 86 | status = "okay"; 87 | }; 88 | 89 | &gpiote { 90 | status = "okay"; 91 | }; 92 | 93 | &gpio0 { 94 | status = "okay"; 95 | }; 96 | 97 | &gpio1 { 98 | status = "okay"; 99 | }; 100 | 101 | &i2c0 { 102 | compatible = "nordic,nrf-twim"; 103 | status = "okay"; 104 | zephyr,concat-buf-size = <1023>; 105 | zephyr,flash-buf-max-size = <1023>; 106 | clock-frequency = ; 107 | pinctrl-0 = <&i2c0_default>; 108 | pinctrl-1 = <&i2c0_sleep>; 109 | pinctrl-names = "default", "sleep"; 110 | 111 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 112 | compatible = "i2c-device"; 113 | label = "imu"; 114 | reg = <0>; 115 | }; 116 | 117 | mag: mag@0 { 118 | compatible = "i2c-device"; 119 | label = "mag"; 120 | reg = <0>; 121 | }; 122 | 123 | }; 124 | 125 | &pwm0 { 126 | status = "okay"; 127 | pinctrl-0 = <&pwm0_default>; 128 | pinctrl-1 = <&pwm0_sleep>; 129 | pinctrl-names = "default", "sleep"; 130 | }; 131 | 132 | zephyr_udc0: &usbd { 133 | compatible = "nordic,nrf-usbd"; 134 | status = "disabled"; 135 | cdc_acm_uart0: cdc_acm_uart0 { 136 | compatible = "zephyr,cdc-acm-uart"; 137 | }; 138 | }; 139 | 140 | &cryptocell { 141 | status = "disabled"; 142 | }; 143 | 144 | &nfct { 145 | status = "disabled"; 146 | }; 147 | -------------------------------------------------------------------------------- /prj.conf: -------------------------------------------------------------------------------- 1 | #CONFIG_NCS_SAMPLES_DEFAULTS 2 | CONFIG_ASSERT=y 3 | CONFIG_ASSERT_NO_COND_INFO=y 4 | CONFIG_ASSERT_NO_MSG_INFO=y 5 | CONFIG_RESET_ON_FATAL_ERROR=y 6 | 7 | CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="SlimeVR-Tracker-nRF" 8 | #CONFIG_NCS_BOOT_BANNER=n 9 | CONFIG_BOOT_BANNER=n 10 | 11 | CONFIG_ESB=y 12 | #need to enable for nRF54L 13 | CONFIG_NRFX_DPPI10=y 14 | 15 | CONFIG_ADC=y 16 | CONFIG_ADC_NRFX_SAADC=y 17 | CONFIG_FPU=y 18 | CONFIG_I2C=y 19 | CONFIG_SPI=y 20 | CONFIG_PINCTRL=y 21 | 22 | CONFIG_NVS=y 23 | CONFIG_NVS_LOOKUP_CACHE=y 24 | CONFIG_NVS_INIT_BAD_MEMORY_REGION=y 25 | 26 | CONFIG_POWEROFF=y 27 | CONFIG_REBOOT=y 28 | 29 | CONFIG_FLASH=y 30 | CONFIG_FLASH_PAGE_LAYOUT=y 31 | CONFIG_FLASH_MAP=y 32 | 33 | CONFIG_SETTINGS=y 34 | CONFIG_SETTINGS_RUNTIME=y 35 | CONFIG_SETTINGS_NONE=y 36 | 37 | CONFIG_MPU_ALLOW_FLASH_WRITE=y 38 | 39 | CONFIG_RETAINED_MEM=y 40 | 41 | CONFIG_USE_SEGGER_RTT=y 42 | CONFIG_LOG=y 43 | #CONFIG_PRINTK=y 44 | CONFIG_LOG_MODE_DEFERRED=y 45 | CONFIG_LOG_SPEED=y 46 | CONFIG_LOG_BACKEND_RTT=y 47 | CONFIG_CBPRINTF_FP_SUPPORT=y 48 | CONFIG_ADC_LOG_LEVEL_OFF=y 49 | CONFIG_LOG_FUNC_NAME_PREFIX_ERR=y 50 | CONFIG_LOG_BUFFER_SIZE=1536 51 | CONFIG_LOG_BACKEND_UART_AUTOSTART=n 52 | CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=50 53 | CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=1024 54 | 55 | CONFIG_PWM=y 56 | CONFIG_GPIO=y 57 | 58 | CONFIG_CRC=y 59 | 60 | CONFIG_NEWLIB_LIBC=y 61 | CONFIG_NRFX_TIMER1=y 62 | 63 | #speed up boot? (use internal rc oscillator) 64 | CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y 65 | CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=n 66 | #speed up boot? (synthesize lf clock) 67 | #CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH=y 68 | 69 | # dont need it 70 | CONFIG_CRYPTO=n 71 | 72 | # set timeout for 25ms, sufficient for ~1000 bytes 73 | CONFIG_I2C_NRFX_TRANSFER_TIMEOUT=25 74 | 75 | CONFIG_USB_DEVICE_HID=y 76 | CONFIG_USB_DEVICE_VID=0x1209 77 | CONFIG_USB_DEVICE_PID=0x7692 78 | CONFIG_USB_HID_BOOT_PROTOCOL=y 79 | CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n 80 | CONFIG_USB_CDC_ACM=y 81 | CONFIG_UART_INTERRUPT_DRIVEN=y 82 | CONFIG_USB_WORKQUEUE_STACK_SIZE=512 83 | 84 | CONFIG_SERIAL=y 85 | CONFIG_CONSOLE=y 86 | CONFIG_RTT_CONSOLE=y 87 | CONFIG_UART_CONSOLE=y 88 | CONFIG_UART_LINE_CTRL=y 89 | # fit "write all " 90 | CONFIG_CONSOLE_INPUT_MAX_LINE_LEN=256 91 | 92 | CONFIG_LOG=y 93 | CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y 94 | CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y 95 | CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y 96 | 97 | CONFIG_LOG_BACKEND_UART=y 98 | 99 | CONFIG_CONSOLE_SUBSYS=y 100 | CONFIG_CONSOLE_GETLINE=y 101 | 102 | CONFIG_NVS_LOG_LEVEL_WRN=y 103 | CONFIG_USB_HID_LOG_LEVEL_WRN=y 104 | 105 | CONFIG_USB_DEVICE_SOF=y 106 | CONFIG_USB_HID_REPORTS=256 107 | 108 | #CONFIG_USB_HID_POLL_INTERVAL_MS=1 109 | CONFIG_USB_HID_POLL_INTERVAL_MS=0 110 | CONFIG_HID_INTERRUPT_EP_MPS=64 111 | #CONFIG_ENABLE_HID_INT_OUT_EP=y 112 | 113 | CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=256 114 | CONFIG_MAIN_STACK_SIZE=512 115 | #crashing on nrf54l at 512 116 | 117 | CONFIG_THREAD_NAME=y 118 | 119 | # TODO: because of icm426, this will break things and needs to be raised to at least 3k 120 | CONFIG_HEAP_MEM_POOL_SIZE=2048 121 | CONFIG_ISR_STACK_SIZE=1024 122 | 123 | CONFIG_PM_DEVICE=y 124 | 125 | CONFIG_BASE64=y 126 | 127 | #CONFIG_THREAD_ANALYZER=y 128 | #CONFIG_THREAD_ANALYZER_AUTO=y 129 | #CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=5 130 | -------------------------------------------------------------------------------- /boards/slimevr/microslime/microslime_uf2.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | pwm0_default: pwm0_default { 10 | group1 { 11 | psels = ; // White 12 | nordic,drive-mode = ; 13 | }; 14 | }; 15 | 16 | pwm0_sleep: pwm0_sleep { 17 | group1 { 18 | psels = ; // White 19 | low-power-enable; 20 | }; 21 | }; 22 | 23 | spi3_default: spi3_default { 24 | group1 { 25 | psels = , 26 | , 27 | ; 28 | }; 29 | }; 30 | 31 | spi3_sleep: spi3_sleep { 32 | group1 { 33 | psels = , 34 | , 35 | ; 36 | low-power-enable; 37 | }; 38 | }; 39 | }; 40 | //end 41 | 42 | / { 43 | model = "microslime_uf2"; 44 | compatible = "microslime_uf2"; 45 | 46 | chosen { 47 | zephyr,sram = &sram0; 48 | zephyr,flash = &flash0; 49 | zephyr,console = &cdc_acm_uart0; 50 | zephyr,shell-uart = &cdc_acm_uart0; 51 | }; 52 | 53 | pwmleds { 54 | compatible = "pwm-leds"; 55 | pwm_led0: pwm_led_0 { 56 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_NORMAL>; 57 | }; 58 | }; 59 | 60 | leds { 61 | compatible = "gpio-leds"; 62 | led0: led_0 { 63 | gpios = <&gpio0 2 GPIO_OPEN_SOURCE>; 64 | }; 65 | }; 66 | 67 | buttons { 68 | compatible = "gpio-keys"; 69 | button0: button_0 { 70 | gpios = <&gpio0 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 71 | label = "Push button switch 0"; 72 | }; 73 | }; 74 | 75 | aliases { 76 | sw0 = &button0; 77 | pwm-led0 = &pwm_led0; 78 | led0 = &led0; 79 | }; 80 | 81 | battery-divider { 82 | compatible = "voltage-divider"; 83 | status = "okay"; 84 | io-channels = <&adc 7>; 85 | output-ohms = <3300000>; 86 | full-ohms = <(5600000+3300000)>; 87 | }; 88 | 89 | zephyr,user { 90 | int0-gpios = <&gpio0 1 0>; 91 | chg-gpios = <&gpio0 29 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 92 | stby-gpios = <&gpio0 28 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 93 | clk-gpios = <&gpio0 30 (GPIO_OPEN_DRAIN)>; 94 | led0-gpios = <&gpio0 2 (GPIO_OPEN_SOURCE)>; 95 | }; 96 | 97 | }; 98 | 99 | ®1 { 100 | regulator-initial-mode = ; 101 | }; 102 | 103 | &adc { 104 | status = "okay"; 105 | }; 106 | 107 | &gpiote { 108 | status = "okay"; 109 | }; 110 | 111 | &gpio0 { 112 | status = "okay"; 113 | }; 114 | 115 | &gpio1 { 116 | status = "okay"; 117 | }; 118 | 119 | &pwm0 { 120 | status = "okay"; 121 | pinctrl-0 = <&pwm0_default>; 122 | pinctrl-1 = <&pwm0_sleep>; 123 | pinctrl-names = "default", "sleep"; 124 | }; 125 | 126 | zephyr_udc0: &usbd { 127 | compatible = "nordic,nrf-usbd"; 128 | status = "okay"; 129 | cdc_acm_uart0: cdc_acm_uart0 { 130 | compatible = "zephyr,cdc-acm-uart"; 131 | }; 132 | }; 133 | 134 | &nfct { 135 | status = "disabled"; 136 | }; 137 | 138 | &spi3 { 139 | compatible = "nordic,nrf-spim"; 140 | status = "okay"; 141 | max-frequency = ; 142 | pinctrl-0 = <&spi3_default>; 143 | pinctrl-1 = <&spi3_sleep>; 144 | pinctrl-names = "default", "sleep"; 145 | cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; 146 | 147 | imu_spi: imu_spi@0 { 148 | compatible = "vnd,spi-device"; 149 | spi-max-frequency = ; 150 | label = "imu-spi"; 151 | reg = <0>; 152 | }; 153 | }; -------------------------------------------------------------------------------- /src/sensor/interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #ifndef SLIMENRF_SENSOR_INTERFACE 24 | #define SLIMENRF_SENSOR_INTERFACE 25 | 26 | #include 27 | #include 28 | 29 | enum sensor_interface_dev 30 | { 31 | SENSOR_INTERFACE_DEV_IMU, 32 | SENSOR_INTERFACE_DEV_MAG 33 | }; 34 | #define SENSOR_INTERFACE_DEV_COUNT 2 35 | 36 | enum sensor_interface_spec 37 | { 38 | SENSOR_INTERFACE_SPEC_SPI, 39 | SENSOR_INTERFACE_SPEC_I2C, 40 | SENSOR_INTERFACE_SPEC_EXT 41 | }; 42 | 43 | typedef struct sensor_ext_ssi { 44 | int (*ext_write)(const uint8_t, const uint8_t*, uint32_t); 45 | int (*ext_write_read)(const uint8_t, const void*, size_t, void*, size_t); 46 | uint8_t ext_burst; 47 | } sensor_ext_ssi_t; 48 | 49 | void sensor_interface_register_sensor_imu_spi(struct spi_dt_spec *dev); 50 | void sensor_interface_register_sensor_imu_i2c(struct i2c_dt_spec *dev); 51 | 52 | void sensor_interface_register_sensor_mag_spi(struct spi_dt_spec *dev); 53 | void sensor_interface_register_sensor_mag_i2c(struct i2c_dt_spec *dev); 54 | int sensor_interface_register_sensor_mag_ext(uint8_t addr, uint8_t min_burst, uint8_t burst); 55 | 56 | int sensor_interface_spi_configure(enum sensor_interface_dev dev, uint32_t frequency, uint32_t dummy_reads); 57 | void sensor_interface_ext_configure(const sensor_ext_ssi_t *ext); 58 | const sensor_ext_ssi_t *sensor_interface_ext_get(void); 59 | 60 | int ssi_write(enum sensor_interface_dev dev, const uint8_t *buf, uint32_t num_bytes); 61 | int ssi_read(enum sensor_interface_dev dev, uint8_t *buf, uint32_t num_bytes); 62 | int ssi_write_read(enum sensor_interface_dev dev, const void *write_buf, size_t num_write, void *read_buf, size_t num_read); 63 | 64 | int ssi_burst_read(enum sensor_interface_dev dev, uint8_t start_addr, uint8_t *buf, uint32_t num_bytes); 65 | int ssi_burst_write(enum sensor_interface_dev dev, uint8_t start_addr, const uint8_t *buf, uint32_t num_bytes); 66 | int ssi_reg_read_byte(enum sensor_interface_dev dev, uint8_t reg_addr, uint8_t *value); 67 | int ssi_reg_write_byte(enum sensor_interface_dev dev, uint8_t reg_addr, uint8_t value); 68 | int ssi_reg_update_byte(enum sensor_interface_dev dev, uint8_t reg_addr, uint8_t mask, uint8_t value); 69 | 70 | int ssi_reg_read_interval(enum sensor_interface_dev dev, uint8_t start_addr, uint8_t *buf, uint32_t num_bytes, uint32_t interval); 71 | int ssi_burst_read_interval(enum sensor_interface_dev dev, uint8_t start_addr, uint8_t *buf, uint32_t num_bytes, uint32_t interval); 72 | 73 | #endif -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p1_uf2/slimevrmini_p1_uf2.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | i2c0_default: i2c0_default { 10 | group1 { 11 | psels = , ; 12 | bias-disable; 13 | }; 14 | }; 15 | 16 | i2c0_sleep: i2c0_sleep { 17 | group1 { 18 | psels = , ; 19 | bias-disable; 20 | low-power-enable; 21 | }; 22 | }; 23 | 24 | pwm0_default: pwm0_default { 25 | group1 { 26 | psels = ; 27 | nordic,drive-mode = ; 28 | nordic,invert; 29 | }; 30 | }; 31 | 32 | pwm0_sleep: pwm0_sleep { 33 | group1 { 34 | psels = ; 35 | low-power-enable; 36 | }; 37 | }; 38 | }; 39 | //end 40 | 41 | / { 42 | model = "slimevrmini_p1_uf2"; 43 | compatible = "slimevrmini_p1_uf2"; 44 | 45 | chosen { 46 | zephyr,sram = &sram0; 47 | zephyr,flash = &flash0; 48 | zephyr,console = &cdc_acm_uart0; 49 | zephyr,shell-uart = &cdc_acm_uart0; 50 | }; 51 | 52 | pwmleds { 53 | compatible = "pwm-leds"; 54 | pwm_led0: pwm_led_0 { 55 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 56 | }; 57 | }; 58 | 59 | buttons { 60 | compatible = "gpio-keys"; 61 | button0: button_0 { 62 | gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 63 | label = "Push button switch 0"; 64 | }; 65 | }; 66 | 67 | aliases { 68 | sw0 = &button0; 69 | pwm-led0 = &pwm_led0; 70 | }; 71 | 72 | battery-divider { 73 | compatible = "voltage-divider"; 74 | status = "okay"; 75 | io-channels = <&adc 3>; 76 | output-ohms = <40200>; 77 | full-ohms = <(100000+40200)>; 78 | power-gpios = <&gpio1 9 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 79 | }; 80 | 81 | zephyr,user { 82 | int0-gpios = <&gpio0 28 0>; 83 | led-gpios = <&gpio0 31 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 84 | chg-gpios = <&gpio0 11 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 85 | stby-gpios = <&gpio0 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 86 | }; 87 | 88 | }; 89 | 90 | ®1 { 91 | regulator-initial-mode = ; 92 | }; 93 | 94 | &adc { 95 | status = "okay"; 96 | }; 97 | 98 | &gpiote { 99 | status = "okay"; 100 | }; 101 | 102 | &gpio0 { 103 | status = "okay"; 104 | }; 105 | 106 | &gpio1 { 107 | status = "okay"; 108 | }; 109 | 110 | &i2c0 { 111 | compatible = "nordic,nrf-twim"; 112 | status = "okay"; 113 | zephyr,concat-buf-size = <1023>; 114 | zephyr,flash-buf-max-size = <1023>; 115 | clock-frequency = ; 116 | pinctrl-0 = <&i2c0_default>; 117 | pinctrl-1 = <&i2c0_sleep>; 118 | pinctrl-names = "default", "sleep"; 119 | 120 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 121 | compatible = "i2c-device"; 122 | label = "imu"; 123 | reg = <0>; 124 | }; 125 | 126 | mag: mag@0 { 127 | compatible = "i2c-device"; 128 | label = "mag"; 129 | reg = <0>; 130 | }; 131 | 132 | }; 133 | 134 | &pwm0 { 135 | status = "okay"; 136 | pinctrl-0 = <&pwm0_default>; 137 | pinctrl-1 = <&pwm0_sleep>; 138 | pinctrl-names = "default", "sleep"; 139 | }; 140 | 141 | zephyr_udc0: &usbd { 142 | compatible = "nordic,nrf-usbd"; 143 | status = "okay"; 144 | cdc_acm_uart0: cdc_acm_uart0 { 145 | compatible = "zephyr,cdc-acm-uart"; 146 | }; 147 | }; 148 | 149 | &nfct { 150 | status = "disabled"; 151 | }; 152 | -------------------------------------------------------------------------------- /src/connection/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #include "globals.h" 24 | #include "esb.h" 25 | #include "connection.h" 26 | 27 | LOG_MODULE_REGISTER(timer, 4); 28 | 29 | void timer_handler(nrf_timer_event_t event_type, void *p_context) 30 | { 31 | if (event_type == NRF_TIMER_EVENT_COMPARE1 && esb_state == true) 32 | { 33 | if (last_reset < LAST_RESET_LIMIT) 34 | { 35 | last_reset++; 36 | if (send_data) 37 | { // scuffed check 38 | // esb_write_payload(&tx_payload); // Add transmission to queue 39 | esb_start_tx(); 40 | send_data = false; 41 | } 42 | // esb_flush_tx(); 43 | } 44 | else 45 | { 46 | esb_disable(); 47 | esb_initialize(false); 48 | esb_start_rx(); 49 | esb_state = false; 50 | // nrfx_timer_pause(&m_timer); 51 | timer_state = false; 52 | LOG_INF("Timer reset elapsed"); 53 | } 54 | } 55 | else if (event_type == NRF_TIMER_EVENT_COMPARE2 && esb_state == true) 56 | { 57 | esb_disable(); 58 | esb_initialize(false); 59 | esb_start_rx(); 60 | esb_state = false; 61 | } 62 | else if (event_type == NRF_TIMER_EVENT_COMPARE3 && esb_state == false) 63 | { 64 | esb_stop_rx(); 65 | esb_disable(); 66 | esb_initialize(true); 67 | esb_state = true; 68 | } 69 | } 70 | 71 | void timer_init(void) 72 | { 73 | // uint8_t tracker_id = connection_get_id(); // TODO: make sure it is ready 74 | // nrfx_err_t err; 75 | // nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG(1000000); 76 | //timer_cfg.frequency = NRF_TIMER_FREQ_1MHz; 77 | //timer_cfg.mode = NRF_TIMER_MODE_TIMER; 78 | //timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16; 79 | //timer_cfg.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY; 80 | //timer_cfg.p_context = NULL; 81 | // nrfx_timer_init(&m_timer, &timer_cfg, timer_handler); 82 | // uint32_t ticks = nrfx_timer_ms_to_ticks(&m_timer, 3); 83 | // nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false); 84 | // LOG_INF("Timer at %d", ticks * (tracker_id*2 + 3) / 21); // TODO: temp set max 8 85 | // nrfx_timer_compare(&m_timer, NRF_TIMER_CC_CHANNEL1, ticks * (tracker_id*2 + 3) / 21, true); // timeslot to send data TODO: temp set max 8 86 | // nrfx_timer_compare(&m_timer, NRF_TIMER_CC_CHANNEL2, ticks * 19 / 21, true); // switch to rx 87 | // nrfx_timer_compare(&m_timer, NRF_TIMER_CC_CHANNEL3, ticks * 2 / 21, true); // switch to tx 88 | // nrfx_timer_enable(&m_timer); 89 | // IRQ_DIRECT_CONNECT(TIMER1_IRQn, 0, nrfx_timer_1_irq_handler, 0); 90 | // irq_enable(TIMER1_IRQn); 91 | timer_state = true; 92 | } 93 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r7_uf2/slimevrmini_p3r7_uf2.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | i2c0_default: i2c0_default { 10 | group1 { 11 | psels = , ; 12 | bias-disable; 13 | }; 14 | }; 15 | 16 | i2c0_sleep: i2c0_sleep { 17 | group1 { 18 | psels = , ; 19 | bias-disable; 20 | low-power-enable; 21 | }; 22 | }; 23 | 24 | pwm0_default: pwm0_default { 25 | group1 { 26 | psels = ; 27 | nordic,drive-mode = ; 28 | nordic,invert; 29 | }; 30 | }; 31 | 32 | pwm0_sleep: pwm0_sleep { 33 | group1 { 34 | psels = ; 35 | low-power-enable; 36 | }; 37 | }; 38 | }; 39 | //end 40 | 41 | / { 42 | model = "slimevrmini_p3r7_uf2"; 43 | compatible = "slimevrmini_p3r7_uf2"; 44 | 45 | chosen { 46 | zephyr,sram = &sram0; 47 | zephyr,flash = &flash0; 48 | zephyr,console = &cdc_acm_uart0; 49 | zephyr,shell-uart = &cdc_acm_uart0; 50 | }; 51 | 52 | pwmleds { 53 | compatible = "pwm-leds"; 54 | pwm_led0: pwm_led_0 { 55 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 56 | }; 57 | }; 58 | 59 | buttons { 60 | compatible = "gpio-keys"; 61 | button0: button_0 { 62 | gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 63 | label = "Push button switch 0"; 64 | }; 65 | }; 66 | 67 | aliases { 68 | sw0 = &button0; 69 | pwm-led0 = &pwm_led0; 70 | }; 71 | 72 | battery-divider { 73 | compatible = "voltage-divider"; 74 | status = "okay"; 75 | io-channels = <&adc 4>; 76 | output-ohms = <40200>; 77 | full-ohms = <(100000+40200)>; 78 | power-gpios = <&gpio0 2 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 79 | }; 80 | 81 | zephyr,user { 82 | int0-gpios = <&gpio0 20 0>; 83 | led-gpios = <&gpio1 9 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 84 | chg-gpios = <&gpio0 30 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 85 | stby-gpios = <&gpio0 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 86 | clk-gpios = <&gpio0 31 (GPIO_OPEN_DRAIN)>; 87 | }; 88 | 89 | }; 90 | 91 | ®1 { 92 | regulator-initial-mode = ; 93 | }; 94 | 95 | &adc { 96 | status = "okay"; 97 | }; 98 | 99 | &gpiote { 100 | status = "okay"; 101 | }; 102 | 103 | &gpio0 { 104 | status = "okay"; 105 | }; 106 | 107 | &gpio1 { 108 | status = "okay"; 109 | }; 110 | 111 | &i2c0 { 112 | compatible = "nordic,nrf-twim"; 113 | status = "okay"; 114 | zephyr,concat-buf-size = <1023>; 115 | zephyr,flash-buf-max-size = <1023>; 116 | clock-frequency = ; 117 | pinctrl-0 = <&i2c0_default>; 118 | pinctrl-1 = <&i2c0_sleep>; 119 | pinctrl-names = "default", "sleep"; 120 | 121 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 122 | compatible = "i2c-device"; 123 | label = "imu"; 124 | reg = <0>; 125 | }; 126 | 127 | mag: mag@0 { 128 | compatible = "i2c-device"; 129 | label = "mag"; 130 | reg = <0>; 131 | }; 132 | 133 | }; 134 | 135 | &pwm0 { 136 | status = "okay"; 137 | pinctrl-0 = <&pwm0_default>; 138 | pinctrl-1 = <&pwm0_sleep>; 139 | pinctrl-names = "default", "sleep"; 140 | }; 141 | 142 | zephyr_udc0: &usbd { 143 | compatible = "nordic,nrf-usbd"; 144 | status = "okay"; 145 | cdc_acm_uart0: cdc_acm_uart0 { 146 | compatible = "zephyr,cdc-acm-uart"; 147 | }; 148 | }; 149 | 150 | &nfct { 151 | status = "disabled"; 152 | }; 153 | -------------------------------------------------------------------------------- /src/sensor/magneto/mymathlib_matrix.h: -------------------------------------------------------------------------------- 1 | void Multiply_Self_Transpose(double *, double *, int, int); 2 | void Get_Submatrix(double *, int, int, double *, int, int, int); 3 | int Choleski_LU_Decomposition(double *, int); 4 | int Choleski_LU_Inverse(double *, int); 5 | void Multiply_Matrices(double *, double *, int, int, double *, int); 6 | void Identity_Matrix(double *, int); 7 | 8 | int Hessenberg_Form_Elementary(double *, double *, int); 9 | void Hessenberg_Elementary_Transform(double *, double *, int[], int); 10 | 11 | void Copy_Vector(double *, double *, int); 12 | 13 | int QR_Hessenberg_Matrix(double *, double *, double[], double[], int, int); 14 | void One_Real_Eigenvalue(double[], double[], double[], int, double); 15 | void Two_Eigenvalues(double *, double *, double[], double[], int, int, double); 16 | void Update_Row(double *, double, double, int, int); 17 | void Update_Column(double *, double, double, int, int); 18 | void Update_Transformation(double *, double, double, int, int); 19 | void Double_QR_Iteration(double *, double *, int, int, int, double *, int); 20 | void Product_and_Sum_of_Shifts(double *, int, int, double *, double *, double *, int); 21 | int Two_Consecutive_Small_Subdiagonal(double *, int, int, int, double, double); 22 | void Double_QR_Step(double *, int, int, int, double, double, double *, int); 23 | void BackSubstitution(double *, double[], double[], int); 24 | void BackSubstitute_Real_Vector(double *, double[], double[], int, double, int); 25 | void BackSubstitute_Complex_Vector(double *, double[], double[], int, double, int); 26 | void Calculate_Eigenvectors(double *, double *, double[], double[], int); 27 | void Complex_Division(double, double, double, double, double *, double *); 28 | 29 | void Transpose_Square_Matrix(double *, int); 30 | 31 | int Lower_Triangular_Solve(double* L, double B[], double x[], int n); 32 | int Lower_Triangular_Inverse(double* L, int n); 33 | int Upper_Triangular_Solve(double* U, double B[], double x[], int n); 34 | 35 | void Interchange_Rows(double* A, int row1, int row2, int ncols); 36 | void Interchange_Columns(double* A, int col1, int col2, int nrows, int ncols); 37 | void Identity_Matrix(double* A, int n); 38 | void Copy_Vector(double* d, double* s, int n); 39 | 40 | void Hessenberg_Elementary_Transform(double* H, double* S, int perm[], int n); 41 | 42 | void One_Real_Eigenvalue(double Hrow[], double eigen_real[], double eigen_imag[], int row, double shift); 43 | void Two_Eigenvalues(double* H, double* S, double eigen_real[], double eigen_imag[], int n, int k, double t); 44 | void Update_Row(double* Hrow, double cos, double sin, int n, int k); 45 | void Update_Column(double* H, double cos, double sin, int n, int k); 46 | void Update_Transformation(double* S, double cos, double sin, int n, int k); 47 | void Double_QR_Iteration(double* H, double* S, int row, int min_row, int n, double* shift, int iteration); 48 | void Product_and_Sum_of_Shifts(double* H, int n, int max_row, double* shift, double* trace, double* det, int iteration); 49 | int Two_Consecutive_Small_Subdiagonal(double* H, int min_row, int max_row, int n, double trace, double det); 50 | void Double_QR_Step(double* H, int min_row, int max_row, int min_col, double trace, double det, double* S, int n); 51 | void Complex_Division(double x, double y, double u, double v, double* a, double* b); 52 | void BackSubstitution(double* H, double eigen_real[], double eigen_imag[], int n); 53 | void BackSubstitute_Real_Vector(double* H, double eigen_real[], double eigen_imag[], int row, double zero_tolerance, int n); 54 | void BackSubstitute_Complex_Vector(double* H, double eigen_real[], double eigen_imag[], int row, double zero_tolerance, int n); 55 | void Calculate_Eigenvectors(double* H, double* S, double eigen_real[], double eigen_imag[], int n); -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p2_uf2/slimevrmini_p2_uf2.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | i2c0_default: i2c0_default { 10 | group1 { 11 | psels = , ; 12 | bias-disable; 13 | }; 14 | }; 15 | 16 | i2c0_sleep: i2c0_sleep { 17 | group1 { 18 | psels = , ; 19 | bias-disable; 20 | low-power-enable; 21 | }; 22 | }; 23 | 24 | pwm0_default: pwm0_default { 25 | group1 { 26 | psels = ; 27 | nordic,drive-mode = ; 28 | nordic,invert; 29 | }; 30 | }; 31 | 32 | pwm0_sleep: pwm0_sleep { 33 | group1 { 34 | psels = ; 35 | low-power-enable; 36 | }; 37 | }; 38 | }; 39 | //end 40 | 41 | / { 42 | model = "slimevrmini_p2_uf2"; 43 | compatible = "slimevrmini_p2_uf2"; 44 | 45 | chosen { 46 | zephyr,sram = &sram0; 47 | zephyr,flash = &flash0; 48 | zephyr,console = &cdc_acm_uart0; 49 | zephyr,shell-uart = &cdc_acm_uart0; 50 | }; 51 | 52 | pwmleds { 53 | compatible = "pwm-leds"; 54 | pwm_led0: pwm_led_0 { 55 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 56 | }; 57 | }; 58 | 59 | buttons { 60 | compatible = "gpio-keys"; 61 | button0: button_0 { 62 | gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 63 | label = "Push button switch 0"; 64 | }; 65 | }; 66 | 67 | aliases { 68 | sw0 = &button0; 69 | pwm-led0 = &pwm_led0; 70 | }; 71 | 72 | battery-divider { 73 | compatible = "voltage-divider"; 74 | status = "okay"; 75 | io-channels = <&adc 0>; 76 | output-ohms = <402000>; 77 | full-ohms = <(402000+402000)>; 78 | power-gpios = <&gpio0 14 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 79 | }; 80 | 81 | zephyr,user { 82 | int0-gpios = <&gpio0 28 0>; 83 | int1-gpios = <&gpio0 30 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 84 | led-gpios = <&gpio0 6 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 85 | //clk-gpios = <&gpio0 28 GPIO_OPEN_DRAIN>; 86 | chg-gpios = <&gpio0 17 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 87 | stby-gpios = <&gpio0 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 88 | //dcdc-gpios = <&gpio1 1 GPIO_OPEN_DRAIN>; 89 | //ldo-gpios = <&gpio1 2 GPIO_OPEN_DRAIN>; 90 | }; 91 | 92 | }; 93 | 94 | ®1 { 95 | regulator-initial-mode = ; 96 | }; 97 | 98 | &adc { 99 | status = "okay"; 100 | }; 101 | 102 | &gpiote { 103 | status = "okay"; 104 | }; 105 | 106 | &gpio0 { 107 | status = "okay"; 108 | }; 109 | 110 | &gpio1 { 111 | status = "okay"; 112 | }; 113 | 114 | &i2c0 { 115 | compatible = "nordic,nrf-twim"; 116 | status = "okay"; 117 | zephyr,concat-buf-size = <1023>; 118 | zephyr,flash-buf-max-size = <1023>; 119 | clock-frequency = ; 120 | pinctrl-0 = <&i2c0_default>; 121 | pinctrl-1 = <&i2c0_sleep>; 122 | pinctrl-names = "default", "sleep"; 123 | 124 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 125 | compatible = "i2c-device"; 126 | label = "imu"; 127 | reg = <0>; 128 | }; 129 | 130 | mag: mag@0 { 131 | compatible = "i2c-device"; 132 | label = "mag"; 133 | reg = <0>; 134 | }; 135 | 136 | }; 137 | 138 | &pwm0 { 139 | status = "okay"; 140 | pinctrl-0 = <&pwm0_default>; 141 | pinctrl-1 = <&pwm0_sleep>; 142 | pinctrl-names = "default", "sleep"; 143 | }; 144 | 145 | zephyr_udc0: &usbd { 146 | compatible = "nordic,nrf-usbd"; 147 | status = "okay"; 148 | cdc_acm_uart0: cdc_acm_uart0 { 149 | compatible = "zephyr,cdc-acm-uart"; 150 | }; 151 | }; 152 | 153 | &nfct { 154 | status = "disabled"; 155 | }; 156 | -------------------------------------------------------------------------------- /boards/slimevr/slimevrmini_p3r6_uf2/slimevrmini_p3r6_uf2.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | i2c0_default: i2c0_default { 10 | group1 { 11 | psels = , ; 12 | bias-disable; 13 | }; 14 | }; 15 | 16 | i2c0_sleep: i2c0_sleep { 17 | group1 { 18 | psels = , ; 19 | bias-disable; 20 | low-power-enable; 21 | }; 22 | }; 23 | 24 | pwm0_default: pwm0_default { 25 | group1 { 26 | psels = ; 27 | nordic,drive-mode = ; 28 | nordic,invert; 29 | }; 30 | }; 31 | 32 | pwm0_sleep: pwm0_sleep { 33 | group1 { 34 | psels = ; 35 | low-power-enable; 36 | }; 37 | }; 38 | }; 39 | //end 40 | 41 | / { 42 | model = "slimevrmini_p3r6_uf2"; 43 | compatible = "slimevrmini_p3r6_uf2"; 44 | 45 | chosen { 46 | zephyr,sram = &sram0; 47 | zephyr,flash = &flash0; 48 | zephyr,console = &cdc_acm_uart0; 49 | zephyr,shell-uart = &cdc_acm_uart0; 50 | }; 51 | 52 | pwmleds { 53 | compatible = "pwm-leds"; 54 | pwm_led0: pwm_led_0 { 55 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 56 | }; 57 | }; 58 | 59 | buttons { 60 | compatible = "gpio-keys"; 61 | button0: button_0 { 62 | gpios = <&gpio0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 63 | label = "Push button switch 0"; 64 | }; 65 | button1: button_1 { 66 | gpios = <&gpio0 31 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 67 | label = "Push button switch 1"; 68 | }; 69 | }; 70 | 71 | aliases { 72 | sw0 = &button0; 73 | sw1 = &button1; 74 | pwm-led0 = &pwm_led0; 75 | }; 76 | 77 | battery-divider { 78 | compatible = "voltage-divider"; 79 | status = "okay"; 80 | io-channels = <&adc 4>; 81 | output-ohms = <40200>; 82 | full-ohms = <(100000+40200)>; 83 | power-gpios = <&gpio0 29 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 84 | }; 85 | 86 | zephyr,user { 87 | int0-gpios = <&gpio0 28 0>; 88 | led-gpios = <&gpio0 15 (GPIO_OPEN_DRAIN | GPIO_ACTIVE_LOW)>; 89 | chg-gpios = <&gpio0 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 90 | stby-gpios = <&gpio0 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 91 | clk-gpios = <&gpio0 30 (GPIO_OPEN_DRAIN)>; 92 | }; 93 | 94 | }; 95 | 96 | ®1 { 97 | regulator-initial-mode = ; 98 | }; 99 | 100 | &adc { 101 | status = "okay"; 102 | }; 103 | 104 | &gpiote { 105 | status = "okay"; 106 | }; 107 | 108 | &gpio0 { 109 | status = "okay"; 110 | }; 111 | 112 | &gpio1 { 113 | status = "okay"; 114 | }; 115 | 116 | &i2c0 { 117 | compatible = "nordic,nrf-twim"; 118 | status = "okay"; 119 | zephyr,concat-buf-size = <1023>; 120 | zephyr,flash-buf-max-size = <1023>; 121 | clock-frequency = ; 122 | pinctrl-0 = <&i2c0_default>; 123 | pinctrl-1 = <&i2c0_sleep>; 124 | pinctrl-names = "default", "sleep"; 125 | 126 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 127 | compatible = "i2c-device"; 128 | label = "imu"; 129 | reg = <0>; 130 | }; 131 | 132 | mag: mag@0 { 133 | compatible = "i2c-device"; 134 | label = "mag"; 135 | reg = <0>; 136 | }; 137 | 138 | }; 139 | 140 | &pwm0 { 141 | status = "okay"; 142 | pinctrl-0 = <&pwm0_default>; 143 | pinctrl-1 = <&pwm0_sleep>; 144 | pinctrl-names = "default", "sleep"; 145 | }; 146 | 147 | zephyr_udc0: &usbd { 148 | compatible = "nordic,nrf-usbd"; 149 | status = "okay"; 150 | cdc_acm_uart0: cdc_acm_uart0 { 151 | compatible = "zephyr,cdc-acm-uart"; 152 | }; 153 | }; 154 | 155 | &nfct { 156 | status = "disabled"; 157 | }; 158 | -------------------------------------------------------------------------------- /src/sensor/scan_spi.c: -------------------------------------------------------------------------------- 1 | /* 2 | SlimeVR Code is placed under the MIT license 3 | Copyright (c) 2025 SlimeVR Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | */ 23 | #include 24 | #include 25 | #include 26 | 27 | LOG_MODULE_REGISTER(sensor_scan_spi, LOG_LEVEL_DBG); 28 | 29 | int sensor_scan_spi(struct spi_dt_spec *bus, uint8_t *spi_dev_reg, int dev_addr_count, const uint8_t dev_reg[], const uint8_t dev_id[], const int dev_ids[]) 30 | { 31 | uint8_t buf[3] = {0}; 32 | struct spi_buf tx_buf = {.len = 1}; 33 | const struct spi_buf_set tx = {.buffers = &tx_buf, .count = 1}; 34 | struct spi_buf rx_buf = {.buf = buf, .len = 3}; 35 | const struct spi_buf_set rx = {.buffers = &rx_buf, .count = 1}; 36 | 37 | int reg_index = 0; 38 | int id_index = 0; 39 | int found_id = 0; 40 | 41 | for (int i = 0; i < dev_addr_count; i++) 42 | { 43 | int reg_count = dev_reg[reg_index]; 44 | int id_count = dev_id[id_index]; 45 | reg_index++; 46 | id_index++; 47 | int id_cnt = id_count; 48 | int id_ind = id_index; 49 | int fnd_id = found_id; 50 | for (int k = 0; k < reg_count; k++) 51 | { 52 | uint8_t reg = dev_reg[reg_index + k]; 53 | if (*spi_dev_reg == 0xFF || *spi_dev_reg == reg) 54 | { 55 | uint8_t id; 56 | tx_buf.buf = ® 57 | reg |= 0x80; // set read bit 58 | LOG_DBG("Scanning register: 0x%02X", reg); 59 | // TODO: BMM150 workaround? 60 | int err = spi_transceive_dt(bus, &tx, &rx); 61 | LOG_DBG("err: %d", err); 62 | id = buf[1] ? buf[1] : buf[2]; // ID may be in first byte, or skip one byte (such as BMI270) 63 | LOG_DBG("Read value: 0x%02X, 0x%02X, 0x%02X (0x%02X)", buf[0], buf[1], buf[2], id); 64 | if (err) 65 | continue; 66 | for (int l = 0; l < id_cnt; l++) 67 | { 68 | if (id == dev_id[id_ind + l]) 69 | { 70 | *spi_dev_reg = reg; 71 | LOG_INF("Valid device found using register: 0x%02X (value: 0x%02X)", reg, id); 72 | return dev_ids[fnd_id + l]; 73 | } 74 | } 75 | } 76 | id_ind += id_cnt; 77 | fnd_id += id_cnt; 78 | id_cnt = dev_id[id_ind]; 79 | id_ind++; 80 | } 81 | reg_index += reg_count; 82 | id_index += id_count; 83 | found_id += id_count; 84 | for (int j = 1; j < reg_count; j++) 85 | { 86 | id_count = dev_id[id_index]; 87 | id_index++; 88 | id_index += id_count; 89 | found_id += id_count; 90 | } 91 | } 92 | 93 | if (*spi_dev_reg != 0xFF) // preferred register failed, try again with full scan 94 | { 95 | LOG_WRN("No device found using register: 0x%02X", *spi_dev_reg); 96 | *spi_dev_reg = 0xFF; 97 | return sensor_scan_spi(bus, spi_dev_reg, dev_addr_count, dev_reg, dev_id, dev_ids); 98 | } 99 | 100 | return -1; 101 | } 102 | -------------------------------------------------------------------------------- /boards/sctanf/slimenrf_r3/slimenrf_r3.dts: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Nordic Semiconductor ASA 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | /dts-v1/; 5 | #include 6 | 7 | //move to dtsi? 8 | &pinctrl { 9 | i2c0_default: i2c0_default { 10 | group1 { 11 | psels = , ; 12 | bias-disable; 13 | }; 14 | }; 15 | 16 | i2c0_sleep: i2c0_sleep { 17 | group1 { 18 | psels = , ; 19 | bias-disable; 20 | low-power-enable; 21 | }; 22 | }; 23 | 24 | pwm0_default: pwm0_default { 25 | group1 { 26 | psels = ; 27 | nordic,drive-mode = ; 28 | nordic,invert; 29 | }; 30 | }; 31 | 32 | pwm0_sleep: pwm0_sleep { 33 | group1 { 34 | psels = ; 35 | low-power-enable; 36 | }; 37 | }; 38 | }; 39 | //end 40 | 41 | / { 42 | model = "slimenrf_r3"; 43 | compatible = "slimenrf_r3"; 44 | 45 | chosen { 46 | zephyr,sram = &sram0; 47 | zephyr,flash = &flash0; 48 | zephyr,console = &cdc_acm_uart0; 49 | zephyr,shell-uart = &cdc_acm_uart0; 50 | }; 51 | 52 | pwmleds { 53 | compatible = "pwm-leds"; 54 | pwm_led0: pwm_led_0 { 55 | pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_INVERTED>; 56 | }; 57 | }; 58 | 59 | buttons { 60 | compatible = "gpio-keys"; 61 | button0: button_0 { 62 | gpios = <&gpio0 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; 63 | label = "Push button switch 0"; 64 | }; 65 | }; 66 | 67 | aliases { 68 | sw0 = &button0; 69 | pwm-led0 = &pwm_led0; 70 | }; 71 | 72 | battery-divider { 73 | compatible = "voltage-divider"; 74 | status = "okay"; 75 | io-channels = <&adc 1>; 76 | output-ohms = <510000>; 77 | full-ohms = <(1000000+510000)>; 78 | power-gpios = <&gpio1 10 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 79 | }; 80 | 81 | zephyr,user { 82 | dock-gpios = <&gpio0 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 83 | int0-gpios = <&gpio0 8 0>; 84 | led-gpios = <&gpio0 7 (GPIO_OPEN_DRAIN|GPIO_ACTIVE_LOW)>; 85 | clk-gpios = <&gpio0 28 GPIO_OPEN_DRAIN>; 86 | chg-gpios = <&gpio1 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 87 | stby-gpios = <&gpio0 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 88 | dcdc-gpios = <&gpio0 31 GPIO_OPEN_DRAIN>; 89 | ldo-gpios = <&gpio0 30 GPIO_PUSH_PULL>; 90 | }; 91 | 92 | }; 93 | 94 | ®1 { 95 | regulator-initial-mode = ; 96 | }; 97 | 98 | &adc { 99 | status = "okay"; 100 | }; 101 | 102 | &gpiote { 103 | status = "okay"; 104 | }; 105 | 106 | &gpio0 { 107 | status = "okay"; 108 | }; 109 | 110 | &gpio1 { 111 | status = "okay"; 112 | }; 113 | 114 | &i2c0 { 115 | compatible = "nordic,nrf-twim"; 116 | status = "okay"; 117 | zephyr,concat-buf-size = <1023>; 118 | zephyr,flash-buf-max-size = <1023>; 119 | clock-frequency = ; 120 | pinctrl-0 = <&i2c0_default>; 121 | pinctrl-1 = <&i2c0_sleep>; 122 | pinctrl-names = "default", "sleep"; 123 | 124 | imu: imu@0 { // any address out of range (00, 7f, etc. will search all addresses and stored address first if available, specify an address here to search first otherwise 125 | compatible = "i2c-device"; 126 | label = "imu"; 127 | reg = <0>; 128 | }; 129 | 130 | mag: mag@0 { 131 | compatible = "i2c-device"; 132 | label = "mag"; 133 | reg = <0>; 134 | }; 135 | 136 | }; 137 | 138 | &pwm0 { 139 | status = "okay"; 140 | pinctrl-0 = <&pwm0_default>; 141 | pinctrl-1 = <&pwm0_sleep>; 142 | pinctrl-names = "default", "sleep"; 143 | }; 144 | 145 | zephyr_udc0: &usbd { 146 | compatible = "nordic,nrf-usbd"; 147 | status = "okay"; 148 | cdc_acm_uart0: cdc_acm_uart0 { 149 | compatible = "zephyr,cdc-acm-uart"; 150 | }; 151 | }; 152 | 153 | &cryptocell { 154 | status = "disabled"; 155 | }; 156 | 157 | &nfct { 158 | status = "disabled"; 159 | }; 160 | --------------------------------------------------------------------------------