Create a new function pointer type in StreamCallbacks.h for endpoint/pipe stream...
[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 << PEPNUM0));
49 UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
50
51 return Pipe_IsConfigured();
52 }
53
54 void Pipe_ClearPipes(void)
55 {
56 UPINT = 0;
57
58 for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
59 {
60 Pipe_ResetPipe(PNum);
61 Pipe_SelectPipe(PNum);
62 UPIENX = 0;
63 UPINTX = 0;
64 Pipe_ClearError();
65 Pipe_ClearErrorFlags();
66 Pipe_DeallocateMemory();
67 Pipe_DisablePipe();
68 }
69 }
70
71 uint8_t Pipe_WaitUntilReady(void)
72 {
73 #if (USB_STREAM_TIMEOUT_MS < 0xFF)
74 uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
75 #else
76 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
77 #endif
78
79 USB_INT_Clear(USB_INT_HSOFI);
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 if ((ErrorCode = Pipe_WaitUntilReady()))
119 return ErrorCode;
120
121 while (Length)
122 {
123 if (!(Pipe_IsReadWriteAllowed()))
124 {
125 Pipe_ClearOUT();
126
127 #if !defined(NO_STREAM_CALLBACKS)
128 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
129 return PIPE_RWSTREAM_CallbackAborted;
130 #endif
131
132 if ((ErrorCode = Pipe_WaitUntilReady()))
133 return ErrorCode;
134 }
135 else
136 {
137 Pipe_Write_Byte(*(DataStream++));
138 Length--;
139 }
140 }
141
142 return PIPE_RWSTREAM_NoError;
143 }
144
145 uint8_t Pipe_Write_Stream_BE(const void* Data, uint16_t Length
146 #if !defined(NO_STREAM_CALLBACKS)
147 , StreamCallbackPtr_t Callback
148 #endif
149 )
150 {
151 uint8_t* DataStream = (uint8_t*)(Data + Length - 1);
152 uint8_t ErrorCode;
153
154 if ((ErrorCode = Pipe_WaitUntilReady()))
155 return ErrorCode;
156
157 while (Length)
158 {
159 if (!(Pipe_IsReadWriteAllowed()))
160 {
161 Pipe_ClearOUT();
162
163 #if !defined(NO_STREAM_CALLBACKS)
164 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
165 return PIPE_RWSTREAM_CallbackAborted;
166 #endif
167
168 if ((ErrorCode = Pipe_WaitUntilReady()))
169 return ErrorCode;
170 }
171 else
172 {
173 Pipe_Write_Byte(*(DataStream--));
174 Length--;
175 }
176 }
177
178 return PIPE_RWSTREAM_NoError;
179 }
180
181 uint8_t Pipe_Discard_Stream(uint16_t Length
182 #if !defined(NO_STREAM_CALLBACKS)
183 , StreamCallbackPtr_t Callback
184 #endif
185 )
186 {
187 uint8_t ErrorCode;
188
189 if ((ErrorCode = Pipe_WaitUntilReady()))
190 return ErrorCode;
191
192 while (Length)
193 {
194 if (!(Pipe_IsReadWriteAllowed()))
195 {
196 Pipe_ClearIN();
197
198 #if !defined(NO_STREAM_CALLBACKS)
199 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
200 return PIPE_RWSTREAM_CallbackAborted;
201 #endif
202
203 if ((ErrorCode = Pipe_WaitUntilReady()))
204 return ErrorCode;
205 }
206 else
207 {
208 Pipe_Discard_Byte();
209 Length--;
210 }
211 }
212
213 return PIPE_RWSTREAM_NoError;
214 }
215
216 uint8_t Pipe_Read_Stream_LE(void* Buffer, uint16_t Length
217 #if !defined(NO_STREAM_CALLBACKS)
218 , StreamCallbackPtr_t Callback
219 #endif
220 )
221 {
222 uint8_t* DataStream = (uint8_t*)Buffer;
223 uint8_t ErrorCode;
224
225 if ((ErrorCode = Pipe_WaitUntilReady()))
226 return ErrorCode;
227
228 while (Length)
229 {
230 if (!(Pipe_IsReadWriteAllowed()))
231 {
232 Pipe_ClearIN();
233
234 #if !defined(NO_STREAM_CALLBACKS)
235 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
236 return PIPE_RWSTREAM_CallbackAborted;
237 #endif
238
239 if ((ErrorCode = Pipe_WaitUntilReady()))
240 return ErrorCode;
241 }
242 else
243 {
244 *(DataStream++) = Pipe_Read_Byte();
245 Length--;
246 }
247 }
248
249 return PIPE_RWSTREAM_NoError;
250 }
251
252 uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
253 #if !defined(NO_STREAM_CALLBACKS)
254 , StreamCallbackPtr_t Callback
255 #endif
256 )
257 {
258 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
259 uint8_t ErrorCode;
260
261 if ((ErrorCode = Pipe_WaitUntilReady()))
262 return ErrorCode;
263
264 while (Length)
265 {
266 if (!(Pipe_IsReadWriteAllowed()))
267 {
268 Pipe_ClearIN();
269
270 #if !defined(NO_STREAM_CALLBACKS)
271 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
272 return PIPE_RWSTREAM_CallbackAborted;
273 #endif
274
275 if ((ErrorCode = Pipe_WaitUntilReady()))
276 return ErrorCode;
277 }
278 else
279 {
280 *(DataStream--) = Pipe_Read_Byte();
281 Length--;
282 }
283 }
284
285 return PIPE_RWSTREAM_NoError;
286 }
287
288 #endif