Endpoint.c 9.19 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
	uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
78
79
80

	USB_INT_Clear(USB_INT_SOFI);

81
	for (;;)
82
	{
83
84
85
86
87
88
89
90
91
92
93
		if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
		{
			if (Endpoint_IsINReady())
			  return ENDPOINT_READYWAIT_NoError;
		}
		else
		{
			if (Endpoint_IsOUTReceived())
			  return ENDPOINT_READYWAIT_NoError;		
		}
		
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
		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)
                                , uint8_t (* const Callback)(void)
#endif
								)
{
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

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

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

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
134
135
136
		else
		{
			Endpoint_Discard_Byte();
137
			Length--;
138
		}
139
140
	}
	
141
	return ENDPOINT_RWSTREAM_NoError;
142
143
144
145
146
147
148
149
150
151
152
153
154
155
}

uint8_t Endpoint_Write_Stream_LE(const void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                                 , uint8_t (* const Callback)(void)
#endif
								 )
{
	uint8_t* DataStream   = (uint8_t*)Buffer;
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

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

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
170
171
172
		else
		{
			Endpoint_Write_Byte(*(DataStream++));
173
			Length--;
174
		}
175
176
	}
	
177
	return ENDPOINT_RWSTREAM_NoError;
178
179
180
181
182
183
184
185
186
187
188
189
190
191
}

uint8_t Endpoint_Write_Stream_BE(const void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                                 , uint8_t (* const Callback)(void)
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

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

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

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
206
207
208
		else
		{
			Endpoint_Write_Byte(*(DataStream--));
209
			Length--;
210
		}
211
212
	}
	
213
	return ENDPOINT_RWSTREAM_NoError;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
}

uint8_t Endpoint_Read_Stream_LE(void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                                 , uint8_t (* const Callback)(void)
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)Buffer;
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

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

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

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
242
243
244
		else
		{
			*(DataStream++) = Endpoint_Read_Byte();
245
			Length--;
246
		}
247
248
	}
	
249
	return ENDPOINT_RWSTREAM_NoError;
250
251
252
253
254
255
256
257
258
259
260
261
262
263
}

uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                                 , uint8_t (* const Callback)(void)
#endif
								 )
{
	uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

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

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

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

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

322
	return ENDPOINT_RWCSTREAM_NoError;
323
324
325
326
}

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

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

359
	return ENDPOINT_RWCSTREAM_NoError;
360
361
362
363
364
365
366
367
}

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

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

405
	return ENDPOINT_RWCSTREAM_NoError;
406
407
408
}

#endif