HF Interface Wrapper 0.1.0-dev
Embedded C++ hardware abstraction layer
Loading...
Searching...
No Matches
EspI2c.h
Go to the documentation of this file.
1#ifndef ESP_I2C_H_
2#define ESP_I2C_H_
3
109#pragma once
110
111#include "BaseI2c.h"
112#include "utils/EspTypes.h"
113#include "utils/PlatformMutex.h"
114#include <memory>
115#include <vector>
116
117// ESP-IDF C headers must be wrapped in extern "C" for C++ compatibility
118#ifdef __cplusplus
119extern "C" {
120#endif
121#include "driver/i2c_master.h"
122#include "esp_log.h"
123#ifdef __cplusplus
124}
125#endif
126
127// Forward declarations
128class EspI2cBus;
129class EspI2cDevice;
130
143
149const char* HfI2COperationToString(hf_i2c_operation_t op) noexcept;
150
164class EspI2cDevice : public BaseI2c {
165public:
171 EspI2cDevice(EspI2cBus* parent, const hf_i2c_device_config_t& config);
172
176 ~EspI2cDevice() noexcept override;
177
182 bool Initialize() noexcept override;
183
191 bool MarkAsDeinitialized() noexcept;
192
200 bool Deinitialize() noexcept override;
201
210 hf_i2c_err_t Write(const hf_u8_t* data, hf_u16_t length,
211 hf_u32_t timeout_ms = 0) noexcept override;
212
221 hf_i2c_err_t Read(hf_u8_t* data, hf_u16_t length, hf_u32_t timeout_ms = 0) noexcept override;
222
233 hf_i2c_err_t WriteRead(const hf_u8_t* tx_data, hf_u16_t tx_length, hf_u8_t* rx_data,
234 hf_u16_t rx_length, hf_u32_t timeout_ms = 0) noexcept override;
235
236 //==============================================//
237 // ASYNC OPERATIONS - ESP-IDF v5.5+ FEATURES //
238 //==============================================//
239
253 hf_i2c_err_t WriteAsync(const hf_u8_t* data, hf_u16_t length, hf_i2c_async_callback_t callback,
254 void* user_data = nullptr, hf_u32_t timeout_ms = 1000) noexcept;
255
270 void* user_data = nullptr, hf_u32_t timeout_ms = 1000) noexcept;
271
287 hf_i2c_err_t WriteReadAsync(const hf_u8_t* tx_data, hf_u16_t tx_length, hf_u8_t* rx_data,
288 hf_u16_t rx_length, hf_i2c_async_callback_t callback,
289 void* user_data = nullptr, hf_u32_t timeout_ms = 1000) noexcept;
290
295 bool IsAsyncModeSupported() const noexcept;
296
301 bool IsAsyncOperationInProgress() const noexcept;
302
307 bool IsSyncOperationInProgress() const noexcept;
308
314 bool WaitAsyncOperationComplete(hf_u32_t timeout_ms = 0) noexcept;
315
321 hf_i2c_err_t GetStatistics(hf_i2c_statistics_t& statistics) const noexcept override;
322
328 hf_i2c_err_t GetDiagnostics(hf_i2c_diagnostics_t& diagnostics) const noexcept override;
329
334 hf_i2c_err_t ResetStatistics() noexcept override;
335
340 i2c_master_dev_handle_t GetHandle() const noexcept;
341
346 const hf_i2c_device_config_t& GetConfig() const noexcept;
347
352 hf_u16_t GetDeviceAddress() const noexcept;
353
359 hf_i2c_err_t GetActualClockFrequency(hf_u32_t& actual_freq_hz) const noexcept;
360
365 bool ProbeDevice() noexcept;
366
371 i2c_master_dev_handle_t GetDeviceHandle() const noexcept {
372 return handle_;
373 }
374
382
387 void* GetCurrentUserData() const noexcept {
388 return current_user_data_;
389 }
390
395 void UpdateErrorRecoveryAttempt() noexcept;
396
397 //==============================================//
398 // MODE-AWARE OPERATION METHODS //
399 //==============================================//
400
405 hf_i2c_mode_t GetMode() const noexcept;
406
411 bool IsAsyncMode() const noexcept;
412
417 bool IsSyncMode() const noexcept;
418
419private:
420 //==============================================//
421 // ESP-IDF v5.5 ASYNC CALLBACK BRIDGE //
422 //==============================================//
423
432 static bool InternalAsyncCallback(i2c_master_dev_handle_t i2c_dev,
433 const i2c_master_event_data_t* evt_data, void* arg);
434
442 bool RegisterTemporaryCallback(hf_i2c_async_callback_t callback, void* user_data,
443 hf_u32_t timeout_ms) noexcept;
444
448 void UnregisterTemporaryCallback() noexcept;
449
453 inline void StartAsyncOperationTracking() noexcept;
454
461 void UpdateStatistics(bool success, size_t bytes_transferred,
462 hf_u64_t operation_time_us) noexcept;
463
468 void UpdateErrorStatistics(hf_i2c_err_t error_code) noexcept;
469
475 hf_i2c_err_t ConvertEspError(esp_err_t esp_error) const noexcept;
476
484 bool ValidateOperation(const void* data, hf_u16_t length,
485 hf_i2c_operation_t operation_type) noexcept;
486
492 bool SetupSyncOperation(hf_i2c_operation_t operation_type) noexcept;
493
497 void CleanupSyncOperation() noexcept;
498
502 void CleanupAsyncOperation() noexcept;
503
511 bool SetupAsyncOperation(hf_i2c_async_callback_t callback, void* user_data,
512 hf_u32_t timeout_ms) noexcept;
513
514 //==============================================//
515 // MEMBER VARIABLES //
516 //==============================================//
517
519 i2c_master_dev_handle_t handle_;
526
527 //==============================================//
528 // ASYNC OPERATION SUPPORT //
529 //==============================================//
538};
539
549public:
554 explicit EspI2cBus(const hf_i2c_master_bus_config_t& config) noexcept;
555
559 ~EspI2cBus() noexcept;
560
561 // Non-copyable, non-movable
562 EspI2cBus(const EspI2cBus&) = delete;
563 EspI2cBus& operator=(const EspI2cBus&) = delete;
564 EspI2cBus(EspI2cBus&&) = delete;
566
571 bool Initialize() noexcept;
572
577 bool Deinitialize() noexcept;
578
584 int CreateDevice(const hf_i2c_device_config_t& device_config) noexcept;
585
591 BaseI2c* GetDevice(int device_index) noexcept;
592
598 const BaseI2c* GetDevice(int device_index) const noexcept;
599
605 EspI2cDevice* GetEspDevice(int device_index) noexcept;
606
612 const EspI2cDevice* GetEspDevice(int device_index) const noexcept;
613
619 BaseI2c* GetDeviceByAddress(hf_u16_t device_address) noexcept;
620
625 std::size_t GetDeviceCount() const noexcept;
626
632 bool RemoveDevice(int device_index) noexcept;
633
639 bool RemoveDeviceByAddress(hf_u16_t device_address) noexcept;
640
641 //==============================================//
642 // INDEX-BASED ACCESS AND ITERATION METHODS //
643 //==============================================//
644
651 BaseI2c* operator[](int device_index) noexcept;
652
659 const BaseI2c* operator[](int device_index) const noexcept;
660
667 EspI2cDevice* At(int device_index) noexcept;
668
675 const EspI2cDevice* At(int device_index) const noexcept;
676
682 bool IsValidIndex(int device_index) const noexcept;
683
688 BaseI2c* GetFirstDevice() noexcept;
689
694 const BaseI2c* GetFirstDevice() const noexcept;
695
700 BaseI2c* GetLastDevice() noexcept;
701
706 const BaseI2c* GetLastDevice() const noexcept;
707
713 std::vector<BaseI2c*> GetAllDevices() noexcept;
714
720 std::vector<const BaseI2c*> GetAllDevices() const noexcept;
721
727 std::vector<EspI2cDevice*> GetAllEspDevices() noexcept;
728
734 std::vector<const EspI2cDevice*> GetAllEspDevices() const noexcept;
735
741 int FindDeviceIndex(hf_u16_t device_address) const noexcept;
742
748 std::vector<hf_u16_t> GetDeviceAddresses() const noexcept;
749
754 bool HasDevices() const noexcept;
755
760 bool IsEmpty() const noexcept;
761
767 bool ClearAllDevices() noexcept;
768
773 const hf_i2c_master_bus_config_t& GetConfig() const noexcept;
774
779 i2c_master_bus_handle_t GetHandle() const noexcept;
780
785 int GetPort() const noexcept;
786
791 bool IsInitialized() const noexcept;
792
801 size_t ScanDevices(std::vector<hf_u16_t>& found_devices, hf_u16_t start_addr = 0x08,
802 hf_u16_t end_addr = 0x77, hf_u32_t scan_timeout_ms = 0) noexcept;
803
810 bool ProbeDevice(hf_u16_t device_addr, hf_u32_t timeout_ms = 10) noexcept;
811
816 bool ResetBus() noexcept;
817
818 //==============================================//
819 // MODE MANAGEMENT METHODS //
820 //==============================================//
821
826 hf_i2c_mode_t GetMode() const noexcept;
827
832 bool IsAsyncMode() const noexcept;
833
838 bool IsSyncMode() const noexcept;
839
847 bool SwitchMode(hf_i2c_mode_t new_mode, uint8_t queue_depth = 10) noexcept;
848
849private:
850 //==============================================//
851 // PRIVATE METHODS //
852 //==============================================//
853
859 int FindDeviceIndexByAddress(hf_u16_t device_address) const noexcept;
860
866 hf_i2c_err_t ConvertEspError(esp_err_t esp_error) const noexcept;
867
876 bool CustomFastProbe(hf_u16_t device_addr, hf_u32_t timeout_ms) noexcept;
877
878 //==============================================//
879 // MEMBER VARIABLES //
880 //==============================================//
881
883 i2c_master_bus_handle_t bus_handle_;
886 std::vector<std::unique_ptr<EspI2cDevice>> devices_;
887 hf_i2c_mode_t current_mode_;
888
889 // Bus-level statistics and diagnostics
892};
893
894#endif // ESP_I2C_H_
Abstract base class for I2C device implementations in the HardFOC system.
hf_i2c_err_t
Definition BaseI2c.h:85
const char * HfI2COperationToString(hf_i2c_operation_t op) noexcept
Convert operation type to string for logging.
Definition EspI2c.cpp:61
hf_i2c_operation_t
Enumeration for I2C operation types used in logging and validation.
Definition EspI2c.h:135
@ HF_I2C_OP_WRITE_READ_ASYNC
Asynchronous write-then-read operation.
@ HF_I2C_OP_READ
Read operation.
@ HF_I2C_OP_WRITE_ASYNC
Asynchronous write operation.
@ HF_I2C_OP_WRITE_READ
Write-then-read operation.
@ HF_I2C_OP_WRITE
Write operation.
@ HF_I2C_OP_READ_ASYNC
Asynchronous read operation.
Consolidated MCU-specific type definitions for hardware abstraction (hf_* types).
hf_i2c_transaction_type_t
ESP32 I2C transaction types.
Definition EspTypes_I2C.h:89
hf_i2c_mode_t
I2C operation mode - determines available APIs.
Definition EspTypes_I2C.h:140
void(*)(hf_i2c_err_t result, size_t bytes_transferred, void *user_data) hf_i2c_async_callback_t
Callback function signature for asynchronous I2C operations.
Definition EspTypes_I2C.h:159
uint32_t hf_u32_t
Platform-agnostic 32-bit unsigned integer type.
Definition HardwareTypes.h:52
uint8_t hf_u8_t
Platform-agnostic 8-bit unsigned integer type.
Definition HardwareTypes.h:40
uint64_t hf_u64_t
Platform-agnostic 64-bit unsigned integer type.
Definition HardwareTypes.h:58
uint16_t hf_u16_t
Platform-agnostic 16-bit unsigned integer type.
Definition HardwareTypes.h:46
Cross-platform RTOS mutex and synchronization primitives.
Abstract base class for I2C device implementations.
Definition BaseI2c.h:196
bool IsInitialized() const noexcept
Checks if the bus is initialized.
Definition BaseI2c.h:236
Manages a single I2C bus. Handles bus initialization and device creation.
Definition EspI2c.h:548
EspI2cBus & operator=(EspI2cBus &&)=delete
EspI2cBus & operator=(const EspI2cBus &)=delete
EspI2cBus(const EspI2cBus &)=delete
EspI2cBus(EspI2cBus &&)=delete
Represents a single I2C device on a bus.
Definition EspI2c.h:164
hf_i2c_async_callback_t GetCurrentCallback() const noexcept
Get current async callback (for static callback bridge).
Definition EspI2c.h:379
bool ValidateOperation(const void *data, hf_u16_t length, hf_i2c_operation_t operation_type) noexcept
Common validation for all I2C operations.
Definition EspI2c.cpp:1615
bool MarkAsDeinitialized() noexcept
Mark device as deinitialized without ESP-IDF cleanup.
Definition EspI2c.cpp:971
bool IsSyncOperationInProgress() const noexcept
Check if a sync operation is currently in progress.
Definition EspI2c.cpp:1448
bool WaitAsyncOperationComplete(hf_u32_t timeout_ms=0) noexcept
Wait for current async operation to complete.
Definition EspI2c.cpp:1461
bool IsSyncMode() const noexcept
Check if this device is in sync mode.
Definition EspI2c.cpp:1918
bool ProbeDevice() noexcept
Probe if the device is present on the bus.
Definition EspI2c.cpp:1589
bool sync_operation_in_progress_
Is sync operation active (mutual exclusion)
Definition EspI2c.h:531
hf_i2c_err_t Read(hf_u8_t *data, hf_u16_t length, hf_u32_t timeout_ms=0) noexcept override
Read data from the I2C device.
Definition EspI2c.cpp:1105
hf_u16_t last_read_length_
Length of last read operation for async tracking.
Definition EspI2c.h:537
bool IsAsyncOperationInProgress() const noexcept
Check if an async operation is currently in progress.
Definition EspI2c.cpp:1435
hf_i2c_diagnostics_t diagnostics_
Per-device diagnostics.
Definition EspI2c.h:523
bool SetupAsyncOperation(hf_i2c_async_callback_t callback, void *user_data, hf_u32_t timeout_ms) noexcept
Common async operation setup.
Definition EspI2c.cpp:1670
void UpdateErrorStatistics(hf_i2c_err_t error_code) noexcept
Update error-specific statistics.
Definition EspI2c.cpp:1750
i2c_master_dev_handle_t handle_
ESP-IDF device handle.
Definition EspI2c.h:519
void CleanupAsyncOperation() noexcept
Common async operation cleanup.
Definition EspI2c.cpp:1942
hf_i2c_err_t ConvertEspError(esp_err_t esp_error) const noexcept
Convert ESP-IDF error to HardFOC error.
Definition EspI2c.cpp:1783
const hf_i2c_device_config_t & GetConfig() const noexcept
Get the device configuration.
Definition EspI2c.cpp:1568
bool SetupSyncOperation(hf_i2c_operation_t operation_type) noexcept
Common sync operation setup and cleanup.
Definition EspI2c.cpp:1631
bool async_operation_in_progress_
Is async operation active.
Definition EspI2c.h:530
EspI2cBus * parent_bus_
Parent bus pointer.
Definition EspI2c.h:518
void StartAsyncOperationTracking() noexcept
Start async operation tracking after I2C operation is successfully started.
Definition EspI2c.cpp:1933
bool Initialize() noexcept override
Initialize the I2C device (no-op if already initialized).
Definition EspI2c.cpp:910
bool initialized_
Initialization status.
Definition EspI2c.h:521
void UpdateStatistics(bool success, size_t bytes_transferred, hf_u64_t operation_time_us) noexcept
Update statistics with operation result.
Definition EspI2c.cpp:1698
hf_i2c_err_t GetDiagnostics(hf_i2c_diagnostics_t &diagnostics) const noexcept override
Get I2C bus diagnostics.
Definition EspI2c.cpp:1521
EspI2cDevice(EspI2cBus *parent, const hf_i2c_device_config_t &config)
Construct a new EspI2cDevice.
Definition EspI2c.cpp:841
PlatformMutex mutex_
Device mutex for thread safety.
Definition EspI2c.h:524
bool IsAsyncMode() const noexcept
Check if this device is in async mode.
Definition EspI2c.cpp:1906
static bool InternalAsyncCallback(i2c_master_dev_handle_t i2c_dev, const i2c_master_event_data_t *evt_data, void *arg)
Internal C callback bridge for ESP-IDF callbacks.
Definition EspI2c.cpp:1829
hf_i2c_err_t GetStatistics(hf_i2c_statistics_t &statistics) const noexcept override
Get I2C bus statistics.
Definition EspI2c.cpp:1507
bool RegisterTemporaryCallback(hf_i2c_async_callback_t callback, void *user_data, hf_u32_t timeout_ms) noexcept
Register temporary async callback for single operation.
Definition EspI2c.cpp:1817
void CleanupSyncOperation() noexcept
Common sync operation cleanup.
Definition EspI2c.cpp:1660
hf_i2c_device_config_t config_
Device configuration.
Definition EspI2c.h:520
hf_i2c_transaction_type_t current_op_type_
Current operation type.
Definition EspI2c.h:535
void UnregisterTemporaryCallback() noexcept
Unregister temporary async callback after operation.
Definition EspI2c.cpp:1824
hf_i2c_mode_t device_mode_
Device operation mode (inherited from bus)
Definition EspI2c.h:525
hf_u16_t GetDeviceAddress() const noexcept
Get the device address.
Definition EspI2c.cpp:1535
void UpdateErrorRecoveryAttempt() noexcept
Update error recovery attempt statistics.
Definition EspI2c.cpp:1777
hf_i2c_err_t WriteRead(const hf_u8_t *tx_data, hf_u16_t tx_length, hf_u8_t *rx_data, hf_u16_t rx_length, hf_u32_t timeout_ms=0) noexcept override
Write then read data from the I2C device.
Definition EspI2c.cpp:1168
hf_i2c_err_t ResetStatistics() noexcept override
Reset I2C statistics.
Definition EspI2c.cpp:1541
void * current_user_data_
Current user data.
Definition EspI2c.h:533
i2c_master_dev_handle_t GetHandle() const noexcept
Get the ESP-IDF device handle.
Definition EspI2c.cpp:1556
hf_u16_t last_write_length_
Length of last write operation for async tracking.
Definition EspI2c.h:536
hf_u64_t async_start_time_
Async operation start time.
Definition EspI2c.h:534
bool Deinitialize() noexcept override
Deinitialize the device (internal cleanup only)
Definition EspI2c.cpp:994
bool IsAsyncModeSupported() const noexcept
Check if async mode is supported on this device.
Definition EspI2c.cpp:1423
hf_i2c_err_t Write(const hf_u8_t *data, hf_u16_t length, hf_u32_t timeout_ms=0) noexcept override
Write data to the I2C device.
Definition EspI2c.cpp:1042
hf_i2c_err_t WriteReadAsync(const hf_u8_t *tx_data, hf_u16_t tx_length, hf_u8_t *rx_data, hf_u16_t rx_length, hf_i2c_async_callback_t callback, void *user_data=nullptr, hf_u32_t timeout_ms=1000) noexcept
Write then read data from the I2C device asynchronously.
Definition EspI2c.cpp:1359
hf_i2c_err_t ReadAsync(hf_u8_t *data, hf_u16_t length, hf_i2c_async_callback_t callback, void *user_data=nullptr, hf_u32_t timeout_ms=1000) noexcept
Read data from the I2C device asynchronously.
Definition EspI2c.cpp:1300
hf_i2c_async_callback_t current_callback_
Current user callback.
Definition EspI2c.h:532
hf_i2c_err_t GetActualClockFrequency(hf_u32_t &actual_freq_hz) const noexcept
Get the actual clock frequency for this device.
Definition EspI2c.cpp:1574
hf_i2c_mode_t GetMode() const noexcept
Get the current I2C operation mode for this device.
Definition EspI2c.cpp:1894
hf_i2c_err_t WriteAsync(const hf_u8_t *data, hf_u16_t length, hf_i2c_async_callback_t callback, void *user_data=nullptr, hf_u32_t timeout_ms=1000) noexcept
Write data to the I2C device asynchronously.
Definition EspI2c.cpp:1241
void * GetCurrentUserData() const noexcept
Get current user data (for static callback bridge).
Definition EspI2c.h:387
~EspI2cDevice() noexcept override
Destructor. Automatically removes device from bus if needed.
Definition EspI2c.cpp:892
i2c_master_dev_handle_t GetDeviceHandle() const noexcept
Get the ESP-IDF device handle for internal operations.
Definition EspI2c.h:371
hf_i2c_statistics_t statistics_
Per-device statistics.
Definition EspI2c.h:522
Definition PlatformMutex.h:78
I2C device configuration structure.
Definition EspTypes_I2C.h:225
I2C diagnostic information.
Definition BaseI2c.h:139
I2C master bus configuration structure.
Definition EspTypes_I2C.h:195
I2C operation statistics.
Definition BaseI2c.h:111