Endpoint.c 9.26 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
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
		else
		{
			Endpoint_Discard_Byte();
137
			Length--;
138
		}
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
	}
	
	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;

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

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
170
171
172
		else
		{
			Endpoint_Write_Byte(*(DataStream++));
173
			Length--;
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;

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

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

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

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

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

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

264
	while (Length)
265
	{
266
		if (!(Endpoint_IsReadWriteAllowed()))
267
		{
268
			Endpoint_ClearOUT();
269
270
271
272
273
274
275
276
277

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

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

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

	return ENDPOINT_RWCSTREAM_ERROR_NoError;
}

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

	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)
	{
363
		while (!(Endpoint_IsOUTReceived()));
364
365
366
367
368
369
370
		
		while (Length && Endpoint_BytesInEndpoint())
		{
			*(DataStream++) = Endpoint_Read_Byte();
			Length--;
		}
		
371
		Endpoint_ClearOUT();
372
373
	}
	
374
	while (!(Endpoint_IsINReady()));
375
376
377
378
379
380
381
382
383
384
	
	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)
	{
385
		while (!(Endpoint_IsOUTReceived()));
386
387
388
389
390
391
392
		
		while (Length && Endpoint_BytesInEndpoint())
		{
			*(DataStream--) = Endpoint_Read_Byte();
			Length--;
		}
		
393
		Endpoint_ClearOUT();
394
395
	}
	
396
	while (!(Endpoint_IsINReady()));
397
398
399
400
401

	return ENDPOINT_RWCSTREAM_ERROR_NoError;
}

#endif