Endpoint.c 9.21 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
	for (;;)
84
	{
85
86
87
88
89
90
91
92
93
94
95
		if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
		{
			if (Endpoint_IsINReady())
			  return ENDPOINT_READYWAIT_NoError;
		}
		else
		{
			if (Endpoint_IsOUTReceived())
			  return ENDPOINT_READYWAIT_NoError;		
		}
		
96
97
98
99
100
		if (!(USB_IsConnected))
		  return ENDPOINT_READYWAIT_DeviceDisconnected;
		else if (Endpoint_IsStalled())
		  return ENDPOINT_READYWAIT_EndpointStalled;
			  
101
		if (FrameElapsed)
102
		{
103
			FrameElapsed = false;
104
105
106
107
108
109
110
111
112

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

324
	return ENDPOINT_RWCSTREAM_NoError;
325
326
327
328
}

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

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

361
	return ENDPOINT_RWCSTREAM_NoError;
362
363
364
365
366
367
368
369
}

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

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

407
	return ENDPOINT_RWCSTREAM_NoError;
408
409
410
}

#endif