aboutsummaryrefslogtreecommitdiff
path: root/cores
diff options
context:
space:
mode:
Diffstat (limited to 'cores')
-rw-r--r--cores/arduino/CDC.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp
index 7f33a6e..6d3929e 100644
--- a/cores/arduino/CDC.cpp
+++ b/cores/arduino/CDC.cpp
@@ -101,13 +101,26 @@ bool WEAK CDC_Setup(Setup& setup)
if (CDC_SET_CONTROL_LINE_STATE == r)
{
_usbLineInfo.lineState = setup.wValueL;
+
// auto-reset into the bootloader is triggered when the port, already
// open at 1200 bps, is closed. this is the signal to start the watchdog
// with a relatively long period so it can finish housekeeping tasks
// like servicing endpoints before the sketch ends
- if (0 != _usbLineInfo.lineState && 1200 == _usbLineInfo.dwDTERate) {
+
+ // We check DTR state to determine if host port is open (bit 0 of lineState).
+ // Serial1.print(">"); Serial1.println(_usbLineInfo.lineState, HEX);
+ if ((_usbLineInfo.lineState & 0x01) == 0 && _usbLineInfo.dwDTERate == 1200) {
*(uint16_t *)0x0A00 = 0x7777;
wdt_enable(WDTO_250MS);
+ } else {
+ // Most OSs do some intermediate steps when configuring ports and DTR can
+ // twiggle more than once before stabilizing.
+ // To avoid spurious resets we set the watchdog to 250ms and eventually
+ // cancel if DTR goes back high.
+
+ wdt_disable();
+ wdt_reset();
+ *(uint16_t *)0x0A00 = 0x0;
}
return true;
}
@@ -202,4 +215,4 @@ size_t Serial_::write(uint8_t c)
Serial_ Serial;
#endif
-#endif /* if defined(USBCON) */ \ No newline at end of file
+#endif /* if defined(USBCON) */