return of the test + more documentation

This commit is contained in:
myles-parfeniuk 2024-11-27 15:54:47 -08:00
parent 71e276e76a
commit e4e6d67e40
60 changed files with 2711 additions and 150 deletions

View File

@ -79,6 +79,28 @@ menu "esp32_BNO08x"
Amount of SPI transactions that can be queued during operation. Amount of SPI transactions that can be queued during operation.
This argument is loaded directly into the spi_device_interface_config_t struct used for SPI configuration. This argument is loaded directly into the spi_device_interface_config_t struct used for SPI configuration.
config ESP32_BNO08X_HINT_TIMEOUT_MS
int "HINT TIMEOUT (ms)"
range 100 10000
default 500
help
Max wait between HINT being asserted by BNO08x before transaction is considered failed. (in miliseconds).
config ESP32_BNO08X_DATA_AVAILABLE_TIMEOUT_MS
int "DATA AVAILABLE TIMEOUT (ms)"
range 100 10000
default 3000
help
Max wait between data_available() being called and no new data/report being detected. (in miliseconds).
config ESP32_BNO08X_HARD_RESET_DELAY_MS
int "HARD RESET DELAY (ms)"
range 100 10000
default 100
help
How long RST pin is held low during hard reset (min 10ns according to datasheet,
but should be longer for stable operation). Not recommended to lower below 100ms.
endmenu #SPI Configuration endmenu #SPI Configuration
menu "Logging" menu "Logging"
@ -97,7 +119,7 @@ menu "esp32_BNO08x"
endmenu #Logging endmenu #Logging
menu "Callbacks" menu "Callbacks & Tasks"
config ESP32_BNO08X_CB_TASK_SZ config ESP32_BNO08X_CB_TASK_SZ
int "Callback task size, (cb_task())" int "Callback task size, (cb_task())"
@ -108,6 +130,30 @@ menu "esp32_BNO08x"
Note that callbacks should remain as short as possible, pass the data out of Note that callbacks should remain as short as possible, pass the data out of
the callback with a queue or save it to different variables for longer operations. the callback with a queue or save it to different variables for longer operations.
endmenu #Callbacks config ESP32_BNO08X_CB_QUEUE_SZ
int "Callback queue size."
range 1 200
default 16
help
Amount of callbacks that can be in the air/pending to be executed at any given time.
config ESP32_BNO08X_DATA_PROC_TASK_SZ
int "Data processing task size, (data_proc_task())"
range 1024 20480
default 2048
help
Stack size of task responsible for parsing/handling sensor events sent by SH2 HAL and
updating data that is returned to user.
config ESP32_BNO08X_SH2_HAL_SERVICE_TASK_SZ
int "Data processing task size, (data_proc_task())"
range 1024 20480
default 4096
help
Stack size of task responsible for calling shtp_service() when HINT is asserted,
to dispatch any sh2 HAL lib callbacks.
endmenu #Callbacks & Tasks
endmenu endmenu

View File

@ -2,10 +2,10 @@
* @file BNO08x.hpp * @file BNO08x.hpp
* @author Myles Parfeniuk * @author Myles Parfeniuk
*/ */
#pragma once #pragma once
// standard library includes // standard library includes
#include <functional>
#include <variant> #include <variant>
#include <vector> #include <vector>
#include <map> #include <map>
@ -119,7 +119,6 @@ class BNO08x
bool data_proc_task; ///< True if xTaskCreate has been called successfully for data_proc_task. bool data_proc_task; ///< True if xTaskCreate has been called successfully for data_proc_task.
bool sh2_HAL_service_task; ///< True if xTaskCreate has been called successfully for sh2_HAL_service_task. bool sh2_HAL_service_task; ///< True if xTaskCreate has been called successfully for sh2_HAL_service_task.
bool cb_task; ///< True if xTaskCreate has been called successfully for cb_task. bool cb_task; ///< True if xTaskCreate has been called successfully for cb_task.
uint8_t task_init_cnt; ///< Amount of tasks that have been successfully initialized.
bno08x_init_status_t() bno08x_init_status_t()
: gpio_outputs(false) : gpio_outputs(false)
@ -131,7 +130,6 @@ class BNO08x
, data_proc_task(false) , data_proc_task(false)
, sh2_HAL_service_task(false) , sh2_HAL_service_task(false)
, cb_task(false) , cb_task(false)
, task_init_cnt(0)
{ {
} }
} bno08x_init_status_t; } bno08x_init_status_t;
@ -145,13 +143,15 @@ class BNO08x
} bno08x_cb_data_t; } bno08x_cb_data_t;
// data processing task // data processing task
static const constexpr configSTACK_DEPTH_TYPE DATA_PROC_TASK_SZ = 2048UL; ///< Size of data_proc_task() stack in bytes static const constexpr configSTACK_DEPTH_TYPE DATA_PROC_TASK_SZ =
CONFIG_ESP32_BNO08X_DATA_PROC_TASK_SZ; ///< Size of data_proc_task() stack in bytes
TaskHandle_t data_proc_task_hdl; ///<data_proc_task() task handle TaskHandle_t data_proc_task_hdl; ///<data_proc_task() task handle
static void data_proc_task_trampoline(void* arg); static void data_proc_task_trampoline(void* arg);
void data_proc_task(); void data_proc_task();
// sh2 service task // sh2 service task
static const constexpr configSTACK_DEPTH_TYPE SH2_HAL_SERVICE_TASK_SZ = 4095UL; ///< Size of sh2_HAL_service_task() stack in bytes static const constexpr configSTACK_DEPTH_TYPE SH2_HAL_SERVICE_TASK_SZ =
CONFIG_ESP32_BNO08X_SH2_HAL_SERVICE_TASK_SZ; ///< Size of sh2_HAL_service_task() stack in bytes
TaskHandle_t sh2_HAL_service_task_hdl; ///<sh2_HAL_service_task() task handle TaskHandle_t sh2_HAL_service_task_hdl; ///<sh2_HAL_service_task() task handle
static void sh2_HAL_service_task_trampoline(void* arg); static void sh2_HAL_service_task_trampoline(void* arg);
void sh2_HAL_service_task(); void sh2_HAL_service_task();
@ -172,6 +172,7 @@ class BNO08x
void unlock_user_data(); void unlock_user_data();
void handle_sensor_report(sh2_SensorValue_t* sensor_val); void handle_sensor_report(sh2_SensorValue_t* sensor_val);
void handle_cb(uint8_t rpt_ID, bno08x_cb_data_t& cb_entry);
esp_err_t init_config_args(); esp_err_t init_config_args();
esp_err_t init_gpio(); esp_err_t init_gpio();
@ -236,14 +237,15 @@ class BNO08x
static const constexpr uint16_t RX_DATA_LENGTH = 300U; ///<length buffer containing data received over spi static const constexpr uint16_t RX_DATA_LENGTH = 300U; ///<length buffer containing data received over spi
static const constexpr TickType_t HOST_INT_TIMEOUT_DEFAULT_MS = static const constexpr TickType_t HOST_INT_TIMEOUT_DEFAULT_MS =
500UL / CONFIG_ESP32_BNO08X_HINT_TIMEOUT_MS /
portTICK_PERIOD_MS; ///<Max wait between HINT being asserted by BNO08x before transaction is considered failed (in miliseconds), when no reports are enabled (ie during reset) portTICK_PERIOD_MS; ///<Max wait between HINT being asserted by BNO08x before transaction is considered failed (in miliseconds).
static const constexpr TickType_t DATA_AVAILABLE_TIMEOUT_MS = static const constexpr TickType_t DATA_AVAILABLE_TIMEOUT_MS =
3000UL / portTICK_PERIOD_MS; ///<Max wait between data_available() being called and no new data/report being detected. CONFIG_ESP32_BNO08X_DATA_AVAILABLE_TIMEOUT_MS /
portTICK_PERIOD_MS; ///<Max wait between data_available() being called and no new data/report being detected.
static const constexpr TickType_t HARD_RESET_DELAY_MS = static const constexpr TickType_t HARD_RESET_DELAY_MS =
100UL / CONFIG_ESP32_BNO08X_HARD_RESET_DELAY_MS /
portTICK_PERIOD_MS; ///<How long RST pin is held low during hard reset (min 10ns according to datasheet, but should be longer for stable operation) portTICK_PERIOD_MS; ///<How long RST pin is held low during hard reset (min 10ns according to datasheet, but should be longer for stable operation)
static const constexpr uint32_t SCLK_MAX_SPEED = 3000000UL; ///<Max SPI SCLK speed BNO08x is capable of. static const constexpr uint32_t SCLK_MAX_SPEED = 3000000UL; ///<Max SPI SCLK speed BNO08x is capable of.
@ -301,6 +303,7 @@ class BNO08x
// we have a lot of friends // we have a lot of friends
friend class BNO08xSH2HAL; friend class BNO08xSH2HAL;
friend class BNO08xTestHelper;
friend class BNO08xRpt; friend class BNO08xRpt;
friend class BNO08xRptRVGeneric; friend class BNO08xRptRVGeneric;
friend class BNO08xRptRV; friend class BNO08xRptRV;

View File

@ -1,7 +1,13 @@
/**
* @file BNO08xRpt.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include <stdint.h> // standard library includes
#include <functional> #include <functional>
// in-house includes
#include "BNO08x_global_types.hpp" #include "BNO08x_global_types.hpp"
// forward dec to prevent compile errors // forward dec to prevent compile errors

View File

@ -2,6 +2,7 @@
* @file BNO08xSH2HAL.hpp * @file BNO08xSH2HAL.hpp
* @author Myles Parfeniuk * @author Myles Parfeniuk
*/ */
#pragma once #pragma once
// hill-crest labs includes (apache 2.0 license, compatible with MIT) // hill-crest labs includes (apache 2.0 license, compatible with MIT)

View File

@ -0,0 +1,255 @@
/**
* @file BNO08xTestHelper.hpp
* @author Myles Parfeniuk
*/
#pragma once
// standard library includes
#include <stdio.h>
// in-house includes
#include "BNO08x.hpp"
/**
* @class BNO08xTestHelper
*
* @brief BNO08x unit test helper class.
* */
class BNO08xTestHelper
{
private:
inline static BNO08x* test_imu = nullptr;
inline static bno08x_config_t imu_cfg;
static const constexpr char* TAG = "BNO08xTestHelper";
public:
/**
* @brief Prints test begin banner.
*
* @param TEST_TAG String containing test name.
*
* @return void, nothing to return
*/
static void print_test_start_banner(const char* TEST_TAG)
{
printf("------------------------ BEGIN TEST: %s ------------------------\n\r", TEST_TAG);
}
/**
* @brief Prints end begin banner.
*
* @param TEST_TAG String containing test name.
*
* @return void, nothing to return
*/
static void print_test_end_banner(const char* TEST_TAG)
{
printf("------------------------ END TEST: %s ------------------------\n\r", TEST_TAG);
}
/**
* @brief Prints a message during a test.
*
* @param TEST_TAG String containing test name.
* @param msg String containing message to print.
*
* @return void, nothing to return
*/
static void print_test_msg(const char* TEST_TAG, const char* msg)
{
printf("%s: %s: %s\n\r", TAG, TEST_TAG, msg);
}
/**
* @brief Set test imu configuration used with create_test_imu()
*
* @param cfg String containing test name.
*
* @return void, nothing to return
*/
static void set_test_imu_cfg(bno08x_config_t cfg)
{
imu_cfg = cfg;
}
/**
* @brief Calls BNO08x constructor and creates new test IMU on heap.
*
* @return void, nothing to return
*/
static void create_test_imu()
{
if (test_imu != nullptr)
destroy_test_imu();
test_imu = new BNO08x();
}
/**
* @brief Deletes test IMU calling deconstructor and releases heap allocated memory.
*
* @return void, nothing to return
*/
static void destroy_test_imu()
{
if (test_imu != nullptr)
{
delete test_imu;
test_imu = nullptr;
}
}
/**
* @brief Deletes test IMU calling deconstructor and releases heap allocated memory.
*
* @return Pointer to BNO08x IMU object to test.
*/
static BNO08x* get_test_imu()
{
return test_imu;
}
/**
* @brief Used to call private BNO08x::init_config_args() member for tests.
*
* @return ESP_OK if init succeeded.
*/
static esp_err_t call_init_config_args()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->init_config_args();
}
/**
* @brief Used to call private BNO08x::init_gpio() member for tests.
*
* @return ESP_OK if init succeeded.
*/
static esp_err_t call_init_gpio()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->init_gpio();
}
/**
* @brief Used to call private BNO08x::init_hint_isr() member for tests.
*
* @return ESP_OK if init succeeded.
*/
static esp_err_t call_init_hint_isr()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->init_hint_isr();
}
/**
* @brief Used to call private BNO08x::init_spi() member for tests.
*
* @return ESP_OK if init succeeded.
*/
static esp_err_t call_init_spi()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->init_spi();
}
/**
* @brief Used to call private BNO08x::init_tasks() member for tests.
*
* @return ESP_OK if init succeeded.
*/
static esp_err_t call_init_tasks()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->init_tasks();
}
/**
* @brief Used to call private BNO08x::init_tasks() member for tests.
*
* @return ESP_OK if init succeeded.
*/
static esp_err_t call_init_sh2_HAL()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->init_sh2_HAL();
}
/**
* @brief Used to call private BNO08x::deinit_gpio() member for tests.
*
* @return ESP_OK if deinit succeeded.
*/
static esp_err_t call_deinit_gpio()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->deinit_gpio();
}
/**
* @brief Used to call private BNO08x::deinit_hint_isr() member for tests.
*
* @return ESP_OK if deinit succeeded.
*/
static esp_err_t call_deinit_hint_isr()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->deinit_hint_isr();
}
/**
* @brief Used to call private BNO08x::deinit_spi() member for tests.
*
* @return ESP_OK if deinit succeeded.
*/
static esp_err_t call_deinit_spi()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->deinit_spi();
}
/**
* @brief Used to call private BNO08x::deinit_tasks() member for tests.
*
* @return ESP_OK if deinit succeeded.
*/
static esp_err_t call_deinit_tasks()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->deinit_tasks();
}
/**
* @brief Used to call private BNO08x::deinit_tasks() member for tests.
*
* @return ESP_OK if deinit succeeded.
*/
static esp_err_t call_deinit_sh2_HAL()
{
if (test_imu == nullptr)
return ESP_FAIL;
return test_imu->deinit_sh2_HAL();
}
};

125
include/BNO08xTestSuite.hpp Normal file
View File

@ -0,0 +1,125 @@
/**
* @file BNO08xTestSuite.hpp
* @author Myles Parfeniuk
*/
#pragma once
// standard library includes
#include <stdio.h>
#include <string.h>
// esp-idf includes
#include "unity.h"
// in-house includes
#include "BNO08xTestHelper.hpp"
/**
* @class BNO08xTestSuite
*
* @brief BNO08x unit test launch point class.
* */
class BNO08xTestSuite
{
private:
static void print_begin_tests_banner(const char* test_set_name)
{
printf("####################### BEGIN TESTS: %s #######################\n\r", test_set_name);
}
static void print_end_tests_banner(const char* test_set_name)
{
printf("####################### END TESTS: %s #######################\n\r", test_set_name);
}
public:
static void run_all_tests()
{
UNITY_BEGIN();
run_init_deinit_tests(false);
run_single_report_tests(false);
run_multi_report_tests(false);
run_callback_tests(false);
run_feature_tests(false);
UNITY_END();
}
static void run_init_deinit_tests(bool call_unity_end_begin = true)
{
print_begin_tests_banner("init_denit_tests");
if (call_unity_end_begin)
UNITY_BEGIN();
unity_run_tests_by_tag("[InitComprehensive]", false);
unity_run_tests_by_tag("[DeinitComprehensive]", false);
unity_run_tests_by_tag("[InitDenit]", false);
if (call_unity_end_begin)
UNITY_END();
print_end_tests_banner("init_denit_tests");
}
static void run_single_report_tests(bool call_unity_end_begin = true)
{
print_begin_tests_banner("single_report_enable_disable_tests");
if (call_unity_end_begin)
UNITY_BEGIN();
unity_run_tests_by_tag("[SingleReportEnableDisable]", false);
if (call_unity_end_begin)
UNITY_END();
print_end_tests_banner("single_report_enable_disable_tests");
}
static void run_multi_report_tests(bool call_unity_end_begin = true)
{
print_begin_tests_banner("multi_report_enable_disable_tests");
if (call_unity_end_begin)
UNITY_BEGIN();
unity_run_tests_by_tag("[MultiReportEnableDisable]", false);
if (call_unity_end_begin)
UNITY_END();
print_end_tests_banner("multi_report_enable_disable_tests");
}
static void run_callback_tests(bool call_unity_end_begin = true)
{
print_begin_tests_banner("callback_tests");
if (call_unity_end_begin)
UNITY_BEGIN();
unity_run_tests_by_tag("[CallbackAllReportVoidInputParam]", false);
unity_run_tests_by_tag("[CallbackAllReportIDInputParam]", false);
unity_run_tests_by_tag("[CallbackSingleReportVoidInputParam]", false);
if (call_unity_end_begin)
UNITY_END();
print_end_tests_banner("callback_tests");
}
static void run_feature_tests(bool call_unity_end_begin = true)
{
print_begin_tests_banner("feature_tests");
if (call_unity_end_begin)
UNITY_BEGIN();
unity_run_tests_by_tag("[FeatureTests]", false);
if (call_unity_end_begin)
UNITY_END();
print_end_tests_banner("feature_tests");
}
};

View File

@ -2,6 +2,7 @@
* @file BNO08x_global_types.hpp * @file BNO08x_global_types.hpp
* @author Myles Parfeniuk * @author Myles Parfeniuk
*/ */
#pragma once #pragma once
// standard library includes // standard library includes

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptARVRStabilizedGameRV.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRptRVGeneric.hpp" #include "BNO08xRptRVGeneric.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptARVRStabilizedRV.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRptRVGeneric.hpp" #include "BNO08xRptRVGeneric.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptAcceleration.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptActivityClassifier.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptCalGyro.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptCalMagnetometer.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptGameRV.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRptRVGeneric.hpp" #include "BNO08xRptRVGeneric.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptGravity.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptIGyroRV.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRptRVGeneric.hpp" #include "BNO08xRptRVGeneric.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptLinearAcceleration.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRV.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRptRVGeneric.hpp" #include "BNO08xRptRVGeneric.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRVGeneric.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRVGeomag.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRptRVGeneric.hpp" #include "BNO08xRptRVGeneric.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRawMEMSAccelerometer.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRawMEMSGyro.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRawMEMSMagnetometer.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptStepCounter.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptUncalGyro.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,9 @@
/**
* @file BNO08xRptUncalMagnetometer.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xShakeDetector.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xStabilityClassifier.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xTapDetector.hpp
* @author Myles Parfeniuk
*/
#pragma once #pragma once
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08x.cpp
* @author Myles Parfeniuk
*/
#include "BNO08x.hpp" #include "BNO08x.hpp"
/** /**
@ -39,8 +44,8 @@ BNO08x::BNO08x(bno08x_config_t imu_config)
, evt_grp_bno08x_task(xEventGroupCreate()) , evt_grp_bno08x_task(xEventGroupCreate())
, evt_grp_report_en(xEventGroupCreate()) , evt_grp_report_en(xEventGroupCreate())
, evt_grp_report_data_available(xEventGroupCreate()) , evt_grp_report_data_available(xEventGroupCreate())
, queue_rx_sensor_event(xQueueCreate(5, sizeof(sh2_SensorEvent_t))) , queue_rx_sensor_event(xQueueCreate(10, sizeof(sh2_SensorEvent_t)))
, queue_cb_report_id(xQueueCreate(5, sizeof(uint8_t))) , queue_cb_report_id(xQueueCreate(20, sizeof(uint8_t)))
, imu_config(imu_config) , imu_config(imu_config)
{ {
} }
@ -54,24 +59,21 @@ BNO08x::BNO08x(bno08x_config_t imu_config)
*/ */
BNO08x::~BNO08x() BNO08x::~BNO08x()
{ {
// disable interrupts before beginning so we can ensure SPI transaction doesn't attempt to run // deinitialize tasks if they have been initialized
gpio_intr_disable(imu_config.io_int); ESP_ERROR_CHECK(deinit_tasks());
// deinitialize sh2 HAL if it has been initialized // deinitialize sh2 HAL if it has been initialized
ESP_ERROR_CHECK(deinit_sh2_HAL()); ESP_ERROR_CHECK(deinit_sh2_HAL());
// deinitialize spi if has been initialized
ESP_ERROR_CHECK(deinit_spi());
// deinitialize hint ISR if it has been initialized // deinitialize hint ISR if it has been initialized
ESP_ERROR_CHECK(deinit_hint_isr()); ESP_ERROR_CHECK(deinit_hint_isr());
// deinitialize spi if has been initialized
ESP_ERROR_CHECK(deinit_spi());
// deinitialize GPIO if they have been initialized // deinitialize GPIO if they have been initialized
ESP_ERROR_CHECK(deinit_gpio()); ESP_ERROR_CHECK(deinit_gpio());
// deinitialize tasks if they have been initialized
ESP_ERROR_CHECK(deinit_tasks());
// delete all semaphores // delete all semaphores
vSemaphoreDelete(sh2_HAL_lock); vSemaphoreDelete(sh2_HAL_lock);
vSemaphoreDelete(data_lock); vSemaphoreDelete(data_lock);
@ -157,29 +159,26 @@ void BNO08x::data_proc_task_trampoline(void* arg)
void BNO08x::data_proc_task() void BNO08x::data_proc_task()
{ {
EventBits_t evt_grp_bno08x_task_bits = 0U; EventBits_t evt_grp_bno08x_task_bits = 0U;
BaseType_t queue_rx_success = pdFALSE;
sh2_SensorEvent_t sensor_evt; sh2_SensorEvent_t sensor_evt;
sh2_SensorValue_t sensor_val; sh2_SensorValue_t sensor_val;
while (1) do
{
if (xQueueReceive(queue_rx_sensor_event, &sensor_evt, portMAX_DELAY) == pdTRUE)
{
evt_grp_bno08x_task_bits = xEventGroupGetBits(evt_grp_bno08x_task);
if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING)
{ {
if (queue_rx_success == pdTRUE)
{
if (sh2_decodeSensorEvent(&sensor_val, &sensor_evt) != SH2_ERR) if (sh2_decodeSensorEvent(&sensor_val, &sensor_evt) != SH2_ERR)
handle_sensor_report(&sensor_val); handle_sensor_report(&sensor_val);
} }
else
{ queue_rx_success = xQueueReceive(queue_rx_sensor_event, &sensor_evt, portMAX_DELAY);
break; // exit loop, deconstructor requested task to commit self-deletion evt_grp_bno08x_task_bits = xEventGroupGetBits(evt_grp_bno08x_task);
}
} } while (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING);
}
xSemaphoreGive(sem_kill_tasks); // signal to deconstructor deletion is completed xSemaphoreGive(sem_kill_tasks); // signal to deconstructor deletion is completed
init_status.data_proc_task = false;
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@ -206,16 +205,11 @@ void BNO08x::sh2_HAL_service_task()
{ {
EventBits_t evt_grp_bno08x_task_bits = 0U; EventBits_t evt_grp_bno08x_task_bits = 0U;
while (1) do
{ {
xEventGroupWaitBits(
evt_grp_bno08x_task, EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT | EVT_GRP_BNO08x_TASK_RESET_OCCURRED, pdFALSE, pdFALSE, portMAX_DELAY);
evt_grp_bno08x_task_bits = xEventGroupGetBits(evt_grp_bno08x_task);
if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING)
{
if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASK_RESET_OCCURRED) if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASK_RESET_OCCURRED)
{
if (!re_enable_reports()) if (!re_enable_reports())
{ {
// clang-format off // clang-format off
@ -224,18 +218,22 @@ void BNO08x::sh2_HAL_service_task()
#endif #endif
// clang-format on // clang-format on
} }
}
if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT)
{
lock_sh2_HAL(); lock_sh2_HAL();
sh2_service(); sh2_service();
unlock_sh2_HAL(); unlock_sh2_HAL();
} }
else
{ evt_grp_bno08x_task_bits = xEventGroupWaitBits(
break; // exit loop, deconstructor requested task to commit self-deletion evt_grp_bno08x_task, EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT | EVT_GRP_BNO08x_TASK_RESET_OCCURRED, pdFALSE, pdFALSE, portMAX_DELAY);
}
} } while (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING);
xSemaphoreGive(sem_kill_tasks); // signal to deconstructor deletion is completed xSemaphoreGive(sem_kill_tasks); // signal to deconstructor deletion is completed
init_status.sh2_HAL_service_task = false;
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@ -261,47 +259,22 @@ void BNO08x::cb_task_trampoline(void* arg)
void BNO08x::cb_task() void BNO08x::cb_task()
{ {
EventBits_t evt_grp_bno08x_task_bits = 0U; EventBits_t evt_grp_bno08x_task_bits = 0U;
uint8_t rpt_ID; uint8_t rpt_ID = 0;
while (1) do
{ {
// execute callbacks
for (auto& cb_entry : cb_list)
handle_cb(rpt_ID, cb_entry);
xQueueReceive(queue_cb_report_id, &rpt_ID, portMAX_DELAY); xQueueReceive(queue_cb_report_id, &rpt_ID, portMAX_DELAY);
evt_grp_bno08x_task_bits = xEventGroupGetBits(evt_grp_bno08x_task); evt_grp_bno08x_task_bits = xEventGroupGetBits(evt_grp_bno08x_task);
if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING) } while (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING);
{
// execute callbacks
for (auto& cb_entry : cb_list)
{
// only execute callback if it is registered to this report or all reports
if ((cb_entry.report_ID == 0) || (cb_entry.report_ID == rpt_ID))
{
std::visit(
[rpt_ID](auto&& cb_fxn)
{
if constexpr (std::is_invocable_v<decltype(cb_fxn)>)
{
// Handles std::function<void()> (i.e., no parameters)
cb_fxn();
}
else
{
// Handles std::function<void(uint8_t)> (i.e., with a report ID)
cb_fxn(rpt_ID);
}
},
cb_entry.cb);
}
}
}
else
{
break; // exit loop, deconstructor requested task to commit self-deletion
}
}
xSemaphoreGive(sem_kill_tasks); // signal to deconstructor deletion is completed xSemaphoreGive(sem_kill_tasks); // signal to deconstructor deletion is completed
init_status.cb_task = false;
vTaskDelete(NULL); vTaskDelete(NULL);
} }
@ -355,15 +328,16 @@ void BNO08x::handle_sensor_report(sh2_SensorValue_t* sensor_val)
uint8_t rpt_ID = sensor_val->sensorId; uint8_t rpt_ID = sensor_val->sensorId;
// check if report exists within map // check if report exists within map
auto it = usr_reports.find(rpt_ID); if ((rpt_ID > 0) && (rpt_ID < SH2_MAX_SENSOR_ID))
if (it != usr_reports.end())
{ {
// update respective report with new data auto& rpt = usr_reports.at(rpt_ID);
it->second->update_data(sensor_val);
// send report ids to cb_task for callback execution (only if this report is enabled) // send report ids to cb_task for callback execution (only if this report is enabled)
if (usr_reports.at(rpt_ID)->rpt_bit & xEventGroupGetBits(evt_grp_report_en)) if (rpt->rpt_bit & xEventGroupGetBits(evt_grp_report_en))
{ {
// update respective report with new data
rpt->update_data(sensor_val);
if (cb_list.size() != 0) if (cb_list.size() != 0)
if (xQueueSend(queue_cb_report_id, &rpt_ID, 0) != pdTRUE) if (xQueueSend(queue_cb_report_id, &rpt_ID, 0) != pdTRUE)
{ {
@ -377,6 +351,30 @@ void BNO08x::handle_sensor_report(sh2_SensorValue_t* sensor_val)
} }
} }
/**
* @brief Determines the flavor of a passed callback and executes it appropriately.
*
* @return void, nothing to return
*/
void BNO08x::handle_cb(uint8_t rpt_ID, bno08x_cb_data_t& cb_entry)
{
// only execute callback if it is registered to this report or all reports
if ((cb_entry.report_ID == 0) || (cb_entry.report_ID == rpt_ID))
{
// check the type of the callback stored in the variant
if (std::holds_alternative<std::function<void()>>(cb_entry.cb))
{
// handles std::function<void()> (i.e., no parameters)
std::get<std::function<void()>>(cb_entry.cb)();
}
else
{
// handles std::function<void(uint8_t)> (i.e., with a report ID)
std::get<std::function<void(uint8_t)>>(cb_entry.cb)(rpt_ID);
}
}
}
/** /**
* @brief Initializes required esp-idf SPI data structures with values from user passed bno08x_config_t struct. * @brief Initializes required esp-idf SPI data structures with values from user passed bno08x_config_t struct.
* *
@ -647,30 +645,9 @@ esp_err_t BNO08x::init_tasks()
} }
else else
{ {
init_status.task_init_cnt++;
init_status.data_proc_task = true; init_status.data_proc_task = true;
} }
// launch data processing task
task_created =
xTaskCreate(&sh2_HAL_service_task_trampoline, "bno08x_sh2_HAL_service_task", SH2_HAL_SERVICE_TASK_SZ, this, 7, &sh2_HAL_service_task_hdl);
if (task_created != pdTRUE)
{
// clang-format off
#ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS
ESP_LOGE(TAG, "Initialization failed, sh2_HAL_service_task failed to launch.");
#endif
// clang-format on
return ESP_FAIL;
}
else
{
init_status.task_init_cnt++;
init_status.sh2_HAL_service_task = true;
}
// launch cb task // launch cb task
task_created = xTaskCreate(&cb_task_trampoline, "bno08x_cb_task", CB_TASK_SZ, this, 5, &cb_task_hdl); task_created = xTaskCreate(&cb_task_trampoline, "bno08x_cb_task", CB_TASK_SZ, this, 5, &cb_task_hdl);
@ -686,10 +663,28 @@ esp_err_t BNO08x::init_tasks()
} }
else else
{ {
init_status.task_init_cnt++;
init_status.cb_task = true; init_status.cb_task = true;
} }
// launch sh2 hal service task
task_created =
xTaskCreate(&sh2_HAL_service_task_trampoline, "bno08x_sh2_HAL_service_task", SH2_HAL_SERVICE_TASK_SZ, this, 7, &sh2_HAL_service_task_hdl);
if (task_created != pdTRUE)
{
// clang-format off
#ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS
ESP_LOGE(TAG, "Initialization failed, sh2_HAL_service_task failed to launch.");
#endif
// clang-format on
return ESP_FAIL;
}
else
{
init_status.sh2_HAL_service_task = true;
}
return ESP_OK; return ESP_OK;
} }
@ -810,6 +805,8 @@ esp_err_t BNO08x::deinit_gpio()
ret = deinit_gpio_inputs(); ret = deinit_gpio_inputs();
if (ret != ESP_OK) if (ret != ESP_OK)
return ret; return ret;
init_status.gpio_inputs = false;
} }
if (init_status.gpio_outputs) if (init_status.gpio_outputs)
@ -817,6 +814,8 @@ esp_err_t BNO08x::deinit_gpio()
ret = deinit_gpio_outputs(); ret = deinit_gpio_outputs();
if (ret != ESP_OK) if (ret != ESP_OK)
return ret; return ret;
init_status.gpio_outputs = false;
} }
return ret; return ret;
@ -917,6 +916,8 @@ esp_err_t BNO08x::deinit_hint_isr()
return ret; return ret;
} }
init_status.isr_handler = false;
} }
if (init_status.isr_service) if (init_status.isr_service)
@ -953,6 +954,8 @@ esp_err_t BNO08x::deinit_spi()
return ret; return ret;
} }
init_status.spi_device = false;
} }
if (init_status.spi_bus) if (init_status.spi_bus)
@ -968,6 +971,8 @@ esp_err_t BNO08x::deinit_spi()
return ret; return ret;
} }
init_status.spi_bus = false;
} }
return ret; return ret;
@ -980,15 +985,25 @@ esp_err_t BNO08x::deinit_spi()
*/ */
esp_err_t BNO08x::deinit_tasks() esp_err_t BNO08x::deinit_tasks()
{ {
static const constexpr uint8_t TASK_DELETE_TIMEOUT_MS = 100UL; static const constexpr uint8_t TASK_DELETE_TIMEOUT_MS = HOST_INT_TIMEOUT_DEFAULT_MS;
uint8_t kill_count = 0; uint8_t kill_count = 0;
uint8_t init_count = 0;
sh2_SensorEvent_t empty_event; sh2_SensorEvent_t empty_event;
uint8_t empty_ID = 0; uint8_t empty_ID = 0;
sem_kill_tasks = xSemaphoreCreateCounting(init_status.task_init_cnt, 0); // disable interrupts before beginning so we can ensure SPI transaction doesn't attempt to run
gpio_intr_disable(imu_config.io_int);
// signal tasks to commit self-deletion init_count += (static_cast<uint8_t>(init_status.cb_task) + static_cast<uint8_t>(init_status.data_proc_task) +
xEventGroupClearBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASKS_RUNNING); static_cast<uint8_t>(init_status.sh2_HAL_service_task));
if (init_count != 0)
{
sem_kill_tasks = xSemaphoreCreateCounting(init_count, 0);
xEventGroupClearBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASKS_RUNNING); // clear task running bit request deletion of tasks
if (init_status.cb_task)
xQueueSend(queue_cb_report_id, &empty_ID, 0);
if (init_status.data_proc_task) if (init_status.data_proc_task)
xQueueSend(queue_rx_sensor_event, &empty_event, 0); xQueueSend(queue_rx_sensor_event, &empty_event, 0);
@ -996,23 +1011,21 @@ esp_err_t BNO08x::deinit_tasks()
if (init_status.sh2_HAL_service_task) if (init_status.sh2_HAL_service_task)
xEventGroupSetBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT); xEventGroupSetBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT);
if (init_status.cb_task) for (uint8_t i = 0; i < init_count; i++)
xQueueSend(queue_cb_report_id, &empty_ID, 0); if (xSemaphoreTake(sem_kill_tasks, TASK_DELETE_TIMEOUT_MS) == pdTRUE)
for (uint8_t i = 0; i < init_status.task_init_cnt; i++)
if (xSemaphoreTake(sem_kill_tasks, TASK_DELETE_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE)
kill_count++; kill_count++;
if (kill_count != init_status.task_init_cnt) if (kill_count != init_count)
{ {
// clang-format off // clang-format off
#ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS #ifdef CONFIG_ESP32_BNO08x_DEBUG_STATEMENTS
ESP_LOGE(TAG, "Task deletion timed out in deconstructor call."); ESP_LOGE(TAG, "Task deletion timed out in deconstructor call.");
#endif #endif
// clang-format on // clang-format on
return ESP_FAIL; return ESP_FAIL;
} }
}
return ESP_OK; return ESP_OK;
} }
@ -1025,7 +1038,10 @@ esp_err_t BNO08x::deinit_tasks()
esp_err_t BNO08x::deinit_sh2_HAL() esp_err_t BNO08x::deinit_sh2_HAL()
{ {
if (init_status.sh2_HAL) if (init_status.sh2_HAL)
{
init_status.sh2_HAL = false;
sh2_close(); sh2_close();
}
return ESP_OK; return ESP_OK;
} }

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRpt.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRpt.hpp" #include "BNO08xRpt.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"
@ -29,7 +34,7 @@ bool BNO08xRpt::enable(uint32_t time_between_reports, sh2_SensorConfig_t sensor_
{ {
period_us = time_between_reports; // Update the period period_us = time_between_reports; // Update the period
xEventGroupSetBits(imu->evt_grp_report_en, rpt_bit); // Set the event group bit xEventGroupSetBits(imu->evt_grp_report_en, rpt_bit); // Set the event group bit
vTaskDelay(20UL / portTICK_PERIOD_MS); // delay a bit to allow command to execute vTaskDelay(30UL / portTICK_PERIOD_MS); // delay a bit to allow command to execute
return true; return true;
} }
} }

View File

@ -1,13 +1,30 @@
/**
* @file BNO08xSH2HAL.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xSH2HAL.hpp" #include "BNO08xSH2HAL.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"
BNO08x* BNO08xSH2HAL::imu; BNO08x* BNO08xSH2HAL::imu;
/**
* @brief Sets the BNO08x driver object to be used with sh2 HAL lib callbacks.
*
* @param hal_imu Pointer to BNO08x driver object to be used with sh2 HAL lib callbacks.
*
* @return void, nothing to return
*/
void BNO08xSH2HAL::set_hal_imu(BNO08x* hal_imu) void BNO08xSH2HAL::set_hal_imu(BNO08x* hal_imu)
{ {
imu = hal_imu; imu = hal_imu;
} }
/**
* @brief Opens SPI instance by waiting for interrupt.
*
* @return Always returns 0.
*/
int BNO08xSH2HAL::spi_open(sh2_Hal_t* self) int BNO08xSH2HAL::spi_open(sh2_Hal_t* self)
{ {
spi_wait_for_int(); spi_wait_for_int();
@ -15,11 +32,26 @@ int BNO08xSH2HAL::spi_open(sh2_Hal_t* self)
return 0; return 0;
} }
/**
* @brief Closes SPI instance (nothing to do here, but required by sh2 HAL lib for cases where other communication protocols are used.)
*
* @return void, nothing to return
*/
void BNO08xSH2HAL::spi_close(sh2_Hal_t* self) void BNO08xSH2HAL::spi_close(sh2_Hal_t* self)
{ {
// do nothing // do nothing
} }
/**
* @brief SPI rx callback for sh2 HAL lib.
*
* @param self sh2 HAL lib object being used with BNO08x driver instance.
* @param pBuffer Buffer to store received packet.
* @param len Length of bytes to read.
* @param t_us Time in microseconds (unused, forced sh2 HAL lib required function type)
*
* @return Size of received packet in bytes, 0 on failure.
*/
int BNO08xSH2HAL::spi_read(sh2_Hal_t* self, uint8_t* pBuffer, unsigned len, uint32_t* t_us) int BNO08xSH2HAL::spi_read(sh2_Hal_t* self, uint8_t* pBuffer, unsigned len, uint32_t* t_us)
{ {
uint16_t packet_sz = 0; uint16_t packet_sz = 0;
@ -47,6 +79,15 @@ int BNO08xSH2HAL::spi_read(sh2_Hal_t* self, uint8_t* pBuffer, unsigned len, uint
return packet_sz; return packet_sz;
} }
/**
* @brief SPI tx callback for sh2 HAL lib.
*
* @param self sh2 HAL lib object being used with BNO08x driver instance.
* @param pBuffer Buffer containing data to write.
* @param len Length in bytes to write.
*
* @return Size of sent data (len param), 0 on failure.
*/
int BNO08xSH2HAL::spi_write(sh2_Hal_t* self, uint8_t* pBuffer, unsigned len) int BNO08xSH2HAL::spi_write(sh2_Hal_t* self, uint8_t* pBuffer, unsigned len)
{ {
// hint never asserted, fail transaction // hint never asserted, fail transaction
@ -67,6 +108,13 @@ int BNO08xSH2HAL::spi_write(sh2_Hal_t* self, uint8_t* pBuffer, unsigned len)
return len; return len;
} }
/**
* @brief Get time in microseconds callback for sh2 HAL lib.
*
* @param self sh2 HAL lib object being used with BNO08x driver instance.
*
* @return Time in microseconds.
*/
uint32_t BNO08xSH2HAL::get_time_us(sh2_Hal_t* self) uint32_t BNO08xSH2HAL::get_time_us(sh2_Hal_t* self)
{ {
uint64_t time_us = esp_timer_get_time(); uint64_t time_us = esp_timer_get_time();
@ -77,22 +125,48 @@ uint32_t BNO08xSH2HAL::get_time_us(sh2_Hal_t* self)
return static_cast<uint32_t>(time_us & 0xFFFFFFFFU); return static_cast<uint32_t>(time_us & 0xFFFFFFFFU);
} }
/**
* @brief General event callback for sh2 HAL lib, used to notify tasks of reset.
*
* @param cookie User set input parameter as void pointer (unused), see sh2_Open().
* @param pEvent Pointer to asynchronous event.
*
* @return void, nothing to return
*/
void BNO08xSH2HAL::hal_cb(void* cookie, sh2_AsyncEvent_t* pEvent) void BNO08xSH2HAL::hal_cb(void* cookie, sh2_AsyncEvent_t* pEvent)
{ {
if (pEvent->eventId == SH2_RESET) if (pEvent->eventId == SH2_RESET)
xEventGroupSetBits(imu->evt_grp_bno08x_task, BNO08x::EVT_GRP_BNO08x_TASK_RESET_OCCURRED); xEventGroupSetBits(imu->evt_grp_bno08x_task, BNO08x::EVT_GRP_BNO08x_TASK_RESET_OCCURRED);
} }
/**
* @brief Sensor event callback for sh2 HAL lib, sends received reports to data_proc_task().
*
* @param cookie User set input parameter as void pointer (unused), see sh2_Open().
* @param event Pointer to sensor event.
*
* @return void, nothing to return
*/
void BNO08xSH2HAL::sensor_event_cb(void* cookie, sh2_SensorEvent_t* event) void BNO08xSH2HAL::sensor_event_cb(void* cookie, sh2_SensorEvent_t* event)
{ {
xQueueSend(imu->queue_rx_sensor_event, event, 0); xQueueSend(imu->queue_rx_sensor_event, event, 0);
} }
/**
* @brief Hardware reset callback for sh2 HAL lib, toggle RST gpio.
*
* @return void, nothing to return
*/
void BNO08xSH2HAL::hardware_reset() void BNO08xSH2HAL::hardware_reset()
{ {
imu->toggle_reset(); imu->toggle_reset();
} }
/**
* @brief SPI wait for HINT sh2 HAL lib callback.
*
* @return True if interrupt was detected before timeout.
*/
bool BNO08xSH2HAL::spi_wait_for_int() bool BNO08xSH2HAL::spi_wait_for_int()
{ {
if (imu->wait_for_hint() != ESP_OK) if (imu->wait_for_hint() != ESP_OK)
@ -104,6 +178,13 @@ bool BNO08xSH2HAL::spi_wait_for_int()
return true; return true;
} }
/**
* @brief SPI rx packet header (invoked from SPI rx callback.)
*
* @param pBuffer Buffer to store received header.
*
* @return Packet size (should always be 4), 0 on failure.
*/
uint16_t BNO08xSH2HAL::spi_read_sh2_packet_header(uint8_t* pBuffer) uint16_t BNO08xSH2HAL::spi_read_sh2_packet_header(uint8_t* pBuffer)
{ {
uint8_t dummy_header_tx[4] = {0}; uint8_t dummy_header_tx[4] = {0};
@ -127,6 +208,13 @@ uint16_t BNO08xSH2HAL::spi_read_sh2_packet_header(uint8_t* pBuffer)
return packet_sz; return packet_sz;
} }
/**
* @brief SPI rx packet body (invoked from SPI rx callback.)
*
* @param pBuffer Buffer to store received packet body.
*
* @return Packet size, 0 on failure.
*/
int BNO08xSH2HAL::spi_read_sh2_packet_body(uint8_t* pBuffer, uint16_t packet_sz) int BNO08xSH2HAL::spi_read_sh2_packet_body(uint8_t* pBuffer, uint16_t packet_sz)
{ {
imu->spi_transaction.rx_buffer = pBuffer + 4; imu->spi_transaction.rx_buffer = pBuffer + 4;

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptARVRStabilizedGameRV.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptARVRStabilizedGameRV.hpp" #include "BNO08xRptARVRStabilizedGameRV.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptARVRStabilizedRV.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptARVRStabilizedRV.hpp" #include "BNO08xRptARVRStabilizedRV.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptAcceleration.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptAcceleration.hpp" #include "BNO08xRptAcceleration.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptActivityClassifier.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptActivityClassifier.hpp" #include "BNO08xRptActivityClassifier.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptCalGyro.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptCalGyro.hpp" #include "BNO08xRptCalGyro.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptCalMagnetometer.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptCalMagnetometer.hpp" #include "BNO08xRptCalMagnetometer.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptGameRV.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptGameRV.hpp" #include "BNO08xRptGameRV.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptGravity.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptGravity.hpp" #include "BNO08xRptGravity.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptIGyroRV.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptIGyroRV.hpp" #include "BNO08xRptIGyroRV.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptLinearAcceleration.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptLinearAcceleration.hpp" #include "BNO08xRptLinearAcceleration.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRV.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptRV.hpp" #include "BNO08xRptRV.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRVGeneric.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptRVGeneric.hpp" #include "BNO08xRptRVGeneric.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRVGeomag.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptRVGeomag.hpp" #include "BNO08xRptRVGeomag.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRawMEMSAccelerometer.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptRawMEMSAccelerometer.hpp" #include "BNO08xRptRawMEMSAccelerometer.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRawMEMSGyro.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptRawMEMSGyro.hpp" #include "BNO08xRptRawMEMSGyro.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptRawMEMSMagnetometer.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptRawMEMSMagnetometer.hpp" #include "BNO08xRptRawMEMSMagnetometer.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptStepCounter.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptStepCounter.hpp" #include "BNO08xRptStepCounter.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptUncalGyro.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptUncalGyro.hpp" #include "BNO08xRptUncalGyro.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xRptUncalMagnetometer.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xRptUncalMagnetometer.hpp" #include "BNO08xRptUncalMagnetometer.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xShakeDetector.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xShakeDetector.hpp" #include "BNO08xShakeDetector.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xStabilityClassifier.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xStabilityClassifier.hpp" #include "BNO08xStabilityClassifier.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,3 +1,8 @@
/**
* @file BNO08xTapDetector.cpp
* @author Myles Parfeniuk
*/
#include "BNO08xTapDetector.hpp" #include "BNO08xTapDetector.hpp"
#include "BNO08x.hpp" #include "BNO08x.hpp"

View File

@ -1,5 +1,5 @@
idf_component_register(SRC_DIRS "source" "SH2" idf_component_register(SRC_DIRS "."
INCLUDE_DIRS "include" "include/report" "SH2" INCLUDE_DIRS "."
REQUIRES cmock esp32_BNO08x) REQUIRES cmock esp32_BNO08x)
# supress unused var warnings from test_imu # supress unused var warnings from test_imu

436
test/CallbackTests.cpp Normal file
View File

@ -0,0 +1,436 @@
/**
* @file CallbackTests.cpp
* @author Myles Parfeniuk
*
*
* @warning YOU MUST ADD THE FOLLOWING LINE TO YOUR MAIN PROJECTS CMakeLists.txt IN ORDER FOR THIS TEST SUITE TO BE BUILT WITH PROJECT:
* set(TEST_COMPONENTS "esp32_BNO08x" CACHE STRING "Components to test.")
*/
#include "unity.h"
#include "../include/BNO08xTestHelper.hpp"
TEST_CASE("BNO08x Driver Creation for [CallbackAllReportVoidInputParam] Tests", "[CallbackAllReportVoidInputParam]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Creation for [CallbackAllReportVoidInputParam] Tests";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Creating & initializing BNO08x driver.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
// ensure IMU initialized successfully
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Void Input Param Flavor Cb", "[CallbackAllReportVoidInputParam]")
{
const constexpr char* TEST_TAG = "Void Input Param Flavor Cb";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 8;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available_accel = false;
bool data_available_lin_accel = false;
bool data_available_grav = false;
bool data_available_cal_gyro = false;
bool data_available_cal_magnetometer = false;
bool data_available_rv = false;
bool data_available_rv_game = false;
bool data_available_rv_geomagnetic = false;
bool test_running = true;
bno08x_accel_t data_accel;
bno08x_gyro_t data_vel;
bno08x_magf_t data_magf;
bno08x_quat_t data_quat;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
imu->register_cb(
[&imu, &data_available_accel, &data_available_lin_accel, &data_available_grav, &data_available_cal_gyro, &data_available_cal_magnetometer,
&data_accel, &data_available_rv, &data_available_rv_game, &data_available_rv_geomagnetic, &data_quat, &data_vel, &data_magf,
&msg_buff, &test_running]()
{
static int i = 0;
if (i < RX_REPORT_TRIAL_CNT)
{
if (imu->accelerometer.has_new_data())
{
data_available_accel = true;
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x,
data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
else if (imu->linear_accelerometer.has_new_data())
{
data_available_lin_accel = true;
data_accel = imu->linear_accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: LinAccel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x,
data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
else if (imu->gravity.has_new_data())
{
data_available_grav = true;
data_accel = imu->gravity.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Gravity: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x,
data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
else if (imu->cal_gyro.has_new_data())
{
data_available_cal_gyro = true;
data_vel = imu->cal_gyro.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalGyro: [rad/s] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_vel.x,
data_vel.y, data_vel.z, BNO08x::accuracy_to_str(data_vel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
else if (imu->cal_magnetometer.has_new_data())
{
data_available_cal_magnetometer = true;
data_magf = imu->cal_magnetometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalMagnetometer: [uTesla] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1),
data_magf.x, data_magf.y, data_magf.z, BNO08x::accuracy_to_str(data_magf.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
else if (imu->rv.has_new_data())
{
data_available_rv = true;
data_quat = imu->rv.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1),
data_quat.real, data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
else if (imu->rv_game.has_new_data())
{
data_available_rv_game = true;
data_quat = imu->rv_game.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Game: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1),
data_quat.real, data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
else if (imu->rv_geomagnetic.has_new_data())
{
data_available_rv_geomagnetic = true;
data_quat = imu->rv_geomagnetic.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Geomagnetic: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1),
data_quat.real, data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
i++;
}
else if (test_running)
{
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->gravity.disable());
TEST_ASSERT_EQUAL(true, imu->cal_gyro.disable());
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.disable());
TEST_ASSERT_EQUAL(true, imu->rv.disable());
TEST_ASSERT_EQUAL(true, imu->rv_game.disable());
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.disable());
test_running = false;
}
});
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->gravity.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->cal_gyro.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv_game.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.enable(REPORT_PERIOD));
while (test_running)
{
}
TEST_ASSERT_EQUAL(true, data_available_accel);
TEST_ASSERT_EQUAL(true, data_available_lin_accel);
TEST_ASSERT_EQUAL(true, data_available_grav);
TEST_ASSERT_EQUAL(true, data_available_cal_gyro);
TEST_ASSERT_EQUAL(true, data_available_cal_magnetometer);
TEST_ASSERT_EQUAL(true, data_available_rv);
TEST_ASSERT_EQUAL(true, data_available_rv_game);
TEST_ASSERT_EQUAL(true, data_available_rv_geomagnetic);
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Cleanup for [CallbackAllReportVoidInputParam] Tests", "[CallbackAllReportVoidInputParam]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Cleanup for [CallbackAllReportVoidInputParam] Tests";
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Destroying BNO08x Driver.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Creation for [CallbackAllReportIDInputParam] Tests", "[CallbackAllReportIDInputParam]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Creation for [CallbackAllReportIDInputParam] Tests";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Creating & initializing BNO08x driver.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
// ensure IMU initialized successfully
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Report ID Input Param Flavor Cb", "[CallbackAllReportIDInputParam]")
{
const constexpr char* TEST_TAG = "Report ID Input Param Flavor Cb";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 8;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available_accel = false;
bool data_available_lin_accel = false;
bool data_available_grav = false;
bool data_available_cal_gyro = false;
bool data_available_cal_magnetometer = false;
bool data_available_rv = false;
bool data_available_rv_game = false;
bool data_available_rv_geomagnetic = false;
bool test_running = true;
bno08x_accel_t data_accel;
bno08x_gyro_t data_vel;
bno08x_magf_t data_magf;
bno08x_quat_t data_quat;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
imu->register_cb(
[&imu, &data_available_accel, &data_available_lin_accel, &data_available_grav, &data_available_cal_gyro, &data_available_cal_magnetometer,
&data_accel, &data_available_rv, &data_available_rv_game, &data_available_rv_geomagnetic, &data_quat, &data_vel, &data_magf,
&msg_buff, &test_running](uint8_t report_ID)
{
static int i = 0;
if (i < RX_REPORT_TRIAL_CNT)
{
switch (report_ID)
{
case SH2_ACCELEROMETER:
data_available_accel = true;
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x,
data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
case SH2_LINEAR_ACCELERATION:
data_available_lin_accel = true;
data_accel = imu->linear_accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: LinAccel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1),
data_accel.x, data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
case SH2_GRAVITY:
data_available_grav = true;
data_accel = imu->gravity.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Gravity: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1),
data_accel.x, data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
case SH2_GYROSCOPE_CALIBRATED:
data_available_cal_gyro = true;
data_vel = imu->cal_gyro.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalGyro: [rad/s] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_vel.x,
data_vel.y, data_vel.z, BNO08x::accuracy_to_str(data_vel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
case SH2_MAGNETIC_FIELD_CALIBRATED:
data_available_cal_magnetometer = true;
data_magf = imu->cal_magnetometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalMagnetometer: [uTesla] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1),
data_magf.x, data_magf.y, data_magf.z, BNO08x::accuracy_to_str(data_magf.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
case SH2_ROTATION_VECTOR:
data_available_rv = true;
data_quat = imu->rv.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1),
data_quat.real, data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
case SH2_GAME_ROTATION_VECTOR:
data_available_rv_game = true;
data_quat = imu->rv_game.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Game: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1),
data_quat.real, data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
case SH2_GEOMAGNETIC_ROTATION_VECTOR:
data_available_rv_geomagnetic = true;
data_quat = imu->rv_geomagnetic.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Geomagnetic: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ",
(i + 1), data_quat.real, data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
break;
default:
break;
}
i++;
}
else if (test_running)
{
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->gravity.disable());
TEST_ASSERT_EQUAL(true, imu->cal_gyro.disable());
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.disable());
TEST_ASSERT_EQUAL(true, imu->rv.disable());
TEST_ASSERT_EQUAL(true, imu->rv_game.disable());
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.disable());
test_running = false;
}
});
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->gravity.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->cal_gyro.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv_game.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.enable(REPORT_PERIOD));
while (test_running)
{
}
TEST_ASSERT_EQUAL(true, data_available_accel);
TEST_ASSERT_EQUAL(true, data_available_lin_accel);
TEST_ASSERT_EQUAL(true, data_available_grav);
TEST_ASSERT_EQUAL(true, data_available_cal_gyro);
TEST_ASSERT_EQUAL(true, data_available_cal_magnetometer);
TEST_ASSERT_EQUAL(true, data_available_rv);
TEST_ASSERT_EQUAL(true, data_available_rv_game);
TEST_ASSERT_EQUAL(true, data_available_rv_geomagnetic);
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Cleanup for [CallbackAllReportIDInputParam] Tests", "[CallbackAllReportIDInputParam]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Cleanup for [CallbackAllReportIDInputParam] Tests";
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Destroying BNO08x Driver.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Creation for [CallbackSingleReportVoidInputParam] Tests", "[CallbackSingleReportVoidInputParam]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Creation for [CallbackSingleReportVoidInputParam] Tests";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Creating & initializing BNO08x driver.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
// ensure IMU initialized successfully
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Single Report Void Input Param Flavor Cb", "[CallbackSingleReportVoidInputParam]")
{
const constexpr char* TEST_TAG = "Single Report Void Input Param Flavor Cb";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 1;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available_accel = false;
bool test_running = true;
bno08x_accel_t data_accel;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
imu->accelerometer.register_cb(
[&imu, &data_available_accel, &data_accel, &msg_buff, &test_running]()
{
static int i = 0;
if (i < RX_REPORT_TRIAL_CNT)
{
data_available_accel = true;
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x,
data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
i++;
}
else if (test_running)
{
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
test_running = false;
}
});
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
while (test_running)
{
}
TEST_ASSERT_EQUAL(true, data_available_accel);
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Cleanup for [CallbackSingleReportVoidInputParam] Tests", "[CallbackSingleReportVoidInputParam]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Cleanup for [CallbackSingleReportVoidInputParam] Tests";
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Destroying BNO08x Driver.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}

282
test/FeatureTests.cpp Normal file
View File

@ -0,0 +1,282 @@
/**
* @file FeatureTets.cpp
* @author Myles Parfeniuk
*
*
* @warning YOU MUST ADD THE FOLLOWING LINE TO YOUR MAIN PROJECTS CMakeLists.txt IN ORDER FOR THIS TEST SUITE TO BE BUILT WITH PROJECT:
* set(TEST_COMPONENTS "esp32_BNO08x" CACHE STRING "Components to test.")
*/
#include "unity.h"
#include "../include/BNO08xTestHelper.hpp"
TEST_CASE("BNO08x Driver Creation for [FeatureTests] Tests", "[FeatureTests]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Creation for [FeatureTests] Tests";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Creating & initializing BNO08x driver.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
// ensure IMU initialized successfully
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Hard Reset", "[FeatureTests]")
{
const constexpr char* TEST_TAG = "Hard Reset";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 1;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bno08x_accel_t data_accel;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
BNO08xTestHelper::print_test_msg(TEST_TAG, "Hard reseting...");
TEST_ASSERT_EQUAL(true, imu->hard_reset());
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Soft Reset", "[FeatureTests]")
{
const constexpr char* TEST_TAG = "Soft Reset";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 1;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bno08x_accel_t data_accel;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
BNO08xTestHelper::print_test_msg(TEST_TAG, "Soft reseting...");
TEST_ASSERT_EQUAL(true, imu->soft_reset());
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Sleep", "[FeatureTests]")
{
const constexpr char* TEST_TAG = "Sleep";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 1;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bno08x_accel_t data_accel;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->sleep());
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
sprintf(msg_buff, "Sleeping... %ds", RX_REPORT_TRIAL_CNT - i);
vTaskDelay(1000UL / portTICK_PERIOD_MS);
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->on());
BNO08xTestHelper::print_test_msg(TEST_TAG, "Woke.");
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Get Metadata", "[FeatureTests]")
{
const constexpr char* TEST_TAG = "Get Metadata";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 1;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bno08x_accel_t data_accel;
bno08x_meta_data_t meta_data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
BNO08xTestHelper::print_test_msg(TEST_TAG, "Getting meta data...");
TEST_ASSERT_EQUAL(true, imu->accelerometer.get_meta_data(meta_data));
sprintf(msg_buff, "Re-enabling report with fastest possible period of %ldus from accelerometer meta data.", meta_data.min_period_us);
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(meta_data.min_period_us));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Get Sample Counts", "[FeatureTests]")
{
const constexpr char* TEST_TAG = "Get Sample Counts";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 1;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bno08x_accel_t data_accel;
bno08x_sample_counts_t sample_counts;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
BNO08xTestHelper::print_test_msg(TEST_TAG, "Getting sample counts...");
TEST_ASSERT_EQUAL(true, imu->accelerometer.get_sample_counts(sample_counts));
sprintf(msg_buff, "offered: %ld on: %ld accepted: %ld attempted: %ld", sample_counts.offered, sample_counts.on, sample_counts.accepted,
sample_counts.attempted);
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
TEST_ASSERT_EQUAL(true, imu->data_available());
TEST_ASSERT_EQUAL(true, imu->accelerometer.has_new_data());
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Cleanup for [FeatureTests] Tests", "[FeatureTests]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Cleanup for [FeatureTests] Tests";
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Destroying BNO08x Driver.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}

191
test/InitDenitTests.cpp Normal file
View File

@ -0,0 +1,191 @@
/**
* @file InitDenitTests.cpp
* @author Myles Parfeniuk
*
*
* @warning YOU MUST ADD THE FOLLOWING LINE TO YOUR MAIN PROJECTS CMakeLists.txt IN ORDER FOR THIS TEST SUITE TO BE BUILT WITH PROJECT:
* set(TEST_COMPONENTS "esp32_BNO08x" CACHE STRING "Components to test.")
*/
#include "unity.h"
#include "../include/BNO08xTestHelper.hpp"
TEST_CASE("InitComprehensive Config Args", "[InitComprehensive]")
{
const constexpr char* TEST_TAG = "InitComprehensive Config Args";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Creating test IMU for [InitComprehensive] and [DeinitComprehensive].");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_init_config_args());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("InitComprehensive GPIO", "[InitComprehensive]")
{
const constexpr char* TEST_TAG = "InitComprehensive GPIO";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_init_gpio());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("InitComprehensive HINT ISR", "[InitComprehensive]")
{
const constexpr char* TEST_TAG = "InitComprehensive HINT ISR";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_init_hint_isr());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("InitComprehensive SPI", "[InitComprehensive]")
{
const constexpr char* TEST_TAG = "InitComprehensive SPI";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_init_spi());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("InitComprehensive sh2 HAL", "[InitComprehensive]")
{
const constexpr char* TEST_TAG = "InitComprehensive sh2 HAL";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_init_sh2_HAL());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("InitComprehensive Tasks", "[InitComprehensive]")
{
const constexpr char* TEST_TAG = "InitComprehensive Tasks";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_init_tasks());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("DeinitComprehensive Tasks", "[DeinitComprehensive]")
{
const constexpr char* TEST_TAG = "DeinitComprehensive Tasks";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_deinit_tasks());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("DeinitComprehensive sh2 HAL", "[DeinitComprehensive]")
{
const constexpr char* TEST_TAG = "DeinitComprehensive sh2 HAL";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_deinit_sh2_HAL());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("DeinitComprehensive HINT ISR", "[DeinitComprehensive]")
{
const constexpr char* TEST_TAG = "DeinitComprehensive HINT ISR";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_deinit_hint_isr());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("DeinitComprehensive SPI", "[DeinitComprehensive]")
{
const constexpr char* TEST_TAG = "DeinitComprehensive SPI";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_deinit_spi());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("DeinitComprehensive GPIO", "[DeinitComprehensive]")
{
const constexpr char* TEST_TAG = "DeinitComprehensive GPIO";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(ESP_OK, BNO08xTestHelper::call_deinit_gpio());
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Init and Deinit", "[InitDenit]")
{
const constexpr char* TEST_TAG = "Init and Deinit";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Initializing BNO08x Driver Object attempt 1.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_msg(TEST_TAG, "Success, deinitializing BNO08x Driver Object.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_msg(TEST_TAG, "Initializing BNO08x Driver Object attempt 2.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_msg(TEST_TAG, "Success, deinitializing BNO08x Driver Object.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}

311
test/MultiReportTests.cpp Normal file
View File

@ -0,0 +1,311 @@
/**
* @file MultiReportTests.cpp
* @author Myles Parfeniuk
*
*
* @warning YOU MUST ADD THE FOLLOWING LINE TO YOUR MAIN PROJECTS CMakeLists.txt IN ORDER FOR THIS TEST SUITE TO BE BUILT WITH PROJECT:
* set(TEST_COMPONENTS "esp32_BNO08x" CACHE STRING "Components to test.")
*/
#include "unity.h"
#include "../include/BNO08xTestHelper.hpp"
TEST_CASE("BNO08x Driver Creation for [MultiReportEnableDisable] Tests", "[MultiReportEnableDisable]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Creation for [MultiReportEnableDisable] Tests";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Creating & initializing BNO08x driver.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
// ensure IMU initialized successfully
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Dual Report", "[MultiReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Dual Report";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 2;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool data_available_accel = false;
bool data_available_lin_accel = false;
bno08x_accel_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
if (imu->accelerometer.has_new_data())
{
data_available_accel = true;
data = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y, data.z,
BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->linear_accelerometer.has_new_data())
{
data_available_lin_accel = true;
data = imu->linear_accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: LinAccel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y, data.z,
BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.disable());
TEST_ASSERT_EQUAL(true, data_available_accel);
TEST_ASSERT_EQUAL(true, data_available_lin_accel);
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Quad Report", "[MultiReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Quad Report";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 4;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool data_available_accel = false;
bool data_available_lin_accel = false;
bool data_available_gravity = false;
bool data_available_cal_gyro = false;
bno08x_accel_t data_accel;
bno08x_gyro_t data_vel;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->gravity.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->cal_gyro.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
if (imu->accelerometer.has_new_data())
{
data_available_accel = true;
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->linear_accelerometer.has_new_data())
{
data_available_lin_accel = true;
data_accel = imu->linear_accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: LinAccel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x,
data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->gravity.has_new_data())
{
data_available_gravity = true;
data_accel = imu->gravity.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Gravity: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->cal_gyro.has_new_data())
{
data_available_cal_gyro = true;
data_vel = imu->cal_gyro.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalGyro: [rad/s] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_vel.x, data_vel.y,
data_vel.z, BNO08x::accuracy_to_str(data_vel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->gravity.disable());
TEST_ASSERT_EQUAL(true, imu->cal_gyro.disable());
TEST_ASSERT_EQUAL(true, data_available_accel);
TEST_ASSERT_EQUAL(true, data_available_lin_accel);
TEST_ASSERT_EQUAL(true, data_available_gravity);
TEST_ASSERT_EQUAL(true, data_available_cal_gyro);
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Octo Report", "[MultiReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Octo Report";
static const constexpr uint8_t ENABLED_REPORT_COUNT = 8;
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = ENABLED_REPORT_COUNT * 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool data_available_accel = false;
bool data_available_lin_accel = false;
bool data_available_gravity = false;
bool data_available_cal_gyro = false;
bool data_available_cal_magnetometer = false;
bool data_available_rv = false;
bool data_available_rv_game = false;
bool data_available_rv_geomagnetic = false;
bno08x_accel_t data_accel;
bno08x_gyro_t data_vel;
bno08x_magf_t data_magf;
bno08x_quat_t data_quat;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->gravity.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->cal_gyro.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv_game.enable(REPORT_PERIOD));
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
if (imu->accelerometer.has_new_data())
{
data_available_accel = true;
data_accel = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->linear_accelerometer.has_new_data())
{
data_available_lin_accel = true;
data_accel = imu->linear_accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: LinAccel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x,
data_accel.y, data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->gravity.has_new_data())
{
data_available_gravity = true;
data_accel = imu->gravity.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Gravity: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_accel.x, data_accel.y,
data_accel.z, BNO08x::accuracy_to_str(data_accel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->cal_gyro.has_new_data())
{
data_available_cal_gyro = true;
data_vel = imu->cal_gyro.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalGyro: [rad/s] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_vel.x, data_vel.y,
data_vel.z, BNO08x::accuracy_to_str(data_vel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->cal_magnetometer.has_new_data())
{
data_available_cal_magnetometer = true;
data_magf = imu->cal_magnetometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalMagnetometer: [uTesla] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data_magf.x,
data_magf.y, data_magf.z, BNO08x::accuracy_to_str(data_magf.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->rv.has_new_data())
{
data_available_rv = true;
data_quat = imu->rv.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1), data_quat.real,
data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->rv_game.has_new_data())
{
data_available_rv_game = true;
data_quat = imu->rv_game.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Game: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1), data_quat.real,
data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
if (imu->rv_geomagnetic.has_new_data())
{
data_available_rv_geomagnetic = true;
data_quat = imu->rv_geomagnetic.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Geomagnetic: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1),
data_quat.real, data_quat.i, data_quat.j, data_quat.k, BNO08x::accuracy_to_str(data_quat.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.disable());
TEST_ASSERT_EQUAL(true, imu->gravity.disable());
TEST_ASSERT_EQUAL(true, imu->cal_gyro.disable());
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.disable());
TEST_ASSERT_EQUAL(true, imu->rv.disable());
TEST_ASSERT_EQUAL(true, imu->rv_game.disable());
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.disable());
TEST_ASSERT_EQUAL(true, data_available_accel);
TEST_ASSERT_EQUAL(true, data_available_lin_accel);
TEST_ASSERT_EQUAL(true, data_available_gravity);
TEST_ASSERT_EQUAL(true, data_available_cal_gyro);
TEST_ASSERT_EQUAL(true, data_available_cal_magnetometer);
TEST_ASSERT_EQUAL(true, data_available_rv);
TEST_ASSERT_EQUAL(true, data_available_rv_game);
TEST_ASSERT_EQUAL(true, data_available_rv_geomagnetic);
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Cleanup for [MultiReportEnableDisable] Tests", "[MultiReportEnableDisable]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Cleanup for [MultiReportEnableDisable] Tests";
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Destroying BNO08x Driver.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}

574
test/SingleReportTests.cpp Normal file
View File

@ -0,0 +1,574 @@
/**
* @file SingleReportTests.cpp
* @author Myles Parfeniuk
*
*
* @warning YOU MUST ADD THE FOLLOWING LINE TO YOUR MAIN PROJECTS CMakeLists.txt IN ORDER FOR THIS TEST SUITE TO BE BUILT WITH PROJECT:
* set(TEST_COMPONENTS "esp32_BNO08x" CACHE STRING "Components to test.")
*/
#include "unity.h"
#include "../include/BNO08xTestHelper.hpp"
TEST_CASE("BNO08x Driver Creation for [SingleReportEnableDisable] Tests", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Creation for [SingleReportEnableDisable] Tests";
BNO08x* imu = nullptr;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Creating & initializing BNO08x driver.");
BNO08xTestHelper::create_test_imu();
imu = BNO08xTestHelper::get_test_imu();
// ensure IMU initialized successfully
TEST_ASSERT_EQUAL(true, imu->initialize());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable Incorrect Report", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable Incorrect Report";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool wrong_report_data_available = true;
bno08x_accel_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
wrong_report_data_available = imu->linear_accelerometer.has_new_data();
TEST_ASSERT_EQUAL(false, wrong_report_data_available);
data = imu->linear_accelerometer.get();
sprintf(msg_buff, "No Rx Data Trial %d Success: LinAccelDefaults: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y,
data.z, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Accelerometer", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Accelerometer";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_accel_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->accelerometer.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Accel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y, data.z,
BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Linear Accelerometer", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Linear Accelerometer";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_accel_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->linear_accelerometer.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->linear_accelerometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: LinearAccel: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y, data.z,
BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->linear_accelerometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Gravity", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Gravity";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_accel_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->gravity.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->gravity.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->gravity.get();
sprintf(msg_buff, "Rx Data Trial %d Success: Gravity: [m/s^2] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y, data.z,
BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->gravity.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Cal Magnetometer", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Cal Magnetometer";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_magf_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->cal_magnetometer.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->cal_magnetometer.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalMagnetometer: [uTesla] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y,
data.z, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->cal_magnetometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Uncal Magnetometer", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Uncal Magnetometer";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_magf_t data_magf;
bno08x_magf_bias_t data_bias;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->uncal_magnetometer.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->uncal_magnetometer.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
imu->uncal_magnetometer.get(data_magf, data_bias);
sprintf(msg_buff,
"Rx Data Trial %d Success: UncalMagnetometer: [uTesla] x: %.2f y: %.2f z: %.2f x_bias: %.2f y_bias: %.2f z_bias: %.2f accuracy: %s ",
(i + 1), data_magf.x, data_magf.y, data_magf.z, data_bias.x, data_bias.y, data_bias.z, BNO08x::accuracy_to_str(data_magf.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->uncal_magnetometer.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Cal Gyro", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Cal Gyro";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_gyro_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->cal_gyro.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->cal_gyro.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->cal_gyro.get();
sprintf(msg_buff, "Rx Data Trial %d Success: CalGyro: [rad/s] x: %.2f y: %.2f z: %.2f accuracy: %s ", (i + 1), data.x, data.y, data.z,
BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->cal_gyro.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Uncal Gyro", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Uncal Gyro";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_gyro_t data_vel;
bno08x_gyro_bias_t data_bias;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->uncal_gyro.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->uncal_gyro.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
imu->uncal_gyro.get(data_vel, data_bias);
sprintf(msg_buff, "Rx Data Trial %d Success: UncalGyro: [rad/s] x: %.2f y: %.2f z: %.2f x_bias: %.2f y_bias: %.2f z_bias: %.2f accuracy: %s ",
(i + 1), data_vel.x, data_vel.y, data_vel.z, data_bias.x, data_bias.y, data_bias.z, BNO08x::accuracy_to_str(data_vel.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->uncal_gyro.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable RV", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable RV";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_quat_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->rv.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->rv.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->rv.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1), data.real, data.i, data.j,
data.k, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->rv.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Game RV", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Game RV";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_quat_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->rv_game.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->rv_game.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->rv_game.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Game: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1), data.real, data.i,
data.j, data.k, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->rv_game.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable ARVR Stabilized RV", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable ARVR Stabilized RV";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_quat_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->rv_ARVR_stabilized.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->rv_ARVR_stabilized.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->rv_ARVR_stabilized.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV ARVR Stabilized: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1), data.real,
data.i, data.j, data.k, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->rv_ARVR_stabilized.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable ARVR Stabilized Game RV", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable ARVR Stabilized Game RV";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_quat_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->rv_ARVR_stabilized_game.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->rv_ARVR_stabilized_game.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->rv_ARVR_stabilized_game.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV ARVR Stabilized Game: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1),
data.real, data.i, data.j, data.k, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->rv_ARVR_stabilized_game.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Gyro Integrated RV", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Gyro Integrated RV";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_quat_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->rv_gyro_integrated.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->rv_gyro_integrated.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->rv_gyro_integrated.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Gyro Integrated: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1), data.real,
data.i, data.j, data.k, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->rv_gyro_integrated.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("Enable/Disable Geomagnetic RV", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "Enable/Disable Geomagnetic RV";
static const constexpr uint8_t RX_REPORT_TRIAL_CNT = 5;
static const constexpr uint32_t REPORT_PERIOD = 100000UL; // 100ms
BNO08x* imu = nullptr;
char msg_buff[200] = {};
bool data_available = false;
bool report_data_available = true;
bno08x_quat_t data;
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
imu = BNO08xTestHelper::get_test_imu();
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.enable(REPORT_PERIOD));
for (int i = 0; i < RX_REPORT_TRIAL_CNT; i++)
{
data_available = imu->data_available();
TEST_ASSERT_EQUAL(true, data_available);
report_data_available = imu->rv_geomagnetic.has_new_data();
TEST_ASSERT_EQUAL(true, report_data_available);
data = imu->rv_geomagnetic.get_quat();
sprintf(msg_buff, "Rx Data Trial %d Success: RV Geomagnetic: [n/a] real: %.2f i: %.2f j: %.2f k: %.2f accuracy: %s ", (i + 1), data.real,
data.i, data.j, data.k, BNO08x::accuracy_to_str(data.accuracy));
BNO08xTestHelper::print_test_msg(TEST_TAG, msg_buff);
}
TEST_ASSERT_EQUAL(true, imu->rv_geomagnetic.disable());
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}
TEST_CASE("BNO08x Driver Cleanup for [SingleReportEnableDisable] Tests", "[SingleReportEnableDisable]")
{
const constexpr char* TEST_TAG = "BNO08x Driver Cleanup for [SingleReportEnableDisable] Tests";
BNO08xTestHelper::print_test_start_banner(TEST_TAG);
BNO08xTestHelper::print_test_msg(TEST_TAG, "Destroying BNO08x Driver.");
BNO08xTestHelper::destroy_test_imu();
BNO08xTestHelper::print_test_end_banner(TEST_TAG);
}