+                               return UPBCX;
+                       }
+                       
+                       /** Returns the pipe address of the currently selected pipe. This is typically used to save the
+                        *  currently selected pipe number so that it can be restored after another pipe has been manipulated.
+                        *
+                        *  \return Index of the currently selected pipe.
+                        */
+                       static inline uint8_t Pipe_GetCurrentPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline uint8_t Pipe_GetCurrentPipe(void)
+                       {
+                               return (UPNUM & PIPE_PIPENUM_MASK);
+                       }
+
+                       /** Selects the given pipe number. Any pipe operations which do not require the pipe number to be
+                        *  indicated will operate on the currently selected pipe.
+                        *
+                        *  \param[in] PipeNumber  Index of the pipe to select.
+                        */
+                       static inline void Pipe_SelectPipe(const uint8_t PipeNumber) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_SelectPipe(const uint8_t PipeNumber)
+                       {
+                               UPNUM = PipeNumber;
+                       }
+                       
+                       /** Resets the desired pipe, including the pipe banks and flags.
+                        *
+                        *  \param[in] PipeNumber  Index of the pipe to reset.
+                        */
+                       static inline void Pipe_ResetPipe(const uint8_t PipeNumber) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ResetPipe(const uint8_t PipeNumber)
+                       {
+                               UPRST = (1 << PipeNumber);
+                               UPRST = 0;
+                       }
+                       
+                       /** Enables the currently selected pipe so that data can be sent and received through it to and from
+                        *  an attached device.
+                        *
+                        *  \pre The currently selected pipe must first be configured properly via \ref Pipe_ConfigurePipe().
+                        */
+                       static inline void Pipe_EnablePipe(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_EnablePipe(void)
+                       {
+                               UPCONX |= (1 << PEN);
+                       }
+
+                       /** Disables the currently selected pipe so that data cannot be sent and received through it to and
+                        *  from an attached device.
+                        */
+                       static inline void Pipe_DisablePipe(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_DisablePipe(void)
+                       {
+                               UPCONX &= ~(1 << PEN);
+                       }
+
+                       /** Determines if the currently selected pipe is enabled, but not necessarily configured.
+                        *
+                        * \return Boolean True if the currently selected pipe is enabled, false otherwise.
+                        */
+                       static inline bool Pipe_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsEnabled(void)
+                       {
+                               return ((UPCONX & (1 << PEN)) ? true : false);
+                       }
+                       
+                       /** Gets the current pipe token, indicating the pipe's data direction and type.
+                        *
+                        *  \return The current pipe token, as a PIPE_TOKEN_* mask.
+                        */
+                       static inline uint8_t Pipe_GetPipeToken(void) ATTR_ALWAYS_INLINE;
+                       static inline uint8_t Pipe_GetPipeToken(void)
+                       {
+                               return (UPCFG0X & (0x03 << PTOKEN0));
+                       }
+                       
+                       /** Sets the token for the currently selected pipe to one of the tokens specified by the PIPE_TOKEN_*
+                        *  masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during
+                        *  control requests, or on regular pipes to allow for half-duplex bidirectional data transfer to devices
+                        *  which have two endpoints of opposite direction sharing the same endpoint address within the device.
+                        *
+                        *  \param[in] Token  New pipe token to set the selected pipe to, as a PIPE_TOKEN_* mask.
+                        */
+                       static inline void Pipe_SetPipeToken(const uint8_t Token) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_SetPipeToken(const uint8_t Token)
+                       {
+                               UPCFG0X = ((UPCFG0X & ~(0x03 << PTOKEN0)) | Token);
+                       }
+                       
+                       /** Configures the currently selected pipe to allow for an unlimited number of IN requests. */
+                       static inline void Pipe_SetInfiniteINRequests(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_SetInfiniteINRequests(void)
+                       {
+                               UPCONX |= (1 << INMODE);
+                       }
+                       
+                       /** Configures the currently selected pipe to only allow the specified number of IN requests to be
+                        *  accepted by the pipe before it is automatically frozen.
+                        *
+                        *  \param[in] TotalINRequests  Total number of IN requests that the pipe may receive before freezing.
+                        */
+                       static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests)
+                       {
+                               UPCONX &= ~(1 << INMODE);
+                               UPINRQX = TotalINRequests;
+                       }
+
+                       /** Determines if the currently selected pipe is configured.
+                        *
+                        *  \return Boolean true if the selected pipe is configured, false otherwise.
+                        */
+                       static inline bool Pipe_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsConfigured(void)
+                       {
+                               return ((UPSTAX & (1 << CFGOK)) ? true : false);
+                       }
+                       
+                       /** Retrieves the endpoint number of the endpoint within the attached device that the currently selected
+                        *  pipe is bound to.
+                        *
+                        *  \return Endpoint number the currently selected pipe is bound to.
+                        */
+                       static inline uint8_t Pipe_BoundEndpointNumber(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline uint8_t Pipe_BoundEndpointNumber(void)
+                       {
+                               return ((UPCFG0X >> PEPNUM0) & PIPE_EPNUM_MASK);
+                       }
+
+                       /** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds.
+                        *
+                        *  \param[in] Milliseconds  Number of milliseconds between each pipe poll.
+                        */
+                       static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds)
+                       {
+                               UPCFG2X = Milliseconds;
+                       }
+                       
+                       /** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should
+                        *  be serviced.
+                        *
+                        *  \return Mask whose bits indicate which pipes have interrupted.
+                        */
+                       static inline uint8_t Pipe_GetPipeInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline uint8_t Pipe_GetPipeInterrupts(void)
+                       {
+                               return UPINT;
+                       }
+                       
+                       /** Determines if the specified pipe number has interrupted (valid only for INTERRUPT type
+                        *  pipes).
+                        *
+                        *  \param[in] PipeNumber  Index of the pipe whose interrupt flag should be tested.
+                        *
+                        *  \return Boolean true if the specified pipe has interrupted, false otherwise.
+                        */
+                       static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber)
+                       {
+                               return ((UPINT & (1 << PipeNumber)) ? true : false);
+                       }
+                       
+                       /** Unfreezes the selected pipe, allowing it to communicate with an attached device. */
+                       static inline void Pipe_Unfreeze(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_Unfreeze(void)
+                       {
+                               UPCONX &= ~(1 << PFREEZE);
+                       }
+                       
+                       /** Freezes the selected pipe, preventing it from communicating with an attached device. */
+                       static inline void Pipe_Freeze(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_Freeze(void)
+                       {
+                               UPCONX |= (1 << PFREEZE);
+                       }
+
+                       /** Determines if the currently selected pipe is frozen, and not able to accept data.
+                        *
+                        *  \return Boolean true if the currently selected pipe is frozen, false otherwise.
+                        */
+                       static inline bool Pipe_IsFrozen(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsFrozen(void)
+                       {
+                               return ((UPCONX & (1 << PFREEZE)) ? true : false);
+                       }
+                       
+                       /** Clears the master pipe error flag. */
+                       static inline void Pipe_ClearError(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ClearError(void)
+                       {
+                               UPINTX &= ~(1 << PERRI);
+                       }
+                       
+                       /** Determines if the master pipe error flag is set for the currently selected pipe, indicating that
+                        *  some sort of hardware error has occurred on the pipe.
+                        *
+                        *  \see \ref Pipe_GetErrorFlags() macro for information on retrieving the exact error flag.
+                        *
+                        *  \return Boolean true if an error has occurred on the selected pipe, false otherwise.
+                        */
+                       static inline bool Pipe_IsError(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsError(void)
+                       {
+                               return ((UPINTX & (1 << PERRI)) ? true : false);
+                       }
+                       
+                       /** Clears all the currently selected pipe's hardware error flags, but does not clear the master error
+                        *  flag for the pipe.
+                        */
+                       static inline void Pipe_ClearErrorFlags(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ClearErrorFlags(void)
+                       {
+                               UPERRX = 0;
+                       }
+                       
+                       /** Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This
+                        *  value can then be masked against the PIPE_ERRORFLAG_* masks to determine what error has occurred.
+                        *
+                        *  \return  Mask comprising of PIPE_ERRORFLAG_* bits indicating what error has occurred on the selected pipe.
+                        */
+                       static inline uint8_t Pipe_GetErrorFlags(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline uint8_t Pipe_GetErrorFlags(void)
+                       {
+                               return ((UPERRX & (PIPE_ERRORFLAG_CRC16 | PIPE_ERRORFLAG_TIMEOUT |
+                                                  PIPE_ERRORFLAG_PID   | PIPE_ERRORFLAG_DATAPID |
+                                                  PIPE_ERRORFLAG_DATATGL)) |
+                                       (UPSTAX & (PIPE_ERRORFLAG_OVERFLOW | PIPE_ERRORFLAG_UNDERFLOW)));
+                       }
+                       
+                       /** Determines if the currently selected pipe may be read from (if data is waiting in the pipe
+                        *  bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT
+                        *  direction). This function will return false if an error has occurred in the pipe, or if the pipe
+                        *  is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT
+                        *  direction and the pipe bank is full.
+                        *
+                        *  \note This function is not valid on CONTROL type pipes.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        *  
+                        *  \return Boolean true if the currently selected pipe may be read from or written to, depending on its direction.
+                        */
+                       static inline bool Pipe_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsReadWriteAllowed(void)
+                       {
+                               return ((UPINTX & (1 << RWAL)) ? true : false);
+                       }
+                       
+                       /** Determines if an IN request has been received on the currently selected pipe.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        *
+                        *  \return Boolean true if the current pipe has received an IN packet, false otherwise.
+                        */
+                       static inline bool Pipe_IsINReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsINReceived(void)
+                       {
+                               return ((UPINTX & (1 << RXINI)) ? true : false);
+                       }
+                       
+                       /** Determines if the currently selected pipe is ready to send an OUT request.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        *
+                        *  \return Boolean true if the current pipe is ready for an OUT packet, false otherwise.
+                        */
+                       static inline bool Pipe_IsOUTReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsOUTReady(void)
+                       {
+                               return ((UPINTX & (1 << TXOUTI)) ? true : false);
+                       }
+
+                       /** Determines if no SETUP request is currently being sent to the attached device on the selected
+                        *  CONTROL type pipe.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        *
+                        *  \return Boolean true if the current pipe is ready for a SETUP packet, false otherwise.
+                        */
+                       static inline bool Pipe_IsSETUPSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsSETUPSent(void)
+                       {
+                               return ((UPINTX & (1 << TXSTPI)) ? true : false);
+                       }
+                       
+                       /** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet.
+                        *
+                        *  \ingroup Group_PipePacketManagement         
+                        */
+                       static inline void Pipe_ClearSETUP(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ClearSETUP(void)
+                       {
+                               UPINTX &= ~((1 << TXSTPI) | (1 << FIFOCON));
+                       }
+
+                       /** Acknowledges the reception of a setup IN request from the attached device on the currently selected
+                        *  pipe, freeing the bank ready for the next packet.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        */
+                       static inline void Pipe_ClearIN(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ClearIN(void)
+                       {
+                               UPINTX &= ~((1 << RXINI) | (1 << FIFOCON));
+                       }
+
+                       /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing
+                        *  the bank ready for the next packet.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        */
+                       static inline void Pipe_ClearOUT(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ClearOUT(void)
+                       {
+                               UPINTX &= ~((1 << TXOUTI) | (1 << FIFOCON));
+                       }
+
+                       /** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on
+                        *  the currently selected pipe. This occurs when the host sends a packet to the device, but the device
+                        *  is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been
+                        *  received, it must be cleared using \ref Pipe_ClearNAKReceived() before the previous (or any other) packet
+                        *  can be re-sent.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        *
+                        *  \return Boolean true if an NAK has been received on the current pipe, false otherwise.
+                        */
+                       static inline bool Pipe_IsNAKReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsNAKReceived(void)
+                       {
+                               return ((UPINTX & (1 << NAKEDI)) ? true : false);
+                       }
+
+                       /** Clears the NAK condition on the currently selected pipe.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        *
+                        *  \see \ref Pipe_IsNAKReceived() for more details.
+                        */
+                       static inline void Pipe_ClearNAKReceived(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ClearNAKReceived(void)
+                       {
+                               UPINTX &= ~(1 << NAKEDI);
+                       }
+                        
+                       /** Determines if the currently selected pipe has had the STALL condition set by the attached device.
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        *
+                        *  \return Boolean true if the current pipe has been stalled by the attached device, false otherwise.
+                        */
+                       static inline bool Pipe_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+                       static inline bool Pipe_IsStalled(void)
+                       {
+                               return ((UPINTX & (1 << RXSTALLI)) ? true : false);
+                       }
+                       
+                       /** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the
+                        *  STALL condition itself (this must be done via a ClearFeature control request to the device).
+                        *
+                        *  \ingroup Group_PipePacketManagement
+                        */
+                       static inline void Pipe_ClearStall(void) ATTR_ALWAYS_INLINE;
+                       static inline void Pipe_ClearStall(void)
+                       {
+                               UPINTX &= ~(1 << RXSTALLI);
+                       }