/* ---------------------------------------------------------------------------- */ /* Atmel Microcontroller Software Support */ /* SAM Software Package License */ /* ---------------------------------------------------------------------------- */ /* Copyright (c) 2015, Atmel Corporation */ /* */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following condition is met: */ /* */ /* - Redistributions of source code must retain the above copyright notice, */ /* this list of conditions and the disclaimer below. */ /* */ /* Atmel's name may not be used to endorse or promote products derived from */ /* this software without specific prior written permission. */ /* */ /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* ---------------------------------------------------------------------------- */ /** \file */ #ifndef USBHS_H #define USBHS_H /** addtogroup usbd_hal *@{ */ #define USB_DEVICE_HS_SUPPORT //! Control endpoint size #define USB_DEVICE_EP_CTRL_SIZE 64 /** Indicates chip has an UDP High Speed. */ #define CHIP_USB_UDP /** Indicates chip has an internal pull-up. */ #define CHIP_USB_PULLUP_INTERNAL /** Number of USB endpoints */ #define CHIP_USB_NUMENDPOINTS 10 /** Endpoints max packet size */ #define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(ep) \ ((ep == 0) ? 64 : 1024) /** Endpoints Number of Bank */ #define CHIP_USB_ENDPOINTS_BANKS(ep) ((ep==0)?1:((ep<=2)?3:2)) #define CHIP_USB_ENDPOINTS_HBW(ep) ((((ep)>=1) &&((ep)<=2))?true:false) /** Endpoints DMA support */ #define CHIP_USB_ENDPOINTS_DMA(ep) ((((ep)>=1)&&((ep)<=7))?true:false) /** Max size of the FMA FIFO */ #define DMA_MAX_FIFO_SIZE (65536/1) /** fifo space size in DW */ #define EPT_VIRTUAL_SIZE 8192 //! @name USBHS Host IP properties //! //! @{ //! Get maximal number of endpoints #define uhd_get_pipe_max_nbr() (9) #define USBHS_EPT_NUM (uhd_get_pipe_max_nbr()+1) //! Get maximal number of banks of endpoints #define uhd_get_pipe_bank_max_nbr(ep) ((ep == 0) ? 1 : ((ep <= 2) ? 3 : 2)) //! Get maximal size of endpoint (3X, 1024/64) #define uhd_get_pipe_size_max(ep) (((ep) == 0) ? 64 : 1024) //! Get DMA support of endpoints #define Is_uhd_pipe_dma_supported(ep) ((((ep) >= 1) && ((ep) <= 7)) ? true : false) //! Get High Band Width support of endpoints #define Is_uhd_pipe_high_bw_supported(ep) (((ep) >= 2) ? true : false) //! @} typedef enum { HOST_MODE = 0, DEVICE_MODE = 1 } USB_Mode_t; //! Maximum transfer size on USB DMA #define UHD_PIPE_MAX_TRANS 0x8000 /** ================================= USBHS_CTRL ================================= **/ /** * \brief Freeze or unfreeze USB clock * \param pUsbhs Pointer to an USBHS instance. * \param Enable Enable or disable */ __STATIC_INLINE void USBHS_FreezeClock(Usbhs *pUsbhs) { pUsbhs->USBHS_CTRL |= USBHS_CTRL_FRZCLK; } /** * \brief Freeze or unfreeze USB clock * \param pUsbhs Pointer to an USBHS instance. * \param Enable Enable or disable */ __STATIC_INLINE void USBHS_UnFreezeClock(Usbhs *pUsbhs) { pUsbhs->USBHS_CTRL &= ~((uint32_t)USBHS_CTRL_FRZCLK); } /** * \brief Freeze or unfreeze USB clock * \param pUsbhs Pointer to an USBHS instance. * \param Enable Enable or disable */ __STATIC_INLINE void USBHS_VBusHWC(Usbhs *pUsbhs, uint8_t Enable) { if (!Enable) pUsbhs->USBHS_CTRL |= (1 << 8); else pUsbhs->USBHS_CTRL &= ~((uint32_t)(1 << 8)); } /** * \brief Enables or disables USB * \param pUsbhs Pointer to an USBHS instance. * \param Enable Enable or disable */ __STATIC_INLINE void USBHS_UsbEnable(Usbhs *pUsbhs, uint8_t Enable) { if (Enable) pUsbhs->USBHS_CTRL |= USBHS_CTRL_USBE; else pUsbhs->USBHS_CTRL &= ~((uint32_t)USBHS_CTRL_USBE); } /** * \brief Device or Host Mode * \param pUsbhs Pointer to an USBHS instance. * \param Mode Device or Host Mode */ __STATIC_INLINE void USBHS_UsbMode(Usbhs *pUsbhs, USB_Mode_t Mode) { if (Mode) pUsbhs->USBHS_CTRL |= USBHS_CTRL_UIMOD_DEVICE; else pUsbhs->USBHS_CTRL &= ~((uint32_t)USBHS_CTRL_UIMOD_DEVICE); } /********************* USBHS_SR *****************/ /** * \brief Check if clock is usable or not * \param pUsbhs Pointer to an USBHS instance. * \return 1 if USB clock is usable */ __STATIC_INLINE uint8_t USBHS_ISUsableClock(Usbhs *pUsbhs) { return ((pUsbhs->USBHS_SR & USBHS_SR_CLKUSABLE) >> 14); } /** * \brief Raise interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \return USB status */ __STATIC_INLINE uint32_t USBHS_ReadStatus(Usbhs *pUsbhs) { return (pUsbhs->USBHS_SR); } /** * \brief Enable or disable USB address * \param pUsbhs Pointer to an USBHS instance. * \return USB speed status */ __STATIC_INLINE uint32_t USBHS_GetUsbSpeed(Usbhs *pUsbhs) { return ((pUsbhs->USBHS_SR & USBHS_SR_SPEED_Msk)); } /** * \brief Enable or disable USB address * \param pUsbhs Pointer to an USBHS instance. * \return USB speed status */ __STATIC_INLINE bool USBHS_IsUsbFullSpeed(Usbhs *pUsbhs) { return ((pUsbhs->USBHS_SR & USBHS_SR_SPEED_Msk) == USBHS_SR_SPEED_FULL_SPEED) ? true : false; } /** * \brief Enable or disable USB address * \param pUsbhs Pointer to an USBHS instance. * \return USB speed status */ __STATIC_INLINE bool USBHS_IsUsbHighSpeed(Usbhs *pUsbhs) { return ((pUsbhs->USBHS_SR & USBHS_SR_SPEED_Msk) == USBHS_SR_SPEED_HIGH_SPEED) ? true : false; } /** * \brief Enable or disable USB address * \param pUsbhs Pointer to an USBHS instance. * \return USB speed status */ __STATIC_INLINE bool USBHS_IsUsbLowSpeed(Usbhs *pUsbhs) { return ((pUsbhs->USBHS_SR & USBHS_SR_SPEED_Msk) == USBHS_SR_SPEED_LOW_SPEED) ? true : false; } /********************* USBHS_SCR *****************/ /** * \brief Raise interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param AckType Interrupt Acknowledge type */ __STATIC_INLINE void USBHS_Ack(Usbhs *pUsbhs, uint32_t AckType) { pUsbhs->USBHS_SCR |= AckType; } /********************* USBHS_SFR *****************/ /** * \brief Raise interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param SetStatus Set USB status */ __STATIC_INLINE void USBHS_Set(Usbhs *pUsbhs, uint32_t SetStatus) { pUsbhs->USBHS_SFR |= SetStatus; } /*-------------------------------------------------------- * =========== USB Device functions ====================== *---------------------------------------------------------*/ /** * \brief Enable or disable USB address * \param pUsbhs Pointer to an USBHS instance. * \param SetStatus Set USB status */ __STATIC_INLINE void USBHS_EnableAddress(Usbhs *pUsbhs, uint8_t Enable) { if (Enable) pUsbhs->USBHS_DEVCTRL |= USBHS_DEVCTRL_ADDEN; else pUsbhs->USBHS_DEVCTRL &= ~((uint32_t)USBHS_DEVCTRL_ADDEN); } /** * \brief Configure USB address and enable or disable it * \param pUsbhs Pointer to an USBHS instance. * \param Addr USB device status */ __STATIC_INLINE void USBHS_SetAddress(Usbhs *pUsbhs, uint8_t Addr) { pUsbhs->USBHS_DEVCTRL |= USBHS_DEVCTRL_UADD(Addr); pUsbhs->USBHS_DEVCTRL |= USBHS_DEVCTRL_ADDEN; } /** * \brief Get USB address * \param pUsbhs Pointer to an USBHS instance. */ __STATIC_INLINE uint8_t USBHS_GetAddress(Usbhs *pUsbhs) { return (pUsbhs->USBHS_DEVCTRL & USBHS_DEVCTRL_UADD_Msk); } /** * \brief Attach or detach USB. * \param pUsbhs Pointer to an USBHS instance. * \param Enable Attachs or detach USB device */ __STATIC_INLINE void USBHS_DetachUsb(Usbhs *pUsbhs, uint8_t Enable) { if (Enable) pUsbhs->USBHS_DEVCTRL |= USBHS_DEVCTRL_DETACH; else pUsbhs->USBHS_DEVCTRL &= ~((uint32_t)USBHS_DEVCTRL_DETACH); } /** * \brief Force Low Speed mode * \param pUsbhs Pointer to an USBHS instance. * \param Enable Enables the Full speed */ __STATIC_INLINE void USBHS_ForceLowSpeed(Usbhs *pUsbhs, uint8_t Enable) { if (Enable) pUsbhs->USBHS_DEVCTRL |= USBHS_DEVCTRL_LS; else pUsbhs->USBHS_DEVCTRL &= ~((uint32_t)USBHS_DEVCTRL_LS); } /** * \brief Disable/Enables High Speed mode * \param pUsbhs Pointer to an USBHS instance. * \param Enable Enables/disable option */ __STATIC_INLINE void USBHS_EnableHighSpeed(Usbhs *pUsbhs, uint8_t Enable) { uint32_t cfg = pUsbhs->USBHS_DEVCTRL; cfg &= ~((uint32_t)USBHS_DEVCTRL_SPDCONF_Msk); if (Enable) pUsbhs->USBHS_DEVCTRL |= cfg; else pUsbhs->USBHS_DEVCTRL |= (cfg | USBHS_DEVCTRL_SPDCONF_FORCED_FS); } /** * \brief Set Remote WakeUp mode * \param pUsbhs Pointer to an USBHS instance. */ __STATIC_INLINE void USBHS_SetRemoteWakeUp(Usbhs *pUsbhs) { pUsbhs->USBHS_DEVCTRL |= USBHS_DEVCTRL_RMWKUP; } /** * \brief Disable/Enables Test mode * \param pUsbhs Pointer to an USBHS instance. * \param mode Enables/disable option */ __STATIC_INLINE void USBHS_EnableTestMode(Usbhs *pUsbhs, uint32_t mode) { pUsbhs->USBHS_DEVCTRL |= mode; } /** * \brief Disable/Enables HS Test mode * \param pUsbhs Pointer to an USBHS instance. */ __STATIC_INLINE void USBHS_EnableHSTestMode(Usbhs *pUsbhs) { pUsbhs->USBHS_DEVCTRL |= USBHS_DEVCTRL_SPDCONF_HIGH_SPEED; } /** * \brief Read status for an interrupt * \param pUsbhs Pointer to an USBHS instance. * \param IntType Interrupt type */ __STATIC_INLINE uint32_t USBHS_ReadIntStatus(Usbhs *pUsbhs, uint32_t IntType) { return (pUsbhs->USBHS_DEVISR & IntType); } /** * \brief Read status for an Endpoint * \param pUsbhs Pointer to an USBHS instance. * \param EpNum Endpoint */ __STATIC_INLINE uint32_t USBHS_ReadEpIntStatus(Usbhs *pUsbhs, uint8_t EpNum) { return (pUsbhs->USBHS_DEVISR & (USBHS_DEVISR_PEP_0 << EpNum)); } /** * \brief Read status for a DMA Endpoint * \param pUsbhs Pointer to an USBHS instance. * \param DmaNum DMA Endpoint */ __STATIC_INLINE uint32_t USBHS_ReadDmaIntStatus(Usbhs *pUsbhs, uint8_t DmaNum) { return (pUsbhs->USBHS_DEVISR & (USBHS_DEVISR_DMA_1 << DmaNum)); } /** * \brief Acknowledge interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param IntType Interrupt Type */ __STATIC_INLINE void USBHS_AckInt(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_DEVICR |= IntType; } /** * \brief Raise interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param IntType Interrupt Type */ __STATIC_INLINE void USBHS_RaiseInt(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_DEVIFR |= IntType; } /** * \brief Raise DMA interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param IntType Interrupt Type */ __STATIC_INLINE void USBHS_RaiseDmaInt(Usbhs *pUsbhs, uint8_t Dma) { assert(Dma < USBHSDEVDMA_NUMBER); pUsbhs->USBHS_DEVIFR |= (USBHS_DEVIFR_DMA_1 << Dma); } /** * \brief check for interrupt of endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param IntType Interrupt Type */ __STATIC_INLINE uint32_t USBHS_IsIntEnable(Usbhs *pUsbhs, uint32_t IntType) { return (pUsbhs->USBHS_DEVIMR & IntType); } /** * \brief Check if endpoint's interrupt is enabled for a given endpoint number * \param pUsbhs Pointer to an USBHS instance. * \param EpNum Endpoint number */ __STATIC_INLINE uint32_t USBHS_IsIntEnableEP(Usbhs *pUsbhs, uint8_t EpNum) { return (pUsbhs->USBHS_DEVIMR & (USBHS_DEVIMR_PEP_0 << EpNum)); } /** * \brief Check if endpoint's DMA interrupt is enabled for a given endpoint * DMA number * \param pUsbhs Pointer to an USBHS instance. * \param DmaNum Endpoint's DMA number */ __STATIC_INLINE uint32_t USBHS_IsDmaIntEnable(Usbhs *pUsbhs, uint8_t DmaNum) { return (pUsbhs->USBHS_DEVIMR & (USBHS_DEVIMR_DMA_1 << DmaNum)); } /** * \brief Enables Interrupt * \param pUsbhs Pointer to an USBHS instance. * \param IntType Interrupt Type */ __STATIC_INLINE void USBHS_EnableInt(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_DEVIER |= IntType; } /** * \brief Enables interrupt for a given endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param DmaNum Endpoint's DMA number */ __STATIC_INLINE void USBHS_EnableIntEP(Usbhs *pUsbhs, uint8_t EpNum) { pUsbhs->USBHS_DEVIER |= (USBHS_DEVIER_PEP_0 << EpNum); } /** * \brief Enables DMA interrupt for a given endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param DmaEp Endpoint's DMA interrupt number */ __STATIC_INLINE void USBHS_EnableDMAIntEP(Usbhs *pUsbhs, uint32_t DmaEp) { assert(DmaEp < USBHSDEVDMA_NUMBER); pUsbhs->USBHS_DEVIER |= (USBHS_DEVIER_DMA_1 << DmaEp); } /** * \brief Disables interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param IntType Int type */ __STATIC_INLINE void USBHS_DisableInt(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_DEVIDR |= IntType; } /** * \brief Disables interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param Ep Endpoint number */ __STATIC_INLINE void USBHS_DisableIntEP(Usbhs *pUsbhs, uint8_t Ep) { pUsbhs->USBHS_DEVIDR |= (USBHS_DEVIDR_PEP_0 << Ep); } /** * \brief Disables DMA interrupt for endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param DmaEp Endpoint's DMA number */ __STATIC_INLINE void USBHS_DisableDMAIntEP(Usbhs *pUsbhs, uint8_t DmaEp) { assert(DmaEp < USBHSDEVDMA_NUMBER); pUsbhs->USBHS_DEVIDR |= (USBHS_DEVIDR_DMA_1 << DmaEp); } /** * \brief Enables or disables endpoint. * \param pUsbhs Pointer to an USBHS instance. * \param Enable Enable/disable endpoint */ __STATIC_INLINE void USBHS_EnableEP(Usbhs *pUsbhs, uint8_t Ep, uint8_t Enable) { if (Enable) pUsbhs->USBHS_DEVEPT |= (USBHS_DEVEPT_EPEN0 << Ep); else pUsbhs->USBHS_DEVEPT &= ~(uint32_t)(USBHS_DEVEPT_EPEN0 << Ep); } /** * \brief Rests Endpoint * \param pUsbhs Pointer to an USBHS instance. * \param Ep Endpoint Number */ __STATIC_INLINE void USBHS_ResetEP(Usbhs *pUsbhs, uint8_t Ep) { pUsbhs->USBHS_DEVEPT |= (USBHS_DEVEPT_EPRST0 << Ep); pUsbhs->USBHS_DEVEPT &= ~(uint32_t)(USBHS_DEVEPT_EPRST0 << Ep); } /** * \brief Checks if Endpoint is enable * \param pUsbhs Pointer to an USBHS instance. * \param Ep Endpoint Number */ __STATIC_INLINE uint32_t USBHS_IsEPEnabled(Usbhs *pUsbhs, uint8_t Ep) { return (pUsbhs->USBHS_DEVEPT & (USBHS_DEVEPT_EPEN0 << Ep)); } /** * \brief Get MicrFrame number * \param pUsbhs Pointer to an USBHS instance. * \retruns Micro frame number */ __STATIC_INLINE uint8_t USBHS_GetMicroFrameNum(Usbhs *pUsbhs) { return (pUsbhs->USBHS_DEVFNUM & USBHS_DEVFNUM_MFNUM_Msk); } /** * \brief Get Frame number * \param pUsbhs Pointer to an USBHS instance. * \retruns frame number */ __STATIC_INLINE uint8_t USBHS_GetFrameNum(Usbhs *pUsbhs) { return ((pUsbhs->USBHS_DEVFNUM & USBHS_DEVFNUM_FNUM_Msk) >> USBHS_DEVFNUM_FNUM_Pos); } /** * \brief Get Frame number CRC error * \param pUsbhs Pointer to an USBHS instance. * \retruns Frame number error status */ __STATIC_INLINE uint8_t USBHS_GetFrameNumCrcErr(Usbhs *pUsbhs) { return ((pUsbhs->USBHS_DEVFNUM & USBHS_DEVFNUM_FNCERR) >> 15); } /*----------------------------------------- * =========== USB Device's Endpoint functions ======== *------------------------------------------*/ /** * Set Endpoints configuration * Bank size, type and direction */ __STATIC_INLINE void USBHS_ConfigureEPs(Usbhs *pUsbhs, const uint8_t Ep, const uint8_t Type, const uint8_t Dir, const uint8_t Size, const uint8_t Bank) { pUsbhs->USBHS_DEVEPTCFG[Ep] |= ((Size << USBHS_DEVEPTCFG_EPSIZE_Pos) & USBHS_DEVEPTCFG_EPSIZE_Msk); pUsbhs->USBHS_DEVEPTCFG[Ep] |= ((Dir << 8) & USBHS_DEVEPTCFG_EPDIR); pUsbhs->USBHS_DEVEPTCFG[Ep] |= (((Type) << USBHS_DEVEPTCFG_EPTYPE_Pos) & USBHS_DEVEPTCFG_EPTYPE_Msk); pUsbhs->USBHS_DEVEPTCFG[Ep] |= (((Bank) << USBHS_DEVEPTCFG_EPBK_Pos) & USBHS_DEVEPTCFG_EPBK_Msk); } /** * Enable or disable Auto switch of banks */ __STATIC_INLINE void USBHS_AutoSwitchBankEnable(Usbhs *pUsbhs, uint8_t Ep, uint8_t Enable) { if (Enable) pUsbhs->USBHS_DEVEPTCFG[Ep] |= USBHS_DEVEPTCFG_AUTOSW; else pUsbhs->USBHS_DEVEPTCFG[Ep] &= ~((uint32_t)USBHS_DEVEPTCFG_AUTOSW); } /** * Allocate Endpoint memory */ __STATIC_INLINE void USBHS_AllocateMemory(Usbhs *pUsbhs, uint8_t Ep) { pUsbhs->USBHS_DEVEPTCFG[Ep] |= USBHS_DEVEPTCFG_ALLOC; } /** * Free allocated Endpoint memory */ __STATIC_INLINE void USBHS_FreeMemory(Usbhs *pUsbhs, uint8_t Ep) { pUsbhs->USBHS_DEVEPTCFG[Ep] &= ~((uint32_t)USBHS_DEVEPTCFG_ALLOC); } /** * Get Endpoint configuration */ __STATIC_INLINE uint32_t USBHS_GetConfigureEPs(Usbhs *pUsbhs, uint8_t Ep, uint32_t IntType) { return ((pUsbhs->USBHS_DEVEPTCFG[Ep]) & IntType); } /** * Get Endpoint Type */ __STATIC_INLINE uint8_t USBHS_GetEpType(Usbhs *pUsbhs, uint8_t Ep) { return ((pUsbhs->USBHS_DEVEPTCFG[Ep] & USBHS_DEVEPTCFG_EPTYPE_Msk) >> USBHS_DEVEPTCFG_EPTYPE_Pos); } /** * Get Endpoint Size */ __STATIC_INLINE uint32_t USBHS_GetEpSize(Usbhs *pUsbhs, uint8_t Ep) { return (8 << ((pUsbhs->USBHS_DEVEPTCFG[Ep] & USBHS_DEVEPTCFG_EPSIZE_Msk) >> USBHS_DEVEPTCFG_EPSIZE_Pos)); } /** * Sets ISO endpoint's Number of Transfer for High Speed */ __STATIC_INLINE void USBHS_SetIsoTrans(Usbhs *pUsbhs, uint8_t Ep, uint8_t nbTrans) { pUsbhs->USBHS_DEVEPTCFG[Ep] |= USBHS_DEVEPTCFG_NBTRANS(nbTrans); } /** * Check for interrupt types enabled for a given endpoint */ __STATIC_INLINE uint32_t USBHS_IsEpIntEnable(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpIntType) { return (pUsbhs->USBHS_DEVEPTIMR[Ep] & EpIntType); } /** * Enables an interrupt type for a given endpoint */ __STATIC_INLINE void USBHS_EnableEPIntType(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt) { pUsbhs->USBHS_DEVEPTIER[Ep] |= EpInt; } /** * Enables an interrupt type for a given endpoint */ __STATIC_INLINE uint32_t USBHS_IsBankKilled(Usbhs *pUsbhs, uint8_t Ep) { return (pUsbhs->USBHS_DEVEPTIMR[Ep] & USBHS_DEVEPTIMR_KILLBK); } /** * Enables an interrupt type for a given endpoint */ __STATIC_INLINE void USBHS_KillBank(Usbhs *pUsbhs, uint8_t Ep) { pUsbhs->USBHS_DEVEPTIER[Ep] = USBHS_DEVEPTIER_KILLBKS; } /** * Disables an interrupt type for a given endpoint */ __STATIC_INLINE void USBHS_DisableEPIntType(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt) { pUsbhs->USBHS_DEVEPTIDR[Ep] |= EpInt; } /** * Clears register/acknowledge for a given endpoint */ __STATIC_INLINE void USBHS_AckEpInterrupt(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt) { pUsbhs->USBHS_DEVEPTICR[Ep] |= EpInt; } /** * Sets/Raise register for a given endpoint */ __STATIC_INLINE void USBHS_RaiseEPInt(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt) { pUsbhs->USBHS_DEVEPTIFR[Ep] |= EpInt; } /** * Gets interrupt status for a given EP */ __STATIC_INLINE uint32_t USBHS_ReadEPStatus(Usbhs *pUsbhs, uint8_t Ep, uint32_t EpInt) { return (pUsbhs->USBHS_DEVEPTISR[Ep] & EpInt); } /** * Check if given endpoint's bank is free */ __STATIC_INLINE uint8_t USBHS_IsBankFree(Usbhs *pUsbhs, uint8_t Ep) { if ((pUsbhs->USBHS_DEVEPTISR[Ep] & USBHS_DEVEPTISR_NBUSYBK_Msk)) return false; else return true; } /** * Read endpoint's bank number in use */ __STATIC_INLINE uint8_t USBHS_NumOfBanksInUse(Usbhs *pUsbhs, uint8_t Ep) { return ((pUsbhs->USBHS_DEVEPTISR[Ep] & USBHS_DEVEPTISR_NBUSYBK_Msk) >> USBHS_DEVEPTISR_NBUSYBK_Pos); } /** * Read endpoint's byte count of the FIFO */ __STATIC_INLINE uint16_t USBHS_ByteCount(Usbhs *pUsbhs, uint8_t Ep) { return (uint16_t)((pUsbhs->USBHS_DEVEPTISR[Ep] & USBHS_DEVEPTISR_BYCT_Msk) >> USBHS_DEVEPTISR_BYCT_Pos); } /*-------------------------------------------------------- * =========== USB Device's Ep's DMA functions ========= *---------------------------------------------------------*/ /** * \brief Sets DMA next descriptor address * \param pUsbDma USBHS device DMA instance * \param Desc NDA address */ __STATIC_INLINE void USBHS_SetDmaNDA(UsbhsDevdma *pUsbDma, uint32_t Desc) { pUsbDma->USBHS_DEVDMANXTDSC = Desc; } /** * \brief Gets DMA next descriptor address * \param pUsbDma USBHS device DMA instance * \return Next DMA descriptor */ __STATIC_INLINE uint32_t USBHS_GetDmaNDA(UsbhsDevdma *pUsbDma) { return (pUsbDma->USBHS_DEVDMANXTDSC); } /** * \brief Sets USBHS's DMA Buffer addresse * \param pUsbDma USBHS device DMA instance * \param Addr DMA's buffer Addrs */ __STATIC_INLINE void USBHS_SetDmaBuffAdd(UsbhsDevdma *pUsbDma, uint32_t Addr) { pUsbDma->USBHS_DEVDMAADDRESS = Addr; } /** * \brief Gets USBHS's DMA Buffer addresse * \param pUsbDma USBHS device DMA instance * \return DMA addrs */ __STATIC_INLINE uint32_t USBHS_GetDmaBuffAdd(UsbhsDevdma *pUsbDma) { return (pUsbDma->USBHS_DEVDMAADDRESS); } /** * \brief Setup the USBHS DMA * \param pUsbDma USBHS device DMA instance * \param Cfg DMA's configuration */ __STATIC_INLINE void USBHS_ConfigureDma(UsbhsDevdma *pUsbDma, uint32_t Cfg) { pUsbDma->USBHS_DEVDMACONTROL |= Cfg; } /** * \brief Get DMA configuration * \param pUsbDma USBHS device DMA instance * \return DMA control setup */ __STATIC_INLINE uint32_t USBHS_GetDmaConfiguration(UsbhsDevdma *pUsbDma) { return (pUsbDma->USBHS_DEVDMACONTROL); } /** * \brief Set DMA status * \param pUsbDma USBHS device DMA instance * \Status Set DMA status */ __STATIC_INLINE void USBHS_SetDmaStatus(UsbhsDevdma *pUsbDma, uint32_t Status) { pUsbDma->USBHS_DEVDMASTATUS = Status; } /** * \brief Get Dma Status * \param pUsbDma USBHS device DMA instance * \return Dma status */ __STATIC_INLINE uint32_t USBHS_GetDmaStatus(UsbhsDevdma *pUsbDma) { return (pUsbDma->USBHS_DEVDMASTATUS); } /** * \brief Get DMA buffer's count * \param pUsbDma USBHS device DMA instance * \return Buffer count */ __STATIC_INLINE uint16_t USBHS_GetDmaBuffCount(UsbhsDevdma *pUsbDma) { return ((pUsbDma->USBHS_DEVDMASTATUS & USBHS_DEVDMASTATUS_BUFF_COUNT_Msk) >> USBHS_DEVDMASTATUS_BUFF_COUNT_Pos); } /*-------------------------------------------------------- * =========== USB Host Functions ======================== *---------------------------------------------------------*/ /** Number of USB endpoints */ #define CHIP_USB_NUMPIPE 10 /** Number of USB endpoints */ #define CHIP_USB_DMA_NUMPIPE 7 /** Endpoints max paxcket size */ #define CHIP_USB_PIPE_MAXPACKETSIZE(ep) \ ((ep == 0) ? 64 : 1024) /** Endpoints Number of Bank */ #define CHIP_USB_PIPE_BANKS(ep) ((ep==0)?1:((ep<=2)?3:2)) #define CHIP_USB_PIPE_HBW(ep) ((((ep)>=1) &&((ep)<=2))?true:false) /** Endpoints DMA support */ #define CHIP_USB_PIPE_DMA(ep) ((((ep)>=1)&&((ep)<=7))?true:false) /** * \brief Sets USB host's speed to Normal , it sets to HS from FS * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_SetHostHighSpeed(Usbhs *pUsbhs) { pUsbhs->USBHS_HSTCTRL &= ~USBHS_HSTCTRL_SPDCONF_Msk; pUsbhs->USBHS_HSTCTRL |= USBHS_HSTCTRL_SPDCONF_NORMAL; } /** * \brief Sets USB host's speed to Low speed * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_SetHostLowSpeed(Usbhs *pUsbhs) { pUsbhs->USBHS_HSTCTRL &= ~USBHS_HSTCTRL_SPDCONF_Msk; pUsbhs->USBHS_HSTCTRL |= USBHS_HSTCTRL_SPDCONF_LOW_POWER; } /** * \brief Sets USB host's speed to forced Full speed * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_SetHostForcedFullSpeed(Usbhs *pUsbhs) { pUsbhs->USBHS_HSTCTRL &= ~USBHS_HSTCTRL_SPDCONF_Msk; pUsbhs->USBHS_HSTCTRL |= USBHS_HSTCTRL_SPDCONF_FORCED_FS; } /** * \brief Sets USB host sends reste signal on USB Bus * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_Reset(void) { USBHS->USBHS_HSTCTRL |= USBHS_HSTCTRL_RESET; } /** * \brief Sets USB host sends reste signal on USB Bus * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_StopReset(void) { USBHS->USBHS_HSTCTRL &= ~USBHS_HSTCTRL_RESET; } /** * \brief Sets USB host send Resume on USB bus * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_Resume(void) { USBHS->USBHS_HSTCTRL |= USBHS_HSTCTRL_RESUME; } /** * \brief Sets USB host Enable the Generation of Start of Frame * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_EnableSOF(Usbhs *pUsbhs) { pUsbhs->USBHS_HSTCTRL |= USBHS_HSTCTRL_SOFE; } /** * \brief Sets USB host Enable the Generation of Start of Frame * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_IsEnableSOF(Usbhs *pUsbhs) { return (pUsbhs->USBHS_HSTCTRL & USBHS_HSTCTRL_SOFE) >> 8; } /** * \brief Sets USB host disable the Generation of Start of Frame * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_DisableSOF(void) { USBHS->USBHS_HSTCTRL &= ~USBHS_HSTCTRL_SOFE; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_GetHostStatus(Usbhs *pUsbhs, uint8_t IntType) { return (pUsbhs->USBHS_HSTISR & IntType); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_GetHostPipeStatus(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt < CHIP_USB_NUMPIPE); return (pUsbhs->USBHS_HSTISR & (USBHS_HSTISR_PEP_0 << PipeInt)); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_GetHostDmaPipeStatus(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt); assert(PipeInt < CHIP_USB_DMA_NUMPIPE); return (pUsbhs->USBHS_HSTISR & (USBHS_HSTISR_DMA_1 << PipeInt)); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_ClearHostStatus(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_HSTICR = IntType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_SetHostStatus(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_HSTIFR = IntType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_SetHostDmaStatus(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt); assert(PipeInt < CHIP_USB_DMA_NUMPIPE); pUsbhs->USBHS_HSTIFR = (USBHS_HSTIFR_DMA_1 << PipeInt); } /*** Interrupt Mask ****/ /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_IsHostIntEnable(Usbhs *pUsbhs, uint8_t IntType) { return (pUsbhs->USBHS_HSTIMR & IntType); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_IsHostPipeIntEnable(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt < CHIP_USB_NUMPIPE); return (pUsbhs->USBHS_HSTIMR & (USBHS_HSTIMR_PEP_0 << PipeInt)); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_IsHostDmaIntEnable(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt); assert(PipeInt < CHIP_USB_DMA_NUMPIPE); return (pUsbhs->USBHS_HSTIMR & (USBHS_HSTIMR_DMA_1 << PipeInt)); } /*** Interrupt Disable ****/ /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostIntDisable(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_HSTIDR = IntType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostPipeIntDisable(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt < CHIP_USB_NUMPIPE); pUsbhs->USBHS_HSTIDR = (USBHS_HSTIDR_PEP_0 << PipeInt); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostDmaIntDisable(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt); assert(PipeInt < CHIP_USB_DMA_NUMPIPE); pUsbhs->USBHS_HSTIDR = (USBHS_HSTIDR_DMA_1 << PipeInt); } /*** Interrupt Enable ****/ /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostIntEnable(Usbhs *pUsbhs, uint32_t IntType) { pUsbhs->USBHS_HSTIER = IntType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostPipeIntEnable(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt < CHIP_USB_NUMPIPE); pUsbhs->USBHS_HSTIER = (USBHS_HSTIER_PEP_0 << PipeInt); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostDmaIntEnable(Usbhs *pUsbhs, uint8_t PipeInt) { assert(PipeInt < CHIP_USB_DMA_NUMPIPE); pUsbhs->USBHS_HSTIER |= (USBHS_HSTIER_DMA_1 << PipeInt); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint16_t USBHS_HostGetSOF(void) { return ((USBHS->USBHS_HSTFNUM & USBHS_HSTFNUM_FNUM_Msk) >> USBHS_HSTFNUM_FNUM_Pos); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint16_t USBHS_HostGetFramePos(void) { return ((USBHS->USBHS_HSTFNUM & USBHS_HSTFNUM_FLENHIGH_Msk) >> USBHS_HSTFNUM_FLENHIGH_Pos); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint16_t USBHS_HostGetMSOF(void) { return ((USBHS->USBHS_HSTFNUM & USBHS_HSTFNUM_MFNUM_Msk) >> USBHS_HSTFNUM_MFNUM_Pos); } __STATIC_INLINE void USBHS_HostSetAddr(Usbhs *pUsbhs, uint8_t Pipe, uint8_t Addr) { assert(Pipe < CHIP_USB_NUMPIPE); if (Pipe < 4) pUsbhs->USBHS_HSTADDR1 |= (Addr << (8 * Pipe)); else if ((Pipe < 8) && (Pipe >= 4)) pUsbhs->USBHS_HSTADDR2 |= (Addr << (8 * (Pipe - 4))); else pUsbhs->USBHS_HSTADDR3 |= (Addr << (8 * (Pipe - 8))); } __STATIC_INLINE uint8_t USBHS_HostGetAddr(Usbhs *pUsbhs, uint8_t Pipe) { assert(Pipe < CHIP_USB_NUMPIPE); if (Pipe < 4) return (pUsbhs->USBHS_HSTADDR1 >> (8 * Pipe)); else if ((Pipe < 8) && (Pipe >= 4)) return (pUsbhs->USBHS_HSTADDR2 >> (8 * (Pipe - 4))); else return (pUsbhs->USBHS_HSTADDR3 >> (8 * (Pipe - 8))); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostPipeEnable(Usbhs *pUsbhs, uint8_t Pipe) { assert(Pipe < CHIP_USB_NUMPIPE); pUsbhs->USBHS_HSTPIP |= (USBHS_HSTPIP_PEN0 << Pipe); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostPipeDisable(Usbhs *pUsbhs, uint8_t Pipe) { assert(Pipe < CHIP_USB_NUMPIPE); pUsbhs->USBHS_HSTPIP &= ~(USBHS_HSTPIP_PEN0 << Pipe); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_IsHostPipeEnable(Usbhs *pUsbhs, uint8_t Pipe) { assert(Pipe < CHIP_USB_NUMPIPE); return (pUsbhs->USBHS_HSTPIP & (USBHS_HSTPIP_PEN0 << Pipe)); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostPipeReset(Usbhs *pUsbhs, uint8_t Pipe) { assert(Pipe < CHIP_USB_NUMPIPE); pUsbhs->USBHS_HSTPIP |= (USBHS_HSTPIP_PRST0 << Pipe); pUsbhs->USBHS_HSTPIP &= ~(USBHS_HSTPIP_PRST0 << Pipe); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostConfigure(Usbhs *pUsbhs, uint8_t Pipe, uint32_t pipeBank, uint8_t pipeSize, uint32_t pipeType, uint32_t pipeToken, uint8_t pipeEpNum, uint8_t PipeIntFreq) { assert(Pipe < CHIP_USB_NUMPIPE); pUsbhs->USBHS_HSTPIPCFG[Pipe] |= (pipeBank | pipeToken | USBHS_HSTPIPCFG_PSIZE( pipeSize) | pipeType | USBHS_HSTPIPCFG_PEPNUM(pipeEpNum) | USBHS_HSTPIPCFG_INTFRQ(PipeIntFreq)); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostAllocMem(Usbhs *pUsbhs, uint8_t Pipe) { pUsbhs->USBHS_HSTPIPCFG[Pipe] |= USBHS_HSTPIPCFG_ALLOC; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostFreeMem(Usbhs *pUsbhs, uint8_t Pipe) { pUsbhs->USBHS_HSTPIPCFG[Pipe] &= ~USBHS_HSTPIPCFG_ALLOC; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint16_t USBHS_HostGetSize(Usbhs *pUsbhs, uint8_t Pipe) { return (8 << ((pUsbhs->USBHS_HSTPIPCFG[Pipe] & USBHS_HSTPIPCFG_PSIZE_Msk) >> USBHS_HSTPIPCFG_PSIZE_Pos)); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostSetToken(Usbhs *pUsbhs, uint8_t Pipe, uint32_t Token) { pUsbhs->USBHS_HSTPIPCFG[Pipe] &= ~USBHS_HSTPIPCFG_PTOKEN_Msk; pUsbhs->USBHS_HSTPIPCFG[Pipe] |= Token; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_HostGetToken(Usbhs *pUsbhs, uint8_t Pipe) { return (pUsbhs->USBHS_HSTPIPCFG[Pipe] & USBHS_HSTPIPCFG_PTOKEN_Msk); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostSetPipeType(Usbhs *pUsbhs, uint8_t Pipe, uint8_t PipeType) { pUsbhs->USBHS_HSTPIPCFG[Pipe] &= ~USBHS_HSTPIPCFG_PTYPE_Msk; pUsbhs->USBHS_HSTPIPCFG[Pipe] |= PipeType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_HostGetPipeType(Usbhs *pUsbhs, uint8_t Pipe) { return (pUsbhs->USBHS_HSTPIPCFG[Pipe] & USBHS_HSTPIPCFG_PTYPE_Msk); } __STATIC_INLINE uint8_t USBHS_GetPipeEpAddr(Usbhs *pUsbhs, uint8_t Pipe) { if (USBHS_HostGetToken(USBHS, Pipe) == USBHS_HSTPIPCFG_PTOKEN_IN) return (((pUsbhs->USBHS_HSTPIPCFG[Pipe] & USBHS_HSTPIPCFG_PEPNUM_Msk) >> USBHS_HSTPIPCFG_PEPNUM_Pos) | 0x80); else return (((pUsbhs->USBHS_HSTPIPCFG[Pipe] & USBHS_HSTPIPCFG_PEPNUM_Msk) >> USBHS_HSTPIPCFG_PEPNUM_Pos) | 0x00); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostEnableAutoSw(Usbhs *pUsbhs, uint8_t Pipe) { pUsbhs->USBHS_HSTPIPCFG[Pipe] |= USBHS_HSTPIPCFG_AUTOSW; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostDisableAutoSw(Usbhs *pUsbhs, uint8_t Pipe) { pUsbhs->USBHS_HSTPIPCFG[Pipe] &= ~USBHS_HSTPIPCFG_AUTOSW; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostSetIntFreq(Usbhs *pUsbhs, uint8_t Pipe, uint8_t Freq) { pUsbhs->USBHS_HSTPIPCFG[Pipe] |= USBHS_HSTPIPCFG_BINTERVAL(Freq); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostEnablePing(Usbhs *pUsbhs, uint8_t Pipe) { pUsbhs->USBHS_HSTPIPCFG[Pipe] |= USBHS_HSTPIPCFG_PINGEN; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_HostGetDataTogSeq(Usbhs *pUsbhs, uint8_t Pipe) { return ((pUsbhs->USBHS_HSTPIPISR[Pipe] & USBHS_HSTPIPISR_DTSEQ_Msk) >> USBHS_HSTPIPISR_DTSEQ_Pos); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_HostGetNumOfBusyBank(Usbhs *pUsbhs, uint8_t Pipe) { return ((pUsbhs->USBHS_HSTPIPISR[Pipe] & USBHS_HSTPIPISR_NBUSYBK_Msk) >> USBHS_HSTPIPISR_NBUSYBK_Pos); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_HostGetCurrentBank(Usbhs *pUsbhs, uint8_t Pipe) { return ((pUsbhs->USBHS_HSTPIPISR[Pipe] & USBHS_HSTPIPISR_CURRBK_Msk) >> USBHS_HSTPIPISR_CURRBK_Pos); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_HostGetPipeByteCount(Usbhs *pUsbhs, uint8_t Pipe) { return ((pUsbhs->USBHS_HSTPIPISR[Pipe] & USBHS_HSTPIPISR_PBYCT_Msk) >> USBHS_HSTPIPISR_PBYCT_Pos); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_IsHostConfigOk(Usbhs *pUsbhs, uint8_t Pipe) { return (pUsbhs->USBHS_HSTPIPISR[Pipe] & USBHS_DEVEPTISR_CFGOK); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_HostGetIntTypeStatus(Usbhs *pUsbhs, uint8_t Pipe, uint32_t intType) { return (pUsbhs->USBHS_HSTPIPISR[Pipe] & intType); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostAckPipeIntType(Usbhs *pUsbhs, uint8_t Pipe, uint32_t intType) { pUsbhs->USBHS_HSTPIPICR[Pipe] = intType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostSetPipeIntType(Usbhs *pUsbhs, uint8_t Pipe, uint32_t intType) { pUsbhs->USBHS_HSTPIPIFR[Pipe] = intType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint32_t USBHS_IsHostPipeIntTypeEnable(Usbhs *pUsbhs, uint8_t Pipe, uint32_t intType) { return (pUsbhs->USBHS_HSTPIPIMR[Pipe] & intType); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostDisablePipeIntType(Usbhs *pUsbhs, uint8_t Pipe, uint32_t intType) { pUsbhs->USBHS_HSTPIPIDR[Pipe] = intType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostEnablePipeIntType(Usbhs *pUsbhs, uint8_t Pipe, uint32_t intType) { pUsbhs->USBHS_HSTPIPIER[Pipe] = intType; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostEnableInReq(Usbhs *pUsbhs, uint8_t Pipe) { pUsbhs->USBHS_HSTPIPINRQ[Pipe] |= USBHS_HSTPIPINRQ_INMODE; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostDisableInReq(Usbhs *pUsbhs, uint8_t Pipe) { pUsbhs->USBHS_HSTPIPINRQ[Pipe] &= ~USBHS_HSTPIPINRQ_INMODE; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_IsHostInReqEnable(Usbhs *pUsbhs, uint8_t Pipe) { return ((pUsbhs->USBHS_HSTPIPINRQ[Pipe] & USBHS_HSTPIPINRQ_INMODE) >> 8); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostInReq(Usbhs *pUsbhs, uint8_t Pipe, uint8_t InReq) { pUsbhs->USBHS_HSTPIPINRQ[Pipe] = USBHS_HSTPIPINRQ_INRQ(InReq - 1); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostSetErr(Usbhs *pUsbhs, uint8_t Pipe, uint8_t Err) { pUsbhs->USBHS_HSTPIPERR[Pipe] |= Err; } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE uint8_t USBHS_HostGetErr(Usbhs *pUsbhs, uint8_t Pipe, uint8_t Err) { return (pUsbhs->USBHS_HSTPIPERR[Pipe] & Err); } /** * \brief Gets USB host interrupt status * \param pUsbhs USBHS host instance */ __STATIC_INLINE void USBHS_HostClearErr(Usbhs *pUsbhs, uint8_t Pipe, uint8_t Err) { pUsbhs->USBHS_HSTPIPERR[Pipe] = Err; } __STATIC_INLINE uint8_t USBHS_GetInterruptPipeNum(void) { uint32_t status = USBHS->USBHS_HSTISR; uint32_t mask = USBHS->USBHS_HSTIMR; return ctz(((status & mask) >> 8) | (1 << USBHS_EPT_NUM)); } static inline uint8_t USBHS_GetInterruptPipeDmaNum(void) { uint32_t status = USBHS->USBHS_HSTISR; uint32_t mask = USBHS->USBHS_HSTIMR; return (ctz(((status & mask) >> 25) | (1 << (USBHS_EPT_NUM - 1))) + 1); } /*-------------------------------------------------------- * =========== USB Host's pipe DMA functions ========= *---------------------------------------------------------*/ /** * \brief Sets DMA next descriptor address * \param pUsbDma USBHS device DMA instance * \param Desc NDA addrs */ __STATIC_INLINE void USBHS_SetHostDmaNDA(UsbhsHstdma *pUsbDma, uint32_t Desc) { pUsbDma->USBHS_HSTDMANXTDSC = Desc; } /** * \brief Gets DMA next descriptor address * \param pUsbDma USBHS device DMA instance * \return Next DMA descriptor */ __STATIC_INLINE uint32_t USBHS_GetHostDmaNDA(UsbhsHstdma *pUsbDma) { return (pUsbDma->USBHS_HSTDMANXTDSC); } /** * \brief Sets USBHS's DMA Buffer addresse * \param pUsbDma USBHS device DMA instance * \param Addr DMA's buffer Addrs */ __STATIC_INLINE void USBHS_SetHostDmaBuffAdd(UsbhsHstdma *pUsbDma, uint32_t Addr) { pUsbDma->USBHS_HSTDMAADDRESS = Addr; } /** * \brief Gets USBHS's DMA Buffer addresse * \param pUsbDma USBHS device DMA instance * \return DMA addrs */ __STATIC_INLINE uint32_t USBHS_GetHostDmaBuffAdd(UsbhsHstdma *pUsbDma) { return (pUsbDma->USBHS_HSTDMAADDRESS); } /** * \brief Setup the USBHS DMA * \param pUsbDma USBHS device DMA instance * \param Cfg DMA's configuration */ __STATIC_INLINE void USBHS_HostConfigureDma(UsbhsHstdma *pUsbDma, uint32_t Cfg) { pUsbDma->USBHS_HSTDMACONTROL |= Cfg; } /** * \brief Get DMA configuration * \param pUsbDma USBHS device DMA instance * \return DMA control setup */ __STATIC_INLINE uint32_t USBHS_GetHostDmaConfiguration(UsbhsHstdma *pUsbDma) { return (pUsbDma->USBHS_HSTDMACONTROL); } /** * \brief Set DMA status * \param pUsbDma USBHS device DMA instance * \Status Set DMA status */ __STATIC_INLINE void USBHS_SetHostPipeDmaStatus(UsbhsHstdma *pUsbDma, uint32_t Status) { pUsbDma->USBHS_HSTDMASTATUS = Status; } /** * \brief Get Dma Status * \param pUsbDma USBHS device DMA instance * \return Dma status */ __STATIC_INLINE uint32_t USBHS_GetHostPipeDmaStatus(UsbhsHstdma *pUsbDma) { return (pUsbDma->USBHS_HSTDMASTATUS); } /**@}*/ #endif /* #ifndef USBHS_H */