/**************************************************************************//** * @file usbd.h * @version V1.00 * $Revision: 21 $ * $Date: 14/10/06 1:29p $ * @brief NUC472/NUC442 USBD driver header file * * @note * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #ifndef __USBD_H__ #define __USBD_H__ #ifdef __cplusplus extern "C" { #endif /** @addtogroup NUC472_442_Device_Driver NUC472/NUC442 Device Driver @{ */ /** @addtogroup NUC472_442_USBD_Driver USBD Driver @{ */ /** @addtogroup NUC472_442_USBD_EXPORTED_CONSTANTS USBD Exported Constants @{ */ /// @cond HIDDEN_SYMBOLS #define USBD_MAX_EP 12 #define Maximum(a,b) (a)>(b) ? (a) : (b) #define Minimum(a,b) (a)<(b) ? (a) : (b) #define CEP 0xff /*!< Control Endpoint \hideinitializer */ #define EPA 0 /*!< Endpoint A \hideinitializer */ #define EPB 1 /*!< Endpoint B \hideinitializer */ #define EPC 2 /*!< Endpoint C \hideinitializer */ #define EPD 3 /*!< Endpoint D \hideinitializer */ #define EPE 4 /*!< Endpoint E \hideinitializer */ #define EPF 5 /*!< Endpoint F \hideinitializer */ #define EPG 6 /*!< Endpoint G \hideinitializer */ #define EPH 7 /*!< Endpoint H \hideinitializer */ #define EPI 8 /*!< Endpoint I \hideinitializer */ #define EPJ 9 /*!< Endpoint J \hideinitializer */ #define EPK 10 /*!< Endpoint K \hideinitializer */ #define EPL 11 /*!< Endpoint L \hideinitializer */ /* USB Request Type */ #define REQ_STANDARD 0x00 #define REQ_CLASS 0x20 #define REQ_VENDOR 0x40 /* USB Standard Request */ #define USBD_GET_STATUS 0x00 #define USBD_CLEAR_FEATURE 0x01 #define USBD_SET_FEATURE 0x03 #define USBD_SET_ADDRESS 0x05 #define USBD_GET_DESCRIPTOR 0x06 #define USBD_SET_DESCRIPTOR 0x07 #define USBD_GET_CONFIGURATION 0x08 #define USBD_SET_CONFIGURATION 0x09 #define USBD_GET_INTERFACE 0x0A #define USBD_SET_INTERFACE 0x0B #define USBD_SYNC_FRAME 0x0C /* USB Descriptor Type */ #define DESC_DEVICE 0x01 #define DESC_CONFIG 0x02 #define DESC_STRING 0x03 #define DESC_INTERFACE 0x04 #define DESC_ENDPOINT 0x05 #define DESC_QUALIFIER 0x06 #define DESC_OTHERSPEED 0x07 #define DESC_IFPOWER 0x08 #define DESC_OTG 0x09 /* USB HID Descriptor Type */ #define DESC_HID 0x21 #define DESC_HID_RPT 0x22 /* USB Descriptor Length */ #define LEN_DEVICE 18 #define LEN_QUALIFIER 10 #define LEN_CONFIG 9 #define LEN_INTERFACE 9 #define LEN_ENDPOINT 7 #define LEN_OTG 5 #define LEN_HID 9 /* USB Endpoint Type */ #define EP_ISO 0x01 #define EP_BULK 0x02 #define EP_INT 0x03 #define EP_INPUT 0x80 #define EP_OUTPUT 0x00 /* USB Feature Selector */ #define FEATURE_DEVICE_REMOTE_WAKEUP 0x01 #define FEATURE_ENDPOINT_HALT 0x00 /// @endcond HIDDEN_SYMBOLS /********************* Bit definition of CEPCTL register **********************/ #define USB_CEPCTL_NAKCLR ((uint32_t)0x00000000) /*!PHYCTL |= (USBD_PHYCTL_PHYEN_Msk|USBD_PHYCTL_DPPUEN_Msk))) /*!PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk)) /*!PHYCTL |= USBD_PHYCTL_PHYEN_Msk)) /*!PHYCTL &= ~USBD_PHYCTL_PHYEN_Msk)) /*!PHYCTL &= ~USBD_PHYCTL_DPPUEN_Msk)) /*!PHYCTL |= USBD_PHYCTL_DPPUEN_Msk)) /*!FADDR = (addr)) /*!FADDR)) /*!GINTEN = (intr)) /*!BUSINTEN = (intr)) /*!BUSINTSTS) /*!BUSINTSTS = flag) /*!CEPINTEN = (intr)) /*!CEPINTSTS = flag) /*!CEPCTL = flag) /*!CEPTXCNT = size) /*!EPAMPS + (uint32_t)((ep)*0x28))) = (size)) /*!EPAINTEN + (uint32_t)((ep)*0x28))) = (intr)) /*!EPAINTSTS + (uint32_t)((ep)*0x28)))) /*!EPAINTSTS + (uint32_t)((ep)*0x28))) = (flag)) /*!DMACNT = len) /*!DMAADDR = addr) /*!DMACTL = (USBD->DMACTL & ~USBD_DMACTL_EPNUM_Msk) | USBD_DMACTL_DMARD_Msk | epnum) /*!DMACTL = (USBD->DMACTL & ~(USBD_DMACTL_EPNUM_Msk | USBD_DMACTL_DMARD_Msk)) | epnum) /*!DMACTL |= USBD_DMACTL_DMAEN_Msk) /*!PHYCTL & USBD_PHYCTL_VBUSDET_Msk)) /*!DMACNT = 0; USBD->DMACTL = 0x80; USBD->DMACTL = 0x00; } /** * @brief USBD_SetEpBufAddr, Set Endpoint buffer address * @param[in] u32Ep Endpoint Number * @param[in] u32Base Buffer Start Address * @param[in] u32Len Buffer length * @retval None. */ static __INLINE void USBD_SetEpBufAddr(uint32_t u32Ep, uint32_t u32Base, uint32_t u32Len) { if (u32Ep == CEP) { USBD->CEPBUFSTART = u32Base; USBD->CEPBUFEND = u32Base + u32Len - 1; } else { *((__IO uint32_t *) ((uint32_t)&USBD->EPABUFSTART + (uint32_t)(u32Ep*0x28))) = u32Base; *((__IO uint32_t *) ((uint32_t)&USBD->EPABUFEND + (uint32_t)(u32Ep*0x28))) = u32Base + u32Len - 1; } } /** * @brief USBD_ConfigEp, Config Endpoint * @param[in] u32Ep USB endpoint * @param[in] u32EpNum Endpoint number * @param[in] u32EpType Endpoint type * @param[in] u32EpDir Endpoint direction * @retval None. */ static __INLINE void USBD_ConfigEp(uint32_t u32Ep, uint32_t u32EpNum, uint32_t u32EpType, uint32_t u32EpDir) { if (u32EpType == USB_EP_CFG_TYPE_BULK) *((__IO uint32_t *)((uint32_t)&USBD->EPARSPCTL+(uint32_t)(u32Ep*0x28)))=(USB_EP_RSPCTL_FLUSH|USB_EP_RSPCTL_MODE_AUTO); else if (u32EpType == USB_EP_CFG_TYPE_INT) *((__IO uint32_t *)((uint32_t)&USBD->EPARSPCTL+(uint32_t)(u32Ep*0x28)))=(USB_EP_RSPCTL_FLUSH|USB_EP_RSPCTL_MODE_MANUAL); else if (u32EpType == USB_EP_CFG_TYPE_ISO) *((__IO uint32_t *)((uint32_t)&USBD->EPARSPCTL+(uint32_t)(u32Ep*0x28)))=(USB_EP_RSPCTL_FLUSH|USB_EP_RSPCTL_MODE_FLY); *((__IO uint32_t *)((uint32_t)&USBD->EPACFG+(uint32_t)(u32Ep*0x28)))=(u32EpType|u32EpDir|USB_EP_CFG_VALID|(u32EpNum << 4)); } /** * @brief Set USB endpoint stall state * * @param[in] u32Ep USB endpoint * @return None * * @details Set USB endpoint stall state, endpoint will return STALL token. */ static __INLINE void USBD_SetStall(uint32_t u32Ep) { uint32_t u32CfgAddr; uint32_t u32Cfg; int i; if (u32Ep == 0) USBD_SET_CEP_STATE(USB_CEPCTL_STALL); else { for (i=0; iEPACFG + (uint32_t)(i * 0x28); u32Cfg = *((__IO uint32_t *) (u32CfgAddr)); if (((u32Cfg & 0xf0) >> 4) == u32Ep) { u32CfgAddr = (uint32_t)&USBD->EPARSPCTL + (uint32_t)(i * 0x28); u32Cfg = *((__IO uint32_t *) (u32CfgAddr)) & 0xf7; /* avoid clear TOGGLE bit */ *((__IO uint32_t *) (u32CfgAddr)) = (u32Cfg | USB_EP_RSPCTL_HALT); } } } } /** * @brief Clear USB endpoint stall state * * @param[in] u32Ep USB endpoint * @return None * * @details Clear USB endpoint stall state, endpoint will return ACK/NAK token. */ static __INLINE void USBD_ClearStall(uint32_t u32Ep) { uint32_t u32CfgAddr; uint32_t u32Cfg; int i; for (i=0; iEPACFG + (uint32_t)(i * 0x28); u32Cfg = *((__IO uint32_t *) (u32CfgAddr)); if (((u32Cfg & 0xf0) >> 4) == u32Ep) { u32CfgAddr = (uint32_t)&USBD->EPARSPCTL + (uint32_t)(i * 0x28); *((__IO uint32_t *) (u32CfgAddr)) = USB_EP_RSPCTL_TOGGLE; } } } /** * @brief Get USB endpoint stall state * * @param[in] u32Ep USB endpoint * @retval 0: USB endpoint is not stalled. * @retval non-0: USB endpoint is stalled. * * @details Get USB endpoint stall state. */ static __INLINE uint32_t USBD_GetStall(uint32_t u32Ep) { uint32_t u32CfgAddr; uint32_t u32Cfg; int i; for (i=0; iEPACFG + (uint32_t)(i * 0x28); u32Cfg = *((__IO uint32_t *) (u32CfgAddr)); if (((u32Cfg & 0xf0) >> 4) == u32Ep) { u32CfgAddr = (uint32_t)&USBD->EPARSPCTL + (uint32_t)(i * 0x28); return ((*((__IO uint32_t *) (u32CfgAddr))) & USB_EP_RSPCTL_HALT); } } return 0; } /*-------------------------------------------------------------------------------------------*/ typedef void (*VENDOR_REQ)(void); /*!