2 * @brief Common USB Pipe 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_PipeManagement
\r
34 * @defgroup Group_PipeRW Pipe Data Reading and Writing
\r
35 * @brief Pipe data read/write definitions.
\r
37 * Functions, macros, variables, enums and types related to data reading and writing from and to pipes.
\r
40 /** @ingroup Group_PipeRW
\r
41 * @defgroup Group_PipePrimitiveRW Read/Write of Primitive Data Types
\r
42 * @brief Pipe 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 pipes.
\r
48 /** @ingroup Group_PipeManagement
\r
49 * @defgroup Group_PipePacketManagement Pipe Packet Management
\r
50 * @brief Pipe packet management definitions.
\r
52 * Functions, macros, variables, enums and types related to packet management of pipes.
\r
55 /** @ingroup Group_PipeManagement
\r
56 * @defgroup Group_PipeControlReq Pipe Control Request Management
\r
57 * @brief Pipe control request definitions.
\r
59 * Module for host mode request processing. This module allows for the transmission of standard, class and
\r
60 * vendor control requests to the default control endpoint of an attached device while in host mode.
\r
62 * @see Chapter 9 of the USB 2.0 specification.
\r
65 /** @ingroup Group_USB
\r
66 * @defgroup Group_PipeManagement Pipe Management
\r
67 * @brief Pipe management definitions.
\r
69 * This module contains functions, macros and enums related to pipe management when in USB Host mode. This
\r
70 * module contains the pipe management macros, as well as pipe interrupt and data send/receive functions
\r
71 * for various data types.
\r
80 #include "../../../Common/Common.h"
\r
81 #include "USBMode.h"
\r
83 /* Enable C linkage for C++ Compilers: */
\r
84 #if defined(__cplusplus)
\r
88 /* Preprocessor Checks: */
\r
89 #if !defined(__INCLUDE_FROM_USB_DRIVER)
\r
90 #error Do not include this file directly. Include lpcroot/libraries/LPCUSBlib/Drivers/USB/USB.h instead.
\r
93 /* Public Interface - May be used in end-application: */
\r
95 /** Pipe address for the default control pipe, which always resides in address 0. This is
\r
96 * defined for convenience to give more readable code when used with the pipe macros.
\r
98 #define PIPE_CONTROLPIPE 0
\r
100 /** Pipe number mask, for masking against pipe addresses to retrieve the pipe's numerical address
\r
103 #define PIPE_PIPENUM_MASK 0x0F
\r
105 /** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
\r
106 * numerical address in the attached device.
\r
108 #define PIPE_EPNUM_MASK 0x0F
\r
110 /** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's
\r
111 * direction for comparing with the \c ENDPOINT_DESCRIPTOR_DIR_* masks.
\r
113 #define PIPE_EPDIR_MASK 0x80
\r
115 #include "USBTask.h"
\r
116 #include "HCD/HCD.h"
\r
117 #include "USBMemory.h" // FIXME move later
\r
118 #include <stdbool.h>
\r
121 /** \name Pipe Error Flag Masks */
\r
123 /** Mask for @ref Pipe_GetErrorFlags(), indicating that an overflow error occurred in the pipe on the received data. */
\r
124 #define PIPE_ERRORFLAG_OVERFLOW (1 << 6)
\r
126 /** Mask for @ref Pipe_GetErrorFlags(), indicating that an underflow error occurred in the pipe on the received data. */
\r
127 #define PIPE_ERRORFLAG_UNDERFLOW (1 << 5)
\r
129 /** Mask for @ref Pipe_GetErrorFlags(), indicating that a CRC error occurred in the pipe on the received data. */
\r
130 #define PIPE_ERRORFLAG_CRC16 (1 << 4)
\r
132 /** Mask for @ref Pipe_GetErrorFlags(), indicating that a hardware timeout error occurred in the pipe. */
\r
133 #define PIPE_ERRORFLAG_TIMEOUT (1 << 3)
\r
135 /** Mask for @ref Pipe_GetErrorFlags(), indicating that a hardware PID error occurred in the pipe. */
\r
136 #define PIPE_ERRORFLAG_PID (1 << 2)
\r
138 /** Mask for @ref Pipe_GetErrorFlags(), indicating that a hardware data PID error occurred in the pipe. */
\r
139 #define PIPE_ERRORFLAG_DATAPID (1 << 1)
\r
141 /** Mask for @ref Pipe_GetErrorFlags(), indicating that a hardware data toggle error occurred in the pipe. */
\r
142 #define PIPE_ERRORFLAG_DATATGL (1 << 0)
\r
145 /** \name Pipe Token Masks */
\r
147 /** Token mask for @ref Pipe_ConfigurePipe(). This sets the pipe as a SETUP token (for CONTROL type pipes),
\r
148 * which will trigger a control request on the attached device when data is written to the pipe.
\r
150 #define PIPE_TOKEN_SETUP (0)
\r
152 /** Token mask for @ref Pipe_ConfigurePipe(). This sets the pipe as a IN token (for non-CONTROL type pipes),
\r
153 * indicating that the pipe data will flow from device to host.
\r
155 #define PIPE_TOKEN_IN (1)
\r
157 /** Token mask for @ref Pipe_ConfigurePipe(). This sets the pipe as a OUT token (for non-CONTROL type pipes),
\r
158 * indicating that the pipe data will flow from host to device.
\r
160 #define PIPE_TOKEN_OUT (2)
\r
163 /** \name Pipe Bank Mode Masks */
\r
165 /** Mask for the bank mode selection for the @ref Pipe_ConfigurePipe() macro. This indicates that the pipe
\r
166 * should have one single bank, which requires less USB FIFO memory but results in slower transfers as
\r
167 * only one USB device (the LPC or the attached device) can access the pipe's bank at the one time.
\r
169 #define PIPE_BANK_SINGLE (0 << 1)
\r
171 /** Mask for the bank mode selection for the @ref Pipe_ConfigurePipe() macro. This indicates that the pipe
\r
172 * should have two banks, which requires more USB FIFO memory but results in faster transfers as one
\r
173 * USB device (the LPC or the attached device) can access one bank while the other accesses the second
\r
176 #define PIPE_BANK_DOUBLE (1 << 1)
\r
179 /** Default size of the default control pipe's bank, until altered by the Endpoint0Size value
\r
180 * in the device descriptor of the attached device.
\r
182 #define PIPE_CONTROLPIPE_DEFAULT_SIZE 8
\r
184 /** Total number of pipes (including the default control pipe at address 0) which may be used in
\r
185 * the device. Different USB LPC models support different amounts of pipes, this value reflects
\r
186 * the maximum number of pipes for the currently selected LPC model.
\r
188 #define PIPE_TOTAL_PIPES HCD_MAX_ENDPOINT
\r
190 /** Size in bytes of the largest pipe bank size possible in the device. Not all banks on each LPC
\r
191 * model supports the largest bank size possible on the device; different pipe numbers support
\r
192 * different maximum bank sizes. This value reflects the largest possible bank of any pipe on the
\r
193 * currently selected USB LPC model.
\r
195 #define PIPE_MAX_SIZE 512
\r
198 /** Enum for the possible error return codes of the @ref Pipe_WaitUntilReady() function.
\r
200 * @ingroup Group_PipeRW
\r
202 enum Pipe_WaitUntilReady_ErrorCodes_t {
\r
203 PIPE_READYWAIT_NoError = 0, /**< Pipe ready for next packet, no error. */
\r
204 PIPE_READYWAIT_PipeStalled = 1, /**< The device stalled the pipe while waiting. */
\r
205 PIPE_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while waiting. */
\r
206 PIPE_READYWAIT_Timeout = 3, /**< The device failed to accept or send the next packet
\r
207 * within the software timeout period set by the
\r
208 * @ref USB_STREAM_TIMEOUT_MS macro.
\r
212 /** Structure stores necessary information to control a pipe
\r
215 uint32_t PipeHandle; /**< Encode chip's USB port number, index to specific transfer array */
\r
216 uint8_t *Buffer; /**< Pointer to share memory space between this pipe and USB module */
\r
217 uint16_t BufferSize; /**< Size of the share memory */
\r
218 uint16_t StartIdx; /**< Indexer inside share buffer */
\r
219 uint16_t ByteTransfered; /**< Number of bytes transfer */
\r
220 uint8_t EndponitAddress; /**< Logical address of connected endpoint */
\r
223 /** Current active USB module number
\r
225 extern uint8_t hostselected;
\r
227 /** USB speed of connected devices
\r
229 extern HCD_USB_SPEED hostportspeed[];
\r
231 /** Array stores current active pipe number of each USB module
\r
233 extern uint8_t pipeselected[MAX_USB_CORE];
\r
235 /** Array stores all pipes \ref USB_Pipe_Data_t information available of all USB modules
\r
237 extern USB_Pipe_Data_t PipeInfo[MAX_USB_CORE][PIPE_TOTAL_PIPES];
\r
239 /* Inline Functions: */
\r
241 * @brief Indicates the number of bytes currently stored in the current pipes's selected bank.
\r
243 * @note The return width of this function may differ, depending on the maximum pipe bank size
\r
244 * of the selected LPC model.
\r
246 * @ingroup Group_PipeRW
\r
248 * @param corenum : USB port number
\r
249 * @return Total number of bytes in the currently selected pipe's FIFO buffer
\r
251 static inline uint16_t Pipe_BytesInPipe(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
253 static inline uint16_t Pipe_BytesInPipe(const uint8_t corenum)
\r
255 return PipeInfo[corenum][pipeselected[corenum]].ByteTransfered - PipeInfo[corenum][pipeselected[corenum]].StartIdx;
\r
259 * @brief Returns the pipe address of the currently selected pipe. This is typically used to save the
\r
260 * currently selected pipe number so that it can be restored after another pipe has been manipulated.
\r
262 * @param corenum : USB port number
\r
263 * @return Index of the currently selected pipe
\r
265 static inline uint8_t Pipe_GetCurrentPipe(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
267 static inline uint8_t Pipe_GetCurrentPipe(const uint8_t corenum)
\r
269 return pipeselected[corenum];
\r
273 * @brief Selects the given pipe number. Any pipe operations which do not require the pipe number to be
\r
274 * indicated will operate on the currently selected pipe.
\r
276 * @param corenum : USB port number
\r
277 * @param PipeNumber : Index of the pipe to select
\r
280 static inline void Pipe_SelectPipe(const uint8_t corenum, const uint8_t PipeNumber) ATTR_ALWAYS_INLINE;
\r
282 static inline void Pipe_SelectPipe(const uint8_t corenum, const uint8_t PipeNumber)
\r
284 pipeselected[corenum] = PipeNumber;
\r
288 * @brief Resets the desired pipe, including the pipe banks and flags
\r
289 * @param corenum : USB port number
\r
290 * @param PipeNumber : Index of the pipe to reset
\r
293 static inline void Pipe_ResetPipe(const uint8_t corenum, const uint8_t PipeNumber) ATTR_ALWAYS_INLINE;
\r
295 static inline void Pipe_ResetPipe(const uint8_t corenum, const uint8_t PipeNumber)
\r
297 PipeInfo[corenum][pipeselected[corenum]].StartIdx = PipeInfo[corenum][pipeselected[corenum]].ByteTransfered = 0;
\r
300 /** Enables the currently selected pipe so that data can be sent and received through it to and from
\r
301 * an attached device.
\r
303 * \pre The currently selected pipe must first be configured properly via @ref Pipe_ConfigurePipe().
\r
305 static inline void Pipe_EnablePipe(void) ATTR_ALWAYS_INLINE;
\r
307 static inline void Pipe_EnablePipe(void)
\r
309 // TODO implement later
\r
312 /** Disables the currently selected pipe so that data cannot be sent and received through it to and
\r
313 * from an attached device.
\r
315 static inline void Pipe_DisablePipe(void) ATTR_ALWAYS_INLINE;
\r
317 static inline void Pipe_DisablePipe(void)
\r
319 // TODO implement later
\r
323 * @brief Determines if the currently selected pipe is enabled, but not necessarily configured
\r
324 * @return Boolean \c true if the currently selected pipe is enabled, \c false otherwise.
\r
326 static inline bool Pipe_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
328 static inline bool Pipe_IsEnabled(void)
\r
330 // TODO implement later
\r
335 * @brief Gets the current pipe token, indicating the pipe's data direction and type
\r
336 * @param corenum : USB port number
\r
337 * @return The current pipe token, as a \c PIPE_TOKEN_* mask.
\r
339 static inline uint8_t Pipe_GetPipeToken(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
341 static inline uint8_t Pipe_GetPipeToken(const uint8_t corenum)
\r
343 return (PipeInfo[corenum][pipeselected[corenum]].EndponitAddress &
\r
344 PIPE_EPDIR_MASK) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT;
\r
348 * @brief Sets the token for the currently selected pipe to one of the tokens specified by the \c PIPE_TOKEN_*
\r
349 * masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during
\r
350 * control requests, or on regular pipes to allow for half-duplex bidirectional data transfer to devices
\r
351 * which have two endpoints of opposite direction sharing the same endpoint address within the device.
\r
353 * @param Token : New pipe token to set the selected pipe to, as a \c PIPE_TOKEN_* mask.
\r
356 static inline void Pipe_SetPipeToken(const uint8_t Token) ATTR_DEPRECATED ATTR_ALWAYS_INLINE;
\r
358 static inline void Pipe_SetPipeToken(const uint8_t Token)
\r
361 /** Configures the currently selected pipe to allow for an unlimited number of IN requests. */
\r
362 static inline void Pipe_SetInfiniteINRequests(void) ATTR_DEPRECATED ATTR_ALWAYS_INLINE;
\r
364 static inline void Pipe_SetInfiniteINRequests(void)
\r
368 * @brief Configures the currently selected pipe to only allow the specified number of IN requests to be
\r
369 * accepted by the pipe before it is automatically frozen.
\r
371 * @param TotalINRequests : Total number of IN requests that the pipe may receive before freezing
\r
374 static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) ATTR_DEPRECATED ATTR_ALWAYS_INLINE;
\r
376 static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests)
\r
380 * @brief Determines if the currently selected pipe is configured.
\r
381 * @param corenum : USB port number
\r
382 * @return Boolean \c true if the selected pipe is configured, \c false otherwise.
\r
384 static inline bool Pipe_IsConfigured(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
386 static inline bool Pipe_IsConfigured(const uint8_t corenum)
\r
388 return PipeInfo[corenum][pipeselected[corenum]].Buffer != NULL; // TODO implement using status later
\r
392 * @brief Retrieves the endpoint address of the endpoint within the attached device that the currently selected
\r
393 * pipe is bound to.
\r
395 * @param corenum : USB port number
\r
396 * @return address the currently selected pipe is bound to.
\r
398 static inline uint8_t Pipe_GetBoundEndpointAddress(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
400 static inline uint8_t Pipe_GetBoundEndpointAddress(const uint8_t corenum)
\r
402 return PipeInfo[corenum][pipeselected[corenum]].EndponitAddress;
\r
406 * @brief Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds
\r
407 * @param Milliseconds : Number of milliseconds between each pipe poll.
\r
410 static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) ATTR_ALWAYS_INLINE;
\r
412 static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds)
\r
414 // TODO implement later
\r
418 * @brief Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should
\r
420 * @return Mask whose bits indicate which pipes have interrupted.
\r
422 static inline uint8_t Pipe_GetPipeInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
424 static inline uint8_t Pipe_GetPipeInterrupts(void)
\r
426 return 0; // TODO implement later
\r
430 * @brief Determines if the specified pipe number has interrupted (valid only for INTERRUPT type
\r
433 * @param PipeNumber : Index of the pipe whose interrupt flag should be tested
\r
434 * @return Boolean \c true if the specified pipe has interrupted, \c false otherwise.
\r
436 static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
438 static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber)
\r
440 return false; // TODO implement later
\r
443 /** Unfreezes the selected pipe, allowing it to communicate with an attached device. */
\r
444 static inline void Pipe_Unfreeze(void) ATTR_ALWAYS_INLINE;
\r
446 static inline void Pipe_Unfreeze(void)
\r
448 // TODO implement later
\r
451 /** Freezes the selected pipe, preventing it from communicating with an attached device. */
\r
452 static inline void Pipe_Freeze(void) ATTR_ALWAYS_INLINE;
\r
454 static inline void Pipe_Freeze(void)
\r
456 // TODO implement later
\r
460 * @brief Determines if the currently selected pipe is frozen, and not able to accept data.
\r
461 * @return Boolean \c true if the currently selected pipe is frozen, \c false otherwise.
\r
463 static inline bool Pipe_IsFrozen(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
465 static inline bool Pipe_IsFrozen(void)
\r
467 return false; // TODO implement later
\r
470 /** Clears the error flags for the currently selected pipe. */
\r
471 static inline void Pipe_ClearError(void) ATTR_ALWAYS_INLINE;
\r
473 static inline void Pipe_ClearError(void)
\r
475 // TODO implement later
\r
479 * @brief Determines if the master pipe error flag is set for the currently selected pipe, indicating that
\r
480 * some sort of hardware error has occurred on the pipe.
\r
482 * \see @ref Pipe_GetErrorFlags() macro for information on retrieving the exact error flag.
\r
484 * @return Boolean \c true if an error has occurred on the selected pipe, \c false otherwise.
\r
486 static inline bool Pipe_IsError(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
488 static inline bool Pipe_IsError(void)
\r
490 return false; // TODO implement later
\r
494 * @brief Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This
\r
495 * value can then be masked against the \c PIPE_ERRORFLAG_* masks to determine what error has occurred.
\r
497 * @return Mask comprising of \c PIPE_ERRORFLAG_* bits indicating what error has occurred on the selected pipe.
\r
499 static inline uint8_t Pipe_GetErrorFlags(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
501 static inline uint8_t Pipe_GetErrorFlags(void)
\r
503 return 0; // TODO implement later
\r
507 * @brief Retrieves the number of busy banks in the currently selected pipe, which have been queued for
\r
508 * transmission via the @ref Pipe_ClearOUT() command, or are awaiting acknowledgement via the
\r
509 * @ref Pipe_ClearIN() command.
\r
511 * @ingroup Group_PipePacketManagement
\r
513 * @return Total number of busy banks in the selected pipe.
\r
515 static inline uint8_t Pipe_GetBusyBanks(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
517 static inline uint8_t Pipe_GetBusyBanks(void)
\r
519 return 0; // TODO implement later
\r
523 * @brief Determines if a packet has been received on the currently selected IN pipe from the attached device.
\r
525 * @ingroup Group_PipePacketManagement
\r
527 * @param corenum : USB port number
\r
528 * @return Boolean \c true if the current pipe has received an IN packet, \c false otherwise.
\r
530 // static inline bool Pipe_IsINReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
531 bool Pipe_IsINReceived(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT;
\r
534 * @brief Determines if the currently selected OUT pipe is ready to send an OUT packet to the attached device.
\r
536 * @ingroup Group_PipePacketManagement
\r
538 * @param corenum : USB port number
\r
539 * @return Boolean \c true if the current pipe is ready for an OUT packet, \c false otherwise.
\r
541 static inline bool Pipe_IsOUTReady(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
543 static inline bool Pipe_IsOUTReady(const uint8_t corenum)
\r
545 return (HcdGetPipeStatus(PipeInfo[corenum][pipeselected[corenum]].PipeHandle) == HCD_STATUS_OK)
\r
546 && (PipeInfo[corenum][pipeselected[corenum]].ByteTransfered <
\r
547 PipeInfo[corenum][pipeselected[corenum]].BufferSize);
\r
551 * @brief Determines if the currently selected pipe may be read from (if data is waiting in the pipe
\r
552 * bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT
\r
553 * direction). This function will return false if an error has occurred in the pipe, or if the pipe
\r
554 * is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT
\r
555 * direction and the pipe bank is full.
\r
557 * @note This function is not valid on CONTROL type pipes.
\r
559 * @ingroup Group_PipePacketManagement
\r
561 * @param corenum : USB port number
\r
562 * @return Boolean \c true if the currently selected pipe may be read from or written to, depending
\r
563 * on its direction.
\r
565 static inline bool Pipe_IsReadWriteAllowed(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
567 static inline bool Pipe_IsReadWriteAllowed(const uint8_t corenum)
\r
569 if (Pipe_GetPipeToken(corenum) == PIPE_TOKEN_IN) {
\r
570 return (HCD_STATUS_OK == HcdGetPipeStatus(PipeInfo[corenum][pipeselected[corenum]].PipeHandle)) &&
\r
571 Pipe_BytesInPipe(corenum);
\r
574 return Pipe_IsOUTReady(corenum);
\r
579 * @brief Determines if pipe's status is OK
\r
581 * @ingroup Group_PipePacketManagement
\r
583 * @return Boolean \c true if the current pipe's status is OK , \c false otherwise.
\r
585 static inline bool Pipe_IsStatusOK(uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
586 static inline bool Pipe_IsStatusOK(uint8_t corenum)
\r
588 return (HCD_STATUS_OK == HcdGetPipeStatus(PipeInfo[corenum][pipeselected[corenum]].PipeHandle));
\r
592 * @brief Determines if no SETUP request is currently being sent to the attached device on the selected
\r
593 * CONTROL type pipe.
\r
595 * @ingroup Group_PipePacketManagement
\r
597 * @return Boolean \c true if the current pipe is ready for a SETUP packet, \c false otherwise.
\r
599 static inline bool Pipe_IsSETUPSent(void) ATTR_DEPRECATED ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
601 static inline bool Pipe_IsSETUPSent(void)
\r
606 /** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet.
\r
608 * @ingroup Group_PipePacketManagement
\r
610 static inline void Pipe_ClearSETUP(void) ATTR_DEPRECATED ATTR_ALWAYS_INLINE;
\r
612 static inline void Pipe_ClearSETUP(void)
\r
615 /** Acknowledges the reception of a setup IN request from the attached device on the currently selected
\r
616 * pipe, freeing the bank ready for the next packet.
\r
618 * @ingroup Group_PipePacketManagement
\r
619 * @param corenum : USB port number
\r
621 static inline void Pipe_ClearIN(const uint8_t corenum) ATTR_ALWAYS_INLINE;
\r
623 static inline void Pipe_ClearIN(const uint8_t corenum)
\r
625 PipeInfo[corenum][pipeselected[corenum]].StartIdx = PipeInfo[corenum][pipeselected[corenum]].ByteTransfered = 0;
\r
628 /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing
\r
629 * the bank ready for the next packet.
\r
631 * @ingroup Group_PipePacketManagement
\r
632 * @param corenum : USB port number
\r
634 static inline void Pipe_ClearOUT(const uint8_t corenum) ATTR_ALWAYS_INLINE;
\r
636 static inline void Pipe_ClearOUT(const uint8_t corenum)
\r
638 HcdDataTransfer(PipeInfo[corenum][pipeselected[corenum]].PipeHandle,
\r
639 PipeInfo[corenum][pipeselected[corenum]].Buffer,
\r
640 PipeInfo[corenum][pipeselected[corenum]].ByteTransfered,
\r
641 NULL /* FIXME &PipeInfo[pipeselected].ByteTransfered*/);
\r
642 PipeInfo[corenum][pipeselected[corenum]].StartIdx = PipeInfo[corenum][pipeselected[corenum]].ByteTransfered = 0;
\r
646 * @brief Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on
\r
647 * the currently selected pipe. This occurs when the host sends a packet to the device, but the device
\r
648 * is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been
\r
649 * received, it must be cleared using @ref Pipe_ClearNAKReceived() before the previous (or any other) packet
\r
652 * @ingroup Group_PipePacketManagement
\r
654 * @return Boolean \c true if an NAK has been received on the current pipe, \c false otherwise.
\r
656 static inline bool Pipe_IsNAKReceived(void) ATTR_DEPRECATED ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
658 static inline bool Pipe_IsNAKReceived(void)
\r
663 /** Clears the NAK condition on the currently selected pipe.
\r
665 * @ingroup Group_PipePacketManagement
\r
667 * \see @ref Pipe_IsNAKReceived() for more details.
\r
669 static inline void Pipe_ClearNAKReceived(void) ATTR_DEPRECATED ATTR_ALWAYS_INLINE;
\r
671 static inline void Pipe_ClearNAKReceived(void)
\r
675 * @brief Determines if the currently selected pipe has had the STALL condition set by the attached device.
\r
677 * @ingroup Group_PipePacketManagement
\r
679 * @param corenum : USB port number
\r
680 * @return Boolean \c true if the current pipe has been stalled by the attached device, \c false otherwise.
\r
682 static inline bool Pipe_IsStalled(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
684 static inline bool Pipe_IsStalled(const uint8_t corenum)
\r
686 return HcdGetPipeStatus(PipeInfo[corenum][pipeselected[corenum]].PipeHandle) == HCD_STATUS_TRANSFER_Stall;
\r
689 /** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the
\r
690 * STALL condition itself (this must be done via a ClearFeature control request to the device).
\r
692 * @ingroup Group_PipePacketManagement
\r
693 * @param corenum : USB port number
\r
695 static inline void Pipe_ClearStall(const uint8_t corenum) ATTR_ALWAYS_INLINE;
\r
697 static inline void Pipe_ClearStall(const uint8_t corenum)
\r
699 HcdClearEndpointHalt(PipeInfo[corenum][pipeselected[corenum]].PipeHandle);
\r
703 * @brief Reads one byte from the currently selected pipe's bank, for OUT direction pipes
\r
705 * @ingroup Group_PipePrimitiveRW
\r
707 * @param corenum : USB port number
\r
708 * @return Next byte in the currently selected pipe's FIFO buffer
\r
710 static inline uint8_t Pipe_Read_8(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
712 static inline uint8_t Pipe_Read_8(const uint8_t corenum)
\r
714 if (PipeInfo[corenum][pipeselected[corenum]].StartIdx < PipeInfo[corenum][pipeselected[corenum]].ByteTransfered ) {
\r
716 PipeInfo[corenum][pipeselected[corenum]].Buffer[PipeInfo[corenum][pipeselected[corenum]].StartIdx];
\r
717 PipeInfo[corenum][pipeselected[corenum]].StartIdx++;
\r
726 * @brief Writes one byte to the currently selected pipe's bank, for IN direction pipes
\r
728 * @ingroup Group_PipePrimitiveRW
\r
730 * @param corenum : USB port number
\r
731 * @param Data : Data to write into the the currently selected pipe's FIFO buffer
\r
734 static inline void Pipe_Write_8(const uint8_t corenum, const uint8_t Data) ATTR_ALWAYS_INLINE;
\r
736 static inline void Pipe_Write_8(const uint8_t corenum, const uint8_t Data)
\r
738 if (PipeInfo[corenum][pipeselected[corenum]].ByteTransfered <
\r
739 PipeInfo[corenum][pipeselected[corenum]].BufferSize) {
\r
740 PipeInfo[corenum][pipeselected[corenum]].Buffer[PipeInfo[corenum][pipeselected[corenum]].ByteTransfered] = Data;
\r
741 PipeInfo[corenum][pipeselected[corenum]].ByteTransfered++;
\r
745 /** Discards one byte from the currently selected pipe's bank, for OUT direction pipes.
\r
747 * @ingroup Group_PipePrimitiveRW
\r
749 static inline void Pipe_Discard_8(void) ATTR_ALWAYS_INLINE;
\r
751 static inline void Pipe_Discard_8(void)
\r
755 * @brief Reads two bytes from the currently selected pipe's bank in little endian format, for OUT
\r
758 * @ingroup Group_PipePrimitiveRW
\r
760 * @param corenum : USB port number
\r
761 * @return Next two bytes in the currently selected pipe's FIFO buffer.
\r
763 static inline uint16_t Pipe_Read_16_LE(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
765 static inline uint16_t Pipe_Read_16_LE(const uint8_t corenum)
\r
768 uint8_t tem1, tem2;
\r
770 tem1 = Pipe_Read_8(corenum);
\r
771 tem2 = Pipe_Read_8(corenum);
\r
772 tem = (tem2 << 8) | tem1;
\r
777 * @brief Reads two bytes from the currently selected pipe's bank in big endian format, for OUT
\r
780 * @ingroup Group_PipePrimitiveRW
\r
782 * @param corenum : USB port number
\r
783 * @return Next two bytes in the currently selected pipe's FIFO buffer.
\r
785 static inline uint16_t Pipe_Read_16_BE(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
787 static inline uint16_t Pipe_Read_16_BE(const uint8_t corenum)
\r
790 uint8_t tem1, tem2;
\r
792 tem1 = Pipe_Read_8(corenum);
\r
793 tem2 = Pipe_Read_8(corenum);
\r
794 tem = (tem1 << 8) | tem2;
\r
799 * @brief Writes two bytes to the currently selected pipe's bank in little endian format, for IN
\r
802 * @ingroup Group_PipePrimitiveRW
\r
804 * @param corenum : USB port number
\r
805 * @param Data : Data to write to the currently selected pipe's FIFO buffer
\r
808 static inline void Pipe_Write_16_LE(const uint8_t corenum, const uint16_t Data) ATTR_ALWAYS_INLINE;
\r
810 static inline void Pipe_Write_16_LE(const uint8_t corenum, const uint16_t Data)
\r
812 Pipe_Write_8(corenum, Data & 0xFF);
\r
813 Pipe_Write_8(corenum, (Data >> 8) & 0xFF);
\r
817 * @brief Writes two bytes to the currently selected pipe's bank in big endian format, for IN
\r
820 * @ingroup Group_PipePrimitiveRW
\r
822 * @param corenum : USB port number
\r
823 * @param Data : Data to write to the currently selected pipe's FIFO buffer.
\r
826 static inline void Pipe_Write_16_BE(const uint8_t corenum, const uint16_t Data) ATTR_ALWAYS_INLINE;
\r
828 static inline void Pipe_Write_16_BE(const uint8_t corenum, const uint16_t Data)
\r
830 Pipe_Write_8(corenum, (Data >> 8) & 0xFF);
\r
831 Pipe_Write_8(corenum, Data & 0xFF);
\r
834 /** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes.
\r
836 * @ingroup Group_PipePrimitiveRW
\r
838 static inline void Pipe_Discard_16(void) ATTR_ALWAYS_INLINE;
\r
840 static inline void Pipe_Discard_16(void)
\r
844 * @brief Reads four bytes from the currently selected pipe's bank in little endian format, for OUT
\r
847 * @ingroup Group_PipePrimitiveRW
\r
849 * @param corenum : USB port number
\r
850 * @return Next four bytes in the currently selected pipe's FIFO buffer.
\r
852 static inline uint32_t Pipe_Read_32_LE(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
854 static inline uint32_t Pipe_Read_32_LE(const uint8_t corenum)
\r
857 uint8_t tem1, tem2, tem3, tem4;
\r
859 tem1 = Pipe_Read_8(corenum);
\r
860 tem2 = Pipe_Read_8(corenum);
\r
861 tem3 = Pipe_Read_8(corenum);
\r
862 tem4 = Pipe_Read_8(corenum);
\r
863 tem = (tem4 << 24) | (tem3 << 16) | (tem2 << 8) | tem1;
\r
868 * @brief Reads four bytes from the currently selected pipe's bank in big endian format, for OUT
\r
871 * @ingroup Group_PipePrimitiveRW
\r
873 * @param corenum : USB port number
\r
874 * @return Next four bytes in the currently selected pipe's FIFO buffer.
\r
876 static inline uint32_t Pipe_Read_32_BE(const uint8_t corenum) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
\r
878 static inline uint32_t Pipe_Read_32_BE(const uint8_t corenum)
\r
881 uint8_t tem1, tem2, tem3, tem4;
\r
883 tem1 = Pipe_Read_8(corenum);
\r
884 tem2 = Pipe_Read_8(corenum);
\r
885 tem3 = Pipe_Read_8(corenum);
\r
886 tem4 = Pipe_Read_8(corenum);
\r
887 tem = (tem1 << 24) | (tem2 << 16) | (tem3 << 8) | tem4;
\r
892 * @brief Writes four bytes to the currently selected pipe's bank in little endian format, for IN
\r
895 * @ingroup Group_PipePrimitiveRW
\r
897 * @param corenum : USB port number
\r
898 * @param Data : Data to write to the currently selected pipe's FIFO buffer.
\r
901 static inline void Pipe_Write_32_LE(const uint8_t corenum, const uint32_t Data) ATTR_ALWAYS_INLINE;
\r
903 static inline void Pipe_Write_32_LE(const uint8_t corenum, const uint32_t Data)
\r
905 Pipe_Write_8(corenum, Data & 0xFF);
\r
906 Pipe_Write_8(corenum, (Data >> 8) & 0xFF);
\r
907 Pipe_Write_8(corenum, (Data >> 16) & 0xFF);
\r
908 Pipe_Write_8(corenum, (Data >> 24) & 0xFF);
\r
912 * @brief Writes four bytes to the currently selected pipe's bank in big endian format, for IN
\r
915 * @ingroup Group_PipePrimitiveRW
\r
917 * @param corenum : USB port number
\r
918 * @param Data : Data to write to the currently selected pipe's FIFO buffer
\r
921 static inline void Pipe_Write_32_BE(const uint8_t corenum, const uint32_t Data) ATTR_ALWAYS_INLINE;
\r
923 static inline void Pipe_Write_32_BE(const uint8_t corenum, const uint32_t Data)
\r
925 Pipe_Write_8(corenum, (Data >> 24) & 0xFF);
\r
926 Pipe_Write_8(corenum, (Data >> 16) & 0xFF);
\r
927 Pipe_Write_8(corenum, (Data >> 8) & 0xFF);
\r
928 Pipe_Write_8(corenum, Data & 0xFF);
\r
931 /** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes.
\r
933 * @ingroup Group_PipePrimitiveRW
\r
935 static inline void Pipe_Discard_32(void) ATTR_ALWAYS_INLINE;
\r
937 static inline void Pipe_Discard_32(void)
\r
940 /* External Variables: */
\r
941 /** Global indicating the maximum packet size of the default control pipe located at address
\r
942 * 0 in the device. This value is set to the value indicated in the attached device's device
\r
943 * descriptor once the USB interface is initialized into host mode and a device is attached
\r
946 * @note This variable should be treated as read-only in the user application, and never manually
\r
947 * changed in value.
\r
950 /* Function Prototypes: */
\r
952 * @brief Configures the specified pipe number with the given pipe type, token, target endpoint number in the
\r
953 * attached device, bank size and banking mode.
\r
955 * A newly configured pipe is frozen by default, and must be unfrozen before use via the @ref Pipe_Unfreeze()
\r
956 * before being used. Pipes should be kept frozen unless waiting for data from a device while in IN mode, or
\r
957 * sending data to the device in OUT mode. IN type pipes are also automatically configured to accept infinite
\r
958 * numbers of IN requests without automatic freezing - this can be overridden by a call to
\r
959 * @ref Pipe_SetFiniteINRequests().
\r
960 * @param corenum : USB port number
\r
961 * @param Number : Pipe number to configure. This must be more than 0 and less than @ref PIPE_TOTAL_PIPES.
\r
962 * @param Type : Type of pipe to configure, an \c EP_TYPE_* mask. Not all pipe types are available on Low
\r
963 * Speed USB devices - refer to the USB 2.0 specification.
\r
964 * @param Token : Pipe data token, either @ref PIPE_TOKEN_SETUP, @ref PIPE_TOKEN_OUT or @ref PIPE_TOKEN_IN.
\r
965 * All pipes (except Control type) are unidirectional - data may only be read from or
\r
966 * written to the pipe bank based on its direction, not both.
\r
967 * @param EndpointNumber : Endpoint index within the attached device that the pipe should interface to.
\r
968 * @param Size : Size of the pipe's bank, where packets are stored before they are transmitted to
\r
969 * the USB device, or after they have been received from the USB device (depending on
\r
970 * the pipe's data direction). The bank size must indicate the maximum packet size that
\r
971 * the pipe can handle.
\r
972 * @param Banks : Number of banks to use for the pipe being configured, a \c PIPE_BANK_* mask. More banks
\r
973 * uses more USB DPRAM, but offers better performance. Isochronous type pipes <b>must</b>
\r
974 * have at least two banks.
\r
975 * @note When the \c ORDERED_EP_CONFIG compile time option is used, Pipes <b>must</b> be configured in ascending order,
\r
976 * or bank corruption will occur.
\r
979 * @note Certain microcontroller model's pipes may have different maximum packet sizes based on the pipe's
\r
980 * index - refer to the chosen microcontroller's datasheet to determine the maximum bank size for each pipe.
\r
983 * @note The default control pipe should not be manually configured by the user application, as it is
\r
984 * automatically configured by the library internally.
\r
987 * @note This routine will automatically select the specified pipe upon success. Upon failure, the pipe which
\r
988 * failed to reconfigure correctly will be selected.
\r
990 * @return Boolean \c true if the configuration succeeded, \c false otherwise.
\r
992 bool Pipe_ConfigurePipe(const uint8_t corenum,
\r
993 const uint8_t Number,
\r
994 const uint8_t Type,
\r
995 const uint8_t Token,
\r
996 const uint8_t EndpointNumber,
\r
997 const uint16_t Size,
\r
998 const uint8_t Banks);
\r
1000 void Pipe_ClosePipe(const uint8_t corenum, uint8_t pipenum);
\r
1003 * @brief Spin-loops until the currently selected non-control pipe is ready for the next packed of data to be read
\r
1004 * or written to it, aborting in the case of an error condition (such as a timeout or device disconnect).
\r
1006 * @ingroup Group_PipeRW
\r
1008 * @return A value from the @ref Pipe_WaitUntilReady_ErrorCodes_t enum
\r
1010 uint8_t Pipe_WaitUntilReady(const uint8_t corenum);
\r
1013 * @brief Determines if a pipe has been bound to the given device endpoint address. If a pipe which is bound to the given
\r
1014 * endpoint is found, it is automatically selected.
\r
1016 * @param EndpointAddress : EndpointAddress Address and direction mask of the endpoint within the attached device to check
\r
1017 * @return Boolean \c true if a pipe bound to the given endpoint address of the specified direction is found,
\r
1018 * \c false otherwise.
\r
1020 bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) ATTR_WARN_UNUSED_RESULT;
\r
1022 /* Private Interface - For use in library only: */
\r
1023 #if !defined(__DOXYGEN__)
\r
1025 #if !defined(ENDPOINT_CONTROLEP)
\r
1026 #define ENDPOINT_CONTROLEP 0
\r
1029 /* Inline Functions: */
\r
1030 static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
\r
1031 ATTR_ALWAYS_INLINE;
\r
1033 static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes)
\r
1035 return 0; // implement later
\r
1038 /* Function Prototypes: */
\r
1039 void Pipe_ClearPipes(void);
\r
1043 /* Disable C linkage for C++ Compilers: */
\r
1044 #if defined(__cplusplus)
\r