/**************************************************************************//** * @file usbd.h * @brief N9H30 USBD driver header file * * @note * SPDX-License-Identifier: Apache-2.0 * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #ifndef __NU_USBD_H__ #define __NU_USBD_H__ #ifdef __cplusplus extern "C" { #endif /** @addtogroup N9H30_Device_Driver N9H30 Device Driver @{ */ /** @addtogroup N9H30_USBD_Driver USBD Driver @{ */ /** @addtogroup N9H30_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 GET_STATUS 0x00 #define CLEAR_FEATURE 0x01 #define SET_FEATURE 0x03 #define SET_ADDRESS 0x05 #define GET_DESCRIPTOR 0x06 #define SET_DESCRIPTOR 0x07 #define GET_CONFIGURATION 0x08 #define SET_CONFIGURATION 0x09 #define GET_INTERFACE 0x0A #define SET_INTERFACE 0x0B #define 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) /*!EP[ep].EPMPS = (size)) /*!EP[ep].EPINTEN = (intr)) /*!EP[ep].EPINTSTS) /*!EP[ep].EPINTSTS = (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 { USBD->EP[u32Ep].EPBUFSTART = u32Base; USBD->EP[u32Ep].EPBUFEND = 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) USBD->EP[u32Ep].EPRSPCTL = (USB_EP_RSPCTL_FLUSH | USB_EP_RSPCTL_MODE_AUTO); else if (u32EpType == USB_EP_CFG_TYPE_INT) USBD->EP[u32Ep].EPRSPCTL = (USB_EP_RSPCTL_FLUSH | USB_EP_RSPCTL_MODE_MANUAL); else if (u32EpType == USB_EP_CFG_TYPE_ISO) USBD->EP[u32Ep].EPRSPCTL = (USB_EP_RSPCTL_FLUSH | USB_EP_RSPCTL_MODE_FLY); USBD->EP[u32Ep].EPCFG = (u32EpType | u32EpDir | USB_EP_CFG_VALID | (u32EpNum << 4)); } /** * @brief Set USB endpoint stall state * @param[in] u32Ep The USB endpoint ID. * @return None * @details Set USB endpoint stall state for the specified endpoint ID. Endpoint will respond STALL token automatically. */ static __inline void USBD_SetEpStall(uint32_t u32Ep) { if (u32Ep == CEP) USBD_SET_CEP_STATE(USB_CEPCTL_STALL); else { USBD->EP[u32Ep].EPRSPCTL = USBD->EP[u32Ep].EPRSPCTL & 0xf7 | USB_EP_RSPCTL_HALT; } } /** * @brief Set USB endpoint stall state * * @param[in] u32EpNum USB endpoint * @return None * * @details Set USB endpoint stall state, endpoint will return STALL token. */ static __inline void USBD_SetStall(uint32_t u32EpNum) { int i; if (u32EpNum == 0) USBD_SET_CEP_STATE(USB_CEPCTL_STALL); else { for (i = 0; i < USBD_MAX_EP; i++) { if (((USBD->EP[i].EPCFG & 0xf0) >> 4) == u32EpNum) { USBD->EP[i].EPRSPCTL = USBD->EP[i].EPRSPCTL & 0xf7 | USB_EP_RSPCTL_HALT; } } } } /** * @brief Clear USB endpoint stall state * @param[in] u32Ep The USB endpoint ID. * @return None * @details Clear USB endpoint stall state for the specified endpoint ID. Endpoint will respond ACK/NAK token. */ static __inline void USBD_ClearEpStall(uint32_t u32Ep) { USBD->EP[u32Ep].EPRSPCTL = USB_EP_RSPCTL_TOGGLE; } /** * @brief Clear USB endpoint stall state * * @param[in] u32EpNum USB endpoint * @return None * * @details Clear USB endpoint stall state, endpoint will return ACK/NAK token. */ static __inline void USBD_ClearStall(uint32_t u32EpNum) { int i; for (i = 0; i < USBD_MAX_EP; i++) { if (((USBD->EP[i].EPCFG & 0xf0) >> 4) == u32EpNum) { USBD->EP[i].EPRSPCTL = USB_EP_RSPCTL_TOGGLE; } } } /** * @brief Get USB endpoint stall state * @param[in] u32Ep The USB endpoint ID. * @retval 0 USB endpoint is not stalled. * @retval Others USB endpoint is stalled. * @details Get USB endpoint stall state of the specified endpoint ID. */ static __inline uint32_t USBD_GetEpStall(uint32_t u32Ep) { return (USBD->EP[u32Ep].EPRSPCTL & USB_EP_RSPCTL_HALT); } /** * @brief Get USB endpoint stall state * * @param[in] u32EpNum 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 u32EpNum) { int i; for (i = 0; i < USBD_MAX_EP; i++) { if (((USBD->EP[i].EPCFG & 0xf0) >> 4) == u32EpNum) { return (USBD->EP[i].EPRSPCTL & USB_EP_RSPCTL_HALT); } } return 0; } /*-------------------------------------------------------------------------------------------*/ typedef void (*VENDOR_REQ)(void); /*!