aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Drivers/USB/LowLevel/Host.c
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-05-13 14:13:57 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-05-13 14:13:57 +0000
commit4904b10ef689a11b420c0a32da747533f4378712 (patch)
tree23dc4404afedee73a51d4c53791e199e4d785d01 /LUFA/Drivers/USB/LowLevel/Host.c
parentda007db18d255d907938e6759735d75287b4862a (diff)
downloadlufa-4904b10ef689a11b420c0a32da747533f4378712.tar.gz
lufa-4904b10ef689a11b420c0a32da747533f4378712.tar.bz2
lufa-4904b10ef689a11b420c0a32da747533f4378712.zip
Moved USB Host state machine code out from USBTask.c and into Host.c, where it more properly belongs.
Diffstat (limited to 'LUFA/Drivers/USB/LowLevel/Host.c')
-rw-r--r--LUFA/Drivers/USB/LowLevel/Host.c173
1 files changed, 172 insertions, 1 deletions
diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c
index fe02f7cd1..9630b6aa1 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.c
+++ b/LUFA/Drivers/USB/LowLevel/Host.c
@@ -32,8 +32,179 @@
#if defined(USB_CAN_BE_HOST)
+#define INCLUDE_FROM_HOST_C
#include "Host.h"
+void USB_Host_ProcessNextHostState(void)
+{
+ uint8_t ErrorCode = HOST_ENUMERROR_NoError;
+ uint8_t SubErrorCode = HOST_ENUMERROR_NoError;
+
+ static uint16_t WaitMSRemaining;
+ static uint8_t PostWaitState;
+
+ switch (USB_HostState)
+ {
+ case HOST_STATE_WaitForDevice:
+ if (WaitMSRemaining)
+ {
+ if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
+ {
+ USB_HostState = PostWaitState;
+ ErrorCode = HOST_ENUMERROR_WaitStage;
+ break;
+ }
+
+ if (!(WaitMSRemaining--))
+ USB_HostState = PostWaitState;
+ }
+
+ break;
+ case HOST_STATE_Attached:
+ WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS;
+
+ USB_HostState = HOST_STATE_Attached_WaitForDeviceSettle;
+ break;
+ case HOST_STATE_Attached_WaitForDeviceSettle:
+ _delay_ms(1);
+
+ if (!(WaitMSRemaining--))
+ {
+ USB_Host_VBUS_Manual_Off();
+
+ USB_OTGPAD_On();
+ USB_Host_VBUS_Auto_Enable();
+ USB_Host_VBUS_Auto_On();
+
+ USB_HostState = HOST_STATE_Attached_WaitForConnect;
+ }
+
+ break;
+ case HOST_STATE_Attached_WaitForConnect:
+ if (USB_INT_HasOccurred(USB_INT_DCONNI))
+ {
+ USB_INT_Clear(USB_INT_DCONNI);
+ USB_INT_Clear(USB_INT_DDISCI);
+
+ USB_INT_Clear(USB_INT_VBERRI);
+ USB_INT_Enable(USB_INT_VBERRI);
+
+ USB_IsConnected = true;
+ RAISE_EVENT(USB_Connect);
+
+ USB_Host_ResumeBus();
+ Pipe_ClearPipes();
+
+ HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Attached_DoReset);
+ }
+
+ break;
+ case HOST_STATE_Attached_DoReset:
+ USB_Host_ResetDevice();
+
+ HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered);
+ break;
+ case HOST_STATE_Powered:
+ Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
+ PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
+ PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE);
+
+ if (!(Pipe_IsConfigured()))
+ {
+ ErrorCode = HOST_ENUMERROR_PipeConfigError;
+ SubErrorCode = 0;
+ break;
+ }
+
+ USB_HostState = HOST_STATE_Default;
+ break;
+ case HOST_STATE_Default:
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
+ .bRequest = REQ_GetDescriptor,
+ .wValue = (DTYPE_Device << 8),
+ .wIndex = 0,
+ .wLength = 8,
+ };
+
+ uint8_t DataBuffer[8];
+
+ if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful)
+ {
+ ErrorCode = HOST_ENUMERROR_ControlError;
+ break;
+ }
+
+ #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
+ USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
+ #else
+ USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, bMaxPacketSize0)];
+ #endif
+
+ USB_Host_ResetDevice();
+
+ HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset);
+ break;
+ case HOST_STATE_Default_PostReset:
+ Pipe_DisablePipe();
+ Pipe_DeallocateMemory();
+ Pipe_ResetPipe(PIPE_CONTROLPIPE);
+
+ Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
+ PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
+ USB_ControlPipeSize, PIPE_BANK_SINGLE);
+
+ if (!(Pipe_IsConfigured()))
+ {
+ ErrorCode = HOST_ENUMERROR_PipeConfigError;
+ SubErrorCode = 0;
+ break;
+ }
+
+ Pipe_SetInfiniteINRequests();
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
+ .bRequest = REQ_SetAddress,
+ .wValue = USB_HOST_DEVICEADDRESS,
+ .wIndex = 0,
+ .wLength = 0,
+ };
+
+ if ((SubErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+ {
+ ErrorCode = HOST_ENUMERROR_ControlError;
+ break;
+ }
+
+ HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet);
+ break;
+ case HOST_STATE_Default_PostAddressSet:
+ USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);
+
+ RAISE_EVENT(USB_DeviceEnumerationComplete);
+ USB_HostState = HOST_STATE_Addressed;
+
+ break;
+ }
+
+ if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached))
+ {
+ RAISE_EVENT(USB_DeviceEnumerationFailed, ErrorCode, SubErrorCode);
+
+ USB_Host_VBUS_Auto_Off();
+
+ RAISE_EVENT(USB_DeviceUnattached);
+
+ if (USB_IsConnected)
+ RAISE_EVENT(USB_Disconnect);
+
+ USB_ResetInterface();
+ }
+}
+
uint8_t USB_Host_WaitMS(uint8_t MS)
{
bool BusSuspended = USB_Host_IsBusSuspended();
@@ -80,7 +251,7 @@ uint8_t USB_Host_WaitMS(uint8_t MS)
return ErrorCode;
}
-void USB_Host_ResetDevice(void)
+static void USB_Host_ResetDevice(void)
{
bool BusSuspended = USB_Host_IsBusSuspended();