Endpoint.c 9.22 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
120
121
		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;

	while (Length--)
	{
122
		if (!(Endpoint_IsReadWriteAllowed()))
123
		{
124
			Endpoint_ClearOUT();
125
126
127
128
129
130
131
132
133

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
			#endif

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

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;

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

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

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;

	while (Length--)
	{
192
		if (!(Endpoint_IsReadWriteAllowed()))
193
		{
194
			Endpoint_ClearIN();
195
196
197
198
199
200
201
202
203

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
			#endif

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

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;

	while (Length--)
	{
227
		if (!(Endpoint_IsReadWriteAllowed()))
228
		{
229
			Endpoint_ClearOUT();
230
231
232
233
234
235
236
237
238

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
239
240
241
242
		else
		{
			*(DataStream++) = Endpoint_Read_Byte();
		}
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
	}
	
	return ENDPOINT_RWSTREAM_ERROR_NoError;
}

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;

	while (Length--)
	{
262
		if (!(Endpoint_IsReadWriteAllowed()))
263
		{
264
			Endpoint_ClearOUT();
265
266
267
268
269
270
271
272
273

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return ENDPOINT_RWSTREAM_ERROR_CallbackAborted;
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
274
275
276
277
		else
		{
			*(DataStream--) = Endpoint_Read_Byte();
		}
278
279
280
281
	}
	
	return ENDPOINT_RWSTREAM_ERROR_NoError;
}
282
#endif
283
284
285

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

	return ENDPOINT_RWCSTREAM_ERROR_NoError;
}

uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
{
321
322
323
	uint8_t* DataStream     = (uint8_t*)(Buffer + Length - 1);
	bool     LastPacketFull = false;
	bool     ShortTransfer  = (Length < USB_ControlRequest.wLength);
324
	
325
	while (Length && !(Endpoint_IsOUTReceived()))
326
	{
327
		while (!(Endpoint_IsINReady()));
328
329
330
331
332
333
334
335
		
		while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
		{
			Endpoint_Write_Byte(*(DataStream--));
			
			Length--;
		}
		
336
		LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
337
		Endpoint_ClearIN();
338
339
	}
	
340
	if (Endpoint_IsOUTReceived())
341
342
	  return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
	
343
	if (LastPacketFull || ShortTransfer)
344
	{
345
		while (!(Endpoint_IsINReady()));
346
		Endpoint_ClearIN();
347
348
	}
	
349
	while (!(Endpoint_IsOUTReceived()));
350
351
352
353
354
355
356
357
358
359

	return ENDPOINT_RWCSTREAM_ERROR_NoError;
}

uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
{
	uint8_t* DataStream = (uint8_t*)Buffer;
	
	while (Length)
	{
360
		while (!(Endpoint_IsOUTReceived()));
361
362
363
364
365
366
367
368
		
		while (Length && Endpoint_BytesInEndpoint())
		{
			*(DataStream++) = Endpoint_Read_Byte();
			
			Length--;
		}
		
369
		Endpoint_ClearOUT();
370
371
	}
	
372
	while (!(Endpoint_IsINReady()));
373
374
375
376
377
378
379
380
381
382
	
	return ENDPOINT_RWCSTREAM_ERROR_NoError;
}

uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
{
	uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
	
	while (Length)
	{
383
		while (!(Endpoint_IsOUTReceived()));
384
385
386
387
388
389
390
391
		
		while (Length && Endpoint_BytesInEndpoint())
		{
			*(DataStream--) = Endpoint_Read_Byte();
			
			Length--;
		}
		
392
		Endpoint_ClearOUT();
393
394
	}
	
395
	while (!(Endpoint_IsINReady()));
396
397
398
399
400

	return ENDPOINT_RWCSTREAM_ERROR_NoError;
}

#endif