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
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 uint8_t PrevPipe
= Pipe_GetCurrentPipe();
91 Pipe_SelectPipe(PIPE_CONTROLPIPE
);
93 switch (USB_HostState
)
95 case HOST_STATE_WaitForDevice
:
98 if ((SubErrorCode
= USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful
)
100 USB_HostState
= PostWaitState
;
101 ErrorCode
= HOST_ENUMERROR_WaitStage
;
109 USB_HostState
= PostWaitState
;
113 case HOST_STATE_Attached
:
114 WaitMSRemaining
= HOST_DEVICE_SETTLE_DELAY_MS
;
116 USB_HostState
= HOST_STATE_Attached_WaitForDeviceSettle
;
118 case HOST_STATE_Attached_WaitForDeviceSettle
:
121 if (!(WaitMSRemaining
--))
123 USB_Host_VBUS_Manual_Off();
126 USB_Host_VBUS_Auto_Enable();
127 USB_Host_VBUS_Auto_On();
129 USB_HostState
= HOST_STATE_Attached_WaitForConnect
;
133 case HOST_STATE_Attached_WaitForConnect
:
134 if (USB_INT_HasOccurred(USB_INT_DCONNI
))
136 USB_INT_Clear(USB_INT_DCONNI
);
137 USB_INT_Clear(USB_INT_DDISCI
);
139 USB_INT_Clear(USB_INT_VBERRI
);
140 USB_INT_Enable(USB_INT_VBERRI
);
142 USB_IsConnected
= true;
143 RAISE_EVENT(USB_Connect
);
145 USB_Host_ResumeBus();
148 HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Attached_DoReset
);
152 case HOST_STATE_Attached_DoReset
:
153 USB_Host_ResetDevice();
155 HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered
);
157 case HOST_STATE_Powered
:
158 Pipe_ConfigurePipe(PIPE_CONTROLPIPE
, EP_TYPE_CONTROL
,
159 PIPE_TOKEN_SETUP
, PIPE_CONTROLPIPE
,
160 PIPE_CONTROLPIPE_DEFAULT_SIZE
, PIPE_BANK_SINGLE
);
162 if (!(Pipe_IsConfigured()))
164 ErrorCode
= HOST_ENUMERROR_PipeConfigError
;
169 USB_HostState
= HOST_STATE_Default
;
171 case HOST_STATE_Default
:
172 USB_HostRequest
= (USB_Host_Request_Header_t
)
174 bmRequestType
: (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_DEVICE
),
175 bRequest
: REQ_GetDescriptor
,
176 wValue
: (DTYPE_Device
<< 8),
178 wLength
: PIPE_CONTROLPIPE_DEFAULT_SIZE
,
181 uint8_t DataBuffer
[PIPE_CONTROLPIPE_DEFAULT_SIZE
];
183 if ((SubErrorCode
= USB_Host_SendControlRequest(DataBuffer
)) != HOST_SENDCONTROL_Successful
)
185 ErrorCode
= HOST_ENUMERROR_ControlError
;
189 #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
190 USB_ControlPipeSize
= DataBuffer
[offsetof(USB_Descriptor_Device_t
, Endpoint0Size
)];
192 USB_ControlPipeSize
= DataBuffer
[offsetof(USB_Descriptor_Device_t
, bMaxPacketSize0
)];
195 USB_Host_ResetDevice();
197 HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset
);
199 case HOST_STATE_Default_PostReset
:
201 Pipe_DeallocateMemory();
202 Pipe_ResetPipe(PIPE_CONTROLPIPE
);
204 Pipe_ConfigurePipe(PIPE_CONTROLPIPE
, EP_TYPE_CONTROL
,
205 PIPE_TOKEN_SETUP
, PIPE_CONTROLPIPE
,
206 USB_ControlPipeSize
, PIPE_BANK_SINGLE
);
208 if (!(Pipe_IsConfigured()))
210 ErrorCode
= HOST_ENUMERROR_PipeConfigError
;
215 Pipe_SetInfiniteINRequests();
217 USB_HostRequest
= (USB_Host_Request_Header_t
)
219 bmRequestType
: (REQDIR_HOSTTODEVICE
| REQTYPE_STANDARD
| REQREC_DEVICE
),
220 bRequest
: REQ_SetAddress
,
221 wValue
: USB_HOST_DEVICEADDRESS
,
226 if ((SubErrorCode
= USB_Host_SendControlRequest(NULL
)) != HOST_SENDCONTROL_Successful
)
228 ErrorCode
= HOST_ENUMERROR_ControlError
;
232 HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet
);
234 case HOST_STATE_Default_PostAddressSet
:
235 USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS
);
237 RAISE_EVENT(USB_DeviceEnumerationComplete
);
238 USB_HostState
= HOST_STATE_Addressed
;
243 if ((ErrorCode
!= HOST_ENUMERROR_NoError
) && (USB_HostState
!= HOST_STATE_Unattached
))
245 RAISE_EVENT(USB_DeviceEnumerationFailed
, ErrorCode
, SubErrorCode
);
247 USB_Host_VBUS_Auto_Off();
249 RAISE_EVENT(USB_DeviceUnattached
);
252 RAISE_EVENT(USB_Disconnect
);
254 USB_ResetInterface();
257 Pipe_SelectPipe(PrevPipe
);