USB CDC

About

USB Communications Device Class API. This class is used to enable communication between the host and the device.

This class is often used to enable serial communication and can be used to flash the firmware on the ESP32 without the external USB to Serial chip.

APIs

onEvent

Event handling functions.

void onEvent(esp_event_handler_t callback);
void onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback);

Where event can be:

  • ARDUINO_USB_CDC_ANY_EVENT

  • ARDUINO_USB_CDC_CONNECTED_EVENT

  • ARDUINO_USB_CDC_DISCONNECTED_EVENT

  • ARDUINO_USB_CDC_LINE_STATE_EVENT

  • ARDUINO_USB_CDC_LINE_CODING_EVENT

  • ARDUINO_USB_CDC_RX_EVENT

  • ARDUINO_USB_CDC_TX_EVENT

  • ARDUINO_USB_CDC_RX_OVERFLOW_EVENT

  • ARDUINO_USB_CDC_MAX_EVENT

setRxBufferSize

The setRxBufferSize function is used to set the size of the RX buffer.

size_t setRxBufferSize(size_t size);

setTxTimeoutMs

This function is used to define the time to reach the timeout for the TX.

void setTxTimeoutMs(uint32_t timeout);

begin

This function is used to start the peripheral using the default CDC configuration.

void begin(unsigned long baud);

Where:

  • baud is the baud rate.

end

This function will finish the peripheral as CDC and release all the allocated resources. After calling end you need to use begin again in order to initialize the USB CDC driver again.

void end();

available

This function will return if there are messages in the queue.

int available(void);

The return is the number of bytes available to read.

availableForWrite

This function will return if the hardware is available to write data.

int availableForWrite(void);

peek

This function is used to peek messages from the queue.

int peek(void);

read

This function is used to read the bytes available.

size_t read(uint8_t *buffer, size_t size);

Where:

  • buffer is the pointer to the buffer to be read.

  • size is the number of bytes to be read.

write

This function is used to write the message.

size_t write(const uint8_t *buffer, size_t size);

Where:

  • buffer is the pointer to the buffer to be written.

  • size is the number of bytes to be written.

flush

This function is used to flush the data.

void flush(void);

baudRate

This function is used to get the baudRate.

uint32_t baudRate();

setDebugOutput

This function will enable the debug output, usually from the UART0, to the USB CDC.

void setDebugOutput(bool);

enableReboot

This function enables the device to reboot by the DTR as RTS signals.

void enableReboot(bool enable);

rebootEnabled

This function will return if the reboot is enabled.

bool rebootEnabled(void);

Example Code

Here is an example of how to use the USB CDC.

USBSerial

#ifndef ARDUINO_USB_MODE
#error This ESP32 SoC has no Native USB interface
#elif ARDUINO_USB_MODE == 1
#warning This sketch should be used when USB is in OTG mode
void setup(){}
void loop(){}
#else
#include "USB.h"

static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
  if(event_base == ARDUINO_USB_EVENTS){
    arduino_usb_event_data_t * data = (arduino_usb_event_data_t*)event_data;
    switch (event_id){
      case ARDUINO_USB_STARTED_EVENT:
        Serial.println("USB PLUGGED");
        break;
      case ARDUINO_USB_STOPPED_EVENT:
        Serial.println("USB UNPLUGGED");
        break;
      case ARDUINO_USB_SUSPEND_EVENT:
        Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en);
        break;
      case ARDUINO_USB_RESUME_EVENT:
        Serial.println("USB RESUMED");
        break;
      
      default:
        break;
    }
  } else if(event_base == ARDUINO_USB_CDC_EVENTS){
    arduino_usb_cdc_event_data_t * data = (arduino_usb_cdc_event_data_t*)event_data;
    switch (event_id){
      case ARDUINO_USB_CDC_CONNECTED_EVENT:
        Serial.println("CDC CONNECTED");
        break;
      case ARDUINO_USB_CDC_DISCONNECTED_EVENT:
        Serial.println("CDC DISCONNECTED");
        break;
      case ARDUINO_USB_CDC_LINE_STATE_EVENT:
        Serial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts);
        break;
      case ARDUINO_USB_CDC_LINE_CODING_EVENT:
        Serial.printf("CDC LINE CODING: bit_rate: %lu, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity);
        break;
      case ARDUINO_USB_CDC_RX_EVENT:
        Serial.printf("CDC RX [%u]:", data->rx.len);
        {
            uint8_t buf[data->rx.len];
            size_t len = USBSerial.read(buf, data->rx.len);
            Serial.write(buf, len);
        }
        Serial.println();
        break;
       case ARDUINO_USB_CDC_RX_OVERFLOW_EVENT:
        Serial.printf("CDC RX Overflow of %d bytes", data->rx_overflow.dropped_bytes);
        break;
     
      default:
        break;
    }
  }
}

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  
  USB.onEvent(usbEventCallback);
  USBSerial.onEvent(usbEventCallback);
  
  USBSerial.begin();
  USB.begin();
}

void loop() {
  while(Serial.available()){
    size_t l = Serial.available();
    uint8_t b[l];
    l = Serial.read(b, l);
    USBSerial.write(b, l);
  }
}
#endif /* ARDUINO_USB_MODE */