@@ -92,6 +92,7 @@ const DeviceDescriptor USB_DeviceDescriptorA =
92
92
// ==================================================================
93
93
94
94
volatile u8 _usbConfiguration = 0 ;
95
+ volatile u8 _usbCurrentStatus = 0 ; // meaning of bits see usb_20.pdf, Figure 9-4. Information Returned by a GetStatus() Request to a Device
95
96
96
97
static inline void WaitIN (void )
97
98
{
@@ -527,16 +528,37 @@ ISR(USB_COM_vect)
527
528
{
528
529
// Standard Requests
529
530
u8 r = setup.bRequest ;
531
+ u16 wValue = setup.wValueL | (setup.wValueH << 8 );
530
532
if (GET_STATUS == r)
531
533
{
532
- Send8 (0 ); // TODO
533
- Send8 (0 );
534
+ if (requestType == (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_DEVICE))
535
+ {
536
+ Send8 (_usbCurrentStatus);
537
+ Send8 (0 );
538
+ }
539
+ else
540
+ {
541
+ // TODO: handle the HALT state of an endpoint here
542
+ // see "Figure 9-6. Information Returned by a GetStatus() Request to an Endpoint" in usb_20.pdf for more information
543
+ Send8 (0 );
544
+ Send8 (0 );
545
+ }
534
546
}
535
547
else if (CLEAR_FEATURE == r)
536
548
{
549
+ if ((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
550
+ && (wValue == DEVICE_REMOTE_WAKEUP))
551
+ {
552
+ _usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED;
553
+ }
537
554
}
538
555
else if (SET_FEATURE == r)
539
556
{
557
+ if ((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
558
+ && (wValue == DEVICE_REMOTE_WAKEUP))
559
+ {
560
+ _usbCurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
561
+ }
540
562
}
541
563
else if (SET_ADDRESS == r)
542
564
{
@@ -644,6 +666,7 @@ USBDevice_::USBDevice_()
644
666
void USBDevice_::attach ()
645
667
{
646
668
_usbConfiguration = 0 ;
669
+ _usbCurrentStatus = 0 ;
647
670
UHWCON = 0x01 ; // power internal reg
648
671
USBCON = (1 <<USBE)|(1 <<FRZCLK); // clock frozen, usb enabled
649
672
#if F_CPU == 16000000UL
@@ -681,4 +704,22 @@ void USBDevice_::poll()
681
704
{
682
705
}
683
706
707
+
708
+ bool USBDevice_::wakeupHost ()
709
+ {
710
+ // clear any previous wakeup request which might have been set but could be processed at that time
711
+ // e.g. because the host was not suspended at that time
712
+ UDCON &= ~(1 << RMWKUP);
713
+
714
+ if (!(UDCON & (1 << RMWKUP)) && (_usbCurrentStatus & FEATURE_REMOTE_WAKEUP_ENABLED))
715
+ {
716
+ // This short version will only work, when the device has not been suspended. Currently the
717
+ // Arduino core doesn't handle SUSPEND at all, so this is ok.
718
+ UDCON |= (1 << RMWKUP); // send the wakeup request
719
+ return true ;
720
+ }
721
+
722
+ return false ;
723
+ }
724
+
684
725
#endif /* if defined(USBCON) */
0 commit comments