Statistics
| Branch: | Tag: | Revision:

root / LUFA / Drivers / USB / Core / HostStandardReq.c @ 978b99e5

History | View | Annotate | Download (8.17 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_HOSTSTDREQ_C
37
#include "HostStandardReq.h"
38

    
39
uint8_t USB_Host_ConfigurationNumber;
40

    
41
uint8_t USB_Host_SendControlRequest(void* const BufferPtr)
42
{
43
        uint8_t* DataStream   = (uint8_t*)BufferPtr;
44
        bool     BusSuspended = USB_Host_IsBusSuspended();
45
        uint8_t  ReturnStatus = HOST_SENDCONTROL_Successful;
46
        uint16_t DataLen      = USB_ControlRequest.wLength;
47

    
48
        USB_Host_ResumeBus();
49

    
50
        if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
51
          goto End_Of_Control_Send;
52

    
53
        Pipe_SetPipeToken(PIPE_TOKEN_SETUP);
54
        Pipe_ClearError();
55

    
56
        Pipe_Unfreeze();
57

    
58
        #if defined(ARCH_BIG_ENDIAN)
59
        Pipe_Write_8(USB_ControlRequest.bmRequestType);
60
        Pipe_Write_8(USB_ControlRequest.bRequest);
61
        Pipe_Write_16_LE(USB_ControlRequest.wValue);
62
        Pipe_Write_16_LE(USB_ControlRequest.wIndex);
63
        Pipe_Write_16_LE(USB_ControlRequest.wLength);
64
        #else
65
        uint8_t* HeaderStream = (uint8_t*)&USB_ControlRequest;
66

    
67
        for (uint8_t HeaderByte = 0; HeaderByte < sizeof(USB_Request_Header_t); HeaderByte++)
68
          Pipe_Write_8(*(HeaderStream++));        
69
        #endif
70
        
71
        Pipe_ClearSETUP();
72

    
73
        if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_SetupSent)) != HOST_SENDCONTROL_Successful)
74
          goto End_Of_Control_Send;
75

    
76
        Pipe_Freeze();
77

    
78
        if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
79
          goto End_Of_Control_Send;
80

    
81
        if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST)
82
        {
83
                Pipe_SetPipeToken(PIPE_TOKEN_IN);
84

    
85
                if (DataStream != NULL)
86
                {
87
                        while (DataLen)
88
                        {
89
                                Pipe_Unfreeze();
90

    
91
                                if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful)
92
                                  goto End_Of_Control_Send;
93

    
94
                                if (!(Pipe_BytesInPipe()))
95
                                  DataLen = 0;
96

    
97
                                while (Pipe_BytesInPipe() && DataLen)
98
                                {
99
                                        *(DataStream++) = Pipe_Read_8();
100
                                        DataLen--;
101
                                }
102

    
103
                                Pipe_Freeze();
104
                                Pipe_ClearIN();
105
                        }
106
                }
107

    
108
                Pipe_SetPipeToken(PIPE_TOKEN_OUT);
109
                Pipe_Unfreeze();
110

    
111
                if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
112
                  goto End_Of_Control_Send;
113

    
114
                Pipe_ClearOUT();
115

    
116
                if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
117
                  goto End_Of_Control_Send;
118
        }
119
        else
120
        {
121
                if (DataStream != NULL)
122
                {
123
                        Pipe_SetPipeToken(PIPE_TOKEN_OUT);
124
                        Pipe_Unfreeze();
125

    
126
                        while (DataLen)
127
                        {
128
                                if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
129
                                  goto End_Of_Control_Send;
130

    
131
                                while (DataLen && (Pipe_BytesInPipe() < USB_Host_ControlPipeSize))
132
                                {
133
                                        Pipe_Write_8(*(DataStream++));
134
                                        DataLen--;
135
                                }
136

    
137
                                Pipe_ClearOUT();
138
                        }
139

    
140
                        if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
141
                          goto End_Of_Control_Send;
142

    
143
                        Pipe_Freeze();
144
                }
145

    
146
                Pipe_SetPipeToken(PIPE_TOKEN_IN);
147
                Pipe_Unfreeze();
148

    
149
                if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful)
150
                  goto End_Of_Control_Send;
151

    
152
                Pipe_ClearIN();
153
        }
154

    
155
End_Of_Control_Send:
156
        Pipe_Freeze();
157

    
158
        if (BusSuspended)
159
          USB_Host_SuspendBus();
160

    
161
        Pipe_ResetPipe(PIPE_CONTROLPIPE);
162

    
163
        return ReturnStatus;
164
}
165

    
166
static uint8_t USB_Host_WaitForIOS(const uint8_t WaitType)
167
{
168
        #if (USB_HOST_TIMEOUT_MS < 0xFF)
169
        uint8_t  TimeoutCounter = USB_HOST_TIMEOUT_MS;
170
        #else
171
        uint16_t TimeoutCounter = USB_HOST_TIMEOUT_MS;
172
        #endif
173

    
174
        while (!(((WaitType == USB_HOST_WAITFOR_SetupSent)  && Pipe_IsSETUPSent())  ||
175
                 ((WaitType == USB_HOST_WAITFOR_InReceived) && Pipe_IsINReceived()) ||
176
                 ((WaitType == USB_HOST_WAITFOR_OutReady)   && Pipe_IsOUTReady())))
177
        {
178
                uint8_t ErrorCode;
179

    
180
                if ((ErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
181
                  return ErrorCode;
182

    
183
                if (!(TimeoutCounter--))
184
                  return HOST_SENDCONTROL_SoftwareTimeOut;
185
        }
186

    
187
        return HOST_SENDCONTROL_Successful;
188
}
189

    
190
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber)
191
{
192
        uint8_t ErrorCode;
193

    
194
        USB_ControlRequest = (USB_Request_Header_t)
195
                {
196
                        .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
197
                        .bRequest      = REQ_SetConfiguration,
198
                        .wValue        = ConfigNumber,
199
                        .wIndex        = 0,
200
                        .wLength       = 0,
201
                };
202

    
203
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
204
        
205
        if ((ErrorCode = USB_Host_SendControlRequest(NULL)) == HOST_SENDCONTROL_Successful)
206
        {
207
                USB_Host_ConfigurationNumber = ConfigNumber;
208
                USB_HostState                = (ConfigNumber) ? HOST_STATE_Configured : HOST_STATE_Addressed;
209
        }
210

    
211
        return ErrorCode;
212
}
213

    
214
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr)
215
{
216
        USB_ControlRequest = (USB_Request_Header_t)
217
                {
218
                        .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
219
                        .bRequest      = REQ_GetDescriptor,
220
                        .wValue        = (DTYPE_Device << 8),
221
                        .wIndex        = 0,
222
                        .wLength       = sizeof(USB_Descriptor_Device_t),
223
                };
224

    
225
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
226

    
227
        return USB_Host_SendControlRequest(DeviceDescriptorPtr);
228
}
229

    
230
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
231
                                           void* const Buffer,
232
                                           const uint8_t BufferLength)
233
{
234
        USB_ControlRequest = (USB_Request_Header_t)
235
                {
236
                        .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
237
                        .bRequest      = REQ_GetDescriptor,
238
                        .wValue        = (DTYPE_String << 8) | Index,
239
                        .wIndex        = 0,
240
                        .wLength       = BufferLength,
241
                };
242

    
243
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
244

    
245
        return USB_Host_SendControlRequest(Buffer);
246
}
247

    
248
uint8_t USB_Host_GetDeviceStatus(uint8_t* const FeatureStatus)
249
{
250
        USB_ControlRequest = (USB_Request_Header_t)
251
                {
252
                        .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
253
                        .bRequest      = REQ_GetStatus,
254
                        .wValue        = 0,
255
                        .wIndex        = 0,
256
                        .wLength       = 0,
257
                };
258

    
259
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
260

    
261
        return USB_Host_SendControlRequest(FeatureStatus);
262
}
263

    
264
uint8_t USB_Host_ClearEndpointStall(const uint8_t EndpointAddress)
265
{
266
        USB_ControlRequest = (USB_Request_Header_t)
267
                {
268
                        .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
269
                        .bRequest      = REQ_ClearFeature,
270
                        .wValue        = FEATURE_SEL_EndpointHalt,
271
                        .wIndex        = EndpointAddress,
272
                        .wLength       = 0,
273
                };
274

    
275
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
276

    
277
        return USB_Host_SendControlRequest(NULL);
278
}
279

    
280
uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
281
                                        const uint8_t AltSetting)
282
{
283
        USB_ControlRequest = (USB_Request_Header_t)
284
                {
285
                        .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
286
                        .bRequest      = REQ_SetInterface,
287
                        .wValue        = AltSetting,
288
                        .wIndex        = InterfaceIndex,
289
                        .wLength       = 0,
290
                };
291

    
292
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
293

    
294
        return USB_Host_SendControlRequest(NULL);
295
}
296

    
297
#endif
298