diff --git a/Kconfig.projbuild b/Kconfig.projbuild index 2b2477d..2f3450c 100644 --- a/Kconfig.projbuild +++ b/Kconfig.projbuild @@ -77,7 +77,29 @@ menu "esp32_BNO08x" default 5 help 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 @@ -97,7 +119,7 @@ menu "esp32_BNO08x" endmenu #Logging - menu "Callbacks" + menu "Callbacks & Tasks" config ESP32_BNO08X_CB_TASK_SZ 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 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 \ No newline at end of file diff --git a/include/BNO08x.hpp b/include/BNO08x.hpp index 9cf9a58..db3cd0b 100644 --- a/include/BNO08x.hpp +++ b/include/BNO08x.hpp @@ -2,10 +2,10 @@ * @file BNO08x.hpp * @author Myles Parfeniuk */ + #pragma once // standard library includes -#include #include #include #include @@ -119,7 +119,6 @@ class BNO08x 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 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() : gpio_outputs(false) @@ -131,7 +130,6 @@ class BNO08x , data_proc_task(false) , sh2_HAL_service_task(false) , cb_task(false) - , task_init_cnt(0) { } } bno08x_init_status_t; @@ -145,14 +143,16 @@ class BNO08x } bno08x_cb_data_t; // data processing task - static const constexpr configSTACK_DEPTH_TYPE DATA_PROC_TASK_SZ = 2048UL; ///< Size of data_proc_task() stack in bytes - TaskHandle_t data_proc_task_hdl; /// +// standard library includes #include +// in-house includes #include "BNO08x_global_types.hpp" // forward dec to prevent compile errors diff --git a/include/BNO08xSH2HAL.hpp b/include/BNO08xSH2HAL.hpp index 4a8112e..02de54b 100644 --- a/include/BNO08xSH2HAL.hpp +++ b/include/BNO08xSH2HAL.hpp @@ -2,6 +2,7 @@ * @file BNO08xSH2HAL.hpp * @author Myles Parfeniuk */ + #pragma once // hill-crest labs includes (apache 2.0 license, compatible with MIT) diff --git a/include/BNO08xTestHelper.hpp b/include/BNO08xTestHelper.hpp new file mode 100644 index 0000000..0ed915e --- /dev/null +++ b/include/BNO08xTestHelper.hpp @@ -0,0 +1,255 @@ +/** + * @file BNO08xTestHelper.hpp + * @author Myles Parfeniuk + */ + +#pragma once + +// standard library includes +#include +// 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(); + } +}; \ No newline at end of file diff --git a/include/BNO08xTestSuite.hpp b/include/BNO08xTestSuite.hpp new file mode 100644 index 0000000..dd2ad27 --- /dev/null +++ b/include/BNO08xTestSuite.hpp @@ -0,0 +1,125 @@ +/** + * @file BNO08xTestSuite.hpp + * @author Myles Parfeniuk + */ + +#pragma once + +// standard library includes +#include +#include +// 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"); + } +}; diff --git a/include/BNO08x_global_types.hpp b/include/BNO08x_global_types.hpp index 820b4b5..ab69e2d 100644 --- a/include/BNO08x_global_types.hpp +++ b/include/BNO08x_global_types.hpp @@ -2,6 +2,7 @@ * @file BNO08x_global_types.hpp * @author Myles Parfeniuk */ + #pragma once // standard library includes diff --git a/include/report/BNO08xRptARVRStabilizedGameRV.hpp b/include/report/BNO08xRptARVRStabilizedGameRV.hpp index 209450d..6208273 100644 --- a/include/report/BNO08xRptARVRStabilizedGameRV.hpp +++ b/include/report/BNO08xRptARVRStabilizedGameRV.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptARVRStabilizedGameRV.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRptRVGeneric.hpp" diff --git a/include/report/BNO08xRptARVRStabilizedRV.hpp b/include/report/BNO08xRptARVRStabilizedRV.hpp index 4b94ca4..6dd6cbc 100644 --- a/include/report/BNO08xRptARVRStabilizedRV.hpp +++ b/include/report/BNO08xRptARVRStabilizedRV.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptARVRStabilizedRV.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRptRVGeneric.hpp" diff --git a/include/report/BNO08xRptAcceleration.hpp b/include/report/BNO08xRptAcceleration.hpp index 9f86fce..77c385b 100644 --- a/include/report/BNO08xRptAcceleration.hpp +++ b/include/report/BNO08xRptAcceleration.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptAcceleration.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptActivityClassifier.hpp b/include/report/BNO08xRptActivityClassifier.hpp index 7f29ee1..34ea98a 100644 --- a/include/report/BNO08xRptActivityClassifier.hpp +++ b/include/report/BNO08xRptActivityClassifier.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptActivityClassifier.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptCalGyro.hpp b/include/report/BNO08xRptCalGyro.hpp index 1437265..c3c7ea4 100644 --- a/include/report/BNO08xRptCalGyro.hpp +++ b/include/report/BNO08xRptCalGyro.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptCalGyro.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptCalMagnetometer.hpp b/include/report/BNO08xRptCalMagnetometer.hpp index b90ac13..a40e183 100644 --- a/include/report/BNO08xRptCalMagnetometer.hpp +++ b/include/report/BNO08xRptCalMagnetometer.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptCalMagnetometer.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptGameRV.hpp b/include/report/BNO08xRptGameRV.hpp index bbaa571..ab0e1e7 100644 --- a/include/report/BNO08xRptGameRV.hpp +++ b/include/report/BNO08xRptGameRV.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptGameRV.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRptRVGeneric.hpp" diff --git a/include/report/BNO08xRptGravity.hpp b/include/report/BNO08xRptGravity.hpp index 2a39489..288ac0a 100644 --- a/include/report/BNO08xRptGravity.hpp +++ b/include/report/BNO08xRptGravity.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptGravity.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptIGyroRV.hpp b/include/report/BNO08xRptIGyroRV.hpp index e5f6bfa..eb0282d 100644 --- a/include/report/BNO08xRptIGyroRV.hpp +++ b/include/report/BNO08xRptIGyroRV.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptIGyroRV.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRptRVGeneric.hpp" diff --git a/include/report/BNO08xRptLinearAcceleration.hpp b/include/report/BNO08xRptLinearAcceleration.hpp index 8ad5b88..d4ed409 100644 --- a/include/report/BNO08xRptLinearAcceleration.hpp +++ b/include/report/BNO08xRptLinearAcceleration.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptLinearAcceleration.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptRV.hpp b/include/report/BNO08xRptRV.hpp index 1700483..abe0ae6 100644 --- a/include/report/BNO08xRptRV.hpp +++ b/include/report/BNO08xRptRV.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRV.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRptRVGeneric.hpp" diff --git a/include/report/BNO08xRptRVGeneric.hpp b/include/report/BNO08xRptRVGeneric.hpp index 0ff89b7..1f58c26 100644 --- a/include/report/BNO08xRptRVGeneric.hpp +++ b/include/report/BNO08xRptRVGeneric.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRVGeneric.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptRVGeomag.hpp b/include/report/BNO08xRptRVGeomag.hpp index 5776057..57437f4 100644 --- a/include/report/BNO08xRptRVGeomag.hpp +++ b/include/report/BNO08xRptRVGeomag.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRVGeomag.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRptRVGeneric.hpp" diff --git a/include/report/BNO08xRptRawMEMSAccelerometer.hpp b/include/report/BNO08xRptRawMEMSAccelerometer.hpp index b403a36..f201527 100644 --- a/include/report/BNO08xRptRawMEMSAccelerometer.hpp +++ b/include/report/BNO08xRptRawMEMSAccelerometer.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRawMEMSAccelerometer.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptRawMEMSGyro.hpp b/include/report/BNO08xRptRawMEMSGyro.hpp index b80b832..299b401 100644 --- a/include/report/BNO08xRptRawMEMSGyro.hpp +++ b/include/report/BNO08xRptRawMEMSGyro.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRawMEMSGyro.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptRawMEMSMagnetometer.hpp b/include/report/BNO08xRptRawMEMSMagnetometer.hpp index a52b78e..d8e9f41 100644 --- a/include/report/BNO08xRptRawMEMSMagnetometer.hpp +++ b/include/report/BNO08xRptRawMEMSMagnetometer.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRawMEMSMagnetometer.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptStepCounter.hpp b/include/report/BNO08xRptStepCounter.hpp index 2d47c14..fce6c2f 100644 --- a/include/report/BNO08xRptStepCounter.hpp +++ b/include/report/BNO08xRptStepCounter.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptStepCounter.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptUncalGyro.hpp b/include/report/BNO08xRptUncalGyro.hpp index 58075d9..1f70a42 100644 --- a/include/report/BNO08xRptUncalGyro.hpp +++ b/include/report/BNO08xRptUncalGyro.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptUncalGyro.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xRptUncalMagnetometer.hpp b/include/report/BNO08xRptUncalMagnetometer.hpp index 52a9e00..7f6166c 100644 --- a/include/report/BNO08xRptUncalMagnetometer.hpp +++ b/include/report/BNO08xRptUncalMagnetometer.hpp @@ -1,3 +1,9 @@ + +/** + * @file BNO08xRptUncalMagnetometer.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xShakeDetector.hpp b/include/report/BNO08xShakeDetector.hpp index f7e6e1d..72ecccf 100644 --- a/include/report/BNO08xShakeDetector.hpp +++ b/include/report/BNO08xShakeDetector.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xShakeDetector.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xStabilityClassifier.hpp b/include/report/BNO08xStabilityClassifier.hpp index 36ed1d0..034fb02 100644 --- a/include/report/BNO08xStabilityClassifier.hpp +++ b/include/report/BNO08xStabilityClassifier.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xStabilityClassifier.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/include/report/BNO08xTapDetector.hpp b/include/report/BNO08xTapDetector.hpp index f760386..3e6b954 100644 --- a/include/report/BNO08xTapDetector.hpp +++ b/include/report/BNO08xTapDetector.hpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xTapDetector.hpp + * @author Myles Parfeniuk + */ + #pragma once #include "BNO08xRpt.hpp" diff --git a/source/BNO08x.cpp b/source/BNO08x.cpp index 7b30e24..4f69e5b 100644 --- a/source/BNO08x.cpp +++ b/source/BNO08x.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08x.cpp + * @author Myles Parfeniuk + */ + #include "BNO08x.hpp" /** @@ -39,8 +44,8 @@ BNO08x::BNO08x(bno08x_config_t imu_config) , evt_grp_bno08x_task(xEventGroupCreate()) , evt_grp_report_en(xEventGroupCreate()) , evt_grp_report_data_available(xEventGroupCreate()) - , queue_rx_sensor_event(xQueueCreate(5, sizeof(sh2_SensorEvent_t))) - , queue_cb_report_id(xQueueCreate(5, sizeof(uint8_t))) + , queue_rx_sensor_event(xQueueCreate(10, sizeof(sh2_SensorEvent_t))) + , queue_cb_report_id(xQueueCreate(20, sizeof(uint8_t))) , imu_config(imu_config) { } @@ -54,24 +59,21 @@ BNO08x::BNO08x(bno08x_config_t imu_config) */ BNO08x::~BNO08x() { - // disable interrupts before beginning so we can ensure SPI transaction doesn't attempt to run - gpio_intr_disable(imu_config.io_int); + // deinitialize tasks if they have been initialized + ESP_ERROR_CHECK(deinit_tasks()); // deinitialize sh2 HAL if it has been initialized 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 ESP_ERROR_CHECK(deinit_hint_isr()); + // deinitialize spi if has been initialized + ESP_ERROR_CHECK(deinit_spi()); + // deinitialize GPIO if they have been initialized ESP_ERROR_CHECK(deinit_gpio()); - // deinitialize tasks if they have been initialized - ESP_ERROR_CHECK(deinit_tasks()); - // delete all semaphores vSemaphoreDelete(sh2_HAL_lock); vSemaphoreDelete(data_lock); @@ -157,29 +159,26 @@ void BNO08x::data_proc_task_trampoline(void* arg) void BNO08x::data_proc_task() { EventBits_t evt_grp_bno08x_task_bits = 0U; + BaseType_t queue_rx_success = pdFALSE; sh2_SensorEvent_t sensor_evt; sh2_SensorValue_t sensor_val; - while (1) + do { - if (xQueueReceive(queue_rx_sensor_event, &sensor_evt, portMAX_DELAY) == pdTRUE) + + if (queue_rx_success == pdTRUE) { - evt_grp_bno08x_task_bits = xEventGroupGetBits(evt_grp_bno08x_task); - - if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING) - { - - if (sh2_decodeSensorEvent(&sensor_val, &sensor_evt) != SH2_ERR) - handle_sensor_report(&sensor_val); - } - else - { - break; // exit loop, deconstructor requested task to commit self-deletion - } + if (sh2_decodeSensorEvent(&sensor_val, &sensor_evt) != SH2_ERR) + handle_sensor_report(&sensor_val); } - } + + queue_rx_success = xQueueReceive(queue_rx_sensor_event, &sensor_evt, portMAX_DELAY); + 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 + init_status.data_proc_task = false; vTaskDelete(NULL); } @@ -206,36 +205,35 @@ void BNO08x::sh2_HAL_service_task() { 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()) - { - // clang-format off - #ifdef CONFIG_ESP32_BNO08x_DEBUG_STATEMENTS - ESP_LOGE(TAG, "Failed to re-enable enabled reports after IMU reset."); - #endif - // clang-format on - } + if (!re_enable_reports()) + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_DEBUG_STATEMENTS + ESP_LOGE(TAG, "Failed to re-enable enabled reports after IMU reset."); + #endif + // clang-format on + } + } + if (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT) + { lock_sh2_HAL(); sh2_service(); unlock_sh2_HAL(); } - else - { - break; // exit loop, deconstructor requested task to commit self-deletion - } - } + + evt_grp_bno08x_task_bits = xEventGroupWaitBits( + 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 + init_status.sh2_HAL_service_task = false; vTaskDelete(NULL); } @@ -261,47 +259,22 @@ void BNO08x::cb_task_trampoline(void* arg) void BNO08x::cb_task() { 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); evt_grp_bno08x_task_bits = xEventGroupGetBits(evt_grp_bno08x_task); - if (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) - { - // Handles std::function (i.e., no parameters) - cb_fxn(); - } - else - { - // Handles std::function (i.e., with a report ID) - cb_fxn(rpt_ID); - } - }, - cb_entry.cb); - } - } - } - else - { - break; // exit loop, deconstructor requested task to commit self-deletion - } - } + } while (evt_grp_bno08x_task_bits & EVT_GRP_BNO08x_TASKS_RUNNING); xSemaphoreGive(sem_kill_tasks); // signal to deconstructor deletion is completed + init_status.cb_task = false; vTaskDelete(NULL); } @@ -355,28 +328,53 @@ void BNO08x::handle_sensor_report(sh2_SensorValue_t* sensor_val) uint8_t rpt_ID = sensor_val->sensorId; // check if report exists within map - auto it = usr_reports.find(rpt_ID); - if (it != usr_reports.end()) + if ((rpt_ID > 0) && (rpt_ID < SH2_MAX_SENSOR_ID)) { - // update respective report with new data - it->second->update_data(sensor_val); + auto& rpt = usr_reports.at(rpt_ID); // 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 (xQueueSend(queue_cb_report_id, &rpt_ID, 0) != pdTRUE) { // clang-format off - #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS - ESP_LOGE(TAG, "Callback queue full, callback execution for report missed."); - #endif + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Callback queue full, callback execution for report missed."); + #endif // clang-format on } } } } +/** + * @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>(cb_entry.cb)) + { + // handles std::function (i.e., no parameters) + std::get>(cb_entry.cb)(); + } + else + { + // handles std::function (i.e., with a report ID) + std::get>(cb_entry.cb)(rpt_ID); + } + } +} + /** * @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 { - init_status.task_init_cnt++; 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 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 { - init_status.task_init_cnt++; 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; } @@ -810,6 +805,8 @@ esp_err_t BNO08x::deinit_gpio() ret = deinit_gpio_inputs(); if (ret != ESP_OK) return ret; + + init_status.gpio_inputs = false; } if (init_status.gpio_outputs) @@ -817,6 +814,8 @@ esp_err_t BNO08x::deinit_gpio() ret = deinit_gpio_outputs(); if (ret != ESP_OK) return ret; + + init_status.gpio_outputs = false; } return ret; @@ -917,6 +916,8 @@ esp_err_t BNO08x::deinit_hint_isr() return ret; } + + init_status.isr_handler = false; } if (init_status.isr_service) @@ -953,6 +954,8 @@ esp_err_t BNO08x::deinit_spi() return ret; } + + init_status.spi_device = false; } if (init_status.spi_bus) @@ -968,6 +971,8 @@ esp_err_t BNO08x::deinit_spi() return ret; } + + init_status.spi_bus = false; } return ret; @@ -980,38 +985,46 @@ esp_err_t BNO08x::deinit_spi() */ 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 init_count = 0; sh2_SensorEvent_t empty_event; 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 - xEventGroupClearBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASKS_RUNNING); + init_count += (static_cast(init_status.cb_task) + static_cast(init_status.data_proc_task) + + static_cast(init_status.sh2_HAL_service_task)); - if (init_status.data_proc_task) - xQueueSend(queue_rx_sensor_event, &empty_event, 0); - - if (init_status.sh2_HAL_service_task) - xEventGroupSetBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT); - - if (init_status.cb_task) - xQueueSend(queue_cb_report_id, &empty_ID, 0); - - 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++; - - if (kill_count != init_status.task_init_cnt) + if (init_count != 0) { - // clang-format off - #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS - ESP_LOGE(TAG, "Task deletion timed out in deconstructor call."); - #endif - // clang-format on + 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 - return ESP_FAIL; + if (init_status.cb_task) + xQueueSend(queue_cb_report_id, &empty_ID, 0); + + if (init_status.data_proc_task) + xQueueSend(queue_rx_sensor_event, &empty_event, 0); + + if (init_status.sh2_HAL_service_task) + xEventGroupSetBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASK_HINT_ASSRT_BIT); + + for (uint8_t i = 0; i < init_count; i++) + if (xSemaphoreTake(sem_kill_tasks, TASK_DELETE_TIMEOUT_MS) == pdTRUE) + kill_count++; + + if (kill_count != init_count) + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_DEBUG_STATEMENTS + ESP_LOGE(TAG, "Task deletion timed out in deconstructor call."); + #endif + // clang-format on + + return ESP_FAIL; + } } return ESP_OK; @@ -1025,7 +1038,10 @@ esp_err_t BNO08x::deinit_tasks() esp_err_t BNO08x::deinit_sh2_HAL() { if (init_status.sh2_HAL) + { + init_status.sh2_HAL = false; sh2_close(); + } return ESP_OK; } diff --git a/source/BNO08xRpt.cpp b/source/BNO08xRpt.cpp index 0fb1bcc..81a7f2e 100644 --- a/source/BNO08xRpt.cpp +++ b/source/BNO08xRpt.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRpt.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRpt.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 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; } } diff --git a/source/BNO08xSH2HAL.cpp b/source/BNO08xSH2HAL.cpp index fed8789..3d8de4d 100644 --- a/source/BNO08xSH2HAL.cpp +++ b/source/BNO08xSH2HAL.cpp @@ -1,13 +1,30 @@ +/** + * @file BNO08xSH2HAL.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xSH2HAL.hpp" #include "BNO08x.hpp" 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) { imu = hal_imu; } +/** + * @brief Opens SPI instance by waiting for interrupt. + * + * @return Always returns 0. + */ int BNO08xSH2HAL::spi_open(sh2_Hal_t* self) { spi_wait_for_int(); @@ -15,11 +32,26 @@ int BNO08xSH2HAL::spi_open(sh2_Hal_t* self) 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) { // 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) { 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; } +/** + * @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) { // hint never asserted, fail transaction @@ -67,6 +108,13 @@ int BNO08xSH2HAL::spi_write(sh2_Hal_t* self, uint8_t* pBuffer, unsigned 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) { 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(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) { if (pEvent->eventId == SH2_RESET) 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) { 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() { 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() { if (imu->wait_for_hint() != ESP_OK) @@ -104,6 +178,13 @@ bool BNO08xSH2HAL::spi_wait_for_int() 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) { 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; } +/** + * @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) { imu->spi_transaction.rx_buffer = pBuffer + 4; diff --git a/source/report/BNO08xRptARVRStabilizedGameRV.cpp b/source/report/BNO08xRptARVRStabilizedGameRV.cpp index ab36a18..c269ded 100644 --- a/source/report/BNO08xRptARVRStabilizedGameRV.cpp +++ b/source/report/BNO08xRptARVRStabilizedGameRV.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptARVRStabilizedGameRV.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptARVRStabilizedGameRV.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptARVRStabilizedRV.cpp b/source/report/BNO08xRptARVRStabilizedRV.cpp index 425012e..cab1fe7 100644 --- a/source/report/BNO08xRptARVRStabilizedRV.cpp +++ b/source/report/BNO08xRptARVRStabilizedRV.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptARVRStabilizedRV.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptARVRStabilizedRV.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptAcceleration.cpp b/source/report/BNO08xRptAcceleration.cpp index 4cf8b90..29a079b 100644 --- a/source/report/BNO08xRptAcceleration.cpp +++ b/source/report/BNO08xRptAcceleration.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptAcceleration.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptAcceleration.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptActivityClassifier.cpp b/source/report/BNO08xRptActivityClassifier.cpp index 33a0e44..3821fb6 100644 --- a/source/report/BNO08xRptActivityClassifier.cpp +++ b/source/report/BNO08xRptActivityClassifier.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptActivityClassifier.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptActivityClassifier.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptCalGyro.cpp b/source/report/BNO08xRptCalGyro.cpp index 4d4eca4..0107800 100644 --- a/source/report/BNO08xRptCalGyro.cpp +++ b/source/report/BNO08xRptCalGyro.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptCalGyro.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptCalGyro.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptCalMagnetometer.cpp b/source/report/BNO08xRptCalMagnetometer.cpp index c20117d..bfed8a2 100644 --- a/source/report/BNO08xRptCalMagnetometer.cpp +++ b/source/report/BNO08xRptCalMagnetometer.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptCalMagnetometer.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptCalMagnetometer.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptGameRV.cpp b/source/report/BNO08xRptGameRV.cpp index bb83814..43a8284 100644 --- a/source/report/BNO08xRptGameRV.cpp +++ b/source/report/BNO08xRptGameRV.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptGameRV.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptGameRV.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptGravity.cpp b/source/report/BNO08xRptGravity.cpp index cb8beac..6219b4e 100644 --- a/source/report/BNO08xRptGravity.cpp +++ b/source/report/BNO08xRptGravity.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptGravity.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptGravity.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptIGyroRV.cpp b/source/report/BNO08xRptIGyroRV.cpp index 893f6b4..9199399 100644 --- a/source/report/BNO08xRptIGyroRV.cpp +++ b/source/report/BNO08xRptIGyroRV.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptIGyroRV.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptIGyroRV.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptLinearAcceleration.cpp b/source/report/BNO08xRptLinearAcceleration.cpp index 612795b..c02bdb7 100644 --- a/source/report/BNO08xRptLinearAcceleration.cpp +++ b/source/report/BNO08xRptLinearAcceleration.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptLinearAcceleration.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptLinearAcceleration.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptRV.cpp b/source/report/BNO08xRptRV.cpp index d231978..e78b60e 100644 --- a/source/report/BNO08xRptRV.cpp +++ b/source/report/BNO08xRptRV.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRV.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptRV.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptRVGeneric.cpp b/source/report/BNO08xRptRVGeneric.cpp index 70495e8..d4e7433 100644 --- a/source/report/BNO08xRptRVGeneric.cpp +++ b/source/report/BNO08xRptRVGeneric.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRVGeneric.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptRVGeneric.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptRVGeomag.cpp b/source/report/BNO08xRptRVGeomag.cpp index e3dbf3e..552cdba 100644 --- a/source/report/BNO08xRptRVGeomag.cpp +++ b/source/report/BNO08xRptRVGeomag.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRVGeomag.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptRVGeomag.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptRawMEMSAccelerometer.cpp b/source/report/BNO08xRptRawMEMSAccelerometer.cpp index d10d749..2c11443 100644 --- a/source/report/BNO08xRptRawMEMSAccelerometer.cpp +++ b/source/report/BNO08xRptRawMEMSAccelerometer.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRawMEMSAccelerometer.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptRawMEMSAccelerometer.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptRawMEMSGyro.cpp b/source/report/BNO08xRptRawMEMSGyro.cpp index ac3280e..6c5bd7a 100644 --- a/source/report/BNO08xRptRawMEMSGyro.cpp +++ b/source/report/BNO08xRptRawMEMSGyro.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRawMEMSGyro.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptRawMEMSGyro.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptRawMEMSMagnetometer.cpp b/source/report/BNO08xRptRawMEMSMagnetometer.cpp index ce7c3ce..45c0801 100644 --- a/source/report/BNO08xRptRawMEMSMagnetometer.cpp +++ b/source/report/BNO08xRptRawMEMSMagnetometer.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptRawMEMSMagnetometer.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptRawMEMSMagnetometer.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptStepCounter.cpp b/source/report/BNO08xRptStepCounter.cpp index 9fabfff..2872682 100644 --- a/source/report/BNO08xRptStepCounter.cpp +++ b/source/report/BNO08xRptStepCounter.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptStepCounter.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptStepCounter.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptUncalGyro.cpp b/source/report/BNO08xRptUncalGyro.cpp index 1702634..7af340c 100644 --- a/source/report/BNO08xRptUncalGyro.cpp +++ b/source/report/BNO08xRptUncalGyro.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptUncalGyro.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptUncalGyro.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xRptUncalMagnetometer.cpp b/source/report/BNO08xRptUncalMagnetometer.cpp index 1d8abf3..2619821 100644 --- a/source/report/BNO08xRptUncalMagnetometer.cpp +++ b/source/report/BNO08xRptUncalMagnetometer.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xRptUncalMagnetometer.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xRptUncalMagnetometer.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xShakeDetector.cpp b/source/report/BNO08xShakeDetector.cpp index 5897cd0..0d24437 100644 --- a/source/report/BNO08xShakeDetector.cpp +++ b/source/report/BNO08xShakeDetector.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xShakeDetector.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xShakeDetector.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xStabilityClassifier.cpp b/source/report/BNO08xStabilityClassifier.cpp index 26eeda7..2ff7def 100644 --- a/source/report/BNO08xStabilityClassifier.cpp +++ b/source/report/BNO08xStabilityClassifier.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xStabilityClassifier.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xStabilityClassifier.hpp" #include "BNO08x.hpp" diff --git a/source/report/BNO08xTapDetector.cpp b/source/report/BNO08xTapDetector.cpp index b13feb6..ca41453 100644 --- a/source/report/BNO08xTapDetector.cpp +++ b/source/report/BNO08xTapDetector.cpp @@ -1,3 +1,8 @@ +/** + * @file BNO08xTapDetector.cpp + * @author Myles Parfeniuk + */ + #include "BNO08xTapDetector.hpp" #include "BNO08x.hpp" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9c885d3..c832d06 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ -idf_component_register(SRC_DIRS "source" "SH2" - INCLUDE_DIRS "include" "include/report" "SH2" +idf_component_register(SRC_DIRS "." + INCLUDE_DIRS "." REQUIRES cmock esp32_BNO08x) # supress unused var warnings from test_imu diff --git a/test/CallbackTests.cpp b/test/CallbackTests.cpp new file mode 100644 index 0000000..4fa3774 --- /dev/null +++ b/test/CallbackTests.cpp @@ -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); +} diff --git a/test/FeatureTests.cpp b/test/FeatureTests.cpp new file mode 100644 index 0000000..a2eb252 --- /dev/null +++ b/test/FeatureTests.cpp @@ -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); +} \ No newline at end of file diff --git a/test/InitDenitTests.cpp b/test/InitDenitTests.cpp new file mode 100644 index 0000000..4a68fd9 --- /dev/null +++ b/test/InitDenitTests.cpp @@ -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); +} \ No newline at end of file diff --git a/test/MultiReportTests.cpp b/test/MultiReportTests.cpp new file mode 100644 index 0000000..62b3c38 --- /dev/null +++ b/test/MultiReportTests.cpp @@ -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); +} \ No newline at end of file diff --git a/test/SingleReportTests.cpp b/test/SingleReportTests.cpp new file mode 100644 index 0000000..4606523 --- /dev/null +++ b/test/SingleReportTests.cpp @@ -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); +} \ No newline at end of file