📄 usb_framework.h
字号:
/// \name Module Data
//@{
/// Endpoint status (used with USB_INFO.ep0Status / pEpInStatus[] / pEpOutStatus[])
typedef enum {
EP_IDLE = 0x00, ///< The endpoint is idle, or a setup token has been received
EP_TX = 0x01, ///< Setup IN data is transmitted automatically by the framework
EP_RX = 0x02, ///< Setup OUT data is received automatically by the framework
EP_HALT = 0x03, ///< The endpoint is halted (returns stalls to the host)
EP_STALL = 0x04, ///< Send procedural stall in the next status phase
EP_MANUAL_TX = 0x05, ///< Setup IN data is transmitted manually by the user application
EP_MANUAL_RX = 0x06, ///< Setup OUT data is received manually by the user application
EP_CANCEL = 0x07 ///< The current transfer was cancelled by the host
} EP_STATUS;
/// Device state (used with USB_INFO.usbState)
typedef enum {
DEV_ATTACHED = 0x00, ///< Device attached (invisible state)
DEV_POWERED = 0x01, ///< Device powered (invisible state)
DEV_DEFAULT = 0x02, ///< Default state (the \c USBADDR register is 0)
DEV_ADDRESS = 0x03, ///< Addressed state (the \c USBADDR register has been set)
DEV_CONFIGURED = 0x04, ///< Configured state (\c usbfwData.configurationValue != 0)
DEV_SUSPENDED = 0x05 ///< Suspended state
} USB_STATE;
/// USBFW internal module data
typedef struct {
USB_STATE usbState; ///< USB device state
UINT8 configurationValue; ///< Current configuration value
UINT8 pAlternateSetting[USB_SETUP_MAX_NUMBER_OF_INTERFACES]; ///< Current alternate settings
EP_STATUS ep0Status; ///< Endpoint 0 status
EP_STATUS pEpInStatus[5]; ///< Endpoint 1-5 IN status
EP_STATUS pEpOutStatus[5]; ///< Endpoint 1-5 OUT status
BOOL remoteWakeup; ///< Remote wakeup allowed
BOOL selfPowered; ///< Is currently self-powered?
} USBFW_DATA;
EXTERN USBFW_DATA __data usbfwData; ///< USBFW internal module data
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// Setup header (contains the 8 bytes received during the setup phase)
typedef struct {
BYTE requestType; ///< Request type (direction, type and recipient, see the \c RT_ definitions)
BYTE request; ///< Request ID
WORD value; ///< Value field
WORD index; ///< Index field
WORD length; ///< Length of data phase
} USB_SETUP_HEADER;
/// Setup handler data phase configuration
typedef struct {
BYTE __generic *pBuffer; ///< Pointer to where IN/OUT data should be taken from/received
UINT16 bytesLeft; ///< The number of bytes to transfer
} USB_SETUP_DATA;
/// \name Setup Handler Data
//@{
EXTERN USB_SETUP_DATA __data usbSetupData; ///< Setup handler data phase configuration
EXTERN USB_SETUP_HEADER __data usbSetupHeader; ///< Setup header
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// \name Request Type Fields
//@{
// Field masks
#define RT_MASK_DIR 0x80 ///< Request direction bit mask
#define RT_MASK_TYPE 0x60 ///< Request type bit mask
#define RT_MASK_RECIP 0x1F ///< Request recipient bit mask
// Direction field
#define RT_DIR_IN 0x80 ///< IN Request
#define RT_DIR_OUT 0x00 ///< OUT Request
// Type field
#define RT_TYPE_STD 0x00 ///< Standard Request
#define RT_TYPE_CLASS 0x20 ///< Class Request
#define RT_TYPE_VEND 0x40 ///< Vendor Request
// Recipient field
#define RT_RECIP_DEV 0x00 ///< Device Request
#define RT_RECIP_IF 0x01 ///< Interface Request
#define RT_RECIP_EP 0x02 ///< Endpoint Request
#define RT_RECIP_OTHER 0x03 ///< Other Request
// Type + direction
#define RT_STD_OUT (RT_TYPE_STD | RT_DIR_OUT) ///< Standard request, direction is OUT
#define RT_STD_IN (RT_TYPE_STD | RT_DIR_IN) ///< Standard request, direction is IN
#define RT_VEND_OUT (RT_TYPE_VEND | RT_DIR_OUT) ///< Vendor request, direction is OUT
#define RT_VEND_IN (RT_TYPE_VEND | RT_DIR_IN) ///< Vendor request, direction is IN
#define RT_CLASS_OUT (RT_TYPE_CLASS | RT_DIR_OUT) ///< Class request, direction is OUT
#define RT_CLASS_IN (RT_TYPE_CLASS | RT_DIR_IN) ///< Class request, direction is IN
// Direction + recepient
#define RT_OUT_DEVICE (RT_DIR_OUT | RT_RECIP_DEV) ///< Request made to device, direction is OUT
#define RT_IN_DEVICE (RT_DIR_IN | RT_RECIP_DEV) ///< Request made to device, direction is IN
#define RT_OUT_INTERFACE (RT_DIR_OUT | RT_RECIP_IF) ///< Request made to interface, direction is OUT
#define RT_IN_INTERFACE (RT_DIR_IN | RT_RECIP_IF) ///< Request made to interface, direction is IN
#define RT_OUT_ENDPOINT (RT_DIR_OUT | RT_RECIP_EP) ///< Request made to endpoint, direction is OUT
#define RT_IN_ENDPOINT (RT_DIR_IN | RT_RECIP_EP) ///< Request made to endpoint, direction is IN
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// \name Vendor and Class Request Hooks
/// Unused hooks must stall endpoint 0.
//@{
/// Hook which is called upon reception of a class request with OUT data phase
void usbcrHookProcessOut(void);
/// Hook which is called upon reception of a class request with IN data phase
void usbcrHookProcessIn(void);
/// Hook which is called upon reception of a vendor request with OUT data phase
void usbvrHookProcessOut(void);
/// Hook which is called upon reception of a vendor request with IN data phase
void usbvrHookProcessIn(void);
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
/// \name Endpoint Access Macros
/// Note that the endpoint control registers are indexed, meaning that an endpoint must be selected
/// before the control operations listed below can be used. Interrupts using any of these macros, must
/// save the current selection and restore it upon return.
//@{
/// Selects which IN/OUT endpoint (by index 0 to 5) to operate on
#define USBFW_SELECT_ENDPOINT(n) (USBINDEX = (n))
/// Gets the currently selected IN/OUT endpoint
#define USBFW_GET_SELECTED_ENDPOINT() (USBINDEX)
/// Stalls the selected IN endpoint
#define USBFW_STALL_IN_ENDPOINT() \
do { \
USBCSIL = USBCSIL_SEND_STALL; \
usbfwData.pEpInStatus[USBINDEX] = EP_HALT; \
} while (0)
/// Returns the stall condition for the selected IN endpoint
#define USBFW_IN_ENDPOINT_STALLED() (USBCSIL & USBCSIL_SEND_STALL)
/// Flushes the FIFO for the selected IN endpoint (flush twice when using double-buffering)
#define USBFW_FLUSH_IN_ENDPOINT() \
do { \
USBCSIL = USBCSIL_FLUSH_PACKET; \
while (USBCSIL & USBCSIL_FLUSH_PACKET); \
} while (0)
/// Arms the selected IN endpoint, so that contents of the endpoint FIFO can be sent to the host
#define USBFW_ARM_IN_ENDPOINT() (USBCSIL = USBCSIL_INPKT_RDY)
/// Is the selected IN endpoint disarmed?
#define USBFW_IN_ENDPOINT_DISARMED() !(USBCSIL & USBCSIL_INPKT_RDY)
/// Is the FIFO for the selected IN endpoint empty?
#define USBFW_IN_ENDPOINT_FIFO_EMPTY() !(USBCSIL & USBCSIL_PKT_PRESENT)
/// Stalls the selected OUT endpoint
#define USBFW_STALL_OUT_ENDPOINT() \
do { \
USBCSOL = USBCSOL_SEND_STALL; \
usbfwData.pEpOutStatus[USBINDEX] = EP_HALT; \
} while (0)
/// Returns the stall condition for the selected OUT endpoint
#define USBFW_OUT_ENDPOINT_STALLED() (USBCSOL & USBCSOL_SEND_STALL)
/// Flushes the FIFO for the selected OUT endpoint (flush twice when using double-buffering)
#define USBFW_FLUSH_OUT_ENDPOINT() \
do { \
USBCSOL = USBCSOL_FLUSH_PACKET; \
while (USBCSOL & USBCSOL_FLUSH_PACKET); \
} while (0)
/// Arms the selected OUT endpoint, so that the FIFO can receive data from the host
#define USBFW_ARM_OUT_ENDPOINT() (USBCSOL = 0)
/// Is the selected OUT endpoint disarmed? If so, there is data waiting in the FIFO
#define USBFW_OUT_ENDPOINT_DISARMED() (USBCSOL & USBCSOL_OUTPKT_RDY)
/// Returns the number of bytes currently in the FIFO of the selected OUT endpoint
#define USBFW_GET_OUT_ENDPOINT_COUNT() ((WORD) USBCNTL + (((WORD) USBCNTH) << 8))
//@}
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// Function prototypes
void usbfwInit(void);
void usbfwResetHandler(void);
void usbfwSetupHandler(void);
void usbfwSetAllEpStatus(EP_STATUS status);
void usbfwWriteFifo(BYTE volatile __xdata *pFifo, UINT8 count, void __generic *pData);
void usbfwReadFifo(BYTE volatile __xdata *pFifo, UINT8 count, void __generic *pData);
//-------------------------------------------------------------------------------------------------------
//@}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -