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
|
@ -45,6 +45,23 @@ uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
|||
volatile uint32_t USB_Endpoint_SelectedEndpoint = ENDPOINT_CONTROLEP;
|
||||
volatile uint8_t* USB_Endpoint_FIFOPos[ENDPOINT_TOTAL_ENDPOINTS];
|
||||
|
||||
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 uint32_t UECFG0Data)
|
||||
{
|
||||
|
|
|
@ -90,47 +90,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_UC3A0_AVR32) || defined(USB_SERIES_UC3A1_AVR32)
|
||||
#define ENDPOINT_DETAILS_MAXEP 7
|
||||
|
||||
#define ENDPOINT_DETAILS_EP0 64, 1
|
||||
#define ENDPOINT_DETAILS_EP1 256, 2
|
||||
#define ENDPOINT_DETAILS_EP2 256, 2
|
||||
#define ENDPOINT_DETAILS_EP3 64, 2
|
||||
#define ENDPOINT_DETAILS_EP4 64, 2
|
||||
#define ENDPOINT_DETAILS_EP5 256, 2
|
||||
#define ENDPOINT_DETAILS_EP6 256, 2
|
||||
#elif defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32)
|
||||
#define ENDPOINT_DETAILS_MAXEP 8
|
||||
|
||||
#define ENDPOINT_DETAILS_EP0 64, 1
|
||||
#define ENDPOINT_DETAILS_EP1 512, 3
|
||||
#define ENDPOINT_DETAILS_EP2 512, 3
|
||||
#define ENDPOINT_DETAILS_EP3 512, 3
|
||||
#define ENDPOINT_DETAILS_EP4 512, 3
|
||||
#define ENDPOINT_DETAILS_EP5 512, 3
|
||||
#define ENDPOINT_DETAILS_EP6 512, 3
|
||||
#define ENDPOINT_DETAILS_EP7 512, 3
|
||||
#elif defined(USB_SERIES_UC3B0_AVR32) || defined(USB_SERIES_UC3B1_AVR32)
|
||||
#define ENDPOINT_DETAILS_MAXEP 7
|
||||
|
||||
#define ENDPOINT_DETAILS_EP0 64, 1
|
||||
#define ENDPOINT_DETAILS_EP1 64, 2
|
||||
#define ENDPOINT_DETAILS_EP2 64, 2
|
||||
#define ENDPOINT_DETAILS_EP3 64, 2
|
||||
#define ENDPOINT_DETAILS_EP4 64, 2
|
||||
#define ENDPOINT_DETAILS_EP5 256, 2
|
||||
#define ENDPOINT_DETAILS_EP6 256, 2
|
||||
#endif
|
||||
|
||||
#define ENDPOINT_HSB_ADDRESS_SPACE_SIZE (64 * 1024UL)
|
||||
|
||||
/* Inline Functions: */
|
||||
|
@ -162,34 +121,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 AVR32_USBB_UECFG0_EPBK_SINGLE
|
||||
|
||||
/** 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 AVR32_USBB_UECFG0_EPBK_DOUBLE
|
||||
|
||||
#if defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) || defined(__DOXYGEN__)
|
||||
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
|
||||
* that the endpoint should have three 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 remaining banks.
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define ENDPOINT_BANK_TRIPLE AVR32_USBB_UECFG0_EPBK_TRIPLE
|
||||
#endif
|
||||
//@}
|
||||
|
||||
#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.
|
||||
|
@ -197,30 +128,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 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_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32)
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 8
|
||||
#else
|
||||
/** Total number of endpoints (including the default control endpoint at address 0) which may
|
||||
* be used in the device. Different 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 7
|
||||
#endif
|
||||
#else
|
||||
#define ENDPOINT_TOTAL_ENDPOINTS 1
|
||||
#endif
|
||||
|
@ -250,28 +167,21 @@
|
|||
};
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Configures the specified endpoint number with the given endpoint type, direction, bank size
|
||||
/** Configures the specified endpoint address 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.
|
||||
*
|
||||
* \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 hardware 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.
|
||||
|
@ -289,22 +199,21 @@
|
|||
*
|
||||
* \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, (AVR32_USBB_ALLOC_MASK |
|
||||
((uint32_t)Type << AVR32_USBB_EPTYPE_OFFSET) |
|
||||
((uint32_t)(Direction ? AVR32_USBB_UECFG0_EPDIR_MASK : 0) |
|
||||
((uint32_t)Banks << AVR32_USBB_EPBK_OFFSET) |
|
||||
Endpoint_BytesToEPSizeMask(Size))));
|
||||
return Endpoint_ConfigureEndpoint_Prv((Address & ENDPOINT_EPNUM_MASK),
|
||||
(AVR32_USBB_ALLOC_MASK |
|
||||
((uint32_t)Type << AVR32_USBB_EPTYPE_OFFSET) |
|
||||
((uint32_t)(Address & ENDPOINT_DIR_IN) ? AVR32_USBB_UECFG0_EPDIR_MASK : 0) |
|
||||
((uint32_t)Banks << AVR32_USBB_EPBK_OFFSET) |
|
||||
Endpoint_BytesToEPSizeMask(Size)));
|
||||
}
|
||||
|
||||
/** Indicates the number of bytes currently stored in the current endpoint's selected bank.
|
||||
|
@ -319,41 +228,51 @@
|
|||
return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].byct;
|
||||
}
|
||||
|
||||
/** Determines the currently selected endpoint's direction.
|
||||
*
|
||||
* \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask.
|
||||
*/
|
||||
static inline uint32_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint32_t Endpoint_GetEndpointDirection(void)
|
||||
{
|
||||
return ((&AVR32_USBB.UECFG0)[USB_Endpoint_SelectedEndpoint].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.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_GetCurrentEndpoint(void)
|
||||
{
|
||||
return USB_Endpoint_SelectedEndpoint;
|
||||
return (USB_Endpoint_SelectedEndpoint | Endpoint_GetEndpointDirection());
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
USB_Endpoint_SelectedEndpoint = EndpointNumber;
|
||||
USB_Endpoint_SelectedEndpoint = (Address & ENDPOINT_EPNUM_MASK);
|
||||
}
|
||||
|
||||
/** 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 number 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)
|
||||
{
|
||||
uint32_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK);
|
||||
|
||||
AVR32_USBB.uerst |= (AVR32_USBB_EPRST0_MASK << EndpointNumber);
|
||||
AVR32_USBB.uerst &= ~(AVR32_USBB_EPRST0_MASK << EndpointNumber);
|
||||
USB_Endpoint_FIFOPos[EndpointNumber] = &AVR32_USBB_SLAVE[EndpointNumber * ENDPOINT_HSB_ADDRESS_SPACE_SIZE];
|
||||
|
@ -452,8 +371,8 @@
|
|||
*
|
||||
* \return Mask whose bits indicate which endpoints have interrupted.
|
||||
*/
|
||||
static inline uint8_t Endpoint_GetEndpointInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Endpoint_GetEndpointInterrupts(void)
|
||||
static inline uint32_t Endpoint_GetEndpointInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint32_t Endpoint_GetEndpointInterrupts(void)
|
||||
{
|
||||
return ((AVR32_USBB.udint & (AVR32_USBB_EP6INT_MASK | AVR32_USBB_EP5INT_MASK |
|
||||
AVR32_USBB_EP4INT_MASK | AVR32_USBB_EP3INT_MASK |
|
||||
|
@ -464,14 +383,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() & (AVR32_USBB_EP0INT_MASK << EndpointNumber)) ? true : false);
|
||||
return ((Endpoint_GetEndpointInterrupts() & (AVR32_USBB_EP0INT_MASK << (Address & ENDPOINT_EPNUM_MASK))) ? true : false);
|
||||
}
|
||||
|
||||
/** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.
|
||||
|
@ -596,16 +515,6 @@
|
|||
(&AVR32_USBB.UECON0SET)[USB_Endpoint_SelectedEndpoint].rstdts = true;
|
||||
}
|
||||
|
||||
/** Determines the currently selected endpoint's direction.
|
||||
*
|
||||
* \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask.
|
||||
*/
|
||||
static inline uint32_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint32_t Endpoint_GetEndpointDirection(void)
|
||||
{
|
||||
return ((&AVR32_USBB.UECFG0)[USB_Endpoint_SelectedEndpoint].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.
|
||||
|
@ -837,6 +746,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;
|
||||
|
|
|
@ -43,13 +43,35 @@ uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
|||
volatile uint32_t USB_Pipe_SelectedPipe = PIPE_CONTROLPIPE;
|
||||
volatile uint8_t* USB_Pipe_FIFOPos[PIPE_TOTAL_PIPES];
|
||||
|
||||
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;
|
||||
|
||||
USB_Pipe_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * 0x10000];
|
||||
|
||||
#if defined(ORDERED_EP_CONFIG)
|
||||
|
@ -60,7 +82,7 @@ bool Pipe_ConfigurePipe(const uint8_t Number,
|
|||
(&AVR32_USBB.upcfg0)[Number] = (AVR32_USBB_ALLOC_MASK |
|
||||
((uint32_t)Type << AVR32_USBB_PTYPE_OFFSET) |
|
||||
((uint32_t)Token << AVR32_USBB_PTOKEN_OFFSET) |
|
||||
((uint32_t)Banks << AVR32_USBB_PBK_OFFSET) |
|
||||
((Banks > 1) ? AVR32_USBB_PBK_MASK : 0) |
|
||||
Pipe_BytesToEPSizeMask(Size) |
|
||||
((EndpointNumber & PIPE_EPNUM_MASK) << AVR32_USBB_PEPNUM_OFFSET));
|
||||
|
||||
|
@ -79,9 +101,9 @@ bool Pipe_ConfigurePipe(const uint8_t Number,
|
|||
UPCFG0Temp = (AVR32_USBB_ALLOC_MASK |
|
||||
((uint32_t)Type << AVR32_USBB_PTYPE_OFFSET) |
|
||||
((uint32_t)Token << AVR32_USBB_PTOKEN_OFFSET) |
|
||||
((uint32_t)Banks << AVR32_USBB_PBK_OFFSET) |
|
||||
((Banks > 1) ? AVR32_USBB_PBK_MASK : 0) |
|
||||
Pipe_BytesToEPSizeMask(Size) |
|
||||
((EndpointNumber & PIPE_EPNUM_MASK) << AVR32_USBB_PEPNUM_OFFSET));
|
||||
((EndpointAddress & PIPE_EPNUM_MASK) << AVR32_USBB_PEPNUM_OFFSET));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -131,49 +131,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 AVR32_USBB_UPCFG0_PTOKEN_SETUP
|
||||
|
||||
/** 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 AVR32_USBB_UPCFG0_PTOKEN_IN
|
||||
|
||||
/** 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 AVR32_USBB_UPCFG0_PTOKEN_OUT
|
||||
//@}
|
||||
|
||||
/** \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 AVR32_USBB_UPCFG0_PBK_SINGLE
|
||||
|
||||
/** 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 AVR32_USBB_UPCFG0_PBK_DOUBLE
|
||||
|
||||
#if defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) || defined(__DOXYGEN__)
|
||||
/** Mask for the bank mode selection for the \ref Pipe_ConfigurePipe() macro. This indicates that the
|
||||
* pipe should have three 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
|
||||
* remaining banks.
|
||||
*
|
||||
* \note Not available on all AVR models.
|
||||
*/
|
||||
#define PIPE_BANK_TRIPLE AVR32_USBB_UPCFG0_PBK_TRIPLE
|
||||
#endif
|
||||
//@}
|
||||
|
||||
/** Default size of the default control pipe's bank, until altered by the Endpoint0Size value
|
||||
* in the device descriptor of the attached device.
|
||||
*/
|
||||
|
@ -224,6 +197,16 @@
|
|||
return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].pbyct;
|
||||
}
|
||||
|
||||
/** 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 (((&AVR32_USBB.UPCFG0)[USB_Endpoint_SelectedEndpoint].ptoken == PIPE_TOKEN_OUT) ? PIPE_DIR_OUT : PIPE_DIR_IN);
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*
|
||||
|
@ -232,30 +215,32 @@
|
|||
static inline uint8_t Pipe_GetCurrentPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Pipe_GetCurrentPipe(void)
|
||||
{
|
||||
return USB_Pipe_SelectedPipe;
|
||||
return (USB_Pipe_SelectedPipe | 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)
|
||||
{
|
||||
USB_Pipe_SelectedPipe = PipeNumber;
|
||||
USB_Pipe_SelectedPipe = (Address & PIPE_EPNUM_MASK);
|
||||
}
|
||||
|
||||
/** Resets the desired pipe, including the pipe banks and flags.
|
||||
*
|
||||
* \param[in] PipeNumber Index of the pipe to reset.
|
||||
* \param[in] Address 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)
|
||||
static inline void Pipe_ResetPipe(const uint8_t Address) ATTR_ALWAYS_INLINE;
|
||||
static inline void Pipe_ResetPipe(const uint8_t Address)
|
||||
{
|
||||
uint32_t PipeNumber = (Address & PIPE_EPNUM_MASK);
|
||||
|
||||
AVR32_USBB.uprst |= (AVR32_USBB_PRST0_MASK << PipeNumber);
|
||||
AVR32_USBB.uprst &= ~(AVR32_USBB_PRST0_MASK << PipeNumber);
|
||||
USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[USB_Pipe_SelectedPipe * PIPE_HSB_ADDRESS_SPACE_SIZE];
|
||||
USB_Pipe_FIFOPos[PipeNumber] = &AVR32_USBB_SLAVE[PipeNumber * PIPE_HSB_ADDRESS_SPACE_SIZE];
|
||||
}
|
||||
|
||||
/** Enables the currently selected pipe so that data can be sent and received through it to and from
|
||||
|
@ -349,7 +334,7 @@
|
|||
static inline uint8_t Pipe_GetBoundEndpointAddress(void)
|
||||
{
|
||||
return ((&AVR32_USBB.UPCFG0)[USB_Pipe_SelectedPipe].pepnum |
|
||||
((Pipe_GetPipeToken() == PIPE_TOKEN_IN) ? PIPE_EPDIR_MASK : 0));
|
||||
((Pipe_GetPipeToken() == PIPE_TOKEN_IN) ? PIPE_DIR_IN : PIPE_DIR_OUT));
|
||||
}
|
||||
|
||||
/** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds.
|
||||
|
@ -376,17 +361,17 @@
|
|||
AVR32_USBB_P0INT_MASK)) >> AVR32_USBB_P0INT_OFFSET);
|
||||
}
|
||||
|
||||
/** 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 ((AVR32_USBB.uhint & (AVR32_USBB_P0INTES_MASK << PipeNumber)) ? true : false);
|
||||
return ((AVR32_USBB.uhint & (AVR32_USBB_P0INTES_MASK << (Address & PIPE_EPNUM_MASK))) ? true : false);
|
||||
}
|
||||
|
||||
/** Unfreezes the selected pipe, allowing it to communicate with an attached device. */
|
||||
|
@ -821,8 +806,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
|
||||
|
@ -830,25 +829,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.
|
||||
*
|
||||
* \note 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.
|
||||
|
@ -867,10 +860,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);
|
||||
|
||||
|
|
|
@ -191,8 +191,7 @@ static void USB_Init_Device(void)
|
|||
USB_INT_Enable(USB_INT_VBUSTI);
|
||||
|
||||
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);
|
||||
|
|
|
@ -121,8 +121,7 @@ ISR(USB_GEN_vect)
|
|||
|
||||
USB_Device_SetDeviceAddress(0);
|
||||
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