USBDevice.connected() does not work
pillilz opened this issue · 0 comments
USBDevice.connected()
should return true
if and only if the device is connected to a host.
Its actual return value does not reflect the connection state. If called repeatedly in a tight loop in connected state it shows periodic behavior. Every 2 seconds it returns false
for 0.25s and true
for the remaining time.
This is cause by two errors in the code:
bool USBDeviceClass::connected()
{
// Count frame numbers
uint8_t f = USB->DEVICE.FNUM.bit.FNUM;
//delay(3);
return f != USB->DEVICE.FNUM.bit.FNUM;
}
Error 1: FNUM is a 11bit number. Writing it to uint8_t
variable discards the upper three bits and makes the comparison in the return
statement invalid if FNUM is >= 256.
Error 2: Due to the commented out delay
call, the two FNUM
reads result in the same value with high probability, if I understand Wikipedia correctly, because it changes only every millisecond.
The errors explain the observed behavior. In connected state FNUM
changes every millisecond. For 0 <= FNUM < 256
the return value is false
. For 256 <= FNUM < 2048
the return value is true
. In disconnected state FNUM
does not change. Depending on its (random) value the function returns either true
or false
as described.
The following code fixes the issues for me.
bool USBDeviceClass::connected()
{
// Count frame numbers
uint16_t f = USB->DEVICE.FNUM.bit.FNUM;
delay(1); // wait for next SOF
return f != USB->DEVICE.FNUM.bit.FNUM;
}
Happy to raise a PR.