HardFOC Vortex V1 HAL
Unified HAL API for the HardFOC Vortex motor-control platform (ESP32-C6, TMC9660)
Loading...
Searching...
No Matches
CommChannelsManager.h
Go to the documentation of this file.
1
23#ifndef VORTEX_COMM_CHANNELS_MANAGER_H_
24#define VORTEX_COMM_CHANNELS_MANAGER_H_
25
26#include <array>
27#include <atomic>
28#include <cstdint>
29#include <memory>
30
31
32#include "base/BaseSpi.h"
33#include "base/BaseI2c.h"
34#include "base/BaseUart.h"
35#include "base/BaseCan.h"
36#include "RtosMutex.h"
37
38//==============================================================================
39// COMM CHANNELS ERROR CODES
40//==============================================================================
41
62
68constexpr const char* CommErrorToString(CommError error) noexcept {
69 switch (error) {
70 case CommError::SUCCESS: return "Success";
71 case CommError::NOT_INITIALIZED: return "Not initialized";
72 case CommError::INITIALIZATION_FAILED: return "Initialization failed";
73 case CommError::BUS_NOT_AVAILABLE: return "Bus not available";
74 case CommError::DEVICE_NOT_FOUND: return "Device not found";
75 case CommError::INVALID_BUS_INDEX: return "Invalid bus index";
76 case CommError::INVALID_DEVICE_INDEX: return "Invalid device index";
77 case CommError::DEVICE_ALREADY_EXISTS: return "Device already exists";
78 case CommError::DEVICE_CREATION_FAILED: return "Device creation failed";
79 case CommError::COMMUNICATION_FAILED: return "Communication failed";
80 case CommError::INVALID_PARAMETER: return "Invalid parameter";
81 case CommError::MUTEX_LOCK_FAILED: return "Mutex lock failed";
82 default: return "Unknown error";
83 }
84}
85
86//==============================================================================
87// COMM CHANNELS DIAGNOSTICS
88//==============================================================================
89
104
105//==============================================================================
106// SPI DEVICE IDENTIFIERS
107//==============================================================================
108
113enum class SpiDeviceId : uint8_t {
119};
120
121//==============================================================================
122// I2C DEVICE IDENTIFIERS
123//==============================================================================
124
128enum class I2cDeviceId : uint8_t {
129 BNO08X_IMU = 0,
132};
133
134//==============================================================================
135// COMM CHANNELS MANAGER
136//==============================================================================
137
150public:
152 static CommChannelsManager& GetInstance() noexcept;
153
154 // Non-copyable, non-movable
159
160 //==========================================================================
161 // INITIALIZATION
162 //==========================================================================
163
168 bool EnsureInitialized() noexcept;
169
174 [[nodiscard]] bool IsInitialized() const noexcept { return initialized_.load(std::memory_order_acquire); }
175
180 [[nodiscard]] CommError GetLastError() const noexcept { return last_error_.load(std::memory_order_acquire); }
181
187 [[nodiscard]] CommError GetSystemDiagnostics(CommSystemDiagnostics& diagnostics) const noexcept;
188
193 bool Deinitialize() noexcept;
194
195 //==========================================================================
196 // SPI ACCESSORS
197 //==========================================================================
198
204 BaseSpi* GetSpiDevice(SpiDeviceId device_id) noexcept;
205
211 BaseSpi* GetSpiDevice(uint8_t device_index) noexcept;
212
213 //==========================================================================
214 // I2C ACCESSORS
215 //==========================================================================
216
222 BaseI2c* GetI2cDevice(I2cDeviceId device_id) noexcept;
223
230 BaseI2c* GetI2cDevice(uint8_t bus_index, int device_index) noexcept;
231
232 //==========================================================================
233 // RUNTIME I2C DEVICE MANAGEMENT (for ImuManager)
234 //==========================================================================
235
242 int CreateI2cDevice(uint8_t device_address, uint32_t speed_hz = 400000) noexcept;
243
250 bool HasI2cDeviceAtAddress(uint8_t bus_index, uint8_t device_address) const noexcept;
251
257 bool RemoveI2cDevice(int device_index) noexcept;
258
259 //==========================================================================
260 // I2C BUS DIAGNOSTICS — bring-up helpers
261 //==========================================================================
262
269 [[nodiscard]] bool I2cProbeAddress(uint8_t address, uint32_t timeout_ms = 25) noexcept;
270
277 size_t I2cScanBus(uint8_t* out, size_t max_results) noexcept;
278
283 bool I2cResetBus() noexcept;
284
285 //==========================================================================
286 // UART / CAN ACCESSORS
287 //==========================================================================
288
293 BaseUart* GetUartBus() noexcept;
294
299 BaseCan* GetCanBus() noexcept;
300
307 BaseCan* GetCanOpenBus() noexcept { return GetCanBus(); }
308
309 // The concrete TWAI controller (EspCan, for hf-core's EspTwaiPort) is not handed out here: this
310 // header is MCU-free. Platform code gets it from its board binding, e.g. on the ESP32-C6
311 // vortex::bsp::esp32c6::CanController() in bsp_bind/esp32c6/VortexBoardBindEsp32c6.h.
312
314 uint32_t GetCanBitRate() const noexcept;
315
316 //==========================================================================
317 // DIAGNOSTICS
318 //==========================================================================
319
321 void DumpStatistics() const noexcept;
322
323private:
324 CommChannelsManager() noexcept;
326
327 bool Initialize() noexcept;
328
330 void ReleaseLocked() noexcept;
331
332 //==========================================================================
333 // BUS RESOURCES — created by the board binding (bsp_bind/VortexBoardBind.h),
334 // which owns the bus objects in static storage; this manager keeps indices
335 // and non-owning pointers.
336 //==========================================================================
337
338 // SPI bus + device indices
339 static constexpr uint8_t kSpiDeviceCount =
340 static_cast<uint8_t>(SpiDeviceId::DEVICE_COUNT);
342 bool spi_bus_valid_{false};
343 bool uart_bus_valid_{false};
344 bool can_bus_valid_{false};
345
346 // I2C bus — built-in devices + bounded runtime slots
347 static constexpr uint8_t kI2cBuiltinCount =
348 static_cast<uint8_t>(I2cDeviceId::DEVICE_COUNT);
349 static constexpr uint8_t kMaxI2cRuntimeDevices = 4;
350 std::array<int, kI2cBuiltinCount> i2c_builtin_indices_{};
351 bool i2c_bus_valid_{false};
352
355 uint8_t address{0xFF};
356 bool active{false};
357 };
358 std::array<RuntimeI2cSlot, kMaxI2cRuntimeDevices> i2c_runtime_slots_{};
359
360 // UART bus (TMC9660 TMCL) and CAN bus
361 BaseUart* uart_bus_{nullptr};
362 BaseCan* can_bus_{nullptr};
363
364 std::atomic<bool> initialized_{false};
365 std::atomic<CommError> last_error_{CommError::SUCCESS};
366 mutable RtosMutex mutex_;
367
368 void UpdateLastError(CommError error) noexcept {
369 last_error_.store(error, std::memory_order_release);
370 }
371};
372
380
381#endif // VORTEX_COMM_CHANNELS_MANAGER_H_
CommChannelsManager & GetCommChannelsManager() noexcept
Convenience accessor — equivalent to CommChannelsManager::GetInstance().
Definition CommChannelsManager.h:377
constexpr const char * CommErrorToString(CommError error) noexcept
Convert CommError to a human-readable string.
Definition CommChannelsManager.h:68
CommError
Communication channels manager error codes for consistent error reporting.
Definition CommChannelsManager.h:48
@ NOT_INITIALIZED
Manager not yet initialised.
@ INVALID_BUS_INDEX
Bus index out of range.
@ MUTEX_LOCK_FAILED
RTOS mutex acquire timed out.
@ INVALID_DEVICE_INDEX
Device index out of range.
@ COMMUNICATION_FAILED
A bus-level transfer failed.
@ DEVICE_ALREADY_EXISTS
A device at that address already exists.
@ DEVICE_NOT_FOUND
Device index or id not in registry.
@ SUCCESS
Operation completed successfully.
@ DEVICE_CREATION_FAILED
Heap allocation or driver init for device failed.
@ BUS_NOT_AVAILABLE
Requested bus is not present or not ready.
@ INITIALIZATION_FAILED
Bus or device initialisation failed.
@ INVALID_PARAMETER
Null pointer or out-of-range argument.
SpiDeviceId
SPI device identifiers for the Vortex V1 board.
Definition CommChannelsManager.h:113
@ DEVICE_COUNT
Sentinel — total number of SPI devices.
@ EXTERNAL_DEVICE_2
External device slot 2 (SPI Mode 0)
@ AS5047U_POSITION_ENCODER
AS5047U position encoder (SPI Mode 1)
@ TMC9660_MOTOR_CONTROLLER
TMC9660 motor controller (SPI Mode 3)
@ EXTERNAL_DEVICE_1
External device slot 1 (SPI Mode 0)
I2cDeviceId
I2C device identifiers for the Vortex V1 board (built-in devices).
Definition CommChannelsManager.h:128
@ DEVICE_COUNT
Sentinel — total number of built-in I2C devices.
@ PCAL9555_GPIO_EXPANDER
PCAL95555 GPIO expander (address 0x20)
@ BNO08X_IMU
BNO08x IMU sensor (address 0x4A)
Singleton managing all board communication channels for Vortex V1.
Definition CommChannelsManager.h:149
bool HasI2cDeviceAtAddress(uint8_t bus_index, uint8_t device_address) const noexcept
Check if an I2C device exists at the specified address.
Definition CommChannelsManager.cpp:333
static constexpr uint8_t kMaxI2cRuntimeDevices
Definition CommChannelsManager.h:349
size_t I2cScanBus(uint8_t *out, size_t max_results) noexcept
Scan the primary I²C bus and copy ACKing addresses into out.
Definition CommChannelsManager.cpp:391
BaseCan * GetCanOpenBus() noexcept
TWAI bus used for CANopen / hf-utils-canopen framing (HfUtilsCanOpenTransport).
Definition CommChannelsManager.h:307
BaseUart * GetUartBus() noexcept
Get the UART bus (TMC9660 TMCL).
Definition CommChannelsManager.cpp:415
bool RemoveI2cDevice(int device_index) noexcept
Remove a runtime-created I2C device.
Definition CommChannelsManager.cpp:351
void DumpStatistics() const noexcept
Log communication channel statistics and bus health to the console.
Definition CommChannelsManager.cpp:433
static constexpr uint8_t kI2cBuiltinCount
Definition CommChannelsManager.h:347
CommChannelsManager & operator=(const CommChannelsManager &)=delete
uint32_t GetCanBitRate() const noexcept
Nominal bit rate the TWAI bus was configured with (bit/s).
Definition CommChannelsManager.cpp:427
bool uart_bus_valid_
Definition CommChannelsManager.h:343
CommChannelsManager(const CommChannelsManager &)=delete
bool i2c_bus_valid_
Definition CommChannelsManager.h:351
bool I2cProbeAddress(uint8_t address, uint32_t timeout_ms=25) noexcept
Probe a single 7-bit address on the primary I²C bus.
Definition CommChannelsManager.cpp:383
std::array< int, kI2cBuiltinCount > i2c_builtin_indices_
Definition CommChannelsManager.h:350
BaseCan * GetCanBus() noexcept
Get the TWAI/CAN bus.
Definition CommChannelsManager.cpp:421
static constexpr uint8_t kSpiDeviceCount
Definition CommChannelsManager.h:339
CommError GetSystemDiagnostics(CommSystemDiagnostics &diagnostics) const noexcept
Fill a diagnostics snapshot with current system state.
Definition CommChannelsManager.cpp:457
bool I2cResetBus() noexcept
Reset the I²C peripheral / clear-bus sequence (only attempts when bus is up).
Definition CommChannelsManager.cpp:403
std::array< RuntimeI2cSlot, kMaxI2cRuntimeDevices > i2c_runtime_slots_
Definition CommChannelsManager.h:358
bool Initialize() noexcept
Definition CommChannelsManager.cpp:73
bool spi_bus_valid_
Definition CommChannelsManager.h:342
bool Deinitialize() noexcept
Release all bus resources and reset to uninitialized state.
Definition CommChannelsManager.cpp:491
std::array< int, kSpiDeviceCount > spi_device_indices_
Definition CommChannelsManager.h:341
CommChannelsManager(CommChannelsManager &&)=delete
void UpdateLastError(CommError error) noexcept
Definition CommChannelsManager.h:368
BaseUart * uart_bus_
Definition CommChannelsManager.h:361
BaseSpi * GetSpiDevice(SpiDeviceId device_id) noexcept
Get an SPI device handle by enum identifier.
Definition CommChannelsManager.cpp:237
bool can_bus_valid_
Definition CommChannelsManager.h:344
int CreateI2cDevice(uint8_t device_address, uint32_t speed_hz=400000) noexcept
Create an I2C device on the primary bus at runtime.
Definition CommChannelsManager.cpp:276
void ReleaseLocked() noexcept
Close every bus through the binding and forget the indices. Caller holds mutex_.
Definition CommChannelsManager.cpp:502
RtosMutex mutex_
Definition CommChannelsManager.h:366
std::atomic< bool > initialized_
Definition CommChannelsManager.h:364
static CommChannelsManager & GetInstance() noexcept
Return the singleton CommChannelsManager instance.
Definition CommChannelsManager.cpp:46
CommChannelsManager & operator=(CommChannelsManager &&)=delete
bool IsInitialized() const noexcept
Check whether the communication subsystem has been initialised.
Definition CommChannelsManager.h:174
BaseI2c * GetI2cDevice(I2cDeviceId device_id) noexcept
Get a built-in I²C device by enum identifier.
Definition CommChannelsManager.cpp:254
BaseCan * can_bus_
Definition CommChannelsManager.h:362
CommError GetLastError() const noexcept
Get the most recent error code.
Definition CommChannelsManager.h:180
bool EnsureInitialized() noexcept
Initialise all communication buses if not already initialised.
Definition CommChannelsManager.cpp:60
std::atomic< CommError > last_error_
Definition CommChannelsManager.h:365
Definition CommChannelsManager.h:353
uint8_t address
Definition CommChannelsManager.h:355
bool active
Definition CommChannelsManager.h:356
int device_index
Definition CommChannelsManager.h:354
System-level diagnostics snapshot for communication channels.
Definition CommChannelsManager.h:93
bool i2c_bus_valid
I²C bus initialised and usable.
Definition CommChannelsManager.h:97
bool system_healthy
True when all configured buses are operational.
Definition CommChannelsManager.h:94
bool can_bus_valid
CAN/TWAI bus initialised and usable.
Definition CommChannelsManager.h:99
bool uart_bus_valid
UART bus initialised and usable.
Definition CommChannelsManager.h:98
uint8_t i2c_runtime_device_count
Number of active runtime I²C devices.
Definition CommChannelsManager.h:101
uint8_t spi_device_count
Number of SPI devices with valid indices.
Definition CommChannelsManager.h:100
bool spi_bus_valid
SPI bus initialised and usable.
Definition CommChannelsManager.h:96
bool system_initialized
True if EnsureInitialized() completed.
Definition CommChannelsManager.h:95
CommError last_error
Most recent error code from any operation.
Definition CommChannelsManager.h:102