Endpoint.c 9.27 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
             LUFA Library
     Copyright (C) Dean Camera, 2009.
              
  dean [at] fourwalledcubicle [dot] com
      www.fourwalledcubicle.com
*/

/*
  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)

  Permission to use, copy, modify, and distribute this software
  and its documentation for any purpose and without fee is hereby
  granted, provided that the above copyright notice appear in all
  copies and that both that the copyright notice and this
  permission notice and warranty disclaimer appear in supporting
  documentation, and that the name of the author not be used in
  advertising or publicity pertaining to distribution of the
  software without specific, written prior permission.

  The author disclaim all warranties with regard to this
  software, including all implied warranties of merchantability
  and fitness.  In no event shall the author be liable for any
  special, indirect or consequential damages or any damages
  whatsoever resulting from loss of use, data or profits, whether
  in an action of contract, negligence or other tortious action,
  arising out of or in connection with the use or performance of
  this software.
*/

31
32
#include "../HighLevel/USBMode.h"

33
34
35
36
37
38
39
40
41
#if defined(USB_CAN_BE_DEVICE)

#define  INCLUDE_FROM_ENDPOINT_C
#include "Endpoint.h"

#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
#endif

42
uint8_t Endpoint_BytesToEPSizeMaskDynamic(const uint16_t Size)
43
{
44
	return Endpoint_BytesToEPSizeMask(Size);
45
}
46
47

bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, const uint8_t UECFG0XData, const uint8_t UECFG1XData)
48
49
50
51
{
	Endpoint_SelectEndpoint(Number);
	Endpoint_EnableEndpoint();

52
	UECFG1X = 0;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

	UECFG0X = UECFG0XData;
	UECFG1X = UECFG1XData;

	return Endpoint_IsConfigured();
}

void Endpoint_ClearEndpoints(void)
{
	UEINT = 0;

	for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
	{
		Endpoint_SelectEndpoint(EPNum);	
		UEIENX = 0;
		UEINTX = 0;
		Endpoint_DeallocateMemory();
		Endpoint_DisableEndpoint();
	}
}

74
#if !defined(CONTROL_ONLY_DEVICE)
75
76
uint8_t Endpoint_WaitUntilReady(void)
{
77
78
79
	#if (USB_STREAM_TIMEOUT_MS < 0xFF)
	uint8_t  TimeoutMSRem = USB_STREAM_TIMEOUT_MS;	
	#else
80
	uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
81
	#endif
82
83
84

	USB_INT_Clear(USB_INT_SOFI);

85
	for (;;)
86
	{
87
88
89
90
91
92
93
94
95
96
97
		if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
		{
			if (Endpoint_IsINReady())
			  return ENDPOINT_READYWAIT_NoError;
		}
		else
		{
			if (Endpoint_IsOUTReceived())
			  return ENDPOINT_READYWAIT_NoError;		
		}
		
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
		if (!(USB_IsConnected))
		  return ENDPOINT_READYWAIT_DeviceDisconnected;
		else if (Endpoint_IsStalled())
		  return ENDPOINT_READYWAIT_EndpointStalled;
			  
		if (USB_INT_HasOccurred(USB_INT_SOFI))
		{
			USB_INT_Clear(USB_INT_SOFI);

			if (!(TimeoutMSRem--))
			  return ENDPOINT_READYWAIT_Timeout;
		}
	}
}

uint8_t Endpoint_Discard_Stream(uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
115
                                , StreamCallbackPtr_t Callback
116
117
118
119
120
121
122
123
#endif
								)
{
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

124
	while (Length)
125
	{
126
		if (!(Endpoint_IsReadWriteAllowed()))
127
		{
128
			Endpoint_ClearOUT();
129
130
131

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
132
			  return ENDPOINT_RWSTREAM_CallbackAborted;
133
134
135
136
137
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
138
139
140
		else
		{
			Endpoint_Discard_Byte();
141
			Length--;
142
		}
143
144
	}
	
145
	return ENDPOINT_RWSTREAM_NoError;
146
147
148
149
}

uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
150
                                 , StreamCallbackPtr_t Callback
151
152
153
154
155
156
157
158
159
#endif
								 )
{
	uint8_t* DataStream   = (uint8_t*)Buffer;
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

160
	while (Length)
161
	{
162
		if (!(Endpoint_IsReadWriteAllowed()))
163
		{
164
			Endpoint_ClearIN();
165
166
167
			
			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
168
			  return ENDPOINT_RWSTREAM_CallbackAborted;
169
170
171
172
173
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
174
175
176
		else
		{
			Endpoint_Write_Byte(*(DataStream++));
177
			Length--;
178
		}
179
180
	}
	
181
	return ENDPOINT_RWSTREAM_NoError;
182
183
184
185
}

uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
186
                                 , StreamCallbackPtr_t Callback
187
188
189
190
191
192
193
194
195
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

196
	while (Length)
197
	{
198
		if (!(Endpoint_IsReadWriteAllowed()))
199
		{
200
			Endpoint_ClearIN();
201
202
203

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
204
			  return ENDPOINT_RWSTREAM_CallbackAborted;
205
206
207
208
209
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
210
211
212
		else
		{
			Endpoint_Write_Byte(*(DataStream--));
213
			Length--;
214
		}
215
216
	}
	
217
	return ENDPOINT_RWSTREAM_NoError;
218
219
220
221
}

uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
222
                                 , StreamCallbackPtr_t Callback
223
224
225
226
227
228
229
230
231
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)Buffer;
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

232
	while (Length)
233
	{
234
		if (!(Endpoint_IsReadWriteAllowed()))
235
		{
236
			Endpoint_ClearOUT();
237
238
239

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
240
			  return ENDPOINT_RWSTREAM_CallbackAborted;
241
242
243
244
245
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
246
247
248
		else
		{
			*(DataStream++) = Endpoint_Read_Byte();
249
			Length--;
250
		}
251
252
	}
	
253
	return ENDPOINT_RWSTREAM_NoError;
254
255
256
257
}

uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
258
                                 , StreamCallbackPtr_t Callback
259
260
261
262
263
264
265
266
267
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

268
	while (Length)
269
	{
270
		if (!(Endpoint_IsReadWriteAllowed()))
271
		{
272
			Endpoint_ClearOUT();
273
274
275

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
276
			  return ENDPOINT_RWSTREAM_CallbackAborted;
277
278
279
280
281
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
282
283
284
		else
		{
			*(DataStream--) = Endpoint_Read_Byte();
285
			Length--;
286
		}
287
288
	}
	
289
	return ENDPOINT_RWSTREAM_NoError;
290
}
291
#endif
292
293
294

uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
{
295
	uint8_t* DataStream     = (uint8_t*)Buffer;
296
	bool     LastPacketFull = false;
297
298
299
	
	if (Length > USB_ControlRequest.wLength)
	  Length = USB_ControlRequest.wLength;
300
	
301
	while (Length && !(Endpoint_IsOUTReceived()))
302
	{
303
		while (!(Endpoint_IsINReady()));
304
305
306
307
308
309
310
		
		while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
		{
			Endpoint_Write_Byte(*(DataStream++));
			Length--;
		}
		
311
		LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
312
		Endpoint_ClearIN();
313
314
	}
	
315
	if (Endpoint_IsOUTReceived())
316
	  return ENDPOINT_RWCSTREAM_HostAborted;
317
	
318
	if (LastPacketFull)
319
	{
320
		while (!(Endpoint_IsINReady()));
321
		Endpoint_ClearIN();
322
323
	}
	
324
	while (!(Endpoint_IsOUTReceived()));
325

326
	return ENDPOINT_RWCSTREAM_NoError;
327
328
329
330
}

uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
{
331
332
	uint8_t* DataStream     = (uint8_t*)(Buffer + Length - 1);
	bool     LastPacketFull = false;
333
	
334
335
336
	if (Length > USB_ControlRequest.wLength)
	  Length = USB_ControlRequest.wLength;

337
	while (Length && !(Endpoint_IsOUTReceived()))
338
	{
339
		if (Endpoint_IsINReady())
340
		{
341
342
343
344
345
346
347
348
			while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
			{
				Endpoint_Write_Byte(*(DataStream--));
				Length--;
			}
			
			LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
			Endpoint_ClearIN();
349
350
351
		}
	}
	
352
	if (Endpoint_IsOUTReceived())
353
	  return ENDPOINT_RWCSTREAM_HostAborted;
354
	
355
	if (LastPacketFull)
356
	{
357
		while (!(Endpoint_IsINReady()));
358
		Endpoint_ClearIN();
359
360
	}
	
361
	while (!(Endpoint_IsOUTReceived()));
362

363
	return ENDPOINT_RWCSTREAM_NoError;
364
365
366
367
368
369
370
371
}

uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
{
	uint8_t* DataStream = (uint8_t*)Buffer;
	
	while (Length)
	{
372
		if (Endpoint_IsOUTReceived())
373
		{
374
375
376
377
378
379
380
			while (Length && Endpoint_BytesInEndpoint())
			{
				*(DataStream++) = Endpoint_Read_Byte();
				Length--;
			}
			
			Endpoint_ClearOUT();
381
382
383
		}
	}
	
384
	while (!(Endpoint_IsINReady()));
385
	
386
	return ENDPOINT_RWCSTREAM_NoError;
387
388
389
390
391
392
393
394
}

uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
{
	uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
	
	while (Length)
	{
395
		if (Endpoint_IsOUTReceived())
396
		{
397
398
399
400
401
402
403
			while (Length && Endpoint_BytesInEndpoint())
			{
				*(DataStream--) = Endpoint_Read_Byte();
				Length--;
			}
			
			Endpoint_ClearOUT();
404
405
406
		}
	}
	
407
	while (!(Endpoint_IsINReady()));
408

409
	return ENDPOINT_RWCSTREAM_NoError;
410
411
412
}

#endif