From 0e9c27bfde831c4b532b26ab7c56aea4573a8936 Mon Sep 17 00:00:00 2001 From: myles-parfeniuk Date: Tue, 26 Nov 2024 00:47:01 -0800 Subject: [PATCH] soft_reset(), hard_reset() --- include/BNO08x.hpp | 8 +- include/BNO08x_global_types.hpp | 11 ++ source/BNO08x.cpp | 184 +++++++++++++++++++++++++++++--- source/BNO08xRpt.cpp | 1 - source/BNO08xSH2HAL.cpp | 2 +- 5 files changed, 188 insertions(+), 18 deletions(-) diff --git a/include/BNO08x.hpp b/include/BNO08x.hpp index a8c1a40..6662e48 100644 --- a/include/BNO08x.hpp +++ b/include/BNO08x.hpp @@ -67,7 +67,8 @@ class BNO08x ~BNO08x(); bool initialize(); - void hard_reset(); + bool hard_reset(); + bool soft_reset(); bool data_available(); void register_cb(std::function cb_fxn); @@ -147,7 +148,7 @@ class BNO08x void data_proc_task(); // sh2 service task - static const constexpr configSTACK_DEPTH_TYPE SH2_HAL_SERVICE_TASK_SZ = 2048UL; ///< Size of sh2_HAL_service_task() stack in bytes + static const constexpr configSTACK_DEPTH_TYPE SH2_HAL_SERVICE_TASK_SZ = 4095UL; ///< Size of sh2_HAL_service_task() stack in bytes TaskHandle_t sh2_HAL_service_task_hdl; ///(product_IDs.entry[0].resetCause) == BNO08xResetReason::EXT_RST) + { + return true; + } + else + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Hard reset failure, incorrect reset reason returned: %d.", product_IDs.entry[0].resetCause); + #endif + // clang-format on + } + } + else + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Hard reset failure, failed to get prodIDs."); + #endif + // clang-format on + } + } + else + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Hard reset failure, reset never detected after toggling reset pin"); + #endif + // clang-format on + } + + return false; +} + +/** + * @brief Soft resets BNO08x device by sending RESET (1) command on "device" channel. + * + * @return True if soft reset operation succeeded. + */ +bool BNO08x::soft_reset() +{ + int op_success = SH2_ERR; + + lock_sh2_HAL(); + op_success = sh2_devReset(); + unlock_sh2_HAL(); + + if (op_success == SH2_OK) + { + // wait for reset and run service to dispatch callbacks + if (wait_for_reset() == ESP_OK) + { + lock_sh2_HAL(); + sh2_service(); + unlock_sh2_HAL(); + + // get product ids and check reset reason + memset(&product_IDs, 0, sizeof(sh2_ProductIds_t)); + lock_sh2_HAL(); + op_success = sh2_getProdIds(&product_IDs); + unlock_sh2_HAL(); + + if (op_success == SH2_OK) + { + if (static_cast(product_IDs.entry[0].resetCause) == BNO08xResetReason::EXT_RST) + { + return true; + } + else + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Soft reset failure, incorrect reset reason returned."); + #endif + // clang-format on + } + } + else + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Soft reset failure, failed to get prodIDs."); + #endif + // clang-format on + } + } + else + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Soft reset failure, reset never detected after sending command."); + #endif + // clang-format on + } + } + else + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Soft reset failure, failed to send reset command"); + #endif + // clang-format on + } + + return false; } /** @@ -1063,6 +1176,42 @@ esp_err_t BNO08x::wait_for_hint() return ESP_ERR_TIMEOUT; } +/** + * @brief Waits for SH2 HAL lib to detect reset or HOST_INT_TIMEOUT_DEFAULT_MS to elapse. + * + * + * @return ESP_OK if reset was detected by SH2 HAL lib. + */ +esp_err_t BNO08x::wait_for_reset() +{ + if (xEventGroupWaitBits(evt_grp_bno08x_task, EVT_GRP_BNO08x_TASK_RESET_OCCURRED, pdFALSE, pdFALSE, HOST_INT_TIMEOUT_DEFAULT_MS) & + EVT_GRP_BNO08x_TASK_RESET_OCCURRED) + return ESP_OK; + else + return ESP_ERR_TIMEOUT; +} + +/** + * @brief Toggles reset gpio pin for hard reset of BNO08x device. + * + * + * @return void, nothing to return + */ +void BNO08x::toggle_reset() +{ + gpio_intr_disable(imu_config.io_int); // disable interrupts before reset + + gpio_set_level(imu_config.io_cs, 1); + + if (imu_config.io_wake != GPIO_NUM_NC) + gpio_set_level(imu_config.io_wake, 1); + + gpio_set_level(imu_config.io_rst, 0); // set reset pin low + vTaskDelay(HARD_RESET_DELAY_MS); // 10ns min, set to larger delay to let things stabilize(Anton) + gpio_intr_enable(imu_config.io_int); // enable interrupts before bringing out of reset + gpio_set_level(imu_config.io_rst, 1); // bring out of reset +} + /** * @brief Re-enables all reports enabled by user (called when BNO08x reset is detected by sh2 HAL lib). * @@ -1079,7 +1228,14 @@ esp_err_t BNO08x::re_enable_reports() if (rpt->rpt_bit & report_en_bits) { if (!rpt->enable(rpt->period_us)) + { + // clang-format off + #ifdef CONFIG_ESP32_BNO08x_LOG_STATEMENTS + ESP_LOGE(TAG, "Failed to re-enable: %d", rpt->ID); + #endif + // clang-format on return ESP_FAIL; + } } } diff --git a/source/BNO08xRpt.cpp b/source/BNO08xRpt.cpp index 2599bda..0f8bf8c 100644 --- a/source/BNO08xRpt.cpp +++ b/source/BNO08xRpt.cpp @@ -27,7 +27,6 @@ bool BNO08xRpt::enable(uint32_t time_between_reports, sh2_SensorConfig_t sensor_ } else { - flush(); period_us = time_between_reports; // Update the period xEventGroupSetBits(imu->evt_grp_report_en, rpt_bit); // Set the event group bit return true; diff --git a/source/BNO08xSH2HAL.cpp b/source/BNO08xSH2HAL.cpp index 0609a00..fed8789 100644 --- a/source/BNO08xSH2HAL.cpp +++ b/source/BNO08xSH2HAL.cpp @@ -90,7 +90,7 @@ void BNO08xSH2HAL::sensor_event_cb(void* cookie, sh2_SensorEvent_t* event) void BNO08xSH2HAL::hardware_reset() { - imu->hard_reset(); + imu->toggle_reset(); } bool BNO08xSH2HAL::spi_wait_for_int()