Compare commits

...
59 Commits
Author SHA1 Message Date
skrueckenandCursor f006f8b912 Add software LiPo UV protection with energy-save boot.
Detect under-voltage on GPIO1/11, persist UV state in NVS, enter a minimal
power mode without ESP-NOW, and recover after charge; expose LED mode 6
battery-low for host testing via goTool.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 18:22:52 +02:00
skruecken be18b758ed Added LIPO 2 Reading 2026-06-23 17:54:18 +02:00
skrueckenandCursor 490e0ee61f Add UART SET_LOG_LEVEL for runtime master ESP-IDF logging.
Expose the command via goTool CLI/REST and dashboard controls so log verbosity can be tuned without reflashing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 18:03:34 +02:00
skruecken ac223ada72 Added ECHO cmd and fixed some timing issues 2026-06-06 17:44:40 +02:00
skruecken 35ce1476d8 Missed for Previous Commit 2026-06-06 17:17:42 +02:00
skruecken f89ea3cbe3 Stabelized OTA Update with Retries 2026-06-06 17:15:55 +02:00
skruecken 99956e3362 Update InputClientSample struct to make TapKind optional and improve WebSocket API documentation. Adjust README to reflect changes in input push stream format and clarify connection flow. Enhance API_WEBSOCKET.md with detailed command and push message descriptions. 2026-06-06 12:26:31 +02:00
skrueckenandCursor ab1844ac32 Fix UART hang after master restart from the dashboard.
ReadFrame now returns on serial timeout instead of looping forever, and
serve closes and reopens the port after a master reboot so polling and
API commands can resume.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 16:45:57 +02:00
skrueckenandCursor e4ce18edd8 Close UART gracefully on SIGINT/SIGTERM in goTool.
Go exits on Ctrl+C without running defers, leaving the serial port locked; register shutdown hooks for serve and CLI commands.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 16:40:22 +02:00
skrueckenandCursor 0eea27a876 Fix web OTA upload and isolate OTA sessions across firmware and goTool.
Split ESP-NOW into core/master/slave modules, block non-OTA UART traffic during updates, and hold the host serial port exclusively so dashboard polling cannot interleave with firmware uploads.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 16:35:18 +02:00
skrueckenandCursor 0cbc4d0644 Add ESP firmware architecture and reference documentation.
Document UART command flow, ESP-NOW data paths, and module map for
developers without covering goTool; link from main/README.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 15:55:32 +02:00
skrueckenandCursor 35b39fce46 Add configurable BMA456 tap detection profile in bosch456.h.
Centralize multitap tuning so sensitivity and timing can be adjusted without changing driver init logic.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 14:03:46 +02:00
skrueckenandCursor 41a66d4417 Unify external WebSocket push into a single input stream.
Replace separate accel/tap commands and messages with set_input_stream and input pushes that combine accel and tap per client, including pre_fetch timing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 13:47:39 +02:00
skrueckenandCursor 498b89d7ba Clear tap status in dashboard after 2s display window.
formatLastTap no longer falls back to server last_tap once the
ephemeral tapDisplay timer expires.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 21:25:03 +02:00
skrueckenandCursor 31e539052a Unify cache polling on CACHE_STATUS and split API docs.
Replace separate accel/tap snapshot UART commands with one clients[] response
that omits unsubscribed fields; remove snapshot handlers and CLI commands.
Add goTool/docs for WebSocket streams and REST; tap-snapshot REST uses CACHE_STATUS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 21:23:09 +02:00
skrueckenandCursor a85d48320e Add list_clients WebSocket command to external API.
Lets API clients discover slave IDs and stream/notify flags before configuring per-slave accel or tap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 21:02:41 +02:00
skrueckenandCursor f512936d97 Add CACHE_STATUS UART poll and dashboard live stream.
Combine cached accel and tap in one low-overhead master command for ~16 ms
host polling. The dashboard uses a single live-stream toggle plus per-slave
accel-stream controls; fix live_stream state so polling is not cleared every
slow client refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 20:57:54 +02:00
skrueckenandCursor a8d4d42920 Add BMA456 tap detection with ESP-NOW notify and host snapshot API.
Slaves forward configured tap kinds to the master; goTool exposes CLI, dashboard, REST, and WebSocket with separate notify vs receive and 2s display cache.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 20:42:57 +02:00
skrueckenandCursor 3cb0b5bbe9 Add LiPo battery monitoring with ESP-NOW cache and dashboard API.
Slaves report pack voltages every 30s; the master caches them for fast
BATTERY_STATUS reads. goTool exposes REST/WebSocket and shows values in
the dashboard, with a nanopb fix so optional lipo submessages encode.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 20:14:28 +02:00
skrueckenandCursor eb67a46158 Add LED ring control per client and broadcast over REST and WebSocket.
Solid color mode fills all ring LEDs; master routes UART commands to slaves
via ESPNOW_LED_RING. goTool exposes POST /api/led-ring, WebSocket set_led_ring,
and a dashboard LED panel with master/slave/all targets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 19:24:55 +02:00
skrueckenandCursor 47c75110c9 Stream slave accel via ESP-NOW with master snapshot cache.
Slaves push BMA456 samples at 16ms when enabled; the master caches per
client and exposes ACCEL_SNAPSHOT and ACCEL_STREAM over UART. goTool adds
dashboard stream controls, HTTP accel-stream routes, and an external
WebSocket API with per-connection receive/interval and slave stream commands.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 19:11:36 +02:00
skrueckenandCursor ba20544762 Add UART ACCEL_READ command for on-demand BMA456 samples.
Expose MessageType 24 with protobuf response (success, x, y, z in raw LSB),
firmware handler with mutex-safe I2C read, goTool `accel` CLI, and docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 19:55:02 +02:00
skrueckenandCursor 16c521f71c Move UART command handlers into main/cmd/ for clearer layout.
Add cmd/ to CMake include paths and update documentation paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 22:49:11 +02:00
skrueckenandCursor 95d5a9747a Extend autotest to cover all UART commands except OTA upload.
Add led_ring, find_me, restart, and ota_progress steps plus uart_cmds scenario.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 22:41:23 +02:00
skrueckenandCursor a9e08107b4 Add RESTART command for master and slaves via ESP-NOW.
UART RESTART (client_id 0 = local reboot, >0 = unicast); dashboard and CLI hooks; delayed esp_restart after response.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 22:33:22 +02:00
skrueckenandCursor 5c3cf65bca Persist accelerometer deadzone in NVS across reboots.
Each node saves its local deadzone on UART or ESP-NOW set; pod_settings loads and applies it after BMA456 init.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 22:29:00 +02:00
skrueckenandCursor 2e88358c53 Add feature development guide and fix ESP-NOW proto generation.
Document UART-to-ESP-NOW flow using Find me; align proto_generate_espnow with uart (python3, -I .).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 22:09:24 +02:00
skrueckenandCursor efd6260201 Add find-me LED locate on master and slaves via ESP-NOW.
UART FIND_ME (client_id 0 = local ring, >0 = unicast), ESPNOW_FIND_ME payload, CLI/dashboard buttons per slave.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 22:04:07 +02:00
skrueckenandCursor 8931912583 Dim LED ring, add blink mode, and signal OTA outcome on the ring.
Default brightness is ~5%; UART blink mode and green/red pulses mark OTA success or failure. Failed UART uploads skip ESP-NOW distribution.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 21:53:10 +02:00
skrueckenandCursor 508b684fdf Add UART LED_RING command for progress bar, digits, and clear.
Stop the main-loop digit demo so host-driven display persists; expose
clear/progress/digit modes with RGB and intensity via protobuf and goTool.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 21:18:18 +02:00
skrueckenandCursor a0f4a81a55 Add per-slave ESP-NOW OTA progress over UART and fix dashboard updates.
Expose OTA_SLAVE_PROGRESS on the master, track per-slave state during
distribution, run ESP-NOW OTA in a background task so the host can poll
while slaves update, and show master/slave progress in the dashboard
with table layout and faster WebSocket refresh during uploads.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 21:07:46 +02:00
skrueckenandCursor 5a948a5c8c Document ESP-NOW slave OTA and dashboard upload flow.
Describe master-to-slave distribution after UART OTA, partial final block, reboot, and goTool /api/ota behaviour.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 01:02:45 +02:00
skrueckenandCursor 9b7bda8551 Distribute master OTA images to slaves over ESP-NOW.
After UART OTA the master reads the staged partition in 4 KiB blocks (200 B ESP-NOW chunks), waits for per-slave block ACKs, and fixes the final partial block. Slaves reuse ota_uart; send pacing and logging improve reliability.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 01:00:56 +02:00
skrueckenandCursor 4bf43d8a5e Add web dashboard OTA upload with live progress.
Share UART OTA logic between CLI and serve via POST /api/ota, WebSocket progress events, and a dashboard upload UI showing the running partition.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:45:54 +02:00
skrueckenandCursor 59ca269407 Add UART OTA upload with A/B partition support.
Firmware buffers 200-byte chunks into 4 KiB blocks for esp_ota_write; goTool
uploads with per-block ACK flow control and larger UART buffers to avoid stalls.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:39:59 +02:00
skrueckenandCursor 1ad527119d Add board input driver for button and LiPo ADC logging.
TODO: Hardware pinning in powerpod.h (TASTER_GPIO, V_LIPO_1/2_GPIO) does not
match final hardware yet — verify against schematic before production.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:16:40 +02:00
skrueckenandCursor 80fb9cf55e Improve dashboard master config and separate slave deadzone updates.
Always show master deadzone input with read/set controls; apply bulk slave
changes via slaves_only without changing the master's BMA456.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:15:35 +02:00
skrueckenandCursor 85aeab85c0 Add web dashboard configuration for master and slaves.
Expose deadzone and unicast-test via HTTP API and UI, reusing the same UART commands as the CLI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:10:33 +02:00
skrueckenandCursor caf1b8d0d8 Add Makefile target for goTool web dashboard.
gotool-serve runs serve with configurable SERVE_ADDR (default :8080).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:05:46 +02:00
skrueckenandCursor c4696657a7 Add goTool web dashboard with UART auto-reconnect.
Serve polls the master over UART and pushes live state via WebSocket;
reopens the serial port when the device is unplugged and comes back.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:04:57 +02:00
skrueckenandCursor 0299ba44fd Add bench UART ports and cold-start reset to goTool autotest.
Bench configs define command and console serial paths; scenarios can
reset nodes via esptool before tests. Smoke resets all nodes then waits
for ESP-NOW join.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 23:44:58 +02:00
skrueckenandCursor d24b0cb5c3 Add goTool autotest with bench configs and UART scenarios.
JSON configs describe network and node MACs; scenarios run command
sequences with expect checks. Share UART client API across CLI and tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 23:36:28 +02:00
skrueckenandCursor a8ae65d9dc Align BMA456H driver with Powerpod and document sensor integration.
Clarify hearable variant usage, clean up I2C/GPIO/tap init, and add README
coverage for hardware, boot behavior, deadzone paths, and logging.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 23:27:20 +02:00
skrueckenandCursor e95097085d Add uart_cmd helpers to deduplicate UART command handlers.
Centralize protobuf decode, response init/send, registration, and common
nanopb encode callbacks; refactor existing cmd_* modules to use them.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 23:21:48 +02:00
skrueckenandCursor 20fea02b78 Add Makefile shortcuts for goTool and ignore built binary.
Expose common gotool targets (build, clients, version, unicast-test,
deadzone) with configurable PORT, and add goTool/.gitignore for gotool.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 23:16:29 +02:00
skrueckenandCursor 241e82b35b Fix ESP-NOW unicast by using sender MAC in client registry.
Register slaves from recv src_addr instead of protobuf mac bytes, add
ESPNOW_UNICAST_TEST for path verification, restore unicast deadzone, and
expose unicast-test in goTool.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 23:15:03 +02:00
skrueckenandCursor ee38ce551a Add accelerometer deadzone via UART and ESP-NOW.
Filter BMA456 logs by configurable LSB threshold; master can set deadzone
for local sensor or slaves using ACCEL_DEADZONE (UART) and ESP-NOW broadcast
until unicast delivery is restored.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 23:06:25 +02:00
skrueckenandCursor e5db0b21c7 Add optional BMA456 accelerometer init on shared I2C bus.
Probe and configure the sensor when present; log and continue boot if
init fails so boards without BMA456 still run normally.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:51:32 +02:00
skrueckenandCursor 755bdd92d7 Refactor ESP-NOW air protocol to nanopb protobuf.
Add esp_now_messages.proto with EspNowMessage types, encode/decode helpers,
and Makefile targets to regenerate firmware and UART schemas together.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:44:57 +02:00
skrueckenandCursor 6cdca4f3ad Add ESP-NOW heartbeat, client timeout, and slave reconnect.
Slaves send HEARTBEAT every 1s; the master marks clients inactive after
3s without traffic and reactivates on reconnect. CLIENT_INFO reports
last_ping as milliseconds since the last packet, not uptime.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:39:10 +02:00
skrueckenandCursor 16bfbd1091 Add goTool clients subcommand for CLIENT_INFO query.
Refactor into version/clients subcommands with shared serial framing
to list registered slaves from the master over UART.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:26:42 +02:00
skrueckenandCursor 92e146e2ed Add client registry and CLIENT_INFO UART command on master.
Track ESP-NOW slaves in a shared registry and respond to CLIENT_INFO
with protobuf ClientInfoResponse; ESP-NOW path upserts registry entries.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:26:42 +02:00
skrueckenandCursor 81e479ecd1 Ignore repeat master discover after slave has joined network.
Slave responds and logs only on first discover from a given master MAC;
subsequent broadcasts on the same network are silently ignored.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:21:08 +02:00
skrueckenandCursor b592401e78 Document firmware architecture, ESP-NOW, UART, and goTool in README.
Expand main/README with master/slave overview, boot config, protocols,
and build notes; point goTool README at the full system doc.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:17:53 +02:00
skrueckenandCursor 54f2a7de5b Add ESP-NOW master/slave discovery on DIP network channel.
Initialize WiFi and ESP-NOW from shared app config; master broadcasts
discover packets and collects slave info, slaves respond on matching
network while UART commands stay master-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:16:19 +02:00
skrueckenandCursor bde4c473ef Add Go UART tool to query firmware VERSION over serial.
Framed protobuf client for /dev/ttyUSB0 at 921600 baud with generated
uart_messages types matching the device protocol.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:06:58 +02:00
skrueckenandCursor a1629fb3db Fix UART1 GPIO mapping and simplify command logging.
Use TX=GPIO3 and RX=GPIO2 at 921600 to match the terminal adapter wiring;
log received message id and which handler command is triggered.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:06:49 +02:00
skrueckenandCursor 43a85ce697 Add command queue dispatcher and VERSION UART handler.
Centralize command dispatch over a FreeRTOS queue so UART and future
ESP-NOW transports can register handlers; implement the protobuf VERSION
command with framed nanopb responses including build git hash.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 21:46:51 +02:00
skruecken 6b7ccb4256 Added nanopb as submodule 2026-05-10 17:08:11 +02:00
312 changed files with 71425 additions and 73 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "libs/nanopb"]
path = libs/nanopb
url = https://github.com/nanopb/nanopb.git
+75
View File
@@ -0,0 +1,75 @@
# Serial port for goTool (override: make gotool-clients PORT=/dev/ttyACM0)
PORT ?= /dev/ttyUSB0
GOTOOL_DIR := goTool
GOTOOL := $(GOTOOL_DIR)/gotool
GOTOOL_RUN := cd $(GOTOOL_DIR) && go run . -port $(PORT)
.PHONY: default proto_generate proto_generate_uart proto_generate_espnow \
gotool-build gotool-proto gotool-tidy gotool-test-units \
gotool-version gotool-clients gotool-unicast-test gotool-deadzone-get gotool-deadzone-set \
gotool-test gotool-serve
TEST_CONFIG ?= example-lab
SERVE_ADDR ?= :8080
TEST_SCENARIO ?= smoke
default:
@echo "Targets: proto_generate gotool-build gotool-clients gotool-version …"
@echo "Set PORT=$(PORT) (current) for goTool targets."
proto_generate_espnow:
cd main/proto && python3 ../../libs/nanopb/generator/nanopb_generator.py \
-I . -I ../../libs/nanopb/generator/proto esp_now_messages.proto
proto_generate: proto_generate_uart proto_generate_espnow
gotool-proto:
cd $(GOTOOL_DIR) && protoc --go_out=./pb --go_opt=paths=source_relative \
--go_opt=Muart_messages.proto=powerpod/gotool/pb \
--go_opt=Mnanopb.proto=powerpod/gotool/pb/nanopb \
-I ../main/proto \
-I ../libs/nanopb/generator/proto \
../main/proto/uart_messages.proto
@sed -i '/powerpod\/gotool\/pb\/nanopb/d' $(GOTOOL_DIR)/pb/uart_messages.pb.go
proto_generate_uart:
cd main/proto && python3 ../../libs/nanopb/generator/nanopb_generator.py \
-I . -I ../../libs/nanopb/generator/proto uart_messages.proto
gotool-tidy:
cd $(GOTOOL_DIR) && go mod tidy
gotool-build: gotool-tidy
cd $(GOTOOL_DIR) && go build -o gotool .
gotool-version: $(GOTOOL)
$(GOTOOL) -port $(PORT) version
gotool-clients: $(GOTOOL)
$(GOTOOL) -port $(PORT) clients
# CLIENT=<slave id> SEQ=42 (optional)
gotool-unicast-test: $(GOTOOL)
@test -n "$(CLIENT)" || (echo "Usage: make gotool-unicast-test CLIENT=16 [SEQ=42]"; exit 1)
$(GOTOOL) -port $(PORT) unicast-test -client $(CLIENT) -seq $(or $(SEQ),1)
gotool-deadzone-get: $(GOTOOL)
$(GOTOOL) -port $(PORT) deadzone -client $(or $(CLIENT),0)
# DEADZONE=100 CLIENT=0 (local) or slave id
gotool-deadzone-set: $(GOTOOL)
@test -n "$(DEADZONE)" || (echo "Usage: make gotool-deadzone-set DEADZONE=100 [CLIENT=16]"; exit 1)
$(GOTOOL) -port $(PORT) deadzone -set -value $(DEADZONE) -client $(or $(CLIENT),0)
gotool-test-units:
cd $(GOTOOL_DIR) && go test ./...
# CONFIG=example-lab SCENARIO=smoke
gotool-test: $(GOTOOL)
$(GOTOOL) -port $(PORT) test -config $(TEST_CONFIG) -scenario $(TEST_SCENARIO)
gotool-serve: $(GOTOOL)
$(GOTOOL) -port $(PORT) serve -addr $(SERVE_ADDR)
$(GOTOOL): gotool-build
+7
View File
@@ -0,0 +1,7 @@
idf_component_register(
SRCS
"bma456h.c"
"bma4.c"
INCLUDE_DIRS "."
REQUIRES driver
)
+30
View File
@@ -0,0 +1,30 @@
Copyright (c) 2024 Bosch Sensortec GmbH. All rights reserved.
BSD-3-Clause
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.
+58
View File
@@ -0,0 +1,58 @@
# BMA456 Sensor API
> This package contains SensorAPIs for BMA456 Sensor
## Sensor Overview
The BMA456 is an ultra-small, triaxial, low-g acceleration sensor with digital interfaces, aiming for low-power consumer electronics applications. Featuring 16 bit digital resolution and embedded intelligence, the device is optimized to fulfill low power accelerometer requirements.
## Applications
### BMA456W
- Any motion
- No motion
- Step detector
- Step counter
- Step activity
- Tap
- Single tap
- Double tap
### BMA456H
- Any motion
- No motion
- Step detector
- Step counter
- Step activity
- Auto low power
- Tap
- Single tap
- Double tap
- Triple tap
### BMA456MM
- Any motion
- No motion
- Orientation
- High-g
- Low-g
- Significant motion
- Auto low power
- Tap
- Single tap
- Double tap
- Triple tap
### BMA456AN
- Any motion
- No motion
### BMA456 tablet
- Any/no motion
- Low-g
- Single, double and triple tap
- Orientation
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+619
View File
@@ -0,0 +1,619 @@
/**
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* BSD-3-Clause
*
* 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.
*
* @file bma456_an.c
* @date 2023-07-05
* @version V2.29.0
*
*/
/*! \file bma456_an.c
* \brief Sensor Driver for BMA456_AN sensor
*/
#include "bma456_an.h"
/**\name Feature configuration file */
const uint8_t bma456_an_config_file[] = {
0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00,
0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x58, 0x01, 0x80, 0x2e, 0x42, 0x02, 0xb0, 0xf0,
0x10, 0x30, 0x21, 0x2e, 0x16, 0xf0, 0x80, 0x2e, 0xf0, 0x00, 0x1f, 0x50, 0x1d, 0x52, 0x01, 0x42, 0x3b, 0x80, 0x41,
0x30, 0x01, 0x42, 0x3c, 0x80, 0x00, 0x2e, 0x01, 0x40, 0x01, 0x42, 0x21, 0x2e, 0xff, 0xaf, 0xb8, 0x2e, 0x2c, 0x82,
0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18,
0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x2e, 0x55, 0xf0, 0xc0, 0x2e, 0x21, 0x2e, 0x55, 0xf0, 0x44, 0x47, 0xaa, 0x00, 0x05, 0x00, 0xaa,
0x00, 0x05, 0x00, 0x42, 0x58, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x52, 0x0b, 0x50, 0x60, 0x42, 0x00, 0x3f, 0x0d, 0x54, 0x42, 0x42, 0x69, 0x82,
0x0f, 0x54, 0x42, 0x42, 0x42, 0x82, 0x4b, 0x30, 0x42, 0x40, 0x10, 0x08, 0x50, 0x42, 0x7e, 0x80, 0x4b, 0x42, 0x61,
0x30, 0x01, 0x42, 0x10, 0x50, 0x03, 0x2e, 0x40, 0xf0, 0x56, 0xb2, 0x08, 0x80, 0x31, 0x30, 0xf0, 0x7f, 0x03, 0x2f,
0x01, 0x2e, 0x40, 0xf0, 0x1a, 0x90, 0x21, 0x2f, 0x98, 0x2e, 0x1e, 0xb0, 0x03, 0x30, 0x13, 0x50, 0x17, 0x52, 0x11,
0x54, 0x54, 0x33, 0x06, 0x30, 0x55, 0x32, 0x1d, 0x1a, 0xe3, 0x22, 0x18, 0x1a, 0x15, 0x58, 0xe3, 0x22, 0x04, 0x30,
0xd5, 0x40, 0xb5, 0x0d, 0xe1, 0xbe, 0x6f, 0xbb, 0x80, 0x91, 0xa9, 0x0d, 0x01, 0x89, 0xb5, 0x23, 0x10, 0xa1, 0xf7,
0x2f, 0xda, 0x0e, 0x54, 0x33, 0xeb, 0x2f, 0x01, 0x2e, 0x25, 0x00, 0x70, 0x1a, 0x00, 0x30, 0x21, 0x30, 0x48, 0x22,
0x40, 0xb2, 0x06, 0x2f, 0x23, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0x3a, 0x00, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xf0,
0x6f, 0x01, 0x31, 0x20, 0x26, 0x01, 0x42, 0x10, 0x30, 0x21, 0x2e, 0x59, 0xf0, 0x98, 0x2e, 0x3a, 0x00, 0x01, 0x50,
0x03, 0x52, 0x98, 0x2e, 0x7f, 0x01, 0x01, 0x50, 0x05, 0x84, 0x13, 0x30, 0x05, 0x50, 0x64, 0x30, 0x07, 0x52, 0x93,
0x42, 0x84, 0x42, 0x98, 0x2e, 0x7f, 0x01, 0x05, 0x50, 0x06, 0x80, 0x71, 0x30, 0x01, 0x42, 0x00, 0x2e, 0x00, 0x2e,
0xd0, 0x2e, 0x98, 0x2e, 0xd6, 0x00, 0x01, 0x2e, 0x36, 0x00, 0x00, 0xb2, 0x0d, 0x2f, 0x00, 0x30, 0x21, 0x2e, 0x36,
0x00, 0x09, 0x50, 0x98, 0x2e, 0x18, 0x01, 0x09, 0x50, 0x01, 0x52, 0x98, 0x2e, 0x90, 0x01, 0x09, 0x50, 0x05, 0x52,
0x98, 0x2e, 0x90, 0x01, 0x98, 0x2e, 0x3a, 0x00, 0xe6, 0x2d, 0x07, 0x2e, 0x00, 0xf0, 0x03, 0x2e, 0x00, 0xf0, 0x21,
0x50, 0x9c, 0xbe, 0x02, 0x40, 0x1d, 0x52, 0xf4, 0x33, 0xdc, 0xba, 0xd9, 0x0f, 0x94, 0x08, 0x06, 0x2f, 0x49, 0xaf,
0x04, 0x2f, 0x51, 0x0a, 0x02, 0x34, 0x47, 0xa3, 0x8a, 0x0a, 0x91, 0x22, 0x3c, 0x80, 0x25, 0x2e, 0x59, 0xf0, 0x01,
0x40, 0x01, 0x42, 0xb8, 0x2e, 0x1a, 0x24, 0x26, 0x00, 0x80, 0x2e, 0x58, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e,
0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x80, 0x2e, 0x18, 0x00, 0x46,
0x00, 0x40, 0x00, 0x4f, 0x00, 0x42, 0x00, 0x37, 0x00, 0xaf, 0x00, 0xff, 0x00, 0xec, 0x00, 0xff, 0xb7, 0x00, 0x02,
0x00, 0xb0, 0x05, 0x80, 0xc9, 0xf0, 0x88, 0x00, 0x80, 0x00, 0x5e, 0xf0, 0x59, 0xf0, 0x89, 0xf0, 0x3a, 0x00, 0x80,
0x2e, 0x00, 0xae, 0x44, 0x47, 0xfd, 0x2d, 0x00, 0x0c, 0x60, 0x50, 0x03, 0x2e, 0x45, 0x00, 0xe0, 0x7f, 0xf1, 0x7f,
0xdb, 0x7f, 0x30, 0x30, 0x1b, 0x54, 0x0a, 0x1a, 0x28, 0x2f, 0x1a, 0x25, 0x7a, 0x82, 0x00, 0x30, 0x43, 0x30, 0x32,
0x30, 0x05, 0x30, 0x04, 0x30, 0xf6, 0x6f, 0xf2, 0x09, 0xfc, 0x13, 0xc2, 0xab, 0xb3, 0x09, 0xef, 0x23, 0x80, 0xb3,
0xe6, 0x6f, 0xb7, 0x01, 0x00, 0x2e, 0x8b, 0x41, 0x4b, 0x42, 0x03, 0x2f, 0x46, 0x40, 0x86, 0x17, 0x81, 0x8d, 0x46,
0x42, 0x41, 0x8b, 0x23, 0xbd, 0xb3, 0xbd, 0x03, 0x89, 0x41, 0x82, 0x07, 0x0c, 0x43, 0xa3, 0xe6, 0x2f, 0xe1, 0x6f,
0xa2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xb2, 0x6f, 0x52, 0x42, 0x00, 0x2e, 0xc2, 0x6f, 0x42, 0x42, 0x03, 0xb2, 0x03,
0x2e, 0x59, 0xf0, 0xf3, 0x3d, 0x02, 0x32, 0x0b, 0x08, 0x8a, 0x0a, 0xdb, 0x6f, 0x02, 0x22, 0xa0, 0x5f, 0x21, 0x2e,
0x59, 0xf0, 0xb8, 0x2e, 0x60, 0x50, 0xc3, 0x7f, 0xd4, 0x7f, 0xe7, 0x7f, 0xf6, 0x7f, 0xb2, 0x7f, 0xa5, 0x7f, 0x36,
0x30, 0x07, 0x2e, 0x01, 0xf0, 0xbe, 0xbd, 0xbe, 0xbb, 0x23, 0x58, 0x77, 0x05, 0x09, 0x56, 0x25, 0x54, 0x27, 0x41,
0x06, 0x41, 0xf8, 0xbf, 0xbe, 0x0b, 0xb5, 0x11, 0xd6, 0x42, 0x03, 0x89, 0x5a, 0x0e, 0xf6, 0x2f, 0x12, 0x30, 0x25,
0x2e, 0x36, 0x00, 0x02, 0x31, 0x25, 0x2e, 0xb8, 0xf0, 0xd4, 0x6f, 0xc3, 0x6f, 0xe7, 0x6f, 0xb2, 0x6f, 0xa5, 0x6f,
0xf6, 0x6f, 0xa0, 0x5f, 0xc8, 0x2e, 0x09, 0x86, 0x02, 0x30, 0x12, 0x42, 0x43, 0x0e, 0xfc, 0x2f, 0x37, 0x80, 0x13,
0x30, 0x13, 0x42, 0x12, 0x42, 0x12, 0x42, 0x12, 0x42, 0x02, 0x42, 0x03, 0x80, 0x41, 0x84, 0x11, 0x42, 0x02, 0x42,
0xb8, 0x2e, 0x46, 0x84, 0x80, 0x50, 0xa3, 0x40, 0x83, 0x88, 0x82, 0x40, 0x04, 0x41, 0xc3, 0x7f, 0x42, 0x8a, 0x06,
0x41, 0x6d, 0xbb, 0xf6, 0x7f, 0x80, 0xb3, 0xd5, 0x7f, 0xe0, 0x7f, 0x59, 0x2f, 0x31, 0x25, 0x55, 0x40, 0x41, 0x91,
0xb1, 0x7f, 0x0f, 0x2f, 0x01, 0x30, 0xc1, 0x42, 0x00, 0x2e, 0xd2, 0x6f, 0x13, 0x40, 0x93, 0x42, 0x00, 0x2e, 0x13,
0x40, 0x93, 0x42, 0x00, 0x2e, 0x00, 0x40, 0x80, 0x42, 0xbd, 0x80, 0xc0, 0x2e, 0x01, 0x42, 0x80, 0x5f, 0xc7, 0x86,
0x01, 0x30, 0xc5, 0x40, 0xfb, 0x86, 0x45, 0x41, 0x04, 0x41, 0x43, 0xbe, 0xd5, 0xbe, 0x43, 0xba, 0xd5, 0xba, 0x84,
0x7f, 0x95, 0x7f, 0xa1, 0x7f, 0x14, 0x30, 0x61, 0x15, 0xf5, 0x09, 0x15, 0x40, 0xc0, 0xb3, 0x0b, 0x2f, 0xc6, 0x40,
0xae, 0x05, 0x07, 0x30, 0xfe, 0x05, 0x80, 0xa9, 0xb7, 0x23, 0x97, 0x6f, 0x77, 0x0f, 0xa6, 0x6f, 0xe6, 0x23, 0xf6,
0x6f, 0xa7, 0x7f, 0x80, 0x90, 0x00, 0x2f, 0xc5, 0x42, 0x41, 0x82, 0xc1, 0x86, 0x43, 0xa2, 0xe7, 0x2f, 0xa1, 0x6f,
0xb0, 0x6f, 0x0a, 0x1a, 0x02, 0x2f, 0x01, 0x30, 0x1b, 0x2c, 0x01, 0x42, 0x01, 0x40, 0x4c, 0x28, 0x82, 0x6f, 0x01,
0x42, 0x4a, 0x0e, 0x13, 0x2f, 0xc0, 0x6f, 0x00, 0xb2, 0x03, 0x2f, 0x3f, 0x80, 0x20, 0x14, 0x21, 0x2e, 0x5e, 0xf0,
0xe1, 0x6f, 0xd0, 0x6f, 0x52, 0x40, 0x12, 0x42, 0x00, 0x2e, 0x52, 0x40, 0x12, 0x42, 0x00, 0x2e, 0x41, 0x40, 0x03,
0x2c, 0x01, 0x42, 0x10, 0x30, 0x40, 0x42, 0x80, 0x5f, 0xb8, 0x2e, 0x80, 0x2e, 0x18, 0x00, 0xfd, 0x2d, 0x30, 0x50,
0x2a, 0x25, 0xbd, 0x84, 0xfb, 0x7f, 0x8b, 0x31, 0x27, 0x56, 0x83, 0x42, 0xeb, 0x7f, 0x06, 0x30, 0x14, 0x30, 0x05,
0x30, 0x0d, 0x2c, 0x13, 0x56, 0x43, 0x1a, 0x02, 0x2f, 0x4e, 0x04, 0x06, 0x30, 0x15, 0x50, 0xec, 0x09, 0xd7, 0x01,
0x41, 0x8b, 0xcb, 0x41, 0xc6, 0x01, 0x81, 0x8d, 0xcb, 0x43, 0x31, 0x0e, 0xf1, 0x2f, 0xfb, 0x6f, 0xd0, 0x5f, 0xb8,
0x2e, 0x10, 0x50, 0x01, 0x2e, 0x35, 0x00, 0x00, 0xb2, 0xfb, 0x7f, 0x19, 0x2f, 0x29, 0x56, 0x2f, 0x52, 0x13, 0x54,
0xc3, 0x00, 0x48, 0x04, 0xc2, 0x0f, 0x18, 0x22, 0x41, 0xb2, 0x0e, 0x2f, 0x12, 0x30, 0x8a, 0x08, 0x80, 0xb2, 0x06,
0x2f, 0x7f, 0x82, 0x98, 0x2e, 0x00, 0xb0, 0x2d, 0x52, 0x23, 0x2e, 0xff, 0xb9, 0x06, 0x2d, 0xfb, 0x6f, 0xf0, 0x5f,
0x80, 0x2e, 0x00, 0xb0, 0x2b, 0x52, 0x01, 0x42, 0x00, 0x2e, 0xfb, 0x6f, 0xf0, 0x5f, 0xb8, 0x2e, 0x10, 0x24, 0x58,
0x02, 0x11, 0x24, 0x00, 0x0c, 0x12, 0x24, 0x80, 0x2e, 0x13, 0x24, 0x18, 0x00, 0x12, 0x42, 0x13, 0x42, 0x41, 0x1a,
0xfb, 0x2f, 0x10, 0x24, 0x50, 0x39, 0x11, 0x24, 0x21, 0x2e, 0x21, 0x2e, 0x10, 0x00, 0x23, 0x2e, 0x11, 0x00, 0x80,
0x2e, 0x10, 0x00
};
/***************************************************************************/
/**\name Function definitions
****************************************************************************/
/*!
* @brief This API is the entry point.
* Call this API before using all other APIs.
* This API reads the chip-id of the sensor and sets the resolution.
*/
int8_t bma456_an_init(struct bma4_dev *dev)
{
int8_t rslt;
/* Structure to define the default values for axes re-mapping */
struct bma4_axes_remap axes_remap = {
.x_axis = BMA4_MAP_X_AXIS, .x_axis_sign = BMA4_MAP_POSITIVE, .y_axis = BMA4_MAP_Y_AXIS,
.y_axis_sign = BMA4_MAP_POSITIVE, .z_axis = BMA4_MAP_Z_AXIS, .z_axis_sign = BMA4_MAP_POSITIVE
};
rslt = bma4_init(dev);
if (rslt == BMA4_OK)
{
if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC))
{
/* Resolution of BMA456_AN sensor is 16 bit */
dev->resolution = BMA4_16_BIT_RESOLUTION;
dev->feature_len = BMA456_AN_FEATURE_SIZE;
dev->config_size = sizeof(bma456_an_config_file);
/* Set the default values for axis
* re-mapping in the device structure
*/
dev->remap = axes_remap;
}
else
{
rslt = BMA4_E_INVALID_SENSOR;
}
}
return rslt;
}
/*!
* @brief This API is used to upload the configuration file to enable the
* features of the sensor.
*/
int8_t bma456_an_write_config_file(struct bma4_dev *dev)
{
int8_t rslt = BMA4_OK;
if (dev != NULL)
{
if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC))
{
/* Configuration stream read/write length boundary
* check
*/
if ((dev->read_write_len >= BMA456_AN_RD_WR_MIN_LEN) && (dev->read_write_len <= BMA456_AN_RD_WR_MAX_LEN))
{
/* Even or odd check */
if ((dev->read_write_len % 2) != 0)
{
dev->read_write_len = dev->read_write_len - 1;
}
/* Assign stream data */
dev->config_file_ptr = bma456_an_config_file;
rslt = bma4_write_config_file(dev);
}
else
{
rslt = BMA4_E_RD_WR_LENGTH_INVALID;
}
}
else
{
rslt = BMA4_E_INVALID_SENSOR;
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API is used to get the config file major and minor information.
*/
int8_t bma456_an_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev)
{
/* Initialize configuration file */
uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 };
/* Update index to config file version */
uint8_t index = BMA456_AN_CONFIG_ID_OFFSET;
/* Variable to define LSB */
uint8_t lsb = 0;
/* Variable to define MSB */
uint8_t msb = 0;
/* Variable to define LSB and MSB */
uint16_t lsb_msb = 0;
/* Result of api are returned to this variable */
int8_t rslt = BMA4_OK;
if ((config_major != NULL) && (config_minor != NULL))
{
rslt = bma4_set_advance_power_save(BMA4_DISABLE, dev);
if (rslt == BMA4_OK)
{
/* Wait for sensor time synchronization. Refer the data-sheet for
* more information
*/
dev->delay_us(450, dev->intf_ptr);
/* Get config file identification from the sensor */
rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_FEATURE_SIZE, dev);
if (rslt == BMA4_OK)
{
/* Get word to calculate config file identification */
lsb = feature_config[index++];
msb = feature_config[index++];
lsb_msb = (uint16_t)(msb << 8 | lsb);
/* Get major and minor version */
*config_major = BMA4_GET_BITSLICE(lsb_msb, BMA4_CONFIG_MAJOR);
*config_minor = BMA4_GET_BITS_POS_0(lsb, BMA4_CONFIG_MINOR);
}
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API sets/un-sets the user provided interrupt to either interrupt
* pin1 or pin2 in the sensor.
*/
int8_t bma456_an_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev)
{
int8_t rslt = BMA4_OK;
if (dev != NULL)
{
if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC))
{
if (int_line <= 1)
{
/* Map/Unmap the interrupt */
rslt = bma4_map_interrupt(int_line, int_map, enable, dev);
}
else
{
rslt = BMA4_E_INT_LINE_INVALID;
}
}
else
{
rslt = BMA4_E_INVALID_SENSOR;
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API reads the bma456_an interrupt status from the sensor.
*/
int8_t bma456_an_read_int_status(uint16_t *int_status, struct bma4_dev *dev)
{
int8_t rslt = BMA4_OK;
if ((dev != NULL) && (int_status != NULL))
{
if ((dev->chip_id == BMA456_AN_CHIP_ID_PRIM) || (dev->chip_id == BMA456_AN_CHIP_ID_SEC))
{
/* Read the interrupt status */
rslt = bma4_read_int_status(int_status, dev);
}
else
{
rslt = BMA4_E_INVALID_SENSOR;
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API performs x, y and z axis remapping in the sensor.
*/
int8_t bma456_an_set_remap_axes(const struct bma4_remap *remap_axes, struct bma4_dev *dev)
{
uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 };
uint8_t index = BMA456_AN_AXES_REMAP_OFFSET;
int8_t rslt = BMA4_OK;
if (remap_axes != NULL)
{
rslt = bma4_set_remap_axes(remap_axes, feature_config, index, BMA456_AN_FEATURE_SIZE, dev);
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API reads the x, y and z axis remap data from the sensor.
*/
int8_t bma456_an_get_remap_axes(struct bma4_remap *remap_axes, struct bma4_dev *dev)
{
uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 };
uint8_t index = BMA456_AN_AXES_REMAP_OFFSET;
int8_t rslt = BMA4_OK;
if (remap_axes != NULL)
{
rslt = bma4_get_remap_axes(remap_axes, feature_config, index, BMA456_AN_FEATURE_SIZE, dev);
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API sets the configuration of any-motion feature in the sensor.
* This API enables/disables the any-motion feature according to the axis set.
*/
int8_t bma456_an_set_any_mot_config(const struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMA4_OK;
/* Initialize configuration file */
uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 };
/* Update index to configure any-motion axes */
uint8_t index = BMA456_AN_ANY_MOT_OFFSET;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define LSB and MSB */
uint16_t lsb_msb = 0;
if ((dev != NULL) && (any_motion != NULL))
{
/* Get any-motion configuration from the sensor */
rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_ANY_MOT_LEN, dev);
if (rslt == BMA4_OK)
{
/* Set threshold value in feature configuration array */
feature_config[index++] = BMA4_GET_LSB(any_motion->threshold);
feature_config[index++] = BMA4_GET_MSB(any_motion->threshold);
/* Extract the word where duration and axes enable
* resides
*/
lsb = feature_config[index];
msb = feature_config[index + 1] << 8;
lsb_msb = lsb | msb;
/* Set the duration in the same word */
lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_AN_ANY_NO_MOT_DUR, any_motion->duration);
/* Set the axes in the same word */
lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456_AN_ANY_NO_MOT_AXIS_EN, any_motion->axes_en);
/* Assign the word with set duration and axes enable
* value back to feature configuration array
*/
feature_config[index++] = BMA4_GET_LSB(lsb_msb);
feature_config[index] = BMA4_GET_MSB(lsb_msb);
/* Set any-motion configuration to the sensor */
rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_ANY_MOT_LEN, dev);
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API gets the configuration of any-motion feature from the
* sensor.
*/
int8_t bma456_an_get_any_mot_config(struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMA4_OK;
/* Initialize configuration file */
uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 };
/* Update index to configure any-motion axes */
uint8_t index = BMA456_AN_ANY_MOT_OFFSET;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define LSB and MSB */
uint16_t lsb_msb = 0;
if ((dev != NULL) && (any_motion != NULL))
{
/* Get any-motion configuration from the sensor */
rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_ANY_MOT_LEN, dev);
if (rslt == BMA4_OK)
{
/* Get word to calculate threshold and any-motion
* select
*/
lsb = (uint16_t)feature_config[index++];
msb = ((uint16_t)feature_config[index++] << 8);
lsb_msb = lsb | msb;
/* Extract threshold value */
any_motion->threshold = lsb_msb & BMA456_AN_ANY_NO_MOT_THRES_MSK;
/* Get word to calculate duration and axes enable */
lsb = (uint16_t)feature_config[index++];
msb = ((uint16_t)feature_config[index] << 8);
lsb_msb = lsb | msb;
/* Extract duration value */
any_motion->duration = lsb_msb & BMA456_AN_ANY_NO_MOT_DUR_MSK;
/* Extract axes enable value */
any_motion->axes_en =
(uint8_t)((lsb_msb & BMA456_AN_ANY_NO_MOT_AXIS_EN_MSK) >> BMA456_AN_ANY_NO_MOT_AXIS_EN_POS);
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API sets the configuration of no-motion feature in the sensor.
* This API enables/disables the no-motion feature according to the axis set.
*/
int8_t bma456_an_set_no_mot_config(const struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMA4_OK;
/* Initialize configuration file */
uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 };
/* Update index to configure no-motion axes */
uint8_t index = BMA456_AN_NO_MOT_OFFSET;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define LSB and MSB */
uint16_t lsb_msb = 0;
if ((dev != NULL) && (no_motion != NULL))
{
/* Get no-motion configuration from the sensor */
rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_NO_MOT_RD_WR_LEN, dev);
if (rslt == BMA4_OK)
{
/* Set threshold value in feature configuration array */
feature_config[index++] = BMA4_GET_LSB(no_motion->threshold);
feature_config[index++] = BMA4_GET_MSB(no_motion->threshold);
/* Extract the word where duration and axes enable
* resides
*/
lsb = feature_config[index];
msb = feature_config[index + 1] << 8;
lsb_msb = lsb | msb;
/* Set the duration in the same word */
lsb_msb = BMA4_SET_BITS_POS_0(lsb_msb, BMA456_AN_ANY_NO_MOT_DUR, no_motion->duration);
/* Set the axes in the same word */
lsb_msb = BMA4_SET_BITSLICE(lsb_msb, BMA456_AN_ANY_NO_MOT_AXIS_EN, no_motion->axes_en);
/* Assign the word with set duration and axes enable
* value back to feature configuration array
*/
feature_config[index++] = BMA4_GET_LSB(lsb_msb);
feature_config[index] = BMA4_GET_MSB(lsb_msb);
/* Set no-motion configuration to the sensor */
rslt = bma4_write_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_NO_MOT_RD_WR_LEN, dev);
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief This API gets the configuration of no-motion feature from the
* sensor.
*/
int8_t bma456_an_get_no_mot_config(struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev)
{
/* Variable to define error */
int8_t rslt = BMA4_OK;
/* Initialize configuration file */
uint8_t feature_config[BMA456_AN_FEATURE_SIZE] = { 0 };
/* Update index to configure no-motion axes */
uint8_t index = BMA456_AN_NO_MOT_OFFSET;
/* Variable to define LSB */
uint16_t lsb = 0;
/* Variable to define MSB */
uint16_t msb = 0;
/* Variable to define LSB and MSB */
uint16_t lsb_msb = 0;
if ((dev != NULL) && (no_motion != NULL))
{
/* Get no-motion configuration from the sensor */
rslt = bma4_read_regs(BMA4_FEATURE_CONFIG_ADDR, feature_config, BMA456_AN_NO_MOT_RD_WR_LEN, dev);
if (rslt == BMA4_OK)
{
/* Get word to calculate threshold and no-motion
* select
*/
lsb = (uint16_t)feature_config[index++];
msb = ((uint16_t)feature_config[index++] << 8);
lsb_msb = lsb | msb;
/* Extract threshold value */
no_motion->threshold = lsb_msb & BMA456_AN_ANY_NO_MOT_THRES_MSK;
/* Get word to calculate duration and axes enable */
lsb = (uint16_t)feature_config[index++];
msb = ((uint16_t)feature_config[index] << 8);
lsb_msb = lsb | msb;
/* Extract duration value */
no_motion->duration = lsb_msb & BMA456_AN_ANY_NO_MOT_DUR_MSK;
/* Extract axes enable value */
no_motion->axes_en =
(uint8_t)((lsb_msb & BMA456_AN_ANY_NO_MOT_AXIS_EN_MSK) >> BMA456_AN_ANY_NO_MOT_AXIS_EN_POS);
}
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*! @endcond */
+566
View File
@@ -0,0 +1,566 @@
/**
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* BSD-3-Clause
*
* 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.
*
* @file bma456_an.h
* @date 2023-07-05
* @version V2.29.0
*
*/
/**
* \ingroup bma4xy
* \defgroup bma456_an BMA456_AN
* @brief Sensor driver for BMA456_AN sensor
*/
#ifndef BMA456_AN_H
#define BMA456_AN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bma4.h"
/**\name Chip ID of BMA456_AN sensor */
#define BMA456_AN_CHIP_ID_PRIM UINT8_C(0x16)
#define BMA456_AN_CHIP_ID_SEC UINT8_C(0x1A)
/**\name Sensor feature size */
#define BMA456_AN_FEATURE_SIZE UINT8_C(12)
#define BMA456_AN_ANY_MOT_LEN UINT8_C(4)
/**\name Feature offset address */
#define BMA456_AN_ANY_MOT_OFFSET UINT8_C(0x00)
#define BMA456_AN_NO_MOT_OFFSET UINT8_C(0x04)
#define BMA456_AN_CONFIG_ID_OFFSET UINT8_C(0x08)
#define BMA456_AN_AXES_REMAP_OFFSET UINT8_C(0x0A)
/**\name Read/Write Lengths */
#define BMA456_AN_RD_WR_MIN_LEN UINT8_C(2)
/*! @name Maximum valid read write length is size of config file array */
#define BMA456_AN_RD_WR_MAX_LEN ((uint16_t)sizeof(bma456_an_config_file))
#define BMA456_AN_NO_MOT_RD_WR_LEN (BMA456_AN_ANY_MOT_LEN + BMA456_AN_NO_MOT_OFFSET)
/**************************************************************/
/**\name Re-map Axes */
/**************************************************************/
#define BMA456_AN_X_AXIS_MASK UINT8_C(0x03)
#define BMA456_AN_X_AXIS_SIGN_MASK UINT8_C(0x04)
#define BMA456_AN_Y_AXIS_MASK UINT8_C(0x18)
#define BMA456_AN_Y_AXIS_SIGN_MASK UINT8_C(0x20)
#define BMA456_AN_Z_AXIS_MASK UINT8_C(0xC0)
#define BMA456_AN_Z_AXIS_SIGN_MASK UINT8_C(0x01)
/**************************************************************/
/**\name Any/no Motion */
/**************************************************************/
/**\name Any/No motion threshold macros */
#define BMA456_AN_ANY_NO_MOT_THRES_MSK UINT16_C(0x07FF)
/**\name Any/No motion duration macros */
#define BMA456_AN_ANY_NO_MOT_DUR_MSK UINT16_C(0x1FFF)
/**\name Any/No motion enable macros */
#define BMA456_AN_ANY_NO_MOT_AXIS_EN_POS UINT8_C(0x0D)
#define BMA456_AN_ANY_NO_MOT_AXIS_EN_MSK UINT16_C(0xE000)
/**************************************************************/
/**\name User macros */
/**************************************************************/
/**\name Any-motion/No-motion axis enable macros */
#define BMA456_AN_X_AXIS_EN UINT8_C(0x01)
#define BMA456_AN_Y_AXIS_EN UINT8_C(0x02)
#define BMA456_AN_Z_AXIS_EN UINT8_C(0x04)
#define BMA456_AN_EN_ALL_AXIS UINT8_C(0x07)
#define BMA456_AN_DIS_ALL_AXIS UINT8_C(0x00)
/**\name Interrupt status macros */
#define BMA456_AN_ANY_MOT_INT UINT8_C(0x20)
#define BMA456_AN_NO_MOT_INT UINT8_C(0x40)
#define BMA456_AN_ERROR_INT UINT8_C(0x80)
/******************************************************************************/
/*! @name Structure Declarations */
/******************************************************************************/
/*!
* @brief Any/No motion configuration
*/
struct bma456_an_any_no_mot_config
{
/*! Expressed in 50 Hz samples (20 ms) */
uint16_t duration;
/*! Threshold value for Any-motion/No-motion detection in
* 5.11g format
*/
uint16_t threshold;
/*! To enable selected axes */
uint8_t axes_en;
};
/***************************************************************************/
/*! BMA456_AN User Interface function prototypes
****************************************************************************/
/**
* \ingroup bma456_an
* \defgroup bma456_anApiInit Initialization
* @brief Initialize the sensor and device structure
*/
/*!
* \ingroup bma456_anApiInit
* \page bma456_an_api_bma456_an_init bma456_an_init
* \code
* int8_t bma456_an_init(struct bma4_dev *dev);
* \endcode
* @details This API is the entry point.
* Call this API before using all other APIs.
* This API reads the chip-id of the sensor and sets the resolution.
*
* @param[in,out] dev : Structure instance of bma4_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_init(struct bma4_dev *dev);
/**
* \ingroup bma456_an
* \defgroup bma456_anApiConfig ConfigFile
* @brief Write binary configuration in the sensor
*/
/*!
* \ingroup bma456_anApiConfig
* \page bma456_an_api_bma456_an_write_config_file bma456_an_write_config_file
* \code
* int8_t bma456_an_write_config_file(struct bma4_dev *dev);
* \endcode
* @details This API is used to upload the config file to enable the features of
* the sensor.
*
* @param[in] dev : Structure instance of bma4_dev.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_write_config_file(struct bma4_dev *dev);
/*!
* \ingroup bma456_anApiConfig
* \page bma456_an_api_bma456_an_get_version_config bma456_an_get_version_config
* \code
*int8_t bma456_an_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev);
* \endcode
* @details This API is used to get the config file major and minor information.
*
* @param[in] dev : Structure instance of bma4_dev.
* @param[out] config_major : Pointer to data buffer to store the config major.
* @param[out] config_minor : Pointer to data buffer to store the config minor.
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_get_version_config(uint16_t *config_major, uint16_t *config_minor, struct bma4_dev *dev);
/**
* \ingroup bma456_an
* \defgroup bma456_anApiMapInt Map / Unmap Interrupt
* @brief Map / Unmap user provided interrupt to interrupt pin1 or pin2 of the sensor
*/
/*!
* \ingroup bma456_anApiMapInt
* \page bma456_an_api_bma456_an_map_interrupt bma456_an_map_interrupt
* \code
* int8_t bma456_an_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev);
* \endcode
* @details This API sets/unsets the user provided interrupt to either
* interrupt pin1 or pin2 in the sensor.
*
* @param[in] int_line: Variable to select either interrupt pin1 or pin2.
*
*@verbatim
* int_line | Macros
* ------------|-------------------
* 0x00 | BMA4_INTR1_MAP
* 0x01 | BMA4_INTR2_MAP
*@endverbatim
*
* @param[in] int_map : Variable to specify the interrupts.
* @param[in] enable : Variable to specify mapping or unmapping of interrupts.
*
*@verbatim
* enable | Macros
* --------|-------------------
* 0x00 | BMA4_DISABLE
* 0x01 | BMA4_ENABLE
*@endverbatim
*
* @param[in] dev : Structure instance of bma4_dev.
*
* @note Below macros specify the interrupts.
*
* Feature Interrupts
* - BMA456_AN_ANY_MOT_INT
* - BMA456_AN_NO_MOT_INT
* - BMA456_AN_ERROR_INT
*
* Hardware Interrupts
* - BMA4_FIFO_FULL_INT
* - BMA4_FIFO_WM_INT
* - BMA4_ACCEL_DATA_RDY_INT
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_map_interrupt(uint8_t int_line, uint16_t int_map, uint8_t enable, struct bma4_dev *dev);
/**
* \ingroup bma456_an
* \defgroup bma456_anApiIntS Interrupt Status
* @brief Read interrupt status of the sensor
*/
/*!
* \ingroup bma456_anApiIntS
* \page bma456_an_api_bma456_an_read_int_status bma456_an_read_int_status
* \code
* int8_t bma456_an_read_int_status(uint16_t *int_status, struct bma4_dev *dev);
* \endcode
* @details This API reads the bma456_an interrupt status from the sensor.
*
* @param[out] int_status : Variable to store the interrupt status read from
* the sensor.
* @param[in] dev : Structure instance of bma4_dev.
*
* @note Below macros are used to check the interrupt status.
*
* Feature Interrupts
* - BMA456_AN_ANY_MOT_INT
* - BMA456_AN_NO_MOT_INT
* - BMA456_AN_ERROR_INT
*
* Hardware Interrupts
* - BMA4_FIFO_FULL_INT
* - BMA4_FIFO_WM_INT
* - BMA4_ACCEL_DATA_RDY_INT
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_read_int_status(uint16_t *int_status, struct bma4_dev *dev);
/**
* \ingroup bma456_an
* \defgroup bma456_anApiRemap Remap Axes
* @brief Set / Get x, y and z axis re-mapping in the sensor
*/
/*!
* \ingroup bma456_anApiRemap
* \page bma456_an_api_bma456_an_set_remap_axes bma456_an_set_remap_axes
* \code
* int8_t bma456_an_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev);
* \endcode
* @details This API performs x, y and z axis remapping in the sensor.
*
* @param[in] remap_data : Pointer to store axes remapping data.
* @param[in] dev : Structure instance of bma4_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_set_remap_axes(const struct bma4_remap *remap_data, struct bma4_dev *dev);
/*!
* \ingroup bma456_anApiRemap
* \page bma456_an_api_bma456_an_get_remap_axes bma456_an_get_remap_axes
* \code
* int8_t bma456_an_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev);
* \endcode
* @details This API reads the x, y and z axis remap data from the sensor.
*
* @param[out] remap_data : Pointer to store axis remap data which is read
* from the bma456_an sensor.
* @param[in] dev : Structure instance of bma4_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_get_remap_axes(struct bma4_remap *remap_data, struct bma4_dev *dev);
/**
* \ingroup bma456_an
* \defgroup bma456_anApiAnyMot Any motion Feature
* @brief Functions of Any motion feature of the sensor
*/
/*!
* \ingroup bma456_anApiAnyMot
* \page bma456_an_api_bma456_an_set_any_mot_config bma456_an_set_any_mot_config
* \code
* int8_t bma456_an_set_any_mot_config(const struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev);
* \endcode
* @details This API sets the configuration of any-motion feature in the sensor
* This API enables/disables the any-motion feature according to the axis set.
*
* @param[in] any_motion : Pointer to structure variable to configure
* any-motion.
*
* @verbatim
* -------------------------------------------------------------------------
* Structure parameters | Description
* --------------------------------|----------------------------------------
* | Defines the number of
* | consecutive data points for
* | which the threshold condition
* duration | must be respected, for interrupt
* | assertion. It is expressed in
* | 50 Hz samples (20 ms).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* --------------------------------|----------------------------------------
* | Slope threshold value for
* | Any-motion detection
* threshold | in 5.11g format.
* | Range is 0 to 1g.
* | Default value is 0xAA = 83mg.
* --------------------------------|----------------------------------------
* | Enables the feature on a per-axis
* axis_en | basis.
* ---------------------------------------------------------------------------
* @endverbatim
*
*@verbatim
* Value | axis_en
* ---------|-------------------------
* 0x00 | BMA456_AN_DIS_ALL_AXIS
* 0x01 | BMA456_AN_X_AXIS_EN
* 0x02 | BMA456_AN_Y_AXIS_EN
* 0x04 | BMA456_AN_Z_AXIS_EN
* 0x07 | BMA456_AN_EN_ALL_AXIS
*@endverbatim
*
* @param[in] dev : Structure instance of bma4_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_set_any_mot_config(const struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev);
/*!
* \ingroup bma456_anApiNomot
* \page bma456_an_api_bma456_an_get_any_motion_config bma456_an_get_any_motion_config
* \code
* int8_t bma456_an_get_any_motion_config(struct bma456_an_anymotion_config *any_motion, struct bma4_dev *dev);
* \endcode
* @details This API gets the configuration of any-motion feature from the
* sensor.
*
* @param[out] any_motion : Pointer to structure variable to configure
* any-motion.
*
* @verbatim
* -------------------------------------------------------------------------
* Structure parameters | Description
* --------------------------------|----------------------------------------
* | Defines the number of
* | consecutive data points for
* | which the threshold condition
* duration | must be respected, for interrupt
* | assertion. It is expressed in
* | 50 Hz samples (20 ms).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* --------------------------------|----------------------------------------
* | Slope threshold value for
* | Any-motion detection
* threshold | in 5.11g format.
* | Range is 0 to 1g.
* | Default value is 0xAA = 83mg.
* --------------------------------|-----------------------------------------
* | Enables the feature on a per-axis
* axis_en | basis.
* ---------------------------------------------------------------------------
* @endverbatim
*
*@verbatim
* Value | axis_en
* ---------|-------------------------
* 0x00 | BMA456_AN_DIS_ALL_AXIS
* 0x01 | BMA456_AN_X_AXIS_EN
* 0x02 | BMA456_AN_Y_AXIS_EN
* 0x04 | BMA456_AN_Z_AXIS_EN
* 0x07 | BMA456_AN_EN_ALL_AXIS
*@endverbatim
*
* @param[in] dev : Structure instance of bma4_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_get_any_mot_config(struct bma456_an_any_no_mot_config *any_motion, struct bma4_dev *dev);
/**
* \ingroup bma456_an
* \defgroup bma456_anApiNomot No-Motion Feature
* @brief Operations of no-motion feature of the sensor
*/
/*!
* \ingroup bma456_anApiNomot
* \page bma456_an_api_bma456_an_set_no_motion_config bma456_an_set_no_motion_config
* \code
* int8_t bma456_an_set_no_motion_config(const struct bma456_an_nomotion_config *no_motion, struct bma4_dev *dev);
* \endcode
* @details This API sets the configuration of no-motion feature in the sensor
* This API enables/disables the no-motion feature according to the axis set.
*
* @param[in] no_motion : Pointer to structure variable to configure
* no-motion.
* @verbatim
* -------------------------------------------------------------------------
* Structure parameters | Description
* --------------------------------|----------------------------------------
* | Defines the number of
* | consecutive data points for
* | which the threshold condition
* duration | must be respected, for interrupt
* | assertion. It is expressed in
* | 50 Hz samples (20 ms).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* --------------------------------|----------------------------------------
* | Slope threshold value for
* | No-motion detection
* threshold | in 5.11g format.
* | Range is 0 to 1g.
* | Default value is 0xAA = 83mg.
* --------------------------------|----------------------------------------
* | Enables the feature on a per-axis
* axis_en | basis.
* ---------------------------------------------------------------------------
* @endverbatim
*
*@verbatim
* Value | axis_en
* ---------|-------------------------
* 0x00 | BMA456_AN_DIS_ALL_AXIS
* 0x01 | BMA456_AN_X_AXIS_EN
* 0x02 | BMA456_AN_Y_AXIS_EN
* 0x04 | BMA456_AN_Z_AXIS_EN
* 0x07 | BMA456_AN_EN_ALL_AXIS
*@endverbatim
*
* @param[in] dev : Structure instance of bma4_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_set_no_mot_config(const struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev);
/*!
* \ingroup bma456_anApiAnyMot
* \page bma456_an_api_bma456_an_get_no_motion_config bma456_an_get_no_motion_config
* \code
* int8_t bma456_an_get_no_motion_config(struct bma456_an_nomotion_config *no_motion, struct bma4_dev *dev);
* \endcode
* @details This API gets the configuration of no-motion feature from the
* sensor.
*
* @param[out] no_motion : Pointer to structure variable to configure
* no-motion.
*
* @verbatim
* -------------------------------------------------------------------------
* Structure parameters | Description
* --------------------------------|----------------------------------------
* | Defines the number of
* | consecutive data points for
* | which the threshold condition
* duration | must be respected, for interrupt
* | assertion. It is expressed in
* | 50 Hz samples (20 ms).
* | Range is 0 to 163sec.
* | Default value is 5 = 100ms.
* --------------------------------|----------------------------------------
* | Slope threshold value for
* | No-motion detection
* threshold | in 5.11g format.
* | Range is 0 to 1g.
* | Default value is 0xAA = 83mg.
* --------------------------------|-----------------------------------------
* | Enables the feature on a per-axis
* axis_en | basis.
* ---------------------------------------------------------------------------
* @endverbatim
*
*@verbatim
* Value | axis_en
* ---------|-------------------------
* 0x00 | BMA456_AN_DIS_ALL_AXIS
* 0x01 | BMA456_AN_X_AXIS_EN
* 0x02 | BMA456_AN_Y_AXIS_EN
* 0x04 | BMA456_AN_Z_AXIS_EN
* 0x07 | BMA456_AN_EN_ALL_AXIS
*@endverbatim
*
* @param[in] dev : Structure instance of bma4_dev
*
* @return Result of API execution status
* @retval 0 -> Success
* @retval < 0 -> Fail
*/
int8_t bma456_an_get_no_mot_config(struct bma456_an_any_no_mot_config *no_motion, struct bma4_dev *dev);
#ifdef __cplusplus
}
#endif /*End of CPP guard */
#endif /*End of header guard macro */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accel_foc.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,735 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
/******************************************************************************/
/*! Header Files */
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "bma456_tablet.h"
#include "common.h"
#include "coines.h"
/******************************************************************************/
/*! Macro Definitions */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Global Variable Declaration */
/* Structure to store temporary axes data values */
struct temp_axes_val
{
/* X data */
int32_t x;
/* Y data */
int32_t y;
/* Z data */
int32_t z;
};
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used perform accel foc and determine limits based on range
*
* @param[in] range : Range of Accel
* @param[in] input_axis : Axis selected for Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev);
/*!
* @brief This internal API is to determine if average accel FOC data is within limits
*
* @param[in] avg_accel_foc_data : Average Accel FOC value
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] foc_sign : Input sign of performed Accel FOC
* @param[in] min_val : Minimum acceptable LSB limit
* @param[in] max_val : Maximum acceptable LSB limit
*
* @return Status of execution.
*/
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val);
/*!
* @brief This internal API is to collect and verify accel sensor data
*
* @param[in] range : Value of Accel range
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] matched_axis : Input Axis to perform Accel FOC
* @param[in] foc_sign : Input sign to perform Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev);
/*!
* @brief This internal API is to calculate noise level for Accel FOC data
*
* @param[in] matched_axis : Input Axis to perform accel FOC
* @param[in] accel_foc_data : Array of Accel FOC data
* @param[in] avg_accel_foc_data : Average Accel FOC data
*
* @return Status of execution.
*/
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Sensor initialization configuration. */
struct bma4_dev dev;
uint8_t try = 0, j;
int8_t rslt;
struct bma4_accel_config accel_conf = { 0 };
uint8_t data = 0, range, input_axis = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
printf("Functional test for accel foc start..\n\n");
printf("Choose the axis for accel FOC to be done\n");
printf("Press '1' to choose X axis\n");
printf("Press '2' to choose Y axis\n");
printf("Press '3' to choose Z axis\n");
printf("Press '4' to choose -X axis\n");
printf("Press '5' to choose -Y axis\n");
printf("Press '6' to choose -Z axis\n");
for (;;)
{
scanf("%u", (unsigned int *)&input_axis);
if (input_axis > 0 && input_axis < 7)
{
break;
}
}
if (input_axis == 1)
{
printf("The choosen input axis for FOC is : X\n");
}
else if (input_axis == 2)
{
printf("The choosen input axis for FOC is : Y\n");
}
else if (input_axis == 3)
{
printf("The choosen input axis for FOC is : Z\n");
}
else if (input_axis == 4)
{
printf("The choosen input axis for FOC is : -X\n");
}
else if (input_axis == 5)
{
printf("The choosen input axis for FOC is : -Y\n");
}
else if (input_axis == 6)
{
printf("The choosen input axis for FOC is : -Z\n");
}
printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n");
for (j = 0; j < 2; j++)
{
try = 0;
if (j == 1)
{
printf("Keep sensor in wrong position and press 5\n");
}
else if (j == 0)
{
printf("Keep sensor in right position and press 5\n");
}
for (;;)
{
scanf("%hu", (short unsigned int *)&try);
if (try == 5)
{
break;
}
}
for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++)
{
/****************************************************************/
/* Initialize by enabling configuration load */
printf("#########################################################\n\n");
rslt = bma456_tablet_init(&dev);
bma4_error_codes_print_result("bma456_tablet_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_tablet_write_config_file(&dev);
bma4_error_codes_print_result("bma456_tablet_write_config_file", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Accelerometer Configuration Settings */
/* Output Data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = range;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth);
/* Perform FOC for different ranges */
rslt = perform_foc_range_test(range, input_axis, &dev);
if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_OK))
{
printf("\n######### Valid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_OK))
{
printf("\n######### Invalid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
}
/* Disable offset compensation */
rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_read_regs", rslt);
data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET);
rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_write_regs", rslt);
}
bma4_coines_deinit();
return rslt;
}
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val)
{
int8_t rslt = BMA4_OK;
int16_t diff_after = 0;
if (foc_sign == 0)
{
if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val)))
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
if (foc_sign == 1)
{
if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val)))
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
return rslt;
}
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data)
{
int32_t variance = 0;
double noise_level;
uint16_t idx = 0;
if (matched_axis == 'X')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x));
}
}
else if (matched_axis == 'Y')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y));
}
}
else if (matched_axis == 'Z')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z));
}
}
noise_level = sqrt((double)variance);
printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level);
}
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev)
{
int8_t rslt = BMA4_E_INVALID_STATUS;
uint8_t i;
uint16_t reg_status = 0;
int16_t xl, yl, zl;
int16_t xh, yh, zh;
int16_t min_val = 0;
int16_t max_val = 0;
struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } };
struct temp_axes_val temp_foc_data = { 0 };
struct bma4_accel avg_accel_foc_data = { 0 };
struct bma4_accel sensor_data = { 0 };
/* Setting initial values */
xl = yl = zl = 32767;
xh = yh = zh = -32768;
/* Read accelerometer values before/after FOC */
for (i = 0; i < ACCEL_SAMPLE_COUNT; i++)
{
for (;;)
{
/* To get the data ready interrupt status */
rslt = bma4_read_int_status(&reg_status, dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
/* Read accelerometer data based on data ready interrupt */
if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&sensor_data, dev);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel));
printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n",
i,
accel_foc_data[i].x,
i,
accel_foc_data[i].y,
i,
accel_foc_data[i].z);
if (xl > accel_foc_data[i].x)
{
xl = accel_foc_data[i].x;
}
if (xh < accel_foc_data[i].x)
{
xh = accel_foc_data[i].x;
}
if (yl > accel_foc_data[i].y)
{
yl = accel_foc_data[i].y;
}
if (yh < accel_foc_data[i].y)
{
yh = accel_foc_data[i].y;
}
if (zl > accel_foc_data[i].z)
{
zl = accel_foc_data[i].z;
}
if (zh < accel_foc_data[i].z)
{
zh = accel_foc_data[i].z;
}
temp_foc_data.x += accel_foc_data[i].x;
temp_foc_data.y += accel_foc_data[i].y;
temp_foc_data.z += accel_foc_data[i].z;
break;
}
}
}
/* Taking average values to calculate percentage deviation */
avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT);
printf("********* MIN & MAX VALUES ********\n");
printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl);
printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh);
printf("***** AVERAGE AFTER FOC *****\n");
printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n",
avg_accel_foc_data.x,
avg_accel_foc_data.y,
avg_accel_foc_data.z);
/* Calculate noise level */
calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data);
/* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 12-bit resolution) */
if (range == 0)
{
/* Min and Max limits for Range 2G */
min_val = BMA4_12BIT_ACC_2G_MIN_NOISE_LIMIT;
max_val = BMA4_12BIT_ACC_2G_MAX_NOISE_LIMIT;
}
else if (range == 1)
{
/* Min and Max limits for Range 4G */
min_val = BMA4_12BIT_ACC_4G_MIN_NOISE_LIMIT;
max_val = BMA4_12BIT_ACC_4G_MAX_NOISE_LIMIT;
}
else if (range == 2)
{
/* Min and Max limits for Range 8G */
min_val = BMA4_12BIT_ACC_8G_MIN_NOISE_LIMIT;
max_val = BMA4_12BIT_ACC_8G_MAX_NOISE_LIMIT;
}
else if (range == 3)
{
/* Min and Max limits for Range 16G */
min_val = BMA4_12BIT_ACC_16G_MIN_NOISE_LIMIT;
max_val = BMA4_12BIT_ACC_16G_MAX_NOISE_LIMIT;
}
if ((matched_axis == 'X') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Y') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Z') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'X') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.x,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Y') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.y,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Z') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.z,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
return rslt;
}
/* Perform FOC for different range and resolutions */
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev)
{
int8_t rslt;
int8_t matched_axis = 0;
int16_t reference = 0;
/* Set accel foc axis and it's sign (x, y, z, sign)*/
struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 };
if (input_axis == 1)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 2)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 3)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 0;
}
else if (input_axis == 4)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 5)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 6)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 1;
}
switch (range)
{
/* Reference LSB value of 2G */
case 0:
reference = BMA4_12BIT_ACC_FOC_2G_REF;
break;
/* Reference LSB value of 4G */
case 1:
reference = BMA4_12BIT_ACC_FOC_4G_REF;
break;
/* Reference LSB value of 8G */
case 2:
reference = BMA4_12BIT_ACC_FOC_8G_REF;
break;
/* Reference LSB value of 16G */
case 3:
reference = BMA4_12BIT_ACC_FOC_16G_REF;
break;
default:
break;
}
if (g_value_foc.x == 1)
{
matched_axis = 'X';
}
else if (g_value_foc.y == 1)
{
matched_axis = 'Y';
}
else if (g_value_foc.z == 1)
{
matched_axis = 'Z';
}
if (g_value_foc.sign == 1)
{
printf("MATCHED AXIS is = -%c\n", matched_axis);
}
else
{
printf("MATCHED AXIS is = %c\n", matched_axis);
}
printf("\n\n# Before FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
printf("\n\n######### Perform Accel FOC #########\n\n");
/* Perform accelerometer FOC */
rslt = bma4_perform_accel_foc(&g_value_foc, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
printf("\n\n# After FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accelerometer.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,163 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Earth's gravity in m/s^2 */
#define GRAVITY_EARTH (9.80665f)
/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*
* @param[in] val : Raw sensor value.
* @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G).
* @param[in] bit_width : Resolution of the sensor.
*
* @return Accel values in meters per second square.
*
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store accel data ready interrupt status */
uint16_t int_status = 0;
/* Variable that holds the accelerometer sample count */
uint8_t n_data = 1;
struct bma4_accel sens_data = { 0 };
float x = 0, y = 0, z = 0;
struct bma4_accel_config accel_conf = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_tablet_init(&bma);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_tablet_write_config_file(&bma);
bma4_error_codes_print_result("bma456_tablet_write_config status", rslt);
/* Accelerometer configuration settings */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
/* Read the accel x, y, z data */
rslt = bma4_read_accel_xyz(&sens_data, &bma);
bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt);
if (rslt == BMA4_OK)
{
/* Converting lsb to meter per second squared for 12 bit resolution at 2G range */
x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution);
y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution);
z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution);
/* Print the data in m/s2 */
printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z);
}
/* Increment the count that determines the number of samples to be printed */
n_data++;
/* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */
if (n_data > ACCEL_SAMPLE_COUNT)
{
break;
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width)
{
double power = 2;
float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f));
return (GRAVITY_EARTH * val * g_range) / half_scale;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE = axis_remap.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,356 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include <stdlib.h>
#include "coines.h"
#include "bma456_tablet.h"
#include "common.h"
/*********************************************************************/
/* functions */
/*********************************************************************/
/*!
* @brief Main Function where the execution getting started to test the code.
*/
int main(void)
{
int8_t rslt;
struct bma4_dev bma4;
struct bma4_remap remap_data = { 0 };
struct bma4_accel accel = { 0 };
struct bma4_accel_config accel_conf = { 0 };
uint16_t int_status = 0;
char data_array[13][11] =
{ { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" },
{ "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma4, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_tablet_init(&bma4);
bma4_error_codes_print_result("bma456_tablet_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_tablet_write_config_file(&bma4);
bma4_error_codes_print_result("bma456_tablet_write_config", rslt);
/* Accelerometer configuration Setting */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma4);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma4);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
printf("\nAXIS_REMAP_FUNC_TEST 1\n");
printf("Get sensor data of re-mapped axes\n");
rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt);
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
printf("Expected Re-mapped x value = BMA4_X\n");
printf("Expected Re-mapped y value = BMA4_Y\n");
printf("Expected Re-mapped z value = BMA4_Z\n");
if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 2\n");
printf("Get sensor data of re-mapped axes\n");
remap_data.x = BMA4_NEG_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_NEG_X;
rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_NEG_X\n");
if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 3\n");
printf("Get sensor data of re-mapped axes - 2nd combination\n");
remap_data.x = BMA4_NEG_Z;
remap_data.y = BMA4_NEG_X;
remap_data.z = BMA4_Y;
rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Z\n");
printf("Expected Re-mapped y value = BMA4_NEG_X\n");
printf("Expected Re-mapped z value = BMA4_Y\n");
if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 4\n");
printf("Get sensor data of re-mapped axes - 3rd combination\n");
remap_data.x = BMA4_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_X;
rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_X\n");
if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 5\n");
printf("Get sensor data of re-mapped axes - 4th combination\n");
remap_data.x = BMA4_NEG_X;
remap_data.y = BMA4_NEG_Y;
remap_data.z = BMA4_NEG_Z;
rslt = bma456_tablet_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_tablet_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_tablet_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_X\n");
printf("Expected Re-mapped y value = BMA4_NEG_Y\n");
printf("Expected Re-mapped z value = BMA4_NEG_Z\n");
if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,242 @@
/**
* Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "bma4_defs.h"
#include "common.h"
/******************************************************************************/
/*! Macro definitions */
/*! Read write length varies based on user requirement */
#define BMA4_READ_WRITE_LEN UINT8_C(46)
/******************************************************************************/
/*! Static variable definition */
/*! Variable that holds the I2C device address or SPI chip selection */
static uint8_t dev_addr;
/******************************************************************************/
/*! User interface functions */
/*!
* I2C read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* I2C write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* SPI read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* SPI write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* Delay function map to COINES platform
*/
void bma4_delay_us(uint32_t period, void *intf_ptr)
{
(void) intf_ptr;
coines_delay_usec(period);
}
/*!
* @brief Function to select the interface between SPI and I2C.
* Also to initialize coines platform
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant)
{
int8_t rslt = BMA4_OK;
if (bma != NULL)
{
int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL);
struct coines_board_info board_info;
if (result < COINES_SUCCESS)
{
printf(
"\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n"
" 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n");
exit(result);
}
result = coines_get_board_info(&board_info);
#if defined(PC)
setbuf(stdout, NULL);
#endif
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_usec(10000);
/* Bus configuration : I2C */
if (intf == BMA4_I2C_INTF)
{
printf("I2C Interface \n");
/* To initialize the user I2C function */
dev_addr = BMA4_I2C_ADDR_PRIMARY;
bma->intf = BMA4_I2C_INTF;
bma->bus_read = bma4_i2c_read;
bma->bus_write = bma4_i2c_write;
/* SDO to Ground */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
/* Make CSB pin HIGH */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH);
coines_delay_msec(100);
/* SDO pin is made low */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
(void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
}
/* Bus configuration : SPI */
else if (intf == BMA4_SPI_INTF)
{
printf("SPI Interface \n");
/* To initialize the user SPI function */
dev_addr = COINES_SHUTTLE_PIN_7;
bma->intf = BMA4_SPI_INTF;
bma->bus_read = bma4_spi_read;
bma->bus_write = bma4_spi_write;
(void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
}
/* Assign variant information */
bma->variant = variant;
/* Assign device address to interface pointer */
bma->intf_ptr = &dev_addr;
/* Configure delay in microseconds */
bma->delay_us = bma4_delay_us;
/* Configure max read/write length (in bytes) ( Supported length depends on target machine) */
bma->read_write_len = BMA4_READ_WRITE_LEN;
/* Set Performance mode status */
bma->perf_mode_status = BMA4_DISABLE;
coines_delay_msec(100);
(void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
coines_delay_msec(200);
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief Prints the execution status of the APIs.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt)
{
if (rslt != BMA4_OK)
{
printf("%s\t", api_name);
if (rslt == BMA4_E_NULL_PTR)
{
printf("Error [%d] : Null pointer\r\n", rslt);
}
else if (rslt == BMA4_E_COM_FAIL)
{
printf("Error [%d] : Communication failure\r\n", rslt);
}
else if (rslt == BMA4_E_CONFIG_STREAM_ERROR)
{
printf("Error [%d] : Invalid configuration stream\r\n", rslt);
}
else if (rslt == BMA4_E_SELF_TEST_FAIL)
{
printf("Error [%d] : Self test failed\r\n", rslt);
}
else if (rslt == BMA4_E_INVALID_SENSOR)
{
printf("Error [%d] : Device not found\r\n", rslt);
}
else if (rslt == BMA4_E_OUT_OF_RANGE)
{
printf("Error [%d] : Out of Range\r\n", rslt);
}
else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF)
{
printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt);
}
else
{
/* For more error codes refer "*_defs.h" */
printf("Error [%d] : Unknown error code\r\n", rslt);
}
}
}
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void)
{
(void)fflush(stdout);
coines_delay_msec(200);
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_msec(1000);
/* Coines interface reset */
coines_soft_reset();
coines_delay_msec(1000);
(void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL);
}
@@ -0,0 +1,127 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#ifndef COMMON_H
#define COMMON_H
/*! CPP guard */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include "bma4.h"
#include "coines.h"
/*!
* @brief Function for reading the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose value is to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for reading the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose data has to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the
* APIs.
*
* @param[in] period_us : The required wait time in microsecond.
* @param[in] intf_ptr : Interface pointer
*
* @return void.
*
*/
void bma4_delay_us(uint32_t period, void *intf_ptr);
/*!
* @brief Function to select the interface between SPI and I2C.
*
* @param[in] bma : Structure instance of bma4_dev
* @param[in] intf : Interface selection parameter
* @param[in] variant : Variant information of the sensor
* ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT )
* ( BMA45x variants values - BMA45X_VARIANT )
*
* @return Status of execution
* @retval 0 -> Success
* @retval < 0 -> Failure Info
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant);
/*!
* @brief Prints the execution status of the APIs.
*
* @param[in] api_name : Name of the API whose execution status has to be printed.
* @param[in] rslt : Error code returned by the API whose execution status has to be printed.
*
* @return void.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt);
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void);
#ifdef __cplusplus
}
#endif /* End of CPP guard */
#endif /* COMMON_H */
@@ -0,0 +1,20 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_full_header_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
TARGET=MCU_APP30
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,173 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1.
* fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames
*
* Extra frames to parse sensortime data
*/
#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(170)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */
struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_TABLET */
rslt = bma456_tablet_init(&dev);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE;
printf("FIFO is configured in header mode\n");
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
while (loop <= 10)
{
rslt = bma456_tablet_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
/* Print control frames like sensor time and skipped frame count */
printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count);
printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION));
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_full_headerless_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,171 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_buffer = 1024, accel_frame_len = 6.
* fifo_accel_frame_count = (1024 / 6) = 170 frames
*/
#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(170)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */
struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_TABLET */
rslt = bma456_tablet_init(&dev);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH;
/* To enable headerless mode, disable the header. */
rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config status", rslt);
printf("FIFO is configured in headerless mode\n");
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
while (loop <= 10)
{
rslt = bma456_tablet_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
loop++;
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,20 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_watermark_header_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
TARGET=MCU_APP30
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,188 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Setting a watermark level in FIFO */
#define BMA456_TABLET_FIFO_WATERMARK_LEVEL UINT16_C(650)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1.
* fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames
* NOTE: Extra frames are read in order to get sensor time
*/
#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(120)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */
struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
uint16_t watermark = 0;
/* To set the watermark level in FIFO */
uint16_t wm_lvl;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_TABLET */
rslt = bma456_tablet_init(&dev);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE;
printf("FIFO is configured in header mode\n");
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
wm_lvl = BMA456_TABLET_FIFO_WATERMARK_LEVEL;
rslt = bma4_set_fifo_wm(wm_lvl, &dev);
bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt);
while (loop <= 10)
{
rslt = bma456_tablet_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_wm(&watermark, &dev);
bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt);
printf("FIFO watermark level : %d\n", watermark);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
/* Print control frames like sensor time and skipped frame count */
printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count);
printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION));
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,188 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Setting a watermark level in FIFO */
#define BMA456_TABLET_FIFO_WATERMARK_LEVEL UINT16_C(600)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_watermark_level = 600, accel_frame_len = 6.
* fifo_accel_frame_count = (600 / 6) = 100 frames
*/
#define BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT UINT8_C(100)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_TABLET_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */
struct bma4_accel fifo_accel_data[BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
uint16_t watermark = 0;
/* To set the watermark level in FIFO */
uint16_t wm_lvl;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_TABLET */
rslt = bma456_tablet_init(&dev);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_TABLET_FIFO_RAW_DATA_USER_LENGTH;
/* To enable headerless mode, disable the header. */
rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config status", rslt);
printf("FIFO is configured in headerless mode\n");
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
wm_lvl = BMA456_TABLET_FIFO_WATERMARK_LEVEL;
rslt = bma4_set_fifo_wm(wm_lvl, &dev);
bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt);
while (loop <= 10)
{
rslt = bma456_tablet_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_wm(&watermark, &dev);
bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt);
printf("FIFO watermark level : %d\n", watermark);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_TABLET_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= low_g.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,96 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store step activity interrupt status */
uint16_t int_status = 0;
struct bma456_tablet_low_g_config low_g = { 0 };
struct bma456_tablet_low_g_config get_low_g = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_tablet_init(&bma);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_tablet_write_config_file(&bma);
bma4_error_codes_print_result("bma456_tablet_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
low_g.threshold = 0x133;
low_g.duration = 0x0;
low_g.hysteresis = 0x100;
rslt = bma456_tablet_set_low_g_config(&low_g, &bma);
bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt);
rslt = bma456_tablet_get_low_g_config(&get_low_g, &bma);
bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt);
printf("Low-g Threshold : 0x%x\n\n", get_low_g.threshold);
/* Enable low-g feature */
rslt = bma456_tablet_feature_enable(BMA456_TABLET_LOW_G, 1, &bma);
bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Map the interrupt 1 for low-g detection */
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA456_TABLET_LOW_G_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
if (rslt == BMA4_OK)
{
printf("Drop the board for low-g\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the low-g interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA456_TABLET_LOW_G_INT))
{
printf("\nLow-g interrupt occurred\n");
break;
}
int_status = 0;
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= motion.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,190 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/*****************************************************************************/
/*! Global variable */
/*! Structure to define any/no-motion configurations */
struct bma456_tablet_any_no_mot_config any_no_mot = { 0 };
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used to get any/no-motion configurations.
*
* @param[in] bma : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store any/no-motion interrupt status */
uint16_t int_status = 0;
uint8_t iteration = 20;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_tablet_init(&bma);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_tablet_write_config_file(&bma);
bma4_error_codes_print_result("bma456_tablet_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Map the interrupt pin 1 for any/no-motion */
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP,
(BMA456_TABLET_ANY_MOT_INT | BMA456_TABLET_NO_MOT_INT),
BMA4_ENABLE,
&bma);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
/* Get any-motion and no-motion configurations */
rslt = get_any_no_mot_config(&bma);
bma4_error_codes_print_result("get_any_no_mot_config status", rslt);
printf("Shake the board for any-motion interrupt whereas do not shake the board for no-motion interrupt\n");
if (rslt == BMA4_OK)
{
for (;;)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
if (rslt == BMA4_OK)
{
/* Enters only if the obtained interrupt is any-motion */
if (int_status & BMA456_TABLET_ANY_MOT_INT)
{
printf("Any-motion interrupt occurred\n");
iteration--;
}
/* Enters only if the obtained interrupt is no-motion */
else if (int_status & BMA456_TABLET_NO_MOT_INT)
{
printf("No-motion interrupt occurred\n");
iteration--;
}
int_status = 0;
/* Break out of the loop when iteration has reached zero */
if (iteration == 0)
{
printf("Iterations are done. Exiting !\n\n");
break;
}
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API is used to get any/no-motion configurations.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma)
{
/* Variable to store the status of API */
int8_t rslt;
/* Getting any-motion configuration to get default configuration */
rslt = bma456_tablet_get_any_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_tablet_get_any_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/* Select the axis for which any/no motion interrupt should be generated */
any_no_mot.axes_en = BMA456_TABLET_EN_ALL_AXIS;
/*
* Set the slope threshold:
* Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG)
*/
any_no_mot.threshold = 10;
/*
* Set the duration for any-motion interrupt:
* Duration defines the number of consecutive data points for which threshold condition must be true(1
* bit =
* 20ms)
*/
any_no_mot.duration = 4;
/* Like threshold and duration, we can also change the config of int_bhvr and slope */
/* Set the threshold and duration configuration */
rslt = bma456_tablet_set_any_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_tablet_set_any_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/* Getting no-motion configuration to get default configuration */
rslt = bma456_tablet_get_no_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_tablet_get_no_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/* Select the axis for which any/no motion interrupt should be generated */
any_no_mot.axes_en = BMA456_TABLET_EN_ALL_AXIS;
/*
* Set the slope threshold:
* Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG)
*/
any_no_mot.threshold = 10;
/*
* Set the duration for no-motion interrupt:
* Duration defines the number of consecutive data points for which threshold condition must be
* true(1 bit = 20ms)
*/
any_no_mot.duration = 4;
/* Like threshold and duration, we can also change the config of int_bhvr */
/* Set the threshold and duration configuration */
rslt = bma456_tablet_set_no_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_tablet_set_no_mot_config status", rslt);
}
}
}
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= orientation.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,147 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Macros */
#define COUNT UINT8_C(5)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store step activity interrupt status */
uint16_t int_status = 0;
/* Variable to hold iteration value */
uint8_t loop = 1;
/* Structure to hold orientation configuration */
struct bma456_tablet_orientation_config orient;
uint8_t orientation_out = 0;
uint8_t orientation_faceup_down = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_tablet_init(&bma);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_tablet_write_config_file(&bma);
bma4_error_codes_print_result("bma456_tablet_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Enable orientation feature */
rslt = bma456_tablet_feature_enable(BMA456_TABLET_ORIENTATION, 1, &bma);
bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt);
orient.upside_down = 0x01;
orient.mode = 0x02;
orient.blocking = 0x01;
orient.hold_time = 0x14;
orient.slope_thres = 0xA4;
orient.hysteresis = 0x80;
orient.theta = 0x33;
rslt = bma456_tablet_set_orientation_config(&orient, &bma);
bma4_error_codes_print_result("bma456_tablet_set_orientation_config status", rslt);
if (rslt == BMA4_OK)
{
/* Map the interrupt 1 for orientation detection */
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA456_TABLET_ORIENTATION_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
if (rslt == BMA4_OK)
{
printf("Move the board to detect orientation\n");
while (loop <= COUNT)
{
int_status = 0;
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the orientation interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA456_TABLET_ORIENTATION_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma456_tablet_orientation_output(&orientation_out, &orientation_faceup_down, &bma);
bma4_error_codes_print_result("bma456_tablet_orientation_output", rslt);
printf("The Orientation output is %d\n", orientation_out);
printf("The Orientation faceup/down output is %d\n", orientation_faceup_down);
switch (orientation_faceup_down)
{
case BMA456_TABLET_FACE_UP:
printf("\nOrientation state is face up\n");
break;
case BMA456_TABLET_FACE_DOWN:
printf("\nOrientation state is face down\n");
break;
default:
break;
}
switch (orientation_out)
{
case BMA456_TABLET_LANDSCAPE_LEFT:
printf("\nOrientation state is landscape left\n\n");
break;
case BMA456_TABLET_LANDSCAPE_RIGHT:
printf("\nOrientation state is landscape right\n\n");
break;
case BMA456_TABLET_PORTRAIT_UP_DOWN:
printf("\nOrientation state is portrait upside down\n\n");
break;
case BMA456_TABLET_PORTRAIT_UP_RIGHT:
printf("\nOrientation state is portrait upright\n\n");
break;
default:
break;
}
loop++;
if (loop > COUNT)
{
break;
}
}
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= tap.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_tablet.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,127 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_tablet.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store tap interrupt status */
uint16_t int_status = 0;
/* Loop variable */
uint8_t loop = 10;
struct bma456_tablet_tap_output tap_out = { 0 };
struct bma456_tablet_tap_settings settings = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_tablet_init(&bma);
bma4_error_codes_print_result("bma456_tablet_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_tablet_write_config_file(&bma);
bma4_error_codes_print_result("bma456_tablet_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Map the interrupt pin 1 for tap detection */
rslt = bma456_tablet_map_interrupt(BMA4_INTR1_MAP, BMA456_TABLET_TAP_OUT_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456_tablet_map_interrupt status", rslt);
if (rslt == BMA4_OK)
{
/* Enabling the single, double and triple tap features */
rslt =
bma456_tablet_feature_enable(
(BMA456_TABLET_SINGLE_TAP | BMA456_TABLET_DOUBLE_TAP | BMA456_TABLET_TRIPLE_TAP),
BMA4_ENABLE,
&bma);
bma4_error_codes_print_result("bma456_tablet_feature_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Getting tap parameters settings */
rslt = bma456_tablet_tap_get_parameter(&settings, &bma);
bma4_error_codes_print_result("bma456_tablet_tap_get_parameter status", rslt);
}
}
if (rslt == BMA4_OK)
{
printf("Tap the board either single, double or triple tap\n");
while (loop > 0)
{
/* Read interrupt status */
rslt = bma456_tablet_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_tablet_read_int_status", rslt);
/* Filtering only the tap interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA456_TABLET_TAP_OUT_INT))
{
rslt = bma456_tablet_tap_output(&tap_out, &bma);
if (BMA4_OK == rslt)
{
/* Enters only if the obtained interrupt is single-tap */
if (tap_out.s_tap)
{
printf("Single Tap interrupt occurred\n");
}
/* Enters only if the obtained interrupt is double-tap */
else if (tap_out.d_tap)
{
printf("Double Tap interrupt occurred\n");
}
/* Enters only if the obtained interrupt is triple-tap */
else if (tap_out.t_tap)
{
printf("Triple Tap interrupt occurred\n");
}
loop--;
}
int_status = 0;
}
}
/* Break out of the loop when iteration has reached zero */
if (loop == 0)
{
printf("Iterations are done. Exiting !\n\n");
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accel_foc.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,741 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
/******************************************************************************/
/*! Header Files */
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "bma456_an.h"
#include "common.h"
#include "coines.h"
/******************************************************************************/
/*! Macro Definitions */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Global Variable Declaration */
/* Structure to store temporary axes data values */
struct temp_axes_val
{
/* X data */
int32_t x;
/* Y data */
int32_t y;
/* Z data */
int32_t z;
};
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used perform accel foc and determine limits based on range
*
* @param[in] range : Range of Accel
* @param[in] input_axis : Axis selected for Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev);
/*!
* @brief This internal API is to determine if average accel FOC data is within limits
*
* @param[in] avg_accel_foc_data : Average Accel FOC value
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] foc_sign : Input sign of performed Accel FOC
* @param[in] min_val : Minimum acceptable LSB limit
* @param[in] max_val : Maximum acceptable LSB limit
*
* @return Status of execution.
*/
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val);
/*!
* @brief This internal API is to collect and verify accel sensor data
*
* @param[in] range : Value of Accel range
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] matched_axis : Input Axis to perform Accel FOC
* @param[in] foc_sign : Input sign to perform Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev);
/*!
* @brief This internal API is to calculate noise level for Accel FOC data
*
* @param[in] matched_axis : Input Axis to perform accel FOC
* @param[in] accel_foc_data : Array of Accel FOC data
* @param[in] avg_accel_foc_data : Average Accel FOC data
*
* @return Status of execution.
*/
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Sensor initialization configuration. */
struct bma4_dev dev;
uint8_t try = 0, j;
int8_t rslt;
struct bma4_accel_config accel_conf = { 0 };
uint8_t data = 0, range, input_axis = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
printf("Functional test for accel foc start..\n\n");
printf("Choose the axis for accel FOC to be done\n");
printf("Press '1' to choose X axis\n");
printf("Press '2' to choose Y axis\n");
printf("Press '3' to choose Z axis\n");
printf("Press '4' to choose -X axis\n");
printf("Press '5' to choose -Y axis\n");
printf("Press '6' to choose -Z axis\n");
for (;;)
{
scanf("%u", (unsigned int *)&input_axis);
if (input_axis > 0 && input_axis < 7)
{
break;
}
}
if (input_axis == 1)
{
printf("The choosen input axis for FOC is : X\n");
}
else if (input_axis == 2)
{
printf("The choosen input axis for FOC is : Y\n");
}
else if (input_axis == 3)
{
printf("The choosen input axis for FOC is : Z\n");
}
else if (input_axis == 4)
{
printf("The choosen input axis for FOC is : -X\n");
}
else if (input_axis == 5)
{
printf("The choosen input axis for FOC is : -Y\n");
}
else if (input_axis == 6)
{
printf("The choosen input axis for FOC is : -Z\n");
}
printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n");
for (j = 0; j < 2; j++)
{
try = 0;
if (j == 1)
{
printf("Keep sensor in wrong position and press 5\n");
}
else if (j == 0)
{
printf("Keep sensor in right position and press 5\n");
}
for (;;)
{
scanf("%hu", (short unsigned int *)&try);
if (try == 5)
{
break;
}
}
for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++)
{
/****************************************************************/
/* Initialize by enabling configuration load */
printf("#########################################################\n\n");
rslt = bma456_an_init(&dev);
bma4_error_codes_print_result("bma4_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_an_write_config_file(&dev);
bma4_error_codes_print_result("bma4_write_config", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Accelerometer Configuration Settings */
/* Output Data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = range;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* Delay to set accel sensor configurations (20ms for 50HZ) */
dev.delay_us(20000, dev.intf_ptr);
/* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth);
/* Perform FOC for different ranges */
rslt = perform_foc_range_test(range, input_axis, &dev);
if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_OK))
{
printf("\n######### Valid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_OK))
{
printf("\n######### Invalid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
}
/* Disable offset compensation */
rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_read_regs", rslt);
data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET);
rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_write_regs", rslt);
}
bma4_coines_deinit();
return rslt;
}
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val)
{
int8_t rslt = BMA4_OK;
int16_t diff_after = 0;
if (foc_sign == 0)
{
if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val)))
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
if (foc_sign == 1)
{
if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val)))
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
return rslt;
}
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data)
{
int32_t variance = 0;
double noise_level;
uint16_t idx = 0;
if (matched_axis == 'X')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x));
}
}
else if (matched_axis == 'Y')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y));
}
}
else if (matched_axis == 'Z')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z));
}
}
noise_level = sqrt((double)variance);
printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level);
}
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev)
{
int8_t rslt = BMA4_E_INVALID_STATUS;
uint8_t i;
uint16_t reg_status = 0;
int16_t xl, yl, zl;
int16_t xh, yh, zh;
int16_t min_val = 0;
int16_t max_val = 0;
struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } };
struct temp_axes_val temp_foc_data = { 0 };
struct bma4_accel avg_accel_foc_data = { 0 };
struct bma4_accel sensor_data = { 0 };
/* Setting initial values */
xl = yl = zl = 32767;
xh = yh = zh = -32768;
/* Read accelerometer values before/after FOC */
for (i = 0; i < ACCEL_SAMPLE_COUNT; i++)
{
for (;;)
{
/* To get the data ready interrupt status */
rslt = bma4_read_int_status(&reg_status, dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
/* Read accelerometer data based on data ready interrupt */
if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&sensor_data, dev);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel));
printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n",
i,
accel_foc_data[i].x,
i,
accel_foc_data[i].y,
i,
accel_foc_data[i].z);
if (xl > accel_foc_data[i].x)
{
xl = accel_foc_data[i].x;
}
if (xh < accel_foc_data[i].x)
{
xh = accel_foc_data[i].x;
}
if (yl > accel_foc_data[i].y)
{
yl = accel_foc_data[i].y;
}
if (yh < accel_foc_data[i].y)
{
yh = accel_foc_data[i].y;
}
if (zl > accel_foc_data[i].z)
{
zl = accel_foc_data[i].z;
}
if (zh < accel_foc_data[i].z)
{
zh = accel_foc_data[i].z;
}
temp_foc_data.x += accel_foc_data[i].x;
temp_foc_data.y += accel_foc_data[i].y;
temp_foc_data.z += accel_foc_data[i].z;
break;
}
}
}
/* Taking average values to calculate percentage deviation */
avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT);
printf("********* MIN & MAX VALUES ********\n");
printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl);
printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh);
printf("***** AVERAGE AFTER FOC *****\n");
printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n",
avg_accel_foc_data.x,
avg_accel_foc_data.y,
avg_accel_foc_data.z);
/* Calculate noise level */
calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data);
/* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 16-bit resolution) */
if (range == 0)
{
/* Min and Max limits for Range 2G */
min_val = BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT;
}
else if (range == 1)
{
/* Min and Max limits for Range 4G */
min_val = BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT;
}
else if (range == 2)
{
/* Min and Max limits for Range 8G */
min_val = BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT;
}
else if (range == 3)
{
/* Min and Max limits for Range 16G */
min_val = BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT;
}
if ((matched_axis == 'X') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Y') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Z') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'X') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.x,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Y') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.y,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Z') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.z,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
return rslt;
}
/* Perform FOC for different range and resolutions */
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev)
{
int8_t rslt;
int8_t matched_axis = 0;
int16_t reference = 0;
/* Set accel foc axis and it's sign (x, y, z, sign)*/
struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 };
if (input_axis == 1)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 2)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 3)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 0;
}
else if (input_axis == 4)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 5)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 6)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 1;
}
switch (range)
{
/* Reference LSB value of 2G */
case 0:
reference = BMA4_16BIT_ACC_FOC_2G_REF;
break;
/* Reference LSB value of 4G */
case 1:
reference = BMA4_16BIT_ACC_FOC_4G_REF;
break;
/* Reference LSB value of 8G */
case 2:
reference = BMA4_16BIT_ACC_FOC_8G_REF;
break;
/* Reference LSB value of 16G */
case 3:
reference = BMA4_16BIT_ACC_FOC_16G_REF;
break;
default:
break;
}
if (g_value_foc.x == 1)
{
matched_axis = 'X';
}
else if (g_value_foc.y == 1)
{
matched_axis = 'Y';
}
else if (g_value_foc.z == 1)
{
matched_axis = 'Z';
}
if (g_value_foc.sign == 1)
{
printf("MATCHED AXIS is = -%c\n", matched_axis);
}
else
{
printf("MATCHED AXIS is = %c\n", matched_axis);
}
printf("\n\n# Before FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
printf("\n\n######### Perform Accel FOC #########\n\n");
/* Perform accelerometer FOC */
rslt = bma4_perform_accel_foc(&g_value_foc, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
/* Delay after performing Accel FOC */
dev->delay_us(30000, dev->intf_ptr);
printf("\n\n# After FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accelerometer.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,162 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_an.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Earth's gravity in m/s^2 */
#define GRAVITY_EARTH (9.80665f)
/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*
* @param[in] val : Raw sensor value.
* @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G).
* @param[in] bit_width : Resolution of the sensor.
*
* @return Accel values in meters per second square.
*
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store accel data ready interrupt status */
uint16_t int_status = 0;
/* Variable that holds the accelerometer sample count */
uint8_t n_data = 1;
struct bma4_accel sens_data = { 0 };
float x = 0, y = 0, z = 0;
struct bma4_accel_config accel_conf = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_an_init(&bma);
bma4_error_codes_print_result("bma456_an_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_an_write_config_file(&bma);
bma4_error_codes_print_result("bma456_an_write_config status", rslt);
/* Accelerometer configuration settings */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(1, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt);
printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
/* Read the accel x, y, z data */
rslt = bma4_read_accel_xyz(&sens_data, &bma);
bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt);
if (rslt == BMA4_OK)
{
/* Converting lsb to meter per second squared for 16 bit resolution at 2G range */
x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution);
y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution);
z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution);
/* Print the data in m/s2 */
printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z);
}
/* Increment the count that determines the number of samples to be printed */
n_data++;
/* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */
if (n_data > ACCEL_SAMPLE_COUNT)
{
break;
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width)
{
double power = 2;
float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f));
return (GRAVITY_EARTH * val * g_range) / half_scale;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= any_motion.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,133 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_an.h"
#include "common.h"
#include "coines.h"
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used to get any-motion configurations.
*
* @param[in] bma : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store any/no-motion interrupt status */
uint16_t int_status = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_an_init(&bma);
bma4_error_codes_print_result("bma456_an_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_an_write_config_file(&bma);
bma4_error_codes_print_result("bma456_an_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Map the interrupt 1 for any-motion */
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA456_AN_ANY_MOT_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt);
/* Get any-motion configurations */
rslt = get_any_no_mot_config(&bma);
bma4_error_codes_print_result("get_any_no_mot_config status", rslt);
printf("Shake the board for any-motion interrupt\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
if (rslt == BMA4_OK)
{
/* Enters only if the obtained interrupt is any-motion */
if (int_status & BMA456_AN_ANY_MOT_INT)
{
printf("Any-motion interrupt occurred\n");
break;
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API is used to get any-motion configurations.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma)
{
/* Variable to store the status of API */
int8_t rslt;
/*! Structure to define any/no-motion configurations */
struct bma456_an_any_no_mot_config any_no_mot = { 0 };
/* Getting any-motion configuration to get default configuration */
rslt = bma456_an_get_any_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_an_get_any_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/*
* Set the slope threshold:
* Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG)
*/
any_no_mot.threshold = 10;
/*
* Set the duration for any-motion interrupt:
* Duration defines the number of consecutive data points for which threshold condition must be true(1
* bit =
* 20ms)
*/
any_no_mot.duration = 4;
/* Enabling X, Y, and Z axis for Any-motion feature */
any_no_mot.axes_en = BMA456_AN_EN_ALL_AXIS;
/* Like threshold and duration, we can also change the config of int_bhvr and slope */
/* Set the threshold and duration configuration */
rslt = bma456_an_set_any_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_an_set_any_mot_config status", rslt);
}
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE = axis_remap.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,362 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include <stdlib.h>
#include "coines.h"
#include "bma456_an.h"
#include "common.h"
/*********************************************************************/
/* functions */
/*********************************************************************/
/*!
* @brief Main Function where the execution getting started to test the code.
*
* @param[in] argc
* @param[in] argv
*
* @return status
*
*/
int main(void)
{
int8_t rslt;
struct bma4_dev bma4;
struct bma4_remap remap_data = { 0 };
struct bma4_accel accel = { 0 };
struct bma4_accel_config accel_conf = { 0 };
uint16_t int_status = 0;
char data_array[13][11] =
{ { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" },
{ "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma4, BMA4_SPI_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_an_init(&bma4);
bma4_error_codes_print_result("bma456_an_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_an_write_config_file(&bma4);
bma4_error_codes_print_result("bma456_an_write_config", rslt);
/* Accelerometer configuration Setting */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma4);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(1, &bma4);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4);
bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt);
printf("\nAXIS_REMAP_FUNC_TEST 1\n");
printf("Get sensor data of re-mapped axes\n");
rslt = bma456_an_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt);
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
printf("Expected Re-mapped x value = BMA4_X\n");
printf("Expected Re-mapped y value = BMA4_Y\n");
printf("Expected Re-mapped z value = BMA4_Z\n");
if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 2\n");
printf("Get sensor data of re-mapped axes\n");
remap_data.x = BMA4_NEG_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_NEG_X;
rslt = bma456_an_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_an_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_NEG_X\n");
if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 3\n");
printf("Get sensor data of re-mapped axes - 2nd combination\n");
remap_data.x = BMA4_NEG_Z;
remap_data.y = BMA4_NEG_X;
remap_data.z = BMA4_Y;
rslt = bma456_an_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_an_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Z\n");
printf("Expected Re-mapped y value = BMA4_NEG_X\n");
printf("Expected Re-mapped z value = BMA4_Y\n");
if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 4\n");
printf("Get sensor data of re-mapped axes - 3rd combination\n");
remap_data.x = BMA4_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_X;
rslt = bma456_an_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_an_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_X\n");
if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 5\n");
printf("Get sensor data of re-mapped axes - 4th combination\n");
remap_data.x = BMA4_NEG_X;
remap_data.y = BMA4_NEG_Y;
remap_data.z = BMA4_NEG_Z;
rslt = bma456_an_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456_an_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456_an_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_X\n");
printf("Expected Re-mapped y value = BMA4_NEG_Y\n");
printf("Expected Re-mapped z value = BMA4_NEG_Z\n");
if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,242 @@
/**
* Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "bma4_defs.h"
#include "common.h"
/******************************************************************************/
/*! Macro definitions */
/*! Read write length varies based on user requirement */
#define BMA4_READ_WRITE_LEN UINT8_C(46)
/******************************************************************************/
/*! Static variable definition */
/*! Variable that holds the I2C device address or SPI chip selection */
static uint8_t dev_addr;
/******************************************************************************/
/*! User interface functions */
/*!
* I2C read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* I2C write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* SPI read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* SPI write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* Delay function map to COINES platform
*/
void bma4_delay_us(uint32_t period, void *intf_ptr)
{
(void) intf_ptr;
coines_delay_usec(period);
}
/*!
* @brief Function to select the interface between SPI and I2C.
* Also to initialize coines platform
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant)
{
int8_t rslt = BMA4_OK;
if (bma != NULL)
{
int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL);
struct coines_board_info board_info;
if (result < COINES_SUCCESS)
{
printf(
"\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n"
" 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n");
exit(result);
}
result = coines_get_board_info(&board_info);
#if defined(PC)
setbuf(stdout, NULL);
#endif
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_usec(10000);
/* Bus configuration : I2C */
if (intf == BMA4_I2C_INTF)
{
printf("I2C Interface \n");
/* To initialize the user I2C function */
dev_addr = BMA4_I2C_ADDR_PRIMARY;
bma->intf = BMA4_I2C_INTF;
bma->bus_read = bma4_i2c_read;
bma->bus_write = bma4_i2c_write;
/* SDO to Ground */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
/* Make CSB pin HIGH */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH);
coines_delay_msec(100);
/* SDO pin is made low */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
(void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
}
/* Bus configuration : SPI */
else if (intf == BMA4_SPI_INTF)
{
printf("SPI Interface \n");
/* To initialize the user SPI function */
dev_addr = COINES_SHUTTLE_PIN_7;
bma->intf = BMA4_SPI_INTF;
bma->bus_read = bma4_spi_read;
bma->bus_write = bma4_spi_write;
(void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
}
/* Assign variant information */
bma->variant = variant;
/* Assign device address to interface pointer */
bma->intf_ptr = &dev_addr;
/* Configure delay in microseconds */
bma->delay_us = bma4_delay_us;
/* Configure max read/write length (in bytes) ( Supported length depends on target machine) */
bma->read_write_len = BMA4_READ_WRITE_LEN;
/* Set Performance mode status */
bma->perf_mode_status = BMA4_DISABLE;
coines_delay_msec(100);
(void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
coines_delay_msec(200);
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief Prints the execution status of the APIs.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt)
{
if (rslt != BMA4_OK)
{
printf("%s\t", api_name);
if (rslt == BMA4_E_NULL_PTR)
{
printf("Error [%d] : Null pointer\r\n", rslt);
}
else if (rslt == BMA4_E_COM_FAIL)
{
printf("Error [%d] : Communication failure\r\n", rslt);
}
else if (rslt == BMA4_E_CONFIG_STREAM_ERROR)
{
printf("Error [%d] : Invalid configuration stream\r\n", rslt);
}
else if (rslt == BMA4_E_SELF_TEST_FAIL)
{
printf("Error [%d] : Self test failed\r\n", rslt);
}
else if (rslt == BMA4_E_INVALID_SENSOR)
{
printf("Error [%d] : Device not found\r\n", rslt);
}
else if (rslt == BMA4_E_OUT_OF_RANGE)
{
printf("Error [%d] : Out of Range\r\n", rslt);
}
else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF)
{
printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt);
}
else
{
/* For more error codes refer "*_defs.h" */
printf("Error [%d] : Unknown error code\r\n", rslt);
}
}
}
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void)
{
(void)fflush(stdout);
coines_delay_msec(200);
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_msec(1000);
/* Coines interface reset */
coines_soft_reset();
coines_delay_msec(1000);
(void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL);
}
@@ -0,0 +1,127 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#ifndef COMMON_H
#define COMMON_H
/*! CPP guard */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include "bma4.h"
#include "coines.h"
/*!
* @brief Function for reading the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose value is to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for reading the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose data has to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the
* APIs.
*
* @param[in] period_us : The required wait time in microsecond.
* @param[in] intf_ptr : Interface pointer
*
* @return void.
*
*/
void bma4_delay_us(uint32_t period, void *intf_ptr);
/*!
* @brief Function to select the interface between SPI and I2C.
*
* @param[in] bma : Structure instance of bma4_dev
* @param[in] intf : Interface selection parameter
* @param[in] variant : Variant information of the sensor
* ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT )
* ( BMA45x variants values - BMA45X_VARIANT )
*
* @return Status of execution
* @retval 0 -> Success
* @retval < 0 -> Failure Info
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant);
/*!
* @brief Prints the execution status of the APIs.
*
* @param[in] api_name : Name of the API whose execution status has to be printed.
* @param[in] rslt : Error code returned by the API whose execution status has to be printed.
*
* @return void.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt);
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void);
#ifdef __cplusplus
}
#endif /* End of CPP guard */
#endif /* COMMON_H */
@@ -0,0 +1,20 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_full_header_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
TARGET=MCU_APP30
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,173 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_an.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1.
* fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames
*
* Extra frames to parse sensortime data
*/
#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(170)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */
struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_AN */
rslt = bma456_an_init(&dev);
bma4_error_codes_print_result("bma456_an_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(1, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE;
printf("FIFO is configured in header mode\n");
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
while (loop <= 10)
{
rslt = bma456_an_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
/* Print control frames like sensor time and skipped frame count */
printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count);
printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION));
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_full_headerless_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,171 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_an.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_buffer = 1024, accel_frame_len = 6.
* fifo_accel_frame_count = (1024 / 6) = 170 frames
*/
#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(170)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */
struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_AN */
rslt = bma456_an_init(&dev);
bma4_error_codes_print_result("bma456_an_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(1, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH;
/* To enable headerless mode, disable the header. */
rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config status", rslt);
printf("FIFO is configured in headerless mode\n");
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
while (loop <= 10)
{
rslt = bma456_an_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,20 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_watermark_header_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
TARGET=MCU_APP30
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,188 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_an.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Setting a watermark level in FIFO */
#define BMA456_AN_FIFO_WATERMARK_LEVEL UINT16_C(650)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1.
* fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames
* NOTE: Extra frames are read in order to get sensor time
*/
#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(100)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */
struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
uint16_t watermark = 0;
/* To set the watermark level in FIFO */
uint16_t wm_lvl;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_AN */
rslt = bma456_an_init(&dev);
bma4_error_codes_print_result("bma456_an_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(1, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE;
printf("FIFO is configured in header mode\n");
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
wm_lvl = BMA456_AN_FIFO_WATERMARK_LEVEL;
rslt = bma4_set_fifo_wm(wm_lvl, &dev);
bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt);
while (loop <= 10)
{
rslt = bma456_an_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_wm(&watermark, &dev);
bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt);
printf("FIFO watermark level : %d\n", watermark);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
/* Print control frames like sensor time and skipped frame count */
printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count);
printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION));
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,188 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_an.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456_AN_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Setting a watermark level in FIFO */
#define BMA456_AN_FIFO_WATERMARK_LEVEL UINT16_C(600)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_watermark_level = 600, accel_frame_len = 6.
* fifo_accel_frame_count = (600 / 6) = 100 frames
*/
#define BMA456_AN_FIFO_ACCEL_FRAME_COUNT UINT8_C(100)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456_AN_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */
struct bma4_accel fifo_accel_data[BMA456_AN_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
uint16_t watermark = 0;
/* To set the watermark level in FIFO */
uint16_t wm_lvl;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456_AN */
rslt = bma456_an_init(&dev);
bma4_error_codes_print_result("bma456_an_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(1, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456_AN_FIFO_RAW_DATA_USER_LENGTH;
/* To enable headerless mode, disable the header. */
rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config status", rslt);
printf("FIFO is configured in headerless mode\n");
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
wm_lvl = BMA456_AN_FIFO_WATERMARK_LEVEL;
rslt = bma4_set_fifo_wm(wm_lvl, &dev);
bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt);
while (loop <= 10)
{
rslt = bma456_an_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_wm(&watermark, &dev);
bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt);
printf("FIFO watermark level : %d\n", watermark);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456_AN_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= no_motion.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456_an.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,131 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456_an.h"
#include "common.h"
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used to get no-motion configurations.
*
* @param[in] bma : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store any/no-motion interrupt status */
uint16_t int_status = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456_an_init(&bma);
bma4_error_codes_print_result("bma456_an_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456_an_write_config_file(&bma);
bma4_error_codes_print_result("bma456_an_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Map the interrupt 1 for no-motion */
rslt = bma456_an_map_interrupt(BMA4_INTR1_MAP, BMA456_AN_NO_MOT_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456_an_map_interrupt status", rslt);
/* Get no-motion configurations */
rslt = get_any_no_mot_config(&bma);
bma4_error_codes_print_result("get_any_no_mot_config status", rslt);
printf("Do not shake the board for no-motion interrupt\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456_an_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456_an_read_int_status", rslt);
if (rslt == BMA4_OK)
{
/* Enters only if the obtained interrupt is no-motion */
if (int_status & BMA456_AN_NO_MOT_INT)
{
printf("No-motion interrupt occurred\n");
break;
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API is used to get any/no-motion configurations.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma)
{
/* Variable to store the status of API */
int8_t rslt;
/* Structure to define any/no-motion configurations */
struct bma456_an_any_no_mot_config any_no_mot = { 0 };
/* Getting no-motion configuration to get default configuration */
rslt = bma456_an_get_no_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_an_get_no_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/*
* Set the slope threshold:
* Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG)
*/
any_no_mot.threshold = 10;
/*
* Set the duration for no-motion interrupt:
* Duration defines the number of consecutive data points for which threshold condition must be
* true(1 bit = 20ms)
*/
any_no_mot.duration = 4;
/* Enabling X, Y, and Z axis for no-motion feature */
any_no_mot.axes_en = BMA456_AN_EN_ALL_AXIS;
/* Like threshold and duration, we can also change the config of int_bhvr */
/* Set the threshold and duration configuration */
rslt = bma456_an_set_no_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456_an_set_no_mot_config status", rslt);
}
return rslt;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accel_foc.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,741 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
/******************************************************************************/
/*! Header Files */
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "bma456h.h"
#include "common.h"
#include "coines.h"
/******************************************************************************/
/*! Macro Definitions */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Global Variable Declaration */
/* Structure to store temporary axes data values */
struct temp_axes_val
{
/* X data */
int32_t x;
/* Y data */
int32_t y;
/* Z data */
int32_t z;
};
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used perform accel foc and determine limits based on range
*
* @param[in] range : Range of Accel
* @param[in] input_axis : Axis selected for Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev);
/*!
* @brief This internal API is to determine if average accel FOC data is within limits
*
* @param[in] avg_accel_foc_data : Average Accel FOC value
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] foc_sign : Input sign of performed Accel FOC
* @param[in] min_val : Minimum acceptable LSB limit
* @param[in] max_val : Maximum acceptable LSB limit
*
* @return Status of execution.
*/
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val);
/*!
* @brief This internal API is to collect and verify accel sensor data
*
* @param[in] range : Value of Accel range
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] matched_axis : Input Axis to perform Accel FOC
* @param[in] foc_sign : Input sign to perform Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev);
/*!
* @brief This internal API is to calculate noise level for Accel FOC data
*
* @param[in] matched_axis : Input Axis to perform accel FOC
* @param[in] accel_foc_data : Array of Accel FOC data
* @param[in] avg_accel_foc_data : Average Accel FOC data
*
* @return Status of execution.
*/
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Sensor initialization configuration. */
struct bma4_dev dev;
uint8_t try = 0, j;
int8_t rslt;
struct bma4_accel_config accel_conf = { 0 };
uint8_t data = 0, range, input_axis = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
printf("Functional test for accel foc start..\n\n");
printf("Choose the axis for accel FOC to be done\n");
printf("Press '1' to choose X axis\n");
printf("Press '2' to choose Y axis\n");
printf("Press '3' to choose Z axis\n");
printf("Press '4' to choose -X axis\n");
printf("Press '5' to choose -Y axis\n");
printf("Press '6' to choose -Z axis\n");
for (;;)
{
scanf("%u", (unsigned int *)&input_axis);
if (input_axis > 0 && input_axis < 7)
{
break;
}
}
if (input_axis == 1)
{
printf("The choosen input axis for FOC is : X\n");
}
else if (input_axis == 2)
{
printf("The choosen input axis for FOC is : Y\n");
}
else if (input_axis == 3)
{
printf("The choosen input axis for FOC is : Z\n");
}
else if (input_axis == 4)
{
printf("The choosen input axis for FOC is : -X\n");
}
else if (input_axis == 5)
{
printf("The choosen input axis for FOC is : -Y\n");
}
else if (input_axis == 6)
{
printf("The choosen input axis for FOC is : -Z\n");
}
printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n");
for (j = 0; j < 2; j++)
{
try = 0;
if (j == 1)
{
printf("Keep sensor in wrong position and press 5\n");
}
else if (j == 0)
{
printf("Keep sensor in right position and press 5\n");
}
for (;;)
{
scanf("%hu", (short unsigned int *)&try);
if (try == 5)
{
break;
}
}
for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++)
{
/****************************************************************/
/* Initialize by enabling configuration load */
printf("#########################################################\n\n");
rslt = bma456h_init(&dev);
bma4_error_codes_print_result("bma4_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&dev);
bma4_error_codes_print_result("bma4_write_config", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Accelerometer Configuration Settings */
/* Output Data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = range;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* Delay to set accel sensor configurations (20ms for 50HZ) */
dev.delay_us(20000, dev.intf_ptr);
/* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth);
/* Perform FOC for different ranges */
rslt = perform_foc_range_test(range, input_axis, &dev);
if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_OK))
{
printf("\n######### Valid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_OK))
{
printf("\n######### Invalid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
}
/* Disable offset compensation */
rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_read_regs", rslt);
data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET);
rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_write_regs", rslt);
}
bma4_coines_deinit();
return rslt;
}
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val)
{
int8_t rslt = BMA4_OK;
int16_t diff_after = 0;
if (foc_sign == 0)
{
if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val)))
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
if (foc_sign == 1)
{
if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val)))
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
return rslt;
}
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data)
{
int32_t variance = 0;
double noise_level;
uint16_t idx = 0;
if (matched_axis == 'X')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x));
}
}
else if (matched_axis == 'Y')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y));
}
}
else if (matched_axis == 'Z')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z));
}
}
noise_level = sqrt((double)variance);
printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level);
}
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev)
{
int8_t rslt = BMA4_E_INVALID_STATUS;
uint8_t i;
uint16_t reg_status = 0;
int16_t xl, yl, zl;
int16_t xh, yh, zh;
int16_t min_val = 0;
int16_t max_val = 0;
struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } };
struct temp_axes_val temp_foc_data = { 0 };
struct bma4_accel avg_accel_foc_data = { 0 };
struct bma4_accel sensor_data = { 0 };
/* Setting initial values */
xl = yl = zl = 32767;
xh = yh = zh = -32768;
/* Read accelerometer values before/after FOC */
for (i = 0; i < ACCEL_SAMPLE_COUNT; i++)
{
for (;;)
{
/* To get the data ready interrupt status */
rslt = bma4_read_int_status(&reg_status, dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
/* Read accelerometer data based on data ready interrupt */
if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&sensor_data, dev);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel));
printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n",
i,
accel_foc_data[i].x,
i,
accel_foc_data[i].y,
i,
accel_foc_data[i].z);
if (xl > accel_foc_data[i].x)
{
xl = accel_foc_data[i].x;
}
if (xh < accel_foc_data[i].x)
{
xh = accel_foc_data[i].x;
}
if (yl > accel_foc_data[i].y)
{
yl = accel_foc_data[i].y;
}
if (yh < accel_foc_data[i].y)
{
yh = accel_foc_data[i].y;
}
if (zl > accel_foc_data[i].z)
{
zl = accel_foc_data[i].z;
}
if (zh < accel_foc_data[i].z)
{
zh = accel_foc_data[i].z;
}
temp_foc_data.x += accel_foc_data[i].x;
temp_foc_data.y += accel_foc_data[i].y;
temp_foc_data.z += accel_foc_data[i].z;
break;
}
}
}
/* Taking average values to calculate percentage deviation */
avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT);
printf("********* MIN & MAX VALUES ********\n");
printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl);
printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh);
printf("***** AVERAGE AFTER FOC *****\n");
printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n",
avg_accel_foc_data.x,
avg_accel_foc_data.y,
avg_accel_foc_data.z);
/* Calculate noise level */
calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data);
/* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 16-bit resolution) */
if (range == 0)
{
/* Min and Max limits for Range 2G */
min_val = BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT;
}
else if (range == 1)
{
/* Min and Max limits for Range 4G */
min_val = BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT;
}
else if (range == 2)
{
/* Min and Max limits for Range 8G */
min_val = BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT;
}
else if (range == 3)
{
/* Min and Max limits for Range 16G */
min_val = BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT;
}
if ((matched_axis == 'X') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Y') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Z') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'X') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.x,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Y') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.y,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Z') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.z,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
return rslt;
}
/* Perform FOC for different range and resolutions */
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev)
{
int8_t rslt;
int8_t matched_axis = 0;
int16_t reference = 0;
/* Set accel foc axis and it's sign (x, y, z, sign)*/
struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 };
if (input_axis == 1)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 2)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 3)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 0;
}
else if (input_axis == 4)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 5)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 6)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 1;
}
switch (range)
{
/* Reference LSB value of 2G */
case 0:
reference = BMA4_16BIT_ACC_FOC_2G_REF;
break;
/* Reference LSB value of 4G */
case 1:
reference = BMA4_16BIT_ACC_FOC_4G_REF;
break;
/* Reference LSB value of 8G */
case 2:
reference = BMA4_16BIT_ACC_FOC_8G_REF;
break;
/* Reference LSB value of 16G */
case 3:
reference = BMA4_16BIT_ACC_FOC_16G_REF;
break;
default:
break;
}
if (g_value_foc.x == 1)
{
matched_axis = 'X';
}
else if (g_value_foc.y == 1)
{
matched_axis = 'Y';
}
else if (g_value_foc.z == 1)
{
matched_axis = 'Z';
}
if (g_value_foc.sign == 1)
{
printf("MATCHED AXIS is = -%c\n", matched_axis);
}
else
{
printf("MATCHED AXIS is = %c\n", matched_axis);
}
printf("\n\n# Before FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
printf("\n\n######### Perform Accel FOC #########\n\n");
/* Perform accelerometer FOC */
rslt = bma4_perform_accel_foc(&g_value_foc, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
/* Delay after performing Accel FOC */
dev->delay_us(30000, dev->intf_ptr);
printf("\n\n# After FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accelerometer.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,162 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Earth's gravity in m/s^2 */
#define GRAVITY_EARTH (9.80665f)
/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Static Function Declaration */
/*! @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*
* @param[in] val : Raw sensor value.
* @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G).
* @param[in] bit_width : Resolution of the sensor.
*
* @return Accel values in meters per second square.
*
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store accel data ready interrupt status */
uint16_t int_status = 0;
/* Variable that holds the accelerometer sample count */
uint8_t n_data = 1;
struct bma4_accel sens_data = { 0 };
float x = 0, y = 0, z = 0;
struct bma4_accel_config accel_conf = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&bma);
bma4_error_codes_print_result("bma456h_write_config status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
/* Accelerometer configuration settings */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
/* Read the accel x, y, z data */
rslt = bma4_read_accel_xyz(&sens_data, &bma);
bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt);
if (rslt == BMA4_OK)
{
/* Converting lsb to meter per second squared for 16 bit resolution at 2G range */
x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution);
y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution);
z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution);
/* Print the data in m/s2 */
printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z);
}
/* Increment the count that determines the number of samples to be printed */
n_data++;
/* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */
if (n_data > ACCEL_SAMPLE_COUNT)
{
break;
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width)
{
double power = 2;
float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f));
return (GRAVITY_EARTH * val * g_range) / half_scale;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= auto_low_power.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,146 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store auto low power state */
uint8_t auto_low_power_state = 0;
struct bma4_accel_config accel_conf = { 0 };
struct bma456h_auto_low_power auto_low_power = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&bma);
bma4_error_codes_print_result("bma456h_write_config status", rslt);
/* Get the accel configurations */
rslt = bma4_get_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_get_accel_config status", rslt);
if (rslt == BMA4_OK)
{
/* Accelerometer configuration settings */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Enable auto low power state through no-motion interrupt */
auto_low_power.no_motion = 0;
/* Enable auto low power state through time-out duration */
auto_low_power.time_out = 1;
/* Time-out duration is (value * resolution) eg: (10 * 20ms) */
auto_low_power.time_out_dur = 10;
/* These bits used to set odr at auto low power mode. default
* value is '0'(i.e) 25/16 HZ */
auto_low_power.lp_odr = 0;
/* Set this bit to set default odr of titan core in auto low power mode */
auto_low_power.pwr_mgt = 1;
/* Configure Auto low power settings */
rslt = bma456h_set_auto_low_power_config(&auto_low_power, &bma);
bma4_error_codes_print_result("bma456h_set_auto_low_power_config status", rslt);
if (rslt == BMA4_OK)
{
/* Get output of auto low power state */
rslt = bma456h_get_auto_low_power_state(&auto_low_power_state, &bma);
bma4_error_codes_print_result("bma456h_get_auto_low_power_state status", rslt);
}
}
}
if (rslt == BMA4_OK)
{
/* Enable auto low power feature */
rslt = bma456h_feature_enable(BMA456H_AUTO_LOW_POWER_EN, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_feature_enable status", rslt);
}
if (rslt == BMA4_OK)
{
/* Read and check the ODR change after changing the auto low power settings */
rslt = bma4_get_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_get_accel_config status", rslt);
if (rslt == BMA4_OK)
{
printf("ODR : %X\n", accel_conf.odr);
if (auto_low_power_state)
{
printf("Auto low power state : Disabled(Auto wake state)");
}
else
{
printf("Auto low power state : Enabled(Auto sleep state)");
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE = axis_remap.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,362 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include <stdlib.h>
#include "coines.h"
#include "bma456h.h"
#include "common.h"
/*********************************************************************/
/* functions */
/*********************************************************************/
/*!
* @brief Main Function where the execution getting started to test the code.
*
* @param[in] argc
* @param[in] argv
*
* @return status
*
*/
int main(void)
{
int8_t rslt;
struct bma4_dev bma4;
uint16_t int_status = 0;
struct bma4_remap remap_data = { 0 };
struct bma4_accel accel = { 0 };
struct bma4_accel_config accel_conf = { 0 };
char data_array[13][11] =
{ { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" },
{ "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma4, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma4);
bma4_error_codes_print_result("bma456h_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&bma4);
bma4_error_codes_print_result("bma456h_write_config", rslt);
/* Accelerometer configuration Setting */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma4);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma4);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
printf("\nAXIS_REMAP_FUNC_TEST 1\n");
printf("Get sensor data of re-mapped axes\n");
rslt = bma456h_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_get_remap_axes", rslt);
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
printf("Expected Re-mapped x value = BMA4_X\n");
printf("Expected Re-mapped y value = BMA4_Y\n");
printf("Expected Re-mapped z value = BMA4_Z\n");
if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 2\n");
printf("Get sensor data of re-mapped axes\n");
remap_data.x = BMA4_NEG_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_NEG_X;
rslt = bma456h_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456h_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_NEG_X\n");
if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 3\n");
printf("Get sensor data of re-mapped axes - 2nd combination\n");
remap_data.x = BMA4_NEG_Z;
remap_data.y = BMA4_NEG_X;
remap_data.z = BMA4_Y;
rslt = bma456h_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456h_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Z\n");
printf("Expected Re-mapped y value = BMA4_NEG_X\n");
printf("Expected Re-mapped z value = BMA4_Y\n");
if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 4\n");
printf("Get sensor data of re-mapped axes - 3rd combination\n");
remap_data.x = BMA4_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_X;
rslt = bma456h_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456h_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_X\n");
if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 5\n");
printf("Get sensor data of re-mapped axes - 4th combination\n");
remap_data.x = BMA4_NEG_X;
remap_data.y = BMA4_NEG_Y;
remap_data.z = BMA4_NEG_Z;
rslt = bma456h_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456h_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456h_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_X\n");
printf("Expected Re-mapped y value = BMA4_NEG_Y\n");
printf("Expected Re-mapped z value = BMA4_NEG_Z\n");
if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,242 @@
/**
* Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "bma4_defs.h"
#include "common.h"
/******************************************************************************/
/*! Macro definitions */
/*! Read write length varies based on user requirement */
#define BMA4_READ_WRITE_LEN UINT8_C(46)
/******************************************************************************/
/*! Static variable definition */
/*! Variable that holds the I2C device address or SPI chip selection */
static uint8_t dev_addr;
/******************************************************************************/
/*! User interface functions */
/*!
* I2C read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* I2C write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* SPI read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* SPI write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* Delay function map to COINES platform
*/
void bma4_delay_us(uint32_t period, void *intf_ptr)
{
(void) intf_ptr;
coines_delay_usec(period);
}
/*!
* @brief Function to select the interface between SPI and I2C.
* Also to initialize coines platform
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant)
{
int8_t rslt = BMA4_OK;
if (bma != NULL)
{
int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL);
struct coines_board_info board_info;
if (result < COINES_SUCCESS)
{
printf(
"\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n"
" 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n");
exit(result);
}
result = coines_get_board_info(&board_info);
#if defined(PC)
setbuf(stdout, NULL);
#endif
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_usec(10000);
/* Bus configuration : I2C */
if (intf == BMA4_I2C_INTF)
{
printf("I2C Interface \n");
/* To initialize the user I2C function */
dev_addr = BMA4_I2C_ADDR_PRIMARY;
bma->intf = BMA4_I2C_INTF;
bma->bus_read = bma4_i2c_read;
bma->bus_write = bma4_i2c_write;
/* SDO to Ground */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
/* Make CSB pin HIGH */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH);
coines_delay_msec(100);
/* SDO pin is made low */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
(void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
}
/* Bus configuration : SPI */
else if (intf == BMA4_SPI_INTF)
{
printf("SPI Interface \n");
/* To initialize the user SPI function */
dev_addr = COINES_SHUTTLE_PIN_7;
bma->intf = BMA4_SPI_INTF;
bma->bus_read = bma4_spi_read;
bma->bus_write = bma4_spi_write;
(void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
}
/* Assign variant information */
bma->variant = variant;
/* Assign device address to interface pointer */
bma->intf_ptr = &dev_addr;
/* Configure delay in microseconds */
bma->delay_us = bma4_delay_us;
/* Configure max read/write length (in bytes) ( Supported length depends on target machine) */
bma->read_write_len = BMA4_READ_WRITE_LEN;
/* Set Performance mode status */
bma->perf_mode_status = BMA4_DISABLE;
coines_delay_msec(100);
(void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
coines_delay_msec(200);
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief Prints the execution status of the APIs.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt)
{
if (rslt != BMA4_OK)
{
printf("%s\t", api_name);
if (rslt == BMA4_E_NULL_PTR)
{
printf("Error [%d] : Null pointer\r\n", rslt);
}
else if (rslt == BMA4_E_COM_FAIL)
{
printf("Error [%d] : Communication failure\r\n", rslt);
}
else if (rslt == BMA4_E_CONFIG_STREAM_ERROR)
{
printf("Error [%d] : Invalid configuration stream\r\n", rslt);
}
else if (rslt == BMA4_E_SELF_TEST_FAIL)
{
printf("Error [%d] : Self test failed\r\n", rslt);
}
else if (rslt == BMA4_E_INVALID_SENSOR)
{
printf("Error [%d] : Device not found\r\n", rslt);
}
else if (rslt == BMA4_E_OUT_OF_RANGE)
{
printf("Error [%d] : Out of Range\r\n", rslt);
}
else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF)
{
printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt);
}
else
{
/* For more error codes refer "*_defs.h" */
printf("Error [%d] : Unknown error code\r\n", rslt);
}
}
}
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void)
{
(void)fflush(stdout);
coines_delay_msec(200);
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_msec(1000);
/* Coines interface reset */
coines_soft_reset();
coines_delay_msec(1000);
(void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL);
}
@@ -0,0 +1,127 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#ifndef COMMON_H
#define COMMON_H
/*! CPP guard */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include "bma4.h"
#include "coines.h"
/*!
* @brief Function for reading the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose value is to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for reading the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose data has to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the
* APIs.
*
* @param[in] period_us : The required wait time in microsecond.
* @param[in] intf_ptr : Interface pointer
*
* @return void.
*
*/
void bma4_delay_us(uint32_t period, void *intf_ptr);
/*!
* @brief Function to select the interface between SPI and I2C.
*
* @param[in] bma : Structure instance of bma4_dev
* @param[in] intf : Interface selection parameter
* @param[in] variant : Variant information of the sensor
* ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT )
* ( BMA45x variants values - BMA45X_VARIANT )
*
* @return Status of execution
* @retval 0 -> Success
* @retval < 0 -> Failure Info
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant);
/*!
* @brief Prints the execution status of the APIs.
*
* @param[in] api_name : Name of the API whose execution status has to be printed.
* @param[in] rslt : Error code returned by the API whose execution status has to be printed.
*
* @return void.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt);
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void);
#ifdef __cplusplus
}
#endif /* End of CPP guard */
#endif /* COMMON_H */
@@ -0,0 +1,20 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_full_header_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
TARGET=MCU_APP30
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,173 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_buffer = 1024, accel_frame_len = 6, header_byte = 1.
* fifo_accel_frame_count = (1024 / (6 + 1)) = 147 frames
*
* Extra frames to parse sensortime data
*/
#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(170)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 147 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 1029 bytes */
struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456H */
rslt = bma456h_init(&dev);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE;
printf("FIFO is configured in header mode\n");
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
while (loop <= 10)
{
rslt = bma456h_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
/* Print control frames like sensor time and skipped frame count */
printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count);
printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION));
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_full_headerless_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,171 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_buffer = 1024, accel_frame_len = 6.
* fifo_accel_frame_count = (1024 / 6) = 170 frames
*/
#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(170)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 170 * (6 axes bytes(+/- x,y,z)) = 1020 bytes */
struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456H */
rslt = bma456h_init(&dev);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH;
/* To enable headerless mode, disable the header. */
rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config status", rslt);
printf("FIFO is configured in headerless mode\n");
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_FULL_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
while (loop <= 10)
{
rslt = bma456h_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_FULL_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,20 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_watermark_header_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
TARGET=MCU_APP30
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,188 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Setting a watermark level in FIFO */
#define BMA456H_FIFO_WATERMARK_LEVEL UINT16_C(650)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_watermark_level = 650, accel_frame_len = 6, header_byte = 1.
* fifo_accel_frame_count = (650 / (6 + 1)) = 93 frames
* NOTE: Extra frames are read in order to get sensor time
*/
#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(100)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE + BMA4_SENSORTIME_OVERHEAD_BYTE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 100 * (6 axes bytes(+/- x,y,z) + 1 header byte) = 700 bytes */
struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
uint16_t watermark = 0;
/* To set the watermark level in FIFO */
uint16_t wm_lvl;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456H */
rslt = bma456h_init(&dev);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL | BMA4_FIFO_HEADER | BMA4_FIFO_TIME, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE;
printf("FIFO is configured in header mode\n");
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
wm_lvl = BMA456H_FIFO_WATERMARK_LEVEL;
rslt = bma4_set_fifo_wm(wm_lvl, &dev);
bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt);
while (loop <= 10)
{
rslt = bma456h_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_wm(&watermark, &dev);
bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt);
printf("FIFO watermark level : %d\n", watermark);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
/* Print control frames like sensor time and skipped frame count */
printf("Skipped frame count = %d\n", fifoframe.skipped_frame_count);
printf("Sensor time(in seconds) = %.4lf s\r\n", (fifoframe.sensor_time * BMA4_SENSORTIME_RESOLUTION));
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_watermark_headerless_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,188 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Setting a watermark level in FIFO */
#define BMA456H_FIFO_WATERMARK_LEVEL UINT16_C(600)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_watermark_level = 600, accel_frame_len = 6.
* fifo_accel_frame_count = (600 / 6) = 100 frames
*/
#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(100)
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void)
{
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = { 0 };
/* Sensor initialization configuration */
struct bma4_dev dev = { 0 };
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to maintain count of loop to run FIFO read */
uint8_t loop = 1;
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */
struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = { 0 };
/* Variable that contains interrupt status value */
uint16_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
uint16_t watermark = 0;
/* To set the watermark level in FIFO */
uint16_t wm_lvl;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Initialize BMA456H */
rslt = bma456h_init(&dev);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
acc_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH;
/* To enable headerless mode, disable the header. */
rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config status", rslt);
printf("FIFO is configured in headerless mode\n");
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
wm_lvl = BMA456H_FIFO_WATERMARK_LEVEL;
rslt = bma4_set_fifo_wm(wm_lvl, &dev);
bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt);
while (loop <= 10)
{
rslt = bma456h_read_int_status(&int_status, &dev);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & BMA4_FIFO_WM_INT))
{
printf("\nIteration : %d\n", loop);
rslt = bma4_get_fifo_wm(&watermark, &dev);
bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt);
printf("FIFO watermark level : %d\n", watermark);
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK)
{
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
printf("ACCEL, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < accel_length; idx++)
{
printf("%d, %d, %d, %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
}
loop++;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= motion.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,186 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/*****************************************************************************/
/*! Global variable */
/*! Structure to define any/no-motion configurations */
struct bma456h_any_no_mot_config any_no_mot = { 0 };
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used to get any/no-motion configurations.
*
* @param[in] bma : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store any/no-motion interrupt status */
uint16_t int_status = 0;
uint8_t iteration = 20;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&bma);
bma4_error_codes_print_result("bma456h_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Map the interrupt pin 1 for any/no-motion */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, (BMA456H_ANY_MOT_INT | BMA456H_NO_MOT_INT), BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
/* Enabling X, Y, and Z axis for Any and No-motion feature */
rslt = bma456h_feature_enable((BMA456H_ANY_MOTION_ALL_AXIS_EN | BMA456H_NO_MOTION_ALL_AXIS_EN), BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_feature_enable status", rslt);
/* Get any-motion and no-motion configurations */
rslt = get_any_no_mot_config(&bma);
bma4_error_codes_print_result("get_any_no_mot_config status", rslt);
printf("Shake the board for any-motion interrupt whereas do not shake the board for no-motion interrupt\n");
if (rslt == BMA4_OK)
{
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
if (rslt == BMA4_OK)
{
/* Enters only if the obtained interrupt is any-motion */
if (int_status & BMA456H_ANY_MOT_INT)
{
printf("Any-motion interrupt occurred\n");
iteration--;
}
/* Enters only if the obtained interrupt is no-motion */
else if (int_status & BMA456H_NO_MOT_INT)
{
printf("No-motion interrupt occurred\n");
iteration--;
}
int_status = 0;
/* Break out of the loop when iteration has reached zero */
if (iteration == 0)
{
printf("Iterations are done. Exiting !");
break;
}
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API is used to get any/no-motion configurations.
*/
static int8_t get_any_no_mot_config(struct bma4_dev *bma)
{
/* Variable to store the status of API */
int8_t rslt;
/* Getting any-motion configuration to get default configuration */
rslt = bma456h_get_any_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456h_get_any_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/*
* Set the slope threshold:
* Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG)
*/
any_no_mot.threshold = 10;
/*
* Set the duration for any-motion interrupt:
* Duration defines the number of consecutive data points for which threshold condition must be true(1
* bit =
* 20ms)
*/
any_no_mot.duration = 4;
/* Like threshold and duration, we can also change the config of int_bhvr and slope */
/* Set the threshold and duration configuration */
rslt = bma456h_set_any_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456h_set_any_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/* Getting no-motion configuration to get default configuration */
rslt = bma456h_get_no_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456h_get_no_mot_config status", rslt);
if (rslt == BMA4_OK)
{
/*
* Set the slope threshold:
* Interrupt will be generated if the slope of all the axis exceeds the threshold (1 bit = 0.48mG)
*/
any_no_mot.threshold = 10;
/*
* Set the duration for no-motion interrupt:
* Duration defines the number of consecutive data points for which threshold condition must be
* true(1 bit = 20ms)
*/
any_no_mot.duration = 4;
/* Like threshold and duration, we can also change the config of int_bhvr */
/* Set the threshold and duration configuration */
rslt = bma456h_set_no_mot_config(&any_no_mot, bma);
bma4_error_codes_print_result("bma456h_set_no_mot_config status", rslt);
}
}
}
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= selftest.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,47 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store result of self-test */
int8_t selftest_rslt = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
printf("Perform accel self-test\n");
rslt = bma4_perform_accel_selftest(&selftest_rslt, &bma);
bma4_error_codes_print_result("bma4_perform_accel_selftest", rslt);
printf("Self-test result is %d\n", selftest_rslt);
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= step_activity.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,116 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to hold iteration value */
uint8_t loop = 1;
/* Variable to store step activity interrupt status */
uint16_t int_status = 0;
struct bma456h_out_state activity_output = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Upload the configuration file to enable the features of the sensor */
rslt = bma456h_write_config_file(&bma);
bma4_error_codes_print_result("bma456h_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Enabling step activity feature */
rslt = bma456h_feature_enable(BMA456H_STEP_ACTIVITY_EN, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_feature_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Map the interrupt pin 1 for step counter */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_ACTIVITY_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
}
if (rslt == BMA4_OK)
{
printf("Move the board in steps to perform step activity\n");
while (loop <= 5)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
/* Filtering only the activity interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA456H_ACTIVITY_INT))
{
printf("\nIteration : %d\n", loop);
/* Get step activity output */
rslt = bma456h_output_state(&activity_output, &bma);
if (rslt == BMA4_OK)
{
printf("The Activity output is %d\n", activity_output.activity_type);
switch (activity_output.activity_type)
{
case BMA456H_USER_STATIONARY:
printf("User state is stationary\n");
break;
case BMA456H_USER_WALKING:
printf("User state is walking\n");
break;
case BMA456H_USER_RUNNING:
printf("User state is running\n");
break;
case BMA456H_UNKNOWN_ACTVTY:
printf("User state is invalid state\n");
break;
default:
break;
}
loop++;
}
}
int_status = 0;
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= step_counter.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,103 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store step counter interrupt status */
uint16_t int_status = 0;
/* Variable to store step counter output */
uint32_t step_out = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_SPI_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&bma);
bma4_error_codes_print_result("bma456h_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Map the interrupt pin 1 for step counter */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_STEP_CNTR_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
if (rslt == BMA4_OK)
{
/* Setting watermark level 1, the output step resolution is 20 steps.
* Eg: 1 means, 1 * 20 = 20. Every 20 steps once output triggers
*/
rslt = bma456h_step_counter_set_watermark(1, &bma);
bma4_error_codes_print_result("bma456h_step_counter_set_watermark status", rslt);
if (rslt == BMA4_OK)
{
/* Enabling step counter feature */
rslt = bma456h_feature_enable(BMA456H_STEP_COUNTER_EN, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_feature_enable status", rslt);
}
}
if (rslt == BMA4_OK)
{
printf("Step counter feature is enabled\n");
printf("Step counter watermark level is 1 (Output resolution is 20 steps)\n");
printf("Move the board in steps to perform step counter\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
/* Enters only if the obtained interrupt is step counter */
if ((rslt == BMA4_OK) && (int_status & BMA456H_STEP_CNTR_INT))
{
printf("Step counter interrupt received when watermark level is reached (20 steps)\n");
rslt = bma456h_step_counter_output(&step_out, &bma);
printf("The step counter output is %lu\n", (long unsigned int)step_out);
break;
}
int_status = 0;
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= step_detector.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,93 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store step detector interrupt status */
uint16_t int_status = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&bma);
bma4_error_codes_print_result("bma456h_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Map the interrupt pin 1 for step detector */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_STEP_CNTR_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
if (rslt == BMA4_OK)
{
/* Enabling step detector feature */
rslt = bma456h_feature_enable(BMA456H_STEP_DETECTOR_EN, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_feature_enable status", rslt);
if (rslt == BMA4_OK)
{
/* By setting watermark level 1, the output step resolution is 20 steps.
* By setting watermark level 0, it provides output for each steps for step detection.
*/
rslt = bma456h_step_counter_set_watermark(0, &bma);
bma4_error_codes_print_result("bma456h_step_counter_set_watermark status", rslt);
}
}
if (rslt == BMA4_OK)
{
printf("Move the board in steps to get interrupt\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
/* Filtering only the step detector interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA456H_STEP_CNTR_INT))
{
printf("The step detector interrupt is occurred\n");
break;
}
int_status = 0;
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= tap.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456h.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,125 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456h.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store tap interrupt status */
uint16_t int_status = 0;
/* Loop variable */
uint8_t loop = 10;
struct bma456h_out_state tap_out = { 0 };
struct bma456h_multitap_settings settings = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456h_init(&bma);
bma4_error_codes_print_result("bma456h_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456h_write_config_file(&bma);
bma4_error_codes_print_result("bma456h_write_config status", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Map the interrupt pin 1 for tap detection */
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_TAP_OUT_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
if (rslt == BMA4_OK)
{
/* Enabling the single, double and triple tap features */
rslt = bma456h_feature_enable((BMA456H_SINGLE_TAP_EN | BMA456H_DOUBLE_TAP_EN | BMA456H_TRIPLE_TAP_EN),
BMA4_ENABLE,
&bma);
bma4_error_codes_print_result("bma456h_feature_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Getting tap parameters settings */
rslt = bma456h_tap_get_parameter(&settings, &bma);
bma4_error_codes_print_result("bma456h_tap_get_parameter status", rslt);
}
}
if (rslt == BMA4_OK)
{
printf("Tap the board either single, double or triple tap\n");
while (loop > 0)
{
/* Read interrupt status */
rslt = bma456h_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
/* Filtering only the tap interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA456H_TAP_OUT_INT))
{
rslt = bma456h_output_state(&tap_out, &bma);
if (BMA4_OK == rslt)
{
/* Enters only if the obtained interrupt is single-tap */
if (tap_out.single_tap)
{
printf("Single Tap interrupt occurred\n");
}
/* Enters only if the obtained interrupt is double-tap */
else if (tap_out.double_tap)
{
printf("Double Tap interrupt occurred\n");
}
/* Enters only if the obtained interrupt is triple-tap */
else if (tap_out.triple_tap)
{
printf("Triple Tap interrupt occurred\n");
}
loop--;
}
int_status = 0;
}
}
/* Break out of the loop when iteration has reached zero */
if (loop == 0)
{
printf("Iterations are done. Exiting !");
}
}
}
bma4_coines_deinit();
return rslt;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accel_foc.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456mm.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,741 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
/******************************************************************************/
/*! Header Files */
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "bma456mm.h"
#include "common.h"
#include "coines.h"
/******************************************************************************/
/*! Macro Definitions */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Global Variable Declaration */
/* Structure to store temporary axes data values */
struct temp_axes_val
{
/* X data */
int32_t x;
/* Y data */
int32_t y;
/* Z data */
int32_t z;
};
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used perform accel foc and determine limits based on range
*
* @param[in] range : Range of Accel
* @param[in] input_axis : Axis selected for Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev);
/*!
* @brief This internal API is to determine if average accel FOC data is within limits
*
* @param[in] avg_accel_foc_data : Average Accel FOC value
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] foc_sign : Input sign of performed Accel FOC
* @param[in] min_val : Minimum acceptable LSB limit
* @param[in] max_val : Maximum acceptable LSB limit
*
* @return Status of execution.
*/
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val);
/*!
* @brief This internal API is to collect and verify accel sensor data
*
* @param[in] range : Value of Accel range
* @param[in] reference : Reference LSB based on Accel Range
* @param[in] matched_axis : Input Axis to perform Accel FOC
* @param[in] foc_sign : Input sign to perform Accel FOC
* @param[in,out] dev : Structure instance of bma4_dev.
*
* @return Status of execution.
*/
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev);
/*!
* @brief This internal API is to calculate noise level for Accel FOC data
*
* @param[in] matched_axis : Input Axis to perform accel FOC
* @param[in] accel_foc_data : Array of Accel FOC data
* @param[in] avg_accel_foc_data : Average Accel FOC data
*
* @return Status of execution.
*/
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Sensor initialization configuration. */
struct bma4_dev dev;
uint8_t try = 0, j;
int8_t rslt;
struct bma4_accel_config accel_conf = { 0 };
uint8_t data = 0, range, input_axis = 0;
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&dev, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
printf("Functional test for accel foc start..\n\n");
printf("Choose the axis for accel FOC to be done\n");
printf("Press '1' to choose X axis\n");
printf("Press '2' to choose Y axis\n");
printf("Press '3' to choose Z axis\n");
printf("Press '4' to choose -X axis\n");
printf("Press '5' to choose -Y axis\n");
printf("Press '6' to choose -Z axis\n");
for (;;)
{
scanf("%u", (unsigned int *)&input_axis);
if (input_axis > 0 && input_axis < 7)
{
break;
}
}
if (input_axis == 1)
{
printf("The choosen input axis for FOC is : X\n");
}
else if (input_axis == 2)
{
printf("The choosen input axis for FOC is : Y\n");
}
else if (input_axis == 3)
{
printf("The choosen input axis for FOC is : Z\n");
}
else if (input_axis == 4)
{
printf("The choosen input axis for FOC is : -X\n");
}
else if (input_axis == 5)
{
printf("The choosen input axis for FOC is : -Y\n");
}
else if (input_axis == 6)
{
printf("The choosen input axis for FOC is : -Z\n");
}
printf("Confirm your chosen axis and the sensor keeping position are same before doing FOC\n");
for (j = 0; j < 2; j++)
{
try = 0;
if (j == 1)
{
printf("Keep sensor in wrong position and press 5\n");
}
else if (j == 0)
{
printf("Keep sensor in right position and press 5\n");
}
for (;;)
{
scanf("%hu", (short unsigned int *)&try);
if (try == 5)
{
break;
}
}
for (range = BMA4_ACCEL_RANGE_2G; range <= BMA4_ACCEL_RANGE_16G; range++)
{
/****************************************************************/
/* Initialize by enabling configuration load */
printf("#########################################################\n\n");
rslt = bma456mm_init(&dev);
bma4_error_codes_print_result("bma4_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456mm_write_config_file(&dev);
bma4_error_codes_print_result("bma4_write_config", rslt);
/* Enable the accelerometer */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Accelerometer Configuration Settings */
/* Output Data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = range;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* Delay to set accel sensor configurations (20ms for 50HZ) */
dev.delay_us(20000, dev.intf_ptr);
/* Mapping data ready interrupt with interrupt1 to get interrupt status once getting new accel data */
rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_map_interrupt status", rslt);
printf("ODR = %d, RANGE = %d, BANDWIDTH = %d\n", accel_conf.odr, accel_conf.range, accel_conf.bandwidth);
/* Perform FOC for different ranges */
rslt = perform_foc_range_test(range, input_axis, &dev);
if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_OK))
{
printf("\n######### Valid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_OK))
{
printf("\n######### Invalid input - Right position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Wrong position #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 0) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Valid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
else if ((j == 1) && (rslt == BMA4_E_OUT_OF_RANGE))
{
printf("\n######### Invalid input - Right position #########\n\n");
printf("\n######### Before FOC is better than after FOC #########\n\n");
bma4_error_codes_print_result("perform_foc_range_test", rslt);
}
}
/* Disable offset compensation */
rslt = bma4_read_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_read_regs", rslt);
data = BMA4_SET_BIT_VAL_0(data, BMA4_NV_ACCEL_OFFSET);
rslt = bma4_write_regs(BMA4_NV_CONFIG_ADDR, &data, 1, &dev);
bma4_error_codes_print_result("bma4_write_regs", rslt);
}
bma4_coines_deinit();
return rslt;
}
static int8_t accel_foc_report(int16_t avg_accel_foc_data,
int16_t reference,
uint8_t foc_sign,
int16_t min_val,
int16_t max_val)
{
int8_t rslt = BMA4_OK;
int16_t diff_after = 0;
if (foc_sign == 0)
{
if ((avg_accel_foc_data >= (min_val)) && (avg_accel_foc_data <= (max_val)))
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data >= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
if (foc_sign == 1)
{
if ((avg_accel_foc_data <= (min_val)) && (avg_accel_foc_data >= (max_val)))
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** PASS | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d in range\n", avg_accel_foc_data);
rslt = BMA4_OK;
}
else
{
if (avg_accel_foc_data <= reference)
{
diff_after = avg_accel_foc_data - reference;
}
else
{
diff_after = reference - avg_accel_foc_data;
}
printf("\n# ********** FAIL | Difference = %d **********\n", diff_after);
printf("\n# Avg_FOC %d not in range\n", avg_accel_foc_data);
rslt = BMA4_E_OUT_OF_RANGE;
}
}
return rslt;
}
static void calculate_noise(int8_t matched_axis,
const struct bma4_accel *accel_foc_data,
const struct bma4_accel avg_accel_foc_data)
{
int32_t variance = 0;
double noise_level;
uint16_t idx = 0;
if (matched_axis == 'X')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].x - avg_accel_foc_data.x) * (accel_foc_data[idx].x - avg_accel_foc_data.x));
}
}
else if (matched_axis == 'Y')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].y - avg_accel_foc_data.y) * (accel_foc_data[idx].y - avg_accel_foc_data.y));
}
}
else if (matched_axis == 'Z')
{
for (idx = 0; idx < ACCEL_SAMPLE_COUNT; idx++)
{
variance +=
((accel_foc_data[idx].z - avg_accel_foc_data.z) * (accel_foc_data[idx].z - avg_accel_foc_data.z));
}
}
noise_level = sqrt((double)variance);
printf("\n# ********** NOISE LEVEL = %lf **********\n", noise_level);
}
static int8_t verify_accel_foc_data(uint8_t range,
int16_t reference,
int8_t matched_axis,
uint8_t foc_sign,
struct bma4_dev *dev)
{
int8_t rslt = BMA4_E_INVALID_STATUS;
uint8_t i;
uint16_t reg_status = 0;
int16_t xl, yl, zl;
int16_t xh, yh, zh;
int16_t min_val = 0;
int16_t max_val = 0;
struct bma4_accel accel_foc_data[ACCEL_SAMPLE_COUNT] = { { 0 } };
struct temp_axes_val temp_foc_data = { 0 };
struct bma4_accel avg_accel_foc_data = { 0 };
struct bma4_accel sensor_data = { 0 };
/* Setting initial values */
xl = yl = zl = 32767;
xh = yh = zh = -32768;
/* Read accelerometer values before/after FOC */
for (i = 0; i < ACCEL_SAMPLE_COUNT; i++)
{
for (;;)
{
/* To get the data ready interrupt status */
rslt = bma4_read_int_status(&reg_status, dev);
bma4_error_codes_print_result("bma4_read_int_status", rslt);
/* Read accelerometer data based on data ready interrupt */
if ((rslt == BMA4_OK) && (reg_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&sensor_data, dev);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
memcpy(&accel_foc_data[i], &sensor_data, sizeof(struct bma4_accel));
printf("X[%d] = %5d Y[%d] = %5d Z[%d] = %5d\n",
i,
accel_foc_data[i].x,
i,
accel_foc_data[i].y,
i,
accel_foc_data[i].z);
if (xl > accel_foc_data[i].x)
{
xl = accel_foc_data[i].x;
}
if (xh < accel_foc_data[i].x)
{
xh = accel_foc_data[i].x;
}
if (yl > accel_foc_data[i].y)
{
yl = accel_foc_data[i].y;
}
if (yh < accel_foc_data[i].y)
{
yh = accel_foc_data[i].y;
}
if (zl > accel_foc_data[i].z)
{
zl = accel_foc_data[i].z;
}
if (zh < accel_foc_data[i].z)
{
zh = accel_foc_data[i].z;
}
temp_foc_data.x += accel_foc_data[i].x;
temp_foc_data.y += accel_foc_data[i].y;
temp_foc_data.z += accel_foc_data[i].z;
break;
}
}
}
/* Taking average values to calculate percentage deviation */
avg_accel_foc_data.x = (int16_t)(temp_foc_data.x / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.y = (int16_t)(temp_foc_data.y / ACCEL_SAMPLE_COUNT);
avg_accel_foc_data.z = (int16_t)(temp_foc_data.z / ACCEL_SAMPLE_COUNT);
printf("********* MIN & MAX VALUES ********\n");
printf("XL = %5d YL = %5d ZL = %5d\n", xl, yl, zl);
printf("XH = %5d YH = %5d ZH = %5d\n", xh, yh, zh);
printf("***** AVERAGE AFTER FOC *****\n");
printf("Avg-X = %d Avg-Y = %d Avg-Z = %d\n",
avg_accel_foc_data.x,
avg_accel_foc_data.y,
avg_accel_foc_data.z);
/* Calculate noise level */
calculate_noise(matched_axis, accel_foc_data, avg_accel_foc_data);
/* "zero-g offset" of accel is +/- 20 mg for all ranges as per datasheet (for 16-bit resolution) */
if (range == 0)
{
/* Min and Max limits for Range 2G */
min_val = BMA4_16BIT_ACC_2G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_2G_MAX_NOISE_LIMIT;
}
else if (range == 1)
{
/* Min and Max limits for Range 4G */
min_val = BMA4_16BIT_ACC_4G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_4G_MAX_NOISE_LIMIT;
}
else if (range == 2)
{
/* Min and Max limits for Range 8G */
min_val = BMA4_16BIT_ACC_8G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_8G_MAX_NOISE_LIMIT;
}
else if (range == 3)
{
/* Min and Max limits for Range 16G */
min_val = BMA4_16BIT_ACC_16G_MIN_NOISE_LIMIT;
max_val = BMA4_16BIT_ACC_16G_MAX_NOISE_LIMIT;
}
if ((matched_axis == 'X') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.x, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Y') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.y, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'Z') && (foc_sign == 0))
{
rslt = accel_foc_report(avg_accel_foc_data.z, reference, foc_sign, min_val, max_val);
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
reference,
min_val,
max_val);
}
else if ((matched_axis == 'X') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.x,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.x,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Y') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.y,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.y,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
else if ((matched_axis == 'Z') && (foc_sign == 1))
{
rslt = accel_foc_report(avg_accel_foc_data.z,
(int16_t)(reference * (-1)),
foc_sign,
(int16_t)(min_val * (-1)),
(int16_t)(max_val * (-1)));
printf("Range : %u Avg_FOC-X : %d Reference : %d Min_Value : %d Max_Value : %d\n",
range,
avg_accel_foc_data.z,
(reference * (-1)),
(min_val * (-1)),
(max_val * (-1)));
}
return rslt;
}
/* Perform FOC for different range and resolutions */
static int8_t perform_foc_range_test(uint8_t range, uint8_t input_axis, struct bma4_dev *dev)
{
int8_t rslt;
int8_t matched_axis = 0;
int16_t reference = 0;
/* Set accel foc axis and it's sign (x, y, z, sign)*/
struct bma4_accel_foc_g_value g_value_foc = { 0, 0, 0, 0 };
if (input_axis == 1)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 2)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 0;
}
else if (input_axis == 3)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 0;
}
else if (input_axis == 4)
{
g_value_foc.x = 1;
g_value_foc.y = 0;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 5)
{
g_value_foc.x = 0;
g_value_foc.y = 1;
g_value_foc.z = 0;
g_value_foc.sign = 1;
}
else if (input_axis == 6)
{
g_value_foc.x = 0;
g_value_foc.y = 0;
g_value_foc.z = 1;
g_value_foc.sign = 1;
}
switch (range)
{
/* Reference LSB value of 2G */
case 0:
reference = BMA4_16BIT_ACC_FOC_2G_REF;
break;
/* Reference LSB value of 4G */
case 1:
reference = BMA4_16BIT_ACC_FOC_4G_REF;
break;
/* Reference LSB value of 8G */
case 2:
reference = BMA4_16BIT_ACC_FOC_8G_REF;
break;
/* Reference LSB value of 16G */
case 3:
reference = BMA4_16BIT_ACC_FOC_16G_REF;
break;
default:
break;
}
if (g_value_foc.x == 1)
{
matched_axis = 'X';
}
else if (g_value_foc.y == 1)
{
matched_axis = 'Y';
}
else if (g_value_foc.z == 1)
{
matched_axis = 'Z';
}
if (g_value_foc.sign == 1)
{
printf("MATCHED AXIS is = -%c\n", matched_axis);
}
else
{
printf("MATCHED AXIS is = %c\n", matched_axis);
}
printf("\n\n# Before FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
printf("\n\n######### Perform Accel FOC #########\n\n");
/* Perform accelerometer FOC */
rslt = bma4_perform_accel_foc(&g_value_foc, dev);
bma4_error_codes_print_result("bma4_perform_accel_foc", rslt);
/* Delay after performing Accel FOC */
dev->delay_us(30000, dev->intf_ptr);
printf("\n\n# After FOC\n");
rslt = verify_accel_foc_data(range, reference, matched_axis, g_value_foc.sign, dev);
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= accelerometer.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456mm.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,163 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456mm.h"
#include "common.h"
/******************************************************************************/
/*! Macro definition */
/*! Earth's gravity in m/s^2 */
#define GRAVITY_EARTH (9.80665f)
/*! Macro that holds the total number of accel x,y and z axes sample counts to be printed */
#define ACCEL_SAMPLE_COUNT UINT8_C(100)
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*
* @param[in] val : Raw sensor value.
* @param[in] g_range : Accel Range selected (2G, 4G, 8G, 16G).
* @param[in] bit_width : Resolution of the sensor.
*
* @return Accel values in meters per second square.
*
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store accel data ready interrupt status */
uint16_t int_status = 0;
/* Variable that holds the accelerometer sample count */
uint8_t n_data = 1;
struct bma4_accel sens_data = { 0 };
float x = 0, y = 0, z = 0;
struct bma4_accel_config accel_conf = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456mm_init(&bma);
bma4_error_codes_print_result("bma456mm_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456mm_write_config_file(&bma);
bma4_error_codes_print_result("bma456mm_write_config status", rslt);
/* Accelerometer configuration settings */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt);
printf("Data, Acc_Raw_X, Acc_Raw_Y, Acc_Raw_Z, Acc_ms2_X, Acc_ms2_Y, Acc_ms2_Z\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456mm_read_int_status(&int_status, &bma);
bma4_error_codes_print_result("bma456mm_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
/* Read the accel x, y, z data */
rslt = bma4_read_accel_xyz(&sens_data, &bma);
bma4_error_codes_print_result("bma4_read_accel_xyz status", rslt);
if (rslt == BMA4_OK)
{
/* Converting lsb to meter per second squared for 16 bit resolution at 2G range */
x = lsb_to_ms2(sens_data.x, (float)2, bma.resolution);
y = lsb_to_ms2(sens_data.y, (float)2, bma.resolution);
z = lsb_to_ms2(sens_data.z, (float)2, bma.resolution);
/* Print the data in m/s2 */
printf("%d, %d, %d, %d, %4.2f, %4.2f, %4.2f\n", n_data, sens_data.x, sens_data.y, sens_data.z, x, y, z);
}
/* Increment the count that determines the number of samples to be printed */
n_data++;
/* When the count reaches more than ACCEL_SAMPLE_COUNT, break and exit the loop */
if (n_data > ACCEL_SAMPLE_COUNT)
{
break;
}
}
}
bma4_coines_deinit();
return rslt;
}
/*!
* @brief This internal API converts raw sensor values(LSB) to meters per seconds square.
*/
static float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width)
{
double power = 2;
float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f));
return (GRAVITY_EARTH * val * g_range) / half_scale;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= auto_low_power.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456mm.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,146 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include "bma456mm.h"
#include "common.h"
/******************************************************************************/
/*! Function */
/* This function starts the execution of program. */
int main(void)
{
/* Variable to store the status of API */
int8_t rslt;
/* Sensor initialization configuration */
struct bma4_dev bma = { 0 };
/* Variable to store auto low power state */
uint8_t auto_low_power_state = 0;
struct bma4_accel_config accel_conf = { 0 };
struct bma456mm_auto_low_power auto_low_power = { 0 };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456mm_init(&bma);
bma4_error_codes_print_result("bma456mm_init status", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456mm_write_config_file(&bma);
bma4_error_codes_print_result("bma456mm_write_config status", rslt);
/* Get the accel configurations */
rslt = bma4_get_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_get_accel_config status", rslt);
if (rslt == BMA4_OK)
{
/* Accelerometer configuration settings */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
if (rslt == BMA4_OK)
{
/* Enable auto low power state through no-motion interrupt */
auto_low_power.no_motion = 0;
/* Enable auto low power state through time-out duration */
auto_low_power.time_out = 1;
/* Time-out duration is (value * resolution) eg: (10 * 20ms) */
auto_low_power.time_out_dur = 10;
/* These bits used to set odr at auto low power mode. default
* value is '0'(i.e) 25/16 HZ */
auto_low_power.lp_odr = 0;
/* Set this bit to set default odr of titan core in auto low power mode */
auto_low_power.pwr_mgt = 1;
/* Configure Auto low power settings */
rslt = bma456mm_set_auto_low_power_config(&auto_low_power, &bma);
bma4_error_codes_print_result("bma456mm_set_auto_low_power_config status", rslt);
if (rslt == BMA4_OK)
{
/* Get output of auto low power state */
rslt = bma456mm_get_auto_low_power_state(&auto_low_power_state, &bma);
bma4_error_codes_print_result("bma456mm_get_auto_low_power_state status", rslt);
}
}
}
if (rslt == BMA4_OK)
{
/* Enable auto low power feature */
rslt = bma456mm_feature_enable(BMA456MM_AUTO_LOW_POWER, BMA4_ENABLE, &bma);
bma4_error_codes_print_result("bma456mm_feature_enable status", rslt);
}
if (rslt == BMA4_OK)
{
/* Read and check the ODR change after changing the auto low power settings */
rslt = bma4_get_accel_config(&accel_conf, &bma);
bma4_error_codes_print_result("bma4_get_accel_config status", rslt);
if (rslt == BMA4_OK)
{
printf("ODR : %X\n", accel_conf.odr);
if (auto_low_power_state)
{
printf("Auto low power state : Disabled(Auto wake state)");
}
else
{
printf("Auto low power state : Enabled(Auto sleep state)");
}
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,18 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE = axis_remap.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456mm.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk
@@ -0,0 +1,362 @@
/**\
* Copyright (c) 2022 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#include <stdio.h>
#include <stdlib.h>
#include "coines.h"
#include "bma456mm.h"
#include "common.h"
/*********************************************************************/
/* functions */
/*********************************************************************/
/*!
* @brief Main Function where the execution getting started to test the code.
*
* @param[in] argc
* @param[in] argv
*
* @return status
*
*/
int main(void)
{
int8_t rslt;
struct bma4_dev bma4;
struct bma4_remap remap_data = { 0 };
struct bma4_accel accel = { 0 };
struct bma4_accel_config accel_conf = { 0 };
uint16_t int_status = 0;
char data_array[13][11] =
{ { 0 }, { "BMA4_X" }, { "BMA4_Y" }, { 0 }, { "BMA4_Z" }, { 0 }, { 0 }, { 0 }, { 0 }, { "BMA4_NEG_X" },
{ "BMA4_NEG_Y" }, { 0 }, { "BMA4_NEG_Z" } };
/* Interface reference is given as a parameter
* For I2C : BMA4_I2C_INTF
* For SPI : BMA4_SPI_INTF
* Variant information given as parameter - BMA45X_VARIANT
*/
rslt = bma4_interface_init(&bma4, BMA4_I2C_INTF, BMA45X_VARIANT);
bma4_error_codes_print_result("bma4_interface_init", rslt);
/* Sensor initialization */
rslt = bma456mm_init(&bma4);
bma4_error_codes_print_result("bma456mm_init", rslt);
/* Upload the configuration file to enable the features of the sensor. */
rslt = bma456mm_write_config_file(&bma4);
bma4_error_codes_print_result("bma456mm_write_config", rslt);
/* Accelerometer configuration Setting */
/* Output data Rate */
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_50HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G) */
accel_conf.range = BMA4_ACCEL_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a less noisier signal, but
* this has an adverse effect on the power consumed.
*/
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Averaging samples (Default)
* 1 -> No averaging
* For more info on No Averaging mode refer datasheet.
*/
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&accel_conf, &bma4);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* NOTE : Enable accel after set of configurations */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &bma4);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Mapping data ready interrupt with interrupt pin 1 to get interrupt status once getting new accel data */
rslt = bma456mm_map_interrupt(BMA4_INTR1_MAP, BMA4_DATA_RDY_INT, BMA4_ENABLE, &bma4);
bma4_error_codes_print_result("bma456mm_map_interrupt status", rslt);
printf("\nAXIS_REMAP_FUNC_TEST 1\n");
printf("Get sensor data of re-mapped axes\n");
rslt = bma456mm_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt);
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
printf("Expected Re-mapped x value = BMA4_X\n");
printf("Expected Re-mapped y value = BMA4_Y\n");
printf("Expected Re-mapped z value = BMA4_Z\n");
if ((remap_data.x == BMA4_X) && (remap_data.y == BMA4_Y) && (remap_data.z == BMA4_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456mm_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456mm_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 2\n");
printf("Get sensor data of re-mapped axes\n");
remap_data.x = BMA4_NEG_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_NEG_X;
rslt = bma456mm_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456mm_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_NEG_X\n");
if ((remap_data.x == BMA4_NEG_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_NEG_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456mm_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456mm_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 3\n");
printf("Get sensor data of re-mapped axes - 2nd combination\n");
remap_data.x = BMA4_NEG_Z;
remap_data.y = BMA4_NEG_X;
remap_data.z = BMA4_Y;
rslt = bma456mm_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456mm_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_Z\n");
printf("Expected Re-mapped y value = BMA4_NEG_X\n");
printf("Expected Re-mapped z value = BMA4_Y\n");
if ((remap_data.x == BMA4_NEG_Z) && (remap_data.y == BMA4_NEG_X) && (remap_data.z == BMA4_Y))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456mm_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456mm_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 4\n");
printf("Get sensor data of re-mapped axes - 3rd combination\n");
remap_data.x = BMA4_Y;
remap_data.y = BMA4_Z;
remap_data.z = BMA4_X;
rslt = bma456mm_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456mm_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_Y\n");
printf("Expected Re-mapped y value = BMA4_Z\n");
printf("Expected Re-mapped z value = BMA4_X\n");
if ((remap_data.x == BMA4_Y) && (remap_data.y == BMA4_Z) && (remap_data.z == BMA4_X))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456mm_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456mm_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
printf("\nAXIS_REMAP_FUNC_TEST 5\n");
printf("Get sensor data of re-mapped axes - 4th combination\n");
remap_data.x = BMA4_NEG_X;
remap_data.y = BMA4_NEG_Y;
remap_data.z = BMA4_NEG_Z;
rslt = bma456mm_set_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_set_remap_axes", rslt);
if (rslt == BMA4_OK)
{
rslt = bma456mm_get_remap_axes(&remap_data, &bma4);
bma4_error_codes_print_result("bma456mm_get_remap_axes", rslt);
if (rslt == BMA4_OK)
{
printf("Re-mapped x value = %s\n", data_array[remap_data.x]);
printf("Re-mapped y value = %s\n", data_array[remap_data.y]);
printf("Re-mapped z value = %s\n", data_array[remap_data.z]);
}
printf("Expected Re-mapped x value = BMA4_NEG_X\n");
printf("Expected Re-mapped y value = BMA4_NEG_Y\n");
printf("Expected Re-mapped z value = BMA4_NEG_Z\n");
if ((remap_data.x == BMA4_NEG_X) && (remap_data.y == BMA4_NEG_Y) && (remap_data.z == BMA4_NEG_Z))
{
printf(">> PASS\n");
}
else
{
printf(">> FAIL\n");
}
}
printf("Print mapped data\n");
for (;;)
{
/* Read interrupt status */
rslt = bma456mm_read_int_status(&int_status, &bma4);
bma4_error_codes_print_result("bma456mm_read_int_status", rslt);
/* Filtering only the accel data ready interrupt */
if ((rslt == BMA4_OK) && (int_status & BMA4_ACCEL_DATA_RDY_INT))
{
rslt = bma4_read_accel_xyz(&accel, &bma4);
bma4_error_codes_print_result("bma4_read_accel_xyz", rslt);
printf("Accel :: X = %d Y = %d Z = %d\n", accel.x, accel.y, accel.z);
break;
}
}
bma4_coines_deinit();
return rslt;
}
@@ -0,0 +1,242 @@
/**
* Copyright (C) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "bma4_defs.h"
#include "common.h"
/******************************************************************************/
/*! Macro definitions */
/*! Read write length varies based on user requirement */
#define BMA4_READ_WRITE_LEN UINT8_C(46)
/******************************************************************************/
/*! Static variable definition */
/*! Variable that holds the I2C device address or SPI chip selection */
static uint8_t dev_addr;
/******************************************************************************/
/*! User interface functions */
/*!
* I2C read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* I2C write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_i2c(COINES_I2C_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* SPI read function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_read_spi(COINES_SPI_BUS_0, dev_address, reg_addr, reg_data, (uint16_t)len);
}
/*!
* SPI write function map to COINES platform
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
uint8_t dev_address = *(uint8_t*)intf_ptr;
(void)intf_ptr;
return coines_write_spi(COINES_SPI_BUS_0, dev_address, reg_addr, (uint8_t *)reg_data, (uint16_t)len);
}
/*!
* Delay function map to COINES platform
*/
void bma4_delay_us(uint32_t period, void *intf_ptr)
{
(void) intf_ptr;
coines_delay_usec(period);
}
/*!
* @brief Function to select the interface between SPI and I2C.
* Also to initialize coines platform
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant)
{
int8_t rslt = BMA4_OK;
if (bma != NULL)
{
int16_t result = coines_open_comm_intf(COINES_COMM_INTF_USB, NULL);
struct coines_board_info board_info;
if (result < COINES_SUCCESS)
{
printf(
"\n Unable to connect with Application Board ! \n" " 1. Check if the board is connected and powered on. \n" " 2. Check if Application Board USB driver is installed. \n"
" 3. Check if board is in use by another application. (Insufficient permissions to access USB) \n");
exit(result);
}
result = coines_get_board_info(&board_info);
#if defined(PC)
setbuf(stdout, NULL);
#endif
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_usec(10000);
/* Bus configuration : I2C */
if (intf == BMA4_I2C_INTF)
{
printf("I2C Interface \n");
/* To initialize the user I2C function */
dev_addr = BMA4_I2C_ADDR_PRIMARY;
bma->intf = BMA4_I2C_INTF;
bma->bus_read = bma4_i2c_read;
bma->bus_write = bma4_i2c_write;
/* SDO to Ground */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_22, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
/* Make CSB pin HIGH */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_21, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_HIGH);
coines_delay_msec(100);
/* SDO pin is made low */
(void)coines_set_pin_config(COINES_SHUTTLE_PIN_SDO, COINES_PIN_DIRECTION_OUT, COINES_PIN_VALUE_LOW);
(void)coines_config_i2c_bus(COINES_I2C_BUS_0, COINES_I2C_STANDARD_MODE);
}
/* Bus configuration : SPI */
else if (intf == BMA4_SPI_INTF)
{
printf("SPI Interface \n");
/* To initialize the user SPI function */
dev_addr = COINES_SHUTTLE_PIN_7;
bma->intf = BMA4_SPI_INTF;
bma->bus_read = bma4_spi_read;
bma->bus_write = bma4_spi_write;
(void)coines_config_spi_bus(COINES_SPI_BUS_0, COINES_SPI_SPEED_7_5_MHZ, COINES_SPI_MODE0);
}
/* Assign variant information */
bma->variant = variant;
/* Assign device address to interface pointer */
bma->intf_ptr = &dev_addr;
/* Configure delay in microseconds */
bma->delay_us = bma4_delay_us;
/* Configure max read/write length (in bytes) ( Supported length depends on target machine) */
bma->read_write_len = BMA4_READ_WRITE_LEN;
/* Set Performance mode status */
bma->perf_mode_status = BMA4_DISABLE;
coines_delay_msec(100);
(void)coines_set_shuttleboard_vdd_vddio_config(3300, 3300);
coines_delay_msec(200);
}
else
{
rslt = BMA4_E_NULL_PTR;
}
return rslt;
}
/*!
* @brief Prints the execution status of the APIs.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt)
{
if (rslt != BMA4_OK)
{
printf("%s\t", api_name);
if (rslt == BMA4_E_NULL_PTR)
{
printf("Error [%d] : Null pointer\r\n", rslt);
}
else if (rslt == BMA4_E_COM_FAIL)
{
printf("Error [%d] : Communication failure\r\n", rslt);
}
else if (rslt == BMA4_E_CONFIG_STREAM_ERROR)
{
printf("Error [%d] : Invalid configuration stream\r\n", rslt);
}
else if (rslt == BMA4_E_SELF_TEST_FAIL)
{
printf("Error [%d] : Self test failed\r\n", rslt);
}
else if (rslt == BMA4_E_INVALID_SENSOR)
{
printf("Error [%d] : Device not found\r\n", rslt);
}
else if (rslt == BMA4_E_OUT_OF_RANGE)
{
printf("Error [%d] : Out of Range\r\n", rslt);
}
else if (rslt == BMA4_E_AVG_MODE_INVALID_CONF)
{
printf("Error [%d] : Invalid bandwidth and ODR combination in Accel Averaging mode\r\n", rslt);
}
else
{
/* For more error codes refer "*_defs.h" */
printf("Error [%d] : Unknown error code\r\n", rslt);
}
}
}
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void)
{
(void)fflush(stdout);
coines_delay_msec(200);
(void)coines_set_shuttleboard_vdd_vddio_config(0, 0);
coines_delay_msec(1000);
/* Coines interface reset */
coines_soft_reset();
coines_delay_msec(1000);
(void)coines_close_comm_intf(COINES_COMM_INTF_USB, NULL);
}
@@ -0,0 +1,127 @@
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
#ifndef COMMON_H
#define COMMON_H
/*! CPP guard */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include "bma4.h"
#include "coines.h"
/*!
* @brief Function for reading the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through I2C bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose value is to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for reading the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[out] reg_data : Pointer to the data buffer to store the read data.
* @param[in] length : No of bytes to read.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief Function for writing the sensor's registers through SPI bus.
*
* @param[in] reg_addr : Register address.
* @param[in] reg_data : Pointer to the data buffer whose data has to be written.
* @param[in] length : No of bytes to write.
* @param[in] intf_ptr : Interface pointer
*
* @return Status of execution
* @retval = BMA4_INTF_RET_SUCCESS -> Success
* @retval != BMA4_INTF_RET_SUCCESS -> Failure Info
*
*/
BMA4_INTF_RET_TYPE bma4_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
/*!
* @brief This function provides the delay for required time (Microsecond) as per the input provided in some of the
* APIs.
*
* @param[in] period_us : The required wait time in microsecond.
* @param[in] intf_ptr : Interface pointer
*
* @return void.
*
*/
void bma4_delay_us(uint32_t period, void *intf_ptr);
/*!
* @brief Function to select the interface between SPI and I2C.
*
* @param[in] bma : Structure instance of bma4_dev
* @param[in] intf : Interface selection parameter
* @param[in] variant : Variant information of the sensor
* ( BMA42x variants values - BMA42X_VARIANT / BMA42X_B_VARIANT )
* ( BMA45x variants values - BMA45X_VARIANT )
*
* @return Status of execution
* @retval 0 -> Success
* @retval < 0 -> Failure Info
*/
int8_t bma4_interface_init(struct bma4_dev *bma, uint8_t intf, enum bma4_variant variant);
/*!
* @brief Prints the execution status of the APIs.
*
* @param[in] api_name : Name of the API whose execution status has to be printed.
* @param[in] rslt : Error code returned by the API whose execution status has to be printed.
*
* @return void.
*/
void bma4_error_codes_print_result(const char api_name[], int8_t rslt);
/*!
* @brief Deinitializes coines platform
*
* @return void.
*/
void bma4_coines_deinit(void);
#ifdef __cplusplus
}
#endif /* End of CPP guard */
#endif /* COMMON_H */
@@ -0,0 +1,20 @@
COINES_INSTALL_PATH ?= ../../../..
EXAMPLE_FILE ?= fifo_full_header_mode.c
API_LOCATION ?= ../..
COMMON_LOCATION ?= ..
C_SRCS += \
$(API_LOCATION)/bma4.c \
$(API_LOCATION)/bma456mm.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
TARGET=MCU_APP30
include $(COINES_INSTALL_PATH)/coines.mk

Some files were not shown because too many files have changed in this diff Show More