Problem: as per #4046, (and maybe #4079), using board.I2C() causes a hard reboot after the first run. It doesn't show an error message or anything.
-
Test sketch:
import board import busio i2c = board.I2C() #i2c = busio.I2C(board.IO5, board.IO6) def printdevices(): i2c.try_lock() devices = i2c.scan() print("I2C devices:", len(devices)) for device in devices: print(hex(device)) i2c.unlock() printdevices()
-
Note, the WROVER doesn't normally have a board.I2C so I added one with arbitrary pins 5 and 6
-
JTAG debugging:
-
JTAG had a few hiccups, needed VCC, and also the addition of never_resets on 39 through 42
-
I see the target reset, but it doesn't ever hit a reset controller so a
where
is not possible by default. The below, which appears every time the I2C sketch is run past the first, does not break into GDBesp32s2: Debug controller 0 was reset. esp32s2: Core 0 was reset.
-
How to break on reset so I can find this thing?
-
-
Recreating issue:
- Start up chip with reset
- enable JTAG
- break on common_hal_busio_i2c_probe but disable it
- gdb r to restart
- after sketch is finished, break, enable breakpoint, and then continue. Soft reboot with ctr-d
- Should fail on the second probe.
-
Weirdness with the return of i2c_cmd_link_create
- default cmd is 0x3fffc2a0. This stays the same between all of the individual probes within scan()
- After rebooting, the broken value of cmd is 0x3fffc2b0. This also stays the same
- This might be a red herring? When using actual pin values instead of board.I2C(), value under reset is still 0x3fffc2b0, but it doesn't fail.
-
Some kinda breakage in the ISR?
#0 0x4001a8d7 in ?? () #1 0x4003017c in vPortExitCritical (mux=0x3fffc388) at ../../esp-idf/components/freertos/xtensa/port.c:419 #2 0x40032593 in xQueueGenericSendFromISR (xQueue=0x3fffc33c, pvItemToQueue=<optimized out>, pxHigherPriorityTaskWoken=0x3ffce808, xCopyPosition=<optimized out>) at ../../esp-idf/components/freertos/queue.c:1287 #3 0x4002bd7e in i2c_isr_handler_default (arg=0x3fffc238) at ../../esp-idf/components/driver/i2c.c:463 #4 0x400294a1 in _xt_lowint1 () at ../../esp-idf/components/freertos/xtensa/xtensa_vectors.S:1105 #5 0x40031378 in ?? () at ../../esp-idf/components/esp_timer/src/esp_timer_impl_systimer.c:153 Backtrace stopped: previous frame identical to this frame (corrupt stack?)
-
What is different about board.I2C()?
-
Adding i2c_driver_delete() to i2c_reset solves the reset, but it makes the probes fail
-
Returns error 259, which is ESP_ERR_INVALID_STATE, probably from this:
-
I2C_CHECK(p_i2c_obj[i2c_num] != NULL, I2C_DRIVER_NOT_INSTALL_ERR_STR, ESP_ERR_INVALID_STATE);
-
-
Should board.I2C be getting deleted, given the reset? How is this supposed to work?
-
i2c_master_cmd_begin is where things actually have to fail
-
why does mp_load_method_maybe sometimes come up after the debugger is connected?
-
Reverting this PR (by re-enabling the driver delete in I2C) fixes the immediate issue but causes a hang when using WIFI adafruit/circuitpython#3803
-
What is going on during the hang in GDB?
-
Seems to get stuck here:
esp32s2: Target halted, PC=0x400A1142, debug_reason=00000001 run_code_py (safe_mode=NO_SAFE_MODE) at ../../main.c:330 330 RUN_BACKGROUND_TASKS; (gdb) n esp32s2: Target halted, PC=0x400A025F, debug_reason=00000001 331 if (reload_requested) { (gdb) n main () at ../../main.c:600 600 skip_repl = run_code_py(safe_mode); (gdb) n esp32s2: Target halted, PC=0x400A028B, debug_reason=00000001 esp32s2: Target halted, PC=0x400A0291, debug_reason=00000001 ^Cesp32s2: Target halted, PC=0x400A02F2, debug_reason=00000001 Thread 1 received signal SIGINT, Interrupt.
-
This isn't that useful though since it seems to be skipping around a lot, so it's clearly optimized. Re-building in debug mode.
-
Debug mode stays entirely in run_code_py, doesn't show the main.c step, but it still doesn't explain why usb has disconnected.
-