HardFOC Vortex V1 HAL
Unified HAL API for the HardFOC Vortex motor-control platform (ESP32-C6, TMC9660)
Loading...
Searching...
No Matches
ImuManager.h
Go to the documentation of this file.
1
13#pragma once
14
15#include <array>
16#include <optional>
17#include "RtosMutex.h"
18#include "SignalSemaphore.h"
19#include "handlers/bno08x/Bno08xHandler.h"
20
21// Forward declarations (types defined in other managers)
23enum class SpiDeviceId : uint8_t;
24class GpioManager;
25class BaseGpio;
26class BaseI2c;
27class BaseSpi;
28
83using ImuInterruptCallback = void (*)(void* user_data);
84
85//==============================================================================
86// IMU ERROR CODES
87//==============================================================================
88
112
118constexpr const char* ImuErrorToString(ImuError error) noexcept {
119 switch (error) {
120 case ImuError::SUCCESS: return "Success";
121 case ImuError::NOT_INITIALIZED: return "Not initialized";
122 case ImuError::INITIALIZATION_FAILED: return "Initialization failed";
123 case ImuError::DEVICE_ALREADY_EXISTS: return "Device already exists";
124 case ImuError::DEVICE_NOT_FOUND: return "Device not found";
125 case ImuError::INVALID_DEVICE_INDEX: return "Invalid device index";
126 case ImuError::CANNOT_DELETE_ONBOARD: return "Cannot delete onboard device";
127 case ImuError::INVALID_I2C_ADDRESS: return "Invalid I2C address";
128 case ImuError::DEPENDENCY_NOT_READY: return "Dependency not ready";
129 case ImuError::COMMUNICATION_FAILED: return "Communication failed";
130 case ImuError::I2C_DEVICE_CREATION_FAILED: return "I2C device creation failed";
131 case ImuError::HANDLER_CREATION_FAILED: return "Handler creation failed";
132 case ImuError::INTERRUPT_ERROR: return "Interrupt configuration error";
133 case ImuError::ALREADY_DEINITIALIZED: return "Already deinitialized";
134 case ImuError::MUTEX_LOCK_FAILED: return "Mutex lock failed";
135 default: return "Unknown error";
136 }
137}
138
139//==============================================================================
140// IMU DIAGNOSTICS
141//==============================================================================
142
166
168public:
169 static constexpr uint8_t MAX_IMU_DEVICES = 4;
170 static constexpr uint8_t ONBOARD_IMU_INDEX = 0;
171 static constexpr uint8_t EXTERNAL_IMU_1_INDEX = 1;
172 static constexpr uint8_t EXTERNAL_IMU_2_INDEX = 2;
173 static constexpr uint8_t EXTERNAL_IMU_3_INDEX = 3;
174
175public:
180 static ImuManager& GetInstance() noexcept;
181
182 //**************************************************************************//
183 //** DEVICE MANAGEMENT METHODS **//
184 //**************************************************************************//
185
191 bool EnsureInitialized() noexcept;
192
197 bool IsInitialized() const noexcept;
198
203 [[nodiscard]] ImuError GetLastError() const noexcept { return last_error_.load(std::memory_order_acquire); }
204
210 [[nodiscard]] ImuError GetSystemDiagnostics(ImuSystemDiagnostics& diagnostics) const noexcept;
211
216 bool Deinitialize() noexcept;
217
218 //**************************************************************************//
219 //** HANDLER AND DRIVER MANAGEMENT **//
220 //**************************************************************************//
221
228 Bno08xHandler* GetBno08xHandler(uint8_t deviceIndex = ONBOARD_IMU_INDEX) noexcept;
229
240 template <typename Fn>
241 bool VisitSensor(uint8_t deviceIndex, Fn&& fn) noexcept {
242 MutexLockGuard lock(manager_mutex_);
243 if (deviceIndex >= MAX_IMU_DEVICES || !device_active_[deviceIndex] ||
244 !device_initialized_[deviceIndex] || !bno08x_handlers_[deviceIndex]) {
245 return false;
246 }
247 bool ran = false;
248 bno08x_handlers_[deviceIndex]->visitDriver([&](IBno08xDriverOps& driver) {
249 ran = true;
250 fn(driver);
251 });
252 return ran;
253 }
254
255 //**************************************************************************//
256 //** DEVICES MANAGEMENT METHODS **//
257 //**************************************************************************//
258
268 [[nodiscard]] ImuError CreateExternalBno08xDevice(uint8_t deviceIndex,
269 uint8_t i2c_address,
270 uint32_t i2c_speed_hz = 400000,
271 const Bno08xConfig& config = Bno08xHandler::GetDefaultConfig()) noexcept;
272
273
274
282 [[nodiscard]] ImuError CreateExternalBno08xDevice(uint8_t deviceIndex,
283 SpiDeviceId spiDeviceId,
284 const Bno08xConfig& config = Bno08xHandler::GetDefaultConfig()) noexcept;
285
294 [[nodiscard]] ImuError CreateExternalBno08xDevice(uint8_t deviceIndex,
295 BaseI2c& i2c_interface,
296 const Bno08xConfig& config = Bno08xHandler::GetDefaultConfig()) noexcept;
297
306 [[nodiscard]] ImuError CreateExternalBno08xDevice(uint8_t deviceIndex,
307 BaseSpi& spi_interface,
308 const Bno08xConfig& config = Bno08xHandler::GetDefaultConfig()) noexcept;
309
316 [[nodiscard]] ImuError DeleteExternalDevice(uint8_t deviceIndex) noexcept;
317
323 uint8_t GetDeviceCount() const noexcept;
324
330 bool IsDeviceValid(uint8_t deviceIndex) const noexcept;
331
337 bool IsExternalSlotAvailable(uint8_t deviceIndex) const noexcept;
338
344 void GetActiveDeviceIndices(std::array<uint8_t, MAX_IMU_DEVICES>& out, size_t& count) const noexcept;
345
351 size_t InitializeAllDevices(std::array<bool, MAX_IMU_DEVICES>& results) noexcept;
352
357 void GetInitializationStatus(std::array<bool, MAX_IMU_DEVICES>& status) const noexcept;
358
359 //**************************************************************************//
360 //** DEVICE INFORMATION METHODS **//
361 //**************************************************************************//
362
368 void GetAvailableDevices(std::array<const char*, MAX_IMU_DEVICES>& out, size_t& count) const noexcept;
369
375 [[nodiscard]] const char* GetDeviceType(uint8_t deviceIndex) const noexcept;
376
377 //**************************************************************************//
378 //** INTERRUPT SUPPORT METHODS **//
379 //**************************************************************************//
380
389 bool ConfigureInterrupt(uint8_t deviceIndex, ImuInterruptCallback callback = nullptr,
390 void* user_data = nullptr) noexcept;
391
398 bool EnableInterrupt(uint8_t deviceIndex) noexcept;
399
405 bool DisableInterrupt(uint8_t deviceIndex) noexcept;
406
412 bool IsInterruptEnabled(uint8_t deviceIndex) const noexcept;
413
421 bool WaitForInterrupt(uint8_t deviceIndex, uint32_t timeout_ms = 0) noexcept;
422
428 uint32_t GetInterruptCount(uint8_t deviceIndex) const noexcept;
429
434 void DumpStatistics() const noexcept;
435
436 // Delete copy/move constructors and assignment operators
437 ImuManager(const ImuManager&) = delete;
438 ImuManager& operator=(const ImuManager&) = delete;
440 ImuManager& operator=(ImuManager&&) = delete;
441
442private:
446 ImuManager() noexcept;
447
451 ~ImuManager() noexcept;
452
458 bool Initialize() noexcept;
459
464 bool InitializeOnboardBno08xDevice() noexcept;
465
470 bool InitializeInterruptGpio() noexcept;
471
477 bool IsExternalDeviceIndex(uint8_t deviceIndex) const noexcept;
478
484 void UpdateLastError(ImuError error, int deviceIndex = -1) noexcept;
485
492 static void GpioInterruptHandler(BaseGpio* gpio, hf_gpio_interrupt_trigger_t trigger, void* user_data) noexcept;
493
494 // ===============================
495 // SYSTEM STATE
496 // ===============================
497
501 std::atomic<bool> initialized_{false};
502
506 std::atomic<ImuError> last_error_{ImuError::SUCCESS};
507
511 std::array<std::atomic<uint32_t>, MAX_IMU_DEVICES> device_error_counts_{};
512
517 mutable RtosMutex manager_mutex_;
518
519 // ===============================
520 // DEVICE STORAGE
521 // ===============================
522
529 std::array<std::optional<Bno08xHandler>, MAX_IMU_DEVICES> bno08x_handlers_;
530
535 std::array<bool, MAX_IMU_DEVICES> device_initialized_;
536
541 std::array<bool, MAX_IMU_DEVICES> device_active_;
542
548
556 std::array<int, MAX_IMU_DEVICES> i2c_device_indices_;
557
558 // ===============================
559 // DEPENDENCIES
560 // ===============================
561
567
573
577 // PCAL95555 pins from GpioManager (non-owning; valid while GpioManager is initialised).
578 BaseGpio* onboard_bno_reset_gpio_{nullptr};
579 BaseGpio* onboard_bno_boot_gpio_{nullptr};
580 BaseGpio* onboard_bno_int_gpio_{nullptr};
581
582 // ===============================
583 // INTERRUPT SUPPORT
584 // ===============================
585
590 BaseGpio* interrupt_gpio_ = nullptr;
594 bool interrupt_enabled_ = false;
595 std::atomic<uint32_t> interrupt_count_{0};
596 SignalSemaphore interrupt_semaphore_{"VxImuInt"};
598};
599
600//==============================================================================
601// CONVENIENCE
602//==============================================================================
603
608[[nodiscard]] inline ImuManager& GetImuManager() noexcept {
610}
SpiDeviceId
SPI device identifiers for the Vortex V1 board.
Definition CommChannelsManager.h:113
constexpr const char * ImuErrorToString(ImuError error) noexcept
Convert ImuError to a human-readable string.
Definition ImuManager.h:118
ImuError
IMU manager error codes for consistent error reporting.
Definition ImuManager.h:95
@ NOT_INITIALIZED
Manager not yet initialised.
@ INTERRUPT_ERROR
GPIO interrupt configuration failed.
@ MUTEX_LOCK_FAILED
RTOS mutex acquire timed out.
@ INVALID_DEVICE_INDEX
Device index out of valid range.
@ DEPENDENCY_NOT_READY
Required dependency not initialised.
@ HANDLER_CREATION_FAILED
Heap allocation or handler init failed.
@ COMMUNICATION_FAILED
A bus-level transfer failed.
@ DEVICE_ALREADY_EXISTS
A device already occupies this slot.
@ CANNOT_DELETE_ONBOARD
Onboard device (index 0) cannot be deleted.
@ ALREADY_DEINITIALIZED
Manager already in deinitialized state.
@ DEVICE_NOT_FOUND
No active device at the given index.
@ SUCCESS
Operation completed successfully.
@ I2C_DEVICE_CREATION_FAILED
CommChannelsManager I²C device creation failed.
@ INVALID_I2C_ADDRESS
I²C address outside 0x08–0x77.
@ INITIALIZATION_FAILED
Device initialisation failed.
void(*)(void *user_data) ImuInterruptCallback
Callback for the onboard IMU interrupt (task context: the PCAL95555 handler dispatches it).
Definition ImuManager.h:83
ImuManager & GetImuManager() noexcept
Convenience accessor — equivalent to ImuManager::GetInstance().
Definition ImuManager.h:608
Singleton managing all board communication channels for Vortex V1.
Definition CommChannelsManager.h:149
Singleton managing GPIO pins across ESP32, PCAL95555 I/O expander, and TMC9660 controllers.
Definition GpioManager.h:110
Singleton for managing multiple IMU devices with indexed access and flexible device management.
Definition ImuManager.h:167
std::atomic< uint32_t > interrupt_count_
Definition ImuManager.h:595
std::array< int, MAX_IMU_DEVICES > i2c_device_indices_
Track I2C device indices created by ImuManager for proper cleanup. This is needed because external I2...
Definition ImuManager.h:556
uint8_t GetDeviceCount() const noexcept
Get the number of active IMU devices.
Definition ImuManager.cpp:404
RtosMutex manager_mutex_
Main system mutex for thread-safe operations. Uses RtosMutex for embedded RTOS compatibility.
Definition ImuManager.h:517
static void GpioInterruptHandler(BaseGpio *gpio, hf_gpio_interrupt_trigger_t trigger, void *user_data) noexcept
GPIO interrupt handler for BNO08x INT pin.
Definition ImuManager.cpp:859
bool VisitSensor(uint8_t deviceIndex, Fn &&fn) noexcept
Run fn on the BNO08x driver of one initialised device, under both locks.
Definition ImuManager.h:241
void GetAvailableDevices(std::array< const char *, MAX_IMU_DEVICES > &out, size_t &count) const noexcept
Get human-readable names of all available IMU devices.
Definition ImuManager.cpp:477
BaseGpio * interrupt_gpio_
GPIO interrupt support for onboard device. External devices may have their own interrupt configuratio...
Definition ImuManager.h:590
bool EnsureInitialized() noexcept
Ensure the IMU manager system is initialized.
Definition ImuManager.cpp:51
static constexpr uint8_t EXTERNAL_IMU_2_INDEX
External IMU device 2 index.
Definition ImuManager.h:172
bool IsInterruptEnabled(uint8_t deviceIndex) const noexcept
Check if interrupt is configured and enabled for specific device.
Definition ImuManager.cpp:618
bool Initialize() noexcept
Initialize the IMU manager system.
Definition ImuManager.cpp:662
size_t InitializeAllDevices(std::array< bool, MAX_IMU_DEVICES > &results) noexcept
Initialize all active IMU devices.
Definition ImuManager.cpp:442
std::array< bool, MAX_IMU_DEVICES > device_active_
Device active status tracking. Tracks which device slots have active devices.
Definition ImuManager.h:541
BaseGpio * onboard_bno_reset_gpio_
PCAL95555 nets for onboard BNO08x (Vortex): RSTN, BOOTN, INT — kept alive for handler lifetime.
Definition ImuManager.h:578
void UpdateLastError(ImuError error, int deviceIndex=-1) noexcept
Store a new error code and update per-device counter.
Definition ImuManager.cpp:787
std::array< std::optional< Bno08xHandler >, MAX_IMU_DEVICES > bno08x_handlers_
Array of BNO08x IMU handlers (one per device slot). Uses unique_ptr for exclusive ownership of each h...
Definition ImuManager.h:529
static constexpr uint8_t EXTERNAL_IMU_1_INDEX
External IMU device 1 index.
Definition ImuManager.h:171
void * interrupt_callback_user_
Definition ImuManager.h:592
bool IsExternalDeviceIndex(uint8_t deviceIndex) const noexcept
Validate if device index is for external device.
Definition ImuManager.cpp:398
Bno08xHandler * GetBno08xHandler(uint8_t deviceIndex=ONBOARD_IMU_INDEX) noexcept
Get access to BNO08x IMU handler by device index.
Definition ImuManager.cpp:128
static constexpr uint8_t EXTERNAL_IMU_3_INDEX
External IMU device 3 index.
Definition ImuManager.h:173
bool InitializeInterruptGpio() noexcept
Initialize GPIO interrupt for BNO08x INT pin.
Definition ImuManager.cpp:826
const char * GetDeviceType(uint8_t deviceIndex) const noexcept
Get device type by index.
Definition ImuManager.cpp:494
std::array< std::atomic< uint32_t >, MAX_IMU_DEVICES > device_error_counts_
Per-device cumulative error counters.
Definition ImuManager.h:511
GpioManager * gpio_manager_
Reference to GPIO manager for interrupt pin access. Used for configuring interrupt pins for IMU devic...
Definition ImuManager.h:572
static ImuManager & GetInstance() noexcept
Get the singleton instance of ImuManager.
Definition ImuManager.cpp:33
std::atomic< bool > initialized_
System initialization state (atomic for thread safety).
Definition ImuManager.h:501
BaseGpio * onboard_bno_boot_gpio_
Definition ImuManager.h:579
bool ConfigureInterrupt(uint8_t deviceIndex, ImuInterruptCallback callback=nullptr, void *user_data=nullptr) noexcept
Configure GPIO interrupt for BNO08x INT pin on specific device.
Definition ImuManager.cpp:508
bool DisableInterrupt(uint8_t deviceIndex) noexcept
Disable BNO08x GPIO interrupt for specific device.
Definition ImuManager.cpp:589
uint32_t GetInterruptCount(uint8_t deviceIndex) const noexcept
Get interrupt statistics for monitoring for specific device.
Definition ImuManager.cpp:649
void GetInitializationStatus(std::array< bool, MAX_IMU_DEVICES > &status) const noexcept
Get initialization status of all device slots.
Definition ImuManager.cpp:465
bool interrupt_semaphore_ready_
Definition ImuManager.h:597
bool IsInitialized() const noexcept
Check if the IMU manager is initialized.
Definition ImuManager.cpp:66
static constexpr uint8_t MAX_IMU_DEVICES
Maximum supported IMU devices.
Definition ImuManager.h:169
SignalSemaphore interrupt_semaphore_
Signalled per INT edge; WaitForInterrupt() takes it.
Definition ImuManager.h:596
bool InitializeOnboardBno08xDevice() noexcept
Initialize the onboard BNO08x IMU device with I2C transport.
Definition ImuManager.cpp:737
ImuError DeleteExternalDevice(uint8_t deviceIndex) noexcept
Delete an external IMU device.
Definition ImuManager.cpp:364
static constexpr uint8_t ONBOARD_IMU_INDEX
Onboard IMU device index (BNO08x)
Definition ImuManager.h:170
void DumpStatistics() const noexcept
Dump comprehensive system statistics to log as INFO level. Logs all device statistics,...
Definition ImuManager.cpp:883
ImuError GetSystemDiagnostics(ImuSystemDiagnostics &diagnostics) const noexcept
Fill a diagnostics snapshot with current system state.
Definition ImuManager.cpp:794
bool interrupt_configured_
Definition ImuManager.h:593
ImuInterruptCallback interrupt_callback_
Plain function pointer (no heap)
Definition ImuManager.h:591
std::array< bool, MAX_IMU_DEVICES > device_initialized_
Device initialization status tracking. Tracks which devices have been successfully initialized.
Definition ImuManager.h:535
bool WaitForInterrupt(uint8_t deviceIndex, uint32_t timeout_ms=0) noexcept
Wait for interrupt signal with timeout for specific device.
Definition ImuManager.cpp:629
ImuError GetLastError() const noexcept
Get the most recent error code.
Definition ImuManager.h:203
bool IsExternalSlotAvailable(uint8_t deviceIndex) const noexcept
Check if an external device slot is available for creation.
Definition ImuManager.cpp:421
bool onboard_device_created_
Onboard device creation tracking. Tracks if onboard device has been created.
Definition ImuManager.h:547
bool Deinitialize() noexcept
Deinitialize all IMUs and release resources.
Definition ImuManager.cpp:70
bool IsDeviceValid(uint8_t deviceIndex) const noexcept
Check if a device index is valid and has an active device.
Definition ImuManager.cpp:416
void GetActiveDeviceIndices(std::array< uint8_t, MAX_IMU_DEVICES > &out, size_t &count) const noexcept
Get indices of all active IMU devices.
Definition ImuManager.cpp:431
CommChannelsManager * comm_manager_
Reference to communication manager for I2C/SPI access. Used for creating IMU devices with proper tran...
Definition ImuManager.h:566
std::atomic< ImuError > last_error_
Most recent error code for system-level tracking.
Definition ImuManager.h:506
BaseGpio * onboard_bno_int_gpio_
Definition ImuManager.h:580
bool EnableInterrupt(uint8_t deviceIndex) noexcept
Enable BNO08x GPIO interrupt for specific device.
Definition ImuManager.cpp:559
ImuError CreateExternalBno08xDevice(uint8_t deviceIndex, uint8_t i2c_address, uint32_t i2c_speed_hz=400000, const Bno08xConfig &config=Bno08xHandler::GetDefaultConfig()) noexcept
Create an external BNO08x IMU device on I2C interface with specified address.
Definition ImuManager.cpp:142
bool interrupt_enabled_
Definition ImuManager.h:594
Per-device health snapshot.
Definition ImuManager.h:154
uint32_t error_count
Cumulative errors for this slot.
Definition ImuManager.h:157
bool initialized
Device initialised successfully.
Definition ImuManager.h:156
bool active
Slot has a device.
Definition ImuManager.h:155
System-level diagnostics snapshot for IMU health monitoring.
Definition ImuManager.h:146
bool interrupt_configured
True if onboard interrupt GPIO is configured.
Definition ImuManager.h:163
ImuError last_error
Most recent error code.
Definition ImuManager.h:151
bool system_initialized
ImuManager::IsInitialized()
Definition ImuManager.h:148
uint32_t total_interrupt_count
Cumulative interrupt events across all devices.
Definition ImuManager.h:162
static constexpr uint8_t kMaxDevices
Definition ImuManager.h:159
bool system_healthy
True when all active devices are healthy.
Definition ImuManager.h:147
uint8_t initialized_device_count
Number of successfully initialised devices.
Definition ImuManager.h:150
bool interrupt_enabled
True if onboard interrupt is actively enabled.
Definition ImuManager.h:164
DeviceSnapshot devices[kMaxDevices]
Per-slot snapshots (0–kMaxDevices-1)
Definition ImuManager.h:160
uint8_t active_device_count
Number of active device slots.
Definition ImuManager.h:149