USBSerial port reset and lockup


I use an Arduino DUE in an instrument controller operating in an industrial environment. In this application I use the Native USB interface to communicate with a PC or MAC running a host application. Most of the time this works fine but I do experience communications errors in some installations, likely due to electrical noise issues. This can lock up the system causing a watchdog timer system reset or rendering the USBserial port inoperable until reboot. I have read similar problems from others and I would like to share a few things I have done and found useful.

My environment is:
IDE: 1.8.7
SAM drivers: 1.6.11

First the following code will reset the SerialUSB interface without the need to reboot the DUE:

// Reset the serial USB port
void SerialPortReset(void)
otg_disable(); // Disable the hardware
otg_enable(); // Enable the hardware
USBDevice.attach(); // Inits the USB serial port
SerialInit(); // My serial port initialization code

I modified the USBCore.cpp file and its header, USBCore.h, to address the lockup issues. I found several places where the driver was polling the hardware in a tight loop with no timeout. I added timeouts and a flag to indicate an error had occurred. In the main loop of my Arduino app I poll for this error flag and if found I reset the USBserial interface. My host app then looks for the port to close and reopens in the event of the error. I added a couple functions to the USBCore.cpp file to help this process, below is my main loop error detection code:


The functions isUSBerror() and clearUSBerror() I added to the USBCore.cpp file. I have attached a zip file with USBCore.cpp and USBCore.h for reference. You will also notice that I hard coded my ID info for the USB port enumeration process.
This process has worked for me and I just wanted to share what I have learned in case it may help others with the similar problem.

–Gordon (10.5 KB)

Thanks for sharing.