Skip to content

Commit 966748f

Browse files
committed
Wakeup for USB host. First clean version
1 parent fc8103c commit 966748f

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

hardware/arduino/cores/arduino/USBAPI.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class USBDevice_
1818
void attach();
1919
void detach(); // Serial port goes down too...
2020
void poll();
21+
bool wakeupHost(); // returns false, when wakeup cannot be processed
2122
};
2223
extern USBDevice_ USBDevice;
2324

hardware/arduino/cores/arduino/USBCore.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ const DeviceDescriptor USB_DeviceDescriptorA =
9292
//==================================================================
9393

9494
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
9596

9697
static inline void WaitIN(void)
9798
{
@@ -527,16 +528,37 @@ ISR(USB_COM_vect)
527528
{
528529
// Standard Requests
529530
u8 r = setup.bRequest;
531+
u16 wValue = setup.wValueL | (setup.wValueH << 8);
530532
if (GET_STATUS == r)
531533
{
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+
}
534546
}
535547
else if (CLEAR_FEATURE == r)
536548
{
549+
if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
550+
&& (wValue == DEVICE_REMOTE_WAKEUP))
551+
{
552+
_usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED;
553+
}
537554
}
538555
else if (SET_FEATURE == r)
539556
{
557+
if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
558+
&& (wValue == DEVICE_REMOTE_WAKEUP))
559+
{
560+
_usbCurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
561+
}
540562
}
541563
else if (SET_ADDRESS == r)
542564
{
@@ -644,6 +666,7 @@ USBDevice_::USBDevice_()
644666
void USBDevice_::attach()
645667
{
646668
_usbConfiguration = 0;
669+
_usbCurrentStatus = 0;
647670
UHWCON = 0x01; // power internal reg
648671
USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled
649672
#if F_CPU == 16000000UL
@@ -681,4 +704,22 @@ void USBDevice_::poll()
681704
{
682705
}
683706

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+
684725
#endif /* if defined(USBCON) */

hardware/arduino/cores/arduino/USBCore.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@
7979
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
8080
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
8181

82+
// usb_20.pdf Table 9.6 Standard Feature Selectors
83+
#define DEVICE_REMOTE_WAKEUP 1
84+
#define ENDPOINT_HALT 2
85+
#define TEST_MODE 3
86+
87+
// usb_20.pdf Figure 9-4. Information Returned by a GetStatus() Request to a Device
88+
#define FEATURE_SELFPOWERED_ENABLED (1 << 0)
89+
#define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1)
90+
8291
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
8392
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
8493
#define USB_DEVICE_CLASS_STORAGE 0x08
@@ -282,7 +291,7 @@ typedef struct
282291
{ 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
283292

284293
#define D_CONFIG(_totalLength,_interfaces) \
285-
{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) }
294+
{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, USB_CONFIG_POWER_MA(500) }
286295

287296
#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
288297
{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }

0 commit comments

Comments
 (0)