diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f8bf58..664f1ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRC_DIRS "source" "tests" - INCLUDE_DIRS "include" "tests" - REQUIRES driver esp_timer) +idf_component_register(SRC_DIRS "source" + INCLUDE_DIRS "include" + REQUIRES driver esp_timer cmock) diff --git a/include/BNO08x.hpp b/include/BNO08x.hpp index 13d6e6d..230b043 100644 --- a/include/BNO08x.hpp +++ b/include/BNO08x.hpp @@ -307,7 +307,6 @@ class BNO08x static const constexpr int16_t GRAVITY_Q1 = 8; ///< Gravity Q point (See SH-2 Ref. Manual 6.5.11) private: - /// @brief Holds data that is received over spi. typedef struct bno08x_rx_packet_t { @@ -326,15 +325,15 @@ class BNO08x /// @brief Holds info about which functionality has been successfully initialized (used by deconstructor during cleanup). typedef struct bno08x_init_status_t { - bool gpio_outputs; ///< True if GPIO outputs have been initialized. - bool gpio_inputs; ///< True if GPIO inputs have been initialized. - bool isr_service; ///< True if global ISR service has been initialized. - bool isr_handler; ///< True if HINT ISR handler has been initialized. - uint8_t task_count; ///< How many successfully initialized tasks (max of TSK_CNT) - bool data_proc_task; ///< True if xTaskCreate has been called successfully for data_proc_task. - bool spi_task; ///< True if xTaskCreate has been called successfully for spi_task. - bool spi_bus; ///< True if spi_bus_initialize() has been called successfully. - bool spi_device; ///< True if spi_bus_add_device() has been called successfully. + bool gpio_outputs; ///< True if GPIO outputs have been initialized. + bool gpio_inputs; ///< True if GPIO inputs have been initialized. + bool isr_service; ///< True if global ISR service has been initialized. + bool isr_handler; ///< True if HINT ISR handler has been initialized. + uint8_t task_count; ///< How many successfully initialized tasks (max of TSK_CNT) + bool data_proc_task; ///< True if xTaskCreate has been called successfully for data_proc_task. + bool spi_task; ///< True if xTaskCreate has been called successfully for spi_task. + bool spi_bus; ///< True if spi_bus_initialize() has been called successfully. + bool spi_device; ///< True if spi_bus_add_device() has been called successfully. bno08x_init_status_t() : gpio_outputs(false) @@ -368,6 +367,7 @@ class BNO08x bool wait_for_data(); bool receive_packet(); void send_packet(bno08x_tx_packet_t* packet); + void flush_rx_packets(uint8_t flush_count, TickType_t delay); void enable_report(uint8_t report_ID, uint32_t time_between_reports, const EventBits_t report_evt_grp_bit, uint32_t special_config = 0); void disable_report(uint8_t report_ID, const EventBits_t report_evt_grp_bit); void queue_packet(uint8_t channel_number, uint8_t data_length, uint8_t* commands); @@ -421,7 +421,8 @@ class BNO08x spi_device_interface_config_t imu_spi_config{}; /// +#include +#include "unity.h" +#include "BNO08xTestHelper.hpp" + +class BNO08xTestSuite +{ + public: + static void run_all_tests(); + static void run_init_deinit_tests(); + +}; \ No newline at end of file diff --git a/source/BNO08x.cpp b/source/BNO08x.cpp index 83a706c..4772336 100644 --- a/source/BNO08x.cpp +++ b/source/BNO08x.cpp @@ -438,7 +438,7 @@ bool BNO08x::wait_for_rx_done() gpio_intr_enable(imu_config.io_int); // re-enable interrupts // wait until an interrupt has been asserted and data received or timeout has occured - if (xEventGroupWaitBits(evt_grp_spi, EVT_GRP_SPI_RX_DONE_BIT, pdTRUE, pdTRUE, HOST_INT_TIMEOUT_MS / portTICK_PERIOD_MS)) + if (xEventGroupWaitBits(evt_grp_spi, EVT_GRP_SPI_RX_DONE_BIT, pdTRUE, pdTRUE, HOST_INT_TIMEOUT_MS)) { #ifdef CONFIG_ESP32_BNO08x_DEBUG_STATEMENTS ESP_LOGI(TAG, "int asserted"); @@ -471,11 +471,11 @@ bool BNO08x::wait_for_data() gpio_intr_enable(imu_config.io_int); // re-enable interrupts // check to see receive operation has finished - if (xEventGroupWaitBits(evt_grp_spi, EVT_GRP_SPI_RX_DONE_BIT, pdTRUE, pdTRUE, HOST_INT_TIMEOUT_MS / portTICK_PERIOD_MS)) + if (xEventGroupWaitBits(evt_grp_spi, EVT_GRP_SPI_RX_DONE_BIT, pdTRUE, pdTRUE, HOST_INT_TIMEOUT_MS)) { // wait until processing is done, this should never go to timeout; however, it will be set slightly after EVT_GRP_SPI_RX_DONE_BIT - if (xEventGroupWaitBits(evt_grp_spi, EVT_GRP_SPI_RX_VALID_PACKET_BIT | EVT_GRP_SPI_RX_INVALID_PACKET_BIT, pdFALSE, pdFALSE, - HOST_INT_TIMEOUT_MS / portTICK_PERIOD_MS)) + if (xEventGroupWaitBits( + evt_grp_spi, EVT_GRP_SPI_RX_VALID_PACKET_BIT | EVT_GRP_SPI_RX_INVALID_PACKET_BIT, pdFALSE, pdFALSE, HOST_INT_TIMEOUT_MS)) { // only return true if packet is valid if (xEventGroupGetBits(evt_grp_spi) & EVT_GRP_SPI_RX_VALID_PACKET_BIT) @@ -514,7 +514,7 @@ bool BNO08x::wait_for_tx_done() if (xEventGroupGetBits(evt_grp_report_en) == 0) gpio_intr_enable(imu_config.io_int); // re-enable interrupts - if (xEventGroupWaitBits(evt_grp_spi, EVT_GRP_SPI_TX_DONE_BIT, pdTRUE, pdTRUE, HOST_INT_TIMEOUT_MS / portTICK_PERIOD_MS)) + if (xEventGroupWaitBits(evt_grp_spi, EVT_GRP_SPI_TX_DONE_BIT, pdTRUE, pdTRUE, HOST_INT_TIMEOUT_MS)) { #ifdef CONFIG_ESP32_BNO08x_DEBUG_STATEMENTS ESP_LOGI(TAG, "Packet sent successfully."); @@ -547,7 +547,7 @@ bool BNO08x::hard_reset() gpio_set_level(imu_config.io_wake, 1); gpio_set_level(imu_config.io_rst, 0); // set reset pin low - vTaskDelay(50 / portTICK_PERIOD_MS); // 10ns min, set to 50ms to let things stabilize(Anton) + vTaskDelay(HARD_RESET_DELAY_MS); // 10ns min, set to larger delay to let things stabilize(Anton) gpio_set_level(imu_config.io_rst, 1); // bring out of reset // Receive advertisement message on boot (see SH2 Ref. Manual 5.2 & 5.3) @@ -592,11 +592,7 @@ bool BNO08x::soft_reset() success = wait_for_tx_done(); // flush any packets received - for (int i = 0; i < 3; i++) - { - wait_for_rx_done(); - vTaskDelay(20 / portTICK_PERIOD_MS); - } + flush_rx_packets(3, FLUSH_PKT_DELAY_MS); return success; } @@ -620,7 +616,7 @@ IMUResetReason BNO08x::get_reset_reason() { // receive product ID report if (wait_for_data()) - xQueueReceive(queue_reset_reason, &reset_reason, HOST_INT_TIMEOUT_MS / portTICK_PERIOD_MS); + xQueueReceive(queue_reset_reason, &reset_reason, HOST_INT_TIMEOUT_MS); else ESP_LOGE(TAG, "Failed to receive product ID report."); } @@ -643,11 +639,7 @@ bool BNO08x::mode_on() success = wait_for_tx_done(); // flush any packets received - for (int i = 0; i < 3; i++) - { - wait_for_rx_done(); - vTaskDelay(10 / portTICK_PERIOD_MS); - } + flush_rx_packets(3, FLUSH_PKT_DELAY_MS); return success; } @@ -667,11 +659,7 @@ bool BNO08x::mode_sleep() success = wait_for_tx_done(); // flush any packets received - for (int i = 0; i < 3; i++) - { - wait_for_rx_done(); - vTaskDelay(10 / portTICK_PERIOD_MS); - } + flush_rx_packets(3, FLUSH_PKT_DELAY_MS); return success; } @@ -753,8 +741,7 @@ void BNO08x::enable_report(uint8_t report_ID, uint32_t time_between_reports, con } // flush the first few reports returned to ensure new data - for (int i = 0; i < 3; i++) - wait_for_rx_done(); + flush_rx_packets(3, 0); } /** @@ -835,6 +822,15 @@ void BNO08x::send_packet(bno08x_tx_packet_t* packet) xEventGroupSetBits(evt_grp_spi, EVT_GRP_SPI_TX_DONE_BIT); } +void BNO08x::flush_rx_packets(uint8_t flush_count, TickType_t delay) +{ + for (int i = 0; i < flush_count; i++) + { + wait_for_rx_done(); + vTaskDelay(delay); + } +} + /** * @brief Queues a packet containing a command. * @@ -877,7 +873,7 @@ void BNO08x::calibrate_all() { queue_calibrate_command(CALIBRATE_ACCEL_GYRO_MAG); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -889,7 +885,7 @@ void BNO08x::calibrate_accelerometer() { queue_calibrate_command(CALIBRATE_ACCEL); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -901,7 +897,7 @@ void BNO08x::calibrate_gyro() { queue_calibrate_command(CALIBRATE_GYRO); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -913,7 +909,7 @@ void BNO08x::calibrate_magnetometer() { queue_calibrate_command(CALIBRATE_MAG); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -925,7 +921,7 @@ void BNO08x::calibrate_planar_accelerometer() { queue_calibrate_command(CALIBRATE_PLANAR_ACCEL); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -990,7 +986,7 @@ void BNO08x::request_calibration_status() // Using this commands packet, send a command queue_command(COMMAND_ME_CALIBRATE, commands); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -1015,7 +1011,7 @@ void BNO08x::end_calibration() { queue_calibrate_command(CALIBRATE_STOP); // Disables all calibrations wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -1030,7 +1026,7 @@ void BNO08x::save_calibration() // Using this shtpData packet, send a command queue_command(COMMAND_DCD, commands); // Save DCD command wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(50 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -1874,7 +1870,7 @@ void BNO08x::tare_now(uint8_t axis_sel, uint8_t rotation_vector_basis) { queue_tare_command(TARE_NOW, axis_sel, rotation_vector_basis); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(12 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -1886,7 +1882,7 @@ void BNO08x::save_tare() { queue_tare_command(TARE_PERSIST); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(12 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -1898,7 +1894,7 @@ void BNO08x::clear_tare() { queue_tare_command(TARE_SET_REORIENTATION); wait_for_tx_done(); // wait for transmit operation to complete - vTaskDelay(12 / portTICK_PERIOD_MS); // allow some time for command to be executed + vTaskDelay(CMD_EXECUTION_DELAY_MS); // allow some time for command to be executed } /** @@ -2945,7 +2941,7 @@ bool BNO08x::FRS_read_data(uint16_t record_ID, uint8_t start_location, uint8_t w return false; } - if (xQueueReceive(queue_frs_read_data, &packet_body, HOST_INT_TIMEOUT_MS / portTICK_PERIOD_MS)) + if (xQueueReceive(queue_frs_read_data, &packet_body, HOST_INT_TIMEOUT_MS)) { if ((((uint16_t) packet_body[13] << 8) | (uint16_t) packet_body[12]) == record_ID) break; @@ -3195,6 +3191,9 @@ esp_err_t BNO08x::kill_all_tasks() static const constexpr uint8_t TASK_DELETE_TIMEOUT_MS = 10; uint8_t kill_count = 0; bno08x_rx_packet_t dummy_packet; + sem_kill_tasks = xSemaphoreCreateCounting(init_status.task_count, 0); + + memset(&dummy_packet, 0, sizeof(dummy_packet)); xEventGroupClearBits( evt_grp_task_flow, EVT_GRP_TSK_FLW_RUNNING_BIT); // clear task running bit in task flow event group to request deletion of tasks diff --git a/source/BNO08xTestSuite.cpp b/source/BNO08xTestSuite.cpp new file mode 100644 index 0000000..989b520 --- /dev/null +++ b/source/BNO08xTestSuite.cpp @@ -0,0 +1,13 @@ +#include "BNO08xTestSuite.hpp" + +void BNO08xTestSuite::run_all_tests() +{ + run_init_deinit_tests(); +} + +void BNO08xTestSuite::run_init_deinit_tests() +{ + UNITY_BEGIN(); + unity_run_test_by_name("Full Init & Deinit"); + UNITY_END(); +} \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..967612e --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRC_DIRS "." + INCLUDE_DIRS "." + REQUIRES cmock esp32_BNO08x) \ No newline at end of file diff --git a/test/InitDeinitTests.cpp b/test/InitDeinitTests.cpp new file mode 100644 index 0000000..106aa32 --- /dev/null +++ b/test/InitDeinitTests.cpp @@ -0,0 +1,26 @@ +#include "unity.h" +#include "../include/BNO08xTestHelper.hpp" + +TEST_CASE("Full Init & Deinit", "[InitDenit]") +{ + const constexpr char *TEST_TAG ="Full Init & Deinit"; + BNO08x* imu; + + BNO08xTestHelper::print_test_start_banner(TEST_TAG); + + BNO08xTestHelper::print_test_msg(TEST_TAG, "Initializing IMU 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 IMU."); + BNO08xTestHelper::destroy_test_imu(); + + BNO08xTestHelper::print_test_msg(TEST_TAG, "Initializing IMU 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 IMU."); + BNO08xTestHelper::destroy_test_imu(); + + BNO08xTestHelper::print_test_end_banner(TEST_TAG); +} \ No newline at end of file diff --git a/tests/BNO08xTestHelper.cpp b/tests/BNO08xTestHelper.cpp deleted file mode 100644 index 243f3b7..0000000 --- a/tests/BNO08xTestHelper.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "BNO08xTestHelper.hpp" - -BNO08x* BNO08xTestHelper::test_imu = nullptr; - -void BNO08xTestHelper::set_test_imu(BNO08x *imu) -{ - test_imu = imu; -} - -BNO08x* BNO08xTestHelper::get_test_imu() -{ - return test_imu; -} \ No newline at end of file diff --git a/tests/BNO08xTestHelper.hpp b/tests/BNO08xTestHelper.hpp deleted file mode 100644 index d116bf4..0000000 --- a/tests/BNO08xTestHelper.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "stdio.h" -#include "BNO08x.hpp" - -class BNO08xTestHelper -{ - public: - static void set_test_imu(BNO08x *imu); - static BNO08x* get_test_imu(); - private: - static BNO08x *test_imu; -}; \ No newline at end of file diff --git a/tests/BNO08xTestSuite.cpp b/tests/BNO08xTestSuite.cpp deleted file mode 100644 index 2652b07..0000000 --- a/tests/BNO08xTestSuite.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "BNO08xTestSuite.hpp" - -void BNO08xTestSuite::run_tests() -{ - BNO08x imu; - - BNO08xTestHelper::set_test_imu(&imu); - -} \ No newline at end of file diff --git a/tests/BNO08xTestSuite.hpp b/tests/BNO08xTestSuite.hpp deleted file mode 100644 index 32a52ef..0000000 --- a/tests/BNO08xTestSuite.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "BNO08xTestHelper.hpp" - -class BNO08xTestSuite -{ - public: - static void run_tests(); -}; \ No newline at end of file