espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.44k stars 7.38k forks source link

USB CDC serial connection state does not work properly #7073

Open FlorianBaumgartner opened 2 years ago

FlorianBaumgartner commented 2 years ago

Board

ESP32-S2

Device Description

Unexpected Maker FeatherS2

Hardware Configuration

Onboard LED on Pin 13

Version

v2.0.4

IDE Name

Arduino IDE

Operating System

Windows 10

Flash frequency

80 Mhz

PSRAM enabled

yes

Upload speed

921600

Description

While the COM port is opened (e.g. Arduino Console or Tera Term) the onboard LED should light up. If then the console gets closed and reopened again, this is not the case (LED stays turned off). When closed and reopened again it works (LED stays on as long as the console is opened). Basically every second time the COM port is opened it works as it should (this is consistently).

Further investigation showed that the TinyUSB Library does not throw an ARDUINO_USB_CDC_CONNECTED_EVENT or ARDUINO_USB_CDC_DISCONNECTED_EVENT event. Maybe this is an issue related to the TinyUSB framework.

Sketch

void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin();
}

void loop()
{
  digitalWrite(13, Serial);
}

Debug Message

None

Other Steps to Reproduce

Can be reproduced on multiple ESP32-S2 boards (Unexpected Maker FeatherS2, Lilygo V1.1, S2 Mini) and in multiple IDEs (Arduino IDE and Plaform IO).

I have checked existing issues, online documentation and the Troubleshooting Guide

FlorianBaumgartner commented 2 years ago

Meanwhile I found the problem. The bug is caused in the USBCDC.cpp file in the ESP32 core libraries. To make it work I've commented out the if statement on line 236 as shown below:

//if(lineState == CDC_LINE_IDLE){
    if(dtr && rts && !connected){
        connected = true;
        arduino_usb_cdc_event_data_t p;
        arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_CONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
    } else if(!dtr && connected){
        connected = false;
        arduino_usb_cdc_event_data_t p;
        arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_DISCONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
    }
    arduino_usb_cdc_event_data_t l;
    l.line_state.dtr = dtr;
    l.line_state.rts = rts;
    arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_LINE_STATE_EVENT, &l, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
//}

I don't know why this check was there in the first place, but it works flawlessly without it. Maybe someone can have a look at this and integrate it into the next release...

SuGlider commented 2 years ago

Thanks @FlorianBaumgartner -

It's necessary to investigate the reason for that if(lineState == CDC_LINE_IDLE){, but I think it may be there for when the USB port is used for uploading binaries.

Line State may be used for reseting the board right after finishing uploading.