Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions src/lgfx/v1/platforms/esp32/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,13 @@ namespace lgfx
__attribute__ ((unused))
static void i2c_periph_reset(int i2c_num)
{
#if LGFX_LP_I2C_NUM > 0
if (isLpPort(i2c_num))
{ // HP 用の i2c_ll_reset_register は SoC の PCR I2C 配列を範囲外参照するため LP 専用関数を使う;
lp_i2c_ll_reset_register(i2c_num - LGFX_HP_I2C_NUM);
return;
}
#endif
I2C_RCC_ATOMIC() {
i2c_ll_reset_register(i2c_num);
(void)__DECLARE_RCC_ATOMIC_ENV;
Expand Down Expand Up @@ -1491,6 +1498,7 @@ namespace lgfx
if (i2c_context[i2c_port].state == i2c_context_t::state_disconnect) { return res; }
auto dev = getDev(i2c_port);
typeof(dev->int_raw) int_raw;
int_raw.val = dev->int_raw.val; // ACK待ちステージをスキップした場合も後段の分岐で参照されるため必ず初期化する;
static constexpr uint32_t intmask = I2C_ACK_ERR_INT_RAW_M | I2C_END_DETECT_INT_RAW_M | I2C_ARBITRATION_LOST_INT_RAW_M;

if (i2c_context[i2c_port].wait_ack_stage)
Expand Down Expand Up @@ -1534,12 +1542,17 @@ namespace lgfx
if (flg_stop || res.has_error())
{
#if defined ( CONFIG_IDF_TARGET_ESP32C2 ) || defined ( CONFIG_IDF_TARGET_ESP32S3 ) || defined ( CONFIG_IDF_TARGET_ESP32C5 ) || defined ( CONFIG_IDF_TARGET_ESP32C6 ) || defined ( CONFIG_IDF_TARGET_ESP32C61 ) || defined ( CONFIG_IDF_TARGET_ESP32P4 ) || defined ( CONFIG_IDF_TARGET_ESP32H2 )
if (res.has_error() || i2c_context[i2c_port].state == i2c_context_t::state_read || !int_raw.end_detect_int_raw)
// エラー発生後はペリフェラルが強制停止済みの場合があり、通常のSTOPコマンド発行では完了割り込みが来ずタイムアウトまで待たされるため強制STOP側へ分岐する;
if (res.has_error() || i2c_context[i2c_port].state.has_error() || i2c_context[i2c_port].state == i2c_context_t::state_read || !int_raw.end_detect_int_raw)
#else
if (res.has_error() || i2c_context[i2c_port].state == i2c_context_t::state_read || !int_raw.end_detect)
if (res.has_error() || i2c_context[i2c_port].state.has_error() || i2c_context[i2c_port].state == i2c_context_t::state_read || !int_raw.end_detect)
#endif
{ // force stop
i2c_stop(i2c_port);
// state が既にエラーの場合はエラー検出箇所で停止済みのため再停止しない (res のエラーはこの呼び出しで検出されたもので未停止);
if (res.has_error() || !i2c_context[i2c_port].state.has_error())
{
i2c_stop(i2c_port);
}
}
else
{
Expand Down Expand Up @@ -2137,8 +2150,17 @@ namespace lgfx

if (0 == getRxFifoCount(dev))
{
uint32_t int_raw_val = dev->int_raw.val;
i2c_stop(i2c_port);
ESP_LOGW("LGFX", "i2c read error : read timeout");
if ((int_raw_val & I2C_ACK_ERR_INT_RAW_M)
&& !(int_raw_val & (I2C_TIME_OUT_INT_RAW_M | I2C_ARBITRATION_LOST_INT_RAW_M)))
{ // Pure address NACK means no device is present: not a timeout, so no warning.
ESP_LOGV("LGFX", "i2c read error : nack");
}
else
{
ESP_LOGW("LGFX", "i2c read error : read timeout");
}
res = cpp::fail(error_t::connection_lost);
i2c_context[i2c_port].state = cpp::fail(error_t::connection_lost);
i2c_context[i2c_port].wait_ack_stage = 0;
Expand Down
Loading