Description
CircuitPython version and board name
Adafruit CircuitPython 9.2.8 on ESP32-S3
Adafruit CircuitPython 10.0.1 on ESP32-S3
Adafruit CircuitPython 9.0.2 on ESP32-S3
Board name: heltec_esp32s3_wifi_lora_v3
Code/REPL
# Board does not boot (aka does not get to the REPL)
Behavior
During power-on or reset, the LED on GPIO35 is active, but OLED does not activate, and REPL does not appear on USB/Serial port.
Serial terminal shows:
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x29 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40381126
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2820,len:0x18c
load:0x403c8700,len:0x4
load:0x403c8704,len:0xa7c
load:0x403cb700,len:0x2740
entry 0x403c8854
Serial console setup
I tried on 9.0.2, 9.2.8, and a 10.0.0 build. None of them would get past this point.
Description
No response
Additional information
Identify the problem is related to I2C and the OLED
As a troubleshooting step, I compiled a version of 9.2.8 that commented out display_init()
from boards.c
.
That build booted CircuitPython to the REPL.
Once booted, CircuitPython code to fill the OLED worked but had erratic behavior.
Erratic Behavior
Sometimes, the serial interface with the custom build would become unbearable and slow to use. It turns out if the signal controller Vext
is left floating, I2C will occasionally fail and cause errors that are not visible unless compiled with DEBUG=1
.
Errors in the code
Need to pull GPIO36 LOW
In display_init(void)
of board.c
, there is a common that GPIO21
needs to be high to power the OLED and I2C bus. However, according to Heltec's schematic for versions 3.1 and 3.2 of the board, GPIO21
is connected to the OLED's RESET
line.
Power for I2C and the OLED is controlled by GPIO36
(Vext_Ctrl
). A logic LOW
enables a PFET, which enables Vext.
So, before enabling I2C, this pin needs to be held LOW
. Otherwise, uncaught exceptions appear to cause the board to lock up (and never finish booting to the REPL.)
Code related to display_on
should be:
common_hal_digitalio_digitalinout_construct(&display_on, &pin_GPIO36);
common_hal_digitalio_digitalinout_switch_to_output(&display_on, false, DRIVE_MODE_PUSH_PULL);
common_hal_digitalio_digitalinout_never_reset(&display_on);
Add RESET to displaybus construct
Existing construct has null
instead of defining the OLED's RESET. It should be:
common_hal_i2cdisplaybus_i2cdisplaybus_construct(
bus,
i2c,
0x3c,
&pin_GPIO21 // oled has reset line
);