0

The dev boards for the ESP32 family of MCU use CP210x (or similar) "FTDI" chips to communicate with the MCU when flashing. CP210x presents a COM port to the host computer which runs esptool.py, a script which implements the Esressif communication protocol. Rather then use a CP210x, I would like to utilize a SAMD21 in its place.

I have managed to receive logs from my ESP32, to a serial monitor on my computer, via the SAMD21, over USB. The SAMD21 connects to the ESP32 via UART, with the standard ESP configuration of 115200 8N1. I can manually enter bootloader mode by holding the correct pins low at boot, and I get the log back confirming the correct bootloader mode.

When I run esptool.py, however, the connection fails, and I get a timeout. Likewise the esptool "monitor" fails to acknowledge the same logs which my terminal emulator easily detects.

What is the communication protocol between the host computer running esptool.py, the CP210x FTDI chip, and the ESP32, and how can I emulate the CP210x with a SAMD21? The definition of "FTDI", "TTL" and "RS232" are all a bit fuzzy, as far as I can determine with research online, so if anyone has experience in this arena, I would be very curious to hear your advice.

The code I have on my SAMD21 is just:

#include <Arduino.h>

void setup()
{
    Serial.begin(115200);
    Serial1.begin(115200);
}

void loop()
{
    if(Serial.available())
    {
        Serial1.write(Serial.read());
    }
    if(Serial1.available())
    {
        Serial.write(Serial1.read());
    }
}

Where Serial1 is the UART and Serial is the USB Serial connection.

Marchingband
  • 489
  • 1
  • 7
  • 14

2 Answers2

2

esptool.py expects a serial port (known as COM port on Windows) to communicate with the ESP32. It doesn't care if the computer has an old-style serial port, is using a USB-to-serial bridge with a proprietary protocol (FTDI, CP210x and the like) or is using the standardized UBS protocol for serial communication (USB CDC ACM). This is left to the operating system and the installed drivers.

However, esptool.py modifies the baud rate and uses the RTS and DTR signals to reset the ESP32. It is also rather susceptible to timing issues with regards to the reset. If you set the ESP32 in boot mode manually, you should be able to get away without these.

However, the most likely cause is that the Arduino CDC implementation does not implement flow control. If esptool.py sends more data than fit into the internal buffer, it is likely discarded, instead of sending a NAK back so the host computer can retry later.

I don't fully understand the SAMD21 Arduino core to verify it. If so, I don't see how you can make it work with an Arduino program. You would need to resort to some other framework for programming the SAMD21.

Update

After more tests, it turns out the USB CDC implementation of the SAMD21 Arduino core correctly implements flow control. So no data will be lost.

In fact, I was able to successfully upload code to an ESP32 module. The setup was:

  • Arduino code built with PlatformIO. Instead of Serial, I've used SerialUSB as I'm unsure how to control the project settings available in the regular Arduino IDE.
  • For the ESP32, I've used a ESP32-WROOM-32 module on a minimal board (reset and boot button, 2 pull-up resistors).
  • I've connected the board via GND, 3.3V, TX, RX directly to the SAMD21 dev board.
  • I've verified that I can see the ESP32 log output in normal run mode and the "waiting for download" prompt in bootloader mode (after pressing BOOT and RESET).
Codo
  • 75,595
  • 17
  • 168
  • 206
  • Thank you so much, this is very helpful. I am manually entering bootloader mode. The XIAO dev board I am using offers 2 different CDC implementations in its Arduino repo, both mention flow control cts/rts logic. https://github.com/Seeed-Studio/ArduinoCore-samd/blob/master/cores/arduino/USB/CDC.cpp and the tinyUSB version here https://github.com/adafruit/Adafruit_TinyUSB_ArduinoCore/blob/e7b892095f2bb5d8bef6a748238369bdd268ed5e/Adafruit_USBD_CDC.cpp – Marchingband Apr 24 '22 at 17:14
  • I dont see any mention of "NAK" anywhere. Do you have any tips on how I could proceed? Can you recommend another framework that might implement CDC with flow control? – Marchingband Apr 24 '22 at 17:15
  • The NAK as a response to USB packages is very low-level. Even you program an MCU at the lowest-level, you just indicate that you cannot accept further packets and the NAK is sent by the hardware. I did a quick test with a SAMD21 board and the serial connection was very robust. So it might implement flow-control after all. So your problem might be the timing or baud rate after all. And you might one to looked into what *esptool.py* expects regarding reset even if you put the board into bootloader mode manually. – Codo Apr 24 '22 at 18:12
  • And regarding other frameworks: The main candidate is Atmel ASF. – Codo Apr 24 '22 at 18:12
  • interesting! Thank you for clarifying and testing. I know that esptool does not expect resets or anything else from the ESP32, because I regularly use an FTDI module to program ESP32 and it only connects with RX and TX – Marchingband Apr 24 '22 at 18:18
  • In your testing, did you use Atmel ASF, or an Arduino lib? If Arduino, which USB lib? – Marchingband Apr 24 '22 at 18:19
  • I used the standard Arduino core for SAMD21 and the built-in `SerialUSB`. No libraries. Depending on your settings in the Arduino IDE, your `Serial` is the same as `SerialUSB`. Did you fix the baud rate at 115,200? *esptool.py* can change the baud rate. That's part of the used [protocol](https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html) (search for `CHANGE_BAUDRATE`). This page although describes the initialization sequence. – Codo Apr 24 '22 at 18:39
  • Yes the -b 115200 sets the baud rate. I also used --trace and can see that esptool receives no response at all, and is only sending about 100 bytes in its initial package. – Marchingband Apr 24 '22 at 19:16
  • I've just tried it myself and it worked. I could successfully upload code. I've built the Arduino code with PlatformIO and replaced *Serial* with *SerialUSB*. Other than that, I don't see any difference. So what's the difference? Wiring? Entering boot mode? I can't tell. – Codo Apr 24 '22 at 20:15
  • Well that is amazing news! It's so great to know for sure that this is possible. I cant thank you enough. Do you know what is the correct etiquette with this question now? Should I delete it altogether? – Marchingband Apr 25 '22 at 05:34
  • I wouldn't delete it. There are valuable information on this page. But if you figure out, why it doesn't currently work for you, add an answer with the solution yourself. – Codo Apr 25 '22 at 07:21
0

Arduino has multiple boards where the esp32 is on-board as WiFi adapter. To flash the esp32, there is a tool sketch called SerialNINAPassthrough in examples of the WiFi library, which should be uploaded into the main MCU of the board (SAMD21 on two of the official boards).

The SerialNINAPassthrough sketch handles the DTR and RTS signals sent by the esptool to reset the board into the flashing mode.

Juraj
  • 3,490
  • 4
  • 18
  • 25