Add branch for the conversion of demos to use standard C header files for configuration, rather than makefile defined macros.
This commit is contained in:
parent
e8570c4a37
commit
359fbfe14d
395 changed files with 9912 additions and 2756 deletions
|
@ -42,6 +42,21 @@
|
|||
uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
||||
#endif
|
||||
|
||||
bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table,
|
||||
const uint8_t Entries)
|
||||
{
|
||||
for (uint8_t i = 0; i < Entries; i++)
|
||||
{
|
||||
if (!(Table[i].Address))
|
||||
continue;
|
||||
|
||||
if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
|
||||
const uint8_t UECFG0XData,
|
||||
const uint8_t UECFG1XData)
|
||||
|
|
|
@ -89,35 +89,6 @@
|
|||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define _ENDPOINT_GET_MAXSIZE(EPIndex) _ENDPOINT_GET_MAXSIZE2(ENDPOINT_DETAILS_EP ## EPIndex)
|
||||
#define _ENDPOINT_GET_MAXSIZE2(EPDetails) _ENDPOINT_GET_MAXSIZE3(EPDetails)
|
||||
#define _ENDPOINT_GET_MAXSIZE3(MaxSize, Banks) (MaxSize)
|
||||
|
||||
#define _ENDPOINT_GET_BANKS(EPIndex) _ENDPOINT_GET_BANKS2(ENDPOINT_DETAILS_EP ## EPIndex)
|
||||
#define _ENDPOINT_GET_BANKS2(EPDetails) _ENDPOINT_GET_BANKS3(EPDetails)
|
||||
#define _ENDPOINT_GET_BANKS3(MaxSize, Banks) (Banks)
|
||||
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
|
||||
#define ENDPOINT_DETAILS_MAXEP 7
|
||||
|
||||
#define ENDPOINT_DETAILS_EP0 64, 1
|
||||
#define ENDPOINT_DETAILS_EP1 256, 2
|
||||
#define ENDPOINT_DETAILS_EP2 64, 2
|
||||
#define ENDPOINT_DETAILS_EP3 64, 2
|
||||
#define ENDPOINT_DETAILS_EP4 64, 2
|
||||
#define ENDPOINT_DETAILS_EP5 64, 2
|
||||
#define ENDPOINT_DETAILS_EP6 64, 2
|
||||
#else
|
||||
#define ENDPOINT_DETAILS_MAXEP 5
|
||||
|
||||
#define ENDPOINT_DETAILS_EP0 64, 1
|
||||
#define ENDPOINT_DETAILS_EP1 64, 1
|
||||
#define ENDPOINT_DETAILS_EP2 64, 1
|
||||
#define ENDPOINT_DETAILS_EP3 64, 2
|
||||
#define ENDPOINT_DETAILS_EP4 64, 2
|
||||
#endif
|
||||
|
||||
/* Inline Functions: */
|
||||
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST
|
||||
ATTR_ALWAYS_INLINE;
|
||||
|
@ -145,23 +116,6 @@
|
|||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name Endpoint Bank Mode Masks */
|
||||
//@{
|
||||
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
|
||||
* that the endpoint should have one single bank, which requires less USB FIFO memory but results
|
||||
* in slower transfers as only one USB device (the AVR or the host) can access the endpoint's
|
||||
* bank at the one time.
|
||||
*/
|
||||
#define ENDPOINT_BANK_SINGLE (0 << EPBK0)
|
||||
|
||||
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
|
||||
* that the endpoint should have two banks, which requires more USB FIFO memory but results
|
||||
* in faster transfers as one USB device (the AVR or the host) can access one bank while the other
|
||||
* accesses the second bank.
|
||||
*/
|
||||
#define ENDPOINT_BANK_DOUBLE (1 << EPBK0)
|
||||
//@}
|
||||
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
|
||||
/** Default size of the default control endpoint's bank, until altered by the control endpoint bank size
|
||||
* value in the device descriptor. Not available if the \c FIXED_CONTROL_ENDPOINT_SIZE token is defined.
|
||||
|
@ -169,30 +123,16 @@
|
|||
#define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8
|
||||
#endif
|
||||
|
||||
/** Retrieves the maximum bank size in bytes of a given endpoint.
|
||||
*
|
||||
* \attention This macro will only work correctly on endpoint indexes that are compile-time constants
|
||||
* defined by the preprocessor.
|
||||
*
|
||||
* \param[in] EPIndex Endpoint number, a value between 0 and (\ref ENDPOINT_TOTAL_ENDPOINTS - 1)
|
||||
*/
|
||||
#define ENDPOINT_MAX_SIZE(EPIndex) _ENDPOINT_GET_MAXSIZE(EPIndex)
|
||||
|
||||
/** Retrieves the total number of banks supported by the given endpoint.
|
||||
*
|
||||
* \attention This macro will only work correctly on endpoint indexes that are compile-time constants
|
||||
* defined by the preprocessor.
|
||||
*
|
||||
* \param[in] EPIndex Endpoint number, a value between 0 and (\ref ENDPOINT_TOTAL_ENDPOINTS - 1)
|
||||
*/
|
||||
#define ENDPOINT_BANKS_SUPPORTED(EPIndex) _ENDPOINT_GET_BANKS(EPIndex)
|
||||
|
||||
#if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__)
|
||||
/** Total number of endpoints (including the default control endpoint at address 0) which may
|
||||
* be used in the device. Different USB AVR models support different amounts of endpoints,
|
||||
* this value reflects the maximum number of endpoints for the currently selected AVR model.
|
||||
*/
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS ENDPOINT_DETAILS_MAXEP
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 7
|
||||
#else
|
||||
/** Total number of endpoints (including the default control endpoint at address 0) which may
|
||||
* be used in the device. Different USB AVR models support different amounts of endpoints,
|
||||
* this value reflects the maximum number of endpoints for the currently selected AVR model.
|
||||
*/
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 5
|
||||
#endif
|
||||
#else
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 1
|
||||
#endif
|
||||
|
@ -222,28 +162,20 @@
|
|||
};
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Configures the specified endpoint number with the given endpoint type, direction, bank size
|
||||
* and banking mode. Once configured, the endpoint may be read from or written to, depending
|
||||
* on its direction.
|
||||
/** Configures the specified endpoint address with the given endpoint type, bank size and number of hardware
|
||||
* banks. Once configured, the endpoint may be read from or written to, depending on its direction.
|
||||
*
|
||||
* \param[in] Number Endpoint number to configure. This must be more than 0 and less than
|
||||
* \ref ENDPOINT_TOTAL_ENDPOINTS.
|
||||
* \param[in] Address Endpoint address to configure.
|
||||
*
|
||||
* \param[in] Type Type of endpoint to configure, a \c EP_TYPE_* mask. Not all endpoint types
|
||||
* are available on Low Speed USB devices - refer to the USB 2.0 specification.
|
||||
*
|
||||
* \param[in] Direction Endpoint data direction, either \ref ENDPOINT_DIR_OUT or \ref ENDPOINT_DIR_IN.
|
||||
* All endpoints (except Control type) are unidirectional - data may only be read
|
||||
* from or written to the endpoint bank based on its direction, not both.
|
||||
*
|
||||
* \param[in] Size Size of the endpoint's bank, where packets are stored before they are transmitted
|
||||
* to the USB host, or after they have been received from the USB host (depending on
|
||||
* the endpoint's data direction). The bank size must indicate the maximum packet size
|
||||
* that the endpoint can handle.
|
||||
*
|
||||
* \param[in] Banks Number of banks to use for the endpoint being configured, an \c ENDPOINT_BANK_* mask.
|
||||
* More banks uses more USB DPRAM, but offers better performance. Isochronous type
|
||||
* endpoints <b>must</b> have at least two banks.
|
||||
* \param[in] Banks Number of banks to use for the endpoint being configured.
|
||||
*
|
||||
* \attention 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.
|
||||
|
@ -261,19 +193,18 @@
|
|||
*
|
||||
* \return Boolean \c true if the configuration succeeded, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Number,
|
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address,
|
||||
const uint8_t Type,
|
||||
const uint8_t Direction,
|
||||
const uint16_t Size,
|
||||
const uint8_t Banks) ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Number,
|
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address,
|
||||
const uint8_t Type,
|
||||
const uint8_t Direction,
|
||||
const uint16_t Size,
|
||||
const uint8_t Banks)
|
||||
{
|
||||
return Endpoint_ConfigureEndpoint_Prv(Number, ((Type << EPTYPE0) | (Direction ? (1 << EPDIR) : 0)),
|
||||
((1 << ALLOC) | Banks | Endpoint_BytesToEPSizeMask(Size)));
|
||||
return Endpoint_ConfigureEndpoint_Prv((Address & ENDPOINT_EPNUM_MASK),
|
||||
((Type << EPTYPE0) | ((Address & ENDPOINT_DIR_IN) ? (1 << EPDIR) : 0)),
|
||||
((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Endpoint_BytesToEPSizeMask(Size)));
|
||||
}
|
||||
|
||||
/** Indicates the number of bytes currently stored in the current endpoint's selected bank.
|
||||
|
@ -294,9 +225,19 @@
|
|||
#endif
|
||||
}
|
||||
|
||||
/** Determines the currently selected endpoint's direction.
|
||||
*
|
||||
* \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_GetEndpointDirection(void)
|
||||
{
|
||||
return (UECFG0X & (1 << EPDIR)) ? ENDPOINT_DIR_IN : ENDPOINT_DIR_OUT;
|
||||
}
|
||||
|
||||
/** Get the endpoint address of the currently selected endpoint. This is typically used to save
|
||||
* the currently selected endpoint number so that it can be restored after another endpoint has
|
||||
* been manipulated.
|
||||
* the currently selected endpoint so that it can be restored after another endpoint has been
|
||||
* manipulated.
|
||||
*
|
||||
* \return Index of the currently selected endpoint.
|
||||
*/
|
||||
|
@ -304,38 +245,36 @@
|
|||
static inline uint8_t Endpoint_GetCurrentEndpoint(void)
|
||||
{
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
return (UENUM & ENDPOINT_EPNUM_MASK);
|
||||
return ((UENUM & ENDPOINT_EPNUM_MASK) | Endpoint_GetEndpointDirection());
|
||||
#else
|
||||
return ENDPOINT_CONTROLEP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Selects the given endpoint number. If the address from the device descriptors is used, the
|
||||
* value should be masked with the \ref ENDPOINT_EPNUM_MASK constant to extract only the endpoint
|
||||
* number (and discarding the endpoint direction bit).
|
||||
/** Selects the given endpoint address.
|
||||
*
|
||||
* Any endpoint operations which do not require the endpoint number to be indicated will operate on
|
||||
* Any endpoint operations which do not require the endpoint address to be indicated will operate on
|
||||
* the currently selected endpoint.
|
||||
*
|
||||
* \param[in] EndpointNumber Endpoint number to select.
|
||||
* \param[in] Address Endpoint address 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 Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_SelectEndpoint(const uint8_t Address)
|
||||
{
|
||||
#if !defined(CONTROL_ONLY_DEVICE)
|
||||
UENUM = EndpointNumber;
|
||||
UENUM = (Address & ENDPOINT_EPNUM_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
|
||||
* data In and Out pointers to the bank's contents.
|
||||
*
|
||||
* \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset.
|
||||
* \param[in] Address Endpoint address whose FIFO buffers are to be reset.
|
||||
*/
|
||||
static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ResetEndpoint(const uint8_t EndpointNumber)
|
||||
static inline void Endpoint_ResetEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void Endpoint_ResetEndpoint(const uint8_t Address)
|
||||
{
|
||||
UERST = (1 << EndpointNumber);
|
||||
UERST = (1 << (Address & ENDPOINT_EPNUM_MASK));
|
||||
UERST = 0;
|
||||
}
|
||||
|
||||
|
@ -441,14 +380,14 @@
|
|||
/** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type
|
||||
* endpoints).
|
||||
*
|
||||
* \param[in] EndpointNumber Index of the endpoint whose interrupt flag should be tested.
|
||||
* \param[in] Address Address of the endpoint whose interrupt flag should be tested.
|
||||
*
|
||||
* \return Boolean \c true if the specified endpoint has interrupted, \c false otherwise.
|
||||
*/
|
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber)
|
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address)
|
||||
{
|
||||
return ((Endpoint_GetEndpointInterrupts() & (1 << EndpointNumber)) ? true : false);
|
||||
return ((Endpoint_GetEndpointInterrupts() & (1 << (Address & ENDPOINT_EPNUM_MASK))) ? true : false);
|
||||
}
|
||||
|
||||
/** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.
|
||||
|
@ -576,16 +515,6 @@
|
|||
UECONX |= (1 << RSTDT);
|
||||
}
|
||||
|
||||
/** Determines the currently selected endpoint's direction.
|
||||
*
|
||||
* \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_GetEndpointDirection(void)
|
||||
{
|
||||
return (UECFG0X & (1 << EPDIR)) ? ENDPOINT_DIR_IN : ENDPOINT_DIR_OUT;
|
||||
}
|
||||
|
||||
/** Sets the direction of the currently selected endpoint.
|
||||
*
|
||||
* \param[in] DirectionMask New endpoint direction, as a \c ENDPOINT_DIR_* mask.
|
||||
|
@ -841,6 +770,20 @@
|
|||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures a table of endpoint descriptions, in sequence. This function can be used to configure multiple
|
||||
* endpoints at the same time.
|
||||
*
|
||||
* \note Endpoints with a zero address will be ignored, thus this function cannot be used to configure the
|
||||
* control endpoint.
|
||||
*
|
||||
* \param[in] Table Pointer to a table of endpoint descriptions.
|
||||
* \param[in] Entries Number of entries in the endpoint table to configure.
|
||||
*
|
||||
* \return Boolean \c true if all endpoints configured successfully, \c false otherwise.
|
||||
*/
|
||||
bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table,
|
||||
const uint8_t Entries);
|
||||
|
||||
/** Completes the status stage of a control transfer on a CONTROL type endpoint automatically,
|
||||
* with respect to the data direction. This is a convenience function which can be used to
|
||||
* simplify user control request handling.
|
||||
|
|
|
@ -114,9 +114,7 @@ void USB_Host_ProcessNextHostState(void)
|
|||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe);
|
||||
break;
|
||||
case HOST_STATE_Powered_ConfigPipe:
|
||||
if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
|
||||
PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
|
||||
PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE)))
|
||||
if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, PIPE_CONTROLPIPE_DEFAULT_SIZE, 1)))
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_PipeConfigError;
|
||||
SubErrorCode = 0;
|
||||
|
@ -151,9 +149,7 @@ void USB_Host_ProcessNextHostState(void)
|
|||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset);
|
||||
break;
|
||||
case HOST_STATE_Default_PostReset:
|
||||
if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
|
||||
PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
|
||||
USB_Host_ControlPipeSize, PIPE_BANK_SINGLE)))
|
||||
if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, USB_Host_ControlPipeSize, 1)))
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_PipeConfigError;
|
||||
SubErrorCode = 0;
|
||||
|
|
|
@ -40,21 +40,43 @@
|
|||
|
||||
uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
|
||||
bool Pipe_ConfigurePipe(const uint8_t Number,
|
||||
bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table,
|
||||
const uint8_t Entries)
|
||||
{
|
||||
for (uint8_t i = 0; i < Entries; i++)
|
||||
{
|
||||
if (!(Table[i].Address))
|
||||
continue;
|
||||
|
||||
if (!(Pipe_ConfigurePipe(Table[i].Address, Table[i].Type, Table[i].EndpointAddress, Table[i].Size, Table[i].Banks)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pipe_ConfigurePipe(const uint8_t Address,
|
||||
const uint8_t Type,
|
||||
const uint8_t Token,
|
||||
const uint8_t EndpointNumber,
|
||||
const uint8_t EndpointAddress,
|
||||
const uint16_t Size,
|
||||
const uint8_t Banks)
|
||||
{
|
||||
uint8_t Number = (Address & PIPE_EPNUM_MASK);
|
||||
uint8_t Token = (Address & PIPE_DIR_IN) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT;
|
||||
|
||||
if (Type == EP_TYPE_CONTROL)
|
||||
Token = PIPE_TOKEN_SETUP;
|
||||
|
||||
#if defined(ORDERED_EP_CONFIG)
|
||||
Pipe_SelectPipe(Number);
|
||||
Pipe_EnablePipe();
|
||||
|
||||
UPCFG1X = 0;
|
||||
|
||||
UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
|
||||
UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
|
||||
UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0));
|
||||
UPCFG1X = ((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Pipe_BytesToEPSizeMask(Size));
|
||||
|
||||
Pipe_SetInfiniteINRequests();
|
||||
|
||||
|
@ -71,7 +93,7 @@ bool Pipe_ConfigurePipe(const uint8_t Number,
|
|||
|
||||
if (PNum == Number)
|
||||
{
|
||||
UPCFG0XTemp = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
|
||||
UPCFG0XTemp = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0));
|
||||
UPCFG1XTemp = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
|
||||
UPCFG2XTemp = 0;
|
||||
UPIENXTemp = 0;
|
||||
|
|
|
@ -124,38 +124,22 @@
|
|||
|
||||
/** \name Pipe Token Masks */
|
||||
//@{
|
||||
/** Token mask for \ref Pipe_ConfigurePipe(). This sets the pipe as a SETUP token (for CONTROL type pipes),
|
||||
/** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a SETUP token (for CONTROL type pipes),
|
||||
* which will trigger a control request on the attached device when data is written to the pipe.
|
||||
*/
|
||||
#define PIPE_TOKEN_SETUP (0 << PTOKEN0)
|
||||
|
||||
/** Token mask for \ref Pipe_ConfigurePipe(). This sets the pipe as a IN token (for non-CONTROL type pipes),
|
||||
/** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a IN token (for non-CONTROL type pipes),
|
||||
* indicating that the pipe data will flow from device to host.
|
||||
*/
|
||||
#define PIPE_TOKEN_IN (1 << PTOKEN0)
|
||||
|
||||
/** Token mask for \ref Pipe_ConfigurePipe(). This sets the pipe as a OUT token (for non-CONTROL type pipes),
|
||||
/** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a OUT token (for non-CONTROL type pipes),
|
||||
* indicating that the pipe data will flow from host to device.
|
||||
*/
|
||||
#define PIPE_TOKEN_OUT (2 << PTOKEN0)
|
||||
//@}
|
||||
|
||||
/** \name Pipe Bank Mode Masks */
|
||||
//@{
|
||||
/** Mask for the bank mode selection for the \ref Pipe_ConfigurePipe() macro. This indicates that the pipe
|
||||
* should have one single bank, which requires less USB FIFO memory but results in slower transfers as
|
||||
* only one USB device (the AVR or the attached device) can access the pipe's bank at the one time.
|
||||
*/
|
||||
#define PIPE_BANK_SINGLE (0 << EPBK0)
|
||||
|
||||
/** Mask for the bank mode selection for the \ref Pipe_ConfigurePipe() macro. This indicates that the pipe
|
||||
* should have two banks, which requires more USB FIFO memory but results in faster transfers as one
|
||||
* USB device (the AVR or the attached device) can access one bank while the other accesses the second
|
||||
* bank.
|
||||
*/
|
||||
#define PIPE_BANK_DOUBLE (1 << EPBK0)
|
||||
//@}
|
||||
|
||||
/** Default size of the default control pipe's bank, until altered by the Endpoint0Size value
|
||||
* in the device descriptor of the attached device.
|
||||
*/
|
||||
|
@ -203,36 +187,46 @@
|
|||
return UPBCX;
|
||||
}
|
||||
|
||||
/** Determines the currently selected pipe's direction.
|
||||
*
|
||||
* \return The currently selected pipe's direction, as a \c PIPE_DIR_* mask.
|
||||
*/
|
||||
static inline uint8_t Pipe_GetPipeDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Pipe_GetPipeDirection(void)
|
||||
{
|
||||
return (UPCFG0X & (1 << EPDIR)) ? PIPE_DIR_IN : PIPE_DIR_OUT;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
* currently selected pipe address 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);
|
||||
return ((UPNUM & PIPE_PIPENUM_MASK) | Pipe_GetPipeDirection());
|
||||
}
|
||||
|
||||
/** Selects the given pipe number. Any pipe operations which do not require the pipe number to be
|
||||
/** Selects the given pipe address. Any pipe operations which do not require the pipe address to be
|
||||
* indicated will operate on the currently selected pipe.
|
||||
*
|
||||
* \param[in] PipeNumber Index of the pipe to select.
|
||||
* \param[in] Address Address 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)
|
||||
static inline void Pipe_SelectPipe(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void Pipe_SelectPipe(const uint8_t Address)
|
||||
{
|
||||
UPNUM = PipeNumber;
|
||||
UPNUM = (Address & PIPE_PIPENUM_MASK);
|
||||
}
|
||||
|
||||
/** Resets the desired pipe, including the pipe banks and flags.
|
||||
*
|
||||
* \param[in] PipeNumber Index of the pipe to reset.
|
||||
* \param[in] Address Address 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)
|
||||
static inline void Pipe_ResetPipe(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void Pipe_ResetPipe(const uint8_t Address)
|
||||
{
|
||||
UPRST = (1 << PipeNumber);
|
||||
UPRST = (1 << (Address & PIPE_PIPENUM_MASK));
|
||||
UPRST = 0;
|
||||
}
|
||||
|
||||
|
@ -326,8 +320,9 @@
|
|||
static inline uint8_t Pipe_GetBoundEndpointAddress(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Pipe_GetBoundEndpointAddress(void)
|
||||
{
|
||||
return (((UPCFG0X >> PEPNUM0) & PIPE_EPNUM_MASK) |
|
||||
((Pipe_GetPipeToken() == PIPE_TOKEN_IN) ? PIPE_EPDIR_MASK : 0));
|
||||
uint8_t UPCFG0X_Temp = UPCFG0X;
|
||||
|
||||
return (((UPCFG0X_Temp >> PEPNUM0) & PIPE_EPNUM_MASK) | ((UPCFG0X_Temp & PEPNUM1) ? ENDPOINT_DIR_OUT : ENDPOINT_DIR_IN));
|
||||
}
|
||||
|
||||
/** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds.
|
||||
|
@ -351,17 +346,17 @@
|
|||
return UPINT;
|
||||
}
|
||||
|
||||
/** Determines if the specified pipe number has interrupted (valid only for INTERRUPT type
|
||||
/** Determines if the specified pipe address has interrupted (valid only for INTERRUPT type
|
||||
* pipes).
|
||||
*
|
||||
* \param[in] PipeNumber Index of the pipe whose interrupt flag should be tested.
|
||||
* \param[in] Address Address of the pipe whose interrupt flag should be tested.
|
||||
*
|
||||
* \return Boolean \c true if the specified pipe has interrupted, \c 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)
|
||||
static inline bool Pipe_HasPipeInterrupted(const uint8_t Address) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline bool Pipe_HasPipeInterrupted(const uint8_t Address)
|
||||
{
|
||||
return ((UPINT & (1 << PipeNumber)) ? true : false);
|
||||
return ((UPINT & (1 << (Address & PIPE_PIPENUM_MASK))) ? true : false);
|
||||
}
|
||||
|
||||
/** Unfreezes the selected pipe, allowing it to communicate with an attached device. */
|
||||
|
@ -810,8 +805,22 @@
|
|||
extern uint8_t USB_Host_ControlPipeSize;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the specified pipe number with the given pipe type, token, target endpoint number in the
|
||||
* attached device, bank size and banking mode.
|
||||
/** Configures a table of pipe descriptions, in sequence. This function can be used to configure multiple
|
||||
* pipes at the same time.
|
||||
*
|
||||
* \note Pipe with a zero address will be ignored, thus this function cannot be used to configure the
|
||||
* control pipe.
|
||||
*
|
||||
* \param[in] Table Pointer to a table of pipe descriptions.
|
||||
* \param[in] Entries Number of entries in the pipe table to configure.
|
||||
*
|
||||
* \return Boolean \c true if all pipes configured successfully, \c false otherwise.
|
||||
*/
|
||||
bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table,
|
||||
const uint8_t Entries);
|
||||
|
||||
/** Configures the specified pipe address with the given pipe type, endpoint address within the attached device, bank size
|
||||
* and number of hardware banks.
|
||||
*
|
||||
* A newly configured pipe is frozen by default, and must be unfrozen before use via the \ref Pipe_Unfreeze()
|
||||
* before being used. Pipes should be kept frozen unless waiting for data from a device while in IN mode, or
|
||||
|
@ -819,25 +828,19 @@
|
|||
* numbers of IN requests without automatic freezing - this can be overridden by a call to
|
||||
* \ref Pipe_SetFiniteINRequests().
|
||||
*
|
||||
* \param[in] Number Pipe number to configure. This must be more than 0 and less than \ref PIPE_TOTAL_PIPES.
|
||||
* \param[in] Address Pipe address to configure.
|
||||
*
|
||||
* \param[in] Type Type of pipe to configure, an \c EP_TYPE_* mask. Not all pipe types are available on Low
|
||||
* Speed USB devices - refer to the USB 2.0 specification.
|
||||
* \param[in] Type Type of pipe to configure, an \c EP_TYPE_* mask. Not all pipe types are available on Low
|
||||
* Speed USB devices - refer to the USB 2.0 specification.
|
||||
*
|
||||
* \param[in] Token Pipe data token, either \ref PIPE_TOKEN_SETUP, \ref PIPE_TOKEN_OUT or \ref PIPE_TOKEN_IN.
|
||||
* All pipes (except Control type) are unidirectional - data may only be read from or
|
||||
* written to the pipe bank based on its direction, not both.
|
||||
* \param[in] EndpointAddress Endpoint address within the attached device that the pipe should interface to.
|
||||
*
|
||||
* \param[in] EndpointNumber Endpoint index within the attached device that the pipe should interface to.
|
||||
* \param[in] Size Size of the pipe's bank, where packets are stored before they are transmitted to
|
||||
* the USB device, or after they have been received from the USB device (depending on
|
||||
* the pipe's data direction). The bank size must indicate the maximum packet size that
|
||||
* the pipe can handle.
|
||||
*
|
||||
* \param[in] Size Size of the pipe's bank, where packets are stored before they are transmitted to
|
||||
* the USB device, or after they have been received from the USB device (depending on
|
||||
* the pipe's data direction). The bank size must indicate the maximum packet size that
|
||||
* the pipe can handle.
|
||||
*
|
||||
* \param[in] Banks Number of banks to use for the pipe being configured, a \c PIPE_BANK_* mask. More banks
|
||||
* uses more USB DPRAM, but offers better performance. Isochronous type pipes <b>must</b>
|
||||
* have at least two banks.
|
||||
* \param[in] Banks Number of banks to use for the pipe being configured.
|
||||
*
|
||||
* \attention When the \c ORDERED_EP_CONFIG compile time option is used, Pipes <b>must</b> be configured in ascending order,
|
||||
* or bank corruption will occur.
|
||||
|
@ -855,10 +858,9 @@
|
|||
*
|
||||
* \return Boolean \c true if the configuration succeeded, \c false otherwise.
|
||||
*/
|
||||
bool Pipe_ConfigurePipe(const uint8_t Number,
|
||||
bool Pipe_ConfigurePipe(const uint8_t Address,
|
||||
const uint8_t Type,
|
||||
const uint8_t Token,
|
||||
const uint8_t EndpointNumber,
|
||||
const uint8_t EndpointAddress,
|
||||
const uint16_t Size,
|
||||
const uint8_t Banks);
|
||||
|
||||
|
|
|
@ -232,8 +232,7 @@ static void USB_Init_Device(void)
|
|||
#endif
|
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
|
||||
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
USB_Device_ControlEndpointSize, 1);
|
||||
|
||||
USB_INT_Clear(USB_INT_SUSPI);
|
||||
USB_INT_Enable(USB_INT_SUSPI);
|
||||
|
|
|
@ -171,8 +171,7 @@ ISR(USB_GEN_vect, ISR_BLOCK)
|
|||
USB_INT_Enable(USB_INT_WAKEUPI);
|
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
|
||||
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
USB_Device_ControlEndpointSize, 1);
|
||||
|
||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
USB_INT_Enable(USB_INT_RXSTPI);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue