Fixed minor issue with the RNDISEthernet demo DHCP protocol decoder routine using...
[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 uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
74
75 USB_INT_Clear(USB_INT_HSOFI);
76
77 while (!(Pipe_ReadWriteAllowed()))
78 {
79 if (Pipe_IsStalled())
80 return PIPE_READYWAIT_PipeStalled;
81 else if (!(USB_IsConnected))
82 return PIPE_READYWAIT_DeviceDisconnected;
83
84 if (USB_INT_HasOccurred(USB_INT_HSOFI))
85 {
86 USB_INT_Clear(USB_INT_HSOFI);
87
88 if (!(TimeoutMSRem--))
89 return PIPE_READYWAIT_Timeout;
90 }
91 }
92
93 return PIPE_READYWAIT_NoError;
94 }
95
96 uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length
97 #if !defined(NO_STREAM_CALLBACKS)
98 , uint8_t (* const Callback)(void)
99 #endif
100 )
101 {
102 uint8_t* DataStream = (uint8_t*)Data;
103 uint8_t ErrorCode;
104
105 if ((ErrorCode = Pipe_WaitUntilReady()))
106 return ErrorCode;
107
108 while (Length--)
109 {
110 if (!(Pipe_ReadWriteAllowed()))
111 {
112 Pipe_ClearCurrentBank();
113
114 #if !defined(NO_STREAM_CALLBACKS)
115 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
116 return PIPE_RWSTREAM_ERROR_CallbackAborted;
117 #endif
118
119 if ((ErrorCode = Pipe_WaitUntilReady()))
120 return ErrorCode;
121 }
122
123 Pipe_Write_Byte(*(DataStream++));
124 }
125
126 return PIPE_RWSTREAM_ERROR_NoError;
127 }
128
129 uint8_t Pipe_Write_Stream_BE(const void* Data, uint16_t Length
130 #if !defined(NO_STREAM_CALLBACKS)
131 , uint8_t (* const Callback)(void)
132 #endif
133 )
134 {
135 uint8_t* DataStream = (uint8_t*)(Data + Length - 1);
136 uint8_t ErrorCode;
137
138 if ((ErrorCode = Pipe_WaitUntilReady()))
139 return ErrorCode;
140
141 while (Length--)
142 {
143 if (!(Pipe_ReadWriteAllowed()))
144 {
145 Pipe_ClearCurrentBank();
146
147 #if !defined(NO_STREAM_CALLBACKS)
148 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
149 return PIPE_RWSTREAM_ERROR_CallbackAborted;
150 #endif
151
152 if ((ErrorCode = Pipe_WaitUntilReady()))
153 return ErrorCode;
154 }
155
156 Pipe_Write_Byte(*(DataStream--));
157 }
158
159 return PIPE_RWSTREAM_ERROR_NoError;
160 }
161
162 uint8_t Pipe_Discard_Stream(uint16_t Length
163 #if !defined(NO_STREAM_CALLBACKS)
164 , uint8_t (* const Callback)(void)
165 #endif
166 )
167 {
168 uint8_t ErrorCode;
169
170 if ((ErrorCode = Pipe_WaitUntilReady()))
171 return ErrorCode;
172
173 while (Length--)
174 {
175 if (!(Pipe_ReadWriteAllowed()))
176 {
177 Pipe_ClearCurrentBank();
178
179 #if !defined(NO_STREAM_CALLBACKS)
180 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
181 return PIPE_RWSTREAM_ERROR_CallbackAborted;
182 #endif
183
184 if ((ErrorCode = Pipe_WaitUntilReady()))
185 return ErrorCode;
186 }
187
188 Pipe_Discard_Byte();
189 }
190
191 return PIPE_RWSTREAM_ERROR_NoError;
192 }
193
194 uint8_t Pipe_Read_Stream_LE(void* Buffer, uint16_t Length
195 #if !defined(NO_STREAM_CALLBACKS)
196 , uint8_t (* const Callback)(void)
197 #endif
198 )
199 {
200 uint8_t* DataStream = (uint8_t*)Buffer;
201 uint8_t ErrorCode;
202
203 if ((ErrorCode = Pipe_WaitUntilReady()))
204 return ErrorCode;
205
206 while (Length--)
207 {
208 if (!(Pipe_ReadWriteAllowed()))
209 {
210 Pipe_ClearCurrentBank();
211
212 #if !defined(NO_STREAM_CALLBACKS)
213 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
214 return PIPE_RWSTREAM_ERROR_CallbackAborted;
215 #endif
216
217 if ((ErrorCode = Pipe_WaitUntilReady()))
218 return ErrorCode;
219 }
220
221 *(DataStream++) = Pipe_Read_Byte();
222 }
223
224 return PIPE_RWSTREAM_ERROR_NoError;
225 }
226
227 uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length
228 #if !defined(NO_STREAM_CALLBACKS)
229 , uint8_t (* const Callback)(void)
230 #endif
231 )
232 {
233 uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
234 uint8_t ErrorCode;
235
236 if ((ErrorCode = Pipe_WaitUntilReady()))
237 return ErrorCode;
238
239 while (Length--)
240 {
241 if (!(Pipe_ReadWriteAllowed()))
242 {
243 Pipe_ClearCurrentBank();
244
245 #if !defined(NO_STREAM_CALLBACKS)
246 if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
247 return PIPE_RWSTREAM_ERROR_CallbackAborted;
248 #endif
249
250 if ((ErrorCode = Pipe_WaitUntilReady()))
251 return ErrorCode;
252 }
253
254 *(DataStream--) = Pipe_Read_Byte();
255 }
256
257 return PIPE_RWSTREAM_ERROR_NoError;
258 }
259
260 #endif