/******************************************************************************* * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * * PolarFire SoC MSS USB Driver Stack * USB Core Interface Layer (USB-CIFL) * USB-CIF. * * This file provides interfaces to perform register bit level * I\O operations which are independent of USB Device/host mode. * */ #ifndef __MSS_USB_COMMON_REG_IO_H_ #define __MSS_USB_COMMON_REG_IO_H_ #include #include "mss_usb_common_cif.h" #include "mss_usb_core_regs.h" #define __INLINE inline #ifdef __cplusplus extern "C" { #endif /*-------------------------------------------------------------------------*//** * Common function for DEVICE and HOST mode. */ /*-------------------------------------------------------------------------*//** SOFT_RST register related APIs */ static __INLINE void MSS_USB_CIF_soft_reset ( void ) { volatile uint8_t soft_reset; USB->SOFT_RST = SOFT_RESET_REG_MASK; do { soft_reset = USB->SOFT_RST; } while (soft_reset != 0x00u); } /*-------------------------------------------------------------------------*//** POWER register related APIs */ static __INLINE void MSS_USB_CIF_enable_hs_mode ( void ) { USB->POWER |= POWER_REG_ENABLE_HS_MASK; } static __INLINE void MSS_USB_CIF_disable_hs_mode ( void ) { USB->POWER &= ~POWER_REG_ENABLE_HS_MASK; } /*-------------------------------------------------------------------------*//** Read USB interrupt register to know which interrupt has occurred. */ static __INLINE uint8_t MSS_USB_CIF_read_irq_reg ( void ) { return (USB->USB_IRQ); } /*-------------------------------------------------------------------------*//** EP IRQ related APIs */ /* TX IRQ related APIs */ static __INLINE uint16_t MSS_USB_CIF_read_tx_ep_irq_reg ( void ) { return (USB->TX_IRQ); } static __INLINE uint16_t MSS_USB_CIF_read_rx_ep_irq_reg ( void ) { return (USB->RX_IRQ); } static __INLINE void MSS_USB_CIF_clr_usb_irq_reg ( void ) { USB->USB_IRQ = 0u; } static __INLINE void MSS_USB_CIF_tx_ep_enable_irq ( mss_usb_ep_num_t ep_num ) { USB->TX_IRQ_ENABLE |= (uint16_t)(MSS_USB_WORD_BIT_0_MASK << (uint8_t)ep_num); } static __INLINE void MSS_USB_CIF_tx_ep_disable_irq ( mss_usb_ep_num_t ep_num ) { USB->TX_IRQ_ENABLE &= (uint16_t)(~(MSS_USB_WORD_BIT_0_MASK << (uint8_t)ep_num)); } static __INLINE void MSS_USB_CIF_tx_ep_disable_irq_all ( void ) { /* Keep D0, CEP interrupt bit unaltered.*/ USB->TX_IRQ_ENABLE = (USB->TX_IRQ_ENABLE & TX_IRQ_ENABLE_REG_CEP_MASK); } static __INLINE void MSS_USB_CIF_rx_ep_enable_irq ( mss_usb_ep_num_t ep_num ) { USB->RX_IRQ_ENABLE |= (uint16_t)(MSS_USB_WORD_BIT_0_MASK << (uint8_t)ep_num); } static __INLINE void MSS_USB_CIF_rx_ep_disable_irq ( mss_usb_ep_num_t ep_num ) { USB->RX_IRQ_ENABLE &= (uint16_t)(~(MSS_USB_WORD_BIT_0_MASK << (uint8_t)ep_num)); } static __INLINE void MSS_USB_CIF_rx_ep_disable_irq_all ( void ) { USB->RX_IRQ_ENABLE = 0u ; } /*-------------------------------------------------------------------------*//** FRAME register related APIs */ static __INLINE uint16_t MSS_USB_CIF_get_last_frame_nbr ( void ) { return (USB->FRAME); } /*-------------------------------------------------------------------------*//** DEVCTL register related APIs */ static __INLINE mss_usb_core_mode_t MSS_USB_CIF_get_mode ( void ) { return (((USB->DEV_CTRL & DEV_CTRL_HOST_MODE_MASK) ? MSS_USB_CORE_MODE_HOST : MSS_USB_CORE_MODE_DEVICE)); } static __INLINE mss_usb_vbus_level_t MSS_USB_CIF_get_vbus_level ( void ) { uint8_t vbus; mss_usb_vbus_level_t ret_val = VBUS_BLOW_SESSIONEND; vbus = (USB->DEV_CTRL & DEV_CTRL_VBUS_MASK); switch (vbus) { case VBUS_BELOW_SESSION_END: ret_val = VBUS_BLOW_SESSIONEND; break; case VBUS_ABOVE_SESSION_END: ret_val = VBUS_ABV_SESSIONEND_BLOW_AVALID; break; case VBUS_ABOVE_AVALID: ret_val = VBUS_ABV_AVALID_BLOW_VB_VALID; break; case VBUS_ABOVE_VBUS_VALID: ret_val = VBUS_ABV_VB_VALID; break; default: /* Empty */ break; } return ret_val; } static __INLINE mss_usb_device_role_t MSS_USB_CIF_get_role ( void ) { /* TODO:only valid when session bit is set */ return (((USB->DEV_CTRL & DEV_CTRL_B_DEVICE_MASK) ? MSS_USB_DEVICE_ROLE_DEVICE_B : MSS_USB_DEVICE_ROLE_DEVICE_A)); } static __INLINE uint8_t MSS_USB_CIF_is_session_on ( void ) { /* TODO:only valid when session bit is set */ return (((USB->DEV_CTRL & DEV_CTRL_SESSION_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_start_session(void) { USB->DEV_CTRL |= DEV_CTRL_SESSION_MASK; } static __INLINE void MSS_USB_CIF_stop_session(void) { USB->DEV_CTRL &= ~DEV_CTRL_SESSION_MASK; } /*-------------------------------------------------------------------------*//** INDEXED registers */ /*-------------------------------------------------------------------------*//** CSR0L register related APIs */ static __INLINE uint8_t MSS_USB_CIF_cep_is_rxpktrdy ( void ) { return (((USB->INDEXED_CSR.DEVICE_EP0.CSR0 & CSR0L_DEV_RX_PKT_RDY_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_cep_set_txpktrdy ( void ) { USB->INDEXED_CSR.DEVICE_EP0.CSR0 |= CSR0L_DEV_TX_PKT_RDY_MASK; } static __INLINE void MSS_USB_CIF_cep_clr_stall_sent ( void ) { USB->INDEXED_CSR.DEVICE_EP0.CSR0 &= ~CSR0L_DEV_STALL_SENT_MASK; } static __INLINE uint8_t MSS_USB_CIF_cep_is_stall_sent ( void ) { return (((USB->INDEXED_CSR.DEVICE_EP0.CSR0 & CSR0L_DEV_STALL_SENT_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_cep_clr_setupend ( void ) { /* Setting SERVICED_SETUP_END bit clears SetupEnd bit */ USB->INDEXED_CSR.DEVICE_EP0.CSR0 |= CSR0L_DEV_SERVICED_SETUP_END_MASK; } static __INLINE uint8_t MSS_USB_CIF_cep_is_setupend ( void ) { return (((USB->INDEXED_CSR.DEVICE_EP0.CSR0 & CSR0L_DEV_SETUP_END_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_cep_reset_csr0_reg ( void ) { /* load the reset value for the register */ USB->INDEXED_CSR.DEVICE_EP0.CSR0 = 0u; } /*-------------------------------------------------------------------------*//** CNTRH0 register related APIs */ static __INLINE uint8_t MSS_USB_CIF_cep_rx_byte_count ( void ) { /* TODO:confirm CSR0.D0 bit before returning */ return (USB->INDEXED_CSR.DEVICE_EP0.COUNT0 & COUNT0_REG_MASK); } /*-------------------------------------------------------------------------*//** TXMAXP register related APIs */ static __INLINE void MSS_USB_CIF_tx_ep_set_max_pkt ( mss_usb_ep_num_t ep_num, mss_usb_xfr_type_t xfr_type, uint16_t max_pkt_size, uint8_t num_usb_pkt ) { /* TODO:make sure that there is no data in FIFO before writing into the maxP reg */ if ((ep_num > MSS_USB_CEP) && ((max_pkt_size % 8) == 0u) && (num_usb_pkt > 0u)) { if((num_usb_pkt > 31u)) { /* not allowed */ } else { USB->ENDPOINT[ep_num].TX_MAX_P = 0u; USB->ENDPOINT[ep_num].TX_MAX_P = num_usb_pkt - 1u; USB->ENDPOINT[ep_num].TX_MAX_P <<= TX_MAX_P_REG_NUM_USB_PKT_SHIFT; USB->ENDPOINT[ep_num].TX_MAX_P |= (max_pkt_size); } } } /*-------------------------------------------------------------------------*//** TXCSRL register related APIs */ static __INLINE void MSS_USB_CIF_tx_ep_set_txpktrdy ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRL_REG_EPN_TX_PKT_RDY_MASK; } static __INLINE uint8_t MSS_USB_CIF_tx_ep_is_txpktrdy ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].TX_CSR & TxCSRL_REG_EPN_TX_PKT_RDY_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_tx_ep_set_send_stall_bit ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRL_REG_EPN_SEND_STALL_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_clr_send_stall_bit ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRL_REG_EPN_SEND_STALL_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_clr_stall_sent_bit ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRL_REG_EPN_STALL_SENT_MASK; } static __INLINE uint8_t MSS_USB_CIF_tx_ep_is_stall_sent_bit ( mss_usb_ep_num_t ep_num ) { return (uint8_t)(((USB->ENDPOINT[ep_num].TX_CSR & TxCSRL_REG_EPN_STALL_SENT_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_tx_ep_clr_data_tog ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRL_REG_EPN_CLR_DATA_TOG_MASK; } static __INLINE uint8_t MSS_USB_CIF_tx_ep_is_isoincomp ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].TX_CSR & TxCSRL_REG_EPN_ISO_INCOMP_TX_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } /*-------------------------------------------------------------------------*//** TXCSRH register related APIs */ static __INLINE void MSS_USB_CIF_tx_ep_set_dma_mode1 ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRH_REG_EPN_DMA_MODE_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_set_dma_mode0 ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRH_REG_EPN_DMA_MODE_MASK; } static __INLINE uint8_t MSS_USB_CIF_tx_ep_get_dma_mode ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].TX_CSR & TxCSRH_REG_EPN_DMA_MODE_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_tx_ep_set_force_data_tog ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRH_REG_EPN_FRC_DAT_TOG_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_clr_force_data_tog ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRH_REG_EPN_FRC_DAT_TOG_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_enable_dma ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRH_REG_EPN_ENABLE_DMA_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_disable_dma ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRH_REG_EPN_ENABLE_DMA_MASK; } static __INLINE uint8_t MSS_USB_CIF_tx_ep_is_dma_enabled ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].TX_CSR & TxCSRH_REG_EPN_ENABLE_DMA_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_tx_ep_set_tx_mode ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRH_REG_EPN_TXRX_MODE_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_set_rx_mode ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRH_REG_EPN_TXRX_MODE_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_enable_iso ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRH_REG_EPN_ENABLE_ISO_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_disable_iso ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRH_REG_EPN_ENABLE_ISO_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_set_autoset ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR |= TxCSRH_REG_EPN_ENABLE_AUTOSET_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_clr_autoset ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRH_REG_EPN_ENABLE_AUTOSET_MASK; } static __INLINE uint8_t MSS_USB_CIF_tx_ep_is_autoset ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].TX_CSR & TxCSRH_REG_EPN_ENABLE_AUTOSET_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE uint8_t MSS_USB_CIF_tx_ep_is_underrun ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].TX_CSR & TxCSRL_REG_EPN_UNDERRUN_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_tx_ep_clr_underrun ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR &= ~TxCSRL_REG_EPN_UNDERRUN_MASK; } static __INLINE void MSS_USB_CIF_tx_ep_clr_csrreg ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].TX_CSR = 0x0000U; } /*-------------------------------------------------------------------------*//** RXMAXP register related APIs */ static __INLINE void MSS_USB_CIF_rx_ep_set_max_pkt ( mss_usb_ep_num_t ep_num, mss_usb_xfr_type_t xfr_type, uint16_t max_pkt_size, uint8_t num_usb_pkt ) { /* TODO:make sure that there is no data in FIFO before writing into the maxP reg */ if ((ep_num > MSS_USB_CEP) && (max_pkt_size > 0u) && ((max_pkt_size % 8) == 0u)) { if ((num_usb_pkt > 31u)) { /*not allowed*/ } else { USB->ENDPOINT[ep_num].RX_MAX_P = 0u; USB->ENDPOINT[ep_num].RX_MAX_P = num_usb_pkt - 1u; USB->ENDPOINT[ep_num].RX_MAX_P <<= RX_MAX_P_REG_NUM_USB_PKT_SHIFT; USB->ENDPOINT[ep_num].RX_MAX_P |= (max_pkt_size); } } } /*-------------------------------------------------------------------------*//** RXCSRL register related APIs */ static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_rxpktrdy ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_RX_PKT_RDY_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_rx_ep_clr_rxpktrdy ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].RX_CSR &= ~RxCSRL_REG_EPN_RX_PKT_RDY_MASK; } static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_overrun ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_OVERRUN_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_rx_ep_clr_overrun ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_OVERRUN_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_dataerr ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_DATA_ERR_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_rx_ep_set_send_stall_bit ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].RX_CSR |= (RxCSRL_REG_EPN_SEND_STALL_MASK | RxCSRL_REG_EPN_RX_PKT_RDY_MASK); } static __INLINE void MSS_USB_CIF_rx_ep_clr_send_stall_bit ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_SEND_STALL_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_stall_sent_bit ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_STALL_SENT_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_rx_ep_clr_stall_sent_bit ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_STALL_SENT_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE void MSS_USB_CIF_rx_ep_clr_data_tog ( mss_usb_ep_num_t ep_num ) { /* setting CLR_DAT_TOG bit clears USB Data toggle bit */ USB->ENDPOINT[ep_num].RX_CSR |= (RxCSRL_REG_EPN_CLR_DAT_TOG_MASK | RxCSRL_REG_EPN_RX_PKT_RDY_MASK); } /*-------------------------------------------------------------------------*//** RXCSRH register related APIs */ static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_isoincomp ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_RX_ISO_INCOMP) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE mss_usb_dma_mode_t MSS_USB_CIF_rx_ep_get_dma_mode ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_DMA_MODE_MASK) ? MSS_USB_DMA_MODE1 : MSS_USB_DMA_MODE0)); } static __INLINE void MSS_USB_CIF_rx_ep_set_dma_mode1 ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].RX_CSR |= (RxCSRL_REG_EPN_DMA_MODE_MASK | RxCSRL_REG_EPN_RX_PKT_RDY_MASK); } static __INLINE void MSS_USB_CIF_rx_ep_set_dma_mode0 ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_DMA_MODE_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE void MSS_USB_CIF_rx_ep_enable_dma ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].RX_CSR |= (RxCSRL_REG_EPN_ENABLE_DMA_MASK | RxCSRL_REG_EPN_RX_PKT_RDY_MASK); } static __INLINE void MSS_USB_CIF_rx_ep_disable_dma ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_ENABLE_DMA_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_dma_enabled ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_ENABLE_DMA_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_piderr ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_ISO_PID_ERR_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_rx_ep_disable_nyet ( mss_usb_ep_num_t ep_num ) { /* Setting BI_DIS_NYET mask disables NYET */ USB->ENDPOINT[ep_num].RX_CSR |= (RxCSRL_REG_EPN_BI_DIS_NYET_MASK | RxCSRL_REG_EPN_RX_PKT_RDY_MASK); } static __INLINE void MSS_USB_CIF_rx_ep_enable_nyet ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_BI_DIS_NYET_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE void MSS_USB_CIF_rx_ep_disable_iso ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_ENABLE_ISO_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE void MSS_USB_CIF_rx_ep_enable_iso ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].RX_CSR |= (RxCSRL_REG_EPN_ENABLE_ISO_MASK | RxCSRL_REG_EPN_RX_PKT_RDY_MASK); } static __INLINE void MSS_USB_CIF_rx_ep_set_autoclr ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].RX_CSR |= (RxCSRL_REG_EPN_ENABLE_AUTOCLR_MASK | RxCSRL_REG_EPN_RX_PKT_RDY_MASK); } static __INLINE void MSS_USB_CIF_rx_ep_clr_autoclr ( mss_usb_ep_num_t ep_num ) { uint16_t reg_val = USB->ENDPOINT[ep_num].RX_CSR; reg_val &= ~RxCSRL_REG_EPN_ENABLE_AUTOCLR_MASK; reg_val |= RxCSRL_REG_EPN_RX_PKT_RDY_MASK; USB->ENDPOINT[ep_num].RX_CSR = reg_val; } static __INLINE uint8_t MSS_USB_CIF_rx_ep_is_autoclr ( mss_usb_ep_num_t ep_num ) { return (((USB->ENDPOINT[ep_num].RX_CSR & RxCSRL_REG_EPN_ENABLE_AUTOCLR_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_rx_ep_clr_csrreg ( mss_usb_ep_num_t ep_num ) { USB->ENDPOINT[ep_num].RX_CSR = 0x0000U; } /*-------------------------------------------------------------------------*//** RXCOUNT register related APIs */ static __INLINE uint16_t MSS_USB_CIF_rx_ep_read_count ( mss_usb_ep_num_t ep_num ) { /* only valid when rxpktrdy is set */ return (USB->ENDPOINT[ep_num].RX_COUNT); } /*-------------------------------------------------------------------------*//** FIFOx register related APIs */ static __INLINE void MSS_USB_CIF_load_tx_fifo ( mss_usb_ep_num_t ep_num, void * in_data, uint32_t length ) { uint32_t idx; uint32_t* temp; uint8_t* temp_8bit; uint16_t words = length / 4; temp = in_data; temp_8bit = in_data; for(idx = 0u; idx < words; ++idx) { USB->FIFO[ep_num].WORD.VALUE = (uint32_t)temp[idx]; } for(idx = (length - (length % 4)); idx < length; ++idx) { USB->FIFO[ep_num].BYTE.VALUE = (uint8_t)temp_8bit[idx]; } } static __INLINE void MSS_USB_CIF_read_rx_fifo ( mss_usb_ep_num_t ep_num, void * out_data, uint32_t length ) { uint32_t idx; volatile uint32_t* temp; uint8_t* temp_8bit; uint16_t words = length / 4; temp = out_data; temp_8bit = out_data; for(idx = 0u; idx < words; ++idx) { temp[idx] = USB->FIFO[ep_num].WORD.VALUE; } for(idx = (length - (length % 4u)); idx < length; ++idx) { temp_8bit[idx] = USB->FIFO[ep_num].BYTE.VALUE; } } static __INLINE uint8_t MSS_USB_CIF_read_rx_fifo_byte ( mss_usb_ep_num_t ep_num ) { return (uint8_t)(USB->FIFO[ep_num].BYTE.VALUE); } static __INLINE uint16_t MSS_USB_CIF_read_rx_fifo_halfword ( mss_usb_ep_num_t ep_num ) { return (uint16_t)(USB->FIFO[ep_num].HALFWORD.VALUE); } static __INLINE uint32_t MSS_USB_CIF_read_rx_fifo_word ( mss_usb_ep_num_t ep_num ) { return (uint32_t)(USB->FIFO[ep_num].WORD.VALUE); } /*-------------------------------------------------------------------------*//** DynFIFOSIZE register related APIs */ static __INLINE void MSS_USB_CIF_tx_ep_set_fifo_size ( mss_usb_ep_num_t ep_num, uint16_t fifo_size, uint8_t dpb ) { uint16_t temp; uint8_t i = 0; /* Valid FIFO sizes are 8,16,32,64,128,512,1024,2048,4096 */ if ((ep_num > MSS_USB_CEP) && (fifo_size >= MIN_EP_FIFO_SZ)) { USB->INDEX = ep_num; temp = (fifo_size / MIN_EP_FIFO_SZ); while (!(temp & MSS_USB_WORD_BIT_0_MASK)) { temp >>= 1u; i++; } USB->TX_FIFO_SIZE = ((dpb << TXFIFOSZ_REG_DPB_SHIFT) | i); } } static __INLINE void MSS_USB_CIF_rx_ep_set_fifo_size ( mss_usb_ep_num_t ep_num, uint16_t fifo_size, uint8_t dpb ) { /* fifo_size is the size in terms of number of bytes.*/ uint16_t temp; uint8_t i = 0u; /* Valid FIFO sizes are 8,16,32,64,128,512,1024,2048,4096 */ if ((ep_num > MSS_USB_CEP) && (fifo_size >= MIN_EP_FIFO_SZ)) { USB->INDEX = ep_num; temp= (fifo_size / MIN_EP_FIFO_SZ); while (!(temp & MSS_USB_WORD_BIT_0_MASK)) { temp >>= 1u; i++; } USB->RX_FIFO_SIZE = ((dpb << RXFIFOSZ_REG_DPB_SHIFT) | i); } } /*-------------------------------------------------------------------------*//** DynFIFOAD register related APIs */ static __INLINE void MSS_USB_CIF_tx_ep_set_fifo_addr ( mss_usb_ep_num_t ep_num, uint16_t addr ) { /* Valid address values are from 0 to FFF8 in steps of 8 */ if (ep_num > MSS_USB_CEP) { USB->INDEX = ep_num; USB->TX_FIFO_ADDR = (addr / EP_FIFO_ADDR_STEP); } } static __INLINE void MSS_USB_CIF_rx_ep_set_fifo_addr ( mss_usb_ep_num_t ep_num, uint16_t addr ) { /* Valid address values are from 0 to FFF8 in steps of 8 */ if (ep_num > MSS_USB_CEP) { USB->INDEX = ep_num; USB->RX_FIFO_ADDR = (addr / EP_FIFO_ADDR_STEP); } } /*-------------------------------------------------------------------------*//** RX_DPKTBUFDIS register related APIs */ static __INLINE void MSS_USB_CIF_disable_rx_ep_dpb ( mss_usb_ep_num_t ep_num ) { USB->RX_DPBUF_DIS |= (uint16_t)(MSS_USB_WORD_BIT_0_MASK << ep_num); } static __INLINE void MSS_USB_CIF_enable_rx_ep_dpb ( mss_usb_ep_num_t ep_num ) { USB->RX_DPBUF_DIS &= (uint16_t)(~(MSS_USB_WORD_BIT_0_MASK << ep_num)); } /*-------------------------------------------------------------------------*//** TX_DPKTBUFDIS register related APIs */ static __INLINE void MSS_USB_disable_tx_ep_dpb ( mss_usb_ep_num_t ep_num ) { USB->TX_DPBUF_DIS |= (uint16_t)(MSS_USB_WORD_BIT_0_MASK << ep_num); } static __INLINE void MSS_USB_enable_tx_ep_dpb ( mss_usb_ep_num_t ep_num ) { USB->TX_DPBUF_DIS &= (uint16_t)(~(MSS_USB_WORD_BIT_0_MASK << ep_num)); } /*-------------------------------------------------------------------------*//** DMA_INTR register related APIs */ static __INLINE uint32_t MSS_USB_CIF_dma_read_irq ( void ) { return (USB->DMA_CHANNEL[0].IRQ); } /*-------------------------------------------------------------------------*//** * DMA_CNTL register related APIs */ static __INLINE void MSS_USB_CIF_dma_start_xfr ( mss_usb_dma_channel_t dma_channel ) { USB->DMA_CHANNEL[dma_channel].CNTL |= DMA_CNTL_REG_START_XFR_MASK; } static __INLINE void MSS_USB_CIF_dma_stop_xfr ( mss_usb_dma_channel_t dma_channel ) { USB->DMA_CHANNEL[dma_channel].CNTL &= ~DMA_CNTL_REG_START_XFR_MASK; } static __INLINE void MSS_USB_CIF_dma_set_dir ( mss_usb_dma_channel_t dma_channel, mss_usb_dma_dir_t dir ) { /* dir = 1 => DMA read (TX EP) dir = 0 => DMA write (RX EP) */ USB->DMA_CHANNEL[dma_channel].CNTL |= (dir << DMA_CNTL_REG_DMA_DIR_SHIFT); } static __INLINE mss_usb_dma_dir_t MSS_USB_CIF_dma_get_dir ( mss_usb_dma_channel_t dma_channel ) { return(((USB->DMA_CHANNEL[dma_channel].CNTL & DMA_CNTL_REG_DMA_DIR_MASK) ? MSS_USB_DMA_READ : MSS_USB_DMA_WRITE)); } static __INLINE void MSS_USB_CIF_dma_set_mode ( mss_usb_dma_channel_t dma_channel, mss_usb_dma_mode_t dma_mode ) { USB->DMA_CHANNEL[dma_channel].CNTL |= (dma_mode << DMA_CNTL_REG_DMA_MODE_SHIFT); } static __INLINE mss_usb_dma_mode_t MSS_USB_CIF_dma_get_mode ( mss_usb_dma_channel_t dma_channel ) { return (((USB->DMA_CHANNEL[dma_channel].CNTL & DMA_CNTL_REG_DMA_MODE_MASK) ? MSS_USB_DMA_MODE1: MSS_USB_DMA_MODE0)); } static __INLINE void MSS_USB_CIF_dma_enable_irq ( mss_usb_dma_channel_t dma_channel ) { USB->DMA_CHANNEL[dma_channel].CNTL |= DMA_CNTL_REG_ENABLE_DMA_IRQ_MASK; } static __INLINE void MSS_USB_CIF_dma_disable_irq ( mss_usb_dma_channel_t dma_channel ) { USB->DMA_CHANNEL[dma_channel].CNTL &= ~DMA_CNTL_REG_ENABLE_DMA_IRQ_MASK; } static __INLINE void MSS_USB_CIF_dma_assign_to_epnum ( mss_usb_dma_channel_t dma_channel, mss_usb_ep_num_t ep_num ) { USB->DMA_CHANNEL[dma_channel].CNTL |= ((ep_num << DMA_CNTL_REG_DMA_EP_NUM_SHIFT) & DMA_CNTL_REG_DMA_EP_NUM_MASK); } static __INLINE mss_usb_ep_num_t MSS_USB_CIF_dma_get_epnum ( mss_usb_dma_channel_t dma_channel ) { /* This API will return numbers from 0 to 15, mss_usb_ep_num_t maps it to TX EP numbers. Using DMA DIR, CIF driver should correctly map it as TX EP or RX EP. */ volatile uint8_t ep_num; ep_num = (USB->DMA_CHANNEL[dma_channel].CNTL & DMA_CNTL_REG_DMA_EP_NUM_MASK); return (mss_usb_ep_num_t)(ep_num >> DMA_CNTL_REG_DMA_EP_NUM_SHIFT); } static __INLINE uint8_t MSS_USB_CIF_dma_is_bus_err ( mss_usb_dma_channel_t dma_channel ) { return (((USB->DMA_CHANNEL[dma_channel].CNTL & DMA_CNTL_REG_DMA_BUS_ERR_MASK) ? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE)); } static __INLINE void MSS_USB_CIF_dma_clr_bus_err ( mss_usb_dma_channel_t dma_channel ) { USB->DMA_CHANNEL[dma_channel].CNTL &= ~DMA_CNTL_REG_DMA_BUS_ERR_MASK; } static __INLINE void MSS_USB_CIF_dma_set_burst_mode ( mss_usb_dma_channel_t dma_channel, mss_usb_dma_burst_mode_t burst_mode ) { USB->DMA_CHANNEL[dma_channel].CNTL |= ((burst_mode << DMA_CNTL_REG_DMA_BURST_MODE_SHIFT) & DMA_CNTL_REG_DMA_BURST_MODE_MASK); } static __INLINE mss_usb_dma_burst_mode_t MSS_USB_CIF_dma_get_burst_mode ( mss_usb_dma_channel_t dma_channel, mss_usb_dma_burst_mode_t burst_mode ) { uint8_t mode; mode = (USB->DMA_CHANNEL[dma_channel].CNTL & DMA_CNTL_REG_DMA_BURST_MODE_MASK); return (mss_usb_dma_burst_mode_t)(mode >> DMA_CNTL_REG_DMA_BURST_MODE_SHIFT); } static __INLINE void MSS_USB_CIF_dma_clr_ctrlreg ( mss_usb_dma_channel_t dma_channel ) { USB->DMA_CHANNEL[dma_channel].CNTL = 0x0000U; } /*-------------------------------------------------------------------------*//** DMA_ADDR register related APIs */ static __INLINE uint32_t MSS_USB_CIF_dma_read_addr ( mss_usb_dma_channel_t dma_channel ) { return (USB->DMA_CHANNEL[dma_channel].ADDR); } static __INLINE void MSS_USB_CIF_dma_write_addr ( mss_usb_dma_channel_t dma_channel, uint32_t addr ) { USB->DMA_CHANNEL[dma_channel].ADDR = addr; } /*-------------------------------------------------------------------------*//** DMA_COUNT register related APIs */ static __INLINE uint32_t MSS_USB_CIF_dma_read_count ( mss_usb_dma_channel_t dma_channel ) { return (USB->DMA_CHANNEL[dma_channel].COUNT); } static __INLINE void MSS_USB_CIF_dma_write_count ( mss_usb_dma_channel_t dma_channel, uint32_t count ) { USB->DMA_CHANNEL[dma_channel].COUNT = count; } #ifdef __cplusplus } #endif #endif /* __MSS_USB_COMMON_REG_IO_H_ */