Emulate CP210x USB-FTDI chip using SAMD21

691 views Asked by At

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.

2

There are 2 answers

11
Codo On

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).
1
Juraj On

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.