ESP32-S3-LCD-EV-Board

Hey all - I purchased one of the Espressif development platform boards that has the 480x480 LCD display sandwiched on it. It’s an ESP32-S3 with 16M Flash and 16M of PSRAM as well as that LCD being driven by a GC9503 driver chip.

I’m very familiar with PlatformIO and also with the Arduino framework, but all I’m seeing for this board is using esp-idf. How should I go about co-opting a board definition to use this board on the arduino framework in PlatformIO?

Thanks!!
–bob

Choose the nearest matching available board and make the necessary changes in the platformio.ini.
The board you mentioned is based upon an ESP32-S3-WROOM-1-N16R16.
In this case the board should be esp32-s3-devktic-1

The changes you have to apply can be found here:

Boris,
Thanks for this. I’ll do that.

Can you tell me if the UART being a CP2102N means I need to account for that in a config file as well so the platform knows how to do the right thing? Or does the magic of USB devices just make it all “okay” as it becomes a /dev/tty.usb* device?

Thanks!
–bob

I don’t get the point here.

The board has two USB ports. One is connected to the builtin USB of the ESP32-S3 and the other is connected to a USB-to-UART chip which is then connected to the UART of the ESP32-S3.

If you are using the Arduino Framework, you can specify how the Serial object should behave and which ports should be used for output.

See ESP32-S3 native USB interface and Serial Monitor missing first messages - #10 by sivar2311

Just poking around the edges at whether there’s any special config in underlying json files and such due to the type of uart being used. I had suspect it would be a non-issue due to USB discovery and platformio just looking for the uart at the system level, but wasn’t sure if there might be some other impact.
From your answer it sounds like it’ll be just fine! :slight_smile: - Thanks for your help.

–bob

Thanks again for leading me in the right direction. After a bit more study, I have created a bit more full-bodied solution outside of just the .ini file updates.

The following .json file is placed in the .platformio/platforms/espressif32/boards/ which then enables creating new projects using this name “esp32-s3-lcd-ev” as the board. The .json file also enables USB_CDC (CDC/JTAG) mode allowing the use of the USB connector for both serial as well as programming/debug and obviating the need for the BOOT button to program things - sweet.

esp32-s3-lcd-ev.json

{
  "build": {
    "arduino":{
      "ldscript": "esp32s3_out.ld",
      "partitions": "default_16MB.csv",
      "memory_type": "qio_opi"
    },
    "core": "esp32",
    "extra_flags": [
      "-DARDUINO_ESP32S3_DEV",
      "-DBOARD_HAS_PSRAM",
      "-DARDUINO_USB_MODE=1",
      "-DARDUINO_RUNNING_CORE=1",
      "-DARDUINO_USB_CDC_ON_BOOT=1",
      "-DARDUINO_EVENT_RUNNING_CORE=1"
    ],
    "f_cpu": "240000000L",
    "f_flash": "80000000L",
    "flash_mode": "qio",
    "psram_type": "opi",
    "hwids": [
      [
        "0x303A",
        "0x1001"
      ]
    ],
    "mcu": "esp32s3",
    "variant": "esp32s3"
  },
  "connectivity": [
    "wifi",
    "bluetooth"
  ],
  "debug": {
    "default_tool": "esp-builtin",
    "onboard_tools": [
      "esp-builtin"
    ],
    "openocd_target": "esp32s3.cfg"
  },
  "frameworks": [
    "arduino",
    "espidf"
  ],
  "name": "Espressif ESP32-S3-LCD-EV-N16 (16 MB QD, 16 MB PSRAM)",
  "upload": {
    "flash_size": "16MB",
    "maximum_ram_size": 327680,
    "maximum_size": 16777216,
    "require_upload_port": true,
    "speed": 921600
  },
  "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html",
  "vendor": "Espressif"
}

The following is my platformio.ini file which enables the log_e() function to print error logs. You can increase this LEVEL to 2 for warnings and 3 for info, 4 for debug.

[env:esp32-s3-lcd-ev]
platform = espressif32
board = esp32-s3-lcd-ev
framework = arduino
board_build.filesystem = littlefs
build_flags =
    -D CORE_DEBUG_LEVEL=1

Here’s the simple program that shows some nice information about free memory, memory sizes, and cpu model/frequency/cores and such as well followed by a sample of the output using my board.

#include <Arduino.h>

void systemInfo() {
  uint32_t psrSize, hSize, fSize;
  uint32_t psrFree, hFree;
  uint32_t maxAllocHeap, maxAllocPsram;
  uint32_t freq;
  uint8_t cores;
  const char* model;

  psrSize = ESP.getPsramSize();
  fSize   = ESP.getFlashChipSize();
  hSize   = ESP.getHeapSize();

  psrFree = ESP.getFreePsram();
  hFree   = ESP.getFreeHeap();
  
  maxAllocHeap  = ESP.getMaxAllocHeap();
  maxAllocPsram = ESP.getMaxAllocPsram();

  cores = ESP.getChipCores();
  freq  = ESP.getCpuFreqMHz();
  model = ESP.getChipModel();

  Serial.printf("Model: %s, Cores:%u, Frequency:%lu\n", model, cores, freq);
  Serial.printf("SIZE(K): Heap:%lu, PSram:%lu, Flash:%lu\n", hSize/1024, psrSize/1024, fSize/1024);
  Serial.printf("Free(K): Heap:%lu, PSram:%lu\n", hFree/1024, psrFree/1024);
  Serial.printf("MaxAlloc(K): Heap:%lu, PSram:%lu\n", maxAllocHeap/1024, maxAllocPsram/1024);
}

void setup() {
  Serial.begin(115200);
  while (!Serial)
    ;
  
  // Without this, you won't see the startup messages below as the UART won't be
  // reconnected yet or the monitor won't be re-instantiated in VSCode.
  delay(1000); 

  systemInfo();
  Serial.println("Setup completed.");
}

void loop() {
  static int iters=0;
  Serial.printf("Serial.println #%d\n", iters);
  iters++;
  log_e("log_e");
  delay(1000);
}

Output from the program:

Model: ESP32-S3, Cores:2, Frequency:240
SIZE(K): Heap:382, PSram:16381, Flash:16384
Free(K): Heap:358, PSram:16381
MaxAlloc(K): Heap:327, PSram:16127
Setup completed.
Serial.println #0
[  1098][E][main.cpp:48] loop(): log_e
Serial.println #1
[  2099][E][main.cpp:48] loop(): log_e
Serial.println #2
[  3099][E][main.cpp:48] loop(): log_e

Hey @sivar2311 - found a pretty important oddity I hope you can help understand. After getting things running on the esp32-s3 eval kit, I wanted to toy around with setting things up to do guru meditation exception decoding in the monitor as I once had on an original ESP32. So I set up to do a divide by zero or a throw or a print of a null string to cause the crash and to my surprise I found there was no register printout nor a guru meditation. Hmm.

Here’s a sample of output - it just reboots quietly. Note as part of this test I went back to the esp32-s3-devkitc-1 board as my “baseline” to allow me to turn on and off the ARDUINO_USB_CDC_ON_BOOT which winds up being the culprit so that’s why this output shows no PSRAM. The purpose of this output is really just to show there is no backtrace or register dump.

Model: ESP32-S3, Cores:2, Frequency:240
SIZE(K): Heap:385, PSram:0, Flash:16384
Free(K): Heap:361, PSram:0
MaxAlloc(K): Heap:327, PSram:0
Setup completed.
Serial.println #0
[  1106][E][main.cpp:60] loop(): log_e
<<SNIP normal loops before intentionally throwing an exception>>
Going to throw an unhandled exception.
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x4201e896
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x44c
load:0x403c9700,len:0xbec
load:0x403cc700,len:0x2920
entry 0x403c98d8
Model: ESP32-S3, Cores:2, Frequency:240
SIZE(K): Heap:385, PSram:0, Flash:16384
Free(K): Heap:361, PSram:0
MaxAlloc(K): Heap:327, PSram:0
Setup completed.
Serial.println #0
[  1106][E][main.cpp:60] loop(): log_e

After quite a bit of fiddling and digging, I had a suspicion and confirmed it … if I recompile WITHOUT ARDUINO_USB_CDC_ON_BOOT=1 and switch my USB C cable over to the UART instead of the USB connector, I actually get Guru Meditation and backtrace information.

Is it a simple rule that backtrace information can only happen over the UART? That seems silly to me, but wondering if you or someone else knows how to enable the panic handler to do backtrace/guru meditation information over the USB connector (CDC/JTAG) port.

Thanks!
Bob

Hi @robobob68 !

This is a legit way, but keep in mind, nobody else has your .json file.

Personally I would avoid these settings in the boards.json:

This should set per project in the platformio.ini.
Otherwise you always have to unflag these settings when you want to change them.

1 Like

So far I have no experience with debug output via USBSerial and would have to have a look / try it out. Unfortunately, I’m traveling all day today and can’t get to my ESP32-S3 board.

Please note that not only ARDUINO_USB_CDC_ON_BOOT but the combination of ARDUINO_USB_MODE is crucial! See ESP32-S3 native USB interface and Serial Monitor missing first messages - #10 by sivar2311

Hi @robobob68 !

Here are my test results (using pioarduino / Arduino core 3.0.7) on an esp32-s3-devkitc-1 (N16R8):

CDC_ON_BOOT USB_MODE Debug output on
UART
Debug output on
native USB
0 0 Yes Yes
0 1 Yes Yes
1 0 Yes No*
1 1 Yes Yes

*) When CDC_ON_BOOT=1 & USB_MODE=0 the USB connection is handled by software. As soon as the ESP crashes the USB gets disconnected.

Thanks for your reply and the testing - wow.

I think I’m pretty clear on what debug (generally) goes to which connector (USB or UART connector), but the question here is about what happens upon a crash/exception.

I did another experiment last night and hooked up a secondary connection so I had two cables - one on USB and one on UART. I then had a serial connection to both so I could see both outputs at the same time. When USB_CDC_ON_BOOT=1, the guru meditation and registers and backtrace info from panic all go to the UART and do not go to the USB.

I’m hoping to figure a way to get that backtrace info on the USB connector, ultimately. I have seen a few others identify this exact same problem on other forums but never with an answer that leads to a solution.

At worst case, if I do have a spurious reboot in my project and come to realize it must be a crash, I could hook up the secondary serial cable on UART to get the backtrace, but that feels like such a “widget solution”. :slight_smile:

Thanks,
bob

The only case where the crash log is only available via UART is when USB_MODE is set to 0.

It is always a combination of both settings! See my table above.

(Tested on pioarduino with Espressif Arduino 3.0.7)

I tested this with both ARDUINO_USB_MODE=0 and =1 and I do not see the exception / guru meditation / registers / backtrace on the USB connector monitor in either case.

How can I check my espressif arduino version and any other versioning that might matter to get this sorted? You specifically mention arduino 3.0.7.

I tried pio run

pio run
Processing esp32-s3-lcd-ev (platform: espressif32; board: esp32-s3-lcd-ev; framework: arduino)
-------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32-s3-lcd-ev.html
PLATFORM: Espressif 32 (6.0.1) > Espressif ESP32-S3-LCD-EV-N16 (16 MB QD, 16 MB PSRAM)
HARDWARE: ESP32S3 240MHz, 320KB RAM, 16MB Flash
DEBUG: Current (esp-builtin) On-board (esp-builtin) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: 
 - framework-arduinoespressif32 @ 3.20006.221224 (2.0.6) 
 - tool-esptoolpy @ 1.40400.0 (4.4.0) 
 - toolchain-riscv32-esp @ 8.4.0+2021r2-patch5 
 - toolchain-xtensa-esp32s3 @ 8.4.0+2021r2-patch5
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 34 compatible libraries
Scanning dependencies...
No dependencies
Building in debug mode
Retrieving maximum program size .pio/build/esp32-s3-lcd-ev/firmware.elf
Checking size .pio/build/esp32-s3-lcd-ev/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   5.8% (used 18908 bytes from 327680 bytes)
Flash: [          ]   3.8% (used 247989 bytes from 6553600 bytes)
=============================== [SUCCESS] Took 0.91 seconds ==========================

Thanks
Bob

You are using platform = espressif32 @ 6.0.1 which is arduino 2.0.6 based on esp-idf 4.4.3. That’s an ancient version!

The latest available Espressif32 platform is 6.9.0 which is arduino 2.0.17 based on esp-idf 4.4.7

Unfortunately, PlatformIO does not support Espressif32 Arduino 3.x officially.

That’s why i am using a community fork called pioarduino: See GitHub - pioarduino/platform-espressif32: Espressif 32: pioarduino community platform for PlatformIO

To change to the latest official supported Espressif 2.0.17 arduino core change the platform setting in your platformio.ini:

platform = espressif32 @ 6.9.0

To make use of the latest Espressif 3.0.7 arduino core based on esp-idf 5.1.4 (pioarduino), simply change the platform setting in your platformio.ini:

platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.07/platform-espressif32.zip
1 Like

Dude - you are a ROCK STAR of information. This is great. I’ll play with these tonight and tomorrow.

Can you tell me - are there some particular features in the 3.0.7 / 5.1.4 pioarduino project that you would say are “must have” items or important over the 6.9.0/2.0.17 official platform?

Thanks!
bob
P.S. With the pioarduino you spec’d for me, the backtrace information does actually print out when USB_MODE=1 - so my results now match your table above. Woot Woot!

pioarduino provides the latest Espressif Arduino 3.x core, which PlatformIO unfortunately does not do.

See Support Arduino ESP32 v3.0 based on ESP-IDF v5.1 · Issue #1225 · platformio/platform-espressif32 · GitHub for more details about this.

Please note that Espressif Arduino 3.x comes with a few breaking changes!
For detailed information please see migration guide 2.x → 3.x

To get an overview of the available platform / arduino (/ underlying esp-idf) versions see this table: platform-espressif32 versions · GitHub

1 Like

Super - again thanks to you. You’re one heck of a resource to the community and I sure appreciate that.

–bob

1 Like