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 detach(); // Serial port goes down too...
void poll();
bool wakeupHost(); // returns false, when wakeup cannot be processed
};
extern USBDevice_ USBDevice;

@ -92,6 +92,7 @@ const DeviceDescriptor USB_DeviceDescriptorA =
//==================================================================
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)
{
@ -527,16 +528,37 @@ ISR(USB_COM_vect)
{
// Standard Requests
u8 r = setup.bRequest;
u16 wValue = setup.wValueL | (setup.wValueH << 8);
if (GET_STATUS == r)
{
Send8(0); // TODO
Send8(0);
if(requestType == (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_DEVICE))
{
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)
{
if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
&& (wValue == DEVICE_REMOTE_WAKEUP))
{
_usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED;
}
}
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)
{
@ -644,6 +666,7 @@ USBDevice_::USBDevice_()
void USBDevice_::attach()
{
_usbConfiguration = 0;
_usbCurrentStatus = 0;
UHWCON = 0x01; // power internal reg
USBCON = (1<<USBE)|(1<<FRZCLK); // clock frozen, usb enabled
#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) */

@ -79,6 +79,15 @@
#define USB_INTERFACE_DESCRIPTOR_TYPE 4
#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_HUMAN_INTERFACE 0x03
#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 }
#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) \
{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }

Loading…
Cancel
Save