Hi Steven,
Figured out how to change the editor mode with the first icon on the top at the left of the BOLD button. Some of the code got colors only 
I kow you do not need these upcomming instructions, but I will add them for anyone willing to try this.
platformio.ini
[env]
platform = espressif32
board = esp32-s3-devkitc1-n8r2
framework = arduino
lib_deps = adafruit/Adafruit NeoPixel@^1.15.4
monitor_speed = 115200
; --- NORMAL RUNNING (Release) ---
[env:release]
build_type = release
build_flags =
-Os
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_MODE=1
-DNDEBUG ; Disables assert() macros for speed
-fno-exceptions ; Reduces binary size if not using C++ exceptions
; --- DEBUGGING (Stable Config) ---
[env:DEBUG]
build_type = debug
; Flags to help Windows 11 keep the USB stack stable
build_flags =
-O0
-g3
-DDEBUG
-DARDUINO_USB_CDC_ON_BOOT=1
-DARDUINO_USB_DFU_ON_BOOT=1
-DARDUINO_USB_MODE=0 ; Use "Hardware CDC and JTAG"
-DCORE_DEBUG_LEVEL=4 ; Sets log level to Verbose (adjust as needed)
debug_tool = esp-builtin
upload_protocol = esp-builtin
debug_speed = 10000
debug_load_mode = manual
debug_init_break = tbreak setup
; When we start the Serial Monitor we do not want a COM port reset that afects the debugger
monitor_dtr = 0
monitor_rts = 0
; Remove 'monitor reset halt', it is likely what's crashing the W11 driver
debug_extra_cmds =
set remotetimeout 20
flushregs
main.cpp
#include <Adafruit_NeoPixel.h>
#include <debug_log.h>
#include <esp_task_wdt.h>
#include "rom/ets_sys.h"
#define PIN 38 // GPIO 38 for most DevKitC-1 boards (be sure to check as some boards use 48 or 21)
#define NUMPIXELS 1 // The onboard RGB LED is a single pixel
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int loop_counter = 1;
unsigned long previousMicros;
unsigned long currentMicros;
long micros_interval = 10;
void u_delay(long u_length) {
}
// Helper function modified for ESP32-S3 (Xtensa)
bool dw_is_debugger_attached() {
uint32_t dsr;
// Read the Xtensa Debug Status Register (SREG 233)
asm volatile("rsr %0, 233" : "=a" (dsr));
// Bit 0 (RunSt) is 0 when the target is halted by a debugger
// However, usually checking if the JTAG is connected involves
// checking if the debug interrupt is enabled.
// If dsr is non-zero, it means a debugger has performed
// an operation or is currently halting the core.
// return (dsr & (1 << 4)); // FOR SOME REASON THIS DID NOT WORK
return (dsr);
}
void setup() {
int k = 0;
Serial.begin(115200);
// Only execute this wait if we are in a DEBUG build
#ifdef DEBUG
// We do this only when we deubug, to avoid any possible wd reset while stopped at a breakpoint
esp_task_wdt_init(30, false); // 30-second timeout, and do NOT reset on trigger
// Force the chip to wait here until the JTAG debugger is active
micros_interval = 10; // Let us wait 10 microseconds at a time
previousMicros = micros();
while (!dw_is_debugger_attached()) {
// Start of microseconds delay
do {
currentMicros = micros();
}
while (currentMicros - previousMicros < micros_interval);
previousMicros = currentMicros;
// End of microseconds delay
k++; // In case you want to know how many delays where required for the debugger to attach
}
#endif
// Instead of while(!Serial)
// This gives the JTAG controller "gaps" to breathe
micros_interval = 100; // Let us wait 100 microseconds at a time
previousMicros = micros();
for (int i = 0; i < 1000; i++) {
if (Serial) break;
// Start of microseconds delay
do {
currentMicros = micros();
}
while (currentMicros - previousMicros < 100);
previousMicros = currentMicros;
// End of microseconds delay
}
// After this comment you put your first break point. After this dummy assignment your real setup() function starts
previousMicros = micros();
#ifdef DEBUG
my_simple_log("ESP32-S3 source code debugging started!");
#else
my_simple_log("ESP32-S3 printf scheme debugging started!");
#endif
// Once your code is finished and you do not need any printf debugging or source code debugging anymore, you can get rid
// of all code from this line up. The same holds for any other app different than LED blink, regardless of its complexity.
pixels.begin();
}
void loop() {
// In loop() we will use regular milliseconds delays
my_flexible_log("Alive %d!", loop_counter);
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 0, 5)); // Set single LED color to Green (R, G, B)
pixels.show(); // Show the LED ON
delay(500); // Keep it on for half a second
pixels.clear(); // Set the LED to OFF
pixels.show(); // Show the LED OFF
delay(500); // Keep it off for half a second
loop_counter++;
}
debug_log.h
#ifndef DEBUG_LOG_H
#define DEBUG_LOG_H
// Only one argument that will get a carriage return at the end
void my_simple_log(const char* message);
// Allows you to use it with variable arguments
void my_flexible_log(const char* format, ...);
#endif
debug_log.cpp
#include "debug_log.h"
#include <Arduino.h>
#include <stdarg.h>
#include "rom/ets_sys.h"
void my_simple_log(const char* message) {
#ifdef DEBUG
ets_printf("%s\n", message);
#else
Serial.println(message);
#endif
}
void my_flexible_log(const char* format, ...) {
char buffer[128]; // Adjust size as needed
va_list args;
va_start(args, format);
vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
#ifdef DEBUG
ets_printf("%s\n", buffer);
#else
Serial.println(buffer);
#endif
}
esp32-s3-devkitc1-n8r2.json
{
"build": {
"arduino": {
"partitions": "default_8MB.csv",
"memory_type": "qio_qspi"
},
"core": "esp32",
"extra_flags": [
"-DARDUINO_ESP32S3_DEV",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1",
"-DBOARD_HAS_PSRAM"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"psram_type": "qio",
"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"
],
"platforms": [
"espressif32"
],
"name": "Espressif ESP32-S3-DevKitC-1-N8R2 (8 MB Flash Quad, 2 MB PSRAM quad)",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"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 INI file defines the âreleaseâ and the âDEBUGâ environments.
You select acording to what you want to do.
For DEBUG you:
0) Put a breakpoint in the setup() function at line 73 (if you make a verbatim copy of this code). The code on that line is "previousMicros = micros();", which is a dummy instruction you can change later.
1) Compile and upload the code (arrow to the right). Ignore this message "Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED"
2) Start your serial monitor (plug icon)
3) Select in the leftmost panel of VSC the DEBUG icon (Triangle with a small bug on it)
4) At the top of the DEBUG panel, on the dropdown menu at the right of the green triangle, select "PIO Debug (without uploading), because your code is already running in an infinite loop somwhere :upside_down_face:
5) Press the green triangle to debug without uploading
6) Wait a couple of seconds for the DEBUG toolbox to appear, that should only have the PAUSE, RESTART and STOP buttons active. Depress the PAUSE button.
The DEBUG CONSOLE should show these two lines at the end:
....
esp32s3.cpu1: Debug controller was reset.
esp32s3.cpu1: Core was reset.
7) In my case it is stopping at a waiti assembler routine that I recall is a delay function maybe?
8) Now you have all the buttons enabled on the DEBUG toolbox (CONTINUE, STEP OVER, STEP INTO, STEP OUT, RESTART and STOP). Press CONTINUE and the debugger should stop at your breakpoint in the setup() function.
If you want to get a private class on how to manage the WATCH window or understand the CALL STACK window, you can ask GEMINI or the AI of your choice.
For sure there are configurations and settings that might be not essential for this to work, but I think it is imho a viable start point from were you can improve either by knowledge or try and error.
Feel free to point out any misconception or improvement that can be done, as we all will benefit from it.
Regards!