diff --git a/.ci/Jenkinsfile-compile b/.ci/Jenkinsfile-compile
index f6a6275632..a6628c8b6d 100644
--- a/.ci/Jenkinsfile-compile
+++ b/.ci/Jenkinsfile-compile
@@ -9,7 +9,7 @@ pipeline {
script {
def build_nodes = [:]
def docker_images = [
- armhf: "px4io/px4-dev-armhf:2022-08-12",
+ armhf: "px4io/px4-dev-armhf:2023-06-26",
arm64: "px4io/px4-dev-aarch64:2022-08-12",
base: "px4io/px4-dev-ros2-foxy:2022-08-12",
nuttx: "px4io/px4-dev-nuttx-focal:2022-08-12",
@@ -40,6 +40,8 @@ pipeline {
"ark_can-flow_default",
"ark_can-gps_canbootloader",
"ark_can-gps_default",
+ "ark_cannode_canbootloader",
+ "ark_cannode_default",
"ark_can-rtk-gps_canbootloader",
"ark_can-rtk-gps_default",
"ark_fmu-v6x_bootloader",
@@ -53,8 +55,10 @@ pipeline {
"cuav_nora_default",
"cuav_x7pro_default",
"cubepilot_cubeorange_default",
+ "cubepilot_cubeorangeplus_default",
"cubepilot_cubeyellow_default",
"diatone_mamba-f405-mk2_default",
+ "flywoo_gn-f405_default",
"freefly_can-rtk-gps_canbootloader",
"freefly_can-rtk-gps_default",
"holybro_can-gps-v1_canbootloader",
@@ -72,7 +76,7 @@ pipeline {
"matek_h743_default",
"modalai_fc-v1_default",
"modalai_fc-v2_default",
- "modalai_voxl2-io_default",
+ "mro_ctrl-zero-classic_default",
"mro_ctrl-zero-f7_default",
"mro_ctrl-zero-f7-oem_default",
"mro_ctrl-zero-h7-oem_default",
@@ -85,6 +89,7 @@ pipeline {
"nxp_fmuk66-v3_default",
"nxp_fmuk66-v3_socketcan",
"nxp_fmurt1062-v1_default",
+ "nxp_mr-canhubk3_default",
"nxp_ucans32k146_canbootloader",
"nxp_ucans32k146_default",
"omnibus_f4sd_default",
@@ -112,7 +117,8 @@ pipeline {
"spracing_h7extreme_default",
"thepeach_k1_default",
"thepeach_r1_default",
- "uvify_core_default"
+ "uvify_core_default",
+ "siyi_n7_default"
],
image: docker_images.nuttx,
archive: true
@@ -164,7 +170,7 @@ pipeline {
}
options {
buildDiscarder(logRotator(numToKeepStr: '5', artifactDaysToKeepStr: '14'))
- timeout(time: 90, unit: 'MINUTES')
+ timeout(time: 120, unit: 'MINUTES')
}
}
diff --git a/.ci/Jenkinsfile-hardware b/.ci/Jenkinsfile-hardware
index bb1b8f8a73..73483107a7 100644
--- a/.ci/Jenkinsfile-hardware
+++ b/.ci/Jenkinsfile-hardware
@@ -12,7 +12,7 @@ pipeline {
stage("build cubepilot_cubeorange_test") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -91,7 +91,7 @@ pipeline {
stage("build cuav_x7pro_test") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -165,7 +165,7 @@ pipeline {
stage("build px4_fmu-v4_test") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -238,7 +238,7 @@ pipeline {
stage("build px4_fmu-v4pro_test") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -312,7 +312,7 @@ pipeline {
stage("build px4_fmu-v5_debug") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -362,7 +362,7 @@ pipeline {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "sd_stress"'
// test dataman
- sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman"'
+ sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman" --ignore-stdout-errors'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests file" || true'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "uorb_tests"'
@@ -403,7 +403,7 @@ pipeline {
stage("build px4_fmu-v5_stackcheck") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -449,7 +449,7 @@ pipeline {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "uorb_tests latency_test" || true'
// test dataman
- sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman"'
+ sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-*` --cmd "tests dataman" --ignore-stdout-errors'
}
}
stage("status") {
@@ -486,7 +486,7 @@ pipeline {
stage("build px4_fmu-v5_test") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
@@ -560,7 +560,7 @@ pipeline {
stage("build nxp_fmuk66-v3_test") {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-09-08'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '--cpu-shares 512 -e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index b0914106ed..a9ac652d18 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -2,7 +2,7 @@
// https://github.com/microsoft/vscode-dev-containers/tree/v0.134.0/containers/cpp
{
"name": "px4-dev-nuttx",
- "image": "px4io/px4-dev-nuttx-focal:2021-09-08",
+ "image": "px4io/px4-dev-nuttx-focal:2022-08-12",
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
@@ -29,7 +29,8 @@
"twxs.cmake",
"uavcan.dsdl",
"wholroyd.jinja",
- "zixuanwang.linkerscript"
+ "zixuanwang.linkerscript",
+ "ms-vscode.makefile-tools"
],
"containerUser": "user",
diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.md b/.github/ISSUE_TEMPLATE/1_Bug_report.md
deleted file mode 100644
index cc0bc6d96f..0000000000
--- a/.github/ISSUE_TEMPLATE/1_Bug_report.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-name: 🐛 Bug report
-about: Create a report to help us improve
-labels: bug-report
-
----
-
-## Describe the bug
-A clear and concise description of the bug.
-
-## To Reproduce
-Steps to reproduce the behavior:
-1. Drone switched on '...'
-2. Uploaded mission '....' (attach QGC mission file)
-3. Took off '....'
-4. See error
-
-## Expected behavior
-A clear and concise description of what you expected to happen.
-
-## Log Files and Screenshots
-*Always* provide a link to the flight log file:
-- Download the flight log file from the vehicle ([tutorial](https://docs.px4.io/main/en/getting_started/flight_reporting.html)).
-- Upload the log to the [PX4 Flight Review](http://logs.px4.io/)
-- Share the link to the log (Copy and paste the URL of the log)
-
-Add screenshots to help explain your problem.
-
-## Drone (please complete the following information):
-- Describe the type of drone.
-- Photo of the IMU / autopilot setup if possible.
-
-## Additional context
-Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/2_Feature_request.md b/.github/ISSUE_TEMPLATE/2_Feature_request.md
deleted file mode 100644
index adcdc30fd8..0000000000
--- a/.github/ISSUE_TEMPLATE/2_Feature_request.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-name: 🚀 Feature Request
-about: Suggest an idea for this project
-labels: feature-request
-
----
-
-For general questions please use [PX4 Discuss](http://discuss.px4.io/) or Discord (you can find an invite link on this project README).
-
-## Describe problem solved by the proposed feature
-A clear and concise description of the problem, if any, this feature will solve. E.g. I'm always frustrated when ...
-
-## Describe your preferred solution
-A clear and concise description of what you want to happen.
-
-## Describe possible alternatives
-A clear and concise description of alternative solutions or features you've considered.
-
-## Additional context
-Add any other context or screenshots for the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/3_Support_question.md b/.github/ISSUE_TEMPLATE/3_Support_question.md
deleted file mode 100644
index 7c331f2dc1..0000000000
--- a/.github/ISSUE_TEMPLATE/3_Support_question.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-name: ⛔ Support Question
-about: See http://discuss.px4.io/ for questions about using PX4.
-
----
-
-## Attention! Please read the note below
-
-We use GitHub issues only to discuss PX4 bugs and new features.
-
-**For questions about using PX4 or related components, please use [PX4 Discuss](http://discuss.px4.io/).**
-
-Thanks!
diff --git a/.github/ISSUE_TEMPLATE/4_Documentation_issue.md b/.github/ISSUE_TEMPLATE/4_Documentation_issue.md
deleted file mode 100644
index 0e14e82cc5..0000000000
--- a/.github/ISSUE_TEMPLATE/4_Documentation_issue.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-name: ⛔ Documentation Issue
-about: See https://github.com/PX4/px4_user_guide for documentation issues
-
----
-
-## Attention! Please read the note below
-
-**Please submit the documentation issue to the [User Guide](https://github.com/PX4/px4_user_guide) repository.**
-
-Thanks!
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000000..60d93ea9b8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,94 @@
+name: 🐛 Bug report
+description: Create a report to help us improve
+title: "[Bug] "
+labels: ["bug-report"]
+body:
+ - type: textarea
+ attributes:
+ label: Describe the bug
+ description: A clear and concise description of the bug.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: To Reproduce
+ description: |
+ Steps to reproduce the behavior.
+ 1. Drone switched on '...'
+ 2. Uploaded mission '....' (attach QGC mission file)
+ 3. Took off '....'
+ 4. See error
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Expected behavior
+ description: A clear and concise description of what you expected to happen.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Screenshot / Media
+ description: Add screenshot / media if you have them
+
+ - type: textarea
+ attributes:
+ label: Flight Log
+ description: |
+ *Always* provide a link to the flight log file:
+ - Download the flight log file from the vehicle ([tutorial](https://docs.px4.io/main/en/getting_started/flight_reporting.html)).
+ - Upload the log to the [PX4 Flight Review](http://logs.px4.io/)
+ - Share the link to the log (Copy and paste the URL of the log)
+ placeholder: |
+ # PASTE HERE THE LINK TO THE LOG
+ validations:
+ required: true
+
+ - type: markdown
+ attributes:
+ value: |
+ ## Setup
+
+ - type: textarea
+ attributes:
+ label: Software Version
+ description: |
+ Which version of PX4 are you using?
+ placeholder: |
+ # If you don't know the version, paste the output of `ver all` in the MAVLink Shell of QGC
+ validations:
+ required: true
+
+ - type: input
+ attributes:
+ label: Flight controller
+ description: Specify your flight controller model (what type is it, where was it bought from, ...).
+ validations:
+ required: true
+
+ - type: dropdown
+ attributes:
+ label: Vehicle type
+ options:
+ - Multicopter
+ - Helicopter
+ - Fixed Wing
+ - Hybrid VTOL
+ - Airship/Balloon
+ - Rover
+ - Boat
+ - Submarine
+ - Other
+
+ - type: textarea
+ attributes:
+ label: How are the different components wired up (including port information)
+ description: Details about how all is wired.
+
+ - type: textarea
+ attributes:
+ label: Additional context
+ description: Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..92ab6b5184
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,8 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Support Question
+ url: https://docs.px4.io/main/en/contribute/support.html#forums-and-chat
+ about: For questions about using PX4 or related components, please use the discuss forum and discord server
+ - name: Documentation Issue
+ url: https://github.com/PX4/PX4-user_guide/issues
+ about: If you found an issue in documentation, please submit it directly to the docs repository issues
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000000..955ef1f353
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,35 @@
+name: 🚀 Feature Request
+description: Suggest an idea for this project
+labels: ["feature-request"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Please note that feature requests are not 'fire and forget'
+ It is a lot more likely that the feature you would like to have will be implemented if you keep watching your feature request, and provide more details to developers looking into implementing your feature, and help them with testing.
+
+ - type: textarea
+ attributes:
+ label: Describe problem solved by the proposed feature
+ description: A clear and concise description of the problem, if any, this feature will solve. E.g. I'm always frustrated when ...
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Describe your preferred solution
+ description: A clear and concise description of what you want to happen.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Describe possible alternatives
+ description: A clear and concise description of any alternative solutions or features you've considered.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Additional context
+ description: Add any other context or screenshots for the feature request here.
diff --git a/.github/slack.svg b/.github/slack.svg
deleted file mode 100644
index 2b0fbae4aa..0000000000
--- a/.github/slack.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index f20bbd3977..0000000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-# Number of days of inactivity before an issue becomes stale
-daysUntilStale: 90
-# Number of days of inactivity before a stale issue is closed, or `false` to disable
-daysUntilClose: false
-# Issues with these labels will never be considered stale
-exemptLabels:
- - pinned
-# Label to use when marking an issue as stale
-staleLabel: stale
-# Comment to post when marking an issue as stale. Set to `false` to disable
-markComment: >
- This issue has been automatically marked as stale because it has not had
- recent activity. Thank you for your contributions.
-# Comment to post when closing a stale issue. Set to `false` to disable
-closeComment: false
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index ef15d32171..f8a893e747 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -28,7 +28,7 @@ jobs:
"parameters_metadata",
]
container:
- image: px4io/px4-dev-nuttx-focal:2021-09-08
+ image: px4io/px4-dev-nuttx-focal:2022-08-12
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
steps:
- uses: actions/checkout@v1
diff --git a/.github/workflows/compile_linux.yml b/.github/workflows/compile_linux.yml
index d14b533475..23e46deab7 100644
--- a/.github/workflows/compile_linux.yml
+++ b/.github/workflows/compile_linux.yml
@@ -1,9 +1,12 @@
-name: Linux Targets
+name: Compile Linux Targets
on:
push:
branches:
- 'main'
+ - 'stable'
+ - 'beta'
+ - 'release/*'
pull_request:
branches:
- '*'
@@ -11,7 +14,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
- container: px4io/px4-dev-armhf:2021-09-08
+ container: px4io/px4-dev-armhf:2023-06-26
strategy:
matrix:
config: [
@@ -24,7 +27,8 @@ jobs:
- uses: actions/checkout@v1
with:
token: ${{secrets.ACCESS_TOKEN}}
-
+ - name: ownership workaround
+ run: git config --system --add safe.directory '*'
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
diff --git a/.github/workflows/compile_linux_arm64.yml b/.github/workflows/compile_linux_arm64.yml
index 81ecc12569..5c1c318b41 100644
--- a/.github/workflows/compile_linux_arm64.yml
+++ b/.github/workflows/compile_linux_arm64.yml
@@ -1,9 +1,12 @@
-name: Linux ARM64 Targets
+name: Compile Linux ARM64 Targets
on:
push:
branches:
- 'main'
+ - 'stable'
+ - 'beta'
+ - 'release/*'
pull_request:
branches:
- '*'
@@ -11,7 +14,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
- container: px4io/px4-dev-aarch64:2021-09-08
+ container: px4io/px4-dev-aarch64:2022-08-12
strategy:
matrix:
config: [
diff --git a/.github/workflows/compile_macos.yml b/.github/workflows/compile_macos.yml
index 45f6f5a615..227b6d3c05 100644
--- a/.github/workflows/compile_macos.yml
+++ b/.github/workflows/compile_macos.yml
@@ -10,13 +10,12 @@ on:
jobs:
build:
- runs-on: macos-10.15
+ runs-on: macos-latest
strategy:
matrix:
config: [
px4_fmu-v5_default,
px4_sitl
- #tests, # includes px4_sitl
]
steps:
- uses: actions/checkout@v1
diff --git a/.github/workflows/compile_nuttx.yml b/.github/workflows/compile_nuttx.yml
index 67b055fdd9..de5a0b7c72 100644
--- a/.github/workflows/compile_nuttx.yml
+++ b/.github/workflows/compile_nuttx.yml
@@ -1,9 +1,12 @@
-name: Nuttx Targets
+name: Compile Nuttx Targets
on:
push:
branches:
- 'main'
+ - 'stable'
+ - 'beta'
+ - 'release/*'
pull_request:
branches:
- '*'
@@ -11,7 +14,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
- container: px4io/px4-dev-nuttx-focal:2021-09-08
+ container: px4io/px4-dev-nuttx-focal:2022-08-12
strategy:
fail-fast: false
matrix:
@@ -70,7 +73,8 @@ jobs:
raspberrypi_pico,
sky-drones_smartap-airlink,
spracing_h7extreme,
- uvify_core
+ uvify_core,
+ siyi_n7
]
steps:
- uses: actions/checkout@v1
diff --git a/.github/workflows/deploy_all.yml b/.github/workflows/deploy_all.yml
index 8b0925e688..b4b6ebc814 100644
--- a/.github/workflows/deploy_all.yml
+++ b/.github/workflows/deploy_all.yml
@@ -24,12 +24,15 @@ jobs:
needs: enumerate_targets
strategy:
matrix: ${{fromJson(needs.enumerate_targets.outputs.matrix)}}
- container: px4io/px4-dev-${{ matrix.container }}:2021-09-08
+ container: ${{ matrix.container }}
steps:
- uses: actions/checkout@v1
with:
token: ${{secrets.ACCESS_TOKEN}}
+ - name: ownership workaround
+ run: git config --system --add safe.directory '*'
+
- name: make ${{matrix.target}}
run: make ${{matrix.target}}
diff --git a/.github/workflows/failsafe_sim.yml b/.github/workflows/failsafe_sim.yml
index 6d5e73d5a5..4d2ed21728 100644
--- a/.github/workflows/failsafe_sim.yml
+++ b/.github/workflows/failsafe_sim.yml
@@ -21,7 +21,7 @@ jobs:
"failsafe_web",
]
container:
- image: px4io/px4-dev-nuttx-focal:2021-09-08
+ image: px4io/px4-dev-nuttx-focal:2022-08-12
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
steps:
- uses: actions/checkout@v1
diff --git a/.github/workflows/metadata.yml b/.github/workflows/metadata.yml
index 10799ba38f..e7289b34f7 100644
--- a/.github/workflows/metadata.yml
+++ b/.github/workflows/metadata.yml
@@ -103,7 +103,7 @@ jobs:
uorb_graph:
runs-on: ubuntu-latest
- container: px4io/px4-dev-nuttx-focal:2021-09-08
+ container: px4io/px4-dev-nuttx-focal:2022-08-12
steps:
- uses: actions/checkout@v1
with:
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 7cbba4b282..9e97122d43 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -1,4 +1,4 @@
-name: 'Close stale issues and PRs'
+name: 'Handle stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
@@ -7,14 +7,10 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- - uses: actions/stale@v4.1.1
+ - uses: actions/stale@v8
with:
- stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
- stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.'
- close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
- close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
- days-before-issue-stale: 30
- days-before-pr-stale: 45
- days-before-issue-close: 5
- days-before-pr-close: 10
- debug-only: true
+ days-before-stale: 30
+ days-before-close: -1
+ stale-issue-label: 'stale'
+ stale-pr-label: 'stale'
+ remove-stale-when-updated: true
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index b49f659083..ec49a0c75f 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -18,6 +18,7 @@
"twxs.cmake",
"uavcan.dsdl",
"wholroyd.jinja",
- "zixuanwang.linkerscript"
+ "zixuanwang.linkerscript",
+ "ms-vscode.makefile-tools"
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 35c3146dcf..67016f0983 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -127,5 +127,6 @@
"terminal.integrated.scrollback": 15000,
"yaml.schemas": {
"${workspaceFolder}/validation/module_schema.yaml": "${workspaceFolder}/src/modules/*/module.yaml"
- }
+ },
+ "ros.distro": "humble"
}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 741e8e574a..b1587b157a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -414,6 +414,8 @@ endif()
#
add_library(parameters_interface INTERFACE)
add_library(kernel_parameters_interface INTERFACE)
+add_library(events_interface INTERFACE)
+add_library(kernel_events_interface INTERFACE)
include(px4_add_library)
add_subdirectory(src/lib EXCLUDE_FROM_ALL)
@@ -440,8 +442,11 @@ add_subdirectory(src/lib/parameters EXCLUDE_FROM_ALL)
if(${PX4_PLATFORM} STREQUAL "nuttx" AND NOT CONFIG_BUILD_FLAT)
target_link_libraries(parameters_interface INTERFACE usr_parameters)
target_link_libraries(kernel_parameters_interface INTERFACE parameters)
+ target_link_libraries(events_interface INTERFACE usr_events)
+ target_link_libraries(kernel_events_interface INTERFACE events)
else()
target_link_libraries(parameters_interface INTERFACE parameters)
+ target_link_libraries(events_interface INTERFACE events)
endif()
# firmware added last to generate the builtin for included modules
diff --git a/Jenkinsfile b/Jenkinsfile
index a983c043c0..30683ffe16 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -94,7 +94,7 @@ pipeline {
stage('failsafe docs') {
agent {
- docker { image 'px4io/px4-dev-nuttx-focal:2021-08-18' }
+ docker { image 'px4io/px4-dev-nuttx-focal:2022-08-12' }
}
steps {
sh '''#!/bin/bash -l
@@ -125,7 +125,7 @@ pipeline {
stage('uORB graphs') {
agent {
docker {
- image 'px4io/px4-dev-nuttx-focal:2021-08-18'
+ image 'px4io/px4-dev-nuttx-focal:2022-08-12'
args '-e CCACHE_BASEDIR=$WORKSPACE -v ${CCACHE_DIR}:${CCACHE_DIR}:rw'
}
}
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1010_gazebo-classic_iris_opt_flow b/ROMFS/px4fmu_common/init.d-posix/airframes/1010_gazebo-classic_iris_opt_flow
index e59ce4d24f..28c3e34f71 100644
--- a/ROMFS/px4fmu_common/init.d-posix/airframes/1010_gazebo-classic_iris_opt_flow
+++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1010_gazebo-classic_iris_opt_flow
@@ -31,6 +31,7 @@ param set-default PWM_MAIN_FUNC4 104
# EKF2
param set-default EKF2_GPS_CTRL 0
+param set-default EKF2_HGT_REF 0
param set-default EKF2_EVP_NOISE 0.05
param set-default EKF2_EVA_NOISE 0.05
param set-default EKF2_OF_CTRL 1
@@ -39,6 +40,9 @@ param set-default EKF2_OF_CTRL 1
param set-default LPE_FUSION 242
param set-default LPE_FAKE_ORIGIN 1
+# Commander
+# param set-default COM_HOME_EN 0 # Disable setting of home position
+
param set-default MPC_ALT_MODE 2
param set-default SENS_FLOW_ROT 6
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1015_gazebo-classic_iris_obs_avoid b/ROMFS/px4fmu_common/init.d-posix/airframes/1014_gazebo-classic_iris_obs_avoid
similarity index 100%
rename from ROMFS/px4fmu_common/init.d-posix/airframes/1015_gazebo-classic_iris_obs_avoid
rename to ROMFS/px4fmu_common/init.d-posix/airframes/1014_gazebo-classic_iris_obs_avoid
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1015_gazebo-classic_iris_obs_avoid.post b/ROMFS/px4fmu_common/init.d-posix/airframes/1014_gazebo-classic_iris_obs_avoid.post
similarity index 100%
rename from ROMFS/px4fmu_common/init.d-posix/airframes/1015_gazebo-classic_iris_obs_avoid.post
rename to ROMFS/px4fmu_common/init.d-posix/airframes/1014_gazebo-classic_iris_obs_avoid.post
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1015_gazebo-classic_iris_depth_camera b/ROMFS/px4fmu_common/init.d-posix/airframes/1015_gazebo-classic_iris_depth_camera
new file mode 100644
index 0000000000..3dc7b0fd75
--- /dev/null
+++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1015_gazebo-classic_iris_depth_camera
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# @name 3DR Iris Quadrotor with a depth camera (forward-facing)
+#
+# @type Quadrotor Wide
+#
+
+. ${R}etc/init.d-posix/airframes/10015_gazebo-classic_iris
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1016_gazebo-classic_iris_downward_depth_camera b/ROMFS/px4fmu_common/init.d-posix/airframes/1016_gazebo-classic_iris_downward_depth_camera
new file mode 100644
index 0000000000..b7e7bf51b9
--- /dev/null
+++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1016_gazebo-classic_iris_downward_depth_camera
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# @name 3DR Iris Quadrotor with a depth camera (downward-facing)
+#
+# @type Quadrotor Wide
+#
+
+. ${R}etc/init.d-posix/airframes/10015_gazebo-classic_iris
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult b/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult
index d730e4a55f..9ce6cb61dd 100644
--- a/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult
+++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1032_gazebo-classic_plane_catapult
@@ -7,6 +7,7 @@
param set-default FW_LAUN_DETCN_ON 1
param set-default FW_THR_IDLE 0.1 # needs to be running before throw as that's how gazebo detects arming
+param set-default FW_LAUN_AC_THLD 10
param set-default FW_LND_ANG 8
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane b/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane
index 768a8fbf84..a998b87831 100644
--- a/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane
+++ b/ROMFS/px4fmu_common/init.d-posix/airframes/1039_gazebo-classic_advanced_plane
@@ -8,7 +8,6 @@
param set-default FW_LND_ANG 8
-param set-default FW_THR_LND_MAX 0
param set-default NPFG_PERIOD 12
@@ -36,7 +35,6 @@ param set-default NAV_DLL_ACT 2
param set-default RWTO_TKOFF 1
-#param set-default SYS_CTRL_ALLOC 1
param set-default CA_AIRFRAME 1
param set-default CA_ROTOR_COUNT 1
@@ -61,7 +59,3 @@ param set-default PWM_MAIN_FUNC7 202
param set-default PWM_MAIN_FUNC8 203
param set-default PWM_MAIN_FUNC9 206
param set-default PWM_MAIN_REV 256
-
-
-set MIXER_FILE etc/mixers-sitl/plane_sitl.main.mix
-set MIXER custom
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/8011_gz_omnicopter b/ROMFS/px4fmu_common/init.d-posix/airframes/8011_gz_omnicopter
new file mode 100644
index 0000000000..707df1bba1
--- /dev/null
+++ b/ROMFS/px4fmu_common/init.d-posix/airframes/8011_gz_omnicopter
@@ -0,0 +1,122 @@
+#!/bin/sh
+#
+# @name 6DoF Omnicopter SITL
+#
+# @type Quadrotor Wide
+#
+# @maintainer Jaeyoung Lim
+#
+
+. ${R}etc/init.d/rc.mc_defaults
+
+PX4_SIMULATOR=${PX4_SIMULATOR:=gz}
+PX4_GZ_WORLD=${PX4_GZ_WORLD:=default}
+PX4_SIM_MODEL=${PX4_SIM_MODEL:=omnicopter}
+
+param set-default CA_AIRFRAME 0
+
+param set-default CA_ROTOR_COUNT 8
+param set-default CA_R_REV 255
+
+param set-default CA_ROTOR0_PX 0.14435
+param set-default CA_ROTOR0_PY -0.14435
+param set-default CA_ROTOR0_PZ -0.14435
+param set-default CA_ROTOR0_KM 0.05 # CCW
+param set-default CA_ROTOR0_AX -0.788675
+param set-default CA_ROTOR0_AY -0.211325
+param set-default CA_ROTOR0_AZ -0.57735
+
+param set-default CA_ROTOR1_PX -0.14435
+param set-default CA_ROTOR1_PY -0.14435
+param set-default CA_ROTOR1_PZ -0.14435
+param set-default CA_ROTOR1_KM 0.05
+param set-default CA_ROTOR1_AX 0.211325
+param set-default CA_ROTOR1_AY -0.788675
+param set-default CA_ROTOR1_AZ 0.57735
+
+param set-default CA_ROTOR2_PX 0.14435
+param set-default CA_ROTOR2_PY 0.14435
+param set-default CA_ROTOR2_PZ -0.14435
+param set-default CA_ROTOR2_KM 0.05
+param set-default CA_ROTOR2_AX -0.211325
+param set-default CA_ROTOR2_AY 0.788675
+param set-default CA_ROTOR2_AZ 0.57735
+
+param set-default CA_ROTOR3_PX -0.14435
+param set-default CA_ROTOR3_PY 0.14435
+param set-default CA_ROTOR3_PZ -0.14435
+param set-default CA_ROTOR3_KM 0.05
+param set-default CA_ROTOR3_AX 0.788675
+param set-default CA_ROTOR3_AY 0.211325
+param set-default CA_ROTOR3_AZ -0.57735
+
+param set-default CA_ROTOR4_PX 0.14435
+param set-default CA_ROTOR4_PY -0.14435
+param set-default CA_ROTOR4_PZ 0.14435
+param set-default CA_ROTOR4_KM 0.05
+param set-default CA_ROTOR4_AX 0.788675
+param set-default CA_ROTOR4_AY 0.211325
+param set-default CA_ROTOR4_AZ -0.57735
+
+param set-default CA_ROTOR5_PX -0.14435
+param set-default CA_ROTOR5_PY -0.14435
+param set-default CA_ROTOR5_PZ 0.14435
+param set-default CA_ROTOR5_KM 0.05
+param set-default CA_ROTOR5_AX -0.211325
+param set-default CA_ROTOR5_AY 0.788675
+param set-default CA_ROTOR5_AZ 0.57735
+
+param set-default CA_ROTOR6_PX 0.14435
+param set-default CA_ROTOR6_PY 0.14435
+param set-default CA_ROTOR6_PZ 0.14435
+param set-default CA_ROTOR6_KM 0.05
+param set-default CA_ROTOR6_AX 0.211325
+param set-default CA_ROTOR6_AY -0.788675
+param set-default CA_ROTOR6_AZ 0.57735
+
+param set-default CA_ROTOR7_PX -0.14435
+param set-default CA_ROTOR7_PY 0.14435
+param set-default CA_ROTOR7_PZ 0.14435
+param set-default CA_ROTOR7_KM 0.05
+param set-default CA_ROTOR7_AX -0.788675
+param set-default CA_ROTOR7_AY -0.211325
+param set-default CA_ROTOR7_AZ -0.57735
+
+param set-default SIM_GZ_EN 1
+param set-default SENS_EN_GPSSIM 1
+param set-default SENS_EN_BAROSIM 0
+param set-default SENS_EN_MAGSIM 1
+
+param set-default SIM_GZ_EC_FUNC1 101
+param set-default SIM_GZ_EC_FUNC2 102
+param set-default SIM_GZ_EC_FUNC3 103
+param set-default SIM_GZ_EC_FUNC4 104
+param set-default SIM_GZ_EC_FUNC5 105
+param set-default SIM_GZ_EC_FUNC6 106
+param set-default SIM_GZ_EC_FUNC7 107
+param set-default SIM_GZ_EC_FUNC8 108
+
+param set-default SIM_GZ_EC_MIN1 0
+param set-default SIM_GZ_EC_MIN2 0
+param set-default SIM_GZ_EC_MIN3 0
+param set-default SIM_GZ_EC_MIN4 0
+param set-default SIM_GZ_EC_MIN5 0
+param set-default SIM_GZ_EC_MIN6 0
+param set-default SIM_GZ_EC_MIN7 0
+param set-default SIM_GZ_EC_MIN8 0
+
+param set-default SIM_GZ_EC_MAX1 1100
+param set-default SIM_GZ_EC_MAX2 1100
+param set-default SIM_GZ_EC_MAX3 1100
+param set-default SIM_GZ_EC_MAX4 1100
+param set-default SIM_GZ_EC_MAX5 1100
+param set-default SIM_GZ_EC_MAX6 1100
+param set-default SIM_GZ_EC_MAX7 1100
+param set-default SIM_GZ_EC_MAX8 1100
+# disable MC desaturation which improves attitude tracking
+param set-default CA_METHOD 0
+
+# disable attitude failure detection
+param set-default FD_FAIL_P 0
+param set-default FD_FAIL_R 0
+
diff --git a/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt b/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt
index d54134e437..ded0ace48b 100644
--- a/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt
+++ b/ROMFS/px4fmu_common/init.d-posix/airframes/CMakeLists.txt
@@ -39,8 +39,10 @@ px4_add_romfs_files(
1012_gazebo-classic_iris_rplidar
1013_gazebo-classic_iris_vision
1013_gazebo-classic_iris_vision.post
- 1015_gazebo-classic_iris_obs_avoid
- 1015_gazebo-classic_iris_obs_avoid.post
+ 1014_gazebo-classic_iris_obs_avoid
+ 1014_gazebo-classic_iris_obs_avoid.post
+ 1015_gazebo-classic_iris_depth_camera
+ 1016_gazebo-classic_iris_downward_depth_camera
1017_gazebo-classic_iris_opt_flow_mockup
1019_gazebo-classic_iris_dual_gps
1021_gazebo-classic_uuv_hippocampus
@@ -81,6 +83,8 @@ px4_add_romfs_files(
6011_gazebo-classic_typhoon_h480
6011_gazebo-classic_typhoon_h480.post
+ 8011_gz_omnicopter
+
10015_gazebo-classic_iris
10016_none_iris
10017_jmavsim_iris
@@ -94,4 +98,6 @@ px4_add_romfs_files(
17001_flightgear_tf-g1
17002_flightgear_tf-g2
+
+ # [22000, 22999] Reserve for custom models
)
diff --git a/ROMFS/px4fmu_common/init.d-posix/px4-rc.simulator b/ROMFS/px4fmu_common/init.d-posix/px4-rc.simulator
index 1f4693d4c1..b0025563df 100644
--- a/ROMFS/px4fmu_common/init.d-posix/px4-rc.simulator
+++ b/ROMFS/px4fmu_common/init.d-posix/px4-rc.simulator
@@ -38,6 +38,19 @@ if [ "$PX4_SIMULATOR" = "sihsim" ] || [ "$(param show -q SYS_AUTOSTART)" -eq "0"
elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" -eq "1" ]; then
+ # set local coordinate frame reference
+ if [ -n "${PX4_HOME_LAT}" ]; then
+ param set SIM_GZ_HOME_LAT ${PX4_HOME_LAT}
+ fi
+
+ if [ -n "${PX4_HOME_LON}" ]; then
+ param set SIM_GZ_HOME_LON ${PX4_HOME_LON}
+ fi
+
+ if [ -n "${PX4_HOME_ALT}" ]; then
+ param set SIM_GZ_HOME_ALT ${PX4_HOME_LON}
+ fi
+
# source generated gz_env.sh for GZ_SIM_RESOURCE_PATH
if [ -f ./gz_env.sh ]; then
. ./gz_env.sh
@@ -59,7 +72,7 @@ elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" -eq "1" ]; th
fi
# look for running ${gz_command} gazebo world
- gz_world=$( ${gz_command} topic -l | grep -m 1 -e "/world/.*/clock" | sed 's/\/world\///g; s/\/clock//g' )
+ gz_world=$( ${gz_command} topic -l | grep -m 1 -e "^/world/.*/clock" | sed 's/\/world\///g; s/\/clock//g' )
# shellcheck disable=SC2153
if [ -z "${gz_world}" ] && [ -n "${PX4_GZ_WORLDS}" ] && [ -n "${PX4_GZ_WORLD}" ]; then
diff --git a/ROMFS/px4fmu_common/init.d-posix/rcS b/ROMFS/px4fmu_common/init.d-posix/rcS
index 7ecbfc3dcb..4421c3c389 100644
--- a/ROMFS/px4fmu_common/init.d-posix/rcS
+++ b/ROMFS/px4fmu_common/init.d-posix/rcS
@@ -187,6 +187,11 @@ param set-default SYS_FAILURE_EN 1
# does not go below 50% by default, but failure injection can trigger failsafes.
param set-default COM_LOW_BAT_ACT 2
+# Allow to override SYS_MC_EST_GROUP via env
+if [ -n "$SYS_MC_EST_GROUP" ]; then
+ param set SYS_MC_EST_GROUP $SYS_MC_EST_GROUP
+fi
+
# Adapt timeout parameters if simulation runs faster or slower than realtime.
if [ -n "$PX4_SIM_SPEED_FACTOR" ]; then
COM_DL_LOSS_T_LONGER=$(echo "$PX4_SIM_SPEED_FACTOR * 10" | bc)
diff --git a/ROMFS/px4fmu_common/init.d/airframes/2106_albatross b/ROMFS/px4fmu_common/init.d/airframes/2106_albatross
index e918ea0f3c..3b51c32f61 100644
--- a/ROMFS/px4fmu_common/init.d/airframes/2106_albatross
+++ b/ROMFS/px4fmu_common/init.d/airframes/2106_albatross
@@ -17,6 +17,7 @@
# @maintainer Andreas Antener
#
# @board bitcraze_crazyflie exclude
+# @board diatone_mamba-f405-mk2 exclude
#
. ${R}etc/init.d/rc.fw_defaults
diff --git a/ROMFS/px4fmu_common/init.d/airframes/4019_x500_v2 b/ROMFS/px4fmu_common/init.d/airframes/4019_x500_v2
index 1fb639236e..e9127020c3 100644
--- a/ROMFS/px4fmu_common/init.d/airframes/4019_x500_v2
+++ b/ROMFS/px4fmu_common/init.d/airframes/4019_x500_v2
@@ -34,9 +34,7 @@ param set-default CA_ROTOR3_PX -0.25
param set-default CA_ROTOR3_PY 0.25
param set-default CA_ROTOR3_KM -0.05
-param set-default PWM_AUX_FUNC1 101
-param set-default PWM_AUX_FUNC2 102
-param set-default PWM_AUX_FUNC3 103
-param set-default PWM_AUX_FUNC4 104
-param set-default PWM_AUX_TIM0 -4
-
+param set-default PWM_MAIN_FUNC1 101
+param set-default PWM_MAIN_FUNC2 102
+param set-default PWM_MAIN_FUNC3 103
+param set-default PWM_MAIN_FUNC4 104
diff --git a/ROMFS/px4fmu_common/init.d/airframes/4900_crazyflie b/ROMFS/px4fmu_common/init.d/airframes/4900_crazyflie
index 211feb4924..7424b9fdb7 100644
--- a/ROMFS/px4fmu_common/init.d/airframes/4900_crazyflie
+++ b/ROMFS/px4fmu_common/init.d/airframes/4900_crazyflie
@@ -13,6 +13,7 @@
# @board px4_fmu-v4pro exclude
# @board px4_fmu-v5 exclude
# @board px4_fmu-v5x exclude
+# @board diatone_mamba-f405-mk2 exclude
#
. ${R}etc/init.d/rc.mc_defaults
@@ -42,7 +43,6 @@ param set-default MC_ROLLRATE_P 0.07
param set-default MC_YAW_P 3
param set-default MPC_THR_HOVER 0.7
-param set-default MPC_THR_MAX 1
param set-default MPC_Z_P 1.5
param set-default MPC_Z_VEL_P_ACC 8
param set-default MPC_Z_VEL_I_ACC 6
diff --git a/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21 b/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21
index 3462b7575f..f9bf887f1e 100644
--- a/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21
+++ b/ROMFS/px4fmu_common/init.d/airframes/4901_crazyflie21
@@ -13,6 +13,7 @@
# @board px4_fmu-v4pro exclude
# @board px4_fmu-v5 exclude
# @board px4_fmu-v5x exclude
+# @board diatone_mamba-f405-mk2 exclude
#
. ${R}etc/init.d/rc.mc_defaults
@@ -41,7 +42,6 @@ param set-default MC_ROLLRATE_P 0.07
param set-default MC_YAW_P 3
param set-default MPC_THR_HOVER 0.7
-param set-default MPC_THR_MAX 1
param set-default MPC_Z_P 1.5
param set-default MPC_Z_VEL_P_ACC 8
param set-default MPC_Z_VEL_I_ACC 6
diff --git a/ROMFS/px4fmu_common/init.d/rc.fw_defaults b/ROMFS/px4fmu_common/init.d/rc.fw_defaults
index 77b10d8cfc..06c6bf717a 100644
--- a/ROMFS/px4fmu_common/init.d/rc.fw_defaults
+++ b/ROMFS/px4fmu_common/init.d/rc.fw_defaults
@@ -34,6 +34,7 @@ param set-default EKF2_REQ_EPV 10
param set-default EKF2_REQ_HDRIFT 0.5
param set-default EKF2_REQ_SACC 1
param set-default EKF2_REQ_VDRIFT 1.0
+param set-default EKF2_RNG_QLTY_T 3.0
param set-default RTL_TYPE 1
param set-default RTL_RETURN_ALT 100
diff --git a/ROMFS/px4fmu_common/init.d/rc.sensors b/ROMFS/px4fmu_common/init.d/rc.sensors
index dd7a1d6bf2..490038c608 100644
--- a/ROMFS/px4fmu_common/init.d/rc.sensors
+++ b/ROMFS/px4fmu_common/init.d/rc.sensors
@@ -172,6 +172,12 @@ then
ms5525dso start -X
fi
+# TE ASP5033 differential pressure sensor external I2C
+if param compare -s SENS_EN_ASP5033 1
+then
+ asp5033 start -X
+fi
+
# SHT3x temperature and hygrometer sensor, external I2C
if param compare -s SENS_EN_SHT3X 1
then
diff --git a/ROMFS/px4fmu_common/init.d/rcS b/ROMFS/px4fmu_common/init.d/rcS
index 8b0dbae4b3..7d53e5b71d 100644
--- a/ROMFS/px4fmu_common/init.d/rcS
+++ b/ROMFS/px4fmu_common/init.d/rcS
@@ -93,6 +93,14 @@ then
fi
fi
+ # Check for an update of the ext_autostart folder, and replace the old one with it
+ if [ -e /fs/microsd/ext_autostart_new ]
+ then
+ echo "Updating external autostart files"
+ rm -r $SDCARD_EXT_PATH
+ mv /fs/microsd/ext_autostart_new $SDCARD_EXT_PATH
+ fi
+
set PARAM_FILE /fs/microsd/params
set PARAM_BACKUP_FILE "/fs/microsd/parameters_backup.bson"
fi
@@ -255,6 +263,7 @@ else
rgbled start -X -q
rgbled_ncp5623c start -X -q
rgbled_lp5562 start -X -q
+ rgbled_is31fl3195 start -X -q
#
# Override parameters from user configuration file.
diff --git a/Tools/HIL/run_nsh_cmd.py b/Tools/HIL/run_nsh_cmd.py
index dcdd9ec1e7..7c37679adf 100755
--- a/Tools/HIL/run_nsh_cmd.py
+++ b/Tools/HIL/run_nsh_cmd.py
@@ -39,7 +39,7 @@ def print_line(line):
print('{0}'.format(line), end='')
-def do_nsh_cmd(port_url, baudrate, cmd):
+def do_nsh_cmd(port_url, baudrate, cmd, ignore_stdout_errors=False):
ser = serial.serial_for_url(url=port_url, baudrate=baudrate, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False, inter_byte_timeout=1)
timeout_start = time.monotonic()
@@ -106,7 +106,7 @@ def do_nsh_cmd(port_url, baudrate, cmd):
if success_cmd in serial_line:
sys.exit(return_code)
else:
- if "ERROR " in serial_line:
+ if "ERROR " in serial_line and not ignore_stdout_errors:
return_code = -1
print_line(serial_line)
@@ -148,6 +148,8 @@ def main():
parser.add_argument('--device', "-d", nargs='?', default=default_device, help='', required=device_required)
parser.add_argument("--baudrate", "-b", dest="baudrate", type=int, help="serial port baud rate (default=57600)", default=57600)
parser.add_argument("--cmd", "-c", dest="cmd", help="Command to run")
+ parser.add_argument('--ignore-stdout-errors', action='store_true',
+ help='Ignore errors printed to stdout')
args = parser.parse_args()
tmp_file = "{0}/pyserial_spy_file.txt".format(tempfile.gettempdir())
@@ -155,7 +157,7 @@ def main():
print("pyserial url: {0}".format(port_url))
- do_nsh_cmd(port_url, args.baudrate, args.cmd)
+ do_nsh_cmd(port_url, args.baudrate, args.cmd, args.ignore_stdout_errors)
if __name__ == "__main__":
main()
diff --git a/Tools/auterion/remote_update_fmu.sh b/Tools/auterion/remote_update_fmu.sh
new file mode 100755
index 0000000000..2eeb66b999
--- /dev/null
+++ b/Tools/auterion/remote_update_fmu.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+# Flash PX4 to a device running AuterionOS in the local network
+if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ $# -lt 2 ]; then
+ echo "Usage: $0 -f [-c ] -d [-u ] [-p ] [--revert]"
+ exit 1
+fi
+
+ssh_port=22
+ssh_user=root
+
+while getopts ":f:c:d:p:u:r" opt; do
+ case ${opt} in
+ f )
+ if [ -n "$OPTARG" ]; then
+ firmware_file="$OPTARG"
+ else
+ echo "ERROR: -f requires a non-empty option argument."
+ exit 1
+ fi
+ ;;
+ c )
+ if [ -f "$OPTARG/rc.autostart" ]; then
+ config_dir="$OPTARG"
+ else
+ echo "ERROR: -c configuration directory is empty or does not contain a valid rc.autostart"
+ exit 1
+ fi
+ ;;
+ d )
+ if [ "$OPTARG" ]; then
+ device="$OPTARG"
+ else
+ echo "ERROR: -d requires a non-empty option argument."
+ exit 1
+ fi
+ ;;
+ p )
+ if [[ "$OPTARG" =~ ^[0-9]+$ ]]; then
+ ssh_port="$OPTARG"
+ else
+ echo "ERROR: -p ssh_port must be a number."
+ exit 1
+ fi
+ ;;
+ u )
+ if [ "$OPTARG" ]; then
+ ssh_user="$OPTARG"
+ else
+ echo "ERROR: -u requires a non-empty option argument."
+ exit 1
+ fi
+ ;;
+ r )
+ revert=true
+ ;;
+ esac
+done
+
+if [ -z "$device" ]; then
+ echo "Error: missing device"
+ exit 1
+fi
+
+target_dir=/shared_container_dir/fmu
+target_file_name="update-dev.tar"
+
+if [ "$revert" == true ]; then
+ # revert to the release version which was originally deployed
+ cmd="cp $target_dir/update.tar $target_dir/$target_file_name"
+ ssh -t -p $ssh_port $ssh_user@$device "$cmd"
+else
+ # create custom update-dev.tar
+ tmp_dir="$(mktemp -d)"
+ config_path=""
+ firmware_path=""
+
+ if [ -d "$config_dir" ]; then
+ cp -r "$config_dir" "$tmp_dir/config"
+ config_path=config
+ fi
+
+ if [ -f "$firmware_file" ]; then
+ extension="${firmware_file##*.}"
+ cp "$firmware_file" "$tmp_dir/firmware.$extension"
+ if [ "$extension" == "elf" ]; then
+ # ensure the file is stripped to reduce file size
+ arm-none-eabi-strip "$tmp_dir/firmware.$extension"
+ fi
+ firmware_path="firmware.$extension"
+ fi
+
+ pushd "$tmp_dir" &>/dev/null
+
+ if [ -z $firmware_path ] && [ -z $config_path ]; then
+ exit 1
+ fi
+
+ tar_name="tar"
+
+ if [ -x "$(command -v gtar)" ]; then
+ # check if gnu-tar is installed on macOS and use that instead
+ tar_name="gtar"
+ fi
+
+ $tar_name -C "$tmp_dir" --sort=name --owner=root:0 --group=root:0 --mtime='2019-01-01 00:00:00' -cvf $target_file_name $firmware_path $config_path
+
+ # send it to the target to start flashing
+ scp -P $ssh_port "$target_file_name" $ssh_user@"$device":$target_dir
+ popd &>/dev/null
+ rm -rf "$tmp_dir"
+fi
+
+# grab status output for flashing progress
+cmd="tail --follow=name $target_dir/update_status 2>/dev/null || true"
+ssh -t -p $ssh_port $ssh_user@$device "$cmd"
diff --git a/Tools/auterion/upload_skynode.sh b/Tools/auterion/upload_skynode.sh
new file mode 100755
index 0000000000..10d8740b42
--- /dev/null
+++ b/Tools/auterion/upload_skynode.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+
+DIR="$(dirname $(readlink -f $0))"
+DEFAULT_AUTOPILOT_HOST=10.41.1.1
+DEFAULT_AUTOPILOT_PORT=33333
+DEFAULT_AUTOPILOT_USER=auterion
+
+for i in "$@"
+do
+ case $i in
+ --file=*)
+ PX4_BINARY_FILE="${i#*=}"
+ ;;
+ --default-ip=*)
+ DEFAULT_AUTOPILOT_HOST="${i#*=}"
+ ;;
+ --default-port=*)
+ DEFAULT_AUTOPILOT_PORT="${i#*=}"
+ ;;
+ --default-user=*)
+ DEFAULT_AUTOPILOT_USER="${i#*=}"
+ ;;
+ --revert)
+ REVERT_AUTOPILOT_ARGUMENT=-r
+ ;;
+ --wifi)
+ DEFAULT_AUTOPILOT_HOST=10.41.0.1
+ ;;
+ *)
+ # unknown option
+ ;;
+ esac
+done
+
+# allow these to be overridden
+[ -z "$AUTOPILOT_HOST" ] && AUTOPILOT_HOST=$DEFAULT_AUTOPILOT_HOST
+[ -z "$AUTOPILOT_PORT" ] && AUTOPILOT_PORT=$DEFAULT_AUTOPILOT_PORT
+[ -z "$AUTOPILOT_USER" ] && AUTOPILOT_USER=$DEFAULT_AUTOPILOT_USER
+
+ARGUMENTS=()
+ARGUMENTS+=(-d "$AUTOPILOT_HOST")
+ARGUMENTS+=(-p "$AUTOPILOT_PORT")
+ARGUMENTS+=(-u "$AUTOPILOT_USER")
+ARGUMENTS+=(${PX4_BINARY_FILE:+-f "$PX4_BINARY_FILE"})
+ARGUMENTS+=($REVERT_AUTOPILOT_ARGUMENT)
+
+echo "Flashing $AUTOPILOT_HOST ..."
+
+"$DIR"/remote_update_fmu.sh "${ARGUMENTS[@]}"
+
+exit 0
diff --git a/Tools/docker_run.sh b/Tools/docker_run.sh
index 3ac640428e..c78b9cc7e1 100755
--- a/Tools/docker_run.sh
+++ b/Tools/docker_run.sh
@@ -4,16 +4,16 @@ if [ -z ${PX4_DOCKER_REPO+x} ]; then
echo "guessing PX4_DOCKER_REPO based on input";
if [[ $@ =~ .*px4_fmu.* ]]; then
# nuttx-px4fmu-v{1,2,3,4,5}
- PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2021-09-08"
+ PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2022-08-12"
elif [[ $@ =~ .*navio2.* ]] || [[ $@ =~ .*raspberry.* ]] || [[ $@ =~ .*beaglebone.* ]] || [[ $@ =~ .*pilotpi.default ]]; then
# beaglebone_blue_default, emlid_navio2_default, px4_raspberrypi_default, scumaker_pilotpi_default
- PX4_DOCKER_REPO="px4io/px4-dev-armhf:2021-08-18"
+ PX4_DOCKER_REPO="px4io/px4-dev-armhf:2023-06-26"
elif [[ $@ =~ .*pilotpi.arm64 ]]; then
# scumaker_pilotpi_arm64
- PX4_DOCKER_REPO="px4io/px4-dev-aarch64:latest"
+ PX4_DOCKER_REPO="px4io/px4-dev-aarch64:2022-08-12"
elif [[ $@ =~ .*navio2.* ]] || [[ $@ =~ .*raspberry.* ]] || [[ $@ =~ .*bebop.* ]]; then
# posix_rpi_cross, posix_bebop_default
- PX4_DOCKER_REPO="px4io/px4-dev-armhf:2021-08-18"
+ PX4_DOCKER_REPO="px4io/px4-dev-armhf:2023-06-26"
elif [[ $@ =~ .*clang.* ]] || [[ $@ =~ .*scan-build.* ]]; then
# clang tools
PX4_DOCKER_REPO="px4io/px4-dev-clang:2021-02-04"
@@ -27,7 +27,7 @@ fi
# otherwise default to nuttx
if [ -z ${PX4_DOCKER_REPO+x} ]; then
- PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2021-09-08"
+ PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2022-08-12"
fi
# docker hygiene
diff --git a/Tools/ecl_ekf/analysis/checks.py b/Tools/ecl_ekf/analysis/checks.py
index ac0248a4c1..36f806ead9 100644
--- a/Tools/ecl_ekf/analysis/checks.py
+++ b/Tools/ecl_ekf/analysis/checks.py
@@ -56,11 +56,14 @@ def perform_imu_checks(
# perform the vibration check
imu_status['imu_vibration_check'] = 'Pass'
for imu_vibr_metric in ['imu_coning', 'imu_hfgyro', 'imu_hfaccel']:
- mean_metric = '{:s}_mean'.format(imu_vibr_metric)
- peak_metric = '{:s}_peak'.format(imu_vibr_metric)
- if imu_metrics[mean_metric] > check_levels['{:s}_warn'.format(mean_metric)] \
- or imu_metrics[peak_metric] > check_levels['{:s}_warn'.format(peak_metric)]:
- imu_status['imu_vibration_check'] = 'Warning'
+ mean_metric = '{:s}_mean_warn'.format(imu_vibr_metric)
+ peak_metric = '{:s}_peak_warn'.format(imu_vibr_metric)
+ mean_key = '{:s}_mean'.format(imu_vibr_metric)
+ peak_key = '{:s}_peak'.format(imu_vibr_metric)
+ if mean_key in imu_metrics and peak_key in imu_metrics:
+ if imu_metrics[mean_key] > check_levels[mean_metric] \
+ or imu_metrics[peak_key] > check_levels[peak_metric]:
+ imu_status['imu_vibration_check'] = 'Warning'
if imu_status['imu_vibration_check'] == 'Warning':
print('IMU vibration check warning.')
diff --git a/Tools/ecl_ekf/analysis/metrics.py b/Tools/ecl_ekf/analysis/metrics.py
index 6c07c12caa..d435f88af9 100644
--- a/Tools/ecl_ekf/analysis/metrics.py
+++ b/Tools/ecl_ekf/analysis/metrics.py
@@ -104,9 +104,9 @@ def calculate_innov_fail_metrics(
# calculate innovation check fail metrics
for signal_id, signal, result in [('posv', 'reject_ver_pos', 'hgt_fail_percentage'),
- ('magx', 'reject_mag_x', 'magx_fail_percentage'),
- ('magy', 'reject_mag_y', 'magy_fail_percentage'),
- ('magz', 'reject_mag_z', 'magz_fail_percentage'),
+ ('magx', 'fs_bad_mag_x', 'magx_fail_percentage'),
+ ('magy', 'fs_bad_mag_y', 'magy_fail_percentage'),
+ ('magz', 'fs_bad_mag_z', 'magz_fail_percentage'),
('yaw', 'reject_yaw', 'yaw_fail_percentage'),
('velh', 'reject_hor_vel', 'vel_fail_percentage'),
('velv', 'reject_ver_vel', 'vel_fail_percentage'),
diff --git a/Tools/ecl_ekf/plotting/pdf_report.py b/Tools/ecl_ekf/plotting/pdf_report.py
index a22e7fec63..785ea4df22 100644
--- a/Tools/ecl_ekf/plotting/pdf_report.py
+++ b/Tools/ecl_ekf/plotting/pdf_report.py
@@ -222,7 +222,7 @@ def create_pdf_report(ulog: ULog, multi_instance: int, output_plot_filename: str
data_plot = CheckFlagsPlot(
status_flags_time, estimator_status_flags, [['reject_hor_vel', 'reject_hor_pos'], ['reject_ver_vel', 'reject_ver_pos',
'reject_hagl'],
- ['reject_mag_x', 'reject_mag_y', 'reject_mag_z',
+ ['fs_bad_mag_x', 'fs_bad_mag_y', 'fs_bad_mag_z',
'reject_yaw'], ['reject_airspeed'], ['reject_sideslip'],
['reject_optflow_x',
'reject_optflow_y']], x_label='time (sec)',
diff --git a/Tools/generate_board_targets_json.py b/Tools/generate_board_targets_json.py
index 83b21e9a74..931d5c1477 100755
--- a/Tools/generate_board_targets_json.py
+++ b/Tools/generate_board_targets_json.py
@@ -61,18 +61,19 @@ def process_target(px4board_file, target_name):
if platform not in excluded_platforms:
# get the container based on the platform and toolchain
- container = platform
if platform == 'posix':
- container = 'base-focal'
+ container = 'px4io/px4-dev-base-focal:2021-09-08'
if toolchain:
if toolchain.startswith('aarch64'):
- container = 'aarch64'
+ container = 'px4io/px4-dev-aarch64:2022-08-12'
elif toolchain == 'arm-linux-gnueabihf':
- container = 'armhf'
+ container = 'px4io/px4-dev-armhf:2023-06-26'
else:
- if verbose: print(f'possibly unmatched toolchain: {toolchain}')
+ if verbose: print(f'unmatched toolchain: {toolchain}')
elif platform == 'nuttx':
- container = 'nuttx-focal'
+ container = 'px4io/px4-dev-nuttx-focal:2022-08-12'
+ else:
+ if verbose: print(f'unmatched platform: {platform}')
ret = {'target': target_name, 'container': container}
@@ -113,4 +114,3 @@ extra_args = {}
if args.pretty:
extra_args['indent'] = 2
print(json.dumps(github_action_config, **extra_args))
-
diff --git a/Tools/msg/templates/ucdr/msg.h.em b/Tools/msg/templates/ucdr/msg.h.em
index 5f68b9256e..d9cbc839f4 100644
--- a/Tools/msg/templates/ucdr/msg.h.em
+++ b/Tools/msg/templates/ucdr/msg.h.em
@@ -124,8 +124,9 @@ static inline constexpr int ucdr_topic_size_@(topic)()
return @(struct_size);
}
-bool ucdr_serialize_@(topic)(const @(uorb_struct)& topic, ucdrBuffer& buf, int64_t time_offset = 0)
+bool ucdr_serialize_@(topic)(const void* data, ucdrBuffer& buf, int64_t time_offset = 0)
{
+ const @(uorb_struct)& topic = *static_cast(data);
@{
for field_type, field_name, field_size, padding in fields:
if padding > 0:
diff --git a/Tools/msg/templates/uorb/msg.cpp.em b/Tools/msg/templates/uorb/msg.cpp.em
index e613d9511f..c3a82cc014 100644
--- a/Tools/msg/templates/uorb/msg.cpp.em
+++ b/Tools/msg/templates/uorb/msg.cpp.em
@@ -77,7 +77,7 @@ topic_fields = ["%s %s" % (convert_type(field.type, True), field.name) for field
constexpr char __orb_@(name_snake_case)_fields[] = "@( ";".join(topic_fields) );";
@[for topic in topics]@
-ORB_DEFINE(@topic, struct @uorb_struct, @(struct_size-padding_end_size), __orb_@(name_snake_case)_fields, static_cast(ORB_ID::@topic));
+ORB_DEFINE(@topic, struct @uorb_struct, @(struct_size-padding_end_size), __orb_@(name_snake_case)_fields, static_cast(ORB_ID::@topic));
@[end for]
void print_message(const orb_metadata *meta, const @uorb_struct& message)
diff --git a/Tools/msg/templates/uorb/uORBTopics.cpp.em b/Tools/msg/templates/uorb/uORBTopics.cpp.em
index c8b1c88397..9a087416e4 100644
--- a/Tools/msg/templates/uorb/uORBTopics.cpp.em
+++ b/Tools/msg/templates/uorb/uORBTopics.cpp.em
@@ -76,5 +76,5 @@ const struct orb_metadata *get_orb_meta(ORB_ID id)
return nullptr;
}
- return uorb_topics_list[static_cast(id)];
+ return uorb_topics_list[static_cast(id)];
}
diff --git a/Tools/msg/templates/uorb/uORBTopics.hpp.em b/Tools/msg/templates/uorb/uORBTopics.hpp.em
index aea7015cc7..425661b2fb 100644
--- a/Tools/msg/templates/uorb/uORBTopics.hpp.em
+++ b/Tools/msg/templates/uorb/uORBTopics.hpp.em
@@ -62,7 +62,7 @@ static constexpr size_t orb_topics_count() { return ORB_TOPICS_COUNT; }
*/
extern const struct orb_metadata *const *orb_get_topics() __EXPORT;
-enum class ORB_ID : uint8_t {
+enum class ORB_ID : orb_id_size_t {
@[for idx, topic_name in enumerate(topic_names_all)]@
@(topic_name) = @(idx),
@[end for]
diff --git a/Tools/setup/optional-requirements.txt b/Tools/setup/optional-requirements.txt
index e13696aa4e..844ad80bb5 100644
--- a/Tools/setup/optional-requirements.txt
+++ b/Tools/setup/optional-requirements.txt
@@ -1 +1 @@
-symforce>=0.5.0
+symforce>=0.9.0
diff --git a/Tools/simulation/gazebo-classic/sitl_gazebo-classic b/Tools/simulation/gazebo-classic/sitl_gazebo-classic
index 2e3ed9bfb0..20ded0757b 160000
--- a/Tools/simulation/gazebo-classic/sitl_gazebo-classic
+++ b/Tools/simulation/gazebo-classic/sitl_gazebo-classic
@@ -1 +1 @@
-Subproject commit 2e3ed9bfb04d8865e59380afa575dd37b0d6c8e0
+Subproject commit 20ded0757b4f2cb362833538716caf1e938b162a
diff --git a/Tools/simulation/gz/models/omnicopter/model.config b/Tools/simulation/gz/models/omnicopter/model.config
new file mode 100644
index 0000000000..a090295062
--- /dev/null
+++ b/Tools/simulation/gz/models/omnicopter/model.config
@@ -0,0 +1,15 @@
+
+
+ Omnicopter
+ 1.0
+ model.sdf
+
+
+ Jaeyoung Lim
+ jalim@ethz.ch
+
+
+
+ Omnicopter model for over actuated system
+
+
diff --git a/Tools/simulation/gz/models/omnicopter/model.sdf b/Tools/simulation/gz/models/omnicopter/model.sdf
new file mode 100644
index 0000000000..ad2434fb67
--- /dev/null
+++ b/Tools/simulation/gz/models/omnicopter/model.sdf
@@ -0,0 +1,8 @@
+
+
+
+ omnicopter
+ 0 0 0 0 0 0
+ https://fuel.gazebosim.org/1.0/PX4/models/Omnicopter
+
+
diff --git a/Tools/simulation/gz/worlds/default.sdf b/Tools/simulation/gz/worlds/default.sdf
index 4b6f384002..6ba98ab149 100644
--- a/Tools/simulation/gz/worlds/default.sdf
+++ b/Tools/simulation/gz/worlds/default.sdf
@@ -11,6 +11,7 @@
+ ogre2
diff --git a/_last_entry b/_last_entry
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/boards/airmind/mindpx-v2/nuttx-config/nsh/defconfig b/boards/airmind/mindpx-v2/nuttx-config/nsh/defconfig
index 9a19661dd1..5b1c5bea7f 100644
--- a/boards/airmind/mindpx-v2/nuttx-config/nsh/defconfig
+++ b/boards/airmind/mindpx-v2/nuttx-config/nsh/defconfig
@@ -106,7 +106,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -140,6 +140,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/ark/can-flow/nuttx-config/nsh/defconfig b/boards/ark/can-flow/nuttx-config/nsh/defconfig
index 15d145881e..eb4cb5e929 100644
--- a/boards/ark/can-flow/nuttx-config/nsh/defconfig
+++ b/boards/ark/can-flow/nuttx-config/nsh/defconfig
@@ -115,6 +115,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/ark/can-flow/src/boot_config.h b/boards/ark/can-flow/src/boot_config.h
index eab3c76c6c..76782f9a93 100644
--- a/boards/ark/can-flow/src/boot_config.h
+++ b/boards/ark/can-flow/src/boot_config.h
@@ -65,7 +65,7 @@
#define OPT_PREFERRED_NODE_ID ANY_NODE_ID
//todo:wrap OPT_x in in ifdefs for command line definitions
-#define OPT_TBOOT_MS 5000
+#define OPT_TBOOT_MS 3000
#define OPT_NODE_STATUS_RATE_MS 800
#define OPT_NODE_INFO_RATE_MS 50
#define OPT_BL_NUMBER_TIMERS 7
@@ -93,7 +93,7 @@
*/
#define OPT_WAIT_FOR_GETNODEINFO 0
#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 1
-#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 0
+#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 1
#define OPT_ENABLE_WD 1
diff --git a/boards/ark/can-flow/uavcan_board_identity b/boards/ark/can-flow/uavcan_board_identity
index 8f389d0657..e49fbcac8a 100644
--- a/boards/ark/can-flow/uavcan_board_identity
+++ b/boards/ark/can-flow/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
@@ -14,4 +14,4 @@ add_definitions(
-DHW_UAVCAN_NAME=${uavcanblid_name}
-DHW_VERSION_MAJOR=${uavcanblid_hw_version_major}
-DHW_VERSION_MINOR=${uavcanblid_hw_version_minor}
-)
\ No newline at end of file
+)
diff --git a/boards/ark/can-gps/nuttx-config/nsh/defconfig b/boards/ark/can-gps/nuttx-config/nsh/defconfig
index f734bc8168..8addad7c7d 100644
--- a/boards/ark/can-gps/nuttx-config/nsh/defconfig
+++ b/boards/ark/can-gps/nuttx-config/nsh/defconfig
@@ -117,6 +117,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/ark/can-gps/src/boot_config.h b/boards/ark/can-gps/src/boot_config.h
index eab3c76c6c..76782f9a93 100644
--- a/boards/ark/can-gps/src/boot_config.h
+++ b/boards/ark/can-gps/src/boot_config.h
@@ -65,7 +65,7 @@
#define OPT_PREFERRED_NODE_ID ANY_NODE_ID
//todo:wrap OPT_x in in ifdefs for command line definitions
-#define OPT_TBOOT_MS 5000
+#define OPT_TBOOT_MS 3000
#define OPT_NODE_STATUS_RATE_MS 800
#define OPT_NODE_INFO_RATE_MS 50
#define OPT_BL_NUMBER_TIMERS 7
@@ -93,7 +93,7 @@
*/
#define OPT_WAIT_FOR_GETNODEINFO 0
#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 1
-#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 0
+#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 1
#define OPT_ENABLE_WD 1
diff --git a/boards/ark/can-gps/uavcan_board_identity b/boards/ark/can-gps/uavcan_board_identity
index ca6d098e59..00b23ea028 100644
--- a/boards/ark/can-gps/uavcan_board_identity
+++ b/boards/ark/can-gps/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/ark/can-rtk-gps/init/rc.board_sensors b/boards/ark/can-rtk-gps/init/rc.board_sensors
index d74d5f74b2..545850dc8b 100644
--- a/boards/ark/can-rtk-gps/init/rc.board_sensors
+++ b/boards/ark/can-rtk-gps/init/rc.board_sensors
@@ -6,6 +6,9 @@ gps start -d /dev/ttyS0 -p ubx
icm42688p -R 0 -s start
-bmp388 -I -b 2 start
+if ! bmp388 -I -b 2 start
+then
+ bmp388 -I -b 1 start
+fi
bmm150 -I -b 1 start
diff --git a/boards/ark/can-rtk-gps/nuttx-config/nsh/defconfig b/boards/ark/can-rtk-gps/nuttx-config/nsh/defconfig
index ba2d6f2143..34d42179c7 100644
--- a/boards/ark/can-rtk-gps/nuttx-config/nsh/defconfig
+++ b/boards/ark/can-rtk-gps/nuttx-config/nsh/defconfig
@@ -117,6 +117,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/ark/can-rtk-gps/src/boot_config.h b/boards/ark/can-rtk-gps/src/boot_config.h
index eab3c76c6c..76782f9a93 100644
--- a/boards/ark/can-rtk-gps/src/boot_config.h
+++ b/boards/ark/can-rtk-gps/src/boot_config.h
@@ -65,7 +65,7 @@
#define OPT_PREFERRED_NODE_ID ANY_NODE_ID
//todo:wrap OPT_x in in ifdefs for command line definitions
-#define OPT_TBOOT_MS 5000
+#define OPT_TBOOT_MS 3000
#define OPT_NODE_STATUS_RATE_MS 800
#define OPT_NODE_INFO_RATE_MS 50
#define OPT_BL_NUMBER_TIMERS 7
@@ -93,7 +93,7 @@
*/
#define OPT_WAIT_FOR_GETNODEINFO 0
#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 1
-#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 0
+#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 1
#define OPT_ENABLE_WD 1
diff --git a/boards/ark/can-rtk-gps/uavcan_board_identity b/boards/ark/can-rtk-gps/uavcan_board_identity
index 5db21a4ffb..655384bc07 100644
--- a/boards/ark/can-rtk-gps/uavcan_board_identity
+++ b/boards/ark/can-rtk-gps/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/ark/cannode/nuttx-config/nsh/defconfig b/boards/ark/cannode/nuttx-config/nsh/defconfig
index a0882b71be..8ec02cc3dd 100644
--- a/boards/ark/cannode/nuttx-config/nsh/defconfig
+++ b/boards/ark/cannode/nuttx-config/nsh/defconfig
@@ -117,6 +117,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/ark/cannode/src/boot_config.h b/boards/ark/cannode/src/boot_config.h
index eab3c76c6c..b43795ac4c 100644
--- a/boards/ark/cannode/src/boot_config.h
+++ b/boards/ark/cannode/src/boot_config.h
@@ -65,7 +65,7 @@
#define OPT_PREFERRED_NODE_ID ANY_NODE_ID
//todo:wrap OPT_x in in ifdefs for command line definitions
-#define OPT_TBOOT_MS 5000
+#define OPT_TBOOT_MS 3000
#define OPT_NODE_STATUS_RATE_MS 800
#define OPT_NODE_INFO_RATE_MS 50
#define OPT_BL_NUMBER_TIMERS 7
@@ -92,8 +92,12 @@
*
*/
#define OPT_WAIT_FOR_GETNODEINFO 0
-#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 1
-#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 0
+/* The ARK CANnode uses PH1 for GPIO_BOOT_CONFIG but it is not
+ * compatible with px4_arch_gpioread as Port H = 7 which is greater
+ * than STM32_NPORTS
+ * #define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO 0
+ */
+#define OPT_WAIT_FOR_GETNODEINFO_JUMPER_GPIO_INVERT 1
#define OPT_ENABLE_WD 1
diff --git a/boards/ark/cannode/uavcan_board_identity b/boards/ark/cannode/uavcan_board_identity
index 44ea18cc7d..490b7678bd 100644
--- a/boards/ark/cannode/uavcan_board_identity
+++ b/boards/ark/cannode/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/ark/fmu-v6x/default.px4board b/boards/ark/fmu-v6x/default.px4board
index 4a6af4f6d8..4018e493a2 100644
--- a/boards/ark/fmu-v6x/default.px4board
+++ b/boards/ark/fmu-v6x/default.px4board
@@ -20,6 +20,7 @@ CONFIG_DRIVERS_HEATER=y
CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16507=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y
CONFIG_DRIVERS_IMU_INVENSENSE_IIM42652=y
+CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y
CONFIG_COMMON_LIGHT=y
CONFIG_COMMON_MAGNETOMETER=y
CONFIG_COMMON_OPTICAL_FLOW=y
diff --git a/boards/ark/fmu-v6x/extras/ark_fmu-v6x_bootloader.bin b/boards/ark/fmu-v6x/extras/ark_fmu-v6x_bootloader.bin
index bbe99d9659..f4ec9666cc 100755
Binary files a/boards/ark/fmu-v6x/extras/ark_fmu-v6x_bootloader.bin and b/boards/ark/fmu-v6x/extras/ark_fmu-v6x_bootloader.bin differ
diff --git a/boards/ark/fmu-v6x/init/rc.board_defaults b/boards/ark/fmu-v6x/init/rc.board_defaults
index 2f2c8cfeae..7a26ee01c8 100644
--- a/boards/ark/fmu-v6x/init/rc.board_defaults
+++ b/boards/ark/fmu-v6x/init/rc.board_defaults
@@ -17,12 +17,21 @@ param set-default SENS_EN_INA228 0
param set-default SENS_EN_INA226 1
param set-default SENS_EN_THERMAL 1
-param set-default SENS_TEMP_ID 2818058
param set-default SENS_IMU_TEMP 10.0
#param set-default SENS_IMU_TEMP_FF 0.0
#param set-default SENS_IMU_TEMP_I 0.025
#param set-default SENS_IMU_TEMP_P 1.0
+if ver hwtypecmp ARKV6X000000 ARKV6X001000 ARKV6X002000 ARKV6X003000 ARKV6X004000 ARKV6X005000 ARKV6X006000 ARKV6X007000
+then
+ param set-default SENS_TEMP_ID 2818058
+fi
+
+if ver hwtypecmp ARKV6X000001 ARKV6X001001 ARKV6X002001 ARKV6X003001 ARKV6X004001 ARKV6X005001 ARKV6X006001 ARKV6X007001
+then
+ param set-default SENS_TEMP_ID 3014666
+fi
+
if ver hwtypecmp ARKV6X001000 ARKV6X001001 ARKV6X001002 ARKV6X001003 ARKV6X001004 ARKV6X001005 ARKV6X001006 ARKV6X001007
then
param set-default SYS_USE_IO 0
diff --git a/boards/ark/fmu-v6x/init/rc.board_sensors b/boards/ark/fmu-v6x/init/rc.board_sensors
index 84f985cecb..0e04ed41cb 100644
--- a/boards/ark/fmu-v6x/init/rc.board_sensors
+++ b/boards/ark/fmu-v6x/init/rc.board_sensors
@@ -3,10 +3,12 @@
# ARK FMUARKV6X specific board sensors init
#------------------------------------------------------------------------------
set HAVE_PM2 yes
+set HAVE_PM3 yes
if ver hwtypecmp ARKV6X005000 ARKV6X005001 ARKV6X005002 ARKV6X005003 ARKV6X005004
then
set HAVE_PM2 no
+ set HAVE_PM3 no
fi
if param compare -s ADC_ADS1115_EN 1
@@ -25,36 +27,68 @@ then
then
ina226 -X -b 2 -t 2 -k start
fi
+
+ if [ $HAVE_PM3 = yes ]
+ then
+ ina226 -X -b 3 -t 2 -k start
+ fi
fi
if param compare SENS_EN_INA228 1
then
# Start Digital power monitors
ina228 -X -b 1 -t 1 -k start
+
if [ $HAVE_PM2 = yes ]
then
ina228 -X -b 2 -t 2 -k start
fi
+
+ if [ $HAVE_PM3 = yes ]
+ then
+ ina228 -X -b 3 -t 2 -k start
+ fi
fi
if param compare SENS_EN_INA238 1
then
# Start Digital power monitors
ina238 -X -b 1 -t 1 -k start
+
if [ $HAVE_PM2 = yes ]
then
ina238 -X -b 2 -t 2 -k start
fi
+
+ if [ $HAVE_PM3 = yes ]
+ then
+ ina238 -X -b 3 -t 2 -k start
+ fi
fi
-# Internal SPI bus IIM42652 with SPIX measured frequency of 32.051kHz
-iim42652 -R 3 -s -b 1 -C 32051 start
+if ver hwtypecmp ARKV6X000000 ARKV6X001000 ARKV6X002000 ARKV6X003000 ARKV6X004000 ARKV6X005000 ARKV6X006000 ARKV6X007000
+then
+ # Internal SPI bus IIM42652 with SPIX measured frequency of 32.051kHz
+ iim42652 -R 3 -s -b 1 -C 32051 start
-# Internal SPI bus ICM42688p with SPIX measured frequency of 32.051kHz
-icm42688p -R 9 -s -b 2 -C 32051 start
+ # Internal SPI bus ICM42688p with SPIX measured frequency of 32.051kHz
+ icm42688p -R 9 -s -b 2 -C 32051 start
-# Internal SPI bus ICM42688p with SPIX measured frequency of 32.051kHz
-icm42688p -R 6 -s -b 3 -C 32051 start
+ # Internal SPI bus ICM42688p with SPIX measured frequency of 32.051kHz
+ icm42688p -R 6 -s -b 3 -C 32051 start
+fi
+
+if ver hwtypecmp ARKV6X000001 ARKV6X001001 ARKV6X002001 ARKV6X003001 ARKV6X004001 ARKV6X005001 ARKV6X006001 ARKV6X007001
+then
+ # Internal SPI bus IIM42653 with SPIX measured frequency of 32.051kHz
+ iim42653 -R 3 -s -b 1 -C 32051 start
+
+ # Internal SPI bus IIM42653 with SPIX measured frequency of 32.051kHz
+ iim42653 -R 9 -s -b 2 -C 32051 start
+
+ # Internal SPI bus IIM42653 with SPIX measured frequency of 32.051kHz
+ iim42653 -R 6 -s -b 3 -C 32051 start
+fi
# Internal magnetometer on I2C
bmm150 -I start
@@ -63,3 +97,4 @@ bmm150 -I start
bmp388 -I start
unset HAVE_PM2
+unset HAVE_PM3
diff --git a/boards/ark/fmu-v6x/nuttx-config/bootloader/defconfig b/boards/ark/fmu-v6x/nuttx-config/bootloader/defconfig
index 97fe8b7937..c830932873 100644
--- a/boards/ark/fmu-v6x/nuttx-config/bootloader/defconfig
+++ b/boards/ark/fmu-v6x/nuttx-config/bootloader/defconfig
@@ -7,6 +7,7 @@
#
# CONFIG_DEV_CONSOLE is not set
# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
+# CONFIG_DISABLE_PTHREAD is not set
# CONFIG_SPI_EXCHANGE is not set
# CONFIG_STM32H7_SYSCFG is not set
CONFIG_ARCH="arm"
@@ -48,13 +49,14 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
CONFIG_MEMSET_64BIT=y
CONFIG_MEMSET_OPTSPEED=y
CONFIG_PREALLOC_TIMERS=50
+CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/ark/fmu-v6x/nuttx-config/include/board.h b/boards/ark/fmu-v6x/nuttx-config/include/board.h
index b29b8fc686..333c20905d 100644
--- a/boards/ark/fmu-v6x/nuttx-config/include/board.h
+++ b/boards/ark/fmu-v6x/nuttx-config/include/board.h
@@ -387,7 +387,7 @@
#define GPIO_UART7_RX GPIO_UART7_RX_4 /* PF6 */
#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */
-#define GPIO_UART7_RTS (GPIO_UART7_RTS_2 | GPIO_PULLDOWN) /* PF8 */
+#define GPIO_UART7_RTS GPIO_UART7_RTS_2 /* PF8 */
#define GPIO_UART7_CTS (GPIO_UART7_CTS_1 | GPIO_PULLDOWN) /* PE10 */
#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */
diff --git a/boards/ark/fmu-v6x/nuttx-config/nsh/defconfig b/boards/ark/fmu-v6x/nuttx-config/nsh/defconfig
index 212213f994..17da75424e 100644
--- a/boards/ark/fmu-v6x/nuttx-config/nsh/defconfig
+++ b/boards/ark/fmu-v6x/nuttx-config/nsh/defconfig
@@ -118,7 +118,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_IPCFG_BINARY=y
@@ -189,6 +189,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
@@ -292,7 +294,7 @@ CONFIG_UART4_TXBUFSIZE=1500
CONFIG_UART5_IFLOWCONTROL=y
CONFIG_UART5_OFLOWCONTROL=y
CONFIG_UART5_RXDMA=y
-CONFIG_UART5_TXBUFSIZE=3000
+CONFIG_UART5_TXBUFSIZE=10000
CONFIG_UART5_TXDMA=y
CONFIG_UART7_BAUD=57600
CONFIG_UART7_IFLOWCONTROL=y
diff --git a/boards/ark/fmu-v6x/src/board_config.h b/boards/ark/fmu-v6x/src/board_config.h
index 1317d42668..001a31ae73 100644
--- a/boards/ark/fmu-v6x/src/board_config.h
+++ b/boards/ark/fmu-v6x/src/board_config.h
@@ -211,23 +211,18 @@
#define GPIO_HW_VER_SENSE /* PH3 */ GPIO_ADC3_INP14
#define HW_INFO_INIT_PREFIX "ARKV6X"
-#define BOARD_NUM_SPI_CFG_HW_VERSIONS 2 // Rev 0 and Rev 3,4 Sensor sets
+#define BOARD_NUM_SPI_CFG_HW_VERSIONS 8 // Rev 0 and Rev 1
// Base/FMUM
-#define ARKV6X00 HW_VER_REV(0x0,0x0) // ARKV6X, Rev 0
-#define ARKV6X01 HW_VER_REV(0x0,0x1) // ARKV6X, BMI388 I2C2 Rev 1
-#define ARKV6X03 HW_VER_REV(0x0,0x3) // ARKV6X, Sensor Set Rev 3
-#define ARKV6X04 HW_VER_REV(0x0,0x4) // ARKV6X, Sensor Set Rev 4
-#define ARKV6X10 HW_VER_REV(0x1,0x0) // NO PX4IO, Rev 0
-#define ARKV6X13 HW_VER_REV(0x1,0x3) // NO PX4IO, Sensor Set Rev 3
-#define ARKV6X14 HW_VER_REV(0x1,0x4) // NO PX4IO, Sensor Set Rev 4
-//#define ARKV6X40 HW_VER_REV(0x4,0x0) // ARKV6X, HB CM4 base Rev 0 // never shipped
-//#define ARKV6X41 HW_VER_REV(0x4,0x1) // ARKV6X, BMI388 I2C2 HB CM4 base Rev 1 // never shipped
-#define ARKV6X43 HW_VER_REV(0x4,0x3) // ARKV6X, Sensor Set HB CM4 base Rev 3
-#define ARKV6X44 HW_VER_REV(0x4,0x4) // ARKV6X, Sensor Set HB CM4 base Rev 4
-#define ARKV6X50 HW_VER_REV(0x5,0x0) // ARKV6X, ARKV6X Rev 0 with HB Mini Rev 5
-//#define ARKV6X51 HW_VER_REV(0x5,0x1) // ARKV6X, BMI388 I2C2 HB Mini Rev 1 // never shipped
-#define ARKV6X53 HW_VER_REV(0x5,0x3) // ARKV6X, Sensor Set HB Mini Rev 3
-#define ARKV6X54 HW_VER_REV(0x5,0x4) // ARKV6X, Sensor Set HB Mini Rev 4
+#define ARKV6X00 HW_VER_REV(0x0,0x0) // ARKV6X, Sensor Set Rev 0
+#define ARKV6X01 HW_VER_REV(0x0,0x1) // ARKV6X, Sensor Set Rev 1
+//#define ARKV6X03 HW_VER_REV(0x0,0x3) // ARKV6X, Sensor Set Rev 3
+//#define ARKV6X04 HW_VER_REV(0x0,0x4) // ARKV6X, Sensor Set Rev 4
+#define ARKV6X10 HW_VER_REV(0x1,0x0) // NO PX4IO, Sensor Set Rev 0
+#define ARKV6X11 HW_VER_REV(0x1,0x1) // NO PX4IO, Sensor Set Rev 1
+#define ARKV6X40 HW_VER_REV(0x4,0x0) // ARKV6X, Sensor Set Rev 0 HB CM4 base Rev 3
+#define ARKV6X41 HW_VER_REV(0x4,0x1) // ARKV6X, Sensor Set Rev 1 HB CM4 base Rev 4
+#define ARKV6X50 HW_VER_REV(0x5,0x0) // ARKV6X, Sensor Set Rev 0 HB Mini Rev 5
+#define ARKV6X51 HW_VER_REV(0x5,0x1) // ARKV6X, Sensor Set Rev 1 HB Mini Rev 1 // never shipped
#define UAVCAN_NUM_IFACES_RUNTIME 1
diff --git a/boards/ark/fmu-v6x/src/manifest.c b/boards/ark/fmu-v6x/src/manifest.c
index 6b8405bcf5..f4e012bfb0 100644
--- a/boards/ark/fmu-v6x/src/manifest.c
+++ b/boards/ark/fmu-v6x/src/manifest.c
@@ -160,21 +160,14 @@ static const px4_hw_mft_item_t hw_mft_list_v0650[] = {
static px4_hw_mft_list_entry_t mft_lists[] = {
// ver_rev
- {ARKV6X00, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)},
- {ARKV6X01, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2
- {ARKV6X03, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, Sensor Set 3
- //{ARKV6X40, hw_mft_list_v0640, arraySize(hw_mft_list_v0640)}, // HB CM4 base // never shipped
- //{ARKV6X41, hw_mft_list_v0640, arraySize(hw_mft_list_v0640)}, // BMP388 moved to I2C2 HB CM4 base // never shipped
- {ARKV6X43, hw_mft_list_v0640, arraySize(hw_mft_list_v0640)}, // BMP388 moved to I2C2, HB CM4 base Sensor Set 3
- {ARKV6X44, hw_mft_list_v0640, arraySize(hw_mft_list_v0640)}, // BMP388 moved to I2C2, HB CM4 base Sensor Set 4
- {ARKV6X50, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // ARKV6X Rev 0 with HB Mini Rev 5
- //{ARKV6X51, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // BMP388 moved to I2C2 HB Mini // never shipped
- {ARKV6X53, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // BMP388 moved to I2C2, HB Mini Sensor Set 3
- {ARKV6X54, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // BMP388 moved to I2C2, HB Mini Sensor Set 4
- {ARKV6X10, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // No PX4IO
- {ARKV6X13, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // No PX4IO BMP388 moved to I2C2, Sensor Set 3
- {ARKV6X04, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, Sensor Set 4
- {ARKV6X14, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // No PX4IO BMP388 moved to I2C2, Sensor Set 4
+ {ARKV6X00, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // ARKV6X, Sensor Set Rev 0
+ {ARKV6X01, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // ARKV6X, Sensor Set Rev 1
+ {ARKV6X10, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // NO PX4IO, Sensor Set Rev 0
+ {ARKV6X11, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // NO PX4IO, Sensor Set Rev 1
+ {ARKV6X40, hw_mft_list_v0640, arraySize(hw_mft_list_v0640)}, // ARKV6X, Sensor Set Rev 0 HB CM4 base Rev 3
+ {ARKV6X41, hw_mft_list_v0640, arraySize(hw_mft_list_v0640)}, // ARKV6X, Sensor Set Rev 1 HB CM4 base Rev 4
+ {ARKV6X50, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // ARKV6X, Sensor Set Rev 0 HB Mini Rev 5
+ {ARKV6X51, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // ARKV6X, Sensor Set Rev 1 HB Mini Rev 1 // never shipped
};
/************************************************************************************
diff --git a/boards/ark/fmu-v6x/src/mtd.cpp b/boards/ark/fmu-v6x/src/mtd.cpp
index 3ece10aeca..80d41e0b78 100644
--- a/boards/ark/fmu-v6x/src/mtd.cpp
+++ b/boards/ark/fmu-v6x/src/mtd.cpp
@@ -34,7 +34,7 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi5 = { // FM25V02A on FMUM 32K 512 X 64
+static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
@@ -45,18 +45,12 @@ static const px4_mft_device_t i2c3 = { // 24LC64T on Base 8K 32 X 2
static const px4_mtd_entry_t fmum_fram = {
.device = &spi5,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/boards/ark/fmu-v6x/src/spi.cpp b/boards/ark/fmu-v6x/src/spi.cpp
index 2d047cff1d..f83a5a91cd 100644
--- a/boards/ark/fmu-v6x/src/spi.cpp
+++ b/boards/ark/fmu-v6x/src/spi.cpp
@@ -59,7 +59,30 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}),
}),
- initSPIHWVersion(ARKV6X01, { // Placeholder
+ initSPIHWVersion(ARKV6X01, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
+ initSPIHWVersion(ARKV6X10, {
initSPIBus(SPI::Bus::SPI1, {
initSPIDevice(DRV_IMU_DEVTYPE_IIM42652, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
}, {GPIO::PortI, GPIO::Pin11}),
@@ -81,6 +104,121 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
}),
}),
+
+ initSPIHWVersion(ARKV6X11, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
+ initSPIHWVersion(ARKV6X40, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42652, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
+ initSPIHWVersion(ARKV6X41, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
+ initSPIHWVersion(ARKV6X50, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42652, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
+ initSPIHWVersion(ARKV6X51, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42653, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
};
static constexpr bool unused = validateSPIConfig(px4_spi_buses_all_hw);
diff --git a/boards/atl/mantis-edu/nuttx-config/nsh/defconfig b/boards/atl/mantis-edu/nuttx-config/nsh/defconfig
index 3368ce48e1..b6e976d427 100644
--- a/boards/atl/mantis-edu/nuttx-config/nsh/defconfig
+++ b/boards/atl/mantis-edu/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/av/x-v1/nuttx-config/nsh/defconfig b/boards/av/x-v1/nuttx-config/nsh/defconfig
index 73efed90a1..d5e4039047 100644
--- a/boards/av/x-v1/nuttx-config/nsh/defconfig
+++ b/boards/av/x-v1/nuttx-config/nsh/defconfig
@@ -120,7 +120,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_LIBC_LONG_LONG=y
diff --git a/boards/bitcraze/crazyflie/nuttx-config/nsh/defconfig b/boards/bitcraze/crazyflie/nuttx-config/nsh/defconfig
index 85951b83dd..15c99f925e 100644
--- a/boards/bitcraze/crazyflie/nuttx-config/nsh/defconfig
+++ b/boards/bitcraze/crazyflie/nuttx-config/nsh/defconfig
@@ -105,7 +105,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
diff --git a/boards/bitcraze/crazyflie/src/board_config.h b/boards/bitcraze/crazyflie/src/board_config.h
index 5b9529a682..b69a021a15 100644
--- a/boards/bitcraze/crazyflie/src/board_config.h
+++ b/boards/bitcraze/crazyflie/src/board_config.h
@@ -140,15 +140,7 @@
#define PX4_PWM_ALTERNATE_RANGES
#define PWM_LOWEST_MIN 0
-#define PWM_MOTOR_OFF 0
-#define PWM_SERVO_STOP 0
-#define PWM_DEFAULT_MIN 20
-#define PWM_HIGHEST_MIN 0
#define PWM_HIGHEST_MAX 255
-#define PWM_DEFAULT_MAX 255
-#define PWM_LOWEST_MAX 255
-#define PWM_DEFAULT_TRIM 1500
-
/* High-resolution timer */
#define HRT_TIMER 8 /* use timer8 for the HRT */
diff --git a/boards/bitcraze/crazyflie/src/mtd.cpp b/boards/bitcraze/crazyflie/src/mtd.cpp
index 2b00e231b2..d81e3e4596 100644
--- a/boards/bitcraze/crazyflie/src/mtd.cpp
+++ b/boards/bitcraze/crazyflie/src/mtd.cpp
@@ -42,18 +42,12 @@ static const px4_mft_device_t i2c1 = { // 24AA64FT on Base 8K 32 X
static const px4_mtd_entry_t fmu_eeprom = {
.device = &i2c1,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
.nblocks = 128
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 128
-
}
},
};
diff --git a/boards/bitcraze/crazyflie21/default.px4board b/boards/bitcraze/crazyflie21/default.px4board
index a5e5244cc8..bd99fc6964 100644
--- a/boards/bitcraze/crazyflie21/default.px4board
+++ b/boards/bitcraze/crazyflie21/default.px4board
@@ -15,6 +15,7 @@ CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
CONFIG_MODULES_EKF2=y
# CONFIG_EKF2_GNSS_YAW is not set
+# CONFIG_EKF2_MAGNETOMETER is not set
# CONFIG_EKF2_SIDESLIP is not set
CONFIG_MODULES_EVENTS=y
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
@@ -33,6 +34,7 @@ CONFIG_MODULES_NAVIGATOR=y
CONFIG_MODULES_RC_UPDATE=y
CONFIG_MODULES_SENSORS=y
# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set
+# CONFIG_SENSORS_VEHICLE_MAGNETOMETER is not set
CONFIG_SYSTEMCMDS_DMESG=y
CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y
CONFIG_SYSTEMCMDS_MTD=y
diff --git a/boards/bitcraze/crazyflie21/nuttx-config/nsh/defconfig b/boards/bitcraze/crazyflie21/nuttx-config/nsh/defconfig
index 4840814672..a8e182bc1d 100644
--- a/boards/bitcraze/crazyflie21/nuttx-config/nsh/defconfig
+++ b/boards/bitcraze/crazyflie21/nuttx-config/nsh/defconfig
@@ -106,7 +106,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
diff --git a/boards/bitcraze/crazyflie21/src/board_config.h b/boards/bitcraze/crazyflie21/src/board_config.h
index a8ee6029c2..b636bfd08c 100644
--- a/boards/bitcraze/crazyflie21/src/board_config.h
+++ b/boards/bitcraze/crazyflie21/src/board_config.h
@@ -141,15 +141,7 @@
#define PX4_PWM_ALTERNATE_RANGES
#define PWM_LOWEST_MIN 0
-#define PWM_MOTOR_OFF 0
-#define PWM_SERVO_STOP 0
-#define PWM_DEFAULT_MIN 20
-#define PWM_HIGHEST_MIN 0
#define PWM_HIGHEST_MAX 255
-#define PWM_DEFAULT_MAX 255
-#define PWM_LOWEST_MAX 255
-#define PWM_DEFAULT_TRIM 1500
-
/* High-resolution timer */
#define HRT_TIMER 8 /* use timer8 for the HRT */
diff --git a/boards/cuav/can-gps-v1/nuttx-config/nsh/defconfig b/boards/cuav/can-gps-v1/nuttx-config/nsh/defconfig
index 64f884c2db..aa13dbdb1e 100644
--- a/boards/cuav/can-gps-v1/nuttx-config/nsh/defconfig
+++ b/boards/cuav/can-gps-v1/nuttx-config/nsh/defconfig
@@ -119,6 +119,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/cuav/can-gps-v1/uavcan_board_identity b/boards/cuav/can-gps-v1/uavcan_board_identity
index a547589079..0cf273dde7 100644
--- a/boards/cuav/can-gps-v1/uavcan_board_identity
+++ b/boards/cuav/can-gps-v1/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/cuav/nora/nuttx-config/bootloader/defconfig b/boards/cuav/nora/nuttx-config/bootloader/defconfig
index a05449844b..cc5ca67d2d 100644
--- a/boards/cuav/nora/nuttx-config/bootloader/defconfig
+++ b/boards/cuav/nora/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/cuav/nora/nuttx-config/nsh/defconfig b/boards/cuav/nora/nuttx-config/nsh/defconfig
index fb84cac440..b84688f9b1 100644
--- a/boards/cuav/nora/nuttx-config/nsh/defconfig
+++ b/boards/cuav/nora/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/cuav/x7pro/nuttx-config/bootloader/defconfig b/boards/cuav/x7pro/nuttx-config/bootloader/defconfig
index b3a4aa12cd..d0e6e6194a 100644
--- a/boards/cuav/x7pro/nuttx-config/bootloader/defconfig
+++ b/boards/cuav/x7pro/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/cuav/x7pro/nuttx-config/nsh/defconfig b/boards/cuav/x7pro/nuttx-config/nsh/defconfig
index 1088a24c02..039d5ee9b9 100644
--- a/boards/cuav/x7pro/nuttx-config/nsh/defconfig
+++ b/boards/cuav/x7pro/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/cuav/x7pro/nuttx-config/test/defconfig b/boards/cuav/x7pro/nuttx-config/test/defconfig
index 7506c06387..392e47c9b4 100644
--- a/boards/cuav/x7pro/nuttx-config/test/defconfig
+++ b/boards/cuav/x7pro/nuttx-config/test/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/cubepilot/cubeorange/default.px4board b/boards/cubepilot/cubeorange/default.px4board
index 521dd3bde8..91ddcda596 100644
--- a/boards/cubepilot/cubeorange/default.px4board
+++ b/boards/cubepilot/cubeorange/default.px4board
@@ -19,6 +19,7 @@ CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16448=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20602=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20649=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y
+CONFIG_COMMON_INS=y
CONFIG_DRIVERS_IRLOCK=y
CONFIG_COMMON_LIGHT=y
CONFIG_COMMON_MAGNETOMETER=y
@@ -49,7 +50,6 @@ CONFIG_MODULES_FW_POS_CONTROL=y
CONFIG_MODULES_FW_RATE_CONTROL=y
CONFIG_MODULES_GIMBAL=y
CONFIG_MODULES_GYRO_CALIBRATION=y
-CONFIG_MODULES_GYRO_FFT=y
CONFIG_MODULES_LAND_DETECTOR=y
CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y
CONFIG_MODULES_LOAD_MON=y
diff --git a/boards/cubepilot/cubeorange/nuttx-config/bootloader/defconfig b/boards/cubepilot/cubeorange/nuttx-config/bootloader/defconfig
index 2203424943..59041c61c4 100644
--- a/boards/cubepilot/cubeorange/nuttx-config/bootloader/defconfig
+++ b/boards/cubepilot/cubeorange/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/cubepilot/cubeorange/nuttx-config/nsh/defconfig b/boards/cubepilot/cubeorange/nuttx-config/nsh/defconfig
index fe6a962c27..192e7c713a 100644
--- a/boards/cubepilot/cubeorange/nuttx-config/nsh/defconfig
+++ b/boards/cubepilot/cubeorange/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/cubepilot/cubeorange/nuttx-config/test/defconfig b/boards/cubepilot/cubeorange/nuttx-config/test/defconfig
index 54613e1e61..9bb0b35420 100644
--- a/boards/cubepilot/cubeorange/nuttx-config/test/defconfig
+++ b/boards/cubepilot/cubeorange/nuttx-config/test/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/cubepilot/cubeorangeplus/default.px4board b/boards/cubepilot/cubeorangeplus/default.px4board
index e9f6c2d005..837876ee7d 100644
--- a/boards/cubepilot/cubeorangeplus/default.px4board
+++ b/boards/cubepilot/cubeorangeplus/default.px4board
@@ -20,6 +20,7 @@ CONFIG_DRIVERS_IMU_INVENSENSE_ICM20649=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y
+CONFIG_COMMON_INS=y
CONFIG_DRIVERS_IRLOCK=y
CONFIG_COMMON_LIGHT=y
CONFIG_COMMON_MAGNETOMETER=y
diff --git a/boards/cubepilot/cubeorangeplus/init/rc.board_sensors b/boards/cubepilot/cubeorangeplus/init/rc.board_sensors
index 61a3fbf138..d4a1052f92 100644
--- a/boards/cubepilot/cubeorangeplus/init/rc.board_sensors
+++ b/boards/cubepilot/cubeorangeplus/init/rc.board_sensors
@@ -8,16 +8,21 @@ board_adc start
# 1. Isolated {ICM42688p, ICM20948(with mag)}, body-fixed {ICM20649}
# 2. Isolated {ICM42688p, ICM42688p}, body-fixed {ICM20649, ICM45686, AK09918}
# 3. Isolated {ICM42688p, ICM42688p}, body-fixed {ICM45686, AK09918}
+# 4. Isolated {ICM45686, ICM45686}, body-fixed {ICM45686, AK09918}
# SPI4 is isolated, SPI1 is body-fixed
# SPI4, isolated
ms5611 -s -b 4 start
-icm42688p -s -b 4 -R 10 start -c 15
-if ! icm20948 -s -b 4 -R 10 -M -q start
-then
- icm42688p -s -b 4 -R 6 start -c 13
+if icm42688p -s -b 4 -R 10 -q start -c 15
+ if ! icm20948 -s -b 4 -R 10 -M -q start
+ then
+ icm42688p -s -b 4 -R 6 start -c 13
+ fi
+else
+ icm45686 -s -b 4 -R 10 start -c 15
+ icm45686 -s -b 4 -R 6 start -c 13
fi
# SPI1, body-fixed
diff --git a/boards/cubepilot/cubeorangeplus/nuttx-config/bootloader/defconfig b/boards/cubepilot/cubeorangeplus/nuttx-config/bootloader/defconfig
index 15ca3bfe79..3861e2c8dc 100644
--- a/boards/cubepilot/cubeorangeplus/nuttx-config/bootloader/defconfig
+++ b/boards/cubepilot/cubeorangeplus/nuttx-config/bootloader/defconfig
@@ -49,7 +49,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/cubepilot/cubeorangeplus/nuttx-config/nsh/defconfig b/boards/cubepilot/cubeorangeplus/nuttx-config/nsh/defconfig
index 7bab0a36af..3a3d954783 100644
--- a/boards/cubepilot/cubeorangeplus/nuttx-config/nsh/defconfig
+++ b/boards/cubepilot/cubeorangeplus/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/cubepilot/cubeorangeplus/nuttx-config/test/defconfig b/boards/cubepilot/cubeorangeplus/nuttx-config/test/defconfig
index ba34d8a40f..9b0814ae08 100644
--- a/boards/cubepilot/cubeorangeplus/nuttx-config/test/defconfig
+++ b/boards/cubepilot/cubeorangeplus/nuttx-config/test/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/cubepilot/cubeyellow/nuttx-config/nsh/defconfig b/boards/cubepilot/cubeyellow/nuttx-config/nsh/defconfig
index f00b3e93a3..c696b87e08 100644
--- a/boards/cubepilot/cubeyellow/nuttx-config/nsh/defconfig
+++ b/boards/cubepilot/cubeyellow/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/diatone/mamba-f405-mk2/default.px4board b/boards/diatone/mamba-f405-mk2/default.px4board
index 6655e8e388..32ec4fd47b 100644
--- a/boards/diatone/mamba-f405-mk2/default.px4board
+++ b/boards/diatone/mamba-f405-mk2/default.px4board
@@ -23,6 +23,8 @@ CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
CONFIG_MODULES_EKF2=y
+# CONFIG_EKF2_GNSS_YAW is not set
+# CONFIG_EKF2_SIDESLIP is not set
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
CONFIG_MODULES_LAND_DETECTOR=y
CONFIG_MODULES_LOAD_MON=y
@@ -36,7 +38,6 @@ CONFIG_MODULES_NAVIGATOR=y
CONFIG_MODULES_RC_UPDATE=y
CONFIG_MODULES_SENSORS=y
CONFIG_SYSTEMCMDS_DMESG=y
-CONFIG_SYSTEMCMDS_MFT=y
CONFIG_SYSTEMCMDS_MTD=y
CONFIG_SYSTEMCMDS_NSHTERM=y
CONFIG_SYSTEMCMDS_PARAM=y
diff --git a/boards/diatone/mamba-f405-mk2/init/rc.board_defaults b/boards/diatone/mamba-f405-mk2/init/rc.board_defaults
index 97bbcd6ee6..61c5953c41 100644
--- a/boards/diatone/mamba-f405-mk2/init/rc.board_defaults
+++ b/boards/diatone/mamba-f405-mk2/init/rc.board_defaults
@@ -11,8 +11,7 @@ param set-default CBRK_IO_SAFETY 22027
# use the Q attitude estimator, it works w/o mag or GPS.
param set-default SYS_MC_EST_GROUP 3
-param set-default ATT_ACC_COMP 0
-param set-default ATT_W_ACC 0.4000
-param set-default ATT_W_GYRO_BIAS 0.0000
+param set-default ATT_W_ACC 0.4
+param set-default ATT_W_GYRO_BIAS 0
param set-default SYS_HAS_MAG 0
diff --git a/boards/diatone/mamba-f405-mk2/nuttx-config/nsh/defconfig b/boards/diatone/mamba-f405-mk2/nuttx-config/nsh/defconfig
index 8fed52b508..07573c0f9e 100644
--- a/boards/diatone/mamba-f405-mk2/nuttx-config/nsh/defconfig
+++ b/boards/diatone/mamba-f405-mk2/nuttx-config/nsh/defconfig
@@ -62,7 +62,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
CONFIG_MEMSET_64BIT=y
diff --git a/boards/flywoo/gn-f405/init/rc.board_defaults b/boards/flywoo/gn-f405/init/rc.board_defaults
index d5ae67dc8d..c1fc72c526 100644
--- a/boards/flywoo/gn-f405/init/rc.board_defaults
+++ b/boards/flywoo/gn-f405/init/rc.board_defaults
@@ -17,9 +17,8 @@ param set-default SYS_MC_EST_GROUP 2
param set-default EKF2_MAG_TYPE 5
param set-default SENS_BOARD_ROT 6
-param set-default ATT_ACC_COMP 0
-param set-default ATT_W_ACC 0.4000
-param set-default ATT_W_GYRO_BIAS 0.0000
+param set-default ATT_W_ACC 0.4
+param set-default ATT_W_GYRO_BIAS 0
param set-default SYS_HAS_MAG 0
diff --git a/boards/flywoo/gn-f405/nuttx-config/nsh/defconfig b/boards/flywoo/gn-f405/nuttx-config/nsh/defconfig
index 52ed2f86da..ea831c0b91 100644
--- a/boards/flywoo/gn-f405/nuttx-config/nsh/defconfig
+++ b/boards/flywoo/gn-f405/nuttx-config/nsh/defconfig
@@ -109,7 +109,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
diff --git a/boards/freefly/can-rtk-gps/nuttx-config/nsh/defconfig b/boards/freefly/can-rtk-gps/nuttx-config/nsh/defconfig
index 3ea9c492e6..d295254d69 100644
--- a/boards/freefly/can-rtk-gps/nuttx-config/nsh/defconfig
+++ b/boards/freefly/can-rtk-gps/nuttx-config/nsh/defconfig
@@ -132,6 +132,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/freefly/can-rtk-gps/uavcan_board_identity b/boards/freefly/can-rtk-gps/uavcan_board_identity
index 997b26e2ae..2531725501 100644
--- a/boards/freefly/can-rtk-gps/uavcan_board_identity
+++ b/boards/freefly/can-rtk-gps/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/holybro/can-gps-v1/nuttx-config/nsh/defconfig b/boards/holybro/can-gps-v1/nuttx-config/nsh/defconfig
index 4dcee619f1..f95e8f5c0c 100644
--- a/boards/holybro/can-gps-v1/nuttx-config/nsh/defconfig
+++ b/boards/holybro/can-gps-v1/nuttx-config/nsh/defconfig
@@ -120,6 +120,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/holybro/can-gps-v1/uavcan_board_identity b/boards/holybro/can-gps-v1/uavcan_board_identity
index c34b51cd77..bb7a514fd6 100644
--- a/boards/holybro/can-gps-v1/uavcan_board_identity
+++ b/boards/holybro/can-gps-v1/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/holybro/durandal-v1/nuttx-config/bootloader/defconfig b/boards/holybro/durandal-v1/nuttx-config/bootloader/defconfig
index 14f38276ef..be49e9a560 100644
--- a/boards/holybro/durandal-v1/nuttx-config/bootloader/defconfig
+++ b/boards/holybro/durandal-v1/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/holybro/durandal-v1/nuttx-config/nsh/defconfig b/boards/holybro/durandal-v1/nuttx-config/nsh/defconfig
index 85363a602e..19647f3b1f 100644
--- a/boards/holybro/durandal-v1/nuttx-config/nsh/defconfig
+++ b/boards/holybro/durandal-v1/nuttx-config/nsh/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -149,6 +149,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/holybro/kakutef7/default.px4board b/boards/holybro/kakutef7/default.px4board
index 6919df33f2..bcaedd9cf2 100644
--- a/boards/holybro/kakutef7/default.px4board
+++ b/boards/holybro/kakutef7/default.px4board
@@ -10,16 +10,26 @@ CONFIG_BOARD_SERIAL_RC="/dev/ttyS4"
CONFIG_DRIVERS_ADC_BOARD_ADC=y
CONFIG_DRIVERS_BAROMETER_BMP280=y
CONFIG_DRIVERS_DSHOT=y
+CONFIG_DRIVERS_GPS=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20689=y
CONFIG_DRIVERS_IMU_INVENSENSE_MPU6000=y
+CONFIG_DRIVERS_OSD_ATXXXX=y
CONFIG_DRIVERS_PWM_OUT=y
CONFIG_DRIVERS_RC_INPUT=y
CONFIG_DRIVERS_TELEMETRY_FRSKY_TELEMETRY=y
-CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y
CONFIG_MODULES_BATTERY_STATUS=y
CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
+CONFIG_MODULES_EKF2=y
+# CONFIG_EKF2_AUXVEL is not set
+# CONFIG_EKF2_BARO_COMPENSATION is not set
+# CONFIG_EKF2_DRAG_FUSION is not set
+# CONFIG_EKF2_EXTERNAL_VISION is not set
+# CONFIG_EKF2_GNSS_YAW is not set
+# CONFIG_EKF2_MAGNETOMETER is not set
+# CONFIG_EKF2_RANGE_FINDER is not set
+# CONFIG_EKF2_SIDESLIP is not set
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
CONFIG_MODULES_LAND_DETECTOR=y
CONFIG_MODULES_LOGGER=y
@@ -31,5 +41,9 @@ CONFIG_MODULES_MC_RATE_CONTROL=y
CONFIG_MODULES_NAVIGATOR=y
CONFIG_MODULES_RC_UPDATE=y
CONFIG_MODULES_SENSORS=y
-CONFIG_MODULES_UXRCE_DDS_CLIENT=y
+# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set
+# CONFIG_SENSORS_VEHICLE_MAGNETOMETER is not set
+# CONFIG_SENSORS_VEHICLE_OPTICAL_FLOW is not set
+CONFIG_SYSTEMCMDS_DMESG=y
CONFIG_SYSTEMCMDS_PARAM=y
+CONFIG_SYSTEMCMDS_TOP=y
diff --git a/boards/holybro/kakutef7/init/rc.board_defaults b/boards/holybro/kakutef7/init/rc.board_defaults
index 2968cb67ca..7a3bc92e84 100644
--- a/boards/holybro/kakutef7/init/rc.board_defaults
+++ b/boards/holybro/kakutef7/init/rc.board_defaults
@@ -12,14 +12,11 @@ param set-default CBRK_SUPPLY_CHK 894281
# Select the Generic 250 Racer by default
param set-default SYS_AUTOSTART 4050
-# use the Q attitude estimator, it works w/o mag or GPS.
-param set-default SYS_MC_EST_GROUP 3
-param set-default ATT_ACC_COMP 0
-param set-default ATT_W_ACC 0.4000
-param set-default ATT_W_GYRO_BIAS 0.0000
-
param set-default SYS_HAS_MAG 0
+# enable gravity fusion
+param set-default EKF2_IMU_CONTROL 7
+
# the startup tune is not great on a binary output buzzer, so disable it
param set-default CBRK_BUZZER 782090
diff --git a/boards/holybro/kakutef7/nuttx-config/nsh/defconfig b/boards/holybro/kakutef7/nuttx-config/nsh/defconfig
index faf8655412..88d57ea784 100644
--- a/boards/holybro/kakutef7/nuttx-config/nsh/defconfig
+++ b/boards/holybro/kakutef7/nuttx-config/nsh/defconfig
@@ -115,7 +115,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -150,6 +150,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/holybro/kakutef7/src/board_config.h b/boards/holybro/kakutef7/src/board_config.h
index 9254c57c52..3164a97836 100644
--- a/boards/holybro/kakutef7/src/board_config.h
+++ b/boards/holybro/kakutef7/src/board_config.h
@@ -113,6 +113,7 @@
/* RC Serial port */
#define RC_SERIAL_PORT "/dev/ttyS4"
+#define RC_SERIAL_SINGLEWIRE
#define GPIO_RSSI_IN /* PC5 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN5)
@@ -129,6 +130,8 @@
GPIO_RSSI_IN, \
}
+#define BOARD_ENABLE_CONSOLE_BUFFER
+
#define BOARD_NUM_IO_TIMERS 4
__BEGIN_DECLS
diff --git a/boards/holybro/kakutef7/src/init.c b/boards/holybro/kakutef7/src/init.c
index da2a545c2a..9b8a0140f4 100644
--- a/boards/holybro/kakutef7/src/init.c
+++ b/boards/holybro/kakutef7/src/init.c
@@ -252,9 +252,5 @@ __EXPORT int board_app_initialize(uintptr_t arg)
#endif
- /* Configure the HW based on the manifest */
-
- px4_platform_configure();
-
return OK;
}
diff --git a/boards/holybro/kakuteh7/default.px4board b/boards/holybro/kakuteh7/default.px4board
index 713c736d50..a9f38ba78c 100644
--- a/boards/holybro/kakuteh7/default.px4board
+++ b/boards/holybro/kakuteh7/default.px4board
@@ -33,6 +33,12 @@ CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
CONFIG_MODULES_EKF2=y
+# CONFIG_EKF2_AUXVEL is not set
+# CONFIG_EKF2_BARO_COMPENSATION is not set
+# CONFIG_EKF2_DRAG_FUSION is not set
+# CONFIG_EKF2_EXTERNAL_VISION is not set
+# CONFIG_EKF2_GNSS_YAW is not set
+# CONFIG_EKF2_SIDESLIP is not set
CONFIG_MODULES_ESC_BATTERY=y
CONFIG_MODULES_EVENTS=y
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
diff --git a/boards/holybro/kakuteh7/init/rc.board_defaults b/boards/holybro/kakuteh7/init/rc.board_defaults
index fa014c6b48..47dea71be6 100644
--- a/boards/holybro/kakuteh7/init/rc.board_defaults
+++ b/boards/holybro/kakuteh7/init/rc.board_defaults
@@ -22,13 +22,10 @@ param set-default CBRK_SUPPLY_CHK 894281
# Select the Generic 250 Racer by default
param set-default SYS_AUTOSTART 4050
-# use the Q attitude estimator, it works w/o mag or GPS.
-param set-default SYS_MC_EST_GROUP 3
-param set-default ATT_ACC_COMP 0
-param set-default ATT_W_ACC 0.4000
-param set-default ATT_W_GYRO_BIAS 0.0000
-
+# use EKF2 without mag
param set-default SYS_HAS_MAG 0
+# and enable gravity fusion
+param set-default EKF2_IMU_CONTROL 7
# the startup tune is not great on a binary output buzzer, so disable it
param set-default CBRK_BUZZER 782090
diff --git a/boards/holybro/kakuteh7/nuttx-config/bootloader/defconfig b/boards/holybro/kakuteh7/nuttx-config/bootloader/defconfig
index 9e7ac9fa4a..4557ffca77 100644
--- a/boards/holybro/kakuteh7/nuttx-config/bootloader/defconfig
+++ b/boards/holybro/kakuteh7/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/holybro/kakuteh7/nuttx-config/nsh/defconfig b/boards/holybro/kakuteh7/nuttx-config/nsh/defconfig
index c7d29ddb92..4dc58311a1 100644
--- a/boards/holybro/kakuteh7/nuttx-config/nsh/defconfig
+++ b/boards/holybro/kakuteh7/nuttx-config/nsh/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -149,6 +149,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/holybro/kakuteh7mini/default.px4board b/boards/holybro/kakuteh7mini/default.px4board
index b019b753f9..3310e79fbb 100644
--- a/boards/holybro/kakuteh7mini/default.px4board
+++ b/boards/holybro/kakuteh7mini/default.px4board
@@ -32,6 +32,12 @@ CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
CONFIG_MODULES_EKF2=y
+# CONFIG_EKF2_AUXVEL is not set
+# CONFIG_EKF2_BARO_COMPENSATION is not set
+# CONFIG_EKF2_DRAG_FUSION is not set
+# CONFIG_EKF2_EXTERNAL_VISION is not set
+# CONFIG_EKF2_GNSS_YAW is not set
+# CONFIG_EKF2_SIDESLIP is not set
CONFIG_MODULES_ESC_BATTERY=y
CONFIG_MODULES_EVENTS=y
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
diff --git a/boards/holybro/kakuteh7mini/nuttx-config/bootloader/defconfig b/boards/holybro/kakuteh7mini/nuttx-config/bootloader/defconfig
index cefb4421b7..bc47e6b75b 100644
--- a/boards/holybro/kakuteh7mini/nuttx-config/bootloader/defconfig
+++ b/boards/holybro/kakuteh7mini/nuttx-config/bootloader/defconfig
@@ -47,7 +47,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/holybro/kakuteh7mini/nuttx-config/nsh/defconfig b/boards/holybro/kakuteh7mini/nuttx-config/nsh/defconfig
index f40b0ccbfd..685ea6c247 100644
--- a/boards/holybro/kakuteh7mini/nuttx-config/nsh/defconfig
+++ b/boards/holybro/kakuteh7mini/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/holybro/kakuteh7v2/default.px4board b/boards/holybro/kakuteh7v2/default.px4board
index d326a78797..9c060d8442 100644
--- a/boards/holybro/kakuteh7v2/default.px4board
+++ b/boards/holybro/kakuteh7v2/default.px4board
@@ -33,6 +33,12 @@ CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
CONFIG_MODULES_EKF2=y
+# CONFIG_EKF2_AUXVEL is not set
+# CONFIG_EKF2_BARO_COMPENSATION is not set
+# CONFIG_EKF2_DRAG_FUSION is not set
+# CONFIG_EKF2_EXTERNAL_VISION is not set
+# CONFIG_EKF2_GNSS_YAW is not set
+# CONFIG_EKF2_SIDESLIP is not set
CONFIG_MODULES_ESC_BATTERY=y
CONFIG_MODULES_EVENTS=y
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
diff --git a/boards/holybro/kakuteh7v2/nuttx-config/bootloader/defconfig b/boards/holybro/kakuteh7v2/nuttx-config/bootloader/defconfig
index 0f46c66f71..10011bc456 100644
--- a/boards/holybro/kakuteh7v2/nuttx-config/bootloader/defconfig
+++ b/boards/holybro/kakuteh7v2/nuttx-config/bootloader/defconfig
@@ -47,7 +47,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig b/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig
index 8ac32ef349..1b85f5b0fd 100644
--- a/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig
+++ b/boards/holybro/kakuteh7v2/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/holybro/pix32v5/nuttx-config/nsh/defconfig b/boards/holybro/pix32v5/nuttx-config/nsh/defconfig
index 76efc7a11e..370b24dfe6 100644
--- a/boards/holybro/pix32v5/nuttx-config/nsh/defconfig
+++ b/boards/holybro/pix32v5/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/matek/gnss-m9n-f4/nuttx-config/canbootloader/defconfig b/boards/matek/gnss-m9n-f4/nuttx-config/canbootloader/defconfig
index 8c973887bf..0e5f3cf684 100644
--- a/boards/matek/gnss-m9n-f4/nuttx-config/canbootloader/defconfig
+++ b/boards/matek/gnss-m9n-f4/nuttx-config/canbootloader/defconfig
@@ -30,7 +30,7 @@ CONFIG_FDCLONE_STDIO=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=4096
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/matek/gnss-m9n-f4/nuttx-config/nsh/defconfig b/boards/matek/gnss-m9n-f4/nuttx-config/nsh/defconfig
index fb6ecf3ba4..f74d825a37 100644
--- a/boards/matek/gnss-m9n-f4/nuttx-config/nsh/defconfig
+++ b/boards/matek/gnss-m9n-f4/nuttx-config/nsh/defconfig
@@ -104,7 +104,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -138,6 +138,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=131072
CONFIG_RAM_START=0x20000000
diff --git a/boards/matek/gnss-m9n-f4/uavcan_board_identity b/boards/matek/gnss-m9n-f4/uavcan_board_identity
index 70123f7d91..fb24ed9f11 100755
--- a/boards/matek/gnss-m9n-f4/uavcan_board_identity
+++ b/boards/matek/gnss-m9n-f4/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/matek/h743-mini/nuttx-config/bootloader/defconfig b/boards/matek/h743-mini/nuttx-config/bootloader/defconfig
index 94223808e7..a5e157f541 100644
--- a/boards/matek/h743-mini/nuttx-config/bootloader/defconfig
+++ b/boards/matek/h743-mini/nuttx-config/bootloader/defconfig
@@ -47,7 +47,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/matek/h743-mini/nuttx-config/nsh/defconfig b/boards/matek/h743-mini/nuttx-config/nsh/defconfig
index a4c347fe03..600180fa6d 100644
--- a/boards/matek/h743-mini/nuttx-config/nsh/defconfig
+++ b/boards/matek/h743-mini/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
diff --git a/boards/matek/h743-slim/nuttx-config/bootloader/defconfig b/boards/matek/h743-slim/nuttx-config/bootloader/defconfig
index 7130c17c78..636630ffd7 100644
--- a/boards/matek/h743-slim/nuttx-config/bootloader/defconfig
+++ b/boards/matek/h743-slim/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/matek/h743-slim/nuttx-config/nsh/defconfig b/boards/matek/h743-slim/nuttx-config/nsh/defconfig
index 94267a1a2b..cc3124fca0 100644
--- a/boards/matek/h743-slim/nuttx-config/nsh/defconfig
+++ b/boards/matek/h743-slim/nuttx-config/nsh/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
diff --git a/boards/matek/h743/nuttx-config/bootloader/defconfig b/boards/matek/h743/nuttx-config/bootloader/defconfig
index 2bdea5edd9..a39e59702e 100644
--- a/boards/matek/h743/nuttx-config/bootloader/defconfig
+++ b/boards/matek/h743/nuttx-config/bootloader/defconfig
@@ -47,7 +47,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/matek/h743/nuttx-config/nsh/defconfig b/boards/matek/h743/nuttx-config/nsh/defconfig
index 39e976d11c..eba77a1a90 100644
--- a/boards/matek/h743/nuttx-config/nsh/defconfig
+++ b/boards/matek/h743/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
diff --git a/boards/modalai/fc-v1/nuttx-config/nsh/defconfig b/boards/modalai/fc-v1/nuttx-config/nsh/defconfig
index b2d2e7eb77..d1f84d56ee 100644
--- a/boards/modalai/fc-v1/nuttx-config/nsh/defconfig
+++ b/boards/modalai/fc-v1/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -146,6 +146,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/modalai/fc-v2/default.px4board b/boards/modalai/fc-v2/default.px4board
index becef2d482..a34d1ad7a4 100644
--- a/boards/modalai/fc-v2/default.px4board
+++ b/boards/modalai/fc-v2/default.px4board
@@ -14,10 +14,6 @@ CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
CONFIG_COMMON_DISTANCE_SENSOR=y
CONFIG_DRIVERS_DSHOT=y
CONFIG_DRIVERS_GPS=y
-# CONFIG_DRIVERS_IMU_BOSCH_BMI088=y
-# CONFIG_DRIVERS_IMU_INVENSENSE_ICM20602=y
-# CONFIG_DRIVERS_IMU_INVENSENSE_ICM20649=y
-# CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y
CONFIG_DRIVERS_IRLOCK=y
CONFIG_COMMON_LIGHT=y
@@ -29,13 +25,11 @@ CONFIG_DRIVERS_POWER_MONITOR_INA226=y
CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y
CONFIG_DRIVERS_PWM_OUT=y
CONFIG_DRIVERS_RC_INPUT=y
-CONFIG_DRIVERS_RPM=y
CONFIG_COMMON_TELEMETRY=y
CONFIG_DRIVERS_UAVCAN=y
CONFIG_BOARD_UAVCAN_INTERFACES=1
CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2
CONFIG_MODULES_AIRSPEED_SELECTOR=y
-# CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y
CONFIG_MODULES_CAMERA_FEEDBACK=y
CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
@@ -54,7 +48,6 @@ CONFIG_MODULES_GYRO_FFT=y
CONFIG_MODULES_LAND_DETECTOR=y
CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y
CONFIG_MODULES_LOAD_MON=y
-# CONFIG_MODULES_LOCAL_POSITION_ESTIMATOR=y
CONFIG_MODULES_LOGGER=y
CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
CONFIG_MODULES_MANUAL_CONTROL=y
diff --git a/boards/modalai/fc-v2/nuttx-config/bootloader/defconfig b/boards/modalai/fc-v2/nuttx-config/bootloader/defconfig
index 58ac8586ae..1a138a659b 100644
--- a/boards/modalai/fc-v2/nuttx-config/bootloader/defconfig
+++ b/boards/modalai/fc-v2/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/modalai/fc-v2/nuttx-config/nsh/defconfig b/boards/modalai/fc-v2/nuttx-config/nsh/defconfig
index 11bb3c3da9..7fb9744c18 100644
--- a/boards/modalai/fc-v2/nuttx-config/nsh/defconfig
+++ b/boards/modalai/fc-v2/nuttx-config/nsh/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_NCHAINS=24
CONFIG_LIBC_FLOATINGPOINT=y
@@ -152,6 +152,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/modalai/fc-v2/src/mtd.cpp b/boards/modalai/fc-v2/src/mtd.cpp
index 644b96581d..48a5bd334c 100644
--- a/boards/modalai/fc-v2/src/mtd.cpp
+++ b/boards/modalai/fc-v2/src/mtd.cpp
@@ -34,25 +34,19 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi5 = { // FM25V02A on FMUM 32K 512 X 64
+static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
static const px4_mtd_entry_t fmum_fram = {
.device = &spi5,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/boards/mro/ctrl-zero-classic/nuttx-config/bootloader/defconfig b/boards/mro/ctrl-zero-classic/nuttx-config/bootloader/defconfig
index c8a5905f54..1167e3eefa 100644
--- a/boards/mro/ctrl-zero-classic/nuttx-config/bootloader/defconfig
+++ b/boards/mro/ctrl-zero-classic/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/mro/ctrl-zero-classic/nuttx-config/nsh/defconfig b/boards/mro/ctrl-zero-classic/nuttx-config/nsh/defconfig
index e5169e78ed..0811c67f0a 100644
--- a/boards/mro/ctrl-zero-classic/nuttx-config/nsh/defconfig
+++ b/boards/mro/ctrl-zero-classic/nuttx-config/nsh/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -149,6 +149,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/mro/ctrl-zero-f7-oem/nuttx-config/nsh/defconfig b/boards/mro/ctrl-zero-f7-oem/nuttx-config/nsh/defconfig
index da43bb2b3f..93af46bab6 100644
--- a/boards/mro/ctrl-zero-f7-oem/nuttx-config/nsh/defconfig
+++ b/boards/mro/ctrl-zero-f7-oem/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -146,6 +146,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/mro/ctrl-zero-f7/nuttx-config/nsh/defconfig b/boards/mro/ctrl-zero-f7/nuttx-config/nsh/defconfig
index 8ec771c53c..64878f212a 100644
--- a/boards/mro/ctrl-zero-f7/nuttx-config/nsh/defconfig
+++ b/boards/mro/ctrl-zero-f7/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -146,6 +146,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/mro/ctrl-zero-h7-oem/nuttx-config/bootloader/defconfig b/boards/mro/ctrl-zero-h7-oem/nuttx-config/bootloader/defconfig
index 6d945355d7..8a44a577f1 100644
--- a/boards/mro/ctrl-zero-h7-oem/nuttx-config/bootloader/defconfig
+++ b/boards/mro/ctrl-zero-h7-oem/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/mro/ctrl-zero-h7-oem/nuttx-config/nsh/defconfig b/boards/mro/ctrl-zero-h7-oem/nuttx-config/nsh/defconfig
index a79a19a5e0..cbfdca2b5c 100644
--- a/boards/mro/ctrl-zero-h7-oem/nuttx-config/nsh/defconfig
+++ b/boards/mro/ctrl-zero-h7-oem/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/mro/ctrl-zero-h7/nuttx-config/bootloader/defconfig b/boards/mro/ctrl-zero-h7/nuttx-config/bootloader/defconfig
index 8ce4dddb0b..5a696370f9 100644
--- a/boards/mro/ctrl-zero-h7/nuttx-config/bootloader/defconfig
+++ b/boards/mro/ctrl-zero-h7/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/mro/ctrl-zero-h7/nuttx-config/nsh/defconfig b/boards/mro/ctrl-zero-h7/nuttx-config/nsh/defconfig
index a0f041492e..c5f40e5b55 100644
--- a/boards/mro/ctrl-zero-h7/nuttx-config/nsh/defconfig
+++ b/boards/mro/ctrl-zero-h7/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/mro/pixracerpro/nuttx-config/bootloader/defconfig b/boards/mro/pixracerpro/nuttx-config/bootloader/defconfig
index d34cea0b6a..584011e926 100644
--- a/boards/mro/pixracerpro/nuttx-config/bootloader/defconfig
+++ b/boards/mro/pixracerpro/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/mro/pixracerpro/nuttx-config/nsh/defconfig b/boards/mro/pixracerpro/nuttx-config/nsh/defconfig
index 10446138d7..e8005ce5bb 100644
--- a/boards/mro/pixracerpro/nuttx-config/nsh/defconfig
+++ b/boards/mro/pixracerpro/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/mro/x21-777/nuttx-config/nsh/defconfig b/boards/mro/x21-777/nuttx-config/nsh/defconfig
index 6d15b6c475..5a768e24ed 100644
--- a/boards/mro/x21-777/nuttx-config/nsh/defconfig
+++ b/boards/mro/x21-777/nuttx-config/nsh/defconfig
@@ -111,7 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -146,6 +146,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/mro/x21/nuttx-config/nsh/defconfig b/boards/mro/x21/nuttx-config/nsh/defconfig
index 9d891cd2f7..681db5c36b 100644
--- a/boards/mro/x21/nuttx-config/nsh/defconfig
+++ b/boards/mro/x21/nuttx-config/nsh/defconfig
@@ -107,7 +107,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -141,6 +141,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/nxp/fmuk66-e/default.px4board b/boards/nxp/fmuk66-e/default.px4board
index f53c438f88..b8bc5cc7f4 100644
--- a/boards/nxp/fmuk66-e/default.px4board
+++ b/boards/nxp/fmuk66-e/default.px4board
@@ -32,6 +32,7 @@ CONFIG_DRIVERS_SMART_BATTERY_BATMON=y
CONFIG_COMMON_TELEMETRY=y
CONFIG_DRIVERS_TONE_ALARM=y
CONFIG_DRIVERS_UAVCAN=y
+CONFIG_DRIVERS_UWB_UWB_SR150=y
CONFIG_MODULES_AIRSPEED_SELECTOR=y
CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y
CONFIG_MODULES_BATTERY_STATUS=y
diff --git a/boards/nxp/fmuk66-e/nuttx-config/nsh/defconfig b/boards/nxp/fmuk66-e/nuttx-config/nsh/defconfig
index 6b9fa1a438..57d0c64bb6 100644
--- a/boards/nxp/fmuk66-e/nuttx-config/nsh/defconfig
+++ b/boards/nxp/fmuk66-e/nuttx-config/nsh/defconfig
@@ -61,7 +61,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_KINETIS_ADC0=y
@@ -168,6 +168,8 @@ CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x1fff0000
diff --git a/boards/nxp/fmuk66-e/nuttx-config/socketcan/defconfig b/boards/nxp/fmuk66-e/nuttx-config/socketcan/defconfig
index 2d05953375..377f2cd48e 100644
--- a/boards/nxp/fmuk66-e/nuttx-config/socketcan/defconfig
+++ b/boards/nxp/fmuk66-e/nuttx-config/socketcan/defconfig
@@ -62,7 +62,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=48
CONFIG_IOB_NCHAINS=18
CONFIG_KINETIS_ADC0=y
@@ -171,6 +171,8 @@ CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x1fff0000
diff --git a/boards/nxp/fmuk66-v3/nuttx-config/nsh/defconfig b/boards/nxp/fmuk66-v3/nuttx-config/nsh/defconfig
index 23a497e7b0..9ef98c951f 100644
--- a/boards/nxp/fmuk66-v3/nuttx-config/nsh/defconfig
+++ b/boards/nxp/fmuk66-v3/nuttx-config/nsh/defconfig
@@ -65,7 +65,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_KINETIS_ADC0=y
CONFIG_KINETIS_ADC1=y
@@ -171,6 +171,8 @@ CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x1fff0000
diff --git a/boards/nxp/fmuk66-v3/nuttx-config/socketcan/defconfig b/boards/nxp/fmuk66-v3/nuttx-config/socketcan/defconfig
index 4638f1ee76..e99d7c6e90 100644
--- a/boards/nxp/fmuk66-v3/nuttx-config/socketcan/defconfig
+++ b/boards/nxp/fmuk66-v3/nuttx-config/socketcan/defconfig
@@ -63,7 +63,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=48
CONFIG_IOB_NCHAINS=18
CONFIG_KINETIS_ADC0=y
@@ -170,6 +170,8 @@ CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x1fff0000
diff --git a/boards/nxp/fmuk66-v3/nuttx-config/test/defconfig b/boards/nxp/fmuk66-v3/nuttx-config/test/defconfig
index c428852e9b..9818be1f54 100644
--- a/boards/nxp/fmuk66-v3/nuttx-config/test/defconfig
+++ b/boards/nxp/fmuk66-v3/nuttx-config/test/defconfig
@@ -63,7 +63,7 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_KINETIS_ADC0=y
@@ -171,6 +171,8 @@ CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x1fff0000
diff --git a/boards/nxp/fmurt1062-v1/default.px4board b/boards/nxp/fmurt1062-v1/default.px4board
index 2a7791db8f..331b6d36bb 100644
--- a/boards/nxp/fmurt1062-v1/default.px4board
+++ b/boards/nxp/fmurt1062-v1/default.px4board
@@ -22,7 +22,7 @@ CONFIG_DRIVERS_PWM_OUT=y
CONFIG_DRIVERS_RC_INPUT=y
CONFIG_DRIVERS_SAFETY_BUTTON=y
CONFIG_DRIVERS_TONE_ALARM=y
-CONFIG_COMMON_UWB=y
+CONFIG_DRIVERS_UWB_UWB_SR150=y
CONFIG_MODULES_BATTERY_STATUS=y
CONFIG_MODULES_CAMERA_FEEDBACK=y
CONFIG_MODULES_COMMANDER=y
diff --git a/boards/nxp/fmurt1062-v1/nuttx-config/nsh/defconfig b/boards/nxp/fmurt1062-v1/nuttx-config/nsh/defconfig
index 106dc07237..31175960f9 100644
--- a/boards/nxp/fmurt1062-v1/nuttx-config/nsh/defconfig
+++ b/boards/nxp/fmurt1062-v1/nuttx-config/nsh/defconfig
@@ -115,7 +115,7 @@ CONFIG_IMXRT_USDHC1=y
CONFIG_IMXRT_USDHC1_INVERT_CD=y
CONFIG_IMXRT_USDHC1_WIDTH_D1_D4=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
CONFIG_LPUART2_BAUD=57600
@@ -184,6 +184,8 @@ CONFIG_PIPES=y
CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=1048576
CONFIG_RAM_START=0x20200000
diff --git a/boards/nxp/mr-canhubk3/fmu.px4board b/boards/nxp/mr-canhubk3/fmu.px4board
index c85a77330d..9505bb74a8 100644
--- a/boards/nxp/mr-canhubk3/fmu.px4board
+++ b/boards/nxp/mr-canhubk3/fmu.px4board
@@ -1,20 +1,25 @@
# CONFIG_BOARD_ROMFSROOT is not set
CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS1"
+CONFIG_BOARD_SERIAL_GPS2="/dev/ttyS4"
CONFIG_BOARD_SERIAL_RC="/dev/ttyS5"
CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS2"
+CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS3"
CONFIG_BOARD_UAVCAN_INTERFACES=1
CONFIG_COMMON_LIGHT=y
CONFIG_CYPHAL_BMS_SUBSCRIBER=y
+CONFIG_DRIVERS_ADC_BOARD_ADC=y
CONFIG_DRIVERS_CYPHAL=y
CONFIG_DRIVERS_GPS=y
CONFIG_DRIVERS_IRLOCK=y
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y
CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y
CONFIG_DRIVERS_RC_INPUT=y
+CONFIG_DRIVERS_SAFETY_BUTTON=y
CONFIG_DRIVERS_UAVCAN=y
CONFIG_EXAMPLES_FAKE_GPS=y
CONFIG_MODULES_AIRSPEED_SELECTOR=y
CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=y
+CONFIG_MODULES_BATTERY_STATUS=y
CONFIG_MODULES_CAMERA_FEEDBACK=y
CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_ESC_BATTERY=y
diff --git a/boards/nxp/mr-canhubk3/init/rc.board_defaults b/boards/nxp/mr-canhubk3/init/rc.board_defaults
index 64dedb9fe8..7ef22a054c 100644
--- a/boards/nxp/mr-canhubk3/init/rc.board_defaults
+++ b/boards/nxp/mr-canhubk3/init/rc.board_defaults
@@ -17,6 +17,17 @@ param set-default MAV_1_UDP_PRT 14550
param set-default SENS_EXT_I2C_PRB 0
param set-default CYPHAL_ENABLE 0
+if ver hwtypecmp MR-CANHUBK3-ADAP
+then
+ param set-default GPS_1_CONFIG 202
+ param set-default RC_PORT_CONFIG 104
+ param set-default SENS_INT_BARO_EN 0
+ param set-default SYS_HAS_BARO 0
+ # MR-CANHUBK3-ADAP voltage divider
+ param set-default BAT1_V_DIV 13.158
+ safety_button start
+fi
+
if param greater -s UAVCAN_ENABLE 0
then
ifup can0
diff --git a/boards/nxp/mr-canhubk3/init/rc.board_sensors b/boards/nxp/mr-canhubk3/init/rc.board_sensors
index fd2dc79a17..642a254efc 100644
--- a/boards/nxp/mr-canhubk3/init/rc.board_sensors
+++ b/boards/nxp/mr-canhubk3/init/rc.board_sensors
@@ -2,22 +2,31 @@
#
# NXP MR-CANHUBK3 specific board sensors init
#------------------------------------------------------------------------------
+if ver hwtypecmp MR-CANHUBK3-ADAP
+then
+ icm42688p -c 2 -b 3 -R 0 -S -f 15000 start
+ # Internal magnetometer on I2c on ADAP
+ bmm150 -X -a 18 start
+ ist8310 -X -b 1 -R 10 start
+ # ADC for voltage input sensing
+ board_adc start
-#board_adc start FIXME no ADC drivers
+ # External SPI bus ICM20649
+ icm20649 -b 4 -S -R 10 start
-#FMUv5Xbase board orientation
+ # External SPI bus ICM42688p
+ icm42688p -c 1 -b 3 -R 10 -S -f 15000 start
+else
+ bmm150 -X start
+ # External compass on GPS1/I2C1 (the 3rd external bus): standard Holybro Pixhawk 4 or CUAV V5 GPS/compass puck (with lights, safety button, and buzzer)
+ ist8310 -X -b 2 -R 10 start
-# Internal SPI bus ICM20649
-icm20649 -s -R 6 start
+ # External SPI bus ICM20649
+ icm20649 -b 4 -S -R 6 start
-# Internal SPI bus ICM42688p
-icm42688p -R 6 -s start
-
-# Internal magnetometer on I2c
-bmm150 -I start
-
-# External compass on GPS1/I2C1 (the 3rd external bus): standard Holybro Pixhawk 4 or CUAV V5 GPS/compass puck (with lights, safety button, and buzzer)
-ist8310 -X -b 2 -R 10 start
+ # External SPI bus ICM42688p
+ icm42688p -c 1 -b 3 -R 6 -S -f 15000 start
+fi
# External compass on GPS1/I2C1 (the 3rd external bus): Drotek RTK GPS with LIS3MDL Compass
lis3mdl -X -b 2 -R 2 start
@@ -25,5 +34,5 @@ lis3mdl -X -b 2 -R 2 start
# Disable startup of internal baros if param is set to false
if param compare SENS_INT_BARO_EN 1
then
- bmp388 -I -a 0x77 start
+ bmp388 -X -a 0x77 start
fi
diff --git a/boards/nxp/mr-canhubk3/nuttx-config/include/board.h b/boards/nxp/mr-canhubk3/nuttx-config/include/board.h
index 04d0478528..457f63c5cf 100644
--- a/boards/nxp/mr-canhubk3/nuttx-config/include/board.h
+++ b/boards/nxp/mr-canhubk3/nuttx-config/include/board.h
@@ -152,6 +152,18 @@
#define PIN_LPUART1_RX (PIN_LPUART1_RX_3 | PIN_INPUT_PULLUP) /* PTC6 */
#define PIN_LPUART1_TX PIN_LPUART1_TX_3 /* PTC7 */
+
+/* LPUART4 /dev/ttyS3 P8B 3X7 Pin 3 Single wire RC UART */
+
+#define PIN_LPUART4_RX PIN_LPUART4_TX_3 /* Dummy since it's Single Wire TX-only */
+#define PIN_LPUART4_TX PIN_LPUART4_TX_3 /* PTE11 */
+
+
+/* LPUART7 /dev/ttyS4 P8B 3X7 Pin 3 and Pin 8 */
+
+#define PIN_LPUART7_RX (PIN_LPUART7_RX_3 | PIN_INPUT_PULLUP) /* PTE0 */
+#define PIN_LPUART7_TX PIN_LPUART7_TX_3 /* PTE1 */
+
/* LPUART9 P24 UART connector */
#define PIN_LPUART9_RX (PIN_LPUART9_RX_1 | PIN_INPUT_PULLUP) /* PTB2 */
@@ -209,7 +221,8 @@
#define PIN_LPSPI4_PCS0 PIN_LPSPI4_PCS0_1 /* PTB8 */
#define PIN_LPSPI4_PCS3 PIN_LPSPI4_PCS3_1 /* PTA16 */
-#define PIN_LPSPI4_PCS (PIN_PTA16 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) /* PTA16 */
+#define PIN_LPSPI4_CS_P26 (PIN_PTA16 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) /* PTA16 */
+#define PIN_LPSPI4_CS_P8B (PIN_PTB8 | GPIO_LOWDRIVE | GPIO_OUTPUT_ONE) /* PTB8 */
/* LPSPI5 P26 external IMU connector */
diff --git a/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig b/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig
index f5facd0fdd..f306f5eb9d 100644
--- a/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig
+++ b/boards/nxp/mr-canhubk3/nuttx-config/nsh/defconfig
@@ -109,7 +109,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=900
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_IPCFG_BINARY=y
@@ -245,6 +245,8 @@ CONFIG_S32K3XX_LPUART13=y
CONFIG_S32K3XX_LPUART14=y
CONFIG_S32K3XX_LPUART1=y
CONFIG_S32K3XX_LPUART2=y
+CONFIG_S32K3XX_LPUART4=y
+CONFIG_S32K3XX_LPUART7=y
CONFIG_S32K3XX_LPUART9=y
CONFIG_S32K3XX_LPUART_INVERT=y
CONFIG_S32K3XX_LPUART_SINGLEWIRE=y
diff --git a/boards/nxp/mr-canhubk3/nuttx-config/sysview/defconfig b/boards/nxp/mr-canhubk3/nuttx-config/sysview/defconfig
index 32169a8ae5..e9d287c2cd 100644
--- a/boards/nxp/mr-canhubk3/nuttx-config/sysview/defconfig
+++ b/boards/nxp/mr-canhubk3/nuttx-config/sysview/defconfig
@@ -110,7 +110,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=900
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_IPCFG_BINARY=y
diff --git a/boards/nxp/mr-canhubk3/src/CMakeLists.txt b/boards/nxp/mr-canhubk3/src/CMakeLists.txt
index 3a5ac9c0e6..26a13272e2 100644
--- a/boards/nxp/mr-canhubk3/src/CMakeLists.txt
+++ b/boards/nxp/mr-canhubk3/src/CMakeLists.txt
@@ -38,6 +38,7 @@ if("${PX4_BOARD_LABEL}" STREQUAL "canbootloader")
clockconfig.c
periphclocks.c
timer_config.cpp
+ hw_rev_ver_canhubk3.c
)
target_link_libraries(drivers_board
@@ -65,6 +66,8 @@ else()
spi.cpp
timer_config.cpp
s32k3xx_userleds.c
+ hw_rev_ver_canhubk3.c
+ manifest.c
)
target_link_libraries(drivers_board
diff --git a/boards/nxp/mr-canhubk3/src/board_config.h b/boards/nxp/mr-canhubk3/src/board_config.h
index 49a3162af6..7ea2a91e8b 100644
--- a/boards/nxp/mr-canhubk3/src/board_config.h
+++ b/boards/nxp/mr-canhubk3/src/board_config.h
@@ -88,7 +88,7 @@ __BEGIN_DECLS
#define DIRECT_PWM_OUTPUT_CHANNELS 8
#define RC_SERIAL_PORT "/dev/ttyS5"
-#define RC_SERIAL_SINGLEWIRE
+#define RC_SERIAL_SINGLEWIRE_FORCE
#define RC_SERIAL_INVERT_RX_ONLY
#define BOARD_ENABLE_CONSOLE_BUFFER
@@ -110,6 +110,40 @@ __BEGIN_DECLS
/* Reboot and ulog we store on a wear-level filesystem */
#define HARDFAULT_REBOOT_PATH "/mnt/progmem/reboot"
+/* To detect MR-CANHUBK3-ADAP board */
+#define BOARD_HAS_HW_VERSIONING 1
+#define CANHUBK3_ADAP_DETECT (PIN_PTA12 | GPIO_INPUT | GPIO_PULLUP)
+
+
+/*
+ * ADC channels
+ *
+ * These are the channel numbers of the ADCs of the microcontroller that can be used by the Px4
+ * Firmware in the adc driver. ADC1 has 32 channels, with some a/b selection overlap
+ * in the AD4-AD7 range on the same ADC.
+ *
+ * Only ADC1 is used
+ * Bits 31:0 are ADC1 channels 31:0
+ */
+
+#define ADC1_CH(c) (((c) & 0x1f)) /* Define ADC number Channel number */
+
+/* ADC defines to be used in sensors.cpp to read from a particular channel */
+
+#define ADC_BATTERY_VOLTAGE_CHANNEL ADC1_CH(0) /* BAT_VSENS 85 PTB4 ADC1_SE10 */
+#define ADC_BATTERY_CURRENT_CHANNEL ADC1_CH(1) /* Non-existant but needed for compilation */
+
+
+/* Mask use to initialize the ADC driver */
+
+#define ADC_CHANNELS ((1 << ADC_BATTERY_VOLTAGE_CHANNEL))
+
+/* Safety Switch
+ * TBD
+ */
+#define GPIO_LED_SAFETY (PIN_PTE26 | GPIO_OUTPUT | GPIO_OUTPUT_ZERO)
+#define GPIO_BTN_SAFETY (PIN_PTA11 | GPIO_INPUT | GPIO_PULLDOWN)
+
/****************************************************************************
* Public Data
****************************************************************************/
diff --git a/boards/nxp/mr-canhubk3/src/hw_rev_ver_canhubk3.c b/boards/nxp/mr-canhubk3/src/hw_rev_ver_canhubk3.c
new file mode 100644
index 0000000000..990c17492a
--- /dev/null
+++ b/boards/nxp/mr-canhubk3/src/hw_rev_ver_canhubk3.c
@@ -0,0 +1,142 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file hw_rev_ver_canhubk3.c
+ * CANHUBK3 Hardware Revision and Version ID API
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#if defined(BOARD_HAS_HW_VERSIONING)
+
+
+#define HW_INFO_SIZE HW_INFO_VER_DIGITS + HW_INFO_REV_DIGITS
+
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+static int is_adap_connected = 0;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+/************************************************************************************
+ * Name: board_get_hw_type
+ *
+ * Description:
+ * Optional returns a 0 terminated string defining the HW type.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * a 0 terminated string defining the HW type. This my be a 0 length string ""
+ *
+ ************************************************************************************/
+
+__EXPORT const char *board_get_hw_type_name()
+{
+ if (is_adap_connected) {
+ return (const char *)"MR-CANHUBK3-ADAP";
+
+ } else {
+ return (const char *)"MR-CANHUBK344";
+ }
+}
+
+/************************************************************************************
+ * Name: board_get_hw_version
+ *
+ * Description:
+ * Optional returns a integer HW version
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * An integer value of this boards hardware version.
+ * A value of -1 is the default for boards not supporting the BOARD_HAS_VERSIONING API.
+ * A value of 0 is the default for boards supporting the API but not having version.
+ *
+ ************************************************************************************/
+
+__EXPORT int board_get_hw_version()
+{
+ return 0;
+}
+
+/************************************************************************************
+ * Name: board_get_hw_revision
+ *
+ * Description:
+ * Optional returns a integer HW revision
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * An integer value of this boards hardware revision.
+ * A value of -1 is the default for boards not supporting the BOARD_HAS_VERSIONING API.
+ * A value of 0 is the default for boards supporting the API but not having revision.
+ *
+ ************************************************************************************/
+
+__EXPORT int board_get_hw_revision()
+{
+ return 0;
+}
+
+/************************************************************************************
+ * Name: board_determine_hw_info
+ *
+ * Description:
+ * Uses GPIO to detect MR-CANHUBK3-ADAP
+ *
+ ************************************************************************************/
+
+int board_determine_hw_info()
+{
+ s32k3xx_pinconfig(CANHUBK3_ADAP_DETECT);
+ is_adap_connected = !s32k3xx_gpioread(CANHUBK3_ADAP_DETECT);
+ return 0;
+}
+#endif
diff --git a/boards/nxp/mr-canhubk3/src/i2c.cpp b/boards/nxp/mr-canhubk3/src/i2c.cpp
index f8639282ae..c99547def4 100644
--- a/boards/nxp/mr-canhubk3/src/i2c.cpp
+++ b/boards/nxp/mr-canhubk3/src/i2c.cpp
@@ -34,6 +34,6 @@
#include
constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = {
- initI2CBusInternal(PX4_BUS_NUMBER_TO_PX4(0)),
- initI2CBusExternal(PX4_BUS_NUMBER_TO_PX4(1)),
+ initI2CBusExternal(PX4_BUS_NUMBER_TO_PX4(0)),
+ initI2CBusInternal(PX4_BUS_NUMBER_TO_PX4(1)),
};
diff --git a/boards/nxp/mr-canhubk3/src/init.c b/boards/nxp/mr-canhubk3/src/init.c
index 1075daece6..97a41f8430 100644
--- a/boards/nxp/mr-canhubk3/src/init.c
+++ b/boards/nxp/mr-canhubk3/src/init.c
@@ -44,6 +44,7 @@
#include "board_config.h"
#include
+#include
#if defined(CONFIG_S32K3XX_LPSPI1) && defined(CONFIG_MMCSD)
#include
@@ -96,6 +97,8 @@ __EXPORT int board_app_initialize(uintptr_t arg)
int rv;
+ board_determine_hw_info();
+
#if defined(CONFIG_S32K3XX_LPSPI1) && defined(CONFIG_MMCSD)
/* LPSPI1 *****************************************************************/
diff --git a/boards/nxp/mr-canhubk3/src/manifest.c b/boards/nxp/mr-canhubk3/src/manifest.c
new file mode 100644
index 0000000000..afd3de58e5
--- /dev/null
+++ b/boards/nxp/mr-canhubk3/src/manifest.c
@@ -0,0 +1,79 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file manifest.c
+ *
+ * This module supplies the interface to the manifest of hardware that is
+ * optional and dependent on the HW REV and HW VER IDs
+ *
+ * The manifest allows the system to know whether a hardware option
+ * say for example the PX4IO is an no-pop option vs it is broken.
+ *
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+#include
+
+#include "systemlib/px4_macros.h"
+#include "px4_log.h"
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+
+/************************************************************************************
+ * Name: board_query_manifest
+ *
+ * Description:
+ * Optional returns manifest item.
+ *
+ * Input Parameters:
+ * manifest_id - the ID for the manifest item to retrieve
+ *
+ * Returned Value:
+ * 0 - item is not in manifest => assume legacy operations
+ * pointer to a manifest item
+ *
+ ************************************************************************************/
+
+__EXPORT px4_hw_mft_item board_query_manifest(px4_hw_mft_item_id_t id)
+{
+ return px4_hw_mft_unsupported;
+}
diff --git a/boards/nxp/mr-canhubk3/src/s32k3xx_bringup.c b/boards/nxp/mr-canhubk3/src/s32k3xx_bringup.c
index 529ed7ed9b..53eda463be 100644
--- a/boards/nxp/mr-canhubk3/src/s32k3xx_bringup.c
+++ b/boards/nxp/mr-canhubk3/src/s32k3xx_bringup.c
@@ -107,6 +107,9 @@ int s32k3xx_bringup(void)
s32k3xx_spidev_initialize();
#endif
+ s32k3xx_pinconfig(GPIO_LED_SAFETY);
+ s32k3xx_pinconfig(GPIO_BTN_SAFETY);
+
#ifdef CONFIG_INPUT_BUTTONS
/* Register the BUTTON driver */
diff --git a/boards/nxp/mr-canhubk3/src/s32k3xx_periphclocks.c b/boards/nxp/mr-canhubk3/src/s32k3xx_periphclocks.c
index 0314fce44f..42cf924059 100644
--- a/boards/nxp/mr-canhubk3/src/s32k3xx_periphclocks.c
+++ b/boards/nxp/mr-canhubk3/src/s32k3xx_periphclocks.c
@@ -168,6 +168,22 @@ const struct peripheral_clock_config_s g_peripheral_clockconfig0[] = {
.clkgate = true,
#else
.clkgate = false,
+#endif
+ },
+ {
+ .clkname = LPUART4_CLK,
+#ifdef CONFIG_S32K3XX_LPUART4
+ .clkgate = true,
+#else
+ .clkgate = false,
+#endif
+ },
+ {
+ .clkname = LPUART7_CLK,
+#ifdef CONFIG_S32K3XX_LPUART7
+ .clkgate = true,
+#else
+ .clkgate = false,
#endif
},
{
@@ -258,6 +274,10 @@ const struct peripheral_clock_config_s g_peripheral_clockconfig0[] = {
.clkname = EMIOS0_CLK,
.clkgate = true,
},
+ {
+ .clkname = ADC2_CLK,
+ .clkgate = true,
+ }
};
unsigned int const num_of_peripheral_clocks_0 =
diff --git a/boards/nxp/mr-canhubk3/src/spi.cpp b/boards/nxp/mr-canhubk3/src/spi.cpp
index 325ad7b7d7..40d9e9a7c1 100644
--- a/boards/nxp/mr-canhubk3/src/spi.cpp
+++ b/boards/nxp/mr-canhubk3/src/spi.cpp
@@ -70,11 +70,12 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
initSPIBus(SPI::Bus::SPI3, { // SPI3 is ignored only used for FS26 by a NuttX driver
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortD, GPIO::Pin17})
}),
- initSPIBus(SPI::Bus::SPI4, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortA, GPIO::Pin16}, SPI::DRDY{PIN_WKPU20})
+ initSPIBusExternal(SPI::Bus::SPI4, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin16}, SPI::DRDY{PIN_WKPU20}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortB, GPIO::Pin8}, SPI::DRDY{PIN_WKPU56})
}),
- initSPIBus(SPI::Bus::SPI5, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortA, GPIO::Pin14}, SPI::DRDY{PIN_WKPU4})
+ initSPIBusExternal(SPI::Bus::SPI5, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin14}, SPI::DRDY{PIN_WKPU4})
}),
};
@@ -337,7 +338,14 @@ void s32k3xx_lpspi4select(FAR struct spi_dev_s *dev, uint32_t devid,
spiinfo("devid: %" PRId32 ", CS: %s\n", devid,
selected ? "assert" : "de-assert");
- s32k3xx_gpiowrite(PIN_LPSPI4_PCS, !selected);
+ devid = ((devid) & 0xF);
+
+ if (devid == 0) {
+ s32k3xx_gpiowrite(PIN_LPSPI4_CS_P26, !selected);
+
+ } else if (devid == 1) {
+ s32k3xx_gpiowrite(PIN_LPSPI4_CS_P8B, !selected);
+ }
}
uint8_t s32k3xx_lpspi4status(FAR struct spi_dev_s *dev, uint32_t devid)
diff --git a/boards/nxp/ucans32k146/default.px4board b/boards/nxp/ucans32k146/default.px4board
index eb28094dd9..f953043875 100644
--- a/boards/nxp/ucans32k146/default.px4board
+++ b/boards/nxp/ucans32k146/default.px4board
@@ -28,6 +28,7 @@ CONFIG_UAVCANNODE_RTK_DATA=y
CONFIG_UAVCANNODE_SERVO_ARRAY_COMMAND=y
CONFIG_UAVCANNODE_STATIC_PRESSURE=y
CONFIG_UAVCANNODE_STATIC_TEMPERATURE=y
+CONFIG_DRIVERS_UWB_UWB_SR150=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_SENSORS=y
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y
diff --git a/boards/nxp/ucans32k146/init/rc.board_defaults b/boards/nxp/ucans32k146/init/rc.board_defaults
index 2e52bc7b72..0cd4598d2a 100644
--- a/boards/nxp/ucans32k146/init/rc.board_defaults
+++ b/boards/nxp/ucans32k146/init/rc.board_defaults
@@ -3,7 +3,7 @@
# board specific defaults
#------------------------------------------------------------------------------
-pwm_out mode_pwm1 start
+pwm_out start
ifup can0
diff --git a/boards/nxp/ucans32k146/uavcan_board_identity b/boards/nxp/ucans32k146/uavcan_board_identity
index dd7e3fcb77..7ff76347f8 100644
--- a/boards/nxp/ucans32k146/uavcan_board_identity
+++ b/boards/nxp/ucans32k146/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/omnibus/f4sd/default.px4board b/boards/omnibus/f4sd/default.px4board
index ceabc36840..287d991659 100644
--- a/boards/omnibus/f4sd/default.px4board
+++ b/boards/omnibus/f4sd/default.px4board
@@ -22,6 +22,7 @@ CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
CONFIG_MODULES_LAND_DETECTOR=y
+CONFIG_MODULES_LOAD_MON=y
CONFIG_MODULES_LOGGER=y
CONFIG_MODULES_MANUAL_CONTROL=y
CONFIG_MODULES_MAVLINK=y
@@ -32,6 +33,9 @@ CONFIG_MODULES_NAVIGATOR=y
CONFIG_MODULES_RC_UPDATE=y
CONFIG_MODULES_SENSORS=y
# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set
-CONFIG_MODULES_UXRCE_DDS_CLIENT=y
+CONFIG_SYSTEMCMDS_DMESG=y
CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y
CONFIG_SYSTEMCMDS_PARAM=y
+CONFIG_SYSTEMCMDS_TOP=y
+CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y
+CONFIG_SYSTEMCMDS_UORB=y
diff --git a/boards/omnibus/f4sd/init/rc.board_defaults b/boards/omnibus/f4sd/init/rc.board_defaults
index 5b492c4359..9e6affd345 100644
--- a/boards/omnibus/f4sd/init/rc.board_defaults
+++ b/boards/omnibus/f4sd/init/rc.board_defaults
@@ -14,8 +14,7 @@ param set-default CBRK_IO_SAFETY 22027
# use the Q attitude estimator, it works w/o mag or GPS.
param set-default SYS_MC_EST_GROUP 3
-param set-default ATT_ACC_COMP 0
-param set-default ATT_W_ACC 0.4000
-param set-default ATT_W_GYRO_BIAS 0.0000
+param set-default ATT_W_ACC 0.4
+param set-default ATT_W_GYRO_BIAS 0
param set-default SYS_HAS_MAG 0
diff --git a/boards/omnibus/f4sd/nuttx-config/nsh/defconfig b/boards/omnibus/f4sd/nuttx-config/nsh/defconfig
index 8cdd6c1e6f..b154c61070 100644
--- a/boards/omnibus/f4sd/nuttx-config/nsh/defconfig
+++ b/boards/omnibus/f4sd/nuttx-config/nsh/defconfig
@@ -62,7 +62,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
CONFIG_MEMSET_64BIT=y
diff --git a/boards/px4/fmu-v2/nuttx-config/nsh/defconfig b/boards/px4/fmu-v2/nuttx-config/nsh/defconfig
index e03b0218f4..f3d181112b 100644
--- a/boards/px4/fmu-v2/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v2/nuttx-config/nsh/defconfig
@@ -103,7 +103,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -136,6 +136,8 @@ CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_DEFAULT_PRIO_INHERIT=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/px4/fmu-v3/nuttx-config/nsh/defconfig b/boards/px4/fmu-v3/nuttx-config/nsh/defconfig
index c836579fe4..2c9487ddaf 100644
--- a/boards/px4/fmu-v3/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v3/nuttx-config/nsh/defconfig
@@ -108,7 +108,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -141,6 +141,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/px4/fmu-v4/default.px4board b/boards/px4/fmu-v4/default.px4board
index f63e0618f4..0e1bb8f547 100644
--- a/boards/px4/fmu-v4/default.px4board
+++ b/boards/px4/fmu-v4/default.px4board
@@ -54,7 +54,6 @@ CONFIG_MODULES_FW_POS_CONTROL=y
CONFIG_MODULES_FW_RATE_CONTROL=y
CONFIG_MODULES_GIMBAL=y
CONFIG_MODULES_GYRO_CALIBRATION=y
-CONFIG_MODULES_GYRO_FFT=y
CONFIG_MODULES_LAND_DETECTOR=y
CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y
CONFIG_MODULES_LOAD_MON=y
diff --git a/boards/px4/fmu-v4/nuttx-config/nsh/defconfig b/boards/px4/fmu-v4/nuttx-config/nsh/defconfig
index a8ac1b9a34..3566ccc30c 100644
--- a/boards/px4/fmu-v4/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v4/nuttx-config/nsh/defconfig
@@ -107,7 +107,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -140,6 +140,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/px4/fmu-v4/nuttx-config/test/defconfig b/boards/px4/fmu-v4/nuttx-config/test/defconfig
index aa3d5890a8..3c90516de3 100644
--- a/boards/px4/fmu-v4/nuttx-config/test/defconfig
+++ b/boards/px4/fmu-v4/nuttx-config/test/defconfig
@@ -108,7 +108,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -141,6 +141,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/px4/fmu-v4/test.px4board b/boards/px4/fmu-v4/test.px4board
index 6f18488d5c..c1c005f905 100644
--- a/boards/px4/fmu-v4/test.px4board
+++ b/boards/px4/fmu-v4/test.px4board
@@ -1,4 +1,6 @@
CONFIG_DRIVERS_ADC_ADS1115=n
+CONFIG_DRIVERS_CAMERA_CAPTURE=n
+CONFIG_DRIVERS_CAMERA_TRIGGER=n
CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16448=n
CONFIG_DRIVERS_IRLOCK=n
CONFIG_DRIVERS_PCA9685_PWM_OUT=n
diff --git a/boards/px4/fmu-v4/uavcan_board_identity b/boards/px4/fmu-v4/uavcan_board_identity
index 0905752e49..507d3ec578 100644
--- a/boards/px4/fmu-v4/uavcan_board_identity
+++ b/boards/px4/fmu-v4/uavcan_board_identity
@@ -1,6 +1,6 @@
# UAVCAN boot loadable Module ID
-set(uavcanblid_sw_version_major 0)
-set(uavcanblid_sw_version_minor 1)
+set(uavcanblid_sw_version_major ${PX4_VERSION_MAJOR})
+set(uavcanblid_sw_version_minor ${PX4_VERSION_MINOR})
add_definitions(
-DAPP_VERSION_MAJOR=${uavcanblid_sw_version_major}
-DAPP_VERSION_MINOR=${uavcanblid_sw_version_minor}
diff --git a/boards/px4/fmu-v4pro/nuttx-config/nsh/defconfig b/boards/px4/fmu-v4pro/nuttx-config/nsh/defconfig
index e8ecbaee38..e479b13646 100644
--- a/boards/px4/fmu-v4pro/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v4pro/nuttx-config/nsh/defconfig
@@ -107,7 +107,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -140,6 +140,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=393216
CONFIG_RAM_START=0x20000000
diff --git a/boards/px4/fmu-v4pro/nuttx-config/test/defconfig b/boards/px4/fmu-v4pro/nuttx-config/test/defconfig
index 7825cb6c63..a1145fe284 100644
--- a/boards/px4/fmu-v4pro/nuttx-config/test/defconfig
+++ b/boards/px4/fmu-v4pro/nuttx-config/test/defconfig
@@ -108,7 +108,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -141,6 +141,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=393216
CONFIG_RAM_START=0x20000000
diff --git a/boards/px4/fmu-v4pro/src/mtd.cpp b/boards/px4/fmu-v4pro/src/mtd.cpp
index 4bd93619db..f32f1dee1d 100644
--- a/boards/px4/fmu-v4pro/src/mtd.cpp
+++ b/boards/px4/fmu-v4pro/src/mtd.cpp
@@ -34,7 +34,7 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi2 = { // FM25V01A on FMUM 16K
+static const px4_mft_device_t spi2 = { // FM25V01A on FMUM native: 16K X 8, emulated as (512 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
@@ -46,7 +46,7 @@ static const px4_mtd_entry_t fmum_fram = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
+ .nblocks = (16384 / (1 << CONFIG_RAMTRON_EMULATE_PAGE_SHIFT))
},
},
};
diff --git a/boards/px4/fmu-v5/debug.px4board b/boards/px4/fmu-v5/debug.px4board
index 7e590cf43a..0b8ab3fc3e 100644
--- a/boards/px4/fmu-v5/debug.px4board
+++ b/boards/px4/fmu-v5/debug.px4board
@@ -28,7 +28,6 @@ CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=n
CONFIG_MODULES_TEMPERATURE_COMPENSATION=n
CONFIG_MODULES_UUV_ATT_CONTROL=n
CONFIG_MODULES_UUV_POS_CONTROL=n
-CONFIG_SYSTEMCMDS_SERIAL_TEST=n
CONFIG_BOARD_CONSTRAINED_FLASH=y
CONFIG_BOARD_TESTING=y
CONFIG_DRIVERS_BAROMETER_MS5611=y
@@ -45,3 +44,4 @@ CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y
CONFIG_DRIVERS_MAGNETOMETER_RM3100=y
CONFIG_DRIVERS_MAGNETOMETER_VTRANTECH_VCM1193L=y
CONFIG_DRIVERS_TEST_PPM=y
+CONFIG_SYSTEMCMDS_SD_STRESS=y
diff --git a/boards/px4/fmu-v5/default.px4board b/boards/px4/fmu-v5/default.px4board
index fe8b0759c6..bfb8b6af46 100644
--- a/boards/px4/fmu-v5/default.px4board
+++ b/boards/px4/fmu-v5/default.px4board
@@ -98,8 +98,6 @@ CONFIG_SYSTEMCMDS_PERF=y
CONFIG_SYSTEMCMDS_REBOOT=y
CONFIG_SYSTEMCMDS_REFLECT=y
CONFIG_SYSTEMCMDS_SD_BENCH=y
-CONFIG_SYSTEMCMDS_SD_STRESS=y
-CONFIG_SYSTEMCMDS_SERIAL_TEST=y
CONFIG_SYSTEMCMDS_SYSTEM_TIME=y
CONFIG_SYSTEMCMDS_TOP=y
CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y
diff --git a/boards/px4/fmu-v5/nuttx-config/cryptotest/defconfig b/boards/px4/fmu-v5/nuttx-config/cryptotest/defconfig
index ff995b6cf5..171589b494 100644
--- a/boards/px4/fmu-v5/nuttx-config/cryptotest/defconfig
+++ b/boards/px4/fmu-v5/nuttx-config/cryptotest/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5/nuttx-config/cyphal/defconfig b/boards/px4/fmu-v5/nuttx-config/cyphal/defconfig
index 9e3596c1f0..2c7bafc1e8 100644
--- a/boards/px4/fmu-v5/nuttx-config/cyphal/defconfig
+++ b/boards/px4/fmu-v5/nuttx-config/cyphal/defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -148,6 +148,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5/nuttx-config/debug/defconfig b/boards/px4/fmu-v5/nuttx-config/debug/defconfig
index 74f4ecac3c..08e2bb9e8a 100644
--- a/boards/px4/fmu-v5/nuttx-config/debug/defconfig
+++ b/boards/px4/fmu-v5/nuttx-config/debug/defconfig
@@ -157,7 +157,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=1064
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -192,6 +192,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5/nuttx-config/nsh/defconfig b/boards/px4/fmu-v5/nuttx-config/nsh/defconfig
index b0453967b2..ae31f2b0af 100644
--- a/boards/px4/fmu-v5/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v5/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -146,6 +146,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5/nuttx-config/protected/defconfig b/boards/px4/fmu-v5/nuttx-config/protected/defconfig
index 1902014e3b..7733599a7f 100644
--- a/boards/px4/fmu-v5/nuttx-config/protected/defconfig
+++ b/boards/px4/fmu-v5/nuttx-config/protected/defconfig
@@ -115,7 +115,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="px4_entry"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -152,6 +152,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5/nuttx-config/stackcheck/defconfig b/boards/px4/fmu-v5/nuttx-config/stackcheck/defconfig
index c5450ab1f4..7350cb4532 100644
--- a/boards/px4/fmu-v5/nuttx-config/stackcheck/defconfig
+++ b/boards/px4/fmu-v5/nuttx-config/stackcheck/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=878
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -147,6 +147,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5/nuttx-config/test/defconfig b/boards/px4/fmu-v5/nuttx-config/test/defconfig
index 357c5b29b6..21babe66f6 100644
--- a/boards/px4/fmu-v5/nuttx-config/test/defconfig
+++ b/boards/px4/fmu-v5/nuttx-config/test/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -146,6 +146,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5/protected.px4board b/boards/px4/fmu-v5/protected.px4board
index de913d6ac8..e5371b2a7d 100644
--- a/boards/px4/fmu-v5/protected.px4board
+++ b/boards/px4/fmu-v5/protected.px4board
@@ -36,8 +36,6 @@ CONFIG_SYSTEMCMDS_MTD=n
CONFIG_SYSTEMCMDS_NSHTERM=n
CONFIG_SYSTEMCMDS_REFLECT=n
CONFIG_SYSTEMCMDS_SD_BENCH=n
-CONFIG_SYSTEMCMDS_SD_STRESS=n
-CONFIG_SYSTEMCMDS_SERIAL_TEST=n
CONFIG_SYSTEMCMDS_SYSTEM_TIME=n
CONFIG_SYSTEMCMDS_USB_CONNECTED=n
CONFIG_BOARD_PROTECTED=y
diff --git a/boards/px4/fmu-v5/stackcheck.px4board b/boards/px4/fmu-v5/stackcheck.px4board
index fb10b4c77a..812a0f7295 100644
--- a/boards/px4/fmu-v5/stackcheck.px4board
+++ b/boards/px4/fmu-v5/stackcheck.px4board
@@ -3,6 +3,8 @@ CONFIG_COMMON_BAROMETERS=n
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=n
CONFIG_COMMON_DISTANCE_SENSOR=n
CONFIG_COMMON_HYGROMETERS=n
+CONFIG_COMMON_OSD=n
+CONFIG_COMMON_RC=n
CONFIG_COMMON_TELEMETRY=n
CONFIG_DRIVERS_ADC_ADS1115=n
CONFIG_DRIVERS_BATT_SMBUS=n
@@ -35,7 +37,6 @@ CONFIG_MODULES_TEMPERATURE_COMPENSATION=n
CONFIG_MODULES_UUV_ATT_CONTROL=n
CONFIG_MODULES_UUV_POS_CONTROL=n
CONFIG_SYSTEMCMDS_REFLECT=n
-CONFIG_SYSTEMCMDS_SERIAL_TEST=n
CONFIG_BOARD_CONSTRAINED_FLASH=y
CONFIG_BOARD_TESTING=y
CONFIG_DRIVERS_BAROMETER_MS5611=y
diff --git a/boards/px4/fmu-v5/test.px4board b/boards/px4/fmu-v5/test.px4board
index 6dad087c1c..2dcd6925f2 100644
--- a/boards/px4/fmu-v5/test.px4board
+++ b/boards/px4/fmu-v5/test.px4board
@@ -1,7 +1,14 @@
+# CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE is not set
+CONFIG_COMMON_HYGROMETERS=n
+CONFIG_COMMON_OSD=n
CONFIG_DRIVERS_ADC_ADS1115=n
+CONFIG_DRIVERS_BATT_SMBUS=n
+CONFIG_DRIVERS_CAMERA_CAPTURE=n
+CONFIG_DRIVERS_CAMERA_TRIGGER=n
CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16448=n
CONFIG_DRIVERS_IRLOCK=n
CONFIG_DRIVERS_PCA9685_PWM_OUT=n
+CONFIG_DRIVERS_UAVCAN=n
CONFIG_EXAMPLES_FAKE_GPS=n
CONFIG_MODULES_ATTITUDE_ESTIMATOR_Q=n
CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n
@@ -11,3 +18,5 @@ CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=n
CONFIG_BOARD_TESTING=y
CONFIG_DRIVERS_TEST_PPM=y
CONFIG_SYSTEMCMDS_MICROBENCH=y
+CONFIG_SYSTEMCMDS_SD_STRESS=y
+CONFIG_SYSTEMCMDS_SERIAL_TEST=y
diff --git a/boards/px4/fmu-v5/uavcanv0periph.px4board b/boards/px4/fmu-v5/uavcanv0periph.px4board
index 70e35abd44..c9e9823c03 100644
--- a/boards/px4/fmu-v5/uavcanv0periph.px4board
+++ b/boards/px4/fmu-v5/uavcanv0periph.px4board
@@ -32,8 +32,6 @@ CONFIG_SYSTEMCMDS_I2CDETECT=n
CONFIG_SYSTEMCMDS_LED_CONTROL=n
CONFIG_SYSTEMCMDS_REFLECT=n
CONFIG_SYSTEMCMDS_SD_BENCH=n
-CONFIG_SYSTEMCMDS_SD_STRESS=n
-CONFIG_SYSTEMCMDS_SERIAL_TEST=n
CONFIG_SYSTEMCMDS_SYSTEM_TIME=n
CONFIG_SYSTEMCMDS_TOPIC_LISTENER=n
CONFIG_BOARD_UAVCAN_PERIPHERALS="cuav_can-gps-v1_default"
diff --git a/boards/px4/fmu-v5x/cmake/upload.cmake b/boards/px4/fmu-v5x/cmake/upload.cmake
new file mode 100644
index 0000000000..e5c23c3e1c
--- /dev/null
+++ b/boards/px4/fmu-v5x/cmake/upload.cmake
@@ -0,0 +1,49 @@
+############################################################################
+#
+# Copyright (c) 2020 PX4 Development Team. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name PX4 nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+
+set(PX4_FW_NAME ${PX4_BINARY_DIR}/${PX4_BOARD_VENDOR}_${PX4_BOARD_MODEL}_${PX4_BOARD_LABEL}.px4)
+
+add_custom_target(upload_skynode_usb
+ COMMAND ${PX4_SOURCE_DIR}/Tools/auterion/upload_skynode.sh --file=${PX4_FW_NAME}
+ DEPENDS ${PX4_FW_NAME}
+ COMMENT "Uploading PX4"
+ USES_TERMINAL
+)
+
+add_custom_target(upload_skynode_wifi
+ COMMAND ${PX4_SOURCE_DIR}/Tools/auterion/upload_skynode.sh --file=${PX4_FW_NAME} --wifi
+ DEPENDS ${PX4_FW_NAME}
+ COMMENT "Uploading PX4"
+ USES_TERMINAL
+)
diff --git a/boards/px4/fmu-v5x/default.px4board b/boards/px4/fmu-v5x/default.px4board
index 5c662fbca8..8ba73bcdcc 100644
--- a/boards/px4/fmu-v5x/default.px4board
+++ b/boards/px4/fmu-v5x/default.px4board
@@ -17,6 +17,7 @@ CONFIG_DRIVERS_CAMERA_TRIGGER=y
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
CONFIG_COMMON_DISTANCE_SENSOR=y
CONFIG_DRIVERS_DSHOT=y
+CONFIG_DRIVERS_GPIO_MCP23009=y
CONFIG_DRIVERS_GPS=y
CONFIG_DRIVERS_HEATER=y
CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16448=y
@@ -36,6 +37,7 @@ CONFIG_COMMON_OSD=y
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
CONFIG_DRIVERS_POWER_MONITOR_INA228=y
CONFIG_DRIVERS_POWER_MONITOR_INA238=y
+CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y
CONFIG_DRIVERS_PWM_OUT=y
CONFIG_DRIVERS_PX4IO=y
CONFIG_COMMON_RC=y
@@ -82,6 +84,7 @@ CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y
CONFIG_MODULES_TEMPERATURE_COMPENSATION=y
CONFIG_MODULES_UXRCE_DDS_CLIENT=y
CONFIG_MODULES_VTOL_ATT_CONTROL=y
+CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y
CONFIG_SYSTEMCMDS_BL_UPDATE=y
CONFIG_SYSTEMCMDS_BSONDUMP=y
diff --git a/boards/px4/fmu-v5x/init/rc.board_defaults b/boards/px4/fmu-v5x/init/rc.board_defaults
index ba812e4b7b..50402d17b2 100644
--- a/boards/px4/fmu-v5x/init/rc.board_defaults
+++ b/boards/px4/fmu-v5x/init/rc.board_defaults
@@ -19,3 +19,14 @@ param set-default SENS_EN_INA226 1
param set-default SYS_USE_IO 1
safety_button start
+
+# GPIO Expander driver on external I2C3
+if ver hwtypecmp V5X009000 V5X009001
+then
+ # No USB
+ mcp23009 start -b 3 -X -D 0xf0 -O 0xf0 -P 0x0f -U 10
+fi
+if ver hwtypecmp V5X00a000 V5X00a001 V5X008000 V5X008001
+then
+ mcp23009 start -b 3 -X -D 0xf1 -O 0xf0 -P 0x0f -U 10
+fi
diff --git a/boards/px4/fmu-v5x/init/rc.board_mavlink b/boards/px4/fmu-v5x/init/rc.board_mavlink
index dad84376ce..ae59f79dff 100644
--- a/boards/px4/fmu-v5x/init/rc.board_mavlink
+++ b/boards/px4/fmu-v5x/init/rc.board_mavlink
@@ -7,4 +7,7 @@ if ver hwtypecmp V5X009000 V5X009001 V5X00a000 V5X00a001 V5X008000 V5X008001 V5X
then
# Start MAVLink on the UART connected to the mission computer
mavlink start -d /dev/ttyS4 -b 3000000 -r 290000 -m onboard_low_bandwidth -x -z
+
+ # Ensure nothing else starts on TEL2 (ttyS4)
+ set PRT_TEL2_ 1
fi
diff --git a/boards/px4/fmu-v5x/init/rc.board_sensors b/boards/px4/fmu-v5x/init/rc.board_sensors
index 4f7c1d078d..d6b91f4505 100644
--- a/boards/px4/fmu-v5x/init/rc.board_sensors
+++ b/boards/px4/fmu-v5x/init/rc.board_sensors
@@ -94,6 +94,9 @@ else
# Internal magnetometer on I2c
bmm150 -I -R 6 start
+ # Auto start power monitors
+ pm_selector_auterion start
+
fi
# External compass on GPS1/I2C1 (the 3rd external bus): standard Holybro Pixhawk 4 or CUAV V5 GPS/compass puck (with lights, safety button, and buzzer)
diff --git a/boards/px4/fmu-v5x/nuttx-config/nsh/defconfig b/boards/px4/fmu-v5x/nuttx-config/nsh/defconfig
index 5de6af261f..8c21923c64 100644
--- a/boards/px4/fmu-v5x/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v5x/nuttx-config/nsh/defconfig
@@ -117,7 +117,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_IPCFG_BINARY=y
@@ -185,6 +185,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5x/nuttx-config/test/defconfig b/boards/px4/fmu-v5x/nuttx-config/test/defconfig
index 2b8361d327..12333125f9 100644
--- a/boards/px4/fmu-v5x/nuttx-config/test/defconfig
+++ b/boards/px4/fmu-v5x/nuttx-config/test/defconfig
@@ -116,7 +116,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_IPCFG_BINARY=y
@@ -183,6 +183,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v5x/src/board_config.h b/boards/px4/fmu-v5x/src/board_config.h
index 281c769f26..67cac1acd3 100644
--- a/boards/px4/fmu-v5x/src/board_config.h
+++ b/boards/px4/fmu-v5x/src/board_config.h
@@ -250,8 +250,8 @@
#define GPIO_VDD_3V3_SD_CARD_EN /* PC13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN13)
/* MCP23009 GPIO expander */
-#define BOARD_GPIO_VDD_5V_COMP_VALID "/dev/gpin4"
-#define BOARD_GPIO_VDD_5V_CAN1_GPS1_VALID "/dev/gpin5"
+#define BOARD_GPIO_VDD_5V_COMP_VALID "/dev/gpio4"
+#define BOARD_GPIO_VDD_5V_CAN1_GPS1_VALID "/dev/gpio5"
/* Spare GPIO */
diff --git a/boards/px4/fmu-v5x/src/init.cpp b/boards/px4/fmu-v5x/src/init.cpp
index a6606761db..5987f66ffa 100644
--- a/boards/px4/fmu-v5x/src/init.cpp
+++ b/boards/px4/fmu-v5x/src/init.cpp
@@ -264,8 +264,9 @@ __EXPORT int board_app_initialize(uintptr_t arg)
led_on(LED_RED);
}
+ int ret;
#ifdef CONFIG_MMCSD
- int ret = stm32_sdio_initialize();
+ ret = stm32_sdio_initialize();
if (ret != OK) {
led_on(LED_RED);
@@ -274,30 +275,11 @@ __EXPORT int board_app_initialize(uintptr_t arg)
#endif /* CONFIG_MMCSD */
- int hw_version = board_get_hw_version();
+ ret = mcp23009_register_gpios(3, 0x25);
- if (hw_version == 0x9 || hw_version == 0xa) {
- static MCP23009 mcp23009{3, 0x25};
-
- // No USB
- if (hw_version == 0x9) {
- // < P8
- ret = mcp23009.init(0xf0, 0xf0, 0x0f);
- // >= P8
- //ret = mcp23009.init(0xf1, 0xf0, 0x0f);
- }
-
- if (hw_version == 0xa) {
- // < P6
- //ret = mcp23009.init(0xf0, 0xf0, 0x0f);
- // >= P6
- ret = mcp23009.init(0xf1, 0xf0, 0x0f);
- }
-
- if (ret != OK) {
- led_on(LED_RED);
- return ret;
- }
+ if (ret != OK) {
+ led_on(LED_RED);
+ return ret;
}
return OK;
diff --git a/boards/px4/fmu-v5x/src/mtd.cpp b/boards/px4/fmu-v5x/src/mtd.cpp
index fc1e97d2c8..c0139d1232 100644
--- a/boards/px4/fmu-v5x/src/mtd.cpp
+++ b/boards/px4/fmu-v5x/src/mtd.cpp
@@ -34,7 +34,7 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi5 = { // FM25V02A on FMUM 32K 512 X 64
+static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
@@ -50,18 +50,12 @@ static const px4_mft_device_t i2c4 = { // 24LC64T on IMU 8K 32 X 2
static const px4_mtd_entry_t fmum_fram = {
.device = &spi5,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/boards/px4/fmu-v5x/test.px4board b/boards/px4/fmu-v5x/test.px4board
index 87fa5f8101..278cc285a1 100644
--- a/boards/px4/fmu-v5x/test.px4board
+++ b/boards/px4/fmu-v5x/test.px4board
@@ -2,6 +2,8 @@ CONFIG_COMMON_DISTANCE_SENSOR=n
CONFIG_COMMON_INS=n
CONFIG_COMMON_TELEMETRY=n
CONFIG_DRIVERS_ADC_ADS1115=n
+CONFIG_DRIVERS_CAMERA_CAPTURE=n
+CONFIG_DRIVERS_CAMERA_TRIGGER=n
CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16448=n
CONFIG_DRIVERS_IRLOCK=n
CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n
diff --git a/boards/px4/fmu-v6c/nuttx-config/bootloader/defconfig b/boards/px4/fmu-v6c/nuttx-config/bootloader/defconfig
index d3a1497dd5..a5269376c6 100644
--- a/boards/px4/fmu-v6c/nuttx-config/bootloader/defconfig
+++ b/boards/px4/fmu-v6c/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/px4/fmu-v6c/nuttx-config/nsh/defconfig b/boards/px4/fmu-v6c/nuttx-config/nsh/defconfig
index 78963cf699..9e051bd1f9 100644
--- a/boards/px4/fmu-v6c/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v6c/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_NCHAINS=24
CONFIG_LIBC_FLOATINGPOINT=y
@@ -151,6 +151,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v6c/src/mtd.cpp b/boards/px4/fmu-v6c/src/mtd.cpp
index b315ff399d..5efe7bac64 100644
--- a/boards/px4/fmu-v6c/src/mtd.cpp
+++ b/boards/px4/fmu-v6c/src/mtd.cpp
@@ -34,7 +34,7 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi2 = { // FM25V02A on FMUM 32K 512 X 64
+static const px4_mft_device_t spi2 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
@@ -47,18 +47,12 @@ static const px4_mft_device_t i2c4 = { // 24LC64T on IMU 8K 32 X 2
static const px4_mtd_entry_t fmum_fram = {
.device = &spi2,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/boards/px4/fmu-v6u/nuttx-config/bootloader/defconfig b/boards/px4/fmu-v6u/nuttx-config/bootloader/defconfig
index 745b587413..0ca6729cfa 100644
--- a/boards/px4/fmu-v6u/nuttx-config/bootloader/defconfig
+++ b/boards/px4/fmu-v6u/nuttx-config/bootloader/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/px4/fmu-v6u/nuttx-config/nsh/defconfig b/boards/px4/fmu-v6u/nuttx-config/nsh/defconfig
index f716ae6932..40513352ae 100644
--- a/boards/px4/fmu-v6u/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v6u/nuttx-config/nsh/defconfig
@@ -112,7 +112,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_NCHAINS=24
CONFIG_LIBC_FLOATINGPOINT=y
@@ -151,6 +151,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/px4/fmu-v6u/src/mtd.cpp b/boards/px4/fmu-v6u/src/mtd.cpp
index 644b96581d..48a5bd334c 100644
--- a/boards/px4/fmu-v6u/src/mtd.cpp
+++ b/boards/px4/fmu-v6u/src/mtd.cpp
@@ -34,25 +34,19 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi5 = { // FM25V02A on FMUM 32K 512 X 64
+static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
static const px4_mtd_entry_t fmum_fram = {
.device = &spi5,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/boards/px4/fmu-v6x/cmake/upload.cmake b/boards/px4/fmu-v6x/cmake/upload.cmake
new file mode 100644
index 0000000000..7319b46df3
--- /dev/null
+++ b/boards/px4/fmu-v6x/cmake/upload.cmake
@@ -0,0 +1,49 @@
+############################################################################
+#
+# Copyright (c) 2023 PX4 Development Team. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name PX4 nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+
+set(PX4_FW_NAME ${PX4_BINARY_DIR}/${PX4_BOARD_VENDOR}_${PX4_BOARD_MODEL}_${PX4_BOARD_LABEL}.px4)
+
+add_custom_target(upload_skynode_usb
+ COMMAND ${PX4_SOURCE_DIR}/Tools/auterion/upload_skynode.sh --file=${PX4_FW_NAME}
+ DEPENDS ${PX4_FW_NAME}
+ COMMENT "Uploading PX4"
+ USES_TERMINAL
+)
+
+add_custom_target(upload_skynode_wifi
+ COMMAND ${PX4_SOURCE_DIR}/Tools/auterion/upload_skynode.sh --file=${PX4_FW_NAME} --wifi
+ DEPENDS ${PX4_FW_NAME}
+ COMMENT "Uploading PX4"
+ USES_TERMINAL
+)
diff --git a/boards/px4/fmu-v6x/default.px4board b/boards/px4/fmu-v6x/default.px4board
index ba22d9296c..9dc9d9a444 100644
--- a/boards/px4/fmu-v6x/default.px4board
+++ b/boards/px4/fmu-v6x/default.px4board
@@ -7,11 +7,11 @@ CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS6"
CONFIG_BOARD_SERIAL_TEL2="/dev/ttyS4"
CONFIG_BOARD_SERIAL_TEL3="/dev/ttyS1"
CONFIG_BOARD_SERIAL_EXT2="/dev/ttyS3"
+CONFIG_DRIVERS_ADC_ADS1115=y
CONFIG_DRIVERS_ADC_BOARD_ADC=y
CONFIG_DRIVERS_BAROMETER_BMP388=y
CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP201XX=y
CONFIG_DRIVERS_BAROMETER_MS5611=y
-CONFIG_DRIVERS_BATT_SMBUS=y
CONFIG_DRIVERS_CAMERA_CAPTURE=y
CONFIG_DRIVERS_CAMERA_TRIGGER=y
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
@@ -19,20 +19,23 @@ CONFIG_COMMON_DISTANCE_SENSOR=y
CONFIG_DRIVERS_DSHOT=y
CONFIG_DRIVERS_GPS=y
CONFIG_DRIVERS_HEATER=y
+CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16470=y
CONFIG_DRIVERS_IMU_BOSCH_BMI088=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20602=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20649=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42670P=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y
+CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y
+CONFIG_DRIVERS_IMU_INVENSENSE_IIM42652=y
CONFIG_COMMON_INS=y
CONFIG_COMMON_LIGHT=y
CONFIG_COMMON_MAGNETOMETER=y
-CONFIG_COMMON_OPTICAL_FLOW=y
CONFIG_COMMON_OSD=y
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
CONFIG_DRIVERS_POWER_MONITOR_INA228=y
CONFIG_DRIVERS_POWER_MONITOR_INA238=y
+CONFIG_DRIVERS_POWER_MONITOR_PM_SELECTOR_AUTERION=y
CONFIG_DRIVERS_PWM_OUT=y
CONFIG_DRIVERS_PX4IO=y
CONFIG_DRIVERS_RC_INPUT=y
@@ -41,6 +44,7 @@ CONFIG_DRIVERS_TONE_ALARM=y
CONFIG_DRIVERS_UAVCAN=y
CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2
CONFIG_MODULES_AIRSPEED_SELECTOR=y
+CONFIG_MODULES_BATTERY_STATUS=y
CONFIG_MODULES_CAMERA_FEEDBACK=y
CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
diff --git a/boards/px4/fmu-v6x/init/rc.board_mavlink b/boards/px4/fmu-v6x/init/rc.board_mavlink
new file mode 100644
index 0000000000..6001553a76
--- /dev/null
+++ b/boards/px4/fmu-v6x/init/rc.board_mavlink
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# PX4 FMUv6X specific board MAVLink startup script.
+#------------------------------------------------------------------------------
+
+# if skynode base board is detected start Mavlink on Telem2
+if ver hwtypecmp V6X009010 V6X010010
+then
+ mavlink start -d /dev/ttyS4 -b 3000000 -r 290000 -m onboard_low_bandwidth -x -z
+
+ # Ensure nothing else starts on TEL2 (ttyS4)
+ set PRT_TEL2_ 1
+fi
diff --git a/boards/px4/fmu-v6x/init/rc.board_sensors b/boards/px4/fmu-v6x/init/rc.board_sensors
index 52aa8f9c78..5155fcf96c 100644
--- a/boards/px4/fmu-v6x/init/rc.board_sensors
+++ b/boards/px4/fmu-v6x/init/rc.board_sensors
@@ -47,25 +47,38 @@ then
fi
fi
-
-if ver hwtypecmp V6X000004 V6X001004 V6X004004 V6X005004
+#Start Auterion Power Module selector for Skynode boards
+if ver hwtypecmp V6X009010 V6X010010
then
- # Internal SPI bus ICM20649
- icm20649 -s -R 6 start
+ pm_selector_auterion start
+fi
+
+if ver hwtypecmp V6X000006 V6X004006 V6X005006
+then
+ # Internal SPI bus ICM45686
+ icm45686 -s -R 10 start
+ iim42652 -s -R 6 start
+ adis16470 -s -R 0 start
else
- # Internal SPI BMI088
- if ver hwtypecmp V6X009010 V6X010010
+ if ver hwtypecmp V6X000004 V6X001004 V6X004004 V6X005004
then
- bmi088 -A -R 6 -s start
- bmi088 -G -R 6 -s start
+ # Internal SPI bus ICM20649
+ icm20649 -s -R 6 start
else
- if ver hwtypecmp V6X000010
+ # Internal SPI BMI088
+ if ver hwtypecmp V6X009010 V6X010010
then
- bmi088 -A -R 0 -s start
- bmi088 -G -R 0 -s start
+ bmi088 -A -R 6 -s start
+ bmi088 -G -R 6 -s start
else
- bmi088 -A -R 4 -s start
- bmi088 -G -R 4 -s start
+ if ver hwtypecmp V6X000010
+ then
+ bmi088 -A -R 0 -s start
+ bmi088 -G -R 0 -s start
+ else
+ bmi088 -A -R 4 -s start
+ bmi088 -G -R 4 -s start
+ fi
fi
fi
fi
@@ -102,13 +115,8 @@ if ver hwtypecmp V6X002001
then
rm3100 -I -b 4 start
else
- if ver hwtypecmp V6X009010 V6X010010
- then
- # Internal magnetometer on I2C
- bmm150 -I -R 0 start
- else
- bmm150 -I -R 6 start
- fi
+ # Internal magnetometer on I2C
+ bmm150 -I -R 0 start
fi
# External compass on GPS1/I2C1 (the 3rd external bus): standard Holybro Pixhawk 4 or CUAV V5 GPS/compass puck (with lights, safety button, and buzzer)
@@ -117,7 +125,7 @@ ist8310 -X -b 1 -R 10 start
# Possible internal Baro
if param compare SENS_INT_BARO_EN 1
then
- if ver hwtypecmp V6X002001
+ if ver hwtypecmp V6X002001 V6X000006 V6X004006 V6X005006
then
icp201xx -I -a 0x64 start
else
diff --git a/boards/px4/fmu-v6x/nuttx-config/bootloader/defconfig b/boards/px4/fmu-v6x/nuttx-config/bootloader/defconfig
index c2069035c5..41dc164e0a 100644
--- a/boards/px4/fmu-v6x/nuttx-config/bootloader/defconfig
+++ b/boards/px4/fmu-v6x/nuttx-config/bootloader/defconfig
@@ -49,7 +49,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="bootloader_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_STRERROR=y
diff --git a/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig b/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig
index a38915d99f..e5f02a46a7 100644
--- a/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig
+++ b/boards/px4/fmu-v6x/nuttx-config/nsh/defconfig
@@ -118,7 +118,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_IPCFG_BINARY=y
@@ -189,6 +189,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
@@ -291,7 +293,6 @@ CONFIG_UART4_RXBUFSIZE=600
CONFIG_UART4_TXBUFSIZE=1500
CONFIG_UART5_IFLOWCONTROL=y
CONFIG_UART5_OFLOWCONTROL=y
-CONFIG_UART7_RXBUFSIZE=1500
CONFIG_UART5_RXDMA=y
CONFIG_UART5_TXBUFSIZE=10000
CONFIG_UART5_TXDMA=y
diff --git a/boards/px4/fmu-v6x/src/board_config.h b/boards/px4/fmu-v6x/src/board_config.h
index fecd7efc9c..ff0676fab7 100644
--- a/boards/px4/fmu-v6x/src/board_config.h
+++ b/boards/px4/fmu-v6x/src/board_config.h
@@ -215,24 +215,28 @@
#define GPIO_HW_VER_SENSE /* PH3 */ GPIO_ADC3_INP14
#define HW_INFO_INIT_PREFIX "V6X"
-#define BOARD_NUM_SPI_CFG_HW_VERSIONS 11 // Rev 0 and Rev 3,4 Sensor sets
+#define BOARD_NUM_SPI_CFG_HW_VERSIONS 13 // Rev 0 and Rev 3,4,6 Sensor sets
// Base/FMUM
#define V6X00 HW_VER_REV(0x0,0x0) // FMUV6X, Rev 0
#define V6X01 HW_VER_REV(0x0,0x1) // FMUV6X, BMI388 I2C2 Rev 1
#define V6X03 HW_VER_REV(0x0,0x3) // FMUV6X, Sensor Set Rev 3
#define V6X04 HW_VER_REV(0x0,0x4) // FMUV6X, Sensor Set Rev 4
+#define V6X06 HW_VER_REV(0x0,0x6) // FMUV6X, Sensor Set Rev 6
#define V6X10 HW_VER_REV(0x1,0x0) // NO PX4IO, Rev 0
#define V6X13 HW_VER_REV(0x1,0x3) // NO PX4IO, Sensor Set Rev 3
#define V6X14 HW_VER_REV(0x1,0x4) // NO PX4IO, Sensor Set Rev 4
+#define V6X16 HW_VER_REV(0x1,0x6) // NO PX4IO, Sensor Set Rev 6
#define V6X21 HW_VER_REV(0x2,0x1) // FMUV6X, CUAV Sensor Set
#define V6X40 HW_VER_REV(0x4,0x0) // FMUV6X, HB CM4 base Rev 0
#define V6X41 HW_VER_REV(0x4,0x1) // FMUV6X, BMI388 I2C2 HB CM4 base Rev 1
#define V6X43 HW_VER_REV(0x4,0x3) // FMUV6X, Sensor Set HB CM4 base Rev 3
#define V6X44 HW_VER_REV(0x4,0x4) // FMUV6X, Sensor Set HB CM4 base Rev 4
+#define V6X46 HW_VER_REV(0x4,0x6) // FMUV6X, Sensor Set HB CM4 base Rev 6
#define V6X50 HW_VER_REV(0x5,0x0) // FMUV6X, HB Mini Rev 0
#define V6X51 HW_VER_REV(0x5,0x1) // FMUV6X, BMI388 I2C2 HB Mini Rev 1
#define V6X53 HW_VER_REV(0x5,0x3) // FMUV6X, Sensor Set HB Mini Rev 3
#define V6X54 HW_VER_REV(0x5,0x4) // FMUV6X, Sensor Set HB Mini Rev 4
+#define V6X56 HW_VER_REV(0x5,0x6) // FMUV6X, Sensor Set HB Mini Rev 6
#define V6X90 HW_VER_REV(0x9,0x0) // Rev 0
#define V6X0910 HW_VER_REV(0x9,0x10) // FMUV6X, rev from EEPROM Auterion Skynode ver9
#define V6X1010 HW_VER_REV(0x10,0x10) // FMUV6X, rev from EEPROM Auterion Skynode ver10
diff --git a/boards/px4/fmu-v6x/src/manifest.c b/boards/px4/fmu-v6x/src/manifest.c
index 313d49f9bf..bda800b749 100644
--- a/boards/px4/fmu-v6x/src/manifest.c
+++ b/boards/px4/fmu-v6x/src/manifest.c
@@ -142,17 +142,20 @@ static px4_hw_mft_list_entry_t mft_lists[] = {
{V6X00, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)},
{V6X01, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2
{V6X03, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, Sensor Set 3
+ {V6X04, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, Sensor Set 4
+ {V6X06, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, Sensor Set 6
{V6X40, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // HB CM4 base
{V6X41, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2 HB CM4 base
{V6X43, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, HB CM4 base Sensor Set 3
{V6X44, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, HB CM4 base Sensor Set 4
+ {V6X46, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, Sensor Set 6
{V6X50, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // HB Mini
{V6X51, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // BMP388 moved to I2C2 HB Mini
{V6X53, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // BMP388 moved to I2C2, HB Mini Sensor Set 3
{V6X54, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // BMP388 moved to I2C2, HB Mini Sensor Set 4
+ {V6X56, hw_mft_list_v0650, arraySize(hw_mft_list_v0650)}, // BMP388 moved to I2C2, HB Mini Sensor Set 6
{V6X10, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // No PX4IO
{V6X13, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // No PX4IO BMP388 moved to I2C2, Sensor Set 3
- {V6X04, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // BMP388 moved to I2C2, Sensor Set 4
{V6X14, hw_mft_list_v0610, arraySize(hw_mft_list_v0610)}, // No PX4IO BMP388 moved to I2C2, Sensor Set 4
{V6X21, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)},
{V6X0910, hw_mft_list_v0600, arraySize(hw_mft_list_v0600)}, // FMUV6X, rev from EEPROM Auterion Skynode ver9
diff --git a/boards/px4/fmu-v6x/src/mtd.cpp b/boards/px4/fmu-v6x/src/mtd.cpp
index fc1e97d2c8..c0139d1232 100644
--- a/boards/px4/fmu-v6x/src/mtd.cpp
+++ b/boards/px4/fmu-v6x/src/mtd.cpp
@@ -34,7 +34,7 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi5 = { // FM25V02A on FMUM 32K 512 X 64
+static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
@@ -50,18 +50,12 @@ static const px4_mft_device_t i2c4 = { // 24LC64T on IMU 8K 32 X 2
static const px4_mtd_entry_t fmum_fram = {
.device = &spi5,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/boards/px4/fmu-v6x/src/spi.cpp b/boards/px4/fmu-v6x/src/spi.cpp
index d3bbdb9315..8b002e157e 100644
--- a/boards/px4/fmu-v6x/src/spi.cpp
+++ b/boards/px4/fmu-v6x/src/spi.cpp
@@ -84,6 +84,29 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}),
}),
+ initSPIHWVersion(V6X06, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM45686, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42652, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ADIS16470, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
initSPIHWVersion(V6X21, {
initSPIBus(SPI::Bus::SPI1, {
initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
@@ -132,6 +155,52 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}),
}),
+ initSPIHWVersion(V6X44, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM42670P, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
+ initSPIHWVersion(V6X46, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM45686, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42652, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ADIS16470, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
initSPIHWVersion(V6X50, {
initSPIBus(SPI::Bus::SPI1, {
initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
@@ -156,75 +225,6 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}),
}),
- initSPIHWVersion(V6X44, {
- initSPIBus(SPI::Bus::SPI1, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM42670P, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
- }, {GPIO::PortI, GPIO::Pin11}),
- initSPIBus(SPI::Bus::SPI2, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
- }, {GPIO::PortF, GPIO::Pin4}),
- initSPIBus(SPI::Bus::SPI3, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
- }, {GPIO::PortE, GPIO::Pin7}),
- // initSPIBus(SPI::Bus::SPI4, {
- // // no devices
- // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
- // }, {GPIO::PortG, GPIO::Pin8}),
- initSPIBus(SPI::Bus::SPI5, {
- initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
- }),
- initSPIBusExternal(SPI::Bus::SPI6, {
- initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
- initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
- }),
- }),
-
- // never shipped
- //initSPIHWVersion(V6X50, {
- // initSPIBus(SPI::Bus::SPI1, {
- // initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
- // }, {GPIO::PortI, GPIO::Pin11}),
- // initSPIBus(SPI::Bus::SPI2, {
- // initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
- // }, {GPIO::PortF, GPIO::Pin4}),
- // initSPIBus(SPI::Bus::SPI3, {
- // initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin8}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
- // initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin6}),
- // }, {GPIO::PortE, GPIO::Pin7}),
- // // initSPIBus(SPI::Bus::SPI4, {
- // // // no devices
- // // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
- // // }, {GPIO::PortG, GPIO::Pin8}),
- // initSPIBus(SPI::Bus::SPI5, {
- // initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
- // }),
- // initSPIBusExternal(SPI::Bus::SPI6, {
- // initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
- // initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
- // }),
- //}),
- initSPIHWVersion(V6X04, {
- initSPIBus(SPI::Bus::SPI1, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM42670P, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
- }, {GPIO::PortI, GPIO::Pin11}),
- initSPIBus(SPI::Bus::SPI2, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
- }, {GPIO::PortF, GPIO::Pin4}),
- initSPIBus(SPI::Bus::SPI3, {
- initSPIDevice(DRV_IMU_DEVTYPE_ICM20649, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
- }, {GPIO::PortE, GPIO::Pin7}),
- // initSPIBus(SPI::Bus::SPI4, {
- // // no devices
- // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
- // }, {GPIO::PortG, GPIO::Pin8}),
- initSPIBus(SPI::Bus::SPI5, {
- initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
- }),
- initSPIBusExternal(SPI::Bus::SPI6, {
- initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
- initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
- }),
- }),
initSPIHWVersion(V6X53, {
initSPIBus(SPI::Bus::SPI1, {
initSPIDevice(DRV_IMU_DEVTYPE_ICM42670P, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
@@ -248,6 +248,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
}),
}),
+
initSPIHWVersion(V6X54, {
initSPIBus(SPI::Bus::SPI1, {
initSPIDevice(DRV_IMU_DEVTYPE_ICM42670P, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
@@ -270,6 +271,30 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
}),
}),
+
+ initSPIHWVersion(V6X56, {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM45686, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
+ }, {GPIO::PortI, GPIO::Pin11}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(DRV_IMU_DEVTYPE_IIM42652, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
+ }, {GPIO::PortF, GPIO::Pin4}),
+ initSPIBus(SPI::Bus::SPI3, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ADIS16470, SPI::CS{GPIO::PortI, GPIO::Pin4}, SPI::DRDY{GPIO::PortI, GPIO::Pin7}),
+ }, {GPIO::PortE, GPIO::Pin7}),
+ // initSPIBus(SPI::Bus::SPI4, {
+ // // no devices
+ // TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
+ // }, {GPIO::PortG, GPIO::Pin8}),
+ initSPIBus(SPI::Bus::SPI5, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+ }),
+ initSPIBusExternal(SPI::Bus::SPI6, {
+ initSPIConfigExternal(SPI::CS{GPIO::PortI, GPIO::Pin10}, SPI::DRDY{GPIO::PortD, GPIO::Pin11}),
+ initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
+ }),
+ }),
+
initSPIHWVersion(V6X0910, {
initSPIBus(SPI::Bus::SPI1, {
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
@@ -293,6 +318,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
initSPIConfigExternal(SPI::CS{GPIO::PortA, GPIO::Pin15}, SPI::DRDY{GPIO::PortD, GPIO::Pin12}),
}),
}),
+
initSPIHWVersion(V6X1010, {
initSPIBus(SPI::Bus::SPI1, {
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
diff --git a/boards/px4/raspberrypi/cmake/upload.cmake b/boards/px4/raspberrypi/cmake/upload.cmake
index c77e80cd2e..5abefb01e6 100644
--- a/boards/px4/raspberrypi/cmake/upload.cmake
+++ b/boards/px4/raspberrypi/cmake/upload.cmake
@@ -38,7 +38,7 @@ else()
endif()
add_custom_target(upload
- COMMAND rsync -arh --progress
+ COMMAND rsync -arh --progress -e "ssh -o StrictHostKeyChecking=no"
${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${PX4_SOURCE_DIR}/posix-configs/rpi/*.config ${PX4_BINARY_DIR}/etc # source
pi@${AUTOPILOT_HOST}:/home/pi/px4 # destination
DEPENDS px4
diff --git a/boards/px4/raspberrypi/default.px4board b/boards/px4/raspberrypi/default.px4board
index 3e059cffe7..ade7dd4235 100644
--- a/boards/px4/raspberrypi/default.px4board
+++ b/boards/px4/raspberrypi/default.px4board
@@ -4,15 +4,15 @@ CONFIG_BOARD_TOOLCHAIN="arm-linux-gnueabihf"
CONFIG_BOARD_ARCHITECTURE="cortex-a53"
CONFIG_BOARD_TESTING=y
CONFIG_DRIVERS_ADC_ADS1115=y
-CONFIG_DRIVERS_BAROMETER_MS5611=y
+CONFIG_COMMON_BAROMETERS=y
CONFIG_DRIVERS_BATT_SMBUS=y
CONFIG_DRIVERS_CAMERA_TRIGGER=y
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
CONFIG_COMMON_DISTANCE_SENSOR=y
CONFIG_DRIVERS_GPS=y
+CONFIG_COMMON_IMU=y
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y
-CONFIG_DRIVERS_IMU_INVENSENSE_MPU9250=y
-CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y
+CONFIG_COMMON_MAGNETOMETER=y
CONFIG_DRIVERS_PCA9685_PWM_OUT=y
CONFIG_DRIVERS_RC_INPUT=y
CONFIG_DRIVERS_RPI_RC_IN=y
diff --git a/boards/px4/sitl/default.px4board b/boards/px4/sitl/default.px4board
index db358c3e4d..fa7276f76e 100644
--- a/boards/px4/sitl/default.px4board
+++ b/boards/px4/sitl/default.px4board
@@ -49,6 +49,7 @@ CONFIG_MODULES_UUV_ATT_CONTROL=y
CONFIG_MODULES_UUV_POS_CONTROL=y
CONFIG_MODULES_UXRCE_DDS_CLIENT=y
CONFIG_MODULES_VTOL_ATT_CONTROL=y
+CONFIG_MODE_NAVIGATOR_VTOL_TAKEOFF=y
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y
CONFIG_SYSTEMCMDS_BSONDUMP=y
CONFIG_SYSTEMCMDS_DYN=y
diff --git a/boards/raspberrypi/pico/init/rc.board_defaults b/boards/raspberrypi/pico/init/rc.board_defaults
index ec0c720608..f1a26f4a51 100644
--- a/boards/raspberrypi/pico/init/rc.board_defaults
+++ b/boards/raspberrypi/pico/init/rc.board_defaults
@@ -12,10 +12,3 @@ param set-default CBRK_SUPPLY_CHK 894281
# Disable safety switch by default
param set-default CBRK_IO_SAFETY 22027
-# use the Q attitude estimator, it works w/o mag or GPS.
-# param set-default SYS_MC_EST_GROUP 3
-# param set-default ATT_ACC_COMP 0
-# param set-default ATT_W_ACC 0.4000
-# param set-default ATT_W_GYRO_BIAS 0.0000
-
-# param set-default SYS_HAS_MAG 0
diff --git a/boards/raspberrypi/pico/nuttx-config/nsh/defconfig b/boards/raspberrypi/pico/nuttx-config/nsh/defconfig
index 2efb22fc35..ebce067020 100644
--- a/boards/raspberrypi/pico/nuttx-config/nsh/defconfig
+++ b/boards/raspberrypi/pico/nuttx-config/nsh/defconfig
@@ -48,7 +48,7 @@ CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
diff --git a/boards/siyi/n7/bootloader.px4board b/boards/siyi/n7/bootloader.px4board
new file mode 100644
index 0000000000..19b6e662be
--- /dev/null
+++ b/boards/siyi/n7/bootloader.px4board
@@ -0,0 +1,3 @@
+CONFIG_BOARD_TOOLCHAIN="arm-none-eabi"
+CONFIG_BOARD_ARCHITECTURE="cortex-m7"
+CONFIG_BOARD_ROMFSROOT=""
diff --git a/boards/siyi/n7/default.px4board b/boards/siyi/n7/default.px4board
new file mode 100644
index 0000000000..cb42f3530c
--- /dev/null
+++ b/boards/siyi/n7/default.px4board
@@ -0,0 +1,86 @@
+CONFIG_BOARD_TOOLCHAIN="arm-none-eabi"
+CONFIG_BOARD_ARCHITECTURE="cortex-m7"
+CONFIG_BOARD_SERIAL_GPS1="/dev/ttyS0"
+CONFIG_BOARD_SERIAL_TEL1="/dev/ttyS1"
+CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS2"
+CONFIG_DRIVERS_ADC_BOARD_ADC=y
+CONFIG_COMMON_BAROMETERS=y
+CONFIG_DRIVERS_BATT_SMBUS=y
+CONFIG_DRIVERS_CAMERA_CAPTURE=y
+CONFIG_DRIVERS_CAMERA_TRIGGER=y
+CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
+CONFIG_COMMON_DISTANCE_SENSOR=y
+CONFIG_DRIVERS_DSHOT=y
+CONFIG_DRIVERS_GPS=y
+CONFIG_DRIVERS_HEATER=y
+CONFIG_DRIVERS_IMU_BOSCH_BMI088=y
+CONFIG_DRIVERS_IMU_INVENSENSE_ICM20689=y
+CONFIG_COMMON_LIGHT=y
+CONFIG_COMMON_MAGNETOMETER=y
+CONFIG_COMMON_OPTICAL_FLOW=y
+CONFIG_DRIVERS_POWER_MONITOR_INA226=y
+CONFIG_DRIVERS_PWM_OUT=y
+CONFIG_DRIVERS_PX4IO=y
+CONFIG_DRIVERS_SMART_BATTERY_BATMON=y
+CONFIG_COMMON_TELEMETRY=y
+CONFIG_DRIVERS_TONE_ALARM=y
+CONFIG_DRIVERS_UAVCAN=y
+CONFIG_MODULES_AIRSPEED_SELECTOR=y
+CONFIG_MODULES_BATTERY_STATUS=y
+CONFIG_MODULES_CAMERA_FEEDBACK=y
+CONFIG_MODULES_COMMANDER=y
+CONFIG_MODULES_CONTROL_ALLOCATOR=y
+CONFIG_MODULES_DATAMAN=y
+CONFIG_MODULES_EKF2=y
+CONFIG_MODULES_ESC_BATTERY=y
+CONFIG_MODULES_EVENTS=y
+CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
+CONFIG_MODULES_FW_ATT_CONTROL=y
+CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=y
+CONFIG_MODULES_FW_POS_CONTROL=y
+CONFIG_MODULES_FW_RATE_CONTROL=y
+CONFIG_MODULES_GIMBAL=y
+CONFIG_MODULES_GYRO_CALIBRATION=y
+CONFIG_MODULES_LAND_DETECTOR=y
+CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y
+CONFIG_MODULES_LOAD_MON=y
+CONFIG_MODULES_LOGGER=y
+CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
+CONFIG_MODULES_MANUAL_CONTROL=y
+CONFIG_MODULES_MAVLINK=y
+CONFIG_MODULES_MC_ATT_CONTROL=y
+CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y
+CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y
+CONFIG_MODULES_MC_POS_CONTROL=y
+CONFIG_MODULES_MC_RATE_CONTROL=y
+CONFIG_MODULES_NAVIGATOR=y
+CONFIG_MODULES_RC_UPDATE=y
+CONFIG_MODULES_ROVER_POS_CONTROL=y
+CONFIG_MODULES_SENSORS=y
+CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=y
+CONFIG_MODULES_TEMPERATURE_COMPENSATION=y
+CONFIG_MODULES_UXRCE_DDS_CLIENT=y
+CONFIG_MODULES_VTOL_ATT_CONTROL=y
+CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y
+CONFIG_SYSTEMCMDS_BSONDUMP=y
+CONFIG_SYSTEMCMDS_DMESG=y
+CONFIG_SYSTEMCMDS_GPIO=y
+CONFIG_SYSTEMCMDS_HARDFAULT_LOG=y
+CONFIG_SYSTEMCMDS_I2CDETECT=y
+CONFIG_SYSTEMCMDS_LED_CONTROL=y
+CONFIG_SYSTEMCMDS_MFT=y
+CONFIG_SYSTEMCMDS_MTD=y
+CONFIG_SYSTEMCMDS_NSHTERM=y
+CONFIG_SYSTEMCMDS_PARAM=y
+CONFIG_SYSTEMCMDS_PERF=y
+CONFIG_SYSTEMCMDS_REBOOT=y
+CONFIG_SYSTEMCMDS_SD_BENCH=y
+CONFIG_SYSTEMCMDS_SD_STRESS=y
+CONFIG_SYSTEMCMDS_SYSTEM_TIME=y
+CONFIG_SYSTEMCMDS_TOP=y
+CONFIG_SYSTEMCMDS_TOPIC_LISTENER=y
+CONFIG_SYSTEMCMDS_TUNE_CONTROL=y
+CONFIG_SYSTEMCMDS_UORB=y
+CONFIG_SYSTEMCMDS_USB_CONNECTED=y
+CONFIG_SYSTEMCMDS_VER=y
+CONFIG_SYSTEMCMDS_WORK_QUEUE=y
diff --git a/boards/siyi/n7/extras/px4_io-v2_default.bin b/boards/siyi/n7/extras/px4_io-v2_default.bin
new file mode 100755
index 0000000000..957f0f13a1
Binary files /dev/null and b/boards/siyi/n7/extras/px4_io-v2_default.bin differ
diff --git a/boards/siyi/n7/extras/siyi_n7_bootloader.bin b/boards/siyi/n7/extras/siyi_n7_bootloader.bin
new file mode 100755
index 0000000000..6f0ff949f5
Binary files /dev/null and b/boards/siyi/n7/extras/siyi_n7_bootloader.bin differ
diff --git a/boards/siyi/n7/firmware.prototype b/boards/siyi/n7/firmware.prototype
new file mode 100644
index 0000000000..b4c1d9362a
--- /dev/null
+++ b/boards/siyi/n7/firmware.prototype
@@ -0,0 +1,13 @@
+{
+ "board_id": 1123,
+ "magic": "PX4FWv1",
+ "description": "Firmware for the N7 board",
+ "image": "",
+ "build_time": 0,
+ "summary": "N7",
+ "version": "0.1",
+ "image_size": 0,
+ "image_maxsize": 1966080,
+ "git_identity": "",
+ "board_revision": 0
+}
diff --git a/boards/siyi/n7/init/rc.board_defaults b/boards/siyi/n7/init/rc.board_defaults
new file mode 100644
index 0000000000..a7d3d20bf9
--- /dev/null
+++ b/boards/siyi/n7/init/rc.board_defaults
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# board specific defaults
+#------------------------------------------------------------------------------
+param set-default MAV_0_RATE 100000
+
+param set-default BAT1_V_DIV 18.1
+
+param set-default BAT1_A_PER_V 36.367515152
+
+# Enable IMU thermal control
+param set-default SENS_EN_THERMAL 1
+
+param set-default SYS_USE_IO 1
diff --git a/boards/siyi/n7/init/rc.board_sensors b/boards/siyi/n7/init/rc.board_sensors
new file mode 100644
index 0000000000..e790785884
--- /dev/null
+++ b/boards/siyi/n7/init/rc.board_sensors
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# board specific sensors init
+#------------------------------------------------------------------------------
+board_adc start
+
+# SPI1
+bmi088 -s -b 1 -A -R 2 start
+bmi088 -s -b 1 -G -R 2 start
+
+# SPI1
+icm20689 -s -b 1 -R 2 start
+
+# I2C1
+ist8310 -X -b 1 -R 10 -a 0xE start
+
+# I2C3
+ist8310 -I -b 3 -R 10 -a 0xE start
+
+# SPI4
+ms5611 -s -b 4 start
diff --git a/boards/siyi/n7/nuttx-config/Kconfig b/boards/siyi/n7/nuttx-config/Kconfig
new file mode 100644
index 0000000000..bb33d3cfda
--- /dev/null
+++ b/boards/siyi/n7/nuttx-config/Kconfig
@@ -0,0 +1,17 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+config BOARD_HAS_PROBES
+ bool "Board provides GPIO or other Hardware for signaling to timing analyze."
+ default y
+ ---help---
+ This board provides GPIO FMU-CH1-5, CAP1-6 as PROBE_1-11 to provide timing signals from selected drivers.
+
+config BOARD_USE_PROBES
+ bool "Enable the use the board provided FMU-CH1-5, CAP1-6 as PROBE_1-11"
+ default n
+ depends on BOARD_HAS_PROBES
+
+ ---help---
+ Select to use GPIO FMU-CH1-5, CAP1-6 to provide timing signals from selected drivers.
diff --git a/boards/siyi/n7/nuttx-config/bootloader/defconfig b/boards/siyi/n7/nuttx-config/bootloader/defconfig
new file mode 100644
index 0000000000..775acfb2a0
--- /dev/null
+++ b/boards/siyi/n7/nuttx-config/bootloader/defconfig
@@ -0,0 +1,93 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_DEV_CONSOLE is not set
+# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
+# CONFIG_SPI_EXCHANGE is not set
+# CONFIG_STM32H7_SYSCFG is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD_CUSTOM=y
+CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/siyi/n7/nuttx-config"
+CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y
+CONFIG_ARCH_BOARD_CUSTOM_NAME="px4"
+CONFIG_ARCH_CHIP="stm32h7"
+CONFIG_ARCH_CHIP_STM32H743II=y
+CONFIG_ARCH_CHIP_STM32H7=y
+CONFIG_ARCH_INTERRUPTSTACK=768
+CONFIG_ARMV7M_BASEPRI_WAR=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_MEMCPY=y
+CONFIG_ARMV7M_USEBASEPRI=y
+CONFIG_BOARDCTL=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_ASSERT_RESET_VALUE=0
+CONFIG_BOARD_INITTHREAD_PRIORITY=254
+CONFIG_BOARD_LATE_INITIALIZE=y
+CONFIG_BOARD_LOOPSPERMSEC=22114
+CONFIG_BOARD_RESET_ON_ASSERT=2
+CONFIG_CDCACM=y
+CONFIG_CDCACM_IFLOWCONTROL=y
+CONFIG_CDCACM_PRODUCTID=0x0038
+CONFIG_CDCACM_PRODUCTSTR="PX4 BL Siyi N7"
+CONFIG_CDCACM_RXBUFSIZE=600
+CONFIG_CDCACM_TXBUFSIZE=12000
+CONFIG_CDCACM_VENDORID=0x3185
+CONFIG_CDCACM_VENDORSTR="Siyi"
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEBUG_TCBINFO=y
+CONFIG_DEFAULT_SMALL=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_FDCLONE_DISABLE=y
+CONFIG_FDCLONE_STDIO=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=750
+CONFIG_INIT_ENTRYPOINT="bootloader_main"
+CONFIG_INIT_STACKSIZE=3194
+CONFIG_LIBC_FLOATINGPOINT=y
+CONFIG_LIBC_LONG_LONG=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_MEMSET_64BIT=y
+CONFIG_MEMSET_OPTSPEED=y
+CONFIG_PREALLOC_TIMERS=50
+CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAM_SIZE=245760
+CONFIG_RAM_START=0x20010000
+CONFIG_RAW_BINARY=y
+CONFIG_SERIAL_TERMIOS=y
+CONFIG_SIG_DEFAULT=y
+CONFIG_SIG_SIGALRM_ACTION=y
+CONFIG_SIG_SIGUSR1_ACTION=y
+CONFIG_SIG_SIGUSR2_ACTION=y
+CONFIG_SPI=y
+CONFIG_STACK_COLORATION=y
+CONFIG_START_DAY=30
+CONFIG_START_MONTH=11
+CONFIG_STDIO_BUFFER_SIZE=32
+CONFIG_STM32H7_BKPSRAM=y
+CONFIG_STM32H7_DMA1=y
+CONFIG_STM32H7_DMA2=y
+CONFIG_STM32H7_OTGFS=y
+CONFIG_STM32H7_PROGMEM=y
+CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y
+CONFIG_STM32H7_TIM1=y
+CONFIG_STM32H7_UART8=y
+CONFIG_SYSTEMTICK_HOOK=y
+CONFIG_SYSTEM_CDCACM=y
+CONFIG_TASK_NAME_SIZE=24
+CONFIG_TTY_SIGINT=y
+CONFIG_TTY_SIGINT_CHAR=0x03
+CONFIG_TTY_SIGTSTP=y
+CONFIG_UART8_RXBUFSIZE=512
+CONFIG_UART8_RXDMA=y
+CONFIG_UART8_TXBUFSIZE=512
+CONFIG_UART8_TXDMA=y
+CONFIG_USBDEV=y
+CONFIG_USBDEV_BUSPOWERED=y
+CONFIG_USBDEV_MAXPOWER=500
+CONFIG_USEC_PER_TICK=1000
diff --git a/boards/siyi/n7/nuttx-config/include/board.h b/boards/siyi/n7/nuttx-config/include/board.h
new file mode 100644
index 0000000000..d6b690c293
--- /dev/null
+++ b/boards/siyi/n7/nuttx-config/include/board.h
@@ -0,0 +1,381 @@
+/************************************************************************************
+ * nuttx-config/include/board.h
+ *
+ * Copyright (C) 2016-2019 Gregory Nutt. All rights reserved.
+ * Authors: David Sidrane
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+#pragma once
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include "board_dma_map.h"
+
+#include
+
+#ifndef __ASSEMBLY__
+# include
+#endif
+
+#include "stm32_rcc.h"
+#include "stm32_sdmmc.h"
+
+
+/* Clocking *************************************************************************/
+/* The board provides the following clock sources:
+ *
+ * X1: 16 MHz crystal for HSE
+ *
+ * So we have these clock source available within the STM32
+ *
+ * HSI: 16 MHz RC factory-trimmed
+ * HSE: 16 MHz crystal for HSE
+ */
+
+#define STM32_BOARD_XTAL 16000000ul
+
+#define STM32_HSI_FREQUENCY 16000000ul
+#define STM32_LSI_FREQUENCY 32000
+#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL
+#define STM32_LSE_FREQUENCY 32768
+
+/* Main PLL Configuration.
+ *
+ * PLL source is HSE = 16,000,000
+ *
+ * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN
+ * Subject to:
+ *
+ * 1 <= PLLM <= 63
+ * 4 <= PLLN <= 512
+ * 150 MHz <= PLL_VCOL <= 420MHz
+ * 192 MHz <= PLL_VCOH <= 836MHz
+ *
+ * SYSCLK = PLL_VCO / PLLP
+ * CPUCLK = SYSCLK / D1CPRE
+ * Subject to
+ *
+ * PLLP1 = {2, 4, 6, 8, ..., 128}
+ * PLLP2,3 = {2, 3, 4, ..., 128}
+ * CPUCLK <= 480 MHz
+ */
+
+#define STM32_BOARD_USEHSE
+
+#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE
+
+/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR
+ *
+ * PLL1_VCO = (16,000,000 / 1) * 60 = 960 MHz
+ *
+ * PLL1P = PLL1_VCO/2 = 960 MHz / 2 = 480 MHz
+ * PLL1Q = PLL1_VCO/4 = 960 MHz / 4 = 240 MHz
+ * PLL1R = PLL1_VCO/8 = 960 MHz / 8 = 120 MHz
+ */
+
+#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE|RCC_PLLCFGR_PLL1RGE_4_8_MHZ|RCC_PLLCFGR_DIVP1EN|RCC_PLLCFGR_DIVQ1EN|RCC_PLLCFGR_DIVR1EN)
+#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(1)
+#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(60)
+#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2)
+#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4)
+#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8)
+
+#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 1) * 60)
+#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2)
+#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4)
+#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8)
+
+/* PLL2 */
+
+#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE|RCC_PLLCFGR_PLL2RGE_4_8_MHZ|RCC_PLLCFGR_DIVP2EN|RCC_PLLCFGR_DIVQ2EN|RCC_PLLCFGR_DIVR2EN)
+#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(4)
+#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(48)
+#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(2)
+#define STM32_PLLCFG_PLL2Q RCC_PLL2DIVR_Q2(2)
+#define STM32_PLLCFG_PLL2R RCC_PLL2DIVR_R2(2)
+
+#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 4) * 48)
+#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2)
+#define STM32_PLL2Q_FREQUENCY (STM32_VCO2_FREQUENCY / 2)
+#define STM32_PLL2R_FREQUENCY (STM32_VCO2_FREQUENCY / 2)
+
+/* PLL3 */
+
+#define STM32_PLLCFG_PLL3CFG (RCC_PLLCFGR_PLL3VCOSEL_WIDE|RCC_PLLCFGR_PLL3RGE_4_8_MHZ|RCC_PLLCFGR_DIVQ3EN)
+#define STM32_PLLCFG_PLL3M RCC_PLLCKSELR_DIVM3(4)
+#define STM32_PLLCFG_PLL3N RCC_PLL3DIVR_N3(48)
+#define STM32_PLLCFG_PLL3P RCC_PLL3DIVR_P3(2)
+#define STM32_PLLCFG_PLL3Q RCC_PLL3DIVR_Q3(4)
+#define STM32_PLLCFG_PLL3R RCC_PLL3DIVR_R3(2)
+
+#define STM32_VCO3_FREQUENCY ((STM32_HSE_FREQUENCY / 4) * 48)
+#define STM32_PLL3P_FREQUENCY (STM32_VCO3_FREQUENCY / 2)
+#define STM32_PLL3Q_FREQUENCY (STM32_VCO3_FREQUENCY / 4)
+#define STM32_PLL3R_FREQUENCY (STM32_VCO3_FREQUENCY / 2)
+
+/* SYSCLK = PLL1P = 480MHz
+ * CPUCLK = SYSCLK / 1 = 480 MHz
+ */
+
+#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK)
+#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY)
+#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1)
+
+/* Configure Clock Assignments */
+
+/* AHB clock (HCLK) is SYSCLK/2 (240 MHz max)
+ * HCLK1 = HCLK2 = HCLK3 = HCLK4 = 240
+ */
+
+#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */
+#define STM32_ACLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */
+#define STM32_HCLK_FREQUENCY (STM32_CPUCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */
+#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */
+
+/* APB1 clock (PCLK1) is HCLK/2 (120 MHz) */
+
+#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd2 /* PCLK1 = HCLK / 2 */
+#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2)
+
+/* APB2 clock (PCLK2) is HCLK/2 (120 MHz) */
+
+#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */
+#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2)
+
+/* APB3 clock (PCLK3) is HCLK/2 (120 MHz) */
+
+#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd2 /* PCLK3 = HCLK / 2 */
+#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/2)
+
+/* APB4 clock (PCLK4) is HCLK/4 (120 MHz) */
+
+#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd2 /* PCLK4 = HCLK / 2 */
+#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/2)
+
+/* Timer clock frequencies */
+
+/* Timers driven from APB1 will be twice PCLK1 */
+
+#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY)
+
+/* Timers driven from APB2 will be twice PCLK2 */
+
+#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY)
+
+/* Kernel Clock Configuration
+ *
+ * Note: look at Table 54 in ST Manual
+ */
+
+
+
+#define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI /* I2C123 clock source */
+
+#define STM32_RCC_D3CCIPR_I2C4SRC RCC_D3CCIPR_I2C4SEL_HSI /* I2C4 clock source */
+
+#define STM32_RCC_D2CCIP1R_SPI123SRC RCC_D2CCIP1R_SPI123SEL_PLL2 /* SPI123 clock source */
+
+#define STM32_RCC_D2CCIP1R_SPI45SRC RCC_D2CCIP1R_SPI45SEL_PLL2 /* SPI45 clock source */
+
+#define STM32_RCC_D3CCIPR_SPI6SRC RCC_D3CCIPR_SPI6SEL_PLL2 /* SPI6 clock source */
+
+#define STM32_RCC_D2CCIP2R_USBSRC RCC_D2CCIP2R_USBSEL_PLL3 /* USB 1 and 2 clock source */
+
+#define STM32_RCC_D3CCIPR_ADCSEL RCC_D3CCIPR_ADCSEL_PLL2 /* ADC 1 2 3 clock source */
+
+#define STM32_RCC_D2CCIP1R_FDCANSEL RCC_D2CCIP1R_FDCANSEL_HSE /* FDCAN 1 2 clock source */
+
+#define STM32_FDCANCLK STM32_HSE_FREQUENCY
+
+/* FLASH wait states */
+
+#define BOARD_FLASH_WAITSTATES 2
+
+/* SDMMC definitions ********************************************************/
+
+/* Init 400kHz, freq = PLL1Q/(2*div) div = PLL1Q/(2*freq) */
+
+#define STM32_SDMMC_INIT_CLKDIV (300 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+
+/* 25 MHz Max for now, 25 mHZ = PLL1Q/(2*div), div = PLL1Q/(2*freq)
+ * div = 4.8 = 240 / 50, So round up to 5 for default speed 24 MB/s
+ */
+
+#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA)
+# define STM32_SDMMC_MMCXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#else
+# define STM32_SDMMC_MMCXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#endif
+#if defined(CONFIG_STM32H7_SDMMC_XDMA) || defined(CONFIG_STM32H7_SDMMC_IDMA)
+# define STM32_SDMMC_SDXFR_CLKDIV (5 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#else
+# define STM32_SDMMC_SDXFR_CLKDIV (100 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#endif
+
+#define STM32_SDMMC_CLKCR_EDGE STM32_SDMMC_CLKCR_NEGEDGE
+
+/* LED definitions ******************************************************************/
+/* The board has three, LED_GREEN a Green LED, LED_BLUE
+ * a Blue LED and LED_RED a Red LED, that can be controlled by software.
+ *
+ * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way.
+ * The following definitions are used to access individual LEDs.
+ */
+
+/* LED index values for use with board_userled() */
+
+#define BOARD_LED1 0
+#define BOARD_LED2 1
+#define BOARD_LED3 2
+#define BOARD_NLEDS 3
+
+#define BOARD_LED_RED BOARD_LED1
+#define BOARD_LED_GREEN BOARD_LED2
+#define BOARD_LED_BLUE BOARD_LED3
+
+/* LED bits for use with board_userled_all() */
+
+#define BOARD_LED1_BIT (1 << BOARD_LED1)
+#define BOARD_LED2_BIT (1 << BOARD_LED2)
+#define BOARD_LED3_BIT (1 << BOARD_LED3)
+
+/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in
+ * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related
+ * events as follows:
+ *
+ *
+ * SYMBOL Meaning LED state
+ * Red Green Blue
+ * ---------------------- -------------------------- ------ ------ ----*/
+
+#define LED_STARTED 0 /* NuttX has been started OFF OFF OFF */
+#define LED_HEAPALLOCATE 1 /* Heap has been allocated OFF OFF ON */
+#define LED_IRQSENABLED 2 /* Interrupts enabled OFF ON OFF */
+#define LED_STACKCREATED 3 /* Idle stack created OFF ON ON */
+#define LED_INIRQ 4 /* In an interrupt N/C N/C GLOW */
+#define LED_SIGNAL 5 /* In a signal handler N/C GLOW N/C */
+#define LED_ASSERTION 6 /* An assertion failed GLOW N/C GLOW */
+#define LED_PANIC 7 /* The system has crashed Blink OFF N/C */
+#define LED_IDLE 8 /* MCU is is sleep mode ON OFF OFF */
+
+/* Thus if the Green LED is statically on, NuttX has successfully booted and
+ * is, apparently, running normally. If the Red LED is flashing at
+ * approximately 2Hz, then a fatal error has been detected and the system
+ * has halted.
+ */
+
+/* Alternate function pin selections ************************************************/
+
+#define GPIO_USART1_RX GPIO_USART1_RX_3 /* PB7 */
+#define GPIO_USART1_TX GPIO_USART1_TX_3 /* PB6 */
+
+#define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */
+#define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */
+#define GPIO_USART2_RTS GPIO_USART2_RTS_2 /* PD4 */
+#define GPIO_USART2_CTS GPIO_USART2_CTS_NSS_2 /* PD3 */
+
+
+#define GPIO_UART4_RX GPIO_UART4_RX_5 /* PD0 */
+#define GPIO_UART4_TX GPIO_UART4_TX_5 /* PD1 */
+
+
+
+#define GPIO_UART7_RX GPIO_UART7_RX_4 /* PF6 */
+#define GPIO_UART7_TX GPIO_UART7_TX_3 /* PE8 */
+
+#define GPIO_UART8_RX GPIO_UART8_RX_1 /* PE0 */
+#define GPIO_UART8_TX GPIO_UART8_TX_1 /* PE1 */
+
+/* CAN
+ *
+ * CAN1 is routed to transceiver.
+ */
+#define GPIO_CAN1_RX GPIO_CAN1_RX_5 /* PI9 */
+#define GPIO_CAN1_TX GPIO_CAN1_TX_4 /* PH13 */
+
+/* SPI
+ * SPI1 sensors
+ * SPI2 is FRAM.
+ * SPI4 is BARO
+ */
+
+#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 /* PA6 */
+#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_3 /* PD7 */
+#define GPIO_SPI1_SCK GPIO_SPI1_SCK_3 /* PG11 */
+
+#define GPIO_SPI2_MISO GPIO_SPI2_MISO_3 /* PI2 */
+#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_4 /* PI3 */
+#define GPIO_SPI2_SCK GPIO_SPI2_SCK_6 /* PI1 */
+
+#define GPIO_SPI4_MISO GPIO_SPI4_MISO_1 /* PE13 */
+#define GPIO_SPI4_MOSI GPIO_SPI4_MOSI_2 /* PE6 */
+#define GPIO_SPI4_SCK GPIO_SPI4_SCK_2 /* PE2 */
+
+
+
+/* I2C
+ *
+ * Each I2C is associated with a U[S]ART
+ * hence the naming I2C2_SDA_UART4 in FMU USAGE spreadsheet
+ *
+ * The optional _GPIO configurations allow the I2C driver to manually
+ * reset the bus to clear stuck slaves. They match the pin configuration,
+ * but are normally-high GPIOs.
+ *
+ */
+
+#define GPIO_I2C1_SCL GPIO_I2C1_SCL_2 /* PB8 */
+#define GPIO_I2C1_SDA GPIO_I2C1_SDA_2 /* PB9 */
+
+#define GPIO_I2C2_SCL GPIO_I2C2_SCL_2 /* PF1 */
+#define GPIO_I2C2_SDA GPIO_I2C2_SDA_2 /* PF0 */
+
+#define GPIO_I2C3_SCL GPIO_I2C3_SCL_2 /* PH7 */
+#define GPIO_I2C3_SDA GPIO_I2C3_SDA_2 /* PH8 */
+
+#define GPIO_I2C4_SCL GPIO_I2C4_SCL_2 /* PF14 */
+#define GPIO_I2C4_SDA GPIO_I2C4_SDA_2 /* PF15 */
+
+
+
diff --git a/boards/siyi/n7/nuttx-config/include/board_dma_map.h b/boards/siyi/n7/nuttx-config/include/board_dma_map.h
new file mode 100644
index 0000000000..6577106c23
--- /dev/null
+++ b/boards/siyi/n7/nuttx-config/include/board_dma_map.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+// DMAMUX1
+#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* DMA1:37 */
+#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* DMA1:38 */
+
+#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* 3 DMA1:39 FRAM */
+#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* 4 DMA1:40 FRAM */
+
+#define DMAMAP_UART8_RX DMAMAP_DMA12_UART8RX_0 /* DMA1:81 */
+#define DMAMAP_UART8_TX DMAMAP_DMA12_UART8TX_0 /* DMA1:82 */
+
diff --git a/boards/siyi/n7/nuttx-config/nsh/defconfig b/boards/siyi/n7/nuttx-config/nsh/defconfig
new file mode 100644
index 0000000000..f2f14e7cc9
--- /dev/null
+++ b/boards/siyi/n7/nuttx-config/nsh/defconfig
@@ -0,0 +1,252 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_DISABLE_ENVIRON is not set
+# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
+# CONFIG_DISABLE_PTHREAD is not set
+# CONFIG_MMCSD_HAVE_CARDDETECT is not set
+# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set
+# CONFIG_MMCSD_MMCSUPPORT is not set
+# CONFIG_MMCSD_SPI is not set
+# CONFIG_NSH_DISABLEBG is not set
+# CONFIG_NSH_DISABLESCRIPT is not set
+# CONFIG_NSH_DISABLE_CAT is not set
+# CONFIG_NSH_DISABLE_CD is not set
+# CONFIG_NSH_DISABLE_CP is not set
+# CONFIG_NSH_DISABLE_DATE is not set
+# CONFIG_NSH_DISABLE_DF is not set
+# CONFIG_NSH_DISABLE_ECHO is not set
+# CONFIG_NSH_DISABLE_ENV is not set
+# CONFIG_NSH_DISABLE_EXEC is not set
+# CONFIG_NSH_DISABLE_EXIT is not set
+# CONFIG_NSH_DISABLE_EXPORT is not set
+# CONFIG_NSH_DISABLE_FREE is not set
+# CONFIG_NSH_DISABLE_GET is not set
+# CONFIG_NSH_DISABLE_HELP is not set
+# CONFIG_NSH_DISABLE_ITEF is not set
+# CONFIG_NSH_DISABLE_KILL is not set
+# CONFIG_NSH_DISABLE_LOOPS is not set
+# CONFIG_NSH_DISABLE_LS is not set
+# CONFIG_NSH_DISABLE_MKDIR is not set
+# CONFIG_NSH_DISABLE_MKFATFS is not set
+# CONFIG_NSH_DISABLE_MOUNT is not set
+# CONFIG_NSH_DISABLE_MV is not set
+# CONFIG_NSH_DISABLE_PS is not set
+# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set
+# CONFIG_NSH_DISABLE_PWD is not set
+# CONFIG_NSH_DISABLE_RM is not set
+# CONFIG_NSH_DISABLE_RMDIR is not set
+# CONFIG_NSH_DISABLE_SEMICOLON is not set
+# CONFIG_NSH_DISABLE_SET is not set
+# CONFIG_NSH_DISABLE_SLEEP is not set
+# CONFIG_NSH_DISABLE_SOURCE is not set
+# CONFIG_NSH_DISABLE_TEST is not set
+# CONFIG_NSH_DISABLE_TIME is not set
+# CONFIG_NSH_DISABLE_UMOUNT is not set
+# CONFIG_NSH_DISABLE_UNSET is not set
+# CONFIG_NSH_DISABLE_USLEEP is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD_CUSTOM=y
+CONFIG_ARCH_BOARD_CUSTOM_DIR="../../../../boards/siyi/n7/nuttx-config"
+CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y
+CONFIG_ARCH_BOARD_CUSTOM_NAME="px4"
+CONFIG_ARCH_CHIP="stm32h7"
+CONFIG_ARCH_CHIP_STM32H743II=y
+CONFIG_ARCH_CHIP_STM32H7=y
+CONFIG_ARCH_INTERRUPTSTACK=768
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV7M_BASEPRI_WAR=y
+CONFIG_ARMV7M_DCACHE=y
+CONFIG_ARMV7M_DTCM=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_MEMCPY=y
+CONFIG_ARMV7M_USEBASEPRI=y
+CONFIG_ARM_MPU_EARLY_RESET=y
+CONFIG_BOARDCTL_RESET=y
+CONFIG_BOARD_ASSERT_RESET_VALUE=0
+CONFIG_BOARD_CRASHDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=95150
+CONFIG_BOARD_RESET_ON_ASSERT=2
+CONFIG_BUILTIN=y
+CONFIG_CDCACM=y
+CONFIG_CDCACM_IFLOWCONTROL=y
+CONFIG_CDCACM_PRODUCTID=0x0038
+CONFIG_CDCACM_PRODUCTSTR="PX4 N7"
+CONFIG_CDCACM_RXBUFSIZE=600
+CONFIG_CDCACM_TXBUFSIZE=12000
+CONFIG_CDCACM_VENDORID=0x3185
+CONFIG_CDCACM_VENDORSTR="Siyi"
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_HARDFAULT_ALERT=y
+CONFIG_DEBUG_MEMFAULT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEBUG_TCBINFO=y
+CONFIG_DEFAULT_SMALL=y
+CONFIG_DEV_FIFO_SIZE=0
+CONFIG_DEV_PIPE_MAXSIZE=1024
+CONFIG_DEV_PIPE_SIZE=70
+CONFIG_EXPERIMENTAL=y
+CONFIG_FAT_DMAMEMORY=y
+CONFIG_FAT_LCNAMES=y
+CONFIG_FAT_LFN=y
+CONFIG_FAT_LFN_ALIAS_HASH=y
+CONFIG_FDCLONE_STDIO=y
+CONFIG_FS_BINFS=y
+CONFIG_FS_CROMFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FATTIME=y
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_INCLUDE_PROGMEM=y
+CONFIG_FS_PROCFS_MAX_TASKS=64
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_FS_ROMFS=y
+CONFIG_GRAN=y
+CONFIG_GRAN_INTR=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_I2C=y
+CONFIG_I2C_RESET=y
+CONFIG_IDLETHREAD_STACKSIZE=750
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=3194
+CONFIG_LIBC_FLOATINGPOINT=y
+CONFIG_LIBC_LONG_LONG=y
+CONFIG_LIBC_MAX_EXITFUNS=1
+CONFIG_LIBC_STRERROR=y
+CONFIG_MEMSET_64BIT=y
+CONFIG_MEMSET_OPTSPEED=y
+CONFIG_MMCSD=y
+CONFIG_MMCSD_SDIO=y
+CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y
+CONFIG_MM_REGIONS=4
+CONFIG_MTD=y
+CONFIG_MTD_BYTE_WRITE=y
+CONFIG_MTD_PARTITION=y
+CONFIG_MTD_PROGMEM=y
+CONFIG_MTD_RAMTRON=y
+CONFIG_NAME_MAX=40
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_ARGCAT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_CMDPARMS=y
+CONFIG_NSH_CROMFSETC=y
+CONFIG_NSH_LINELEN=128
+CONFIG_NSH_MAXARGUMENTS=15
+CONFIG_NSH_NESTDEPTH=8
+CONFIG_NSH_QUOTE=y
+CONFIG_NSH_ROMFSETC=y
+CONFIG_NSH_ROMFSSECTSIZE=128
+CONFIG_NSH_STRERROR=y
+CONFIG_NSH_VARS=y
+CONFIG_OTG_ID_GPIO_DISABLE=y
+CONFIG_PIPES=y
+CONFIG_PREALLOC_TIMERS=50
+CONFIG_PRIORITY_INHERITANCE=y
+CONFIG_PTHREAD_MUTEX_ROBUST=y
+CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
+CONFIG_RAMTRON_SETSPEED=y
+CONFIG_RAM_SIZE=245760
+CONFIG_RAM_START=0x20010000
+CONFIG_RAW_BINARY=y
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_READLINE_TABCOMPLETION=y
+CONFIG_RTC_DATETIME=y
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_HPWORKPRIORITY=249
+CONFIG_SCHED_HPWORKSTACKSIZE=1280
+CONFIG_SCHED_INSTRUMENTATION=y
+CONFIG_SCHED_INSTRUMENTATION_EXTERNAL=y
+CONFIG_SCHED_INSTRUMENTATION_SWITCH=y
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_LPWORKPRIORITY=50
+CONFIG_SCHED_LPWORKSTACKSIZE=1632
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDMMC1_SDIO_PULLUP=y
+CONFIG_SEM_PREALLOCHOLDERS=32
+CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS=y
+CONFIG_SERIAL_TERMIOS=y
+CONFIG_SIG_DEFAULT=y
+CONFIG_SIG_SIGALRM_ACTION=y
+CONFIG_SIG_SIGUSR1_ACTION=y
+CONFIG_SIG_SIGUSR2_ACTION=y
+CONFIG_SIG_SIGWORK=4
+CONFIG_STACK_COLORATION=y
+CONFIG_START_DAY=30
+CONFIG_START_MONTH=11
+CONFIG_STDIO_BUFFER_SIZE=256
+CONFIG_STM32H7_ADC1=y
+CONFIG_STM32H7_ADC3=y
+CONFIG_STM32H7_BBSRAM=y
+CONFIG_STM32H7_BBSRAM_FILES=5
+CONFIG_STM32H7_BDMA=y
+CONFIG_STM32H7_BKPSRAM=y
+CONFIG_STM32H7_DMA1=y
+CONFIG_STM32H7_DMA2=y
+CONFIG_STM32H7_DMACAPABLE=y
+CONFIG_STM32H7_FLOWCONTROL_BROKEN=y
+CONFIG_STM32H7_I2C1=y
+CONFIG_STM32H7_I2C2=y
+CONFIG_STM32H7_I2C3=y
+CONFIG_STM32H7_I2C4=y
+CONFIG_STM32H7_I2C_DYNTIMEO=y
+CONFIG_STM32H7_I2C_DYNTIMEO_STARTSTOP=10
+CONFIG_STM32H7_OTGFS=y
+CONFIG_STM32H7_PROGMEM=y
+CONFIG_STM32H7_RTC=y
+CONFIG_STM32H7_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY=y
+CONFIG_STM32H7_RTC_MAGIC_REG=1
+CONFIG_STM32H7_SAVE_CRASHDUMP=y
+CONFIG_STM32H7_SDMMC1=y
+CONFIG_STM32H7_SERIALBRK_BSDCOMPAT=y
+CONFIG_STM32H7_SERIAL_DISABLE_REORDERING=y
+CONFIG_STM32H7_SPI1=y
+CONFIG_STM32H7_SPI1_DMA=y
+CONFIG_STM32H7_SPI1_DMA_BUFFER=1024
+CONFIG_STM32H7_SPI2=y
+CONFIG_STM32H7_SPI4=y
+CONFIG_STM32H7_TIM1=y
+CONFIG_STM32H7_TIM3=y
+CONFIG_STM32H7_TIM4=y
+CONFIG_STM32H7_UART4=y
+CONFIG_STM32H7_UART7=y
+CONFIG_STM32H7_UART8=y
+CONFIG_STM32H7_USART1=y
+CONFIG_STM32H7_USART2=y
+CONFIG_STM32H7_USART_BREAKS=y
+CONFIG_STM32H7_USART_INVERT=y
+CONFIG_STM32H7_USART_SINGLEWIRE=y
+CONFIG_STM32H7_USART_SWAP=y
+CONFIG_SYSTEM_CDCACM=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=24
+CONFIG_TTY_SIGINT=y
+CONFIG_TTY_SIGTSTP=y
+CONFIG_UART4_BAUD=57600
+CONFIG_UART4_RXBUFSIZE=600
+CONFIG_UART4_TXBUFSIZE=1500
+CONFIG_UART7_BAUD=57600
+CONFIG_UART7_RXBUFSIZE=600
+CONFIG_UART7_SERIAL_CONSOLE=y
+CONFIG_UART7_TXBUFSIZE=1500
+CONFIG_UART8_BAUD=57600
+CONFIG_UART8_RXBUFSIZE=600
+CONFIG_UART8_TXBUFSIZE=1500
+CONFIG_USART1_BAUD=57600
+CONFIG_USART1_RXBUFSIZE=600
+CONFIG_USART1_TXBUFSIZE=1500
+CONFIG_USART2_BAUD=57600
+CONFIG_USART2_IFLOWCONTROL=y
+CONFIG_USART2_OFLOWCONTROL=y
+CONFIG_USART2_RXBUFSIZE=600
+CONFIG_USART2_TXBUFSIZE=1500
+CONFIG_USBDEV=y
+CONFIG_USBDEV_BUSPOWERED=y
+CONFIG_USBDEV_MAXPOWER=500
+CONFIG_USEC_PER_TICK=1000
+CONFIG_WATCHDOG=y
diff --git a/boards/siyi/n7/nuttx-config/scripts/bootloader_script.ld b/boards/siyi/n7/nuttx-config/scripts/bootloader_script.ld
new file mode 100644
index 0000000000..43d36e7dc9
--- /dev/null
+++ b/boards/siyi/n7/nuttx-config/scripts/bootloader_script.ld
@@ -0,0 +1,215 @@
+/****************************************************************************
+ * scripts/script.ld
+ *
+ * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/* The board uses an STM32H743II has 2048Kb of main FLASH memory.
+ * The flash memory is partitioned into a User Flash memory and a System
+ * Flash memory. Each of these memories has two banks:
+ *
+ * 1) User Flash memory:
+ *
+ * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each
+ * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each
+ *
+ * 2) System Flash memory:
+ *
+ * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector
+ * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector
+ *
+ * 3) User option bytes for user configuration, only in Bank 1.
+ *
+ * In the STM32H743II, two different boot spaces can be selected through
+ * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and
+ * BOOT_ADD1 option bytes:
+ *
+ * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0].
+ * ST programmed value: Flash memory at 0x0800:0000
+ * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0].
+ * ST programmed value: System bootloader at 0x1FF0:0000
+ *
+ * The board has a test point on board, the BOOT0 pin is at ground so by
+ * default, the STM32 will boot to address 0x0800:0000 in FLASH unless the test
+ * point is pulled to 3.3V.then the boot will be from 0x1FF0:0000
+ *
+ * The STM32H743ZI also has 1024Kb of data SRAM.
+ * SRAM is split up into several blocks and into three power domains:
+ *
+ * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with
+ * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus
+ *
+ * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000
+ *
+ * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit
+ * DTCM ports. The DTCM-RAM could be used for critical real-time
+ * data, such as interrupt service routines or stack / heap memory.
+ * Both DTCM-RAMs can be used in parallel (for load/store operations)
+ * thanks to the Cortex-M7 dual issue capability.
+ *
+ * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000
+ *
+ * This RAM is connected to ITCM 64-bit interface designed for
+ * execution of critical real-times routines by the CPU.
+ *
+ * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA
+ * through D1 domain AXI bus matrix
+ *
+ * 2.1) 512Kb of SRAM beginning at address 0x2400:0000
+ *
+ * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA
+ * through D2 domain AHB bus matrix
+ *
+ * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000
+ * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000
+ * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000
+ *
+ * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000
+ *
+ * 4) AHB SRAM (D3 domain) accessible by most of system masters
+ * through D3 domain AHB bus matrix
+ *
+ * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000
+ * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000
+ *
+ * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
+ * where the code expects to begin execution by jumping to the entry point in
+ * the 0x0800:0000 address range.
+ *
+ * The bootloader uses the first sector of the flash, which is 128K in length.
+ */
+
+MEMORY
+{
+ itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 64K
+ flash (rx) : ORIGIN = 0x08000000, LENGTH = 128K
+ dtcm1 (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ dtcm2 (rwx) : ORIGIN = 0x20010000, LENGTH = 64K
+ sram (rwx) : ORIGIN = 0x24000000, LENGTH = 512K
+ sram1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K
+ sram2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K
+ sram3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K
+ sram4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K
+ bbram (rwx) : ORIGIN = 0x38800000, LENGTH = 4K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+ENTRY(_stext)
+
+/*
+ * Ensure that abort() is present in the final object. The exception handling
+ * code pulled in by libgcc.a requires it (and that code cannot be easily avoided).
+ */
+EXTERN(abort)
+EXTERN(_bootdelay_signature)
+
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ . = ALIGN(32);
+ /*
+ This signature provides the bootloader with a way to delay booting
+ */
+ _bootdelay_signature = ABSOLUTE(.);
+ FILL(0xffecc2925d7d05c5)
+ . += 8;
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+
+ } > flash
+
+ /*
+ * Init functions (static constructors and the like)
+ */
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ KEEP(*(.init_array .init_array.*))
+ _einit = ABSOLUTE(.);
+ } > flash
+
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > flash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > flash
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ _edata = ABSOLUTE(.);
+ } > sram AT > flash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = ABSOLUTE(.);
+ } > sram
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/siyi/n7/nuttx-config/scripts/script.ld b/boards/siyi/n7/nuttx-config/scripts/script.ld
new file mode 100644
index 0000000000..d6019c0d13
--- /dev/null
+++ b/boards/siyi/n7/nuttx-config/scripts/script.ld
@@ -0,0 +1,229 @@
+/****************************************************************************
+ * scripts/script.ld
+ *
+ * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/* The board uses an STM32H743II has 2048Kb of main FLASH memory.
+ * The flash memory is partitioned into a User Flash memory and a System
+ * Flash memory. Each of these memories has two banks:
+ *
+ * 1) User Flash memory:
+ *
+ * Bank 1: Start address 0x0800:0000 to 0x080F:FFFF with 8 sectors, 128Kb each
+ * Bank 2: Start address 0x0810:0000 to 0x081F:FFFF with 8 sectors, 128Kb each
+ *
+ * 2) System Flash memory:
+ *
+ * Bank 1: Start address 0x1FF0:0000 to 0x1FF1:FFFF with 1 x 128Kb sector
+ * Bank 1: Start address 0x1FF4:0000 to 0x1FF5:FFFF with 1 x 128Kb sector
+ *
+ * 3) User option bytes for user configuration, only in Bank 1.
+ *
+ * In the STM32H743II, two different boot spaces can be selected through
+ * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and
+ * BOOT_ADD1 option bytes:
+ *
+ * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0].
+ * ST programmed value: Flash memory at 0x0800:0000
+ * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0].
+ * ST programmed value: System bootloader at 0x1FF0:0000
+ *
+ * The board has a test point on board, the BOOT0 pin is at ground so by
+ * default, the STM32 will boot to address 0x0800:0000 in FLASH unless the test
+ * point is pulled to 3.3V.then the boot will be from 0x1FF0:0000
+ *
+ * The STM32H743ZI also has 1024Kb of data SRAM.
+ * SRAM is split up into several blocks and into three power domains:
+ *
+ * 1) TCM SRAMs are dedicated to the Cortex-M7 and are accessible with
+ * 0 wait states by the Cortex-M7 and by MDMA through AHBS slave bus
+ *
+ * 1.1) 128Kb of DTCM-RAM beginning at address 0x2000:0000
+ *
+ * The DTCM-RAM is organized as 2 x 64Kb DTCM-RAMs on 2 x 32 bit
+ * DTCM ports. The DTCM-RAM could be used for critical real-time
+ * data, such as interrupt service routines or stack / heap memory.
+ * Both DTCM-RAMs can be used in parallel (for load/store operations)
+ * thanks to the Cortex-M7 dual issue capability.
+ *
+ * 1.2) 64Kb of ITCM-RAM beginning at address 0x0000:0000
+ *
+ * This RAM is connected to ITCM 64-bit interface designed for
+ * execution of critical real-times routines by the CPU.
+ *
+ * 2) AXI SRAM (D1 domain) accessible by all system masters except BDMA
+ * through D1 domain AXI bus matrix
+ *
+ * 2.1) 512Kb of SRAM beginning at address 0x2400:0000
+ *
+ * 3) AHB SRAM (D2 domain) accessible by all system masters except BDMA
+ * through D2 domain AHB bus matrix
+ *
+ * 3.1) 128Kb of SRAM1 beginning at address 0x3000:0000
+ * 3.2) 128Kb of SRAM2 beginning at address 0x3002:0000
+ * 3.3) 32Kb of SRAM3 beginning at address 0x3004:0000
+ *
+ * SRAM1 - SRAM3 are one contiguous block: 288Kb at address 0x3000:0000
+ *
+ * 4) AHB SRAM (D3 domain) accessible by most of system masters
+ * through D3 domain AHB bus matrix
+ *
+ * 4.1) 64Kb of SRAM4 beginning at address 0x3800:0000
+ * 4.1) 4Kb of backup RAM beginning at address 0x3880:0000
+ *
+ * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
+ * where the code expects to begin execution by jumping to the entry point in
+ * the 0x0800:0000 address range.
+ */
+
+MEMORY
+{
+ ITCM_RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 64K
+ FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 1920K
+
+ DTCM1_RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ DTCM2_RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K
+ AXI_SRAM (rwx) : ORIGIN = 0x24000000, LENGTH = 512K /* D1 domain AXI bus */
+ SRAM1 (rwx) : ORIGIN = 0x30000000, LENGTH = 128K /* D2 domain AHB bus */
+ SRAM2 (rwx) : ORIGIN = 0x30020000, LENGTH = 128K /* D2 domain AHB bus */
+ SRAM3 (rwx) : ORIGIN = 0x30040000, LENGTH = 32K /* D2 domain AHB bus */
+ SRAM4 (rwx) : ORIGIN = 0x38000000, LENGTH = 64K /* D3 domain */
+ BKPRAM (rwx) : ORIGIN = 0x38800000, LENGTH = 4K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+ENTRY(_stext)
+
+/*
+ * Ensure that abort() is present in the final object. The exception handling
+ * code pulled in by libgcc.a requires it (and that code cannot be easily avoided).
+ */
+EXTERN(abort)
+EXTERN(_bootdelay_signature)
+EXTERN(board_get_manifest)
+
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ . = ALIGN(32);
+ /*
+ This signature provides the bootloader with a way to delay booting
+ */
+ _bootdelay_signature = ABSOLUTE(.);
+ FILL(0xffecc2925d7d05c5)
+ . += 8;
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+
+ } > FLASH
+
+ /*
+ * Init functions (static constructors and the like)
+ */
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ KEEP(*(.init_array .init_array.*))
+ _einit = ABSOLUTE(.);
+ } > FLASH
+
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > FLASH
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > FLASH
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ _edata = ABSOLUTE(.);
+
+ /* Pad out last section as the STM32H7 Flash write size is 256 bits. 32 bytes */
+ . = ALIGN(16);
+ FILL(0xffff)
+ . += 16;
+ } > AXI_SRAM AT > FLASH = 0xffff
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = ABSOLUTE(.);
+ } > AXI_SRAM
+
+ /* Emit the the D3 power domain section for locating BDMA data */
+
+ .sram4_reserve (NOLOAD) :
+ {
+ *(.sram4)
+ . = ALIGN(4);
+ _sram4_heap_start = ABSOLUTE(.);
+ } > SRAM4
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/boards/siyi/n7/src/CMakeLists.txt b/boards/siyi/n7/src/CMakeLists.txt
new file mode 100644
index 0000000000..c1386c4181
--- /dev/null
+++ b/boards/siyi/n7/src/CMakeLists.txt
@@ -0,0 +1,70 @@
+############################################################################
+#
+# Copyright (c) 2016 PX4 Development Team. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name PX4 nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+if("${PX4_BOARD_LABEL}" STREQUAL "bootloader")
+ add_library(drivers_board
+ bootloader_main.c
+ usb.c
+ )
+ target_link_libraries(drivers_board
+ PRIVATE
+ nuttx_arch # sdio
+ nuttx_drivers # sdio
+ bootloader
+ )
+ target_include_directories(drivers_board PRIVATE ${PX4_SOURCE_DIR}/platforms/nuttx/src/bootloader/common)
+
+else()
+ add_library(drivers_board
+ can.c
+ i2c.cpp
+ init.c
+ led.c
+ manifest.c
+ sdio.c
+ spi.cpp
+ timer_config.cpp
+ usb.c
+ )
+ add_dependencies(drivers_board arch_board_hw_info)
+
+ target_link_libraries(drivers_board
+ PRIVATE
+ arch_io_pins
+ arch_spi
+ arch_board_hw_info
+ drivers__led # drv_led_start
+ nuttx_arch # sdio
+ nuttx_drivers # sdio
+ px4_layer
+ )
+endif()
diff --git a/boards/siyi/n7/src/board_config.h b/boards/siyi/n7/src/board_config.h
new file mode 100644
index 0000000000..e705c87890
--- /dev/null
+++ b/boards/siyi/n7/src/board_config.h
@@ -0,0 +1,310 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2019 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file board_config.h
+ *
+ * Board internal definitions
+ */
+
+#pragma once
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+#include
+#include
+
+#include
+
+/****************************************************************************************************
+ * Definitions
+ ****************************************************************************************************/
+
+/* PX4IO connection configuration */
+
+#define BOARD_USES_PX4IO_VERSION 2
+#define PX4IO_SERIAL_DEVICE "/dev/ttyS4"
+#define PX4IO_SERIAL_TX_GPIO GPIO_UART8_TX
+#define PX4IO_SERIAL_RX_GPIO GPIO_UART8_RX
+#define PX4IO_SERIAL_BASE STM32_UART8_BASE
+#define PX4IO_SERIAL_VECTOR STM32_IRQ_UART8
+#define PX4IO_SERIAL_TX_DMAMAP DMAMAP_UART8_TX
+#define PX4IO_SERIAL_RX_DMAMAP DMAMAP_UART8_RX
+#define PX4IO_SERIAL_RCC_REG STM32_RCC_APB1LENR
+#define PX4IO_SERIAL_RCC_EN RCC_APB1LENR_UART8EN
+#define PX4IO_SERIAL_CLOCK STM32_PCLK1_FREQUENCY
+#define PX4IO_SERIAL_BITRATE 1500000 /* 1.5Mbps -> max rate for IO */
+
+/* LEDs are driven with push open drain to support Anode to 5V or 3.3V */
+
+#define GPIO_nLED_RED /* PB1 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_nLED_BLUE /* PC7 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN7)
+
+#define BOARD_HAS_CONTROL_STATUS_LEDS 1
+#define BOARD_OVERLOAD_LED LED_RED
+#define BOARD_ARMED_STATE_LED LED_BLUE
+
+/* ADC channels */
+
+
+
+/* Define GPIO pins used as ADC N.B. Channel numbers must match below */
+
+#define PX4_ADC_GPIO \
+ /* PA0 */ GPIO_ADC1_INP16, \
+ /* PA1 */ GPIO_ADC1_INP17, \
+ /* PB0 */ GPIO_ADC12_INP9, \
+ /* PC0 */ GPIO_ADC123_INP10, \
+ /* PC1 */ GPIO_ADC123_INP11, \
+ /* PC2 */ GPIO_ADC123_INP12, \
+ /* PC3 */ GPIO_ADC12_INP13
+
+
+/* Define Channel numbers must match above GPIO pin IN(n)*/
+
+#define ADC_BATTERY_VOLTAGE_CHANNEL /* PA0 */ 16
+#define ADC_BATTERY_CURRENT_CHANNEL /* PA1 */ 17
+#define ADC_RSSI_IN_CHANNEL /* PB0 */ 9
+#define ADC_SCALED_V5_CHANNEL /* PC0 */ 10
+#define ADC_SCALED_VDD_3V3_SENSORS_CHANNEL /* PC1 */ 11
+#define ADC_HW_VER_SENSE_CHANNEL /* PC2 */ 12
+#define ADC_HW_REV_SENSE_CHANNEL /* PC3 */ 13
+
+#define ADC_CHANNELS \
+ ((1 << ADC_BATTERY_VOLTAGE_CHANNEL) | \
+ (1 << ADC_BATTERY_CURRENT_CHANNEL) | \
+ (1 << ADC_RSSI_IN_CHANNEL) | \
+ (1 << ADC_SCALED_V5_CHANNEL) | \
+ (1 << ADC_SCALED_VDD_3V3_SENSORS_CHANNEL) | \
+ (1 << ADC_HW_VER_SENSE_CHANNEL) | \
+ (1 << ADC_HW_REV_SENSE_CHANNEL))
+
+/* HW has to large of R termination on ADC todo:change when HW value is chosen */
+
+#define BOARD_ADC_OPEN_CIRCUIT_V (5.6f)
+
+/* HW Version and Revision drive signals Default to 1 to detect */
+
+#define BOARD_HAS_HW_VERSIONING
+
+#define GPIO_HW_REV_DRIVE /* PH14 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTH|GPIO_PIN14)
+#define GPIO_HW_REV_SENSE /* PC3 */ GPIO_ADC12_INP13
+#define GPIO_HW_VER_DRIVE /* PG0 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN0)
+#define GPIO_HW_VER_SENSE /* PC2 */ GPIO_ADC123_INP12
+#define HW_INFO_INIT_PREFIX "VD"
+
+
+#define VER00 HW_VER_REV(0x0,0x0)
+
+/* CAN Silence
+ *
+ * Silent mode control \ ESC Mux select
+ */
+
+#define GPIO_CAN1_SILENT_S0 /* PH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN2)
+
+/* HEATER
+ * PWM in future
+ */
+#define GPIO_HEATER_OUTPUT /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
+#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
+
+/* PWM
+ */
+#define DIRECT_PWM_OUTPUT_CHANNELS 5
+
+#define BOARD_NUM_IO_TIMERS 2
+
+
+/* Power supply control and monitoring GPIOs */
+
+#define GPIO_nPOWER_IN_A /* PG1 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN1)
+#define GPIO_nPOWER_IN_B /* PG3 */ (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTG|GPIO_PIN3)
+
+#define GPIO_nVDD_BRICK_VALID GPIO_nPOWER_IN_A /* Brick 1 Is Chosen */
+#define BOARD_NUMBER_BRICKS 1
+#define GPIO_nVDD_USB_VALID GPIO_nPOWER_IN_B /* USB Is Chosen */
+
+#define GPIO_VDD_5V_PERIPH_nEN /* PG4 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN4)
+#define GPIO_VDD_5V_PERIPH_nOC /* PE15 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTE|GPIO_PIN15)
+#define GPIO_VDD_5V_HIPOWER_nEN /* PF12 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTF|GPIO_PIN12)
+#define GPIO_VDD_5V_HIPOWER_nOC /* PG13 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTF|GPIO_PIN13)
+#define GPIO_VDD_3V3_SD_CARD_EN /* PG7 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN7)
+
+
+/* Define True logic Power Control in arch agnostic form */
+
+#define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_nEN, !(on_true))
+#define VDD_5V_HIPOWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_HIPOWER_nEN, !(on_true))
+#define VDD_3V3_SD_CARD_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SD_CARD_EN, (on_true))
+
+/* Tone alarm output */
+
+#define TONE_ALARM_TIMER 15 /* timer 15 */
+#define TONE_ALARM_CHANNEL 1 /* PE5 TIM15_CH1 */
+
+#define GPIO_BUZZER_1 /* PE5 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN5)
+
+#define GPIO_TONE_ALARM_IDLE GPIO_BUZZER_1
+#define GPIO_TONE_ALARM GPIO_TIM15_CH1OUT_2
+
+/* USB OTG FS
+ *
+ * PA9 OTG_FS_VBUS VBUS sensing
+ */
+#define GPIO_OTGFS_VBUS /* PA9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_SPEED_100MHz|GPIO_PORTA|GPIO_PIN9)
+
+/* High-resolution timer */
+#define HRT_TIMER 8 /* use timer8 for the HRT */
+#define HRT_TIMER_CHANNEL 3 /* use capture/compare channel 3 */
+
+/* PWM input driver. Use FMU AUX5 pins attached to timer4 channel 2 */
+
+#define PWMIN_TIMER 4
+#define PWMIN_TIMER_CHANNEL /* T4C2 */ 2
+#define GPIO_PWM_IN /* PD13 */ GPIO_TIM4_CH2IN
+
+#define SDIO_SLOTNO 0 /* Only one slot */
+#define SDIO_MINOR 0
+
+/* SD card bringup does not work if performed on the IDLE thread because it
+ * will cause waiting. Use either:
+ *
+ * CONFIG_BOARDCTL=y, OR
+ * CONFIG_BOARD_INITIALIZE=y && CONFIG_BOARD_INITTHREAD=y
+ */
+
+#if defined(CONFIG_BOARD_INITIALIZE) && !defined(CONFIG_BOARDCTL) && \
+ !defined(CONFIG_BOARD_INITTHREAD)
+# warning SDIO initialization cannot be perfomed on the IDLE thread
+#endif
+
+/* By Providing BOARD_ADC_USB_CONNECTED (using the px4_arch abstraction)
+ * this board support the ADC system_power interface, and therefore
+ * provides the true logic GPIO BOARD_ADC_xxxx macros.
+ */
+#define BOARD_ADC_USB_CONNECTED (px4_arch_gpioread(GPIO_OTGFS_VBUS))
+#define BOARD_ADC_USB_VALID (!px4_arch_gpioread(GPIO_nVDD_USB_VALID))
+
+/* Board never powers off the Servo rail */
+
+#define BOARD_ADC_SERVO_VALID (1)
+
+#define BOARD_ADC_BRICK_VALID (!px4_arch_gpioread(GPIO_nVDD_BRICK_VALID))
+
+
+#define BOARD_ADC_PERIPH_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_PERIPH_nOC))
+#define BOARD_ADC_HIPOWER_5V_OC (!px4_arch_gpioread(GPIO_VDD_5V_HIPOWER_nOC))
+
+
+/* This board provides a DMA pool and APIs */
+#define BOARD_DMA_ALLOC_POOL_SIZE 5120
+
+/* This board provides the board_on_reset interface */
+
+#define BOARD_HAS_ON_RESET 1
+#define SDMMC_PIN_OFF(def) (((def) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_2MHz))
+
+#define PX4_GPIO_INIT_LIST { \
+ PX4_ADC_GPIO, \
+ GPIO_HW_REV_DRIVE, \
+ GPIO_HW_VER_DRIVE, \
+ GPIO_CAN1_TX, \
+ GPIO_CAN1_RX, \
+ GPIO_CAN1_SILENT_S0, \
+ GPIO_HEATER_OUTPUT, \
+ GPIO_nPOWER_IN_A, \
+ GPIO_nPOWER_IN_B, \
+ GPIO_VDD_5V_PERIPH_nEN, \
+ GPIO_VDD_5V_PERIPH_nOC, \
+ GPIO_VDD_5V_HIPOWER_nEN, \
+ GPIO_VDD_5V_HIPOWER_nOC, \
+ SDMMC_PIN_OFF(GPIO_SDMMC1_D0), \
+ SDMMC_PIN_OFF(GPIO_SDMMC1_D1), \
+ SDMMC_PIN_OFF(GPIO_SDMMC1_D2), \
+ SDMMC_PIN_OFF(GPIO_SDMMC1_D3), \
+ SDMMC_PIN_OFF(GPIO_SDMMC1_CMD), \
+ GPIO_VDD_3V3_SD_CARD_EN, \
+ GPIO_TONE_ALARM_IDLE, \
+ }
+
+#define BOARD_ENABLE_CONSOLE_BUFFER
+
+__BEGIN_DECLS
+
+/****************************************************************************************************
+ * Public Types
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public data
+ ****************************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************************************
+ * Public Functions
+ ****************************************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_sdio_initialize
+ *
+ * Description:
+ * Initialize SDIO-based MMC/SD card support
+ *
+ ****************************************************************************/
+
+int stm32_sdio_initialize(void);
+
+/****************************************************************************************************
+ * Name: stm32_spiinitialize
+ *
+ * Description:
+ * Called to configure SPI chip select GPIO pins for the board.
+ *
+ ****************************************************************************************************/
+
+extern void stm32_spiinitialize(void);
+
+extern void stm32_usbinitialize(void);
+
+extern void board_peripheral_reset(int ms);
+
+#include
+
+#endif /* __ASSEMBLY__ */
+
+__END_DECLS
diff --git a/src/modules/ekf2/EKF/utils.hpp b/boards/siyi/n7/src/bootloader_main.c
similarity index 65%
rename from src/modules/ekf2/EKF/utils.hpp
rename to boards/siyi/n7/src/bootloader_main.c
index 4d911f6e20..cec6abd467 100644
--- a/src/modules/ekf2/EKF/utils.hpp
+++ b/boards/siyi/n7/src/bootloader_main.c
@@ -1,6 +1,6 @@
/****************************************************************************
*
- * Copyright (c) 2020-2022 PX4 Development Team. All rights reserved.
+ * Copyright (c) 2019-2021 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,45 +31,45 @@
*
****************************************************************************/
-#include
+/**
+ * @file bootloader_main.c
+ *
+ * FMU-specific early startup code for bootloader
+*/
-#ifndef EKF_UTILS_HPP
-#define EKF_UTILS_HPP
+#include "board_config.h"
+#include "bl.h"
-// Use Kahan summation algorithm to get the sum of "sum_previous" and "input".
-// This function relies on the caller to be responsible for keeping a copy of
-// "accumulator" and passing this value at the next iteration.
-// Ref: https://en.wikipedia.org/wiki/Kahan_summation_algorithm
-inline float kahanSummation(float sum_previous, float input, float &accumulator)
+#include
+#include
+#include
+#include
+#include
+#include "arm_internal.h"
+#include
+
+extern int sercon_main(int c, char **argv);
+
+__EXPORT void board_on_reset(int status) {}
+
+__EXPORT void stm32_boardinitialize(void)
{
- const float y = input - accumulator;
- const float t = sum_previous + y;
- accumulator = (t - sum_previous) - y;
- return t;
+ /* configure USB interfaces */
+ stm32_usbinitialize();
}
-namespace ecl
+__EXPORT int board_app_initialize(uintptr_t arg)
{
-inline float powf(float x, int exp)
-{
- float ret;
-
- if (exp > 0) {
- ret = x;
-
- for (int count = 1; count < exp; count++) {
- ret *= x;
- }
-
- return ret;
-
- } else if (exp < 0) {
- return 1.0f / ecl::powf(x, -exp);
- }
-
- return 1.0f;
+ return 0;
}
-} // namespace ecl
+void board_late_initialize(void)
+{
+ sercon_main(0, NULL);
+}
-#endif // EKF_UTILS_HPP
+extern void sys_tick_handler(void);
+void board_timerhook(void)
+{
+ sys_tick_handler();
+}
diff --git a/boards/siyi/n7/src/can.c b/boards/siyi/n7/src/can.c
new file mode 100644
index 0000000000..c71b2e8793
--- /dev/null
+++ b/boards/siyi/n7/src/can.c
@@ -0,0 +1,128 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2012 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file px4fmu_can.c
+ *
+ * Board-specific CAN functions.
+ */
+
+#ifdef CONFIG_CAN
+
+#include
+#include
+
+#include
+#include
+
+#include "chip.h"
+#include "arm_internal.h"
+
+#include "chip.h"
+#include "stm32_can.h"
+#include "board_config.h"
+
+#ifdef CONFIG_CAN
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* Configuration ********************************************************************/
+
+#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2)
+# warning "Both CAN1 and CAN2 are enabled. Assuming only CAN1."
+# undef CONFIG_STM32_CAN2
+#endif
+
+#ifdef CONFIG_STM32_CAN1
+# define CAN_PORT 1
+#else
+# define CAN_PORT 2
+#endif
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+int can_devinit(void);
+
+/************************************************************************************
+ * Name: can_devinit
+ *
+ * Description:
+ * All STM32 architectures must provide the following interface to work with
+ * examples/can.
+ *
+ ************************************************************************************/
+
+int can_devinit(void)
+{
+ static bool initialized = false;
+ struct can_dev_s *can;
+ int ret;
+
+ /* Check if we have already initialized */
+
+ if (!initialized) {
+ /* Call stm32_caninitialize() to get an instance of the CAN interface */
+
+ can = stm32_caninitialize(CAN_PORT);
+
+ if (can == NULL) {
+ canerr("ERROR: Failed to get CAN interface\n");
+ return -ENODEV;
+ }
+
+ /* Register the CAN driver at "/dev/can0" */
+
+ ret = can_register("/dev/can0", can);
+
+ if (ret < 0) {
+ canerr("ERROR: can_register failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Now we are initialized */
+
+ initialized = true;
+ }
+
+ return OK;
+}
+
+#endif
+
+#endif /* CONFIG_CAN */
diff --git a/boards/siyi/n7/src/hw_config.h b/boards/siyi/n7/src/hw_config.h
new file mode 100644
index 0000000000..a6b71126e0
--- /dev/null
+++ b/boards/siyi/n7/src/hw_config.h
@@ -0,0 +1,128 @@
+/*
+ * hw_config.h
+ *
+ * Created on: May 17, 2015
+ * Author: david_s5
+ */
+
+#ifndef HW_CONFIG_H_
+#define HW_CONFIG_H_
+
+/****************************************************************************
+ * 10-8--2016:
+ * To simplify the ripple effect on the tools, we will be using
+ * /dev/serial/by-id/PX4 to locate PX4 devices. Therefore
+ * moving forward all Bootloaders must contain the prefix "PX4 BL "
+ * in the USBDEVICESTRING
+ * This Change will be made in an upcoming BL release
+ ****************************************************************************/
+/*
+ * Define usage to configure a bootloader
+ *
+ *
+ * Constant example Usage
+ * APP_LOAD_ADDRESS 0x08004000 - The address in Linker Script, where the app fw is org-ed
+ * BOOTLOADER_DELAY 5000 - Ms to wait while under USB pwr or bootloader request
+ * BOARD_FMUV2
+ * INTERFACE_USB 1 - (Optional) Scan and use the USB interface for bootloading
+ * INTERFACE_USART 1 - (Optional) Scan and use the Serial interface for bootloading
+ * USBDEVICESTRING "PX4 BL FMU v2.x" - USB id string
+ * USBPRODUCTID 0x0011 - PID Should match defconfig
+ * BOOT_DELAY_ADDRESS 0x000001a0 - (Optional) From the linker script from Linker Script to get a custom
+ * delay provided by an APP FW
+ * BOARD_TYPE 9 - Must match .prototype boad_id
+ * _FLASH_KBYTES (*(uint16_t *)0x1fff7a22) - Run time flash size detection
+ * BOARD_FLASH_SECTORS ((_FLASH_KBYTES == 0x400) ? 11 : 23) - Run time determine the physical last sector
+ * BOARD_FLASH_SECTORS 11 - Hard coded zero based last sector
+ * BOARD_FLASH_SIZE (_FLASH_KBYTES*1024)- Total Flash size of device, determined at run time.
+ * (1024 * 1024) - Hard coded Total Flash of device - The bootloader and app reserved will be deducted
+ * programmatically
+ *
+ * BOARD_FIRST_FLASH_SECTOR_TO_ERASE 2 - Optional sectors index in the flash_sectors table (F4 only), to begin erasing.
+ * This is to allow sectors to be reserved for app fw usage. That will NOT be erased
+ * during a FW upgrade.
+ * The default is 0, and selects the first sector to be erased, as the 0th entry in the
+ * flash_sectors table. Which is the second physical sector of FLASH in the device.
+ * The first physical sector of FLASH is used by the bootloader, and is not defined
+ * in the table.
+ *
+ * APP_RESERVATION_SIZE (BOARD_FIRST_FLASH_SECTOR_TO_ERASE * 16 * 1024) - Number of bytes reserved by the APP FW. This number plus
+ * BOOTLOADER_RESERVATION_SIZE will be deducted from
+ * BOARD_FLASH_SIZE to determine the size of the App FW
+ * and hence the address space of FLASH to erase and program.
+ * USBMFGSTRING "PX4 AP" - Optional USB MFG string (default is '3D Robotics' if not defined.)
+ * SERIAL_BREAK_DETECT_DISABLED - Optional prevent break selection on Serial port from entering or staying in BL
+ *
+ * * Other defines are somewhat self explanatory.
+ */
+
+/* Boot device selection list*/
+#define USB0_DEV 0x01
+#define SERIAL0_DEV 0x02
+#define SERIAL1_DEV 0x04
+
+#define APP_LOAD_ADDRESS 0x08020000
+#define BOOTLOADER_DELAY 5000
+#define INTERFACE_USB 1
+#define INTERFACE_USB_CONFIG "/dev/ttyACM0"
+#define BOARD_VBUS MK_GPIO_INPUT(GPIO_OTGFS_VBUS)
+
+//#define USE_VBUS_PULL_DOWN
+#define INTERFACE_USART 1
+#define INTERFACE_USART_CONFIG "/dev/ttyS0,115200"
+#define BOOT_DELAY_ADDRESS 0x000001a0
+#define BOARD_TYPE 1123
+#define _FLASH_KBYTES (*(uint32_t *)0x1FF1E880)
+#define BOARD_FLASH_SECTORS (15)
+#define BOARD_FLASH_SIZE (_FLASH_KBYTES * 1024)
+
+#define OSC_FREQ 16
+
+#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE
+#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_RED // RED
+#define BOARD_LED_ON 0
+#define BOARD_LED_OFF 1
+
+#define SERIAL_BREAK_DETECT_DISABLED 1
+
+/*
+ * Uncommenting this allows to force the bootloader through
+ * a PWM output pin. As this can accidentally initialize
+ * an ESC prematurely, it is not recommended. This feature
+ * has not been used and hence defaults now to off.
+ *
+ * # define BOARD_FORCE_BL_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN14)
+ * # define BOARD_FORCE_BL_PIN_IN (GPIO_INPUT|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11)
+ *
+ * # define BOARD_POWER_PIN_OUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4)
+ * # define BOARD_POWER_ON 1
+ * # define BOARD_POWER_OFF 0
+ * # undef BOARD_POWER_PIN_RELEASE // Leave pin enabling Power - un comment to release (disable power)
+ *
+*/
+
+#if !defined(ARCH_SN_MAX_LENGTH)
+# define ARCH_SN_MAX_LENGTH 12
+#endif
+
+#if !defined(APP_RESERVATION_SIZE)
+# define APP_RESERVATION_SIZE 0
+#endif
+
+#if !defined(BOARD_FIRST_FLASH_SECTOR_TO_ERASE)
+# define BOARD_FIRST_FLASH_SECTOR_TO_ERASE 1
+#endif
+
+#if !defined(USB_DATA_ALIGN)
+# define USB_DATA_ALIGN
+#endif
+
+#ifndef BOOT_DEVICES_SELECTION
+# define BOOT_DEVICES_SELECTION USB0_DEV|SERIAL0_DEV|SERIAL1_DEV
+#endif
+
+#ifndef BOOT_DEVICES_FILTER_ONUSB
+# define BOOT_DEVICES_FILTER_ONUSB USB0_DEV|SERIAL0_DEV|SERIAL1_DEV
+#endif
+
+#endif /* HW_CONFIG_H_ */
diff --git a/boards/siyi/n7/src/i2c.cpp b/boards/siyi/n7/src/i2c.cpp
new file mode 100644
index 0000000000..124fc2375c
--- /dev/null
+++ b/boards/siyi/n7/src/i2c.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2020 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include
+
+constexpr px4_i2c_bus_t px4_i2c_buses[I2C_BUS_MAX_BUS_ITEMS] = {
+ initI2CBusExternal(1),
+ initI2CBusExternal(2),
+ initI2CBusInternal(3),
+ initI2CBusExternal(4),
+};
diff --git a/boards/siyi/n7/src/init.c b/boards/siyi/n7/src/init.c
new file mode 100644
index 0000000000..46cf4ae4aa
--- /dev/null
+++ b/boards/siyi/n7/src/init.c
@@ -0,0 +1,269 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2012-2019, 2022 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file init.c
+ *
+ * PX4FMU-specific early startup code. This file implements the
+ * board_app_initialize() function that is called early by nsh during startup.
+ *
+ * Code here is run before the rcS script is invoked; it should start required
+ * subsystems and perform board-specific initialisation.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "board_config.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "arm_internal.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/*
+ * Ideally we'd be able to get these from arm_internal.h,
+ * but since we want to be able to disable the NuttX use
+ * of leds for system indication at will and there is no
+ * separate switch, we need to build independent of the
+ * CONFIG_ARCH_LEDS configuration switch.
+ */
+__BEGIN_DECLS
+extern void led_init(void);
+extern void led_on(int led);
+extern void led_off(int led);
+__END_DECLS
+
+
+/************************************************************************************
+ * Name: board_peripheral_reset
+ *
+ * Description:
+ *
+ ************************************************************************************/
+__EXPORT void board_peripheral_reset(int ms)
+{
+ /* set the peripheral rails off */
+
+ VDD_5V_PERIPH_EN(false);
+ board_control_spi_sensors_power(false, 0xffff);
+
+ /* wait for the peripheral rail to reach GND */
+ usleep(ms * 1000);
+ syslog(LOG_DEBUG, "reset done, %d ms\n", ms);
+
+ /* re-enable power */
+ board_control_spi_sensors_power(true, 0xffff);
+ VDD_5V_PERIPH_EN(true);
+}
+
+/************************************************************************************
+ * Name: board_on_reset
+ *
+ * Description:
+ * Optionally provided function called on entry to board_system_reset
+ * It should perform any house keeping prior to the rest.
+ *
+ * status - 1 if resetting to boot loader
+ * 0 if just resetting
+ *
+ ************************************************************************************/
+__EXPORT void board_on_reset(int status)
+{
+ for (int i = 0; i < DIRECT_PWM_OUTPUT_CHANNELS; ++i) {
+ px4_arch_configgpio(PX4_MAKE_GPIO_INPUT(io_timer_channel_get_as_pwm_input(i)));
+ }
+
+ if (status >= 0) {
+ up_mdelay(6);
+ }
+}
+
+/************************************************************************************
+ * Name: stm32_boardinitialize
+ *
+ * Description:
+ * All STM32 architectures must provide the following entry point. This entry point
+ * is called early in the initialization -- after all memory has been configured
+ * and mapped but before any devices have been initialized.
+ *
+ ************************************************************************************/
+
+__EXPORT void
+stm32_boardinitialize(void)
+{
+ board_on_reset(-1); /* Reset PWM first thing */
+
+ /* configure LEDs */
+
+ board_autoled_initialize();
+
+ /* configure pins */
+
+ const uint32_t gpio[] = PX4_GPIO_INIT_LIST;
+ px4_gpio_init(gpio, arraySize(gpio));
+
+ board_control_spi_sensors_power_configgpio();
+
+ /* configure USB interfaces */
+
+ stm32_usbinitialize();
+
+}
+
+/****************************************************************************
+ * Name: board_app_initialize
+ *
+ * Description:
+ * Perform application specific initialization. This function is never
+ * called directly from application code, but only indirectly via the
+ * (non-standard) boardctl() interface using the command BOARDIOC_INIT.
+ *
+ * Input Parameters:
+ * arg - The boardctl() argument is passed to the board_app_initialize()
+ * implementation without modification. The argument has no
+ * meaning to NuttX; the meaning of the argument is a contract
+ * between the board-specific initalization logic and the the
+ * matching application logic. The value cold be such things as a
+ * mode enumeration value, a set of DIP switch switch settings, a
+ * pointer to configuration data read from a file or serial FLASH,
+ * or whatever you would like to do with it. Every implementation
+ * should accept zero/NULL as a default configuration.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+__EXPORT int board_app_initialize(uintptr_t arg)
+{
+ /* Power on Interfaces */
+ VDD_5V_PERIPH_EN(true);
+ VDD_5V_HIPOWER_EN(true);
+ board_control_spi_sensors_power(true, 0xffff);
+
+ /* Need hrt running before using the ADC */
+
+ px4_platform_init();
+
+ // Use the default HW_VER_REV(0x0,0x0) for Ramtron
+
+ stm32_spiinitialize();
+
+ /* Configure the HW based on the manifest */
+
+ px4_platform_configure();
+
+ if (OK == board_determine_hw_info()) {
+ syslog(LOG_INFO, "[boot] Rev 0x%1x : Ver 0x%1x %s\n", board_get_hw_revision(), board_get_hw_version(),
+ board_get_hw_type_name());
+
+ } else {
+ syslog(LOG_ERR, "[boot] Failed to read HW revision and version\n");
+ }
+
+ /* Configure the actual SPI interfaces (after we determined the HW version) */
+
+ stm32_spiinitialize();
+
+ /* configure the DMA allocator */
+
+ if (board_dma_alloc_init() < 0) {
+ syslog(LOG_ERR, "[boot] DMA alloc FAILED\n");
+ }
+
+#if defined(SERIAL_HAVE_RXDMA)
+ // set up the serial DMA polling at 1ms intervals for received bytes that have not triggered a DMA event.
+ static struct hrt_call serial_dma_call;
+ hrt_call_every(&serial_dma_call, 1000, 1000, (hrt_callout)stm32_serial_dma_poll, NULL);
+#endif
+
+ /* initial LED state */
+ drv_led_start();
+ led_off(LED_RED);
+ led_on(LED_GREEN); // Indicate Power.
+ led_off(LED_BLUE);
+
+ if (board_hardfault_init(2, true) != 0) {
+ led_on(LED_RED);
+ }
+
+ // Ensure Power is off for > 10 mS
+ usleep(15 * 1000);
+ VDD_3V3_SD_CARD_EN(true);
+ usleep(500 * 1000);
+
+#ifdef CONFIG_MMCSD
+ int ret = stm32_sdio_initialize();
+
+ if (ret != OK) {
+ led_on(LED_RED);
+ }
+
+#endif /* CONFIG_MMCSD */
+
+ return OK;
+}
diff --git a/boards/siyi/n7/src/led.c b/boards/siyi/n7/src/led.c
new file mode 100644
index 0000000000..df40a23dca
--- /dev/null
+++ b/boards/siyi/n7/src/led.c
@@ -0,0 +1,235 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2013 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file px4fmu2_led.c
+ *
+ * PX4FMU LED backend.
+ */
+
+#include
+
+#include
+
+#include "chip.h"
+#include "stm32_gpio.h"
+#include "board_config.h"
+
+#include
+#include
+
+/*
+ * Ideally we'd be able to get these from arm_internal.h,
+ * but since we want to be able to disable the NuttX use
+ * of leds for system indication at will and there is no
+ * separate switch, we need to build independent of the
+ * CONFIG_ARCH_LEDS configuration switch.
+ */
+__BEGIN_DECLS
+extern void led_init(void);
+extern void led_on(int led);
+extern void led_off(int led);
+extern void led_toggle(int led);
+__END_DECLS
+
+#ifdef CONFIG_ARCH_LEDS
+static bool nuttx_owns_leds = true;
+// B R S G
+// 0 1 2 3
+static const uint8_t xlatpx4[] = {1, 2, 4, 0};
+# define xlat(p) xlatpx4[(p)]
+static uint32_t g_ledmap[] = {
+ GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN
+ GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE
+ GPIO_nLED_RED, // Indexed by BOARD_LED_RED
+ GPIO_nSAFETY_SWITCH_LED_OUT, // Indexed by LED_SAFETY by xlatpx4
+};
+
+#else
+
+# define xlat(p) (p)
+static uint32_t g_ledmap[] = {
+ GPIO_nLED_BLUE, // Indexed by LED_BLUE
+ GPIO_nLED_RED, // Indexed by LED_RED, LED_AMBER
+ 0, // Indexed by LED_SAFETY (defaulted to an input)
+ 0, // Indexed by LED_GREEN
+};
+
+#endif
+
+__EXPORT void led_init(void)
+{
+ for (size_t l = 0; l < (sizeof(g_ledmap) / sizeof(g_ledmap[0])); l++) {
+ if (g_ledmap[l] != 0) {
+ stm32_configgpio(g_ledmap[l]);
+ }
+ }
+}
+
+static void phy_set_led(int led, bool state)
+{
+ /* Drive Low to switch on */
+
+ if (g_ledmap[led] != 0) {
+ stm32_gpiowrite(g_ledmap[led], !state);
+ }
+}
+
+static bool phy_get_led(int led)
+{
+ /* If Low it is on */
+ if (g_ledmap[led] != 0) {
+ return !stm32_gpioread(g_ledmap[led]);
+ }
+
+ return false;
+}
+
+__EXPORT void led_on(int led)
+{
+ phy_set_led(xlat(led), true);
+}
+
+__EXPORT void led_off(int led)
+{
+ phy_set_led(xlat(led), false);
+}
+
+__EXPORT void led_toggle(int led)
+{
+ phy_set_led(xlat(led), !phy_get_led(xlat(led)));
+}
+
+#ifdef CONFIG_ARCH_LEDS
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_autoled_initialize
+ ****************************************************************************/
+
+void board_autoled_initialize(void)
+{
+ led_init();
+}
+
+/****************************************************************************
+ * Name: board_autoled_on
+ ****************************************************************************/
+
+void board_autoled_on(int led)
+{
+ if (!nuttx_owns_leds) {
+ return;
+ }
+
+ switch (led) {
+ default:
+ break;
+
+ case LED_HEAPALLOCATE:
+ phy_set_led(BOARD_LED_BLUE, true);
+ break;
+
+ case LED_IRQSENABLED:
+ phy_set_led(BOARD_LED_BLUE, false);
+ phy_set_led(BOARD_LED_GREEN, true);
+ break;
+
+ case LED_STACKCREATED:
+ phy_set_led(BOARD_LED_GREEN, true);
+ phy_set_led(BOARD_LED_BLUE, true);
+ break;
+
+ case LED_INIRQ:
+ phy_set_led(BOARD_LED_BLUE, true);
+ break;
+
+ case LED_SIGNAL:
+ phy_set_led(BOARD_LED_GREEN, true);
+ break;
+
+ case LED_ASSERTION:
+ phy_set_led(BOARD_LED_RED, true);
+ phy_set_led(BOARD_LED_BLUE, true);
+ break;
+
+ case LED_PANIC:
+ phy_set_led(BOARD_LED_RED, true);
+ break;
+
+ case LED_IDLE : /* IDLE */
+ phy_set_led(BOARD_LED_RED, true);
+ break;
+ }
+}
+
+/****************************************************************************
+ * Name: board_autoled_off
+ ****************************************************************************/
+
+void board_autoled_off(int led)
+{
+ if (!nuttx_owns_leds) {
+ return;
+ }
+
+ switch (led) {
+ default:
+ break;
+
+ case LED_SIGNAL:
+ phy_set_led(BOARD_LED_GREEN, false);
+ break;
+
+ case LED_INIRQ:
+ phy_set_led(BOARD_LED_BLUE, false);
+ break;
+
+ case LED_ASSERTION:
+ phy_set_led(BOARD_LED_RED, false);
+ phy_set_led(BOARD_LED_BLUE, false);
+ break;
+
+ case LED_PANIC:
+ phy_set_led(BOARD_LED_RED, false);
+ break;
+
+ case LED_IDLE : /* IDLE */
+ phy_set_led(BOARD_LED_RED, false);
+ break;
+ }
+}
+
+#endif /* CONFIG_ARCH_LEDS */
diff --git a/boards/siyi/n7/src/manifest.c b/boards/siyi/n7/src/manifest.c
new file mode 100644
index 0000000000..4bf33cab90
--- /dev/null
+++ b/boards/siyi/n7/src/manifest.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2018-2021 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file manifest.c
+ *
+ * This module supplies the interface to the manifest of hardware that is
+ * optional and dependent on the HW REV and HW VER IDs
+ *
+ * The manifest allows the system to know whether a hardware option
+ * say for example the PX4IO is an no-pop option vs it is broken.
+ *
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include "systemlib/px4_macros.h"
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+typedef struct {
+ uint32_t hw_ver_rev; /* the version and revision */
+ const px4_hw_mft_item_t *mft; /* The first entry */
+ uint32_t entries; /* the lenght of the list */
+} px4_hw_mft_list_entry_t;
+
+typedef px4_hw_mft_list_entry_t *px4_hw_mft_list_entry;
+#define px4_hw_mft_list_uninitialized (px4_hw_mft_list_entry) -1
+
+static const px4_hw_mft_item_t device_unsupported = {0, 0, 0};
+
+// List of components on a specific board configuration
+// The index of those components is given by the enum (px4_hw_mft_item_id_t)
+// declared in board_common.h
+static const px4_hw_mft_item_t hw_mft_list_board[] = {
+ {
+ .present = 1,
+ .mandatory = 1,
+ .connection = px4_hw_con_onboard,
+ },
+};
+
+static px4_hw_mft_list_entry_t mft_lists[] = {
+// ver_rev
+ {VER00, hw_mft_list_board, arraySize(hw_mft_list_board)},
+};
+
+/************************************************************************************
+ * Name: board_query_manifest
+ *
+ * Description:
+ * Optional returns manifest item.
+ *
+ * Input Parameters:
+ * manifest_id - the ID for the manifest item to retrieve
+ *
+ * Returned Value:
+ * 0 - item is not in manifest => assume legacy operations
+ * pointer to a manifest item
+ *
+ ************************************************************************************/
+
+__EXPORT px4_hw_mft_item board_query_manifest(px4_hw_mft_item_id_t id)
+{
+ static px4_hw_mft_list_entry boards_manifest = px4_hw_mft_list_uninitialized;
+
+ if (boards_manifest == px4_hw_mft_list_uninitialized) {
+ uint32_t ver_rev = board_get_hw_version() << 16;
+ ver_rev |= board_get_hw_revision();
+
+ for (unsigned i = 0; i < arraySize(mft_lists); i++) {
+ if (mft_lists[i].hw_ver_rev == ver_rev) {
+ boards_manifest = &mft_lists[i];
+ break;
+ }
+ }
+
+ if (boards_manifest == px4_hw_mft_list_uninitialized) {
+ syslog(LOG_ERR, "[boot] Board %08" PRIx32 " is not supported!\n", ver_rev);
+ }
+ }
+
+ px4_hw_mft_item rv = &device_unsupported;
+
+ if (boards_manifest != px4_hw_mft_list_uninitialized &&
+ id < boards_manifest->entries) {
+ rv = &boards_manifest->mft[id];
+ }
+
+ return rv;
+}
diff --git a/boards/siyi/n7/src/sdio.c b/boards/siyi/n7/src/sdio.c
new file mode 100644
index 0000000000..869d757756
--- /dev/null
+++ b/boards/siyi/n7/src/sdio.c
@@ -0,0 +1,177 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "chip.h"
+#include "board_config.h"
+#include "stm32_gpio.h"
+#include "stm32_sdmmc.h"
+
+#ifdef CONFIG_MMCSD
+
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Card detections requires card support and a card detection GPIO */
+
+#define HAVE_NCD 1
+#if !defined(GPIO_SDMMC1_NCD)
+# undef HAVE_NCD
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static FAR struct sdio_dev_s *sdio_dev;
+#ifdef HAVE_NCD
+static bool g_sd_inserted = 0xff; /* Impossible value */
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_ncd_interrupt
+ *
+ * Description:
+ * Card detect interrupt handler.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_NCD
+static int stm32_ncd_interrupt(int irq, FAR void *context)
+{
+ bool present;
+
+ present = !stm32_gpioread(GPIO_SDMMC1_NCD);
+
+ if (sdio_dev && present != g_sd_inserted) {
+ sdio_mediachange(sdio_dev, present);
+ g_sd_inserted = present;
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_sdio_initialize
+ *
+ * Description:
+ * Initialize SDIO-based MMC/SD card support
+ *
+ ****************************************************************************/
+
+int stm32_sdio_initialize(void)
+{
+ int ret;
+
+#ifdef HAVE_NCD
+ /* Card detect */
+
+ bool cd_status;
+
+ /* Configure the card detect GPIO */
+
+ stm32_configgpio(GPIO_SDMMC1_NCD);
+
+ /* Register an interrupt handler for the card detect pin */
+
+ stm32_gpiosetevent(GPIO_SDMMC1_NCD, true, true, true, stm32_ncd_interrupt);
+#endif
+
+ /* Mount the SDIO-based MMC/SD block driver */
+ /* First, get an instance of the SDIO interface */
+
+ finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO);
+
+ sdio_dev = sdio_initialize(SDIO_SLOTNO);
+
+ if (!sdio_dev) {
+ syslog(LOG_ERR, "[boot] Failed to initialize SDIO slot %d\n", SDIO_SLOTNO);
+ return -ENODEV;
+ }
+
+ /* Now bind the SDIO interface to the MMC/SD driver */
+
+ finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR);
+
+ ret = mmcsd_slotinitialize(SDIO_MINOR, sdio_dev);
+
+ if (ret != OK) {
+ syslog(LOG_ERR, "[boot] Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
+ return ret;
+ }
+
+ finfo("Successfully bound SDIO to the MMC/SD driver\n");
+
+#ifdef HAVE_NCD
+ /* Use SD card detect pin to check if a card is g_sd_inserted */
+
+ cd_status = !stm32_gpioread(GPIO_SDMMC1_NCD);
+ finfo("Card detect : %d\n", cd_status);
+
+ sdio_mediachange(sdio_dev, cd_status);
+#else
+ /* Assume that the SD card is inserted. What choice do we have? */
+
+ sdio_mediachange(sdio_dev, true);
+#endif
+
+ return OK;
+}
+
+#endif /* CONFIG_MMCSD */
diff --git a/boards/siyi/n7/src/spi.cpp b/boards/siyi/n7/src/spi.cpp
new file mode 100644
index 0000000000..c78c7bb250
--- /dev/null
+++ b/boards/siyi/n7/src/spi.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2020-2021 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include
+#include
+#include
+
+constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
+ initSPIBus(SPI::Bus::SPI1, {
+ initSPIDevice(DRV_IMU_DEVTYPE_ICM20689, SPI::CS{GPIO::PortF, GPIO::Pin2}, SPI::DRDY{GPIO::PortB, GPIO::Pin4}),
+ initSPIDevice(DRV_GYR_DEVTYPE_BMI088, SPI::CS{GPIO::PortF, GPIO::Pin4}, SPI::DRDY{GPIO::PortB, GPIO::Pin14}),
+ initSPIDevice(DRV_ACC_DEVTYPE_BMI088, SPI::CS{GPIO::PortG, GPIO::Pin10}, SPI::DRDY{GPIO::PortB, GPIO::Pin15}),
+ initSPIDevice(DRV_DEVTYPE_UNUSED, SPI::CS{GPIO::PortH, GPIO::Pin5}),
+ }, {GPIO::PortE, GPIO::Pin3}),
+ initSPIBus(SPI::Bus::SPI2, {
+ initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortF, GPIO::Pin5})
+ }),
+ initSPIBus(SPI::Bus::SPI4, {
+ initSPIDevice(DRV_BARO_DEVTYPE_MS5611, SPI::CS{GPIO::PortF, GPIO::Pin10}),
+ }),
+};
+
+static constexpr bool unused = validateSPIConfig(px4_spi_buses);
diff --git a/boards/siyi/n7/src/timer_config.cpp b/boards/siyi/n7/src/timer_config.cpp
new file mode 100644
index 0000000000..c9bc0acd46
--- /dev/null
+++ b/boards/siyi/n7/src/timer_config.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2012 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include
+
+constexpr io_timers_t io_timers[MAX_IO_TIMERS] = {
+ initIOTimer(Timer::Timer1, DMA{DMA::Index1}),
+ initIOTimer(Timer::Timer4, DMA{DMA::Index1}),
+};
+
+constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
+ initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}),
+ initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortA, GPIO::Pin10}),
+ initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}),
+ initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortE, GPIO::Pin9}),
+ initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel2}, {GPIO::PortD, GPIO::Pin13}),
+};
+
+constexpr io_timers_channel_mapping_t io_timers_channel_mapping =
+ initIOTimerChannelMapping(io_timers, timer_io_channels);
diff --git a/boards/siyi/n7/src/usb.c b/boards/siyi/n7/src/usb.c
new file mode 100644
index 0000000000..6d42476b71
--- /dev/null
+++ b/boards/siyi/n7/src/usb.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2016 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file px4fmu_usb.c
+ *
+ * Board-specific USB functions.
+ */
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include "board_config.h"
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_usbinitialize
+ *
+ * Description:
+ * Called to setup USB-related GPIO pins for the PX4FMU board.
+ *
+ ************************************************************************************/
+
+__EXPORT void stm32_usbinitialize(void)
+{
+ /* The OTG FS has an internal soft pull-up */
+
+ /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */
+
+#ifdef CONFIG_STM32H7_OTGFS
+ stm32_configgpio(GPIO_OTGFS_VBUS);
+#endif
+}
+
+/************************************************************************************
+ * Name: stm32_usbsuspend
+ *
+ * Description:
+ * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is
+ * used. This function is called whenever the USB enters or leaves suspend mode.
+ * This is an opportunity for the board logic to shutdown clocks, power, etc.
+ * while the USB is suspended.
+ *
+ ************************************************************************************/
+
+__EXPORT void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume)
+{
+ uinfo("resume: %d\n", resume);
+}
diff --git a/boards/sky-drones/smartap-airlink/nuttx-config/nsh/defconfig b/boards/sky-drones/smartap-airlink/nuttx-config/nsh/defconfig
index 3efa0c136f..25c5120d57 100644
--- a/boards/sky-drones/smartap-airlink/nuttx-config/nsh/defconfig
+++ b/boards/sky-drones/smartap-airlink/nuttx-config/nsh/defconfig
@@ -115,7 +115,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_IOB_NBUFFERS=24
CONFIG_IOB_THROTTLE=0
CONFIG_IPCFG_BINARY=y
@@ -181,6 +181,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=245760
CONFIG_RAM_START=0x20010000
diff --git a/boards/sky-drones/smartap-airlink/src/mtd.cpp b/boards/sky-drones/smartap-airlink/src/mtd.cpp
index 8b74a4617c..742b463041 100644
--- a/boards/sky-drones/smartap-airlink/src/mtd.cpp
+++ b/boards/sky-drones/smartap-airlink/src/mtd.cpp
@@ -34,7 +34,7 @@
#include
#include
// KiB BS nB
-static const px4_mft_device_t spi5 = { // FM25V02A on FMUM 32K 512 X 64
+static const px4_mft_device_t spi5 = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
@@ -45,18 +45,12 @@ static const px4_mft_device_t i2c3 = { // 24LC64T on Base 8K 32 X 2
static const px4_mtd_entry_t fmum_fram = {
.device = &spi5,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/boards/spracing/h7extreme/init/rc.board_defaults b/boards/spracing/h7extreme/init/rc.board_defaults
index 34177ec437..d2b9948883 100644
--- a/boards/spracing/h7extreme/init/rc.board_defaults
+++ b/boards/spracing/h7extreme/init/rc.board_defaults
@@ -14,8 +14,7 @@ param set-default SYS_AUTOSTART 4050
# use the Q attitude estimator, it works w/o mag or GPS.
param set-default SYS_MC_EST_GROUP 3
-param set-default ATT_ACC_COMP 0
-param set-default ATT_W_ACC 0.4000
-param set-default ATT_W_GYRO_BIAS 0.0000
+param set-default ATT_W_ACC 0.4
+param set-default ATT_W_GYRO_BIAS 0
param set-default SYS_HAS_MAG 0
diff --git a/boards/thepeach/k1/nuttx-config/nsh/defconfig b/boards/thepeach/k1/nuttx-config/nsh/defconfig
index 3a63ed05bb..78c6bde8df 100644
--- a/boards/thepeach/k1/nuttx-config/nsh/defconfig
+++ b/boards/thepeach/k1/nuttx-config/nsh/defconfig
@@ -108,7 +108,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -141,6 +141,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/thepeach/r1/nuttx-config/nsh/defconfig b/boards/thepeach/r1/nuttx-config/nsh/defconfig
index 51a9be25a1..75c975f76f 100644
--- a/boards/thepeach/r1/nuttx-config/nsh/defconfig
+++ b/boards/thepeach/r1/nuttx-config/nsh/defconfig
@@ -108,7 +108,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
CONFIG_LIBC_STRERROR=y
@@ -141,6 +141,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/boards/uvify/core/nuttx-config/nsh/defconfig b/boards/uvify/core/nuttx-config/nsh/defconfig
index 0dcb89b2b3..6d8e82e9f5 100644
--- a/boards/uvify/core/nuttx-config/nsh/defconfig
+++ b/boards/uvify/core/nuttx-config/nsh/defconfig
@@ -106,7 +106,7 @@ CONFIG_I2C=y
CONFIG_I2C_RESET=y
CONFIG_IDLETHREAD_STACKSIZE=750
CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=2944
+CONFIG_INIT_STACKSIZE=3194
CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LONG_LONG=y
CONFIG_LIBC_MAX_EXITFUNS=1
@@ -140,6 +140,8 @@ CONFIG_PREALLOC_TIMERS=50
CONFIG_PRIORITY_INHERITANCE=y
CONFIG_PTHREAD_MUTEX_ROBUST=y
CONFIG_PTHREAD_STACK_MIN=512
+CONFIG_RAMTRON_EMULATE_PAGE_SHIFT=5
+CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT=5
CONFIG_RAMTRON_SETSPEED=y
CONFIG_RAM_SIZE=262144
CONFIG_RAM_START=0x20000000
diff --git a/cmake/gtest/px4_add_gtest.cmake b/cmake/gtest/px4_add_gtest.cmake
index 1a54456194..c93b15734a 100644
--- a/cmake/gtest/px4_add_gtest.cmake
+++ b/cmake/gtest/px4_add_gtest.cmake
@@ -107,6 +107,7 @@ function(px4_add_functional_gtest)
px4_daemon
work_queue
parameters
+ events
perf
tinybson
uorb_msgs
diff --git a/cmake/kconfig.cmake b/cmake/kconfig.cmake
index ea5e48800e..f96a62b67b 100644
--- a/cmake/kconfig.cmake
+++ b/cmake/kconfig.cmake
@@ -216,15 +216,17 @@ if(EXISTS ${BOARD_DEFCONFIG})
endforeach()
- # Put every module not in userspace also to kernel list
- foreach(modpath ${config_module_list})
+ if (CONFIG_BOARD_PROTECTED)
+ # Put every module not in userspace also to kernel list
+ foreach(modpath ${config_module_list})
get_filename_component(module ${modpath} NAME)
list(FIND config_user_list ${module} _index)
if (${_index} EQUAL -1)
list(APPEND config_kernel_list ${modpath})
endif()
- endforeach()
+ endforeach()
+ endif()
if(PLATFORM)
# set OS, and append specific platform module path
diff --git a/cmake/px4_add_module.cmake b/cmake/px4_add_module.cmake
index 5c0ee1153d..19d2c41da1 100644
--- a/cmake/px4_add_module.cmake
+++ b/cmake/px4_add_module.cmake
@@ -168,10 +168,11 @@ function(px4_add_module)
if(NOT DYNAMIC)
target_link_libraries(${MODULE} PRIVATE prebuild_targets px4_platform systemlib perf)
if (${PX4_PLATFORM} STREQUAL "nuttx" AND NOT CONFIG_BUILD_FLAT AND KERNEL)
- target_link_libraries(${MODULE} PRIVATE kernel_parameters_interface px4_kernel_layer uORB_kernel)
+ target_link_libraries(${MODULE} PRIVATE
+ kernel_events_interface kernel_parameters_interface px4_kernel_layer uORB_kernel)
set_property(GLOBAL APPEND PROPERTY PX4_KERNEL_MODULE_LIBRARIES ${MODULE})
else()
- target_link_libraries(${MODULE} PRIVATE parameters_interface px4_layer uORB)
+ target_link_libraries(${MODULE} PRIVATE events_interface parameters_interface px4_layer uORB)
set_property(GLOBAL APPEND PROPERTY PX4_MODULE_LIBRARIES ${MODULE})
endif()
set_property(GLOBAL APPEND PROPERTY PX4_MODULE_PATHS ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/integrationtests/python_src/px4_it/mavros/mission_test.py b/integrationtests/python_src/px4_it/mavros/mission_test.py
index fac011eb7d..8d7f6e6478 100755
--- a/integrationtests/python_src/px4_it/mavros/mission_test.py
+++ b/integrationtests/python_src/px4_it/mavros/mission_test.py
@@ -303,9 +303,12 @@ class MavrosMissionTest(MavrosTestCommon):
self.assertTrue(abs(res['roll_error_mean']) < 5.0, str(res))
self.assertTrue(abs(res['pitch_error_mean']) < 5.0, str(res))
self.assertTrue(abs(res['yaw_error_mean']) < 5.0, str(res))
+
self.assertTrue(res['roll_error_std'] < 5.0, str(res))
self.assertTrue(res['pitch_error_std'] < 5.0, str(res))
- self.assertTrue(res['yaw_error_std'] < 5.0, str(res))
+
+ # TODO: fix by excluding initial heading init and reset preflight
+ self.assertTrue(res['yaw_error_std'] < 10.0, str(res))
if __name__ == '__main__':
diff --git a/msg/ActuatorTest.msg b/msg/ActuatorTest.msg
index f880720da0..221258f906 100644
--- a/msg/ActuatorTest.msg
+++ b/msg/ActuatorTest.msg
@@ -18,4 +18,4 @@ float32 value # range: [-1, 1], where 1 means maximum positive output,
# and NaN maps to disarmed (stop the motors)
uint32 timeout_ms # timeout in ms after which to exit test mode (if 0, do not time out)
-uint8 ORB_QUEUE_LENGTH = 12 # same as MAX_NUM_MOTORS to support code in esc_calibration
+uint8 ORB_QUEUE_LENGTH = 16 # >= MAX_NUM_MOTORS to support code in esc_calibration
diff --git a/msg/CMakeLists.txt b/msg/CMakeLists.txt
index 611fea9e85..70b09f9cfe 100644
--- a/msg/CMakeLists.txt
+++ b/msg/CMakeLists.txt
@@ -60,6 +60,8 @@ set(msg_files
CollisionReport.msg
ControlAllocatorStatus.msg
Cpuload.msg
+ DatamanRequest.msg
+ DatamanResponse.msg
DebugArray.msg
DebugKeyValue.msg
DebugValue.msg
@@ -90,6 +92,7 @@ set(msg_files
FollowTargetStatus.msg
GeneratorStatus.msg
GeofenceResult.msg
+ GimbalControls.msg
GimbalDeviceAttitudeStatus.msg
GimbalDeviceInformation.msg
GimbalDeviceSetAttitude.msg
@@ -97,9 +100,12 @@ set(msg_files
GimbalManagerSetAttitude.msg
GimbalManagerSetManualControl.msg
GimbalManagerStatus.msg
+ GpioConfig.msg
+ GpioIn.msg
+ GpioOut.msg
+ GpioRequest.msg
GpsDump.msg
GpsInjectData.msg
- GimbalControls.msg
Gripper.msg
HealthReport.msg
HeaterStatus.msg
@@ -174,6 +180,7 @@ set(msg_files
SensorSelection.msg
SensorsStatus.msg
SensorsStatusImu.msg
+ SensorUwb.msg
SystemPower.msg
TakeoffStatus.msg
TaskStackInfo.msg
@@ -190,8 +197,6 @@ set(msg_files
UavcanParameterValue.msg
UlogStream.msg
UlogStreamAck.msg
- UwbDistance.msg
- UwbGrid.msg
VehicleAcceleration.msg
VehicleAirData.msg
VehicleAngularAccelerationSetpoint.msg
diff --git a/msg/DatamanRequest.msg b/msg/DatamanRequest.msg
new file mode 100644
index 0000000000..f819771a45
--- /dev/null
+++ b/msg/DatamanRequest.msg
@@ -0,0 +1,8 @@
+uint64 timestamp # time since system start (microseconds)
+
+uint8 client_id
+uint8 request_type # id/read/write/clear
+uint8 item # dm_item_t
+uint32 index
+uint8[56] data
+uint32 data_length
\ No newline at end of file
diff --git a/msg/DatamanResponse.msg b/msg/DatamanResponse.msg
new file mode 100644
index 0000000000..ebf752db50
--- /dev/null
+++ b/msg/DatamanResponse.msg
@@ -0,0 +1,15 @@
+uint64 timestamp # time since system start (microseconds)
+
+uint8 client_id
+uint8 request_type # id/read/write/clear
+uint8 item # dm_item_t
+uint32 index
+uint8[56] data
+
+uint8 STATUS_SUCCESS = 0
+uint8 STATUS_FAILURE_ID_ERR = 1
+uint8 STATUS_FAILURE_NO_DATA = 2
+uint8 STATUS_FAILURE_READ_FAILED = 3
+uint8 STATUS_FAILURE_WRITE_FAILED = 4
+uint8 STATUS_FAILURE_CLEAR_FAILED = 5
+uint8 status
diff --git a/msg/EstimatorAidSource1d.msg b/msg/EstimatorAidSource1d.msg
index 46faddafac..78273d6b06 100644
--- a/msg/EstimatorAidSource1d.msg
+++ b/msg/EstimatorAidSource1d.msg
@@ -14,7 +14,6 @@ float32 innovation
float32 innovation_variance
float32 test_ratio
-bool fusion_enabled # true when measurements are being fused
bool innovation_rejected # true if the observation has been rejected
bool fused # true if the sample was successfully fused
@@ -22,3 +21,4 @@ bool fused # true if the sample was successfully fused
# TOPICS estimator_aid_src_airspeed estimator_aid_src_sideslip
# TOPICS estimator_aid_src_fake_hgt
# TOPICS estimator_aid_src_mag_heading estimator_aid_src_gnss_yaw estimator_aid_src_ev_yaw
+# TOPICS estimator_aid_src_terrain_range_finder
diff --git a/msg/EstimatorAidSource2d.msg b/msg/EstimatorAidSource2d.msg
index 9fdba8fefa..2d33fc361d 100644
--- a/msg/EstimatorAidSource2d.msg
+++ b/msg/EstimatorAidSource2d.msg
@@ -14,7 +14,6 @@ float32[2] innovation
float32[2] innovation_variance
float32[2] test_ratio
-bool fusion_enabled # true when measurements are being fused
bool innovation_rejected # true if the observation has been rejected
bool fused # true if the sample was successfully fused
diff --git a/msg/EstimatorAidSource3d.msg b/msg/EstimatorAidSource3d.msg
index 5d143bc04d..deb4c05bd0 100644
--- a/msg/EstimatorAidSource3d.msg
+++ b/msg/EstimatorAidSource3d.msg
@@ -14,7 +14,6 @@ float32[3] innovation
float32[3] innovation_variance
float32[3] test_ratio
-bool fusion_enabled # true when measurements are being fused
bool innovation_rejected # true if the observation has been rejected
bool fused # true if the sample was successfully fused
diff --git a/msg/EstimatorStatus.msg b/msg/EstimatorStatus.msg
index f3b76f18ed..5491734b1d 100644
--- a/msg/EstimatorStatus.msg
+++ b/msg/EstimatorStatus.msg
@@ -127,3 +127,8 @@ uint32 mag_device_id
# legacy local position estimator (LPE) flags
uint8 health_flags # Bitmask to indicate sensor health states (vel, pos, hgt)
uint8 timeout_flags # Bitmask to indicate timeout flags (vel, pos, hgt)
+
+float32 mag_inclination_deg
+float32 mag_inclination_ref_deg
+float32 mag_strength_gs
+float32 mag_strength_ref_gs
diff --git a/msg/EstimatorStatusFlags.msg b/msg/EstimatorStatusFlags.msg
index 9d1f77403a..4d747d8268 100644
--- a/msg/EstimatorStatusFlags.msg
+++ b/msg/EstimatorStatusFlags.msg
@@ -39,6 +39,9 @@ bool cs_rng_kin_consistent # 31 - true when the range finder kinematic cons
bool cs_fake_pos # 32 - true when fake position measurements are being fused
bool cs_fake_hgt # 33 - true when fake height measurements are being fused
bool cs_gravity_vector # 34 - true when gravity vector measurements are being fused
+bool cs_mag # 35 - true if 3-axis magnetometer measurement fusion (mag states only) is intended
+bool cs_ev_yaw_fault # 36 - true when the EV heading has been declared faulty and is no longer being used
+bool cs_mag_heading_consistent # 37 - true when the heading obtained from mag data is declared consistent with the filter
# fault status
uint32 fault_status_changes # number of filter fault status (fs) changes
diff --git a/msg/GpioConfig.msg b/msg/GpioConfig.msg
new file mode 100644
index 0000000000..0ff393ec87
--- /dev/null
+++ b/msg/GpioConfig.msg
@@ -0,0 +1,28 @@
+# GPIO configuration
+
+uint64 timestamp # time since system start (microseconds)
+uint32 device_id # Device id
+
+uint32 mask # Pin mask
+uint32 state # Initial pin output state
+
+# Configuration Mask
+# Bit 0-3: Direction: 0=Input, 1=Output
+# Bit 4-7: Input Config: 0=Floating, 1=PullUp, 2=PullDown
+# Bit 8-12: Output Config: 0=PushPull, 1=OpenDrain
+# Bit 13-31: Reserved
+uint32 INPUT = 0 # 0x0000
+uint32 OUTPUT = 1 # 0x0001
+uint32 PULLUP = 16 # 0x0010
+uint32 PULLDOWN = 32 # 0x0020
+uint32 OPENDRAIN = 256 # 0x0100
+
+uint32 INPUT_FLOATING = 0 # 0x0000
+uint32 INPUT_PULLUP = 16 # 0x0010
+uint32 INPUT_PULLDOWN = 32 # 0x0020
+
+uint32 OUTPUT_PUSHPULL = 0 # 0x0000
+uint32 OUTPUT_OPENDRAIN = 256 # 0x0100
+uint32 OUTPUT_OPENDRAIN_PULLUP = 272 # 0x0110
+
+uint32 config
diff --git a/msg/GpioIn.msg b/msg/GpioIn.msg
new file mode 100644
index 0000000000..0482a2188e
--- /dev/null
+++ b/msg/GpioIn.msg
@@ -0,0 +1,6 @@
+# GPIO mask and state
+
+uint64 timestamp # time since system start (microseconds)
+uint32 device_id # Device id
+
+uint32 state # pin state mask
diff --git a/msg/GpioOut.msg b/msg/GpioOut.msg
new file mode 100644
index 0000000000..3865bbf2e9
--- /dev/null
+++ b/msg/GpioOut.msg
@@ -0,0 +1,7 @@
+# GPIO mask and state
+
+uint64 timestamp # time since system start (microseconds)
+uint32 device_id # Device id
+
+uint32 mask # pin mask
+uint32 state # pin state mask
diff --git a/msg/GpioRequest.msg b/msg/GpioRequest.msg
new file mode 100644
index 0000000000..3328b00145
--- /dev/null
+++ b/msg/GpioRequest.msg
@@ -0,0 +1,4 @@
+# Request GPIO mask to be read
+
+uint64 timestamp # time since system start (microseconds)
+uint32 device_id # Device id
diff --git a/msg/Mission.msg b/msg/Mission.msg
index 70fc68ccf2..546959a3b3 100644
--- a/msg/Mission.msg
+++ b/msg/Mission.msg
@@ -3,3 +3,10 @@ uint8 dataman_id # default 0, there are two offboard storage places in the datam
uint16 count # count of the missions stored in the dataman
int32 current_seq # default -1, start at the one changed latest
+
+int32 land_start_index # Index of the land start marker, if unavailable index of the land item, -1 otherwise
+int32 land_index # Index of the land item, -1 otherwise
+
+uint16 mission_update_counter # indicates updates to the mission, reload from dataman if increased
+uint16 geofence_update_counter # indicates updates to the geofence, reload from dataman if increased
+uint16 safe_points_update_counter # indicates updates to the safe points, reload from dataman if increased
diff --git a/msg/SensorGps.msg b/msg/SensorGps.msg
index 4404dd524f..db18899cb1 100644
--- a/msg/SensorGps.msg
+++ b/msg/SensorGps.msg
@@ -5,10 +5,10 @@ uint64 timestamp_sample
uint32 device_id # unique device ID for the sensor that does not change between power cycles
-int32 lat # Latitude in 1E-7 degrees
-int32 lon # Longitude in 1E-7 degrees
-int32 alt # Altitude in 1E-3 meters above MSL, (millimetres)
-int32 alt_ellipsoid # Altitude in 1E-3 meters bove Ellipsoid, (millimetres)
+float64 latitude_deg # Latitude in degrees, allows centimeter level RTK precision
+float64 longitude_deg # Longitude in degrees, allows centimeter level RTK precision
+float64 altitude_msl_m # Altitude above MSL, meters
+float64 altitude_ellipsoid_m # Altitude above Ellipsoid, meters
float32 s_variance_m_s # GPS speed accuracy estimate, (metres/sec)
float32 c_variance_rad # GPS course accuracy estimate, (radians)
@@ -55,4 +55,11 @@ float32 heading_accuracy # heading accuracy (rad, [0, 2PI])
float32 rtcm_injection_rate # RTCM message injection rate Hz
uint8 selected_rtcm_instance # uorb instance that is being used for RTCM corrections
+bool rtcm_crc_failed # RTCM message CRC failure detected
+
+uint8 RTCM_MSG_USED_UNKNOWN = 0
+uint8 RTCM_MSG_USED_NOT_USED = 1
+uint8 RTCM_MSG_USED_USED = 2
+uint8 rtcm_msg_used # Indicates if the RTCM message was used successfully by the receiver
+
# TOPICS sensor_gps vehicle_gps_position
diff --git a/msg/SensorUwb.msg b/msg/SensorUwb.msg
new file mode 100644
index 0000000000..ae889a8bdc
--- /dev/null
+++ b/msg/SensorUwb.msg
@@ -0,0 +1,34 @@
+# UWB distance contains the distance information measured by an ultra-wideband positioning system,
+# such as Pozyx or NXP Rddrone.
+
+uint64 timestamp # time since system start (microseconds)
+
+uint32 sessionid # UWB SessionID
+uint32 time_offset # Time between Ranging Rounds in ms
+uint32 counter # Number of Ranges since last Start of Ranging
+uint16 mac # MAC adress of Initiator (controller)
+
+uint16 mac_dest # MAC adress of Responder (Controlee)
+uint16 status # status feedback #
+uint8 nlos # None line of site condition y/n
+float32 distance # distance in m to the UWB receiver
+
+
+#Angle of arrival, Angle in Degree -60..+60; FOV in both axis is 120 degrees
+float32 aoa_azimuth_dev # Angle of arrival of first incomming RX msg
+float32 aoa_elevation_dev # Angle of arrival of first incomming RX msg
+float32 aoa_azimuth_resp # Angle of arrival of first incomming RX msg at the responder
+float32 aoa_elevation_resp # Angle of arrival of first incomming RX msg at the responder
+
+# Figure of merit for the angle measurements
+uint8 aoa_azimuth_fom # AOA Azimuth FOM
+uint8 aoa_elevation_fom # AOA Elevation FOM
+uint8 aoa_dest_azimuth_fom # AOA Azimuth FOM
+uint8 aoa_dest_elevation_fom # AOA Elevation FOM
+
+# Initiator physical configuration
+uint8 orientation # Direction the sensor faces from MAV_SENSOR_ORIENTATION enum
+ # Standard configuration is Antennas facing down and azimuth aligened in forward direction
+float32 offset_x # UWB initiator offset in X axis (NED drone frame)
+float32 offset_y # UWB initiator offset in Y axis (NED drone frame)
+float32 offset_z # UWB initiator offset in Z axis (NED drone frame)
diff --git a/msg/UwbDistance.msg b/msg/UwbDistance.msg
deleted file mode 100644
index e496a72396..0000000000
--- a/msg/UwbDistance.msg
+++ /dev/null
@@ -1,15 +0,0 @@
-# UWB distance contains the distance information measured by an ultra-wideband positioning system,
-# such as Pozyx or NXP Rddrone.
-
-uint64 timestamp # time since system start (microseconds)
-uint32 time_uwb_ms # Time of UWB device in ms
-uint32 counter # Number of Ranges since last Start of Ranging
-uint32 sessionid # UWB SessionID
-uint32 time_offset # Time between Ranging Rounds in ms
-uint16 status # status feedback #
-
-uint16[12] anchor_distance # distance in cm to each UWB Anchor (UWB Device which takes part in Ranging)
-bool[12] nlos # Visual line of sight yes/no
-float32[12] aoafirst # Angle of arrival of first incoming RX msg
-
-float32[3] position # Position of the Landing point in relation to the Drone (x,y,z in Meters NED)
diff --git a/msg/UwbGrid.msg b/msg/UwbGrid.msg
deleted file mode 100644
index 0862f84330..0000000000
--- a/msg/UwbGrid.msg
+++ /dev/null
@@ -1,25 +0,0 @@
-# UWB report message contains the grid information measured by an ultra-wideband positioning system,
-# such as Pozyx or NXP Rddrone.
-
-uint64 timestamp # time since system start (microseconds)
-uint16 initator_time # time to synchronize clocks (microseconds)
-uint8 num_anchors # Number of anchors
-
-float64[4] target_gps # GPS position of target of the UWB system (Lat / Lon / Alt / Yaw Offset to true North)
-
-# Grid position information
-# Position in x,y,z in (x,y,z in centimeters NED)
-# staring with POI and Anchor 0 up to Anchor 11
-int16[3] target_pos # Point of Interest, mostly landing Target x,y,z
-int16[3] anchor_pos_0
-int16[3] anchor_pos_1
-int16[3] anchor_pos_2
-int16[3] anchor_pos_3
-int16[3] anchor_pos_4
-int16[3] anchor_pos_5
-int16[3] anchor_pos_6
-int16[3] anchor_pos_7
-int16[3] anchor_pos_8
-int16[3] anchor_pos_9
-int16[3] anchor_pos_10
-int16[3] anchor_pos_11
diff --git a/msg/VehicleControlMode.msg b/msg/VehicleControlMode.msg
index 1f4034369d..92324cf03f 100644
--- a/msg/VehicleControlMode.msg
+++ b/msg/VehicleControlMode.msg
@@ -14,3 +14,4 @@ bool flag_control_position_enabled # true if position is controlled
bool flag_control_altitude_enabled # true if altitude is controlled
bool flag_control_climb_rate_enabled # true if climb rate is controlled
bool flag_control_termination_enabled # true if flighttermination is enabled
+bool flag_control_allocation_enabled # true if control allocation is enabled
diff --git a/msg/VehicleLocalPosition.msg b/msg/VehicleLocalPosition.msg
index 4f9238123c..5f17cde407 100644
--- a/msg/VehicleLocalPosition.msg
+++ b/msg/VehicleLocalPosition.msg
@@ -39,6 +39,7 @@ float32 ay # East velocity derivative in NED earth-fixed frame, (metres/s
float32 az # Down velocity derivative in NED earth-fixed frame, (metres/sec^2)
float32 heading # Euler yaw angle transforming the tangent plane relative to NED earth-fixed frame, -PI..+PI, (radians)
+float32 unaided_heading # Same as heading but generated by integrating corrected gyro data only
float32 delta_heading
uint8 heading_reset_counter
bool heading_good_for_control
diff --git a/msg/VehicleStatus.msg b/msg/VehicleStatus.msg
index 878b4b04ed..bf545ea02b 100644
--- a/msg/VehicleStatus.msg
+++ b/msg/VehicleStatus.msg
@@ -6,13 +6,8 @@ uint64 armed_time # Arming timestamp (microseconds)
uint64 takeoff_time # Takeoff timestamp (microseconds)
uint8 arming_state
-uint8 ARMING_STATE_INIT = 0
-uint8 ARMING_STATE_STANDBY = 1
-uint8 ARMING_STATE_ARMED = 2
-uint8 ARMING_STATE_STANDBY_ERROR = 3
-uint8 ARMING_STATE_SHUTDOWN = 4
-uint8 ARMING_STATE_IN_AIR_RESTORE = 5
-uint8 ARMING_STATE_MAX = 6
+uint8 ARMING_STATE_DISARMED = 1
+uint8 ARMING_STATE_ARMED = 2
uint8 latest_arming_reason
uint8 latest_disarming_reason
@@ -121,4 +116,3 @@ bool rc_calibration_in_progress
bool calibration_enabled
bool pre_flight_checks_pass # true if all checks necessary to arm pass
-
diff --git a/platforms/common/CMakeLists.txt b/platforms/common/CMakeLists.txt
index a6e06b9d47..d2e08a405b 100644
--- a/platforms/common/CMakeLists.txt
+++ b/platforms/common/CMakeLists.txt
@@ -43,7 +43,6 @@ endif()
add_library(px4_platform STATIC
board_common.c
board_identity.c
- events.cpp
external_reset_lockout.cpp
i2c.cpp
i2c_spi_buses.cpp
diff --git a/platforms/common/include/px4_platform_common/board_common.h b/platforms/common/include/px4_platform_common/board_common.h
index 832b0dbd6a..7a6af777c4 100644
--- a/platforms/common/include/px4_platform_common/board_common.h
+++ b/platforms/common/include/px4_platform_common/board_common.h
@@ -440,6 +440,8 @@ __BEGIN_DECLS
#if defined(RC_SERIAL_SINGLEWIRE)
static inline bool board_rc_singlewire(const char *device) { return strcmp(device, RC_SERIAL_PORT) == 0; }
+#elif defined(RC_SERIAL_SINGLEWIRE_FORCE)
+static inline bool board_rc_singlewire(const char *device) { return true; }
#else
static inline bool board_rc_singlewire(const char *device) { return false; }
#endif
diff --git a/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp b/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp
index 9bee390323..4df96fa5a9 100644
--- a/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp
+++ b/platforms/common/include/px4_platform_common/px4_work_queue/WorkQueueManager.hpp
@@ -72,7 +72,7 @@ static constexpr wq_config_t INS1{"wq:INS1", 6000, -15};
static constexpr wq_config_t INS2{"wq:INS2", 6000, -16};
static constexpr wq_config_t INS3{"wq:INS3", 6000, -17};
-static constexpr wq_config_t hp_default{"wq:hp_default", 1900, -18};
+static constexpr wq_config_t hp_default{"wq:hp_default", 2392, -18};
static constexpr wq_config_t uavcan{"wq:uavcan", 3624, -19};
diff --git a/platforms/common/uORB/uORB.h b/platforms/common/uORB/uORB.h
index 7fdbb699d1..0e2abb2bcf 100644
--- a/platforms/common/uORB/uORB.h
+++ b/platforms/common/uORB/uORB.h
@@ -42,16 +42,17 @@
#include
#include
+typedef uint16_t orb_id_size_t;
/**
* Object metadata.
*/
struct orb_metadata {
- const char *o_name; /**< unique object name */
- const uint16_t o_size; /**< object size */
- const uint16_t o_size_no_padding; /**< object size w/o padding at the end (for logger) */
- const char *o_fields; /**< semicolon separated list of fields (with type) */
- uint8_t o_id; /**< ORB_ID enum */
+ const char *o_name; /**< unique object name */
+ const uint16_t o_size; /**< object size */
+ const uint16_t o_size_no_padding; /**< object size w/o padding at the end (for logger) */
+ const char *o_fields; /**< semicolon separated list of fields (with type) */
+ orb_id_size_t o_id; /**< ORB_ID enum */
};
typedef const struct orb_metadata *orb_id_t;
diff --git a/platforms/common/uORB/uORBDeviceMaster.cpp b/platforms/common/uORB/uORBDeviceMaster.cpp
index c39e4572db..bd3877f13b 100644
--- a/platforms/common/uORB/uORBDeviceMaster.cpp
+++ b/platforms/common/uORB/uORBDeviceMaster.cpp
@@ -150,7 +150,7 @@ int uORB::DeviceMaster::advertise(const struct orb_metadata *meta, bool is_adver
// add to the node map.
_node_list.add(node);
- _node_exists[node->get_instance()].set((uint8_t)node->id(), true);
+ _node_exists[node->get_instance()].set((orb_id_size_t)node->id(), true);
}
group_tries++;
diff --git a/platforms/common/uORB/uORBDeviceMaster.hpp b/platforms/common/uORB/uORBDeviceMaster.hpp
index 94c97e61df..ccda58f8d3 100644
--- a/platforms/common/uORB/uORBDeviceMaster.hpp
+++ b/platforms/common/uORB/uORBDeviceMaster.hpp
@@ -98,7 +98,7 @@ public:
return false;
}
- return _node_exists[instance][(uint8_t)id];
+ return _node_exists[instance][(orb_id_size_t)id];
}
/**
diff --git a/platforms/common/uORB/uORBDeviceNode.cpp b/platforms/common/uORB/uORBDeviceNode.cpp
index 7cc5c9bd3e..112170de6b 100644
--- a/platforms/common/uORB/uORBDeviceNode.cpp
+++ b/platforms/common/uORB/uORBDeviceNode.cpp
@@ -188,7 +188,10 @@ uORB::DeviceNode::write(cdev::file_t *filp, const char *buffer, size_t buflen)
if (nullptr == _data) {
const size_t data_size = _meta->o_size * _queue_size;
_data = (uint8_t *) px4_cache_aligned_alloc(data_size);
- memset(_data, 0, data_size);
+
+ if (_data) {
+ memset(_data, 0, data_size);
+ }
}
unlock();
diff --git a/platforms/nuttx/NuttX/apps b/platforms/nuttx/NuttX/apps
index a489381b49..616f7024a4 160000
--- a/platforms/nuttx/NuttX/apps
+++ b/platforms/nuttx/NuttX/apps
@@ -1 +1 @@
-Subproject commit a489381b49835ecba6f3b873b5071d882a18152f
+Subproject commit 616f7024a479bf209eadce133bba5dc8820a7f99
diff --git a/platforms/nuttx/NuttX/nuttx b/platforms/nuttx/NuttX/nuttx
index 3f77354c0d..c23b72dffe 160000
--- a/platforms/nuttx/NuttX/nuttx
+++ b/platforms/nuttx/NuttX/nuttx
@@ -1 +1 @@
-Subproject commit 3f77354c0dc88793a47ff3b57595195ab45f7ba9
+Subproject commit c23b72dffeb0de0d1a836ab561eb9169c4a9e58e
diff --git a/platforms/nuttx/init/kinetis/rc.board_arch_defaults b/platforms/nuttx/init/kinetis/rc.board_arch_defaults
index 1cf9c919db..7a7bbb3db4 100644
--- a/platforms/nuttx/init/kinetis/rc.board_arch_defaults
+++ b/platforms/nuttx/init/kinetis/rc.board_arch_defaults
@@ -4,7 +4,7 @@
#------------------------------------------------------------------------------
# Multi-EKF (off by default)
-param set-default EKF2_MULTI_IMU 0
+param set-default -s EKF2_MULTI_IMU 0
param set-default SENS_IMU_MODE 1
set LOGGER_BUF 8
diff --git a/platforms/nuttx/init/stm32/rc.board_arch_defaults b/platforms/nuttx/init/stm32/rc.board_arch_defaults
index cda40b9a40..edef4e1e63 100644
--- a/platforms/nuttx/init/stm32/rc.board_arch_defaults
+++ b/platforms/nuttx/init/stm32/rc.board_arch_defaults
@@ -4,7 +4,7 @@
#------------------------------------------------------------------------------
# Multi-EKF (off by default)
-param set-default EKF2_MULTI_IMU 0
+param set-default -s EKF2_MULTI_IMU 0
param set-default SENS_IMU_MODE 1
set LOGGER_BUF 8
diff --git a/platforms/nuttx/init/stm32f7/rc.board_arch_defaults b/platforms/nuttx/init/stm32f7/rc.board_arch_defaults
index 17bae04429..2c71f7470c 100644
--- a/platforms/nuttx/init/stm32f7/rc.board_arch_defaults
+++ b/platforms/nuttx/init/stm32f7/rc.board_arch_defaults
@@ -4,7 +4,7 @@
#------------------------------------------------------------------------------
# Multi-EKF (across IMUs only)
-param set-default EKF2_MULTI_IMU 3
+param set-default -s EKF2_MULTI_IMU 3
param set-default SENS_IMU_MODE 0
param set-default -s IMU_GYRO_FFT_EN 1
diff --git a/platforms/nuttx/init/stm32h7/rc.board_arch_defaults b/platforms/nuttx/init/stm32h7/rc.board_arch_defaults
index 31d23de1ec..60979fa61b 100644
--- a/platforms/nuttx/init/stm32h7/rc.board_arch_defaults
+++ b/platforms/nuttx/init/stm32h7/rc.board_arch_defaults
@@ -4,7 +4,7 @@
#------------------------------------------------------------------------------
# Multi-EKF
-param set-default EKF2_MULTI_IMU 3
+param set-default -s EKF2_MULTI_IMU 3
param set-default SENS_IMU_MODE 0
param set-default -s IMU_GYRO_FFT_EN 1
diff --git a/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp b/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp
index ede9c2c172..63a60e5484 100644
--- a/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp
+++ b/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
*
- * Copyright (c) 2020 PX4 Development Team. All rights reserved.
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,182 +31,142 @@
*
****************************************************************************/
+#include
#include
-#include
-#include "mcp23009_registers.hpp"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
-using namespace Microchip_MCP23009;
-
-const struct gpio_operations_s MCP23009::gpio_ops = {
-go_read : MCP23009::go_read,
-go_write : MCP23009::go_write,
-go_attach : nullptr,
-go_enable : nullptr,
-go_setpintype : MCP23009::go_setpintype,
+static uint32_t DEVID{0};
+struct mcp23009_gpio_dev_s {
+ struct gpio_dev_s gpio;
+ uint8_t mask;
};
-MCP23009::MCP23009(int bus, int address, int first_minor, int bus_frequency) :
- I2C(DRV_GPIO_DEVTYPE_MCP23009, "MCP23009", bus, address, bus_frequency),
- _first_minor(first_minor)
+/* Copy the read input data */
+class ReadCallback : public uORB::SubscriptionCallback
{
-}
+public:
+ using SubscriptionCallback::SubscriptionCallback;
-MCP23009::~MCP23009()
-{
- /* set all as input & unregister */
- for (int i = 0; i < num_gpios; ++i) {
- go_setpintype(i, GPIO_INPUT_PIN);
- gpio_pin_unregister(&_gpio[i].gpio, _first_minor + i);
- }
-}
+ void call() override
+ {
+ px4::msg::GpioIn new_input;
-int MCP23009::go_read(struct gpio_dev_s *dev, bool *value)
-{
- mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev;
- return gpio->obj->go_read(gpio->id, value);
-}
+ if (update(&new_input) && new_input.device_id == DEVID) {
+ input = new_input.state;
+ }
-int MCP23009::go_write(struct gpio_dev_s *dev, bool value)
-{
- mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev;
- return gpio->obj->go_write(gpio->id, value);
-}
-
-int MCP23009::go_setpintype(struct gpio_dev_s *dev, enum gpio_pintype_e pintype)
-{
- mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev;
- return gpio->obj->go_setpintype(gpio->id, pintype);
-}
-
-
-int MCP23009::read_reg(Register address, uint8_t &data)
-{
- return transfer((uint8_t *)&address, 1, &data, 1);
-}
-
-int MCP23009::write_reg(Register address, uint8_t value)
-{
- uint8_t data[2] = {(uint8_t)address, value};
- return transfer(data, sizeof(data), nullptr, 0);
-}
-
-int MCP23009::init(uint8_t direction, uint8_t intital, uint8_t pull_up)
-{
- /* do I2C init (and probe) first */
- int ret = I2C::init();
-
- if (ret != PX4_OK) {
- return ret;
}
- /* Use this state as the out puts */
+ uint8_t input;
+};
- ret = write_reg(Register::OLAT, intital);
- ret |= write_reg(Register::IODIR, direction);
- ret |= write_reg(Register::GPPU, pull_up);
+static uORB::Publication toGpioRequest{ORB_ID(gpio_request)};
+static ReadCallback fromGpioIn{ORB_ID(gpio_in)};
+static int mcp23009_read(struct gpio_dev_s *dev, bool *value)
+{
+ mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev;
+ *value = fromGpioIn.input & gpio->mask;
+ return OK;
+}
- if (ret != PX4_OK) {
- return ret;
+static uORB::Publication toGpioOut{ORB_ID(gpio_out)};
+static int mcp23009_write(struct gpio_dev_s *dev, bool value)
+{
+ mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev;
+ gpio_out_s msg{
+ hrt_absolute_time(),
+ DEVID,
+ gpio->mask, // clear mask
+ value ? gpio->mask : 0u, // set mask
+ };
+ return toGpioOut.publish(msg) ? OK : -ETIMEDOUT;
+}
+
+static uORB::Publication toGpioConfig{ORB_ID(gpio_config)};
+static int mcp23009_setpintype(struct gpio_dev_s *dev, enum gpio_pintype_e pintype)
+{
+ mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev;
+ gpio_config_s msg{
+ hrt_absolute_time(),
+ DEVID,
+ gpio->mask,
+ };
+
+ switch (pintype) {
+ case GPIO_INPUT_PIN:
+ msg.config = gpio_config_s::INPUT;
+ break;
+
+ case GPIO_INPUT_PIN_PULLUP:
+ msg.config = gpio_config_s::INPUT_PULLUP;
+ break;
+
+ case GPIO_OUTPUT_PIN:
+ msg.config = gpio_config_s::OUTPUT;
+ break;
+
+ default:
+ return -ENOTSUP;
}
- /* register the pins */
- for (int i = 0; i < num_gpios; ++i) {
- _gpio[i].gpio.gp_pintype = GPIO_INPUT_PIN;
- _gpio[i].gpio.gp_ops = &gpio_ops;
- _gpio[i].id = i;
- _gpio[i].obj = this;
- ret = gpio_pin_register(&_gpio[i].gpio, _first_minor + i);
+ return toGpioConfig.publish(msg) ? OK : -ETIMEDOUT;
+}
- if (ret != PX4_OK) {
+
+
+// ----------------------------------------------------------------------------
+static const struct gpio_operations_s mcp23009_gpio_ops {
+ mcp23009_read,
+ mcp23009_write,
+ nullptr,
+ nullptr,
+ mcp23009_setpintype,
+};
+
+static constexpr uint8_t NUM_GPIOS = 8;
+static mcp23009_gpio_dev_s _gpio[NUM_GPIOS] {
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 0) },
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 1) },
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 2) },
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 3) },
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 4) },
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 5) },
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 6) },
+ { {GPIO_INPUT_PIN, {}, &mcp23009_gpio_ops}, (1u << 7) }
+};
+
+// ----------------------------------------------------------------------------
+int mcp23009_register_gpios(uint8_t i2c_bus, uint8_t i2c_addr, int first_minor)
+{
+ const auto device_id = device::Device::DeviceId{
+ device::Device::DeviceBusType_I2C, i2c_bus, i2c_addr, DRV_GPIO_DEVTYPE_MCP23009};
+ DEVID = device_id.devid;
+
+ for (int i = 0; i < NUM_GPIOS; ++i) {
+ int ret = gpio_pin_register(&_gpio[i].gpio, first_minor + i);
+
+ if (ret != OK) {
return ret;
}
}
- return ret;
+ fromGpioIn.registerCallback();
+ return OK;
}
-int MCP23009::probe()
+int mcp23009_unregister_gpios(int first_minor)
{
- // no whoami, try to read IOCON
- uint8_t data;
- return read_reg(Register::IOCON, data);
-}
-
-int MCP23009::go_read(int id, bool *value)
-{
-
- uint8_t data;
- int ret = read_reg(Register::GPIO, data);
-
- if (ret != 0) {
- return ret;
- }
-
- *value = data & (1 << id);
- return 0;
-}
-
-int MCP23009::go_write(int id, bool value)
-{
- uint8_t data;
- int ret = read_reg(Register::GPIO, data);
-
- if (ret != 0) {
- return ret;
- }
-
- if (value) {
- data |= (1 << id);
-
- } else {
- data &= ~(1 << id);
- }
-
- return write_reg(Register::GPIO, data);
-}
-
-int MCP23009::go_setpintype(int id, enum gpio_pintype_e pintype)
-{
- uint8_t direction;
- int ret = read_reg(Register::IODIR, direction);
-
- if (ret != 0) {
- return ret;
- }
-
- uint8_t pullup;
- ret = read_reg(Register::GPPU, pullup);
-
- if (ret != 0) {
- return ret;
- }
-
- switch (pintype) {
- case GPIO_INPUT_PIN:
- direction |= (1 << id);
- pullup &= ~(1 << id);
- break;
-
- case GPIO_INPUT_PIN_PULLUP:
- direction |= (1 << id);
- pullup |= (1 << id);
- break;
-
- case GPIO_OUTPUT_PIN:
- direction &= ~(1 << id);
- break;
-
- default:
- return -EINVAL;
- }
-
- _gpio[id].gpio.gp_pintype = pintype;
-
- ret = write_reg(Register::GPPU, pullup);
-
- if (ret != 0) {
- return ret;
- }
-
- return write_reg(Register::IODIR, direction);
+ for (int i = 0; i < NUM_GPIOS; ++i) {
+ mcp23009_setpintype(&_gpio[i].gpio, GPIO_INPUT_PIN);
+ gpio_pin_unregister(&_gpio[i].gpio, first_minor + i);
+ }
+
+ fromGpioIn.unregisterCallback();
+ return OK;
}
diff --git a/platforms/nuttx/src/px4/common/include/px4_platform/board_ctrl.h b/platforms/nuttx/src/px4/common/include/px4_platform/board_ctrl.h
index 9e1654451c..b85da67e07 100644
--- a/platforms/nuttx/src/px4/common/include/px4_platform/board_ctrl.h
+++ b/platforms/nuttx/src/px4/common/include/px4_platform/board_ctrl.h
@@ -53,7 +53,8 @@
#define _CRYPTOIOCBASE IOCTL_IDX_TO_BASE(2)
#define _PARAMIOCBASE IOCTL_IDX_TO_BASE(3)
#define _PLATFORMIOCBASE IOCTL_IDX_TO_BASE(4)
-#define MAX_IOCTL_PTRS 5
+#define _EVENTSIOCBASE IOCTL_IDX_TO_BASE(5)
+#define MAX_IOCTL_PTRS 6
/* The PLATFORMIOCLAUNCH IOCTL is used to launch kernel side modules
* from the user side code
diff --git a/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp b/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp
index 3a12aaaca7..481f5b51d7 100644
--- a/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp
+++ b/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp
@@ -1,6 +1,6 @@
/****************************************************************************
*
- * Copyright (c) 2020 PX4 Development Team. All rights reserved.
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,49 +33,7 @@
#pragma once
-#include
+#include
-#include
-
-using namespace time_literals;
-
-namespace Microchip_MCP23009
-{
-enum class Register : uint8_t;
-}
-
-class MCP23009 : public device::I2C
-{
-public:
- MCP23009(int bus, int address, int first_minor = 0, int bus_frequency = 400000);
- virtual ~MCP23009();
-
- int init(uint8_t direction, uint8_t intital = 0, uint8_t pull_up = 0);
-
-protected:
- int probe() override;
-
-private:
- static constexpr int num_gpios = 8;
- static const gpio_operations_s gpio_ops;
-
- struct mcp23009_gpio_dev_s {
- struct gpio_dev_s gpio;
- uint8_t id;
- MCP23009 *obj;
- };
-
- static int go_read(struct gpio_dev_s *dev, bool *value);
- static int go_write(struct gpio_dev_s *dev, bool value);
- static int go_setpintype(struct gpio_dev_s *dev, enum gpio_pintype_e pintype);
-
- int go_read(int id, bool *value);
- int go_write(int id, bool value);
- int go_setpintype(int id, enum gpio_pintype_e pintype);
-
- int read_reg(Microchip_MCP23009::Register address, uint8_t &data);
- int write_reg(Microchip_MCP23009::Register address, uint8_t data);
-
- const int _first_minor;
- mcp23009_gpio_dev_s _gpio[num_gpios] {};
-};
+int mcp23009_register_gpios(uint8_t i2c_bus, uint8_t i2c_addr, int first_minor = 0);
+int mcp23009_unregister_gpios(int first_minor = 0);
diff --git a/platforms/nuttx/src/px4/common/px4_init.cpp b/platforms/nuttx/src/px4/common/px4_init.cpp
index 3331eab90e..d22905cd38 100644
--- a/platforms/nuttx/src/px4/common/px4_init.cpp
+++ b/platforms/nuttx/src/px4/common/px4_init.cpp
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -125,6 +126,7 @@ int px4_platform_init()
#if !defined(CONFIG_BUILD_FLAT)
hrt_ioctl_init();
+ events_ioctl_init();
#endif
/* configure CPU load estimation */
@@ -163,7 +165,7 @@ int px4_platform_init()
#if defined(CONFIG_FS_PROCFS)
int ret_mount_procfs = mount(nullptr, "/proc", "procfs", 0, nullptr);
- if (ret < 0) {
+ if (ret_mount_procfs < 0) {
syslog(LOG_ERR, "ERROR: Failed to mount procfs at /proc: %d\n", ret_mount_procfs);
}
diff --git a/platforms/nuttx/src/px4/common/px4_mtd.cpp b/platforms/nuttx/src/px4/common/px4_mtd.cpp
index 8f45bd58e3..f4b3476722 100644
--- a/platforms/nuttx/src/px4/common/px4_mtd.cpp
+++ b/platforms/nuttx/src/px4/common/px4_mtd.cpp
@@ -249,25 +249,19 @@ static const px4_mtd_manifest_t default_mtd_config = {
#else
-const px4_mft_device_t spifram = { // FM25V02A on FMUM 32K 512 X 64
+const px4_mft_device_t spifram = { // FM25V02A on FMUM native: 32K X 8, emulated as (1024 Blocks of 32)
.bus_type = px4_mft_device_t::SPI,
.devid = SPIDEV_FLASH(0)
};
const px4_mtd_entry_t fram = {
.device = &spifram,
- .npart = 2,
+ .npart = 1,
.partd = {
{
.type = MTD_PARAMETERS,
.path = "/fs/mtd_params",
- .nblocks = 32
- },
- {
- .type = MTD_WAYPOINTS,
- .path = "/fs/mtd_waypoints",
- .nblocks = 32
-
+ .nblocks = (32768 / (1 << CONFIG_RAMTRON_EMULATE_SECTOR_SHIFT))
}
},
};
diff --git a/platforms/nuttx/src/px4/common/px4_protected_layers.cmake b/platforms/nuttx/src/px4/common/px4_protected_layers.cmake
index 7f76502e68..9c57b488b6 100644
--- a/platforms/nuttx/src/px4/common/px4_protected_layers.cmake
+++ b/platforms/nuttx/src/px4/common/px4_protected_layers.cmake
@@ -52,6 +52,8 @@ target_link_libraries(px4_kernel_layer
nuttx_kc
nuttx_karch
nuttx_kmm
+ PRIVATE
+ kernel_events_interface # events_ioctl_init
)
target_link_libraries(px4_kernel_layer
diff --git a/platforms/nuttx/src/px4/nxp/s32k3xx/adc/adc.cpp b/platforms/nuttx/src/px4/nxp/s32k3xx/adc/adc.cpp
index 2a3356fb54..92918be161 100644
--- a/platforms/nuttx/src/px4/nxp/s32k3xx/adc/adc.cpp
+++ b/platforms/nuttx/src/px4/nxp/s32k3xx/adc/adc.cpp
@@ -38,144 +38,76 @@
#include
-#include
-
-//todo S32K add ADC fior now steal the kinetis one
-#include
-#include
-
-
-#define _REG(_addr) (*(volatile uint32_t *)(_addr))
-
-/* ADC register accessors */
-
-#define REG(a, _reg) _REG(KINETIS_ADC##a##_BASE + (_reg))
-
-#define rSC1A(adc) REG(adc, KINETIS_ADC_SC1A_OFFSET) /* ADC status and control registers 1 */
-#define rSC1B(adc) REG(adc, KINETIS_ADC_SC1B_OFFSET) /* ADC status and control registers 1 */
-#define rCFG1(adc) REG(adc, KINETIS_ADC_CFG1_OFFSET) /* ADC configuration register 1 */
-#define rCFG2(adc) REG(adc, KINETIS_ADC_CFG2_OFFSET) /* Configuration register 2 */
-#define rRA(adc) REG(adc, KINETIS_ADC_RA_OFFSET) /* ADC data result register */
-#define rRB(adc) REG(adc, KINETIS_ADC_RB_OFFSET) /* ADC data result register */
-#define rCV1(adc) REG(adc, KINETIS_ADC_CV1_OFFSET) /* Compare value registers */
-#define rCV2(adc) REG(adc, KINETIS_ADC_CV2_OFFSET) /* Compare value registers */
-#define rSC2(adc) REG(adc, KINETIS_ADC_SC2_OFFSET) /* Status and control register 2 */
-#define rSC3(adc) REG(adc, KINETIS_ADC_SC3_OFFSET) /* Status and control register 3 */
-#define rOFS(adc) REG(adc, KINETIS_ADC_OFS_OFFSET) /* ADC offset correction register */
-#define rPG(adc) REG(adc, KINETIS_ADC_PG_OFFSET) /* ADC plus-side gain register */
-#define rMG(adc) REG(adc, KINETIS_ADC_MG_OFFSET) /* ADC minus-side gain register */
-#define rCLPD(adc) REG(adc, KINETIS_ADC_CLPD_OFFSET) /* ADC plus-side general calibration value register */
-#define rCLPS(adc) REG(adc, KINETIS_ADC_CLPS_OFFSET) /* ADC plus-side general calibration value register */
-#define rCLP4(adc) REG(adc, KINETIS_ADC_CLP4_OFFSET) /* ADC plus-side general calibration value register */
-#define rCLP3(adc) REG(adc, KINETIS_ADC_CLP3_OFFSET) /* ADC plus-side general calibration value register */
-#define rCLP2(adc) REG(adc, KINETIS_ADC_CLP2_OFFSET) /* ADC plus-side general calibration value register */
-#define rCLP1(adc) REG(adc, KINETIS_ADC_CLP1_OFFSET) /* ADC plus-side general calibration value register */
-#define rCLP0(adc) REG(adc, KINETIS_ADC_CLP0_OFFSET) /* ADC plus-side general calibration value register */
-#define rCLMD(adc) REG(adc, KINETIS_ADC_CLMD_OFFSET) /* ADC minus-side general calibration value register */
-#define rCLMS(adc) REG(adc, KINETIS_ADC_CLMS_OFFSET) /* ADC minus-side general calibration value register */
-#define rCLM4(adc) REG(adc, KINETIS_ADC_CLM4_OFFSET) /* ADC minus-side general calibration value register */
-#define rCLM3(adc) REG(adc, KINETIS_ADC_CLM3_OFFSET) /* ADC minus-side general calibration value register */
-#define rCLM2(adc) REG(adc, KINETIS_ADC_CLM2_OFFSET) /* ADC minus-side general calibration value register */
-#define rCLM1(adc) REG(adc, KINETIS_ADC_CLM1_OFFSET) /* ADC minus-side general calibration value register */
-#define rCLM0(adc) REG(adc, KINETIS_ADC_CLM0_OFFSET) /* ADC minus-side general calibration value register */
+#include
+#include
int px4_arch_adc_init(uint32_t base_address)
{
- /* Input is Buss Clock 56 Mhz We will use /8 for 7 Mhz */
+ uint32_t regval;
- irqstate_t flags = px4_enter_critical_section();
+ /* Configure and perform calibration */
+ putreg32(ADC_MCR_ADCLKSEL_DIV4, S32K3XX_ADC2_MCR);
- _REG(KINETIS_SIM_SCGC3) |= SIM_SCGC3_ADC1;
- rCFG1(1) = ADC_CFG1_ADICLK_BUSCLK | ADC_CFG1_MODE_1213BIT | ADC_CFG1_ADIV_DIV8;
- rCFG2(1) = 0;
- rSC2(1) = ADC_SC2_REFSEL_DEFAULT;
+ regval = getreg32(S32K3XX_ADC2_AMSIO);
+ regval |= ADC_AMSIO_HSEN_MASK;
+ putreg32(regval, S32K3XX_ADC2_AMSIO);
- px4_leave_critical_section(flags);
+ regval = getreg32(S32K3XX_ADC2_CAL2);
+ regval &= ~ADC_CAL2_ENX;
+ putreg32(regval, S32K3XX_ADC2_CAL2);
- /* Clear the CALF and begin the calibration */
+ regval = getreg32(S32K3XX_ADC2_CALBISTREG);
+ regval &= ~(ADC_CALBISTREG_TEST_EN | ADC_CALBISTREG_AVG_EN | ADC_CALBISTREG_NR_SMPL_MASK |
+ ADC_CALBISTREG_CALSTFUL | ADC_CALBISTREG_TSAMP_MASK | ADC_CALBISTREG_RESN_MASK);
+ regval |= ADC_CALBISTREG_TEST_EN | ADC_CALBISTREG_AVG_EN | ADC_CALBISTREG_NR_SMPL_4SMPL |
+ ADC_CALBISTREG_CALSTFUL | ADC_CALBISTREG_RESN_14BIT;
+ putreg32(regval, S32K3XX_ADC2_CALBISTREG);
- rSC3(1) = ADC_SC3_CAL | ADC_SC3_CALF;
+ while (getreg32(S32K3XX_ADC2_CALBISTREG) & ADC_CALBISTREG_C_T_BUSY) {};
- while ((rSC1A(1) & ADC_SC1_COCO) == 0) {
- usleep(100);
+ putreg32(ADC_MCR_PWDN, S32K3XX_ADC2_MCR);
- if (rSC3(1) & ADC_SC3_CALF) {
- return -1;
- }
- }
+ putreg32(22, S32K3XX_ADC2_CTR0);
- /* dummy read to clear COCO of calibration */
+ putreg32(22, S32K3XX_ADC2_CTR1);
- int32_t r = rRA(1);
+ putreg32(0, S32K3XX_ADC2_DMAE);
- /* Check the state of CALF at the end of calibration */
+ putreg32(ADC_MCR_ADCLKSEL_DIV4 | ADC_MCR_AVGS_32CONV | ADC_MCR_AVGEN | ADC_MCR_BCTU_MODE | ADC_MCR_MODE,
+ S32K3XX_ADC2_MCR);
- if (rSC3(1) & ADC_SC3_CALF) {
- return -1;
- }
+ putreg32(0x10, S32K3XX_ADC2_NCMR0);
- /* Calculate the calibration values for single ended positive */
+ putreg32(0x10, S32K3XX_ADC2_NCMR1);
- r = rCLP0(1) + rCLP1(1) + rCLP2(1) + rCLP3(1) + rCLP4(1) + rCLPS(1) ;
- r = 0x8000U | (r >> 1U);
- rPG(1) = r;
+ regval = getreg32(S32K3XX_ADC2_MCR);
- /* Calculate the calibration values for double ended Negitive */
+ regval |= ADC_MCR_NSTART;
- r = rCLM0(1) + rCLM1(1) + rCLM2(1) + rCLM3(1) + rCLM4(1) + rCLMS(1) ;
- r = 0x8000U | (r >> 1U);
- rMG(1) = r;
-
- /* kick off a sample and wait for it to complete */
- hrt_abstime now = hrt_absolute_time();
-
- rSC1A(1) = ADC_SC1_ADCH(ADC_SC1_ADCH_TEMP);
-
- while (!(rSC1A(1) & ADC_SC1_COCO)) {
-
- /* don't wait for more than 500us, since that means something broke - should reset here if we see this */
- if ((hrt_absolute_time() - now) > 500) {
- return -1;
- }
- }
+ putreg32(regval, S32K3XX_ADC2_MCR);
return 0;
}
void px4_arch_adc_uninit(uint32_t base_address)
{
- irqstate_t flags = px4_enter_critical_section();
- _REG(KINETIS_SIM_SCGC3) &= ~SIM_SCGC3_ADC1;
- px4_leave_critical_section(flags);
}
uint32_t px4_arch_adc_sample(uint32_t base_address, unsigned channel)
{
- irqstate_t flags = px4_enter_critical_section();
+ uint32_t result = 0;
- /* clear any previous COCC */
- rRA(1);
+ if (channel == 0) {
+ result = getreg32(S32K3XX_ADC2_PCDR4);
- /* run a single conversion right now - should take about 35 cycles (5 microseconds) max */
- rSC1A(1) = ADC_SC1_ADCH(channel);
+ if ((result & ADC_PCDR_VALID) == ADC_PCDR_VALID) {
+ result = result & 0xFFFF;
- /* wait for the conversion to complete */
- const hrt_abstime now = hrt_absolute_time();
-
- while (!(rSC1A(1) & ADC_SC1_COCO)) {
-
- /* don't wait for more than 10us, since that means something broke - should reset here if we see this */
- if ((hrt_absolute_time() - now) > 10) {
- px4_leave_critical_section(flags);
- return 0xffff;
+ } else {
+ result = 0;
}
}
- /* read the result and clear EOC */
- uint32_t result = rRA(1);
-
- px4_leave_critical_section(flags);
-
return result;
}
@@ -186,10 +118,10 @@ float px4_arch_adc_reference_v()
uint32_t px4_arch_adc_temp_sensor_mask()
{
- return 1 << (ADC_SC1_ADCH_TEMP >> ADC_SC1_ADCH_SHIFT);
+ return 0; // No temp sensor
}
uint32_t px4_arch_adc_dn_fullcount()
{
- return 1 << 12; // 12 bit ADC
+ return 1 << 15; // 15 bit conversion data
}
diff --git a/platforms/posix/src/px4/common/px4_daemon/pxh.cpp b/platforms/posix/src/px4/common/px4_daemon/pxh.cpp
index c17bbda267..9bcf0268ad 100644
--- a/platforms/posix/src/px4/common/px4_daemon/pxh.cpp
+++ b/platforms/posix/src/px4/common/px4_daemon/pxh.cpp
@@ -40,6 +40,7 @@
* @author Julian Oes
*/
+#include
#include
#include
#include
diff --git a/src/drivers/actuators/modal_io/modal_io.cpp b/src/drivers/actuators/modal_io/modal_io.cpp
index 6a9c6e0a24..1e5a2bc08c 100644
--- a/src/drivers/actuators/modal_io/modal_io.cpp
+++ b/src/drivers/actuators/modal_io/modal_io.cpp
@@ -48,7 +48,6 @@ const char *_device;
ModalIo::ModalIo() :
OutputModuleInterface(MODULE_NAME, px4::serial_port_to_wq(MODAL_IO_DEFAULT_PORT)),
- _mixing_output{"MODAL_IO", MODAL_IO_OUTPUT_CHANNELS, *this, MixingOutput::SchedulingPolicy::Auto, false, false},
_cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")),
_output_update_perf(perf_alloc(PC_INTERVAL, MODULE_NAME": output update interval"))
{
@@ -76,6 +75,8 @@ ModalIo::ModalIo() :
_esc_status.esc[i].esc_power = 0;
}
+ _esc_status_pub.advertise();
+
qc_esc_packet_init(&_fb_packet);
qc_esc_packet_init(&_uart_bridge_packet);
diff --git a/src/drivers/actuators/modal_io/modal_io.hpp b/src/drivers/actuators/modal_io/modal_io.hpp
index a61c269e6b..196728aab7 100644
--- a/src/drivers/actuators/modal_io/modal_io.hpp
+++ b/src/drivers/actuators/modal_io/modal_io.hpp
@@ -174,7 +174,7 @@ private:
} led_rsc_t;
ch_assign_t _output_map[MODAL_IO_OUTPUT_CHANNELS] {{1, 1}, {2, 1}, {3, 1}, {4, 1}};
- MixingOutput _mixing_output;
+ MixingOutput _mixing_output{"MODAL_IO", MODAL_IO_OUTPUT_CHANNELS, *this, MixingOutput::SchedulingPolicy::Auto, false, false};
perf_counter_t _cycle_perf;
perf_counter_t _output_update_perf;
diff --git a/src/drivers/adc/ads1115/ADS1115.h b/src/drivers/adc/ads1115/ADS1115.h
index 6f3c1e92be..79a31198c9 100644
--- a/src/drivers/adc/ads1115/ADS1115.h
+++ b/src/drivers/adc/ads1115/ADS1115.h
@@ -37,7 +37,7 @@
#include
#include
#include
-#include
+#include
#include
#include
@@ -127,7 +127,7 @@ protected:
private:
- uORB::Publication _to_adc_report{ORB_ID(adc_report)};
+ uORB::PublicationMulti _to_adc_report{ORB_ID(adc_report)};
static const hrt_abstime SAMPLE_INTERVAL{50_ms};
diff --git a/src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp b/src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp
index a863ac975b..6db6bb76d0 100755
--- a/src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp
+++ b/src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp
@@ -250,7 +250,7 @@ ICP201XX::RunImpl()
case STATE::CONFIG: {
if (configure()) {
_state = STATE::WAIT_READ;
- ScheduleDelayed(10_ms);
+ ScheduleDelayed(30_ms);
} else {
if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) {
diff --git a/src/drivers/camera_capture/camera_capture.cpp b/src/drivers/camera_capture/camera_capture.cpp
index 91ab266311..7bf3813542 100644
--- a/src/drivers/camera_capture/camera_capture.cpp
+++ b/src/drivers/camera_capture/camera_capture.cpp
@@ -226,7 +226,9 @@ void
CameraCapture::capture_trampoline(void *context, uint32_t chan_index, hrt_abstime edge_time, uint32_t edge_state,
uint32_t overflow)
{
- camera_capture::g_camera_capture->capture_callback(chan_index, edge_time, edge_state, overflow);
+ if (camera_capture::g_camera_capture) {
+ camera_capture::g_camera_capture->capture_callback(chan_index, edge_time, edge_state, overflow);
+ }
}
void
@@ -359,6 +361,11 @@ CameraCapture::stop()
work_cancel(HPWORK, &_work_publisher);
+ if (_capture_channel >= 0) {
+ up_input_capture_set(_capture_channel, Disabled, 0, nullptr, nullptr);
+ }
+
+
if (camera_capture::g_camera_capture != nullptr) {
delete (camera_capture::g_camera_capture);
}
diff --git a/src/drivers/cyphal/Publishers/udral/Gnss.hpp b/src/drivers/cyphal/Publishers/udral/Gnss.hpp
index 168b1e437f..ef592c7855 100644
--- a/src/drivers/cyphal/Publishers/udral/Gnss.hpp
+++ b/src/drivers/cyphal/Publishers/udral/Gnss.hpp
@@ -66,9 +66,9 @@ public:
size_t payload_size = reg_udral_physics_kinematics_geodetic_Point_0_1_SERIALIZATION_BUFFER_SIZE_BYTES_;
reg_udral_physics_kinematics_geodetic_Point_0_1 geo {};
- geo.latitude = gps.lat;
- geo.longitude = gps.lon;
- geo.altitude = uavcan_si_unit_length_WideScalar_1_0 { .meter = static_cast(gps.alt) };
+ geo.latitude = (int64_t)(gps.latitude_deg / 1e7);
+ geo.longitude = (int64_t)(gps.longitude_deg / 1e7);
+ geo.altitude = uavcan_si_unit_length_WideScalar_1_0 { .meter = gps.altitude_msl_m };
uint8_t geo_payload_buffer[reg_udral_physics_kinematics_geodetic_Point_0_1_SERIALIZATION_BUFFER_SIZE_BYTES_];
diff --git a/src/drivers/differential_pressure/asp5033/ASP5033.cpp b/src/drivers/differential_pressure/asp5033/ASP5033.cpp
new file mode 100644
index 0000000000..9a3a263bbd
--- /dev/null
+++ b/src/drivers/differential_pressure/asp5033/ASP5033.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+ *
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file ASP5033.cpp
+ *
+ *@author Denislav Petrov
+ */
+
+
+
+#include "ASP5033.hpp"
+
+ASP5033::ASP5033(const I2CSPIDriverConfig &config) :
+ I2C(config),
+ I2CSPIDriver(config)
+{
+}
+
+ASP5033::~ASP5033()
+{
+ perf_free(_sample_perf);
+ perf_free(_comms_errors);
+ perf_free(_fault_perf);
+}
+
+int ASP5033::probe()
+{
+ int ret = sensor_id_check();
+ return ret;
+}
+
+int ASP5033::sensor_id_check()
+{
+ uint8_t id[1];
+ uint8_t cmd_1 = REG_ID_SET_ASP5033;
+ uint8_t cmd_2 = REG_WHOAMI_RECHECK_ID_ASP5033;
+ uint8_t cmd_3 = REG_ID_ASP5033;
+ uint8_t cmd_1_2[2];
+ cmd_1_2[0] = static_cast(cmd_1);
+ cmd_1_2[1] = static_cast(cmd_2);
+
+
+ if ((transfer(&cmd_1, 1, &id[0], sizeof(id)) != PX4_OK) || (*id != REG_WHOAMI_DEFAULT_ID_ASP5033)) { return 0; }
+
+ if (transfer(&cmd_1_2[0], 2, nullptr, 0) != PX4_OK) { return 0; }
+
+ if ((transfer(&cmd_3, 1, &id[0], sizeof(id)) != PX4_OK) || (*id != REG_WHOAMI_RECHECK_ID_ASP5033)) { return 0; }
+
+ return 1;
+
+
+
+}
+
+int ASP5033::init()
+{
+ int ret = I2C::init();
+
+ if (ret != PX4_OK) {
+ DEVICE_DEBUG("I2C::init failed (%i)", ret);
+ return ret;
+ }
+
+ ScheduleNow();
+ return ret;
+}
+
+
+/**
+ * @brief calculation of the differential pressure in this way:
+ * it collect all measured pressure and store it into press_sum,
+ * count the value of collected times-press_count, then divide both
+ * and get the actual value of differential pressure - _pressure
+ *
+ * @return true if pressure is valid and no errors, false if not
+ */
+bool ASP5033::get_differential_pressure()
+{
+ if (hrt_elapsed_time(&last_sample_time) > 200_ms) {
+ return false;
+ }
+
+ if (press_count == 0) {
+ return false;
+ }
+
+ //calculation differential pressure
+ _pressure = press_sum / press_count;
+
+ press_sum = 0.;
+ press_count = 0;
+ return true;
+
+}
+
+
+void ASP5033::print_status()
+{
+
+ I2CSPIDriverBase::print_status();
+
+ perf_print_counter(_sample_perf);
+ perf_print_counter(_comms_errors);
+ perf_print_counter(_fault_perf);
+}
+
+void ASP5033::RunImpl()
+{
+ int ret = PX4_ERROR;
+
+ // collection phase
+ if (_collect_phase) {
+ // perform collection
+ ret = collect();
+
+ if (OK != ret) {
+ perf_count(_comms_errors);
+ /* restart the measurement state machine */
+ _collect_phase = false;
+ _sensor_ok = false;
+ ScheduleNow();
+ return;
+ }
+
+ // next phase is measurement
+ _collect_phase = false;
+
+ // is there a collect->measure gap?
+ if (_measure_interval > CONVERSION_INTERVAL) {
+
+ // schedule a fresh cycle call when we are ready to measure again
+ ScheduleDelayed(_measure_interval - CONVERSION_INTERVAL);
+
+ return;
+ }
+ }
+
+ /* measurement phase */
+ ret = measure();
+
+ if (OK != ret) {
+ DEVICE_DEBUG("measure error");
+ }
+
+ _sensor_ok = (ret == OK);
+
+ // next phase is collection
+ _collect_phase = true;
+
+ // schedule a fresh cycle call when the measurement is done
+ ScheduleDelayed(CONVERSION_INTERVAL);
+}
+
+
+int ASP5033::measure()
+{
+ // Send the command to begin a measurement.
+ uint8_t cmd_1 = CMD_MEASURE_ASP5033;
+ uint8_t cmd_2 = REG_CMD_ASP5033;;
+
+ //write to driver to start
+ uint8_t cmd[2];
+ cmd[0] = static_cast(cmd_2);
+ cmd[1] = static_cast(cmd_1);
+ int ret = transfer(&cmd[0], 2, nullptr, 0);
+
+ if (OK != ret) {
+ perf_count(_comms_errors);
+ }
+
+ return ret;
+}
+
+int ASP5033::collect()
+{
+ perf_begin(_sample_perf);
+ const hrt_abstime timestamp_sample = hrt_absolute_time();
+
+
+ // Read pressure and temperature as one block
+ uint8_t val[5] {0, 0, 0, 0, 0};
+ uint8_t cmd = REG_PRESS_DATA_ASP5033;
+ transfer(&cmd, 1, &val[0], sizeof(val));
+
+ //Pressure is a signed 24-bit value
+ int32_t press = (val[0] << 24) | (val[1] << 16) | (val[2] << 8);
+ // convert back to 24 bit
+ press >>= 8;
+
+ // k is a shift based on the pressure range of the device. See
+ // table in the datasheet
+ constexpr uint8_t k = 7;
+ constexpr float press_scale = 1.0f / (1U << k); //= 1.0f / (1U << k);
+ press_sum += press * press_scale;
+ press_count++;
+
+ // temperature is 16 bit signed in units of 1/256 C
+ const int16_t temp = (val[3] << 8) | val[4];
+ constexpr float temp_scale = 1.0f / 256;
+ _temperature = temp * temp_scale;
+ last_sample_time = hrt_absolute_time();
+ bool status = get_differential_pressure();
+
+ if (status == true && (int)_temperature != 0) {
+ // publish values
+ differential_pressure_s differential_pressure{};
+ differential_pressure.timestamp_sample = timestamp_sample;
+ differential_pressure.device_id = get_device_id();
+ differential_pressure.differential_pressure_pa = _pressure;
+ differential_pressure.temperature = _temperature ;
+ differential_pressure.error_count = perf_event_count(_comms_errors);
+ differential_pressure.timestamp = timestamp_sample;
+ _differential_pressure_pub.publish(differential_pressure);
+
+ }
+
+ perf_end(_sample_perf);
+
+ return PX4_OK;
+}
+
+
+
+
+
diff --git a/src/drivers/differential_pressure/asp5033/ASP5033.hpp b/src/drivers/differential_pressure/asp5033/ASP5033.hpp
new file mode 100644
index 0000000000..37a9fdeb8f
--- /dev/null
+++ b/src/drivers/differential_pressure/asp5033/ASP5033.hpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * @file ASP5033.hpp
+ *
+ * Driver for ASP5033 connected via I2C.
+ *
+ * Supported sensors:
+ *
+ * - ASP5033
+ *
+ * Interface application notes:
+ *
+ *
+ *@author Denislav Petrov
+ */
+
+#pragma once
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+
+
+
+/* Measurement rate is 100Hz */
+#define MEAS_RATE 100
+#define CONVERSION_INTERVAL (1000000 / MEAS_RATE) /* microseconds */
+
+
+/* Configuration Constants */
+static constexpr uint8_t I2C_ADDRESS_DEFAULT = 0x6D; /* 0x6D 0xE4 */
+static constexpr uint32_t I2C_SPEED = 100 * 1000; // 100 kHz I2C serial interface
+
+
+#define REG_CMD_ASP5033 0x30
+#define REG_PRESS_DATA_ASP5033 0X06
+#define REG_TEMP_DATA_ASP5033 0X09
+#define CMD_MEASURE_ASP5033 0X0A
+#define REG_WHOAMI_DEFAULT_ID_ASP5033 0X00
+#define REG_WHOAMI_RECHECK_ID_ASP5033 0X66
+#define REG_ID_ASP5033 0x01
+#define REG_ID_SET_ASP5033 0xa4
+
+using namespace time_literals;
+
+
+class ASP5033 : public device::I2C, public I2CSPIDriver
+{
+public:
+ ASP5033(const I2CSPIDriverConfig &config);
+ ~ASP5033() override;
+
+ static void print_usage();
+ void print_status() override;
+
+
+ void RunImpl();
+
+ int init() override;
+
+
+
+ float press_sum;
+ uint32_t press_count;
+
+
+private:
+
+ float _pressure = 0.f;
+ float _temperature = 0.f;
+ float _pressure_prev = 0.f;
+ float _temperaute_prev = 0.f;
+
+ int probe() override;
+
+ int measure();
+ int collect();
+ int sensor_id_check();
+
+ bool get_differential_pressure();
+ hrt_abstime last_sample_time = hrt_absolute_time();
+ orb_advert_t _mavlink_log_pub {nullptr}; //log send to
+
+
+ uint32_t _measure_interval{CONVERSION_INTERVAL};
+ uint32_t _conversion_interval{CONVERSION_INTERVAL};
+
+ bool _sensor_ok{false};
+ bool _collect_phase{false};
+
+ uORB::PublicationMulti _differential_pressure_pub{ORB_ID(differential_pressure)};
+
+ perf_counter_t _sample_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": read")};
+ perf_counter_t _comms_errors{perf_alloc(PC_COUNT, MODULE_NAME": communication errors")};
+ perf_counter_t _fault_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": fault detected")};
+};
+
diff --git a/src/drivers/differential_pressure/asp5033/CMakeLists.txt b/src/drivers/differential_pressure/asp5033/CMakeLists.txt
new file mode 100644
index 0000000000..3ca04b9d67
--- /dev/null
+++ b/src/drivers/differential_pressure/asp5033/CMakeLists.txt
@@ -0,0 +1,43 @@
+############################################################################
+#
+# Copyright (c) 2023 PX4 Development Team. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name PX4 nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+px4_add_module(
+ MODULE drivers__differential_pressure__asp5033
+ MAIN asp5033
+ COMPILE_FLAGS
+ SRCS
+ asp5033_main.cpp
+ ASP5033.cpp
+ ASP5033.hpp
+ DEPENDS
+ px4_work_queue
+ )
diff --git a/src/drivers/differential_pressure/asp5033/Kconfig b/src/drivers/differential_pressure/asp5033/Kconfig
new file mode 100644
index 0000000000..6bf415af2e
--- /dev/null
+++ b/src/drivers/differential_pressure/asp5033/Kconfig
@@ -0,0 +1,5 @@
+menuconfig DRIVERS_DIFFERENTIAL_PRESSURE_ASP5033
+ bool "asp5033"
+ default n
+ ---help---
+ Enable support for asp5033
diff --git a/src/drivers/differential_pressure/asp5033/asp5033_main.cpp b/src/drivers/differential_pressure/asp5033/asp5033_main.cpp
new file mode 100644
index 0000000000..f34597ef37
--- /dev/null
+++ b/src/drivers/differential_pressure/asp5033/asp5033_main.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+
+#include "ASP5033.hpp"
+#include
+#include
+
+
+
+
+void ASP5033::print_usage()
+{
+ PRINT_MODULE_DESCRIPTION(
+ R"DESCR_STR(
+### Description
+Driver to enable an external [ASP5033]
+(https://www.qio-tek.com/index.php/product/qiotek-asp5033-dronecan-airspeed-and-compass-module/)
+TE connected via I2C.
+This is not included by default in firmware. It can be included with terminal command: "make boardconfig"
+or in default.px4board with adding the line: "CONFIG_DRIVERS_DIFFERENTIAL_PRESSURE_ASP5033=y"
+It can be enabled with the "SENS_EN_ASP5033" parameter set to 1.
+)DESCR_STR");
+ PRINT_MODULE_USAGE_NAME("asp5033", "driver");
+ PRINT_MODULE_USAGE_SUBCATEGORY("airspeed_sensor");
+ PRINT_MODULE_USAGE_COMMAND("start");
+ PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false);
+ PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x6D);
+ PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
+}
+
+extern "C" int asp5033_main(int argc, char *argv[])
+{
+
+ using ThisDriver = ASP5033;
+ BusCLIArguments cli{true, false};
+ cli.i2c_address = I2C_ADDRESS_DEFAULT;
+ cli.default_i2c_frequency = I2C_SPEED;
+
+ const char *verb = cli.parseDefaultArguments(argc, argv);
+
+
+
+ if (!verb) {
+ ThisDriver::print_usage();
+ return -1;
+ }
+
+ BusInstanceIterator iterator(MODULE_NAME, cli, DRV_DIFF_PRESS_DEVTYPE_ASP5033);
+
+
+ if (!strcmp(verb, "start")) {
+ return ThisDriver::module_start(cli, iterator);
+
+ } else if (!strcmp(verb, "stop")) {
+ return ThisDriver::module_stop(iterator);
+
+ } else if (!strcmp(verb, "status")) {
+ return ThisDriver::module_status(iterator);
+ }
+
+ ThisDriver::print_usage();
+ return -1;
+}
diff --git a/src/drivers/differential_pressure/asp5033/parameters.c b/src/drivers/differential_pressure/asp5033/parameters.c
new file mode 100644
index 0000000000..5b50f628f6
--- /dev/null
+++ b/src/drivers/differential_pressure/asp5033/parameters.c
@@ -0,0 +1,46 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+
+/**
+ * ASP5033 differential pressure sensor (external I2C)
+ *
+ * @reboot_required true
+ * @group Sensors
+ * @boolean
+ */
+PARAM_DEFINE_INT32(SENS_EN_ASP5033, 0);
+
+
+
+
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.cpp b/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.cpp
index b66eeeba3d..4419530515 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.cpp
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.cpp
@@ -33,6 +33,7 @@
/* Include Files */
#include "AFBRS50.hpp"
+#include "argus_hal_test.h"
#include
@@ -42,9 +43,6 @@
/*! Define the SPI baud rate (to be used in the SPI module). */
#define SPI_BAUD_RATE 5000000
-#define LONG_RANGE_MODE_HZ 25
-#define SHORT_RANGE_MODE_HZ 50
-
#include "s2pi.h"
#include "timer.h"
#include "argus_hal_test.h"
@@ -52,6 +50,7 @@
AFBRS50 *g_dev{nullptr};
AFBRS50::AFBRS50(uint8_t device_orientation):
+ ModuleParams(nullptr),
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default),
_px4_rangefinder(0, device_orientation)
{
@@ -61,6 +60,7 @@ AFBRS50::AFBRS50(uint8_t device_orientation):
device_id.devid_s.devtype = DRV_DIST_DEVTYPE_AFBRS50;
_px4_rangefinder.set_device_id(device_id.devid);
+ _px4_rangefinder.set_device_type(distance_sensor_s::MAV_DISTANCE_SENSOR_LASER);
}
AFBRS50::~AFBRS50()
@@ -70,12 +70,12 @@ AFBRS50::~AFBRS50()
perf_free(_sample_perf);
}
-status_t AFBRS50::measurement_ready_callback(status_t status, void *data)
+status_t AFBRS50::measurement_ready_callback(status_t status, argus_hnd_t *hnd)
{
if (!up_interrupt_context()) {
if (status == STATUS_OK) {
if (g_dev) {
- g_dev->ProcessMeasurement(data);
+ g_dev->ProcessMeasurement(hnd);
}
} else {
@@ -86,35 +86,33 @@ status_t AFBRS50::measurement_ready_callback(status_t status, void *data)
return status;
}
-void AFBRS50::ProcessMeasurement(void *data)
+void AFBRS50::ProcessMeasurement(argus_hnd_t *hnd)
{
- if (data != nullptr) {
- perf_count(_sample_perf);
+ perf_count(_sample_perf);
- argus_results_t res{};
- status_t evaluate_status = Argus_EvaluateData(_hnd, &res, data);
+ argus_results_t res{};
+ status_t evaluate_status = Argus_EvaluateData(hnd, &res);
- if ((evaluate_status == STATUS_OK) && (res.Status == STATUS_OK)) {
- uint32_t result_mm = res.Bin.Range / (Q9_22_ONE / 1000);
- float result_m = static_cast(result_mm) / 1000.f;
- int8_t quality = res.Bin.SignalQuality;
+ if ((evaluate_status == STATUS_OK) && (res.Status == STATUS_OK)) {
+ uint32_t result_mm = res.Bin.Range / (Q9_22_ONE / 1000);
+ float result_m = static_cast(result_mm) / 1000.f;
+ int8_t quality = res.Bin.SignalQuality;
- // Signal quality indicates 100% for good signals, 50% and lower for weak signals.
- // 1% is an errored signal (not reliable). Signal Quality of 0% is unknown.
- if (quality == 1) {
- quality = 0;
- }
-
- // distance quality check
- if (result_m > _max_distance) {
- result_m = 0.0;
- quality = 0;
- }
-
- _current_distance = result_m;
- _current_quality = quality;
- _px4_rangefinder.update(((res.TimeStamp.sec * 1000000ULL) + res.TimeStamp.usec), result_m, quality);
+ // Signal quality indicates 100% for good signals, 50% and lower for weak signals.
+ // 1% is an errored signal (not reliable). Signal Quality of 0% is unknown.
+ if (quality == 1) {
+ quality = 0;
}
+
+ // distance quality check
+ if (result_m > _max_distance) {
+ result_m = 0.0;
+ quality = 0;
+ }
+
+ _current_distance = result_m;
+ _current_quality = quality;
+ _px4_rangefinder.update(((res.TimeStamp.sec * 1000000ULL) + res.TimeStamp.usec), result_m, quality);
}
}
@@ -137,7 +135,37 @@ int AFBRS50::init()
// Initialize the S2PI hardware required by the API.
S2PI_Init(BROADCOM_AFBR_S50_S2PI_SPI_BUS, SPI_BAUD_RATE);
- status_t status = Argus_Init(_hnd, BROADCOM_AFBR_S50_S2PI_SPI_BUS);
+ int32_t mode_param = _p_sens_afbr_mode.get();
+
+ if (mode_param < 0 || mode_param > 3) {
+ PX4_ERR("Invalid mode parameter: %li", mode_param);
+ return PX4_ERROR;
+ }
+
+ argus_mode_t mode = ARGUS_MODE_LONG_RANGE;
+
+ switch (mode_param) {
+ case 0:
+ mode = ARGUS_MODE_SHORT_RANGE;
+ break;
+
+ case 1:
+ mode = ARGUS_MODE_LONG_RANGE;
+ break;
+
+ case 2:
+ mode = ARGUS_MODE_HIGH_SPEED_SHORT_RANGE;
+ break;
+
+ case 3:
+ mode = ARGUS_MODE_HIGH_SPEED_LONG_RANGE;
+ break;
+
+ default:
+ break;
+ }
+
+ status_t status = Argus_InitMode(_hnd, BROADCOM_AFBR_S50_S2PI_SPI_BUS, mode);
if (status == STATUS_OK) {
uint32_t id = Argus_GetChipID(_hnd);
@@ -148,7 +176,6 @@ int AFBRS50::init()
PX4_INFO_RAW("AFBR-S50 Chip ID: %u, API Version: %u v%d.%d.%d\n", (uint)id, (uint)value, a, b, c);
argus_module_version_t mv = Argus_GetModuleVersion(_hnd);
- argus_laser_type_t lt = Argus_GetLaserType(_hnd);
switch (mv) {
case AFBR_S50MV85G_V1:
@@ -168,19 +195,20 @@ int AFBRS50::init()
case AFBR_S50LV85D_V1:
_min_distance = 0.08f;
-
- if (lt == LASER_H_V2X) {
- _max_distance = 50.f;
- PX4_INFO_RAW("AFBR-S50LX85D (v2)\n");
-
- } else {
- _max_distance = 30.f;
- PX4_INFO_RAW("AFBR-S50LV85D (v1)\n");
- }
-
+ _max_distance = 30.f;
_px4_rangefinder.set_min_distance(_min_distance);
_px4_rangefinder.set_max_distance(_max_distance);
_px4_rangefinder.set_fov(math::radians(6.f));
+ PX4_INFO_RAW("AFBR-S50LV85D\n");
+ break;
+
+ case AFBR_S50LX85D_V1:
+ _min_distance = 0.08f;
+ _max_distance = 50.f;
+ _px4_rangefinder.set_min_distance(_min_distance);
+ _px4_rangefinder.set_max_distance(_max_distance);
+ _px4_rangefinder.set_fov(math::radians(6.f));
+ PX4_INFO_RAW("AFBR-S50LX85D\n");
break;
case AFBR_S50MV68B_V1:
@@ -223,6 +251,9 @@ int AFBRS50::init()
ScheduleDelayed(_measure_interval);
return PX4_OK;
+
+ } else {
+ PX4_ERR("Argus_InitMode failed: %ld", status);
}
return PX4_ERROR;
@@ -230,6 +261,15 @@ int AFBRS50::init()
void AFBRS50::Run()
{
+ if (_parameter_update_sub.updated()) {
+ // clear update
+ parameter_update_s param_update;
+ _parameter_update_sub.copy(¶m_update);
+
+ // update parameters from storage
+ ModuleParams::updateParams();
+ }
+
switch (_state) {
case STATE::TEST: {
if (_testing) {
@@ -243,7 +283,8 @@ void AFBRS50::Run()
break;
case STATE::CONFIGURE: {
- status_t status = set_rate(SHORT_RANGE_MODE_HZ);
+ _current_rate = (uint32_t)_p_sens_afbr_s_rate.get();
+ status_t status = set_rate(_current_rate);
if (status != STATUS_OK) {
PX4_ERR("CONFIGURE status not okay: %i", (int)status);
@@ -251,24 +292,18 @@ void AFBRS50::Run()
ScheduleNow();
}
- status = Argus_SetConfigurationDFMMode(_hnd, ARGUS_MODE_B, DFM_MODE_8X);
+ status = Argus_SetConfigurationDFMMode(_hnd, DFM_MODE_8X);
if (status != STATUS_OK) {
PX4_ERR("Argus_SetConfigurationDFMMode status not okay: %i", (int)status);
+ _state = STATE::STOP;
+ ScheduleNow();
}
- status = Argus_SetConfigurationDFMMode(_hnd, ARGUS_MODE_A, DFM_MODE_8X);
+ status = Argus_SetConfigurationSmartPowerSaveEnabled(_hnd, false);
if (status != STATUS_OK) {
- PX4_ERR("Argus_SetConfigurationDFMMode status not okay: %i", (int)status);
- }
-
- // start in short range mode
- _mode = ARGUS_MODE_B;
- set_mode(_mode);
-
- if (status != STATUS_OK) {
- PX4_ERR("CONFIGURE status not okay: %i", (int)status);
+ PX4_ERR("Argus_SetConfigurationSmartPowerSaveEnabled status not okay: %i", (int)status);
ScheduleNow();
} else {
@@ -288,7 +323,7 @@ void AFBRS50::Run()
}
}
- UpdateMode();
+ Evaluate_rate();
}
break;
@@ -306,49 +341,41 @@ void AFBRS50::Run()
ScheduleDelayed(_measure_interval);
}
-void AFBRS50::UpdateMode()
+void AFBRS50::Evaluate_rate()
{
- // only update mode if _current_distance is a valid measurement
- if ((_current_distance > 0) && (_current_quality > 0)) {
+ // only update mode if _current_distance is a valid measurement and if the last rate switch was more than 1 second ago
+ if ((_current_distance > 0) && (_current_quality > 0) && ((hrt_absolute_time() - _last_rate_switch) > 1_s)) {
- if ((_current_distance >= _long_range_threshold) && (_mode != ARGUS_MODE_A)) {
- // change to long range mode
- argus_mode_t mode = ARGUS_MODE_A;
- status_t status = set_mode(mode);
+ status_t status = STATUS_OK;
- if (status != STATUS_OK) {
- PX4_ERR("set_mode status not okay: %i", (int)status);
- }
+ if ((_current_distance >= (_p_sens_afbr_thresh.get() + _p_sens_afbr_hyster.get()))
+ && (_current_rate != (uint32_t)_p_sens_afbr_l_rate.get())) {
- status = set_rate(LONG_RANGE_MODE_HZ);
+ _current_rate = (uint32_t)_p_sens_afbr_l_rate.get();
+ status = set_rate(_current_rate);
if (status != STATUS_OK) {
PX4_ERR("set_rate status not okay: %i", (int)status);
+
+ } else {
+ PX4_INFO("switched to long range rate: %i", (int)_current_rate);
+ _last_rate_switch = hrt_absolute_time();
}
- status = set_rate(LONG_RANGE_MODE_HZ);
+ } else if ((_current_distance <= (_p_sens_afbr_thresh.get() - _p_sens_afbr_hyster.get()))
+ && (_current_rate != (uint32_t)_p_sens_afbr_s_rate.get())) {
+
+ _current_rate = (uint32_t)_p_sens_afbr_s_rate.get();
+ status = set_rate(_current_rate);
if (status != STATUS_OK) {
PX4_ERR("set_rate status not okay: %i", (int)status);
- }
- } else if ((_current_distance <= _short_range_threshold) && (_mode != ARGUS_MODE_B)) {
- // change to short range mode
- argus_mode_t mode = ARGUS_MODE_B;
- status_t status = set_mode(mode);
-
- if (status != STATUS_OK) {
- PX4_ERR("set_mode status not okay: %i", (int)status);
- }
-
- status = set_rate(SHORT_RANGE_MODE_HZ);
-
- if (status != STATUS_OK) {
- PX4_ERR("set_rate status not okay: %i", (int)status);
+ } else {
+ PX4_INFO("switched to short range rate: %i", (int)_current_rate);
+ _last_rate_switch = hrt_absolute_time();
}
}
-
- ScheduleDelayed(1000_ms); // don't switch again for at least 1 second
}
}
@@ -373,33 +400,6 @@ void AFBRS50::print_info()
get_info();
}
-status_t AFBRS50::set_mode(argus_mode_t mode)
-{
- while (Argus_GetStatus(_hnd) != STATUS_IDLE) {
- px4_usleep(1_ms);
- }
-
- status_t status = Argus_SetConfigurationMeasurementMode(_hnd, mode);
-
- if (status != STATUS_OK) {
- PX4_ERR("Argus_SetConfigurationMeasurementMode status not okay: %i", (int)status);
- return status;
- }
-
- argus_mode_t current_mode;
- status = Argus_GetConfigurationMeasurementMode(_hnd, ¤t_mode);
-
- if (status != STATUS_OK) {
- PX4_ERR("Argus_GetConfigurationMeasurementMode status not okay: %i", (int)status);
- return status;
-
- } else {
- _mode = current_mode;
- }
-
- return status;
-}
-
status_t AFBRS50::set_rate(uint32_t rate_hz)
{
while (Argus_GetStatus(_hnd) != STATUS_IDLE) {
@@ -429,13 +429,10 @@ status_t AFBRS50::set_rate(uint32_t rate_hz)
void AFBRS50::get_info()
{
- argus_mode_t current_mode;
argus_dfm_mode_t dfm_mode;
- Argus_GetConfigurationMeasurementMode(_hnd, ¤t_mode);
- Argus_GetConfigurationDFMMode(_hnd, current_mode, &dfm_mode);
+ Argus_GetConfigurationDFMMode(_hnd, &dfm_mode);
PX4_INFO_RAW("distance: %.3fm\n", (double)_current_distance);
- PX4_INFO_RAW("mode: %d\n", current_mode);
PX4_INFO_RAW("dfm mode: %d\n", dfm_mode);
PX4_INFO_RAW("rate: %u Hz\n", (uint)(1000000 / _measure_interval));
}
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.hpp b/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.hpp
index f7503b321b..2ad767b2fa 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.hpp
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/AFBRS50.hpp
@@ -44,13 +44,16 @@
#include
#include
#include
-#include
#include
+#include
+#include
#include
+#include
+#include
using namespace time_literals;
-class AFBRS50 : public px4::ScheduledWorkItem
+class AFBRS50 : public ModuleParams, public px4::ScheduledWorkItem
{
public:
AFBRS50(const uint8_t device_orientation = distance_sensor_s::ROTATION_DOWNWARD_FACING);
@@ -75,18 +78,16 @@ public:
private:
void Run() override;
- void UpdateMode();
+ void Evaluate_rate();
- void ProcessMeasurement(void *data);
+ void ProcessMeasurement(argus_hnd_t *hnd);
- static status_t measurement_ready_callback(status_t status, void *data);
+ static status_t measurement_ready_callback(status_t status, argus_hnd_t *hnd);
void get_info();
- status_t set_mode(argus_mode_t mode);
status_t set_rate(uint32_t rate_hz);
argus_hnd_t *_hnd{nullptr};
- argus_mode_t _mode{ARGUS_MODE_B}; // Short-Range
enum class STATE : uint8_t {
TEST,
@@ -98,14 +99,24 @@ private:
PX4Rangefinder _px4_rangefinder;
hrt_abstime _measurement_time{0};
+ hrt_abstime _last_rate_switch{0};
perf_counter_t _sample_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": sample interval")};
uint32_t _measure_interval{1000000 / 50}; // 50Hz
float _current_distance{0};
int8_t _current_quality{0};
- const float _short_range_threshold = 4.0; //meters
- const float _long_range_threshold = 6.0; //meters
float _max_distance;
float _min_distance;
+ uint32_t _current_rate{0};
+
+ uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)};
+
+ DEFINE_PARAMETERS(
+ (ParamInt) _p_sens_afbr_mode,
+ (ParamInt) _p_sens_afbr_s_rate,
+ (ParamInt) _p_sens_afbr_l_rate,
+ (ParamInt) _p_sens_afbr_thresh,
+ (ParamInt) _p_sens_afbr_hyster
+ );
};
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/API/Src/s2pi.c b/src/drivers/distance_sensor/broadcom/afbrs50/API/Src/s2pi.c
index 61950a12b8..015249f859 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/API/Src/s2pi.c
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/API/Src/s2pi.c
@@ -85,6 +85,8 @@ static int gpio_falling_edge(int irq, void *context, void *arg)
status_t S2PI_Init(s2pi_slave_t defaultSlave, uint32_t baudRate_Bps)
{
+ (void)defaultSlave;
+
px4_arch_configgpio(BROADCOM_AFBR_S50_S2PI_CS);
s2pi_.spidev = px4_spibus_initialize(BROADCOM_AFBR_S50_S2PI_SPI_BUS);
@@ -107,11 +109,24 @@ status_t S2PI_Init(s2pi_slave_t defaultSlave, uint32_t baudRate_Bps)
* - #STATUS_BUSY: An SPI transfer is in progress.
* - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode.
*****************************************************************************/
-status_t S2PI_GetStatus(void)
+status_t S2PI_GetStatus(s2pi_slave_t slave)
{
+ (void)slave;
+
return s2pi_.Status;
}
+status_t S2PI_TryGetMutex(s2pi_slave_t slave)
+{
+ (void) slave;
+ return STATUS_OK;
+}
+
+void S2PI_ReleaseMutex(s2pi_slave_t slave)
+{
+ (void) slave;
+}
+
/*!***************************************************************************
* @brief Sets the SPI baud rate in bps.
* @param baudRate_Bps The default SPI baud rate in bauds-per-second.
@@ -135,8 +150,10 @@ status_t S2PI_SetBaudRate(uint32_t baudRate_Bps)
* switch back to ordinary SPI functionality.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t S2PI_CaptureGpioControl(void)
+status_t S2PI_CaptureGpioControl(s2pi_slave_t slave)
{
+ (void)slave;
+
/* Check if something is ongoing. */
IRQ_LOCK();
status_t status = s2pi_.Status;
@@ -165,8 +182,10 @@ status_t S2PI_CaptureGpioControl(void)
* the #S2PI_CaptureGpioControl function.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t S2PI_ReleaseGpioControl(void)
+status_t S2PI_ReleaseGpioControl(s2pi_slave_t slave)
{
+ (void)slave;
+
/* Check if something is ongoing. */
IRQ_LOCK();
status_t status = s2pi_.Status;
@@ -202,6 +221,8 @@ status_t S2PI_ReleaseGpioControl(void)
*****************************************************************************/
status_t S2PI_WriteGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t value)
{
+ (void)slave;
+
/* Check if pin is valid. */
if (pin > S2PI_IRQ || value > 1) {
return ERROR_INVALID_ARGUMENT;
@@ -228,6 +249,8 @@ status_t S2PI_WriteGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t value)
*****************************************************************************/
status_t S2PI_ReadGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t *value)
{
+ (void)slave;
+
/* Check if pin is valid. */
if (pin > S2PI_IRQ || !value) {
return ERROR_INVALID_ARGUMENT;
@@ -255,6 +278,8 @@ status_t S2PI_ReadGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t *value)
*****************************************************************************/
status_t S2PI_CycleCsPin(s2pi_slave_t slave)
{
+ (void)slave;
+
/* Check the driver status. */
IRQ_LOCK();
status_t status = s2pi_.Status;
@@ -372,8 +397,10 @@ status_t S2PI_TransferFrame(s2pi_slave_t spi_slave, uint8_t const *txData, uint8
* invoked with the #ERROR_ABORTED error byte.
* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t S2PI_Abort(void)
+status_t S2PI_Abort(s2pi_slave_t slave)
{
+ (void)slave;
+
status_t status = s2pi_.Status;
/* Check if something is ongoing. */
@@ -405,6 +432,8 @@ status_t S2PI_Abort(void)
*****************************************************************************/
status_t S2PI_SetIrqCallback(s2pi_slave_t slave, s2pi_irq_callback_t callback, void *callbackData)
{
+ (void)slave;
+
s2pi_.IrqCallback = callback;
s2pi_.IrqCallbackData = callbackData;
@@ -430,5 +459,7 @@ status_t S2PI_SetIrqCallback(s2pi_slave_t slave, s2pi_irq_callback_t callback, v
*****************************************************************************/
uint32_t S2PI_ReadIrqPin(s2pi_slave_t slave)
{
+ (void)slave;
+
return px4_arch_gpioread(s2pi_.GPIOs[S2PI_IRQ]);
}
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_api.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_api.h
index a933976370..44cdc92168 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_api.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_api.h
@@ -1,12 +1,12 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file provides generic functionality belonging to all
- * devices from the AFBR-S50 product family.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides generic functionality belonging to all
+ * devices from the AFBR-S50 product family.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,21 +37,21 @@
#ifndef ARGUS_API_H
#define ARGUS_API_H
-
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
- * @defgroup argusapi AFBR-S50 API
+ * @defgroup argus_api AFBR-S50 API
+ * @ingroup argus
*
- * @brief The main module of the API from the AFBR-S50 SDK.
+ * @brief The main module of the API from the AFBR-S50 SDK.
*
- * @details General API for the AFBR-S50 time-of-flight sensor device family.\n
- * See the \ref getting_started Guide for a detailed description
- * on how to use the module/API.
+ * @details General API for the AFBR-S50 time-of-flight sensor device family.\n
+ * See the \ref getting_started Guide for a detailed description
+ * on how to use the module/API.
*
- * @addtogroup argusapi
+ * @addtogroup argus_api
* @{
*****************************************************************************/
@@ -61,213 +61,301 @@ extern "C" {
#include "argus_dfm.h"
#include "argus_snm.h"
#include "argus_xtalk.h"
-
-/*! The data structure for the API representing a AFBR-S50 device instance. */
-typedef void argus_hnd_t;
+#include "argus_offset.h"
/*! The S2PI slave identifier. */
typedef int32_t s2pi_slave_t;
/*!***************************************************************************
- * @brief Initializes the API modules and the device with default parameters.
+ * @brief Initializes the device with default measurement mode.
*
* @details The function that needs to be called once after power up to
- * initialize the modules state (i.e. the corresponding handle) and the
- * dedicated Time-of-Flight device. In order to obtain a handle,
- * reference the #Argus_CreateHandle method.
+ * initialize the modules state (i.e. the corresponding handle) and the
+ * dedicated Time-of-Flight device. In order to obtain a handle,
+ * reference the #Argus_CreateHandle method.
*
- * Prior to calling the function, the required peripherals (i.e. S2PI,
- * GPIO w/ IRQ and Timers) must be initialized and ready to use.
+ * Prior to calling the function, the required peripherals (i.e. S2PI,
+ * GPIO w/ IRQ and Timers) must be initialized and ready to use.
*
- * The function executes the following tasks:
- * - Initialization of the internal state represented by the handle
- * object.
- * - Setup the device such that an safe configuration is present in
- * the registers.
- * - Initialize sub modules such as calibration or measurement modules.
- * .
+ * The function executes the following tasks:
+ * - Initialization of the internal state represented by the handle
+ * object.
+ * - Setup the device such that an safe configuration is present in
+ * the registers.
+ * - Initialize sub modules such as calibration or measurement modules.
+ * .
*
- * The modules configuration is initialized with reasonable default values.
+ * The modules configuration is initialized with reasonable default
+ * values. Note that the default measurement mode depends on the
+ * given device.
*
- * @param hnd The API handle; contains all internal states and data.
+ * Also refer to #Argus_InitMode, which uses an specified measurement
+ * mode instead of the dedicated default measurement mode.
*
- * @param spi_slave The SPI hardware slave, i.e. the specified CS and IRQ
- * lines. This is actually just a number that is passed
- * to the SPI interface to distinct for multiple SPI slave
- * devices. Note that the slave must be not equal to 0,
- * since is reserved for error handling.
+ * @param hnd The API handle; contains all internal states and data.
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param spi_slave The SPI hardware slave, i.e. the specified CS and IRQ
+ * lines. This is actually just a number that is passed
+ * to the SPI interface to distinct for multiple SPI slave
+ * devices. Note that the slave must be not equal to 0,
+ * since is reserved for error handling.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_Init(argus_hnd_t *hnd, s2pi_slave_t spi_slave);
/*!***************************************************************************
- * @brief Reinitializes the API modules and the device with default parameters.
+ * @brief Initializes the device with specified measurement mode.
*
- * @details The function reinitializes the device with default configuration.
- * Can be used as reset sequence for the device. See #Argus_Init for
- * more information on the initialization.
+ * @details The function that needs to be called once after power up to
+ * initialize the modules state (i.e. the corresponding handle) and the
+ * dedicated Time-of-Flight device. In order to obtain a handle,
+ * reference the #Argus_CreateHandle method.
*
- * Note that the #Argus_Init function must be called first! Otherwise,
- * the function will return an error if it is called for an yet
- * uninitialized device/handle.
+ * Prior to calling the function, the required peripherals (i.e. S2PI,
+ * GPIO w/ IRQ and Timers) must be initialized and ready to use.
*
- * @param hnd The API handle; contains all internal states and data.
+ * The function executes the following tasks:
+ * - Initialization of the internal state represented by the handle
+ * object.
+ * - Setup the device such that an safe configuration is present in
+ * the registers.
+ * - Initialize sub modules such as calibration or measurement modules.
+ * .
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * The modules configuration is initialized with reasonable default values.
+ *
+ * Also refer to #Argus_Init, which uses the dedicated default measurement
+ * mode instead of an user specified measurement mode.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ *
+ * @param spi_slave The SPI hardware slave, i.e. the specified CS and IRQ
+ * lines. This is actually just a number that is passed
+ * to the SPI interface to distinct for multiple SPI slave
+ * devices. Note that the slave must be not equal to 0,
+ * since is reserved for error handling.
+ *
+ * @param mode The specified measurement mode to be initialized.
+ * Pass 0 as special value to select default measurement mode
+ * (see #Argus_Init).
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ *****************************************************************************/
+status_t Argus_InitMode(argus_hnd_t *hnd, s2pi_slave_t spi_slave, argus_mode_t mode);
+
+/*!***************************************************************************
+ * @brief Reinitializes the device with the current measurement mode.
+ *
+ * @details The function reinitializes the device with the currently active
+ * measurement mode.
+ *
+ * This can be used as a soft reset for the device and API.
+ * See #Argus_Init for more information on the initialization.
+ *
+ * Note that the #Argus_Init or #Argus_InitMode function must be called
+ * first! Otherwise, the function will return an error if it is called
+ * for an yet uninitialized device/handle.
+ *
+ * Also refer to #Argus_ReinitMode, which uses a specified measurement
+ * mode instead of the currently active measurement mode.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_Reinit(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Deinitializes the API modules and the device.
+ * @brief Reinitializes the device with a specified measurement mode.
+ *
+ * @details The function reinitializes the device with a specified (/p mode)
+ * measurement mode.
+ *
+ * This can be used as a soft reset for the device and API.
+ * See #Argus_InitMode for more information on the initialization.
+ *
+ * Note that the #Argus_Init or #Argus_InitMode function must be called
+ * first! Otherwise, the function will return an error if it is called
+ * for an yet uninitialized device/handle.
+ *
+ * Also refer to #Argus_Reinit, which re-uses the currently active
+ * measurement mode instead of an user specified measurement mode.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ *
+ * @param mode The specified measurement mode to be initialized.
+ * Pass 0 as special value to select the current measurement mode
+ * (see #Argus_Init).
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ *****************************************************************************/
+status_t Argus_ReinitMode(argus_hnd_t *hnd, argus_mode_t mode);
+
+/*!***************************************************************************
+ * @brief Deinitializes the API modules and the device.
*
* @details The function deinitializes the device and clear all internal states.
- * Can be used to cleanup before releasing the memory. The device
- * can not be used any more and must be initialized again prior to next
- * usage.
+ * Can be used to cleanup before releasing the memory. The device
+ * can not be used any more and must be initialized again prior to next
+ * usage.
*
- * Note that the #Argus_Init function must be called first! Otherwise,
- * the function will return an error if it is called for an yet
- * uninitialized device/handle.
+ * Note that the #Argus_Init function must be called first! Otherwise,
+ * the function will return an error if it is called for an yet
+ * uninitialized device/handle.
*
- * @param hnd The API handle; contains all internal states and data.
+ * @param hnd The API handle; contains all internal states and data.
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_Deinit(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Creates a new device data handle object to store all internal states.
+ * @brief Creates a new device data handle object to store all internal states.
*
* @details The function must be called to obtain a new device handle object.
- * The handle is basically an abstract object in memory that contains
- * all the internal states and settings of the API module. The handle
- * is passed to all the API methods in order to address the specified
- * device. This allows to use the API with more than a single measurement
- * device.
+ * The handle is basically an abstract object in memory that contains
+ * all the internal states and settings of the API module. The handle
+ * is passed to all the API methods in order to address the specified
+ * device. This allows to use the API with more than a single measurement
+ * device.
*
- * The handler is created by calling the memory allocation method from
- * the standard library: @code void * malloc(size_t size) @endcode
- * In order to implement an individual memory allocation method,
- * define and implement the following weakly binded method and return
- * a pointer to the newly allocated memory. *
+ * The handler is created by calling the memory allocation method from
+ * the standard library: @code void * malloc(size_t size) @endcode
+ * In order to implement an individual memory allocation method,
+ * define and implement the following weakly binded method and return
+ * a pointer to the newly allocated memory. *
*
- * @code void * Argus_Malloc (size_t size) @endcode
+ * @code void * Argus_Malloc (size_t size) @endcode
*
- * Also see the #Argus_DestroyHandle method for the corresponding
- * deallocation of the allocated memory.
+ * Also see the #Argus_DestroyHandle method for the corresponding
+ * deallocation of the allocated memory.
*
- * @note Although the method is using memory allocated on the heap, it
- * is eventually no dynamic memory allocation, since the block of
- * memory is kept all the time and no memory blocks are dynamically
- * freed and re-allocated. If the usage of heap must be avoided, one
- * can always implement its own version of the `Argus_Malloc` function
- * to create the memory elsewhere.
+ * @note Although the method is using memory allocated on the heap, it
+ * is eventually no dynamic memory allocation, since the block of
+ * memory is kept all the time and no memory blocks are dynamically
+ * freed and re-allocated. If the usage of heap must be avoided, one
+ * can always implement its own version of the `Argus_Malloc` function
+ * to create the memory elsewhere.
*
- * @return Returns a pointer to the newly allocated device handler object.
- * Returns a null pointer if the allocation failed!
+ * @return Returns a pointer to the newly allocated device handler object.
+ * Returns a null pointer if the allocation failed!
*****************************************************************************/
argus_hnd_t *Argus_CreateHandle(void);
/*!***************************************************************************
- * @brief Destroys a given device data handle object.
+ * @brief Destroys a given device data handle object.
*
* @details The function can be called to free the previously created device
- * data handle object in order to save memory when the device is not
- * used any more.
+ * data handle object in order to save memory when the device is not
+ * used any more.
*
- * Please refer to the #Argus_CreateHandle method for the corresponding
- * allocation of the memory.
+ * Note that the handle must be deinitialized before it can be
+ * destroyed. The function returns #ERROR_FAIL if the handle is not
+ * yet deinitialized.
*
- * The handler is destroyed by freeing the corresponding memory with the
- * method from the standard library, @code void free(void * ptr) @endcode.
- * In order to implement an individual memory deallocation method, define
- * and implement the following weakly binded method and free the memory
- * object passed to the method by a pointer.
+ * Please refer to the #Argus_CreateHandle method for the corresponding
+ * allocation of the memory.
*
- * @code void Argus_Free (void * ptr) @endcode
+ * The handler is destroyed by freeing the corresponding memory with the
+ * method from the standard library, @code void free(void * ptr) @endcode.
+ * In order to implement an individual memory deallocation method, define
+ * and implement the following weakly binded method and free the memory
+ * object passed to the method by a pointer.
*
- * Also see the #Argus_CreateHandle method for the corresponding
- * allocation of the required memory.
+ * @code void Argus_Free (void * ptr) @endcode
*
- * @param hnd The device handle object to be deallocated.
+ * Also see the #Argus_CreateHandle method for the corresponding
+ * allocation of the required memory.
+ *
+ * @param hnd The device handle object to be deallocated.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-void Argus_DestroyHandle(argus_hnd_t *hnd);
+status_t Argus_DestroyHandle(argus_hnd_t *hnd);
/*!**************************************************************************
* Generic API
****************************************************************************/
/*!***************************************************************************
- * @brief Gets the version number of the current API library.
+ * @brief Gets the version number of the current API library.
*
- * @details The version is compiled of a major (a), minor (b) and bugfix (c)
- * number: a.b.c.
+ * @details The version is compiled of a major (a), minor (b) and bugfix (c)
+ * number: a.b.c.
*
- * The values are encoded into a 32-bit value:
+ * The values are encoded into a 32-bit value:
*
- * - [ 31 .. 24 ] - Major Version Number
- * - [ 23 .. 16 ] - Minor Version Number
- * - [ 15 .. 0 ] - Bugfix Version Number
- * .
+ * - [ 31 .. 24 ] - Major Version Number
+ * - [ 23 .. 16 ] - Minor Version Number
+ * - [ 15 .. 0 ] - Bugfix Version Number
+ * .
*
- * To obtain the parts from the returned uin32_t value:
+ * To obtain the parts from the returned uin32_t value:
*
- * @code
- * uint32_t value = Argus_GetAPIVersion();
- * uint8_t a = (value >> 24) & 0xFFU;
- * uint8_t b = (value >> 16) & 0xFFU;
- * uint8_t c = value & 0xFFFFU;
- * @endcode
+ * @code
+ * uint32_t value = Argus_GetAPIVersion();
+ * uint8_t a = (value >> 24) & 0xFFU;
+ * uint8_t b = (value >> 16) & 0xFFU;
+ * uint8_t c = value & 0xFFFFU;
+ * @endcode
*
- * @return Returns the current version number.
+ * @return Returns the current version number.
*****************************************************************************/
uint32_t Argus_GetAPIVersion(void);
/*!***************************************************************************
- * @brief Gets the build number of the current API library.
+ * @brief Gets the build number of the current API library.
*
- * @return Returns the current build number as a C-string.
+ * @return Returns the current build number as a C-string.
*****************************************************************************/
char const *Argus_GetBuildNumber(void);
/*!***************************************************************************
- * @brief Gets the version/variant of the module.
+ * @brief Gets the version/variant of the module.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the current module number.
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the current module number.
*****************************************************************************/
argus_module_version_t Argus_GetModuleVersion(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Gets the version number of the chip.
+ * @brief Gets the name string of the module.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the current version number.
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the current module name.
+ *****************************************************************************/
+char const *Argus_GetModuleName(argus_hnd_t *hnd);
+
+/*!***************************************************************************
+ * @brief Gets the version number of the chip.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the current version number.
*****************************************************************************/
argus_chip_version_t Argus_GetChipVersion(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Gets the type number of the device laser.
+ * @brief Gets the type number of the device laser.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the current device laser type number.
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the current device laser type number.
*****************************************************************************/
argus_laser_type_t Argus_GetLaserType(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Gets the unique identification number of the chip.
+ * @brief Gets the unique identification number of the chip.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the unique identification number.
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the unique identification number.
*****************************************************************************/
uint32_t Argus_GetChipID(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Gets the SPI hardware slave identifier.
+ * @brief Gets the SPI hardware slave identifier.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return The SPI hardware slave identifier.
+ * @param hnd The API handle; contains all internal states and data.
+ * @return The SPI hardware slave identifier.
*****************************************************************************/
s2pi_slave_t Argus_GetSPISlave(argus_hnd_t *hnd);
@@ -276,323 +364,425 @@ s2pi_slave_t Argus_GetSPISlave(argus_hnd_t *hnd);
/*!**************************************************************************
* Measurement/Device Operation
****************************************************************************
- * @addtogroup argusmeas
+ * @addtogroup argus_meas
* @{
****************************************************************************/
/*!***************************************************************************
- * @brief Starts the timer based measurement cycle asynchronously.
+ * @brief Starts the timer based measurement cycle asynchronously.
*
* @details This function starts a timer based measurement cycle asynchronously
- * in the background. A periodic timer interrupt triggers the measurement
- * frames on the ASIC and the data readout afterwards.
+ * in the background. A periodic timer interrupt triggers the measurement
+ * frames on the ASIC and the data readout afterwards.
*
- * When the measurement has finished, a callback (which is passed as
- * a parameter to the function) is invoked in order to inform the
- * main thread to call the \link #Argus_EvaluateData data evaluation
- * method\endlink. This call is mandatory to release the data buffer
- * for the next measurement and it must not be invoked directly from
- * the callback since it is currently within an interrupt service
- * routine. Rather a flag should inform the main thread or task
- * scheduler to invoke the evaluation as soon as possible in order
- * to not introduce any unwanted delays to the next measurement frame.
+ * When the measurement has finished, a callback (which is passed as
+ * a parameter to the function) is invoked in order to inform the
+ * main thread to call the \link #Argus_EvaluateData data evaluation
+ * method\endlink. This call is mandatory to release the data buffer
+ * for the next measurement and it must not be invoked directly from
+ * the callback since it is currently within an interrupt service
+ * routine. Rather a flag should inform the main thread or task
+ * scheduler to invoke the evaluation as soon as possible in order
+ * to not introduce any unwanted delays to the next measurement frame.
*
- * The next measurement frame will be started as soon as the pre-
- * conditions are meet. These are:
- * 1. timer flag set (i.e. a certain time has passed since the last
- * measurement in order to fulfill eye-safety),
- * 2. device idle (i.e. no measurement currently ongoing) and
- * 3. data buffer ready (i.e. the previous data has been evaluated).
+ * The next measurement frame will be started as soon as the pre-
+ * conditions are meet. These are:
+ * 1. timer flag set (i.e. a certain time has passed since the last
+ * measurement in order to fulfill eye-safety),
+ * 2. device idle (i.e. no measurement currently ongoing) and
+ * 3. data buffer ready (i.e. the previous data has been evaluated).
*
- * Usually, the device idle and data buffer ready conditions are met
- * before the timer tick occurs and thus the timer dictates the frame
- * rate.
+ * Usually, the device idle and data buffer ready conditions are met
+ * before the timer tick occurs and thus the timer dictates the frame
+ * rate.
*
- * The callback function pointer will be invoked when the measurement
- * frame has finished successfully or whenever an error, that cannot
- * be handled internally, occurs.
+ * The callback function pointer will be invoked when the measurement
+ * frame has finished successfully or whenever an error, that cannot
+ * be handled internally, occurs.
*
- * The periodic timer interrupts are used to check the measurement status
- * for timeouts. An error is invoked when a measurement cycle have not
- * finished within the specified time.
+ * The periodic timer interrupts are used to check the measurement status
+ * for timeouts. An error is invoked when a measurement cycle have not
+ * finished within the specified time.
*
- * Use #Argus_StopMeasurementTimer to stop the measurements.
+ * Use #Argus_StopMeasurementTimer to stop the measurements.
*
- * @note In order to use this function, the periodic interrupt timer module
- * (see @ref argus_timer) must be implemented!
+ * @note In order to use this function, the periodic interrupt timer module
+ * (see @ref argus_timer) must be implemented!
*
- * @param hnd The API handle; contains all internal states and data.
- * @param cb Callback function that will be invoked when the measurement
- * is completed. Its parameters are the \link #status_t status
- * \endlink and a pointer to the \link #argus_results_t results
- * \endlink structure. If an error occurred, the status differs
- * from #STATUS_OK and the second parameter is null.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ *
+ * @param cb Callback function that will be invoked when the measurement
+ * is completed. Its parameters are the \link #status_t status
+ * \endlink of the finished measurement cycle and the pointer to
+ * the calling \link #argus_hnd_t API handle\endlink, i.e. the
+ * /p hnd value. The latter must be passed to the
+ * #Argus_EvaluateData function.
+ * If an error occurred, the status differs from #STATUS_OK.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_StartMeasurementTimer(argus_hnd_t *hnd, argus_callback_t cb);
+status_t Argus_StartMeasurementTimer(argus_hnd_t *hnd,
+ argus_measurement_ready_callback_t cb);
/*!***************************************************************************
- * @brief Stops the timer based measurement cycle.
+ * @brief Stops the timer based measurement cycle.
*
* @details This function stops the ongoing timer based measurement cycles
- * that have been started using the #Argus_StartMeasurementTimer
- * function.
+ * that have been started using the #Argus_StartMeasurementTimer
+ * function.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_StopMeasurementTimer(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Triggers a single measurement frame asynchronously.
+ * @brief Triggers a single measurement frame asynchronously.
*
* @details This function immediately triggers a single measurement frame
- * asynchronously if all the pre-conditions are met. Otherwise it
- * returns with a corresponding status (e.g. #STATUS_BUSY or
- * #STATUS_ARGUS_POWERLIMIT).
+ * asynchronously if all the pre-conditions are met. Otherwise it
+ * returns with a corresponding status (e.g. #STATUS_BUSY or
+ * #STATUS_ARGUS_POWERLIMIT).
*
- * When the measurement has finished, a callback (which is passed as
- * a parameter to the function) is invoked in order to inform the
- * main thread to call the \link #Argus_EvaluateData data evaluation
- * method\endlink. This call is mandatory to release the data buffer
- * for the next measurement and it must not be invoked directly from
- * the callback since it is currently within an interrupt service
- * routine. Rather a flag should inform the main thread or task
- * scheduler to invoke the evaluation task.
+ * When the measurement has finished, a callback (which is passed as
+ * a parameter to the function) is invoked in order to inform the
+ * main thread to call the \link #Argus_EvaluateData data evaluation
+ * method\endlink. This call is mandatory to release the data buffer
+ * for the next measurement and it must not be invoked directly from
+ * the callback since it is currently within an interrupt service
+ * routine. Rather a flag should inform the main thread or task
+ * scheduler to invoke the evaluation task.
*
- * The pre-conditions for starting a measurement frame are:
- * 1. timer flag set (i.e. a certain time has passed since the last
- * measurement in order to fulfill eye-safety),
- * 2. device idle (i.e. no measurement currently ongoing) and
- * 3. data buffer ready (i.e. the previous data has been evaluated).
+ * The pre-conditions for starting a measurement frame are:
+ * 1. timer flag set (i.e. a certain time has passed since the last
+ * measurement in order to fulfill eye-safety),
+ * 2. device idle (i.e. no measurement currently ongoing) and
+ * 3. data buffer ready (i.e. the previous data has been evaluated).
*
- * The callback function pointer will be invoked when the measurement
- * frame has finished successfully or whenever an error, that cannot
- * be handled internally, occurs.
+ * The callback function pointer will be invoked when the measurement
+ * frame has finished successfully or whenever an error, that cannot
+ * be handled internally, occurs.
*
- * The successful finishing of the measurement frame is not checked
- * for timeouts! Instead, the user can call the #Argus_GetStatus()
- * function on a regular function to do so.
+ * The successful finishing of the measurement frame is not checked
+ * for timeouts! Instead, the user can call the #Argus_GetStatus()
+ * function on a regular function to do so.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param cb Callback function that will be invoked when the measurement
- * is completed. Its parameters are the \link #status_t status
- * \endlink and a pointer to the \link #argus_results_t results
- * \endlink structure. If an error occurred, the status differs
- * from #STATUS_OK and the second parameter is null.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @note Despite this function triggers a new measurement cycle upon its
+ * invocation, the frame time parameter is still active for this
+ * measurement mode. Basically, the first pre-condition mentioned
+ * above is controlled via the frame time parameter. This means
+ * that measurements cannot be triggered faster than the frame
+ * timer parameters specifies. The maximum integration time (i.e.
+ * exposure time) is also determined by the frame time such that
+ * new measurements are finished with the specified frame time and
+ * the device is ready to trigger a new measurement after the
+ * frame time has elapse.
+ * See #Argus_SetConfigurationFrameTime function for more information
+ * on the frame time.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ *
+ * @param cb Callback function that will be invoked when the measurement
+ * is completed. Its parameters are the \link #status_t status
+ * \endlink of the finished measurement cycle and the pointer to
+ * the calling \link #argus_hnd_t API handle\endlink, i.e. the
+ * /p hnd value. The latter must be passed to the
+ * #Argus_EvaluateData function.
+ * If an error occurred, the status differs from #STATUS_OK.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_TriggerMeasurement(argus_hnd_t *hnd, argus_callback_t cb);
+status_t Argus_TriggerMeasurement(argus_hnd_t *hnd,
+ argus_measurement_ready_callback_t cb);
/*!***************************************************************************
- * @brief Stops the currently ongoing measurements and SPI activity immediately.
+ * @brief Determines whether a data evaluation is pending.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @details If the function returns true, a raw buffer is required to be
+ * evaluated to the #Argus_EvaluateData function. The raw data buffer
+ * is filled with raw data from the measurement tasks which need to
+ * be evaluated and the buffer must be freed in order to restart a
+ * new measurement task.
+ *
+ * Note that no configuration parameters can be update until all raw
+ * buffers are evaluated.
+ *
+ * @note See also the #Argus_GetStatus function to obtain the current device
+ * status and error code if any.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return True if any raw buffer is filled with data that must be evaluated.
+ *****************************************************************************/
+bool Argus_IsDataEvaluationPending(argus_hnd_t *hnd);
+
+/*!***************************************************************************
+ * @brief Determines if the device if active with timer based measurements.
+ * @details If the function returns true, the device is active with timer
+ * scheduled measurements that have been started via the
+ * #Argus_StartMeasurementTimer.
+ *
+ * Note that the active state is independent of the busy state that
+ * is set when the device is actually busy. The active state is also
+ * true if the device is currently idle but waits for the next timer
+ * event to trigger a new measurement cycle.
+ *
+ * @note See also the #Argus_GetStatus function to obtain the current device
+ * status and error code if any.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return True if the device is operating in timer triggered measurement mode.
+ *****************************************************************************/
+bool Argus_IsTimerMeasurementActive(argus_hnd_t *hnd);
+
+/*!***************************************************************************
+ * @brief Stops the currently ongoing measurements and SPI activity immediately.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_Abort(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Checks the state of the device/driver.
+ * @brief Checks the state of the device/driver.
*
- * @details Returns the current module status or error if any.
- * See the following for a list of errors:
+ * @details Returns the current module status or error if any.
*
- * Status:
- * - Idle/OK: Device and SPI interface are idle (== #STATUS_IDLE).
- * - Busy: Device or SPI interface are busy (== #STATUS_BUSY).
- * - Initializing: The modules and devices are currently initializing
- * (== #STATUS_INITIALIZING).
- * .
+ * See the following for a list of errors:
*
- * Error:
- * - Not Initialized: The modules (or any submodule) has not been
- * initialized yet (== #ERROR_NOT_INITIALIZED).
- * - Not Connected: No device has been connected (or connection errors
- * have occurred) (== #ERROR_ARGUS_NOT_CONNECTED).
- * - Timeout: A previous frame measurement has not finished within a
- * specified time (== #ERROR_TIMEOUT).
- * .
+ * Status:
+ * - Idle/OK: Device and SPI interface are idle (== #STATUS_IDLE).
+ * - Busy: Device or SPI interface are busy (== #STATUS_BUSY).
+ * - Initializing: The modules and devices are currently initializing
+ * (== #STATUS_INITIALIZING).
+ * .
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * Error:
+ * - Not Initialized: The modules (or any submodule) has not been
+ * initialized yet (== #ERROR_NOT_INITIALIZED).
+ * - Not Connected: No device has been connected (or connection errors
+ * have occurred) (== #ERROR_ARGUS_NOT_CONNECTED).
+ * - Timeout: A previous frame measurement has not finished within a
+ * specified time (== #ERROR_TIMEOUT).
+ * .
+ *
+ * @note Note that this function returns the actual busy state. This means
+ * that it will return #STATUS_IDLE during the pause between two
+ * consecutive measurement frames. If the device is active with timer
+ * based measurements (i.e. started via the #Argus_StartMeasurementTimer
+ * function), the return state switches from idle to busy and back
+ * periodically. Use the #Argus_IsTimerMeasurementActive function in
+ * order to determine if the device is active with timer based
+ * measurements.
+ *
+ * @note Note also that the device might reject configuration parameter
+ * update despite the status is #STATUS_IDLE. This is due to the fact
+ * that the internal raw data buffers are still busy and require to
+ * be freed by passing them to the #Argus_EvaluateData function. Use
+ * the #Argus_IsDataEvaluationPending function to see whether any of
+ * the raw data buffers is busy or the configuration can be changed.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetStatus(argus_hnd_t *hnd);
/*!*****************************************************************************
- * @brief Tests the connection to the device by sending a ping message.
+ * @brief Tests the connection to the device by sending a ping message.
*
- * @details A ping is transfered to the device in order to check the device and
- * SPI connection status. Returns #STATUS_OK on success and
- * #ERROR_ARGUS_NOT_CONNECTED elsewise.
+ * @details A ping is transferred to the device in order to check the device and
+ * SPI connection status. Returns #STATUS_OK on success and
+ * #ERROR_ARGUS_NOT_CONNECTED else-wise.
*
- * @param hnd The API handle; contains all internal states and data.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
******************************************************************************/
status_t Argus_Ping(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Evaluate useful information from the raw measurement data.
+ * @brief Evaluates measurement data from the raw sensor readout data.
*
- * @details This function is called with a pointer to the raw results obtained
- * from the measurement cycle. It evaluates this data and creates
- * useful information from it. Furthermore, calibration is applied to
- * the data. Finally, the results are used in order to adapt the device
- * configuration to the ambient conditions in order to achieve optimal
- * device performance.
+ * @details This function must be called after each completion of a measurement
+ * cycle. The completion of a measurement cycle is communicated by the
+ * API via the invocation of the measurement data ready callback. The
+ * callback is installed in the API when new measurements are started
+ * either via the #Argus_TriggerMeasurement or via the
+ * #Argus_StartMeasurementTimer functions.
*
- * Therefore, it consists of the following sub-functions:
- * - Apply pre-calibration: Applies calibration steps before evaluating
- * the data, i.e. calculations that are to the integration results
- * directly.
- * - Evaluate data: Calculates measurement parameters such as range,
- * amplitude or ambient light intensity, depending on the configurations.
- * - Apply post-calibration: Applies calibrations after evaluation of
- * measurement data, i.e. calibrations applied to the calculated
- * values such as range.
- * - Dynamic Configuration Adaption: checks if the configuration needs
- * to be adjusted before the next measurement cycle in order to
- * achieve optimum performance. Note that the configuration might not
- * applied directly but before the next measurement starts. This is
- * due to the fact that the device could be busy measuring already
- * the next frame and thus no SPI activity is allowed.
- * .
- * However, if the device is idle, the configuration will be written
- * immediately.
+ * This function evaluates measurement values like distances, amplitudes
+ * states and auxiliary values like temperature or voltage values from
+ * the raw sensor readout data obtained from the device during the
+ * measurement cycle. A pointer to a #argus_results_t data structure
+ * must be passed where all the evaluated values will be written to.
+ * The structure must persist during the whole execution of the
+ * #Argus_EvaluateData function.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param res A pointer to the results structure that will be populated
- * with evaluated data.
- * @param raw The pointer to the raw data that has been obtained by the
- * measurement finished callback.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * In addition to the evaluation of measurement data, the function
+ * feeds back the obtained information to the device in order to
+ * optimize its performance with respect to the ambient conditions,
+ * utilizing the so called Dynamic Configuration Adaption (DCA)
+ * feature.
+ *
+ * Furthermore, several calibration algorithm are applied to the data.
+ *
+ * If the function is called without any data ready to be evaluated
+ * from the measurement module, the error code #ERROR_ARGUS_BUFFER_EMPTY
+ * is returned and not data is written to the passed #argus_results_t
+ * data structure.
+ *
+ * @note The call to this function is mandatory for each finished measurement
+ * cycle, i.e. for each call to the measurement data ready callback.
+ * If the function is not called, the data is not evaluated and the
+ * internal raw data buffers are not freed. In that case, they can not
+ * be reused for the next measurement and the API can not start new
+ * measurements.
+ * There are up to two internal buffers available, the to callback
+ * is called twice before the API must wait for the data evaluation
+ * to finish.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param res A pointer to the results structure that will be populated
+ * with evaluated data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_EvaluateData(argus_hnd_t *hnd, argus_results_t *res, void *raw);
+status_t Argus_EvaluateData(argus_hnd_t *hnd, argus_results_t *res);
/*!***************************************************************************
- * @brief Executes a crosstalk calibration measurement.
+ * @brief Evaluates measurement data from the raw sensor readout data.
+ *
+ * @details This function enhances the #Argus_EvaluateData by adding additional
+ * debug data into a specified debug data structure (\p dbg). If the
+ * \p dbg is null, the function is eqivalent to the #Argus_EvaluateData
+ * function. This, see #Argus_EvaluateData for reference.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param res A pointer to the results structure that will be populated
+ * with evaluated data.
+ * @param dbg An optional pointer (can be null) to the debug data structure.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ *****************************************************************************/
+status_t Argus_EvaluateDataDebug(argus_hnd_t *hnd, argus_results_t *res,
+ argus_results_debug_t *dbg);
+
+/*!***************************************************************************
+ * @brief Executes a crosstalk calibration measurement.
*
* @details This function immediately triggers a crosstalk vector calibration
- * measurement sequence. The ordinary measurement activity is suspended
- * while the calibration is ongoing.
+ * measurement sequence. The ordinary measurement activity is suspended
+ * while the calibration is ongoing.
*
- * In order to perform a crosstalk calibration, the reflection of the
- * transmitted signal must be kept from the receiver side, by either
- * covering the TX completely (or RX respectively) or by setting up
- * an absorbing target at far distance.
+ * In order to perform a crosstalk calibration, the reflection of the
+ * transmitted signal must be kept from the receiver side, by either
+ * covering the TX completely (or RX respectively) or by setting up
+ * an absorbing target at far distance.
*
- * After calibration has finished successfully, the obtained data is
- * applied immediately and can be read from the API using the
- * #Argus_GetCalibrationCrosstalkVectorTable function.
+ * After calibration has finished successfully, the obtained data is
+ * applied immediately and can be read from the API using the
+ * #Argus_GetCalibrationCrosstalkVectorTable function.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_ExecuteXtalkCalibrationSequence(argus_hnd_t *hnd, argus_mode_t mode);
-
+status_t Argus_ExecuteXtalkCalibrationSequence(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Executes a relative range offset calibration measurement.
+ * @brief Executes a relative range offset calibration measurement.
*
* @details This function immediately triggers a relative range offset calibration
- * measurement sequence. The ordinary measurement activity is suspended
- * while the calibration is ongoing.
+ * measurement sequence. The ordinary measurement activity is suspended
+ * while the calibration is ongoing.
*
- * In order to perform a relative range offset calibration, a flat
- * calibration target must be setup perpendicular to the sensors
- * field-of-view.
+ * In order to perform a relative range offset calibration, a flat
+ * calibration target must be setup perpendicular to the sensors
+ * field-of-view.
*
- * \code
+ * \code
* AFBR-S50 ToF Sensor
- * #|
- * #| |
- * #|-----+ |
- * #| Rx | |
- * Reference #|----++ | Calibration
- * Plane #| Tx | | Target
- * #|----+ |
- * #| |
- * #| <------- targetRange -----------------> |
- * \endcode
+ * #|
+ * #| |
+ * #|-----+ |
+ * #| RX | |
+ * Reference #|----++ | Calibration
+ * Plane #| TX | | Target
+ * #|----+ |
+ * #| |
+ * #| <------- targetRange -----------------> |
+ * \endcode
*
- * There are two options to run the offset calibration: relative and
- * absolute.
- * - Relative (#Argus_ExecuteRelativeRangeOffsetCalibrationSequence):
- * when the absolute distance is not essential or the distance to
- * the calibration target is not known, the relative method can be
- * used to compensate the relative pixel range offset w.r.t. the
- * average range. The absolute or global range offset is not changed.
- * - Absolute (#Argus_ExecuteAbsoluteRangeOffsetCalibrationSequence):
- * when the absolute distance is essential and the distance to the
- * calibration target is known, the absolute method can be used to
- * calibrate the absolute measured distance. Additionally, the
- * relative pixel offset w.r.t. the average range is also compensated.
- * .
+ * There are two options to run the offset calibration: relative and
+ * absolute.
*
- * After calibration has finished successfully, the obtained data is
- * applied immediately and can be read from the API using the
- * #Argus_GetCalibrationPixelRangeOffsets or
- * #Argus_GetCalibrationGlobalRangeOffset function.
+ * - Relative (#Argus_ExecuteRelativeRangeOffsetCalibrationSequence):
+ * when the absolute distance is not essential or the distance to
+ * the calibration target is not known, the relative method can be
+ * used to compensate the relative pixel range offset w.r.t. the
+ * average range. The absolute or global range offset is not changed.
+ * - Absolute (#Argus_ExecuteAbsoluteRangeOffsetCalibrationSequence):
+ * when the absolute distance is essential and the distance to the
+ * calibration target is known, the absolute method can be used to
+ * calibrate the absolute measured distance. Additionally, the
+ * relative pixel offset w.r.t. the average range is also compensated.
+ * .
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * After calibration has finished successfully, the obtained data is
+ * applied immediately and can be read from the API using the
+ * #Argus_GetCalibrationPixelRangeOffsets or
+ * #Argus_GetCalibrationGlobalRangeOffset function.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_ExecuteRelativeRangeOffsetCalibrationSequence(argus_hnd_t *hnd,
- argus_mode_t mode);
+status_t Argus_ExecuteRelativeRangeOffsetCalibrationSequence(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Executes an absolute range offset calibration measurement.
+ * @brief Executes an absolute range offset calibration measurement.
*
* @details This function immediately triggers an absolute range offset calibration
- * measurement sequence. The ordinary measurement activity is suspended
- * while the calibration is ongoing.
+ * measurement sequence. The ordinary measurement activity is suspended
+ * while the calibration is ongoing.
*
- * In order to perform a relative range offset calibration, a flat
- * calibration target must be setup perpendicular to the sensors
- * field-of-view.
+ * In order to perform a relative range offset calibration, a flat
+ * calibration target must be setup perpendicular to the sensors
+ * field-of-view.
*
- * \code
+ * \code
* AFBR-S50 ToF Sensor
- * #|
- * #| |
- * #|-----+ |
- * #| Rx | |
- * Reference #|----++ | Calibration
- * Plane #| Tx | | Target
- * #|----+ |
- * #| |
- * #| <------- targetRange -----------------> |
- * \endcode
+ * #|
+ * #| |
+ * #|-----+ |
+ * #| RX | |
+ * Reference #|----++ | Calibration
+ * Plane #| TX | | Target
+ * #|----+ |
+ * #| |
+ * #| <------- targetRange -----------------> |
+ * \endcode
*
- * There are two options to run the offset calibration: relative and
- * absolute.
- * - Relative (#Argus_ExecuteRelativeRangeOffsetCalibrationSequence):
- * when the absolute distance is not essential or the distance to
- * the calibration target is not known, the relative method can be
- * used to compensate the relative pixel range offset w.r.t. the
- * average range. The absolute or global range offset is not changed.
- * - Absolute (#Argus_ExecuteAbsoluteRangeOffsetCalibrationSequence):
- * when the absolute distance is essential and the distance to the
- * calibration target is known, the absolute method can be used to
- * calibrate the absolute measured distance. Additionally, the
- * relative pixel offset w.r.t. the average range is also compensated.
- * .
+ * There are two options to run the offset calibration: relative and
+ * absolute.
*
- * After calibration has finished successfully, the obtained data is
- * applied immediately and can be read from the API using the
- * #Argus_GetCalibrationPixelRangeOffsets or
- * #Argus_GetCalibrationGlobalRangeOffset function.
+ * - Relative (#Argus_ExecuteRelativeRangeOffsetCalibrationSequence):
+ * when the absolute distance is not essential or the distance to
+ * the calibration target is not known, the relative method can be
+ * used to compensate the relative pixel range offset w.r.t. the
+ * average range. The absolute or global range offset is not changed.
+ * - Absolute (#Argus_ExecuteAbsoluteRangeOffsetCalibrationSequence):
+ * when the absolute distance is essential and the distance to the
+ * calibration target is known, the absolute method can be used to
+ * calibrate the absolute measured distance. Additionally, the
+ * relative pixel offset w.r.t. the average range is also compensated.
+ * .
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param targetRange The absolute range between the reference plane and the
- * calibration target in meter an Q9.22 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * After calibration has finished successfully, the obtained data is
+ * applied immediately and can be read from the API using the
+ * #Argus_GetCalibrationPixelRangeOffsets or
+ * #Argus_GetCalibrationGlobalRangeOffset function.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param targetRange The absolute range between the reference plane and the
+ * calibration target in meter an Q9.22 format.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_ExecuteAbsoluteRangeOffsetCalibrationSequence(argus_hnd_t *hnd,
- argus_mode_t mode,
q9_22_t targetRange);
/*! @} */
@@ -600,188 +790,245 @@ status_t Argus_ExecuteAbsoluteRangeOffsetCalibrationSequence(argus_hnd_t *hnd,
/*!**************************************************************************
* Configuration API
****************************************************************************
- * @addtogroup arguscfg
+ * @addtogroup argus_cfg
* @{
****************************************************************************/
/*!***************************************************************************
- * @brief Sets the measurement mode to a specified device.
+ * @brief Gets the default measurement mode for a specified module type.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The new measurement mode.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param module The specified module type.
+ * @return Returns the default measurement mode for the specified module type.
*****************************************************************************/
-status_t Argus_SetConfigurationMeasurementMode(argus_hnd_t *hnd,
- argus_mode_t value);
+argus_mode_t Argus_GetDefaultMeasurementMode(argus_module_version_t module);
/*!***************************************************************************
- * @brief Gets the measurement mode from a specified device.
+ * @brief Sets the measurement mode to a specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The current measurement mode.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @details This generates a new default configuration and calibration for the
+ * specified measurement mode and applies it to the device.
+ *
+ * See #argus_mode_t for a list of all available measurement modes.
+ *
+ * @warning The function overwrites all made changes to the configuration or
+ * calibration parameters with the default values. So this function
+ * must be called before any other changes to the configuration or
+ * calibration parameters are made!
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param mode The new measurement mode.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_GetConfigurationMeasurementMode(argus_hnd_t *hnd,
- argus_mode_t *value);
+status_t Argus_SetMeasurementMode(argus_hnd_t *hnd, argus_mode_t mode);
/*!***************************************************************************
- * @brief Sets the frame time to a specified device.
+ * @brief Resets the measurement mode to a specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The measurement frame time in microseconds.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @details This generates a new default configuration and calibration for the
+ * current measurement mode and applies it to the device.
+ *
+ * @warning The function overwrites all made changes to the configuration or
+ * calibration parameters with the default values. So this function
+ * must be called before any other changes to the configuration or
+ * calibration parameters are made!
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ *****************************************************************************/
+status_t Argus_ResetMeasurementMode(argus_hnd_t *hnd);
+
+/*!***************************************************************************
+ * @brief Gets the measurement mode from a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param mode The current measurement mode.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ *****************************************************************************/
+status_t Argus_GetMeasurementMode(argus_hnd_t *hnd, argus_mode_t *mode);
+
+/*!***************************************************************************
+ * @brief Sets the frame time to a specified device.
+ *
+ * @details The frame time determines the measurement rate of the device.
+ * Usually, this controller the periodicity of measurements to be
+ * triggered via the timer based measurement mode that can be started
+ * via the #Argus_StartMeasurementTimer function. But also the
+ * behavior of the #Argus_TriggerMeasurement function is influenced
+ * by the frame rate parameter.
+ *
+ * The frame time parameter handles the maximum frame rate by limiting
+ * the trigger of a new measurement frame to the specified value.
+ * On the other hand, the accuracy of measurement results it also
+ * influenced since the frame time specifies the maximum integration
+ * depth (i.e. exposure time) along with the laser safety limitations.
+ * This means, the measurement speed can be increased by decreasing
+ * the frame time parameter and the accuracy can be improved by
+ * increasing the frame time parameter.
+ *
+ * Note the additional factor will limit the maximum frame rate on the
+ * one hand and the accuracy on the other hand:
+ * - High CPU load (or slow CPU in general) will lead to delays due
+ * to long data evaluation task (#Argus_EvaluateData) or long user
+ * application code. Reduce CPU load or increase CPU power to
+ * increase maximum frame rate.
+ * - The dual frequency mode (DFM, see #Argus_SetConfigurationDFMMode)
+ * will additionally limit the maximum frame rate to approximately
+ * 100 frames per second. Disable the DFM to increase maximum frame
+ * rates.
+ * - The smart power save (SPS, see
+ * #Argus_SetConfigurationSmartPowerSaveEnabled) mode will decrease
+ * the maximum possible frame rate slightly. Disable it to increase
+ * the maximum frame rate.
+ * - The dynamic configuration adaption with its specific power saving
+ * ratio parameter (see #Argus_SetConfigurationDynamicAdaption)
+ * will limit the maximum integration depth along with the laser
+ * safety limitations. Increase the power saving ratio to increase
+ * accuracy. Note that laser safety limitations might already limit
+ * the maximum integration depth such that the power saving ratio
+ * is ineffective.
+ * .
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The measurement frame time in microseconds.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetConfigurationFrameTime(argus_hnd_t *hnd, uint32_t value);
/*!***************************************************************************
- * @brief Gets the frame time from a specified device.
+ * @brief Gets the frame time from a specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The current frame time in microseconds.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current frame time in microseconds.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetConfigurationFrameTime(argus_hnd_t *hnd, uint32_t *value);
/*!***************************************************************************
- * @brief Sets the smart power save enabled flag to a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new smart power save enabled flag.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Sets the smart power save enabled flag to a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new smart power save enabled flag.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetConfigurationSmartPowerSaveEnabled(argus_hnd_t *hnd,
- argus_mode_t mode,
bool value);
/*!***************************************************************************
- * @brief Gets the smart power save enabled flag from a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current smart power save enabled flag.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Gets the smart power save enabled flag from a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current smart power save enabled flag.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetConfigurationSmartPowerSaveEnabled(argus_hnd_t *hnd,
- argus_mode_t mode,
bool *value);
/*!***************************************************************************
- * @brief Sets the Dual Frequency Mode (DFM) to a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new DFM mode value.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Sets the Dual Frequency Mode (DFM) to a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new DFM mode value.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetConfigurationDFMMode(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_dfm_mode_t value);
/*!***************************************************************************
- * @brief Gets the Dual Frequency Mode (DFM) from a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current DFM mode value.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Gets the Dual Frequency Mode (DFM) from a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current DFM mode value.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetConfigurationDFMMode(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_dfm_mode_t *value);
/*!***************************************************************************
- * @brief Sets the Shot Noise Monitor (SNM) mode to a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new SNM mode value.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Sets the Shot Noise Monitor (SNM) mode to a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new SNM mode value.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetConfigurationShotNoiseMonitorMode(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_snm_mode_t value);
/*!***************************************************************************
- * @brief Gets the Shot Noise Montor (SNM) mode from a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current SNM mode value.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Gets the Shot Noise Monitor (SNM) mode from a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current SNM mode value.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetConfigurationShotNoiseMonitorMode(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_snm_mode_t *value);
-#if 0
-///*!***************************************************************************
-// * @brief Sets the Crosstalk Monitor (XTM) mode to a specified device.
-// * @param hnd The API handle; contains all internal states and data.
-// * @param mode The targeted measurement mode.
-// * @param value The new XTM mode value (true: enabled; false: disabled).
-// * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
-// *****************************************************************************/
-//status_t Argus_SetConfigurationCrosstalkMonitorMode(argus_hnd_t * hnd,
-// argus_mode_t mode,
-// bool value);
-//
-///*!***************************************************************************
-// * @brief Gets the Crosstalk Monitor (XTM) mode from a specified device.
-// * @param hnd The API handle; contains all internal states and data.
-// * @param mode The targeted measurement mode.
-// * @param value The current XTM mode value (true: enabled; false: disabled).
-// * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
-// *****************************************************************************/
-//status_t Argus_GetConfigurationCrosstalkMonitorMode(argus_hnd_t * hnd,
-// argus_mode_t mode,
-// bool * value);
-#endif
/*!***************************************************************************
- * @brief Sets the full DCA module configuration to a specified device.
+* @brief Sets the Crosstalk Monitor (XTM) mode to a specified device.
+*
+* @param hnd The API handle; contains all internal states and data.
+* @param value The new XTM mode value (true: enabled; false: disabled).
+* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+*****************************************************************************/
+status_t Argus_SetConfigurationCrosstalkMonitorMode(argus_hnd_t *hnd,
+ bool value);
+
+/*!***************************************************************************
+* @brief Gets the Crosstalk Monitor (XTM) mode from a specified device.
+*
+* @param hnd The API handle; contains all internal states and data.
+* @param value The current XTM mode value (true: enabled; false: disabled).
+* @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+*****************************************************************************/
+status_t Argus_GetConfigurationCrosstalkMonitorMode(argus_hnd_t *hnd,
+ bool *value);
+
+/*!***************************************************************************
+ * @brief Sets the full DCA module configuration to a specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new DCA configuration set.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new DCA configuration set.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetConfigurationDynamicAdaption(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_cfg_dca_t const *value);
/*!***************************************************************************
- * @brief Gets the # from a specified device.
+ * @brief Gets the # from a specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current DCA configuration set value.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current DCA configuration set value.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetConfigurationDynamicAdaption(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_cfg_dca_t *value);
/*!***************************************************************************
- * @brief Sets the pixel binning configuration parameters to a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new pixel binning configuration parameters.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Sets the pixel binning configuration parameters to a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new pixel binning configuration parameters.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetConfigurationPixelBinning(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_cfg_pba_t const *value);
/*!***************************************************************************
- * @brief Gets the pixel binning configuration parameters from a specified device.
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current pixel binning configuration parameters.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Gets the pixel binning configuration parameters from a specified device.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current pixel binning configuration parameters.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetConfigurationPixelBinning(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_cfg_pba_t *value);
/*!***************************************************************************
- * @brief Gets the current unambiguous range in mm.
- * @param hnd The API handle; contains all internal states and data.
- * @param range_mm The returned range in mm.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Gets the current unambiguous range in mm.
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param range_mm The returned range in mm.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetConfigurationUnambiguousRange(argus_hnd_t *hnd,
uint32_t *range_mm);
@@ -791,458 +1038,398 @@ status_t Argus_GetConfigurationUnambiguousRange(argus_hnd_t *hnd,
/*!**************************************************************************
* Calibration API
****************************************************************************
- * @addtogroup arguscal
+ * @addtogroup argus_cal
* @{
****************************************************************************/
/*!***************************************************************************
- * @brief Sets the global range offset value to a specified device.
+ * @brief Sets the global range offset value to a specified device.
*
- * @details The global range offset is subtracted from the raw range values.
+ * @details The global range offset is subtracted from the raw range values.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new global range offset in meter and Q0.15 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new global range offset in meter and Q0.15 format.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetCalibrationGlobalRangeOffset(argus_hnd_t *hnd,
- argus_mode_t mode,
q0_15_t value);
/*!***************************************************************************
- * @brief Gets the global range offset value from a specified device.
+ * @brief Gets the global range offset value from a specified device.
*
- * @details The global range offset is subtracted from the raw range values.
+ * @details The global range offset is subtracted from the raw range values.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current global range offset in meter and Q0.15 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current global range offset in meter and Q0.15 format.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetCalibrationGlobalRangeOffset(argus_hnd_t *hnd,
- argus_mode_t mode,
q0_15_t *value);
/*!***************************************************************************
- * @brief Sets the relative pixel offset table to a specified device.
+ * @brief Sets the relative pixel offset table to a specified device.
*
* @details The relative pixel offset values are subtracted from the raw range
- * values for each individual pixel. Note that a global range offset
- * is applied additionally. The relative pixel offset values are meant
- * to be with respect to the average range of all pixels, i.e. the
- * average of all relative offsets should be 0!
+ * values for each individual pixel. Note that a global range offset
+ * is applied additionally. The relative pixel offset values are meant
+ * to be with respect to the average range of all pixels, i.e. the
+ * average of all relative offsets should be 0!
*
- * The crosstalk vector table is a two dimensional array of type
- * #q0_15_t.
+ * The crosstalk vector table is a two dimensional array of type
+ * #q0_15_t, wrapped within the #argus_cal_offset_table_t structure.
*
- * The dimensions are:
- * - size(0) = #ARGUS_PIXELS_X (Pixel count in x-direction)
- * - size(1) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
- * .
+ * The dimensions are:
+ * - size(0) = #ARGUS_PIXELS_X (Pixel count in x-direction)
+ * - size(1) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
+ * .
*
- * Its recommended to use the built-in pixel offset calibration
- * sequence (see #Argus_ExecuteRelativeRangeOffsetCalibrationSequence)
- * to determine the offset table for the current device.
+ * Its recommended to use the built-in pixel offset calibration
+ * sequence (see #Argus_ExecuteRelativeRangeOffsetCalibrationSequence)
+ * to determine the offset table for the current device.
*
- * If a constant offset table for all device needs to be incorporated
- * into the sources, the #Argus_GetExternalPixelRangeOffsets_Callback
- * should be used.
+ * If a constant offset table for all device needs to be incorporated
+ * into the sources, the #Argus_GetPixelRangeOffsets_Callback
+ * should be used.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new relative range offset in meter and Q0.15 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new relative range offset in meter and Q0.15 format.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_SetCalibrationPixelRangeOffsets(argus_hnd_t *hnd, argus_mode_t mode,
- q0_15_t value[ARGUS_PIXELS_X][ARGUS_PIXELS_Y]);
+status_t Argus_SetCalibrationPixelRangeOffsets(argus_hnd_t *hnd,
+ argus_cal_offset_table_t const *value);
/*!***************************************************************************
- * @brief Gets the relative pixel offset table from a specified device.
+ * @brief Gets the relative pixel offset table from a specified device.
*
* @details The relative pixel offset values are subtracted from the raw range
- * values for each individual pixel. Note that a global range offset
- * is applied additionally. The relative pixel offset values are meant
- * to be with respect to the average range of all pixels, i.e. the
- * average of all relative offsets should be 0!
+ * values for each individual pixel. Note that a global range offset
+ * is applied additionally. The relative pixel offset values are meant
+ * to be with respect to the average range of all pixels, i.e. the
+ * average of all relative offsets should be 0!
*
- * The crosstalk vector table is a two dimensional array of type
- * #q0_15_t.
+ * The crosstalk vector table is a two dimensional array of type
+ * #q0_15_t, wrapped within the #argus_cal_offset_table_t structure.
*
- * The dimensions are:
- * - size(0) = #ARGUS_PIXELS_X (Pixel count in x-direction)
- * - size(1) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
- * .
+ * The dimensions are:
+ * - size(0) = #ARGUS_PIXELS_X (Pixel count in x-direction)
+ * - size(1) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
+ * .
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current relative range offset in meter and Q0.15 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current relative range offset in meter and Q0.15 format.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_GetCalibrationPixelRangeOffsets(argus_hnd_t *hnd, argus_mode_t mode,
- q0_15_t value[ARGUS_PIXELS_X][ARGUS_PIXELS_Y]);
+status_t Argus_GetCalibrationPixelRangeOffsets(argus_hnd_t *hnd,
+ argus_cal_offset_table_t *value);
/*!***************************************************************************
- * @brief Gets the relative pixel offset table from a specified device.
+ * @brief Resets the relative pixel offset values for the specified device to
+ * the factory calibrated default values.
*
* @details The relative pixel offset values are subtracted from the raw range
- * values for each individual pixel. Note that a global range offset
- * is applied additionally. The relative pixel offset values are meant
- * to be with respect to the average range of all pixels, i.e. the
- * average of all relative offsets should be 0!
+ * values for each individual pixel. Note that a global range offset
+ * is applied additionally.
*
- * The crosstalk vector table is a two dimensional array of type
- * #q0_15_t.
+ * The factory defaults are device specific values.
*
- * The dimensions are:
- * - size(0) = #ARGUS_PIXELS_X (Pixel count in x-direction)
- * - size(1) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
- *
- * The total offset table consists of the custom pixel offset values
- * (set via #Argus_SetCalibrationPixelRangeOffsets) and the internal,
- * factory calibrated device specific offset values.
- * This is informational only!
- *
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current total relative range offset in meter and Q0.15 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_GetCalibrationTotalPixelRangeOffsets(argus_hnd_t *hnd, argus_mode_t mode,
- q0_15_t value[ARGUS_PIXELS_X][ARGUS_PIXELS_Y]);
-
+status_t Argus_ResetCalibrationPixelRangeOffsets(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Resets the relative pixel offset values for the specified device to
- * the factory calibrated default values.
- *
- * @details The relative pixel offset values are subtracted from the raw range
- * values for each individual pixel. Note that a global range offset
- * is applied additionally.
- *
- * The factory defaults are device specific values.
- *
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
- *****************************************************************************/
-status_t Argus_ResetCalibrationPixelRangeOffsets(argus_hnd_t *hnd, argus_mode_t mode);
-
-/*!***************************************************************************
- * @brief A callback that returns the external pixel range offsets.
+ * @brief A callback that returns the external pixel range offsets.
*
* @details The function needs to be implemented by the host application in
- * order to set the external pixel range offsets values upon system
- * initialization. If not defined in user code, the default
- * implementation will return an all zero offset table, assuming there
- * is no (additional) external pixel range offset values.
+ * order to set the external pixel range offsets values upon system
+ * initialization. If not defined in user code, the default
+ * implementation will return an all zero offset table, assuming there
+ * is no (additional) external pixel range offset values.
*
- * If defined in user code, the function must fill all offset values
- * in the provided \par offsets parameter with external range offset
- * values.
- * The values can be obtained by the calibration routine.
+ * If defined in user code, the function must fill all offset values
+ * in the provided \par offsets parameter with external range offset
+ * values.
+ * The values can be obtained by the calibration routine.
*
- * Example usage:
+ * Example usage:
*
- * @code
- * status_t Argus_GetExternalPixelRangeOffsets_Callback(q0_15_t offsets[ARGUS_PIXELS_X][ARGUS_PIXELS_Y],
- * argus_mode_t mode)
- * {
- * (void) mode; // Ignore mode; use same values for all modes.
- * memset(offsets, 0, sizeof(q0_15_t) * ARGUS_PIXELS);
+ * @code
+ * status_t Argus_GetPixelRangeOffsets_Callback(argus_cal_offset_table_t offsets)
+ * {
+ * memset(offsets, 0, sizeof(argus_cal_offset_t));
*
- * // Set offset values in meter and Q0.15 format.
- * offsets[0][0].dS = -16384; offsets[0][0].dC = -32768;
- * offsets[0][1].dS = -32768; offsets[0][1].dC = 0;
- * offsets[0][2].dS = 16384; offsets[0][2].dC = -16384;
- * // etc.
- * }
- * @endcode
+ * // Set offset values in meter and Q0.15 format.
+ * offsets.Table[0][0] = -3542;
+ * offsets.Table[0][1] = -4385;
+ * offsets.Table[0][2] = 2953;
+ * // etc.
+ * }
+ * @endcode
*
- * @param offsets The pixel range offsets in meter and Q0.15 format; to be
- * filled with data.
- * @param mode Determines the current measurement mode; can be ignored if
- * only a single measurement mode is utilized.
+ * @param offsets The pixel range offsets in meter and Q0.15 format; to be
+ * filled with data.
+ * @param mode The current measurement mode.
*****************************************************************************/
-void Argus_GetExternalPixelRangeOffsets_Callback(q0_15_t offsets[ARGUS_PIXELS_X][ARGUS_PIXELS_Y],
- argus_mode_t mode);
+void Argus_GetPixelRangeOffsets_Callback(argus_cal_offset_table_t *offsets,
+ argus_mode_t const mode);
/*!***************************************************************************
- * @brief Sets the sample time for the range offset calibration sequence.
+ * @brief Sets the sample time for the range offset calibration sequence.
*
- * @details Gets the measurement sample acquisition time for executing the
- * range offset calibration sequence and generate the offset data.\n
- * Units: msec.
+ * @details Gets the measurement sample acquisition time for executing the
+ * range offset calibration sequence and generate the offset data.\n
+ * Units: msec.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The new range offset calibration sequence sample time.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new range offset calibration sequence sample time.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetCalibrationRangeOffsetSequenceSampleTime(argus_hnd_t *hnd, uint16_t value);
/*!***************************************************************************
- * @brief Gets the sample time for the range offset calibration sequence.
+ * @brief Gets the sample time for the range offset calibration sequence.
*
- * @details Gets the measurement sample acquisition time for executing the
- * range offset calibration sequence and generate the ooffset data.\n
- * Units: msec.
+ * @details Gets the measurement sample acquisition time for executing the
+ * range offset calibration sequence and generate the offset data.\n
+ * Units: msec.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The current range offset calibration sequence sample time.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current range offset calibration sequence sample time.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetCalibrationRangeOffsetSequenceSampleTime(argus_hnd_t *hnd, uint16_t *value);
/*!***************************************************************************
- * @brief Sets the pixel-to-pixel crosstalk compensation parameters to a specified device.
+ * @brief Sets the pixel-to-pixel crosstalk compensation parameters to a specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new pixel-to-pixel crosstalk compensation parameters.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new pixel-to-pixel crosstalk compensation parameters.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetCalibrationCrosstalkPixel2Pixel(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_cal_p2pxtalk_t const *value);
/*!***************************************************************************
- * @brief Gets the pixel-to-pixel crosstalk compensation parameters from a specified device.
+ * @brief Gets the pixel-to-pixel crosstalk compensation parameters from a specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current pixel-to-pixel crosstalk compensation parameters.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current pixel-to-pixel crosstalk compensation parameters.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetCalibrationCrosstalkPixel2Pixel(argus_hnd_t *hnd,
- argus_mode_t mode,
argus_cal_p2pxtalk_t *value);
/*!***************************************************************************
- * @brief Sets the custom crosstalk vector table to a specified device.
+ * @brief Sets the custom crosstalk vector table to a specified device.
*
* @details The crosstalk vectors are subtracted from the raw sampling data
- * in the data evaluation phase.
+ * in the data evaluation phase.
*
- * The crosstalk vector table is a three dimensional array of type
- * #xtalk_t.
+ * The crosstalk vector table is a three dimensional array of type
+ * #xtalk_t. The #argus_cal_xtalk_table_t is the corresponding
+ * typedef for the required data.
*
- * The dimensions are:
- * - size(0) = #ARGUS_DFM_FRAME_COUNT (Dual-frequency mode A- or B-frame)
- * - size(1) = #ARGUS_PIXELS_X (Pixel count in x-direction)
- * - size(2) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
- * .
+ * The dimensions are:
+ * - size(0) = #ARGUS_DFM_FRAME_COUNT (Dual-frequency mode A- or B-frame)
+ * - size(1) = #ARGUS_PIXELS_X (Pixel count in x-direction)
+ * - size(2) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
+ * .
*
- * Its recommended to use the built-in crosstalk calibration sequence
- * (see #Argus_ExecuteXtalkCalibrationSequence) to determine the
- * crosstalk vector table.
+ * Its recommended to use the built-in crosstalk calibration sequence
+ * (see #Argus_ExecuteXtalkCalibrationSequence) to determine the
+ * crosstalk vector table.
*
- * If a constant table for all device needs to be incorporated into
- * the sources, the #Argus_GetExternalCrosstalkVectorTable_Callback
- * should be used.
+ * If a constant table for all device needs to be incorporated into
+ * the sources, the #Argus_GetCrosstalkVectorTable_Callback
+ * should be used.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The new crosstalk vector table.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new crosstalk vector table.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetCalibrationCrosstalkVectorTable(argus_hnd_t *hnd,
- argus_mode_t mode,
- xtalk_t value[ARGUS_DFM_FRAME_COUNT][ARGUS_PIXELS_X][ARGUS_PIXELS_Y]);
+ argus_cal_xtalk_table_t const *value);
/*!***************************************************************************
- * @brief Gets the custom crosstalk vector table from a specified device.
+ * @brief Gets the custom crosstalk vector table from a specified device.
*
* @details The crosstalk vectors are subtracted from the raw sampling data
- * in the data evaluation phase.
+ * in the data evaluation phase.
*
- * The crosstalk vector table is a three dimensional array of type
- * #xtalk_t.
+ * The crosstalk vector table is a three dimensional array of type
+ * #xtalk_t. The #argus_cal_xtalk_table_t is the corresponding
+ * typedef for the required data.
*
- * The dimensions are:
- * - size(0) = #ARGUS_DFM_FRAME_COUNT (Dual-frequency mode A- or B-frame)
- * - size(1) = #ARGUS_PIXELS_X (Pixel count in x-direction)
- * - size(2) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
- * .
+ * The dimensions are:
+ * - size(0) = #ARGUS_DFM_FRAME_COUNT (Dual-frequency mode A- or B-frame)
+ * - size(1) = #ARGUS_PIXELS_X (Pixel count in x-direction)
+ * - size(2) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
+ * .
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current crosstalk vector table.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current crosstalk vector table.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetCalibrationCrosstalkVectorTable(argus_hnd_t *hnd,
- argus_mode_t mode,
- xtalk_t value[ARGUS_DFM_FRAME_COUNT][ARGUS_PIXELS_X][ARGUS_PIXELS_Y]);
+ argus_cal_xtalk_table_t *value);
/*!***************************************************************************
- * @brief Gets the factory calibrated default crosstalk vector table for the
- * specified device.
+ * @brief Resets the crosstalk vector table for the specified device to the
+ * factory calibrated default values.
*
* @details The crosstalk vectors are subtracted from the raw sampling data
- * in the data evaluation phase.
- *
- * The crosstalk vector table is a three dimensional array of type
- * #xtalk_t.
- *
- * The dimensions are:
- * - size(0) = #ARGUS_DFM_FRAME_COUNT (Dual-frequency mode A- or B-frame)
- * - size(1) = #ARGUS_PIXELS_X (Pixel count in x-direction)
- * - size(2) = #ARGUS_PIXELS_Y (Pixel count in y-direction)
- * .
- *
- * The total vector table consists of the custom crosstalk vector
- * table (set via #Argus_SetCalibrationCrosstalkVectorTable) and
- * an internal, factory calibrated device specific vector table.
- * This is informational only!
- *
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @param value The current total crosstalk vector table.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
- *****************************************************************************/
-status_t Argus_GetCalibrationTotalCrosstalkVectorTable(argus_hnd_t *hnd,
- argus_mode_t mode,
- xtalk_t value[ARGUS_DFM_FRAME_COUNT][ARGUS_PIXELS_X][ARGUS_PIXELS_Y]);
-
-/*!***************************************************************************
- * @brief Resets the crosstalk vector table for the specified device to the
- * factory calibrated default values.
- *
- * @details The crosstalk vectors are subtracted from the raw sampling data
- * in the data evaluation phase.
+ * in the data evaluation phase.
* *
- * The factory defaults are device specific calibrated values.
+ * The factory defaults are device specific calibrated values.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param mode The targeted measurement mode.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_ResetCalibrationCrosstalkVectorTable(argus_hnd_t *hnd,
- argus_mode_t mode);
+status_t Argus_ResetCalibrationCrosstalkVectorTable(argus_hnd_t *hnd);
/*!***************************************************************************
- * @brief Sets the sample time for the crosstalk calibration sequence.
+ * @brief Sets the sample time for the crosstalk calibration sequence.
*
- * @details Sets the measurement sample acquisition time for executing the
- * crosstalk calibration sequence and generate the crosstalk data.\n
- * Units: msec.
+ * @details Sets the measurement sample acquisition time for executing the
+ * crosstalk calibration sequence and generate the crosstalk data.\n
+ * Units: msec.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The new crosstalk calibration sequence sample time.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new crosstalk calibration sequence sample time.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetCalibrationCrosstalkSequenceSampleTime(argus_hnd_t *hnd,
uint16_t value);
/*!***************************************************************************
- * @brief Gets the sample time for the crosstalk calibration sequence.
+ * @brief Gets the sample time for the crosstalk calibration sequence.
*
- * @details Gets the measurement sample acquisition time for executing the
- * crosstalk calibration sequence and generate the crosstalk data.\n
- * Units: msec.
+ * @details Gets the measurement sample acquisition time for executing the
+ * crosstalk calibration sequence and generate the crosstalk data.\n
+ * Units: msec.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The current crosstalk calibration sequence sample time.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current crosstalk calibration sequence sample time.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetCalibrationCrosstalkSequenceSampleTime(argus_hnd_t *hnd,
uint16_t *value);
/*!***************************************************************************
- * @brief Sets the max. amplitude threshold for the crosstalk calibration sequence.
+ * @brief Sets the max. amplitude threshold for the crosstalk calibration sequence.
*
- * @details The maximum amplitude threshold defines a maximum crosstalk vector
- * amplitude before causing an error message. If the crosstalk is
- * too high, there is usually an issue with the measurement setup, i.e.
- * there is still a measurement signal detected.
+ * @details The maximum amplitude threshold defines a maximum crosstalk vector
+ * amplitude before causing an error message. If the crosstalk is
+ * too high, there is usually an issue with the measurement setup, i.e.
+ * there is still a measurement signal detected.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The new crosstalk calibration sequence maximum amplitude
- * threshold value in UQ12.4 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The new crosstalk calibration sequence maximum amplitude
+ * threshold value in UQ12.4 format.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_SetCalibrationCrosstalkSequenceAmplitudeThreshold(argus_hnd_t *hnd,
uq12_4_t value);
/*!***************************************************************************
- * @brief Gets the max. amplitude threshold for the crosstalk calibration sequence.
+ * @brief Gets the max. amplitude threshold for the crosstalk calibration sequence.
*
- * @details The maximum amplitude threshold defines a maximum crosstalk vector
- * amplitude before causing an error message. If the crosstalk is
- * too high, there is usually an issue with the measurement setup, i.e.
- * there is still a measurement signal detected.
+ * @details The maximum amplitude threshold defines a maximum crosstalk vector
+ * amplitude before causing an error message. If the crosstalk is
+ * too high, there is usually an issue with the measurement setup, i.e.
+ * there is still a measurement signal detected.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The current max. amplitude threshold value in UQ12.4 format.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param hnd The API handle; contains all internal states and data.
+ * @param value The current max. amplitude threshold value in UQ12.4 format.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_GetCalibrationCrosstalkSequenceAmplitudeThreshold(argus_hnd_t *hnd,
uq12_4_t *value);
-/*!***************************************************************************
- * @brief Sets the sample count for the substrate voltage calibration sequence.
- *
- * @param hnd The API handle; contains all internal states and data.
- * @param value The new substrate voltage calibration sequence sample count.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
- *****************************************************************************/
-status_t Argus_SetCalibrationVsubSequenceSampleCount(argus_hnd_t *hnd,
- uint16_t value);
/*!***************************************************************************
- * @brief Gets the sample count for the substrate voltage calibration sequence.
+ * @brief Clears all user calibration values from NVM for the specified device.
*
- * @param hnd The API handle; contains all internal states and data.
- * @param value The current substrate voltage calibration sequence sample count.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @details The user calibration values are stored in the non-volatile memory
+ * (NVM) if corresponding \link #argus_nvm NVM hardware layer\endlink
+ * is implemented. This method clears the user calibration data from
+ * the non-volatile memory.
+ *
+ * @warning This does not reset the currently set calibration values to
+ * factory defaults!
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t Argus_GetCalibrationVsubSequenceSampleCount(argus_hnd_t *hnd,
- uint16_t *value);
+status_t Argus_ClearUserCalibration(argus_hnd_t *hnd);
+
/*!***************************************************************************
- * @brief A callback that returns the external crosstalk vector table.
+ * @brief A callback that returns the external crosstalk vector table.
*
* @details The function needs to be implemented by the host application in
- * order to set the external crosstalk vector table upon system
- * initialization. If not defined in user code, the default
- * implementation will return an all zero vector table, assuming there
- * is no (additional) external crosstalk.
+ * order to set the external crosstalk vector table upon system
+ * initialization. If not defined in user code, the default
+ * implementation will return an all zero vector table, assuming there
+ * is no (additional) external crosstalk.
*
- * If defined in user code, the function must fill all vector values
- * in the provided \par xtalk parameter with external crosstalk values.
- * The values can be obtained by the calibration routine.
+ * If defined in user code, the function must fill all vector values
+ * in the provided \par crosstalk parameter with external crosstalk
+ * values. The values can be obtained by the calibration routine.
*
- * Example usage:
+ * Example usage:
*
- * @code
- * status_t Argus_GetExternalCrosstalkVectorTable_Callback(xtalk_t xtalk[ARGUS_DFM_FRAME_COUNT][ARGUS_PIXELS_X][ARGUS_PIXELS_Y],
- * argus_mode_t mode)
- * {
- * (void) mode; // Ignore mode; use same values for all modes.
- * memset(&xtalk, 0, sizeof(xtalk));
+ * @code
+ * status_t Argus_GetCrosstalkVectorTable_Callback(
+ * argus_cal_xtalk_table_t * xtalk)
+ * {
+ * memset(xtalk, 0, sizeof(argus_cal_xtalk_table_t));
*
- * // Set crosstalk vectors in Q11.4 format.
- * // Note on dual-frequency frame index: 0 = A-Frame; 1 = B-Frame
- * xtalk[0][0][0].dS = -9; xtalk[0][0][0].dC = -11;
- * xtalk[0][0][1].dS = -13; xtalk[0][0][1].dC = -16;
- * xtalk[0][0][2].dS = 6; xtalk[0][0][2].dC = -18;
- * // etc.
- * }
- * @endcode
+ * // Set crosstalk vectors in Q11.4 format.
+ * // Note on dual-frequency frame index: 0 = A-Frame; 1 = B-Frame
+ * xtalk.FrameA[0][0].dS = -9; xtalk.FrameB[0][0].dC = -11;
+ * xtalk.FrameA[0][1].dS = -13; xtalk.FrameB[0][1].dC = -16;
+ * xtalk.FrameA[0][2].dS = 6; xtalk.FrameB[0][2].dC = -18;
+ * // etc.
+ * }
+ * @endcode
*
- * @param xtalk The crosstalk vector array; to be filled with data.
- * @param mode Determines the current measurement mode; can be ignored if
- * only a single measurement mode is utilized.
+ * @param xtalk The crosstalk vector array; to be filled with data.
+ * @param mode The current measurement mode.
*****************************************************************************/
-void Argus_GetExternalCrosstalkVectorTable_Callback(xtalk_t
- xtalk[ARGUS_DFM_FRAME_COUNT][ARGUS_PIXELS_X][ARGUS_PIXELS_Y],
- argus_mode_t mode);
+void Argus_GetCrosstalkVectorTable_Callback(argus_cal_xtalk_table_t *xtalk,
+ argus_mode_t const mode);
-#ifdef __cplusplus
-}
-#endif
+/*!***************************************************************************
+ * @brief Gets the currently calibrated Golden Pixel coordinates.
+ *
+ * @details The Golden Pixel is the pixel that is located at the center of the
+ * receiving light beam. Thus it it the one that receives the most
+ * signal and plays a central role in 1D measurement systems.
+ *
+ * The function fills the provided \p x and \p y parameters with
+ * the Golden Pixel coordinates. Typical values are x = 5 and y = 1
+ * or 2. But the actual values depend on the specific sensor.
+ *
+ * Please also note the utility functions provided in the \ref argus_map
+ * module to convert between pixel coordinates and channel numbers or
+ * shift pixel maps by a position offset (#ShiftSelectedPixels) or
+ * generate pixel masks centered around the Golden Pixel
+ * (#FillPixelMask).
+ *
+ * @param hnd The API handle; contains all internal states and data.
+ * @param x The Golden Pixel x-coordinate.
+ * @param y The Golden Pixel y-coordinate.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ *****************************************************************************/
+status_t Argus_GetCalibrationGoldenPixel(argus_hnd_t const *hnd, uint8_t *x, uint8_t *y);
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_API_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dca.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dca.h
index f23d117648..8f6b40bdc5 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dca.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dca.h
@@ -1,12 +1,12 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Defines the dynamic configuration adaption (DCA) setup parameters
- * and data structure.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Defines the dynamic configuration adaption (DCA) setup parameters
+ * and data structure.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,34 +37,37 @@
#ifndef ARGUS_DCA_H
#define ARGUS_DCA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup argusdca Dynamic Configuration Adaption
- * @ingroup argusapi
+ * @defgroup argus_dca Dynamic Configuration Adaption
+ * @ingroup argus_api
*
- * @brief Dynamic Configuration Adaption (DCA) parameter definitions and API functions.
+ * @brief Dynamic Configuration Adaption (DCA) parameter definitions and API functions.
*
- * @details The DCA contains an algorithms that detect ambient conditions
- * and adopt the device configuration to the changing parameters
- * dynamically while operating the sensor. This is achieved by
- * rating the currently received signal quality and changing the
- * device configuration accordingly to the gathered information
- * from the current measurement frame results before the next
- * integration cycle starts.
+ * @details The DCA contains an algorithms that detect ambient conditions
+ * and adopt the device configuration to the changing parameters
+ * dynamically while operating the sensor. This is achieved by
+ * rating the currently received signal quality and changing the
+ * device configuration accordingly to the gathered information
+ * from the current measurement frame results before the next
+ * integration cycle starts.
*
- * The DCA consists of the following features:
- * - Static or Dynamic mode. The first is utilizing the nominal
- * values while the latter is dynamically adopting between min.
- * and max. value and starting from the nominal values.
- * - Analog Integration Depth Adaption (from multiple patterns down to single pulses)
- * - Optical Output Power Adaption
- * - Pixel Input Gain Adaption (w/ ambient light rejection)
- * - ADC Sensitivity (i.e. ADC Range) Adaption
- * - Power Saving Ratio (to decrease the average output power and thus the current consumption)
- * - All that features are heeding the Laser Safety limits.
- * .
+ * The DCA consists of the following features:
+ * - Static or Dynamic mode. The first is utilizing the nominal
+ * values while the latter is dynamically adopting between min.
+ * and max. value and starting from the nominal values.
+ * - Analog Integration Depth Adaption (from multiple patterns down to single pulses)
+ * - Optical Output Power Adaption
+ * - Pixel Input Gain Adaption (w/ ambient light rejection)
+ * - ADC Sensitivity (i.e. ADC Range) Adaption
+ * - Power Saving Ratio (to decrease the average output power and thus the current consumption)
+ * - All that features are heeding the Laser Safety limits.
+ * .
*
- * @addtogroup argusdca
+ * @addtogroup argus_dca
* @{
*****************************************************************************/
@@ -73,39 +76,26 @@
/*! The minimum amplitude threshold value. */
-#define ARGUS_CFG_DCA_ATH_MIN (1U << 6U)
+#define ARGUS_CFG_DCA_ATH_MIN (1U << 6U)
/*! The maximum amplitude threshold value. */
-#define ARGUS_CFG_DCA_ATH_MAX (0xFFFFU)
+#define ARGUS_CFG_DCA_ATH_MAX (0xFFFFU)
/*! The minimum saturated pixel threshold value. */
-#define ARGUS_CFG_DCA_PXTH_MIN (1U)
+#define ARGUS_CFG_DCA_PXTH_MIN (1U)
/*! The maximum saturated pixel threshold value. */
-#define ARGUS_CFG_DCA_PXTH_MAX (33U)
+#define ARGUS_CFG_DCA_PXTH_MAX (33U)
/*! The maximum analog integration depth in UQ10.6 format,
* i.e. the maximum pattern count per sample. */
-#define ARGUS_CFG_DCA_DEPTH_MAX ((uq10_6_t)(ADS_SEQCT_N_MASK << (6U - ADS_SEQCT_N_SHIFT)))
+#define ARGUS_CFG_DCA_DEPTH_MAX ((uq10_6_t)(0xFFC0U))
/*! The minimum analog integration depth in UQ10.6 format,
* i.e. the minimum pattern count per sample. */
-#define ARGUS_CFG_DCA_DEPTH_MIN ((uq10_6_t)(1U)) // 1/64, i.e. 1/2 nibble
-
-
-/*! The maximum optical output power, i.e. the maximum VCSEL high current in LSB. */
-#define ARGUS_CFG_DCA_POWER_MAX_LSB (ADS_LASET_VCSEL_HC1_MASK >> ADS_LASET_VCSEL_HC1_SHIFT)
-
-/*! The minimum optical output power, i.e. the minimum VCSEL high current in mA. */
-#define ARGUS_CFG_DCA_POWER_MIN_LSB (1)
-
-/*! The maximum optical output power, i.e. the maximum VCSEL high current in LSB. */
-#define ARGUS_CFG_DCA_POWER_MAX (ADS0032_HIGH_CURRENT_LSB2MA(ARGUS_CFG_DCA_POWER_MAX_LSB + 1))
-
-/*! The minimum optical output power, i.e. the minimum VCSEL high current in mA. */
-#define ARGUS_CFG_DCA_POWER_MIN (1)
+#define ARGUS_CFG_DCA_DEPTH_MIN ((uq10_6_t)(1U)) // 1/64, i.e. 1/2 nibble
/*! The dynamic configuration algorithm Pixel Input Gain stage count. */
@@ -139,9 +129,9 @@
/*!***************************************************************************
- * @brief The dynamic configuration algorithm enable flags.
+ * @brief The dynamic configuration algorithm enable flags.
*****************************************************************************/
-typedef enum {
+typedef enum argus_dca_enable_t {
/*! @internal
*
* DCA is disabled and will be completely skipped.
@@ -160,9 +150,9 @@ typedef enum {
} argus_dca_enable_t;
/*!***************************************************************************
- * @brief The DCA amplitude evaluation method.
+ * @brief The DCA amplitude evaluation method.
*****************************************************************************/
-typedef enum {
+typedef enum argus_dca_amplitude_mode_t {
/*! Evaluate the DCA amplitude as the maximum of all valid amplitudes. */
DCA_AMPLITUDE_MAX = 1U,
@@ -172,9 +162,9 @@ typedef enum {
} argus_dca_amplitude_mode_t;
/*!***************************************************************************
- * @brief The dynamic configuration algorithm Optical Output Power stages enumerator.
+ * @brief The dynamic configuration algorithm Optical Output Power stages enumerator.
*****************************************************************************/
-typedef enum {
+typedef enum argus_dca_power_t {
/*! Use low output power stage. */
DCA_POWER_LOW = 0,
@@ -187,9 +177,9 @@ typedef enum {
} argus_dca_power_t;
/*!***************************************************************************
- * @brief The dynamic configuration algorithm Pixel Input Gain stages enumerator.
+ * @brief The dynamic configuration algorithm Pixel Input Gain stages enumerator.
*****************************************************************************/
-typedef enum {
+typedef enum argus_dca_gain_t {
/*! Low gain stage. */
DCA_GAIN_LOW = 0,
@@ -206,113 +196,113 @@ typedef enum {
/*!***************************************************************************
- * @brief State flags for the current frame.
- * @details State flags determine the current state of the measurement frame:
- * - [0]: #ARGUS_STATE_MEASUREMENT_MODE
- * - [1]: #ARGUS_STATE_DUAL_FREQ_MODE
- * - [2]: #ARGUS_STATE_MEASUREMENT_FREQ
- * - [3]: #ARGUS_STATE_DEBUG_MODE
- * - [4]: #ARGUS_STATE_WEAK_SIGNAL
- * - [5]: #ARGUS_STATE_BGL_WARNING
- * - [6]: #ARGUS_STATE_BGL_ERROR
- * - [7]: #ARGUS_STATE_PLL_LOCKED
- * - [8]: #ARGUS_STATE_LASER_WARNING
- * - [9]: #ARGUS_STATE_LASER_ERROR
- * - [10]: #ARGUS_STATE_HAS_DATA
- * - [11]: #ARGUS_STATE_HAS_AUX_DATA
- * - [12]: #ARGUS_STATE_DCA_MAX
- * - [13]: DCA Power Stage
- * - [14-15]: DCA Gain Stages
- * .
+ * @brief State flags for the current frame.
+ * @details State flags determine the current state of the measurement frame:
+ * - [0]: #ARGUS_STATE_XTALK_MONITOR_ACTIVE
+ * - [1]: #ARGUS_STATE_DUAL_FREQ_MODE
+ * - [2]: #ARGUS_STATE_MEASUREMENT_FREQ
+ * - [3]: #ARGUS_STATE_DEBUG_MODE
+ * - [4]: #ARGUS_STATE_WEAK_SIGNAL
+ * - [5]: #ARGUS_STATE_BGL_WARNING
+ * - [6]: #ARGUS_STATE_BGL_ERROR
+ * - [7]: #ARGUS_STATE_PLL_LOCKED
+ * - [8]: #ARGUS_STATE_LASER_WARNING
+ * - [9]: #ARGUS_STATE_LASER_ERROR
+ * - [10]: #ARGUS_STATE_HAS_DATA
+ * - [11]: #ARGUS_STATE_HAS_AUX_DATA
+ * - [12]: #ARGUS_STATE_DCA_MAX
+ * - [13]: DCA Power Stage
+ * - [14-15]: DCA Gain Stages
+ * .
*****************************************************************************/
-typedef enum {
+typedef enum argus_state_t {
/*! No state flag set. */
ARGUS_STATE_NONE = 0,
- /*! 0x0001: Measurement Mode.
- * - 0: Mode A: Long Range / Medium Precision
- * - 1: Mode B: Short Range / High Precision */
- ARGUS_STATE_MEASUREMENT_MODE = 1U << 0U,
+ /*! 0x0001: Crosstalk Monitor is enabled and updating.
+ * - 0: Inactive: crosstalk monitor values are not updated,
+ * - 1: Active: crosstalk monitor values are updated. */
+ ARGUS_STATE_XTALK_MONITOR_ACTIVE = 1U << 0U,
/*! 0x0002: Dual Frequency Mode Enabled.
- * - 0: Disabled: measurements with base frequency,
- * - 1: Enabled: measurement with detuned frequency. */
+ * - 0: Disabled: measurements with base frequency,
+ * - 1: Enabled: measurement with detuned frequency. */
ARGUS_STATE_DUAL_FREQ_MODE = 1U << 1U,
/*! 0x0004: Measurement Frequency for Dual Frequency Mode
* (only if #ARGUS_STATE_DUAL_FREQ_MODE flag is set).
- * - 0: A-Frame w/ detuned frequency,
- * - 1: B-Frame w/ detuned frequency */
+ * - 0: A-Frame w/ detuned frequency,
+ * - 1: B-Frame w/ detuned frequency */
ARGUS_STATE_MEASUREMENT_FREQ = 1U << 2U,
/*! 0x0008: Debug Mode. If set, the range value of erroneous pixels
- * are not cleared or reset.
- * - 0: Disabled (default).
- * - 1: Enabled. */
+ * are not cleared or reset.
+ * - 0: Disabled (default).
+ * - 1: Enabled. */
ARGUS_STATE_DEBUG_MODE = 1U << 3U,
/*! 0x0010: Weak Signal Flag.
- * Set whenever the Pixel Binning Algorithm is detecting a
- * weak signal, i.e. if the amplitude dies not reach its
- * (absolute) threshold. If the Golden Pixel is enabled,
- * this also indicates that the Pixel Binning Algorithm
- * falls back to the Golden Pixel.
- * - 0: Normal Signal.
- * - 1: Weak Signal or Golden Pixel Mode. */
+ * Set whenever the Pixel Binning Algorithm is detecting a
+ * weak signal, i.e. if the amplitude dies not reach its
+ * (absolute) threshold. If the Golden Pixel is enabled,
+ * this also indicates that the Pixel Binning Algorithm
+ * falls back to the Golden Pixel.
+ * - 0: Normal Signal.
+ * - 1: Weak Signal or Golden Pixel Mode. */
ARGUS_STATE_WEAK_SIGNAL = 1U << 4U,
/*! 0x0020: Background Light Warning Flag.
- * Set whenever the background light is very high and the
- * measurement data might be unreliable.
- * - 0: No Warning: Background Light is within valid range.
- * - 1: Warning: Background Light is very high. */
+ * Set whenever the background light is very high and the
+ * measurement data might be unreliable.
+ * - 0: No Warning: Background Light is within valid range.
+ * - 1: Warning: Background Light is very high. */
ARGUS_STATE_BGL_WARNING = 1U << 5U,
/*! 0x0040: Background Light Error Flag.
- * Set whenever the background light is too high and the
- * measurement data is unreliable or invalid.
- * - 0: No Error: Background Light is within valid range.
- * - 1: Error: Background Light is too high. */
+ * Set whenever the background light is too high and the
+ * measurement data is unreliable or invalid.
+ * - 0: No Error: Background Light is within valid range.
+ * - 1: Error: Background Light is too high. */
ARGUS_STATE_BGL_ERROR = 1U << 6U,
/*! 0x0080: PLL_LOCKED bit.
- * - 0: PLL not locked at start of integration.
- * - 1: PLL locked at start of integration. */
+ * - 0: PLL not locked at start of integration.
+ * - 1: PLL locked at start of integration. */
ARGUS_STATE_PLL_LOCKED = 1U << 7U,
/*! 0x0100: Laser Failure Warning Flag.
- * Set whenever the an invalid system condition is detected.
- * (i.e. DCA at max state but no amplitude on any (incl. reference)
- * pixel, not amplitude but any saturated pixel).
- * - 0: No Warning: Laser is operating properly.
- * - 1: Warning: Invalid laser conditions detected. If the invalid
- * condition stays, a laser malfunction error is raised. */
+ * Set whenever the an invalid system condition is detected.
+ * (i.e. DCA at max state but no amplitude on any (incl. reference)
+ * pixel, not amplitude but any saturated pixel).
+ * - 0: No Warning: Laser is operating properly.
+ * - 1: Warning: Invalid laser conditions detected. If the invalid
+ * condition stays, a laser malfunction error is raised. */
ARGUS_STATE_LASER_WARNING = 1U << 8U,
/*! 0x0200: Laser Failure Error Flag.
- * Set whenever a laser malfunction error is raised and the
- * system is put into a safe state.
- * - 0: No Error: Laser is operating properly.
- * - 1: Error: Invalid laser conditions are detected for a certain
- * soak time and the system is put into a safe state. */
+ * Set whenever a laser malfunction error is raised and the
+ * system is put into a safe state.
+ * - 0: No Error: Laser is operating properly.
+ * - 1: Error: Invalid laser conditions are detected for a certain
+ * soak time and the system is put into a safe state. */
ARGUS_STATE_LASER_ERROR = 1U << 9U,
/*! 0x0400: Set if current frame has distance measurement data available.
- * - 0: No measurement data available, all values are 0 or stalled.
- * - 1: Measurement data is available and correctly evaluated. */
+ * - 0: No measurement data available, all values are 0 or stalled.
+ * - 1: Measurement data is available and correctly evaluated. */
ARGUS_STATE_HAS_DATA = 1U << 10U,
/*! 0x0800: Set if current frame has auxiliary measurement data available.
- * - 0: No auxiliary data available, all values are 0 or stalled.
- * - 1: Auxiliary data is available and correctly evaluated. */
+ * - 0: No auxiliary data available, all values are 0 or stalled.
+ * - 1: Auxiliary data is available and correctly evaluated. */
ARGUS_STATE_HAS_AUX_DATA = 1U << 11U,
/*! 0x1000: DCA Maximum State Flag.
- * Set whenever the DCA has extended all its parameters to their
- * maximum values and can not increase the integration energy any
- * further.
- * - 0: DCA has not yet reached its maximum state.
- * - 1: DCA has reached its maximum state and can not increase any further. */
+ * Set whenever the DCA has extended all its parameters to their
+ * maximum values and can not increase the integration energy any
+ * further.
+ * - 0: DCA has not yet reached its maximum state.
+ * - 1: DCA has reached its maximum state and can not increase any further. */
ARGUS_STATE_DCA_MAX = 1U << 12U,
/*! 0x2000: DCA is in high Optical Output Power stage. */
@@ -333,20 +323,20 @@ typedef enum {
} argus_state_t;
/*!***************************************************************************
- * @brief Dynamic Configuration Adaption (DCA) Parameters.
- * @details DCA contains:
- * - Static or dynamic mode. The first is utilizing the nominal values
- * while the latter is dynamically adopting between min. and max.
- * value and starting form the nominal values.
- * - Analog Integration Depth Adaption down to single pulses.
- * - Optical Output Power Adaption
- * - Pixel Input Gain Adaption
- * - Digital Integration Depth Adaption
- * - Dynamic Global Phase Shift Injection.
- * - All that features are heeding the Laser Safety limits.
- * .
+ * @brief Dynamic Configuration Adaption (DCA) Parameters.
+ * @details DCA contains:
+ * - Static or dynamic mode. The first is utilizing the nominal values
+ * while the latter is dynamically adopting between min. and max.
+ * value and starting form the nominal values.
+ * - Analog Integration Depth Adaption down to single pulses.
+ * - Optical Output Power Adaption
+ * - Pixel Input Gain Adaption
+ * - Digital Integration Depth Adaption
+ * - Dynamic Global Phase Shift Injection.
+ * - All that features are heeding the Laser Safety limits.
+ * .
*****************************************************************************/
-typedef struct {
+typedef struct argus_cfg_dca_t {
/*! Enables the automatic configuration adaption features.
* Enables the dynamic part if #DCA_ENABLE_DYNAMIC and the static only if
* #DCA_ENABLE_STATIC. */
@@ -494,4 +484,7 @@ typedef struct {
} argus_cfg_dca_t;
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_DCA_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_def.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_def.h
index c639922a7d..6d9dd3e9d3 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_def.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_def.h
@@ -1,12 +1,12 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 hardware API.
- * @details This file provides generic definitions belonging to all
- * devices from the AFBR-S50 product family.
+ * @brief This file is part of the AFBR-S50 hardware API.
+ * @details This file provides generic definitions belonging to all
+ * devices from the AFBR-S50 product family.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,9 @@
#ifndef ARGUS_DEF_H
#define ARGUS_DEF_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
* Include files
@@ -52,36 +55,41 @@
#include
/*!***************************************************************************
- * @addtogroup argusapi
+ * @addtogroup argus_api
* @{
*****************************************************************************/
/*!***************************************************************************
- * @brief Maximum number of phases per measurement cycle.
- * @details The actual phase number is defined in the register configuration.
- * However the software does only support a fixed value of 4 yet.
+ * @brief Maximum number of phases per measurement cycle.
+ * @details The actual phase number is defined in the register configuration.
+ * However the software does only support a fixed value of 4 yet.
*****************************************************************************/
-#define ARGUS_PHASECOUNT 4U
+#define ARGUS_PHASECOUNT 4
/*!***************************************************************************
- * @brief The device pixel field size in x direction (long edge).
+ * @brief The device pixel field size in x direction (long edge).
*****************************************************************************/
-#define ARGUS_PIXELS_X 8U
+#define ARGUS_PIXELS_X 8
/*!***************************************************************************
- * @brief The device pixel field size in y direction (short edge).
+ * @brief The device pixel field size in y direction (short edge).
*****************************************************************************/
-#define ARGUS_PIXELS_Y 4U
+#define ARGUS_PIXELS_Y 4
/*!***************************************************************************
- * @brief The total device pixel count.
+ * @brief The total device pixel count.
*****************************************************************************/
-#define ARGUS_PIXELS ((ARGUS_PIXELS_X)*(ARGUS_PIXELS_Y))
+#define ARGUS_PIXELS ((ARGUS_PIXELS_X)*(ARGUS_PIXELS_Y))
/*!***************************************************************************
- * @brief The AFBR-S50 module types.
+ * @brief A flag indicating that the device is a extended range device.
*****************************************************************************/
-typedef enum {
+#define MODULE_EXTENDED_FLAG (0x40U)
+
+/*!***************************************************************************
+ * @brief The AFBR-S50 module types.
+ *****************************************************************************/
+typedef enum argus_module_version_t {
/*! No device connected or not recognized. */
MODULE_NONE = 0,
@@ -89,54 +97,80 @@ typedef enum {
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* medium range 3D applications.
* Version 1 - legacy version! */
- AFBR_S50MV85G_V1 = 1,
+ AFBR_S50MV85G_V1 = 0x01,
/*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* medium range 3D applications.
* Version 2 - legacy version! */
- AFBR_S50MV85G_V2 = 2,
-
- /*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
- * w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
- * medium range 3D applications.
- * Version 7 - current version! */
- AFBR_S50MV85G_V3 = 7,
+ AFBR_S50MV85G_V2 = 0x02,
/*! AFBR-S50LV85D: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* long range 1D applications.
* Version 1 - current version! */
- AFBR_S50LV85D_V1 = 3,
+ AFBR_S50LV85D_V1 = 0x03,
/*! AFBR-S50MV68B: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and red, 680 nm, laser source for
* medium range 1D applications.
* Version 1 - current version! */
- AFBR_S50MV68B_V1 = 4,
+ AFBR_S50MV68B_V1 = 0x04,
/*! AFBR-S50MV85I: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* medium range 3D applications.
* Version 1 - current version! */
- AFBR_S50MV85I_V1 = 5,
+ AFBR_S50MV85I_V1 = 0x05,
/*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
* w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
* short range 3D applications.
* Version 1 - current version! */
- AFBR_S50SV85K_V1 = 6,
+ AFBR_S50SV85K_V1 = 0x06,
+ /*! AFBR-S50MV85G: an ADS0032 based multi-pixel range finder device
+ * w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
+ * medium range 3D applications.
+ * Version 3 - current version! */
+ AFBR_S50MV85G_V3 = 0x07,
- /*! Reserved for future extensions. */
- Reserved = 0x3F
+ /*! AFBR-S50LX85D: an ADS0032 based multi-pixel range finder device
+ * w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
+ * extended long range 1D applications.
+ * Version 1 - current version! */
+ AFBR_S50LX85D_V1 = AFBR_S50LV85D_V1 | MODULE_EXTENDED_FLAG,
+
+ /*! AFBR-S50MX68B: an ADS0032 based multi-pixel range finder device
+ * w/ 4x8 pixel matrix and red, 680 nm, laser source for
+ * extended medium range 1D applications.
+ * Version 1 - current version! */
+ AFBR_S50MX68B_V1 = AFBR_S50MV68B_V1 | MODULE_EXTENDED_FLAG,
+
+ /*! AFBR-S50MX85I: an ADS0032 based multi-pixel range finder device
+ * w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
+ * extended medium range 3D applications.
+ * Version 1 - current version! */
+ AFBR_S50MX85I_V1 = AFBR_S50MV85I_V1 | MODULE_EXTENDED_FLAG,
+
+ /*! AFBR-S50MX85G: an ADS0032 based multi-pixel range finder device
+ * w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
+ * extended short range 3D applications.
+ * Version 1 - current version! */
+ AFBR_S50SX85K_V1 = AFBR_S50SV85K_V1 | MODULE_EXTENDED_FLAG,
+
+ /*! AFBR-S50MX85G: an ADS0032 based multi-pixel range finder device
+ * w/ 4x8 pixel matrix and infra-red, 850 nm, laser source for
+ * extended medium range 3D applications.
+ * Version 1 - current version! */
+ AFBR_S50MX85G_V1 = AFBR_S50MV85G_V3 | MODULE_EXTENDED_FLAG,
} argus_module_version_t;
/*!***************************************************************************
- * @brief The AFBR-S50 laser configurations.
+ * @brief The AFBR-S50 laser configurations.
*****************************************************************************/
-typedef enum {
+typedef enum argus_laser_type_t {
/*! No laser connected. */
LASER_NONE = 0,
@@ -152,12 +186,15 @@ typedef enum {
/*! 850nm Infra-Red VCSEL v2 /w extended mode. */
LASER_H_V2X = 4,
+ /*! 680nm Red VCSEL v1 w/ extended mode. */
+ LASER_R_V1X = 5,
+
} argus_laser_type_t;
/*!***************************************************************************
- * @brief The AFBR-S50 chip versions.
+ * @brief The AFBR-S50 chip versions.
*****************************************************************************/
-typedef enum {
+typedef enum argus_chip_version_t {
/*! No device connected or not recognized. */
ADS0032_NONE = 0,
@@ -178,37 +215,102 @@ typedef enum {
} argus_chip_version_t;
-/*!***************************************************************************
- * @brief The number of measurement modes with distinct configuration and
- * calibration records.
- *****************************************************************************/
-#define ARGUS_MODE_COUNT (2)
/*!***************************************************************************
- * @brief The measurement modes.
+ * @brief The measurement mode flags.
+ * @details The measurement mode flags that can be combined to a measurement
+ * mode, e.g. high speed short range mode. See #argus_mode_t for
+ * a complete list of available measurement modes.
+ *
+ * - Bit 0: Short Range Mode
+ * - Bit 1: Long Range Mode
+ * - Bit 2: High Speed Mode
+ *
+ * Note that the Long and Short Range Flags are mutual exclusive but
+ * any of those 2 must be set. Thus the value 0 is invalid!
+ * All other flags enhance the base configurations, e.g. the High
+ * Speed flag create the high speed mode of the selected base
+ * measurement mode.
*****************************************************************************/
-typedef enum {
- /*! Measurement Mode A: Long Range Mode. */
- ARGUS_MODE_A = 1,
+typedef enum argus_mode_flags_t {
+ /*! Measurement Mode Flag for Short Range Base Mode. */
+ ARGUS_MODE_FLAG_SHORT_RANGE = 0x01 << 0,
- /*! Measurement Mode B: Short Range Mode. */
- ARGUS_MODE_B = 2,
+ /*! Measurement Mode Flag for Long Range Base Mode. */
+ ARGUS_MODE_FLAG_LONG_RANGE = 0x01 << 1,
+
+ /*! Measurement Mode Flag for High Speed Mode. */
+ ARGUS_MODE_FLAG_HIGH_SPEED = 0x01 << 2
+
+} argus_mode_flags_t;
+
+/*!***************************************************************************
+ * @brief The measurement modes.
+ * @details The measurement modes are composed in binary from of the flags
+ * define in #argus_mode_flags_t, i.e. each bit has a special meaning:
+ *
+ * - Bit 0: Short Range Mode
+ * - Bit 1: Long Range Mode
+ * - Bit 2: High Speed Mode
+ *
+ * Note that the Long and Short Range Bits are mutual exclusive but any
+ * of those 2 must be set. Thus the value 0 is invalid!
+ *****************************************************************************/
+typedef enum argus_mode_t {
+ /*! Measurement Mode: Short Range Mode. */
+ ARGUS_MODE_SHORT_RANGE = // = 0x01 = 0b0001
+ ARGUS_MODE_FLAG_SHORT_RANGE,
+
+ /*! Measurement Mode: Long Range Mode. */
+ ARGUS_MODE_LONG_RANGE = // = 0x02 = 0b0010
+ ARGUS_MODE_FLAG_LONG_RANGE,
+
+ /*! Measurement Mode: High Speed Short Range Mode. */
+ ARGUS_MODE_HIGH_SPEED_SHORT_RANGE = // = 0x05 = 0b0101
+ ARGUS_MODE_FLAG_SHORT_RANGE | ARGUS_MODE_FLAG_HIGH_SPEED,
+
+ /*! Measurement Mode: High Speed Long Range Mode. */
+ ARGUS_MODE_HIGH_SPEED_LONG_RANGE = // = 0x06 = 0b0110
+ ARGUS_MODE_FLAG_LONG_RANGE | ARGUS_MODE_FLAG_HIGH_SPEED,
} argus_mode_t;
+/*! The data structure for the API representing a AFBR-S50 device instance. */
+typedef struct argus_hnd_t argus_hnd_t;
+
/*!***************************************************************************
- * @brief Generic API callback function.
- * @details Invoked by the API. The content of the abstract data pointer
- * depends upon the context.
- * @param status The module status that caused the callback. #STATUS_OK if
- * everything was as expected.
- * @param data An abstract pointer to an user defined data. This will usually
- * be passed to the function that also takes the callback as an
- * parameter. Otherwise it has a special meaning such as
- * configuration or calibration data.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @brief Measurement Ready API callback function.
+ *
+ * @details Invoked by the API whenever a measurement cycle is finished and
+ * new data is ready to be evaluated via the #Argus_EvaluateData API
+ * function.
+ * The callback is passed to the API via the #Argus_TriggerMeasurement
+ * or #Argus_StartMeasurementTimer API functions.
+ * The API passes the status of the currently finished measurement
+ * cycle to the callback as first parameters. The second parameter is
+ * a pointer the API handle structure. The latter is used to identify
+ * the calling instance of the API in case of multiple devices.
+ * Further it can be passed to the #Argus_EvaluateData function.
+ *
+ * @warning Since the callback is called from an interrupt context, the
+ * callback execution must return as fast as possible. The usual task
+ * in the callback is to post an event to the main thread to inform it
+ * about the new data and that is must call the #Argus_EvaluateData
+ * function.
+ *
+ * @param status The module status that caused the callback. #STATUS_OK if
+ * everything was as expected.
+ *
+ * @param hnd The API handle pointer to the calling instance. Identifies the
+ * instance of the API that was invoking the callback and thus the
+ * instance that must call the #Argus_EvaluateData for.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-typedef status_t (*argus_callback_t)(status_t status, void *data);
+typedef status_t (*argus_measurement_ready_callback_t)(status_t status, argus_hnd_t *hnd);
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_DEF_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dfm.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dfm.h
index b2517182f8..4c0182a0b3 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dfm.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_dfm.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Defines the dual frequency mode (DFM) setup parameters.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Defines the dual frequency mode (DFM) setup parameters.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,24 +36,27 @@
#ifndef ARGUS_DFM_H
#define ARGUS_DFM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup argusdfm Dual Frequency Mode
- * @ingroup argusapi
+ * @defgroup argus_dfm Dual Frequency Mode
+ * @ingroup argus_api
*
- * @brief Dual Frequency Mode (DFM) parameter definitions and API functions.
+ * @brief Dual Frequency Mode (DFM) parameter definitions and API functions.
*
- * @details The DFM is an algorithm to extend the unambiguous range of the
- * sensor by utilizing two detuned measurement frequencies.
+ * @details The DFM is an algorithm to extend the unambiguous range of the
+ * sensor by utilizing two detuned measurement frequencies.
*
- * The AFBR-S50 API provides three measurement modes:
- * - 1X: Single Frequency Measurement
- * - 4X: Dual Frequency Measurement w/ 4 times the unambiguous
- * range of the Single Frequency Measurement
- * - 8X: Dual Frequency Measurement w/ 8 times the unambiguous
- * range of the Single Frequency Measurement
+ * The AFBR-S50 API provides three measurement modes:
+ * - 1X: Single Frequency Measurement
+ * - 4X: Dual Frequency Measurement w/ 4 times the unambiguous
+ * range of the Single Frequency Measurement
+ * - 8X: Dual Frequency Measurement w/ 8 times the unambiguous
+ * range of the Single Frequency Measurement
*
- * @addtogroup argusdfm
+ * @addtogroup argus_dfm
* @{
*****************************************************************************/
@@ -61,10 +64,10 @@
#define ARGUS_DFM_FRAME_COUNT (2U)
/*! The Dual Frequency Mode measurement modes count. Excluding the disabled mode. */
-#define ARGUS_DFM_MODE_COUNT (2U) // expect off-mode!
+#define ARGUS_DFM_MODE_COUNT (2U) // except off-mode!
/*! The Dual Frequency Mode measurement modes enumeration. */
-typedef enum {
+typedef enum argus_dfm_mode_t {
/*! Single Frequency Measurement Mode (w/ 1x Unambiguous Range). */
DFM_MODE_OFF = 0U,
@@ -78,4 +81,7 @@ typedef enum {
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_DFM_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_map.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_map.h
index 64588d25f1..4ffa55656b 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_map.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_map.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Defines macros to work with pixel and ADC channel masks.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Defines macros to work with pixel and ADC channel masks.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,217 +37,409 @@
#ifndef ARGUS_MAP_H
#define ARGUS_MAP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup argusmap ADC Channel Mapping
- * @ingroup argusres
+ * @defgroup argus_map Pixel Channel Mapping
+ * @ingroup argus_api
*
- * @brief Pixel ADC Channel Mapping
+ * @brief Pixel Channel Mapping
*
- * @details The ADC Channels of each pixel or auxiliary channel on the device
- * are numbered in a way that is convenient on the chip architecture.
- * The macros in this module are defined in order to map between the
- * chip internal channel number (ch) to the two-dimensional
- * x-y-indices or one-dimensional n-index representation.
+ * @details The ADC Channels of each pixel or auxiliary channel on the device
+ * are numbered in a way that is convenient on the chip architecture.
+ * The macros in this module are defined in order to map between the
+ * chip internal channel number (ch) to the two-dimensional
+ * x-y-indices or one-dimensional n-index representation.
*
- * @addtogroup argusmap
+ * @addtogroup argus_map
* @{
*****************************************************************************/
-#include "api/argus_def.h"
#include "utility/int_math.h"
+#include
+/*!***************************************************************************
+ * @brief The device pixel field size in x direction (long edge).
+ *****************************************************************************/
+#define ARGUS_PIXELS_X 8
+
+/*!***************************************************************************
+ * @brief The device pixel field size in y direction (short edge).
+ *****************************************************************************/
+#define ARGUS_PIXELS_Y 4
+
+/*!***************************************************************************
+ * @brief The total device pixel count.
+ *****************************************************************************/
+#define ARGUS_PIXELS ((ARGUS_PIXELS_X)*(ARGUS_PIXELS_Y))
/*!*****************************************************************************
- * @brief Macro to determine the pixel ADC channel number from the x-z-indices.
- * @param x The x-index of the pixel.
- * @param y The y-index of the pixel.
- * @return The ADC channel number of the pixel.
+ * @brief Macro to determine the pixel ADC channel number from the x-z-indices.
+ * @param x The x-index of the pixel.
+ * @param y The y-index of the pixel.
+ * @return The ADC channel number of the pixel.
******************************************************************************/
#define PIXEL_XY2CH(x, y) ((((y) << 3U) & 0x10U) | (((x) ^ 0x07U) << 1U) | ((y) & 0x01U))
/*!*****************************************************************************
- * @brief Macro to determine the pixel x-index from the ADC channel number.
- * @param c The ADC channel number of the pixel.
- * @return The x-index of the pixel.
+ * @brief Macro to determine the pixel x-index from the ADC channel number.
+ * @param c The ADC channel number of the pixel.
+ * @return The x-index of the pixel.
******************************************************************************/
#define PIXEL_CH2X(c) ((((c) >> 1U) ^ 0x07U) & 0x07U)
/*!*****************************************************************************
- * @brief Macro to determine the pixel y-index from the ADC channel number.
- * @param c The ADC channel number of the pixel.
- * @return The y-index of the pixel.
+ * @brief Macro to determine the pixel y-index from the ADC channel number.
+ * @param c The ADC channel number of the pixel.
+ * @return The y-index of the pixel.
******************************************************************************/
#define PIXEL_CH2Y(c) ((((c) >> 3U) & 0x02U) | ((c) & 0x01U))
/*!*****************************************************************************
- * @brief Macro to determine the n-index from the x-y-indices.
- * @param x The x-index of the pixel.
- * @param y The y-index of the pixel.
- * @return The n-index of the pixel.
+ * @brief Macro to determine the n-index from the x-y-indices.
+ * @param x The x-index of the pixel.
+ * @param y The y-index of the pixel.
+ * @return The n-index of the pixel.
******************************************************************************/
#define PIXEL_XY2N(x, y) (((x) << 2U) | (y))
/*!*****************************************************************************
- * @brief Macro to determine the pixel x-index from the n-index.
- * @param n The n-index of the pixel.
- * @return The x-index number of the pixel.
+ * @brief Macro to determine the pixel x-index from the n-index.
+ * @param n The n-index of the pixel.
+ * @return The x-index number of the pixel.
******************************************************************************/
#define PIXEL_N2X(n) ((n) >> 2U)
/*!*****************************************************************************
- * @brief Macro to determine the pixel y-index from the n-index.
- * @param n The n-index of the pixel.
- * @return The y-index number of the pixel.
+ * @brief Macro to determine the pixel y-index from the n-index.
+ * @param n The n-index of the pixel.
+ * @return The y-index number of the pixel.
******************************************************************************/
#define PIXEL_N2Y(n) ((n) & 0x03U)
/*!*****************************************************************************
- * @brief Macro to determine the pixel n-index from the ADC channel number.
- * @param n The n-index of the pixel.
- * @return The ADC channel number of the pixel.
+ * @brief Macro to determine the pixel n-index from the ADC channel number.
+ * @param n The n-index of the pixel.
+ * @return The ADC channel number of the pixel.
******************************************************************************/
#define PIXEL_N2CH(n) ((((n) << 3U) & 0x10U) | ((((n) >> 1U) ^ 0x0EU) & 0x0EU) | ((n) & 0x01U))
/*!*****************************************************************************
- * @brief Macro to determine the pixel
- * @param c The ADC channel number of the pixel.
- * @return The n-index of the pixel.
+ * @brief Macro to determine the pixel
+ * @param c The ADC channel number of the pixel.
+ * @return The n-index of the pixel.
******************************************************************************/
#define PIXEL_CH2N(c) (((((c) << 1U) ^ 0x1CU) & 0x1CU) | (((c) >> 3U) & 0x02U) | ((c) & 0x01U))
/*!*****************************************************************************
- * @brief Macro to determine if a pixel given by the n-index is enabled in a pixel mask.
- * @param msk 32-bit pixel mask
- * @param n n-index of the pixel.
- * @return True if the pixel (n) is enabled.
+ * @brief Macro to determine if a pixel given by the n-index is enabled in a pixel mask.
+ * @param msk 32-bit pixel mask
+ * @param n n-index of the pixel.
+ * @return True if the pixel (n) is enabled.
******************************************************************************/
#define PIXELN_ISENABLED(msk, n) (((msk) >> (n)) & 0x01U)
/*!*****************************************************************************
- * @brief Macro to enable a pixel given by the n-index in a pixel mask.
- * @param msk 32-bit pixel mask
- * @param n n-index of the pixel to enable.
+ * @brief Macro to enable a pixel given by the n-index in a pixel mask.
+ * @param msk 32-bit pixel mask
+ * @param n n-index of the pixel to enable.
******************************************************************************/
#define PIXELN_ENABLE(msk, n) ((msk) |= (0x01U << (n)))
/*!*****************************************************************************
- * @brief Macro disable a pixel given by the n-index in a pixel mask.
- * @param msk 32-bit pixel mask
- * @param n n-index of the pixel to disable.
+ * @brief Macro disable a pixel given by the n-index in a pixel mask.
+ * @param msk 32-bit pixel mask
+ * @param n n-index of the pixel to disable.
******************************************************************************/
#define PIXELN_DISABLE(msk, n) ((msk) &= (~(0x01U << (n))))
/*!*****************************************************************************
- * @brief Macro to determine if an ADC pixel channel is enabled from a pixel mask.
- * @param msk The 32-bit pixel mask
- * @param c The ADC channel number of the pixel.
- * @return True if the specified pixel ADC channel is enabled.
+ * @brief Macro to determine if an ADC pixel channel is enabled from a pixel mask.
+ * @param msk The 32-bit pixel mask
+ * @param c The ADC channel number of the pixel.
+ * @return True if the specified pixel ADC channel is enabled.
******************************************************************************/
#define PIXELCH_ISENABLED(msk, c) (PIXELN_ISENABLED(msk, PIXEL_CH2N(c)))
/*!*****************************************************************************
- * @brief Macro to enable an ADC pixel channel in a pixel mask.
- * @param msk The 32-bit pixel mask
- * @param c The pixel ADC channel number to enable.
+ * @brief Macro to enable an ADC pixel channel in a pixel mask.
+ * @param msk The 32-bit pixel mask
+ * @param c The pixel ADC channel number to enable.
******************************************************************************/
#define PIXELCH_ENABLE(msk, c) (PIXELN_ENABLE(msk, PIXEL_CH2N(c)))
/*!*****************************************************************************
- * @brief Macro to disable an ADC pixel channel in a pixel mask.
- * @param msk The 32-bit pixel mask
- * @param c The pixel ADC channel number to disable.
+ * @brief Macro to disable an ADC pixel channel in a pixel mask.
+ * @param msk The 32-bit pixel mask
+ * @param c The pixel ADC channel number to disable.
******************************************************************************/
#define PIXELCH_DISABLE(msk, c) (PIXELN_DISABLE(msk, PIXEL_CH2N(c)))
/*!*****************************************************************************
- * @brief Macro to determine if a pixel given by the x-y-indices is enabled in a pixel mask.
- * @param msk 32-bit pixel mask
- * @param x x-index of the pixel.
- * @param y y-index of the pixel.
- * @return True if the pixel (x,y) is enabled.
+ * @brief Macro to determine if a pixel given by the x-y-indices is enabled in a pixel mask.
+ * @param msk 32-bit pixel mask
+ * @param x x-index of the pixel.
+ * @param y y-index of the pixel.
+ * @return True if the pixel (x,y) is enabled.
******************************************************************************/
#define PIXELXY_ISENABLED(msk, x, y) (PIXELN_ISENABLED(msk, PIXEL_XY2N(x, y)))
/*!*****************************************************************************
- * @brief Macro to enable a pixel given by the x-y-indices in a pixel mask.
- * @param msk 32-bit pixel mask
- * @param x x-index of the pixel to enable.
- * @param y y-index of the pixel to enable.
+ * @brief Macro to enable a pixel given by the x-y-indices in a pixel mask.
+ * @param msk 32-bit pixel mask
+ * @param x x-index of the pixel to enable.
+ * @param y y-index of the pixel to enable.
******************************************************************************/
#define PIXELXY_ENABLE(msk, x, y) (PIXELN_ENABLE(msk, PIXEL_XY2N(x, y)))
/*!*****************************************************************************
- * @brief Macro disable a pixel given by the x-y-indices in a pixel mask.
- * @param msk 32-bit pixel mask
- * @param x x-index of the pixel to disable.
- * @param y y-index of the pixel to disable.
+ * @brief Macro disable a pixel given by the x-y-indices in a pixel mask.
+ * @param msk 32-bit pixel mask
+ * @param x x-index of the pixel to disable.
+ * @param y y-index of the pixel to disable.
******************************************************************************/
#define PIXELXY_DISABLE(msk, x, y) (PIXELN_DISABLE(msk, PIXEL_XY2N(x, y)))
/*!*****************************************************************************
- * @brief Macro to determine if an ADC channel is enabled in a channel mask.
- * @param msk 32-bit channel mask
- * @param ch channel number of the ADC channel.
- * @return True if the ADC channel is enabled.
+ * @brief Macro to determine if an ADC channel is enabled in a channel mask.
+ * @param msk 32-bit channel mask
+ * @param ch channel number of the ADC channel.
+ * @return True if the ADC channel is enabled.
******************************************************************************/
#define CHANNELN_ISENABLED(msk, ch) (((msk) >> ((ch) - 32U)) & 0x01U)
/*!*****************************************************************************
- * @brief Macro to determine if an ADC channel is enabled in a channel mask.
- * @param msk 32-bit channel mask
- * @param ch channel number of the ADC channel to enabled.
+ * @brief Macro to determine if an ADC channel is enabled in a channel mask.
+ * @param msk 32-bit channel mask
+ * @param ch channel number of the ADC channel to enabled.
******************************************************************************/
#define CHANNELN_ENABLE(msk, ch) ((msk) |= (0x01U << ((ch) - 32U)))
/*!*****************************************************************************
- * @brief Macro to determine if an ADC channel is disabled in a channel mask.
- * @param msk 32-bit channel mask
- * @param ch channel number of the ADC channel to disable.
+ * @brief Macro to determine if an ADC channel is disabled in a channel mask.
+ * @param msk 32-bit channel mask
+ * @param ch channel number of the ADC channel to disable.
******************************************************************************/
#define CHANNELN_DISABLE(msk, ch) ((msk) &= (~(0x01U << ((ch) - 32U))))
/*!*****************************************************************************
- * @brief Macro to determine the number of enabled pixel/channels in a mask
- * via a popcount algorithm.
- * @param pxmsk 32-bit pixel mask
- * @return The count of enabled pixel channels.
+ * @brief Macro to determine the number of enabled pixel/channels in a mask
+ * via a popcount algorithm.
+ * @param pxmsk 32-bit pixel mask
+ * @return The count of enabled pixel channels.
******************************************************************************/
#define PIXEL_COUNT(pxmsk) popcount(pxmsk)
/*!*****************************************************************************
- * @brief Macro to determine the number of enabled channels via a popcount
- * algorithm.
- * @param pxmsk 32-bit pixel mask
- * @param chmsk 32-bit channel mask
- * @return The count of enabled ADC channels.
+ * @brief Macro to determine the number of enabled channels via a popcount
+ * algorithm.
+ * @param pxmsk 32-bit pixel mask
+ * @param chmsk 32-bit channel mask
+ * @return The count of enabled ADC channels.
******************************************************************************/
#define CHANNEL_COUNT(pxmsk, chmsk) (popcount(pxmsk) + popcount(chmsk))
/*!*****************************************************************************
- * @brief Converts a raw ADC channel mask to a x-y-sorted pixel mask.
- * @param msk The raw ADC channel mask to be converted.
- * @return The converted x-y-sorted pixel mask.
+ * @brief Converts a raw ADC channel mask to a x-y-sorted pixel mask.
+ * @param msk The raw ADC channel mask to be converted.
+ * @return The converted x-y-sorted pixel mask.
******************************************************************************/
static inline uint32_t ChannelToPixelMask(uint32_t msk)
{
uint32_t res = 0;
for (uint_fast8_t n = 0; n < 32; n += 2) {
- res |= ((msk >> PIXEL_N2CH(n)) & 0x3U) << n;
+ res |= ((msk >> PIXEL_N2CH(n)) & 0x3U) << n; // sets 2 bits at once
}
return res;
}
+/*!*****************************************************************************
+ * @brief Converts a x-y-sorted pixel mask to a raw ADC channel mask.
+ * @param msk The x-y-sorted pixel channel mask to be converted.
+ * @return The converted raw ADC channel mask.
+ ******************************************************************************/
+static inline uint32_t PixelToChannelMask(uint32_t msk)
+{
+ uint32_t res = 0;
+
+ for (uint_fast8_t ch = 0; ch < 32; ch += 2) {
+ res |= ((msk >> PIXEL_CH2N(ch)) & 0x3U) << ch; // sets 2 bits at once
+ }
+
+ return res;
+}
+
+
+/*!*****************************************************************************
+ * @brief Shifts a pixel mask by a given offset.
+ *
+ * @details This moves the selected pixel pattern by a specified number of
+ * pixels in x and y direction.
+ * If the shift in y direction is odd (e.g +1), the pattern will be
+ * shifted by +0.5 or -0.5 in x direction due to the hexagonal shape
+ * of the pixel field. Thus, a center pixel (usually the Golden Pixel)
+ * is determined that is used to determine if the pattern is shifted
+ * by +0.5 or -0.5 pixels in x direction. The center pixel is then
+ * always shifted without changing the x index and the surrounding
+ * pixels are adopting its x index accordingly.
+ *
+ * Example: Consider the flower pattern, i.e. the Golden Pixel (e.g.
+ * 5/2) is selected and all is direct neighbors (i.e. 5/1, 6/1, 6/2,
+ * 6/3, 5/3, 4/2). If the pattern is shifted by -1 in y direction, the
+ * new Golden Pixel would be 5/1. Now all surrounding pixels are
+ * selected, namely 4/0, 4/1, 4/2, 5/0, 5/2, 6/1). This yields again
+ * the flower around the Golden Pixel.
+ *
+ * Thus, the pixels can not all be shifted by the same dx/dy values due
+ * to the hexagonal shape of the pixel field, e.g. the upper right
+ * neighbor of 5/2 is 5/1 but the upper right neighbor of 5/1 is NOT
+ * 5/0 but 4/0!
+ * This happens only if the shift in y direction is an odd number.
+ * The algorithm to determine new indices is as follows:
+ * - If the shift in y direction is even (e.g. +2, -2), no compensation
+ * of the hexagonal shape is needed; skip compensation, simply
+ * add/subtract indices.
+ * - If the center pixel y index is even, pixels that will have even y
+ * index after the shift will be additionally shifted by -1 in x
+ * direction.
+ * - If the center pixel y index is odd, pixel that will have odd y
+ * index after the shift will be additionally shifted by +1 in x
+ * direction.
+ *
+ * @see Please also refer to the function #Argus_GetCalibrationGoldenPixel
+ * to obtain the current Golden Pixel location.
+ *
+ * @param pixel_mask The x-y-sorted pixel mask to be shifted.
+ * @param dx The number of pixel to shift in x direction.
+ * @param dy The number of pixel to shift in y direction.
+ * @param center_y The center y index of the pattern that is shifted.
+ * @return The shifted pixel mask.
+ ******************************************************************************/
+static inline uint32_t ShiftSelectedPixels(const uint32_t pixel_mask,
+ const int8_t dx,
+ const int8_t dy,
+ const uint8_t center_y)
+{
+ if (dx == 0 && dy == 0) { return pixel_mask; }
+
+ uint32_t shifted_mask = 0;
+
+ for (uint8_t x = 0; x < ARGUS_PIXELS_X; ++x) {
+ for (uint8_t y = 0; y < ARGUS_PIXELS_Y; ++y) {
+ int8_t x_src = x - dx;
+ int8_t y_src = y - dy;
+
+ if (dy & 0x1) {
+ /* Compensate for hexagonal pixel shape. */
+ if ((center_y & 0x1) && (y & 0x1)) {
+ x_src--;
+ }
+
+ if (!(center_y & 0x1) && !(y & 0x1)) {
+ x_src++;
+ }
+ }
+
+ if (x_src < 0 || x_src >= ARGUS_PIXELS_X) { continue; }
+
+ if (y_src < 0 || y_src >= ARGUS_PIXELS_Y) { continue; }
+
+ if (PIXELXY_ISENABLED(pixel_mask, x_src, y_src)) {
+ PIXELXY_ENABLE(shifted_mask, x, y);
+ }
+ }
+ }
+
+ return shifted_mask;
+}
+
+/*!*****************************************************************************
+ * @brief Fills a pixel mask to a specified number of pixels around a center pixel.
+ *
+ * @details The pixel mask is iteratively filled with the nearest pixel to a
+ * specified center pixel until a specified number of pixels is achieved.
+ * The distance between two pixel is determined via a quadratic metric,
+ * i.e. dx^2 + dy^2. Pixels towards the lower x indices are preferred.
+ *
+ * Note that the distance of only calculated approximately, e.g. the
+ * y distance of pixels is considered to be 2 instead of cos(60)*2.
+ *
+ * Nothing is done if the number of pixels already exceeds the specified
+ * /p pixel_count parameter.
+ *
+ * @see Please also refer to the function #Argus_GetCalibrationGoldenPixel
+ * to obtain the current Golden Pixel location.
+ *
+ * @param pixel_mask The x-y-sorted pixel mask to be filled with pixels.
+ * @param pixel_count The final number of pixels in the pixel mask.
+ * @param center_x The center pixel x-index.
+ * @param center_y The center pixel y-index.
+ * @return The filled pixel mask with at least /p pixel_count pixels selected.
+ ******************************************************************************/
+static inline uint32_t FillPixelMask(uint32_t pixel_mask,
+ const uint8_t pixel_count,
+ const uint8_t center_x,
+ const uint8_t center_y)
+{
+ assert(pixel_count <= ARGUS_PIXELS);
+ assert(center_x < ARGUS_PIXELS_X);
+ assert(center_y < ARGUS_PIXELS_Y);
+
+ if (pixel_count == ARGUS_PIXELS) { return 0xFFFFFFFFU; }
+
+ /* If the pattern was shifted towards boundaries, the pixel count may have
+ * decreased. In this case, the pixels closest to the reference pixel are
+ * selected. Pixel towards lower x index are prioritized. */
+ while (pixel_count > PIXEL_COUNT(pixel_mask)) {
+ int32_t min_dist = INT32_MAX;
+ int8_t min_x = -1;
+ int8_t min_y = -1;
+
+ /* Find nearest not selected pixel. */
+ for (uint8_t x = 0; x < ARGUS_PIXELS_X; ++x) {
+ for (uint8_t y = 0; y < ARGUS_PIXELS_Y; ++y) {
+ if (!PIXELXY_ISENABLED(pixel_mask, x, y)) {
+ int32_t distx = (x - center_x) << 1;
+
+ if (!(y & 0x1)) { distx++; }
+
+ if (!(center_y & 0x1)) { distx--; }
+
+ const int32_t disty = (y - center_y) << 1;
+ int32_t dist = distx * distx + disty * disty;
+
+ if (dist < min_dist) {
+ min_dist = dist;
+ min_x = x;
+ min_y = y;
+ }
+ }
+ }
+ }
+
+ assert(min_x >= 0 && min_x < ARGUS_PIXELS_X);
+ assert(min_y >= 0 && min_y < ARGUS_PIXELS_Y);
+ assert(!PIXELXY_ISENABLED(pixel_mask, min_x, min_y));
+ PIXELXY_ENABLE(pixel_mask, min_x, min_y);
+ }
+
+ return pixel_mask;
+}
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_MAP_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_meas.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_meas.h
index 0e074c6a8b..7a0fa31aa5 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_meas.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_meas.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 hardware API.
- * @details Defines the generic measurement parameters and data structures.
+ * @brief This file is part of the AFBR-S50 hardware API.
+ * @details Defines the generic measurement parameters and data structures.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,17 +36,20 @@
#ifndef ARGUS_MEAS_H
#define ARGUS_MEAS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup argusmeas Measurement/Device Control
- * @ingroup argusapi
+ * @defgroup argus_meas Measurement/Device Control
+ * @ingroup argus_api
*
- * @brief Measurement/Device control module
+ * @brief Measurement/Device control module
*
- * @details This module contains measurement and device control specific
- * definitions and methods.
+ * @details This module contains measurement and device control specific
+ * definitions and methods.
*
- * @addtogroup argusmeas
+ * @addtogroup argus_meas
* @{
*****************************************************************************/
@@ -66,11 +69,11 @@
#define ARGUS_AUX_DATA_SIZE (3U * ARGUS_AUX_CHANNEL_COUNT) // 3 bytes * x channels * 1 phase
/*!***************************************************************************
- * @brief The device measurement configuration structure.
- * @details The portion of the configuration data that belongs to the
- * measurement cycle. I.e. the data that defines a measurement frame.
+ * @brief The device measurement configuration structure.
+ * @details The portion of the configuration data that belongs to the
+ * measurement cycle. I.e. the data that defines a measurement frame.
*****************************************************************************/
-typedef struct {
+typedef struct argus_meas_frame_t {
/*! Frame integration time in microseconds.
* The integration time determines the measured time between
* the start signal and the IRQ. Note that this value will be
@@ -82,13 +85,13 @@ typedef struct {
/*! Pixel enabled mask for the 32 pixels sorted
* by x-y-indices.
- * See [pixel mapping](@ref argusmap) for more
+ * See [pixel mapping](@ref argus_map) for more
* details on the pixel mask. */
uint32_t PxEnMask;
/*! ADS channel enabled mask for the remaining
* channels 31 .. 63 (miscellaneous values).
- * See [pixel mapping](@ref argusmap) for more
+ * See [pixel mapping](@ref argus_map) for more
* details on the ADC channel mask. */
uint32_t ChEnMask;
@@ -113,9 +116,6 @@ typedef struct {
* Determines the optical output power. */
uq12_4_t OutputPower;
- /*! The amplitude that is evaluated and used in the DCA module. */
- uq12_4_t DCAAmplitude;
-
/*! Laser Bias Current Settings in LSB. */
uint8_t BiasCurrent;
@@ -133,4 +133,7 @@ typedef struct {
} argus_meas_frame_t;
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_MEAS_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_offset.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_offset.h
new file mode 100644
index 0000000000..7a41440f39
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_offset.h
@@ -0,0 +1,59 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 hardware API.
+ * @details Defines the generic device calibration API.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef ARGUS_OFFSET_H
+#define ARGUS_OFFSET_H
+
+/*!***************************************************************************
+ * @addtogroup argus_cal
+ * @{
+ *****************************************************************************/
+
+#include "argus_def.h"
+
+/*!***************************************************************************
+ * @brief Pixel Range Offset Table.
+ * @details Contains pixel range offset values for all 32 active pixels.
+ *****************************************************************************/
+typedef struct argus_cal_offset_table_t {
+ /*! The offset values per pixel in meter and Q0.15 format. */
+ q0_15_t Table[ARGUS_PIXELS_X][ARGUS_PIXELS_Y];
+
+} argus_cal_offset_table_t;
+
+
+/*! @} */
+#endif /* ARGUS_OFFSET_T */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_pba.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_pba.h
index 07b4853bda..f28576500d 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_pba.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_pba.h
@@ -1,12 +1,12 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Defines the pixel binning algorithm (PBA) setup parameters and
- * data structure.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Defines the pixel binning algorithm (PBA) setup parameters and
+ * data structure.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,86 +37,98 @@
#ifndef ARGUS_PBA_H
#define ARGUS_PBA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup arguspba Pixel Binning Algorithm
- * @ingroup argusapi
+ * @defgroup argus_pba Pixel Binning Algorithm
+ * @ingroup argus_api
*
- * @brief Pixel Binning Algorithm (PBA) parameter definitions and API functions.
+ * @brief Pixel Binning Algorithm (PBA) parameter definitions and API functions.
*
- * @details Defines the generic pixel binning algorithm (PBA) setup parameters
- * and data structure.
+ * @details Defines the generic Pixel Binning Algorithm (PBA) setup parameters
+ * and data structure.
*
- * The PBA module contains filter algorithms that determine the
- * pixels with the best signal quality and extract an 1d distance
- * information from the filtered pixels.
+ * The PBA module contains filter algorithms that determine the
+ * pixels with the best signal quality and extract an 1D distance
+ * information from the filtered pixels by averaging them in a
+ * specified way.
*
- * The pixel filter algorithm is a three-stage filter with a
- * fallback value:
+ * The Pixel Binning Algorithm is a three-stage filter with a
+ * fallback value:
*
- * -# A fixed pre-filter mask is applied to statically disable
- * specified pixels.
- * -# A relative and absolute amplitude filter is applied in the
- * second stage. The relative filter is determined by a ratio
- * of the maximum amplitude off all available (i.e. not filtered
- * in stage 1) pixels. Pixels that have an amplitude below the
- * relative threshold are dismissed. The same holds true for
- * the absolute amplitude threshold. All pixel with smaller
- * amplitude are dismissed.\n
- * The relative threshold is useful to setup a distance
- * measurement scenario. All well illuminated pixels are
- * selected and considered for the final 1d distance. The
- * absolute threshold is used to dismiss pixels that are below
- * the noise level. The latter would be considered for the 1d
- * result if the maximum amplitude is already very low.
- * -# A distance filter is used to distinguish pixels that target
- * the actual object from pixels that see the brighter background,
- * e.g. white walls. Thus, the pixel with the minimum distance
- * is referenced and all pixel that have a distance between
- * the minimum and the given minimum distance scope are selected
- * for the 1d distance result. The minimum distance scope is
- * determined by an relative (to the current minimum distance)
- * and an absolute value. The larger scope value is the
- * relevant one, i.e. the relative distance scope can be used
- * to heed the increasing noise at larger distances.
- * -# If all of the above filters fail to determine a single valid
- * pixel, the golden pixel is used as a fallback value. The
- * golden pixel is the pixel that sits right at the focus point
- * of the optics at large distances.
- * .
+ * -# A fixed pre-filter mask is applied to statically disable
+ * specified pixels.
+ * -# A relative and absolute amplitude filter is applied in the
+ * second stage. The relative filter is determined by a ratio
+ * of the maximum amplitude off all available (i.e. not filtered
+ * in stage 1) pixels. Pixels that have an amplitude below the
+ * relative threshold are dismissed. The same holds true for
+ * the absolute amplitude threshold. All pixel with smaller
+ * amplitude are dismissed.\n
+ * Note that the absolute amplitude threshold is disabled if
+ * the Golden Pixel (see below) is also disabled in order to
+ * prevent invalid filtering for multi-pixel devices.\n
+ * The relative threshold is useful to setup a distance
+ * measurement scenario. All well illuminated pixels are
+ * selected and considered for the final 1D distance. The
+ * absolute threshold is used to dismiss pixels that are below
+ * the noise level. The latter would be considered for the 1D
+ * result if the maximum amplitude is already very low.
+ * -# An absolute minimum distance filter is applied in addition
+ * to the amplitude filter. This removes all pixel that have
+ * a lower distance than the specified threshold. This is used
+ * to remove invalid pixels that can be detected by a physically
+ * not correct negative distance.
+ * -# A distance filter is used to distinguish pixels that target
+ * the actual object from pixels that see the brighter background,
+ * e.g. white walls. Thus, the pixel with the minimum distance
+ * is referenced and all pixel that have a distance between
+ * the minimum and the given minimum distance scope are selected
+ * for the 1D distance result. The minimum distance scope is
+ * determined by an relative (to the current minimum distance)
+ * and an absolute value. The larger scope value is the
+ * relevant one, i.e. the relative distance scope can be used
+ * to heed the increasing noise at larger distances.
+ * -# If all of the above filters fail to determine a single valid
+ * pixel, the Golden Pixel is used as a fallback value. The
+ * Golden Pixel is the pixel that sits right at the focus point
+ * of the optics at large distances.
+ * .
*
- * After filtering is done, there may be more than a single pixel
- * left to determine the 1d signal. Therefore several averaging
- * methods are implemented to obtain the best 1d result from many
- * pixels. See #argus_pba_averaging_mode_t for details.
+ * After filtering is done, there may be more than a single pixel
+ * left to determine the 1D signal. Therefore several averaging
+ * methods are implemented to obtain the best 1D result from many
+ * pixels. See #argus_pba_averaging_mode_t for details.
*
*
- * @addtogroup arguspba
+ * @addtogroup argus_pba
* @{
*****************************************************************************/
#include "argus_def.h"
/*!***************************************************************************
- * @brief Enable flags for the pixel binning algorithm.
+ * @brief Enable flags for the pixel binning algorithm.
*
* @details Determines the pixel binning algorithm feature enable status.
- * - [0]: #PBA_ENABLE: Enables the pixel binning feature.
- * - [1]: reserved
- * - [2]: reserved
- * - [3]: reserved
- * - [4]: reserved
- * - [5]: #PBA_ENABLE_GOLDPX: Enables the golden pixel feature.
- * - [6]: #PBA_ENABLE_MIN_DIST_SCOPE: Enables the minimum distance scope
- * feature.
- * - [7]: reserved
- * .
+ * - [0]: #PBA_ENABLE: Enables the pixel binning feature.
+ * - [1]: reserved
+ * - [2]: reserved
+ * - [3]: reserved
+ * - [4]: reserved
+ * - [5]: #PBA_ENABLE_GOLDPX: Enables the Golden Pixel feature.
+ * - [6]: #PBA_ENABLE_MIN_DIST_SCOPE: Enables the minimum distance scope
+ * feature.
+ * - [7]: reserved
+ * .
*****************************************************************************/
-typedef enum {
+typedef enum argus_pba_flags_t {
/*! Enables the pixel binning feature. */
PBA_ENABLE = 1U << 0U,
- /*! Enables the golden pixel. */
+ /*! Enables the Golden Pixel. */
PBA_ENABLE_GOLDPX = 1U << 5U,
/*! Enables the minimum distance scope filter. */
@@ -125,9 +137,9 @@ typedef enum {
} argus_pba_flags_t;
/*!***************************************************************************
- * @brief The averaging modes for the pixel binning algorithm.
+ * @brief The averaging modes for the pixel binning algorithm.
*****************************************************************************/
-typedef enum {
+typedef enum argus_pba_averaging_mode_t {
/*! Evaluate the 1D range from all available pixels using
* a simple average. */
PBA_SIMPLE_AVG = 1U,
@@ -140,11 +152,12 @@ typedef enum {
} argus_pba_averaging_mode_t;
/*!***************************************************************************
- * @brief The pixel binning algorithm settings data structure.
- * @details Describes the pixel binning algorithm settings.
+ * @brief The pixel binning algorithm settings data structure.
+ * @details Describes the pixel binning algorithm settings.
*****************************************************************************/
typedef struct {
- /*! Enables the pixel binning features.
+ /*! Enables the Pixel Binning Algorithm.
+ *
* Each bit may enable a different feature. See #argus_pba_flags_t
* for details about the enabled flags. */
argus_pba_flags_t Enabled;
@@ -156,6 +169,7 @@ typedef struct {
argus_pba_averaging_mode_t AveragingMode;
/*! The Relative amplitude threshold value (in %) of the max. amplitude.
+ *
* Pixels with amplitude below this threshold value are dismissed.
*
* All available values from the 8-bit representation are valid.
@@ -165,22 +179,27 @@ typedef struct {
uq0_8_t RelAmplThreshold;
/*! The relative minimum distance scope value in %.
- * Pixels that have a range value within [x0, x0 + dx] are considered
- * for the pixel binning, where x0 is the minimum distance of all
- * amplitude picked pixels and dx is the minimum distance scope value.
- * The minimum distance scope value will be the maximum of relative
- * and absolute value.
+ *
+ * Pixels that have a range value within [x0, x0 + dx] are considered
+ * for the pixel binning, where x0 is the minimum distance of all
+ * amplitude picked pixels and dx is the minimum distance scope value.
+ * The minimum distance scope value will be the maximum of relative
+ * and absolute value.
*
* All available values from the 8-bit representation are valid.
* The actual percentage value is determined by 100%/256*x.
*
- * Special values:
+ * Special values:
* - 0: Use 0 for absolute value only or to choose the pixel with the
- * minimum distance only (of also the absolute value is 0)! */
+ * minimum distance only (of also the absolute value is 0)! */
uq0_8_t RelMinDistanceScope;
- /*! The Absolute amplitude threshold value in LSB.
- * Pixels with amplitude below this threshold value are dismissed.
+ /*! The absolute amplitude threshold value in LSB.
+ *
+ * Pixels with amplitude below this threshold value are dismissed.
+ *
+ * The absolute amplitude threshold is only valid if the Golden Pixel
+ * mode is enabled. Otherwise, the threshold is set to 0 LSB internally.
*
* All available values from the 16-bit representation are valid.
* The actual LSB value is determined by x/16.
@@ -189,33 +208,42 @@ typedef struct {
uq12_4_t AbsAmplThreshold;
/*! The absolute minimum distance scope value in m.
- * Pixels that have a range value within [x0, x0 + dx] are considered
- * for the pixel binning, where x0 is the minimum distance of all
- * amplitude picked pixels and dx is the minimum distance scope value.
- * The minimum distance scope value will be the maximum of relative
- * and absolute value.
+ *
+ * Pixels that have a range value within [x0, x0 + dx] are considered
+ * for the pixel binning, where x0 is the minimum distance of all
+ * amplitude picked pixels and dx is the minimum distance scope value.
+ * The minimum distance scope value will be the maximum of relative
+ * and absolute value.
*
* All available values from the 16-bit representation are valid.
* The actual LSB value is determined by x/2^15.
*
- * Special values:
+ * Special values:
* - 0: Use 0 for relative value only or to choose the pixel with the
- * minimum distance only (of also the relative value is 0)! */
+ * minimum distance only (of also the relative value is 0)! */
uq1_15_t AbsMinDistanceScope;
- /*! The pre-filter pixel mask determines the pixel channels that are
- * statically excluded from the pixel binning (i.e. 1D distance) result.
+ /*! The absolute minimum distance threshold value in m.
*
- * The pixel enabled mask is an 32-bit mask that determines the
- * device internal channel number. It is recommended to use the
- * - #PIXELXY_ISENABLED(msk, x, y)
- * - #PIXELXY_ENABLE(msk, x, y)
- * - #PIXELXY_DISABLE(msk, x, y)
- * .
- * macros to work with the pixel enable masks. */
+ * Pixels with distance below this threshold value are dismissed. */
+ q9_22_t AbsMinDistanceThreshold;
+
+ /*! The pre-filter pixel mask determines the pixel channels that are
+ * statically excluded from the pixel binning (i.e. 1D distance) result.
+ *
+ * The pixel enabled mask is an 32-bit mask that determines the
+ * device internal channel number. It is recommended to use the
+ * - #PIXELXY_ISENABLED(msk, x, y)
+ * - #PIXELXY_ENABLE(msk, x, y)
+ * - #PIXELXY_DISABLE(msk, x, y)
+ * .
+ * macros to work with the pixel enable masks. */
uint32_t PrefilterMask;
} argus_cfg_pba_t;
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_PBA_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_px.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_px.h
index faa031aeb7..a739cea7f3 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_px.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_px.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Defines the device pixel measurement results data structure.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Defines the device pixel measurement results data structure.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,34 +36,40 @@
#ifndef ARGUS_PX_H
#define ARGUS_PX_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @addtogroup argusres
+ * @addtogroup argus_res
* @{
*****************************************************************************/
+#include "argus_def.h"
+
+
/*! Maximum amplitude value in UQ12.4 format. */
-#define ARGUS_AMPLITUDE_MAX (0xFFF0U)
+#define ARGUS_AMPLITUDE_MAX (0xFFF0U)
/*! Maximum range value in Q9.22 format.
* Also used as a special value to determine no object detected or infinity range. */
#define ARGUS_RANGE_MAX (Q9_22_MAX)
/*!***************************************************************************
- * @brief Status flags for the evaluated pixel structure.
+ * @brief Status flags for the evaluated pixel structure.
*
* @details Determines the pixel status. 0 means OK (#PIXEL_OK).
- * - [0]: #PIXEL_OFF: Pixel was disabled and not read from the device.
- * - [1]: #PIXEL_SAT: The pixel was saturated.
- * - [2]: #PIXEL_BIN_EXCL: The pixel was excluded from the 1D result.
- * - [3]: #PIXEL_AMPL_MIN: The pixel amplitude has evaluated to 0.
- * - [4]: #PIXEL_PREFILTERED: The was pre-filtered by static mask.
- * - [5]: #PIXEL_NO_SIGNAL: The pixel has no valid signal.
- * - [6]: #PIXEL_OUT_OF_SYNC: The pixel has lost signal trace.
- * - [7]: #PIXEL_STALLED: The pixel value is stalled due to errors.
- * .
+ * - [0]: #PIXEL_OFF: Pixel was disabled and not read from the device.
+ * - [1]: #PIXEL_SAT: The pixel was saturated.
+ * - [2]: #PIXEL_BIN_EXCL: The pixel was excluded from the 1D result.
+ * - [3]: #PIXEL_INVALID: The pixel data is invalid.
+ * - [4]: #PIXEL_PREFILTERED: The was pre-filtered by static mask.
+ * - [5]: #PIXEL_NO_SIGNAL: The pixel has no valid signal.
+ * - [6]: #PIXEL_OUT_OF_SYNC: The pixel has lost signal trace.
+ * - [7]: #PIXEL_STALLED: The pixel value is stalled due to errors.
+ * .
*****************************************************************************/
-typedef enum {
+typedef enum argus_px_status_t {
/*! 0x00: Pixel status OK. */
PIXEL_OK = 0,
@@ -77,43 +83,45 @@ typedef enum {
/*! 0x04: Pixel is excluded from the pixel binning (1d) result. */
PIXEL_BIN_EXCL = 1U << 2U,
- /*! 0x08: Pixel amplitude minimum underrun
- * (i.e. the amplitude calculation yields 0). */
- PIXEL_AMPL_MIN = 1U << 3U,
+ /*! 0x08: Pixel has invalid data due to miscellaneous reasons, e.g.
+ * - Amplitude calculates to 0 (i.e. division by 0)
+ * - Golden Pixel is invalid due to other saturated pixel.
+ * - Range/distance is negative. */
+ PIXEL_INVALID = 1U << 3U,
/*! 0x10: Pixel is pre-filtered by the static pixel binning pre-filter mask,
- * i.e. the pixel is disabled by software. */
+ * i.e. the pixel is disabled by software. */
PIXEL_PREFILTERED = 1U << 4U,
/*! 0x20: Pixel amplitude is below its threshold value. The received signal
- * strength is too low to evaluate a valid signal. The range value is
- * set to the maximum possible value (approx. 512 m). */
+ * strength is too low to evaluate a valid signal. The range value is
+ * set to the maximum possible value (approx. 512 m). */
PIXEL_NO_SIGNAL = 1U << 5U,
/*! 0x40: Pixel is not in sync with respect to the dual frequency algorithm.
- * I.e. the pixel may have a correct value but is estimated into the
- * wrong unambiguous window. */
+ * I.e. the pixel may have a correct value but is estimated into the
+ * wrong unambiguous window. */
PIXEL_OUT_OF_SYNC = 1U << 6U,
/*! 0x80: Pixel is stalled due to one of the following reasons:
- * - #PIXEL_SAT
- * - #PIXEL_AMPL_MIN
- * - #PIXEL_OUT_OF_SYNC
- * - Global Measurement Error
- * .
- * A stalled pixel does not update its measurement data and keeps the
- * previous values. If the issue is resolved, the stall disappears and
- * the pixel is updating again. */
+ * - #PIXEL_SAT
+ * - #PIXEL_INVALID
+ * - #PIXEL_OUT_OF_SYNC
+ * - Global Measurement Error
+ * .
+ * A stalled pixel does not update its measurement data and keeps the
+ * previous values. If the issue is resolved, the stall disappears and
+ * the pixel is updating again. */
PIXEL_STALLED = 1U << 7U
} argus_px_status_t;
/*!***************************************************************************
- * @brief The evaluated measurement results per pixel.
- * @details This structure contains the evaluated data for a single pixel.\n
- * If the amplitude is 0, the pixel is turned off or has invalid data.
+ * @brief The evaluated measurement results per pixel.
+ * @details This structure contains the evaluated data for a single pixel.\n
+ * If the amplitude is 0, the pixel is turned off or has invalid data.
*****************************************************************************/
-typedef struct {
+typedef struct argus_pixel_t {
/*! Range Values from the device in meter. It is the actual distance before
* software adjustments/calibrations. */
q9_22_t Range;
@@ -141,14 +149,23 @@ typedef struct {
/*!***************************************************************************
* @brief Representation of a correlation vector containing sine/cosine components.
*****************************************************************************/
-typedef struct {
- /*! The sine component. */
- q15_16_t S;
+typedef struct argus_vector_t {
+ union {
+ /*! The sine [0] and cosine [1] components. */
+ q15_16_t SC[2];
- /*! The cosine component. */
- q15_16_t C;
+ struct {
+ /*! The sine component. */
+ q15_16_t S;
+ /*! The cosine component. */
+ q15_16_t C;
+ };
+ };
} argus_vector_t;
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_PX_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_res.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_res.h
index f59d817634..7cb81bfcf1 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_res.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_res.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Defines the generic measurement results data structure.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Defines the generic measurement results data structure.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,35 +36,39 @@
#ifndef ARGUS_RES_H
#define ARGUS_RES_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup argusres Measurement Data
- * @ingroup argusapi
+ * @defgroup argus_res Measurement Data
+ * @ingroup argus_api
*
- * @brief Measurement results data structures.
+ * @brief Measurement results data structures.
*
- * @details The interface defines all data structures that correspond to
- * the AFBR-S50 measurement results, e.g.
- * - 1D distance and amplitude values,
- * - 3D distance and amplitude values (i.e. per pixel),
- * - Auxiliary channel measurement results (VDD, IAPD, temperature, ...)
- * - Device and result status
- * - ...
- * .
+ * @details The interface defines all data structures that correspond to
+ * the AFBR-S50 measurement results, e.g.
+ * - 1D distance and amplitude values,
+ * - 3D distance and amplitude values (i.e. per pixel),
+ * - Auxiliary channel measurement results (VDD, IAPD, temperature, ...)
+ * - Device and result status
+ * - ...
+ * .
*
- * @addtogroup argusres
+ * @addtogroup argus_res
* @{
*****************************************************************************/
-#include "argus_def.h"
#include "argus_px.h"
+#include "argus_def.h"
#include "argus_meas.h"
+#include "argus_xtalk.h"
/*!***************************************************************************
- * @brief The 1d measurement results data structure.
+ * @brief The 1d measurement results data structure.
* @details The 1d measurement results obtained by the Pixel Binning Algorithm.
*****************************************************************************/
-typedef struct {
+typedef struct argus_results_bin_t {
/*! Raw 1D range value in meter (Q9.22 format). The distance obtained by
* the Pixel Binning Algorithm from the current measurement frame. */
q9_22_t Range;
@@ -83,11 +87,11 @@ typedef struct {
} argus_results_bin_t;
/*!***************************************************************************
- * @brief The auxiliary measurement results data structure.
- * @details The auxiliary measurement results obtained by the auxiliary task.\n
- * Special values, i.e. 0xFFFFU, indicate no readout value available.
+ * @brief The auxiliary measurement results data structure.
+ * @details The auxiliary measurement results obtained by the auxiliary task.\n
+ * Special values, i.e. 0xFFFFU, indicate no readout value available.
*****************************************************************************/
-typedef struct {
+typedef struct argus_results_aux_t {
/*! VDD ADC channel readout value.\n
* Special Value if no value has been measured:\n
* Invalid/NotAvailable = 0xFFFFU (UQ12_4_MAX) */
@@ -129,32 +133,66 @@ typedef struct {
} argus_results_aux_t;
/*!***************************************************************************
- * @brief The measurement results data structure.
+ * @brief The debug data of measurement results data structure.
+ * @details This data structure will be filled with API internal data for
+ * debugging purposes.
+ *****************************************************************************/
+typedef struct argus_results_debug_t {
+ /*! The amplitude that is evaluated and used in the DCA module. */
+ uq12_4_t DCAAmplitude;
+
+ /*! Raw x-y-sorted ADC results from the device.\n
+ * Data is arranged as 32-bit values in following order:
+ * index > phase; where index is pixel number n and auxiliary ADC channel.\n
+ * Note that disabled pixels are skipped.\n
+ * e.g. [n=0,p=0][n=0,p=1]..[n=0,p=3][n=1,p=0]...[n=1,p=3]...[n=31,p=3] */
+ uint32_t Data[ARGUS_RAW_DATA_VALUES];
+
+ /*! The current crosstalk correction values as determined by the
+ * crosstalk predictor algorithm. This is basically the temperature
+ * dependent portion of the crosstalk correction.\n
+ * Note that there are two values for the upper and lower two rows
+ * respectively. */
+ xtalk_t XtalkPredictor[ARGUS_PIXELS_Y / 2U];
+
+ /*! The current crosstalk correction values as determined by the
+ * crosstalk monitor algorithm. This is a dynamic portion of the
+ * crosstalk correction that is determined by monitoring passive
+ * pixels.\n
+ * Note that the values are valid row-wise. */
+ xtalk_t XtalkMonitor[ARGUS_PIXELS_Y];
+
+} argus_results_debug_t;
+
+/*!***************************************************************************
+ * @brief The measurement results data structure.
* @details This structure contains all information obtained by a single
- * distance measurement on the device:
- * - The measurement status can be read from the #Status.
- * - A timing information is given via the #TimeStamp.
- * - Information about the frame state is in the #Frame structure.
- * - The 1D distance results are gathered under #Bin.
- * - The 3D distance results for each pixel is at #Pixels or #Pixel.
- * - Auxiliary values such as temperature can be found at #Auxiliary.
- * - Raw data from the device is stored in the #Data array.
- * .
+ * distance measurement on the device:
+ * - The measurement status can be read from the #Status.
+ * - A timing information is given via the #TimeStamp.
+ * - Information about the frame state is in the #Frame structure.
+ * - The 1D distance results are gathered under #Bin.
+ * - The 3D distance results for each pixel is at #Pixels or #Pixel.
+ * - Auxiliary values such as temperature can be found at #Auxiliary.
+ * - Raw data and debug information from the device and API is stored
+ * in the optional #Debug data structure. Note that this points to
+ * an optional structure and can be null!
+ * .
*
- * The pixel x-y orientation is sketched in the following graph. Note that
- * the laser source would be on the right side beyond the reference pixel.
- * See also \link argusmap ADC Channel Mapping\endlink
+ * The pixel x-y orientation is sketched in the following graph. Note that
+ * the laser source would be on the right side beyond the reference pixel.
+ * See also \link argus_map ADC Channel Mapping\endlink
* @code
- * // Pixel Field: Pixel[x][y]
- * //
- * // 0 -----------> x
- * // | O O O O O O O O
- * // | O O O O O O O O
- * // | O O O O O O O O O (ref. Px)
- * // y O O O O O O O O
+ * // Pixel Field: Pixel[x][y]
+ * //
+ * // 0 -----------> x
+ * // | O O O O O O O O
+ * // | O O O O O O O O
+ * // | O O O O O O O O O (ref. Px)
+ * // y O O O O O O O O
* @endcode
*****************************************************************************/
-typedef struct {
+typedef struct argus_results_t {
/*! The \link #status_t status\endlink of the current measurement frame.
* - 0 (i.e. #STATUS_OK) for a good measurement signal.
* - > 0 for warnings and weak measurement signal.
@@ -168,13 +206,6 @@ typedef struct {
/*! The configuration for the current measurement frame. */
argus_meas_frame_t Frame;
- /*! Raw x-y-sorted ADC results from the device.\n
- * Data is arranged as 32-bit values in following order:
- * index > phase; where index is pixel number n and auxiliary ADC channel.\n
- * Note that disabled pixels are skipped.\n
- * e.g. [n=0,p=0][n=0,p=1]..[n=0,p=3][n=1,p=0]...[n=1,p=3]...[n=31,p=3] */
- uint32_t Data[ARGUS_RAW_DATA_VALUES];
-
union {
/*! Pixel data indexed by channel number n.\n
* Contains calibrated range, amplitude and pixel status among others.
@@ -183,14 +214,14 @@ typedef struct {
* - 0..31: active pixels
* - 32: reference pixel
*
- * See also \link argusmap ADC Channel Mapping\endlink */
+ * See also \link argus_map ADC Channel Mapping\endlink */
argus_pixel_t Pixels[ARGUS_PIXELS + 1U];
struct {
/*! Pixel data indexed by x-y-indices.\n
* The pixels are ordered in a two dimensional array that represent
* the x and y indices of the pixel.\n
- * See also \link argusmap ADC Channel Mapping\endlink
+ * See also \link argus_map ADC Channel Mapping\endlink
*
* Contains calibrated range, amplitude and pixel status among others. */
argus_pixel_t Pixel[ARGUS_PIXELS_X][ARGUS_PIXELS_Y];
@@ -213,8 +244,17 @@ typedef struct {
/*! The auxiliary ADC channel data, e.g. sensor temperature. */
argus_results_aux_t Auxiliary;
+ /*! Optional Debug Data.
+ * If the pointer is set to a #argus_results_debug_t data structure before
+ * passing it to the #Argus_EvaluateData function, the data structure is
+ * filled with internal parameters for debugging purposes. */
+ argus_results_debug_t *Debug;
+
} argus_results_t;
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_RES_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_snm.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_snm.h
index 2776308143..2b77965bb0 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_snm.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_snm.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Defines the Shot Noise Monitor (SNM) setup parameters.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Defines the Shot Noise Monitor (SNM) setup parameters.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,30 +36,33 @@
#ifndef ARGUS_SNM_H
#define ARGUS_SNM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup argussnm Shot Noise Monitor
- * @ingroup argusapi
+ * @defgroup argus_snm Shot Noise Monitor
+ * @ingroup argus_api
*
- * @brief Shot Noise Monitor (SNM) parameter definitions and API functions.
+ * @brief Shot Noise Monitor (SNM) parameter definitions and API functions.
*
- * @details The SNM is an algorithm to monitor and react on shot noise
- * induced by harsh environment conditions like high ambient
- * light.
+ * @details The SNM is an algorithm to monitor and react on shot noise
+ * induced by harsh environment conditions like high ambient
+ * light.
*
- * The AFBR-S50 API provides three modes:
- * - Dynamic: Automatic mode, automatically adopts to current
- * ambient conditions.
- * - Static (Outdoor): Static mode, optimized for outdoor applications.
- * - Static (Indoor): Static mode, optimized for indoor applications.
- * .
+ * The AFBR-S50 API provides three modes:
+ * - Dynamic: Automatic mode, automatically adopts to current
+ * ambient conditions.
+ * - Static (Outdoor): Static mode, optimized for outdoor applications.
+ * - Static (Indoor): Static mode, optimized for indoor applications.
+ * .
*
- * @addtogroup argussnm
+ * @addtogroup argus_snm
* @{
*****************************************************************************/
/*! The Shot Noise Monitor modes enumeration. */
-typedef enum {
+typedef enum argus_snm_mode_t {
/*! Static Shot Noise Monitoring Mode, optimized for indoor applications.
* Assumes the best case scenario, i.e. no bad influence from ambient conditions.
* Thus it uses a fixed setting that will result in the best performance.
@@ -79,4 +82,7 @@ typedef enum {
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_SNM_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_status.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_status.h
index 244ad1beec..77cd856413 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_status.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_status.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Provides status codes for the AFBR-S50 API.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Provides status codes for the AFBR-S50 API.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,25 +36,32 @@
#ifndef ARGUS_STATUS_H
#define ARGUS_STATUS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
#include
/*!***************************************************************************
- * @defgroup status Status Codes
+ * @defgroup argus_status Status Codes
+ * @ingroup argus
+ *
* @brief Status and Error Code Definitions
+ *
* @details Defines status and error codes for function return values.
* Basic status number structure:
* - 0 is OK or no error.
* - negative values determine errors.
* - positive values determine warnings or status information.
* .
- * @addtogroup status
+ *
+ * @addtogroup argus_status
* @{
*****************************************************************************/
/*!***************************************************************************
- * @brief Type used for all status and error return values.
- * @details Basic status number structure:
+ * @brief Type used for all status and error return values.
+ * @details Basic status number structure:
* - 0 is OK or no error.
* - negative values determine errors.
* - positive values determine warnings or status information.
@@ -138,8 +145,8 @@ enum Status {
********** NVM / Flash Layer Status *********************************************************
*********************************************************************************************/
- /*! -98: Flash Error: The version of the settings in the flash memory is not compatible. */
- ERROR_NVM_INVALID_FILE_VERSION = -98,
+ /*! -98: Flash Error: The read memory block was not written previously and contains no data. */
+ ERROR_NVM_EMPTY = -98,
/*! -99: Flash Error: The memory is out of range. */
ERROR_NVM_OUT_OF_RANGE = -99,
@@ -183,6 +190,13 @@ enum Status {
/*! -102: AFBR-S50 Error: Inconsistent configuration parameters. */
ERROR_ARGUS_INVALID_CFG = -102,
+ /*! -103: AFBR-S50 Error: The evaluation function has been called but no
+ * raw data is available yet.
+ * See also #Argus_EvaluateData for more information. */
+ ERROR_ARGUS_BUFFER_EMPTY = -103,
+
+ /*! -104: AFBR-S50 Error: Invalid slave identifier is passed to the module. */
+ ERROR_ARGUS_INVALID_SLAVE = -104,
/*! -105: AFBR-S50 Error: Invalid measurement mode configuration parameter. */
ERROR_ARGUS_INVALID_MODE = -105,
@@ -191,7 +205,6 @@ enum Status {
* The current measurement data set is invalid! */
ERROR_ARGUS_BIAS_VOLTAGE_REINIT = -107,
-
/*! -109: AFBR-S50 Error: The EEPROM readout has failed. The failure is detected
* by three distinct read attempts, each resulting in invalid data.
* Note: this state differs from that #STATUS_ARGUS_EEPROM_BIT_ERROR
@@ -224,7 +237,6 @@ enum Status {
* requested command. */
ERROR_ARGUS_BUSY = -191,
-
/*! -199: AFBR-S50 Error: Unknown module number. */
ERROR_ARGUS_UNKNOWN_MODULE = -199,
@@ -235,24 +247,22 @@ enum Status {
ERROR_ARGUS_UNKNOWN_LASER = -197,
+ /*! 191: AFBR-S50 Status (internal): The device is currently busy with testing the
+ * SPI connection to the device. */
+ STATUS_ARGUS_BUSY_TEST = 191,
- /*! 193: AFBR-S50 Status (internal): The device is currently busy with updating the
- * configuration (i.e. with writing register values). */
- STATUS_ARGUS_BUSY_CFG_UPDATE = 193,
-
- /*! 194: AFBR-S50 Status (internal): The device is currently busy with updating the
- * calibration data (i.e. writing to register values). */
- STATUS_ARGUS_BUSY_CAL_UPDATE = 194,
+ /*! 192: AFBR-S50 Status (internal): The device is currently busy with updating the
+ * settings parameter (i.e. with writing register values). */
+ STATUS_ARGUS_BUSY_UPDATE = 192,
/*! 195: AFBR-S50 Status (internal): The device is currently executing a calibration
- * sequence. */
+ * sequence. */
STATUS_ARGUS_BUSY_CAL_SEQ = 195,
/*! 196: AFBR-S50 Status (internal): The device is currently executing a measurement
* cycle. */
STATUS_ARGUS_BUSY_MEAS = 196,
-
/*! 100: AFBR-S50 Status (internal): The ASIC is initializing a new measurement, i.e.
* a register value is written that starts an integration cycle on the ASIC. */
STATUS_ARGUS_STARTING = 100,
@@ -260,9 +270,10 @@ enum Status {
/*! 103: AFBR-S50 Status (internal): The ASIC is performing an integration cycle. */
STATUS_ARGUS_ACTIVE = 103,
-
-
};
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_STATUS_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_version.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_version.h
index ea16342c84..a1a2d878ac 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_version.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_version.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file contains the current API version number.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file contains the current API version number.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,16 +36,19 @@
#ifndef ARGUS_VERSION_H
#define ARGUS_VERSION_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup version API Version
- * @ingroup argusapi
+ * @defgroup argus_version API Version
+ * @ingroup argus_api
*
- * @brief API and library core version number
+ * @brief API and library core version number
*
- * @details Contains the AFBR-S50 API and Library Core Version Number.
+ * @details Contains the AFBR-S50 API and Library Core Version Number.
*
- * @addtogroup version
+ * @addtogroup argus_version
* @{
*****************************************************************************/
@@ -53,13 +56,13 @@
#define ARGUS_API_VERSION_MAJOR 1
/*! Minor version number of the AFBR-S50 API. */
-#define ARGUS_API_VERSION_MINOR 3
+#define ARGUS_API_VERSION_MINOR 4
/*! Bugfix version number of the AFBR-S50 API. */
-#define ARGUS_API_VERSION_BUGFIX 5
+#define ARGUS_API_VERSION_BUGFIX 4
-/*! Build version nunber of the AFBR-S50 API. */
-#define ARGUS_API_VERSION_BUILD "20210812171515"
+/*! Build version number of the AFBR-S50 API. */
+#define ARGUS_API_VERSION_BUILD "20230327150535"
/*****************************************************************************/
@@ -73,4 +76,7 @@
(ARGUS_API_VERSION_BUGFIX))
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_VERSION_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_xtalk.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_xtalk.h
index 5613706267..6f3d40b49a 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_xtalk.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/api/argus_xtalk.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 hardware API.
- * @details Defines the generic device calibration API.
+ * @brief This file is part of the AFBR-S50 hardware API.
+ * @details Defines the generic device calibration API.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,44 +36,71 @@
#ifndef ARGUS_XTALK_H
#define ARGUS_XTALK_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @addtogroup arguscal
+ * @addtogroup argus_cal
* @{
*****************************************************************************/
-#include "api/argus_def.h"
+#include "argus_def.h"
+#include "argus_dfm.h"
/*!***************************************************************************
- * @brief Pixel Crosstalk Compensation Vector.
- * @details Contains calibration data (per pixel) that belongs to the
- * RX-TX-Crosstalk compensation feature.
+ * @brief Pixel Crosstalk Compensation Vector.
+ * @details Contains calibration data (per pixel) that belongs to the
+ * RX-TX-Crosstalk compensation feature.
+ * The crosstalk vector consists of a Sine and Cosine component in LSB.
*****************************************************************************/
-
-/*! Pixel Crosstalk Vector */
-typedef struct {
+typedef struct xtalk_t {
/*! Crosstalk Vector - Sine component.
+ * Units: LSB
* Special Value: Q11_4_MIN == not available */
q11_4_t dS;
/*! Crosstalk Vector - Cosine component.
+ * Units: LSB
* Special Value: Q11_4_MIN == not available */
q11_4_t dC;
} xtalk_t;
/*!***************************************************************************
- * @brief Pixel-To-Pixel Crosstalk Compensation Parameters.
- * @details Contains calibration data that belongs to the pixel-to-pixel
- * crosstalk compensation feature.
+ * @brief Pixel Crosstalk Vector Table.
+ * @details Contains crosstalk vector values for all 32 active pixels,
+ * separated for A/B-Frames.
*****************************************************************************/
-typedef struct {
+typedef struct argus_cal_xtalk_table_t {
+ union {
+ struct {
+ /*! The crosstalk vector table for A-Frames. */
+ xtalk_t FrameA[ARGUS_PIXELS_X][ARGUS_PIXELS_Y];
+
+ /*! The crosstalk vector table for B-Frames. */
+ xtalk_t FrameB[ARGUS_PIXELS_X][ARGUS_PIXELS_Y];
+ };
+
+ /*! The crosstalk vector table for A/B-Frames of all 32 pixels.*/
+ xtalk_t Table[ARGUS_DFM_FRAME_COUNT][ARGUS_PIXELS_X][ARGUS_PIXELS_Y];
+ };
+
+} argus_cal_xtalk_table_t;
+
+
+/*!***************************************************************************
+ * @brief Pixel-To-Pixel Crosstalk Compensation Parameters.
+ * @details Contains calibration data that belongs to the pixel-to-pixel
+ * crosstalk compensation feature.
+ *****************************************************************************/
+typedef struct argus_cal_p2pxtalk_t {
/*! Pixel-To-Pixel Compensation on/off. */
bool Enabled;
/*! The relative threshold determines when the compensation is active for
* each individual pixel. The value determines the ratio of the individual
- * pixel signal is with respect to the overall average signal. If the
+ * pixel signal with respect to the overall average signal. If the
* ratio is smaller than the value, the compensation is active. Absolute
* and relative conditions are connected with AND logic. */
uq0_8_t RelativeThreshold;
@@ -111,4 +138,7 @@ typedef struct {
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_XTALK_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/argus.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/argus.h
index dcea881d02..79cf0ede58 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/argus.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/argus.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file the main header of the AFBR-S50 API.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file the main header of the AFBR-S50 API.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,6 @@
#ifndef ARGUS_H
#define ARGUS_H
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -44,7 +43,6 @@ extern "C" {
#include "api/argus_api.h"
#ifdef __cplusplus
-}
+} // extern "C"
#endif
-
#endif /* ARGUS_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_irq.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_irq.h
index 3eb7d2cfd4..d55097cd8a 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_irq.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_irq.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file provides an interface for enabling/disabling interrupts.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides an interface for enabling/disabling interrupts.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,96 +36,94 @@
#ifndef ARGUS_IRQ_H
#define ARGUS_IRQ_H
-
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
- * @defgroup argus_irq IRQ: Global Interrupt Control Layer
- * @ingroup argus_platform
+ * @defgroup argus_irq IRQ: Global Interrupt Control Layer
+ * @ingroup argus_hal
*
- * @brief Global Interrupt Control Layer
+ * @brief Global Interrupt Control Layer
*
- * @details This module provides functionality to globally enable/disable
- * interrupts in a nested way.
+ * @details This module provides functionality to globally enable/disable
+ * interrupts in a nested way.
*
- * Here is a simple example implementation using the CMSIS functions
- * "__enable_irq()" and "__disable_irq()". An integer counter is
- * used to achieve nested interrupt disabling:
+ * Here is a simple example implementation using the CMSIS functions
+ * "__enable_irq()" and "__disable_irq()". An integer counter is
+ * used to achieve nested interrupt disabling:
*
- * @code
+ * @code
*
- * // Global lock level counter value.
- * static volatile int g_irq_lock_ct;
+ * // Global lock level counter value.
+ * static volatile int g_irq_lock_ct;
*
- * // Global unlock all interrupts using CMSIS function "__enable_irq()".
- * void IRQ_UNLOCK(void)
- * {
- * assert(g_irq_lock_ct > 0);
- * if (--g_irq_lock_ct <= 0)
- * {
- * g_irq_lock_ct = 0;
- * __enable_irq();
- * }
- * }
+ * // Global unlock all interrupts using CMSIS function "__enable_irq()".
+ * void IRQ_UNLOCK(void)
+ * {
+ * assert(g_irq_lock_ct > 0);
+ * if (--g_irq_lock_ct <= 0)
+ * {
+ * g_irq_lock_ct = 0;
+ * __enable_irq();
+ * }
+ * }
*
- * // Global lock all interrupts using CMSIS function "__disable_irq()".
- * void IRQ_LOCK(void)
- * {
- * __disable_irq();
- * g_irq_lock_ct++;
- * }
+ * // Global lock all interrupts using CMSIS function "__disable_irq()".
+ * void IRQ_LOCK(void)
+ * {
+ * __disable_irq();
+ * g_irq_lock_ct++;
+ * }
*
- * @endcode
+ * @endcode
*
- * @note The IRQ locking mechanism is used to create atomic sections
- * (within the scope of the AFBR-S50 API) that are very few processor
- * instruction only. It does NOT lock interrupts for considerable
- * amounts of time.
+ * @note The IRQ locking mechanism is used to create atomic sections
+ * (within the scope of the AFBR-S50 API) that are very few processor
+ * instruction only. It does NOT lock interrupts for considerable
+ * amounts of time.
*
- * @note The IRQ_LOCK might get called multiple times. Therefore, the
- * API expects that the IRQ_UNLOCK must be called as many times as
- * the IRQ_LOCK was called before the interrupts are enabled.
+ * @note The IRQ_LOCK might get called multiple times. Therefore, the
+ * API expects that the IRQ_UNLOCK must be called as many times as
+ * the IRQ_LOCK was called before the interrupts are enabled.
*
- * @note The interrupts utilized by the AFBR-S50 API can be interrupted
- * by other, higher prioritized interrupts, e.g. some system
- * critical interrupts. In this case, the IRQ_LOCK/IRQ_UNLOCK
- * mechanism can be implemented such that only the interrupts
- * required for the AFBR-S50 API are locked. The above example is
- * dedicated to a ARM Corex-M0 architecture, where interrupts
- * can only disabled at a global scope. Other architectures like
- * ARM Cortex-M4 allow selective disabling of interrupts.
+ * @note The interrupts utilized by the AFBR-S50 API can be interrupted
+ * by other, higher prioritized interrupts, e.g. some system
+ * critical interrupts. In this case, the IRQ_LOCK/IRQ_UNLOCK
+ * mechanism can be implemented such that only the interrupts
+ * required for the AFBR-S50 API are locked. The above example is
+ * dedicated to a ARM Corex-M0 architecture, where interrupts
+ * can only disabled at a global scope. Other architectures like
+ * ARM Cortex-M4 allow selective disabling of interrupts.
*
- * @addtogroup argus_irq
+ * @addtogroup argus_irq
* @{
*****************************************************************************/
/*!***************************************************************************
- * @brief Enable IRQ Interrupts
+ * @brief Enable IRQ Interrupts
*
- * @details Enables IRQ interrupts and enters an atomic or critical section.
+ * @details Enables IRQ interrupts and enters an atomic or critical section.
*
- * @note The IRQ_LOCK might get called multiple times. Therefore, the
- * API expects that the IRQ_UNLOCK must be called as many times as
- * the IRQ_LOCK was called before the interrupts are enabled.
+ * @note The IRQ_LOCK might get called multiple times. Therefore, the
+ * API expects that the IRQ_UNLOCK must be called as many times as
+ * the IRQ_LOCK was called before the interrupts are enabled.
*****************************************************************************/
void IRQ_UNLOCK(void);
/*!***************************************************************************
- * @brief Disable IRQ Interrupts
+ * @brief Disable IRQ Interrupts
*
- * @details Disables IRQ interrupts and leaves the atomic or critical section.
+ * @details Disables IRQ interrupts and leaves the atomic or critical section.
*
- * @note The IRQ_LOCK might get called multiple times. Therefore, the
- * API expects that the IRQ_UNLOCK must be called as many times as
- * the IRQ_LOCK was called before the interrupts are enabled.
+ * @note The IRQ_LOCK might get called multiple times. Therefore, the
+ * API expects that the IRQ_UNLOCK must be called as many times as
+ * the IRQ_LOCK was called before the interrupts are enabled.
*****************************************************************************/
void IRQ_LOCK(void);
-#ifdef __cplusplus
-}
-#endif
-
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif // ARGUS_IRQ_H
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_nvm.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_nvm.h
index 69939b7759..b8150f0281 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_nvm.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_nvm.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file provides an interface for the optional non-volatile memory.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides an interface for the optional non-volatile memory.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,99 +36,113 @@
#ifndef ARGUS_NVM_H
#define ARGUS_NVM_H
-
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
- * @defgroup argus_nvm NVM: Non-Volatile Memory Layer
- * @ingroup argus_platform
+ * @defgroup argus_nvm NVM: Non-Volatile Memory Layer
+ * @ingroup argus_hal
*
- * @brief Non-Volatile Memory Layer
+ * @brief Non-Volatile Memory Layer
*
- * @details This module provides functionality to access the non-volatile
- * memory (e.g. flash) on the underlying platform.
+ * @details This module provides functionality to access the non-volatile
+ * memory (e.g. flash) on the underlying platform.
*
- * This module is optional and only required if calibration data
- * needs to be stored within the API.
+ * This module is optional and only required if calibration data
+ * needs to be stored within the API.
*
- * @note The implementation of this module is optional for the correct
- * execution of the API. If not implemented, a weak implementation
- * within the API will be used that disables the NVM feature.
+ * @note The implementation of this module is optional for the correct
+ * execution of the API. If not implemented, a weak implementation
+ * within the API will be used that disables the NVM feature.
*
- * @addtogroup argus_nvm
+ * @addtogroup argus_nvm
* @{
*****************************************************************************/
-#include "argus.h"
+#include "api/argus_def.h"
+
+/*! The NVM block size in the non-volatile memory. */
+#define ARGUS_NVM_BLOCK_SIZE 0x300 // 768 bytes
/*!***************************************************************************
- * @brief Initializes the non-volatile memory unit and reserves a chunk of memory.
+ * @brief Write a block of data to the non-volatile memory.
*
- * @details The function is called upon API initialization sequence. If available,
- * the non-volatile memory module reserves a chunk of memory with the
- * provides number of bytes (size) and returns with #STATUS_OK.
+ * @details The function is called whenever the API wants to write data into
+ * non-volatile memory, e.g. flash. Later, the API reads the written
+ * data via the #NVM_ReadBlock function.
*
- * If not implemented, the function should return #ERROR_NOT_IMPLEMENTED
- * in oder to inform the API to not use the NVM module.
+ * The data shall be written to a specified memory block that is
+ * uniquely dedicated to each individual device. The /p id parameter
+ * is passed to the function that identifies the device. The /p id
+ * is composed of the device ID and module type, i.e. it is unique
+ * among all devices. If only a single device is used anyway, the
+ * /p id parameter can be ignored.
*
- * After initialization, the API calls the #NVM_Write and #NVM_Read
- * methods to write within the reserved chunk of memory.
+ * If no NVM module is available, the function can return with error
+ * #ERROR_NOT_IMPLEMENTED and the API ignores the NVM.
*
- * @note The implementation of this function is optional for the correct
- * execution of the API. If not implemented, a weak implementation
- * within the API will be used that disables the NVM feature.
+ * If write fails, e.g. due to lack of memory, a negative status
+ * must be returned, e.g. #ERROR_NVM_OUT_OF_RANGE.
*
- * @param size The required size of NVM to store all parameters.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * The block size is fixed for a single device. The actual block size
+ * is defined with #ARGUS_NVM_BLOCK_SIZE.
+ *
+ * @note The implementation of this function is optional for the correct
+ * execution of the API. If not implemented, a weak implementation
+ * within the API will be used that disables the NVM feature.
+ *
+ * @param id The 32-bit ID number to identify the corresponding memory block.
+ * @param block_size The number of bytes to be written. Note that this value
+ * is fixed, i.e. the API always writes the same data size.
+ * The size is defined here: #ARGUS_NVM_BLOCK_SIZE.
+ * @param buf The pointer to the data buffer of size /p block_size that needs
+ * to be written to the NVM.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t NVM_Init(uint32_t size);
+status_t NVM_WriteBlock(uint32_t id, uint32_t block_size, uint8_t const *buf);
/*!***************************************************************************
- * @brief Write a block of data to the non-volatile memory.
+ * @brief Reads a block of data from the non-volatile memory.
*
- * @details The function is called whenever the API wants to write data into
- * the previously reserved (#NVM_Init) memory block. The data shall
- * be written at a given offset and with a given size.
+ * @details The function is called whenever the API wants to read data from
+ * non-volatile memory, e.g. flash. The data will be previously
+ * stored using the #NVM_WriteBlock function. Otherwise, the function
+ * must return a corresponding error code, namely #ERROR_NVM_EMPTY.
*
- * If no NVM module is available, the function can return with error
- * #ERROR_NOT_IMPLEMENTED.
+ * The data shall be read from a specified memory block that is
+ * uniquely dedicated to each individual device. The /p id parameter
+ * is passed to the function that identifies the device. The /p id
+ * is composed of the device ID and module type, i.e. it is unique
+ * among all devices. If only a single device is used anyway, the
+ * /p id parameter can be ignored.
*
- * @note The implementation of this function is optional for the correct
- * execution of the API. If not implemented, a weak implementation
- * within the API will be used that disables the NVM feature.
+ * If no NVM module is available, the function can return with error
+ * #ERROR_NOT_IMPLEMENTED and the API ignores the NVM.
*
- * @param offset The index offset where the first byte needs to be written.
- * @param size The number of bytes to be written.
- * @param buf The pointer to the data buffer with the data to be written.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * If read fails, e.g. if data has not been written previously,
+ * a negative status must be returned, e.g. #ERROR_NVM_EMPTY if no
+ * data has been written yet or any other negative error else-wise.
+ *
+ * The block size is fixed for a single device. The actual block size
+ * is defined with #ARGUS_NVM_BLOCK_SIZE.
+ *
+ * @note The implementation of this function is optional for the correct
+ * execution of the API. If not implemented, a weak implementation
+ * within the API will be used that disables the NVM feature.
+ *
+ * @param id The 32-bit ID number to identify the corresponding memory block.
+ * @param block_size The number of bytes to be read. Note that this value
+ * is fixed, i.e. the API always reads the same data size.
+ * The size is defined here: #ARGUS_NVM_BLOCK_SIZE.
+ * @param buf The pointer to the data buffer of size /p block_size to copy
+ * the data to.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t NVM_Write(uint32_t offset, uint32_t size, uint8_t const *buf);
-
-/*!***************************************************************************
- * @brief Reads a block of data from the non-volatile memory.
- *
- * @details The function is called whenever the API wants to read data from
- * the previously reserved (#NVM_Init) memory block. The data shall
- * be read at a given offset and with a given size.
- *
- * If no NVM module is available, the function can return with error
- * #ERROR_NOT_IMPLEMENTED.
- *
- * @note The implementation of this function is optional for the correct
- * execution of the API. If not implemented, a weak implementation
- * within the API will be used that disables the NVM feature.
- *
- * @param offset The index offset where the first byte needs to be read.
- * @param size The number of bytes to be read.
- * @param buf The pointer to the data buffer to copy the data to.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
- *****************************************************************************/
-status_t NVM_Read(uint32_t offset, uint32_t size, uint8_t *buf);
-#ifdef __cplusplus
-}
-#endif
+status_t NVM_ReadBlock(uint32_t id, uint32_t block_size, uint8_t *buf);
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif // ARGUS_NVM_H
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_print.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_print.h
index 0ca49f858c..9a76dbe485 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_print.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_print.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file provides an interface for the optional debug module.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides an interface for the optional debug module.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,48 +36,55 @@
#ifndef ARGUS_PRINT_H
#define ARGUS_PRINT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup argus_log Debug: Logging Interface
- * @ingroup argus_platform
+ * @defgroup argus_log Debug: Logging Interface
+ * @ingroup argus_hal
*
- * @brief Logging interface for the AFBR-S50 API.
+ * @brief Logging interface for the AFBR-S50 API.
*
- * @details This interface provides logging utility functions.
- * Defines a printf-like function that is used to print error and
- * log messages.
+ * @details This interface provides logging utility functions.
+ * Defines a printf-like function that is used to print error and
+ * log messages.
*
- * @addtogroup argus_log
+ * @addtogroup argus_log
* @{
*****************************************************************************/
#include "api/argus_def.h"
/*!***************************************************************************
- * @brief A printf-like function to print formatted data to an debugging interface.
+ * @brief A printf-like function to print formatted data to an debugging interface.
*
* @details Writes the C string pointed by fmt_t to an output. If format
- * includes format specifiers (subsequences beginning with %), the
- * additional arguments following fmt_t are formatted and inserted in
- * the resulting string replacing their respective specifiers.
+ * includes format specifiers (subsequences beginning with %), the
+ * additional arguments following fmt_t are formatted and inserted in
+ * the resulting string replacing their respective specifiers.
*
- * To enable the print functionality, an implementation of the function
- * must be provided that maps the output to an interface like UART or
- * a debugging console, e.g. by forwarding to standard printf() method.
+ * To enable the print functionality, an implementation of the function
+ * must be provided that maps the output to an interface like UART or
+ * a debugging console, e.g. by forwarding to standard printf() method.
*
- * @note The implementation of this function is optional for the correct
- * execution of the API. If not implemented, a weak implementation
- * within the API will be used that does nothing. This will improve
- * the performance but no error messages are logged.
+ * @note The implementation of this function is optional for the correct
+ * execution of the API. If not implemented, a weak implementation
+ * within the API will be used that does nothing. This will improve
+ * the performance but no error messages are logged.
*
- * @note The naming is different from the standard printf() on purpose to
- * prevent builtin compiler optimizations.
+ * @note The naming is different from the standard printf() on purpose to
+ * prevent builtin compiler optimizations.
*
- * @param fmt_s The usual print() format string.
- * @param ... The usual print() parameters. *
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param fmt_s The usual print() format string.
+ * @param ... The usual print() parameters.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t print(const char *fmt_s, ...);
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_PRINT_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_s2pi.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_s2pi.h
index 4b8f5331b5..8d912afc22 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_s2pi.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_s2pi.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file provides an interface for the required S2PI module.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides an interface for the required S2PI module.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,95 +36,94 @@
#ifndef ARGUS_S2PI_H
#define ARGUS_S2PI_H
-
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
- * @defgroup argus_s2pi S2PI: Serial Peripheral Interface
- * @ingroup argus_platform
+ * @defgroup argus_s2pi S2PI: Serial Peripheral Interface
+ * @ingroup argus_hal
*
- * @brief S2PI: SPI incl. GPIO Hardware Layer Module
+ * @brief S2PI: SPI incl. GPIO Hardware Layer Module
*
- * @details The S2PI module consists of a standard SPI interface plus a
- * single GPIO interrupt line. Furthermore, the SPI pins are
- * accessible via GPIO control to allow a software emulation of
- * additional protocols using the same pins.
+ * @details The S2PI module consists of a standard SPI interface plus a
+ * single GPIO interrupt line. Furthermore, the SPI pins are
+ * accessible via GPIO control to allow a software emulation of
+ * additional protocols using the same pins.
*
- * **SPI interface:**
+ * **SPI interface:**
*
- * The SPI interface is based around a single functionality:
+ * The SPI interface is based around a single functionality:
*
- * #S2PI_TransferFrame. This function transfers a specified number
- * of bytes via the interfaces MOSI line and simultaneously reads
- * the incoming data on the MOSI line. The read can also be skipped.
- * The transfer happen asynchronously, e.g. via a DMA request. After
- * finishing the transfer, the provided callback is invoked with
- * the status of the transfer and the provided abstract parameter.
- * Furthermore, the functions receives a slave parameter that can
- * be used to connect multiple slaves, each with its individual
- * chip select line.
+ * #S2PI_TransferFrame. This function transfers a specified number
+ * of bytes via the interfaces MOSI line and simultaneously reads
+ * the incoming data on the MOSI line. The read can also be skipped.
+ * The transfer happen asynchronously, e.g. via a DMA request. After
+ * finishing the transfer, the provided callback is invoked with
+ * the status of the transfer and the provided abstract parameter.
+ * Furthermore, the functions receives a slave parameter that can
+ * be used to connect multiple slaves, each with its individual
+ * chip select line.
*
- * The interface also provides functionality to change the SPI
- * baud rate. An additional abort method is used to cancel the
- * ongoing transfer.
+ * The interface also provides functionality to change the SPI
+ * baud rate. An additional abort method is used to cancel the
+ * ongoing transfer.
*
- * **GPIO interface:**
+ * **GPIO interface:**
*
- * The GPIO part of the S2PI interface has two distinct concerns:
+ * The GPIO part of the S2PI interface has two distinct concerns:
*
- * First, the GPIO interface handles the measurement finished interrupt
- * from the device. When the device invokes the interrupt, it pulls
- * the interrupt line to low. Thus the interrupt must trigger when
- * a transition from high to low occurs on the interrupt line.
+ * First, the GPIO interface handles the measurement finished interrupt
+ * from the device. When the device invokes the interrupt, it pulls
+ * the interrupt line to low. Thus the interrupt must trigger when
+ * a transition from high to low occurs on the interrupt line.
*
- * The module simply invokes a callback when this interrupt occurs.
- * The #S2PI_SetIrqCallback method is used to install the callback
- * for a specified slave. Each slave will have its own interrupt
- * line. An additional callback parameter can be set that would be
- * passed to the callback function.
+ * The module simply invokes a callback when this interrupt occurs.
+ * The #S2PI_SetIrqCallback method is used to install the callback
+ * for a specified slave. Each slave will have its own interrupt
+ * line. An additional callback parameter can be set that would be
+ * passed to the callback function.
*
- * In addition to the interrupt, all SPI pins need to be accessible
- * as GPIO pins through this interface. This is required to read
- * the EEPROM memory on the device hat is connected to the SPI
- * pins but requires a different protocol that is not compatible
- * to any standard SPI interface. Therefore, the interface provides
- * the possibility to switch to GPIO control mode that allows to
- * emulate the EEPROM protocol via software bit banging.
+ * In addition to the interrupt, all SPI pins need to be accessible
+ * as GPIO pins through this interface. This is required to read
+ * the EEPROM memory on the device hat is connected to the SPI
+ * pins but requires a different protocol that is not compatible
+ * to any standard SPI interface. Therefore, the interface provides
+ * the possibility to switch to GPIO control mode that allows to
+ * emulate the EEPROM protocol via software bit banging.
*
- * Two methods are provided to switch forth and back between SPI
- * and GPIO control. In GPIO mode, several functions are used to
- * read and write the individual GPIO pins.
+ * Two methods are provided to switch forth and back between SPI
+ * and GPIO control. In GPIO mode, several functions are used to
+ * read and write the individual GPIO pins.
*
- * Note that the GPIO mode is only required to readout the EEPROM
- * upon initialization of the device, i.e. during execution of the
- * #Argus_Init or #Argus_Reinit methods. The GPIO mode is not used
- * during measurements.
+ * Note that the GPIO mode is only required to readout the EEPROM
+ * upon initialization of the device, i.e. during execution of the
+ * #Argus_Init or #Argus_Reinit methods. The GPIO mode is not used
+ * during measurements.
*
*
- * @addtogroup argus_s2pi
+ * @addtogroup argus_s2pi
* @{
*****************************************************************************/
#include "api/argus_def.h"
/*!***************************************************************************
- * @brief S2PI layer callback function type for the SPI transfer completed event.
+ * @brief S2PI layer callback function type for the SPI transfer completed event.
*
- * @param status The \link #status_t status\endlink of the completed
+ * @param status The \link #status_t status\endlink of the completed
* transfer (#STATUS_OK on success).
*
- * @param param The provided (optional, can be null) callback parameter.
+ * @param param The provided (optional, can be null) callback parameter.
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
typedef status_t (*s2pi_callback_t)(status_t status, void *param);
/*!***************************************************************************
- * @brief S2PI layer callback function type for the GPIO interrupt event.
+ * @brief S2PI layer callback function type for the GPIO interrupt event.
*
- * @param param The provided (optional, can be null) callback parameter.
+ * @param param The provided (optional, can be null) callback parameter.
*****************************************************************************/
typedef void (*s2pi_irq_callback_t)(void *param);
@@ -132,8 +131,8 @@ typedef void (*s2pi_irq_callback_t)(void *param);
* can be used to identify the slave within the SPI module. */
typedef int32_t s2pi_slave_t;
-/*! The enumeration of S2PI pins. */
-typedef enum {
+/*! The enumeration of S2PI pins. */
+typedef enum s2pi_pin_t {
/*! The SPI clock pin. */
S2PI_CLK,
@@ -153,64 +152,141 @@ typedef enum {
/*!***************************************************************************
- * @brief Returns the status of the SPI module.
+ * @brief Returns the status of the SPI module.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_IDLE: No SPI transfer or GPIO access is ongoing.
- * - #STATUS_BUSY: An SPI transfer is in progress.
- * - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode.
+ * @param slave The specified S2PI slave. Note that the slave information is
+ * only required if multiple SPI instances are used in order to
+ * map to the correct SPI instance.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_IDLE: No SPI transfer or GPIO access is ongoing.
+ * - #STATUS_BUSY: An SPI transfer is in progress.
+ * - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode.
*****************************************************************************/
-status_t S2PI_GetStatus(void);
+status_t S2PI_GetStatus(s2pi_slave_t slave);
/*!***************************************************************************
- * @brief Transfers a single SPI frame asynchronously.
+ * @brief Tries to grab the SPI interface mutex for the next transfer.
+ *
+ * @details This mutex prevents new asynchronous SPI requests to interfere
+ * with transfers already in progress for this interface.
+ *
+ * Note that this is only required if multiple device are connected to
+ * a single SPI interface. If only operating a single device per SPI,
+ * the function can simply always return #STATUS_OK.
+ *
+ * There must be a dedicated mutex object per SPI interface if
+ * multiple SPI interfaces are used.
+ *
+ * The mutex will be released in the #S2PI_ReleaseMutex function.
+ * See #S2PI_ReleaseMutex for additional information.
+ *
+ * Here is a simple example implementation for the multiple devices on
+ * a single SPI interface case. Note that the SpiMutexBlocked must be
+ * defined per SPI interface if multiple SPI interfaces are used.
+ *
+ * @code
+ * static volatile bool SpiMutexBlocked = false;
+ * status_t S2PI_TryGetMutex(s2pi_slave_t slave)
+ * {
+ * (void) slave; // not used in this implementation as all
+ * // SPI slaves are on the same SPI interface
+ *
+ * status_t status = STATUS_BUSY;
+ * IRQ_LOCK();
+ * if (!SpiMutexBlocked)
+ * {
+ * SpiMutexBlocked = true;
+ * status = STATUS_OK;
+ * }
+ * IRQ_UNLOCK();
+ * return status;
+ * }
+ * void S2PI_ReleaseMutex(s2pi_slave_t slave)
+ * {
+ * (void) slave; // not used in this implementation
+ * SpiMutexBlocked = false;
+ * }
+ * @endcode
+ *
+ * @param slave The specified S2PI slave. Note that the slave information is
+ * only required if multiple SPI instances are used in order to
+ * map to the correct SPI instance.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK: the SPI interface was successfully reserved for the caller
+ * - #STATUS_BUSY: another transfer is ongoing, the caller must not access the bus
+ *****************************************************************************/
+status_t S2PI_TryGetMutex(s2pi_slave_t slave);
+
+/*!***************************************************************************
+ * @brief Releases the SPI interface mutex.
+ *
+ * @details Once the mutex is captured, only a single thread (the one that
+ * captured it) will call this release function, so there is no
+ * need for any test or thread safe barriers. Also there is no
+ * side effect of calling this function when the Mutex is not
+ * taken so this function can be really simple and doesn't need
+ * to return anything.
+ *
+ * See #S2PI_TryGetMutex on more information and an example
+ * implementation for the single SPI interface case.
+ *
+ * @param slave The specified S2PI slave. Note that the slave information is
+ * only required if multiple SPI instances are used in order to
+ * map to the correct SPI instance.
+ *****************************************************************************/
+void S2PI_ReleaseMutex(s2pi_slave_t slave);
+
+/*!***************************************************************************
+ * @brief Transfers a single SPI frame asynchronously.
*
* @details Transfers a single SPI frame in asynchronous manner. The Tx data
- * buffer is written to the device via the MOSI line.
- * Optionally, the data on the MISO line is written to the provided
- * Rx data buffer. If null, the read data is dismissed. Note that
- * Rx and Tx buffer can be identical. I.e. the same buffer is used
- * for writing and reading data. First, a byte is transmitted and
- * the received byte overwrites the previously send value.
+ * buffer is written to the device via the MOSI line.
+ * Optionally, the data on the MISO line is written to the provided
+ * Rx data buffer. If null, the read data is dismissed. Note that
+ * Rx and Tx buffer can be identical. I.e. the same buffer is used
+ * for writing and reading data. First, a byte is transmitted and
+ * the received byte overwrites the previously send value.
*
- * The transfer of a single frame requires to not toggle the chip
- * select line to high in between the data frame. The maximum
- * number of bytes transfered in a single SPI transfer is given by
- * the data value register of the device, which is 396 data bytes
- * plus a single address byte: 397 bytes.
+ * The transfer of a single frame requires to not toggle the chip
+ * select line to high in between the data frame. The maximum
+ * number of bytes transferred in a single SPI transfer is given by
+ * the data value register of the device, which is 396 data bytes
+ * plus a single address byte: 397 bytes.
*
- * An optional callback is invoked when the asynchronous transfer
- * is finished. If the \p callback parameter is a null pointer,
- * no callback is provided. Note that the provided buffer must not
- * change while the transfer is ongoing.
+ * An optional callback is invoked when the asynchronous transfer
+ * is finished. If the \p callback parameter is a null pointer,
+ * no callback is provided. Note that the provided buffer must not
+ * change while the transfer is ongoing.
*
- * Use the slave parameter to determine the corresponding slave via the
- * given chip select line.
+ * Use the slave parameter to determine the corresponding slave via the
+ * given chip select line.
*
- * Usually, two distinct interrupts are required to handle the RX and
- * TX ready events. The callback must be invoked from whichever
- * interrupt comes after the SPI transfer has been finished. Note
- * that new SPI transfers are invoked from within the callback function
- * (i.e. from within the interrupt service routine of same priority).
+ * Usually, two distinct interrupts are required to handle the RX and
+ * TX ready events. The callback must be invoked from whichever
+ * interrupt comes after the SPI transfer has been finished. Note
+ * that new SPI transfers are invoked from within the callback function
+ * (i.e. from within the interrupt service routine of same priority).
*
- * @param slave The specified S2PI slave.
- * @param txData The 8-bit values to write to the SPI bus MOSI line.
- * @param rxData The 8-bit values received from the SPI bus MISO line
+ * @param slave The specified S2PI slave.
+ * @param txData The 8-bit values to write to the SPI bus MOSI line.
+ * @param rxData The 8-bit values received from the SPI bus MISO line
* (pass a null pointer if the data don't need to be read).
- * @param frameSize The number of 8-bit values to be sent/received.
- * @param callback A callback function to be invoked when the transfer is
- * finished. Pass a null pointer if no callback is required.
- * @param callbackData A pointer to a state that will be passed to the
+ * @param frameSize The number of 8-bit values to be sent/received.
+ * @param callback A callback function to be invoked when the transfer is
+ * finished. Pass a null pointer if no callback is required.
+ * @param callbackData A pointer to a state that will be passed to the
* callback. Pass a null pointer if not used.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK: Successfully invoked the transfer.
- * - #ERROR_INVALID_ARGUMENT: An invalid parameter has been passed.
- * - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
- * - #STATUS_BUSY: An SPI transfer is already in progress. The
- * transfer was not started.
- * - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode. The transfer
- * was not started.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK: Successfully invoked the transfer.
+ * - #ERROR_INVALID_ARGUMENT: An invalid parameter has been passed.
+ * - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
+ * - #STATUS_BUSY: An SPI transfer is already in progress. The
+ * transfer was not started.
+ * - #STATUS_S2PI_GPIO_MODE: The module is in GPIO mode. The transfer
+ * was not started.
*****************************************************************************/
status_t S2PI_TransferFrame(s2pi_slave_t slave,
uint8_t const *txData,
@@ -220,136 +296,158 @@ status_t S2PI_TransferFrame(s2pi_slave_t slave,
void *callbackData);
/*!***************************************************************************
- * @brief Terminates a currently ongoing asynchronous SPI transfer.
+ * @brief Terminates a currently ongoing asynchronous SPI transfer.
*
- * @details When a callback is set for the current ongoing activity, it is
- * invoked with the #ERROR_ABORTED error byte.
+ * @details When a callback is set for the current ongoing activity, it is
+ * invoked with the #ERROR_ABORTED error byte.
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param slave The specified S2PI slave. Note that the slave information is
+ * only required if multiple SPI instances are used in order to
+ * map to the correct SPI instance.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t S2PI_Abort(void);
+status_t S2PI_Abort(s2pi_slave_t slave);
/*!***************************************************************************
- * @brief Set a callback for the GPIO IRQ for a specified S2PI slave.
+ * @brief Set a callback for the GPIO IRQ for a specified S2PI slave.
*
- * @param slave The specified S2PI slave.
- * @param callback A callback function to be invoked when the specified
- * S2PI slave IRQ occurs. Pass a null pointer to disable
- * the callback.
- * @param callbackData A pointer to a state that will be passed to the
+ * @param slave The specified S2PI slave.
+ * @param callback A callback function to be invoked when the specified
+ * S2PI slave IRQ occurs. Pass a null pointer to disable
+ * the callback.
+ * @param callbackData A pointer to a state that will be passed to the
* callback. Pass a null pointer if not used.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK: Successfully installation of the callback.
- * - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK: Successfully installation of the callback.
+ * - #ERROR_S2PI_INVALID_SLAVE: A wrong slave identifier is provided.
*****************************************************************************/
status_t S2PI_SetIrqCallback(s2pi_slave_t slave,
s2pi_irq_callback_t callback,
void *callbackData);
/*!***************************************************************************
- * @brief Reads the current status of the IRQ pin.
+ * @brief Reads the current interrupt pending status of the IRQ pin.
*
* @details In order to keep a low priority for GPIO IRQs, the state of the
- * IRQ pin must be read in order to reliable check for chip timeouts.
+ * IRQ pin must be read in order to reliable check for chip timeouts.
*
- * The execution of the interrupt service routine for the data-ready
- * interrupt from the corresponding GPIO pin might be delayed due to
- * priority issues. The delayed execution might disable the timeout
- * for the eye-safety checker too late causing false error messages.
- * In order to overcome the issue, the state of the IRQ GPIO input
- * pin is read before raising a timeout error in order to check if
- * the device has already finished but the IRQ is still pending to be
- * executed!
+ * The execution of the interrupt service routine for the data-ready
+ * interrupt from the corresponding GPIO pin might be delayed due to
+ * priority issues. The delayed execution might disable the timeout
+ * for the eye-safety checker too late causing false error messages.
+ * In order to overcome the issue, the interrupt state of the IRQ
+ * GPIO input pin is read before raising a timeout error in order to
+ * check if the device has already finished and the IRQ is still
+ * pending to be executed!
+ *
+ * Note: an easy implementation is to simply return the state of the
+ * IRQ line, i.e. 0 if there is a low input state and 1 if there is
+ * a high input state on the IRQ input pin. However, this
+ * implementation is not fully reliable since the GPIO interrupt
+ * (triggered on the falling edge) might be missed and the callback
+ * is never invoked while the IRQ line is correctly asserted to low
+ * state by the device. In that case, the API is waiting forever
+ * until the callback is invoked which might never happen. Therefore,
+ * it is better if the implementation checks the state of the IRQ
+ * pending status register or even combines both variations.
- * @param slave The specified S2PI slave.
- * @return Returns 1U if the IRQ pin is high (IRQ not pending) and 0U if the
- * devices pulls the pin to low state (IRQ pending).
+ * @param slave The specified S2PI slave.
+ *
+ * @return Returns 1U if the IRQ is NOT pending (pin is in high state) and
+ * 0U if the IRQ is pending (pin is pulled to low state by the device).
*****************************************************************************/
uint32_t S2PI_ReadIrqPin(s2pi_slave_t slave);
/*!***************************************************************************
- * @brief Cycles the chip select line.
+ * @brief Cycles the chip select line.
*
* @details In order to cancel the integration on the ASIC, a fast toggling
- * of the chip select pin of the corresponding SPI slave is required.
- * Therefore, this function toggles the CS from high to low and back.
- * The SPI instance for the specified S2PI slave must be idle,
- * otherwise the status #STATUS_BUSY is returned.
+ * of the chip select pin of the corresponding SPI slave is required.
+ * Therefore, this function toggles the CS from high to low and back.
+ * The SPI instance for the specified S2PI slave must be idle,
+ * otherwise the status #STATUS_BUSY is returned.
*
- * @param slave The specified S2PI slave.
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param slave The specified S2PI slave.
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_CycleCsPin(s2pi_slave_t slave);
-
-
/*!*****************************************************************************
- * @brief Captures the S2PI pins for GPIO usage.
+ * @brief Captures the S2PI pins for GPIO usage.
*
- * @details The SPI is disabled (module status: #STATUS_S2PI_GPIO_MODE) and the
- * pins are configured for GPIO operation. The GPIO control must be
- * release with the #S2PI_ReleaseGpioControl function in order to
- * switch back to ordinary SPI functionality.
+ * @details The SPI is disabled (module status: #STATUS_S2PI_GPIO_MODE) and the
+ * pins are configured for GPIO operation. The GPIO control must be
+ * release with the #S2PI_ReleaseGpioControl function in order to
+ * switch back to ordinary SPI functionality.
*
- * @note This function is only called during device initialization!
+ * @note This function is only called during device initialization!
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param slave The specified S2PI slave. Note that the slave information is
+ * only required if multiple SPI instances are used in order to
+ * map to the correct SPI instance.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t S2PI_CaptureGpioControl(void);
+status_t S2PI_CaptureGpioControl(s2pi_slave_t slave);
/*!*****************************************************************************
- * @brief Releases the S2PI pins from GPIO usage and switches back to SPI mode.
+ * @brief Releases the S2PI pins from GPIO usage and switches back to SPI mode.
*
- * @details The GPIO pins are configured for SPI operation and the GPIO mode is
- * left. Must be called if the pins are captured for GPIO operation via
- * the #S2PI_CaptureGpioControl function.
+ * @details The GPIO pins are configured for SPI operation and the GPIO mode is
+ * left. Must be called if the pins are captured for GPIO operation via
+ * the #S2PI_CaptureGpioControl function.
*
- * @note This function is only called during device initialization!
+ * @note This function is only called during device initialization!
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param slave The specified S2PI slave. Note that the slave information is
+ * only required if multiple SPI instances are used in order to
+ * map to the correct SPI instance.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
-status_t S2PI_ReleaseGpioControl(void);
+status_t S2PI_ReleaseGpioControl(s2pi_slave_t slave);
/*!*****************************************************************************
- * @brief Writes the output for a specified SPI pin in GPIO mode.
+ * @brief Writes the output for a specified SPI pin in GPIO mode.
*
* @details This function writes the value of an SPI pin if the SPI pins are
- * captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
+ * captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
*
- * @note Since some GPIO peripherals switch the GPIO pins very fast a delay
- * must be added after each GBIO access (i.e. right before returning
- * from the #S2PI_WriteGpioPin method) in order to decrease the baud
- * rate of the software EEPROM protocol. Increase the delay if timing
- * issues occur while reading the EERPOM. For example:
- * Delay = 10 µsec => Baud Rate < 100 kHz
+ * @note Since some GPIO peripherals switch the GPIO pins very fast a delay
+ * must be added after each GBIO access (i.e. right before returning
+ * from the #S2PI_WriteGpioPin method) in order to decrease the baud
+ * rate of the software EEPROM protocol. Increase the delay if timing
+ * issues occur while reading the EERPOM. For example:
+ * Delay = 10 µsec => Baud Rate < 100 kHz
*
- * @note This function is only called during device initialization!
+ * @note This function is only called during device initialization!
*
- * @param slave The specified S2PI slave.
- * @param pin The specified S2PI pin.
- * @param value The GPIO pin state to write (0 = low, 1 = high).
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param slave The specified S2PI slave.
+ * @param pin The specified S2PI pin.
+ * @param value The GPIO pin state to write (0 = low, 1 = high).
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_WriteGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t value);
/*!*****************************************************************************
- * @brief Reads the input from a specified SPI pin in GPIO mode.
+ * @brief Reads the input from a specified SPI pin in GPIO mode.
*
* @details This function reads the value of an SPI pin if the SPI pins are
- * captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
+ * captured for GPIO operation via the #S2PI_CaptureGpioControl previously.
*
- * @note This function is only called during device initialization!
+ * @note This function is only called during device initialization!
*
- * @param slave The specified S2PI slave.
- * @param pin The specified S2PI pin.
- * @param value The GPIO pin state to read (0 = low, GND level, 1 = high, VCC level).
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param slave The specified S2PI slave.
+ * @param pin The specified S2PI pin.
+ * @param value The GPIO pin state to read (0 = low, GND level, 1 = high, VCC level).
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t S2PI_ReadGpioPin(s2pi_slave_t slave, s2pi_pin_t pin, uint32_t *value);
-#ifdef __cplusplus
-}
-#endif
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif // ARGUS_S2PI_H
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_timer.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_timer.h
index 80deb42016..b736010682 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_timer.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/platform/argus_timer.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file provides an interface for the required timer modules.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides an interface for the required timer modules.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,118 +36,117 @@
#ifndef ARGUS_TIMER_H
#define ARGUS_TIMER_H
-
#ifdef __cplusplus
extern "C" {
#endif
/*!***************************************************************************
- * @defgroup argus_timer Timer: Hardware Timer Interface
- * @ingroup argus_platform
+ * @defgroup argus_timer Timer: Hardware Timer Interface
+ * @ingroup argus_hal
*
- * @brief Timer implementations for lifetime counting as well as periodic
- * callback.
+ * @brief Timer implementations for lifetime counting as well as periodic
+ * callback.
*
- * @details The module provides an interface to the timing utilities that
- * are required by the AFBR-S50 time-of-flight sensor API.
+ * @details The module provides an interface to the timing utilities that
+ * are required by the AFBR-S50 time-of-flight sensor API.
*
- * Two essential features have to be provided by the user code:
- * 1. Time Measurement Capability: In order to keep track of outgoing
- * signals, the API needs to measure elapsed time. In order to
- * provide optimum device performance, the granularity should be
- * around 10 to 100 microseconds.
- * 2. Periodic Callback: The API provides an automatic starting of
- * measurement cycles at a fixed frame rate via a periodic
- * interrupt timer. If this feature is not used, implementation
- * of the periodic interrupts can be skipped. An weak default
- * implementation is provide in the API.
- * .
+ * Two essential features have to be provided by the user code:
+ * 1. Time Measurement Capability: In order to keep track of outgoing
+ * signals, the API needs to measure elapsed time. In order to
+ * provide optimum device performance, the granularity should be
+ * around 10 to 100 microseconds.
+ * 2. Periodic Callback: The API provides an automatic starting of
+ * measurement cycles at a fixed frame rate via a periodic
+ * interrupt timer. If this feature is not used, implementation
+ * of the periodic interrupts can be skipped. An weak default
+ * implementation is provide in the API.
+ * .
*
- * The time measurement feature is simply implemented by the function
- * #Timer_GetCounterValue. Whenever the function is called, the
- * provided counter values must be written with the values obtained
- * by the current time.
+ * The time measurement feature is simply implemented by the function
+ * #Timer_GetCounterValue. Whenever the function is called, the
+ * provided counter values must be written with the values obtained
+ * by the current time.
*
- * The periodic interrupt timer is a simple callback interface.
- * After installing the callback function pointer via #Timer_SetCallback,
- * the timer can be started by setting interval via #Timer_SetInterval.
- * From then, the callback is invoked periodically as the corresponding
- * interval may specify. The timer is stopped by setting the interval
- * to 0 using the #Timer_SetInterval function. The interval can be
- * updated at any time by updating the interval via the #Timer_SetInterval
- * function. To any of these functions, an abstract parameter pointer
- * must be passed. This parameter is passed back to the callback any
- * time it is invoked.
+ * The periodic interrupt timer is a simple callback interface.
+ * After installing the callback function pointer via #Timer_SetCallback,
+ * the timer can be started by setting interval via #Timer_SetInterval.
+ * From then, the callback is invoked periodically as the corresponding
+ * interval may specify. The timer is stopped by setting the interval
+ * to 0 using the #Timer_SetInterval function. The interval can be
+ * updated at any time by updating the interval via the #Timer_SetInterval
+ * function. To any of these functions, an abstract parameter pointer
+ * must be passed. This parameter is passed back to the callback any
+ * time it is invoked.
*
- * In order to provide the usage of multiple devices, an mechanism is
- * introduced to allow the installation of multiple callback interval
- * at the same time. Therefore, the abstract parameter pointer is used
- * to identify the corresponding callback interval. For example, there
- * are two callbacks for two intervals, t1 and t2, required. The user
- * can start two timers by calling the #Timer_SetInterval method twice,
- * but with an individual parameter pointer, ptr1 and ptr2, each:
- * \code
- * Timer_SetInterval(100000, ptr1); // 10 ms callback w/ parameter ptr1
- * Timer_SetInterval(200000, ptr2); // 20 ms callback w/ parameter ptr1
- * \endcode
+ * In order to provide the usage of multiple devices, an mechanism is
+ * introduced to allow the installation of multiple callback interval
+ * at the same time. Therefore, the abstract parameter pointer is used
+ * to identify the corresponding callback interval. For example, there
+ * are two callbacks for two intervals, t1 and t2, required. The user
+ * can start two timers by calling the #Timer_SetInterval method twice,
+ * but with an individual parameter pointer, ptr1 and ptr2, each:
+ * \code
+ * Timer_SetInterval(100000, ptr1); // 10 ms callback w/ parameter ptr1
+ * Timer_SetInterval(200000, ptr2); // 20 ms callback w/ parameter ptr1
+ * \endcode
*
- * Note that the implemented timer module must therefore support
- * as many different intervals as instances of the AFBR-S50 device are
- * used.
+ * Note that the implemented timer module must therefore support
+ * as many different intervals as instances of the AFBR-S50 device are
+ * used.
*
- * @addtogroup argus_timer
+ * @addtogroup argus_timer
* @{
*****************************************************************************/
-#include "api/argus_def.h"
+#include "utility/status.h"
/*******************************************************************************
* Lifetime Counter Timer Interface
******************************************************************************/
/*!***************************************************************************
- * @brief Obtains the lifetime counter value from the timers.
+ * @brief Obtains the lifetime counter value from the timers.
*
* @details The function is required to get the current time relative to any
- * point in time, e.g. the startup time. The returned values \p hct and
- * \p lct are given in seconds and microseconds respectively. The current
- * elapsed time since the reference time is then calculated from:
+ * point in time, e.g. the startup time. The returned values \p hct and
+ * \p lct are given in seconds and microseconds respectively. The current
+ * elapsed time since the reference time is then calculated from:
*
- * t_now [µsec] = hct * 1000000 µsec + lct * 1 µsec
+ * t_now [µsec] = hct * 1000000 µsec + lct * 1 µsec
*
- * Note that the accuracy/granularity of the lifetime counter does
- * not need to be 1 µsec. Usually, a granularity of approximately
- * 100 µsec is sufficient. However, in case of very high frame rates
- * (above 1000 frames per second), it is recommended to implement
- * an even lower granularity (somewhere in the 10 µsec regime).
+ * Note that the accuracy/granularity of the lifetime counter does
+ * not need to be 1 µsec. Usually, a granularity of approximately
+ * 100 µsec is sufficient. However, in case of very high frame rates
+ * (above 1000 frames per second), it is recommended to implement
+ * an even lower granularity (somewhere in the 10 µsec regime).
*
- * It must be guaranteed, that each call of the #Timer_GetCounterValue
- * function must provide a value that is greater or equal, but never lower,
- * than the value returned from the previous call.
+ * It must be guaranteed, that each call of the #Timer_GetCounterValue
+ * function must provide a value that is greater or equal, but never lower,
+ * than the value returned from the previous call.
*
- * A hardware based implementation of the lifetime counter functionality
- * would be to chain two distinct timers such that counter 2 increases
- * its value when counter 1 wraps to 0. The easiest way is to setup
- * counter 1 to wrap exactly every second. Counter 1 would than count
- * the sub-seconds (i.e. µsec) value (\p lct) and counter 2 the seconds
- * (\p hct) value. A 16-bit counter is sufficient in case of counter 1
- * while counter 2 must be a 32-bit version.
+ * A hardware based implementation of the lifetime counter functionality
+ * would be to chain two distinct timers such that counter 2 increases
+ * its value when counter 1 wraps to 0. The easiest way is to setup
+ * counter 1 to wrap exactly every second. Counter 1 would than count
+ * the sub-seconds (i.e. µsec) value (\p lct) and counter 2 the seconds
+ * (\p hct) value. A 16-bit counter is sufficient in case of counter 1
+ * while counter 2 must be a 32-bit version.
*
- * In case of a lack of available hardware timers, a software solution
- * can be used that requires only a 16-bit timer. In a simple scenario,
- * the timer is configured to wrap around every second and increase
- * a software counter value in its interrupt service routine (triggered
- * with the wrap around event) every time the wrap around occurs.
+ * In case of a lack of available hardware timers, a software solution
+ * can be used that requires only a 16-bit timer. In a simple scenario,
+ * the timer is configured to wrap around every second and increase
+ * a software counter value in its interrupt service routine (triggered
+ * with the wrap around event) every time the wrap around occurs.
*
*
- * @note The implementation of this function is mandatory for the correct
- * execution of the API.
+ * @note The implementation of this function is mandatory for the correct
+ * execution of the API.
*
- * @param hct A pointer to the high counter value bits representing current
- * time in seconds.
+ * @param hct A pointer to the high counter value bits representing current
+ * time in seconds.
*
- * @param lct A pointer to the low counter value bits representing current
- * time in microseconds. Range: 0, .., 999999 µsec
+ * @param lct A pointer to the low counter value bits representing current
+ * time in microseconds. Range: 0, .., 999999 µsec
*****************************************************************************/
void Timer_GetCounterValue(uint32_t *hct, uint32_t *lct);
@@ -156,68 +155,70 @@ void Timer_GetCounterValue(uint32_t *hct, uint32_t *lct);
******************************************************************************/
/*!***************************************************************************
- * @brief The callback function type for periodic interrupt timer.
+ * @brief The callback function type for periodic interrupt timer.
*
- * @details The function that is invoked every time a specified interval elapses.
- * An abstract parameter is passed to the function whenever it is called.
+ * @details The function that is invoked every time a specified interval elapses.
+ * An abstract parameter is passed to the function whenever it is called.
*
- * @param param An abstract parameter to be passed to the callback. This is
- * also the identifier of the given interval.
+ * @param param An abstract parameter to be passed to the callback. This is
+ * also the identifier of the given interval.
*****************************************************************************/
typedef void (*timer_cb_t)(void *param);
/*!***************************************************************************
- * @brief Installs an periodic timer callback function.
+ * @brief Installs an periodic timer callback function.
*
- * @details Installs an periodic timer callback function that is invoked whenever
- * an interval elapses. The callback is the same for any interval,
- * however, the single intervals can be identified by the passed
- * parameter.
- * Passing a zero-pointer removes and disables the callback.
+ * @details Installs an periodic timer callback function that is invoked whenever
+ * an interval elapses. The callback is the same for any interval,
+ * however, the single intervals can be identified by the passed
+ * parameter.
+ * Passing a zero-pointer removes and disables the callback.
*
- * @note The implementation of this function is optional for the correct
- * execution of the API. If not implemented, a weak implementation
- * within the API will be used that disable the periodic timer callback
- * and thus the automatic starting of measurements from the background.
+ * @note The implementation of this function is optional for the correct
+ * execution of the API. If not implemented, a weak implementation
+ * within the API will be used that disable the periodic timer callback
+ * and thus the automatic starting of measurements from the background.
*
- * @param f The timer callback function.
+ * @param f The timer callback function.
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_SetCallback(timer_cb_t f);
/*!***************************************************************************
- * @brief Sets the timer interval for a specified callback parameter.
+ * @brief Sets the timer interval for a specified callback parameter.
*
- * @details Sets the callback interval for the specified parameter and starts
- * the timer with a new interval. If there is already an interval with
- * the given parameter, the timer is restarted with the given interval.
- * If the same time interval as already set is passed, nothing happens.
- * Passing a interval of 0 disables the timer.
+ * @details Sets the callback interval for the specified parameter and starts
+ * the timer with a new interval. If there is already an interval with
+ * the given parameter, the timer is restarted with the given interval.
+ * If the same time interval as already set is passed, nothing happens.
+ * Passing a interval of 0 disables the timer.
*
- * Note that a microsecond granularity for the timer interrupt period is
- * not required. Usually a microseconds granularity is sufficient.
- * The required granularity depends on the targeted frame rate, e.g. in
- * case of more than 1 kHz measurement rate, a granularity of less than
- * a microsecond is required to achieve the given frame rate.
+ * When enabling the timer (or resetting by applying another interval),
+ * the first timer interrupt must happen after the specified interval.
*
- * @note The implementation of this function is optional for the correct
- * execution of the API. If not implemented, a weak implementation
- * within the API will be used that disable the periodic timer callback
- * and thus the automatic starting of measurements from the background.
+ * Note that a microsecond granularity for the timer interrupt period is
+ * not required. Usually a milliseconds granularity is sufficient.
+ * The required granularity depends on the targeted frame rate, e.g. in
+ * case of more than 1 kHz measurement rate, a granularity of less than
+ * a millisecond is required to achieve the given frame rate.
*
- * @param dt_microseconds The callback interval in microseconds.
+ * @note The implementation of this function is optional for the correct
+ * execution of the API. If not implemented, a weak implementation
+ * within the API will be used that disable the periodic timer callback
+ * and thus the automatic starting of measurements from the background.
*
- * @param param An abstract parameter to be passed to the callback. This is
- * also the identifier of the given interval.
+ * @param dt_microseconds The callback interval in microseconds.
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * @param param An abstract parameter to be passed to the callback. This is
+ * also the identifier of the given interval.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Timer_SetInterval(uint32_t dt_microseconds, void *param);
-#ifdef __cplusplus
-}
-#endif
-
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* ARGUS_TIMER_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_def.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_def.h
index ae7422ada5..8d5406360b 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_def.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_def.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details Provides definitions and basic macros for fixed point data types.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Provides definitions and basic macros for fixed point data types.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,23 +36,30 @@
#ifndef FP_DEF_H
#define FP_DEF_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup fixedpoint Fixed Point Math
- * @ingroup argusutil
- * @brief A basic math library for fixed point number in the Qx.y fomat.
- * @details This module contains common fixed point type definitions as
- * well as some basic math algorithms. All types are based on
- * integer types. The number are defined with the Q number format.
+ * @defgroup argus_fp Fixed Point Math
+ * @ingroup argus_util
*
- * - For a description of the Q number format refer to:
- * https://en.wikipedia.org/wiki/Q_(number_format)
- * - Another resource for fixed point math in C might be found at
- * http://www.eetimes.com/author.asp?section_id=36&doc_id=1287491
- * .
- * @warning This definitions are not portable and work only with
- * little-endian systems!
- * @addtogroup fixedpoint
+ * @brief A basic math library for fixed point number in the Qx.y fomat.
+ *
+ * @details This module contains common fixed point type definitions as
+ * well as some basic math algorithms. All types are based on
+ * integer types. The number are defined with the Q number format.
+ *
+ * - For a description of the Q number format refer to:
+ * https://en.wikipedia.org/wiki/Q_(number_format)
+ * - Another resource for fixed point math in C might be found at
+ * http://www.eetimes.com/author.asp?section_id=36&doc_id=1287491
+ * .
+ *
+ * @warning This definitions are not portable and work only with
+ * little-endian systems!
+ *
+ * @addtogroup argus_fp
* @{
*****************************************************************************/
@@ -66,11 +73,11 @@
***** UQ6.2
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ6.2
- * @details An unsigned fixed point number format based on the 8-bit unsigned
- * integer type with 6 integer and 2 fractional bits.
- * - Range: 0 .. 63.75
- * - Granularity: 0.25
+ * @brief Unsigned fixed point number: UQ6.2
+ * @details An unsigned fixed point number format based on the 8-bit unsigned
+ * integer type with 6 integer and 2 fractional bits.
+ * - Range: 0 .. 63.75
+ * - Granularity: 0.25
*****************************************************************************/
typedef uint8_t uq6_2_t;
@@ -86,11 +93,11 @@ typedef uint8_t uq6_2_t;
***** UQ4.4
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ4.4
- * @details An unsigned fixed point number format based on the 8-bit unsigned
- * integer type with 4 integer and 4 fractional bits.
- * - Range: 0 .. 15.9375
- * - Granularity: 0.0625
+ * @brief Unsigned fixed point number: UQ4.4
+ * @details An unsigned fixed point number format based on the 8-bit unsigned
+ * integer type with 4 integer and 4 fractional bits.
+ * - Range: 0 .. 15.9375
+ * - Granularity: 0.0625
*****************************************************************************/
typedef uint8_t uq4_4_t;
@@ -106,11 +113,11 @@ typedef uint8_t uq4_4_t;
***** UQ2.6
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ2.6
- * @details An unsigned fixed point number format based on the 8-bit unsigned
- * integer type with 2 integer and 6 fractional bits.
- * - Range: 0 .. 3.984375
- * - Granularity: 0.015625
+ * @brief Unsigned fixed point number: UQ2.6
+ * @details An unsigned fixed point number format based on the 8-bit unsigned
+ * integer type with 2 integer and 6 fractional bits.
+ * - Range: 0 .. 3.984375
+ * - Granularity: 0.015625
*****************************************************************************/
typedef uint8_t uq2_6_t;
@@ -126,11 +133,11 @@ typedef uint8_t uq2_6_t;
***** UQ1.7
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ1.7
- * @details An unsigned fixed point number format based on the 8-bit unsigned
- * integer type with 1 integer and 7 fractional bits.
- * - Range: 0 .. 1.9921875
- * - Granularity: 0.0078125
+ * @brief Unsigned fixed point number: UQ1.7
+ * @details An unsigned fixed point number format based on the 8-bit unsigned
+ * integer type with 1 integer and 7 fractional bits.
+ * - Range: 0 .. 1.9921875
+ * - Granularity: 0.0078125
*****************************************************************************/
typedef uint8_t uq1_7_t;
@@ -146,11 +153,11 @@ typedef uint8_t uq1_7_t;
***** UQ0.8
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ0.8
- * @details An unsigned fixed point number format based on the 8-bit unsigned
- * integer type with 1 integer and 7 fractional bits.
- * - Range: 0 .. 0.99609375
- * - Granularity: 0.00390625
+ * @brief Unsigned fixed point number: UQ0.8
+ * @details An unsigned fixed point number format based on the 8-bit unsigned
+ * integer type with 1 integer and 7 fractional bits.
+ * - Range: 0 .. 0.99609375
+ * - Granularity: 0.00390625
*****************************************************************************/
typedef uint8_t uq0_8_t;
@@ -167,11 +174,11 @@ typedef uint8_t uq0_8_t;
***** Q3.4
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q3.4
- * @details A signed fixed point number format based on the 8-bit signed
- * integer type with 3 integer and 4 fractional bits.
- * - Range: -8 ... 7.9375
- * - Granularity: 0.0625
+ * @brief Signed fixed point number: Q3.4
+ * @details A signed fixed point number format based on the 8-bit signed
+ * integer type with 3 integer and 4 fractional bits.
+ * - Range: -8 ... 7.9375
+ * - Granularity: 0.0625
*****************************************************************************/
typedef int8_t q3_4_t;
@@ -189,11 +196,11 @@ typedef int8_t q3_4_t;
***** Q1.6
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q1.6
- * @details A signed fixed point number format based on the 8-bit signed
- * integer type with 1 integer and 6 fractional bits.
- * - Range: -2 ... 1.984375
- * - Granularity: 0.015625
+ * @brief Signed fixed point number: Q1.6
+ * @details A signed fixed point number format based on the 8-bit signed
+ * integer type with 1 integer and 6 fractional bits.
+ * - Range: -2 ... 1.984375
+ * - Granularity: 0.015625
*****************************************************************************/
typedef int8_t q1_6_t;
@@ -215,11 +222,11 @@ typedef int8_t q1_6_t;
***** UQ12.4
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ12.4
- * @details An unsigned fixed point number format based on the 16-bit unsigned
- * integer type with 12 integer and 4 fractional bits.
- * - Range: 0 ... 4095.9375
- * - Granularity: 0.0625
+ * @brief Unsigned fixed point number: UQ12.4
+ * @details An unsigned fixed point number format based on the 16-bit unsigned
+ * integer type with 12 integer and 4 fractional bits.
+ * - Range: 0 ... 4095.9375
+ * - Granularity: 0.0625
*****************************************************************************/
typedef uint16_t uq12_4_t;
@@ -235,11 +242,11 @@ typedef uint16_t uq12_4_t;
***** UQ10.6
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ10.6
- * @details An unsigned fixed point number format based on the 16-bit unsigned
- * integer type with 10 integer and 6 fractional bits.
- * - Range: 0 ... 1023.984375
- * - Granularity: 0.015625
+ * @brief Unsigned fixed point number: UQ10.6
+ * @details An unsigned fixed point number format based on the 16-bit unsigned
+ * integer type with 10 integer and 6 fractional bits.
+ * - Range: 0 ... 1023.984375
+ * - Granularity: 0.015625
*****************************************************************************/
typedef uint16_t uq10_6_t;
@@ -255,11 +262,11 @@ typedef uint16_t uq10_6_t;
***** UQ1.15
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ1.15
- * @details An unsigned fixed point number format based on the 16-bit unsigned
- * integer type with 1 integer and 15 fractional bits.
- * - Range: 0 .. 1.999969
- * - Granularity: 0.000031
+ * @brief Unsigned fixed point number: UQ1.15
+ * @details An unsigned fixed point number format based on the 16-bit unsigned
+ * integer type with 1 integer and 15 fractional bits.
+ * - Range: 0 .. 1.999969
+ * - Granularity: 0.000031
*****************************************************************************/
typedef uint16_t uq1_15_t;
@@ -275,11 +282,11 @@ typedef uint16_t uq1_15_t;
***** UQ0.16
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ0.16
- * @details An unsigned fixed point number format based on the 16-bit unsigned
- * integer type with 0 integer and 16 fractional bits.
- * - Range: 0 .. 0.9999847412109375
- * - Granularity: 1.52587890625e-5
+ * @brief Unsigned fixed point number: UQ0.16
+ * @details An unsigned fixed point number format based on the 16-bit unsigned
+ * integer type with 0 integer and 16 fractional bits.
+ * - Range: 0 .. 0.9999847412109375
+ * - Granularity: 1.52587890625e-5
*****************************************************************************/
typedef uint16_t uq0_16_t;
@@ -296,11 +303,11 @@ typedef uint16_t uq0_16_t;
***** Q11.4
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q11.4
- * @details A signed fixed point number format based on the 16-bit signed
- * integer type with 11 integer and 4 fractional bits.
- * - Range: -2048 ... 2047.9375
- * - Granularity: 0.0625
+ * @brief Signed fixed point number: Q11.4
+ * @details A signed fixed point number format based on the 16-bit signed
+ * integer type with 11 integer and 4 fractional bits.
+ * - Range: -2048 ... 2047.9375
+ * - Granularity: 0.0625
*****************************************************************************/
typedef int16_t q11_4_t;
@@ -319,11 +326,11 @@ typedef int16_t q11_4_t;
***** Q7.8
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q7.8
- * @details A signed fixed point number format based on the 16-bit signed
- * integer type with 7 integer and 8 fractional bits.
- * - Range: -128 .. 127.99609375
- * - Granularity: 0.00390625
+ * @brief Signed fixed point number: Q7.8
+ * @details A signed fixed point number format based on the 16-bit signed
+ * integer type with 7 integer and 8 fractional bits.
+ * - Range: -128 .. 127.99609375
+ * - Granularity: 0.00390625
*****************************************************************************/
typedef int16_t q7_8_t;
@@ -342,11 +349,11 @@ typedef int16_t q7_8_t;
***** Q3.12
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q3.12
- * @details A signed fixed point number format based on the 16-bit integer
- * type with 3 integer and 12 fractional bits.
- * - Range: -8 .. 7.99975586
- * - Granularity: 0.00024414
+ * @brief Signed fixed point number: Q3.12
+ * @details A signed fixed point number format based on the 16-bit integer
+ * type with 3 integer and 12 fractional bits.
+ * - Range: -8 .. 7.99975586
+ * - Granularity: 0.00024414
*****************************************************************************/
typedef int16_t q3_12_t;
@@ -365,11 +372,11 @@ typedef int16_t q3_12_t;
***** Q0.15
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q0.15
- * @details A signed fixed point number format based on the 16-bit integer
- * type with 0 integer and 15 fractional bits.
- * - Range: -1 .. 0.999969482
- * - Granularity: 0.000030518
+ * @brief Signed fixed point number: Q0.15
+ * @details A signed fixed point number format based on the 16-bit integer
+ * type with 0 integer and 15 fractional bits.
+ * - Range: -1 .. 0.999969482
+ * - Granularity: 0.000030518
*****************************************************************************/
typedef int16_t q0_15_t;
@@ -389,11 +396,11 @@ typedef int16_t q0_15_t;
***** UQ28.4
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ28.4
- * @details An unsigned fixed point number format based on the 32-bit unsigned
- * integer type with 28 integer and 4 fractional bits.
- * - Range: 0 ... 268435455.9375
- * - Granularity: 0.0625
+ * @brief Unsigned fixed point number: UQ28.4
+ * @details An unsigned fixed point number format based on the 32-bit unsigned
+ * integer type with 28 integer and 4 fractional bits.
+ * - Range: 0 ... 268435455.9375
+ * - Granularity: 0.0625
*****************************************************************************/
typedef uint32_t uq28_4_t;
@@ -409,11 +416,11 @@ typedef uint32_t uq28_4_t;
***** UQ16.16
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ16.16
- * @details An unsigned fixed point number format based on the 32-bit unsigned
- * integer type with 16 integer and 16 fractional bits.
- * - Range: 0 ... 65535.999984741
- * - Granularity: 0.000015259
+ * @brief Unsigned fixed point number: UQ16.16
+ * @details An unsigned fixed point number format based on the 32-bit unsigned
+ * integer type with 16 integer and 16 fractional bits.
+ * - Range: 0 ... 65535.999984741
+ * - Granularity: 0.000015259
*****************************************************************************/
typedef uint32_t uq16_16_t;
@@ -432,11 +439,11 @@ typedef uint32_t uq16_16_t;
***** UQ10.22
******************************************************************************/
/*!***************************************************************************
- * @brief Unsigned fixed point number: UQ10.22
- * @details An unsigned fixed point number format based on the 32-bit unsigned
- * integer type with 10 integer and 22 fractional bits.
- * - Range: 0 ... 1023.99999976158
- * - Granularity: 2.38418579101562E-07
+ * @brief Unsigned fixed point number: UQ10.22
+ * @details An unsigned fixed point number format based on the 32-bit unsigned
+ * integer type with 10 integer and 22 fractional bits.
+ * - Range: 0 ... 1023.99999976158
+ * - Granularity: 2.38418579101562E-07
*****************************************************************************/
typedef uint32_t uq10_22_t;
@@ -456,11 +463,11 @@ typedef uint32_t uq10_22_t;
***** Q27.4
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q27.4
- * @details A signed fixed point number format based on the 32-bit signed
- * integer type with 27 integer and 4 fractional bits.
- * - Range: -134217728 ... 134217727.9375
- * - Granularity: 0.0625
+ * @brief Signed fixed point number: Q27.4
+ * @details A signed fixed point number format based on the 32-bit signed
+ * integer type with 27 integer and 4 fractional bits.
+ * - Range: -134217728 ... 134217727.9375
+ * - Granularity: 0.0625
*****************************************************************************/
typedef int32_t q27_4_t;
@@ -475,15 +482,35 @@ typedef int32_t q27_4_t;
+/*******************************************************************************
+ ***** Q16.15
+ ******************************************************************************/
+/*!***************************************************************************
+ * @brief Signed fixed point number: Q16.15
+ * @details A signed fixed point number format based on the 32-bit integer
+ * type with 16 integer and 15 fractional bits.
+ * - Range: -65536 .. 65536.999969482
+ * - Granularity: 0.000030518
+ *****************************************************************************/
+typedef int32_t q16_15_t;
+
+/*! Minimum value of Q16.15 number format. */
+#define Q16_15_MIN ((q16_15_t)INT32_MIN)
+
+/*! Maximum value of Q16.15 number format. */
+#define Q16_15_MAX ((q16_15_t)INT32_MAX)
+
+
+
/*******************************************************************************
***** Q15.16
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q15.16
- * @details A signed fixed point number format based on the 32-bit integer
- * type with 15 integer and 16 fractional bits.
- * - Range: -32768 .. 32767.99998
- * - Granularity: 1.52588E-05
+ * @brief Signed fixed point number: Q15.16
+ * @details A signed fixed point number format based on the 32-bit integer
+ * type with 15 integer and 16 fractional bits.
+ * - Range: -32768 .. 32767.99998
+ * - Granularity: 1.52588E-05
*****************************************************************************/
typedef int32_t q15_16_t;
@@ -502,11 +529,11 @@ typedef int32_t q15_16_t;
***** Q9.22
******************************************************************************/
/*!***************************************************************************
- * @brief Signed fixed point number: Q9.22
- * @details A signed fixed point number format based on the 32-bit integer
- * type with 9 integer and 22 fractional bits.
- * - Range: -512 ... 511.9999998
- * - Granularity: 2.38418579101562E-07
+ * @brief Signed fixed point number: Q9.22
+ * @details A signed fixed point number format based on the 32-bit integer
+ * type with 9 integer and 22 fractional bits.
+ * - Range: -512 ... 511.9999998
+ * - Granularity: 2.38418579101562E-07
*****************************************************************************/
typedef int32_t q9_22_t;
@@ -522,4 +549,7 @@ typedef int32_t q9_22_t;
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* FP_DEF_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_div.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_div.h
new file mode 100644
index 0000000000..60b75a164a
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_div.h
@@ -0,0 +1,173 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Provides definitions and basic macros for fixed point data types.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef FP_DIV_H
+#define FP_DIV_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!***************************************************************************
+ * @addtogroup argus_fp
+ * @{
+ *****************************************************************************/
+
+#include "fp_def.h"
+#include "int_math.h"
+
+/*!***************************************************************************
+ * Set to use hardware division (Cortex-M3/4) over software division (Cortex-M0/1).
+ *****************************************************************************/
+#ifndef USE_HW_DIV
+#define USE_HW_DIV 0
+#endif
+
+/*!***************************************************************************
+ * @brief 32-bit implementation of an Q15.16 division.
+ *
+ * @details Algorithm to evaluate a/b, where b is in Q15.16 format, on a 32-bit
+ * architecture with maximum precision.
+ * The result is correctly rounded and given as the input format.
+ * Division by 0 yields max. values determined by signa of numerator.
+ * Too high/low results are truncated to max/min values.
+ *
+ * Depending on the architecture, the division is implemented with a 64-bit
+ * division and shifting (Cortex-M3/4) or as a fast software algorithm
+ * (Cortex-M0/1) wich runs fast on processors without hardware division.
+ *
+ * @see https://code.google.com/archive/p/libfixmath
+ *
+ * @param a Numerator in any Qx.y format
+ * @param b Denominator in Q15.16 format
+ * @return Result = a/b in the same Qx.y format as the input parameter a.
+ *****************************************************************************/
+inline int32_t fp_div16(int32_t a, q15_16_t b)
+{
+ //assert(b);
+ if (b == 0) { return a < 0 ? INT32_MIN : INT32_MAX; }
+
+#if USE_HW_DIV
+ // Tested on Cortex-M4, it takes approx. 75% of the
+ // software algorithm below.
+ int64_t c = ((int64_t) a) << 30U;
+
+ if ((uint32_t)(a ^ b) & 0x80000000U) {
+ c = (((-c) / b) + (1 << 13U)) >> 14U;
+
+ if (c > 0x80000000U) { return INT32_MIN; }
+
+ return -c;
+
+ } else {
+ c = ((c / b) + (1 << 13U)) >> 14U;
+
+ if (c > (int64_t)INT32_MAX) { return INT32_MAX; }
+
+ return c;
+ }
+
+#else
+ // This uses the basic binary restoring division algorithm.
+ // It appears to be faster to do the whole division manually than
+ // trying to compose a 64-bit divide out of 32-bit divisions on
+ // platforms without hardware divide.
+ // Tested on Cortex-M0, it takes approx. 33% of the time of the
+ // 64-bit version above.
+
+ uint32_t remainder = absval(a);
+ uint32_t divider = absval(b);
+
+ uint32_t quotient = 0;
+ uint32_t bit = 0x10000U;
+
+ /* The algorithm requires D >= R */
+ while (divider < remainder) {
+ divider <<= 1U;
+ bit <<= 1U;
+ }
+
+ if (!bit) {
+ if ((uint32_t)(a ^ b) & 0x80000000U) { // return truncated values
+ return INT32_MIN;
+
+ } else {
+ return INT32_MAX;
+ }
+ }
+
+ if (divider & 0x80000000U) {
+ // Perform one step manually to avoid overflows later.
+ // We know that divider's bottom bit is 0 here.
+ if (remainder >= divider) {
+ quotient |= bit;
+ remainder -= divider;
+ }
+
+ divider >>= 1U;
+ bit >>= 1U;
+ }
+
+ /* Main division loop */
+ while (bit && remainder) {
+ if (remainder >= divider) {
+ quotient |= bit;
+ remainder -= divider;
+ }
+
+ remainder <<= 1U;
+ bit >>= 1U;
+ }
+
+ if (remainder >= divider) {
+ quotient++;
+ }
+
+ uint32_t result = quotient;
+
+ /* Figure out the sign of result */
+ if ((uint32_t)(a ^ b) & 0x80000000U) {
+ result = -result;
+ }
+
+ return (int32_t)result;
+#endif
+}
+
+/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* FP_DIV_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_ema.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_ema.h
new file mode 100644
index 0000000000..f8c494a630
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_ema.h
@@ -0,0 +1,204 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Provides averaging algorithms for fixed point data types.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef FP_EMA_H
+#define FP_EMA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!***************************************************************************
+ * @addtogroup argus_fp
+ * @{
+ *****************************************************************************/
+
+#include "fp_def.h"
+
+#include "utility/fp_rnd.h"
+#include "utility/fp_mul.h"
+
+/*!***************************************************************************
+ * @brief Circular exponentially weighted moving average using UQ1.15 format.
+ *
+ * @details Evaluates the moving average (exponentially weighted) for circular
+ * data in UQ1.15 format.
+ * Circular data is that MAX_VALUE + 1 == MIN_VALUE. For example the
+ * usual phase information.
+ *
+ * Problem: Due to circularity of phase values, i.e. 0+x and 2PI+x are
+ * the same, the usual EMA has issues with the wrap around effect.
+ * Especially for vectors with phase around 0 (or 2PI), two values
+ * like 0 + x and PI - y are averaged to something around PI instead
+ * of 0 which would be more correct.
+ *
+ * Solution: Assume that phase jumps of more than PI are not allowed
+ * or possible. If a deviation of the new value to the smoothed signal
+ * occurs, it is clear that this stems from the wrap around effect and
+ * can be caught and correctly handled by the smoothing algorithm.
+ *
+ * Caution: If a target comes immediately into the field of view, phase
+ * jumps of > PI are indeed possible and volitional. However, the
+ * averaging break there anyway since the smoothed signal approaches
+ * only with delay to the correct values. The error made here is, that
+ * the smoothed signal approaches from the opposite direction. However,
+ * is approaches even faster since it always takes the shortest
+ * direction.
+ *
+ * @param mean The previous mean value in UQ1.15 format.
+ * @param x The current value to be added to the average UQ1.15 format.
+ * @param weight The EMA weight in UQ0.7 format.
+ * @return The new mean value in UQ1.15 format.
+ *****************************************************************************/
+inline uq1_15_t fp_ema15c(uq1_15_t mean, uq1_15_t x, uq0_8_t weight)
+{
+ if (weight == 0) { return x; }
+
+ // Heeds the wrap around effect by casting dx to int16:
+ const int16_t dx = (int16_t)(x - mean);
+ const int32_t diff = weight * dx;
+ return (uq1_15_t)fp_rnds((mean << 8U) + diff, 8U);
+}
+
+/*!***************************************************************************
+ * @brief Exponentially weighted moving average using the Q11.4 format.
+ *
+ * @details Evaluates the moving average (exponentially weighted) for data in
+ * Q11.4 format.
+ *
+ * @param mean The previous mean value in Q11.4 format.
+ * @param x The current value to be added to the average Q11.4 format.
+ * @param weight The EMA weight in UQ0.7 format.
+ * @return The new mean value in Q11.4 format.
+ *****************************************************************************/
+inline q11_4_t fp_ema4(q11_4_t mean, q11_4_t x, uq0_8_t weight)
+{
+ if (weight == 0) { return x; }
+
+ const int32_t dx = x - mean;
+ const int32_t diff = weight * dx;
+ return (q11_4_t)fp_rnds((mean << 8U) + diff, 8U);
+}
+
+/*!***************************************************************************
+ * @brief Exponentially weighted moving average using the Q7.8 format.
+ *
+ * @details Evaluates the moving average (exponentially weighted) for data in
+ * Q7.8 format.
+ *
+ * @param mean The previous mean value in Q7.8 format.
+ * @param x The current value to be added to the average Q7.8 format.
+ * @param weight The EMA weight in UQ0.7 format.
+ * @return The new mean value in Q7.8 format.
+ *****************************************************************************/
+inline q7_8_t fp_ema8(q7_8_t mean, q7_8_t x, uq0_8_t weight)
+{
+ return (q7_8_t)fp_ema4(mean, x, weight);
+}
+
+/*!***************************************************************************
+ * @brief Exponentially weighted moving average using the Q15.16 format.
+ *
+ * @details Evaluates the moving average (exponentially weighted) for data in
+ * Q15.16 format.
+ *
+ * @param mean The previous mean value in Q15.16 format.
+ * @param x The current value to be added to the average Q15.16 format.
+ * @param weight The EMA weight in UQ0.7 format.
+ * @return The new mean value in Q15.16 format.
+ *****************************************************************************/
+inline uint32_t uint_ema32(uint32_t mean, uint32_t x, uq0_8_t weight)
+{
+ if (weight == 0) { return x; }
+
+ if (x > mean) {
+ const uint32_t dx = x - mean;
+ const uint32_t diff = fp_mulu(weight, dx, 8U);
+ return mean + diff;
+
+ } else {
+ const uint32_t dx = mean - x;
+ const uint32_t diff = fp_mulu(weight, dx, 8U);
+ return mean - diff;
+ }
+}
+/*!***************************************************************************
+ * @brief Exponentially weighted moving average using the Q15.16 format.
+ *
+ * @details Evaluates the moving average (exponentially weighted) for data in
+ * Q15.16 format.
+ *
+ * @param mean The previous mean value in Q15.16 format.
+ * @param x The current value to be added to the average Q15.16 format.
+ * @param weight The EMA weight in UQ0.7 format.
+ * @return The new mean value in Q15.16 format.
+ *****************************************************************************/
+inline int32_t int_ema32(int32_t mean, int32_t x, uq0_8_t weight)
+{
+ if (weight == 0) { return x; }
+
+ if (x > mean) {
+ const uint32_t dx = x - mean;
+ const uint32_t diff = fp_mulu(weight, dx, 8U);
+ return mean + diff;
+
+ } else {
+ const uint32_t dx = mean - x;
+ const uint32_t diff = fp_mulu(weight, dx, 8U);
+ return mean - diff;
+ }
+}
+
+/*!***************************************************************************
+ * @brief Exponentially weighted moving average using the Q15.16 format.
+ *
+ * @details Evaluates the moving average (exponentially weighted) for data in
+ * Q15.16 format.
+ *
+ * @param mean The previous mean value in Q15.16 format.
+ * @param x The current value to be added to the average Q15.16 format.
+ * @param weight The EMA weight in UQ0.7 format.
+ * @return The new mean value in Q15.16 format.
+ *****************************************************************************/
+inline q15_16_t fp_ema16(q15_16_t mean, q15_16_t x, uq0_8_t weight)
+{
+ return (q15_16_t)int_ema32(mean, x, weight);
+}
+
+/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* FP_EMA_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_exp.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_exp.h
new file mode 100644
index 0000000000..f845ca6e00
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_exp.h
@@ -0,0 +1,69 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides an exponential function for fixed point type.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef FP_EXP_H
+#define FP_EXP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!***************************************************************************
+ * @addtogroup argus_fp
+ * @{
+ *****************************************************************************/
+
+#include "fp_def.h"
+
+/*!***************************************************************************
+ * @brief Calculates the exponential of an fixed point number Q15.16 format.
+ *
+ * @details Calculates y = exp(x) in fixed point representation.
+ *
+ * Note that the result might not be 100 % accurate and might contain
+ * a small error!
+ *
+ * @see https://www.quinapalus.com/efunc.html
+ *
+ * @param x The input parameter in unsigned fixed point format Q15.16.
+ * @return Result y = exp(x) in the UQ16.16 format.
+ *****************************************************************************/
+uq16_16_t fp_exp16(q15_16_t x);
+
+/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* FP_DIV_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_log.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_log.h
new file mode 100644
index 0000000000..6bc42b2ec7
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_log.h
@@ -0,0 +1,69 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides an logarithm function for fixed point type.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef FP_LOG_H
+#define FP_LOG_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!***************************************************************************
+ * @addtogroup argus_fp
+ * @{
+ *****************************************************************************/
+
+#include "fp_def.h"
+
+/*!***************************************************************************
+ * @brief Calculates the natural logarithm (base e) of an fixed point number.
+ *
+ * @details Calculates y = ln(x) = log_e(x) in fixed point representation.
+ *
+ * Note that the result might not be 100 % accurate and might contain
+ * a small error!
+ *
+ * @see https://www.quinapalus.com/efunc.html
+ *
+ * @param x The input parameter in unsigned fixed point format Q15.16.
+ * @return Result y = ln(x) in the UQ16.16 format.
+ *****************************************************************************/
+q15_16_t fp_log16(uq16_16_t x);
+
+/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* FP_DIV_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_mul.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_mul.h
new file mode 100644
index 0000000000..78db582644
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_mul.h
@@ -0,0 +1,235 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Provides definitions and basic macros for fixed point data types.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef FP_MUL_H
+#define FP_MUL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!***************************************************************************
+ * @addtogroup argus_fp
+ * @{
+ *****************************************************************************/
+
+#include "fp_def.h"
+#include "utility/fp_rnd.h"
+
+/*!***************************************************************************
+ * Set to use hardware division (Cortex-M3/4) over software division (Cortex-M0/1).
+ *****************************************************************************/
+#ifndef USE_64BIT_MUL
+#define USE_64BIT_MUL 0
+#endif
+
+#if !USE_64BIT_MUL
+/*!***************************************************************************
+ * @brief Long multiplication of two unsigned 32-bit into an 64-bit value on
+ * 32-bit architecture.
+ *
+ * @details w (two words) gets the product of u and v (one word each).
+ * w[0] is the most significant word of the result, w[1] the least.
+ * (The words are in big-endian order).
+ * It is Knuth's Algorithm M from [Knu2] section 4.3.1.
+ * *
+ * @see http://www.hackersdelight.org/hdcodetxt/muldwu.c.txt
+ *
+ * @param w The result (u * v) value given as two unsigned 32-bit numbers:
+ * w[0] is the most significant word of the result, w[1] the least.
+ * (The words are in big-endian order).
+ * @param u Left hand side of the multiplication.
+ * @param v Right hand side of the multiplication.
+ *****************************************************************************/
+inline void muldwu(uint32_t w[], uint32_t u, uint32_t v)
+{
+ const uint32_t u0 = u >> 16U;
+ const uint32_t u1 = u & 0xFFFFU;
+ const uint32_t v0 = v >> 16U;
+ const uint32_t v1 = v & 0xFFFFU;
+
+ uint32_t t = u1 * v1;
+ const uint32_t w3 = t & 0xFFFFU;
+ uint32_t k = t >> 16U;
+
+ t = u0 * v1 + k;
+ const uint32_t w2 = t & 0xFFFFU;
+ const uint32_t w1 = t >> 16U;
+
+ t = u1 * v0 + w2;
+ k = t >> 16U;
+
+ w[0] = u0 * v0 + w1 + k;
+ w[1] = (t << 16U) + w3;
+}
+#endif
+
+/*!***************************************************************************
+ * @brief 64-bit implementation of an unsigned multiplication with fixed point format.
+ *
+ * @details Algorithm to evaluate a*b, where a and b are arbitrary fixed point
+ * number of 32-bit width. The multiplication is done in 64-bit and
+ * the result is shifted down by the passed shift parameter in order
+ * to return a 32-bit value.
+ * The shift is executed with correct rounding.
+ *
+ * Note that the result must fit into the 32-bit value. An assertion
+ * error occurs otherwise (or undefined behavior of no assert available).
+ *
+ * @param u The left parameter in UQx1.y1 format
+ * @param v The right parameter in UQx2.y2 format
+ * @param shift The final right shift (rounding) value.
+ * @return Result = (a*b)>>shift in UQx.(y1+y2-shift) format.
+ *****************************************************************************/
+inline uint32_t fp_mulu(uint32_t u, uint32_t v, uint_fast8_t shift)
+{
+ assert(shift <= 32);
+#if USE_64BIT_MUL
+ const uint64_t w = (uint64_t)u * (uint64_t)v;
+ return (w >> shift) + ((w >> (shift - 1)) & 1U);
+#else
+ uint32_t tmp[2] = { 0 };
+ muldwu(tmp, u, v);
+
+ assert(shift ? tmp[0] <= (UINT32_MAX >> (32 - shift)) : tmp[0] == 0);
+
+ if (32 - shift) {
+ return ((tmp[0] << (32 - shift)) + fp_rndu(tmp[1], shift));
+
+ } else {
+ return tmp[1] > (UINT32_MAX >> 1) ? tmp[0] + 1 : tmp[0];
+ }
+
+#endif
+}
+
+/*!***************************************************************************
+ * @brief 64-bit implementation of a signed multiplication with fixed point format.
+ *
+ * @details Algorithm to evaluate a*b, where a and b are arbitrary fixed point
+ * number of 32-bit width. The multiplication is done in 64-bit and
+ * the result is shifted down by the passed shift parameter in order
+ * to return a 32-bit value.
+ * The shift is executed with correct rounding.
+ *
+ * Note that the result must fit into the 32-bit value. An assertion
+ * error occurs otherwise (or undefined behavior of no assert available).
+ *
+ * @param u The left parameter in Qx1.y1 format
+ * @param v The right parameter in Qx2.y2 format
+ * @param shift The final right shift (rounding) value.
+ * @return Result = (a*b)>>shift in Qx.(y1+y2-shift) format.
+ *****************************************************************************/
+inline int32_t fp_muls(int32_t u, int32_t v, uint_fast8_t shift)
+{
+ int_fast8_t sign = 1;
+
+ uint32_t u2, v2;
+
+ if (u < 0) { u2 = -u; sign = -sign; } else { u2 = u; }
+
+ if (v < 0) { v2 = -v; sign = -sign; } else { v2 = v; }
+
+ const uint32_t res = fp_mulu(u2, v2, shift);
+
+ assert(sign > 0 ? res <= 0x7FFFFFFFU : res <= 0x80000000U);
+
+ return sign > 0 ? res : -res;
+}
+
+
+/*!***************************************************************************
+ * @brief 48-bit implementation of a unsigned multiplication with fixed point format.
+ *
+ * @details Algorithm to evaluate a*b, where a and b are arbitrary fixed point
+ * numbers with 32-bit unsigned and 16-bit unsigned format respectively.
+ * The multiplication is done in two 16x16-bit operations and the
+ * result is shifted down by the passed shift parameter in order to
+ * return a 32-bit value.
+ *
+ * Note that the result must fit into the 32-bit value. An assertion
+ * error occurs otherwise (or undefined behavior of no assert available).
+ *
+ * @param u The left parameter in Qx1.y1 format
+ * @param v The right parameter in Qx2.y2 format
+ * @param shift The final right shift (rounding) value.
+ * @return Result = (a*b)>>shift in Qx.(y1+y2-shift) format.
+ *****************************************************************************/
+inline uint32_t fp_mul_u32_u16(uint32_t u, uint16_t v, uint_fast8_t shift)
+{
+ assert(shift <= 48);
+
+ if (shift > 16) {
+ uint32_t msk = 0xFFFFU;
+ uint32_t a = (u >> 16U) * v;
+ uint32_t b = (msk & u) * v;
+ return fp_rndu(a, shift - 16) + fp_rndu(b, shift);
+
+ } else {
+ uint32_t msk = ~(0xFFFFFFFFU << shift);
+ uint32_t a = (u >> shift) * v;
+ uint32_t b = fp_rndu((msk & u) * v, shift);
+ return a + b;
+ }
+}
+
+/*!***************************************************************************
+ * @brief 48-bit implementation of an unsigned/signed multiplication with fixed point format.
+ *
+ * @details Algorithm to evaluate a*b, where a and b are arbitrary fixed point
+ * numbers with 32-bit signed and 16-bit unsigned format respectively.
+ * The multiplication is done in two 16x16-bit operations and the
+ * result is shifted down by the passed shift parameter in order to
+ * return a 32-bit value.
+ * The shift is executed with correct rounding.
+ *
+ * Note that the result must fit into the 32-bit value. An assertion
+ * error occurs otherwise (or undefined behavior of no assert available).
+ *
+ * @param u The left parameter in Qx1.y1 format
+ * @param v The right parameter in Qx2.y2 format
+ * @param shift The final right shift (rounding) value.
+ * @return Result = (a*b)>>shift in Qx.(y1+y2-shift) format.
+ *****************************************************************************/
+inline int32_t fp_mul_s32_u16(int32_t u, uint16_t v, uint_fast8_t shift)
+{
+ return u >= 0 ? fp_mul_u32_u16(u, v, shift) : - fp_mul_u32_u16(-u, v, shift);
+}
+
+/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* FP_MUL_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_rnd.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_rnd.h
new file mode 100644
index 0000000000..ad6f71e09c
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/fp_rnd.h
@@ -0,0 +1,118 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Provides definitions and basic macros for fixed point data types.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef FP_RND_H
+#define FP_RND_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!***************************************************************************
+ * @addtogroup argus_fp
+ * @{
+ *****************************************************************************/
+
+#include "fp_def.h"
+#include
+
+/*!***************************************************************************
+ * @brief Converting with rounding from UQx.n1 to UQx.n2.
+ * @details Equivalent to dividing by 2^n with correct rounding to unsigned
+ * integer values.
+ * @param Q The number in (U)Qx.n1 fixed point format to be rounded.
+ * @param n The number of bits to be rounded,
+ * e.g. UQ8.8 -> UQ12.4 => n = 8 - 4 = 4.
+ * @return The rounded value in (U)Qx.n2 format.
+ *****************************************************************************/
+inline uint32_t fp_rndu(uint32_t Q, uint_fast8_t n)
+{
+ if (n == 0) { return Q; }
+
+ else if (n > 32U) { return 0; }
+
+ // Shift by n>=32 yields undefined behavior! Thus, this extra first
+ // step is essential to prevent issues.
+ Q >>= n - 1;
+ return (Q >> 1) + (Q & 1U);
+}
+
+/*!***************************************************************************
+ * @brief Converting with rounding from Qx.n1 to Qx.n2.
+ * @details Equivalent to dividing by 2^n with correct rounding to integer
+ * values.
+ * @param Q The number in (U)Qx.n1 fixed point format to be rounded.
+ * @param n The number of bits to be rounded,
+ * e.g. Q7.8 -> Q11.4 => n = 8 - 4 = 4.
+ * @return The rounded value in (U)Qx.n2 format.
+ *****************************************************************************/
+inline int32_t fp_rnds(int32_t Q, uint_fast8_t n)
+{
+ return (Q < 0) ? -fp_rndu(-Q, n) : fp_rndu(Q, n);
+}
+
+/*!***************************************************************************
+ * @brief Converting with truncation from UQx.n1 to UQx.n2.
+ * @details Equivalent to dividing by 2^n with truncating (throw away) the
+ * fractional part, resulting in an unsigned integer/fixed-point value.
+ * @param Q The number in (U)Qx.n1 fixed point format to be truncated.
+ * @param n The number of bits to be truncated,
+ * e.g. UQ8.8 -> UQ12.4 => n = 8 - 4 = 4.
+ * @return The truncated value in (U)Qx.n2 format.
+ *****************************************************************************/
+inline uint32_t fp_truncu(uint32_t Q, uint_fast8_t n)
+{
+ return (n < 32U) ? (Q >> n) : 0;
+}
+
+/*!***************************************************************************
+ * @brief Converting with truncation from Qx.n1 to Qx.n2.
+ * @details Equivalent to dividing by 2^n with truncating (throw away) the
+ * fractional part, resulting in a signed integer/fixed-point value.
+ * @param Q The number in (U)Qx.n1 fixed point format to be truncated.
+ * @param n The number of bits to be truncated,
+ * e.g. Q7.8 -> Q11.4 => n = 8 - 4 = 4.
+ * @return The truncated value in (U)Qx.n2 format.
+ *****************************************************************************/
+inline int32_t fp_truncs(int32_t Q, uint_fast8_t n)
+{
+ return (Q < 0) ? -fp_truncu(-Q, n) : fp_truncu(Q, n);
+}
+
+/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* FP_RND_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/int_math.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/int_math.h
new file mode 100644
index 0000000000..27de8cc688
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/int_math.h
@@ -0,0 +1,281 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details Provides algorithms applied to integer values.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef INT_MATH
+#define INT_MATH
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!***************************************************************************
+ * @addtogroup argus_misc
+ * @{
+ *****************************************************************************/
+
+#include
+#include
+
+/*! Enables the integer square root function. */
+#ifndef INT_SQRT
+#define INT_SQRT 0
+#endif
+
+/*!***************************************************************************
+ * @brief Integer Base-2 Logarithm.
+ *
+ * @details Calculates the base-2 logarithm for unsigned integer values. The
+ * result is the integer equivalent of floor(log2(x)).
+ *
+ * @param x Input parameter.
+ * @return The floor of the base-2 logarithm.
+ *****************************************************************************/
+inline uint32_t log2i(uint32_t x)
+{
+ assert(x != 0);
+#if 1
+ return 31 - __builtin_clz(x);
+#else
+#define S(k) if (x >= (1 << k)) { i += k; x >>= k; }
+ int i = 0; S(16); S(8); S(4); S(2); S(1); return i;
+#undef S
+#endif
+}
+
+/*!***************************************************************************
+ * @brief Integer Base-2 Logarithm with rounded result.
+ *
+ * @details Calculates the base-2 logarithm for unsigned integer values and
+ * returns the rounded result. The result is the integer equivalent
+ * of round(log2(x)).
+ *
+ * It is finding the nearest power-of-two value s.t. |x - 2^n| becomes
+ * minimum for all n.
+ *
+ * @param x Input parameter.
+ * @return The rounded value of the base-2 logarithm.
+ *****************************************************************************/
+inline uint32_t log2_round(uint32_t x)
+{
+ assert(x != 0);
+#if 0
+ const uint32_t y = x;
+ const uint32_t i = 0;
+
+ while (y >>= 1) { i++; }
+
+#else
+ const uint32_t i = log2i(x);
+#endif
+ return (i + ((x >> (i - 1U)) == 3U));
+}
+
+/*!***************************************************************************
+ * @brief Finding the nearest power-of-two value.
+ *
+ * @details Implemented s.t. |x - 2^n| becomes minimum for all n.
+ * Special case 0: returns 0;
+ * Maximum input: 3037000499; higher number result in overflow! (returns 0)
+ *
+ * @param x Input parameter.
+ * @return Nearest power-of-two number, i.e. 2^n.
+ *****************************************************************************/
+inline uint32_t binary_round(uint32_t x)
+{
+ assert(x != 0);
+ const uint32_t shift = log2_round(x);
+ return (shift > 31U) ? 0 : 1U << shift;
+}
+
+/*!***************************************************************************
+ * @brief Counting bits set in a 32-bit unsigned integer.
+ *
+ * @details @see http://graphics.stanford.edu/~seander/bithacks.html
+ *
+ * @param x Input parameter.
+ * @return Number of bits set in input value.
+ *****************************************************************************/
+inline uint32_t popcount(uint32_t x)
+{
+ // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ x = x - ((x >> 1) & 0x55555555);
+ x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+ return (((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
+}
+
+/*!***************************************************************************
+ * @brief Determining if an integer is a power of 2
+ *
+ * @details @see http://graphics.stanford.edu/~seander/bithacks.html
+ *
+ * @param x Input parameter.
+ * @return True if integer is power of 2.
+ *****************************************************************************/
+inline uint32_t ispowoftwo(uint32_t x)
+{
+ return x && !(x & (x - 1));
+}
+
+/*!***************************************************************************
+ * @brief Calculates the absolute value.
+ *
+ * @param x Input parameter.
+ * @return The absolute value of x.
+ *****************************************************************************/
+inline uint32_t absval(int32_t x)
+{
+ // Note: special case of INT32_MIN must be handled correctly:
+ return x < 0 ? ((~(uint32_t)(x)) + 1) : (uint32_t)x;
+
+ /* alternative with equal performance:*/
+// int32_t y = x >> 31;
+// return (x ^ y) - y;
+ /* wrong implementation:
+ * does not correctly return abs(INT32_MIN) on 32-bit platform */
+// return x < 0 ? (uint32_t)(-x) : (uint32_t)x;
+}
+
+/*!***************************************************************************
+ * @brief Calculates the floor division by a factor of 2: floor(x / 2^n).
+ *
+ * @param x Input parameter.
+ * @param n The shift value, maximum is 31.
+ * @return The floor division by 2^n result.
+ *****************************************************************************/
+inline uint32_t floor2(uint32_t x, uint_fast8_t n)
+{
+ assert(n < 32);
+ return x >> n;
+}
+
+/*!***************************************************************************
+ * @brief Calculates the ceildiv division by a factor of 2: ceildiv(x / 2^n).
+ *
+ * @param x Input parameter.
+ * @param n The shift value, maximum is 31.
+ * @return The ceildiv division by 2^n result.
+ *****************************************************************************/
+inline uint32_t ceiling2(uint32_t x, uint_fast8_t n)
+{
+ assert(n < 32);
+ return x ? (1 + ((x - 1) >> n)) : 0;
+}
+
+/*!***************************************************************************
+ * @brief Calculates the ceildiv division: ceildiv(x / y).
+ *
+ * @param x Numerator
+ * @param y Denominator
+ * @return The result of the ceildiv division ceildiv(x / y).
+ *****************************************************************************/
+inline uint32_t ceildiv(uint32_t x, uint32_t y)
+{
+ assert(y != 0);
+ return x ? (1 + ((x - 1) / y)) : 0;
+}
+
+/*!***************************************************************************
+ * @brief Calculates the maximum of two values.
+ *
+ * @param a Input parameter.
+ * @param b Input parameter.
+ * @return The maximum value of the input parameters.
+ *****************************************************************************/
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+/*!***************************************************************************
+ * @brief Calculates the minimum of two values.
+ *
+ * @param a Input parameter.
+ * @param b Input parameter.
+ * @return The minimum value of the input parameters.
+ *****************************************************************************/
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/*!***************************************************************************
+ * @brief Clamps a value between a minimum and maximum boundary.
+ *
+ * @details Clamps the values such that the condition min <= x <= max is true.
+ *
+ * @note The condition \p min <= \p max must hold!!!
+ *
+ * @param x The input parameter to be clamped.
+ * @param min The minimum or lower boundary.
+ * @param max The maximum or upper boundary.
+ * @return The clamped value of the input parameter within [min,max].
+ *****************************************************************************/
+#define CLAMP(x, min, max) (MIN(MAX((x), (min)), (max)))
+
+#if INT_SQRT
+/*!***************************************************************************
+ * @brief Calculates the integer square root of x.
+ *
+ * @details The integer square root is defined as:
+ * isqrt(x) = (int)sqrt(x)
+ *
+ * @see https://en.wikipedia.org/wiki/Integer_square_root
+ * @see https://github.com/chmike/fpsqrt/blob/master/fpsqrt.c
+ *
+ * @param x Input parameter.
+ * @return isqrt(x)
+ *****************************************************************************/
+inline uint32_t isqrt(uint32_t v)
+{
+ unsigned t, q, b, r;
+ r = v; // r = v - x²
+ b = 0x40000000; // a²
+ q = 0; // 2ax
+
+ while (b > 0) {
+ t = q + b; // t = 2ax + a²
+ q >>= 1; // if a' = a/2, then q' = q/2
+
+ if (r >= t) { // if (v - x²) >= 2ax + a²
+ r -= t; // r' = (v - x²) - (2ax + a²)
+ q += b; // if x' = (x + a) then ax' = ax + a², thus q' = q' + b
+ }
+
+ b >>= 2; // if a' = a/2, then b' = b / 4
+ }
+
+ return q;
+}
+#endif // INT_SQRT
+
+/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* INT_MATH */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/status.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/status.h
new file mode 100644
index 0000000000..ae9a4648f5
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/status.h
@@ -0,0 +1,49 @@
+/*************************************************************************//**
+ * @file
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file contains status codes for all platform specific
+ * functions.
+ *
+ * @copyright
+ *
+ * Copyright (c) 2023, Broadcom Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef STATUS_H
+#define STATUS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "api/argus_status.h"
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* STATUS_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/time.h b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/time.h
index 9c5f930351..1c2fe480e8 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/time.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/Inc/utility/time.h
@@ -1,11 +1,11 @@
/*************************************************************************//**
* @file
- * @brief This file is part of the AFBR-S50 API.
- * @details This file provides utility functions for timing necessities.
+ * @brief This file is part of the AFBR-S50 API.
+ * @details This file provides utility functions for timing necessities.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom Inc
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,255 +36,563 @@
#ifndef TIME_H
#define TIME_H
+#ifdef __cplusplus
+extern "C" {
+#endif
/*!***************************************************************************
- * @defgroup time Time Utility
- * @ingroup argusutil
- * @brief Timer utilities for time measurement duties.
- * @details This module provides time measurement utility functions like
- * delay or time measurement methods, or time math functions.
- * @addtogroup time
+ * @defgroup argus_time Time Utility
+ * @ingroup argus_util
+ *
+ * @brief Timer utilities for time measurement duties.
+ *
+ * @details This module provides time measurement utility functions like
+ * delay or time measurement methods, or time math functions.
+ *
+ * @addtogroup argus_time
* @{
*****************************************************************************/
+#include "platform/argus_timer.h"
+#include
#include
#include
/*!***************************************************************************
- * @brief A data structure to represent current time.
+ * @brief A data structure to represent current time.
*
- * @details Value is obtained from the PIT time which must be configured as
- * lifetime counter.
+ * @details Value is obtained from the PIT time which must be configured as
+ * lifetime counter.
+ *
+ * Range: [0.000000, 4294967296.999999] seconds
*****************************************************************************/
-typedef struct {
- /*! Seconds. */
+typedef struct ltc_t {
+ /*! Seconds;
+ * Range: [0, UINT32_MAX] seconds */
uint32_t sec;
- /*! Microseconds. */
+ /*! Microseconds;
+ * Range: [0, 999999] microseconds */
uint32_t usec;
} ltc_t;
/*!***************************************************************************
- * @brief Obtains the elapsed time since MCU startup.
- * @param t_now returned current time
+ * @brief Converts #ltc_t to microseconds (uint32_t).
+ * @details The specified time value (type #ltc_t) is converted to microseconds.
+ * The value is truncated to UINT32_MAX value if the result would
+ * exceed UINT32_MAX microseconds.
+ * @param t Input #ltc_t structure.
+ * @return Time value in microseconds.
*****************************************************************************/
-void Time_GetNow(ltc_t *t_now);
+inline uint32_t Time_ToUSec(ltc_t const *t)
+{
+ assert(t != 0);
+
+ // max. value to convert correctly is 4294.967295 sec (UINT32_MAX/1000000)
+ return ((t->sec < 4294U) || (t->sec == 4294U && t->usec < 967295U)) ?
+ t->usec + t->sec * 1000000U : UINT32_MAX;
+}
/*!***************************************************************************
- * @brief Obtains the elapsed microseconds since MCU startup.
- * @details Wrap around effect due to uint32_t result format!!
- * @param -
- * @return Elapsed microseconds since MCU startup as uint32_t.
+ * @brief Converts #ltc_t to milliseconds (uint32_t).
+ * @details The specified time value (type #ltc_t) is converted to milliseconds.
+ * The value is truncated to UINT32_MAX value if the result would
+ * exceed UINT32_MAX milliseconds.
+ * The returned value is correctly rounded to the nearest value.
+ * @param t Input #ltc_t structure.
+ * @return Time value in milliseconds.
*****************************************************************************/
-uint32_t Time_GetNowUSec(void);
+inline uint32_t Time_ToMSec(ltc_t const *t)
+{
+ assert(t != 0);
+
+ // max. value to convert correctly is 4294967.295499 sec (UINT32_MAX/1000)
+ return ((t->sec < 4294967U) || (t->sec == 4294967U && t->usec < 295500U)) ?
+ (t->usec + 500U) / 1000U + t->sec * 1000U : UINT32_MAX;
+}
/*!***************************************************************************
- * @brief Obtains the elapsed milliseconds since MCU startup.
- * @details Wrap around effect due to uint32_t result format!!
- * @param -
- * @return Elapsed milliseconds since MCU startup as uint32_t.
+ * @brief Converts #ltc_t to seconds (uint32_t).
+ * @details The specified time value (type #ltc_t) is converted to seconds.
+ * The returned value is correctly rounded to the nearest value.
+ * @param t Input #ltc_t structure.
+ * @return Time value in seconds.
*****************************************************************************/
-uint32_t Time_GetNowMSec(void);
+inline uint32_t Time_ToSec(ltc_t const *t)
+{
+ assert(t != 0);
+
+ // max. value to convert correctly is 4294967295.499999 sec (UINT32_MAX/1000)
+ return (t->sec < 4294967295U || t->usec < 500000U) ?
+ (t->usec + 500000U) / 1000000U + t->sec : UINT32_MAX;
+}
/*!***************************************************************************
- * @brief Obtains the elapsed seconds since MCU startup.
- * @param -
- * @return Elapsed seconds since MCU startup as uint32_t.
+ * @brief Converts microseconds (uint32_t) to #ltc_t.
+ * @details The specified time value in microseconds is converted to type #ltc_t.
+ * @param t Output #ltc_t structure.
+ * @param t_usec Input time in microseconds.
*****************************************************************************/
-uint32_t Time_GetNowSec(void);
+inline void Time_FromUSec(ltc_t *t, uint32_t t_usec)
+{
+ assert(t != 0);
+ t->sec = t_usec / 1000000U;
+ t->usec = t_usec % 1000000U;
+}
/*!***************************************************************************
- * @brief Obtains the elapsed time since a given time point.
- * @param t_elapsed Returns the elapsed time since t_start.
- * @param t_start Start time point.
+ * @brief Converts milliseconds (uint32_t) to #ltc_t.
+ * @details The specified time value in milliseconds is converted to type #ltc_t.
+ * @param t Output #ltc_t structure.
+ * @param t_msec Input time in milliseconds.
*****************************************************************************/
-void Time_GetElapsed(ltc_t *t_elapsed, ltc_t const *t_start);
+inline void Time_FromMSec(ltc_t *t, uint32_t t_msec)
+{
+ assert(t != 0);
+ t->sec = t_msec / 1000U;
+ t->usec = (t_msec % 1000U) * 1000U;
+}
/*!***************************************************************************
- * @brief Obtains the elapsed microseconds since a given time point.
- * @details Wrap around effect due to uint32_t result format!!
- * @param t_start Start time point.
- * @return Elapsed microseconds since t_start as uint32_t.
+ * @brief Converts seconds (uint32_t) to #ltc_t.
+ * @details The specified time value in seconds is converted to type #ltc_t.
+ * @param t Output #ltc_t structure.
+ * @param t_sec Input time in seconds.
*****************************************************************************/
-uint32_t Time_GetElapsedUSec(ltc_t const *t_start);
+inline void Time_FromSec(ltc_t *t, uint32_t t_sec)
+{
+ assert(t != 0);
+ t->usec = 0;
+ t->sec = t_sec;
+}
+
/*!***************************************************************************
- * @brief Obtains the elapsed milliseconds since a given time point.
- * @details Wrap around effect due to uint32_t result format!!
- * @param t_start Start time point.
- * @return Elapsed milliseconds since t_start as uint32_t.
+ * @brief Checks if /p t1 is greater or equal that /p t2.
+ * @details Handles overflow.
+ * @param t1 1st operand.
+ * @param t2 2nd operand.
+ * @return Returns (t1 >= t2);
*****************************************************************************/
-uint32_t Time_GetElapsedMSec(ltc_t const *t_start);
+inline bool Time_GreaterEqual(ltc_t const *t1, ltc_t const *t2)
+{
+ assert(t1 != 0);
+ assert(t2 != 0);
+ return (t1->sec == t2->sec) ? (t1->usec >= t2->usec) : (t1->sec > t2->sec);
+}
+
/*!***************************************************************************
- * @brief Obtains the elapsed seconds since a given time point.
- * @param t_start Start time point.
- * @return Elapsed seconds since t_start as uint32_t.
+ * @brief Obtains the elapsed time since MCU startup.
+ * @param t_now returned current time
*****************************************************************************/
-uint32_t Time_GetElapsedSec(ltc_t const *t_start);
+inline void Time_GetNow(ltc_t *t_now)
+{
+ assert(t_now != 0);
+ Timer_GetCounterValue(&(t_now->sec), &(t_now->usec));
+ assert(t_now->usec < 1000000U);
+}
/*!***************************************************************************
- * @brief Obtains the time difference between two given time points.
- * @details Result is defined as t_diff = t_end - t_start.
- * Note: since no negative time differences are supported, t_end has
- * to be later/larger than t_start. Otherwise, the result won't be
- * a negative time span but given by max value.
- * @param t_diff Returned time difference.
- * @param t_start Start time point.
- * @param t_end End time point.
+ * @brief Obtains the elapsed time since MCU startup.
+ * @return Returns the current time.
*****************************************************************************/
-void Time_Diff(ltc_t *t_diff, ltc_t const *t_start, ltc_t const *t_end);
+inline ltc_t Time_Now(void)
+{
+ ltc_t t_now;
+ Time_GetNow(&t_now);
+ return t_now;
+}
/*!***************************************************************************
- * @brief Obtains the time difference between two given time points in
- * microseconds.
- * @details Result is defined as t_diff = t_end - t_start.
- * Refers to Time_Diff() and handles overflow such that to large
- * values are limited by 0xFFFFFFFF µs.
- * @param t_start Start time point.
- * @param t_end End time point.
- * @return Time difference in microseconds.
+ * @brief Obtains the elapsed microseconds since MCU startup.
+ * @details Wrap around effect due to uint32_t result format!!
+ * @return Elapsed microseconds since MCU startup as uint32_t.
*****************************************************************************/
-uint32_t Time_DiffUSec(ltc_t const *t_start, ltc_t const *t_end);
+inline uint32_t Time_GetNowUSec(void)
+{
+ ltc_t t_now = Time_Now();
+ return Time_ToUSec(&t_now);
+}
/*!***************************************************************************
- * @brief Obtains the time difference between two given time points in
- * milliseconds.
- * @details Result is defined as t_diff = t_end - t_start.
- * Refers to Time_Diff() and handles overflow.
- * Wrap around effect due to uint32_t result format!!
- * @param t_start Start time point.
- * @param t_end End time point.
- * @return Time difference in milliseconds.
+ * @brief Obtains the elapsed milliseconds (rounded) since MCU startup.
+ * @details Wrap around effect due to uint32_t result format!!
+ * @return Elapsed milliseconds since MCU startup as uint32_t.
*****************************************************************************/
-uint32_t Time_DiffMSec(ltc_t const *t_start, ltc_t const *t_end);
+inline uint32_t Time_GetNowMSec(void)
+{
+ ltc_t t_now = Time_Now();
+ return Time_ToMSec(&t_now);
+}
/*!***************************************************************************
- * @brief Obtains the time difference between two given time points in
- * seconds.
- * @details Result is defined as t_diff = t_end - t_start.
- * Refers to Time_Diff() and handles overflow.
- * @param t_start Start time point.
- * @param t_end End time point.
- * @return Time difference in seconds.
+ * @brief Obtains the elapsed seconds (rounded) since MCU startup.
+ * @return Elapsed seconds since MCU startup as uint32_t.
*****************************************************************************/
-uint32_t Time_DiffSec(ltc_t const *t_start, ltc_t const *t_end);
+inline uint32_t Time_GetNowSec(void)
+{
+ ltc_t t_now = Time_Now();
+ return Time_ToSec(&t_now);
+}
+
/*!***************************************************************************
- * @brief Time delay for a given time period.
- * @param dt Delay time.
+ * @brief Obtains the time difference between two given time points.
+ * @details Result is defined as t_diff = t_end - t_start.
+ * Note: since no negative time differences are supported, t_end has
+ * to be later/larger than t_start. Otherwise, the result is undefined!
+ * @param t_diff Returned time difference.
+ * @param t_start Start time point.
+ * @param t_end End time point.
*****************************************************************************/
-void Time_Delay(ltc_t const *dt);
+inline void Time_Diff(ltc_t *t_diff, ltc_t const *t_start, ltc_t const *t_end)
+{
+ assert(t_diff != 0);
+ assert(t_start != 0);
+ assert(t_end != 0);
+ assert(t_diff != t_start);
+ assert(t_diff != t_end);
+ assert(Time_GreaterEqual(t_end, t_start));
+
+ if (t_start->usec <= t_end->usec) { // no carry over
+ t_diff->sec = t_end->sec - t_start->sec;
+ t_diff->usec = t_end->usec - t_start->usec;
+
+ } else { // with carry over
+ t_diff->sec = t_end->sec - 1 - t_start->sec;
+ t_diff->usec = (1000000U - t_start->usec) + t_end->usec;
+ }
+}
/*!***************************************************************************
- * @brief Time delay for a given time period in microseconds.
- * @param dt_usec Delay time in microseconds.
+ * @brief Obtains the time difference between two given time points in
+ * microseconds.
+ * @details Result is defined as t_diff = t_end - t_start.
+ * Refers to Time_Diff() and handles overflow such that to large
+ * values are limited by 0xFFFFFFFF µs.
+ * @param t_start Start time point.
+ * @param t_end End time point.
+ * @return Time difference in microseconds.
*****************************************************************************/
-void Time_DelayUSec(uint32_t dt_usec);
+inline uint32_t Time_DiffUSec(ltc_t const *t_start, ltc_t const *t_end)
+{
+ ltc_t t_diff;
+ Time_Diff(&t_diff, t_start, t_end);
+ return Time_ToUSec(&t_diff);
+}
/*!***************************************************************************
- * @brief Time delay for a given time period in milliseconds.
- * @param dt_msec Delay time in milliseconds.
+ * @brief Obtains the time difference between two given time points in
+ * milliseconds.
+ * @details Result is defined as t_diff = t_end - t_start.
+ * Refers to Time_Diff() and handles overflow.
+ * Wrap around effect due to uint32_t result format!!
+ * @param t_start Start time point.
+ * @param t_end End time point.
+ * @return Time difference in milliseconds.
*****************************************************************************/
-void Time_DelayMSec(uint32_t dt_msec);
+inline uint32_t Time_DiffMSec(ltc_t const *t_start, ltc_t const *t_end)
+{
+ ltc_t t_diff;
+ Time_Diff(&t_diff, t_start, t_end);
+ return Time_ToMSec(&t_diff);
+}
/*!***************************************************************************
- * @brief Time delay for a given time period in seconds.
- * @param dt_sec Delay time in seconds.
+ * @brief Obtains the time difference between two given time points in
+ * seconds.
+ * @details Result is defined as t_diff = t_end - t_start.
+ * Refers to Time_Diff() and handles overflow.
+ * @param t_start Start time point.
+ * @param t_end End time point.
+ * @return Time difference in seconds.
*****************************************************************************/
-void Time_DelaySec(uint32_t dt_sec);
+inline uint32_t Time_DiffSec(ltc_t const *t_start, ltc_t const *t_end)
+{
+ ltc_t t_diff;
+ Time_Diff(&t_diff, t_start, t_end);
+ return Time_ToSec(&t_diff);
+}
+
/*!***************************************************************************
- * @brief Checks if timeout is reached from a given starting time.
- * @details Handles overflow.
- * @param t_start Start time.
- * @param t_timeout Timeout period.
- * @return Timeout elapsed? True/False (boolean value)
+ * @brief Obtains the elapsed time since a given time point.
+ * @details Calculates the currently elapsed time since a specified start time
+ * (/p t_start).
+ *
+ * Note that /p t_start must be in the past! Otherwise, the behavior is
+ * undefined!
+ *
+ * @param t_elapsed Returns the elapsed time since /p t_start.
+ * @param t_start Start time point.
*****************************************************************************/
-bool Time_CheckTimeout(ltc_t const *t_start, ltc_t const *t_timeout);
+inline void Time_GetElapsed(ltc_t *t_elapsed, ltc_t const *t_start)
+{
+ assert(t_elapsed != 0);
+ assert(t_start != 0);
+ assert(t_elapsed != t_start);
+ ltc_t t_now = Time_Now();
+ Time_Diff(t_elapsed, t_start, &t_now);
+}
/*!***************************************************************************
- * @brief Checks if timeout is reached from a given starting time.
- * @details Handles overflow.
- * @param t_start Start time.
- * @param t_timeout_usec Timeout period in microseconds.
- * @return Timeout elapsed? True/False (boolean value)
+ * @brief Obtains the elapsed microseconds since a given time point.
+ * @details Wrap around effect due to uint32_t result format!!
+ * @param t_start Start time point.
+ * @return Elapsed microseconds since t_start as uint32_t.
*****************************************************************************/
-bool Time_CheckTimeoutUSec(ltc_t const *t_start, uint32_t const t_timeout_usec);
+inline uint32_t Time_GetElapsedUSec(ltc_t const *t_start)
+{
+ assert(t_start != 0);
+ ltc_t t_now = Time_Now();
+ return Time_DiffUSec(t_start, &t_now);
+}
/*!***************************************************************************
- * @brief Checks if timeout is reached from a given starting time.
- * @details Handles overflow.
- * @param t_start Start time.
- * @param t_timeout_msec Timeout period in milliseconds.
- * @return Timeout elapsed? True/False (boolean value)
+ * @brief Obtains the elapsed milliseconds since a given time point.
+ * @details Wrap around effect due to uint32_t result format!!
+ * @param t_start Start time point.
+ * @return Elapsed milliseconds since t_start as uint32_t.
*****************************************************************************/
-bool Time_CheckTimeoutMSec(ltc_t const *t_start, uint32_t const t_timeout_msec);
+inline uint32_t Time_GetElapsedMSec(ltc_t const *t_start)
+{
+ assert(t_start != 0);
+ ltc_t t_now = Time_Now();
+ return Time_DiffMSec(t_start, &t_now);
+}
/*!***************************************************************************
- * @brief Checks if timeout is reached from a given starting time.
- * @details Handles overflow.
- * @param t_start Start time.
- * @param t_timeout_sec Timeout period in seconds.
- * @return Timeout elapsed? True/False (boolean value)
+ * @brief Obtains the elapsed seconds since a given time point.
+ * @param t_start Start time point.
+ * @return Elapsed seconds since t_start as uint32_t.
*****************************************************************************/
-bool Time_CheckTimeoutSec(ltc_t const *t_start, uint32_t const t_timeout_sec);
+inline uint32_t Time_GetElapsedSec(ltc_t const *t_start)
+{
+ assert(t_start != 0);
+ ltc_t t_now = Time_Now();
+ return Time_DiffSec(t_start, &t_now);
+}
+
/*!***************************************************************************
- * @brief Adds two ltc_t values.
- * @details Result is defined as t = t1 + t2. Results are wrapped around at
- * maximum values just like integers.
- * @param t Return value: t = t1 + t2.
- * @param t1 1st operand.
- * @param t2 2nd operand.
+ * @brief Adds two #ltc_t values.
+ * @details Result is defined as t = t1 + t2.
+ * The results are wrapped around at maximum values just like integers.
+ * The references for t, t1 and t2 may point to the same instance(s).
+ *
+ * @param t Return value: t = t1 + t2.
+ * @param t1 1st operand.
+ * @param t2 2nd operand.
*****************************************************************************/
-void Time_Add(ltc_t *t, ltc_t const *t1, ltc_t const *t2);
+inline void Time_Add(ltc_t *t, ltc_t const *t1, ltc_t const *t2)
+{
+ assert(t != 0);
+ assert(t1 != 0);
+ assert(t2 != 0);
+
+ t->sec = t1->sec + t2->sec;
+ t->usec = t1->usec + t2->usec;
+
+ if (t->usec > 999999U) {
+ t->sec += 1U;
+ t->usec -= 1000000U;
+ }
+}
/*!***************************************************************************
- * @brief Adds a given time in microseconds to an ltc_t value.
- * @param t Return value: t = t1 + t2.
- * @param t1 1st operand.
- * @param t2_usec 2nd operand in microseconds.
+ * @brief Adds a given time in microseconds to an #ltc_t value.
+ * @details Result is defined as t = t1 + t2.
+ * The results are wrapped around at maximum values just like integers.
+ * The references for t and t1 may point to the same instance.
+ *
+ * @param t Return value: t = t1 + t2.
+ * @param t1 1st operand.
+ * @param t2_usec 2nd operand in microseconds.
*****************************************************************************/
-void Time_AddUSec(ltc_t *t, ltc_t const *t1, uint32_t t2_usec);
+inline void Time_AddUSec(ltc_t *t, ltc_t const *t1, uint32_t t2_usec)
+{
+ assert(t != 0);
+ assert(t1 != 0);
+ ltc_t t2;
+ Time_FromUSec(&t2, t2_usec);
+ Time_Add(t, t1, &t2);
+}
/*!***************************************************************************
- * @brief Adds a given time in milliseconds to an ltc_t value.
- * @param t Return value: t = t1 + t2.
- * @param t1 1st operand.
- * @param t2_msec 2nd operand in milliseconds.
+ * @brief Adds a given time in milliseconds to an #ltc_t value.
+ * @details Result is defined as t = t1 + t2.
+ * The results are wrapped around at maximum values just like integers.
+ * The references for t and t1 may point to the same instance.
+ *
+ * @param t Return value: t = t1 + t2.
+ * @param t1 1st operand.
+ * @param t2_msec 2nd operand in milliseconds.
*****************************************************************************/
-void Time_AddMSec(ltc_t *t, ltc_t const *t1, uint32_t t2_msec);
+inline void Time_AddMSec(ltc_t *t, ltc_t const *t1, uint32_t t2_msec)
+{
+ assert(t != 0);
+ assert(t1 != 0);
+ ltc_t t2;
+ Time_FromMSec(&t2, t2_msec);
+ Time_Add(t, t1, &t2);
+}
/*!***************************************************************************
- * @brief Adds a given time in seconds to an ltc_t value.
- * @param t Return value: t = t1 + t2.
- * @param t1 1st operand.
- * @param t2_sec 2nd operand in seconds.
+ * @brief Adds a given time in seconds to an #ltc_t value.
+ * @details Result is defined as t = t1 + t2.
+ * The results are wrapped around at maximum values just like integers.
+ * The references for t and t1 may point to the same instance.
+ *
+ * @param t Return value: t = t1 + t2.
+ * @param t1 1st operand.
+ * @param t2_sec 2nd operand in seconds.
*****************************************************************************/
-void Time_AddSec(ltc_t *t, ltc_t const *t1, uint32_t t2_sec);
+inline void Time_AddSec(ltc_t *t, ltc_t const *t1, uint32_t t2_sec)
+{
+ assert(t != 0);
+ assert(t1 != 0);
+ ltc_t t2;
+ Time_FromSec(&t2, t2_sec);
+ Time_Add(t, t1, &t2);
+}
+
/*!***************************************************************************
- * @brief Converts ltc_t to microseconds (uint32_t).
- * @param t Input ltc_t struct.
- * @return Time value in microseconds.
+ * @brief Checks if /p t is within the time interval /p t_start and /p t_end.
+ * @details The interval is from /p t_start to /p t_end.
+ * The function returns true if /p t >= /p t_start AND /p t < /p t_end.
+ * If /p t_end is before /p t_start, /p t_end is consider to be wrapped
+ * around and the condition inverts (i.e. the function returns true if
+ * /p < /p t_end OR /p t >= t_start.
+ * @param t_start The start of the time interval.
+ * @param t_end The end of the time interval.
+ * @param t The time to be checked if it is with the interval.
+ * @return True if t is within t_start and t_stop.
*****************************************************************************/
-uint32_t Time_ToUSec(ltc_t const *t);
+inline bool Time_CheckWithin(ltc_t const *t_start, ltc_t const *t_end, ltc_t const *t)
+{
+ if (Time_GreaterEqual(t_end, t_start)) {
+ return Time_GreaterEqual(t, t_start) && !Time_GreaterEqual(t, t_end);
+
+ } else {
+ return Time_GreaterEqual(t, t_start) || !Time_GreaterEqual(t, t_end);
+ }
+}
+
/*!***************************************************************************
- * @brief Converts ltc_t to milliseconds (uint32_t).
- * @param t Input ltc_t struct.
- * @return Time value in milliseconds.
+ * @brief Checks if timeout is reached from a given starting time.
+ * @details Checks if a specified time (/p t_timeout) has elapsed since a
+ * specified start time (/p t_start).
+ * Handles overflow/wraparound of time values at the maximum value.
+ * @param t_start Start time.
+ * @param t_timeout Timeout period.
+ * @return Timeout elapsed? True/False (boolean value)
*****************************************************************************/
-uint32_t Time_ToMSec(ltc_t const *t);
+inline bool Time_CheckTimeout(ltc_t const *t_start, ltc_t const *t_timeout)
+{
+ assert(t_start != 0);
+ assert(t_timeout != 0);
+
+ ltc_t t_end;
+ ltc_t t_now = Time_Now();
+ Time_Add(&t_end, t_start, t_timeout);
+ return !Time_CheckWithin(t_start, &t_end, &t_now);
+}
/*!***************************************************************************
- * @brief Converts ltc_t to seconds (uint32_t).
- * @param t Input ltc_t struct.
- * @return Time value in seconds.
+ * @brief Checks if timeout is reached from a given starting time.
+ * @details Handles overflow.
+ * @param t_start Start time.
+ * @param t_timeout_usec Timeout period in microseconds.
+ * @return Timeout elapsed? True/False (boolean value)
*****************************************************************************/
-uint32_t Time_ToSec(ltc_t const *t);
+inline bool Time_CheckTimeoutUSec(ltc_t const *t_start, uint32_t const t_timeout_usec)
+{
+ ltc_t t_timeout;
+ Time_FromUSec(&t_timeout, t_timeout_usec);
+ return Time_CheckTimeout(t_start, &t_timeout);
+}
+
+/*!***************************************************************************
+ * @brief Checks if timeout is reached from a given starting time.
+ * @details Handles overflow.
+ * @param t_start Start time.
+ * @param t_timeout_msec Timeout period in milliseconds.
+ * @return Timeout elapsed? True/False (boolean value)
+ *****************************************************************************/
+inline bool Time_CheckTimeoutMSec(ltc_t const *t_start, uint32_t const t_timeout_msec)
+{
+ ltc_t t_timeout;
+ Time_FromMSec(&t_timeout, t_timeout_msec);
+ return Time_CheckTimeout(t_start, &t_timeout);
+}
+
+/*!***************************************************************************
+ * @brief Checks if timeout is reached from a given starting time.
+ * @details Handles overflow.
+ * @param t_start Start time.
+ * @param t_timeout_sec Timeout period in seconds.
+ * @return Timeout elapsed? True/False (boolean value)
+ *****************************************************************************/
+inline bool Time_CheckTimeoutSec(ltc_t const *t_start, uint32_t const t_timeout_sec)
+{
+ ltc_t t_timeout;
+ Time_FromSec(&t_timeout, t_timeout_sec);
+ return Time_CheckTimeout(t_start, &t_timeout);
+}
+
+
+/*!***************************************************************************
+ * @brief Time delay for a given time period.
+ * @param dt Delay time.
+ *****************************************************************************/
+inline void Time_Delay(ltc_t const *dt)
+{
+ assert(dt != 0);
+ ltc_t t_start = Time_Now();
+
+ while (!Time_CheckTimeout(&t_start, dt));
+}
+
+/*!***************************************************************************
+ * @brief Time delay for a given time period in microseconds.
+ * @param dt_usec Delay time in microseconds.
+ *****************************************************************************/
+inline void Time_DelayUSec(uint32_t dt_usec)
+{
+ ltc_t t_start = Time_Now();
+
+ while (!Time_CheckTimeoutUSec(&t_start, dt_usec));
+}
+
+/*!***************************************************************************
+ * @brief Time delay for a given time period in milliseconds.
+ * @param dt_msec Delay time in milliseconds.
+ *****************************************************************************/
+inline void Time_DelayMSec(uint32_t dt_msec)
+{
+ ltc_t t_start = Time_Now();
+
+ while (!Time_CheckTimeoutMSec(&t_start, dt_msec));
+}
+
+/*!***************************************************************************
+ * @brief Time delay for a given time period in seconds.
+ * @param dt_sec Delay time in seconds.
+ *****************************************************************************/
+inline void Time_DelaySec(uint32_t dt_sec)
+{
+ ltc_t t_start = Time_Now();
+
+ while (!Time_CheckTimeoutSec(&t_start, dt_sec));
+}
+
/*! @} */
+#ifdef __cplusplus
+} // extern "C"
+#endif
#endif /* TIME_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu.a b/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu.a
index c646ab3116..e4e6dc0c52 100644
Binary files a/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu.a and b/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu.a differ
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu_os.a b/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu_os.a
index 905b2fa66d..23bcd6fbea 100644
Binary files a/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu_os.a and b/src/drivers/distance_sensor/broadcom/afbrs50/Lib/libafbrs50_m4_fpu_os.a differ
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.c b/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.c
index 5f8fd4b1f1..2e0e8dff16 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.c
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.c
@@ -1,10 +1,10 @@
/*************************************************************************//**
- * @file argus_hal_test.c
- * @brief Tests for the AFBR-S50 API hardware abstraction layer.
+ * @file
+ * @brief Tests for the AFBR-S50 API hardware abstraction layer.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom, Inc.
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
+/*!***************************************************************************
+ * @addtogroup argus_test
+ * @{
+ *****************************************************************************/
/*******************************************************************************
* Include Files
@@ -46,44 +50,44 @@
#include "platform/argus_nvm.h"
#include "platform/argus_irq.h"
-#include
-#include
-#include
-
/*******************************************************************************
* Definitions
******************************************************************************/
-/*! An error log message via print(); */
+/*! An error log message via #print function. */
#define error_log(fmt, ...) print("ERROR: " fmt "\n", ##__VA_ARGS__)
/*******************************************************************************
* Prototypes
******************************************************************************/
+static status_t VerifyHALImplementation(s2pi_slave_t spi_slave);
+
static status_t TimerPlausibilityTest(void);
static status_t TimerWraparoundTest(void);
static status_t SpiConnectionTest(s2pi_slave_t slave);
-static status_t SpiInterruptTest(s2pi_slave_t slave);
+static status_t SpiMaxLengthTest(s2pi_slave_t slave);
+//static status_t SpiInterruptTest(s2pi_slave_t slave);
+static status_t GpioInterruptTest(s2pi_slave_t slave);
static status_t GpioModeTest(s2pi_slave_t slave);
static status_t TimerTest(s2pi_slave_t slave);
static status_t PITTest(void);
+static status_t SpiTransferFromInterruptTest(s2pi_slave_t slave);
static status_t CheckTimerCounterValues(uint32_t hct, uint32_t lct);
-static status_t SPITransferSync(s2pi_slave_t slave, uint8_t *data, uint8_t size);
+static status_t SPITransferSync(s2pi_slave_t slave, uint8_t *data, size_t size);
static status_t ConfigureDevice(s2pi_slave_t slave, int8_t rcoTrim);
-static status_t TriggerMeasurement(s2pi_slave_t slave, uint16_t samples);
-static status_t AwaitDataReady(s2pi_slave_t slave, uint32_t timeout_ms);
+static status_t TriggerMeasurement(s2pi_slave_t slave, uint16_t samples, s2pi_callback_t callback, void *callbackData);
static status_t ReadEEPROM(s2pi_slave_t slave, uint8_t *eeprom);
static status_t ReadRcoTrim(s2pi_slave_t slave, int8_t *RcoTrim);
static status_t RunMeasurement(s2pi_slave_t slave, uint16_t samples);
static status_t RunPITTest(uint32_t exp_dt_us, uint32_t n);
static void PIT_Callback(void *param);
-static void DataReadyCallback(void *param);
+static void GPIO_Callback(void *param);
/// @cond EXTERN
extern uint32_t EEPROM_ReadChipId(uint8_t const *eeprom);
-extern argus_module_version_t EEPROM_ReadModule(uint8_t const *eeprom);
+extern uint8_t EEPROM_ReadModule(uint8_t const *eeprom);
extern status_t EEPROM_Read(s2pi_slave_t slave, uint8_t address, uint8_t *data);
extern uint8_t hamming_decode(uint8_t const *code, uint8_t *data);
/// @endcond
@@ -98,99 +102,129 @@ extern uint8_t hamming_decode(uint8_t const *code, uint8_t *data);
status_t Argus_VerifyHALImplementation(s2pi_slave_t spi_slave)
{
- status_t status = STATUS_OK;
+ print("########################################################\n");
+ print("# Running HAL Verification Test - " HAL_TEST_VERSION "\n");
+ print("########################################################\n");
+ print("- SPI Slave: %d \n\n", spi_slave);
- PX4_INFO_RAW("########################################################\n");
- PX4_INFO_RAW("# Running HAL Verification Test - " HAL_TEST_VERSION "\n");
- PX4_INFO_RAW("########################################################\n\n");
+ const status_t status = VerifyHALImplementation(spi_slave);
- PX4_INFO_RAW("1 > Timer Plausibility Test\n");
- status = TimerPlausibilityTest();
-
- if (status != STATUS_OK) { goto summary; }
-
- PX4_INFO_RAW("1 > PASS\n\n");
-
- PX4_INFO_RAW("2 > Timer Wraparound Test\n");
- status = TimerWraparoundTest();
-
- if (status != STATUS_OK) { goto summary; }
-
- PX4_INFO_RAW("2 > PASS\n\n");
-
- PX4_INFO_RAW("3 > SPI Connection Test\n");
- status = SpiConnectionTest(spi_slave);
-
- if (status != STATUS_OK) { goto summary; }
-
- PX4_INFO_RAW("3 > PASS\n\n");
-
- PX4_INFO_RAW("4 > SPI Interrupt Test\n");
- status = SpiInterruptTest(spi_slave);
-
- if (status != STATUS_OK) { goto summary; }
-
- PX4_INFO_RAW("4 > PASS\n\n");
-
- PX4_INFO_RAW("5 > GPIO Mode Test\n");
- status = GpioModeTest(spi_slave);
-
- if (status != STATUS_OK) { goto summary; }
-
- PX4_INFO_RAW("5 > PASS\n\n");
-
- PX4_INFO_RAW("6 > Lifetime Counter Timer (LTC) Test\n");
- status = TimerTest(spi_slave);
-
- if (status != STATUS_OK) { goto summary; }
-
- PX4_INFO_RAW("6 > PASS\n\n");
-
- PX4_INFO_RAW("7 > Periodic Interrupt Timer (PIT) Test\n");
- status = PITTest();
-
- if (status == ERROR_NOT_IMPLEMENTED) {
- PX4_INFO_RAW("7 > SKIPPED (PIT is not implemented)\n\n");
-
- } else {
- if (status != STATUS_OK) { goto summary; }
-
- PX4_INFO_RAW("7 > PASS\n\n");
- }
-
-
-summary:
- PX4_INFO_RAW("########################################################\n");
+ print("########################################################\n");
if (status != STATUS_OK) {
- PX4_INFO_RAW("# FAIL: HAL Verification Test finished with error %d!\n", (int)status);
+ print("# FAIL: HAL Verification Test finished with error %d!\n", status);
} else {
- PX4_INFO_RAW("# PASS: HAL Verification Test finished successfully!\n");
+ print("# PASS: HAL Verification Test finished successfully!\n");
}
- PX4_INFO_RAW("########################################################\n\n");
+ print("########################################################\n\n");
+
return status;
}
/*!***************************************************************************
- * @brief Checks the validity of timer counter values.
+ * @brief Executes a series of tests in order to verify the HAL implementation.
*
- * @details This verifies that the counter values returned from the
- * #Timer_GetCounterValue function are valid. This means, the low
- * counter value \p lct is within 0 and 999999 µs.
+ * @details See #Argus_VerifyHALImplementation for details.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_FAIL on failure (check the error log for more information).
+ * @param spi_slave The SPI hardware slave.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ *****************************************************************************/
+static status_t VerifyHALImplementation(s2pi_slave_t spi_slave)
+{
+ status_t status = STATUS_OK;
+
+ print("1 > Timer Plausibility Test\n");
+ status = TimerPlausibilityTest();
+
+ if (status != STATUS_OK) { return status; }
+
+ print("1 > PASS\n\n");
+
+ print("2 > Timer Wraparound Test\n");
+ status = TimerWraparoundTest();
+
+ if (status != STATUS_OK) { return status; }
+
+ print("2 > PASS\n\n");
+
+ print("3 > SPI Connection Test\n");
+ status = SpiConnectionTest(spi_slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print("3 > PASS\n\n");
+
+ print("4 > SPI Maximum Data Length Test\n");
+ status = SpiMaxLengthTest(spi_slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print("4 > PASS\n\n");
+
+ print("5 > GPIO Interrupt Test\n");
+ status = GpioInterruptTest(spi_slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print("5 > PASS\n\n");
+
+ print("6 > GPIO Mode Test\n");
+ status = GpioModeTest(spi_slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print("6 > PASS\n\n");
+
+ print("7 > Lifetime Counter Timer (LTC) Test\n");
+ status = TimerTest(spi_slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print("7 > PASS\n\n");
+
+ print("8 > Periodic Interrupt Timer (PIT) Test\n");
+ status = PITTest();
+
+ if (status == ERROR_NOT_IMPLEMENTED) {
+ print("8 > SKIPPED (PIT is not implemented)\n\n");
+
+ } else {
+ if (status != STATUS_OK) { return status; }
+
+ print("8 > PASS\n\n");
+ }
+
+ print("9 > SPI Interrupt Test\n");
+ status = SpiTransferFromInterruptTest(spi_slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print("9 > PASS\n\n");
+
+ return status;
+}
+
+/*!***************************************************************************
+ * @brief Checks the validity of timer counter values.
+ *
+ * @details This verifies that the counter values returned from the
+ * #Timer_GetCounterValue function are valid. This means, the low
+ * counter value \p lct is within 0 and 999999 µs.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_FAIL on failure (check the error log for more information).
*****************************************************************************/
static status_t CheckTimerCounterValues(uint32_t hct, uint32_t lct)
{
if (lct > 999999) {
- PX4_INFO_RAW("Timer plausibility check:\n"
- "The parameter \"lct\" of Timer_GetCounterValue() must always "
- "be within 0 and 999999.\n"
- "Current Values: hct = %d, lct = %d", (uint)hct, (uint)lct);
+ error_log("Timer plausibility check:\n"
+ "The parameter \"lct\" of Timer_GetCounterValue() must always "
+ "be within 0 and 999999.\n"
+ "Current Values: hct = %d, lct = %d", hct, lct);
return ERROR_FAIL;
}
@@ -198,24 +232,24 @@ static status_t CheckTimerCounterValues(uint32_t hct, uint32_t lct)
}
/*!***************************************************************************
- * @brief Plausibility Test for Timer HAL Implementation.
+ * @brief Plausibility Test for Timer HAL Implementation.
*
- * @details Rudimentary tests the lifetime counter (LTC) implementation.
- * This verifies that the LTC is running by checking if the returned
- * values of two consecutive calls to the #Timer_GetCounterValue
- * function are ascending. An artificial delay using the NOP operation
- * is induced such that the timer is not read to fast.
+ * @details Rudimentary tests the lifetime counter (LTC) implementation.
+ * This verifies that the LTC is running by checking if the returned
+ * values of two consecutive calls to the #Timer_GetCounterValue
+ * function are ascending. An artificial delay using the NOP operation
+ * is induced such that the timer is not read to fast.
*
* @warning If using an ultra-fast processor with a rather low timer granularity,
- * the test may fail! In this case, it could help to increase the delay
- * by increasing the for-loop exit criteria.
+ * the test may fail! In this case, it could help to increase the delay
+ * by increasing the for-loop exit criteria.
*
- * @warning This test does not test yet verify if the timing is correct at all!
- * This it done in later test...
+ * @warning This test does not test yet verify if the timing is correct at all!
+ * This it done in later test...
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_FAIL on failure (check the error log for more information).
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_FAIL on failure (check the error log for more information).
*****************************************************************************/
static status_t TimerPlausibilityTest(void)
{
@@ -230,7 +264,7 @@ static status_t TimerPlausibilityTest(void)
/* Check max value is not exceeded for LCT timer (us) */
status_t status = CheckTimerCounterValues(hct0, lct0);
- if (status < STATUS_OK) { return status; }
+ if (status != STATUS_OK) { return status; }
/* Adding a delay. Depending on MCU speed, this takes any time.
* However, the Timer should be able to solve this on any MCU. */
@@ -242,18 +276,18 @@ static status_t TimerPlausibilityTest(void)
/* Check max value is not exceeded for LCT timer (us) */
status = CheckTimerCounterValues(hct1, lct1);
- if (status < STATUS_OK) { return status; }
+ if (status != STATUS_OK) { return status; }
/* Either the hct value must have been increased or the lct value if the hct
* value is still the same. */
if (!((hct1 > hct0) || ((hct1 == hct0) && (lct1 > lct0)))) {
- PX4_INFO_RAW("Timer plausibility check: the elapsed time could not be "
- "measured with the Timer_GetCounterValue() function; no time "
- "has elapsed!\n"
- "The delay was induced by the following code:\n"
- "for (volatile uint32_t i = 0; i < 100000; ++i) __asm(\"nop\");\n"
- "Current Values: hct0 = %d, lct0 = %d, hct1 = %d, lct1 = %d",
- (uint)hct0, (uint)lct0, (uint)hct1, (uint)lct1);
+ error_log("Timer plausibility check: the elapsed time could not be "
+ "measured with the Timer_GetCounterValue() function; no time "
+ "has elapsed!\n"
+ "The delay was induced by the following code:\n"
+ "for (volatile uint32_t i = 0; i < 100000; ++i) __asm(\"nop\");\n",
+ "Current Values: hct0 = %d, lct0 = %d, hct1 = %d, lct1 = %d",
+ hct0, lct0, hct1, lct1);
return ERROR_FAIL;
}
@@ -261,29 +295,29 @@ static status_t TimerPlausibilityTest(void)
}
/*!***************************************************************************
- * @brief Wraparound Test for the Timer HAL Implementation.
+ * @brief Wraparound Test for the Timer HAL Implementation.
*
* @details The LTC values must wrap from 999999 µs to 0 µs and increase the
* seconds counter accordingly. This test verifies the correct wrapping
* by consecutively calling the #Timer_GetCounterValue function until
* at least 2 wraparound events have been occurred.
*
- * @note This test requires the timer to basically run and return ascending
- * values. Also, if the timer is too slow, this may take very long!
- * Usually, the test takes 2 seconds, since 2 wraparound events are
- * verified.
+ * @note This test requires the timer to basically run and return ascending
+ * values. Also, if the timer is too slow, this may take very long!
+ * Usually, the test takes 2 seconds, since 2 wraparound events are
+ * verified.
*
- * @warning This test does not test yet verify if the timing is correct at all!
- * This it done in later test...
+ * @warning This test does not test yet verify if the timing is correct at all!
+ * This it done in later test...
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_FAIL on failure (check the error log for more information).
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_FAIL on failure (check the error log for more information).
*****************************************************************************/
static status_t TimerWraparoundTest(void)
{
/* Test parameter configuration: *****************************************/
- const int8_t n = 2; // The number of wraparounds to test.
+ const uint8_t n = 2; // The number of wraparounds to test.
/*************************************************************************/
uint32_t hct0 = 0;
@@ -297,14 +331,12 @@ static status_t TimerWraparoundTest(void)
/* Check max value is not exceeded for LCT timer (us) */
status_t status = CheckTimerCounterValues(hct0, lct0);
- if (status < STATUS_OK) { return status; }
+ if (status != STATUS_OK) { return status; }
/* Set end after 2 seconds, i.e. 2 wrap around events. */
uint32_t hct2 = hct0 + n;
uint32_t lct2 = lct0;
- px4_usleep(20000);
-
/* Periodically read timer values. From previous tests we
* already know the timer value is increasing. */
while (hct0 < hct2 || lct0 < lct2) {
@@ -315,69 +347,92 @@ static status_t TimerWraparoundTest(void)
/* Check max value is not exceeded for LCT timer (us) */
status = CheckTimerCounterValues(hct0, lct0);
- if (status < STATUS_OK) { return status; }
+ if (status != STATUS_OK) { return status; }
/* Testing if calls to Timer_GetCounterValue are equal or increasing.
* Also testing if wraparound is correctly handled.
* Assumption here is that two sequential calls to the get functions are
- * only a few µs appart! I.e. if hct wraps, the new lct must be smaller
+ * only a few µs apart! I.e. if hct wraps, the new lct must be smaller
* than previous one. */
if (!(((hct1 == hct0 + 1) && (lct1 < lct0))
|| ((hct1 == hct0) && (lct1 >= lct0)))) {
- PX4_INFO_RAW("Timer plausibility check: the wraparound of \"lct\" or "
- "\"hct\" parameters of the Timer_GetCounterValue() "
- "function was not handled correctly!\n"
- "Current Values: hct0 = %d, lct0 = %d, hct1 = %d, lct1 = %d",
- (uint)hct0, (uint)lct0, (uint)hct1, (uint)lct1);
+ error_log("Timer plausibility check: the wraparound of \"lct\" or "
+ "\"hct\" parameters of the Timer_GetCounterValue() "
+ "function was not handled correctly!\n"
+ "Current Values: hct0 = %d, lct0 = %d, hct1 = %d, lct1 = %d",
+ hct0, lct0, hct1, lct1);
return ERROR_FAIL;
}
hct0 = hct1;
lct0 = lct1;
-
- px4_usleep(20000);
}
return STATUS_OK;
}
/*!***************************************************************************
- * @brief Helper function for transfer data to SPI in blocking mode.
+ * @brief SPI interrupt callback function for the SPI transfer interrupt test.
+ *
+ * @details The interrupt callback is invoked from the S2PI module upon
+ * finishing the SPI transfer. The callback is used by the
+ * #SPITransferSync helper function to retrieve the status of the
+ * SPI transfer.
+ *
+ * @param status The S2PI module status passed to the callback.
+ * @param param The abstract interrupt callback parameter.
+ *
+ * @return Returns #STATUS_OK.
+ *****************************************************************************/
+static status_t SpiTransferInterruptCallback(status_t status, void *param)
+{
+ *((status_t *)param) = status;
+ return STATUS_OK;
+}
+
+/*!***************************************************************************
+ * @brief Helper function for transfer data to SPI in blocking mode.
*
* @details Calls the #S2PI_TransferFrame function and waits until the transfer
- * has been finished by checking the #S2PI_GetStatus return code to
- * become #STATUS_IDLE (or #STATUS_OK).
+ * has been finished by checking the #S2PI_GetStatus return code to
+ * become #STATUS_IDLE (or #STATUS_OK).
*
- * @warning The test utilizes already the timer HAL in order to implement a
- * rudimentary timeout. However, at this time, only some basic
- * plausibility checks are performed on the timer HAL. I.e. if there
- * is an issue in the time HAL, e.g. too fast or too slow time
- * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
- * one also needs to verify the timer HAL, especially the
- * #Timer_GetCounterValue function.
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
- * @param data The data array to be transfered.
- * @param size The size of the data array to be transfered.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param data The data array to be transferred.
+ * @param size The size of the data array to be transferred.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_TIMEOUT if the operation did not finished within a specified
- * time (check also timer HAL implementation).
- * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
- * return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the operation did not finished within a specified
+ * time (check also timer HAL implementation).
+ * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
+ * return any negative status.
*****************************************************************************/
-static status_t SPITransferSync(s2pi_slave_t slave, uint8_t *data, uint8_t size)
+static status_t SPITransferSync(s2pi_slave_t slave, uint8_t *data, size_t size)
{
/* Test parameter configuration: *****************************************/
- const uint32_t timeout_ms = 100; // The transfer timeout in ms.
+ const uint32_t timeout_ms = 100; // The transfer timeout in ms.
/*************************************************************************/
- status_t status = S2PI_TransferFrame(slave, data, data, size, 0, 0);
+ /* The status will be changed in the SPI callback. */
+ volatile status_t callbackStatus = STATUS_BUSY;
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI transfer failed! The call to S2PI_TransferFrame "
- "yielded error code: %d", (int)status);
+ status_t status = S2PI_TransferFrame(slave, data, data, size,
+ SpiTransferInterruptCallback,
+ (void *)&callbackStatus);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer failed! The call to S2PI_TransferFrame "
+ "yielded error code: %d",
+ status);
return status;
}
@@ -388,53 +443,67 @@ static status_t SPITransferSync(s2pi_slave_t slave, uint8_t *data, uint8_t size)
Time_GetNow(&start);
do {
- status = S2PI_GetStatus();
+ status = S2PI_GetStatus(slave);
if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI transfer failed! The call to S2PI_GetStatus "
- "yielded error code: %d", (int)status);
- S2PI_Abort();
+ error_log("SPI transfer failed! The call to S2PI_GetStatus "
+ "yielded error code: %d", status);
+ S2PI_Abort(slave);
return status;
}
if (Time_CheckTimeoutMSec(&start, timeout_ms)) {
- PX4_INFO_RAW("SPI transfer failed! The operation did not finished "
- "within %u ms. This may also be caused by an invalid "
- "timer implementation!", (uint)timeout_ms);
+ error_log("SPI transfer failed! The operation did not finished "
+ "within %d ms. This may also be caused by an invalid "
+ "timer implementation!", timeout_ms);
return ERROR_TIMEOUT;
}
} while (status == STATUS_BUSY);
+ if (callbackStatus != STATUS_OK) {
+ error_log("Invocation of the SPI callback failed! The SPI transfer "
+ "callback yielded error code: %d", callbackStatus);
+ return callbackStatus;
+ }
+
return status;
}
/*!***************************************************************************
- * @brief SPI Connection Test for S2PI HAL Implementation.
+ * @brief SPI Connection Test for S2PI HAL Implementation.
*
* @details This test verifies the basic functionality of the SPI interface.
- * The test utilizes the devices laser pattern register, which can
- * be freely programmed by any 128-bit pattern. Thus, it writes a byte
- * sequence and reads back the written values on the consecutive SPI
- * access.
*
- * @warning The test utilizes already the timer HAL in order to implement a
- * rudimentary timeout. However, at this time, only some basic
- * plausibility checks are performed on the timer HAL. I.e. if there
- * is an issue in the time HAL, e.g. too fast or too slow time
- * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
- * one also needs to verify the timer HAL, especially the
- * #Timer_GetCounterValue function.
+ * The test utilizes the devices laser pattern register, which can
+ * be freely programmed by any 128-bit pattern. Thus, it writes a byte
+ * sequence and reads back the written values on the consecutive SPI
+ * access.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * Note: The test verifies the SPI interface transfer functionality
+ * in blocking mode and also verifies the interrupt callback.
+ * In order to wait for the transfer to finish, it reads the S2PI
+ * status in a loop. If the status does not change to #STATUS_IDLE,
+ * the test will fail with an #ERROR_TIMEOUT. Finally, the test will
+ * verify the SPI transfer callback status.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_TIMEOUT if the operation did not finished within a specified
- * time (check also timer HAL implementation).
- * - #ERROR_FAIL if the device access failed and the read data did not
- * match the expected values.
- * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
- * return any negative status.
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
+ *
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the operation did not finished within a specified
+ * time (check also timer HAL implementation).
+ * - #ERROR_FAIL if the device access failed and the read data did not
+ * match the expected values.
+ * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus
+ * or the SPI callback yield any negative status.
*****************************************************************************/
static status_t SpiConnectionTest(s2pi_slave_t slave)
{
@@ -448,8 +517,8 @@ static status_t SpiConnectionTest(s2pi_slave_t slave)
status = SPITransferSync(slave, data, 17U);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI connection test failed!");
+ if (status != STATUS_OK) {
+ error_log("SPI connection test failed!");
return status;
}
@@ -460,18 +529,18 @@ static status_t SpiConnectionTest(s2pi_slave_t slave)
status = SPITransferSync(slave, data, 17U);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI connection test failed!");
+ if (status != STATUS_OK) {
+ error_log("SPI connection test failed!");
return status;
}
/* Verify the read pattern. */
for (uint8_t i = 1; i < 17U; ++i) {
if (data[i] != i) {
- PX4_INFO_RAW("SPI connection test failed!\n"
- "Verification of read data is invalid!\n"
- "read_data[%d] = %d, but expected was %d",
- i, data[i], i);
+ error_log("SPI connection test failed!\n"
+ "Verification of read data is invalid!\n"
+ "read_data[%d] = %d, but expected was %d",
+ i, data[i], i);
return ERROR_FAIL;
}
}
@@ -479,142 +548,236 @@ static status_t SpiConnectionTest(s2pi_slave_t slave)
return STATUS_OK;
}
-
/*!***************************************************************************
- * @brief The data ready callback invoked by the API.
+ * @brief Maximum SPI Data Size Test for S2PI HAL Implementation.
*
- * @details The callback is invoked by the API when the device GPIO IRQ is
- * pending after a measurement has been executed and data is ready to
- * be read from the device.
+ * @details This test verifies the maximum data transfer length of the SPI
+ * interface. The test sends and receives up to 396 data bytes plus
+ * a single address byte over the SPI interface and verifies that no
+ * data get lost.
*
- * @param param The abstract pointer to the boolean value that determines if
- * the callback is invoked.
+ * The test utilizes the channel select register which is 3 bytes plus
+ * address. This register can be repeatedly written with any pattern
+ * using the DMA mode. The register is written 100 times in a row
+ * to verify that long data frames with up to 400 bytes can be
+ * transmitted.
+ *
+ * Note that this test was motivated by an invalid implementation that
+ * used uint8_t type for the frame length in the #S2PI_TransferFrame
+ * function instead of an uint16_t value. This resulted in a maximum
+ * data length of 141 bytes (367 & 0xFF = 141) when reading the
+ * data value register.
+ *
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
+ *
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the operation did not finished within a specified
+ * time (check also timer HAL implementation).
+ * - #ERROR_FAIL if the device access failed and the read data did not
+ * match the expected values.
+ * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
+ * return any negative status.
*****************************************************************************/
-static void DataReadyCallback(void *param)
+static status_t SpiMaxLengthTest(s2pi_slave_t slave)
{
- IRQ_LOCK();
- *((bool *) param) = true;
- IRQ_UNLOCK();
+ status_t status = STATUS_OK;
+ uint8_t data[400U] = { 0 };
+
+ /* Setup device (enable DMA mode). */
+ data[0] = 0x10; data[1] = 0x12;
+ status = SPITransferSync(slave, data, 2);
+
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
+ return status;
+ }
+
+ data[0] = 0x12; data[1] = 0x00; data[2] = 0x2B;
+ status = SPITransferSync(slave, data, 3);
+
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
+ return status;
+ }
+
+ /* Transfer a pattern to the register */
+ for (uint32_t i = 0; i < sizeof(data); i += 4) {
+ data[i + 0] = 0x1E; // Address
+ data[i + 1] = (uint8_t)i; // Random Data Byte 0
+ data[i + 2] = (uint8_t)(i + 1); // Random Data Byte 1
+ data[i + 3] = (uint8_t)(i * 2); // Random Data Byte 2
+ }
+
+ status = SPITransferSync(slave, data, sizeof(data));
+
+ if (status != STATUS_OK) {
+ error_log("SPI maximum data length test failed!");
+ return status;
+ }
+
+ /* Repeat ... */
+ for (uint32_t i = 0; i < sizeof(data); i += 4) {
+ data[i + 0] = 0x1E; // Address
+ data[i + 1] = (uint8_t)i; // Random Data Byte 0
+ data[i + 2] = (uint8_t)(i + 1); // Random Data Byte 1
+ data[i + 3] = (uint8_t)(i * 2); // Random Data Byte 2
+ }
+
+ status = SPITransferSync(slave, data, sizeof(data));
+
+ if (status != STATUS_OK) {
+ error_log("SPI maximum data length test failed!");
+ return status;
+ }
+
+ /* Verify the read pattern; skip all address bytes. */
+ for (uint32_t i = 0; i < sizeof(data); i += 4) {
+ uint32_t j = (i + 4) % sizeof(data);
+
+ if (data[j + 1] != (uint8_t)i
+ || data[j + 2] != (uint8_t)(i + 1)
+ || data[j + 3] != (uint8_t)(i * 2)) {
+ error_log("SPI maximum data length test failed!\n"
+ "Verification of read data is invalid at byte %d!\n"
+ " - expected: 0x%02X%02X%02X\n"
+ " - actual: 0x%02X%02X%02X",
+ i, (uint8_t)i, (uint8_t)(i + 1), (uint8_t)(i * 2),
+ data[j + 1], data[j + 2], data[j + 3]);
+ return ERROR_FAIL;
+ }
+ }
+
+ return STATUS_OK;
}
/*!***************************************************************************
- * @brief Configures the device with a bare minimum setup to run the tests.
+ * @brief Configures the device with a bare minimum setup to run the tests.
*
- * @details This function applies a number of configuration values to the
- * device, such that a pseudo measurement w/o laser output can be
- * performed.
+ * @details This function applies a number of configuration values to the
+ * device, such that a pseudo measurement w/o laser output can be
+ * performed.
*
- * A \p rcoTrim parameter can be passed to adjust the actual clock
- * setup.
+ * A \p rcoTrim parameter can be passed to adjust the actual clock
+ * setup.
*
- * @warning The test utilizes already the timer HAL in order to implement a
- * rudimentary timeout. However, at this time, only some basic
- * plausibility checks are performed on the timer HAL. I.e. if there
- * is an issue in the time HAL, e.g. too fast or too slow time
- * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
- * one also needs to verify the timer HAL, especially the
- * #Timer_GetCounterValue function.
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
- * @param rcoTrim The RCO Trimming value added to the nominal RCO register
- * value. Pass 0 if no fine tuning is required.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param rcoTrim The RCO Trimming value added to the nominal RCO register
+ * value. Pass 0 if no fine tuning is required.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_TIMEOUT if the SPI operation did not finished within a
- * specified time (check also timer HAL implementation).
- * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
- * return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the SPI operation did not finished within a
+ * specified time (check also timer HAL implementation).
+ * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
+ * return any negative status.
*****************************************************************************/
static status_t ConfigureDevice(s2pi_slave_t slave, int8_t rcoTrim)
{
/* Setup Device and Trigger Measurement. */
- uint16_t v = 0x0010U | (((34 + rcoTrim) & 0x3F) << 6);
- uint8_t d1[] = { 0x14, v >> 8, v & 0xFF, 0x21 };
+ assert(rcoTrim >= -34 && rcoTrim < 0x3F - 34);
+ const uint16_t v = (uint16_t)(0x0010U | (((uint16_t)(34 + rcoTrim) & 0x3F) << 6U));
+ uint8_t d1[] = { 0x14U, (uint8_t)(v >> 8U), v & 0xFFU, 0x21U };
status_t status = SPITransferSync(slave, d1, sizeof(d1));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d2[] = { 0x16, 0x7F, 0xFF, 0x7F, 0xE9 };
status = SPITransferSync(slave, d2, sizeof(d2));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d3[] = { 0x18, 0x00, 0x00, 0x03 };
status = SPITransferSync(slave, d3, sizeof(d3));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d4[] = { 0x10, 0x12 };
status = SPITransferSync(slave, d4, sizeof(d4));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d5[] = { 0x12, 0x00, 0x2B };
status = SPITransferSync(slave, d5, sizeof(d5));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d6[] = { 0x08, 0x04, 0x84, 0x10 };
status = SPITransferSync(slave, d6, sizeof(d6));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d7[] = { 0x0A, 0xFE, 0x51, 0x0F, 0x05 };
status = SPITransferSync(slave, d7, sizeof(d7));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d8[] = { 0x0C, 0x00, 0x00, 0x00 };
status = SPITransferSync(slave, d8, sizeof(d8));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d9[] = { 0x1E, 0x00, 0x00, 0x00 };
status = SPITransferSync(slave, d9, sizeof(d9));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d10[] = { 0x20, 0x01, 0xFF, 0xFF };
status = SPITransferSync(slave, d10, sizeof(d10));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
uint8_t d11[] = { 0x22, 0xFF, 0xFF, 0x04 };
status = SPITransferSync(slave, d11, sizeof(d11));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Device configuration failed!");
+ if (status != STATUS_OK) {
+ error_log("Device configuration failed!");
return status;
}
@@ -622,40 +785,55 @@ static status_t ConfigureDevice(s2pi_slave_t slave, int8_t rcoTrim)
}
/*!***************************************************************************
- * @brief Triggers a measurement on the device with specified sample count.
+ * @brief Triggers a measurement on the device with specified sample count.
*
* @details The function triggers a measurement cycle on the device. A
- * \p sample count can be specified to setup individual number of
- * digital averaging.
+ * \p sample count can be specified to setup individual number of
+ * digital averaging.
*
- * @warning The test utilizes already the timer HAL in order to implement a
- * rudimentary timeout. However, at this time, only some basic
- * plausibility checks are performed on the timer HAL. I.e. if there
- * is an issue in the time HAL, e.g. too fast or too slow time
- * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
- * one also needs to verify the timer HAL, especially the
- * #Timer_GetCounterValue function.
+ * The measurement in triggered asynchronously without waiting
+ * for any event to finish.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
- * @param samples The specified number of averaging samples for the measurement.
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_TIMEOUT if the operation did not finished within a specified
- * time (check also timer HAL implementation).
- * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
- * return any negative status.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param samples The specified number of averaging samples for the measurement.
+ * @param callback An optional SPI callback.
+ * @param callbackData The optional callback data parameter.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the operation did not finished within a specified
+ * time (check also timer HAL implementation).
+ * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
+ * return any negative status.
*****************************************************************************/
-static status_t TriggerMeasurement(s2pi_slave_t slave, uint16_t samples)
+static status_t TriggerMeasurement(s2pi_slave_t slave, uint16_t samples,
+ s2pi_callback_t callback, void *callbackData)
{
// samples is zero based, i.e. writing 0 yields 1 sample
samples = samples > 0 ? samples - 1 : samples;
- uint16_t v = 0x8000U | ((samples & 0x03FFU) << 5U);
- uint8_t d[] = { 0x1C, v >> 8, v & 0xFFU };
- status_t status = SPITransferSync(slave, d, sizeof(d));
+ const uint16_t v = (uint16_t)(0x8000U | ((samples & 0x03FFU) << 5U));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Trigger measurement failed!");
+ // data is static as the transfer is asynchronous and the buffer must persist.
+ static uint8_t data[] = { 0x1CU, 0x00U, 0x00U };
+ data[0] = 0x1CU;
+ data[1] = (uint8_t)(v >> 8U);
+ data[2] = v & 0xFFU;
+
+ status_t status = S2PI_TransferFrame(slave, data, data, sizeof(data),
+ callback, callbackData);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer failed to trigger measurements! "
+ "The call to S2PI_TransferFrame yielded error code: %d",
+ status);
return status;
}
@@ -663,162 +841,263 @@ static status_t TriggerMeasurement(s2pi_slave_t slave, uint16_t samples)
}
/*!***************************************************************************
- * @brief Waits for the data ready interrupt to be pending.
+ * @brief Data structure for the GPIO interrupt test.
*
- * @details The function polls the current interrupt pending state of the data
- * ready interrupt from the device, i.e. reads the IRQ GPIO pin until
- * it is pulled to low by the device.
- *
- *
- * @warning The test utilizes already the timer HAL in order to implement a
- * rudimentary timeout. However, at this time, only some basic
- * plausibility checks are performed on the timer HAL. I.e. if there
- * is an issue in the time HAL, e.g. too fast or too slow time
- * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
- * one also needs to verify the timer HAL, especially the
- * #Timer_GetCounterValue function.
- *
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
- * @param timeout_ms The timeout to cancel waiting for the IRQ.
- *
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_TIMEOUT if either the SPI operation did not finished
- * or the IRQ was not detected within a specified time (check also
- * timer HAL implementation).
- * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus
- * or #S2PI_SetIrqCallback return any negative status.
+ * @details Contains data that is required by the GPIO interrupt test.
*****************************************************************************/
-static status_t AwaitDataReady(s2pi_slave_t slave, uint32_t timeout_ms)
-{
- ltc_t start;
- Time_GetNow(&start);
+typedef struct gpio_data_t {
+ /* The S2PI slave parameter passed to the S2PI HAL functions. */
+ s2pi_slave_t Slave;
- while (S2PI_ReadIrqPin(slave)) {
- if (Time_CheckTimeoutMSec(&start, timeout_ms)) {
- PX4_INFO_RAW("SPI interrupt test failed! The S2PI_ReadIrqPin did not "
- "determine an pending interrupt within %u ms.", (uint)timeout_ms);
- return ERROR_TIMEOUT;
- }
+ /* The callback status. */
+ volatile status_t Status;
+
+ /* The GPIO timeout in milliseconds. */
+ uint32_t Timeout_ms;
+
+ /* A counter to determine how often the callback is invoked. */
+ volatile uint32_t CallbackInvoked;
+
+ /* The return value of the #S2PI_ReadIrqPin function. */
+ volatile uint32_t ReadIrqPinValue;
+
+} gpio_data_t;
+
+/*!***************************************************************************
+ * @brief The IRQ callback dedicated to the #GpioInterruptTest.
+ *
+ * @details The callback is invoked by the API when the device GPIO IRQ is
+ * pending after a measurement has been executed and data is ready to
+ * be read from the device.
+ *
+ * @param param The abstract pointer to the boolean value that determines if
+ * the callback is invoked.
+ *****************************************************************************/
+static void GPIO_Callback(void *param)
+{
+ if (param == NULL) {
+ error_log("GPIO interrupt test failed: callback parameter \"param\" was NULL!");
+ return;
}
+ gpio_data_t *data = (gpio_data_t *)param;
+ data->CallbackInvoked = 1;
+}
+
+/*!***************************************************************************
+ * @brief The SPI transfer callback dedicated to the #GpioInterruptTest.
+ *
+ * @details The callback is invoked by the S2PI layer when the SPI transfer
+ * finished IRQ is invoked. The callback is used to simulate a
+ * deferred GPIO interrupt by locking the interrupts until the
+ * #S2PI_ReadIrqPin detects an GPIO interrupt pending state and
+ * returns 0.
+ *
+ * @param status The status of the SPI transfer.
+ * @param param The abstract pointer to the boolean value that determines if
+ * the callback is invoked.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_FAIL if the \p param parameter is NULL.
+ * - #ERROR_TIMEOUT if the #S2PI_ReadIrqPin does not return 0 after
+ * a specified time (check also timer HAL implementation).
+ * - The S2PI layer error code that may be received from the S2PI
+ * module via the \p status parameter.
+ *****************************************************************************/
+static status_t GPIO_SPI_Callback(status_t status, void *param)
+{
+ IRQ_LOCK(); // prevents GPIO interrupt to preempt if set to higher priority.
+
+ if (param == NULL) {
+ IRQ_UNLOCK();
+ error_log("GPIO interrupt test failed: callback parameter \"param\" was NULL!");
+ return ERROR_FAIL;
+ }
+
+ gpio_data_t *data = (gpio_data_t *)param;
+
+ if (status != STATUS_OK) {
+ IRQ_UNLOCK();
+ error_log("GPIO interrupt test failed: callback parameter \"status\" was %d!",
+ status);
+ data->Status = status;
+ return status;
+ }
+
+ /* The S2PI_ReadIrqPin must correctly return the GPIO IRQ state if the GPIO
+ * interrupt is pending but deferred due to any higher priority or critical
+ * sections. Therefore, the SPI callback with the #IRQ_LOCK/#IRQ_UNLOCK is
+ * used to delay the GPIO callback and test the #S2PI_ReadIrqPin function.
+ *
+ * The purpose is to simulate a delayed GPIO interrupt that can in the
+ * production code happen due to any higher priority interrupts (such as
+ * the SPI interrupt in this test). In those cases, the API relies on the
+ * #S2PI_ReadIrqPin method to obtain if the device has finished in time and
+ * the interrupt is already pending. Otherwise, it would fail with an
+ * timeout due to the deferred GPIO interrupt callback event. */
+
+ ltc_t start;
+ Time_GetNow(&start);
+ data->ReadIrqPinValue = S2PI_ReadIrqPin(data->Slave);
+
+ while (data->ReadIrqPinValue) {
+ if (Time_CheckTimeoutMSec(&start, data->Timeout_ms)) {
+ IRQ_UNLOCK();
+ error_log("GPIO interrupt test failed! The IRQ pin did not assert "
+ "to low state when reading from the IRQ callback. "
+ "Elapsed %d ms.", data->Timeout_ms);
+ data->Status = ERROR_TIMEOUT;
+ return ERROR_TIMEOUT;
+ }
+
+ data->ReadIrqPinValue = S2PI_ReadIrqPin(data->Slave);
+ }
+
+ IRQ_UNLOCK();
+ data->Status = STATUS_OK;
return STATUS_OK;
}
/*!***************************************************************************
- * @brief SPI Interrupt Test for S2PI HAL Implementation.
+ * @brief SPI Interrupt Test for S2PI HAL Implementation.
*
- * @details This test verifies the correct implementation of the device
- * integration finished interrupt callback. Therefore it configures
- * the device with a minimal setup to run a pseudo measurement that
- * does not emit any laser light.
+ * @details This test verifies the correct implementation of the device
+ * integration finished interrupt callback, a.k.a. the GPIO interrupt.
+ * Therefore it configures the device with a minimal setup to run a
+ * pseudo measurement that does not emit any laser light but triggers
+ * an GPIO interrupt once finished.
*
- * Note that this test does verify the GPIO interrupt that occurs
- * whenever the device has finished the integration/measurement and
- * new data is waiting to be read from the device. This does not test
- * the interrupt that is triggered when the SPI transfer has finished.
+ * The data ready interrupt implies two S2PI layer functions that
+ * are tested in this test: The #S2PI_SetIrqCallback function installs
+ * a callback function that is invoked whenever the IRQ occurs and
+ * the #S2PI_ReadIrqPin function to obtain the pending interrupt state.
*
- * The data ready interrupt implies two S2PI layer functions that
- * are tested in this test: The #S2PI_SetIrqCallback function installs
- * a callback function that is invoked whenever the IRQ occurs.
- * The IRQ can be delayed due to higher priority task, e.g. from the
- * user code. It is essential for the laser safety timeout algorithm
- * to determine the device ready signal as fast as possible, another
- * method is implemented to read if the IRQ is pending but the
- * callback has not been reset yet. This is what the #S2PI_ReadIrqPin
- * function is for.
+ * The IRQ can be delayed due to higher priority task, e.g. from the
+ * user code. It is essential for the laser safety timeout algorithm
+ * to determine the device ready signal as fast as possible. Thus a
+ * method is required to obtain if the IRQ is currently pending but
+ * the callback has not been invoked yet. This is what the
+ * #S2PI_ReadIrqPin function is for. Note that the #S2PI_ReadIrqPin
+ * must return 0 if not interrupt is pending and 1 else. Just like
+ * the IRQ pin is active low.
*
+ * The test simulate a delayed GPIO interrupt by locking the interrupts
+ * until the #S2PI_ReadIrqPin detects an GPIO interrupt pending state
+ * and returns 0. This is done by the #GPIO_SPI_Callback function.
+ *
+ * Note that this test does verify the GPIO interrupt that occurs
+ * whenever the device has finished the integration/measurement and
+ * new data is waiting to be read from the device. This does not test
+ * the interrupt that is triggered when the SPI transfer has finished.
*
* @warning The test assumes the device is in a fresh power on state and no
- * additional reset is required. If the test fail, one may want to
- * power cycle the device and try again.
+ * additional reset is required. If the test fail, one may want to
+ * power cycle the device and try again.
*
- * @warning The test utilizes already the timer HAL in order to implement a
- * rudimentary timeout. However, at this time, only some basic
- * plausibility checks are performed on the timer HAL. I.e. if there
- * is an issue in the time HAL, e.g. too fast or too slow time
- * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
- * one also needs to verify the timer HAL, especially the
- * #Timer_GetCounterValue function.
+ * @warning The test locks the interrupts for a quite long period of time in
+ * order to simulate a delayed GPIO interrupt. This is not a good
+ * practice in production code. However, it is required to test the
+ * #S2PI_ReadIrqPin function. Please be aware of that when you run
+ * this test.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_TIMEOUT if either the SPI operation did not finished
- * or the IRQ was not detected within a specified time (check also
- * timer HAL implementation).
- * - #ERROR_FAIL if the IRQ pin readout failed and the no or invalid
- * interrupt was detected.
- * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus
- * or #S2PI_SetIrqCallback return any negative status.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if either the SPI operation did not finished
+ * or the IRQ was not detected within a specified time (check also
+ * timer HAL implementation).
+ * - #ERROR_FAIL if the IRQ pin readout failed and the no or invalid
+ * interrupt was detected.
+ * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus
+ * or #S2PI_SetIrqCallback return any negative status.
*****************************************************************************/
-static status_t SpiInterruptTest(s2pi_slave_t slave)
+static status_t GpioInterruptTest(s2pi_slave_t slave)
{
/* Test parameter configuration: *****************************************/
const uint32_t timeout_ms = 300; // timeout for measurement, might be increased..
/*************************************************************************/
- /* Install IRQ callback. */
- volatile bool isDataReady = false;
- status_t status = S2PI_SetIrqCallback(slave, DataReadyCallback, (void *)&isDataReady);
+ gpio_data_t data = { .Slave = slave,
+ .Status = ERROR_FAIL,
+ .Timeout_ms = timeout_ms,
+ .ReadIrqPinValue = 12345,
+ .CallbackInvoked = 0
+ };
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI interrupt test failed! The call to S2PI_SetIrqCallback "
- "yielded error code: %d", (int)status);
+ /* Install IRQ callback. */
+ status_t status = S2PI_SetIrqCallback(slave, GPIO_Callback, &data);
+
+ if (status != STATUS_OK) {
+ error_log("GPIO interrupt test failed! The call to S2PI_SetIrqCallback "
+ "yielded error code: %d", status);
+ return status;
+ }
+
+ /* Setup Device. */
+ status = ConfigureDevice(slave, 0);
+
+ if (status != STATUS_OK) {
+ error_log("GPIO interrupt test failed!");
return status;
}
/* Check if IRQ is not yet pending. */
if (S2PI_ReadIrqPin(slave) == 0) {
- PX4_INFO_RAW("SPI interrupt test failed! The S2PI_ReadIrqPin did "
- "return 0 but no interrupt is pending since no "
- "measurements are executed yet!");
+ error_log("GPIO interrupt test failed! The S2PI_ReadIrqPin did "
+ "return 0 but no interrupt is pending since no "
+ "measurements are executed yet!");
return ERROR_FAIL;
};
- /* Setup Device. */
- status = ConfigureDevice(slave, 0);
-
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI interrupt test failed!");
- return status;
- }
-
/* Trigger Measurement. */
- status = TriggerMeasurement(slave, 0);
+ status = TriggerMeasurement(slave, 0, GPIO_SPI_Callback, &data);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI interrupt test failed!");
- return status;
- }
-
- ltc_t start;
- Time_GetNow(&start);
-
- /* Wait for Interrupt using the S2PI_ReadIrqPin method. */
- status = AwaitDataReady(slave, timeout_ms);
-
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI interrupt test failed!");
+ if (status != STATUS_OK) {
+ error_log("GPIO interrupt test failed!");
return status;
}
/* Wait for Interrupt using the callback method. */
- while (!isDataReady) {
+ ltc_t start;
+ Time_GetNow(&start);
+
+ while (!data.CallbackInvoked) {
if (Time_CheckTimeoutMSec(&start, timeout_ms)) {
- PX4_INFO_RAW("SPI interrupt test failed! The IRQ callback was not "
- "invoked within %u ms.", (uint)timeout_ms);
+ error_log("GPIO interrupt test failed! The IRQ callback was not "
+ "invoked within %d ms.", timeout_ms);
return ERROR_TIMEOUT;
}
}
+ /* Verify ... */
+ if (data.Status != STATUS_OK) {
+ error_log("GPIO interrupt test failed! The SPI IRQ callback yielded "
+ "an error status: %d (expected 0)", data.Status);
+ return ERROR_FAIL;
+ }
+
+ if (data.ReadIrqPinValue != 0) {
+ error_log("GPIO interrupt test failed! The IRQ pin returned "
+ "the wrong value: %d (expected 0)", data.ReadIrqPinValue);
+ return ERROR_FAIL;
+ }
+
/* Remove callback. */
status = S2PI_SetIrqCallback(slave, 0, 0);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("SPI interrupt test failed! The call to S2PI_SetIrqCallback "
- "with null pointers yielded error code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("GPIO interrupt test failed! The call to S2PI_SetIrqCallback "
+ "with null pointers yielded error code: %d", status);
return status;
}
@@ -826,28 +1105,28 @@ static status_t SpiInterruptTest(s2pi_slave_t slave)
}
/*!***************************************************************************
- * @brief Reads the EEPROM bytewise and applies Hamming weight.
- * @details The EEPROM bytes are consecutevly read from the device via GPIO mode.
- * The #EEPROM_Read function is an internal API function that enables
- * the GPIO mode from the S2PI module and reads the data via a software
- * bit-banging protocol. Finally it disables the GPIO mode and returns
- * to SPI mode.
+ * @brief Reads the EEPROM byte-wise and applies Hamming weight.
+ * @details The EEPROM bytes are consecutively read from the device via GPIO mode.
+ * The EEPROM_Read function is an internal API function that enables
+ * the GPIO mode from the S2PI module and reads the data via a software
+ * bit-banging protocol. Finally it disables the GPIO mode and returns
+ * to SPI mode.
*
- * The calls to S2PI HAL module is as follows:
- * 1. S2PI_CaptureGpioControl
- * 2. multiple calls to S2PI_WriteGpioPin and S2PI_ReadGpioPin
- * 3. S2PI_ReleaseGpioControl
+ * The calls to S2PI HAL module is as follows:
+ * 1. S2PI_CaptureGpioControl
+ * 2. multiple calls to S2PI_WriteGpioPin and S2PI_ReadGpioPin
+ * 3. S2PI_ReleaseGpioControl
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
- * @param eeprom The 16 byte array to be filled with EEPROM data.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param eeprom The 16 byte array to be filled with EEPROM data.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the Hamming weight fails.
- * interrupt was detected.
- * - The S2PI layer error code if #S2PI_CaptureGpioControl,
- * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or
- * #S2PI_ReadGpioPin return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the Hamming weight fails.
+ * interrupt was detected.
+ * - The S2PI layer error code if #S2PI_CaptureGpioControl,
+ * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or
+ * #S2PI_ReadGpioPin return any negative status.
*****************************************************************************/
static status_t ReadEEPROM(s2pi_slave_t slave, uint8_t *eeprom)
{
@@ -855,9 +1134,9 @@ static status_t ReadEEPROM(s2pi_slave_t slave, uint8_t *eeprom)
uint8_t d1[] = { 0x12, 0x00, 0x4B };
status_t status = SPITransferSync(slave, d1, sizeof(d1));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("EEPROM readout failed (enable EEPROM), "
- "error code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("EEPROM readout failed (enable EEPROM), "
+ "error code: %d", status);
return status;
}
@@ -868,8 +1147,8 @@ static status_t ReadEEPROM(s2pi_slave_t slave, uint8_t *eeprom)
status = EEPROM_Read(slave, address, &data[address]);
if (status != STATUS_OK) {
- PX4_INFO_RAW("EEPROM readout failed @ address 0x%02x, "
- "error code: %d!", address, (int)status);
+ error_log("EEPROM readout failed @ address 0x%02x, "
+ "error code: %d!", address, status);
return status;
}
}
@@ -878,9 +1157,9 @@ static status_t ReadEEPROM(s2pi_slave_t slave, uint8_t *eeprom)
uint8_t d2[] = { 0x12, 0x00, 0x2B };
status = SPITransferSync(slave, d2, sizeof(d2));
- if (status < STATUS_OK) {
- PX4_INFO_RAW("EEPROM readout failed (enable EEPROM), "
- "error code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("EEPROM readout failed (enable EEPROM), "
+ "error code: %d", status);
return status;
}
@@ -888,8 +1167,8 @@ static status_t ReadEEPROM(s2pi_slave_t slave, uint8_t *eeprom)
uint8_t err = hamming_decode(data, eeprom);
if (err != 0) {
- PX4_INFO_RAW("EEPROM readout failed! Failed to decoding "
- "Hamming weight (error: %d)!", err);
+ error_log("EEPROM readout failed! Failed to decoding "
+ "Hamming weight (Hamming parity error: %d)!", err);
return STATUS_ARGUS_EEPROM_BIT_ERROR;
}
@@ -900,30 +1179,30 @@ static status_t ReadEEPROM(s2pi_slave_t slave, uint8_t *eeprom)
}
/*!***************************************************************************
- * @brief GPIO Mode Test for S2PI HAL Implementation.
+ * @brief GPIO Mode Test for S2PI HAL Implementation.
*
* @details This test verifies the GPIO mode of the S2PI HAL module. This is
- * done by leveraging the EEPROM readout sequence that accesses the
- * devices EEPROM via a software protocol that depends on the GPIO
- * mode.
+ * done by leveraging the EEPROM readout sequence that accesses the
+ * devices EEPROM via a software protocol that depends on the GPIO
+ * mode.
*
- * This the requires several steps, most of them are already verified
- * in previous tests:
- * - Basic device configuration and enable EEPROM.
- * - Read EERPOM via GPIO mode and apply Hamming weight
- * - Repeat several times (to eliminate random readout issues).
- * - Decode the EEPROM (using EEPROM_Decode in argus_cal_eeprom.c)
- * - Check if Module Number and Chip ID is not 0
+ * This the requires several steps, most of them are already verified
+ * in previous tests:
+ * - Basic device configuration and enable EEPROM.
+ * - Read EEPROM via GPIO mode and apply Hamming weight
+ * - Repeat several times (to eliminate random readout issues).
+ * - Decode the EEPROM (using EEPROM_Decode in argus_cal_eeprom.c)
+ * - Check if Module Number and Chip ID is not 0
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_FAIL if the GPIO test fails.
- * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the Hamming weight fails.
- * - The S2PI layer error code if #S2PI_CaptureGpioControl,
- * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or
- * #S2PI_ReadGpioPin return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_FAIL if the GPIO test fails.
+ * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the Hamming weight fails.
+ * - The S2PI layer error code if #S2PI_CaptureGpioControl,
+ * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or
+ * #S2PI_ReadGpioPin return any negative status.
*****************************************************************************/
static status_t GpioModeTest(s2pi_slave_t slave)
{
@@ -934,66 +1213,66 @@ static status_t GpioModeTest(s2pi_slave_t slave)
status_t status = ReadEEPROM(slave, eeprom1);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("GPIO mode test failed (1st attempt)!");
+ if (status != STATUS_OK) {
+ error_log("GPIO mode test failed (1st attempt)!");
return status;
}
status = ReadEEPROM(slave, eeprom2);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("GPIO mode test failed (2nd attempt)!");
+ if (status != STATUS_OK) {
+ error_log("GPIO mode test failed (2nd attempt)!");
return status;
}
status = ReadEEPROM(slave, eeprom3);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("GPIO mode test failed (3rd attempt)!");
+ if (status != STATUS_OK) {
+ error_log("GPIO mode test failed (3rd attempt)!");
return status;
}
/* Verify EEPROM data. */
if ((memcmp(eeprom1, eeprom2, 16) != 0) ||
(memcmp(eeprom1, eeprom3, 16) != 0)) {
- PX4_INFO_RAW("GPIO Mode test failed (data comparison)!\n"
- "The data from 3 distinct EEPROM readout does not match!");
+ error_log("GPIO Mode test failed (data comparison)!\n"
+ "The data from 3 distinct EEPROM readout does not match!");
return ERROR_FAIL;
}
/* Check EEPROM data for reasonable chip and module number (i.e. not 0) */
uint32_t chipID = EEPROM_ReadChipId(eeprom1);
- argus_module_version_t module = EEPROM_ReadModule(eeprom1);
+ uint8_t module = EEPROM_ReadModule(eeprom1);
if (chipID == 0 || module == 0) {
- PX4_INFO_RAW("GPIO Mode test failed (data verification)!\n"
- "Invalid EEPROM data: Module = %d; Chip ID = %u!", module, (uint)chipID);
+ error_log("GPIO Mode test failed (data verification)!\n"
+ "Invalid EEPROM data: Module = %d; Chip ID = %d!", module, chipID);
return ERROR_FAIL;
}
- PX4_INFO_RAW("EEPROM Readout succeeded!\n");
- PX4_INFO_RAW("- Module: %d\n", module);
- PX4_INFO_RAW("- Device ID: %u\n", (uint)chipID);
+ print("EEPROM Readout succeeded!\n");
+ print("- Module: %d\n", module);
+ print("- Device ID: %d\n", chipID);
return STATUS_OK;
}
/*!***************************************************************************
- * @brief Reads the RCO_TRIM value from the devices EEPROM.
+ * @brief Reads the RCO_TRIM value from the devices EEPROM.
*
* @details The function reads the devices EEPROM via GPIO mode and extracts
- * the RCO_TRIM value from the EEPROM map.
+ * the RCO_TRIM value from the EEPROM map.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
- * @param rcotrim The read RCO_TRIM value will be returned via this pointer.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param rcotrim The read RCO_TRIM value will be returned via this pointer.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the Hamming weight fails.
- * - #ERROR_ARGUS_UNKNOWN_MODULE if the EEPROM module number is invalid.
- * - The S2PI layer error code if #S2PI_CaptureGpioControl,
- * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or
- * #S2PI_ReadGpioPin return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the Hamming weight fails.
+ * - #ERROR_ARGUS_UNKNOWN_MODULE if the EEPROM module number is invalid.
+ * - The S2PI layer error code if #S2PI_CaptureGpioControl,
+ * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or
+ * #S2PI_ReadGpioPin return any negative status.
*****************************************************************************/
static status_t ReadRcoTrim(s2pi_slave_t slave, int8_t *rcotrim)
{
@@ -1003,25 +1282,15 @@ static status_t ReadRcoTrim(s2pi_slave_t slave, int8_t *rcotrim)
if (status != STATUS_OK) { return status; }
- argus_module_version_t module = EEPROM_ReadModule(eeprom);
-
- switch (module) {
- case AFBR_S50MV85G_V1:
- case AFBR_S50MV85G_V2:
- case AFBR_S50MV85G_V3:
- case AFBR_S50LV85D_V1:
- case AFBR_S50MV68B_V1:
- case AFBR_S50MV85I_V1:
- case AFBR_S50SV85K_V1:
+ uint8_t module = EEPROM_ReadModule(eeprom);
+ if (module > 0 && module < 8) {
/* Read RCO Trim Value from EEPROM Map 1/2/3: */
*rcotrim = ((int8_t) eeprom[0]) >> 3;
- break;
- case MODULE_NONE: /* Uncalibrated module; use all 0 data. */
- default:
-
- PX4_INFO_RAW("EEPROM Readout failed! Unknown module number: %d", module);
+ } else {
+ /* Uncalibrated module; use all 0 data. */
+ error_log("EEPROM Readout failed! Unknown module number: %d", module);
return ERROR_ARGUS_UNKNOWN_MODULE;
}
@@ -1029,112 +1298,151 @@ static status_t ReadRcoTrim(s2pi_slave_t slave, int8_t *rcotrim)
}
/*!***************************************************************************
- * @brief Triggers a measurement on the device and waits for the data ready
- * interrupt.
+ * @brief Callback function for the data ready interrupt.
+ *
+ * @details The function is called by the S2PI layer when the data ready
+ * interrupt is pending. The function sets the \p param to
+ * #STATUS_IDLE.
+ *
+ * @param param The parameter passed to the #S2PI_SetIrqCallback function as
+ * an abstract pointer to an #status_t type.
+ *****************************************************************************/
+static void MeasurementCallback(void *param)
+{
+ *(status_t *) param = STATUS_IDLE;
+}
+
+/*!***************************************************************************
+ * @brief Triggers a measurement on the device and waits for the data ready
+ * interrupt.
*
* @details The function triggers a measurement cycle on the device and waits
- * until the measurement has been finished. A \p sample count can be
- * specified to setup individual number of digital averaging.
+ * until the measurement has been finished. A \p sample count can be
+ * specified to setup individual number of digital averaging.
*
- * @warning The test utilizes already the timer HAL in order to implement a
- * rudimentary timeout. However, at this time, only some basic
- * plausibility checks are performed on the timer HAL. I.e. if there
- * is an issue in the time HAL, e.g. too fast or too slow time
- * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
- * one also needs to verify the timer HAL, especially the
- * #Timer_GetCounterValue function.
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
- * @param samples The specified number of averaging samples for the measurement.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param samples The specified number of averaging samples for the measurement.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_TIMEOUT if either the SPI operation did not finished
- * or the IRQ was not detected within a specified time (check also
- * timer HAL implementation).
- * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus
- * or #S2PI_SetIrqCallback return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if either the SPI operation did not finished
+ * or the IRQ was not detected within a specified time (check also
+ * timer HAL implementation).
+ * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus
+ * or #S2PI_SetIrqCallback return any negative status.
*****************************************************************************/
static status_t RunMeasurement(s2pi_slave_t slave, uint16_t samples)
{
- status_t status = TriggerMeasurement(slave, samples);
+ /* Test parameter configuration: *****************************************/
+ const uint32_t timeout_ms = 300; // The transfer timeout in ms.
+ /*************************************************************************/
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Speed test failed!\n"
- "Call to TransferFrame returned code: %d",
- (int)status);
+ volatile status_t callbackStatus = STATUS_BUSY;
+
+ status_t status = S2PI_SetIrqCallback(slave, MeasurementCallback, (void *)&callbackStatus);
+
+ if (status != STATUS_OK) {
+ error_log("Failed to run a measurement!\n"
+ "Call to SetIrqCallback returned code: %d", status);
+ return status;
+ }
+
+ status = TriggerMeasurement(slave, samples, 0, 0);
+
+ if (status != STATUS_OK) {
+ error_log("Failed to run a measurement!\n"
+ "Call to TransferFrame returned code: %d", status);
return status;
}
/* Wait until the transfer is finished using a timeout. */
- status = AwaitDataReady(slave, 300);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Speed test failed!\n"
- "SPI Read IRQ pin didn't raised, timeout activated at 200ms, error code: %d",
- (int)status);
- return status;
+ ltc_t start;
+ Time_GetNow(&start);
+
+ while (callbackStatus == STATUS_BUSY) {
+ if (Time_CheckTimeoutMSec(&start, timeout_ms)) {
+ error_log("Failed to run a measurement!\n"
+ "Timeout occurred while waiting for the SPI interrupt (%d ms).",
+ timeout_ms);
+ return ERROR_TIMEOUT;
+ }
}
- return status;
+ if (callbackStatus != STATUS_OK) {
+ error_log("Failed to run a measurement!\n"
+ "The SPI callback yielded returned code: %d",
+ callbackStatus);
+ return callbackStatus;
+ }
+
+ return STATUS_OK;
}
/*!***************************************************************************
- * @brief Test for Timer HAL Implementation by comparing timings to the device.
+ * @brief Test for Timer HAL Implementation by comparing timings to the device.
*
- * @details The test verifies the timer HAL implementation by comparing the
- * timings to the AFBR-S50 device as a reference.
- * Therefore several measurement are executed on the device, each with
- * a different averaging sample count. The elapsed time increases
- * linearly with the number of averaging samples. In order to remove
- * the time for software/setup, a linear regression fit is applied to
- * the measurement results and only the slope is considered for the
- * result. A delta of 102.4 microseconds per sample is expected.
- * If the measured delta per sample is within an specified error range,
- * the timer implementation is considered correct.
+ * @details The test verifies the timer HAL implementation by comparing the
+ * timings to the AFBR-S50 device as a reference.
+ * Therefore several measurement are executed on the device, each with
+ * a different averaging sample count. The elapsed time increases
+ * linearly with the number of averaging samples. In order to remove
+ * the time for software/setup, a linear regression fit is applied to
+ * the measurement results and only the slope is considered for the
+ * result. A delta of 102.4 microseconds per sample is expected.
+ * If the measured delta per sample is within an specified error range,
+ * the timer implementation is considered correct.
*
- * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_FAIL if the timer test fails.
- * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the EEPROM Hamming weight fails.
- * - #ERROR_ARGUS_UNKNOWN_MODULE if the EEPROM module number is invalid.
- * - #ERROR_TIMEOUT if either the SPI operation did not finished
- * or the IRQ was not detected within a specified time (check also
- * timer HAL implementation).
- * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus,
- * #S2PI_SetIrqCallback, #S2PI_CaptureGpioControl,
- * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or #S2PI_ReadGpioPin
- * return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_FAIL if the timer test fails.
+ * - #STATUS_ARGUS_EEPROM_BIT_ERROR if the EEPROM Hamming weight fails.
+ * - #ERROR_ARGUS_UNKNOWN_MODULE if the EEPROM module number is invalid.
+ * - #ERROR_TIMEOUT if either the SPI operation did not finished
+ * or the IRQ was not detected within a specified time (check also
+ * timer HAL implementation).
+ * - The S2PI layer error code if #S2PI_TransferFrame, #S2PI_GetStatus,
+ * #S2PI_SetIrqCallback, #S2PI_CaptureGpioControl,
+ * #S2PI_ReleaseGpioControl, #S2PI_WriteGpioPin or #S2PI_ReadGpioPin
+ * return any negative status.
*****************************************************************************/
static status_t TimerTest(s2pi_slave_t slave)
{
/* Test parameter configuration: *****************************************/
- const int8_t n = 10; // The number of measurements.
- const uint32_t ds = 100; // The step size in averaging samples.
- const float exp_slope = 102.4; // Expected slope is 102.4 µs / phase / sample
- const float rel_slope_error = 3e-2; // Relative slope tolerance is 3%.
+ const int8_t n = 10; // The number of measurements.
+ const uint32_t ds = 100; // The step size in averaging samples.
+ const float exp_slope = 102.4f; // Expected slope is 102.4 µs / phase / sample
+ const float rel_slope_error = 3e-2f; // Relative slope tolerance is 3%.
/*************************************************************************/
/* Read RCOTrim value from EEPROM*/
int8_t RcoTrim = 0;
status_t status = ReadRcoTrim(slave, &RcoTrim);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Timer test failed!\n"
- "EEPROM Read test returned code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("Timer test failed!\n"
+ "EEPROM Read test returned code: %d", status);
return status;
}
- PX4_INFO_RAW("RCOTrim = %d\n", RcoTrim);
+ print("RCOTrim = %d\n", RcoTrim);
/* Configure the device with calibrated RCO to 24MHz. */
status = ConfigureDevice(slave, RcoTrim);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Timer test failed!\n"
- "Configuration test returned code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("Timer test failed!\n"
+ "Configuration test returned code: %d", status);
return status;
}
@@ -1146,21 +1454,23 @@ static status_t TimerTest(s2pi_slave_t slave)
float x2sum = 0;
float xysum = 0;
- PX4_INFO_RAW("+-------+---------+------------+\n");
- PX4_INFO_RAW("| count | samples | elapsed us |\n");
- PX4_INFO_RAW("+-------+---------+------------+\n");
+ print("+-------+---------+------------+\n");
+ print("| count | samples | elapsed us |\n");
+ print("+-------+---------+------------+\n");
for (uint8_t i = 1; i <= n; ++i) {
ltc_t start;
Time_GetNow(&start);
- int samples = ds * i;
- status = RunMeasurement(slave, samples);
+ uint32_t samples = ds * i;
+ assert(samples < UINT16_MAX);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("Timer test failed!\n"
- "Run measurement returned code: %d",
- (int)status);
+ status = RunMeasurement(slave, (uint16_t)samples);
+
+ if (status != STATUS_OK) {
+ error_log("Timer test failed!\n"
+ "Run measurement returned code: %d",
+ status);
return status;
}
@@ -1168,30 +1478,30 @@ static status_t TimerTest(s2pi_slave_t slave)
xsum += (float) samples;
ysum += (float) elapsed_usec;
- x2sum += (float) samples * samples;
- xysum += (float) samples * elapsed_usec;
+ x2sum += (float) samples * (float) samples;
+ xysum += (float) samples * (float) elapsed_usec;
- PX4_INFO_RAW("| %5d | %7d | %10d |\n", i, samples, (uint)elapsed_usec);
+ print("| %5d | %7d | %10d |\n", i, samples, elapsed_usec);
}
- PX4_INFO_RAW("+-------+---------+------------+\n");
+ print("+-------+---------+------------+\n");
const float slope = (n * xysum - xsum * ysum) / (n * x2sum - xsum * xsum);
const float intercept = (ysum * x2sum - xsum * xysum) / (n * x2sum - xsum * xsum);
- PX4_INFO_RAW("Linear Regression: y(x) = %dE-7 sec * x + %dE-7 sec\n",
- (int)(10 * slope), (int)(10 * intercept));
+ print("Linear Regression: y(x) = %dE-7 sec * x + %dE-7 sec\n",
+ (int)(10 * slope), (int)(10 * intercept));
/* Check the error of the slope. */
const float max_slope = exp_slope * (1.f + rel_slope_error);
const float min_slope = exp_slope * (1.f - rel_slope_error);
if (slope > max_slope || slope < min_slope) {
- PX4_INFO_RAW("Time test failed!\n"
- "The measured time slope does not match the expected value! "
- "(actual: %dE-7, expected: %dE-7, min: %dE-7, max: %dE-7)\n",
- (int)(10 * slope), (int)(10 * exp_slope),
- (int)(10 * min_slope), (int)(10 * max_slope));
+ error_log("Time test failed!\n"
+ "The measured time slope does not match the expected value! "
+ "(actual: %dE-7, expected: %dE-7, min: %dE-7, max: %dE-7)\n",
+ (int)(10 * slope), (int)(10 * exp_slope),
+ (int)(10 * min_slope), (int)(10 * max_slope));
return ERROR_FAIL;
}
@@ -1200,11 +1510,11 @@ static status_t TimerTest(s2pi_slave_t slave)
/*!***************************************************************************
- * @brief Data structure for the PIT test.
+ * @brief Data structure for the PIT test.
*
- * @details Contains data that is required by the PIT timer test.
+ * @details Contains data that is required by the PIT timer test.
*****************************************************************************/
-typedef struct {
+typedef struct pit_data_t {
/*! The number of PIT callback events. */
volatile uint32_t n;
@@ -1216,90 +1526,113 @@ typedef struct {
} pit_data_t;
-
-
/*!***************************************************************************
- * @brief Callback function invoked by the PIT.
+ * @brief Callback function invoked by the PIT.
*
- * @details The function that is invoked every time a specified interval elapses.
- * An abstract parameter is passed to the function whenever it is called.
+ * @details The function that is invoked every time a specified interval elapses.
+ * An abstract parameter is passed to the function whenever it is called.
*
- * This implementation collects callback time stamps and counts the
- * number of callback events using the abstract parameter.
+ * This implementation collects callback time stamps and counts the
+ * number of callback events using the abstract parameter.
*
- * @param param An abstract parameter to be passed to the callback. This is
- * also the identifier of the given interval.
+ * @param param An abstract parameter to be passed to the callback. This is
+ * also the identifier of the given interval.
*****************************************************************************/
static void PIT_Callback(void *param)
{
- pit_data_t *data = (pit_data_t *) param;
-
- if (data->n == 0) {
- Time_GetNow(&data->t_first);
- data->t_last = data->t_first;
+ if (param == NULL) {
+ error_log("PIT interrupt test failed: callback parameter \"param\" was NULL!");
} else {
- Time_GetNow(&data->t_last);
- }
+ pit_data_t *data = (pit_data_t *)param;
- data->n++;
+ if (data->n == 0) {
+ Time_GetNow(&data->t_first);
+ data->t_last = data->t_first;
+
+ } else {
+ Time_GetNow(&data->t_last);
+ }
+
+ data->n++;
+ }
}
/*!***************************************************************************
- * @brief Executes a PIT measurement and verifies the callback interval.
+ * @brief Executes a PIT measurement and verifies the callback interval.
*
* @details The function configures the PIT with a given interval and waits
- * several callback events to happen. In each callback event, the
- * elapsed time is measured and the number of calls are counted.
- * Finally, the average interrupt period is compared with the
- * lifetime timer that has been already verified in a previous test
- * (see #Timer_Test).
+ * several callback events to happen. In each callback event, the
+ * elapsed time is measured and the number of calls are counted.
+ * Finally, the average interrupt period is compared with the
+ * lifetime timer that has been already verified in a previous test
+ * (see #TimerTest). The time until the first interrupt event is also
+ * verified.
*
- * @param exp_dt_us The expected timer interval in microseconds.
- * @param n The number of PIT events to await.
+ * @param exp_dt_us The expected timer interval in microseconds.
+ * @param n The number of PIT events to await.
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_FAIL if the measured interval does not match the
- * expectations or the PIT was not disabled properly.
- * - #ERROR_TIMEOUT if either the PIT events do not occur within the
- * expected time.
- * - The PIT layer error code if #Timer_SetInterval return any
- * negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_FAIL if the measured interval does not match the
+ * expectations or the PIT was not disabled properly.
+ * - #ERROR_TIMEOUT if either the PIT events do not occur within the
+ * expected time.
+ * - The PIT layer error code if #Timer_SetInterval return any
+ * negative status.
*****************************************************************************/
static status_t RunPITTest(uint32_t exp_dt_us, uint32_t n)
{
/* Test parameter configuration: *****************************************/
- const float rel_dt_error = 1e-3; // Relative timer interval tolerance is 0.1%.
- const float abs_dt_error = 1.0; // Absolute timer interval tolerance is 1us.
+ const float rel_dt_error = 5e-3f; // Relative timer interval tolerance: 0.5 %.
+ const float abs_dt_error = 5.0f; // Absolute timer interval tolerance: 5.0 us.
/*************************************************************************/
- float dt = exp_dt_us * rel_dt_error;
+ float dt = (float) exp_dt_us * rel_dt_error;
if (dt < abs_dt_error) { dt = abs_dt_error; }
- const float max_dt = exp_dt_us + dt;
- const float min_dt = exp_dt_us - dt;
+ const float max_dt = (float) exp_dt_us + dt;
+ const float min_dt = (float) exp_dt_us - dt;
+
+ if (dt < abs_dt_error * 3) { dt = abs_dt_error * 3; }
+
+ const float t_first_max = (float) exp_dt_us + dt * 5; // use 5x tolerance for
+ const float t_first_min = (float) exp_dt_us - dt * 5; // the first interval
/*************************************************************************/
+ print("Run PIT Test (w/ %d us interval):\n"
+ " - expected event count: %d\n"
+ " - expected interval: %d us, min: %d us, max: %d us\n"
+ " - expected first event: %d us, min: %d us, max: %d us\n",
+ exp_dt_us, n, exp_dt_us, (int)min_dt, (int)max_dt,
+ exp_dt_us, (int)t_first_min, (int)t_first_max);
+
/* Setup the PIT callback with specified interval. */
pit_data_t data = { 0 };
status_t status = Timer_SetInterval(exp_dt_us, &data);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("PIT test failed!\n"
- "Timer_SetInterval returned status code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("PIT test failed!\n"
+ "Timer_SetInterval returned status code: %d", status);
return status;
}
/* Wait until n PIT callback have been happened. */
- uint32_t timeout_us = (n + 1) * exp_dt_us;
+ const uint32_t timeout_us = (n + 1) * exp_dt_us;
+
ltc_t start;
Time_GetNow(&start);
while (data.n < n) {
if (Time_CheckTimeoutUSec(&start, timeout_us)) {
- PX4_INFO_RAW("PIT test failed!\n"
- "Waiting for the PIT interrupt events yielded a timeout.");
+ const uint32_t elapsed_us = Time_GetElapsedUSec(&start);
+ const uint32_t t_first_us = Time_DiffUSec(&start, &data.t_first);
+ const uint32_t t_last_us = Time_DiffUSec(&start, &data.t_last);
+ error_log("PIT test failed!\n"
+ "Waiting for the PIT interrupt events yielded a timeout.\n"
+ "Timeout: %d us; Elapsed: %d us (%d of %d events).\n"
+ "First event @ %d us, last event @ %d us",
+ timeout_us, elapsed_us, data.n, n, t_first_us, t_last_us);
status = ERROR_TIMEOUT;
break;
}
@@ -1309,59 +1642,71 @@ static status_t RunPITTest(uint32_t exp_dt_us, uint32_t n)
/* Disable the PIT timer callback. */
status = Timer_SetInterval(0, &data);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("PIT test failed!\n"
- "Timer_SetInterval returned status code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("PIT test failed!\n"
+ "Timer_SetInterval returned status code: %d", status);
}
}
if (status == STATUS_OK) {
/* Check if PIT callback is not invoked any more. */
- timeout_us = 2 * exp_dt_us;
- Time_GetNow(&start);
-
- while (!Time_CheckTimeoutUSec(&start, timeout_us)) { __asm("nop"); }
+ Time_DelayUSec(3 * exp_dt_us);
if (data.n > n) {
- PX4_INFO_RAW("PIT test failed!\n"
- "Timer_SetInterval has been called after it was disabled.");
+ const uint32_t elapsed_us = Time_GetElapsedUSec(&start);
+ error_log("PIT test failed!\n"
+ "Timer_SetInterval has been called again after it was disabled\n"
+ "(within %d us; %d of %d events in total).",
+ elapsed_us, data.n, n);
status = ERROR_FAIL;
}
}
/* Verify the measured average timer interval. */
- const float act_dt_us = Time_DiffUSec(&data.t_first, &data.t_last) / (n - 1);
+ const float act_dt_us = Time_DiffUSec(&data.t_first, &data.t_last) / (float)(n - 1);
+ const uint32_t t_first_us = Time_DiffUSec(&start, &data.t_first);
+ const uint32_t t_last_us = Time_DiffUSec(&start, &data.t_last);
- if (status == STATUS_OK && (act_dt_us > max_dt || act_dt_us < min_dt)) {
- PX4_INFO_RAW("PIT test failed!\n"
- "The measured timer interval does not match the expected value!\n");
+ print(" - actual event count: %d\n"
+ " - actual interval: %d us\n"
+ " - actual first event: %d us\n"
+ " - actual last event: %d us\n\n",
+ data.n, (int)act_dt_us, t_first_us, t_last_us);
+
+ if (status == STATUS_OK && (t_first_us > t_first_max || t_first_us < t_first_min)) {
+ error_log("PIT test failed!\n"
+ "The first timer event did not occur after the expected interval!");
status = ERROR_FAIL;
}
- PX4_INFO_RAW("PIT Test Results:\n"
- " - event count: %u\n"
- " - actual interval: %d us\n"
- " - expected interval: %d us, min: %d us, max: %d us\n",
- (uint)data.n, (int)act_dt_us, (uint)exp_dt_us, (int)min_dt, (int)max_dt);
+ if (status == STATUS_OK && (act_dt_us > max_dt || act_dt_us < min_dt)) {
+ error_log("PIT test failed!\n"
+ "The measured timer interval does not match the expected value!");
+ status = ERROR_FAIL;
+ }
+
+ print(" - test status: %d\n\n", status);
return status;
}
/*!***************************************************************************
- * @brief Test for PIT HAL Implementation by comparing timings to the device.
+ * @brief Test for PIT HAL Implementation by comparing timings to the device.
*
- * @details The test verifies the timer HAL implementation by comparing the
+ * @details The test verifies the timer HAL implementation by comparing the
+ * period between the interrupts with the lifetime timer values
+ * that has been already verified in a previous test (see #TimerTest).
*
- * @return Returns the \link #status_t status\endlink:
- * - #STATUS_OK on success.
- * - #ERROR_NOT_IMPLEMENTED if the PIT functionality is not
- * implemented and the test is skipped.
- * - #ERROR_FAIL if the measured interval does not match the
- * expectations or the PIT was not disabled properly.
- * - #ERROR_TIMEOUT if either the PIT events do not occur within the
- * expected time.
- * - The PIT layer error code if #Timer_SetInterval or
- * #Timer_SetCallback return any negative status.
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_NOT_IMPLEMENTED if the PIT functionality is not
+ * implemented and the test is skipped.
+ * - #ERROR_FAIL if the measured interval does not match the
+ * expectations or the PIT was not disabled properly.
+ * - #ERROR_TIMEOUT if either the PIT events do not occur within the
+ * expected time.
+ * - The PIT layer error code if #Timer_SetInterval or
+ * #Timer_SetCallback return any negative status.
*****************************************************************************/
static status_t PITTest(void)
{
@@ -1369,31 +1714,595 @@ static status_t PITTest(void)
if (status == ERROR_NOT_IMPLEMENTED) { return status; }
- if (status < STATUS_OK) {
- PX4_INFO_RAW("PIT test failed!\n"
- "Timer_SetCallback returned status code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("PIT test failed!\n"
+ "Timer_SetCallback returned status code: %d", status);
return status;
}
+ status = RunPITTest(200000, 5);
+
+ if (status != STATUS_OK) { return status; }
+
status = RunPITTest(10000, 10);
- if (status < STATUS_OK) { return status; }
+ if (status != STATUS_OK) { return status; }
- status = RunPITTest(333, 1000);
+ /* High Speed Test down to 1000 microseconds. If this fails, just print
+ * a message that very high frame rates might have issues. */
+ status = RunPITTest(1000, 500);
- if (status < STATUS_OK) { return status; }
+ if (status != STATUS_OK) {
+ print("WARNING: PIT test failed for 1000 us interval!\n"
+ " This is only critical if high frame rates (up to 1000 fps)\n"
+ " need to be achieved. Otherwise, the error can be safely ignored.\n");
+ status = STATUS_IGNORE; // ignore
+ }
- status = RunPITTest(100000, 5);
+ if (status == STATUS_OK) { // only run if previous test succeeded!
+ /* High Speed Test down to 333 microseconds. If this fails, just print
+ * a message that very high frame rates might have issues. */
+ status = RunPITTest(333, 500);
- if (status < STATUS_OK) { return status; }
+ if (status != STATUS_OK) {
+ print("WARNING: PIT test failed for 333 us interval!\n"
+ " This is only critical if very high frame rates (up to 3000 fps)\n"
+ " need to be achieved. Otherwise, the error can be safely ignored.\n");
+ status = STATUS_IGNORE; // ignore
+ }
+ }
status = Timer_SetCallback(0);
- if (status < STATUS_OK) {
- PX4_INFO_RAW("PIT test failed!\n"
- "Timer_SetCallback to 0 returned status code: %d", (int)status);
+ if (status != STATUS_OK) {
+ error_log("PIT test failed!\n"
+ "Timer_SetCallback to 0 returned status code: %d", status);
return status;
}
return STATUS_OK;
}
+
+/*!***************************************************************************
+ * @brief Data structure for the S2PI transfer from interrupt tests.
+ *
+ * @details Contains data that is required by the S2PI transfer from interrupt
+ * test. The data structure is passed to the corresponding interrupt
+ * callback functions.
+ *****************************************************************************/
+typedef struct spi_irq_data_t {
+ /*! The status of the interrupt callback function. */
+ volatile status_t Status;
+
+ /*! The S2PI slave parameter passed to the S2PI HAL functions. */
+ s2pi_slave_t Slave;
+
+ /*! The data buffer to be transferred from/to the device for testing purposes. */
+ uint8_t Data[17U];
+
+ /*! Set to true when all SPI transfers are finished. */
+ volatile bool Finished;
+
+ /*! Set to true when the second SPI transfers is started.
+ The second transfer is used to read-back the previously set values. */
+ volatile bool ReadBack;
+
+} spi_irq_data_t;
+
+
+/*!***************************************************************************
+ * @brief SPI interrupt callback function for the SPI transfer from IRQ test.
+ *
+ * @details The interrupt callback is invoked from the S2PI module upon
+ * finishing the SPI transfer. The callback is used by the
+ * #SpiTransferFromSpiInterrupt test to trigger the second SPI transfer
+ * from the interrupt callback context.
+ *
+ * @note The callback also utilizes the #print functionality. This requires
+ * a correct implementation of the corresponding function such that it
+ * can be invoked from the given interrupt context. This usually
+ * requires the underlying send (e.g. UART or USB send functions) to
+ * have higher priority that this interrupt in order to finished the
+ * print statement asynchronously.
+ *
+ * @param status The S2PI module status passed to the callback.
+ * @param param The abstract interrupt callback parameter.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_INVALID_ARGUMENT if the \p param is NULL.
+ * - The S2PI layer error code if any is passed to the callback function.
+ * - The S2PI layer error code if #S2PI_TransferFrame return any.
+ *****************************************************************************/
+static status_t SpiTransferFromSpiInterruptCallback(status_t status, void *param)
+{
+ if (param == NULL) {
+ error_log("SPI transfer from SPI interrupt test failed\n"
+ "callback parameter \"param\" was NULL!");
+ return ERROR_INVALID_ARGUMENT;
+ }
+
+ spi_irq_data_t *data = (spi_irq_data_t *) param;
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from SPI interrupt test failed:\n"
+ "callback received error! Error code: %d", status);
+ data->Status = status;
+ return status;
+ }
+
+ if (!data->ReadBack) {
+ print("Invoking SPI transfer from SPI interrupt callback...\n");
+
+ /* Clear the laser pattern and read back previous values. */
+ data->Data[0] = 0x04; // Laser Pattern Register Address
+
+ for (uint8_t i = 1; i < 17U; ++i) { data->Data[i] = 0; }
+
+ status = S2PI_TransferFrame(data->Slave, data->Data, data->Data, 17U,
+ SpiTransferFromSpiInterruptCallback, param);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from SPI interrupt test failed:\n"
+ "Calling S2PI_TransferFrame from SPI interrupt "
+ "returned error code: %d", status);
+ data->Status = status;
+ return status;
+ }
+
+ data->ReadBack = true;
+
+ } else {
+ data->Finished = true;
+ }
+
+ return STATUS_OK;
+}
+
+/*!***************************************************************************
+ * @brief SPI transfer from SPI interrupt callback test.
+ *
+ * @details This test verifies the interrupt functionality of the SPI interface.
+ * The test verifies that an SPI transfer can be triggered from the SPI
+ * interrupt service routine context.
+ *
+ * The test basically repeats the #SpiConnectionTest but this time it
+ * invokes the second SPI transfer from the SPI callback function.
+ * A very common error is that the callback is invoked while the SPI
+ * module is still busy which does not allow to invoke another SPI
+ * transfer from the callback.
+ *
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the test did not finish within a specified time.
+ * - #ERROR_FAIL if the device access failed and the read data did not
+ * match the expected values.
+ * - The S2PI layer error code if #S2PI_TransferFrame or the SPI
+ * callback yield in any non-OK status.
+ *****************************************************************************/
+static status_t SpiTransferFromSpiInterrupt(s2pi_slave_t slave)
+{
+ /* Test parameter configuration: *****************************************/
+ const uint32_t timeout_us = 100000; // timeout for SPI transfers to finish
+ /*************************************************************************/
+
+ status_t status = STATUS_OK;
+ spi_irq_data_t data = { .Slave = slave };
+
+ print("Invoking SPI transfer from task level...\n");
+
+ /* Transfer a pattern to the register */
+ data.Data[0] = 0x04; // Laser Pattern Register Address
+
+ for (uint8_t i = 1; i < 17U; ++i) { data.Data[i] = i; }
+
+ status = S2PI_TransferFrame(slave, data.Data, data.Data, 17U,
+ SpiTransferFromSpiInterruptCallback, &data);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from SPI interrupt test failed:\n"
+ "Failed to transfer a data frame! Error code: %d", status);
+ return status;
+ }
+
+ /* Wait until transfers has finished. */
+ ltc_t start;
+ Time_GetNow(&start);
+
+ while (!data.Finished && (data.Status == STATUS_OK)) {
+ if (Time_CheckTimeoutUSec(&start, timeout_us)) {
+ const uint32_t elapsed_us = Time_GetElapsedUSec(&start);
+ error_log("SPI transfer from SPI interrupt test failed:\n"
+ "Waiting for the transfers to be finished yielded a timeout.\n"
+ "Timeout: %d us; Elapsed: %d us (%d of %d events).",
+ timeout_us, elapsed_us);
+ status = ERROR_TIMEOUT;
+ break;
+ }
+ }
+
+ if (data.Status != STATUS_OK) {
+ error_log("SPI transfer from SPI interrupt test failed:\n"
+ "Waiting for the transfers to be finished yielded a error code: %d",
+ data.Status);
+ return data.Status;
+ }
+
+ print("Verify read data...\n");
+
+ /* Verify the read pattern. */
+ for (uint8_t i = 1; i < 17U; ++i) {
+ if (data.Data[i] != i) {
+ error_log("SPI transfer from SPI interrupt test failed:\n"
+ "Verification of read data is invalid!\n"
+ "read_data[%d] = %d, but expected was %d",
+ i, data.Data[i], i);
+ return ERROR_FAIL;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+/*!***************************************************************************
+ * @brief GPIO interrupt callback function for the SPI transfer from IRQ test.
+ *
+ * @details The interrupt callback is invoked from the S2PI module upon
+ * receiving an GPIO interrupt from the devices IRQ pin. The callback
+ * is used by the #SpiTransferFromGpioInterrupt test to trigger the
+ * first SPI transfer from the interrupt callback context.
+ *
+ * @note The callback also utilizes the #print functionality. This requires
+ * a correct implementation of the corresponding function such that it
+ * can be invoked from the given interrupt context. This usually
+ * requires the underlying send (e.g. UART or USB send functions) to
+ * have higher priority that this interrupt in order to finished the
+ * print statement asynchronously.
+ *
+ * @param param The abstract interrupt callback parameter.
+ *****************************************************************************/
+static void SpiTransferFromGpioInterruptCallback(void *param)
+{
+ if (param == NULL) {
+ error_log("SPI transfer from GPIO interrupt test failed:\n"
+ "callback parameter \"param\" was NULL!");
+ return;
+ }
+
+ print("Invoking SPI transfer from GPIO interrupt callback...\n");
+
+ /* Clear the laser pattern and read back previous values. */
+ spi_irq_data_t *data = (spi_irq_data_t *) param;
+ data->Data[0] = 0x04; // Laser Pattern Register Address
+
+ for (uint8_t i = 1; i < 17U; ++i) { data->Data[i] = i; }
+
+ status_t status = S2PI_TransferFrame(data->Slave, data->Data, data->Data, 17U,
+ SpiTransferFromSpiInterruptCallback, param);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from GPIO interrupt test failed:\n"
+ "Calling S2PI_TransferFrame from GPIO interrupt "
+ "returned error code: %d", status);
+ data->Status = status;
+ return;
+ }
+}
+
+/*!***************************************************************************
+ * @brief SPI transfer from GPIO interrupt callback test.
+ *
+ * @details This test verifies the interrupt functionality of the SPI interface.
+ * The test verifies that an SPI transfer can be triggered from the
+ * GPIO interrupt service routine context.
+ *
+ * The test basically repeats the #SpiTransferFromSpiInterrupt but
+ * this time it invokes the first SPI transfer from the GPIO callback
+ * function. In order to trigger a GPIO interrupt, the device is
+ * configured and a measurement is started (see #GpioInterruptTest).
+ *
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the test did not finish within a specified time.
+ * - #ERROR_FAIL if the device access failed and the read data did not
+ * match the expected values.
+ * - The S2PI layer error code if #S2PI_TransferFrame or the GPIO or
+ * SPI callback yield in any non-OK status.
+ *****************************************************************************/
+static status_t SpiTransferFromGpioInterrupt(s2pi_slave_t slave)
+{
+ /* Test parameter configuration: *****************************************/
+ const uint32_t timeout_ms = 300; // timeout for measurement, might be increased..
+ /*************************************************************************/
+
+ spi_irq_data_t data = { .Slave = slave };
+
+ /* Install IRQ callback. */
+ status_t status = S2PI_SetIrqCallback(slave, SpiTransferFromGpioInterruptCallback, &data);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from GPIO interrupt test failed:\n"
+ "The call to S2PI_SetIrqCallback returned error code: %d", status);
+ return status;
+ }
+
+ /* Setup Device for invoking GPIO interrupt. */
+ status = ConfigureDevice(slave, 0);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from GPIO interrupt test failed.");
+ return status;
+ }
+
+ /* Trigger Measurement and invoke GPIO interrupt. */
+ status = TriggerMeasurement(slave, 0, 0, 0);
+
+ if (status != STATUS_OK) {
+ error_log("GPIO interrupt test failed!");
+ return status;
+ }
+
+ ltc_t start;
+ Time_GetNow(&start);
+
+ /* Wait for Interrupt using the callback method. */
+ while (!data.Finished) {
+ if (Time_CheckTimeoutMSec(&start, timeout_ms)) {
+ error_log("SPI transfer from GPIO interrupt test failed:\n"
+ "The IRQ callback was not invoked within %d ms.",
+ timeout_ms);
+ return ERROR_TIMEOUT;
+ }
+ }
+
+ if (data.Status != STATUS_OK) {
+ error_log("SPI transfer from GPIO interrupt test failed:\n"
+ "Waiting for the transfers to be finished yielded a error code: %d",
+ data.Status);
+ return data.Status;
+ }
+
+ print("Verify read data...\n");
+
+ /* Verify the read pattern. */
+ for (uint8_t i = 1; i < 17U; ++i) {
+ if (data.Data[i] != i) {
+ error_log("SPI transfer from GPIO interrupt test failed:\n"
+ "Verification of read data is invalid!\n"
+ "read_data[%d] = %d, but expected was %d",
+ i, data.Data[i], i);
+ return ERROR_FAIL;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+/*!***************************************************************************
+ * @brief PIT interrupt callback function for the SPI transfer from IRQ test.
+ *
+ * @details The interrupt callback is invoked from the PIT module upon periodic
+ * timeout event. The callback is used by the
+ * #SpiTransferFromPitInterrupt test to trigger the first SPI transfer
+ * from the interrupt callback context.
+ *
+ * @note The callback also utilizes the #print functionality. This requires
+ * a correct implementation of the corresponding function such that it
+ * can be invoked from the given interrupt context. This usually
+ * requires the underlying send (e.g. UART or USB send functions) to
+ * have higher priority that this interrupt in order to finished the
+ * print statement asynchronously.
+ *
+ * @param param The abstract interrupt callback parameter.
+ *****************************************************************************/
+static void SpiTransferFromPitInterruptCallback(void *param)
+{
+ status_t status = Timer_SetInterval(0, param); // disable timer
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "Timer_SetCallback to 0 returned status code: %d",
+ status);
+
+ if (param != NULL) { ((spi_irq_data_t *)param)->Status = status; }
+
+ return;
+ }
+
+
+ if (param == NULL) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "callback parameter \"param\" was NULL!");
+ return;
+ }
+
+ print("Invoking SPI transfer from PIT interrupt callback...\n");
+
+ /* Clear the laser pattern and read back previous values. */
+ spi_irq_data_t *data = (spi_irq_data_t *) param;
+ data->Data[0] = 0x04; // Laser Pattern Register Address
+
+ for (uint8_t i = 1; i < 17U; ++i) { data->Data[i] = i; }
+
+ status = S2PI_TransferFrame(data->Slave, data->Data, data->Data, 17U,
+ SpiTransferFromSpiInterruptCallback, param);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "Calling S2PI_TransferFrame from GPIO interrupt "
+ "returned error code: %d", status);
+ data->Status = status;
+ return;
+ }
+}
+
+/*!***************************************************************************
+ * @brief SPI transfer from PIT interrupt callback test.
+ *
+ * @details This test verifies the interrupt functionality of the SPI interface.
+ * The test verifies that an SPI transfer can be triggered from the
+ * PIT interrupt service routine context.
+ *
+ * The test basically repeats the #SpiTransferFromSpiInterrupt but
+ * this time it invokes the first SPI transfer from the PIT callback
+ * function. In order to trigger a PIT interrupt, the timer is
+ * configured with a small interval and immediately disabled upon the
+ * first event.
+ *
+ * Note that this test is only executed if the PIT module is actually
+ * implemented.
+ *
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_NOT_IMPLEMENTED if the PIT functionality is not
+ * implemented and the test is skipped.
+ * - #ERROR_TIMEOUT if the test did not finish within a specified time.
+ * - #ERROR_FAIL if the device access failed and the read data did not
+ * match the expected values.
+ * - The S2PI layer error code if #S2PI_TransferFrame or the SPI
+ * callback yield in any non-OK status.
+ * - The PIT layer error code if #Timer_SetCallback or the PIT
+ * callback yield in any non-OK status.
+ *****************************************************************************/
+static status_t SpiTransferFromPitInterrupt(s2pi_slave_t slave)
+{
+ /* Test parameter configuration: *****************************************/
+ const uint32_t timeout_ms = 100; // timeout for test.
+ const uint32_t interval_us = 1000; // PIT interval for the first event.
+ /*************************************************************************/
+
+ spi_irq_data_t data = { .Slave = slave };
+
+ status_t status = Timer_SetCallback(SpiTransferFromPitInterruptCallback);
+
+ if (status == ERROR_NOT_IMPLEMENTED) { return status; }
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "Timer_SetCallback returned status code: %d", status);
+ return status;
+ }
+
+ /* Setup the PIT callback with specified interval. */
+ status = Timer_SetInterval(interval_us, &data);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "Timer_SetInterval returned status code: %d", status);
+ return status;
+ }
+
+ ltc_t start;
+ Time_GetNow(&start);
+
+ /* Wait for test to be finished. */
+ while (!data.Finished) {
+ if (Time_CheckTimeoutMSec(&start, timeout_ms)) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "The IRQ callback was not invoked within %d ms.",
+ timeout_ms);
+ return ERROR_TIMEOUT;
+ }
+ }
+
+ if (data.Status != STATUS_OK) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "Waiting for the transfers to be finished yielded a error code: %d",
+ data.Status);
+ return data.Status;
+ }
+
+ status = Timer_SetCallback(0);
+
+ if (status != STATUS_OK) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "Timer_SetCallback to 0 returned status code: %d", status);
+ return status;
+ }
+
+ print("Verify read data...\n");
+
+ /* Verify the read pattern. */
+ for (uint8_t i = 1; i < 17U; ++i) {
+ if (data.Data[i] != i) {
+ error_log("SPI transfer from PIT interrupt test failed:\n"
+ "Verification of read data is invalid!\n"
+ "read_data[%d] = %d, but expected was %d",
+ i, data.Data[i], i);
+ return ERROR_FAIL;
+ }
+ }
+
+ return STATUS_OK;
+}
+
+/*!***************************************************************************
+ * @brief SPI Transfer from Interrupt Test for S2PI HAL Implementation.
+ *
+ * @details This test verifies the interrupt functionality of the SPI interface.
+ * The test verifies that an SPI transfer can be triggered from the
+ * interrupt service routine context. I.e. the #S2PI_TransferFrame
+ * function is called from the following interrupts:
+ * - SPI interrupt
+ * - GPIO interrupt
+ * - PIT interrupt (optional, if PIT is implemented)
+ *
+ * @warning The test utilizes already the timer HAL in order to implement a
+ * rudimentary timeout. However, at this time, only some basic
+ * plausibility checks are performed on the timer HAL. I.e. if there
+ * is an issue in the time HAL, e.g. too fast or too slow time
+ * counting, the test may fail with an #ERROR_TIMEOUT. In this case,
+ * one also needs to verify the timer HAL, especially the
+ * #Timer_GetCounterValue function.
+ *
+ * @param slave The S2PI slave parameter passed to the S2PI HAL functions.
+ *
+ * @return Returns the \link #status_t status\endlink:
+ * - #STATUS_OK on success.
+ * - #ERROR_TIMEOUT if the operation did not finished within a specified
+ * time (check also timer HAL implementation).
+ * - #ERROR_FAIL if the device access failed and the read data did not
+ * match the expected values.
+ * - The S2PI layer error code if #S2PI_TransferFrame or #S2PI_GetStatus
+ * return any negative status.
+ *****************************************************************************/
+static status_t SpiTransferFromInterruptTest(s2pi_slave_t slave)
+{
+ status_t status = STATUS_OK;
+
+ print(" .1 >> SPI Transfer from SPI Interrupt Test\n");
+ status = SpiTransferFromSpiInterrupt(slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print(" .1 >> PASS\n\n");
+
+ print(" .2 >> SPI Transfer from GPIO Interrupt Test\n");
+ status = SpiTransferFromGpioInterrupt(slave);
+
+ if (status != STATUS_OK) { return status; }
+
+ print(" .2 >> PASS\n\n");
+
+ print(" .3 >> SPI Transfer from PIT Interrupt Test\n");
+ status = SpiTransferFromPitInterrupt(slave);
+
+ if (status == ERROR_NOT_IMPLEMENTED) {
+ print(" .3 >> SKIPPED (PIT is not implemented)\n\n");
+
+ } else {
+ if (status != STATUS_OK) { return status; }
+
+ print(" .3 >> PASS\n\n");
+ }
+
+ return STATUS_OK;
+}
+
+/*! @} */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.h b/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.h
index 5af6660dfa..be9c0071e4 100644
--- a/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.h
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/argus_hal_test.h
@@ -1,10 +1,10 @@
/*************************************************************************//**
- * @file argus_hal_test.c
- * @brief Tests for the AFBR-S50 API hardware abstraction layer.
+ * @file
+ * @brief Tests for the AFBR-S50 API hardware abstraction layer.
*
* @copyright
*
- * Copyright (c) 2021, Broadcom, Inc.
+ * Copyright (c) 2023, Broadcom Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,147 +41,192 @@
extern "C" {
#endif
-
/*!***************************************************************************
- * @defgroup argustest HAL Self Test
+ * @defgroup argus_test HAL Self Test
+ * @ingroup argus
*
- * @brief A test module to verify implementation of the HAL.
+ * @brief A test module to verify implementation of the HAL.
*
- * @details A series of automated tests that can be executed on the target
- * platform in order to verify the implementation of the HAL that
- * are required by the API.
+ * @details A series of automated tests that can be executed on the target
+ * platform in order to verify the implementation of the HAL that
+ * are required by the API.
*
- * @addtogroup argustest
+ * See #Argus_VerifyHALImplementation for a detailed documentation.
+ *
+ * @addtogroup argus_test
* @{
*****************************************************************************/
#include "argus.h"
/*!***************************************************************************
- * @brief Version number of the HAL Self Test.
+ * @brief Version number of the HAL Self Test.
*
* @details Changes:
- * * v1.0:
- * - Initial release.
- * * v1.1:
- * - Added additional print output.
- * - Increased tolerance for timer test to 3%.
- * - Fixed callback issue by disabling it after IRQ test.
- * * v1.1:
- * - Added PIT test cases.
+ * * v1.0:
+ * - Initial release.
+ * * v1.1:
+ * - Added additional print output.
+ * - Increased tolerance for timer test to 3%.
+ * - Fixed callback issue by disabling it after IRQ test.
+ * * v1.2:
+ * - Added PIT test cases.
+ * * v1.3:
+ * - Added test case for SPI maximum data transfer size.
+ * - Added tests for SPI transfers invoked from all IRQ callbacks.
+ * - Added verification of first PIT event occurrence.
+ * - Relaxed PIT pass conditions (0.1% -> 0.5%)
+ * * v1.4:
+ * - Adopted to new multi-device HAL interface of API v1.4.4 release.
+ * - Added verification of SPI callback invocation.
+ * - Updated GPIO interrupt test to verify if delayed interrupt
+ * pending states can be detected via #S2PI_ReadIrqPin.
+ *
*****************************************************************************/
-#define HAL_TEST_VERSION "v1.2"
+#define HAL_TEST_VERSION "v1.4"
/*!***************************************************************************
- * @brief Executes a series of tests in order to verify the HAL implementation.
+ * @brief Executes a series of tests in order to verify the HAL implementation.
*
* @details A series of automated tests are executed on the target platform in
- * order to verify the implementation of the HAL that are required by
- * the API.
+ * order to verify the implementation of the HAL that are required by
+ * the API.
*
- * Each test will write an error description via the print (i.e. UART)
- * function that shows what went wrong. Also an corresponding status is
- * returned in case no print functionality is available.
+ * Each test will write an error description via the print (i.e. UART)
+ * function that shows what went wrong. Also an corresponding status is
+ * returned in case no print functionality is available.
*
- * The following tests are executed:
+ * The following tests are executed:
*
- * **1) Timer Plausibility Test:**
+ * **1) Timer Plausibility Test:**
*
- * Rudimentary tests of the lifetime counter (LTC) implementation.
- * This verifies that the LTC is running by checking if the returned
- * values of two consecutive calls to the #Timer_GetCounterValue
- * function are ascending. An artificial delay using the NOP operation
- * is induced such that the timer is not read to fast.
+ * Rudimentary tests of the lifetime counter (LTC) implementation.
+ * This verifies that the LTC is running by checking if the returned
+ * values of two consecutive calls to the #Timer_GetCounterValue
+ * function are ascending. An artificial delay using the NOP operation
+ * is induced such that the timer is not read to fast.
*
- * **2) Timer Wraparound Test:**
+ * **2) Timer Wraparound Test:**
*
- * The LTC values must wrap from 999999 µs to 0 µs and increase the
- * seconds counter accordingly. This test verifies the correct wrapping
- * by consecutively calling the #Timer_GetCounterValue function until
- * at least 2 wraparound events have been occurred.
+ * The LTC values must wrap from 999999 µs to 0 µs and increase the
+ * seconds counter accordingly. This test verifies the correct wrapping
+ * by consecutively calling the #Timer_GetCounterValue function until
+ * at least 2 wraparound events have been occurred.
*
- * **3) SPI Connection Test:**
+ * **3) SPI Connection Test:**
*
- * This test verifies the basic functionality of the SPI interface.
- * The test utilizes the devices laser pattern register, which can
- * be freely programmed by any 128-bit pattern. Thus, it writes a byte
- * sequence and reads back the written values on the consecutive SPI
- * access.
+ * This test verifies the basic functionality of the SPI interface.
+ * The test utilizes the devices laser pattern register, which can
+ * be freely programmed by any 128-bit pattern. Thus, it writes a byte
+ * sequence and reads back the written values on the consecutive SPI
+ * access.
*
- * **4) SPI Interrupt Test:**
+ * **4) SPI Maximum Data Length Test**:
*
- * This test verifies the correct implementation of the device
- * integration finished interrupt callback. Therefore it configures
- * the device with a minimal setup to run a pseudo measurement that
- * does not emit any laser light.
+ * This test verifies the maximum data transfer length of the SPI
+ * interface. The test sends and receives up to 396 data bytes plus
+ * a single address byte over the SPI interface and verifies that no
+ * data get lost.
*
- * Note that this test does verify the GPIO interrupt that occurs
- * whenever the device has finished the integration/measurement and
- * new data is waiting to be read from the device. This does not test
- * the interrupt that is triggered when the SPI transfer has finished.
+ * **5) SPI Interrupt Test:**
*
- * The data ready interrupt implies two S2PI layer functions that
- * are tested in this test: The #S2PI_SetIrqCallback function installs
- * a callback function that is invoked whenever the IRQ occurs.
- * The IRQ can be delayed due to higher priority task, e.g. from the
- * user code. It is essential for the laser safety timeout algorithm
- * to determine the device ready signal as fast as possible, another
- * method is implemented to read if the IRQ is pending but the
- * callback has not been reset yet. This is what the #S2PI_ReadIrqPin
- * function is for.
+ * This test verifies the correct implementation of the device
+ * integration finished interrupt callback. Therefore it configures
+ * the device with a minimal setup to run a pseudo measurement that
+ * does not emit any laser light.
*
- * **5) GPIO Mode Test:**
+ * Note that this test does verify the GPIO interrupt that occurs
+ * whenever the device has finished the integration/measurement and
+ * new data is waiting to be read from the device. This does not test
+ * the interrupt that is triggered when the SPI transfer has finished.
*
- * This test verifies the GPIO mode of the S2PI HAL module. This is
- * done by leveraging the EEPROM readout sequence that accesses the
- * devices EEPROM via a software protocol that depends on the GPIO
- * mode.
+ * The data ready interrupt implies two S2PI layer functions that
+ * are tested in this test: The #S2PI_SetIrqCallback function installs
+ * a callback function that is invoked whenever the IRQ occurs.
+ * The IRQ can be delayed due to higher priority task, e.g. from the
+ * user code. It is essential for the laser safety timeout algorithm
+ * to determine the device ready signal as fast as possible, another
+ * method is implemented to read if the IRQ is pending but the
+ * callback has not been reset yet. This is what the #S2PI_ReadIrqPin
+ * function is for.
*
- * This the requires several steps, most of them are already verified
- * in previous tests:
+ * **6) GPIO Mode Test:**
*
- * - Basic device configuration and enable EEPROM.
- * - Read EERPOM via GPIO mode and apply Hamming weight.
- * - Repeat several times (to eliminate random readout issues).
- * - Decode the EEPROM (using EEPROM_Decode in argus_cal_eeprom.c).
- * - Check if Module Number and Chip ID is not 0.
+ * This test verifies the GPIO mode of the S2PI HAL module. This is
+ * done by leveraging the EEPROM readout sequence that accesses the
+ * devices EEPROM via a software protocol that depends on the GPIO
+ * mode.
*
- * **6) Timer Test for Lifetime Counter:**
+ * This the requires several steps, most of them are already verified
+ * in previous tests:
*
- * The test verifies the lifetime counter timer HAL implementation by
- * comparing the timings to the AFBR-S50 device as a reference.
- * Therefore several measurement are executed on the device, each with
- * a different averaging sample count. The elapsed time increases
- * linearly with the number of averaging samples. In order to remove
- * the time for software/setup, a linear regression fit is applied to
- * the measurement results and only the slope is considered for the
- * result. A delta of 102.4 microseconds per sample is expected.
- * If the measured delta per sample is within an specified error range,
- * the timer implementation is considered correct.
+ * - Basic device configuration and enable EEPROM.
+ * - Read EERPOM via GPIO mode and apply Hamming weight.
+ * - Repeat several times (to eliminate random readout issues).
+ * - Decode the EEPROM (using EEPROM_Decode in argus_cal_eeprom.c).
+ * - Check if Module Number and Chip ID is not 0.
*
- * **7) Timer Test for Periodic Interrupt Timer:**
+ * **7) Timer Test for Lifetime Counter:**
*
- * The test verifies the correct implementation of the periodic
- * interrupt timer (PIT). It sets different intervals and waits for
- * a certain number of interrupts to happen. Each interrupt event
- * is counted and the time between the first and the last interrupt
- * is measured. Finally, the measured interval is compared to the
- * expectations.
+ * The test verifies the lifetime counter timer HAL implementation by
+ * comparing the timings to the AFBR-S50 device as a reference.
+ * Therefore several measurement are executed on the device, each with
+ * a different averaging sample count. The elapsed time increases
+ * linearly with the number of averaging samples. In order to remove
+ * the time for software/setup, a linear regression fit is applied to
+ * the measurement results and only the slope is considered for the
+ * result. A delta of 102.4 microseconds per sample is expected.
+ * If the measured delta per sample is within an specified error range,
+ * the timer implementation is considered correct.
*
+ * **8) Timer Test for Periodic Interrupt Timer (optional):**
*
- * @param spi_slave The SPI hardware slave, i.e. the specified CS and IRQ
- * lines. This is actually just a number that is passed
- * to the SPI interface to distinct for multiple SPI slave
- * devices. Note that the slave must be not equal to 0,
- * since is reserved for error handling.
+ * The test verifies the correct implementation of the periodic
+ * interrupt timer (PIT). It sets different intervals and waits for
+ * a certain number of interrupts to happen. Each interrupt event
+ * is counted and the time between the first and the last interrupt
+ * is measured. Finally, the measured interval is compared to the
+ * expectations.
*
- * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
+ * Note that this test is only executed if the PIT is actually
+ * implemented. Otherwise, the test is skipped.
+ *
+ * **9) SPI Transfer from Interrupt Callback Test:**
+ *
+ * The test verifies that the #S2PI_TransferFrame method of the
+ * S2PI layer can be invoked from a interrupt callback function too.
+ * Thus, it repeats the S2PI Connection Test but this time from
+ * different interrupt callback functions:
+ *
+ * - SPI Callback: The first transfer is invoked from thread level,
+ * the second transfer is invoke from the SPI interrupt callback
+ * function.
+ *
+ * - GPIO Callback: The device is setup to trigger an GPIO interrupt
+ * (see also the SPI Interrupt Test). The corresponding GPIO
+ * interrupt callback function will trigger the first transfer while
+ * the second one is triggered from the SPI callback function.
+ *
+ * - PIT Callback (optional): This test is only executed optional if
+ * the PIT interface is implemented. The test sequence is the same
+ * as for the GPIO callback, but the first transfer is triggered
+ * from the PIT callback function.
+ *
+ * @note See #HAL_TEST_VERSION for a version history and change log of
+ * the HAL self tests.
+ *
+ * @param spi_slave The SPI hardware slave, i.e. the specified CS and IRQ
+ * lines. This is actually just a number that is passed
+ * to the SPI interface to distinct for multiple SPI slave
+ * devices. Note that the slave must be not equal to 0,
+ * since is reserved for error handling.
+ *
+ * @return Returns the \link #status_t status\endlink (#STATUS_OK on success).
*****************************************************************************/
status_t Argus_VerifyHALImplementation(s2pi_slave_t spi_slave);
-#ifdef __cplusplus
-}
-#endif
-
/*! @} */
-#endif /* ARGUS_CAL_API_H */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif /* ARGUS_HAL_TEST_H */
diff --git a/src/drivers/distance_sensor/broadcom/afbrs50/parameters.c b/src/drivers/distance_sensor/broadcom/afbrs50/parameters.c
new file mode 100644
index 0000000000..28ef2a17c1
--- /dev/null
+++ b/src/drivers/distance_sensor/broadcom/afbrs50/parameters.c
@@ -0,0 +1,102 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * AFBR Rangefinder Mode
+ *
+ * This parameter defines the mode of the AFBR Rangefinder.
+ *
+ * @reboot_required true
+ * @min 0
+ * @max 3
+ * @group Sensors
+ *
+ * @value 0 Short Range Mode
+ * @value 1 Long Range Mode
+ * @value 2 High Speed Short Range Mode
+ * @value 3 High Speed Long Range Mode
+ */
+PARAM_DEFINE_INT32(SENS_AFBR_MODE, 1);
+
+/**
+ * AFBR Rangefinder Short Range Rate
+ *
+ * This parameter defines measurement rate of the AFBR Rangefinder in short range mode.
+ *
+ * @min 1
+ * @max 100
+ * @group Sensors
+ *
+ */
+PARAM_DEFINE_INT32(SENS_AFBR_S_RATE, 50);
+
+/**
+ * AFBR Rangefinder Long Range Rate
+ *
+ * This parameter defines measurement rate of the AFBR Rangefinder in long range mode.
+ *
+ * @min 1
+ * @max 100
+ * @group Sensors
+ *
+ */
+PARAM_DEFINE_INT32(SENS_AFBR_L_RATE, 25);
+
+/**
+ * AFBR Rangefinder Short/Long Range Threshold
+ *
+ * This parameter defines the threshold for switching between short and long range mode.
+ * The mode will switch from short to long range when the distance is greater than the threshold plus the hysteresis.
+ * The mode will switch from long to short range when the distance is less than the threshold minus the hysteresis.
+ *
+ * @unit m
+ * @min 1
+ * @max 50
+ * @group Sensors
+ *
+ */
+PARAM_DEFINE_INT32(SENS_AFBR_THRESH, 5);
+
+
+/**
+ * AFBR Rangefinder Short/Long Range Threshold Hysteresis
+ *
+ * This parameter defines the hysteresis for switching between short and long range mode.
+ *
+ * @unit m
+ * @min 1
+ * @max 10
+ * @group Sensors
+ *
+ */
+PARAM_DEFINE_INT32(SENS_AFBR_HYSTER, 1);
diff --git a/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp b/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp
index baa2649d48..aafa605768 100644
--- a/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp
+++ b/src/drivers/distance_sensor/lightware_laser_i2c/lightware_laser_i2c.cpp
@@ -195,6 +195,13 @@ int LightwareLaser::init()
_type = Type::LW20c;
break;
+ case 7:
+ /* SF/LW30/d (200m 49-20'000Hz) */
+ _px4_rangefinder.set_min_distance(0.2f);
+ _px4_rangefinder.set_max_distance(200.0f);
+ _conversion_interval = 20409;
+ break;
+
default:
PX4_ERR("invalid HW model %" PRId32 ".", hw_model);
return ret;
diff --git a/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c b/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c
index c417efbe9e..b0564780be 100644
--- a/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c
+++ b/src/drivers/distance_sensor/lightware_laser_i2c/parameters.c
@@ -45,5 +45,6 @@
* @value 4 SF11/c
* @value 5 SF/LW20/b
* @value 6 SF/LW20/c
+ * @value 7 SF/LW30/d
*/
PARAM_DEFINE_INT32(SENS_EN_SF1XX, 0);
diff --git a/src/drivers/distance_sensor/lightware_laser_serial/lightware_laser_serial.cpp b/src/drivers/distance_sensor/lightware_laser_serial/lightware_laser_serial.cpp
index de418c69d7..f27636657f 100644
--- a/src/drivers/distance_sensor/lightware_laser_serial/lightware_laser_serial.cpp
+++ b/src/drivers/distance_sensor/lightware_laser_serial/lightware_laser_serial.cpp
@@ -308,7 +308,7 @@ void LightwareLaserSerial::Run()
// LW20: Enable serial mode by sending some characters
if (hw_model == 8) {
const char *data = "www\r\n";
- (void)!::write(_fd, &data, strlen(data));
+ (void)!::write(_fd, data, strlen(data));
}
}
diff --git a/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp b/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp
index 090152d9bc..fb95686381 100644
--- a/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp
+++ b/src/drivers/distance_sensor/vl53l1x/vl53l1x.cpp
@@ -35,10 +35,11 @@
***********/
#include "vl53l1x.hpp"
+#include
-#define VL53L1X_DELAY 20 //ms
+#define VL53L1X_DELAY 50000 // delay to reduce CPU usage (us)
#define VL53L1X_SAMPLE_RATE 200 // ms, default
-#define VL53L1X_INTER_MEAS_MS 200 // ms
+#define VL53L1X_INTER_MEAS_MS 200 // ms
#define VL53L1X_SHORT_RANGE 1 // sub-2 meter distance mode
#define VL53L1X_LONG_RANGE 2 // sub-4 meter distance mode
#define VL53L1X_RANGE_STATUS_OUT_OF_BOUNDS 13 // region of interest out of bounds error
@@ -261,18 +262,19 @@ int VL53L1X::probe()
void VL53L1X::RunImpl()
{
+
uint8_t dataReady = 0;
+
VL53L1X_CheckForDataReady(&dataReady);
if (dataReady == 1) {
collect();
}
+ // Reduce CPU usage
ScheduleDelayed(VL53L1X_DELAY);
-
// zone modulus increment
_zone_index = (_zone_index + 1) % _zone_limit;
-
// Set the ROI center based on zone incrementation
VL53L1X_SetROICenter(roi_center[_zone_index]);
}
@@ -292,6 +294,7 @@ int VL53L1X::init()
uint8_t x = 4;
uint8_t y = 4;
+
ret |= VL53L1X_SensorInit();
ret |= VL53L1X_ConfigBig(_distance_mode, VL53L1X_SAMPLE_RATE);
ret |= VL53L1X_SetROI(x, y);
@@ -488,6 +491,7 @@ int8_t VL53L1X::VL53L1X_CheckForDataReady(uint8_t *isDataReady)
uint8_t IntPol;
int8_t status = 0;
+
status = VL53L1X_GetInterruptPolarity(&IntPol);
status = VL53L1_RdByte(GPIO__TIO_HV_STATUS, &Temp);
@@ -498,6 +502,7 @@ int8_t VL53L1X::VL53L1X_CheckForDataReady(uint8_t *isDataReady)
} else {
*isDataReady = 0;
+
}
}
@@ -520,6 +525,7 @@ int8_t VL53L1X::VL53L1X_ClearInterrupt()
int8_t status = 0;
status = VL53L1_WrByte(SYSTEM__INTERRUPT_CLEAR, 0x01);
+
return status;
}
@@ -528,6 +534,8 @@ int8_t VL53L1X::VL53L1X_StopRanging()
int8_t status = 0;
status = VL53L1_WrByte(SYSTEM__MODE_START, 0x00); /* Disable VL53L1X */
+
+ ScheduleClear();
return status;
}
diff --git a/src/drivers/drv_hrt.h b/src/drivers/drv_hrt.h
index 17563002c4..3e295abfc9 100644
--- a/src/drivers/drv_hrt.h
+++ b/src/drivers/drv_hrt.h
@@ -294,17 +294,17 @@ namespace time_literals
// User-defined integer literals for different time units.
// The base unit is hrt_abstime in microseconds
-constexpr hrt_abstime operator "" _s(unsigned long long seconds)
+constexpr hrt_abstime operator ""_s(unsigned long long seconds)
{
return hrt_abstime(seconds * 1000000ULL);
}
-constexpr hrt_abstime operator "" _ms(unsigned long long milliseconds)
+constexpr hrt_abstime operator ""_ms(unsigned long long milliseconds)
{
return hrt_abstime(milliseconds * 1000ULL);
}
-constexpr hrt_abstime operator "" _us(unsigned long long microseconds)
+constexpr hrt_abstime operator ""_us(unsigned long long microseconds)
{
return hrt_abstime(microseconds);
}
diff --git a/src/drivers/drv_pwm_output.h b/src/drivers/drv_pwm_output.h
index 13251bfebd..6aedf298a3 100644
--- a/src/drivers/drv_pwm_output.h
+++ b/src/drivers/drv_pwm_output.h
@@ -61,41 +61,11 @@ __BEGIN_DECLS
*/
#define PWM_LOWEST_MIN 90
-/**
- * Default value for a shutdown motor
- */
-#define PWM_MOTOR_OFF 900
-
-/**
- * Default minimum PWM in us
- */
-#define PWM_DEFAULT_MIN 1000
-
-/**
- * Highest PWM allowed as the minimum PWM
- */
-#define PWM_HIGHEST_MIN 1600
-
/**
* Highest maximum PWM in us
*/
#define PWM_HIGHEST_MAX 2500
-/**
- * Default maximum PWM in us
- */
-#define PWM_DEFAULT_MAX 2000
-
-/**
- * Default trim PWM in us
- */
-#define PWM_DEFAULT_TRIM 0
-
-/**
- * Lowest PWM allowed as the maximum PWM
- */
-#define PWM_LOWEST_MAX 200
-
#endif // not PX4_PWM_ALTERNATE_RANGES
/**
diff --git a/src/drivers/drv_sensor.h b/src/drivers/drv_sensor.h
index fa64e1d7d3..549b7313c1 100644
--- a/src/drivers/drv_sensor.h
+++ b/src/drivers/drv_sensor.h
@@ -82,6 +82,7 @@
#define DRV_IMU_DEVTYPE_IIM42652 0x2B
#define DRV_IMU_DEVTYPE_IAM20680HP 0x2C
#define DRV_IMU_DEVTYPE_ICM42686P 0x2D
+#define DRV_IMU_DEVTYPE_IIM42653 0x2E
#define DRV_RNG_DEVTYPE_MB12XX 0x31
#define DRV_RNG_DEVTYPE_LL40LS 0x32
@@ -114,6 +115,7 @@
#define DRV_DIFF_PRESS_DEVTYPE_SDP32 0x4B
#define DRV_DIFF_PRESS_DEVTYPE_SDP33 0x4C
+
#define DRV_BARO_DEVTYPE_TCBP001TA 0x4D
#define DRV_BARO_DEVTYPE_MS5837 0x4E
#define DRV_BARO_DEVTYPE_SPL06 0x4F
@@ -233,6 +235,7 @@
#define DRV_INS_DEVTYPE_VN100 0xE1
#define DRV_INS_DEVTYPE_VN200 0xE2
#define DRV_INS_DEVTYPE_VN300 0xE3
+#define DRV_DIFF_PRESS_DEVTYPE_ASP5033 0xE4
#define DRV_DEVTYPE_UNUSED 0xff
diff --git a/src/drivers/dshot/DShot.h b/src/drivers/dshot/DShot.h
index f0cb4458f4..4f314cebb7 100644
--- a/src/drivers/dshot/DShot.h
+++ b/src/drivers/dshot/DShot.h
@@ -143,7 +143,7 @@ private:
void handle_vehicle_commands();
- MixingOutput _mixing_output {PARAM_PREFIX, DIRECT_PWM_OUTPUT_CHANNELS, *this, MixingOutput::SchedulingPolicy::Auto, false, false};
+ MixingOutput _mixing_output{PARAM_PREFIX, DIRECT_PWM_OUTPUT_CHANNELS, *this, MixingOutput::SchedulingPolicy::Auto, false, false};
uint32_t _reversible_outputs{};
Telemetry *_telemetry{nullptr};
diff --git a/src/drivers/gpio/Kconfig b/src/drivers/gpio/Kconfig
new file mode 100644
index 0000000000..902613ebbf
--- /dev/null
+++ b/src/drivers/gpio/Kconfig
@@ -0,0 +1,9 @@
+menu "GPIO"
+ menuconfig COMMON_GPIO
+ bool "Common GPIOs"
+ default n
+ select DRIVERS_GPIO_MCP23009
+ ---help---
+ Enable default set of GPIO drivers
+ rsource "*/Kconfig"
+endmenu
diff --git a/src/drivers/gpio/mcp23009/CMakeLists.txt b/src/drivers/gpio/mcp23009/CMakeLists.txt
new file mode 100644
index 0000000000..c7897fea8e
--- /dev/null
+++ b/src/drivers/gpio/mcp23009/CMakeLists.txt
@@ -0,0 +1,41 @@
+############################################################################
+#
+# Copyright (c) 2023 PX4 Development Team. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name PX4 nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+px4_add_module(
+ MODULE drivers__mcp23009
+ MAIN mcp23009
+ COMPILE_FLAGS
+ SRCS
+ mcp23009_main.cpp
+ mcp23009.cpp
+ DEPENDS
+ )
diff --git a/src/drivers/gpio/mcp23009/Kconfig b/src/drivers/gpio/mcp23009/Kconfig
new file mode 100644
index 0000000000..73078bf8eb
--- /dev/null
+++ b/src/drivers/gpio/mcp23009/Kconfig
@@ -0,0 +1,5 @@
+menuconfig DRIVERS_GPIO_MCP23009
+ bool "mcp23009"
+ default n
+ ---help---
+ Enable support for mcp23009
diff --git a/src/drivers/gpio/mcp23009/mcp23009.cpp b/src/drivers/gpio/mcp23009/mcp23009.cpp
new file mode 100644
index 0000000000..8d8eb92885
--- /dev/null
+++ b/src/drivers/gpio/mcp23009/mcp23009.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include "mcp23009.h"
+
+int MCP23009::read_reg(Register address, uint8_t &data)
+{
+ return transfer((uint8_t *)&address, 1, &data, 1);
+}
+
+int MCP23009::write_reg(Register address, uint8_t value)
+{
+ uint8_t data[2] = {(uint8_t)address, value};
+ return transfer(data, sizeof(data), nullptr, 0);
+}
+
+int MCP23009::init(uint8_t direction, uint8_t state, uint8_t pull_up)
+{
+ // do I2C init (and probe) first
+ int ret = I2C::init();
+
+ if (ret != PX4_OK) {
+ PX4_ERR("I2C init failed");
+ return ret;
+ }
+
+ // buffer the new initial states
+ _iodir = direction;
+ _olat = state;
+ _gppu = pull_up;
+
+ // Write the initial state to the device
+ ret = write_reg(Register::OLAT, _olat);
+ ret |= write_reg(Register::IODIR, _iodir);
+ ret |= write_reg(Register::GPPU, _gppu);
+
+ if (ret != PX4_OK) {
+ PX4_ERR("Device init failed (%i)", ret);
+ return ret;
+ }
+
+ return init_uorb();
+}
+
+int MCP23009::probe()
+{
+ // no whoami, try to read IOCON
+ uint8_t data;
+ return read_reg(Register::IOCON, data);
+}
+
+int MCP23009::read(uint8_t *mask)
+{
+ return read_reg(Register::GPIO, *mask);
+}
+
+int MCP23009::write(uint8_t mask_set, uint8_t mask_clear)
+{
+ // no need to read, we can use the buffered register value
+ _olat = (_olat & ~mask_clear) | mask_set;
+ return write_reg(Register::OLAT, _olat);
+}
+
+int MCP23009::configure(uint8_t mask, PinType type)
+{
+ // no need to read, we can use the buffered register values
+ switch (type) {
+ case PinType::Input:
+ _iodir |= mask;
+ _gppu &= ~mask;
+ break;
+
+ case PinType::InputPullUp:
+ _iodir |= mask;
+ _gppu |= mask;
+ break;
+
+ case PinType::Output:
+ _iodir &= ~mask;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ int ret = write_reg(Register::GPPU, _gppu);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ return write_reg(Register::IODIR, _iodir);
+}
diff --git a/src/drivers/gpio/mcp23009/mcp23009.h b/src/drivers/gpio/mcp23009/mcp23009.h
new file mode 100644
index 0000000000..fce68576c5
--- /dev/null
+++ b/src/drivers/gpio/mcp23009/mcp23009.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2020 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace time_literals;
+
+class MCP23009 : public device::I2C, public I2CSPIDriver
+{
+public:
+ MCP23009(const I2CSPIDriverConfig &config);
+ ~MCP23009() override;
+
+ void RunImpl();
+
+ static void print_usage();
+ static I2CSPIDriverBase *instantiate(const I2CSPIDriverConfig &config, int runtime_instance);
+
+protected:
+ int init_uorb();
+ int init(uint8_t direction, uint8_t state, uint8_t pull_up);
+
+ int probe() override;
+ void print_status() override;
+ void exit_and_cleanup() override;
+
+private:
+ enum class
+ Register : uint8_t {
+ IODIR = 0x00,
+ IPOL = 0x01,
+ GPINTEN = 0x02,
+ DEFVAL = 0x03,
+ INTCON = 0x04,
+ IOCON = 0x05,
+ GPPU = 0x06,
+ INTF = 0x07,
+ INTCAP = 0x08,
+ GPIO = 0x09,
+ OLAT = 0x0a
+ };
+
+ enum class
+ PinType : uint8_t {
+ Output,
+ Input,
+ InputPullUp,
+ };
+
+ uORB::SubscriptionCallbackWorkItem _gpio_out_sub{this, ORB_ID(gpio_out)};
+ uORB::SubscriptionCallbackWorkItem _gpio_request_sub{this, ORB_ID(gpio_request)};
+ uORB::SubscriptionCallbackWorkItem _gpio_config_sub{this, ORB_ID(gpio_config)};
+
+ uORB::Publication _to_gpio_in{ORB_ID(gpio_in)};
+
+ perf_counter_t _cycle_perf;
+
+ // buffer often used (write-only!) registers here
+ uint8_t _olat;
+ uint8_t _iodir;
+ uint8_t _gppu;
+
+ int read(uint8_t *mask);
+ int write(uint8_t mask_set, uint8_t mask_clear);
+ int configure(uint8_t mask, PinType type);
+
+ int read_reg(Register address, uint8_t &data);
+ int write_reg(Register address, uint8_t data);
+};
diff --git a/src/drivers/gpio/mcp23009/mcp23009_main.cpp b/src/drivers/gpio/mcp23009/mcp23009_main.cpp
new file mode 100644
index 0000000000..f5f9a2cfc4
--- /dev/null
+++ b/src/drivers/gpio/mcp23009/mcp23009_main.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/**
+ * Driver for the MCP23009 connected via I2C.
+ */
+
+#include "mcp23009.h"
+#include
+
+MCP23009::MCP23009(const I2CSPIDriverConfig &config) :
+ I2C(config),
+ I2CSPIDriver(config),
+ _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample"))
+{
+}
+
+MCP23009::~MCP23009()
+{
+ ScheduleClear();
+ perf_free(_cycle_perf);
+}
+
+int MCP23009::init_uorb()
+{
+ if (!_gpio_config_sub.registerCallback() ||
+ !_gpio_request_sub.registerCallback() ||
+ !_gpio_out_sub.registerCallback()) {
+ PX4_ERR("callback registration failed");
+ return -1;
+ }
+
+ return PX4_OK;
+}
+
+void MCP23009::exit_and_cleanup()
+{
+ _gpio_config_sub.unregisterCallback();
+ _gpio_request_sub.unregisterCallback();
+ _gpio_out_sub.unregisterCallback();
+}
+
+void MCP23009::RunImpl()
+{
+ perf_begin(_cycle_perf);
+
+ gpio_config_s config;
+
+ if (_gpio_config_sub.update(&config) && config.device_id == get_device_id()) {
+ PinType type = PinType::Input;
+
+ switch (config.config) {
+ case config.INPUT_PULLUP: type = PinType::InputPullUp; break;
+
+ case config.OUTPUT: type = PinType::Output; break;
+ }
+
+ write(config.state, config.mask);
+ configure(config.mask, type);
+ }
+
+ gpio_out_s output;
+
+ if (_gpio_out_sub.update(&output) && output.device_id == get_device_id()) {
+ write(output.state, output.mask);
+ }
+
+ // read every time we run, either when requested or when scheduled on interval
+ {
+ gpio_in_s _gpio_in;
+ _gpio_in.timestamp = hrt_absolute_time();
+ _gpio_in.device_id = get_device_id();
+ uint8_t input;
+ read(&input);
+ _gpio_in.state = input;
+ _to_gpio_in.publish(_gpio_in);
+ }
+
+ perf_end(_cycle_perf);
+}
+
+void MCP23009::print_usage()
+{
+ PRINT_MODULE_USAGE_NAME("MCP23009", "driver");
+ PRINT_MODULE_USAGE_COMMAND("start");
+ PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false);
+ PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x25);
+ PRINT_MODULE_USAGE_PARAM_INT('D', 0, 0, 255, "Direction", true);
+ PRINT_MODULE_USAGE_PARAM_INT('O', 0, 0, 255, "Output", true);
+ PRINT_MODULE_USAGE_PARAM_INT('P', 0, 0, 255, "Pullups", true);
+ PRINT_MODULE_USAGE_PARAM_INT('U', 0, 0, 1000, "Update Interval [ms]", true);
+ PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
+}
+
+void MCP23009::print_status()
+{
+ I2CSPIDriverBase::print_status();
+ perf_print_counter(_cycle_perf);
+}
+
+struct init_config_t {
+ uint16_t interval;
+ uint8_t direction;
+ uint8_t state;
+ uint8_t pullup;
+};
+
+I2CSPIDriverBase *MCP23009::instantiate(const I2CSPIDriverConfig &config, int runtime_instance)
+{
+ auto *init = (const init_config_t *)config.custom_data;
+ auto *instance = new MCP23009(config);
+
+ if (!instance) {
+ PX4_ERR("alloc failed");
+ return nullptr;
+ }
+
+ if (OK != instance->init(init->direction, init->state, init->pullup)) {
+ delete instance;
+ return nullptr;
+ }
+
+ if (init->interval) {
+ instance->ScheduleOnInterval(init->interval * 1000);
+ }
+
+ return instance;
+}
+
+extern "C" int mcp23009_main(int argc, char *argv[])
+{
+ using ThisDriver = MCP23009;
+ BusCLIArguments cli{true, false};
+ cli.default_i2c_frequency = 400000;
+ cli.i2c_address = 0x25;
+ init_config_t config_data{};
+
+ int ch;
+
+ while ((ch = cli.getOpt(argc, argv, "D:O:P:U:")) != EOF) {
+ switch (ch) {
+ case 'D':
+ config_data.direction = (int)strtol(cli.optArg(), nullptr, 0);
+ break;
+
+ case 'O':
+ config_data.state = (int)strtol(cli.optArg(), nullptr, 0);
+ break;
+
+ case 'P':
+ config_data.pullup = (int)strtol(cli.optArg(), nullptr, 0);
+ break;
+
+ case 'U':
+ config_data.interval = atoi(cli.optArg());
+ break;
+ }
+ }
+
+ cli.custom_data = &config_data;
+
+ const char *verb = cli.optArg();
+
+ if (!verb) {
+ ThisDriver::print_usage();
+ return -1;
+ }
+
+ BusInstanceIterator iterator(MODULE_NAME, cli, DRV_GPIO_DEVTYPE_MCP23009);
+
+ if (!strcmp(verb, "start")) {
+ return ThisDriver::module_start(cli, iterator);
+ }
+
+ if (!strcmp(verb, "stop")) {
+ return ThisDriver::module_stop(iterator);
+ }
+
+ if (!strcmp(verb, "status")) {
+ return ThisDriver::module_status(iterator);
+ }
+
+ ThisDriver::print_usage();
+ return -1;
+}
diff --git a/src/drivers/gps/devices b/src/drivers/gps/devices
index 99f5960eca..b443b79f57 160000
--- a/src/drivers/gps/devices
+++ b/src/drivers/gps/devices
@@ -1 +1 @@
-Subproject commit 99f5960eca66150e33dc277e71a4c99187c27ddc
+Subproject commit b443b79f57c5e89353430940af9e4511ea8eb0b8
diff --git a/src/drivers/gps/gps.cpp b/src/drivers/gps/gps.cpp
index 008f4d3977..4ed29a8c6e 100644
--- a/src/drivers/gps/gps.cpp
+++ b/src/drivers/gps/gps.cpp
@@ -60,6 +60,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -203,7 +204,7 @@ private:
const Instance _instance;
- uORB::Subscription _orb_inject_data_sub{ORB_ID(gps_inject_data)};
+ uORB::SubscriptionMultiArray _orb_inject_data_sub{ORB_ID::gps_inject_data};
uORB::Publication _gps_inject_data_pub{ORB_ID(gps_inject_data)};
uORB::Publication _dump_communication_pub{ORB_ID(gps_dump)};
gps_dump_s *_dump_to_device{nullptr};
@@ -530,13 +531,15 @@ void GPS::handleInjectDataTopic()
// If there has not been a valid RTCM message for a while, try to switch to a different RTCM link
if ((hrt_absolute_time() - _last_rtcm_injection_time) > 5_s) {
- for (uint8_t i = 0; i < gps_inject_data_s::MAX_INSTANCES; i++) {
- if (_orb_inject_data_sub.ChangeInstance(i)) {
- if (_orb_inject_data_sub.copy(&msg)) {
+ for (int instance = 0; instance < _orb_inject_data_sub.size(); instance++) {
+ const bool exists = _orb_inject_data_sub[instance].advertised();
+
+ if (exists) {
+ if (_orb_inject_data_sub[instance].copy(&msg)) {
if ((hrt_absolute_time() - msg.timestamp) < 5_s) {
// Remember that we already did a copy on this instance.
already_copied = true;
- _selected_rtcm_instance = i;
+ _selected_rtcm_instance = instance;
break;
}
}
@@ -544,9 +547,6 @@ void GPS::handleInjectDataTopic()
}
}
- // Reset instance in case we didn't actually want to switch
- _orb_inject_data_sub.ChangeInstance(_selected_rtcm_instance);
-
bool updated = already_copied;
// Limit maximum number of GPS injections to 8 since usually
@@ -574,7 +574,7 @@ void GPS::handleInjectDataTopic()
}
}
- updated = _orb_inject_data_sub.update(&msg);
+ updated = _orb_inject_data_sub[_selected_rtcm_instance].update(&msg);
} while (updated && num_injections < max_num_injections);
}
diff --git a/src/drivers/heater/heater.cpp b/src/drivers/heater/heater.cpp
index 170bd859a4..aba6f7066e 100644
--- a/src/drivers/heater/heater.cpp
+++ b/src/drivers/heater/heater.cpp
@@ -231,7 +231,7 @@ void Heater::Run()
_controller_time_on_usec = math::constrain(_controller_time_on_usec, 0, _controller_period_usec);
- if (abs(temperature_delta) < TEMPERATURE_TARGET_THRESHOLD) {
+ if (fabsf(temperature_delta) < TEMPERATURE_TARGET_THRESHOLD) {
_temperature_target_met = true;
} else {
diff --git a/src/drivers/imu/adis16497/ADIS16497.cpp b/src/drivers/imu/adis16497/ADIS16497.cpp
index 9b39f4a071..3d94c4c2c5 100644
--- a/src/drivers/imu/adis16497/ADIS16497.cpp
+++ b/src/drivers/imu/adis16497/ADIS16497.cpp
@@ -342,9 +342,9 @@ ADIS16497::read_reg16(uint8_t reg)
cmd[0] = ((reg | DIR_READ) << 8) & 0xff00;
transferhword(cmd, nullptr, 1);
- up_udelay(T_STALL);
+ px4_udelay(T_STALL);
transferhword(nullptr, cmd, 1);
- up_udelay(T_STALL);
+ px4_udelay(T_STALL);
return cmd[0];
}
@@ -367,9 +367,9 @@ ADIS16497::write_reg16(uint8_t reg, uint16_t value)
cmd[1] = (((reg + 0x1) | DIR_WRITE) << 8) | ((0xff00 & value) >> 8);
transferhword(cmd, nullptr, 1);
- up_udelay(T_STALL);
+ px4_udelay(T_STALL);
transferhword(cmd + 1, nullptr, 1);
- up_udelay(T_STALL);
+ px4_udelay(T_STALL);
}
void
diff --git a/src/drivers/imu/analog_devices/adis16507/ADIS16507.cpp b/src/drivers/imu/analog_devices/adis16507/ADIS16507.cpp
index 0aa216c940..c12e8d356d 100644
--- a/src/drivers/imu/analog_devices/adis16507/ADIS16507.cpp
+++ b/src/drivers/imu/analog_devices/adis16507/ADIS16507.cpp
@@ -283,6 +283,7 @@ void ADIS16507::RunImpl()
if (buffer.checksum != checksum) {
//PX4_DEBUG("adis_report.checksum: %X vs calculated: %X", buffer.checksum, checksum);
perf_count(_bad_transfer_perf);
+ perf_count(_perf_crc_bad);
}
if (buffer.DIAG_STAT != DIAG_STAT_BIT::Data_path_overrun) {
diff --git a/src/drivers/imu/bosch/bmi055/BMI055_Gyroscope.cpp b/src/drivers/imu/bosch/bmi055/BMI055_Gyroscope.cpp
index d2ea514530..cf8a2495ca 100644
--- a/src/drivers/imu/bosch/bmi055/BMI055_Gyroscope.cpp
+++ b/src/drivers/imu/bosch/bmi055/BMI055_Gyroscope.cpp
@@ -33,8 +33,6 @@
#include "BMI055_Gyroscope.hpp"
-#include
-
using namespace time_literals;
namespace Bosch::BMI055::Gyroscope
diff --git a/src/drivers/imu/bosch/bmi088/BMI088_Gyroscope.cpp b/src/drivers/imu/bosch/bmi088/BMI088_Gyroscope.cpp
index 5c8714712f..d945a815f9 100644
--- a/src/drivers/imu/bosch/bmi088/BMI088_Gyroscope.cpp
+++ b/src/drivers/imu/bosch/bmi088/BMI088_Gyroscope.cpp
@@ -33,8 +33,6 @@
#include "BMI088_Gyroscope.hpp"
-#include
-
using namespace time_literals;
namespace Bosch::BMI088::Gyroscope
diff --git a/src/modules/commander/Arming/ArmStateMachine/CMakeLists.txt b/src/drivers/imu/invensense/iim42653/CMakeLists.txt
similarity index 82%
rename from src/modules/commander/Arming/ArmStateMachine/CMakeLists.txt
rename to src/drivers/imu/invensense/iim42653/CMakeLists.txt
index e9f9c54232..4f0e7a7986 100644
--- a/src/modules/commander/Arming/ArmStateMachine/CMakeLists.txt
+++ b/src/drivers/imu/invensense/iim42653/CMakeLists.txt
@@ -30,15 +30,19 @@
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-
-
-px4_add_library(ArmStateMachine
- ArmStateMachine.cpp
-)
-target_include_directories(ArmStateMachine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(ArmStateMachine PUBLIC health_and_arming_checks)
-
-px4_add_functional_gtest(SRC ArmStateMachineTest.cpp
- LINKLIBS ArmStateMachine health_and_arming_checks hysteresis sensor_calibration ArmAuthorization mode_util
+px4_add_module(
+ MODULE drivers__imu__invensense__iim42653
+ MAIN iim42653
+ COMPILE_FLAGS
+ ${MAX_CUSTOM_OPT_LEVEL}
+ #-DDEBUG_BUILD
+ SRCS
+ iim42653_main.cpp
+ IIM42653.cpp
+ IIM42653.hpp
+ InvenSense_IIM42653_registers.hpp
+ DEPENDS
+ px4_work_queue
+ drivers_accelerometer
+ drivers_gyroscope
)
-
diff --git a/src/drivers/imu/invensense/iim42653/IIM42653.cpp b/src/drivers/imu/invensense/iim42653/IIM42653.cpp
new file mode 100644
index 0000000000..d5f1f57c0c
--- /dev/null
+++ b/src/drivers/imu/invensense/iim42653/IIM42653.cpp
@@ -0,0 +1,861 @@
+/****************************************************************************
+ *
+ * Copyright (c) 2023 PX4 Development Team. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include "IIM42653.hpp"
+
+using namespace time_literals;
+
+static constexpr int16_t combine(uint8_t msb, uint8_t lsb)
+{
+ return (msb << 8u) | lsb;
+}
+
+static constexpr uint16_t combine_uint(uint8_t msb, uint8_t lsb)
+{
+ return (msb << 8u) | lsb;
+}
+
+IIM42653::IIM42653(const I2CSPIDriverConfig &config) :
+ SPI(config),
+ I2CSPIDriver(config),
+ _drdy_gpio(config.drdy_gpio),
+ _px4_accel(get_device_id(), config.rotation),
+ _px4_gyro(get_device_id(), config.rotation)
+{
+ if (config.drdy_gpio != 0) {
+ _drdy_missed_perf = perf_alloc(PC_COUNT, MODULE_NAME": DRDY missed");
+ }
+
+ if (config.custom1 != 0) {
+ _enable_clock_input = true;
+ _input_clock_freq = config.custom1;
+ ConfigureCLKIN();
+
+ } else {
+ _enable_clock_input = false;
+ }
+
+ ConfigureSampleRate(_px4_gyro.get_max_rate_hz());
+}
+
+IIM42653::~IIM42653()
+{
+ perf_free(_bad_register_perf);
+ perf_free(_bad_transfer_perf);
+ perf_free(_fifo_empty_perf);
+ perf_free(_fifo_overflow_perf);
+ perf_free(_fifo_reset_perf);
+ perf_free(_drdy_missed_perf);
+}
+
+int IIM42653::init()
+{
+ int ret = SPI::init();
+
+ if (ret != PX4_OK) {
+ DEVICE_DEBUG("SPI::init failed (%i)", ret);
+ return ret;
+ }
+
+ return Reset() ? 0 : -1;
+}
+
+bool IIM42653::Reset()
+{
+ _state = STATE::RESET;
+ DataReadyInterruptDisable();
+ ScheduleClear();
+ ScheduleNow();
+ return true;
+}
+
+void IIM42653::exit_and_cleanup()
+{
+ DataReadyInterruptDisable();
+ I2CSPIDriverBase::exit_and_cleanup();
+}
+
+void IIM42653::print_status()
+{
+ I2CSPIDriverBase::print_status();
+
+ PX4_INFO("FIFO empty interval: %d us (%.1f Hz)", _fifo_empty_interval_us, 1e6 / _fifo_empty_interval_us);
+ PX4_INFO("Clock input: %s", _enable_clock_input ? "enabled" : "disabled");
+
+ perf_print_counter(_bad_register_perf);
+ perf_print_counter(_bad_transfer_perf);
+ perf_print_counter(_fifo_empty_perf);
+ perf_print_counter(_fifo_overflow_perf);
+ perf_print_counter(_fifo_reset_perf);
+ perf_print_counter(_drdy_missed_perf);
+}
+
+int IIM42653::probe()
+{
+ for (int i = 0; i < 3; i++) {
+ uint8_t whoami = RegisterRead(Register::BANK_0::WHO_AM_I);
+
+ if (whoami == WHOAMI) {
+ return PX4_OK;
+
+ } else {
+ DEVICE_DEBUG("unexpected WHO_AM_I 0x%02x", whoami);
+
+ uint8_t reg_bank_sel = RegisterRead(Register::BANK_0::REG_BANK_SEL);
+ int bank = reg_bank_sel >> 4;
+
+ if (bank >= 1 && bank <= 3) {
+ DEVICE_DEBUG("incorrect register bank for WHO_AM_I REG_BANK_SEL:0x%02x, bank:%d", reg_bank_sel, bank);
+ // force bank selection and retry
+ SelectRegisterBank(REG_BANK_SEL_BIT::BANK_SEL_0, true);
+ }
+ }
+ }
+
+ return PX4_ERROR;
+}
+
+void IIM42653::RunImpl()
+{
+ const hrt_abstime now = hrt_absolute_time();
+
+ switch (_state) {
+ case STATE::RESET:
+ // DEVICE_CONFIG: Software reset configuration
+ RegisterWrite(Register::BANK_0::DEVICE_CONFIG, DEVICE_CONFIG_BIT::SOFT_RESET_CONFIG);
+ _reset_timestamp = now;
+ _failure_count = 0;
+ _state = STATE::WAIT_FOR_RESET;
+ ScheduleDelayed(1_ms); // wait 1 ms for soft reset to be effective
+ break;
+
+ case STATE::WAIT_FOR_RESET:
+ if ((RegisterRead(Register::BANK_0::WHO_AM_I) == WHOAMI)
+ && (RegisterRead(Register::BANK_0::DEVICE_CONFIG) == 0x00)
+ && (RegisterRead(Register::BANK_0::INT_STATUS) & INT_STATUS_BIT::RESET_DONE_INT)) {
+
+ // Wakeup accel and gyro and schedule remaining configuration
+ RegisterWrite(Register::BANK_0::PWR_MGMT0, PWR_MGMT0_BIT::GYRO_MODE_LOW_NOISE | PWR_MGMT0_BIT::ACCEL_MODE_LOW_NOISE);
+ _state = STATE::CONFIGURE;
+ ScheduleDelayed(30_ms); // 30 ms gyro startup time, 10 ms accel from sleep to valid data
+
+ } else {
+ // RESET not complete
+ if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) {
+ PX4_DEBUG("Reset failed, retrying");
+ _state = STATE::RESET;
+ ScheduleDelayed(100_ms);
+
+ } else {
+ PX4_DEBUG("Reset not complete, check again in 10 ms");
+ ScheduleDelayed(10_ms);
+ }
+ }
+
+ break;
+
+ case STATE::CONFIGURE:
+ if (Configure()) {
+ // if configure succeeded then reset the FIFO
+ _state = STATE::FIFO_RESET;
+ ScheduleDelayed(1_ms);
+
+ } else {
+ // CONFIGURE not complete
+ if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) {
+ PX4_DEBUG("Configure failed, resetting");
+ _state = STATE::RESET;
+
+ } else {
+ PX4_DEBUG("Configure failed, retrying");
+ }
+
+ ScheduleDelayed(100_ms);
+ }
+
+ break;
+
+ case STATE::FIFO_RESET:
+
+ _state = STATE::FIFO_READ;
+ FIFOReset();
+
+ if (DataReadyInterruptConfigure()) {
+ _data_ready_interrupt_enabled = true;
+
+ // backup schedule as a watchdog timeout
+ ScheduleDelayed(100_ms);
+
+ } else {
+ _data_ready_interrupt_enabled = false;
+ ScheduleOnInterval(_fifo_empty_interval_us, _fifo_empty_interval_us);
+ }
+
+ break;
+
+ case STATE::FIFO_READ: {
+ hrt_abstime timestamp_sample = now;
+ uint8_t samples = 0;
+
+ if (_data_ready_interrupt_enabled) {
+ // scheduled from interrupt if _drdy_timestamp_sample was set as expected
+ const hrt_abstime drdy_timestamp_sample = _drdy_timestamp_sample.fetch_and(0);
+
+ if ((now - drdy_timestamp_sample) < _fifo_empty_interval_us) {
+ timestamp_sample = drdy_timestamp_sample;
+ samples = _fifo_gyro_samples;
+
+ } else {
+ perf_count(_drdy_missed_perf);
+ }
+
+ // push backup schedule back
+ ScheduleDelayed(_fifo_empty_interval_us * 2);
+ }
+
+ if (samples == 0) {
+ // check current FIFO count
+ const uint16_t fifo_count = FIFOReadCount();
+
+ if (fifo_count >= FIFO::SIZE) {
+ FIFOReset();
+ perf_count(_fifo_overflow_perf);
+
+ } else if (fifo_count == 0) {
+ perf_count(_fifo_empty_perf);
+
+ } else {
+ // FIFO count (size in bytes)
+ samples = (fifo_count / sizeof(FIFO::DATA));
+
+ // tolerate minor jitter, leave sample to next iteration if behind by only 1
+ if (samples == _fifo_gyro_samples + 1) {
+ timestamp_sample -= static_cast(FIFO_SAMPLE_DT);
+ samples--;
+ }
+
+ if (samples > FIFO_MAX_SAMPLES) {
+ // not technically an overflow, but more samples than we expected or can publish
+ FIFOReset();
+ perf_count(_fifo_overflow_perf);
+ samples = 0;
+ }
+ }
+ }
+
+ bool success = false;
+
+ if (samples >= 1) {
+ if (FIFORead(timestamp_sample, samples)) {
+ success = true;
+
+ if (_failure_count > 0) {
+ _failure_count--;
+ }
+ }
+ }
+
+ if (!success) {
+ _failure_count++;
+
+ // full reset if things are failing consistently
+ if (_failure_count > 10) {
+ Reset();
+ return;
+ }
+ }
+
+ if (!success || hrt_elapsed_time(&_last_config_check_timestamp) > 100_ms) {
+ // check configuration registers periodically or immediately following any failure
+ if (RegisterCheck(_register_bank0_cfg[_checked_register_bank0])
+ && RegisterCheck(_register_bank1_cfg[_checked_register_bank1])
+ && RegisterCheck(_register_bank2_cfg[_checked_register_bank2])
+ ) {
+ _last_config_check_timestamp = now;
+ _checked_register_bank0 = (_checked_register_bank0 + 1) % size_register_bank0_cfg;
+ _checked_register_bank1 = (_checked_register_bank1 + 1) % size_register_bank1_cfg;
+ _checked_register_bank2 = (_checked_register_bank2 + 1) % size_register_bank2_cfg;
+
+ } else {
+ // register check failed, force reset
+ perf_count(_bad_register_perf);
+ Reset();
+ }
+ }
+ }
+
+ break;
+ }
+}
+
+void IIM42653::ConfigureSampleRate(int sample_rate)
+{
+ // round down to nearest FIFO sample dt
+ const float min_interval = FIFO_SAMPLE_DT;
+ _fifo_empty_interval_us = math::max(roundf((1e6f / (float)sample_rate) / min_interval) * min_interval, min_interval);
+
+ _fifo_gyro_samples = roundf(math::min((float)_fifo_empty_interval_us / (1e6f / GYRO_RATE), (float)FIFO_MAX_SAMPLES));
+
+ // recompute FIFO empty interval (us) with actual gyro sample limit
+ _fifo_empty_interval_us = _fifo_gyro_samples * (1e6f / GYRO_RATE);
+
+ ConfigureFIFOWatermark(_fifo_gyro_samples);
+}
+
+void IIM42653::ConfigureFIFOWatermark(uint8_t samples)
+{
+ // FIFO watermark threshold in number of bytes
+ const uint16_t fifo_watermark_threshold = samples * sizeof(FIFO::DATA);
+
+ for (auto &r : _register_bank0_cfg) {
+ if (r.reg == Register::BANK_0::FIFO_CONFIG2) {
+ // FIFO_WM[7:0] FIFO_CONFIG2
+ r.set_bits = fifo_watermark_threshold & 0xFF;
+
+ } else if (r.reg == Register::BANK_0::FIFO_CONFIG3) {
+ // FIFO_WM[11:8] FIFO_CONFIG3
+ r.set_bits = (fifo_watermark_threshold >> 8) & 0x0F;
+ }
+ }
+}
+
+void IIM42653::ConfigureCLKIN()
+{
+ for (auto &r0 : _register_bank0_cfg) {
+ if (r0.reg == Register::BANK_0::INTF_CONFIG1) {
+ r0.set_bits = INTF_CONFIG1_BIT::RTC_MODE;
+ r0.set_bits = INTF_CONFIG1_BIT::CLKSEL;
+ r0.clear_bits = INTF_CONFIG1_BIT::CLKSEL_CLEAR;
+ }
+ }
+
+ for (auto &r1 : _register_bank1_cfg) {
+ if (r1.reg == Register::BANK_1::INTF_CONFIG5) {
+ r1.set_bits = INTF_CONFIG5_BIT::PIN9_FUNCTION_CLKIN_SET;
+ r1.clear_bits = INTF_CONFIG5_BIT::PIN9_FUNCTION_CLKIN_CLEAR;
+ }
+ }
+}
+
+void IIM42653::SelectRegisterBank(enum REG_BANK_SEL_BIT bank, bool force)
+{
+ if (bank != _last_register_bank || force) {
+ // select BANK_0
+ uint8_t cmd_bank_sel[2] {};
+ cmd_bank_sel[0] = static_cast(Register::BANK_0::REG_BANK_SEL);
+ cmd_bank_sel[1] = bank;
+ transfer(cmd_bank_sel, cmd_bank_sel, sizeof(cmd_bank_sel));
+
+ _last_register_bank = bank;
+ }
+}
+
+bool IIM42653::Configure()
+{
+ // first set and clear all configured register bits
+ for (const auto ®_cfg : _register_bank0_cfg) {
+ RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits);
+ }
+
+ for (const auto ®_cfg : _register_bank1_cfg) {
+ RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits);
+ }
+
+ for (const auto ®_cfg : _register_bank2_cfg) {
+ RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits);
+ }
+
+ // now check that all are configured
+ bool success = true;
+
+ for (const auto ®_cfg : _register_bank0_cfg) {
+ if (!RegisterCheck(reg_cfg)) {
+ success = false;
+ }
+ }
+
+ for (const auto ®_cfg : _register_bank1_cfg) {
+ if (!RegisterCheck(reg_cfg)) {
+ success = false;
+ }
+ }
+
+ for (const auto ®_cfg : _register_bank2_cfg) {
+ if (!RegisterCheck(reg_cfg)) {
+ success = false;
+ }
+ }
+
+ // 20-bits data format used
+ // the only FSR settings that are operational are ±2000dps for gyroscope and ±16g for accelerometer
+ _px4_accel.set_range(16.f * CONSTANTS_ONE_G);
+ _px4_gyro.set_range(math::radians(2000.f));
+
+ return success;
+}
+
+int IIM42653::DataReadyInterruptCallback(int irq, void *context, void *arg)
+{
+ static_cast(arg)->DataReady();
+ return 0;
+}
+
+void IIM42653::DataReady()
+{
+ _drdy_timestamp_sample.store(hrt_absolute_time());
+ ScheduleNow();
+}
+
+bool IIM42653::DataReadyInterruptConfigure()
+{
+ if (_drdy_gpio == 0) {
+ return false;
+ }
+
+ // Setup data ready on falling edge
+ return px4_arch_gpiosetevent(_drdy_gpio, false, true, true, &DataReadyInterruptCallback, this) == 0;
+}
+
+bool IIM42653::DataReadyInterruptDisable()
+{
+ if (_drdy_gpio == 0) {
+ return false;
+ }
+
+ return px4_arch_gpiosetevent(_drdy_gpio, false, false, false, nullptr, nullptr) == 0;
+}
+
+template
+bool IIM42653::RegisterCheck(const T ®_cfg)
+{
+ bool success = true;
+
+ const uint8_t reg_value = RegisterRead(reg_cfg.reg);
+
+ if (reg_cfg.set_bits && ((reg_value & reg_cfg.set_bits) != reg_cfg.set_bits)) {
+ PX4_DEBUG("0x%02hhX: 0x%02hhX (0x%02hhX not set)", (uint8_t)reg_cfg.reg, reg_value, reg_cfg.set_bits);
+ success = false;
+ }
+
+ if (reg_cfg.clear_bits && ((reg_value & reg_cfg.clear_bits) != 0)) {
+ PX4_DEBUG("0x%02hhX: 0x%02hhX (0x%02hhX not cleared)", (uint8_t)reg_cfg.reg, reg_value, reg_cfg.clear_bits);
+ success = false;
+ }
+
+ return success;
+}
+
+template
+uint8_t IIM42653::RegisterRead(T reg)
+{
+ uint8_t cmd[2] {};
+ cmd[0] = static_cast(reg) | DIR_READ;
+ SelectRegisterBank(reg);
+ transfer(cmd, cmd, sizeof(cmd));
+ return cmd[1];
+}
+
+template
+void IIM42653::RegisterWrite(T reg, uint8_t value)
+{
+ uint8_t cmd[2] { (uint8_t)reg, value };
+ SelectRegisterBank(reg);
+ transfer(cmd, cmd, sizeof(cmd));
+}
+
+template