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();