ESP32-C3 Dev Kit In-Circuit Debugging

Adding In-Circuit debugging to the ESP32-C3 Dev Kit.

Using an old USB cable/breakout I had lying around. You’ll probably want to use USB-C. šŸ˜‰

Attach nothing to the Dev Kit USB connector.

Also, I use a lot of power and grounds.

Link: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/usb-serial-jtag-console.html

Debugging (at a break point) in VSCode on Ubuntu.

NOTES:

> The ESP32-C3 is said to be the successor to the ESP-8266. And like the 8266 is limited in Programmable IO compared with the ESP-32. This USB method of In-Circuit debugging uses two processor PIO pins instead of the four pins needed for JTAG debugging–freeing up two pins for general use.


> In the processor’s low power modes, the USB interface is powered down and USB debugging is not possible. If you need to debug while in one of the two low power modes, you should use the JTAG interface.


> Visual Studio Code operates at the source code level and is able to use this method of debugging to set breakpoints, examine variables and the stack, single-step high level source code and flash the device. But VSCode has no knowledge of the processor details (e.g. CPU internal registers, memory configuration–access and format). As a result single-stepping through assembly code while examining CPU registers, flags and memory is not possible.
But the detailed knowledge gained while single-stepping assembly code would be an advantage in learning the ESP32-C3’s risc-v architecture. VSCode teamed with PlatformIO could provide this capability and I have filed an issue to that purpose on PlatformIO’s github. https://github.com/platformio/platform-espressif32/issues/651

DSP Done Dirt Cheap

Created a new GitHub https://github.com/bobh/ESP_DSP and added a Real-Time FIR filter implementation from Espressif’s DSP Library.

Time permitting, I’ll be adding new DSP Library functions and documenting them here and on my YouTube channel @wm6h.

Using the Arduino IDE allows me to add Arduino Libraries for servos, LEDs, etc. along with action figure leitmotifs (WAV audio) for my Holiday displays.

SD Card Support For M5Stack Morse Tutor

Some Morse Tutor projects are adding SD card support (the text file on the SD Card is sent via Morse Code).

I went to gutenberg.org and loaded a large Sherlock Holmes book onto a Samsung 32 GB EVO Plus MicroSDHC UHS-1 Card. Formatted with PC/MAC app SDFORMATTER for Type1 SDHC FAT32

Inserted the card into the M5Stack SD card socket and had no trouble reading/writing it with this code:

#include <M5Stack.h>
 
//Micro SD / TF Card Test
/*
 M5Stack initializing...OK
Listing directory: /
  DIR : /.Spotlight-V100
  DIR : /.fseventsd
  FILE: /SherlockHolmes.txt  SIZE: 590492
  FILE: /._SherlockHolmes.txt  SIZE: 4096
  FILE: /hello.txt  SIZE: 11
Writing file: /hello.txt
File written
Reading file: /hello.txt
Read from file: Hello world from M5Stack !!
 */


void listDir(fs::FS &fs, const char * dirname, uint8_t levels){

    // Print blank line on screen
    M5.Lcd.printf(" \n  ");
    M5.Lcd.printf(" \n  ");
    
    Serial.printf("Listing directory: %s\n", dirname);
    M5.Lcd.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        M5.Lcd.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        M5.Lcd.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            M5.Lcd.print("  DIR : ");
            Serial.println(file.name());
            M5.Lcd.println(file.name());
            if(levels){
                listDir(fs, file.name(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            M5.Lcd.print("  FILE: ");
            Serial.print(file.name());
            M5.Lcd.print(file.name());
            Serial.print("  SIZE: ");
            M5.Lcd.print("  SIZE: ");
            Serial.println(file.size());
            M5.Lcd.println(file.size());
        }
        file = root.openNextFile();
    }
}

void readFile(fs::FS &fs, const char * path) {
    Serial.printf("Reading file: %s\n", path);
    M5.Lcd.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        M5.Lcd.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    M5.Lcd.print("Read from file: ");
    while(file.available()){
        int ch = file.read();
        Serial.write(ch);
        M5.Lcd.write(ch);
    }
}

void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);
    M5.Lcd.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        M5.Lcd.println("Failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
        M5.Lcd.println("File written");
    } else {
        Serial.println("Write failed");
        M5.Lcd.println("Write failed");
    }
}

// the setup routine runs once when M5Stack starts up

void setup() { 
 
    // initialize the M5Stack object
    M5.begin();

    //M5.startupLogo();
    Wire.begin();

    // Lcd display
    M5.Lcd.setBrightness(100);
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setCursor(0, 10);
    M5.Lcd.setTextColor(WHITE);
    M5.Lcd.setTextSize(1);

    // Page Header
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setCursor(0, 05);
    M5.Lcd.printf("           Testing Micro SD Card Functions:\r\n");
    // digitalWrite(TFT_CS, 1);
 
    // Print blank line on screen
    M5.Lcd.printf(" \n    ");
    M5.Lcd.printf(" \n    ");
    
    listDir(SD, "/", 0);
    M5.Lcd.printf("");
    M5.Lcd.printf("");

    // Print blank line on screen
    M5.Lcd.printf(" \n  ");
    M5.Lcd.printf(" \n  ");
    
    writeFile(SD, "/hello.txt", "Hello world from M5Stack !!");
    M5.Lcd.printf("");
    M5.Lcd.printf("");

    // Print blank line on screen
    M5.Lcd.printf(" \n  ");
    M5.Lcd.printf(" \n  ");

    // Print blank line on screen
    M5.Lcd.printf(" \n  ");
    M5.Lcd.printf(" \n  ");
    
    readFile(SD, "/hello.txt");
}

void loop() {

  // put your main code here, to run repeatedly:
    M5.update();
}