Added USB basic lib

This commit is contained in:
Martin Loren
2021-12-06 14:18:57 +08:00
parent 758a0d5839
commit 3113e9a378
24 changed files with 4402 additions and 1 deletions

View File

@@ -0,0 +1,241 @@
/**
******************************************************************************
* File : usb_core.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Standard protocol processing functions prototypes
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CORE_H
#define __USB_CORE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _CONTROL_STATE
{
WAIT_SETUP, /* 0 */
SETTING_UP, /* 1 */
IN_DATA, /* 2 */
OUT_DATA, /* 3 */
LAST_IN_DATA, /* 4 */
LAST_OUT_DATA, /* 5 */
WAIT_STATUS_IN, /* 7 */
WAIT_STATUS_OUT, /* 8 */
STALLED, /* 9 */
PAUSE /* 10 */
} CONTROL_STATE; /* The state machine states of a control pipe */
typedef struct OneDescriptor
{
uint8_t *Descriptor;
uint16_t Descriptor_Size;
}
ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
/* All the request process routines return a value of this type
If the return value is not SUCCESS or NOT_READY,
the software will STALL the correspond endpoint */
typedef enum _RESULT
{
USB_SUCCESS = 0, /* Process successfully */
USB_ERROR,
USB_UNSUPPORT,
USB_NOT_READY /* The process has not been finished, endpoint will be
NAK to further request */
} RESULT;
/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _ENDPOINT_INFO
{
/* When send data out of the device,
CopyData() is used to get data buffer 'Length' bytes data
if Length is 0,
CopyData() returns the total length of the data
if the request is not supported, returns 0
(NEW Feature )
if CopyData() returns -1, the calling routine should not proceed
further and will resume the SETUP process by the class device
if Length is not 0,
CopyData() returns a pointer to indicate the data location
Usb_wLength is the data remain to be sent,
Usb_wOffset is the Offset of original data
When receive data from the host,
CopyData() is used to get user data buffer which is capable
of Length bytes data to copy data from the endpoint buffer.
if Length is 0,
CopyData() returns the available data length,
if Length is not 0,
CopyData() returns user buffer address
Usb_rLength is the data remain to be received,
Usb_rPointer is the Offset of data buffer
*/
uint16_t Usb_wLength;
uint16_t Usb_wOffset;
uint16_t PacketSize;
uint8_t *(*CopyData)(uint16_t Length);
}ENDPOINT_INFO;
/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _DEVICE
{
uint8_t Total_Endpoint; /* Number of endpoints that are used */
uint8_t Total_Configuration;/* Number of configuration available */
}
DEVICE;
typedef union
{
uint16_t w;
struct BW
{
uint8_t bb1;
uint8_t bb0;
}
bw;
} uint16_t_uint8_t;
typedef struct _DEVICE_INFO
{
uint8_t USBbmRequestType; /* bmRequestType */
uint8_t USBbRequest; /* bRequest */
uint16_t_uint8_t USBwValues; /* wValue */
uint16_t_uint8_t USBwIndexs; /* wIndex */
uint16_t_uint8_t USBwLengths; /* wLength */
uint8_t ControlState; /* of type CONTROL_STATE */
uint8_t Current_Feature;
uint8_t Current_Configuration; /* Selected configuration */
uint8_t Current_Interface; /* Selected interface of current configuration */
uint8_t Current_AlternateSetting;/* Selected Alternate Setting of current
interface*/
ENDPOINT_INFO Ctrl_Info;
}DEVICE_INFO;
typedef struct _DEVICE_PROP
{
void (*Init)(void); /* Initialize the device */
void (*Reset)(void); /* Reset routine of this device */
/* Device dependent process after the status stage */
void (*Process_Status_IN)(void);
void (*Process_Status_OUT)(void);
/* Procedure of process on setup stage of a class specified request with data stage */
/* All class specified requests with data stage are processed in Class_Data_Setup
Class_Data_Setup()
responses to check all special requests and fills ENDPOINT_INFO
according to the request
If IN tokens are expected, then wLength & wOffset will be filled
with the total transferring bytes and the starting position
If OUT tokens are expected, then rLength & rOffset will be filled
with the total expected bytes and the starting position in the buffer
If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
CAUTION:
Since GET_CONFIGURATION & GET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_Data_Setup)(uint8_t RequestNo);
/* Procedure of process on setup stage of a class specified request without data stage */
/* All class specified requests without data stage are processed in Class_NoData_Setup
Class_NoData_Setup
responses to check all special requests and perform the request
CAUTION:
Since SET_CONFIGURATION & SET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_NoData_Setup)(uint8_t RequestNo);
/*Class_Get_Interface_Setting
This function is used by the file usb_core.c to test if the selected Interface
and Alternate Setting (uint8_t Interface, uint8_t AlternateSetting) are supported by
the application.
This function is writing by user. It should return "SUCCESS" if the Interface
and Alternate Setting are supported by the application or "UNSUPPORT" if they
are not supported. */
RESULT (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);
uint8_t* (*GetDeviceDescriptor)(uint16_t Length);
uint8_t* (*GetConfigDescriptor)(uint16_t Length);
uint8_t* (*GetStringDescriptor)(uint16_t Length);
/* This field is not used in current library version. It is kept only for
compatibility with previous versions */
void* RxEP_buffer;
uint8_t MaxPacketSize;
}DEVICE_PROP;
typedef struct _USER_STANDARD_REQUESTS
{
void (*User_GetConfiguration)(void); /* Get Configuration */
void (*User_SetConfiguration)(void); /* Set Configuration */
void (*User_GetInterface)(void); /* Get Interface */
void (*User_SetInterface)(void); /* Set Interface */
void (*User_GetStatus)(void); /* Get Status */
void (*User_ClearFeature)(void); /* Clear Feature */
void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */
void (*User_SetDeviceFeature)(void); /* Set Device Feature */
void (*User_SetDeviceAddress)(void); /* Set Device Address */
}
USER_STANDARD_REQUESTS;
/* Exported constants --------------------------------------------------------*/
#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT))
#define Usb_rLength Usb_wLength
#define Usb_rOffset Usb_wOffset
#define USBwValue USBwValues.w
#define USBwValue0 USBwValues.bw.bb0
#define USBwValue1 USBwValues.bw.bb1
#define USBwIndex USBwIndexs.w
#define USBwIndex0 USBwIndexs.bw.bb0
#define USBwIndex1 USBwIndexs.bw.bb1
#define USBwLength USBwLengths.w
#define USBwLength0 USBwLengths.bw.bb0
#define USBwLength1 USBwLengths.bw.bb1
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint8_t Setup0_Process(void);
uint8_t Post0_Process(void);
uint8_t Out0_Process(void);
uint8_t In0_Process(void);
RESULT Standard_SetEndPointFeature(void);
RESULT Standard_SetDeviceFeature(void);
uint8_t *Standard_GetConfiguration(uint16_t Length);
RESULT Standard_SetConfiguration(void);
uint8_t *Standard_GetInterface(uint16_t Length);
RESULT Standard_SetInterface(void);
uint8_t *Standard_GetDescriptorData(uint16_t Length, PONE_DESCRIPTOR pDesc);
uint8_t *Standard_GetStatus(uint16_t Length);
RESULT Standard_ClearFeature(void);
void SetDeviceAddress(uint8_t);
void NOP_Process(void);
extern DEVICE_PROP Device_Property;
extern USER_STANDARD_REQUESTS User_Standard_Requests;
extern DEVICE Device_Table;
extern DEVICE_INFO Device_Info;
/* cells saving status during interrupt servicing */
extern __IO uint16_t SaveRState;
extern __IO uint16_t SaveTState;
#endif /* __USB_CORE_H */

View File

@@ -0,0 +1,75 @@
/**
******************************************************************************
* File : usb_def.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Definitions related to USB Core
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEF_H
#define __USB_DEF_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _RECIPIENT_TYPE
{
DEVICE_RECIPIENT, /* Recipient device */
INTERFACE_RECIPIENT, /* Recipient interface */
ENDPOINT_RECIPIENT, /* Recipient endpoint */
OTHER_RECIPIENT
} RECIPIENT_TYPE;
typedef enum _STANDARD_REQUESTS
{
GET_STATUS = 0,
CLEAR_FEATURE,
RESERVED1,
SET_FEATURE,
RESERVED2,
SET_ADDRESS,
GET_DESCRIPTOR,
SET_DESCRIPTOR,
GET_CONFIGURATION,
SET_CONFIGURATION,
GET_INTERFACE,
SET_INTERFACE,
TOTAL_sREQUEST, /* Total number of Standard request */
SYNCH_FRAME = 12
} STANDARD_REQUESTS;
/* Definition of "USBwValue" */
typedef enum _DESCRIPTOR_TYPE
{
DEVICE_DESCRIPTOR = 1,
CONFIG_DESCRIPTOR,
STRING_DESCRIPTOR,
INTERFACE_DESCRIPTOR,
ENDPOINT_DESCRIPTOR
} DESCRIPTOR_TYPE;
/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */
typedef enum _FEATURE_SELECTOR
{
ENDPOINT_STALL,
DEVICE_REMOTE_WAKEUP
} FEATURE_SELECTOR;
/* Exported constants --------------------------------------------------------*/
/* Definition of "USBbmRequestType" */
#define REQUEST_TYPE 0x60 /* Mask to get request type */
#define STANDARD_REQUEST 0x00 /* Standard request */
#define CLASS_REQUEST 0x20 /* Class request */
#define VENDOR_REQUEST 0x40 /* Vendor request */
#define RECIPIENT 0x1F /* Mask to get recipient */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __USB_DEF_H */

View File

@@ -0,0 +1,51 @@
/**
******************************************************************************
* File : usb_init.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Initialization routines & global variables
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INIT_H
#define __USB_INIT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void USB_Init(void);
/* External variables --------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
extern uint8_t EPindex;
/* The number of current device, it is an index to the Device_Table */
/*extern uint8_t Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_INFO* pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_PROP* pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
extern USER_STANDARD_REQUESTS *pUser_Standard_Requests;
extern uint16_t SaveState ;
extern uint16_t wInterrupt_Mask;
#ifdef __cplusplus
}
#endif
#endif /* __USB_INIT_H */

View File

@@ -0,0 +1,28 @@
/**
******************************************************************************
* File : usb_int.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Endpoint CTRF (Low and High) interrupt's service routines prototypes
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INT_H
#define __USB_INT_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void CTR_LP(void);
void CTR_HP(void);
/* External variables --------------------------------------------------------*/
#endif /* __USB_INT_H */

View File

@@ -0,0 +1,34 @@
/**
******************************************************************************
* File : usb_lib.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : USB library include files
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_LIB_H
#define __USB_LIB_H
/* Includes ------------------------------------------------------------------*/
#include <at32f4xx.h>
#include "usb_type.h"
#include "usb_regs.h"
#include "usb_def.h"
#include "usb_core.h"
#include "usb_init.h"
#include "usb_mem.h"
#include "usb_int.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_LIB_H */

View File

@@ -0,0 +1,34 @@
/**
******************************************************************************
* File : usb_mem.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Utility prototypes functions for memory/PMA transfers
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_MEM_H
#define __USB_MEM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
/* External variables --------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /*__USB_MEM_H*/

View File

@@ -0,0 +1,672 @@
/**
******************************************************************************
* File : usb_reg.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Interface prototype functions to USB cell registers
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REGS_H
#define __USB_REGS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _EP_DBUF_DIR
{
/* double buffered endpoint direction */
EP_DBUF_ERR,
EP_DBUF_OUT,
EP_DBUF_IN
}EP_DBUF_DIR;
/* endpoint buffer number */
enum EP_BUF_NUM
{
EP_NOBUF,
EP_BUF0,
EP_BUF1
};
/* Exported constants --------------------------------------------------------*/
#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */
extern int PMAAddr; /* USB_IP Packet Memory Area base address, default is 0x40006000*/
/******************************************************************************/
/* General registers */
/******************************************************************************/
/* Control register */
#define CTRL ((__IO unsigned *)(RegBase + 0x40))
/* Interrupt status register */
#define INTSTS ((__IO unsigned *)(RegBase + 0x44))
/* Frame number register */
#define FRNUM ((__IO unsigned *)(RegBase + 0x48))
/* Device address register */
#define DEVADR ((__IO unsigned *)(RegBase + 0x4C))
/* Buffer Table address register */
#define BUFTBL ((__IO unsigned *)(RegBase + 0x50))
/******************************************************************************/
/* Endpoint registers */
/******************************************************************************/
#define EP0REG ((__IO unsigned *)(RegBase)) /* endpoint 0 register address */
/* Endpoint Addresses (w/direction) */
#define EP0_OUT ((uint8_t)0x00)
#define EP0_IN ((uint8_t)0x80)
#define EP1_OUT ((uint8_t)0x01)
#define EP1_IN ((uint8_t)0x81)
#define EP2_OUT ((uint8_t)0x02)
#define EP2_IN ((uint8_t)0x82)
#define EP3_OUT ((uint8_t)0x03)
#define EP3_IN ((uint8_t)0x83)
#define EP4_OUT ((uint8_t)0x04)
#define EP4_IN ((uint8_t)0x84)
#define EP5_OUT ((uint8_t)0x05)
#define EP5_IN ((uint8_t)0x85)
#define EP6_OUT ((uint8_t)0x06)
#define EP6_IN ((uint8_t)0x86)
#define EP7_OUT ((uint8_t)0x07)
#define EP7_IN ((uint8_t)0x87)
/* endpoints enumeration */
#define ENDP0 ((uint8_t)0)
#define ENDP1 ((uint8_t)1)
#define ENDP2 ((uint8_t)2)
#define ENDP3 ((uint8_t)3)
#define ENDP4 ((uint8_t)4)
#define ENDP5 ((uint8_t)5)
#define ENDP6 ((uint8_t)6)
#define ENDP7 ((uint8_t)7)
/******************************************************************************/
/* INTSTS interrupt events */
/******************************************************************************/
#define INTSTS_CTFR (0x8000) /* Correct TRansfer (clear-only bit) */
#define INTSTS_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */
#define INTSTS_ERRF (0x2000) /* ERRor (clear-only bit) */
#define INTSTS_WKUPF (0x1000) /* WaKe UP (clear-only bit) */
#define INTSTS_SUSPF (0x0800) /* SUSPend (clear-only bit) */
#define INTSTS_RSTF (0x0400) /* RESET (clear-only bit) */
#define INTSTS_SOFF (0x0200) /* Start Of Frame (clear-only bit) */
#define INTSTS_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */
#define INTSTS_DIR (0x0010) /* DIRection of transaction (read-only bit) */
#define INTSTS_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */
#define CLR_CTFR (~INTSTS_CTFR) /* clear Correct TRansfer bit */
#define CLR_DOVR (~INTSTS_DOVR) /* clear DMA OVeR/underrun bit*/
#define CLR_ERRF (~INTSTS_ERRF) /* clear ERRor bit */
#define CLR_WKUPF (~INTSTS_WKUPF) /* clear WaKe UP bit */
#define CLR_SUSPF (~INTSTS_SUSPF) /* clear SUSPend bit */
#define CLR_RSTF (~INTSTS_RSTF) /* clear RESET bit */
#define CLR_SOFF (~INTSTS_SOFF) /* clear Start Of Frame bit */
#define CLR_ESOF (~INTSTS_ESOF) /* clear Expected Start Of Frame bit */
/******************************************************************************/
/* CTRL control register bits definitions */
/******************************************************************************/
#define CTRL_CTFR_IEN (0x8000) /* Correct TRansfer Mask */
#define CTRL_DOVR_IEN (0x4000) /* DMA OVeR/underrun Mask */
#define CTRL_ERR_IEN (0x2000) /* ERRor Mask */
#define CTRL_WKUP_IEN (0x1000) /* WaKe UP Mask */
#define CTRL_SUSP_IEN (0x0800) /* SUSPend Mask */
#define CTRL_RST_IEN (0x0400) /* RESET Mask */
#define CTRL_SOF_IEN (0x0200) /* Start Of Frame Mask */
#define CTRL_ESOF_IEN (0x0100) /* Expected Start Of Frame Mask */
#define CTRL_RESUME (0x0010) /* RESUME request */
#define CTRL_FSUSP (0x0008) /* Force SUSPend */
#define CTRL_LPWR (0x0004) /* Low-power MODE */
#define CTRL_PDWN (0x0002) /* Power DoWN */
#define CTRL_FRST (0x0001) /* Force USB RESet */
/******************************************************************************/
/* FRNUM Frame Number Register bit definitions */
/******************************************************************************/
#define FRNUM_RXDP (0x8000) /* status of D+ data line */
#define FRNUM_RXDM (0x4000) /* status of D- data line */
#define FRNUM_LCK (0x2000) /* LoCKed */
#define FRNUM_LSOF (0x1800) /* Lost SOF */
#define FRNUM_FN (0x07FF) /* Frame Number */
/******************************************************************************/
/* DEVADR Device ADDRess bit definitions */
/******************************************************************************/
#define DEVADR_EN (0x80)
#define DEVADR_ADR (0x7F)
/******************************************************************************/
/* Endpoint register */
/******************************************************************************/
/* bit positions */
#define EP_CTFR_RX (0x8000) /* EndPoint Correct TRansfer RX */
#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */
#define EP_STS_RX (0x3000) /* EndPoint RX STATus bit field */
#define EP_SETUP (0x0800) /* EndPoint SETUP */
#define EP_T_FIELD (0x0600) /* EndPoint TYPE */
#define EP_SUBTYPE (0x0100) /* EndPoint KIND */
#define EP_CTFR_TX (0x0080) /* EndPoint Correct TRansfer TX */
#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */
#define EP_STS_TX (0x0030) /* EndPoint TX STATus bit field */
#define EPADR_FIELD (0x000F) /* EndPoint ADDRess FIELD */
/* EndPoint REGister MASK (no toggle fields) */
#define EPREG_MASK (EP_CTFR_RX|EP_SETUP|EP_T_FIELD|EP_SUBTYPE|EP_CTFR_TX|EPADR_FIELD)
/* EP_TYPE[1:0] EndPoint TYPE */
#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */
#define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK)
/* EP_SUBTYPE EndPoint KIND */
#define EPKIND_MASK (~EP_SUBTYPE & EPREG_MASK)
/* STAT_TX[1:0] STATus for TX transfer */
#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */
#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */
#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */
#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */
#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */
#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */
#define EPTX_DTOGMASK (EP_STS_TX|EPREG_MASK)
/* STAT_RX[1:0] STATus for RX transfer */
#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */
#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */
#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */
#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */
#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOGMASK (EP_STS_RX|EPREG_MASK)
/* Exported macro ------------------------------------------------------------*/
/* SetCTRL */
#define _SetCTRL(wRegValue) (*CTRL = (uint16_t)wRegValue)
/* SetINTSTS */
#define _SetINTSTS(wRegValue) (*INTSTS = (uint16_t)wRegValue)
/* SetDEVADR */
#define _SetDEVADR(wRegValue) (*DEVADR = (uint16_t)wRegValue)
/* SetBUFTBL */
#define _SetBUFTBL(wRegValue)(*BUFTBL = (uint16_t)(wRegValue & 0xFFF8))
/* GetCTRL */
#define _GetCTRL() ((uint16_t) *CTRL)
/* GetINTSTS */
#define _GetINTSTS() ((uint16_t) *INTSTS)
/* GetFRNUM */
#define _GetFRNUM() ((uint16_t) *FRNUM)
/* GetDEVADR */
#define _GetDEVADR() ((uint16_t) *DEVADR)
/* GetBUFTBL */
#define _GetBUFTBL() ((uint16_t) *BUFTBL)
/* SetENDPOINT */
#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \
(uint16_t)wRegValue)
/* GetENDPOINT */
#define _GetENDPOINT(bEpNum) ((uint16_t)(*(EP0REG + bEpNum)))
/*******************************************************************************
* Macro Name : SetEPType
* Description : sets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* wType
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\
((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType )))
/*******************************************************************************
* Macro Name : GetEPType
* Description : gets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Type
*******************************************************************************/
#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD)
/*******************************************************************************
* Macro Name : SetEPTxStatus
* Description : sets the status for tx transfer (bits STAT_TX[1:0]).
* Input : bEpNum: Endpoint Number.
* wState: new state
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxStatus(bEpNum,wState) {\
register uint16_t _wRegVal; \
_wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, (_wRegVal | EP_CTFR_RX|EP_CTFR_TX)); \
} /* _SetEPTxStatus */
/*******************************************************************************
* Macro Name : SetEPRxStatus
* Description : sets the status for rx transfer (bits STAT_TX[1:0])
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxStatus(bEpNum,wState) {\
register uint16_t _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
_SetENDPOINT(bEpNum, (_wRegVal | EP_CTFR_RX|EP_CTFR_TX)); \
} /* _SetEPRxStatus */
/*******************************************************************************
* Macro Name : SetEPRxTxStatus
* Description : sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* wStaterx: new state.
* wStatetx: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxTxStatus(bEpNum,wStaterx,wStatetx) {\
register uint32_t _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & (EPRX_DTOGMASK |EP_STS_TX) ;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wStaterx)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wStaterx)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wStatetx)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wStatetx)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, _wRegVal | EP_CTFR_RX|EP_CTFR_TX); \
} /* _SetEPRxTxStatus */
/*******************************************************************************
* Macro Name : GetEPTxStatus / GetEPRxStatus
* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0]
* /STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : status .
*******************************************************************************/
#define _GetEPTxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EP_STS_TX)
#define _GetEPRxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EP_STS_RX)
/*******************************************************************************
* Macro Name : SetEPTxValid / SetEPRxValid
* Description : sets directly the VALID tx/rx-status into the enpoint register
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID))
#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID))
/*******************************************************************************
* Macro Name : GetTxStallStatus / GetRxStallStatus.
* Description : checks stall condition in an endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : TRUE = endpoint in stall condition.
*******************************************************************************/
#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \
== EP_TX_STALL)
#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \
== EP_RX_STALL)
/*******************************************************************************
* Macro Name : SetEP_SUBTYPE / ClearEP_SUBTYPE.
* Description : set & clear EP_SUBTYPE bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEP_SUBTYPE(bEpNum) (_SetENDPOINT(bEpNum, \
(EP_CTFR_RX|EP_CTFR_TX|((_GetENDPOINT(bEpNum) | EP_SUBTYPE) & EPREG_MASK))))
#define _ClearEP_SUBTYPE(bEpNum) (_SetENDPOINT(bEpNum, \
(EP_CTFR_RX|EP_CTFR_TX|(_GetENDPOINT(bEpNum) & EPKIND_MASK))))
/*******************************************************************************
* Macro Name : Set_Status_Out / Clear_Status_Out.
* Description : Sets/clears directly STATUS_OUT bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _Set_Status_Out(bEpNum) _SetEP_SUBTYPE(bEpNum)
#define _Clear_Status_Out(bEpNum) _ClearEP_SUBTYPE(bEpNum)
/*******************************************************************************
* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff.
* Description : Sets/clears directly EP_SUBTYPE bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDoubleBuff(bEpNum) _SetEP_SUBTYPE(bEpNum)
#define _ClearEPDoubleBuff(bEpNum) _ClearEP_SUBTYPE(bEpNum)
/*******************************************************************************
* Macro Name : ClearEP_CTFR_RX / ClearEP_CTFR_TX.
* Description : Clears bit CTR_RX / CTR_TX in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearEP_CTFR_RX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK))
#define _ClearEP_CTFR_TX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK))
/*******************************************************************************
* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX .
* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_CTFR_RX|EP_CTFR_TX|EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_CTFR_RX|EP_CTFR_TX|EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
/*******************************************************************************
* Macro Name : ClearDTOG_RX / ClearDTOG_TX.
* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\
_ToggleDTOG_RX(bEpNum)
#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\
_ToggleDTOG_TX(bEpNum)
/*******************************************************************************
* Macro Name : SetEPAddress.
* Description : Sets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* bAddr: Address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\
EP_CTFR_RX|EP_CTFR_TX|(_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr)
/*******************************************************************************
* Macro Name : GetEPAddress.
* Description : Gets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPAddress(bEpNum) ((uint8_t)(_GetENDPOINT(bEpNum) & EPADR_FIELD))
#define _pEPTxAddr(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8 )*2 + PMAAddr))
#define _pEPTxCount(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8+2)*2 + PMAAddr))
#define _pEPRxAddr(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8+4)*2 + PMAAddr))
#define _pEPRxCount(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8+6)*2 + PMAAddr))
/*******************************************************************************
* Macro Name : SetEPTxAddr / SetEPRxAddr.
* Description : sets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* wAddr: address to be set (must be word aligned).
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1))
/*******************************************************************************
* Macro Name : GetEPTxAddr / GetEPRxAddr.
* Description : Gets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : address of the buffer.
*******************************************************************************/
#define _GetEPTxAddr(bEpNum) ((uint16_t)*_pEPTxAddr(bEpNum))
#define _GetEPRxAddr(bEpNum) ((uint16_t)*_pEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPCountRxReg.
* Description : Sets counter of rx buffer with no. of blocks.
* Input : pdwReg: pointer to counter.
* wCount: Counter.
* Output : None.
* Return : None.
*******************************************************************************/
#define _BlocksOf32(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 5;\
if((wCount & 0x1f) == 0)\
wNBlocks--;\
*pdwReg = (uint32_t)((wNBlocks << 10) | 0x8000);\
}/* _BlocksOf32 */
#define _BlocksOf2(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 1;\
if((wCount & 0x1) != 0)\
wNBlocks++;\
*pdwReg = (uint32_t)(wNBlocks << 10);\
}/* _BlocksOf2 */
#define _SetEPCountRxReg(dwReg,wCount) {\
uint16_t wNBlocks;\
if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\
else {_BlocksOf2(dwReg,wCount,wNBlocks);}\
}/* _SetEPCountRxReg */
#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\
uint32_t *pdwReg = _pEPTxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : SetEPTxCount / SetEPRxCount.
* Description : sets counter for the tx/rx buffer.
* Input : bEpNum: endpoint number.
* wCount: Counter value.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount)
#define _SetEPRxCount(bEpNum,wCount) {\
uint32_t *pdwReg = _pEPRxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : GetEPTxCount / GetEPRxCount.
* Description : gets counter of the tx buffer.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : Counter value.
*******************************************************************************/
#define _GetEPTxCount(bEpNum)((uint16_t)(*_pEPTxCount(bEpNum)) & 0x3ff)
#define _GetEPRxCount(bEpNum)((uint16_t)(*_pEPRxCount(bEpNum)) & 0x3ff)
/*******************************************************************************
* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr.
* Description : Sets buffer 0/1 address in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);}
#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);}
/*******************************************************************************
* Macro Name : SetEPDblBuffAddr.
* Description : Sets addresses in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* : wBuf1Addr = buffer 1 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\
} /* _SetEPDblBuffAddr */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum))
#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : bDir: endpoint dir EP_DBUF_OUT = OUT
* EP_DBUF_IN = IN
* : wCount: Counter value
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxDblBuf0Count(bEpNum,wCount);} \
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */ \
*_pEPTxCount(bEpNum) = (uint32_t)wCount; \
} /* SetEPDblBuf0Count*/
#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxCount(bEpNum,wCount);}\
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */\
*_pEPRxCount(bEpNum) = (uint32_t)wCount; \
} /* SetEPDblBuf1Count */
#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\
_SetEPDblBuf0Count(bEpNum, bDir, wCount); \
_SetEPDblBuf1Count(bEpNum, bDir, wCount); \
} /* _SetEPDblBuffCount */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count.
* Description : Gets buffer 0/1 rx/tx counter for double buffering.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum))
#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum))
/* External variables --------------------------------------------------------*/
extern __IO uint16_t wIstr; /* INTSTS register last read value */
/* Exported functions ------------------------------------------------------- */
void SetCTRL(uint16_t /*wRegValue*/);
void SetINTSTS(uint16_t /*wRegValue*/);
void SetDEVADR(uint16_t /*wRegValue*/);
void SetBUFTBL(uint16_t /*wRegValue*/);
void SetBUFTBL(uint16_t /*wRegValue*/);
uint16_t GetCTRL(void);
uint16_t GetINTSTS(void);
uint16_t GetFRNUM(void);
uint16_t GetDEVADR(void);
uint16_t GetBUFTBL(void);
void SetENDPOINT(uint8_t /*bEpNum*/, uint16_t /*wRegValue*/);
uint16_t GetENDPOINT(uint8_t /*bEpNum*/);
void SetEPType(uint8_t /*bEpNum*/, uint16_t /*wType*/);
uint16_t GetEPType(uint8_t /*bEpNum*/);
void SetEPTxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
void SetEPRxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
void SetDouBleBuffEPStall(uint8_t /*bEpNum*/, uint8_t bDir);
uint16_t GetEPTxStatus(uint8_t /*bEpNum*/);
uint16_t GetEPRxStatus(uint8_t /*bEpNum*/);
void SetEPTxValid(uint8_t /*bEpNum*/);
void SetEPRxValid(uint8_t /*bEpNum*/);
uint16_t GetTxStallStatus(uint8_t /*bEpNum*/);
uint16_t GetRxStallStatus(uint8_t /*bEpNum*/);
void SetEP_SUBTYPE(uint8_t /*bEpNum*/);
void ClearEP_SUBTYPE(uint8_t /*bEpNum*/);
void Set_Status_Out(uint8_t /*bEpNum*/);
void Clear_Status_Out(uint8_t /*bEpNum*/);
void SetEPDoubleBuff(uint8_t /*bEpNum*/);
void ClearEPDoubleBuff(uint8_t /*bEpNum*/);
void ClearEP_CTFR_RX(uint8_t /*bEpNum*/);
void ClearEP_CTFR_TX(uint8_t /*bEpNum*/);
void ToggleDTOG_RX(uint8_t /*bEpNum*/);
void ToggleDTOG_TX(uint8_t /*bEpNum*/);
void ClearDTOG_RX(uint8_t /*bEpNum*/);
void ClearDTOG_TX(uint8_t /*bEpNum*/);
void SetEPAddress(uint8_t /*bEpNum*/, uint8_t /*bAddr*/);
uint8_t GetEPAddress(uint8_t /*bEpNum*/);
void SetEPTxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
void SetEPRxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
uint16_t GetEPTxAddr(uint8_t /*bEpNum*/);
uint16_t GetEPRxAddr(uint8_t /*bEpNum*/);
void SetEPCountRxReg(uint32_t * /*pdwReg*/, uint16_t /*wCount*/);
void SetEPTxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
void SetEPRxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
uint16_t GetEPTxCount(uint8_t /*bEpNum*/);
uint16_t GetEPRxCount(uint8_t /*bEpNum*/);
void SetEPDblBuf0Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/);
void SetEPDblBuf1Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf1Addr*/);
void SetEPDblBuffAddr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/, uint16_t /*wBuf1Addr*/);
uint16_t GetEPDblBuf0Addr(uint8_t /*bEpNum*/);
uint16_t GetEPDblBuf1Addr(uint8_t /*bEpNum*/);
void SetEPDblBuffCount(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
void SetEPDblBuf0Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
void SetEPDblBuf1Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
uint16_t GetEPDblBuf0Count(uint8_t /*bEpNum*/);
uint16_t GetEPDblBuf1Count(uint8_t /*bEpNum*/);
EP_DBUF_DIR GetEPDblBufDir(uint8_t /*bEpNum*/);
void FreeUserBuffer(uint8_t bEpNum/*bEpNum*/, uint8_t bDir);
uint16_t ToWord(uint8_t, uint8_t);
uint16_t ByteSwap(uint16_t);
void Set_USB768ByteMode(void);
void Clear_USB768ByteMode(void);
#ifdef __cplusplus
}
#endif
#endif /* __USB_REGS_H */

View File

@@ -0,0 +1,30 @@
/**
******************************************************************************
* File : usb_sil.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Simplified Interface Layer function prototypes.
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_SIL_H
#define __USB_SIL_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint32_t USB_SIL_Init(void);
uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize);
uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer);
/* External variables --------------------------------------------------------*/
#endif /* __USB_SIL_H */

View File

@@ -0,0 +1,37 @@
/**
******************************************************************************
* File : usb_type.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Type definitions used by the USB Library
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_TYPE_H
#define __USB_TYPE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef __cplusplus
typedef enum
{
FALSE = 0, TRUE = !FALSE
}
bool;
#endif
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_TYPE_H */

View File

@@ -0,0 +1,241 @@
/**
******************************************************************************
* File : usb_core.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Standard protocol processing functions prototypes
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CORE_H
#define __USB_CORE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _CONTROL_STATE
{
WAIT_SETUP, /* 0 */
SETTING_UP, /* 1 */
IN_DATA, /* 2 */
OUT_DATA, /* 3 */
LAST_IN_DATA, /* 4 */
LAST_OUT_DATA, /* 5 */
WAIT_STATUS_IN, /* 7 */
WAIT_STATUS_OUT, /* 8 */
STALLED, /* 9 */
PAUSE /* 10 */
} CONTROL_STATE; /* The state machine states of a control pipe */
typedef struct OneDescriptor
{
uint8_t *Descriptor;
uint16_t Descriptor_Size;
}
ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
/* All the request process routines return a value of this type
If the return value is not SUCCESS or NOT_READY,
the software will STALL the correspond endpoint */
typedef enum _RESULT
{
USB_SUCCESS = 0, /* Process successfully */
USB_ERROR,
USB_UNSUPPORT,
USB_NOT_READY /* The process has not been finished, endpoint will be
NAK to further request */
} RESULT;
/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _ENDPOINT_INFO
{
/* When send data out of the device,
CopyData() is used to get data buffer 'Length' bytes data
if Length is 0,
CopyData() returns the total length of the data
if the request is not supported, returns 0
(NEW Feature )
if CopyData() returns -1, the calling routine should not proceed
further and will resume the SETUP process by the class device
if Length is not 0,
CopyData() returns a pointer to indicate the data location
Usb_wLength is the data remain to be sent,
Usb_wOffset is the Offset of original data
When receive data from the host,
CopyData() is used to get user data buffer which is capable
of Length bytes data to copy data from the endpoint buffer.
if Length is 0,
CopyData() returns the available data length,
if Length is not 0,
CopyData() returns user buffer address
Usb_rLength is the data remain to be received,
Usb_rPointer is the Offset of data buffer
*/
uint16_t Usb_wLength;
uint16_t Usb_wOffset;
uint16_t PacketSize;
uint8_t *(*CopyData)(uint16_t Length);
}ENDPOINT_INFO;
/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _DEVICE
{
uint8_t Total_Endpoint; /* Number of endpoints that are used */
uint8_t Total_Configuration;/* Number of configuration available */
}
DEVICE;
typedef union
{
uint16_t w;
struct BW
{
uint8_t bb1;
uint8_t bb0;
}
bw;
} uint16_t_uint8_t;
typedef struct _DEVICE_INFO
{
uint8_t USBbmRequestType; /* bmRequestType */
uint8_t USBbRequest; /* bRequest */
uint16_t_uint8_t USBwValues; /* wValue */
uint16_t_uint8_t USBwIndexs; /* wIndex */
uint16_t_uint8_t USBwLengths; /* wLength */
uint8_t ControlState; /* of type CONTROL_STATE */
uint8_t Current_Feature;
uint8_t Current_Configuration; /* Selected configuration */
uint8_t Current_Interface; /* Selected interface of current configuration */
uint8_t Current_AlternateSetting;/* Selected Alternate Setting of current
interface*/
ENDPOINT_INFO Ctrl_Info;
}DEVICE_INFO;
typedef struct _DEVICE_PROP
{
void (*Init)(void); /* Initialize the device */
void (*Reset)(void); /* Reset routine of this device */
/* Device dependent process after the status stage */
void (*Process_Status_IN)(void);
void (*Process_Status_OUT)(void);
/* Procedure of process on setup stage of a class specified request with data stage */
/* All class specified requests with data stage are processed in Class_Data_Setup
Class_Data_Setup()
responses to check all special requests and fills ENDPOINT_INFO
according to the request
If IN tokens are expected, then wLength & wOffset will be filled
with the total transferring bytes and the starting position
If OUT tokens are expected, then rLength & rOffset will be filled
with the total expected bytes and the starting position in the buffer
If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
CAUTION:
Since GET_CONFIGURATION & GET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_Data_Setup)(uint8_t RequestNo);
/* Procedure of process on setup stage of a class specified request without data stage */
/* All class specified requests without data stage are processed in Class_NoData_Setup
Class_NoData_Setup
responses to check all special requests and perform the request
CAUTION:
Since SET_CONFIGURATION & SET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_NoData_Setup)(uint8_t RequestNo);
/*Class_Get_Interface_Setting
This function is used by the file usb_core.c to test if the selected Interface
and Alternate Setting (uint8_t Interface, uint8_t AlternateSetting) are supported by
the application.
This function is writing by user. It should return "SUCCESS" if the Interface
and Alternate Setting are supported by the application or "UNSUPPORT" if they
are not supported. */
RESULT (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);
uint8_t* (*GetDeviceDescriptor)(uint16_t Length);
uint8_t* (*GetConfigDescriptor)(uint16_t Length);
uint8_t* (*GetStringDescriptor)(uint16_t Length);
/* This field is not used in current library version. It is kept only for
compatibility with previous versions */
void* RxEP_buffer;
uint8_t MaxPacketSize;
}DEVICE_PROP;
typedef struct _USER_STANDARD_REQUESTS
{
void (*User_GetConfiguration)(void); /* Get Configuration */
void (*User_SetConfiguration)(void); /* Set Configuration */
void (*User_GetInterface)(void); /* Get Interface */
void (*User_SetInterface)(void); /* Set Interface */
void (*User_GetStatus)(void); /* Get Status */
void (*User_ClearFeature)(void); /* Clear Feature */
void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */
void (*User_SetDeviceFeature)(void); /* Set Device Feature */
void (*User_SetDeviceAddress)(void); /* Set Device Address */
}
USER_STANDARD_REQUESTS;
/* Exported constants --------------------------------------------------------*/
#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT))
#define Usb_rLength Usb_wLength
#define Usb_rOffset Usb_wOffset
#define USBwValue USBwValues.w
#define USBwValue0 USBwValues.bw.bb0
#define USBwValue1 USBwValues.bw.bb1
#define USBwIndex USBwIndexs.w
#define USBwIndex0 USBwIndexs.bw.bb0
#define USBwIndex1 USBwIndexs.bw.bb1
#define USBwLength USBwLengths.w
#define USBwLength0 USBwLengths.bw.bb0
#define USBwLength1 USBwLengths.bw.bb1
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint8_t Setup0_Process(void);
uint8_t Post0_Process(void);
uint8_t Out0_Process(void);
uint8_t In0_Process(void);
RESULT Standard_SetEndPointFeature(void);
RESULT Standard_SetDeviceFeature(void);
uint8_t *Standard_GetConfiguration(uint16_t Length);
RESULT Standard_SetConfiguration(void);
uint8_t *Standard_GetInterface(uint16_t Length);
RESULT Standard_SetInterface(void);
uint8_t *Standard_GetDescriptorData(uint16_t Length, PONE_DESCRIPTOR pDesc);
uint8_t *Standard_GetStatus(uint16_t Length);
RESULT Standard_ClearFeature(void);
void SetDeviceAddress(uint8_t);
void NOP_Process(void);
extern DEVICE_PROP Device_Property;
extern USER_STANDARD_REQUESTS User_Standard_Requests;
extern DEVICE Device_Table;
extern DEVICE_INFO Device_Info;
/* cells saving status during interrupt servicing */
extern __IO uint16_t SaveRState;
extern __IO uint16_t SaveTState;
#endif /* __USB_CORE_H */

View File

@@ -0,0 +1,75 @@
/**
******************************************************************************
* File : usb_def.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Definitions related to USB Core
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEF_H
#define __USB_DEF_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _RECIPIENT_TYPE
{
DEVICE_RECIPIENT, /* Recipient device */
INTERFACE_RECIPIENT, /* Recipient interface */
ENDPOINT_RECIPIENT, /* Recipient endpoint */
OTHER_RECIPIENT
} RECIPIENT_TYPE;
typedef enum _STANDARD_REQUESTS
{
GET_STATUS = 0,
CLEAR_FEATURE,
RESERVED1,
SET_FEATURE,
RESERVED2,
SET_ADDRESS,
GET_DESCRIPTOR,
SET_DESCRIPTOR,
GET_CONFIGURATION,
SET_CONFIGURATION,
GET_INTERFACE,
SET_INTERFACE,
TOTAL_sREQUEST, /* Total number of Standard request */
SYNCH_FRAME = 12
} STANDARD_REQUESTS;
/* Definition of "USBwValue" */
typedef enum _DESCRIPTOR_TYPE
{
DEVICE_DESCRIPTOR = 1,
CONFIG_DESCRIPTOR,
STRING_DESCRIPTOR,
INTERFACE_DESCRIPTOR,
ENDPOINT_DESCRIPTOR
} DESCRIPTOR_TYPE;
/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */
typedef enum _FEATURE_SELECTOR
{
ENDPOINT_STALL,
DEVICE_REMOTE_WAKEUP
} FEATURE_SELECTOR;
/* Exported constants --------------------------------------------------------*/
/* Definition of "USBbmRequestType" */
#define REQUEST_TYPE 0x60 /* Mask to get request type */
#define STANDARD_REQUEST 0x00 /* Standard request */
#define CLASS_REQUEST 0x20 /* Class request */
#define VENDOR_REQUEST 0x40 /* Vendor request */
#define RECIPIENT 0x1F /* Mask to get recipient */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __USB_DEF_H */

View File

@@ -0,0 +1,51 @@
/**
******************************************************************************
* File : usb_init.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Initialization routines & global variables
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INIT_H
#define __USB_INIT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void USB_Init(void);
/* External variables --------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
extern uint8_t EPindex;
/* The number of current device, it is an index to the Device_Table */
/*extern uint8_t Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_INFO* pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_PROP* pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
extern USER_STANDARD_REQUESTS *pUser_Standard_Requests;
extern uint16_t SaveState ;
extern uint16_t wInterrupt_Mask;
#ifdef __cplusplus
}
#endif
#endif /* __USB_INIT_H */

View File

@@ -0,0 +1,28 @@
/**
******************************************************************************
* File : usb_int.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Endpoint CTRF (Low and High) interrupt's service routines prototypes
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INT_H
#define __USB_INT_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void CTR_LP(void);
void CTR_HP(void);
/* External variables --------------------------------------------------------*/
#endif /* __USB_INT_H */

View File

@@ -0,0 +1,35 @@
/**
******************************************************************************
* File : usb_lib.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : USB library include files
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_LIB_H
#define __USB_LIB_H
/* Includes ------------------------------------------------------------------*/
#include "hw_config.h"
#include "usb_type.h"
#include "usb_regs.h"
#include "usb_def.h"
#include "usb_core.h"
#include "usb_init.h"
#include "usb_sil.h"
#include "usb_mem.h"
#include "usb_int.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_LIB_H */

View File

@@ -0,0 +1,34 @@
/**
******************************************************************************
* File : usb_mem.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Utility prototypes functions for memory/PMA transfers
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_MEM_H
#define __USB_MEM_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
/* External variables --------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /*__USB_MEM_H*/

View File

@@ -0,0 +1,672 @@
/**
******************************************************************************
* File : usb_reg.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Interface prototype functions to USB cell registers
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REGS_H
#define __USB_REGS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _EP_DBUF_DIR
{
/* double buffered endpoint direction */
EP_DBUF_ERR,
EP_DBUF_OUT,
EP_DBUF_IN
}EP_DBUF_DIR;
/* endpoint buffer number */
enum EP_BUF_NUM
{
EP_NOBUF,
EP_BUF0,
EP_BUF1
};
/* Exported constants --------------------------------------------------------*/
#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */
extern int PMAAddr; /* USB_IP Packet Memory Area base address, default is 0x40006000*/
/******************************************************************************/
/* General registers */
/******************************************************************************/
/* Control register */
#define CTRL ((__IO unsigned *)(RegBase + 0x40))
/* Interrupt status register */
#define INTSTS ((__IO unsigned *)(RegBase + 0x44))
/* Frame number register */
#define FRNUM ((__IO unsigned *)(RegBase + 0x48))
/* Device address register */
#define DEVADR ((__IO unsigned *)(RegBase + 0x4C))
/* Buffer Table address register */
#define BUFTBL ((__IO unsigned *)(RegBase + 0x50))
/******************************************************************************/
/* Endpoint registers */
/******************************************************************************/
#define EP0REG ((__IO unsigned *)(RegBase)) /* endpoint 0 register address */
/* Endpoint Addresses (w/direction) */
#define EP0_OUT ((uint8_t)0x00)
#define EP0_IN ((uint8_t)0x80)
#define EP1_OUT ((uint8_t)0x01)
#define EP1_IN ((uint8_t)0x81)
#define EP2_OUT ((uint8_t)0x02)
#define EP2_IN ((uint8_t)0x82)
#define EP3_OUT ((uint8_t)0x03)
#define EP3_IN ((uint8_t)0x83)
#define EP4_OUT ((uint8_t)0x04)
#define EP4_IN ((uint8_t)0x84)
#define EP5_OUT ((uint8_t)0x05)
#define EP5_IN ((uint8_t)0x85)
#define EP6_OUT ((uint8_t)0x06)
#define EP6_IN ((uint8_t)0x86)
#define EP7_OUT ((uint8_t)0x07)
#define EP7_IN ((uint8_t)0x87)
/* endpoints enumeration */
#define ENDP0 ((uint8_t)0)
#define ENDP1 ((uint8_t)1)
#define ENDP2 ((uint8_t)2)
#define ENDP3 ((uint8_t)3)
#define ENDP4 ((uint8_t)4)
#define ENDP5 ((uint8_t)5)
#define ENDP6 ((uint8_t)6)
#define ENDP7 ((uint8_t)7)
/******************************************************************************/
/* INTSTS interrupt events */
/******************************************************************************/
#define INTSTS_CTFR (0x8000) /* Correct TRansfer (clear-only bit) */
#define INTSTS_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */
#define INTSTS_ERRF (0x2000) /* ERRor (clear-only bit) */
#define INTSTS_WKUPF (0x1000) /* WaKe UP (clear-only bit) */
#define INTSTS_SUSPF (0x0800) /* SUSPend (clear-only bit) */
#define INTSTS_RSTF (0x0400) /* RESET (clear-only bit) */
#define INTSTS_SOFF (0x0200) /* Start Of Frame (clear-only bit) */
#define INTSTS_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */
#define INTSTS_DIR (0x0010) /* DIRection of transaction (read-only bit) */
#define INTSTS_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */
#define CLR_CTFR (~INTSTS_CTFR) /* clear Correct TRansfer bit */
#define CLR_DOVR (~INTSTS_DOVR) /* clear DMA OVeR/underrun bit*/
#define CLR_ERRF (~INTSTS_ERRF) /* clear ERRor bit */
#define CLR_WKUPF (~INTSTS_WKUPF) /* clear WaKe UP bit */
#define CLR_SUSPF (~INTSTS_SUSPF) /* clear SUSPend bit */
#define CLR_RSTF (~INTSTS_RSTF) /* clear RESET bit */
#define CLR_SOFF (~INTSTS_SOFF) /* clear Start Of Frame bit */
#define CLR_ESOF (~INTSTS_ESOF) /* clear Expected Start Of Frame bit */
/******************************************************************************/
/* CTRL control register bits definitions */
/******************************************************************************/
#define CTRL_CTFR_IEN (0x8000) /* Correct TRansfer Mask */
#define CTRL_DOVR_IEN (0x4000) /* DMA OVeR/underrun Mask */
#define CTRL_ERR_IEN (0x2000) /* ERRor Mask */
#define CTRL_WKUP_IEN (0x1000) /* WaKe UP Mask */
#define CTRL_SUSP_IEN (0x0800) /* SUSPend Mask */
#define CTRL_RST_IEN (0x0400) /* RESET Mask */
#define CTRL_SOF_IEN (0x0200) /* Start Of Frame Mask */
#define CTRL_ESOF_IEN (0x0100) /* Expected Start Of Frame Mask */
#define CTRL_RESUME (0x0010) /* RESUME request */
#define CTRL_FSUSP (0x0008) /* Force SUSPend */
#define CTRL_LPWR (0x0004) /* Low-power MODE */
#define CTRL_PDWN (0x0002) /* Power DoWN */
#define CTRL_FRST (0x0001) /* Force USB RESet */
/******************************************************************************/
/* FRNUM Frame Number Register bit definitions */
/******************************************************************************/
#define FRNUM_RXDP (0x8000) /* status of D+ data line */
#define FRNUM_RXDM (0x4000) /* status of D- data line */
#define FRNUM_LCK (0x2000) /* LoCKed */
#define FRNUM_LSOF (0x1800) /* Lost SOF */
#define FRNUM_FN (0x07FF) /* Frame Number */
/******************************************************************************/
/* DEVADR Device ADDRess bit definitions */
/******************************************************************************/
#define DEVADR_EN (0x80)
#define DEVADR_ADR (0x7F)
/******************************************************************************/
/* Endpoint register */
/******************************************************************************/
/* bit positions */
#define EP_CTFR_RX (0x8000) /* EndPoint Correct TRansfer RX */
#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */
#define EP_STS_RX (0x3000) /* EndPoint RX STATus bit field */
#define EP_SETUP (0x0800) /* EndPoint SETUP */
#define EP_T_FIELD (0x0600) /* EndPoint TYPE */
#define EP_SUBTYPE (0x0100) /* EndPoint KIND */
#define EP_CTFR_TX (0x0080) /* EndPoint Correct TRansfer TX */
#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */
#define EP_STS_TX (0x0030) /* EndPoint TX STATus bit field */
#define EPADR_FIELD (0x000F) /* EndPoint ADDRess FIELD */
/* EndPoint REGister MASK (no toggle fields) */
#define EPREG_MASK (EP_CTFR_RX|EP_SETUP|EP_T_FIELD|EP_SUBTYPE|EP_CTFR_TX|EPADR_FIELD)
/* EP_TYPE[1:0] EndPoint TYPE */
#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */
#define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK)
/* EP_SUBTYPE EndPoint KIND */
#define EPKIND_MASK (~EP_SUBTYPE & EPREG_MASK)
/* STAT_TX[1:0] STATus for TX transfer */
#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */
#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */
#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */
#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */
#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */
#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */
#define EPTX_DTOGMASK (EP_STS_TX|EPREG_MASK)
/* STAT_RX[1:0] STATus for RX transfer */
#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */
#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */
#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */
#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */
#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOGMASK (EP_STS_RX|EPREG_MASK)
/* Exported macro ------------------------------------------------------------*/
/* SetCTRL */
#define _SetCTRL(wRegValue) (*CTRL = (uint16_t)wRegValue)
/* SetINTSTS */
#define _SetINTSTS(wRegValue) (*INTSTS = (uint16_t)wRegValue)
/* SetDEVADR */
#define _SetDEVADR(wRegValue) (*DEVADR = (uint16_t)wRegValue)
/* SetBUFTBL */
#define _SetBUFTBL(wRegValue)(*BUFTBL = (uint16_t)(wRegValue & 0xFFF8))
/* GetCTRL */
#define _GetCTRL() ((uint16_t) *CTRL)
/* GetINTSTS */
#define _GetINTSTS() ((uint16_t) *INTSTS)
/* GetFRNUM */
#define _GetFRNUM() ((uint16_t) *FRNUM)
/* GetDEVADR */
#define _GetDEVADR() ((uint16_t) *DEVADR)
/* GetBUFTBL */
#define _GetBUFTBL() ((uint16_t) *BUFTBL)
/* SetENDPOINT */
#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \
(uint16_t)wRegValue)
/* GetENDPOINT */
#define _GetENDPOINT(bEpNum) ((uint16_t)(*(EP0REG + bEpNum)))
/*******************************************************************************
* Macro Name : SetEPType
* Description : sets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* wType
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\
((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType )))
/*******************************************************************************
* Macro Name : GetEPType
* Description : gets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Type
*******************************************************************************/
#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD)
/*******************************************************************************
* Macro Name : SetEPTxStatus
* Description : sets the status for tx transfer (bits STAT_TX[1:0]).
* Input : bEpNum: Endpoint Number.
* wState: new state
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxStatus(bEpNum,wState) {\
register uint16_t _wRegVal; \
_wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, (_wRegVal | EP_CTFR_RX|EP_CTFR_TX)); \
} /* _SetEPTxStatus */
/*******************************************************************************
* Macro Name : SetEPRxStatus
* Description : sets the status for rx transfer (bits STAT_TX[1:0])
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxStatus(bEpNum,wState) {\
register uint16_t _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
_SetENDPOINT(bEpNum, (_wRegVal | EP_CTFR_RX|EP_CTFR_TX)); \
} /* _SetEPRxStatus */
/*******************************************************************************
* Macro Name : SetEPRxTxStatus
* Description : sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* wStaterx: new state.
* wStatetx: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxTxStatus(bEpNum,wStaterx,wStatetx) {\
register uint32_t _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & (EPRX_DTOGMASK |EP_STS_TX) ;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wStaterx)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wStaterx)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wStatetx)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wStatetx)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, _wRegVal | EP_CTFR_RX|EP_CTFR_TX); \
} /* _SetEPRxTxStatus */
/*******************************************************************************
* Macro Name : GetEPTxStatus / GetEPRxStatus
* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0]
* /STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : status .
*******************************************************************************/
#define _GetEPTxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EP_STS_TX)
#define _GetEPRxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EP_STS_RX)
/*******************************************************************************
* Macro Name : SetEPTxValid / SetEPRxValid
* Description : sets directly the VALID tx/rx-status into the enpoint register
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID))
#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID))
/*******************************************************************************
* Macro Name : GetTxStallStatus / GetRxStallStatus.
* Description : checks stall condition in an endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : TRUE = endpoint in stall condition.
*******************************************************************************/
#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \
== EP_TX_STALL)
#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \
== EP_RX_STALL)
/*******************************************************************************
* Macro Name : SetEP_SUBTYPE / ClearEP_SUBTYPE.
* Description : set & clear EP_SUBTYPE bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEP_SUBTYPE(bEpNum) (_SetENDPOINT(bEpNum, \
(EP_CTFR_RX|EP_CTFR_TX|((_GetENDPOINT(bEpNum) | EP_SUBTYPE) & EPREG_MASK))))
#define _ClearEP_SUBTYPE(bEpNum) (_SetENDPOINT(bEpNum, \
(EP_CTFR_RX|EP_CTFR_TX|(_GetENDPOINT(bEpNum) & EPKIND_MASK))))
/*******************************************************************************
* Macro Name : Set_Status_Out / Clear_Status_Out.
* Description : Sets/clears directly STATUS_OUT bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _Set_Status_Out(bEpNum) _SetEP_SUBTYPE(bEpNum)
#define _Clear_Status_Out(bEpNum) _ClearEP_SUBTYPE(bEpNum)
/*******************************************************************************
* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff.
* Description : Sets/clears directly EP_SUBTYPE bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDoubleBuff(bEpNum) _SetEP_SUBTYPE(bEpNum)
#define _ClearEPDoubleBuff(bEpNum) _ClearEP_SUBTYPE(bEpNum)
/*******************************************************************************
* Macro Name : ClearEP_CTFR_RX / ClearEP_CTFR_TX.
* Description : Clears bit CTR_RX / CTR_TX in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearEP_CTFR_RX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK))
#define _ClearEP_CTFR_TX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK))
/*******************************************************************************
* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX .
* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_CTFR_RX|EP_CTFR_TX|EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_CTFR_RX|EP_CTFR_TX|EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
/*******************************************************************************
* Macro Name : ClearDTOG_RX / ClearDTOG_TX.
* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\
_ToggleDTOG_RX(bEpNum)
#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\
_ToggleDTOG_TX(bEpNum)
/*******************************************************************************
* Macro Name : SetEPAddress.
* Description : Sets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* bAddr: Address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\
EP_CTFR_RX|EP_CTFR_TX|(_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr)
/*******************************************************************************
* Macro Name : GetEPAddress.
* Description : Gets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPAddress(bEpNum) ((uint8_t)(_GetENDPOINT(bEpNum) & EPADR_FIELD))
#define _pEPTxAddr(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8 )*2 + PMAAddr))
#define _pEPTxCount(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8+2)*2 + PMAAddr))
#define _pEPRxAddr(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8+4)*2 + PMAAddr))
#define _pEPRxCount(bEpNum) ((uint32_t *)((_GetBUFTBL()+bEpNum*8+6)*2 + PMAAddr))
/*******************************************************************************
* Macro Name : SetEPTxAddr / SetEPRxAddr.
* Description : sets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* wAddr: address to be set (must be word aligned).
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1))
/*******************************************************************************
* Macro Name : GetEPTxAddr / GetEPRxAddr.
* Description : Gets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : address of the buffer.
*******************************************************************************/
#define _GetEPTxAddr(bEpNum) ((uint16_t)*_pEPTxAddr(bEpNum))
#define _GetEPRxAddr(bEpNum) ((uint16_t)*_pEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPCountRxReg.
* Description : Sets counter of rx buffer with no. of blocks.
* Input : pdwReg: pointer to counter.
* wCount: Counter.
* Output : None.
* Return : None.
*******************************************************************************/
#define _BlocksOf32(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 5;\
if((wCount & 0x1f) == 0)\
wNBlocks--;\
*pdwReg = (uint32_t)((wNBlocks << 10) | 0x8000);\
}/* _BlocksOf32 */
#define _BlocksOf2(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 1;\
if((wCount & 0x1) != 0)\
wNBlocks++;\
*pdwReg = (uint32_t)(wNBlocks << 10);\
}/* _BlocksOf2 */
#define _SetEPCountRxReg(dwReg,wCount) {\
uint16_t wNBlocks;\
if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\
else {_BlocksOf2(dwReg,wCount,wNBlocks);}\
}/* _SetEPCountRxReg */
#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\
uint32_t *pdwReg = _pEPTxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : SetEPTxCount / SetEPRxCount.
* Description : sets counter for the tx/rx buffer.
* Input : bEpNum: endpoint number.
* wCount: Counter value.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount)
#define _SetEPRxCount(bEpNum,wCount) {\
uint32_t *pdwReg = _pEPRxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : GetEPTxCount / GetEPRxCount.
* Description : gets counter of the tx buffer.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : Counter value.
*******************************************************************************/
#define _GetEPTxCount(bEpNum)((uint16_t)(*_pEPTxCount(bEpNum)) & 0x3ff)
#define _GetEPRxCount(bEpNum)((uint16_t)(*_pEPRxCount(bEpNum)) & 0x3ff)
/*******************************************************************************
* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr.
* Description : Sets buffer 0/1 address in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);}
#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);}
/*******************************************************************************
* Macro Name : SetEPDblBuffAddr.
* Description : Sets addresses in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* : wBuf1Addr = buffer 1 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\
} /* _SetEPDblBuffAddr */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum))
#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : bDir: endpoint dir EP_DBUF_OUT = OUT
* EP_DBUF_IN = IN
* : wCount: Counter value
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxDblBuf0Count(bEpNum,wCount);} \
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */ \
*_pEPTxCount(bEpNum) = (uint32_t)wCount; \
} /* SetEPDblBuf0Count*/
#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxCount(bEpNum,wCount);}\
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */\
*_pEPRxCount(bEpNum) = (uint32_t)wCount; \
} /* SetEPDblBuf1Count */
#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\
_SetEPDblBuf0Count(bEpNum, bDir, wCount); \
_SetEPDblBuf1Count(bEpNum, bDir, wCount); \
} /* _SetEPDblBuffCount */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count.
* Description : Gets buffer 0/1 rx/tx counter for double buffering.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum))
#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum))
/* External variables --------------------------------------------------------*/
extern __IO uint16_t wIstr; /* INTSTS register last read value */
/* Exported functions ------------------------------------------------------- */
void SetCTRL(uint16_t /*wRegValue*/);
void SetINTSTS(uint16_t /*wRegValue*/);
void SetDEVADR(uint16_t /*wRegValue*/);
void SetBUFTBL(uint16_t /*wRegValue*/);
void SetBUFTBL(uint16_t /*wRegValue*/);
uint16_t GetCTRL(void);
uint16_t GetINTSTS(void);
uint16_t GetFRNUM(void);
uint16_t GetDEVADR(void);
uint16_t GetBUFTBL(void);
void SetENDPOINT(uint8_t /*bEpNum*/, uint16_t /*wRegValue*/);
uint16_t GetENDPOINT(uint8_t /*bEpNum*/);
void SetEPType(uint8_t /*bEpNum*/, uint16_t /*wType*/);
uint16_t GetEPType(uint8_t /*bEpNum*/);
void SetEPTxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
void SetEPRxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
void SetDouBleBuffEPStall(uint8_t /*bEpNum*/, uint8_t bDir);
uint16_t GetEPTxStatus(uint8_t /*bEpNum*/);
uint16_t GetEPRxStatus(uint8_t /*bEpNum*/);
void SetEPTxValid(uint8_t /*bEpNum*/);
void SetEPRxValid(uint8_t /*bEpNum*/);
uint16_t GetTxStallStatus(uint8_t /*bEpNum*/);
uint16_t GetRxStallStatus(uint8_t /*bEpNum*/);
void SetEP_SUBTYPE(uint8_t /*bEpNum*/);
void ClearEP_SUBTYPE(uint8_t /*bEpNum*/);
void Set_Status_Out(uint8_t /*bEpNum*/);
void Clear_Status_Out(uint8_t /*bEpNum*/);
void SetEPDoubleBuff(uint8_t /*bEpNum*/);
void ClearEPDoubleBuff(uint8_t /*bEpNum*/);
void ClearEP_CTFR_RX(uint8_t /*bEpNum*/);
void ClearEP_CTFR_TX(uint8_t /*bEpNum*/);
void ToggleDTOG_RX(uint8_t /*bEpNum*/);
void ToggleDTOG_TX(uint8_t /*bEpNum*/);
void ClearDTOG_RX(uint8_t /*bEpNum*/);
void ClearDTOG_TX(uint8_t /*bEpNum*/);
void SetEPAddress(uint8_t /*bEpNum*/, uint8_t /*bAddr*/);
uint8_t GetEPAddress(uint8_t /*bEpNum*/);
void SetEPTxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
void SetEPRxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
uint16_t GetEPTxAddr(uint8_t /*bEpNum*/);
uint16_t GetEPRxAddr(uint8_t /*bEpNum*/);
void SetEPCountRxReg(uint32_t * /*pdwReg*/, uint16_t /*wCount*/);
void SetEPTxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
void SetEPRxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
uint16_t GetEPTxCount(uint8_t /*bEpNum*/);
uint16_t GetEPRxCount(uint8_t /*bEpNum*/);
void SetEPDblBuf0Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/);
void SetEPDblBuf1Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf1Addr*/);
void SetEPDblBuffAddr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/, uint16_t /*wBuf1Addr*/);
uint16_t GetEPDblBuf0Addr(uint8_t /*bEpNum*/);
uint16_t GetEPDblBuf1Addr(uint8_t /*bEpNum*/);
void SetEPDblBuffCount(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
void SetEPDblBuf0Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
void SetEPDblBuf1Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
uint16_t GetEPDblBuf0Count(uint8_t /*bEpNum*/);
uint16_t GetEPDblBuf1Count(uint8_t /*bEpNum*/);
EP_DBUF_DIR GetEPDblBufDir(uint8_t /*bEpNum*/);
void FreeUserBuffer(uint8_t bEpNum/*bEpNum*/, uint8_t bDir);
uint16_t ToWord(uint8_t, uint8_t);
uint16_t ByteSwap(uint16_t);
void Set_USB768ByteMode(void);
void Clear_USB768ByteMode(void);
#ifdef __cplusplus
}
#endif
#endif /* __USB_REGS_H */

View File

@@ -0,0 +1,37 @@
/**
******************************************************************************
* File : usb_type.h
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Type definitions used by the USB Library
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_TYPE_H
#define __USB_TYPE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef __cplusplus
typedef enum
{
FALSE = 0, TRUE = !FALSE
}
bool;
#endif
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_TYPE_H */

View File

@@ -0,0 +1,9 @@
name=AT32_USB-FS-Device_Driver
version=1.0.0
author=AT
maintainer=AT
sentence=Source files wrapper (HAL, LL,...)
paragraph=Allow to not archive source object files to core.a. This avoid the linker to select weak definitions instead of non-weak ones when 'whole-archive' option is not used.
category=Other
url=
architectures=at32

View File

@@ -0,0 +1,975 @@
/**
******************************************************************************
* File : usb_core.c
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Standard protocol processing (USB v2.0)
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ValBit(VAR,Place) (VAR & (1 << Place))
#define SetBit(VAR,Place) (VAR |= (1 << Place))
#define ClrBit(VAR,Place) (VAR &= ((1 << Place) ^ 255))
#define Send0LengthData() { _SetEPTxCount(ENDP0, 0); \
vSetEPTxStatus(EP_TX_VALID); \
}
#define vSetEPRxStatus(st) (SaveRState = st)
#define vSetEPTxStatus(st) (SaveTState = st)
#define USB_StatusIn() Send0LengthData()
#define USB_StatusOut() vSetEPRxStatus(EP_RX_VALID)
#define StatusInfo0 StatusInfo.bw.bb1 /* Reverse bb0 & bb1 */
#define StatusInfo1 StatusInfo.bw.bb0
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint16_t_uint8_t StatusInfo;
bool Data_Mul_MaxPacketSize = FALSE;
/* Private function prototypes -----------------------------------------------*/
static void DataStageOut(void);
static void DataStageIn(void);
static void NoData_Setup0(void);
static void Data_Setup0(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Return the current configuration variable address.
* @param Length: How many bytes are needed.
* @retval 0 if the request is invalid when Length is 0.
* Buffer address if the Length is not 0.
*/
uint8_t *Standard_GetConfiguration(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength =
sizeof(pInformation->Current_Configuration);
return 0;
}
pUser_Standard_Requests->User_GetConfiguration();
return (uint8_t *)&pInformation->Current_Configuration;
}
/**
* @brief This routine is called to set the configuration value
* Then each class should configure device itself.
* @param None.
* @retval USB_SUCCESS if the request is performed.
* USB_UNSUPPORT if the request is invalid.
*/
RESULT Standard_SetConfiguration(void)
{
if ((pInformation->USBwValue0 <=
Device_Table.Total_Configuration) && (pInformation->USBwValue1 == 0)
&& (pInformation->USBwIndex == 0)) /*call Back usb spec 2.0*/
{
pInformation->Current_Configuration = pInformation->USBwValue0;
pUser_Standard_Requests->User_SetConfiguration();
return USB_SUCCESS;
}
else
{
return USB_UNSUPPORT;
}
}
/**
* @brief Return the Alternate Setting of the current interface.
* @param Length: How many bytes are needed.
* @retval 0 if the request is invalid when Length is 0.
* Buffer address if the Length is not 0.
*/
uint8_t *Standard_GetInterface(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength =
sizeof(pInformation->Current_AlternateSetting);
return 0;
}
pUser_Standard_Requests->User_GetInterface();
return (uint8_t *)&pInformation->Current_AlternateSetting;
}
/**
* @brief This routine is called to set the interface.
* Then each class should configure the interface them self.
* @param None.
* @retval USB_SUCCESS if the request is performed.
* USB_UNSUPPORT if the request is invalid.
*/
RESULT Standard_SetInterface(void)
{
RESULT Re;
/*Test if the specified Interface and Alternate Setting are supported by
the application Firmware*/
Re = (*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, pInformation->USBwValue0);
if (pInformation->Current_Configuration != 0)
{
if ((Re != USB_SUCCESS) || (pInformation->USBwIndex1 != 0)
|| (pInformation->USBwValue1 != 0))
{
return USB_UNSUPPORT;
}
else if (Re == USB_SUCCESS)
{
pUser_Standard_Requests->User_SetInterface();
pInformation->Current_Interface = pInformation->USBwIndex0;
pInformation->Current_AlternateSetting = pInformation->USBwValue0;
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}
/**
* @brief Copy the device request data to "StatusInfo buffer".
* @param Length: How many bytes are needed.
* @retval 0 if the Length is 0.
* status address if Length is valid.
*/
uint8_t *Standard_GetStatus(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = 2;
return 0;
}
/* Reset Status Information */
StatusInfo.w = 0;
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{
/*Get Device Status */
uint8_t Feature = pInformation->Current_Feature;
/* Remote Wakeup enabled */
if (ValBit(Feature, 5))
{
SetBit(StatusInfo0, 1);
}
else
{
ClrBit(StatusInfo0, 1);
}
/* Bus-powered */
if (ValBit(Feature, 6))
{
SetBit(StatusInfo0, 0);
}
else /* Self-powered */
{
ClrBit(StatusInfo0, 0);
}
}
/*Interface Status*/
else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
{
return (uint8_t *)&StatusInfo;
}
/*Get EndPoint Status*/
else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
{
uint8_t Related_Endpoint;
uint8_t wIndex0 = pInformation->USBwIndex0;
Related_Endpoint = (wIndex0 & 0x0f);
if (ValBit(wIndex0, 7))
{
/* IN endpoint */
if (_GetTxStallStatus(Related_Endpoint))
{
SetBit(StatusInfo0, 0); /* IN Endpoint stalled */
}
}
else
{
/* OUT endpoint */
if (_GetRxStallStatus(Related_Endpoint))
{
SetBit(StatusInfo0, 0); /* OUT Endpoint stalled */
}
}
}
else
{
return NULL;
}
pUser_Standard_Requests->User_GetStatus();
return (uint8_t *)&StatusInfo;
}
/**
* @brief Clear or disable a specific feature.
* @param None.
* @retval USB_SUCCESS if the request is performed.
* USB_UNSUPPORT if the request is invalid.
*/
RESULT Standard_ClearFeature(void)
{
uint32_t Type_Rec = Type_Recipient;
uint32_t Status;
if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{/*Device Clear Feature*/
ClrBit(pInformation->Current_Feature, 5);
return USB_SUCCESS;
}
else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
{/*EndPoint Clear Feature*/
DEVICE* pDev;
uint32_t Related_Endpoint;
uint32_t wIndex0;
uint32_t rEP;
if ((pInformation->USBwValue != ENDPOINT_STALL)
|| (pInformation->USBwIndex1 != 0))
{
return USB_UNSUPPORT;
}
pDev = &Device_Table;
wIndex0 = pInformation->USBwIndex0;
rEP = wIndex0 & ~0x80;
Related_Endpoint = ENDP0 + rEP;
if (ValBit(pInformation->USBwIndex0, 7))
{
/*Get Status of endpoint & stall the request if the related_ENdpoint
is Disabled*/
Status = _GetEPTxStatus(Related_Endpoint);
}
else
{
Status = _GetEPRxStatus(Related_Endpoint);
}
if ((rEP >= pDev->Total_Endpoint) || (Status == 0)
|| (pInformation->Current_Configuration == 0))
{
return USB_UNSUPPORT;
}
if (wIndex0 & 0x80)
{
/* IN endpoint */
if (_GetTxStallStatus(Related_Endpoint ))
{
ClearDTOG_TX(Related_Endpoint);
SetEPTxStatus(Related_Endpoint, EP_TX_VALID);
}
}
else
{
/* OUT endpoint */
if (_GetRxStallStatus(Related_Endpoint))
{
if (Related_Endpoint == ENDP0)
{
/* After clear the STALL, enable the default endpoint receiver */
SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize);
_SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
}
else
{
ClearDTOG_RX(Related_Endpoint);
_SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
}
}
}
pUser_Standard_Requests->User_ClearFeature();
return USB_SUCCESS;
}
return USB_UNSUPPORT;
}
/**
* @brief Set or enable a specific feature of EndPoint.
* @param None.
* @retval USB_SUCCESS if the request is performed.
* USB_UNSUPPORT if the request is invalid.
*/
RESULT Standard_SetEndPointFeature(void)
{
uint32_t wIndex0;
uint32_t Related_Endpoint;
uint32_t rEP;
uint32_t Status;
wIndex0 = pInformation->USBwIndex0;
rEP = wIndex0 & ~0x80;
Related_Endpoint = ENDP0 + rEP;
if (ValBit(pInformation->USBwIndex0, 7))
{
/* get Status of endpoint & stall the request if the related_ENdpoint
is Disabled*/
Status = _GetEPTxStatus(Related_Endpoint);
}
else
{
Status = _GetEPRxStatus(Related_Endpoint);
}
if (Related_Endpoint >= Device_Table.Total_Endpoint
|| pInformation->USBwValue != 0 || Status == 0
|| pInformation->Current_Configuration == 0)
{
return USB_UNSUPPORT;
}
else
{
if (wIndex0 & 0x80)
{
/* IN endpoint */
_SetEPTxStatus(Related_Endpoint, EP_TX_STALL);
}
else
{
/* OUT endpoint */
_SetEPRxStatus(Related_Endpoint, EP_RX_STALL);
}
}
pUser_Standard_Requests->User_SetEndPointFeature();
return USB_SUCCESS;
}
/**
* @brief Set or enable a specific feature of Device.
* @param None.
* @retval USB_SUCCESS if the request is performed.
* USB_UNSUPPORT if the request is invalid.
*/
RESULT Standard_SetDeviceFeature(void)
{
SetBit(pInformation->Current_Feature, 5);
pUser_Standard_Requests->User_SetDeviceFeature();
return USB_SUCCESS;
}
/**
* @brief Standard_GetDescriptorData is used for descriptors transfer.
This routine is used for the descriptors resident in Flash
* or RAM
* pDesc can be in either Flash or RAM
* The purpose of this routine is to have a versatile way to
* response descriptors request. It allows user to generate
* certain descriptors with software or read descriptors from
* external storage part by part.
* @param Length: Length of the data in this transfer.
* @param pDesc: A pointer points to descriptor struct.
* The structure gives the initial address of the descriptor and its original size
* @retval Address of a part of the descriptor pointed by the Usb_wOffset the buffer pointed
* by this address contains at least Length bytes.
*/
uint8_t *Standard_GetDescriptorData(uint16_t Length, ONE_DESCRIPTOR *pDesc)
{
uint32_t wOffset;
wOffset = pInformation->Ctrl_Info.Usb_wOffset;
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
return 0;
}
return pDesc->Descriptor + wOffset;
}
/**
* @brief Data stage of a Control Write Transfer.
* @param None.
* @retval None.
*/
void DataStageOut(void)
{
ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
uint32_t save_rLength;
save_rLength = pEPinfo->Usb_rLength;
if (pEPinfo->CopyData && save_rLength)
{
uint8_t *Buffer;
uint32_t Length;
Length = pEPinfo->PacketSize;
if (Length > save_rLength)
{
Length = save_rLength;
}
Buffer = (*pEPinfo->CopyData)(Length);
pEPinfo->Usb_rLength -= Length;
pEPinfo->Usb_rOffset += Length;
PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
}
if (pEPinfo->Usb_rLength != 0)
{
vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */
// SetEPTxCount(ENDP0, 0);
// vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */
}
/* Set the next State*/
if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize)
{
pInformation->ControlState = OUT_DATA;
}
else
{
if (pEPinfo->Usb_rLength > 0)
{
pInformation->ControlState = LAST_OUT_DATA;
}
else if (pEPinfo->Usb_rLength == 0)
{
pInformation->ControlState = WAIT_STATUS_IN;
USB_StatusIn();
}
}
}
/**
* @brief Data stage of a Control Read Transfer.
* @param None.
* @retval None.
*/
void DataStageIn(void)
{
ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info;
uint32_t save_wLength = pEPinfo->Usb_wLength;
uint32_t ControlState = pInformation->ControlState;
uint8_t *DataBuffer;
uint32_t Length;
if ((save_wLength == 0) && (ControlState == LAST_IN_DATA))
{
if(Data_Mul_MaxPacketSize == TRUE)
{
/* No more data to send and empty packet */
Send0LengthData();
ControlState = LAST_IN_DATA;
Data_Mul_MaxPacketSize = FALSE;
}
else
{
/* No more data to send so STALL the TX Status*/
ControlState = WAIT_STATUS_OUT;
vSetEPTxStatus(EP_TX_STALL);
}
goto Expect_Status_Out;
}
Length = pEPinfo->PacketSize;
ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA;
if (Length > save_wLength)
{
Length = save_wLength;
}
DataBuffer = (*pEPinfo->CopyData)(Length);
UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
SetEPTxCount(ENDP0, Length);
pEPinfo->Usb_wLength -= Length;
pEPinfo->Usb_wOffset += Length;
vSetEPTxStatus(EP_TX_VALID);
USB_StatusOut();/* Expect the host to abort the data IN stage */
Expect_Status_Out:
pInformation->ControlState = ControlState;
}
/**
* @brief Proceed the processing of setup request without data stage.
* @param None.
* @retval None.
*/
void NoData_Setup0(void)
{
RESULT Result = USB_UNSUPPORT;
uint32_t RequestNo = pInformation->USBbRequest;
uint32_t ControlState;
/* Device Request*/
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{
/* Device Request*/
/* SET_CONFIGURATION*/
if (RequestNo == SET_CONFIGURATION)
{
Result = Standard_SetConfiguration();
}
/*SET ADDRESS*/
else if (RequestNo == SET_ADDRESS)
{
if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0)
|| (pInformation->USBwIndex != 0)
|| (pInformation->Current_Configuration != 0))
/* Device Address should be 127 or less*/
{
ControlState = STALLED;
goto exit_NoData_Setup0;
}
else
{
Result = USB_SUCCESS;
}
}
/*SET FEATURE for Device*/
else if (RequestNo == SET_FEATURE)
{
if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) \
&& (pInformation->USBwIndex == 0))
{
Result = Standard_SetDeviceFeature();
}
else
{
Result = USB_UNSUPPORT;
}
}
/*Clear FEATURE for Device */
else if (RequestNo == CLEAR_FEATURE)
{
if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP
&& pInformation->USBwIndex == 0
&& ValBit(pInformation->Current_Feature, 5))
{
Result = Standard_ClearFeature();
}
else
{
Result = USB_UNSUPPORT;
}
}
}
/* Interface Request*/
else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
{
/*SET INTERFACE*/
if (RequestNo == SET_INTERFACE)
{
Result = Standard_SetInterface();
}
}
/* EndPoint Request*/
else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
{
/*CLEAR FEATURE for EndPoint*/
if (RequestNo == CLEAR_FEATURE)
{
Result = Standard_ClearFeature();
}
/* SET FEATURE for EndPoint*/
else if (RequestNo == SET_FEATURE)
{
Result = Standard_SetEndPointFeature();
}
}
else
{
Result = USB_UNSUPPORT;
}
if (Result != USB_SUCCESS)
{
Result = (*pProperty->Class_NoData_Setup)(RequestNo);
if (Result == USB_NOT_READY)
{
ControlState = PAUSE;
goto exit_NoData_Setup0;
}
}
if (Result != USB_SUCCESS)
{
ControlState = STALLED;
goto exit_NoData_Setup0;
}
ControlState = WAIT_STATUS_IN;/* After no data stage SETUP */
USB_StatusIn();
exit_NoData_Setup0:
pInformation->ControlState = ControlState;
return;
}
/**
* @brief Proceed the processing of setup request with data stage.
* @param None.
* @retval None.
*/
void Data_Setup0(void)
{
uint8_t *(*CopyRoutine)(uint16_t);
RESULT Result;
uint32_t Request_No = pInformation->USBbRequest;
uint32_t Related_Endpoint, Reserved;
uint32_t wOffset, Status;
CopyRoutine = NULL;
wOffset = 0;
/*GET DESCRIPTOR*/
if (Request_No == GET_DESCRIPTOR)
{
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{
uint8_t wValue1 = pInformation->USBwValue1;
if (wValue1 == DEVICE_DESCRIPTOR)
{
CopyRoutine = pProperty->GetDeviceDescriptor;
}
else if (wValue1 == CONFIG_DESCRIPTOR)
{
CopyRoutine = pProperty->GetConfigDescriptor;
}
else if (wValue1 == STRING_DESCRIPTOR)
{
CopyRoutine = pProperty->GetStringDescriptor;
} /* End of GET_DESCRIPTOR */
}
}
/*GET STATUS*/
else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0)
&& (pInformation->USBwLength == 0x0002)
&& (pInformation->USBwIndex1 == 0))
{
/* GET STATUS for Device*/
if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
&& (pInformation->USBwIndex == 0))
{
CopyRoutine = Standard_GetStatus;
}
/* GET STATUS for Interface*/
else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
{
if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)
&& (pInformation->Current_Configuration != 0))
{
CopyRoutine = Standard_GetStatus;
}
}
/* GET STATUS for EndPoint*/
else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
{
Related_Endpoint = (pInformation->USBwIndex0 & 0x0f);
Reserved = pInformation->USBwIndex0 & 0x70;
if (ValBit(pInformation->USBwIndex0, 7))
{
/*Get Status of endpoint & stall the request if the related_ENdpoint
is Disabled*/
Status = _GetEPTxStatus(Related_Endpoint);
}
else
{
Status = _GetEPRxStatus(Related_Endpoint);
}
if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0)
&& (Status != 0))
{
CopyRoutine = Standard_GetStatus;
}
}
}
/*GET CONFIGURATION*/
else if (Request_No == GET_CONFIGURATION)
{
if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
{
CopyRoutine = Standard_GetConfiguration;
}
}
/*GET INTERFACE*/
else if (Request_No == GET_INTERFACE)
{
if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
&& (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0)
&& (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001)
&& ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS))
{
CopyRoutine = Standard_GetInterface;
}
}
if (CopyRoutine)
{
pInformation->Ctrl_Info.Usb_wOffset = wOffset;
pInformation->Ctrl_Info.CopyData = CopyRoutine;
/* sb in the original the cast to word was directly */
/* now the cast is made step by step */
(*CopyRoutine)(0);
Result = USB_SUCCESS;
}
else
{
Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
if (Result == USB_NOT_READY)
{
pInformation->ControlState = PAUSE;
return;
}
}
if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)
{
/* Data is not ready, wait it */
pInformation->ControlState = PAUSE;
return;
}
if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
{
/* Unsupported request */
pInformation->ControlState = STALLED;
return;
}
if (ValBit(pInformation->USBbmRequestType, 7))
{
/* Device ==> Host */
__IO uint32_t wLength = pInformation->USBwLength;
/* Restrict the data length to be the one host asks for */
if (pInformation->Ctrl_Info.Usb_wLength > wLength)
{
pInformation->Ctrl_Info.Usb_wLength = wLength;
}
else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)
{
if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize)
{
Data_Mul_MaxPacketSize = FALSE;
}
else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)
{
Data_Mul_MaxPacketSize = TRUE;
}
}
pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize;
DataStageIn();
}
else
{
pInformation->ControlState = OUT_DATA;
vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */
}
return;
}
/**
* @brief Get the device request data and dispatch to individual process.
* @param None.
* @retval None.
*/
uint8_t Setup0_Process(void)
{
union
{
uint8_t* b;
uint16_t* w;
} pBuf;
uint16_t offset = 1;
pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
if (pInformation->ControlState != PAUSE)
{
pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
pInformation->USBbRequest = *pBuf.b++; /* bRequest */
pBuf.w += offset; /* word not accessed because of 32 bits addressing */
pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
pBuf.w += offset; /* word not accessed because of 32 bits addressing */
pInformation->USBwIndex = ByteSwap(*pBuf.w++); /* wIndex */
pBuf.w += offset; /* word not accessed because of 32 bits addressing */
pInformation->USBwLength = *pBuf.w; /* wLength */
}
pInformation->ControlState = SETTING_UP;
if (pInformation->USBwLength == 0)
{
/* Setup with no data stage */
NoData_Setup0();
}
else
{
/* Setup with data stage */
Data_Setup0();
}
return Post0_Process();
}
/**
* @brief Process the IN token on all default endpoint.
* @param None.
* @retval None.
*/
uint8_t In0_Process(void)
{
uint32_t ControlState = pInformation->ControlState;
if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
{
DataStageIn();
/* ControlState may be changed outside the function */
ControlState = pInformation->ControlState;
}
else if (ControlState == WAIT_STATUS_IN)
{
if ((pInformation->USBbRequest == SET_ADDRESS) &&
(Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
{
SetDeviceAddress(pInformation->USBwValue0);
pUser_Standard_Requests->User_SetDeviceAddress();
}
(*pProperty->Process_Status_IN)();
ControlState = STALLED;
}
else
{
ControlState = STALLED;
}
pInformation->ControlState = ControlState;
return Post0_Process();
}
/**
* @brief Process the OUT token on all default endpoint.
* @param None.
* @retval None.
*/
uint8_t Out0_Process(void)
{
uint32_t ControlState = pInformation->ControlState;
if ((ControlState == IN_DATA) || (ControlState == LAST_IN_DATA))
{
/* host aborts the transfer before finish */
ControlState = STALLED;
}
else if ((ControlState == OUT_DATA) || (ControlState == LAST_OUT_DATA))
{
DataStageOut();
ControlState = pInformation->ControlState; /* may be changed outside the function */
}
else if (ControlState == WAIT_STATUS_OUT)
{
(*pProperty->Process_Status_OUT)();
ControlState = STALLED;
}
/* Unexpect state, STALL the endpoint */
else
{
ControlState = STALLED;
}
pInformation->ControlState = ControlState;
return Post0_Process();
}
/**
* @brief Stall the Endpoint 0 in case of error.
* @param None.
* @retval 0 if the control state is in PAUSE.
* 1 if not.
*/
uint8_t Post0_Process(void)
{
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
/*no need set to STALL*/
if (pInformation->ControlState == STALLED)
{
vSetEPRxStatus(EP_RX_STALL);
vSetEPTxStatus(EP_TX_STALL);
}
return (pInformation->ControlState == PAUSE);
}
/**
* @brief Set the device and all the used Endpoints addresses.
* @param Val: the device address
* @retval None.
*/
void SetDeviceAddress(uint8_t Val)
{
uint32_t i;
uint32_t nEP = Device_Table.Total_Endpoint;
/* set address in every used endpoint */
for (i = 0; i < nEP; i++)
{
_SetEPAddress((uint8_t)i, (uint8_t)i);
} /* for */
_SetDEVADR(Val | DEVADR_EN); /* set device address and enable function */
}
/**
* @brief No operation function.
* @param None.
* @retval None.
*/
void NOP_Process(void)
{
}

View File

@@ -0,0 +1,103 @@
/**
******************************************************************************
* File : usb_init.c
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Initialization routines & global variables
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
uint8_t EPindex;
/* The number of current device, it is an index to the Device_Table */
/* uint8_t Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
DEVICE_INFO *pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
DEVICE_PROP *pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
uint16_t SaveState ;
uint16_t wInterrupt_Mask;
DEVICE_INFO Device_Info;
USER_STANDARD_REQUESTS *pUser_Standard_Requests;
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : USB_Init
* Description : USB system initialization
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
/* Re-enumerate the USB */
void reenumerate() {
// pinMode(PA12, OUTPUT);
GPIO_InitType GPIO_InitStruct = {0};
GPIO_InitStruct.GPIO_Pins = GPIO_Pins_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_WriteBit(GPIOA, GPIO_Pins_12, Bit_RESET); //Blue Pill
for(int i=0;i<1512;i++){};
GPIO_InitStruct.GPIO_Pins = GPIO_Pins_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
for(int i=0;i<512;i++){};
}
void USB_BluePill_Reenumerate()
{
//__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitType GPIO_InitStruct = {0};
GPIO_InitStruct.GPIO_Pins = GPIO_Pins_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT_OD;
GPIO_InitStruct.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_WriteBit(GPIOA, GPIO_Pins_12, Bit_RESET);
//HAL_Delay(1);
}
/**
* @brief USB system initialization.
* @param None.
* @retval None.
*/
void USB_Init(void)
{
//reenumerate();
//USB_BluePill_Reenumerate();
pInformation = &Device_Info;
pInformation->ControlState = 2;
pProperty = &Device_Property;
pUser_Standard_Requests = &User_Standard_Requests;
/* Initialize devices one by one */
pProperty->Init();
//reenumerate();
//USB_BluePill_Reenumerate();
}

View File

@@ -0,0 +1,175 @@
/**
******************************************************************************
* File : usb_int.c
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Endpoint CTRF (Low and High) interrupt's service routines
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t SaveRState;
__IO uint16_t SaveTState;
/* Extern variables ----------------------------------------------------------*/
extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */
extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Low priority Endpoint Correct Transfer interrupt's service.
* routine.
* @param None.
* @retval None.
*/
void CTR_LP(void)
{
__IO uint16_t wEPVal = 0;
/* stay in loop while pending interrupts */
while (((wIstr = _GetINTSTS()) & INTSTS_CTFR) != 0)
{
/* extract highest priority endpoint number */
EPindex = (uint8_t)(wIstr & INTSTS_EP_ID);
if (EPindex == 0 )
{
/* Decode and service control endpoint interrupt */
/* calling related service routine */
/* (Setup0_Process, In0_Process, Out0_Process) */
/* save RX & TX status */
/* and set both to NAK */
SaveRState = _GetENDPOINT(ENDP0);
SaveTState = SaveRState & EP_STS_TX;
SaveRState &= EP_STS_RX;
_SetEPRxTxStatus(ENDP0,EP_RX_NAK,EP_TX_NAK);
/* DIR bit = origin of the interrupt */
if ((wIstr & INTSTS_DIR) == 0)
{
/* DIR = 0 */
/* DIR = 0 => IN int */
/* DIR = 0 implies that (EP_CTFR_TX = 1) always */
_ClearEP_CTFR_TX(ENDP0);
In0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
else
{
/* DIR = 1 */
/* DIR = 1 & CTR_RX => SETUP or OUT int */
/* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
wEPVal = _GetENDPOINT(ENDP0);
if ((wEPVal &EP_SETUP) != 0)
{
_ClearEP_CTFR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
Setup0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
else if ((wEPVal & EP_CTFR_RX) != 0)
{
_ClearEP_CTFR_RX(ENDP0);
Out0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
}
}/* if(EPindex == 0) */
else
{
/* Decode and service non control endpoints interrupt */
/* process related endpoint register */
wEPVal = _GetENDPOINT(EPindex);
if ((wEPVal & EP_CTFR_RX) != 0)
{
/* clear int flag */
_ClearEP_CTFR_RX(EPindex);
/* call OUT service function */
(*pEpInt_OUT[EPindex-1])();
} /* if((wEPVal & EP_CTFR_RX) */
if ((wEPVal & EP_CTFR_TX) != 0)
{
/* clear int flag */
_ClearEP_CTFR_TX(EPindex);
/* call IN service function */
(*pEpInt_IN[EPindex-1])();
} /* if((wEPVal & EP_CTFR_TX) != 0) */
}/* if(EPindex == 0) else */
}/* while(...) */
}
/**
* @brief High Priority Endpoint Correct Transfer interrupt's service.
* routine.
* @param None.
* @retval None.
*/
void CTR_HP(void)
{
uint32_t wEPVal = 0;
while (((wIstr = _GetINTSTS()) & INTSTS_CTFR) != 0)
{
_SetINTSTS((uint16_t)CLR_CTFR); /* clear CTR flag */
/* extract highest priority endpoint number */
EPindex = (uint8_t)(wIstr & INTSTS_EP_ID);
if ( EPindex == 0 )
return;
/* process related endpoint register */
wEPVal = _GetENDPOINT(EPindex);
if ((wEPVal & EP_CTFR_RX) != 0)
{
/* clear int flag */
_ClearEP_CTFR_RX(EPindex);
/* call OUT service function */
(*pEpInt_OUT[EPindex-1])();
} /* if((wEPVal & EP_CTFR_RX) */
else if ((wEPVal & EP_CTFR_TX) != 0)
{
/* clear int flag */
_ClearEP_CTFR_TX(EPindex);
/* call IN service function */
(*pEpInt_IN[EPindex-1])();
} /* if((wEPVal & EP_CTFR_TX) != 0) */
}/* while(...) */
}

View File

@@ -0,0 +1,65 @@
/**
******************************************************************************
* File : usb_mem.c
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Utility functions for memory transfers to/from PMA
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Copy a buffer from user memory area to packet memory area (PMA).
* @param pbUsrBuf: pointer to user memory area.
* @param wPMABufAddr: address into PMA.
* @param wNBytes: number of bytes to be copied.
* @retval None.
*/
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */
uint32_t i, temp1, temp2;
uint16_t *pdwVal;
pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i--)
{
temp1 = (uint16_t) * pbUsrBuf;
pbUsrBuf++;
temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
*pdwVal++ = temp2;
pdwVal++;
pbUsrBuf++;
}
}
/**
* @brief Copy a buffer from packet memory area (PMA) to user memory area.
* @param pbUsrBuf: pointer to user memory area.
* @param wPMABufAddr: address into PMA.
* @param wNBytes: number of bytes to be copied.
* @retval None.
*/
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = (wNBytes + 1) >> 1;/* /2*/
uint32_t i;
uint32_t *pdwVal;
pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i--)
{
*(uint16_t*)pbUsrBuf++ = *pdwVal++;
pbUsrBuf++;
}
}

View File

@@ -0,0 +1,692 @@
/**
******************************************************************************
* File : usb_reg.c
* Version: V1.2.2
* Date : 2020-07-01
* Brief : Interface functions to USB cell registers
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
int PMAAddr = 0x40006000;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Set the CTRL register value.
* @param wRegValue: new register value.
* @retval None.
*/
void SetCTRL(uint16_t wRegValue)
{
_SetCTRL(wRegValue);
}
/**
* @brief returns the CTRL register value.
* @param None.
* @retval CTRL register Value..
*/
uint16_t GetCTRL(void)
{
return(_GetCTRL());
}
/**
* @brief Set the INTSTS register value.
* @param wRegValue: new register value.
* @retval None.
*/
void SetINTSTS(uint16_t wRegValue)
{
_SetINTSTS(wRegValue);
}
/**
* @brief Returns the INTSTS register value.
* @param None.
* @retval INTSTS register Value.
*/
uint16_t GetINTSTS(void)
{
return(_GetINTSTS());
}
/**
* @brief Returns the FRNUM register value.
* @param None.
* @retval FRNUM register Value.
*/
uint16_t GetFRNUM(void)
{
return(_GetFRNUM());
}
/**
* @brief Set the DEVADR register value.
* @param wRegValue: new register value.
* @retval None.
*/
void SetDEVADR(uint16_t wRegValue)
{
_SetDEVADR(wRegValue);
}
/**
* @brief Returns the DEVADR register value.
* @param None.
* @retval DEVADR register Value.
*/
uint16_t GetDEVADR(void)
{
return(_GetDEVADR());
}
/**
* @brief Set the BUFTBL.
* @param wRegValue: New register value.
* @retval None.
*/
void SetBUFTBL(uint16_t wRegValue)
{
_SetBUFTBL(wRegValue);
}
/**
* @brief Returns the BUFTBL register value.
* @param None
* @retval BUFTBL address.
*/
uint16_t GetBUFTBL(void)
{
return(_GetBUFTBL());
}
/**
* @brief Set the Endpoint register value.
* @param bEpNum: Endpoint Number.
* @param wRegValue: New register value.
* @retval None.
*/
void SetENDPOINT(uint8_t bEpNum, uint16_t wRegValue)
{
_SetENDPOINT(bEpNum, wRegValue);
}
/**
* @brief Return the Endpoint register value.
* @param bEpNum: Endpoint Number.
* @retval Endpoint register value.
*/
uint16_t GetENDPOINT(uint8_t bEpNum)
{
return(_GetENDPOINT(bEpNum));
}
/**
* @brief sets the type in the endpoint register.
* @param bEpNum: Endpoint Number.
* @param wType: type definition.
* @retval None.
*/
void SetEPType(uint8_t bEpNum, uint16_t wType)
{
_SetEPType(bEpNum, wType);
}
/**
* @brief Returns the endpoint type.
* @param bEpNum: Endpoint Number.
* @retval Endpoint Type.
*/
uint16_t GetEPType(uint8_t bEpNum)
{
return(_GetEPType(bEpNum));
}
/**
* @brief Set the status of Tx endpoint.
* @param bEpNum: Endpoint Number.
* @param wState: new state.
* @retval None.
*/
void SetEPTxStatus(uint8_t bEpNum, uint16_t wState)
{
_SetEPTxStatus(bEpNum, wState);
}
/**
* @brief Set the status of Rx endpoint.
* @param bEpNum: Endpoint Number.
* @param wState: new state.
* @retval None.
*/
void SetEPRxStatus(uint8_t bEpNum, uint16_t wState)
{
_SetEPRxStatus(bEpNum, wState);
}
/**
* @brief sets the status for Double Buffer Endpoint to STALL
* @param bEpNum: Endpoint Number.
* @param bDir: Endpoint direction.
* @retval None.
*/
void SetDouBleBuffEPStall(uint8_t bEpNum, uint8_t bDir)
{
uint16_t Endpoint_DTOG_Status;
Endpoint_DTOG_Status = GetENDPOINT(bEpNum);
if (bDir == EP_DBUF_OUT)
{ /* OUT double buffered endpoint */
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1);
}
else if (bDir == EP_DBUF_IN)
{ /* IN double buffered endpoint */
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1);
}
}
/**
* @brief Returns the endpoint Tx status.
* @param bEpNum: Endpoint Number.
* @retval Endpoint TX Status.
*/
uint16_t GetEPTxStatus(uint8_t bEpNum)
{
return(_GetEPTxStatus(bEpNum));
}
/**
* @brief Returns the endpoint Rx status.
* @param bEpNum: Endpoint Number.
* @retval Endpoint RX Status.
*/
uint16_t GetEPRxStatus(uint8_t bEpNum)
{
return(_GetEPRxStatus(bEpNum));
}
/**
* @brief Valid the endpoint Tx Status.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void SetEPTxValid(uint8_t bEpNum)
{
_SetEPTxStatus(bEpNum, EP_TX_VALID);
}
/**
* @brief Valid the endpoint Rx Status.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void SetEPRxValid(uint8_t bEpNum)
{
_SetEPRxStatus(bEpNum, EP_RX_VALID);
}
/**
* @brief Clear the EP_SUBTYPE bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void SetEP_SUBTYPE(uint8_t bEpNum)
{
_SetEP_SUBTYPE(bEpNum);
}
/**
* @brief set the EP_SUBTYPE bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ClearEP_SUBTYPE(uint8_t bEpNum)
{
_ClearEP_SUBTYPE(bEpNum);
}
/**
* @brief Clear the Status Out of the related Endpoint
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void Clear_Status_Out(uint8_t bEpNum)
{
_ClearEP_SUBTYPE(bEpNum);
}
/**
* @brief Set the Status Out of the related Endpoint
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void Set_Status_Out(uint8_t bEpNum)
{
_SetEP_SUBTYPE(bEpNum);
}
/**
* @brief Enable the double buffer feature for the endpoint.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void SetEPDoubleBuff(uint8_t bEpNum)
{
_SetEP_SUBTYPE(bEpNum);
}
/**
* @brief Disable the double buffer feature for the endpoint.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ClearEPDoubleBuff(uint8_t bEpNum)
{
_ClearEP_SUBTYPE(bEpNum);
}
/**
* @brief Returns the Stall status of the Tx endpoint.
* @param bEpNum: Endpoint Number.
* @retval Tx Stall status.
*/
uint16_t GetTxStallStatus(uint8_t bEpNum)
{
return(_GetTxStallStatus(bEpNum));
}
/**
* @brief Returns the Stall status of the Rx endpoint.
* @param bEpNum: Endpoint Number.
* @retval Rx Stall status.
*/
uint16_t GetRxStallStatus(uint8_t bEpNum)
{
return(_GetRxStallStatus(bEpNum));
}
/**
* @brief Clear the CTRF_RX bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ClearEP_CTFR_RX(uint8_t bEpNum)
{
_ClearEP_CTFR_RX(bEpNum);
}
/**
* @brief Clear the CTRF_TX bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ClearEP_CTFR_TX(uint8_t bEpNum)
{
_ClearEP_CTFR_TX(bEpNum);
}
/**
* @brief Toggle the DTOG_RX bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ToggleDTOG_RX(uint8_t bEpNum)
{
_ToggleDTOG_RX(bEpNum);
}
/**
* @brief Toggle the DTOG_TX bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ToggleDTOG_TX(uint8_t bEpNum)
{
_ToggleDTOG_TX(bEpNum);
}
/**
* @brief Clear the DTOG_RX bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ClearDTOG_RX(uint8_t bEpNum)
{
_ClearDTOG_RX(bEpNum);
}
/**
* @brief Clear the DTOG_TX bit.
* @param bEpNum: Endpoint Number.
* @retval None.
*/
void ClearDTOG_TX(uint8_t bEpNum)
{
_ClearDTOG_TX(bEpNum);
}
/**
* @brief Set the endpoint address.
* @param bEpNum: Endpoint Number.
* @param bAddr: New endpoint address.
* @retval None.
*/
void SetEPAddress(uint8_t bEpNum, uint8_t bAddr)
{
_SetEPAddress(bEpNum, bAddr);
}
/**
* @brief Get the endpoint address.
* @param bEpNum: Endpoint Number.
* @retval Endpoint address.
*/
uint8_t GetEPAddress(uint8_t bEpNum)
{
return(_GetEPAddress(bEpNum));
}
/**
* @brief Set the endpoint Tx buffer address.
* @param bEpNum: Endpoint Number.
* @param wAddr: New address.
* @retval None.
*/
void SetEPTxAddr(uint8_t bEpNum, uint16_t wAddr)
{
_SetEPTxAddr(bEpNum, wAddr);
}
/**
* @brief Set the endpoint Rx buffer address.
* @param bEpNum: Endpoint Number.
* @param wAddr: New address.
* @retval None.
*/
void SetEPRxAddr(uint8_t bEpNum, uint16_t wAddr)
{
_SetEPRxAddr(bEpNum, wAddr);
}
/**
* @brief Returns the endpoint Tx buffer address.
* @param bEpNum: Endpoint Number.
* @retval Tx buffer address.
*/
uint16_t GetEPTxAddr(uint8_t bEpNum)
{
return(_GetEPTxAddr(bEpNum));
}
/**
* @brief Returns the endpoint Rx buffer address.
* @param bEpNum: Endpoint Number.
* @retval Rx buffer address.
*/
uint16_t GetEPRxAddr(uint8_t bEpNum)
{
return(_GetEPRxAddr(bEpNum));
}
/**
* @brief Set the Tx count.
* @param bEpNum: Endpoint Number.
* @param wCount: new count value.
* @retval None.
*/
void SetEPTxCount(uint8_t bEpNum, uint16_t wCount)
{
_SetEPTxCount(bEpNum, wCount);
}
/**
* @brief Set the Count Rx Register value.
* @param *pdwReg: point to the register.
* @param wCount: the new register value.
* @retval None.
*/
void SetEPCountRxReg(uint32_t *pdwReg, uint16_t wCount)
{
_SetEPCountRxReg(dwReg, wCount);
}
/**
* @brief Set the Rx count.
* @param bEpNum: Endpoint Number.
* @param wCount: the new count value.
* @retval None.
*/
void SetEPRxCount(uint8_t bEpNum, uint16_t wCount)
{
_SetEPRxCount(bEpNum, wCount);
}
/**
* @brief Get the Tx count.
* @param bEpNum: Endpoint Number.
* @retval Tx count value.
*/
uint16_t GetEPTxCount(uint8_t bEpNum)
{
return(_GetEPTxCount(bEpNum));
}
/**
* @brief Get the Rx count.
* @param bEpNum: Endpoint Number.
* @retval Rx count value.
*/
uint16_t GetEPRxCount(uint8_t bEpNum)
{
return(_GetEPRxCount(bEpNum));
}
/**
* @brief Set the addresses of the buffer 0 and 1.
* @param bEpNum: Endpoint Number.
* @param wBuf0Addr: new address of buffer 0.
* @param wBuf1Addr: new address of buffer 1.
* @retval None.
*/
void SetEPDblBuffAddr(uint8_t bEpNum, uint16_t wBuf0Addr, uint16_t wBuf1Addr)
{
_SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr);
}
/**
* @brief Set the Buffer 0 address.
* @param bEpNum: Endpoint Number.
* @param wBuf0Addr: new address of buffer 0.
* @retval None.
*/
void SetEPDblBuf0Addr(uint8_t bEpNum, uint16_t wBuf0Addr)
{
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);
}
/**
* @brief Set the Buffer 1 address.
* @param bEpNum: Endpoint Number.
* @param wBuf1Addr: new address of buffer 1.
* @retval None.
*/
void SetEPDblBuf1Addr(uint8_t bEpNum, uint16_t wBuf1Addr)
{
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);
}
/**
* @brief Returns the address of the Buffer 0.
* @param bEpNum: Endpoint Number.
* @retval buffer 0 address.
*/
uint16_t GetEPDblBuf0Addr(uint8_t bEpNum)
{
return(_GetEPDblBuf0Addr(bEpNum));
}
/**
* @brief Returns the address of the Buffer 1.
* @param bEpNum: Endpoint Number.
* @retval buffer 1 address.
*/
uint16_t GetEPDblBuf1Addr(uint8_t bEpNum)
{
return(_GetEPDblBuf1Addr(bEpNum));
}
/**
* @brief Set the number of bytes for a double Buffer endpoint.
* @param bEpNum: Endpoint Number.
* @param bDin: Endpoint dir (IN/OUT).
* @param wCount: buffer count.
* @retval None.
*/
void SetEPDblBuffCount(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
{
_SetEPDblBuffCount(bEpNum, bDir, wCount);
}
/**
* @brief Set the number of bytes for a double Buffer0 endpoint.
* @param bEpNum: Endpoint Number.
* @param bDin: Endpoint dir (IN/OUT).
* @param wCount: buffer count.
* @retval None.
*/
void SetEPDblBuf0Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
{
_SetEPDblBuf0Count(bEpNum, bDir, wCount);
}
/**
* @brief Set the number of bytes for a double Buffer1 endpoint.
* @param bEpNum: Endpoint Number.
* @param bDin: Endpoint dir (IN/OUT).
* @param wCount: buffer count.
* @retval None.
*/
void SetEPDblBuf1Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
{
_SetEPDblBuf1Count(bEpNum, bDir, wCount);
}
/**
* @brief Returns the number of byte received in the buffer 0
of a double Buffer endpoint.
* @param bEpNum: Endpoint Number.
* @retval Endpoint Buffer 0 count.
*/
uint16_t GetEPDblBuf0Count(uint8_t bEpNum)
{
return(_GetEPDblBuf0Count(bEpNum));
}
/**
* @brief Returns the number of byte received in the buffer 1
of a double Buffer endpoint.
* @param bEpNum: Endpoint Number.
* @retval Endpoint Buffer 1 count.
*/
uint16_t GetEPDblBuf1Count(uint8_t bEpNum)
{
return(_GetEPDblBuf1Count(bEpNum));
}
/**
* @brief gets direction of the double buffered endpoint.
* @param bEpNum: Endpoint Number.
* @retval EP_DBUF_OUT, EP_DBUF_IN,
* EP_DBUF_ERR if the endpoint counter not yet programmed.
*/
EP_DBUF_DIR GetEPDblBufDir(uint8_t bEpNum)
{
if ((uint16_t)(*_pEPRxCount(bEpNum) & 0xFC00) != 0)
return(EP_DBUF_OUT);
else if (((uint16_t)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0)
return(EP_DBUF_IN);
else
return(EP_DBUF_ERR);
}
/**
* @brief free buffer used from the application realizing it to the line
toggles bit SW_BUF in the double buffered endpoint register.
* @param bEpNum: Endpoint Number.
* @param bDir: Endpoint dir (IN/OUT).
* @retval None.
*/
void FreeUserBuffer(uint8_t bEpNum, uint8_t bDir)
{
if (bDir == EP_DBUF_OUT)
{ /* OUT double buffered endpoint */
_ToggleDTOG_TX(bEpNum);
}
else if (bDir == EP_DBUF_IN)
{ /* IN double buffered endpoint */
_ToggleDTOG_RX(bEpNum);
}
}
/**
* @brief merge two byte in a word.
* @param bh: byte high.
* @param bl: bytes low.
* @retval resulted word..
*/
uint16_t ToWord(uint8_t bh, uint8_t bl)
{
uint16_t wRet;
wRet = (uint16_t)bl | ((uint16_t)bh << 8);
return(wRet);
}
/**
* @brief Swap two byte in a word.
* @param wSwW: word to Swap.
* @retval resulted word..
*/
uint16_t ByteSwap(uint16_t wSwW)
{
uint8_t bTemp;
uint16_t wRet;
bTemp = (uint8_t)(wSwW & 0xff);
wRet = (wSwW >> 8) | ((uint16_t)bTemp << 8);
return(wRet);
}
/**
* @brief Set USB SRAM size to 768 byte.
* @param None.
* @retval None..
*/
void Set_USB768ByteMode(void)
{
/*Enable 768 Byte, Enable RCC->MISC*/
RCC->MISC |= 0x1 << 24;
/*USB SRAM Base address*/
PMAAddr = 0x40007800;
}
/**
* @brief Clear USB 768 byte mode, USB SRAM size is 512 byte.
* @param None.
* @retval None..
*/
void Clear_USB768ByteMode(void)
{
/*Clear 768 byte mode*/
RCC->MISC &= ~(0x1 << 24);
/*USB SRAM Base address*/
PMAAddr = 0x40006000;
}

View File

@@ -44,7 +44,7 @@ env.Append(
"-std=gnu11", "-std=gnu11",
], ],
CCFLAGS=[ CCFLAGS=[
"-Os", # optimize for speed "-O1", # optimize for speed Os
"-mcpu=%s" % board_config.get("build.cpu"), "-mcpu=%s" % board_config.get("build.cpu"),
"-mthumb", "-mthumb",
"-ffunction-sections", # place each function in its own section "-ffunction-sections", # place each function in its own section
@@ -93,4 +93,11 @@ libs.append(
join("$BUILD_DIR", "AT32F4xx_StdPeriph"), join(FRAMEWORK_DIR, "libraries", "AT32F4xx_StdPeriph_Driver") join("$BUILD_DIR", "AT32F4xx_StdPeriph"), join(FRAMEWORK_DIR, "libraries", "AT32F4xx_StdPeriph_Driver")
) )
) )
libs.append(
env.BuildLibrary(
join("$BUILD_DIR", "AT32_USB-FS-Device"), join(FRAMEWORK_DIR, "libraries", "AT32_USB-FS-Device_Driver")
)
)
env.Prepend(LIBS=libs) env.Prepend(LIBS=libs)