3      Copyright (C) Dean Camera, 2009. 
   5   dean [at] fourwalledcubicle [dot] com 
   6       www.fourwalledcubicle.com 
  10   Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, and distribute this software 
  13   and its documentation for any purpose and without fee is hereby 
  14   granted, provided that the above copyright notice appear in all 
  15   copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting 
  17   documentation, and that the name of the author not be used in 
  18   advertising or publicity pertaining to distribution of the 
  19   software without specific, written prior permission. 
  21   The author disclaim all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #include "../LowLevel/USBMode.h" 
  33 #define  INCLUDE_FROM_USBTASK_C 
  36 volatile bool      USB_IsSuspended
; 
  37 volatile bool      USB_IsConnected
; 
  38 volatile bool      USB_IsInitialized
; 
  40 #if defined(USB_CAN_BE_HOST) 
  41 volatile uint8_t   USB_HostState
; 
  46         #if defined(USB_HOST_ONLY) 
  48         #elif defined(USB_DEVICE_ONLY) 
  51                 if (USB_CurrentMode 
== USB_MODE_DEVICE
) 
  53                 else if (USB_CurrentMode 
== USB_MODE_HOST
) 
  58 #if defined(USB_CAN_BE_DEVICE) 
  59 static void USB_DeviceTask(void) 
  63                 uint8_t PrevEndpoint 
= Endpoint_GetCurrentEndpoint(); 
  65                 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
); 
  67                 if (Endpoint_IsSetupReceived()) 
  69                         ATOMIC_BLOCK(ATOMIC_RESTORESTATE
) 
  71                                 USB_Device_ProcessControlPacket(); 
  75                 Endpoint_SelectEndpoint(PrevEndpoint
); 
  80 #if defined(USB_CAN_BE_HOST) 
  81 static void USB_HostTask(void) 
  83         uint8_t ErrorCode    
= HOST_ENUMERROR_NoError
; 
  84         uint8_t SubErrorCode 
= HOST_ENUMERROR_NoError
; 
  86         static uint16_t WaitMSRemaining
; 
  87         static uint8_t  PostWaitState
; 
  89         switch (USB_HostState
) 
  91                 case HOST_STATE_WaitForDevice
: 
  94                                 if ((SubErrorCode 
= USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful
) 
  96                                         USB_HostState 
= PostWaitState
; 
  97                                         ErrorCode     
= HOST_ENUMERROR_WaitStage
; 
 105                                 USB_HostState 
= PostWaitState
; 
 109                 case HOST_STATE_Attached
: 
 110                         WaitMSRemaining 
= HOST_DEVICE_SETTLE_DELAY_MS
; 
 112                         USB_HostState 
= HOST_STATE_Attached_WaitForDeviceSettle
; 
 114                 case HOST_STATE_Attached_WaitForDeviceSettle
: 
 117                         if (!(WaitMSRemaining
--)) 
 119                                 USB_Host_VBUS_Manual_Off(); 
 122                                 USB_Host_VBUS_Auto_Enable(); 
 123                                 USB_Host_VBUS_Auto_On(); 
 125                                 USB_HostState 
= HOST_STATE_Attached_WaitForConnect
; 
 129                 case HOST_STATE_Attached_WaitForConnect
:                 
 130                         if (USB_INT_HasOccurred(USB_INT_DCONNI
)) 
 132                                 USB_INT_Clear(USB_INT_DCONNI
); 
 133                                 USB_INT_Clear(USB_INT_DDISCI
); 
 135                                 USB_INT_Clear(USB_INT_VBERRI
); 
 136                                 USB_INT_Enable(USB_INT_VBERRI
); 
 138                                 USB_IsConnected 
= true; 
 139                                 RAISE_EVENT(USB_Connect
); 
 141                                 USB_Host_ResumeBus(); 
 144                                 HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Attached_DoReset
); 
 148                 case HOST_STATE_Attached_DoReset
: 
 149                         USB_Host_ResetDevice(); 
 151                         HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered
); 
 153                 case HOST_STATE_Powered
: 
 154                         Pipe_ConfigurePipe(PIPE_CONTROLPIPE
, EP_TYPE_CONTROL
, 
 155                                                            PIPE_TOKEN_SETUP
, PIPE_CONTROLPIPE
, 
 156                                                            PIPE_CONTROLPIPE_DEFAULT_SIZE
, PIPE_BANK_SINGLE
);             
 158                         if (!(Pipe_IsConfigured())) 
 160                                 ErrorCode    
= HOST_ENUMERROR_PipeConfigError
; 
 165                         USB_HostState 
= HOST_STATE_Default
; 
 167                 case HOST_STATE_Default
: 
 168                         USB_HostRequest 
= (USB_Host_Request_Header_t
) 
 170                                         bmRequestType
: (REQDIR_DEVICETOHOST 
| REQTYPE_STANDARD 
| REQREC_DEVICE
), 
 171                                         bRequest
:      REQ_GetDescriptor
, 
 172                                         wValue
:        (DTYPE_Device 
<< 8), 
 174                                         wLength
:       PIPE_CONTROLPIPE_DEFAULT_SIZE
, 
 177                         uint8_t DataBuffer
[PIPE_CONTROLPIPE_DEFAULT_SIZE
]; 
 179                         if ((SubErrorCode 
= USB_Host_SendControlRequest(DataBuffer
)) != HOST_SENDCONTROL_Successful
) 
 181                                 ErrorCode 
= HOST_ENUMERROR_ControlError
; 
 185                         #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) 
 186                         USB_ControlPipeSize 
= DataBuffer
[offsetof(USB_Descriptor_Device_t
, Endpoint0Size
)]; 
 188                         USB_ControlPipeSize 
= DataBuffer
[offsetof(USB_Descriptor_Device_t
, bMaxPacketSize0
)];                    
 191                         USB_Host_ResetDevice(); 
 193                         HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset
); 
 195                 case HOST_STATE_Default_PostReset
: 
 197                         Pipe_DeallocateMemory();                 
 198                         Pipe_ResetPipe(PIPE_CONTROLPIPE
); 
 200                         Pipe_ConfigurePipe(PIPE_CONTROLPIPE
, EP_TYPE_CONTROL
, 
 201                                            PIPE_TOKEN_SETUP
, PIPE_CONTROLPIPE
, 
 202                                            USB_ControlPipeSize
, PIPE_BANK_SINGLE
); 
 204                         if (!(Pipe_IsConfigured())) 
 206                                 ErrorCode    
= HOST_ENUMERROR_PipeConfigError
; 
 211                         Pipe_SetInfiniteINRequests(); 
 213                         USB_HostRequest 
= (USB_Host_Request_Header_t
) 
 215                                         bmRequestType
: (REQDIR_HOSTTODEVICE 
| REQTYPE_STANDARD 
| REQREC_DEVICE
), 
 216                                         bRequest
:      REQ_SetAddress
, 
 217                                         wValue
:        USB_HOST_DEVICEADDRESS
, 
 222                         if ((SubErrorCode 
= USB_Host_SendControlRequest(NULL
)) != HOST_SENDCONTROL_Successful
) 
 224                                 ErrorCode 
= HOST_ENUMERROR_ControlError
; 
 228                         HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet
); 
 230                 case HOST_STATE_Default_PostAddressSet
: 
 231                         USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS
); 
 233                         RAISE_EVENT(USB_DeviceEnumerationComplete
); 
 234                         USB_HostState 
= HOST_STATE_Addressed
; 
 239         if ((ErrorCode 
!= HOST_ENUMERROR_NoError
) && (USB_HostState 
!= HOST_STATE_Unattached
)) 
 241                 RAISE_EVENT(USB_DeviceEnumerationFailed
, ErrorCode
, SubErrorCode
); 
 243                 USB_Host_VBUS_Auto_Off(); 
 245                 RAISE_EVENT(USB_DeviceUnattached
); 
 248                   RAISE_EVENT(USB_Disconnect
); 
 250                 USB_ResetInterface();