diff --git a/ion/include/ion/usb.h b/ion/include/ion/usb.h index db478b4cc..cd2b29fc0 100644 --- a/ion/include/ion/usb.h +++ b/ion/include/ion/usb.h @@ -5,7 +5,10 @@ namespace Ion { namespace USB { bool isPlugged(); +bool isEnumerated(); // Speed-enumerated, to be accurate + void removeSoftDisconnect(); + void DFU(); } diff --git a/ion/src/device/events_keyboard.cpp b/ion/src/device/events_keyboard.cpp index 4359f3e40..6cc98d46f 100644 --- a/ion/src/device/events_keyboard.cpp +++ b/ion/src/device/events_keyboard.cpp @@ -1,5 +1,4 @@ #include -#include "regs/otg.h" #include namespace Ion { @@ -20,6 +19,7 @@ static bool sleepWithTimeout(int duration, int * timeout) { Event sLastEvent = Events::None; Keyboard::State sLastKeyboardState; bool sLastUSBPlugged = false; +bool sLastUSBEnumerated = false; bool sEventIsRepeating = 0; constexpr int delayBeforeRepeat = 200; constexpr int delayBetweenRepeat = 50; @@ -41,9 +41,12 @@ Event getEvent(int * timeout) { sLastUSBPlugged = usbPlugged; return Events::USBPlug; } + // Second, check if the USB device has been connected to an USB host - if (OTG.GINTSTS()->getENUMDNE()) { - // The device is being enumerated, the speed enumeration is finished. + bool usbEnumerated = USB::isEnumerated(); + bool previousUsbEnumerated = sLastUSBEnumerated; + sLastUSBEnumerated = usbEnumerated; + if (usbEnumerated && !previousUsbEnumerated) { return Events::USBEnumeration; } diff --git a/ion/src/device/usb.cpp b/ion/src/device/usb.cpp index f33fa1b66..5518c338a 100644 --- a/ion/src/device/usb.cpp +++ b/ion/src/device/usb.cpp @@ -13,6 +13,13 @@ bool isPlugged() { return Device::VbusPin.group().IDR()->get(Device::VbusPin.pin()); } +bool isEnumerated() { + /* Note: This implementation is not perfect. One would assume isEnumerated to + * return true for as long as the device is enumerated. But the GINTSTS + * register will be cleared in the poll() routine. */ + return OTG.GINTSTS()->getENUMDNE(); +} + void removeSoftDisconnect() { OTG.DCTL()->setSDIS(false); }