feature: add imu sensor icm42670

This commit is contained in:
zhouli
2021-10-19 15:54:04 +08:00
committed by Yu Zhe
parent 0f4a5eb467
commit 6e26a6dedf
21 changed files with 7727 additions and 23 deletions
-3
View File
@@ -37,6 +37,3 @@
[submodule "examples/freetype/main/lib/freetype"]
path = examples/freetype/main/lib/freetype
url = https://gitlab.freedesktop.org/freetype/freetype.git
[submodule "components/lvgl/lv_lib/lv_lib_qrcode"]
path = components/lvgl/lv_lib/lv_lib_qrcode
url = https://github.com/lvgl/lv_lib_qrcode.git
-16
View File
@@ -1,16 +0,0 @@
# CMakeLists.txt
#
# Copyright 2021 Espressif Systems (Shanghai) Co. Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
+6 -4
View File
@@ -1,9 +1,11 @@
file(GLOB_RECURSE CSRC_FILES *.c)
idf_component_register(
SRCS
${CSRC_FILES}
SRC_DIRS
"icm42670"
"touch_panel"
INCLUDE_DIRS
"include"
"icm42670/include"
"touch_panel/include"
REQUIRES
bsp)
+75
View File
@@ -0,0 +1,75 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2015-2015 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software”) is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
#include "Message.h"
#include <stdio.h>
#include <stdlib.h>
static int msg_level;
static inv_msg_printer_t msg_printer;
void inv_msg_printer_default(int level, const char * str, va_list ap)
{
#if !defined(__ICCARM__)
const char * s[INV_MSG_LEVEL_MAX] = {
"", // INV_MSG_LEVEL_OFF
" [E] ", // INV_MSG_LEVEL_ERROR
" [W] ", // INV_MSG_LEVEL_WARNING
" [I] ", // INV_MSG_LEVEL_INFO
" [V] ", // INV_MSG_LEVEL_VERBOSE
" [D] ", // INV_MSG_LEVEL_DEBUG
};
fprintf(stderr, "%s", s[level]);
vfprintf(stderr, str, ap);
fprintf(stderr, "\n");
#else
(void)level, (void)str, (void)ap;
#endif
}
void inv_msg_setup(int level, inv_msg_printer_t printer)
{
msg_level = level;
if (level < INV_MSG_LEVEL_OFF)
msg_level = INV_MSG_LEVEL_OFF;
else if (level > INV_MSG_LEVEL_MAX)
msg_level = INV_MSG_LEVEL_MAX;
msg_printer = printer;
}
void inv_msg(int level, const char * str, ...)
{
if(level && level <= msg_level && msg_printer) {
va_list ap;
va_start(ap, str);
msg_printer(level, str, ap);
va_end(ap);
}
}
int inv_msg_get_level(void)
{
return msg_level;
}
+169
View File
@@ -0,0 +1,169 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "stdio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "bsp_i2c.h"
#include "Message.h"
#include "inv_imu_driver.h"
static const char *TAG = "icm42670";
/*
* Set of timers used throughout standalone applications
*/
#define SENSOR_ODR_1600HZ 1600
#define SENSOR_ODR_800HZ 800
#define SENSOR_ODR_400HZ 400
#define SENSOR_ODR_200HZ 200
#define SENSOR_ODR_100HZ 100
#define SENSOR_ODR_50HZ 50
#define SENSOR_ODR_25HZ 25
#define SENSOR_ODR_12_5HZ 12.5
static i2c_bus_device_handle_t g_i2c_dev_handle;
static int platform_io_hal_read_reg(void *context, uint8_t reg, uint8_t *buf, uint32_t len)
{
return i2c_bus_read_bytes(g_i2c_dev_handle, reg, len, buf);
}
static int platform_io_hal_write_reg(void *context, uint8_t reg, const uint8_t *buf, uint32_t len)
{
return i2c_bus_write_bytes(g_i2c_dev_handle, reg, len, buf);
}
static void platform_delay_ms(uint32_t ms)
{
vTaskDelay(pdMS_TO_TICKS(ms));
}
static void platform_delay_us(uint32_t us)
{
ets_delay_us(us);
}
/*
* Printer function for message facility
*/
static void msg_printer(int level, const char *str, va_list ap)
{
static char out_str[2560]; /* static to limit stack usage */
uint32_t idx = 0;
#define LOG_COLOR_BLACK "30"
#define LOG_COLOR_RED "31"
#define LOG_COLOR_GREEN "32"
#define LOG_COLOR_BROWN "33"
#define LOG_COLOR_BLUE "34"
#define LOG_COLOR_PURPLE "35"
#define LOG_COLOR_CYAN "36"
#define LOG_COLOR(COLOR) "\033[0;" COLOR "m"
#define LOG_BOLD(COLOR) "\033[1;" COLOR "m"
#define LOG_RESET_COLOR "\033[0m"
#define LOG_COLOR_E LOG_COLOR(LOG_COLOR_RED)
#define LOG_COLOR_W LOG_COLOR(LOG_COLOR_BROWN)
#define LOG_COLOR_I LOG_COLOR(LOG_COLOR_GREEN)
const char *s[INV_MSG_LEVEL_MAX] = {
"", // INV_MSG_LEVEL_OFF
LOG_COLOR_E "[E]", // INV_MSG_LEVEL_ERROR
LOG_COLOR_W "[W]", // INV_MSG_LEVEL_WARNING
LOG_COLOR_I "[I]", // INV_MSG_LEVEL_INFO
LOG_COLOR_BLUE "[V]", // INV_MSG_LEVEL_VERBOSE
LOG_COLOR_BLUE "[D]", // INV_MSG_LEVEL_DEBUG
};
if (level >= INV_MSG_LEVEL_MAX) {
printf("message error!\r\n");
return;
}
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s %s: ", s[level], TAG);
if (idx >= (sizeof(out_str))) {
return;
}
idx += vsnprintf(&out_str[idx], sizeof(out_str) - idx, str, ap);
if (idx >= (sizeof(out_str))) {
return;
}
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, LOG_RESET_COLOR "\r\n");
if (idx >= (sizeof(out_str))) {
return;
}
printf(out_str);
}
esp_err_t icm42670_init(void)
{
esp_err_t ret = ESP_OK;
if (NULL != g_i2c_dev_handle) {
return ESP_FAIL;
}
bsp_i2c_add_device(&g_i2c_dev_handle, 0x68);
if (NULL == g_i2c_dev_handle) {
return ESP_FAIL;
}
/* Setup message facility to see internal traces from FW */
inv_msg_setup(INV_MSG_LEVEL_INFO, msg_printer);
inv_imu_set_serif(platform_io_hal_read_reg, platform_io_hal_write_reg);
inv_imu_set_delay(platform_delay_ms, platform_delay_us);
float hw_rate = 0.0;
/* Init device */
ret = inv_imu_initialize();
if (ret != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize INV concise driver!");
return ret;
}
INV_MSG(INV_MSG_LEVEL_INFO, "IMU device successfully initialized");
// We may customize full scale range here.
ret |= inv_imu_set_accel_fsr(ACCEL_CONFIG0_FS_SEL_4g);
ret |= inv_imu_set_gyro_fsr(GYRO_CONFIG0_FS_SEL_2000dps);
// Below settings are required to configure and enable sensors.
ret |= inv_imu_acc_enable();
ret |= inv_imu_acc_set_rate(SENSOR_ODR_400HZ, 2, &hw_rate); //200Hz ODR, watermark: 2 packets.
ret |= inv_imu_gyro_enable();
ret |= inv_imu_gyro_set_rate(SENSOR_ODR_400HZ, 4, &hw_rate); //50Hz ODR, watermark 4.
if (ret != 0) {
INV_LOG(SENSOR_LOG_LEVEL, "Feature enable Failed. Do nothing %d", ret);
return ret;
}
INV_LOG(SENSOR_LOG_LEVEL, "HW odr setting %f ", hw_rate);
return ESP_OK;
}
esp_err_t icm42670_get_raw_data(AccDataPacket *accData,
GyroDataPacket *gyroData,
chip_temperature *imu_chip_temperature)
{
int ret = inv_data_handler(accData, gyroData, imu_chip_temperature, 1);
if (0 != ret) {
return ESP_FAIL;
}
return ESP_OK;
}
@@ -0,0 +1,39 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2015-2015 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software”) is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
#ifndef _INV_IDD_EXPORT_H_
#define _INV_IDD_EXPORT_H_
#if defined(_WIN32)
#if !defined(INV_EXPORT) && defined(INV_DO_DLL_EXPORT)
#define INV_EXPORT __declspec(dllexport)
#elif !defined(INV_EXPORT) && defined(INV_DO_DLL_IMPORT)
#define INV_EXPORT __declspec(dllimport)
#endif
#endif
#if !defined(INV_EXPORT)
#define INV_EXPORT
#endif
#endif /* _INV_IDD_EXPORT_H_ */
@@ -0,0 +1,181 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2015-2015 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software”) is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/** @defgroup Message Message
* @brief Utility functions to display and redirect diagnostic messages
*
* Use INV_MSG_DISABLE or INV_MSG_ENABLE define before including
* this header to enable/disable messages for a compilation unit.
*
* Under Linux, Windows or Arduino, messages are enabled by default.
* Use INV_MSG_DISABLE to disable them.
*
* Under orther environmment, message are disabled by default.
* Use INV_MSG_ENABLE to disable them.
*
* @ingroup EmbUtils
* @{
*/
#ifndef _INV_MESSAGE_H_
#define _INV_MESSAGE_H_
#include "InvExport.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
/** @brief For eMD target, disable log by default
* If compile switch is set for a compilation unit
* messages will be totally disabled by default
*/
#if !defined(__linux) && !defined(_WIN32) && !defined(ARDUINO)
#define INV_MSG_DISABLE 1
#endif
#define INV_MSG_ENABLE
/** @brief Allow to force enabling messaging using INV_MSG_ENABLE define */
#ifdef INV_MSG_ENABLE
#undef INV_MSG_DISABLE
#endif
/** @brief Helper macro for calling inv_msg()
* If INV_MSG_DISABLE compile switch is set for a compilation unit
* messages will be totally disabled
*/
#define INV_MSG(level, ...) _INV_MSG(level, __VA_ARGS__)
/** @brief Helper macro for calling inv_msg_setup()
* If INV_MSG_DISABLE compile switch is set for a compilation unit
* messages will be totally disabled
*/
#define INV_MSG_SETUP(level, printer) _INV_MSG_SETUP(level, printer)
/** @brief Helper macro for calling inv_msg_setup_level()
* If INV_MSG_DISABLE compile switch is set for a compilation unit
* messages will be totally disabled
*/
#define INV_MSG_SETUP_LEVEL(level) _INV_MSG_SETUP_LEVEL(level)
/** @brief Helper macro for calling inv_msg_setup_default()
* If INV_MSG_DISABLE compile switch is set for a compilation unit
* messages will be totally disabled
*/
#define INV_MSG_SETUP_DEFAULT() _INV_MSG_SETUP_DEFAULT()
/** @brief Return current level
* @warning This macro may expand as a function call
*/
#define INV_MSG_LEVEL _INV_MSG_LEVEL
#if defined(INV_MSG_DISABLE)
#define _INV_MSG(level, ...) (void)0
#define _INV_MSG_SETUP(level, printer) (void)0
#define _INV_MSG_SETUP_LEVEL(level) (void)0
#define _INV_MSG_LEVEL INV_MSG_LEVEL_OFF
#else
#define _INV_MSG(level, ...) inv_msg(level, __VA_ARGS__)
#define _INV_MSG_SETUP(level, printer) inv_msg_setup(level, printer)
#define _INV_MSG_SETUP_LEVEL(level) inv_msg_setup(level, inv_msg_printer_default)
#define _INV_MSG_SETUP_DEFAULT() inv_msg_setup_default()
#define _INV_MSG_LEVEL inv_msg_get_level()
#endif
/** @brief message level definition
*/
enum inv_msg_level {
INV_MSG_LEVEL_OFF = 0,
INV_MSG_LEVEL_ERROR,
INV_MSG_LEVEL_WARNING,
INV_MSG_LEVEL_INFO,
INV_MSG_LEVEL_VERBOSE,
INV_MSG_LEVEL_DEBUG,
INV_MSG_LEVEL_MAX
};
/** @brief Prototype for print routine function
*/
typedef void (*inv_msg_printer_t)(int level, const char * str, va_list ap);
/** @brief Set message level and printer function
* @param[in] level only message above level will be passed to printer function
* @param[in] printer user provided function in charge printing message
* @return none
*/
void INV_EXPORT inv_msg_setup(int level, inv_msg_printer_t printer);
/** @brief Default printer function that display messages to stderr
* Function uses stdio. Care must be taken on embeded platfrom.
* Function does nothing with IAR compiler.
* @return none
*/
void INV_EXPORT inv_msg_printer_default(int level, const char * str, va_list ap);
/** @brief Set message level
* Default printer function will be used.
* @param[in] level only message above level will be passed to printer function
* @return none
*/
static inline void inv_msg_setup_level(int level)
{
inv_msg_setup(level, inv_msg_printer_default);
}
/** @brief Set default message level and printer
* @return none
*/
static inline void inv_msg_setup_default(void)
{
inv_msg_setup(INV_MSG_LEVEL_INFO, inv_msg_printer_default);
}
/** @brief Return current message level
* @return current message level
*/
int INV_EXPORT inv_msg_get_level(void);
/** @brief Display a message (through means of printer function)
* @param[in] level for the message
* @param[in] str message string
* @param[in] ... optional arguments
* @return none
*/
void INV_EXPORT inv_msg(int level, const char * str, ...);
#ifdef __cplusplus
}
#endif
#endif /* INV_MESSAGE_H_ */
/** @} */
@@ -0,0 +1,41 @@
#ifndef _ICM_42670_H_
#define _ICM_42670_H_
#include "esp_err.h"
#include "inv_imu_driver.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Init ICM-42670 IMU
*
* @return
* - ESP_OK: Success
* - Others: Fail
*/
esp_err_t icm42670_init(void);
/**
* @brief Get raw data from ICM-42670
*
* @param accData Pointer to accelerometer data
* @param gyroData Pointor to gyroscope data
* @param imu_chip_temperature Pointer to temperature data
* @return
* - ESP_OK: Success
* - Others: Fail
*/
esp_err_t icm42670_get_raw_data(AccDataPacket *accData,
GyroDataPacket *gyroData,
chip_temperature *imu_chip_temperature);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,104 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2015-2015 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively Software is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
#ifndef _INV_ICM4N607_CONFIG_H_
#define _INV_ICM4N607_CONFIG_H_
#include <stdint.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define FIFO_WM_MODE_EN 0 //1:fifo mode 0:dri mode
#define IS_HIGH_RES_MODE 0 // 1: FIFO high resolution mode (20bits data format); 0: 16 bits data format;
#define SPI_MODE_EN 1 //1:spi 0:i2c
#define DATA_FORMAT_DPS_G 1 // output sensor data with unit in default accel: m/s2 gyro: rad/s
#define SUPPORT_FIFO_TS 1 // support fifo timestamp by default
#define DMP_POWERSAVE_FF 0 // disable apex power save mode for apex freefall for better performance
#define DMP_POWERSAVE_PEDO 1 // setting apex power save mode for apex pedometer by default
#define SUPPORT_DELAY_US 1 // 1: platform supports delay in us; 0: platform does not support delay in ms.
#define SENSOR_REG_DUMP 0 // register dump control
#define SENSOR_LOG_LEVEL 3 //INV_LOG_LEVEL_INFO
#define SENSOR_LOG_TS_ONLY 1 //only print log sensor data TS , FIFO Timestampe is only available in fifo mode
#define SENSOR_DIRECTION 0 // 0~7 sensorConvert map index below
/* { { 1, 1, 1}, {0, 1, 2} },
{ { -1, 1, 1}, {1, 0, 2} },
{ { -1, -1, 1}, {0, 1, 2} },
{ { 1, -1, 1}, {1, 0, 2} },
{ { -1, 1, -1}, {0, 1, 2} },
{ { 1, 1, -1}, {1, 0, 2} },
{ { 1, -1, -1}, {0, 1, 2} },
{ { -1, -1, -1}, {1, 0, 2} }, */
// For Xian the max FIFO size is 2048 Bytes; common FIFO package is 16 Bytes; so the max number of FIFO pakage is ~128.
#define MAX_RECV_PACKET 128
/* Initial WOM threshold to be applied to IMU in mg */
#define WOM_THRESHOLD_INITIAL_MG 200
/* WOM threshold to be applied to IMU, ranges from 1 to 255, in 4mg unit */
#define WOM_THRESHOLD WOM_THRESHOLD_INITIAL_MG/3
#define WOM_THRESHOLD_X WOM_THRESHOLD
#define WOM_THRESHOLD_Y WOM_THRESHOLD
#define WOM_THRESHOLD_Z WOM_THRESHOLD
#if 0
/* customer board, need invoke system marco*/
#define INV_LOG //define INV_LOG(loglevel,fmt,arg...) printf("ICM4n607: "fmt"\n",##arg)
//#define INV_LOG(loglevel,fmt, args...) pr_err("INV icm4n607 "fmt"\n",##args)
//#define INV_MSG(loglevel,fmt, args...) pr_err("INV icm4n607 "fmt"\n",##args)
#define EXIT(a) ;
#else
/* smart motion board*/
#include "Message.h"
#define INV_LOG INV_MSG
#define EXIT(a) exit(a)
#endif
/** @brief enumeration of serial interfaces available on IMU */
typedef enum
{
UI_I2C,
UI_SPI4,
UI_SPI3
} SERIAL_IF_TYPE_t;
#ifdef __cplusplus
}
#endif // __cplusplus
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES unity test_utils icm42670)
@@ -0,0 +1,5 @@
#
#Component Makefile
#
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
@@ -0,0 +1,273 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software? is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/* std */
#include <stdio.h>
/* board driver */
#include "common.h"
#include "uart_mngr.h"
#include "delay.h"
#include "gpio.h"
#include "timer.h"
#include "system_interface.h"
/* InvenSense utils */
#include "Invn/EmbUtils/Message.h"
#include "Invn/EmbUtils/RingBuffer.h"
#include "inv_imu_driver.h"
/*
* Select UART port on which INV_MSG() will be printed.
*/
#define LOG_UART_ID INV_UART_SENSOR_CTRL
/*
* Define msg level
*/
#define MSG_LEVEL INV_MSG_LEVEL_DEBUG
/*
* Set of timers used throughout standalone applications
*/
#define TIMEBASE_TIMER INV_TIMER1
#define DELAY_TIMER INV_TIMER2
#if !USE_FIFO
/*
* Buffer to keep track of the timestamp when IMU data ready interrupt fires.
* The buffer can contain up to 64 items in order to store one timestamp for each packet in FIFO.
*/
RINGBUFFER(timestamp_buffer, 64, uint64_t);
#endif
/* --------------------------------------------------------------------------------------
* Static variables
* -------------------------------------------------------------------------------------- */
/* Flag set from IMU device irq handler */
static volatile int irq_from_device;
/* --------------------------------------------------------------------------------------
* Forward declaration
* -------------------------------------------------------------------------------------- */
static int setup_mcu();
static void ext_interrupt_cb(void * context, unsigned int int_num);
void msg_printer(int level, const char * str, va_list ap);
/* --------------------------------------------------------------------------------------
* Functions definitions
* -------------------------------------------------------------------------------------- */
/*
* This function initializes MCU on which this software is running.
* It configures:
* - a UART link used to print some messages
* - interrupt priority group and GPIO so that MCU can receive interrupts from IMU
* - a microsecond timer requested by IMU driver to compute some delay
* - a microsecond timer used to get some timestamps
* - a serial link to communicate from MCU to IMU
*/
static int setup_mcu()
{
int rc = 0;
platform_io_hal_board_init();
/* configure UART */
config_uart(LOG_UART_ID);
/* Setup message facility to see internal traces from FW */
PLATFORM_MSG_SETUP(MSG_LEVEL, msg_printer);
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
INV_MSG(INV_MSG_LEVEL_INFO, "# #XIAN MCU Driver V1.0 FF EXAMPLE #");
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
/*
* Configure input capture mode GPIO connected to pin EXT3-9 (pin PB03).
* This pin is connected to Icm406xx INT1 output and thus will receive interrupts
* enabled on INT1 from the device.
* A callback function is also passed that will be executed each time an interrupt
* fires.
*/
platform_gpio_sensor_irq_init(INV_GPIO_INT1, ext_interrupt_cb, 0);
/* Init timer peripheral for delay */
rc |= platform_delay_init(DELAY_TIMER);
/*
* Configure the timer for the timebase
*/
rc |= platform_timer_configure_timebase(1000000);
platform_timer_enable(TIMEBASE_TIMER);
inv_imu_set_serif(platform_io_hal_read_reg, platform_io_hal_write_reg);
inv_imu_set_delay(platform_delay_ms,platform_delay_us); //void (*delay_ms)(uint32_t), void (*delay_us)(uint32_t))
rc |= platform_io_hal_init();
return rc;
}
/*
* IMU interrupt handler.
* Function is executed when an IMU interrupt rises on MCU.
* This function get a timestamp and store it in the timestamp buffer.
* Note that this function is executed in an interrupt handler and thus no protection
* are implemented for shared variable timestamp_buffer.
*/
static void ext_interrupt_cb(void * context, unsigned int int_num)
{
(void)context;
#if !USE_FIFO
/*
* Read timestamp from the timer dedicated to timestamping
*/
uint64_t timestamp = platform_timer_get_counter(TIMEBASE_TIMER);
if(int_num == INV_GPIO_INT1) {
if (!RINGBUFFER_FULL(&timestamp_buffer))
RINGBUFFER_PUSH(&timestamp_buffer, &timestamp);
}
#endif
irq_from_device |= TO_MASK(int_num);
}
/* --------------------------------------------------------------------------------------
* Functions definition
* -------------------------------------------------------------------------------------- */
int setup_imu_device()
{
int rc = 0;
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize IMU!");
return rc;
}
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
return rc;
}
/* --------------------------------------------------------------------------------------
* Main
* -------------------------------------------------------------------------------------- */
int main(void)
{
int rc = 0;
bool ff_detect_result = false;
float freefall_distance = 0.0f;
rc |= setup_mcu();
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize INV concise driver!");
return rc;
}
INV_MSG(INV_MSG_LEVEL_INFO, "IMU device successfully initialized");
rc = inv_imu_freefall_enable() ;
if (rc != 0) {
INV_LOG(SENSOR_LOG_LEVEL, "freefall enable Failed. Do nothing %d", rc);
return rc;
}
int i = 0;
do {
/* Poll device for data */
if (irq_from_device & TO_MASK(INV_GPIO_INT1)) {
inv_disable_irq();
freefall_distance = inv_imu_freefall_get_event(&ff_detect_result);
INV_LOG(SENSOR_LOG_LEVEL, "ff result %d, cm %f",ff_detect_result,freefall_distance);
irq_from_device &= ~TO_MASK(INV_GPIO_INT1);
inv_enable_irq();
i++;
}
if (i == 30) {
rc = inv_imu_freefall_disable();
i++;
}
} while(1);
}
/*
* Printer function for message facility
*/
void msg_printer(int level, const char * str, va_list ap)
{
static char out_str[256]; /* static to limit stack usage */
unsigned idx = 0;
const char * s[INV_MSG_LEVEL_MAX] = {
"", // INV_MSG_LEVEL_OFF
"[E] ", // INV_MSG_LEVEL_ERROR
"[W] ", // INV_MSG_LEVEL_WARNING
"[I] ", // INV_MSG_LEVEL_INFO
"[V] ", // INV_MSG_LEVEL_VERBOSE
"[D] ", // INV_MSG_LEVEL_DEBUG
};
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s", s[level]);
if(idx >= (sizeof(out_str)))
return;
idx += vsnprintf(&out_str[idx], sizeof(out_str) - idx, str, ap);
if(idx >= (sizeof(out_str)))
return;
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "\r\n");
if(idx >= (sizeof(out_str)))
return;
platform_uart_mngr_puts(LOG_UART_ID, out_str, idx);
}
@@ -0,0 +1,277 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software? is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/* std */
#include <stdio.h>
/* board driver */
#include "common.h"
#include "uart_mngr.h"
#include "delay.h"
#include "gpio.h"
#include "timer.h"
#include "system_interface.h"
/* InvenSense utils */
#include "Invn/EmbUtils/Message.h"
#include "Invn/EmbUtils/RingBuffer.h"
#include "inv_imu_driver.h"
/*
* Select UART port on which INV_MSG() will be printed.
*/
#define LOG_UART_ID INV_UART_SENSOR_CTRL
/*
* Define msg level
*/
#define MSG_LEVEL INV_MSG_LEVEL_DEBUG
/*
* Set of timers used throughout standalone applications
*/
#define TIMEBASE_TIMER INV_TIMER1
#define DELAY_TIMER INV_TIMER2
#if !USE_FIFO
/*
* Buffer to keep track of the timestamp when IMU data ready interrupt fires.
* The buffer can contain up to 64 items in order to store one timestamp for each packet in FIFO.
*/
RINGBUFFER(timestamp_buffer, 64, uint64_t);
#endif
/* --------------------------------------------------------------------------------------
* Static variables
* -------------------------------------------------------------------------------------- */
/* Flag set from IMU device irq handler */
static volatile int irq_from_device;
/* --------------------------------------------------------------------------------------
* Forward declaration
* -------------------------------------------------------------------------------------- */
static int setup_mcu();
static void ext_interrupt_cb(void * context, unsigned int int_num);
void msg_printer(int level, const char * str, va_list ap);
/* --------------------------------------------------------------------------------------
* Functions definitions
* -------------------------------------------------------------------------------------- */
/*
* This function initializes MCU on which this software is running.
* It configures:
* - a UART link used to print some messages
* - interrupt priority group and GPIO so that MCU can receive interrupts from IMU
* - a microsecond timer requested by IMU driver to compute some delay
* - a microsecond timer used to get some timestamps
* - a serial link to communicate from MCU to IMU
*/
static int setup_mcu()
{
int rc = 0;
platform_io_hal_board_init();
/* configure UART */
config_uart(LOG_UART_ID);
/* Setup message facility to see internal traces from FW */
PLATFORM_MSG_SETUP(MSG_LEVEL, msg_printer);
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
INV_MSG(INV_MSG_LEVEL_INFO, "# #XIAN MCU Driver V1.0 PEDO EXAMPLE#");
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
/*
* Configure input capture mode GPIO connected to pin EXT3-9 (pin PB03).
* This pin is connected to Icm406xx INT1 output and thus will receive interrupts
* enabled on INT1 from the device.
* A callback function is also passed that will be executed each time an interrupt
* fires.
*/
platform_gpio_sensor_irq_init(INV_GPIO_INT1, ext_interrupt_cb, 0);
/* Init timer peripheral for delay */
rc |= platform_delay_init(DELAY_TIMER);
/*
* Configure the timer for the timebase
*/
rc |= platform_timer_configure_timebase(1000000);
platform_timer_enable(TIMEBASE_TIMER);
inv_imu_set_serif(platform_io_hal_read_reg, platform_io_hal_write_reg);
inv_imu_set_delay(platform_delay_ms,platform_delay_us); //void (*delay_ms)(uint32_t), void (*delay_us)(uint32_t))
rc |= platform_io_hal_init();
return rc;
}
/*
* IMU interrupt handler.
* Function is executed when an IMU interrupt rises on MCU.
* This function get a timestamp and store it in the timestamp buffer.
* Note that this function is executed in an interrupt handler and thus no protection
* are implemented for shared variable timestamp_buffer.
*/
static void ext_interrupt_cb(void * context, unsigned int int_num)
{
(void)context;
#if !USE_FIFO
/*
* Read timestamp from the timer dedicated to timestamping
*/
uint64_t timestamp = platform_timer_get_counter(TIMEBASE_TIMER);
if(int_num == INV_GPIO_INT1) {
if (!RINGBUFFER_FULL(&timestamp_buffer))
RINGBUFFER_PUSH(&timestamp_buffer, &timestamp);
}
#endif
irq_from_device |= TO_MASK(int_num);
}
/* --------------------------------------------------------------------------------------
* Functions definition
* -------------------------------------------------------------------------------------- */
int setup_imu_device()
{
int rc = 0;
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize IMU!");
return rc;
}
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
return rc;
}
/* --------------------------------------------------------------------------------------
* Main
* -------------------------------------------------------------------------------------- */
int main(void)
{
int rc = 0;
APEX_DATA3_ACTIVITY_CLASS_t activity_class;
float cadence_step_per_sec;
int step_result = 0;
rc |= setup_mcu();
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize INV concise driver!");
return rc;
}
INV_MSG(INV_MSG_LEVEL_INFO, "IMU device successfully initialized");
rc = inv_imu_pedometer_enable() ;
if (rc != 0) {
INV_MSG(INV_MSG_LEVEL_INFO, "pedometer enable Failed. Do nothing %d", rc);
return rc;
}
int i = 0;
do {
/* Poll device for data */
if (irq_from_device & TO_MASK(INV_GPIO_INT1)) {
inv_disable_irq();
step_result = inv_imu_pedometer_get_event(&cadence_step_per_sec,&activity_class);
if(step_result < 0)
INV_MSG(INV_MSG_LEVEL_ERROR, "pedometer get event failure %d",step_result);
else
INV_MSG(INV_MSG_LEVEL_INFO, "step value %d, %.2f steps/sec, type %d",step_result,cadence_step_per_sec,activity_class);
irq_from_device &= ~TO_MASK(INV_GPIO_INT1);
inv_enable_irq();
i++;
}
if (i == 100) {
rc = inv_imu_pedometer_disable();
i++;
}
} while(1);
}
/*
* Printer function for message facility
*/
void msg_printer(int level, const char * str, va_list ap)
{
static char out_str[256]; /* static to limit stack usage */
unsigned idx = 0;
const char * s[INV_MSG_LEVEL_MAX] = {
"", // INV_MSG_LEVEL_OFF
"[E] ", // INV_MSG_LEVEL_ERROR
"[W] ", // INV_MSG_LEVEL_WARNING
"[I] ", // INV_MSG_LEVEL_INFO
"[V] ", // INV_MSG_LEVEL_VERBOSE
"[D] ", // INV_MSG_LEVEL_DEBUG
};
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s", s[level]);
if(idx >= (sizeof(out_str)))
return;
idx += vsnprintf(&out_str[idx], sizeof(out_str) - idx, str, ap);
if(idx >= (sizeof(out_str)))
return;
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "\r\n");
if(idx >= (sizeof(out_str)))
return;
platform_uart_mngr_puts(LOG_UART_ID, out_str, idx);
}
@@ -0,0 +1,396 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software? is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/* std */
#include <stdio.h>
/* board driver */
#include "common.h"
#include "uart_mngr.h"
#include "delay.h"
#include "gpio.h"
#include "timer.h"
#include "system_interface.h"
/* InvenSense utils */
#include "Invn/EmbUtils/Message.h"
#include "Invn/EmbUtils/RingBuffer.h"
#include "inv_imu_driver.h"
struct SensorData Acc_Receive_dataBuff[2048];
struct SensorData Gyro_Receive_dataBuff[2048];
AccDataPacket accData;
GyroDataPacket gyroData;
chip_temperature imu_chip_temperature;
uint32_t cur_index = 0;
/*
* Select UART port on which INV_MSG() will be printed.
*/
#define LOG_UART_ID INV_UART_SENSOR_CTRL
/*
* Define msg level
*/
#define MSG_LEVEL INV_MSG_LEVEL_DEBUG
/*
* Set of timers used throughout standalone applications
*/
#define TIMEBASE_TIMER INV_TIMER1
#define DELAY_TIMER INV_TIMER2
#define SENSOR_ODR_1600HZ 1600
#define SENSOR_ODR_800HZ 800
#define SENSOR_ODR_400HZ 400
#define SENSOR_ODR_200HZ 200
#define SENSOR_ODR_100HZ 100
#define SENSOR_ODR_50HZ 50
#define SENSOR_ODR_25HZ 25
#define SENSOR_ODR_12_5HZ 12.5
#if !USE_FIFO
/*
* Buffer to keep track of the timestamp when IMU data ready interrupt fires.
* The buffer can contain up to 64 items in order to store one timestamp for each packet in FIFO.
*/
RINGBUFFER(timestamp_buffer, 64, uint64_t);
#endif
/* --------------------------------------------------------------------------------------
* Static variables
* -------------------------------------------------------------------------------------- */
/* Flag set from IMU device irq handler */
static volatile int irq_from_device;
/* --------------------------------------------------------------------------------------
* Forward declaration
* -------------------------------------------------------------------------------------- */
static int setup_mcu();
static void ext_interrupt_cb(void * context, unsigned int int_num);
void msg_printer(int level, const char * str, va_list ap);
/* --------------------------------------------------------------------------------------
* Functions definitions
* -------------------------------------------------------------------------------------- */
/*
* This function initializes MCU on which this software is running.
* It configures:
* - a UART link used to print some messages
* - interrupt priority group and GPIO so that MCU can receive interrupts from IMU
* - a microsecond timer requested by IMU driver to compute some delay
* - a microsecond timer used to get some timestamps
* - a serial link to communicate from MCU to IMU
*/
static int setup_mcu()
{
int rc = 0;
platform_io_hal_board_init();
/* configure UART */
config_uart(LOG_UART_ID);
/* Setup message facility to see internal traces from FW */
PLATFORM_MSG_SETUP(MSG_LEVEL, msg_printer);
INV_MSG(INV_MSG_LEVEL_INFO, "######################");
INV_MSG(INV_MSG_LEVEL_INFO, "# Example Raw AG #");
INV_MSG(INV_MSG_LEVEL_INFO, "######################");
/*
* Configure input capture mode GPIO connected to pin EXT3-9 (pin PB03).
* This pin is connected to Icm406xx INT1 output and thus will receive interrupts
* enabled on INT1 from the device.
* A callback function is also passed that will be executed each time an interrupt
* fires.
*/
platform_gpio_sensor_irq_init(INV_GPIO_INT1, ext_interrupt_cb, 0);
/* Init timer peripheral for delay */
rc |= platform_delay_init(DELAY_TIMER);
/*
* Configure the timer for the timebase
*/
rc |= platform_timer_configure_timebase(1000000);
platform_timer_enable(TIMEBASE_TIMER);
inv_imu_set_serif(platform_io_hal_read_reg, platform_io_hal_write_reg);
inv_imu_set_delay(platform_delay_ms,platform_delay_us); //void (*delay_ms)(uint32_t), void (*delay_us)(uint32_t))
rc |= platform_io_hal_init();
return rc;
}
/*
* IMU interrupt handler.
* Function is executed when an IMU interrupt rises on MCU.
* This function get a timestamp and store it in the timestamp buffer.
* Note that this function is executed in an interrupt handler and thus no protection
* are implemented for shared variable timestamp_buffer.
*/
static void ext_interrupt_cb(void * context, unsigned int int_num)
{
(void)context;
#if !USE_FIFO
/*
* Read timestamp from the timer dedicated to timestamping
*/
uint64_t timestamp = platform_timer_get_counter(TIMEBASE_TIMER);
if(int_num == INV_GPIO_INT1) {
if (!RINGBUFFER_FULL(&timestamp_buffer))
RINGBUFFER_PUSH(&timestamp_buffer, &timestamp);
}
#endif
irq_from_device |= TO_MASK(int_num);
}
/* --------------------------------------------------------------------------------------
* Functions definition
* -------------------------------------------------------------------------------------- */
int setup_imu_device()
{
int rc = 0;
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize IMU!");
return rc;
}
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
return rc;
}
uint32_t get_imu_data()
{
inv_data_handler(&accData,&gyroData,&imu_chip_temperature,false);
if(accData.accDataSize != 0){
memcpy(&Acc_Receive_dataBuff[cur_index], &accData.databuff[0], accData.accDataSize * sizeof(accData.databuff[0]));
//INV_MSG(INV_MSG_LEVEL_ERROR, "acDS %u cidex %u",accData.accDataSize,cur_index);
}
if(gyroData.gyroDataSize != 0){
memcpy(&Gyro_Receive_dataBuff[cur_index], &gyroData.databuff[0], gyroData.gyroDataSize * sizeof(gyroData.databuff[0]));
}
if ((accData.accDataSize != 0) && (gyroData.gyroDataSize != 0))
cur_index = cur_index + (uint32_t)accData.accDataSize;
else if(accData.accDataSize != 0)
cur_index = cur_index + (uint32_t)accData.accDataSize;
else if(gyroData.gyroDataSize != 0)
cur_index = cur_index + (uint32_t)gyroData.gyroDataSize;
return 0;
}
/* --------------------------------------------------------------------------------------
* Main
* -------------------------------------------------------------------------------------- */
int main(void)
{
int rc = 0;
float hw_rate = 0.0;
memset(Acc_Receive_dataBuff,0,sizeof(Acc_Receive_dataBuff));
memset(Gyro_Receive_dataBuff,0,sizeof(Gyro_Receive_dataBuff));
rc |= setup_mcu();
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize INV concise driver!");
return rc;
}
INV_MSG(INV_MSG_LEVEL_INFO, "IMU device successfully initialized");
// We may customize full scale range here.
rc |= inv_imu_set_accel_fsr(ACCEL_CONFIG0_FS_SEL_4g);
rc |= inv_imu_set_gyro_fsr(GYRO_CONFIG0_FS_SEL_2000dps);
// Below settings are required to configure and enable sensors.
rc |= inv_imu_acc_enable();
rc |= inv_imu_acc_set_rate(SENSOR_ODR_400HZ, 2,&hw_rate); //200Hz ODR, watermark: 2 packets.
rc |= inv_imu_gyro_enable();
rc |= inv_imu_gyro_set_rate(SENSOR_ODR_400HZ, 4,&hw_rate); //50Hz ODR, watermark 4.
if (rc != 0) {
INV_LOG(SENSOR_LOG_LEVEL, "Feature enable Failed. Do nothing %d", rc);
return rc;
}
INV_LOG(SENSOR_LOG_LEVEL, "HW odr setting %f ", hw_rate);
do {
/* Poll device for data */
if (irq_from_device & TO_MASK(INV_GPIO_INT1)) {
get_imu_data();
//INV_MSG(INV_MSG_LEVEL_ERROR, "cur idex %lu!",cur_index);
inv_disable_irq();
irq_from_device &= ~TO_MASK(INV_GPIO_INT1);
inv_enable_irq();
}
} while(cur_index <2048);
rc |= inv_imu_acc_disable();
rc |= inv_imu_gyro_disable();
#if SENSOR_LOG_TS_ONLY
uint32_t i;
for(i=0;i< cur_index; i++){
INV_LOG(SENSOR_LOG_LEVEL, "ACC %d TS %lld ", i+1,Acc_Receive_dataBuff[i].timeStamp);
platform_delay_ms(5);
}
for(i=0;i< cur_index; i++){
INV_LOG(SENSOR_LOG_LEVEL, "Gyro %d TS %lld ", i+1,Gyro_Receive_dataBuff[i].timeStamp);
platform_delay_ms(5);
}
#endif
// following code is just repeating the previous code, just to confirm the testing could be alwasys run
int j = 2;
while(1){
memset(Acc_Receive_dataBuff,0,sizeof(Acc_Receive_dataBuff));
memset(Gyro_Receive_dataBuff,0,sizeof(Gyro_Receive_dataBuff));
memset(&accData,0,sizeof(accData));
memset(&gyroData,0,sizeof(gyroData));
INV_LOG(SENSOR_LOG_LEVEL, "repeating test round %d", j);
// Below settings are required to configure and enable sensors.
rc |= inv_imu_acc_enable();
rc |= inv_imu_acc_set_rate(SENSOR_ODR_200HZ, 2,&hw_rate); //200Hz ODR, watermark: 2 packets.
rc |= inv_imu_gyro_enable();
rc |= inv_imu_gyro_set_rate(SENSOR_ODR_200HZ, 4,&hw_rate); //50Hz ODR, watermark 4.
if (rc != 0) {
INV_LOG(SENSOR_LOG_LEVEL, "Feature enable Failed. Do nothing %d", rc);
return rc;
}
INV_LOG(SENSOR_LOG_LEVEL, "HW odr setting %f ", hw_rate);
cur_index = 0;
do {
/* Poll device for data */
if (irq_from_device & TO_MASK(INV_GPIO_INT1)) {
get_imu_data();
//INV_MSG(INV_MSG_LEVEL_ERROR, "cur idex %lu!",cur_index);
inv_disable_irq();
irq_from_device &= ~TO_MASK(INV_GPIO_INT1);
inv_enable_irq();
}
} while(cur_index <2048);
rc |= inv_imu_acc_disable();
rc |= inv_imu_gyro_disable();
#if SENSOR_LOG_TS_ONLY
for(i=0;i< cur_index; i++){
INV_LOG(SENSOR_LOG_LEVEL, "ACC %d TS %lld ", i+1,Acc_Receive_dataBuff[i].timeStamp);
platform_delay_ms(5);
}
for(i=0;i< cur_index; i++){
INV_LOG(SENSOR_LOG_LEVEL, "Gyro %d TS %lld ", i+1,Gyro_Receive_dataBuff[i].timeStamp);
platform_delay_ms(5);
}
#endif
j++;
}
}
/*
* Printer function for message facility
*/
void msg_printer(int level, const char * str, va_list ap)
{
static char out_str[256]; /* static to limit stack usage */
unsigned idx = 0;
const char * s[INV_MSG_LEVEL_MAX] = {
"", // INV_MSG_LEVEL_OFF
"[E] ", // INV_MSG_LEVEL_ERROR
"[W] ", // INV_MSG_LEVEL_WARNING
"[I] ", // INV_MSG_LEVEL_INFO
"[V] ", // INV_MSG_LEVEL_VERBOSE
"[D] ", // INV_MSG_LEVEL_DEBUG
};
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s", s[level]);
if(idx >= (sizeof(out_str)))
return;
idx += vsnprintf(&out_str[idx], sizeof(out_str) - idx, str, ap);
if(idx >= (sizeof(out_str)))
return;
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "\r\n");
if(idx >= (sizeof(out_str)))
return;
platform_uart_mngr_puts(LOG_UART_ID, out_str, idx);
}
@@ -0,0 +1,266 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software? is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/* std */
#include <stdio.h>
/* board driver */
#include "common.h"
#include "uart_mngr.h"
#include "delay.h"
#include "gpio.h"
#include "timer.h"
#include "system_interface.h"
/* InvenSense utils */
#include "Invn/EmbUtils/Message.h"
#include "Invn/EmbUtils/RingBuffer.h"
#include "inv_imu_driver.h"
/*
* Select UART port on which INV_MSG() will be printed.
*/
#define LOG_UART_ID INV_UART_SENSOR_CTRL
/*
* Define msg level
*/
#define MSG_LEVEL INV_MSG_LEVEL_DEBUG
/*
* Set of timers used throughout standalone applications
*/
#define TIMEBASE_TIMER INV_TIMER1
#define DELAY_TIMER INV_TIMER2
#if !USE_FIFO
/*
* Buffer to keep track of the timestamp when IMU data ready interrupt fires.
* The buffer can contain up to 64 items in order to store one timestamp for each packet in FIFO.
*/
RINGBUFFER(timestamp_buffer, 64, uint64_t);
#endif
/* --------------------------------------------------------------------------------------
* Static variables
* -------------------------------------------------------------------------------------- */
/* Flag set from IMU device irq handler */
static volatile int irq_from_device;
/* --------------------------------------------------------------------------------------
* Forward declaration
* -------------------------------------------------------------------------------------- */
static int setup_mcu();
static void ext_interrupt_cb(void * context, unsigned int int_num);
void msg_printer(int level, const char * str, va_list ap);
/* --------------------------------------------------------------------------------------
* Functions definitions
* -------------------------------------------------------------------------------------- */
/*
* This function initializes MCU on which this software is running.
* It configures:
* - a UART link used to print some messages
* - interrupt priority group and GPIO so that MCU can receive interrupts from IMU
* - a microsecond timer requested by IMU driver to compute some delay
* - a microsecond timer used to get some timestamps
* - a serial link to communicate from MCU to IMU
*/
static int setup_mcu()
{
int rc = 0;
platform_io_hal_board_init();
/* configure UART */
config_uart(LOG_UART_ID);
/* Setup message facility to see internal traces from FW */
PLATFORM_MSG_SETUP(MSG_LEVEL, msg_printer);
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
INV_MSG(INV_MSG_LEVEL_INFO, "# #XIAN MCU Driver V1.0 SELFTEST EX #");
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
/*
* Configure input capture mode GPIO connected to pin EXT3-9 (pin PB03).
* This pin is connected to Icm406xx INT1 output and thus will receive interrupts
* enabled on INT1 from the device.
* A callback function is also passed that will be executed each time an interrupt
* fires.
*/
platform_gpio_sensor_irq_init(INV_GPIO_INT1, ext_interrupt_cb, 0);
/* Init timer peripheral for delay */
rc |= platform_delay_init(DELAY_TIMER);
/*
* Configure the timer for the timebase
*/
rc |= platform_timer_configure_timebase(1000000);
platform_timer_enable(TIMEBASE_TIMER);
inv_imu_set_serif(platform_io_hal_read_reg, platform_io_hal_write_reg);
inv_imu_set_delay(platform_delay_ms,platform_delay_us); //void (*delay_ms)(uint32_t), void (*delay_us)(uint32_t))
rc |= platform_io_hal_init();
return rc;
}
/*
* IMU interrupt handler.
* Function is executed when an IMU interrupt rises on MCU.
* This function get a timestamp and store it in the timestamp buffer.
* Note that this function is executed in an interrupt handler and thus no protection
* are implemented for shared variable timestamp_buffer.
*/
static void ext_interrupt_cb(void * context, unsigned int int_num)
{
(void)context;
#if !USE_FIFO
/*
* Read timestamp from the timer dedicated to timestamping
*/
uint64_t timestamp = platform_timer_get_counter(TIMEBASE_TIMER);
if(int_num == INV_GPIO_INT1) {
if (!RINGBUFFER_FULL(&timestamp_buffer))
RINGBUFFER_PUSH(&timestamp_buffer, &timestamp);
}
#endif
irq_from_device |= TO_MASK(int_num);
}
/* --------------------------------------------------------------------------------------
* Functions definition
* -------------------------------------------------------------------------------------- */
int setup_imu_device()
{
int rc = 0;
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize IMU!");
return rc;
}
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
return rc;
}
/* --------------------------------------------------------------------------------------
* Main
* -------------------------------------------------------------------------------------- */
int main(void)
{
int rc = 0;
uint8_t acc_control = 1;
uint8_t gyro_control = 1;
struct inv_imu_selftest_output selftest_result;
rc |= setup_mcu();
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize INV concise driver!");
return rc;
}
INV_MSG(INV_MSG_LEVEL_INFO, "IMU device successfully initialized");
rc |= inv_imu_run_selftest(acc_control,gyro_control, &selftest_result);
if (rc != 0) {
INV_LOG(SENSOR_LOG_LEVEL, "selftest run failure. Do nothing %d", rc);
return rc;
}
if (selftest_result.accel_status == 0x1)
INV_LOG(SENSOR_LOG_LEVEL, "accel Selftest PASS\n");
else
INV_LOG(SENSOR_LOG_LEVEL, "accel Selftest fail\n");
if (selftest_result.gyro_status == 0x1)
INV_LOG(SENSOR_LOG_LEVEL, "gyro Selftest PASS\n");
else
INV_LOG(SENSOR_LOG_LEVEL, "gyro Selftest fail\n");
do {
} while(1);
}
/*
* Printer function for message facility
*/
void msg_printer(int level, const char * str, va_list ap)
{
static char out_str[256]; /* static to limit stack usage */
unsigned idx = 0;
const char * s[INV_MSG_LEVEL_MAX] = {
"", // INV_MSG_LEVEL_OFF
"[E] ", // INV_MSG_LEVEL_ERROR
"[W] ", // INV_MSG_LEVEL_WARNING
"[I] ", // INV_MSG_LEVEL_INFO
"[V] ", // INV_MSG_LEVEL_VERBOSE
"[D] ", // INV_MSG_LEVEL_DEBUG
};
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s", s[level]);
if(idx >= (sizeof(out_str)))
return;
idx += vsnprintf(&out_str[idx], sizeof(out_str) - idx, str, ap);
if(idx >= (sizeof(out_str)))
return;
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "\r\n");
if(idx >= (sizeof(out_str)))
return;
platform_uart_mngr_puts(LOG_UART_ID, out_str, idx);
}
@@ -0,0 +1,273 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software? is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/* std */
#include <stdio.h>
/* board driver */
#include "common.h"
#include "uart_mngr.h"
#include "delay.h"
#include "gpio.h"
#include "timer.h"
#include "system_interface.h"
/* InvenSense utils */
#include "Invn/EmbUtils/Message.h"
#include "Invn/EmbUtils/RingBuffer.h"
#include "inv_imu_driver.h"
/*
* Select UART port on which INV_MSG() will be printed.
*/
#define LOG_UART_ID INV_UART_SENSOR_CTRL
/*
* Define msg level
*/
#define MSG_LEVEL INV_MSG_LEVEL_DEBUG
/*
* Set of timers used throughout standalone applications
*/
#define TIMEBASE_TIMER INV_TIMER1
#define DELAY_TIMER INV_TIMER2
#if !USE_FIFO
/*
* Buffer to keep track of the timestamp when IMU data ready interrupt fires.
* The buffer can contain up to 64 items in order to store one timestamp for each packet in FIFO.
*/
RINGBUFFER(timestamp_buffer, 64, uint64_t);
#endif
/* --------------------------------------------------------------------------------------
* Static variables
* -------------------------------------------------------------------------------------- */
/* Flag set from IMU device irq handler */
static volatile int irq_from_device;
/* --------------------------------------------------------------------------------------
* Forward declaration
* -------------------------------------------------------------------------------------- */
static int setup_mcu();
static void ext_interrupt_cb(void * context, unsigned int int_num);
void msg_printer(int level, const char * str, va_list ap);
/* --------------------------------------------------------------------------------------
* Functions definitions
* -------------------------------------------------------------------------------------- */
/*
* This function initializes MCU on which this software is running.
* It configures:
* - a UART link used to print some messages
* - interrupt priority group and GPIO so that MCU can receive interrupts from IMU
* - a microsecond timer requested by IMU driver to compute some delay
* - a microsecond timer used to get some timestamps
* - a serial link to communicate from MCU to IMU
*/
static int setup_mcu()
{
int rc = 0;
platform_io_hal_board_init();
/* configure UART */
config_uart(LOG_UART_ID);
/* Setup message facility to see internal traces from FW */
PLATFORM_MSG_SETUP(MSG_LEVEL, msg_printer);
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
INV_MSG(INV_MSG_LEVEL_INFO, "# #XIAN MCU Driver V1.0 WOM EXAMPLE #");
INV_MSG(INV_MSG_LEVEL_INFO, "######################################");
/*
* Configure input capture mode GPIO connected to pin EXT3-9 (pin PB03).
* This pin is connected to Icm406xx INT1 output and thus will receive interrupts
* enabled on INT1 from the device.
* A callback function is also passed that will be executed each time an interrupt
* fires.
*/
platform_gpio_sensor_irq_init(INV_GPIO_INT1, ext_interrupt_cb, 0);
/* Init timer peripheral for delay */
rc |= platform_delay_init(DELAY_TIMER);
/*
* Configure the timer for the timebase
*/
rc |= platform_timer_configure_timebase(1000000);
platform_timer_enable(TIMEBASE_TIMER);
inv_imu_set_serif(platform_io_hal_read_reg, platform_io_hal_write_reg);
inv_imu_set_delay(platform_delay_ms,platform_delay_us); //void (*delay_ms)(uint32_t), void (*delay_us)(uint32_t))
rc |= platform_io_hal_init();
return rc;
}
/*
* IMU interrupt handler.
* Function is executed when an IMU interrupt rises on MCU.
* This function get a timestamp and store it in the timestamp buffer.
* Note that this function is executed in an interrupt handler and thus no protection
* are implemented for shared variable timestamp_buffer.
*/
static void ext_interrupt_cb(void * context, unsigned int int_num)
{
(void)context;
#if !USE_FIFO
/*
* Read timestamp from the timer dedicated to timestamping
*/
uint64_t timestamp = platform_timer_get_counter(TIMEBASE_TIMER);
if(int_num == INV_GPIO_INT1) {
if (!RINGBUFFER_FULL(&timestamp_buffer))
RINGBUFFER_PUSH(&timestamp_buffer, &timestamp);
}
#endif
irq_from_device |= TO_MASK(int_num);
}
/* --------------------------------------------------------------------------------------
* Functions definition
* -------------------------------------------------------------------------------------- */
int setup_imu_device()
{
int rc = 0;
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize IMU!");
return rc;
}
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
return rc;
}
/* --------------------------------------------------------------------------------------
* Main
* -------------------------------------------------------------------------------------- */
int main(void)
{
int rc = 0;
bool wom_detect_result = false;
int wom_flag;
rc |= setup_mcu();
#if !USE_FIFO
RINGBUFFER_CLEAR(&timestamp_buffer);
#endif
/* Init device */
rc = inv_imu_initialize();
if (rc != INV_ERROR_SUCCESS) {
INV_MSG(INV_MSG_LEVEL_ERROR, "Failed to initialize INV concise driver!");
return rc;
}
INV_MSG(INV_MSG_LEVEL_INFO, "IMU device successfully initialized");
rc += inv_imu_wom_enable(WOM_THRESHOLD_X,WOM_THRESHOLD_Y,WOM_THRESHOLD_Z,WOM_CONFIG_WOM_INT_DUR_4_SMPL);
if (rc != 0) {
INV_LOG(SENSOR_LOG_LEVEL, "Feature enable Failed. Do nothing %d", rc);
return rc;
}
int i = 0;
do {
/* Poll device for data */
if (irq_from_device & TO_MASK(INV_GPIO_INT1)) {
inv_disable_irq();
wom_flag = inv_imu_wom_get_event(&wom_detect_result);
INV_LOG(SENSOR_LOG_LEVEL, "wom result %d, flag %x",wom_detect_result,wom_flag);
irq_from_device &= ~TO_MASK(INV_GPIO_INT1);
inv_enable_irq();
i++;
}
if (i == 20) {
rc = inv_imu_wom_disable();
i++;
}
} while(1);
}
/*
* Printer function for message facility
*/
void msg_printer(int level, const char * str, va_list ap)
{
static char out_str[256]; /* static to limit stack usage */
unsigned idx = 0;
const char * s[INV_MSG_LEVEL_MAX] = {
"", // INV_MSG_LEVEL_OFF
"[E] ", // INV_MSG_LEVEL_ERROR
"[W] ", // INV_MSG_LEVEL_WARNING
"[I] ", // INV_MSG_LEVEL_INFO
"[V] ", // INV_MSG_LEVEL_VERBOSE
"[D] ", // INV_MSG_LEVEL_DEBUG
};
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s", s[level]);
if(idx >= (sizeof(out_str)))
return;
idx += vsnprintf(&out_str[idx], sizeof(out_str) - idx, str, ap);
if(idx >= (sizeof(out_str)))
return;
idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "\r\n");
if(idx >= (sizeof(out_str)))
return;
platform_uart_mngr_puts(LOG_UART_ID, out_str, idx);
}
@@ -0,0 +1,50 @@
// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "stdio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/timers.h"
#include "esp_log.h"
#include "unity.h"
#include "icm42670.h"
static const char *TAG = "IMU TEST";
static void icm42670_test(void *args)
{
AccDataPacket accData;
GyroDataPacket gyroData;
chip_temperature imu_chip_temperature;
icm42670_init();
while (1) {
int ret = icm42670_get_raw_data(&accData, &gyroData, &imu_chip_temperature);
if (0 == ret) {
INV_LOG(SENSOR_LOG_LEVEL, "temperature=%.1f", imu_chip_temperature);
INV_LOG(SENSOR_LOG_LEVEL, "ACC %d (%.1f, %.1f, %.1f)", accData.accDataSize, accData.databuff[0].x, accData.databuff[0].y, accData.databuff[0].z);
INV_LOG(SENSOR_LOG_LEVEL, "Gyro%d (%.1f, %.1f, %.1f)", gyroData.gyroDataSize, gyroData.databuff[0].x, gyroData.databuff[0].y, gyroData.databuff[0].z);
} else {
INV_LOG(INV_LOG_LEVEL_ERROR, "read err");
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
TEST_CASE("ICM42670 test", "[imu][cube]")
{
icm42670_test(NULL);
}