I am running Arduino 1.8.7 on Windows 10. My arduino is a P1AM from Automation Direct. It is hardware compatible with the MKRZero.
I want to reset the arduino through the USB port as if I am pressing the reset button. If I connect and disconnect with USB at 1200 bps, the sketch is erased and NVIC_SystemReset() is called. I want the ability to call NVIC_SystemReset() without erasing the sketch.
I found that the arduino core software has a file called CDC.cpp that monitors for the 1200 bps connection. I added 6 lines of code to perform a reset when I connect at 2400 bps.
My first question is "Is there a better way to acomplish this other than modifying arduino files outside my sketch?"
My second question is "Why does the 1200 bps code reset after the com port is closed but the 2400 bps code is reset when the port is opened?"
bool CDC_Setup(USBSetup& setup)
{
uint8_t requestType = setup.bmRequestType;
uint8_t r = setup.bRequest;
if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
{
if (r == CDC_GET_LINE_CODING)
{
USBDevice.sendControl((void*)&_usbLineInfo, 7);
return true;
}
}
if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
{
if (r == CDC_SET_LINE_CODING)
{
USBDevice.recvControl((void*)&_usbLineInfo, 7);
}
if (r == CDC_SET_CONTROL_LINE_STATE)
{
_usbLineInfo.lineState = setup.wValueL;
}
if (r == CDC_SET_LINE_CODING || r == CDC_SET_CONTROL_LINE_STATE)
{
// auto-reset is triggered when the port is opened at 2400 bps. // my added code
if (_usbLineInfo.dwDTERate == 2400 && (_usbLineInfo.lineState & 0x01) == 0) // my added code
{ // my added code
__disable_irq(); // my added code
NVIC_SystemReset(); // my added code
while (true); // my added code
} // my added code
// auto-reset into the bootloader is triggered when the port, already
// open at 1200 bps, is closed. We check DTR state to determine if host
// port is open (bit 0 of lineState).
if (_usbLineInfo.dwDTERate == 1200 && (_usbLineInfo.lineState & 0x01) == 0)
{
initiateReset(250);
}
else
{
cancelReset();
}
return false;
}
if (CDC_SEND_BREAK == r)
{
breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
return false;
}
}
return false;
}