Skip to content

Commit 5df9f91

Browse files
committed
Makefile: Fix the timeout issue of i2c driver.
Replace i2c.c of v5.0.4 with i2c.c of release/5.0. Signed-off-by: lbuque <[email protected]>
1 parent 81c03bd commit 5df9f91

File tree

6 files changed

+89
-28
lines changed

6 files changed

+89
-28
lines changed

m5stack/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ patch:
282282
$(call Package/patche,$(abspath ./components/lv_bindings),$(abspath ./patches/0002_avoid_lv_bindings_compile_error.patch))
283283
$(call Package/patche,$(abspath ./../micropython),$(abspath ./patches/0003-modtime-Add-timezone.patch))
284284
$(call Package/patche,$(abspath $(IDF_PATH)),$(abspath ./patches/1000-WIP-Compatible-with-esp-adf-v2.6.patch))
285+
$(call Package/patche,$(abspath $(IDF_PATH)),$(abspath ./patches/1001-Fix-I2C-timeout.patch))
285286
$(call Package/patche,$(abspath ./components/M5Unified/M5Unified),$(abspath ./patches/2003-Support-LTR553.patch))
286287
$(call Package/patche,$(abspath ./components/M5Unified/M5Unified),$(abspath ./patches/2004-Support-AtomS3R.patch))
287288
$(call Package/patche,$(abspath $(ADF_PATH)),$(abspath ./patches/3000-commponents-audio_board-Add-ESP32_S3_BOX_3-board.patch))
@@ -291,6 +292,7 @@ patch:
291292
unpatch:
292293
$(call Package/unpatche,$(abspath ./components/lv_bindings),$(abspath ./patches/0002_avoid_lv_bindings_compile_error.patch))
293294
$(call Package/unpatche,$(abspath ./../micropython),$(abspath ./patches/0003-modtime-Add-timezone.patch))
295+
$(call Package/unpatche,$(abspath $(IDF_PATH)),$(abspath ./patches/1001-Fix-I2C-timeout.patch))
294296
$(call Package/unpatche,$(abspath $(IDF_PATH)),$(abspath ./patches/1000-WIP-Compatible-with-esp-adf-v2.6.patch))
295297
$(call Package/unpatche,$(abspath ./components/M5Unified/M5Unified),$(abspath ./patches/2004-Support-AtomS3R.patch))
296298
$(call Package/unpatche,$(abspath ./components/M5Unified/M5Unified),$(abspath ./patches/2003-Support-LTR553.patch))

m5stack/board.cpp

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,53 @@
99
extern "C" {
1010
#include "uiflow_utility.h"
1111
#include <driver/periph_ctrl.h>
12+
#include "esp_log.h"
1213

13-
void board_init()
14+
void in_i2c_init(void)
1415
{
15-
auto cfg = M5.config();
16-
cfg.output_power = false;
17-
M5.begin(cfg);
18-
if (M5.getBoard() == m5::board_t::board_M5StackCoreS3 || M5.getBoard() == m5::board_t::board_M5StackCoreS3SE) {
19-
periph_module_disable(PERIPH_I2C1_MODULE);
16+
gpio_num_t in_scl = (gpio_num_t)M5.getPin(m5::pin_name_t::in_i2c_scl);
17+
gpio_num_t in_sda = (gpio_num_t)M5.getPin(m5::pin_name_t::in_i2c_sda);
18+
gpio_num_t ex_scl = (gpio_num_t)M5.getPin(m5::pin_name_t::ex_i2c_scl);
19+
gpio_num_t ex_sda = (gpio_num_t)M5.getPin(m5::pin_name_t::ex_i2c_sda);
20+
i2c_port_t ex_port = I2C_NUM_0;
21+
#if SOC_I2C_NUM == 1
22+
i2c_port_t in_port = I2C_NUM_0;
23+
#else
24+
i2c_port_t in_port = I2C_NUM_1;
25+
if (in_scl == ex_scl && in_sda == ex_sda) {
26+
in_port = ex_port;
27+
}
28+
#endif
29+
30+
if (in_scl != 255 || in_sda != 255) {
31+
ESP_LOGW("BOARD", "I2C1 init");
32+
if (in_port == I2C_NUM_0) {
33+
periph_module_enable(PERIPH_I2C0_MODULE);
34+
} else {
35+
periph_module_enable(PERIPH_I2C1_MODULE);
36+
}
2037
i2c_config_t conf;
2138
memset(&conf, 0, sizeof(i2c_config_t));
2239
conf.mode = I2C_MODE_MASTER;
23-
conf.sda_io_num = GPIO_NUM_12;
40+
conf.sda_io_num = in_sda;
2441
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
25-
conf.scl_io_num = GPIO_NUM_11;
42+
conf.scl_io_num = in_scl;
2643
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
2744
conf.master.clk_speed = 100000;
2845
// .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
29-
i2c_param_config(I2C_NUM_1, &conf);
30-
i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0);
46+
i2c_param_config(in_port, &conf);
47+
i2c_driver_install(in_port, I2C_MODE_MASTER, 0, 0, 0);
3148
}
3249
}
3350

51+
void board_init()
52+
{
53+
auto cfg = M5.config();
54+
cfg.output_power = false;
55+
M5.begin(cfg);
56+
in_i2c_init();
57+
}
58+
3459
void power_init()
3560
{
3661
char power_mode[32] = {0};

m5stack/components/M5Unified/mpy_m5unified.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -362,23 +362,14 @@ mp_obj_t m5_begin(size_t n_args, const mp_obj_t *args) {
362362

363363
// initial
364364
M5.begin(cfg);
365-
// if (M5.getBoard() == m5::board_t::board_M5StackCoreS3) {
366-
// periph_module_disable(PERIPH_I2C1_MODULE);
367-
// i2c_config_t conf;
368-
// memset(&conf, 0, sizeof(i2c_config_t));
369-
// conf.mode = I2C_MODE_MASTER;
370-
// conf.sda_io_num = GPIO_NUM_12;
371-
// conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
372-
// conf.scl_io_num = GPIO_NUM_11;
373-
// conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
374-
// conf.master.clk_speed = 100000;
375-
// // .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
376-
// esp_err_t ret = i2c_param_config(I2C_NUM_1, &conf);
377-
// ESP_LOGE("*", "i2c_param_config: %d", ret);
378-
// ret = i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0);
379-
// ESP_LOGE("*", "i2c_driver_install: %d", ret);
380-
// }
365+
// if (M5.getBoard() != m5::board_t::board_M5StackCoreS3
366+
// && M5.getBoard() != m5::board_t::board_M5StackCoreS3SE
367+
// && M5.getBoard() != m5::board_t::board_M5StackCore2
368+
// && M5.getBoard() != m5::board_t::board_M5Tough
369+
// && M5.getBoard() != m5::board_t::board_M5AtomS3
370+
// ) {
381371
M5.In_I2C.release();
372+
// }
382373

383374
M5.Display.clear();
384375
// default display

m5stack/libs/module/mbus.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
M5.BOARD.M5Stack: MBusIO(2, 5, 21, 22, 18, 23, 19),
1515
M5.BOARD.M5StackCore2: MBusIO(32, 33, 21, 22, 18, 23, 38),
1616
M5.BOARD.M5StackCoreS3: MBusIO(2, 1, 12, 11, 36, 37, 35),
17+
M5.BOARD.M5Tough: MBusIO(32, 33, 21, 22, 18, 23, 38),
1718
}.get(M5.getBoard())
1819

1920

m5stack/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,9 @@ void mp_task(void *pvParameter) {
236236

237237
void boardctrl_startup(void) {
238238
// cores3 / core2 / tough
239-
#if BOARD_ID == 10 || BOARD_ID == 2 || BOARD_ID == 8
239+
// #if BOARD_ID == 10 || BOARD_ID == 2 || BOARD_ID == 8
240240
board_init();
241-
#endif
241+
// #endif
242242

243243
esp_err_t ret = nvs_flash_init();
244244
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
diff --git a/components/driver/i2c.c b/components/driver/i2c.c
2+
index 85c6f65..4b15b4e 100644
3+
--- a/components/driver/i2c.c
4+
+++ b/components/driver/i2c.c
5+
@@ -1,5 +1,5 @@
6+
/*
7+
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
8+
+ * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
9+
*
10+
* SPDX-License-Identifier: Apache-2.0
11+
*/
12+
@@ -1494,7 +1494,7 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
13+
// Sometimes when the FSM get stuck, the ACK_ERR interrupt will occur endlessly until we reset the FSM and clear bus.
14+
esp_err_t ret = ESP_FAIL;
15+
i2c_obj_t *p_i2c = p_i2c_obj[i2c_num];
16+
- TickType_t ticks_start = xTaskGetTickCount();
17+
+ const TickType_t ticks_start = xTaskGetTickCount();
18+
portBASE_TYPE res = xSemaphoreTake(p_i2c->cmd_mux, ticks_to_wait);
19+
if (res == pdFALSE) {
20+
return ESP_ERR_TIMEOUT;
21+
@@ -1534,13 +1534,15 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
22+
i2c_cmd_evt_t evt;
23+
while (1) {
24+
TickType_t wait_time = xTaskGetTickCount();
25+
- if (wait_time - ticks_start > ticks_to_wait) { // out of time
26+
- wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
27+
+ const TickType_t elapsed = wait_time - ticks_start;
28+
+ if (elapsed >= ticks_to_wait) { // out of time
29+
+ /* Before triggering a timeout, empty the queue by giving a wait_time of 0:
30+
+ * - if the queue is empty, `pdFALSE` will be returned and the loop will be exited
31+
+ * - if the queue is not empty, we will pop an element and come back here again
32+
+ */
33+
+ wait_time = 0;
34+
} else {
35+
- wait_time = ticks_to_wait - (wait_time - ticks_start);
36+
- if (wait_time < I2C_CMD_ALIVE_INTERVAL_TICK) {
37+
- wait_time = I2C_CMD_ALIVE_INTERVAL_TICK;
38+
- }
39+
+ wait_time = MIN(ticks_to_wait - elapsed, I2C_CMD_ALIVE_INTERVAL_TICK);
40+
}
41+
// In master mode, since we don't have an interrupt to detective bus error or FSM state, what we do here is to make
42+
// sure the interrupt mechanism for master mode is still working.

0 commit comments

Comments
 (0)