Esp32c3 D+ and D- pins as a serial port

sh6623
Posts: 7
Joined: Mon Jul 25, 2022 2:50 am

Esp32c3 D+ and D- pins as a serial port

Postby sh6623 » Fri May 19, 2023 9:56 am

i would like to know if it is possible to use the esp32c3 as a serial port to communicate with other devices? I am currently using the uart channel to do so but i would like to know if it is possible to do a one to one replace to use the D+ and D- pins instead of the Tx and Rx. How would i do so?
https://docs.espressif.com/projects/esp ... nsole.html

I came across this link but i am confused if it is possible. I have tried setting the uart drivers to use D+ and D- but to no avail.

a2800276
Posts: 78
Joined: Sat Jan 23, 2016 1:59 pm

Re: Esp32c3 D+ and D- pins as a serial port

Postby a2800276 » Fri May 19, 2023 11:02 am

The labels of the pins are their default assignment. D+ and D- are the inverted data lines of the USB peripheral. This can emulate a "serial console" to another USB device, typically your development laptop. There types of console connections are used to emulate RS232 style connections, because typical laptops and PCs no longer come with RS232 connections.

If this is what you are looking for, D+ and D- are the correct pins.

"Serial" can also refer to the UART peripheral on the chip. This is more low-level than the USB-Serial-Console emulation, and a laptop would not have this sort of interface (at not exposed for general use). ESP's have the wonderful property that you can route peripherals to more or less any pin (within reason) so you can assign pins with D+ / D- to handle other tasks. If this is what you want to do, search for "UART" and "io MUX" or "pin MUX".

It would help to be a bit more specific in your question. What sort of "devices" are you trying to connect? What is your understanding of a "serial connection"? Which programming environment are you using?

sh6623
Posts: 7
Joined: Mon Jul 25, 2022 2:50 am

Re: Esp32c3 D+ and D- pins as a serial port

Postby sh6623 » Fri May 19, 2023 11:35 am

Hi @a2800276, I will be more specific. Basically I have been working with uart to send messages back and forth from a laptop environment using esp32c3 mini1 dev kit. I have been using Uart Channel 1 with gpio pins 1 & 0 as the dev kit has an onboard USB to uart converter. But due to some constraints in the housing size, I am currently using a custom esp32c3 board and it has a USB connector which is internally wired to gpio 19 and 18. This is a direct connection without a USB uart converter. I have heard about USB CDC which apparently is able to allow me to reuse my uart software interface to communicate through the direct USB lines. But it does not seem to be working as I intend to. So I am trying to find out if this is possible. I have come across some links complaining about issues regarding esp32c3 and it's USB.

sh6623
Posts: 7
Joined: Mon Jul 25, 2022 2:50 am

Re: Esp32c3 D+ and D- pins as a serial port

Postby sh6623 » Fri May 19, 2023 11:37 am

Essentially I would like to know if it's possible to do it as I intend to. So according to the gpio mux, am I able to use the gpio 18 & 19 for serial communication? Because currently i am only using it for flashing firmware but based on the documentation I have posted above, it seems like I can also use it to do serial comm like I have always been doing(?)

a2800276
Posts: 78
Joined: Sat Jan 23, 2016 1:59 pm

Re: Esp32c3 D+ and D- pins as a serial port

Postby a2800276 » Fri May 19, 2023 12:27 pm

Basically I have been working with uart to send messages back and forth from a laptop environment using esp32c3 mini1 dev kit. I have been using Uart Channel 1 with gpio pins 1 & 0 as the dev kit has an onboard USB to uart converter.


This connection uses an additional chip on board the dev kit, labeled "USB to UART bridge". This chips speaks UART to the ESP and USB to your PC to provide some sort of tty / virtual COM port. The C3 has this functionality "built in" and that's what you are using on your own board, I believe:
But due to some constraints in the housing size, I am currently using a custom esp32c3 board and it has a USB connector which is internally wired to gpio 19 and 18. This is a direct connection without a USB uart converter. I have heard about USB CDC which apparently is able to allow me to reuse my uart software interface to communicate through the direct USB lines. But it does not seem to be working as I intend to. So I am trying to find out if this is possible.


PINs 18 and 19 and D- and D+ respectively, for all intents and purposes they "speak" the same thing as the usb to uart bridge speaks towards the PC. Those pins can be wired to the D+/- poles of a physical USB connector and, given the proper wiring and firmware will allow the ESP to provide a tty / vitual COM port to your laptop. So, short answer: this is possible and as far as I can tell from your post, everything is hooked up correctly. While this interface can be exposed as a serial port to you in the ESP firmware, there is no UART hardware peripheral involved, only the USB peripheral. Therefore, there are no RX and TX pins or a UART, only the D+/- signals of the USB connection.

I have come across some links complaining about issues regarding esp32c3 and it's USB.
I came across some links containing pictures of cats that have thumbs.

Essentially I would like to know if it's possible to do it as I intend to. So according to the gpio mux, am I able to use the gpio 18 & 19 for serial communication? Because currently i am only using it for flashing firmware but based on the documentation I have posted above, it seems like I can also use it to do serial comm like I have always been doing(?)
You never said what you intend to do or what you "have always been doing", so I can't really answer beyond what I said above, but if you want to use IO18 and IO19 to program the module's flash, this should work, given proper wiring, firmware and configuration. Programming the module and getting logs is "serial comm", you will also be able to use this channel to send other data.

You're very vague about what's going on. "But it does not seem to be working as I intend to." is not going to help anyone zoom in on potential problems you're having. Perhaps you could link to your board schematics if you're unsure whether the wiring is incorrect. Or a repo with some minimal source code reproducing the problem and error messages you get on the esp and laptop if you suspect problems in the firmware.

sh6623
Posts: 7
Joined: Mon Jul 25, 2022 2:50 am

Re: Esp32c3 D+ and D- pins as a serial port

Postby sh6623 » Fri May 19, 2023 1:56 pm

Hi @ a2800276, apologies for the ambiguity. This is the board i am using
https://files.seeedstudio.com/wiki/XIAO ... C3-SCH.pdf

As you can see, it is a gpio 19 & 18 direct to the usb port.
This is a sample code of what i was doing in esp-idf, and it works when i was using GPIO 0 and 1

Code: Select all

#define BUF_SIZE (4096) // just a large buffer to ensure it can hold all data
#define ECHO_TEST_TXD 1
#define ECHO_TEST_RXD 0
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)

#define UART_PORT_NUM 1
#define UART_BAUD_RATE 115200

void setup_UART_port(QueueHandle_t *queue_ptr)
{
  /* Configure parameters of an UART driver,
   * communication pins and install the driver */
  uart_config_t uart_config = {
      .baud_rate = UART_BAUD_RATE,
      .data_bits = UART_DATA_8_BITS,
      .parity = UART_PARITY_DISABLE,
      .stop_bits = UART_STOP_BITS_1,
      .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
      .source_clk = UART_SCLK_DEFAULT,
  };

  /* intr struct for reference
  uart_intr_config_t uart_interrupt = {
      .intr_enable_mask = UART_RXFIFO_FULL_INT_RAW,
      .rx_timeout_thresh = 1,
      .txfifo_empty_intr_thresh = 10,
      .rxfifo_full_thresh = 1,
  };
  */
  int intr_alloc_flags = 0;
  ESP_ERROR_CHECK(uart_driver_install(UART_PORT_NUM, BUF_SIZE * 2, 0, 1, queue_ptr, intr_alloc_flags));
  ESP_ERROR_CHECK(uart_param_config(UART_PORT_NUM, &uart_config));
  ESP_ERROR_CHECK(uart_set_pin(UART_PORT_NUM, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));
  // ESP_ERROR_CHECK(uart_intr_config(UART_PORT_NUM, &uart_interrupt));
}

Wait_data_thread(void* param)
{
 setup_UART_port(&handler);
 while (1)
  {
    // blocking queue, if receive data, data will be queued and notify this thread
    if (xQueueReceive(UART_queue, (void *)&event, (TickType_t)portMAX_DELAY))
    {
      switch (event.type)
      {
      case UART_DATA:
        // Read data from the UART and wait 20ms(negligble), the checking is done by queue
        int len = uart_read_bytes(UART_PORT_NUM, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);
        ESP_LOG_BUFFER_HEX("From uart", data, len);
        if (len)
        {
          data[len] = '\0';
          ESP_LOGI(TAG, "Recv str: %s", (char *)data);
          unsigned char checksum_buff[len];
          memcpy(checksum_buff, data, len); 
          /*
          if (CRCCCITT(checksum_buff, len) != 0)
          {
            ESP_LOGE(TAG, "Data is corrupted from UART port!");
            continue;
          }
          */
        }
        else
        {
          ESP_LOGE(TAG, "NO DATA FROM UART PORT!");
          continue;
        }
        opcode = extract_opcode(data);
        unicast_addr = extract_addr(data);
        esp_err_t err = Wait_backend_handler(opcode, unicast_addr, data, len);
        if (err != ESP_OK)
        {
          ESP_LOGE(TAG, "Error in Wait_backend_handler");
        }
        break;
      default:
        ESP_LOGI(TAG, "UNHANDLED UART EVT");
        break;
      }
    }
   }
How i usually see if data can be received will be to open a serial port using PuTTY and set baud rate at 115200, before sending data via the terminal to see if the esp can receive. And it can receive.

Now i changed

Code: Select all

#define ECHO_TEST_TXD 19
#define ECHO_TEST_RXD 18
I also tried

Code: Select all

#define ECHO_TEST_TXD 18
#define ECHO_TEST_RXD 19
and enabled the CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG flag
When i tried writing using PuTTY, i am unable to get any data, in some instance the PuTTY terminal will just crash. i am still able to flash if i go into download mode by pressing the boot switch and reset switch (GPIO 9 LOW triggering thingy in the data sheet to go into download mode). But in default mode, i become unable to communicate through UART

a2800276
Posts: 78
Joined: Sat Jan 23, 2016 1:59 pm

Re: Esp32c3 D+ and D- pins as a serial port

Postby a2800276 » Fri May 19, 2023 2:45 pm

In your previous example, the code was using the following hardware peripheral of the ESP32C3 chip: UART TX and RX

The signals coming out of the chip's pins were UART signals. That UART was connected to the UART->USB bridge chip linked to above that was available on your old board. That chip speaks UART to the ESP chip on one end and USB to your laptop on the other side. It generates D+ and D- signal on the physical USB connection.

Your XIAO board does not have a UART->USB bridge. Instead, the ESP32C3 has this functionality to generate D+ and D- built into it. The signals coming out of the chip's pin's 18 and 19 should be: USB D+ and USB D-, those pins are directly connected to your laptop via the physical USB connection. There is no bridge to translate from UART to USB, the esp chip itself can generate the necessary signals for the USB protocol.

Therefor pins IO18 and IO19 need to be configured to speak USB. But you did not configure those pins for USB, you only changed your UART code to use the pins connected to the USB connector. Therefor the pins are being used to generate UART signals and not USB signals. Your laptop doesn't understand UART, especially not in places where it expects USB.

Currently you have the board configured as follows:

Code: Select all



 ┌──────────┐                     ┌────────────┐
 │          │                     │            │
 │        18├───UART TX───────────┤ USB DM     │
 │ ESP32C3  │                     │            │
 │        19|───UART RX───────────┤ USB DP     │
 │          │                     │            │
 │          │                     │            │
 └──────────┘                     │            │
                                  │            │
                                  │Laptop !?!  │
                                  └────────────┘


Your laptop is very confused as to why you connected UART signals to its USB port. You should configure it as follows, using the documentation in the USB Serial JTAG documentation linked to above:

Code: Select all



   ┌──────────┐                     ┌────────────┐
   │          │                     │            │
   │        18├──USB DM─────────────┤ USB DM     │
   │ ESP32C3  │                     │            │
   │        19├──USB DP─────────────┤ USB DP     │
   │          │                     │            │
   │          │                     │            │
   └──────────┘                     │            │
                                    │            │
                                    │Laptop  :)  │
                                    └────────────┘


As you can see, this makes your laptop much less confused and happier.

I'm not going to read the documentation for you, but at a glance, it looks as if you may just need to delete all the UART code because that forces the D+ and D- pins to be a UART and set some variables in menuconfig... So it should be easy to try.

R0b3rt0
Posts: 1
Joined: Tue Apr 30, 2024 12:18 pm

Re: Esp32c3 D+ and D- pins as a serial port

Postby R0b3rt0 » Thu May 02, 2024 10:16 am

Hello Sh6623 and everyone, I find myself in the same situation as you: I've designed a board with a Type C connector and ESP32-C3-Wroom02, and I've connected the USB D+ and D- to the ESP's IO18 and IO19 pins, all without having a transceiver on my board. Currently, I can upload firmware to it, but like you, I'm unable to read from the serial because I don't have the transceiver. I wanted to know if you eventually found a method to write to USB using D+ and D-.
Thanks in advance.

sh6623
Posts: 7
Joined: Mon Jul 25, 2022 2:50 am

Re: Esp32c3 D+ and D- pins as a serial port

Postby sh6623 » Fri May 03, 2024 4:38 am

D+ and D- can be used as USB, but if you want to read UART, you need a USB to UART module converter or you can use software to do the conversion to UART. Don't know if there are any other ways around that

Who is online

Users browsing this forum: No registered users and 66 guests