2 * @brief USB Endpoint definitions for all architectures
\r
5 * Copyright(C) NXP Semiconductors, 2012
\r
6 * Copyright(C) Dean Camera, 2011, 2012
\r
7 * All rights reserved.
\r
10 * Software that is described herein is for illustrative purposes only
\r
11 * which provides customers with programming information regarding the
\r
12 * LPC products. This software is supplied "AS IS" without any warranties of
\r
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
\r
14 * all warranties, express or implied, including all implied warranties of
\r
15 * merchantability, fitness for a particular purpose and non-infringement of
\r
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
\r
17 * or liability for the use of the software, conveys no license or rights under any
\r
18 * patent, copyright, mask work right, or any other intellectual property rights in
\r
19 * or to any products. NXP Semiconductors reserves the right to make changes
\r
20 * in the software without notification. NXP Semiconductors also makes no
\r
21 * representation or warranty that such application will be suitable for the
\r
22 * specified use without further testing or modification.
\r
25 * Permission to use, copy, modify, and distribute this software and its
\r
26 * documentation is hereby granted, under NXP Semiconductors' and its
\r
27 * licensor's relevant copyrights in the software, without fee, provided that it
\r
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
\r
29 * copyright, permission, and disclaimer notice must appear in all copies of
\r
33 /** @ingroup Group_EndpointManagement
\r
34 * @defgroup Group_EndpointRW Endpoint Data Reading and Writing
\r
35 * @brief Endpoint data read/write definitions.
\r
37 * Functions, macros, variables, enums and types related to data reading and writing from and to endpoints.
\r
40 /** @ingroup Group_EndpointRW
\r
41 * @defgroup Group_EndpointPrimitiveRW Read/Write of Primitive Data Types
\r
42 * @brief Endpoint data primitive read/write definitions.
\r
44 * Functions, macros, variables, enums and types related to data reading and writing of primitive data types
\r
45 * from and to endpoints.
\r
48 /** @ingroup Group_EndpointManagement
\r
49 * @defgroup Group_EndpointPacketManagement Endpoint Packet Management
\r
50 * @brief USB Endpoint package management definitions.
\r
52 * Functions, macros, variables, enums and types related to packet management of endpoints.
\r
55 /** @ingroup Group_USB
\r
56 * @defgroup Group_EndpointManagement Endpoint Management
\r
57 * @brief Endpoint management definitions.
\r
59 * Functions, macros and enums related to endpoint management when in USB Device mode. This
\r
60 * module contains the endpoint management macros, as well as endpoint interrupt and data
\r
61 * send/receive functions for various data types.
\r
66 #ifndef __ENDPOINT_H__
\r
67 #define __ENDPOINT_H__
\r
70 #include "../../../Common/Common.h"
\r
71 #include "USBMode.h"
\r
72 #include "USBTask.h"
\r
73 #include "USBInterrupt.h"
\r
75 /* Enable C linkage for C++ Compilers: */
\r
76 #if defined(__cplusplus)
\r
80 /* Preprocessor Checks: */
\r
81 #if !defined(__INCLUDE_FROM_USB_DRIVER)
\r
82 #error Do not include this file directly. Include lpcroot/libraries/LPCUSBlib/Drivers/USB/USB.h instead.
\r
85 /* Public Interface - May be used in end-application: */
\r
87 /** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
\r
88 * numerical address in the device.
\r
90 #define ENDPOINT_EPNUM_MASK 0x0F
\r
92 /** Endpoint address for the default control endpoint, which always resides in address 0. This is
\r
93 * defined for convenience to give more readable code when used with the endpoint macros.
\r
95 #define ENDPOINT_CONTROLEP 0
\r
97 #if defined(__LPC18XX__) || defined(__LPC43XX__)
\r
98 #include "DCD/LPC18XX/Endpoint_LPC18xx.h"
\r
99 #elif defined(__LPC175X_6X__) || defined(__LPC177X_8X__) || defined(__LPC407X_8X__)
\r
100 #include "DCD/LPC17XX/Endpoint_LPC17xx.h"
\r
101 #elif defined(__LPC11U1X__) || defined(__LPC11U2X_3X__) || defined(__LPC1347__)
\r
102 #include "DCD/LPC11UXX/Endpoint_LPC11Uxx.h"
\r
107 /** Mask for the bank mode selection for the @ref Endpoint_ConfigureEndpoint() macro. This indicates
\r
108 * that the endpoint should have one single bank, which requires less USB FIFO memory but results
\r
109 * in slower transfers as only one USB device (the LPC or the host) can access the endpoint's
\r
110 * bank at the one time.
\r
112 #define ENDPOINT_BANK_SINGLE (0 << 1)
\r
114 /** Mask for the bank mode selection for the @ref Endpoint_ConfigureEndpoint() macro. This indicates
\r
115 * that the endpoint should have two banks, which requires more USB FIFO memory but results
\r
116 * in faster transfers as one USB device (the LPC or the host) can access one bank while the other
\r
117 * accesses the second bank.
\r
119 #define ENDPOINT_BANK_DOUBLE (1 << 1)
\r
121 #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
\r
122 /** Default size of the default control endpoint's bank, until altered by the control endpoint bank size
\r
123 * value in the device descriptor. Not available if the \c FIXED_CONTROL_ENDPOINT_SIZE token is defined.
\r
125 #define ENDPOINT_CONTROLEP_DEFAULT_SIZE 64
\r
128 /** Retrieves the maximum bank size in bytes of a given endpoint.
\r
130 * @note This macro will only work correctly on endpoint indexes that are compile-time constants
\r
131 * defined by the preprocessor.
\r
133 * @param EPIndex Endpoint number, a value between 0 and (\ref ENDPOINT_TOTAL_ENDPOINTS - 1)
\r
135 #define ENDPOINT_MAX_SIZE(EPIndex) 512
\r
137 #if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__)
\r
138 /** Total number of endpoints (including the default control endpoint at address 0) which may
\r
139 * be used in the device. Different USB LPC models support different amounts of endpoints,
\r
140 * this value reflects the maximum number of endpoints for the currently selected LPC model.
\r
142 #define ENDPOINT_TOTAL_ENDPOINTS0 ENDPOINT_DETAILS_MAXEP0
\r
143 #define ENDPOINT_TOTAL_ENDPOINTS1 ENDPOINT_DETAILS_MAXEP1
\r
144 #define ENDPOINT_TOTAL_ENDPOINTS(corenum) ((corenum) ? ENDPOINT_DETAILS_MAXEP1 : ENDPOINT_DETAILS_MAXEP0)
\r
146 #define ENDPOINT_TOTAL_ENDPOINTS 1
\r
150 /** Enum for the possible error return codes of the @ref Endpoint_WaitUntilReady() function.
\r
152 * @ingroup Group_EndpointRW
\r
154 enum Endpoint_WaitUntilReady_ErrorCodes_t {
\r
155 ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */
\r
156 ENDPOINT_READYWAIT_EndpointStalled = 1, /**< The endpoint was stalled during the stream
\r
157 * transfer by the host or device.
\r
159 ENDPOINT_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while
\r
160 * waiting for the endpoint to become ready.
\r
162 ENDPOINT_READYWAIT_BusSuspended = 3, /**< The USB bus has been suspended by the host and
\r
163 * no USB endpoint traffic can occur until the bus
\r
166 ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet
\r
167 * within the software timeout period set by the
\r
168 * @ref USB_STREAM_TIMEOUT_MS macro.
\r
173 * @brief Get the endpoint address of the currently selected endpoint. This is typically used to save
\r
174 * the currently selected endpoint number so that it can be restored after another endpoint has
\r
175 * been manipulated.
\r
176 * @param corenum : ID Number of USB Core to be processed.
\r
177 * @return Index of the currently selected endpoint
\r
179 PRAGMA_ALWAYS_INLINE
\r
180 static inline uint8_t Endpoint_GetCurrentEndpoint(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
182 static inline uint8_t Endpoint_GetCurrentEndpoint(uint8_t corenum)
\r
184 return endpointselected[corenum];
\r
188 * @brief Selects the given endpoint number. If the address from the device descriptors is used, the
\r
189 * value should be masked with the @ref ENDPOINT_EPNUM_MASK constant to extract only the endpoint
\r
190 * number (and discarding the endpoint direction bit).
\r
192 * Any endpoint operations which do not require the endpoint number to be indicated will operate on
\r
193 * the currently selected endpoint.
\r
195 * @param corenum : ID Number of USB Core to be processed.
\r
196 * @param EndpointNumber : Endpoint number to select
\r
199 PRAGMA_ALWAYS_INLINE
\r
200 static inline void Endpoint_SelectEndpoint(uint8_t corenum, const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
\r
202 static inline void Endpoint_SelectEndpoint(uint8_t corenum, const uint8_t EndpointNumber)
\r
204 endpointselected[corenum] = EndpointNumber;
\r
205 // usb_data_buffer_index = 0;
\r
209 * @brief Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints.
\r
211 * @ingroup Group_EndpointPrimitiveRW
\r
213 * @param corenum : ID Number of USB Core to be processed.
\r
214 * @return Next byte in the currently selected endpoint's FIFO buffer
\r
216 PRAGMA_ALWAYS_INLINE
\r
217 static inline uint8_t Endpoint_Read_8(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
219 static inline uint8_t Endpoint_Read_8(uint8_t corenum)
\r
222 if (endpointselected[corenum] == ENDPOINT_CONTROLEP) {
\r
223 tem = usb_data_buffer[corenum][usb_data_buffer_index[corenum]];
\r
224 usb_data_buffer_index[corenum]++;
\r
225 usb_data_buffer_size[corenum]--;
\r
228 tem = usb_data_buffer_OUT[corenum][usb_data_buffer_OUT_index[corenum]];
\r
229 usb_data_buffer_OUT_index[corenum]++;
\r
230 usb_data_buffer_OUT_size[corenum]--;
\r
236 * @brief Determines the currently selected endpoint's direction
\r
237 * @param corenum : ID Number of USB Core to be processed.
\r
238 * @return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask.
\r
240 PRAGMA_ALWAYS_INLINE
\r
241 static inline uint8_t Endpoint_GetEndpointDirection(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
243 static inline uint8_t Endpoint_GetEndpointDirection(uint8_t corenum)
\r
245 return (endpointhandle(corenum)[endpointselected[corenum]] % 2) ? ENDPOINT_DIR_IN : ENDPOINT_DIR_OUT;
\r
249 * @brief Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint
\r
250 * bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN
\r
251 * direction). This function will return false if an error has occurred in the endpoint, if the endpoint
\r
252 * is an OUT direction and no packet (or an empty packet) has been received, or if the endpoint is an IN
\r
253 * direction and the endpoint bank is full.
\r
255 * @ingroup Group_EndpointPacketManagement
\r
257 * @param corenum : ID Number of USB Core to be processed.
\r
258 * @return Boolean \c true if the currently selected endpoint may be read from or written to, depending
\r
259 * on its direction.
\r
261 PRAGMA_ALWAYS_INLINE
\r
262 static inline bool Endpoint_IsReadWriteAllowed(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
264 static inline bool Endpoint_IsReadWriteAllowed(uint8_t corenum)
\r
266 return (Endpoint_GetEndpointDirection(corenum) == ENDPOINT_DIR_OUT) ? Endpoint_IsOUTReceived(corenum) : Endpoint_IsINReady(corenum);
\r
270 * @brief Writes one byte to the currently selected endpoint's bank, for IN direction endpoints.
\r
272 * @ingroup Group_EndpointPrimitiveRW
\r
274 * @param corenum : ID Number of USB Core to be processed.
\r
275 * @param Data : Data to write into the the currently selected endpoint's FIFO buffer
\r
278 PRAGMA_ALWAYS_INLINE
\r
279 static inline void Endpoint_Write_8(uint8_t corenum, const uint8_t Data) ATTR_ALWAYS_INLINE;
\r
281 static inline void Endpoint_Write_8(uint8_t corenum, const uint8_t Data)
\r
283 if (endpointselected[corenum] == ENDPOINT_CONTROLEP) {
\r
284 usb_data_buffer[corenum][usb_data_buffer_index[corenum]] = Data;
\r
285 usb_data_buffer_index[corenum]++;
\r
288 usb_data_buffer_IN[corenum][usb_data_buffer_IN_index[corenum]] = Data;
\r
289 usb_data_buffer_IN_index[corenum]++;
\r
294 * @brief Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints.
\r
295 * @param corenum : ID Number of USB Core to be processed.
\r
298 * @ingroup Group_EndpointPrimitiveRW
\r
300 PRAGMA_ALWAYS_INLINE
\r
301 static inline void Endpoint_Discard_8(uint8_t corenum) ATTR_ALWAYS_INLINE;
\r
303 static inline void Endpoint_Discard_8(uint8_t corenum)
\r
305 volatile uint8_t dummy;
\r
306 dummy = Endpoint_Read_8(corenum);
\r
311 * @brief Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
\r
312 * direction endpoints.
\r
314 * @ingroup Group_EndpointPrimitiveRW
\r
315 * @param corenum : ID Number of USB Core to be processed.
\r
316 * @return Next two bytes in the currently selected endpoint's FIFO buffer.
\r
318 PRAGMA_ALWAYS_INLINE
\r
319 static inline uint16_t Endpoint_Read_16_LE(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
321 static inline uint16_t Endpoint_Read_16_LE(uint8_t corenum)
\r
324 uint8_t tem1, tem2;
\r
326 tem1 = Endpoint_Read_8(corenum);
\r
327 tem2 = Endpoint_Read_8(corenum);
\r
328 tem = (tem2 << 8) | tem1;
\r
333 * @brief Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT
\r
334 * direction endpoints.
\r
336 * @ingroup Group_EndpointPrimitiveRW
\r
338 * @param corenum : ID Number of USB Core to be processed.
\r
339 * @return Next two bytes in the currently selected endpoint's FIFO buffer.
\r
341 PRAGMA_ALWAYS_INLINE
\r
342 static inline uint16_t Endpoint_Read_16_BE(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
344 static inline uint16_t Endpoint_Read_16_BE(uint8_t corenum)
\r
347 uint8_t tem1, tem2;
\r
349 tem1 = Endpoint_Read_8(corenum);
\r
350 tem2 = Endpoint_Read_8(corenum);
\r
351 tem = (tem1 << 8) | tem2;
\r
356 * @brief Writes two bytes to the currently selected endpoint's bank in little endian format, for IN
\r
357 * direction endpoints.
\r
359 * @ingroup Group_EndpointPrimitiveRW
\r
361 * @param corenum : ID Number of USB Core to be processed.
\r
362 * @param Data : Data to write to the currently selected endpoint's FIFO buffer
\r
365 PRAGMA_ALWAYS_INLINE
\r
366 static inline void Endpoint_Write_16_LE(uint8_t corenum, const uint16_t Data) ATTR_ALWAYS_INLINE;
\r
368 static inline void Endpoint_Write_16_LE(uint8_t corenum, const uint16_t Data)
\r
370 Endpoint_Write_8(corenum, Data & 0xFF);
\r
371 Endpoint_Write_8(corenum, (Data >> 8) & 0xFF);
\r
375 * @brief Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
\r
376 * direction endpoints.
\r
378 * @ingroup Group_EndpointPrimitiveRW
\r
380 * @param corenum : ID Number of USB Core to be processed.
\r
381 * @param Data : Data to write to the currently selected endpoint's FIFO buffer
\r
384 PRAGMA_ALWAYS_INLINE
\r
385 static inline void Endpoint_Write_16_BE(uint8_t corenum, const uint16_t Data) ATTR_ALWAYS_INLINE;
\r
387 static inline void Endpoint_Write_16_BE(uint8_t corenum, const uint16_t Data)
\r
389 Endpoint_Write_8(corenum, (Data >> 8) & 0xFF);
\r
390 Endpoint_Write_8(corenum, Data & 0xFF);
\r
394 * @brief Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.
\r
397 * @ingroup Group_EndpointPrimitiveRW
\r
398 * @param corenum : ID Number of USB Core to be processed.
\r
400 PRAGMA_ALWAYS_INLINE
\r
401 static inline void Endpoint_Discard_16(uint8_t corenum) ATTR_ALWAYS_INLINE;
\r
403 static inline void Endpoint_Discard_16(uint8_t corenum)
\r
406 tem = Endpoint_Read_8(corenum);
\r
407 tem = Endpoint_Read_8(corenum);
\r
412 * @brief Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT
\r
413 * direction endpoints.
\r
415 * @ingroup Group_EndpointPrimitiveRW
\r
417 * @param corenum : ID Number of USB Core to be processed.
\r
418 * @return Next four bytes in the currently selected endpoint's FIFO buffer.
\r
420 PRAGMA_ALWAYS_INLINE
\r
421 static inline uint32_t Endpoint_Read_32_LE(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
423 static inline uint32_t Endpoint_Read_32_LE(uint8_t corenum)
\r
426 uint8_t tem1, tem2, tem3, tem4;
\r
428 tem1 = Endpoint_Read_8(corenum);
\r
429 tem2 = Endpoint_Read_8(corenum);
\r
430 tem3 = Endpoint_Read_8(corenum);
\r
431 tem4 = Endpoint_Read_8(corenum);
\r
432 tem = (tem4 << 24) | (tem3 << 16) | (tem2 << 8) | tem1;
\r
437 * @brief Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT
\r
438 * direction endpoints.
\r
440 * @ingroup Group_EndpointPrimitiveRW
\r
442 * @param corenum : ID Number of USB Core to be processed.
\r
443 * @return Next four bytes in the currently selected endpoint's FIFO buffer.
\r
445 PRAGMA_ALWAYS_INLINE
\r
446 static inline uint32_t Endpoint_Read_32_BE(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
448 static inline uint32_t Endpoint_Read_32_BE(uint8_t corenum)
\r
451 uint8_t tem1, tem2, tem3, tem4;
\r
453 tem1 = Endpoint_Read_8(corenum);
\r
454 tem2 = Endpoint_Read_8(corenum);
\r
455 tem3 = Endpoint_Read_8(corenum);
\r
456 tem4 = Endpoint_Read_8(corenum);
\r
457 tem = (tem1 << 24) | (tem2 << 16) | (tem3 << 8) | tem4;
\r
462 * @brief Writes four bytes to the currently selected endpoint's bank in little endian format, for IN
\r
463 * direction endpoints.
\r
465 * @ingroup Group_EndpointPrimitiveRW
\r
467 * @param corenum : ID Number of USB Core to be processed.
\r
468 * @param Data : Data to write to the currently selected endpoint's FIFO buffer
\r
471 PRAGMA_ALWAYS_INLINE
\r
472 static inline void Endpoint_Write_32_LE(uint8_t corenum, const uint32_t Data) ATTR_ALWAYS_INLINE;
\r
474 static inline void Endpoint_Write_32_LE(uint8_t corenum, const uint32_t Data)
\r
476 Endpoint_Write_8(corenum, Data & 0xFF);
\r
477 Endpoint_Write_8(corenum, (Data >> 8) & 0xFF);
\r
478 Endpoint_Write_8(corenum, (Data >> 16) & 0xFF);
\r
479 Endpoint_Write_8(corenum, (Data >> 24) & 0xFF);
\r
483 * @brief Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
\r
484 * direction endpoints.
\r
486 * @ingroup Group_EndpointPrimitiveRW
\r
488 * @param corenum : ID Number of USB Core to be processed.
\r
489 * @param Data : Data to write to the currently selected endpoint's FIFO buffer
\r
492 PRAGMA_ALWAYS_INLINE
\r
493 static inline void Endpoint_Write_32_BE(uint8_t corenum, const uint32_t Data) ATTR_ALWAYS_INLINE;
\r
495 static inline void Endpoint_Write_32_BE(uint8_t corenum, const uint32_t Data)
\r
497 Endpoint_Write_8(corenum, (Data >> 24) & 0xFF);
\r
498 Endpoint_Write_8(corenum, (Data >> 16) & 0xFF);
\r
499 Endpoint_Write_8(corenum, (Data >> 8) & 0xFF);
\r
500 Endpoint_Write_8(corenum, Data & 0xFF);
\r
504 * @brief Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.
\r
507 * @ingroup Group_EndpointPrimitiveRW
\r
508 * @param corenum : ID Number of USB Core to be processed.
\r
510 PRAGMA_ALWAYS_INLINE
\r
511 static inline void Endpoint_Discard_32(uint8_t corenum) ATTR_ALWAYS_INLINE;
\r
513 static inline void Endpoint_Discard_32(uint8_t corenum)
\r
516 tem = Endpoint_Read_8(corenum);
\r
517 tem = Endpoint_Read_8(corenum);
\r
518 tem = Endpoint_Read_8(corenum);
\r
519 tem = Endpoint_Read_8(corenum);
\r
523 void Endpoint_GetSetupPackage(uint8_t corenum, uint8_t *pData);
\r
526 /* Disable C linkage for C++ Compilers: */
\r
527 #if defined(__cplusplus)
\r