mirror of
https://github.com/m5stack/M5IOE1.git
synced 2026-05-20 11:49:24 -07:00
1. Optimize i2c-related functions
This commit is contained in:
+273
-36
File diff suppressed because it is too large
Load Diff
+48
-16
@@ -548,10 +548,11 @@ public:
|
||||
m5ioe1_int_mode_t intMode = M5IOE1_INT_MODE_HARDWARE);
|
||||
|
||||
// =====================================================
|
||||
// Type 2A: Existing i2c_master_bus_handle_t, no hardware interrupt
|
||||
// Type 2A/2B: Existing i2c_master_bus_handle_t (ESP-IDF >= 5.3.0 only)
|
||||
// =====================================================
|
||||
#if M5IOE1_HAS_I2C_MASTER
|
||||
/**
|
||||
* @brief Initialize with existing i2c_master_bus handle (ESP-IDF native driver)
|
||||
* @brief Initialize with existing i2c_master_bus handle (ESP-IDF native driver, IDF >= 5.3.0)
|
||||
* @param bus Existing i2c_master_bus_handle_t
|
||||
* @param addr I2C address (default 0x6F)
|
||||
* @param speed I2C speed in Hz (for device handle creation)
|
||||
@@ -561,11 +562,8 @@ public:
|
||||
m5ioe1_err_t begin(i2c_master_bus_handle_t bus, uint8_t addr = M5IOE1_DEFAULT_ADDR,
|
||||
uint32_t speed = M5IOE1_I2C_FREQ_100K, m5ioe1_int_mode_t intMode = M5IOE1_INT_MODE_POLLING);
|
||||
|
||||
// =====================================================
|
||||
// Type 2B: Existing i2c_master_bus_handle_t, with hardware interrupt
|
||||
// =====================================================
|
||||
/**
|
||||
* @brief Initialize with existing i2c_master_bus handle, with hardware interrupt
|
||||
* @brief Initialize with existing i2c_master_bus handle, with hardware interrupt (IDF >= 5.3.0)
|
||||
* @param bus Existing i2c_master_bus_handle_t
|
||||
* @param addr I2C address
|
||||
* @param speed I2C speed in Hz
|
||||
@@ -575,10 +573,12 @@ public:
|
||||
*/
|
||||
m5ioe1_err_t begin(i2c_master_bus_handle_t bus, uint8_t addr, uint32_t speed, int intPin,
|
||||
m5ioe1_int_mode_t intMode = M5IOE1_INT_MODE_HARDWARE);
|
||||
#endif // M5IOE1_HAS_I2C_MASTER
|
||||
|
||||
// =====================================================
|
||||
// Type 3A: Existing i2c_bus_handle_t, no hardware interrupt
|
||||
// =====================================================
|
||||
#if M5IOE1_HAS_I2C_BUS
|
||||
/**
|
||||
* @brief Initialize with existing i2c_bus handle (esp-idf-lib component)
|
||||
* @param bus Existing i2c_bus_handle_t
|
||||
@@ -604,7 +604,33 @@ public:
|
||||
*/
|
||||
m5ioe1_err_t begin(i2c_bus_handle_t bus, uint8_t addr, uint32_t speed, int intPin,
|
||||
m5ioe1_int_mode_t intMode = M5IOE1_INT_MODE_HARDWARE);
|
||||
#endif
|
||||
#else
|
||||
/**
|
||||
* @brief i2c_bus overload is intentionally kept for diagnostics when unavailable
|
||||
* @note This overload exists only to provide a clear compile-time message when called.
|
||||
*/
|
||||
inline m5ioe1_err_t begin(i2c_bus_handle_t bus, uint8_t addr = M5IOE1_DEFAULT_ADDR,
|
||||
uint32_t speed = M5IOE1_I2C_FREQ_100K,
|
||||
m5ioe1_int_mode_t intMode = M5IOE1_INT_MODE_POLLING)
|
||||
{
|
||||
(void)bus;
|
||||
(void)addr;
|
||||
(void)speed;
|
||||
(void)intMode;
|
||||
return M5IOE1_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
inline m5ioe1_err_t begin(i2c_bus_handle_t bus, uint8_t addr, uint32_t speed, int intPin,
|
||||
m5ioe1_int_mode_t intMode = M5IOE1_INT_MODE_HARDWARE)
|
||||
{
|
||||
(void)bus;
|
||||
(void)addr;
|
||||
(void)speed;
|
||||
(void)intPin;
|
||||
(void)intMode;
|
||||
return M5IOE1_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif // M5IOE1_HAS_I2C_BUS
|
||||
#endif // !ARDUINO
|
||||
|
||||
/**
|
||||
* @brief Set interrupt handling mode
|
||||
@@ -1517,20 +1543,26 @@ private:
|
||||
|
||||
// I2C 句柄(根据驱动类型仅使用一对)
|
||||
// I2C handles (only one pair is used based on driver type)
|
||||
// M5IOE1_I2C_DRIVER_SELF_CREATED: 使用 _i2c_master_bus + _i2c_master_dev
|
||||
// M5IOE1_I2C_DRIVER_SELF_CREATED (IDF >= 5.3.0): 使用 _i2c_master_bus + _i2c_master_dev
|
||||
// uses _i2c_master_bus + _i2c_master_dev
|
||||
// M5IOE1_I2C_DRIVER_MASTER: 使用 _i2c_master_bus + _i2c_master_dev
|
||||
// uses _i2c_master_bus + _i2c_master_dev
|
||||
// M5IOE1_I2C_DRIVER_BUS: 使用 _i2c_bus + _i2c_device
|
||||
// uses _i2c_bus + _i2c_device
|
||||
i2c_master_bus_handle_t _i2c_master_bus; // ESP-IDF 原生驱动/自创建
|
||||
// ESP-IDF native driver / self-created
|
||||
i2c_master_dev_handle_t _i2c_master_dev; // ESP-IDF 原生驱动/自创建
|
||||
// ESP-IDF native driver / self-created
|
||||
i2c_bus_handle_t _i2c_bus; // esp-idf-lib 组件
|
||||
// esp-idf-lib component
|
||||
i2c_bus_device_handle_t _i2c_device; // esp-idf-lib 组件
|
||||
// esp-idf-lib component
|
||||
// M5IOE1_I2C_DRIVER_LEGACY (IDF < 5.3.0): 使用 _port + _addr,无额外句柄
|
||||
// uses _port + _addr, no additional handle
|
||||
#if M5IOE1_HAS_I2C_MASTER
|
||||
i2c_master_bus_handle_t _i2c_master_bus; // ESP-IDF 原生驱动/自创建 (IDF >= 5.3.0)
|
||||
// ESP-IDF native driver / self-created (IDF >= 5.3.0)
|
||||
i2c_master_dev_handle_t _i2c_master_dev; // ESP-IDF 原生驱动/自创建 (IDF >= 5.3.0)
|
||||
// ESP-IDF native driver / self-created (IDF >= 5.3.0)
|
||||
#endif // M5IOE1_HAS_I2C_MASTER
|
||||
#if M5IOE1_HAS_I2C_BUS
|
||||
i2c_bus_handle_t _i2c_bus; // esp-idf-lib 组件
|
||||
// esp-idf-lib component
|
||||
i2c_bus_device_handle_t _i2c_device; // esp-idf-lib 组件
|
||||
// esp-idf-lib component
|
||||
#endif
|
||||
|
||||
// I2C 管理标志
|
||||
// I2C management flags
|
||||
|
||||
+264
-48
@@ -32,8 +32,8 @@
|
||||
// Arduino I2C Functions
|
||||
// ============================
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_BYTE
|
||||
static inline bool M5IOE1_I2C_READ_BYTE(TwoWire *wire, uint8_t addr, uint8_t reg, uint8_t *data)
|
||||
#ifndef M5IOE1_I2C_ARDUINO_READ_BYTE
|
||||
static inline bool M5IOE1_I2C_ARDUINO_READ_BYTE(TwoWire *wire, uint8_t addr, uint8_t reg, uint8_t *data)
|
||||
{
|
||||
wire->beginTransmission(addr);
|
||||
wire->write(reg);
|
||||
@@ -49,8 +49,9 @@ static inline bool M5IOE1_I2C_READ_BYTE(TwoWire *wire, uint8_t addr, uint8_t reg
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_BYTES
|
||||
static inline bool M5IOE1_I2C_READ_BYTES(TwoWire *wire, uint8_t addr, uint8_t start_reg, size_t len, uint8_t *data)
|
||||
#ifndef M5IOE1_I2C_ARDUINO_READ_BYTES
|
||||
static inline bool M5IOE1_I2C_ARDUINO_READ_BYTES(TwoWire *wire, uint8_t addr, uint8_t start_reg, size_t len,
|
||||
uint8_t *data)
|
||||
{
|
||||
wire->beginTransmission(addr);
|
||||
wire->write(start_reg);
|
||||
@@ -68,11 +69,11 @@ static inline bool M5IOE1_I2C_READ_BYTES(TwoWire *wire, uint8_t addr, uint8_t st
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_REG16
|
||||
static inline bool M5IOE1_I2C_READ_REG16(TwoWire *wire, uint8_t addr, uint8_t reg, uint16_t *data)
|
||||
#ifndef M5IOE1_I2C_ARDUINO_READ_REG16
|
||||
static inline bool M5IOE1_I2C_ARDUINO_READ_REG16(TwoWire *wire, uint8_t addr, uint8_t reg, uint16_t *data)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
if (!M5IOE1_I2C_READ_BYTES(wire, addr, reg, 2, buf)) {
|
||||
if (!M5IOE1_I2C_ARDUINO_READ_BYTES(wire, addr, reg, 2, buf)) {
|
||||
return false;
|
||||
}
|
||||
// 小端模式:低字节在前
|
||||
@@ -82,8 +83,8 @@ static inline bool M5IOE1_I2C_READ_REG16(TwoWire *wire, uint8_t addr, uint8_t re
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_WRITE_BYTE
|
||||
static inline bool M5IOE1_I2C_WRITE_BYTE(TwoWire *wire, uint8_t addr, uint8_t reg, uint8_t data)
|
||||
#ifndef M5IOE1_I2C_ARDUINO_WRITE_BYTE
|
||||
static inline bool M5IOE1_I2C_ARDUINO_WRITE_BYTE(TwoWire *wire, uint8_t addr, uint8_t reg, uint8_t data)
|
||||
{
|
||||
wire->beginTransmission(addr);
|
||||
wire->write(reg);
|
||||
@@ -96,9 +97,9 @@ static inline bool M5IOE1_I2C_WRITE_BYTE(TwoWire *wire, uint8_t addr, uint8_t re
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_WRITE_BYTES
|
||||
static inline bool M5IOE1_I2C_WRITE_BYTES(TwoWire *wire, uint8_t addr, uint8_t start_reg, size_t len,
|
||||
const uint8_t *data)
|
||||
#ifndef M5IOE1_I2C_ARDUINO_WRITE_BYTES
|
||||
static inline bool M5IOE1_I2C_ARDUINO_WRITE_BYTES(TwoWire *wire, uint8_t addr, uint8_t start_reg, size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
wire->beginTransmission(addr);
|
||||
wire->write(start_reg);
|
||||
@@ -113,23 +114,23 @@ static inline bool M5IOE1_I2C_WRITE_BYTES(TwoWire *wire, uint8_t addr, uint8_t s
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_WRITE_REG16
|
||||
static inline bool M5IOE1_I2C_WRITE_REG16(TwoWire *wire, uint8_t addr, uint8_t reg, uint16_t data)
|
||||
#ifndef M5IOE1_I2C_ARDUINO_WRITE_REG16
|
||||
static inline bool M5IOE1_I2C_ARDUINO_WRITE_REG16(TwoWire *wire, uint8_t addr, uint8_t reg, uint16_t data)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
buf[0] = (uint8_t)(data & 0xFF);
|
||||
buf[1] = (uint8_t)((data >> 8) & 0xFF);
|
||||
return M5IOE1_I2C_WRITE_BYTES(wire, addr, reg, 2, buf);
|
||||
return M5IOE1_I2C_ARDUINO_WRITE_BYTES(wire, addr, reg, 2, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
// 唤醒信号发送 / Wake signal send
|
||||
// IOE1 使用 SDA 引脚下降沿触发唤醒中断
|
||||
// IOE1 uses SDA pin falling edge to trigger wake interrupt
|
||||
#ifndef M5IOE1_I2C_SEND_WAKE
|
||||
static inline void M5IOE1_I2C_SEND_WAKE(TwoWire *wire, uint8_t addr)
|
||||
#ifndef M5IOE1_I2C_ARDUINO_SEND_WAKE
|
||||
static inline void M5IOE1_I2C_ARDUINO_SEND_WAKE(TwoWire *wire, uint8_t addr)
|
||||
{
|
||||
// Send START then STOP to avoid leaving the bus in a busy state
|
||||
wire->beginTransmission(addr);
|
||||
@@ -140,8 +141,102 @@ static inline void M5IOE1_I2C_SEND_WAKE(TwoWire *wire, uint8_t addr)
|
||||
#else // ESP-IDF
|
||||
|
||||
#include <esp_err.h>
|
||||
#include <driver/i2c_master.h> // ESP-IDF native i2c_master driver
|
||||
#include <i2c_bus.h> // esp-idf-lib i2c_bus component
|
||||
#include <esp_idf_version.h>
|
||||
|
||||
// ============================
|
||||
// I2C 驱动检测
|
||||
// I2C Driver Detection
|
||||
// ============================
|
||||
|
||||
// 检测 i2c_bus 是否可用
|
||||
// Detect if i2c_bus is available
|
||||
//
|
||||
// ESP-IDF < 5.3.0
|
||||
// 未启用 BACKWARD_CONFIG
|
||||
// → 不支持 i2c_bus,使用传统 driver/i2c.h Legacy API
|
||||
// 启用 BACKWARD_CONFIG
|
||||
// → i2c_bus.h 内部回退到 driver/i2c.h,可安全使用
|
||||
//
|
||||
// ESP-IDF >= 5.3.0
|
||||
// 启用 BACKWARD_CONFIG
|
||||
// → i2c_bus.h 内部使用 driver/i2c.h,无冲突风险
|
||||
// 未启用 BACKWARD_CONFIG
|
||||
// driver/i2c.h 已被其他组件提前包含(_DRIVER_I2C_H_ 已定义)
|
||||
// → i2c_bus.h 会自定义 i2c_config_t,与已定义的版本冲突 → 禁用
|
||||
// driver/i2c.h 尚未被包含(_DRIVER_I2C_H_ 未定义)
|
||||
// → 无冲突风险,按默认配置启用 i2c_bus
|
||||
//
|
||||
// Detection logic:
|
||||
// ESP-IDF < 5.3.0:
|
||||
// Without BACKWARD_CONFIG: i2c_bus not supported; use legacy driver/i2c.h API.
|
||||
// With BACKWARD_CONFIG: i2c_bus.h falls back to driver/i2c.h internally, safe to use.
|
||||
// ESP-IDF >= 5.3.0:
|
||||
// With BACKWARD_CONFIG: i2c_bus.h uses driver/i2c.h internally, always conflict-free.
|
||||
// Without BACKWARD_CONFIG:
|
||||
// _DRIVER_I2C_H_ defined (driver/i2c.h already included by another component)
|
||||
// → i2c_bus.h would define its own i2c_config_t, conflicting with the existing one → disabled.
|
||||
// _DRIVER_I2C_H_ not defined (driver/i2c.h not yet included)
|
||||
// → no conflict risk, enable i2c_bus with default config.
|
||||
//
|
||||
// Note: _DRIVER_I2C_H_ is the include guard of driver/i2c.h (ESP-IDF legacy I2C header).
|
||||
// Checking it at preprocessor time reflects whether driver/i2c.h was included
|
||||
// BEFORE this header. Inclusion after this header cannot be detected here;
|
||||
// in that case the user is responsible for ensuring no conflict (or enabling BACKWARD_CONFIG).
|
||||
#if __has_include(<i2c_bus.h>)
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||
#if defined(CONFIG_I2C_BUS_BACKWARD_CONFIG)
|
||||
#define M5IOE1_HAS_I2C_BUS 1 // IDF < 5.3.0 + BACKWARD_CONFIG:可用 / available
|
||||
#else
|
||||
#define M5IOE1_HAS_I2C_BUS 0 // IDF < 5.3.0:默认 Legacy API / legacy API by default
|
||||
#endif
|
||||
#else
|
||||
// IDF >= 5.3.0
|
||||
#if defined(CONFIG_I2C_BUS_BACKWARD_CONFIG)
|
||||
#define M5IOE1_HAS_I2C_BUS 1 // BACKWARD_CONFIG:i2c_bus.h 使用 driver/i2c.h,无冲突 / no conflict
|
||||
#elif defined(_DRIVER_I2C_H_)
|
||||
#define M5IOE1_HAS_I2C_BUS \
|
||||
0 // driver/i2c.h 已提前包含 + 无 BACKWARD_CONFIG → 冲突风险,禁用
|
||||
// driver/i2c.h already included + no BACKWARD_CONFIG → conflict risk, disabled
|
||||
#else
|
||||
#define M5IOE1_HAS_I2C_BUS 1 // driver/i2c.h 尚未包含,无冲突风险 / driver/i2c.h not yet included, no conflict
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define M5IOE1_HAS_I2C_BUS 0
|
||||
#endif
|
||||
|
||||
// 选择 I2C 驱动头文件
|
||||
// Select I2C driver header
|
||||
//
|
||||
// ESP-IDF < 5.3.0:使用传统 Legacy I2C API(driver/i2c.h),与 i2c_bus 无关
|
||||
// ESP-IDF < 5.3.0: use legacy I2C API (driver/i2c.h), independent of i2c_bus.
|
||||
//
|
||||
// ESP-IDF >= 5.3.0:优先使用新版 i2c_master 驱动
|
||||
// ESP-IDF >= 5.3.0: prefer the new i2c_master driver.
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||
#include <driver/i2c.h>
|
||||
#elif __has_include(<driver/i2c_master.h>)
|
||||
#include <driver/i2c_master.h>
|
||||
#else
|
||||
#include <driver/i2c.h>
|
||||
#endif
|
||||
|
||||
// i2c_master 原生驱动可用性检测
|
||||
// i2c_master native driver availability detection
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) && __has_include(<driver/i2c_master.h>)
|
||||
#define M5IOE1_HAS_I2C_MASTER 1
|
||||
#else
|
||||
#define M5IOE1_HAS_I2C_MASTER 0
|
||||
#endif
|
||||
|
||||
#if M5IOE1_HAS_I2C_BUS
|
||||
#include <i2c_bus.h>
|
||||
#else
|
||||
// i2c_bus 桩类型
|
||||
// i2c_bus stub types
|
||||
typedef void *i2c_bus_handle_t;
|
||||
typedef void *i2c_bus_device_handle_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -154,12 +249,18 @@ extern "C" {
|
||||
typedef enum {
|
||||
M5IOE1_I2C_DRIVER_NONE = 0, // 未初始化
|
||||
// Not initialized
|
||||
M5IOE1_I2C_DRIVER_SELF_CREATED, // 使用 i2c_port_t 自创建
|
||||
// Self-created using i2c_port_t
|
||||
M5IOE1_I2C_DRIVER_MASTER, // ESP-IDF 原生 i2c_master 驱动
|
||||
// ESP-IDF native i2c_master driver
|
||||
M5IOE1_I2C_DRIVER_BUS // esp-idf-lib i2c_bus 组件
|
||||
// esp-idf-lib i2c_bus component
|
||||
M5IOE1_I2C_DRIVER_SELF_CREATED, // 使用 i2c_port_t 自创建(IDF >= 5.3.0 用 i2c_master,否则用 Legacy)
|
||||
// Self-created using i2c_port_t (i2c_master on IDF >= 5.3.0, Legacy otherwise)
|
||||
M5IOE1_I2C_DRIVER_MASTER, // ESP-IDF 原生 i2c_master 驱动(仅 IDF >= 5.3.0)
|
||||
// ESP-IDF native i2c_master driver (IDF >= 5.3.0 only)
|
||||
#if M5IOE1_HAS_I2C_BUS
|
||||
M5IOE1_I2C_DRIVER_BUS, // esp-idf-lib i2c_bus 组件
|
||||
// esp-idf-lib i2c_bus component
|
||||
#endif
|
||||
#if !M5IOE1_HAS_I2C_MASTER && !M5IOE1_HAS_I2C_BUS
|
||||
M5IOE1_I2C_DRIVER_LEGACY, // 传统 driver/i2c.h API(IDF < 5.3.0 且无 i2c_bus)
|
||||
// Legacy driver/i2c.h API (IDF < 5.3.0 without i2c_bus)
|
||||
#endif
|
||||
} m5ioe1_i2c_driver_t;
|
||||
|
||||
// ============================
|
||||
@@ -167,22 +268,25 @@ typedef enum {
|
||||
// ESP-IDF I2C Functions (i2c_bus)
|
||||
// ============================
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_BYTE
|
||||
static inline esp_err_t M5IOE1_I2C_READ_BYTE(i2c_bus_device_handle_t dev, uint8_t reg, uint8_t *data)
|
||||
#if M5IOE1_HAS_I2C_BUS
|
||||
|
||||
#ifndef M5IOE1_I2C_BUS_READ_BYTE
|
||||
static inline esp_err_t M5IOE1_I2C_BUS_READ_BYTE(i2c_bus_device_handle_t dev, uint8_t reg, uint8_t *data)
|
||||
{
|
||||
return i2c_bus_read_byte(dev, reg, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_BYTES
|
||||
static inline esp_err_t M5IOE1_I2C_READ_BYTES(i2c_bus_device_handle_t dev, uint8_t start_reg, size_t len, uint8_t *data)
|
||||
#ifndef M5IOE1_I2C_BUS_READ_BYTES
|
||||
static inline esp_err_t M5IOE1_I2C_BUS_READ_BYTES(i2c_bus_device_handle_t dev, uint8_t start_reg, size_t len,
|
||||
uint8_t *data)
|
||||
{
|
||||
return i2c_bus_read_bytes(dev, start_reg, len, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_REG16
|
||||
static inline esp_err_t M5IOE1_I2C_READ_REG16(i2c_bus_device_handle_t dev, uint8_t reg, uint16_t *data)
|
||||
#ifndef M5IOE1_I2C_BUS_READ_REG16
|
||||
static inline esp_err_t M5IOE1_I2C_BUS_READ_REG16(i2c_bus_device_handle_t dev, uint8_t reg, uint16_t *data)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
esp_err_t ret = i2c_bus_read_bytes(dev, reg, 2, buf);
|
||||
@@ -195,23 +299,23 @@ static inline esp_err_t M5IOE1_I2C_READ_REG16(i2c_bus_device_handle_t dev, uint8
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_WRITE_BYTE
|
||||
static inline esp_err_t M5IOE1_I2C_WRITE_BYTE(i2c_bus_device_handle_t dev, uint8_t reg, uint8_t data)
|
||||
#ifndef M5IOE1_I2C_BUS_WRITE_BYTE
|
||||
static inline esp_err_t M5IOE1_I2C_BUS_WRITE_BYTE(i2c_bus_device_handle_t dev, uint8_t reg, uint8_t data)
|
||||
{
|
||||
return i2c_bus_write_byte(dev, reg, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_WRITE_BYTES
|
||||
static inline esp_err_t M5IOE1_I2C_WRITE_BYTES(i2c_bus_device_handle_t dev, uint8_t start_reg, size_t len,
|
||||
const uint8_t *data)
|
||||
#ifndef M5IOE1_I2C_BUS_WRITE_BYTES
|
||||
static inline esp_err_t M5IOE1_I2C_BUS_WRITE_BYTES(i2c_bus_device_handle_t dev, uint8_t start_reg, size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return i2c_bus_write_bytes(dev, start_reg, len, (uint8_t *)data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_WRITE_REG16
|
||||
static inline esp_err_t M5IOE1_I2C_WRITE_REG16(i2c_bus_device_handle_t dev, uint8_t reg, uint16_t data)
|
||||
#ifndef M5IOE1_I2C_BUS_WRITE_REG16
|
||||
static inline esp_err_t M5IOE1_I2C_BUS_WRITE_REG16(i2c_bus_device_handle_t dev, uint8_t reg, uint16_t data)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
// 小端模式:低字节在前
|
||||
@@ -222,11 +326,131 @@ static inline esp_err_t M5IOE1_I2C_WRITE_REG16(i2c_bus_device_handle_t dev, uint
|
||||
}
|
||||
#endif
|
||||
|
||||
// 唤醒信号发送 (i2c_bus) / Wake signal send (i2c_bus)
|
||||
#ifndef M5IOE1_I2C_BUS_SEND_WAKE
|
||||
static inline esp_err_t M5IOE1_I2C_BUS_SEND_WAKE(i2c_bus_device_handle_t dev, uint8_t reg)
|
||||
{
|
||||
// Read any register to generate I2C start signal for wake
|
||||
uint8_t dummy;
|
||||
return i2c_bus_read_byte(dev, reg, &dummy);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // !M5IOE1_HAS_I2C_BUS
|
||||
|
||||
// ============================
|
||||
// ESP-IDF I2C 函数 (Legacy - driver/i2c.h,仅 IDF < 5.3.0 且无 i2c_bus)
|
||||
// ESP-IDF I2C Functions (Legacy - driver/i2c.h, IDF < 5.3.0 without i2c_bus only)
|
||||
// 使用 IDF 4.3+ 引入的简单 API:i2c_master_write_to_device / i2c_master_write_read_device
|
||||
// Uses simple API introduced in IDF 4.3+: i2c_master_write_to_device / i2c_master_write_read_device
|
||||
// ============================
|
||||
|
||||
#if !M5IOE1_HAS_I2C_MASTER
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
// 传统 I2C 超时,单位毫秒 / Legacy I2C timeout in milliseconds
|
||||
#ifndef M5IOE1_I2C_LEGACY_TIMEOUT_MS
|
||||
#define M5IOE1_I2C_LEGACY_TIMEOUT_MS 100
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_LEGACY_READ_BYTE
|
||||
static inline esp_err_t M5IOE1_I2C_LEGACY_READ_BYTE(i2c_port_t port, uint8_t addr, uint8_t reg, uint8_t *data)
|
||||
{
|
||||
return i2c_master_write_read_device(port, addr, ®, 1, data, 1, pdMS_TO_TICKS(M5IOE1_I2C_LEGACY_TIMEOUT_MS));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_LEGACY_READ_BYTES
|
||||
static inline esp_err_t M5IOE1_I2C_LEGACY_READ_BYTES(i2c_port_t port, uint8_t addr, uint8_t start_reg, size_t len,
|
||||
uint8_t *data)
|
||||
{
|
||||
return i2c_master_write_read_device(port, addr, &start_reg, 1, data, len,
|
||||
pdMS_TO_TICKS(M5IOE1_I2C_LEGACY_TIMEOUT_MS));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_LEGACY_READ_REG16
|
||||
static inline esp_err_t M5IOE1_I2C_LEGACY_READ_REG16(i2c_port_t port, uint8_t addr, uint8_t reg, uint16_t *data)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
esp_err_t ret =
|
||||
i2c_master_write_read_device(port, addr, ®, 1, buf, 2, pdMS_TO_TICKS(M5IOE1_I2C_LEGACY_TIMEOUT_MS));
|
||||
if (ret == ESP_OK) {
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
*data = (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_LEGACY_WRITE_BYTE
|
||||
static inline esp_err_t M5IOE1_I2C_LEGACY_WRITE_BYTE(i2c_port_t port, uint8_t addr, uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t buf[2] = {reg, data};
|
||||
return i2c_master_write_to_device(port, addr, buf, 2, pdMS_TO_TICKS(M5IOE1_I2C_LEGACY_TIMEOUT_MS));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_LEGACY_WRITE_BYTES
|
||||
static inline esp_err_t M5IOE1_I2C_LEGACY_WRITE_BYTES(i2c_port_t port, uint8_t addr, uint8_t start_reg, size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
// 需要在数据前添加寄存器地址
|
||||
// Need to prepend register address before data
|
||||
uint8_t *buf = (uint8_t *)malloc(len + 1);
|
||||
if (buf == NULL) return ESP_ERR_NO_MEM;
|
||||
buf[0] = start_reg;
|
||||
memcpy(buf + 1, data, len);
|
||||
esp_err_t ret = i2c_master_write_to_device(port, addr, buf, len + 1, pdMS_TO_TICKS(M5IOE1_I2C_LEGACY_TIMEOUT_MS));
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef M5IOE1_I2C_LEGACY_WRITE_REG16
|
||||
static inline esp_err_t M5IOE1_I2C_LEGACY_WRITE_REG16(i2c_port_t port, uint8_t addr, uint8_t reg, uint16_t data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
buf[0] = reg;
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
buf[1] = (uint8_t)(data & 0xFF);
|
||||
buf[2] = (uint8_t)((data >> 8) & 0xFF);
|
||||
return i2c_master_write_to_device(port, addr, buf, 3, pdMS_TO_TICKS(M5IOE1_I2C_LEGACY_TIMEOUT_MS));
|
||||
}
|
||||
#endif
|
||||
|
||||
// 唤醒信号发送 (Legacy) / Wake signal send (Legacy)
|
||||
// 通过读取一个字节来产生 I2C START 信号
|
||||
// Generates I2C START signal by reading one byte
|
||||
#ifndef M5IOE1_I2C_LEGACY_SEND_WAKE
|
||||
static inline esp_err_t M5IOE1_I2C_LEGACY_SEND_WAKE(i2c_port_t port, uint8_t addr)
|
||||
{
|
||||
uint8_t dummy = 0;
|
||||
uint8_t reg = 0x00;
|
||||
// 忽略错误:唤醒时设备可能处于睡眠状态,ACK 可能超时
|
||||
// Ignore error: device may be asleep during wake, ACK may timeout
|
||||
i2c_master_write_read_device(port, addr, ®, 1, &dummy, 1, pdMS_TO_TICKS(10));
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !M5IOE1_HAS_I2C_MASTER
|
||||
|
||||
#endif // M5IOE1_HAS_I2C_BUS
|
||||
|
||||
// ============================
|
||||
// ESP-IDF I2C 函数 (i2c_master - 原生驱动)
|
||||
// ESP-IDF I2C Functions (i2c_master - native driver)
|
||||
// 仅 ESP-IDF >= 5.3.0 支持(driver/i2c_master.h 引入于 5.1,API 稳定于 5.3)
|
||||
// Available on ESP-IDF >= 5.3.0 only (driver/i2c_master.h introduced in 5.1, stable in 5.3)
|
||||
// ============================
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||
|
||||
#ifndef M5IOE1_I2C_MASTER_READ_BYTE
|
||||
static inline esp_err_t M5IOE1_I2C_MASTER_READ_BYTE(i2c_master_dev_handle_t dev, uint8_t reg, uint8_t *data)
|
||||
{
|
||||
@@ -293,16 +517,6 @@ static inline esp_err_t M5IOE1_I2C_MASTER_WRITE_REG16(i2c_master_dev_handle_t de
|
||||
}
|
||||
#endif
|
||||
|
||||
// 唤醒信号发送 (i2c_bus) / Wake signal send (i2c_bus)
|
||||
#ifndef M5IOE1_I2C_SEND_WAKE
|
||||
static inline esp_err_t M5IOE1_I2C_SEND_WAKE(i2c_bus_device_handle_t dev, uint8_t reg)
|
||||
{
|
||||
// Read any register to generate I2C start signal for wake
|
||||
uint8_t dummy;
|
||||
return i2c_bus_read_byte(dev, reg, &dummy);
|
||||
}
|
||||
#endif
|
||||
|
||||
// 唤醒信号发送 (i2c_master) / Wake signal send (i2c_master)
|
||||
#ifndef M5IOE1_I2C_MASTER_SEND_WAKE
|
||||
static inline esp_err_t M5IOE1_I2C_MASTER_SEND_WAKE(i2c_master_bus_handle_t bus, uint8_t addr)
|
||||
@@ -312,6 +526,8 @@ static inline esp_err_t M5IOE1_I2C_MASTER_SEND_WAKE(i2c_master_bus_handle_t bus,
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ESP_IDF_VERSION >= 5.3.0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user