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>
This commit is contained in:
simon 2026-05-18 22:51:32 +02:00
parent 755bdd92d7
commit e5db0b21c7
168 changed files with 42062 additions and 2 deletions

View File

@ -0,0 +1,7 @@
idf_component_register(
SRCS
"bma456h.c"
"bma4.c"
INCLUDE_DIRS "."
REQUIRES driver
)

30
components/bma456/LICENSE Normal file
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.

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

5859
components/bma456/bma4.c Normal file

File diff suppressed because it is too large Load Diff

2209
components/bma456/bma4.h Normal file

File diff suppressed because it is too large Load Diff

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 */

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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

1649
components/bma456/bma456h.c Normal file

File diff suppressed because it is too large Load Diff

1322
components/bma456/bma456h.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

1948
components/bma456/bma456mm.c Normal file

File diff suppressed because it is too large Load Diff

1584
components/bma456/bma456mm.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -0,0 +1,173 @@
/**\
* 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 */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456MM_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456MM_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 BMA456MM_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[BMA456MM_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[BMA456MM_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 BMA456MM */
rslt = bma456mm_init(&dev);
bma4_error_codes_print_result("bma456mm_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 = BMA456MM_FIFO_RAW_DATA_USER_LENGTH + BMA4_SENSORTIME_OVERHEAD_BYTE;
printf("FIFO is configured in header mode\n");
rslt = bma456mm_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 = bma456mm_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 = BMA456MM_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;
}

View File

@ -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)/bma456mm.c \
$(COMMON_LOCATION)/common/common.c
INCLUDEPATHS += \
$(API_LOCATION) \
$(COMMON_LOCATION)/common
include $(COINES_INSTALL_PATH)/coines.mk

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