mirror of
https://github.com/m5stack/M5IOE1.git
synced 2026-05-20 11:49:24 -07:00
1. optimize _initDevice
This commit is contained in:
+165
-111
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user