Wakeup for USB host. First clean version

pull/18/head
Michael Dreher 12 years ago committed by Jesse Vincent
parent eb20e9febb
commit 665692b914

@ -18,6 +18,7 @@ public:
void attach(); void attach();
void detach(); // Serial port goes down too... void detach(); // Serial port goes down too...
void poll(); void poll();
bool wakeupHost(); // returns false, when wakeup cannot be processed
}; };
extern USBDevice_ USBDevice; extern USBDevice_ USBDevice;

@ -92,6 +92,7 @@ const DeviceDescriptor USB_DeviceDescriptorA =
//================================================================== //==================================================================
volatile u8 _usbConfiguration = 0; volatile u8 _usbConfiguration = 0;
volatile u8 _usbCurrentStatus = 0; // meaning of bits see usb_20.pdf, Figure 9-4. Information Returned by a GetStatus() Request to a Device
static inline void WaitIN(void) static inline void WaitIN(void)
{ {
@ -527,16 +528,37 @@ ISR(USB_COM_vect)
{ {
// Standard Requests // Standard Requests
u8 r = setup.bRequest; u8 r = setup.bRequest;
u16 wValue = setup.wValueL | (setup.wValueH << 8);
if (GET_STATUS == r) if (GET_STATUS == r)
{ {
Send8(0); // TODO if(requestType == (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_DEVICE))
Send8(0); {
Send8(_usbCurrentStatus);
Send8(0);
}
else
{
// TODO: handle the HALT state of an endpoint here
// see "Figure 9-6. Information Returned by a GetStatus() Request to an Endpoint" in usb_20.pdf for more information
Send8(0);
Send8(0);
}
} }
else if (CLEAR_FEATURE == r) else if (CLEAR_FEATURE == r)
{ {
if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
&& (wValue == DEVICE_REMOTE_WAKEUP))
{
_usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED;
}
} }
else if (SET_FEATURE == r) else if (SET_FEATURE == r)
{ {
if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
&& (wValue == DEVICE_REMOTE_WAKEUP))
{
_usbCurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
}
} }
else if (SET_ADDRESS == r) else if (SET_ADDRESS == r)
{ {
@ -644,6 +666,7 @@ USBDevice_::USBDevice_()
void USBDevice_::attach() void USBDevice_::attach()
{ {
_usbConfiguration = 0; _usbConfiguration = 0;
_usbCurrentStatus = 0;
UHWCON = 0x01; // power internal reg UHWCON = 0x01; // power internal reg
USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled
#if F_CPU == 16000000UL #if F_CPU == 16000000UL
@ -681,4 +704,22 @@ void USBDevice_::poll()
{ {
} }
bool USBDevice_::wakeupHost()
{
// clear any previous wakeup request which might have been set but could be processed at that time
// e.g. because the host was not suspended at that time
UDCON &= ~(1 << RMWKUP);
if(!(UDCON & (1 << RMWKUP)) && (_usbCurrentStatus & FEATURE_REMOTE_WAKEUP_ENABLED))
{
// This short version will only work, when the device has not been suspended. Currently the
// Arduino core doesn't handle SUSPEND at all, so this is ok.
UDCON |= (1 << RMWKUP); // send the wakeup request
return true;
}
return false;
}
#endif /* if defined(USBCON) */ #endif /* if defined(USBCON) */

@ -79,6 +79,15 @@
#define USB_INTERFACE_DESCRIPTOR_TYPE 4 #define USB_INTERFACE_DESCRIPTOR_TYPE 4
#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 #define USB_ENDPOINT_DESCRIPTOR_TYPE 5
// usb_20.pdf Table 9.6 Standard Feature Selectors
#define DEVICE_REMOTE_WAKEUP 1
#define ENDPOINT_HALT 2
#define TEST_MODE 3
// usb_20.pdf Figure 9-4. Information Returned by a GetStatus() Request to a Device
#define FEATURE_SELFPOWERED_ENABLED (1 << 0)
#define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1)
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 #define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
#define USB_DEVICE_CLASS_STORAGE 0x08 #define USB_DEVICE_CLASS_STORAGE 0x08
@ -282,7 +291,7 @@ typedef struct
{ 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
#define D_CONFIG(_totalLength,_interfaces) \ #define D_CONFIG(_totalLength,_interfaces) \
{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) } { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, USB_CONFIG_POWER_MA(500) }
#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }

Loading…
Cancel
Save