Fixed MassStorage demo not clearing the reset flag when a Mass Storage Reset is issue...
[pub/USBasp.git] / LUFA / Drivers / USB / LowLevel / Pipe.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2009.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
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.
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 #include "../HighLevel/USBMode.h"
32
33 #if defined(USB_CAN_BE_HOST)
34
35 #define INCLUDE_FROM_PIPE_C
36 #include "Pipe.h"
37
38 uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
39
40 bool Pipe_ConfigurePipe(const uint8_t Number, const uint8_t Type, const uint8_t Token, const uint8_t EndpointNumber,
41 const uint16_t Size, const uint8_t Banks)
42 {
43 Pipe_SelectPipe(Number);
44 Pipe_EnablePipe();
45
46 UPCFG1X = 0;
47
48 UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
49 UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
50
51 Pipe_SetInfiniteINRequests();
52
53 return Pipe_IsConfigured();
54 }
55
56 void Pipe_ClearPipes(void)
57 {
58 UPINT = 0;
59
60 for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
61 {
62 Pipe_ResetPipe(PNum);
63 Pipe_SelectPipe(PNum);
64 UPIENX = 0;
65 UPINTX = 0;
66 Pipe_ClearError();
67 Pipe_ClearErrorFlags();
68 Pipe_DeallocateMemory();
69 Pipe_DisablePipe();
70 }
71 }
72
73 uint8_t Pipe_WaitUntilReady(void)
74 {
75 #if (USB_STREAM_TIMEOUT_MS < 0xFF)
76 uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
77 #else
78 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
79 #endif
80
81 for (;;)
82 {
83 if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)
84 {
85 if (Pipe_IsINReceived())
86 return PIPE_READYWAIT_NoError;
87 }
88 else
89 {
90 if (Pipe_IsOUTReady())
91 return PIPE_READYWAIT_NoError;
92 }
93
94 if (Pipe_IsStalled())
95 return PIPE_READYWAIT_PipeStalled;
96 else if (!(USB_IsConnected))
97 return PIPE_READYWAIT_DeviceDisconnected;
98
99 if (USB_INT_HasOccurred(USB_INT_HSOFI))
100 {
101 USB_INT_Clear(USB_INT_HSOFI);
102
103 if (!(TimeoutMSRem--))
104 return PIPE_READYWAIT_Timeout;
105 }
106 }
107 }
108
109 uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length
110 #if !defined(NO_STREAM_CALLBACKS)
111 , StreamCallbackPtr_t Callback
112 #endif
113 )
114 {
115 uint8_t* DataStream = (uint8_t*)Data;
116 uint8_t ErrorCode;
117
118 Pipe_SetToken(PIPE_TOKEN_OUT);
119
120 if ((ErrorCode = Pipe_WaitUntilReady()))
121 return ErrorCode;
122
123 while (Length)
124 {
125 if (!(Pipe_IsReadWriteAllowed()))
126 {
127 Pipe_ClearOUT();
128
129 #if !defined(NO_STREAM_CALLBACKS)
130 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
131 return PIPE_RWSTREAM_CallbackAborted;
132 #endif
133
134 if ((ErrorCode = Pipe_WaitUntilReady()))
135 return ErrorCode;
136 }
137 else
138 {
139 Pipe_Write_Byte(*(DataStream++));
140 Length--;
141 }
142 }
143
144 return PIPE_RWSTREAM_NoError;
145 }
146
147 uint8_t Pipe_Write_Stream_BE(const void* Data, uint16_t Length
148 #if !defined(NO_STREAM_CALLBACKS)
149 , StreamCallbackPtr_t Callback
150 #endif
151 )
152 {
153 uint8_t* DataStream = (uint8_t*)(Data + Length - 1);
154 uint8_t ErrorCode;
155
156 Pipe_SetToken(PIPE_TOKEN_OUT);
157
158 if ((ErrorCode = Pipe_WaitUntilReady()))
159 return ErrorCode;
160
161 while (Length)
162 {
163 if (!(Pipe_IsReadWriteAllowed()))
164 {
165 Pipe_ClearOUT();
166
167 #if !defined(NO_STREAM_CALLBACKS)
168 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
169 return PIPE_RWSTREAM_CallbackAborted;
170 #endif
171
172 if ((ErrorCode = Pipe_WaitUntilReady()))
173 return ErrorCode;
174 }
175 else
176 {
177 Pipe_Write_Byte(*(DataStream--));
178 Length--;
179 }
180 }
181
182 return PIPE_RWSTREAM_NoError;
183 }
184
185 uint8_t Pipe_Discard_Stream(uint16_t Length
186 #if !defined(NO_STREAM_CALLBACKS)
187 , StreamCallbackPtr_t Callback
188 #endif
189 )
190 {
191 uint8_t ErrorCode;
192
193 Pipe_SetToken(PIPE_TOKEN_IN);
194
195 if ((ErrorCode = Pipe_WaitUntilReady()))
196 return ErrorCode;
197
198 while (Length)
199 {
200 if (!(Pipe_IsReadWriteAllowed()))
201 {
202 Pipe_ClearIN();
203
204 #if !defined(NO_STREAM_CALLBACKS)
205 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
206 return PIPE_RWSTREAM_CallbackAborted;
207 #endif
208
209 if ((ErrorCode = Pipe_WaitUntilReady()))
210 return ErrorCode;
211 }
212 else
213 {
214 Pipe_Discard_Byte();
215 Length--;
216 }
217 }
218
219 return PIPE_RWSTREAM_NoError;
220 }
221
222 uint8_t Pipe_Read_Stream_LE(void* Buffer, uint16_t Length
223 #if !defined(NO_STREAM_CALLBACKS)
224 , StreamCallbackPtr_t Callback
225 #endif
226 )
227 {
228 uint8_t* DataStream = (uint8_t*)Buffer;
229 uint8_t ErrorCode;
230
231 Pipe_SetToken(PIPE_TOKEN_IN);
232
233 if ((ErrorCode = Pipe_WaitUntilReady()))
234 return ErrorCode;
235
236 while (Length)
237 {
238 if (!(Pipe_IsReadWriteAllowed()))
239 {
240 Pipe_ClearIN();
241
242 #if !defined(NO_STREAM_CALLBACKS)
243 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
244 return PIPE_RWSTREAM_CallbackAborted;
245 #endif
246
247 if ((ErrorCode = Pipe_WaitUntilReady()))
248 return ErrorCode;
249 }
250 else
251 {
252 *(DataStream++) = Pipe_Read_Byte();
253 Length--;
254 }
255 }
256
257 return PIPE_RWSTREAM_NoError;
258 }
259
260 uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
261 #if !defined(NO_STREAM_CALLBACKS)
262 , StreamCallbackPtr_t Callback
263 #endif
264 )
265 {
266 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
267 uint8_t ErrorCode;
268
269 Pipe_SetToken(PIPE_TOKEN_IN);
270
271 if ((ErrorCode = Pipe_WaitUntilReady()))
272 return ErrorCode;
273
274 while (Length)
275 {
276 if (!(Pipe_IsReadWriteAllowed()))
277 {
278 Pipe_ClearIN();
279
280 #if !defined(NO_STREAM_CALLBACKS)
281 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
282 return PIPE_RWSTREAM_CallbackAborted;
283 #endif
284
285 if ((ErrorCode = Pipe_WaitUntilReady()))
286 return ErrorCode;
287 }
288 else
289 {
290 *(DataStream--) = Pipe_Read_Byte();
291 Length--;
292 }
293 }
294
295 return PIPE_RWSTREAM_NoError;
296 }
297
298 #endif