1. optimize _initDevice

This commit is contained in:
onexs-xsi
2026-01-10 15:23:14 +08:00
parent 3332fd81fa
commit 7caa3db6e7
2 changed files with 202 additions and 116 deletions
+165 -111
View File
@@ -269,27 +269,37 @@ bool M5IOE1::begin(TwoWire *wire, uint8_t addr, uint8_t sda, uint8_t scl, uint32
// 步骤 1: 先尝试100K通信
// Step 1: Try 100K communication first
if (!_initDevice()) {
// 步骤 2: 100K失败,尝试400K
// Step 2: 100K failed, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, trying 400KHz...");
_wire->end();
M5IOE1_DELAY_MS(50);
if (!_wire->begin(sda, scl, M5IOE1_I2C_FREQ_400K)) {
M5IOE1_LOG_E(TAG, "Failed to initialize I2C bus at 400KHz");
return false;
}
M5IOE1_DELAY_MS(100);
// 步骤 2: 100K失败,等待800ms后再尝试一次100K
// Step 2: 100K failed, wait 800ms and retry 100K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, waiting 800ms and retrying 100KHz...");
M5IOE1_DELAY_MS(800);
M5IOE1_I2C_SEND_WAKE(_wire, _addr);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 3: 都失败,初始化失败
// Step 3: Both failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at both 100KHz and 400KHz");
return false;
// 步骤 3: 100K第二次失败,尝试400K
// Step 3: 100K failed again, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz (retry), trying 400KHz...");
_wire->end();
M5IOE1_DELAY_MS(50);
if (!_wire->begin(sda, scl, M5IOE1_I2C_FREQ_400K)) {
M5IOE1_LOG_E(TAG, "Failed to initialize I2C bus at 400KHz");
return false;
}
M5IOE1_DELAY_MS(100);
M5IOE1_I2C_SEND_WAKE(_wire, _addr);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 4: 都失败,初始化失败
// Step 4: All attempts failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at 100KHz (twice) and 400KHz");
return false;
}
}
}
@@ -433,55 +443,65 @@ bool M5IOE1::begin(i2c_port_t port, uint8_t addr, int sda, int scl, uint32_t spe
// 步骤 1: 先尝试100K通信
// Step 1: Try 100K communication first
if (!_initDevice()) {
// 步骤 2: 100K失败,尝试400K
// Step 2: 100K failed, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, trying 400KHz...");
// 删除当前100K设备句柄
// Remove current 100K device handle
i2c_master_bus_rm_device(_i2c_master_dev);
_i2c_master_dev = nullptr;
// 以400K重新创建设备句柄
// Recreate device handle at 400K
i2c_device_config_t dev_config_400k = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = _addr,
.scl_speed_hz = M5IOE1_I2C_FREQ_400K,
.scl_wait_us = 0,
.flags = {
.disable_ack_check = false,
},
};
ret = i2c_master_bus_add_device(_i2c_master_bus, &dev_config_400k, &_i2c_master_dev);
if (ret != ESP_OK) {
M5IOE1_LOG_E(TAG, "Failed to add I2C device at 400KHz: %s", esp_err_to_name(ret));
i2c_del_master_bus(_i2c_master_bus);
_i2c_master_bus = nullptr;
return false;
}
// 步骤 2: 100K失败,等待800ms后再尝试一次100K
// Step 2: 100K failed, wait 800ms and retry 100K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, waiting 800ms and retrying 100KHz...");
M5IOE1_DELAY_MS(800);
M5IOE1_I2C_MASTER_SEND_WAKE(_i2c_master_bus, _addr);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 3: 都失败,初始化失败
// Step 3: Both failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at both 100KHz and 400KHz");
// 步骤 3: 100K第二次失败,尝试400K
// Step 3: 100K failed again, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz (retry), trying 400KHz...");
// 删除当前100K设备句柄
// Remove current 100K device handle
i2c_master_bus_rm_device(_i2c_master_dev);
i2c_del_master_bus(_i2c_master_bus);
_i2c_master_dev = nullptr;
_i2c_master_bus = nullptr;
return false;
// 以400K重新创建设备句柄
// Recreate device handle at 400K
i2c_device_config_t dev_config_400k = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = _addr,
.scl_speed_hz = M5IOE1_I2C_FREQ_400K,
.scl_wait_us = 0,
.flags = {
.disable_ack_check = false,
},
};
ret = i2c_master_bus_add_device(_i2c_master_bus, &dev_config_400k, &_i2c_master_dev);
if (ret != ESP_OK) {
M5IOE1_LOG_E(TAG, "Failed to add I2C device at 400KHz: %s", esp_err_to_name(ret));
i2c_del_master_bus(_i2c_master_bus);
_i2c_master_bus = nullptr;
return false;
}
M5IOE1_I2C_MASTER_SEND_WAKE(_i2c_master_bus, _addr);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 4: 都失败,初始化失败
// Step 4: All attempts failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at 100KHz (twice) and 400KHz");
i2c_master_bus_rm_device(_i2c_master_dev);
i2c_del_master_bus(_i2c_master_bus);
_i2c_master_dev = nullptr;
_i2c_master_bus = nullptr;
return false;
}
}
}
// 步骤 4: 通信成功,设置为已初始化
// Step 4: Communication succeeded, set as initialized
// 步骤 5: 通信成功,设置为已初始化
// Step 5: Communication succeeded, set as initialized
_initialized = true;
// 步骤 5: 强制配置I2C(用户请求的频率 + 关闭休眠)
// 步骤 6: 强制配置I2C(用户请求的频率 + 关闭休眠)
// 注意:setI2cConfig 内部会自动切换主机 I2C 总线速度
// Step 5: Force configure I2C (user requested speed + disable sleep)
// Note: setI2cConfig will automatically switch host I2C bus speed internally
@@ -610,51 +630,61 @@ bool M5IOE1::begin(i2c_master_bus_handle_t bus, uint8_t addr, uint32_t speed, m5
// 步骤 1: 先尝试100K通信
// Step 1: Try 100K communication first
if (!_initDevice()) {
// 步骤 2: 100K失败,尝试400K
// Step 2: 100K failed, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, trying 400KHz...");
// 删除当前100K设备句柄
// Remove current 100K device handle
i2c_master_bus_rm_device(_i2c_master_dev);
_i2c_master_dev = nullptr;
// 以400K重新创建设备句柄
// Recreate device handle at 400K
i2c_device_config_t dev_config_400k = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = _addr,
.scl_speed_hz = M5IOE1_I2C_FREQ_400K,
.scl_wait_us = 0,
.flags = {
.disable_ack_check = false,
},
};
ret = i2c_master_bus_add_device(_i2c_master_bus, &dev_config_400k, &_i2c_master_dev);
if (ret != ESP_OK) {
M5IOE1_LOG_E(TAG, "Failed to add I2C device at 400KHz: %s", esp_err_to_name(ret));
return false;
}
// 步骤 2: 100K失败,等待800ms后再尝试一次100K
// Step 2: 100K failed, wait 800ms and retry 100K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, waiting 800ms and retrying 100KHz...");
M5IOE1_DELAY_MS(800);
M5IOE1_I2C_MASTER_SEND_WAKE(_i2c_master_bus, _addr);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 3: 都失败,初始化失败
// Step 3: Both failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at both 100KHz and 400KHz");
// 步骤 3: 100K第二次失败,尝试400K
// Step 3: 100K failed again, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz (retry), trying 400KHz...");
// 删除当前100K设备句柄
// Remove current 100K device handle
i2c_master_bus_rm_device(_i2c_master_dev);
_i2c_master_dev = nullptr;
return false;
// 以400K重新创建设备句柄
// Recreate device handle at 400K
i2c_device_config_t dev_config_400k = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = _addr,
.scl_speed_hz = M5IOE1_I2C_FREQ_400K,
.scl_wait_us = 0,
.flags = {
.disable_ack_check = false,
},
};
ret = i2c_master_bus_add_device(_i2c_master_bus, &dev_config_400k, &_i2c_master_dev);
if (ret != ESP_OK) {
M5IOE1_LOG_E(TAG, "Failed to add I2C device at 400KHz: %s", esp_err_to_name(ret));
return false;
}
M5IOE1_I2C_MASTER_SEND_WAKE(_i2c_master_bus, _addr);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 4: 都失败,初始化失败
// Step 4: All attempts failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at 100KHz (twice) and 400KHz");
i2c_master_bus_rm_device(_i2c_master_dev);
_i2c_master_dev = nullptr;
return false;
}
}
}
// 步骤 4: 通信成功,设置为已初始化
// Step 4: Communication succeeded, set as initialized
// 步骤 5: 通信成功,设置为已初始化
// Step 5: Communication succeeded, set as initialized
_initialized = true;
// 步骤 5: 强制配置I2C(用户请求的频率 + 关闭休眠)
// 步骤 6: 强制配置I2C(用户请求的频率 + 关闭休眠)
// 注意:setI2cConfig 内部会自动切换主机 I2C 总线速度
// Step 5: Force configure I2C (user requested speed + disable sleep)
// Note: setI2cConfig will automatically switch host I2C bus speed internally
@@ -769,41 +799,51 @@ bool M5IOE1::begin(i2c_bus_handle_t bus, uint8_t addr, uint32_t speed, m5ioe1_in
// 步骤 1: 先尝试100K通信
// Step 1: Try 100K communication first
if (!_initDevice()) {
// 步骤 2: 100K失败,尝试400K
// Step 2: 100K failed, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, trying 400KHz...");
// 删除当前100K设备句柄
// Remove current 100K device handle
i2c_bus_device_delete(&_i2c_device);
_i2c_device = nullptr;
// 以400K重新创建设备句柄
// Recreate device handle at 400K
_i2c_device = i2c_bus_device_create(_i2c_bus, _addr, M5IOE1_I2C_FREQ_400K);
if (_i2c_device == nullptr) {
M5IOE1_LOG_E(TAG, "Failed to create I2C device at 400KHz");
return false;
}
// 步骤 2: 100K失败,等待800ms后再尝试一次100K
// Step 2: 100K failed, wait 800ms and retry 100K
M5IOE1_LOG_W(TAG, "Failed at 100KHz, waiting 800ms and retrying 100KHz...");
M5IOE1_DELAY_MS(800);
M5IOE1_I2C_SEND_WAKE(_i2c_device, M5IOE1_REG_REV);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 3: 都失败,初始化失败
// Step 3: Both failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at both 100KHz and 400KHz");
// 步骤 3: 100K第二次失败,尝试400K
// Step 3: 100K failed again, try 400K
M5IOE1_LOG_W(TAG, "Failed at 100KHz (retry), trying 400KHz...");
// 删除当前100K设备句柄
// Remove current 100K device handle
i2c_bus_device_delete(&_i2c_device);
_i2c_device = nullptr;
return false;
// 以400K重新创建设备句柄
// Recreate device handle at 400K
_i2c_device = i2c_bus_device_create(_i2c_bus, _addr, M5IOE1_I2C_FREQ_400K);
if (_i2c_device == nullptr) {
M5IOE1_LOG_E(TAG, "Failed to create I2C device at 400KHz");
return false;
}
M5IOE1_I2C_SEND_WAKE(_i2c_device, M5IOE1_REG_REV);
M5IOE1_DELAY_MS(10);
if (!_initDevice()) {
// 步骤 4: 都失败,初始化失败
// Step 4: All attempts failed, initialization failed
M5IOE1_LOG_E(TAG, "Failed at 100KHz (twice) and 400KHz");
i2c_bus_device_delete(&_i2c_device);
_i2c_device = nullptr;
return false;
}
}
}
// 步骤 4: 通信成功,设置为已初始化
// Step 4: Communication succeeded, set as initialized
// 步骤 5: 通信成功,设置为已初始化
// Step 5: Communication succeeded, set as initialized
_initialized = true;
// 步骤 5: 强制配置I2C(用户请求的频率 + 关闭休眠)
// 步骤 6: 强制配置I2C(用户请求的频率 + 关闭休眠)
// 注意:setI2cConfig 内部会自动切换主机 I2C 总线速度
// Step 5: Force configure I2C (user requested speed + disable sleep)
// Note: setI2cConfig will automatically switch host I2C bus speed internally
@@ -2089,8 +2129,8 @@ bool M5IOE1::setLeds(const m5ioe1_rgb_t* colors, uint8_t count, uint8_t arraySiz
return false;
}
// 步骤 3: 写入所有 LED 颜色数据
// Step 3: Write all LED color data
// 步骤 3: 写入所有 LED 颜色数据并回读验证
// Step 3: Write all LED color data and read-back verification
for (uint8_t i = 0; i < count; i++) {
// 转换为 RGB565
// Convert to RGB565
@@ -2106,6 +2146,20 @@ bool M5IOE1::setLeds(const m5ioe1_rgb_t* colors, uint8_t count, uint8_t arraySiz
M5IOE1_LOG_E(TAG, "Failed to write LED_RAM for index %d", i);
return false;
}
// 回读验证颜色数据
// Read-back verification for color data
uint8_t actualData[2];
if (!_readBytes(regAddr, actualData, 2)) {
M5IOE1_LOG_E(TAG, "Failed to read back LED_RAM for index %d", i);
return false;
}
uint16_t actualRgb565 = ((uint16_t)actualData[0] << 8) | actualData[1];
if (actualRgb565 != rgb565) {
M5IOE1_LOG_E(TAG, "LED color verification failed for index %d: expected=0x%04X, actual=0x%04X",
i, rgb565, actualRgb565);
return false;
}
}
// 步骤 4: 更新缓存
+37 -5
View File
@@ -45,6 +45,30 @@ typedef enum {
M5IOE1_PIN_14 = 13
} m5ioe1_pin_t;
// ============================
// 错误码
// Error Codes
// ============================
typedef enum {
M5IOE1_OK = 0, // 成功
// Success
M5IOE1_FAIL = -1, // 一般失败
// General failure
M5IOE1_ERR_I2C_CONFIG = -2, // I2C 配置错误 (如频率不支持)
// I2C configuration error
M5IOE1_ERR_RULE_VIOLATION = -3, // 条件规则错误 (如引脚冲突,互斥功能)
// Condition rule violation
M5IOE1_ERR_INVALID_ARG = -4, // 无效参数
// Invalid argument
M5IOE1_ERR_TIMEOUT = -5, // 超时
// Timeout
M5IOE1_ERR_NOT_SUPPORTED = -6, // 不支持的功能
// Function not supported
M5IOE1_ERR_I2C_COMM = -7, // I2C 通信错误
// I2C communication error
} m5ioe1_err_t;
// ============================
// 设备常量
// Device Constants
@@ -598,12 +622,12 @@ public:
int digitalRead(uint8_t pin);
// ========================
// 高级 GPIO 功能
// Advanced GPIO Functions
// GPIO 功能Arduino 风格 - 带返回值)
// GPIO Functions (Arduino-style - WithRes)
// ========================
bool setPullMode(uint8_t pin, uint8_t pullMode);
bool setDriveMode(uint8_t pin, uint8_t driveMode);
bool getInputState(uint8_t pin, uint8_t* state);
void pinModeWithRes(uint8_t pin, uint8_t mode, bool* res);
void digitalWriteWithRes(uint8_t pin, uint8_t value, bool* res);
int digitalReadWithRes(uint8_t pin, bool* res);
// ========================
// 中断功能
@@ -617,6 +641,14 @@ public:
uint16_t getInterruptStatus();
bool clearInterrupt(uint8_t pin);
// ========================
// 高级 GPIO 功能
// Advanced GPIO Functions
// ========================
bool setPullMode(uint8_t pin, uint8_t pullMode);
bool setDriveMode(uint8_t pin, uint8_t driveMode);
bool getInputState(uint8_t pin, uint8_t* state);
// ========================
// ADC 功能
// ADC Functions