Statistics
| Branch: | Tag: | Revision:

root / LUFA / Drivers / USB / Core / UC3 / Host_UC3.c @ 978b99e5

History | View | Annotate | Download (7.23 KB)

1
/*
2
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7
*/
8

    
9
/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all 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.
20

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
28
  this software.
29
*/
30

    
31
#define  __INCLUDE_FROM_USB_DRIVER
32
#include "../USBMode.h"
33

    
34
#if defined(USB_CAN_BE_HOST)
35

    
36
#define  __INCLUDE_FROM_HOST_C
37
#include "../Host.h"
38

    
39
void USB_Host_ProcessNextHostState(void)
40
{
41
        uint8_t ErrorCode    = HOST_ENUMERROR_NoError;
42
        uint8_t SubErrorCode = HOST_ENUMERROR_NoError;
43

    
44
        static uint16_t WaitMSRemaining;
45
        static uint8_t  PostWaitState;
46

    
47
        switch (USB_HostState)
48
        {
49
                case HOST_STATE_WaitForDevice:
50
                        if (WaitMSRemaining)
51
                        {
52
                                if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
53
                                {
54
                                        USB_HostState = PostWaitState;
55
                                        ErrorCode     = HOST_ENUMERROR_WaitStage;
56
                                        break;
57
                                }
58

    
59
                                if (!(--WaitMSRemaining))
60
                                  USB_HostState = PostWaitState;
61
                        }
62

    
63
                        break;
64
                case HOST_STATE_Powered:
65
                        WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS;
66

    
67
                        USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle;
68
                        break;
69
                case HOST_STATE_Powered_WaitForDeviceSettle:
70
                        if (WaitMSRemaining--)
71
                        {
72
                                Delay_MS(1);
73
                                break;
74
                        }
75
                        else
76
                        {
77
                                USB_Host_VBUS_Manual_Off();
78

    
79
                                USB_OTGPAD_On();
80
                                USB_Host_VBUS_Auto_Enable();
81
                                USB_Host_VBUS_Auto_On();
82

    
83
                                USB_HostState = HOST_STATE_Powered_WaitForConnect;
84
                        }
85

    
86
                        break;
87
                case HOST_STATE_Powered_WaitForConnect:
88
                        if (USB_INT_HasOccurred(USB_INT_DCONNI))
89
                        {
90
                                USB_INT_Clear(USB_INT_DCONNI);
91
                                USB_INT_Clear(USB_INT_DDISCI);
92

    
93
                                USB_INT_Clear(USB_INT_VBERRI);
94
                                USB_INT_Enable(USB_INT_VBERRI);
95

    
96
                                USB_Host_ResumeBus();
97
                                Pipe_ClearPipes();
98

    
99
                                HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset);
100
                        }
101

    
102
                        break;
103
                case HOST_STATE_Powered_DoReset:
104
                        USB_Host_ResetDevice();
105

    
106
                        HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe);
107
                        break;
108
                case HOST_STATE_Powered_ConfigPipe:
109
                        Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
110
                                                           PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
111
                                                           PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE);
112

    
113
                        if (!(Pipe_IsConfigured()))
114
                        {
115
                                ErrorCode    = HOST_ENUMERROR_PipeConfigError;
116
                                SubErrorCode = 0;
117
                                break;
118
                        }
119

    
120
                        USB_HostState = HOST_STATE_Default;
121
                        break;
122
                case HOST_STATE_Default:
123
                        USB_ControlRequest = (USB_Request_Header_t)
124
                                {
125
                                        .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
126
                                        .bRequest      = REQ_GetDescriptor,
127
                                        .wValue        = (DTYPE_Device << 8),
128
                                        .wIndex        = 0,
129
                                        .wLength       = 8,
130
                                };
131

    
132
                        uint8_t DataBuffer[8];
133

    
134
                        if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful)
135
                        {
136
                                ErrorCode = HOST_ENUMERROR_ControlError;
137
                                break;
138
                        }
139

    
140
                        USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
141

    
142
                        USB_Host_ResetDevice();
143

    
144
                        HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset);
145
                        break;
146
                case HOST_STATE_Default_PostReset:
147
                        Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
148
                                           PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
149
                                           USB_Host_ControlPipeSize, PIPE_BANK_SINGLE);
150

    
151
                        if (!(Pipe_IsConfigured()))
152
                        {
153
                                ErrorCode    = HOST_ENUMERROR_PipeConfigError;
154
                                SubErrorCode = 0;
155
                                break;
156
                        }
157

    
158
                        USB_ControlRequest = (USB_Request_Header_t)
159
                                {
160
                                        .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
161
                                        .bRequest      = REQ_SetAddress,
162
                                        .wValue        = USB_HOST_DEVICEADDRESS,
163
                                        .wIndex        = 0,
164
                                        .wLength       = 0,
165
                                };
166

    
167
                        if ((SubErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
168
                        {
169
                                ErrorCode = HOST_ENUMERROR_ControlError;
170
                                break;
171
                        }
172

    
173
                        HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet);
174
                        break;
175
                case HOST_STATE_Default_PostAddressSet:
176
                        USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);
177

    
178
                        USB_HostState = HOST_STATE_Addressed;
179

    
180
                        EVENT_USB_Host_DeviceEnumerationComplete();
181
                        break;
182
        }
183

    
184
        if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached))
185
        {
186
                EVENT_USB_Host_DeviceEnumerationFailed(ErrorCode, SubErrorCode);
187

    
188
                USB_Host_VBUS_Auto_Off();
189

    
190
                EVENT_USB_Host_DeviceUnattached();
191

    
192
                USB_ResetInterface();
193
        }
194
}
195

    
196
uint8_t USB_Host_WaitMS(uint8_t MS)
197
{
198
        bool    BusSuspended = USB_Host_IsBusSuspended();
199
        uint8_t ErrorCode    = HOST_WAITERROR_Successful;
200
        bool    HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
201

    
202
        USB_INT_Disable(USB_INT_HSOFI);
203
        USB_INT_Clear(USB_INT_HSOFI);
204

    
205
        USB_Host_ResumeBus();
206

    
207
        while (MS)
208
        {
209
                if (USB_INT_HasOccurred(USB_INT_HSOFI))
210
                {
211
                        USB_INT_Clear(USB_INT_HSOFI);
212
                        MS--;
213
                }
214

    
215
                if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode != USB_MODE_Host))
216
                {
217
                        ErrorCode = HOST_WAITERROR_DeviceDisconnect;
218

    
219
                        break;
220
                }
221

    
222
                if (Pipe_IsError() == true)
223
                {
224
                        Pipe_ClearError();
225
                        ErrorCode = HOST_WAITERROR_PipeError;
226

    
227
                        break;
228
                }
229

    
230
                if (Pipe_IsStalled() == true)
231
                {
232
                        Pipe_ClearStall();
233
                        ErrorCode = HOST_WAITERROR_SetupStalled;
234

    
235
                        break;
236
                }
237
        }
238

    
239
        if (BusSuspended)
240
          USB_Host_SuspendBus();
241

    
242
        if (HSOFIEnabled)
243
          USB_INT_Enable(USB_INT_HSOFI);
244

    
245
        return ErrorCode;
246
}
247

    
248
static void USB_Host_ResetDevice(void)
249
{
250
        bool BusSuspended = USB_Host_IsBusSuspended();
251

    
252
        USB_INT_Disable(USB_INT_DDISCI);
253

    
254
        USB_Host_ResetBus();
255
        while (!(USB_Host_IsBusResetComplete()));
256
        USB_Host_ResumeBus();
257
        
258
        USB_Host_ConfigurationNumber = 0;
259

    
260
        bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
261

    
262
        USB_INT_Disable(USB_INT_HSOFI);
263
        USB_INT_Clear(USB_INT_HSOFI);
264

    
265
        for (uint8_t MSRem = 10; MSRem != 0; MSRem--)
266
        {
267
                /* Workaround for powerless-pull-up devices. After a USB bus reset,
268
                   all disconnection interrupts are suppressed while a USB frame is
269
                   looked for - if it is found within 10ms, the device is still
270
                   present.                                                        */
271

    
272
                if (USB_INT_HasOccurred(USB_INT_HSOFI))
273
                {
274
                        USB_INT_Clear(USB_INT_HSOFI);
275
                        USB_INT_Clear(USB_INT_DDISCI);
276
                        break;
277
                }
278

    
279
                Delay_MS(1);
280
        }
281

    
282
        if (HSOFIEnabled)
283
          USB_INT_Enable(USB_INT_HSOFI);
284

    
285
        if (BusSuspended)
286
          USB_Host_SuspendBus();
287

    
288
        USB_INT_Enable(USB_INT_DDISCI);
289
}
290

    
291
#endif
292