/* Type Defines: */
typedef struct
{
- uint8_t Data[64];
- uint8_t BankSize;
- uint8_t FIFOLength;
- uint8_t FIFOPosition;
- } Endpoint_AuxData_t;
+ uint8_t Data[64];
+
+ uint8_t Length;
+ uint8_t Position;
+ } Endpoint_FIFO_t;
+
+ typedef struct
+ {
+ Endpoint_FIFO_t OUT;
+ Endpoint_FIFO_t IN;
+ } Endpoint_FIFOPair_t;
/* External Variables: */
- extern Endpoint_AuxData_t Endpoint_AuxData[ENDPOINT_DETAILS_MAXEP * 2];
- extern volatile uint8_t Endpoint_SelectedEndpoint;
- extern volatile USB_EP_t* Endpoint_SelectedEndpointHandle;
- extern volatile Endpoint_AuxData_t* Endpoint_SelectedEndpointAux;
+ extern Endpoint_FIFOPair_t USB_Endpoint_FIFOs[ENDPOINT_DETAILS_MAXEP];
+ extern volatile uint8_t USB_Endpoint_SelectedEndpoint;
+ extern volatile USB_EP_t* USB_Endpoint_SelectedHandle;
+ extern volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO;
/* Inline Functions: */
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
*
* \param[in] EndpointNumber Endpoint number to select.
*/
- static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
+ static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber);
static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber)
{
- uint8_t EPTableIndex = ((EndpointNumber & ENDPOINT_EPNUM_MASK) << 1) |
- ((EndpointNumber & ENDPOINT_DIR_IN) ? 0x01 : 0);
-
- Endpoint_SelectedEndpoint = EndpointNumber;
- Endpoint_SelectedEndpointAux = &Endpoint_AuxData[EPTableIndex];
- Endpoint_SelectedEndpointHandle = (EndpointNumber & ENDPOINT_DIR_IN) ?
- &USB_EndpointTable.Endpoints[EndpointNumber & ENDPOINT_EPNUM_MASK].IN :
- &USB_EndpointTable.Endpoints[EndpointNumber & ENDPOINT_EPNUM_MASK].OUT;
+ USB_Endpoint_SelectedEndpoint = EndpointNumber;
+
+ if (EndpointNumber & ENDPOINT_DIR_IN)
+ {
+ USB_Endpoint_SelectedFIFO = &USB_Endpoint_FIFOs[EndpointNumber & ENDPOINT_EPNUM_MASK].IN;
+ USB_Endpoint_SelectedHandle = &USB_EndpointTable.Endpoints[EndpointNumber & ENDPOINT_EPNUM_MASK].IN;
+ }
+ else
+ {
+ USB_Endpoint_SelectedFIFO = &USB_Endpoint_FIFOs[EndpointNumber & ENDPOINT_EPNUM_MASK].OUT;
+ USB_Endpoint_SelectedHandle = &USB_EndpointTable.Endpoints[EndpointNumber & ENDPOINT_EPNUM_MASK].OUT;
+ }
}
/** Configures the specified endpoint number with the given endpoint type, direction, bank size
* More banks uses more USB DPRAM, but offers better performance. Isochronous type
* endpoints <b>must</b> have at least two banks.
*
- * \note When the \c ORDERED_EP_CONFIG compile time option is used, Endpoints <b>must</b> be configured in
- * ascending order, or bank corruption will occur.
- * \n\n
- *
- * \note Different endpoints may have different maximum packet sizes based on the endpoint's index - refer to
- * the chosen microcontroller model's datasheet to determine the maximum bank size for each endpoint.
- * \n\n
- *
* \note The default control endpoint should not be manually configured by the user application, as
* it is automatically configured by the library internally.
* \n\n
*
- * \note This routine will automatically select the specified endpoint upon success. Upon failure, the endpoint
- * which failed to reconfigure correctly will be selected.
+ * \note This routine will automatically select the specified endpoint.
*
* \return Boolean \c true if the configuration succeeded, \c false otherwise.
*/
static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint16_t Endpoint_BytesInEndpoint(void)
{
- return Endpoint_SelectedEndpointAux->FIFOPosition;
+ return USB_Endpoint_SelectedFIFO->Position;
}
/** Get the endpoint address of the currently selected endpoint. This is typically used to save
static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_GetCurrentEndpoint(void)
{
- return Endpoint_SelectedEndpoint;
+ return USB_Endpoint_SelectedEndpoint;
}
/** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber)
{
- Endpoint_SelectedEndpointAux->FIFOPosition = 0;
+ USB_Endpoint_SelectedFIFO->Position = 0;
}
/** Determines if the currently selected endpoint is enabled, but not necessarily configured.
static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsReadWriteAllowed(void)
{
- return (Endpoint_SelectedEndpointAux->FIFOPosition < Endpoint_SelectedEndpointAux->FIFOLength);
+ return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length);
}
/** Determines if the currently selected endpoint is configured.
static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsConfigured(void)
{
- return ((Endpoint_SelectedEndpointHandle->CTRL & USB_EP_TYPE_gm) ? true : false);
+ return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_TYPE_gm) ? true : false);
}
/** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsINReady(void)
{
- return ((Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm) ? true : false);
+ Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN);
+
+ return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_TRNCOMPL0_bm) ? true : false);
}
/** Determines if the selected OUT endpoint has received new packet from the host.
static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsOUTReceived(void)
{
- if (Endpoint_SelectedEndpointHandle->STATUS & USB_EP_TRNCOMPL0_bm)
+ Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN);
+
+ if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_TRNCOMPL0_bm)
{
- Endpoint_SelectedEndpointAux->FIFOLength = Endpoint_SelectedEndpointHandle->CNT;
+ USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT;
return true;
}
static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsSETUPReceived(void)
{
- return ((Endpoint_SelectedEndpointHandle->STATUS & USB_EP_SETUP_bm) ? true : false);
+ Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN);
+
+ if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_SETUP_bm)
+ {
+ USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT;
+ return true;
+ }
+
+ return false;
}
/** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearSETUP(void)
{
- Endpoint_SelectedEndpointHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm);
-
- Endpoint_SelectedEndpointAux->FIFOPosition = 0;
+ USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_BUSNACK0_bm);
+ USB_Endpoint_SelectedFIFO->Position = 0;
}
/** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearIN(void)
{
- Endpoint_SelectedEndpointHandle->CNT = Endpoint_SelectedEndpointAux->FIFOPosition;
- Endpoint_SelectedEndpointHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm);
-
- Endpoint_SelectedEndpointAux->FIFOPosition = 0;
+ USB_Endpoint_SelectedHandle->CNT = USB_Endpoint_SelectedFIFO->Position;
+ USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm);
+ USB_Endpoint_SelectedFIFO->Position = 0;
}
/** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearOUT(void)
{
- Endpoint_SelectedEndpointHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm);
-
- Endpoint_SelectedEndpointAux->FIFOPosition = 0;
+ USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm);
+ USB_Endpoint_SelectedFIFO->Position = 0;
}
/** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_StallTransaction(void)
{
- Endpoint_SelectedEndpointHandle->CTRL |= USB_EP_STALL_bm;
+ USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm;
}
/** Clears the STALL condition on the currently selected endpoint.
static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ClearStall(void)
{
- Endpoint_SelectedEndpointHandle->CTRL &= ~USB_EP_STALL_bm;
+ USB_Endpoint_SelectedHandle->CTRL &= ~USB_EP_STALL_bm;
}
/** Determines if the currently selected endpoint is stalled, false otherwise.
static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_IsStalled(void)
{
- return ((Endpoint_SelectedEndpointHandle->CTRL & USB_EP_STALL_bm) ? true : false);
+ return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false);
}
/** Resets the data toggle of the currently selected endpoint. */
static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_ResetDataToggle(void)
{
- Endpoint_SelectedEndpointHandle->STATUS &= ~USB_EP_TOGGLE_bm;
+ USB_Endpoint_SelectedHandle->STATUS &= ~USB_EP_TOGGLE_bm;
}
/** Determines the currently selected endpoint's direction.
static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_GetEndpointDirection(void)
{
- return ((Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) ? true : false);
+ return ((USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) ? true : false);
}
/** Sets the direction of the currently selected endpoint.
static inline uint8_t Endpoint_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline uint8_t Endpoint_Read_8(void)
{
- return Endpoint_SelectedEndpointAux->Data[Endpoint_SelectedEndpointAux->FIFOPosition++];
+ return USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++];
}
/** Writes one byte to the currently selected endpoint's bank, for IN direction endpoints.
static inline void Endpoint_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Write_8(const uint8_t Data)
{
- Endpoint_SelectedEndpointAux->Data[Endpoint_SelectedEndpointAux->FIFOPosition++] = Data;
+ USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++] = Data;
}
/** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints.
static inline void Endpoint_Discard_8(void) ATTR_ALWAYS_INLINE;
static inline void Endpoint_Discard_8(void)
{
- Endpoint_SelectedEndpointAux->FIFOPosition++;
+ USB_Endpoint_SelectedFIFO->Position++;
}
/** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT