2022-09-04 20:17:32 +08:00
/*
* Copyright ( c ) 2022 , sakumisu
*
* SPDX - License - Identifier : Apache - 2.0
*/
2022-06-14 22:05:48 +08:00
# include "usbd_core.h"
# include "usb_dwc2_reg.h"
2022-09-25 18:04:35 +08:00
// clang-format off
# if defined ( __CC_ARM )
# ifndef __UNALIGNED_UINT32_WRITE
# define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
# endif
# ifndef __UNALIGNED_UINT32_READ
# define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
# endif
# elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
# ifndef __UNALIGNED_UINT32_WRITE
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v ; } ;
# pragma clang diagnostic pop
# define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
# endif
# ifndef __UNALIGNED_UINT32_READ
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpacked"
/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */
__PACKED_STRUCT T_UINT32_READ { uint32_t v ; } ;
# pragma clang diagnostic pop
# define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
# endif
# elif defined ( __GNUC__ )
# ifndef __UNALIGNED_UINT32_WRITE
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpacked"
# pragma GCC diagnostic ignored "-Wattributes"
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v ; } ;
# pragma GCC diagnostic pop
# define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
# endif
# ifndef __UNALIGNED_UINT32_READ
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpacked"
# pragma GCC diagnostic ignored "-Wattributes"
__PACKED_STRUCT T_UINT32_READ { uint32_t v ; } ;
# pragma GCC diagnostic pop
# define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
# endif
# endif
// clang-format on
2022-06-14 22:05:48 +08:00
2024-03-21 23:07:07 +08:00
# ifndef CONFIG_USB_DWC2_RXALL_FIFO_SIZE
2024-05-15 22:37:33 +08:00
# define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
2022-06-14 22:05:48 +08:00
# endif
# ifndef CONFIG_USB_DWC2_TX0_FIFO_SIZE
2024-03-21 23:07:07 +08:00
# define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
2022-06-14 22:05:48 +08:00
# endif
# ifndef CONFIG_USB_DWC2_TX1_FIFO_SIZE
2024-09-26 21:27:56 +08:00
# define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4)
2022-06-14 22:05:48 +08:00
# endif
# ifndef CONFIG_USB_DWC2_TX2_FIFO_SIZE
2024-03-21 23:07:07 +08:00
# define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
2022-06-14 22:05:48 +08:00
# endif
# ifndef CONFIG_USB_DWC2_TX3_FIFO_SIZE
2024-03-21 23:07:07 +08:00
# define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
2022-06-14 22:05:48 +08:00
# endif
# ifndef CONFIG_USB_DWC2_TX4_FIFO_SIZE
2024-03-21 23:07:07 +08:00
# define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
2022-06-14 22:05:48 +08:00
# endif
# ifndef CONFIG_USB_DWC2_TX5_FIFO_SIZE
2024-03-21 23:07:07 +08:00
# define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
2022-07-28 21:25:29 +08:00
# endif
2022-07-31 15:57:59 +08:00
2024-03-21 23:07:07 +08:00
# ifndef CONFIG_USB_DWC2_TX6_FIFO_SIZE
2024-04-03 15:44:43 +08:00
# define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
2022-06-14 22:05:48 +08:00
# endif
2024-03-21 23:07:07 +08:00
# ifndef CONFIG_USB_DWC2_TX7_FIFO_SIZE
2024-04-03 15:44:43 +08:00
# define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
2022-06-14 22:05:48 +08:00
# endif
2024-03-21 23:07:07 +08:00
# ifndef CONFIG_USB_DWC2_TX8_FIFO_SIZE
2024-04-03 15:44:43 +08:00
# define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
2022-07-28 21:25:29 +08:00
# endif
2024-08-22 20:16:40 +08:00
# define USBD_BASE (g_usbdev_bus[busid].reg_base)
2024-02-18 19:36:20 +08:00
2024-05-21 11:50:49 +08:00
# define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE))
# define USB_OTG_DEV ((DWC2_DeviceTypeDef *)(USBD_BASE + USB_OTG_DEVICE_BASE))
2023-12-21 20:23:54 +08:00
# define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)USBD_BASE + USB_OTG_PCGCCTL_BASE)
2024-05-21 11:50:49 +08:00
# define USB_OTG_INEP(i) ((DWC2_INEndpointTypeDef *)(USBD_BASE + USB_OTG_IN_ENDPOINT_BASE + ((i)*USB_OTG_EP_REG_SIZE)))
# define USB_OTG_OUTEP(i) ((DWC2_OUTEndpointTypeDef *)(USBD_BASE + USB_OTG_OUT_ENDPOINT_BASE + ((i)*USB_OTG_EP_REG_SIZE)))
2023-12-21 20:23:54 +08:00
# define USB_OTG_FIFO(i) *(__IO uint32_t *)(USBD_BASE + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE))
2022-06-14 22:05:48 +08:00
extern uint32_t SystemCoreClock ;
/* Endpoint state */
struct dwc2_ep_state {
2022-07-28 21:25:29 +08:00
uint16_t ep_mps ; /* Endpoint max packet size */
uint8_t ep_type ; /* Endpoint type */
uint8_t ep_stalled ; /* Endpoint stall flag */
uint8_t * xfer_buf ;
uint32_t xfer_len ;
uint32_t actual_xfer_len ;
2022-06-14 22:05:48 +08:00
} ;
/* Driver state */
2023-05-08 20:05:32 +08:00
USB_NOCACHE_RAM_SECTION struct dwc2_udc {
2025-05-12 21:06:50 +08:00
uint32_t GSNPSID ;
2022-07-28 21:25:29 +08:00
__attribute__ ( ( aligned ( 32 ) ) ) struct usb_setup_packet setup ;
2023-12-21 20:23:54 +08:00
struct dwc2_ep_state in_ep [ CONFIG_USBDEV_EP_NUM ] ; /*!< IN endpoint parameters*/
struct dwc2_ep_state out_ep [ CONFIG_USBDEV_EP_NUM ] ; /*!< OUT endpoint parameters */
2024-09-08 21:55:30 +08:00
} g_dwc2_udc [ CONFIG_USBDEV_MAX_BUS ] ;
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
static inline int dwc2_reset ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
2023-05-08 20:21:59 +08:00
volatile uint32_t count = 0U ;
2022-06-14 22:05:48 +08:00
/* Wait for AHB master IDLE state. */
do {
if ( + + count > 200000U ) {
return - 1 ;
}
} while ( ( USB_OTG_GLB - > GRSTCTL & USB_OTG_GRSTCTL_AHBIDL ) = = 0U ) ;
/* Core Soft Reset */
count = 0U ;
USB_OTG_GLB - > GRSTCTL | = USB_OTG_GRSTCTL_CSRST ;
2025-05-12 21:06:50 +08:00
if ( g_dwc2_udc [ busid ] . GSNPSID < 0x4F54420AU ) {
do {
if ( + + count > 200000U ) {
USB_LOG_ERR ( " DWC2 reset timeout \r \n " ) ;
return - 1 ;
}
} while ( ( USB_OTG_GLB - > GRSTCTL & USB_OTG_GRSTCTL_CSRST ) = = USB_OTG_GRSTCTL_CSRST ) ;
} else {
do {
if ( + + count > 200000U ) {
USB_LOG_ERR ( " DWC2 reset timeout \r \n " ) ;
return - 1 ;
}
} while ( ( USB_OTG_GLB - > GRSTCTL & USB_OTG_GRSTCTL_CSRSTDONE ) ! = USB_OTG_GRSTCTL_CSRSTDONE ) ;
2022-06-14 22:05:48 +08:00
2025-05-12 21:06:50 +08:00
USB_OTG_GLB - > GRSTCTL & = ~ USB_OTG_GRSTCTL_CSRST ;
USB_OTG_GLB - > GRSTCTL | = USB_OTG_GRSTCTL_CSRSTDONE ;
}
2024-11-25 21:03:51 +08:00
2022-06-14 22:05:48 +08:00
return 0 ;
}
2024-08-22 20:16:40 +08:00
static inline int dwc2_core_init ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
int ret ;
# if defined(CONFIG_USB_HS)
2022-06-29 22:16:42 +08:00
/* Init The ULPI Interface */
USB_OTG_GLB - > GUSBCFG & = ~ ( USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL ) ;
/* Select vbus source */
USB_OTG_GLB - > GUSBCFG & = ~ ( USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI ) ;
/* Reset after a PHY select */
2024-08-22 20:16:40 +08:00
ret = dwc2_reset ( busid ) ;
2022-06-14 22:05:48 +08:00
# else
/* Select FS Embedded PHY */
USB_OTG_GLB - > GUSBCFG | = USB_OTG_GUSBCFG_PHYSEL ;
2022-06-29 22:16:42 +08:00
2022-06-14 22:05:48 +08:00
/* Reset after a PHY select */
2024-08-22 20:16:40 +08:00
ret = dwc2_reset ( busid ) ;
2022-06-29 22:16:42 +08:00
# endif
2022-06-14 22:05:48 +08:00
return ret ;
}
2024-08-22 20:16:40 +08:00
static inline void dwc2_set_mode ( uint8_t busid , uint8_t mode )
2022-06-14 22:05:48 +08:00
{
USB_OTG_GLB - > GUSBCFG & = ~ ( USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD ) ;
if ( mode = = USB_OTG_MODE_HOST ) {
USB_OTG_GLB - > GUSBCFG | = USB_OTG_GUSBCFG_FHMOD ;
} else if ( mode = = USB_OTG_MODE_DEVICE ) {
USB_OTG_GLB - > GUSBCFG | = USB_OTG_GUSBCFG_FDMOD ;
}
2024-08-13 18:10:36 +08:00
usbd_dwc2_delay_ms ( 50 ) ;
2022-06-14 22:05:48 +08:00
}
2024-08-22 20:16:40 +08:00
static inline int dwc2_flush_rxfifo ( uint8_t busid )
2022-06-15 20:50:59 +08:00
{
2024-08-13 18:10:36 +08:00
volatile uint32_t count = 0U ;
/* Wait for AHB master IDLE state. */
do {
if ( + + count > 200000U ) {
return - 1 ;
}
} while ( ( USB_OTG_GLB - > GRSTCTL & USB_OTG_GRSTCTL_AHBIDL ) = = 0U ) ;
2022-06-15 20:50:59 +08:00
2024-08-13 18:10:36 +08:00
count = 0 ;
2022-06-15 20:50:59 +08:00
USB_OTG_GLB - > GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH ;
do {
if ( + + count > 200000U ) {
return - 1 ;
}
} while ( ( USB_OTG_GLB - > GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH ) = = USB_OTG_GRSTCTL_RXFFLSH ) ;
return 0 ;
}
2024-08-22 20:16:40 +08:00
static inline int dwc2_flush_txfifo ( uint8_t busid , uint32_t num )
2022-06-15 20:50:59 +08:00
{
2023-05-08 20:21:59 +08:00
volatile uint32_t count = 0U ;
2022-06-15 20:50:59 +08:00
2024-08-13 18:10:36 +08:00
/* Wait for AHB master IDLE state. */
do {
if ( + + count > 200000U ) {
return - 1 ;
}
} while ( ( USB_OTG_GLB - > GRSTCTL & USB_OTG_GRSTCTL_AHBIDL ) = = 0U ) ;
count = 0 ;
2022-06-15 20:50:59 +08:00
USB_OTG_GLB - > GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH | ( num < < 6 ) ) ;
do {
if ( + + count > 200000U ) {
return - 1 ;
}
} while ( ( USB_OTG_GLB - > GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH ) = = USB_OTG_GRSTCTL_TXFFLSH ) ;
return 0 ;
}
2024-08-22 20:16:40 +08:00
static void dwc2_set_turnaroundtime ( uint8_t busid , uint32_t hclk , uint8_t speed )
2022-06-14 22:05:48 +08:00
{
uint32_t UsbTrd ;
/* The USBTRD is configured according to the tables below, depending on AHB frequency
used by application . In the low AHB frequency range it is used to stretch enough the USB response
time to IN tokens , the USB turnaround time , so to compensate for the longer AHB read access
latency to the Data FIFO */
if ( speed = = USB_OTG_SPEED_FULL ) {
if ( ( hclk > = 14200000U ) & & ( hclk < 15000000U ) ) {
/* hclk Clock Range between 14.2-15 MHz */
UsbTrd = 0xFU ;
} else if ( ( hclk > = 15000000U ) & & ( hclk < 16000000U ) ) {
/* hclk Clock Range between 15-16 MHz */
UsbTrd = 0xEU ;
} else if ( ( hclk > = 16000000U ) & & ( hclk < 17200000U ) ) {
/* hclk Clock Range between 16-17.2 MHz */
UsbTrd = 0xDU ;
} else if ( ( hclk > = 17200000U ) & & ( hclk < 18500000U ) ) {
/* hclk Clock Range between 17.2-18.5 MHz */
UsbTrd = 0xCU ;
} else if ( ( hclk > = 18500000U ) & & ( hclk < 20000000U ) ) {
/* hclk Clock Range between 18.5-20 MHz */
UsbTrd = 0xBU ;
} else if ( ( hclk > = 20000000U ) & & ( hclk < 21800000U ) ) {
/* hclk Clock Range between 20-21.8 MHz */
UsbTrd = 0xAU ;
} else if ( ( hclk > = 21800000U ) & & ( hclk < 24000000U ) ) {
/* hclk Clock Range between 21.8-24 MHz */
UsbTrd = 0x9U ;
} else if ( ( hclk > = 24000000U ) & & ( hclk < 27700000U ) ) {
/* hclk Clock Range between 24-27.7 MHz */
UsbTrd = 0x8U ;
} else if ( ( hclk > = 27700000U ) & & ( hclk < 32000000U ) ) {
/* hclk Clock Range between 27.7-32 MHz */
UsbTrd = 0x7U ;
} else /* if(hclk >= 32000000) */
{
/* hclk Clock Range between 32-200 MHz */
UsbTrd = 0x6U ;
}
} else if ( speed = = USB_OTG_SPEED_HIGH ) {
UsbTrd = USBD_HS_TRDT_VALUE ;
} else {
UsbTrd = USBD_DEFAULT_TRDT_VALUE ;
}
2023-09-07 12:43:30 +08:00
USB_OTG_GLB - > GUSBCFG | = USB_OTG_GUSBCFG_TOCAL ;
2022-06-14 22:05:48 +08:00
USB_OTG_GLB - > GUSBCFG & = ~ USB_OTG_GUSBCFG_TRDT ;
2023-09-07 12:43:30 +08:00
USB_OTG_GLB - > GUSBCFG | = ( uint32_t ) ( ( UsbTrd < < USB_OTG_GUSBCFG_TRDT_Pos ) & USB_OTG_GUSBCFG_TRDT ) ;
2022-06-14 22:05:48 +08:00
}
2024-08-22 20:16:40 +08:00
static void dwc2_set_txfifo ( uint8_t busid , uint8_t fifo , uint16_t size )
2022-06-14 22:05:48 +08:00
{
uint8_t i ;
2024-05-20 19:13:11 +08:00
uint32_t tx_offset ;
2022-06-14 22:05:48 +08:00
/* TXn min size = 16 words. (n : Transmit FIFO index)
When a TxFIFO is not used , the Configuration should be as follows :
case 1 : n > m and Txn is not used ( n , m : Transmit FIFO indexes )
- - > Txm can use the space allocated for Txn .
case2 : n < m and Txn is not used ( n , m : Transmit FIFO indexes )
- - > Txn should be configured with the minimum space of 16 words
The FIFO is used optimally when used TxFIFOs are allocated in the top
of the FIFO . Ex : use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones .
When DMA is used 3 n * FIFO locations should be reserved for internal DMA registers */
2024-05-20 19:13:11 +08:00
tx_offset = USB_OTG_GLB - > GRXFSIZ ;
2022-06-14 22:05:48 +08:00
if ( fifo = = 0U ) {
2024-05-20 19:13:11 +08:00
USB_OTG_GLB - > DIEPTXF0_HNPTXFSIZ = ( ( uint32_t ) size < < 16 ) | tx_offset ;
2022-06-14 22:05:48 +08:00
} else {
2024-05-20 19:13:11 +08:00
tx_offset + = ( USB_OTG_GLB - > DIEPTXF0_HNPTXFSIZ ) > > 16 ;
2022-06-14 22:05:48 +08:00
for ( i = 0U ; i < ( fifo - 1U ) ; i + + ) {
2024-05-20 19:13:11 +08:00
tx_offset + = ( USB_OTG_GLB - > DIEPTXF [ i ] > > 16 ) ;
2022-06-14 22:05:48 +08:00
}
/* Multiply Tx_Size by 2 to get higher performance */
2024-05-20 19:13:11 +08:00
USB_OTG_GLB - > DIEPTXF [ fifo - 1U ] = ( ( uint32_t ) size < < 16 ) | tx_offset ;
2022-06-14 22:05:48 +08:00
}
2023-09-07 12:43:30 +08:00
2024-05-20 19:13:11 +08:00
USB_LOG_INFO ( " fifo%d size:%04x, offset:%04x \r \n " , fifo , size , tx_offset ) ;
2022-06-14 22:05:48 +08:00
}
2024-08-22 20:16:40 +08:00
static uint8_t dwc2_get_devspeed ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
uint8_t speed ;
uint32_t DevEnumSpeed = USB_OTG_DEV - > DSTS & USB_OTG_DSTS_ENUMSPD ;
if ( DevEnumSpeed = = DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ ) {
speed = USB_OTG_SPEED_HIGH ;
} else if ( ( DevEnumSpeed = = DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ ) | |
( DevEnumSpeed = = DSTS_ENUMSPD_FS_PHY_48MHZ ) ) {
speed = USB_OTG_SPEED_FULL ;
} else {
speed = 0xFU ;
}
return speed ;
}
2024-08-22 20:16:40 +08:00
static void dwc2_ep0_start_read_setup ( uint8_t busid , uint8_t * psetup )
2022-07-28 21:25:29 +08:00
{
USB_OTG_OUTEP ( 0U ) - > DOEPTSIZ = 0U ;
USB_OTG_OUTEP ( 0U ) - > DOEPTSIZ | = ( USB_OTG_DOEPTSIZ_PKTCNT & ( 1U < < 19 ) ) ;
USB_OTG_OUTEP ( 0U ) - > DOEPTSIZ | = ( 3U * 8U ) ;
USB_OTG_OUTEP ( 0U ) - > DOEPTSIZ | = USB_OTG_DOEPTSIZ_STUPCNT ;
# ifdef CONFIG_USB_DWC2_DMA_ENABLE
USB_OTG_OUTEP ( 0U ) - > DOEPDMA = ( uint32_t ) psetup ;
/* EP enable */
USB_OTG_OUTEP ( 0U ) - > DOEPCTL | = USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP ;
# endif
}
2024-08-22 20:16:40 +08:00
void dwc2_ep_write ( uint8_t busid , uint8_t ep_idx , uint8_t * src , uint16_t len )
2022-07-28 21:25:29 +08:00
{
uint32_t * pSrc = ( uint32_t * ) src ;
uint32_t count32b , i ;
count32b = ( ( uint32_t ) len + 3U ) / 4U ;
for ( i = 0U ; i < count32b ; i + + ) {
USB_OTG_FIFO ( ( uint32_t ) ep_idx ) = __UNALIGNED_UINT32_READ ( pSrc ) ;
pSrc + + ;
}
}
2024-08-22 20:16:40 +08:00
void dwc2_ep_read ( uint8_t busid , uint8_t * dest , uint16_t len )
2022-07-28 21:25:29 +08:00
{
uint32_t * pDest = ( uint32_t * ) dest ;
uint32_t i ;
uint32_t count32b = ( ( uint32_t ) len + 3U ) / 4U ;
for ( i = 0U ; i < count32b ; i + + ) {
__UNALIGNED_UINT32_WRITE ( pDest , USB_OTG_FIFO ( 0U ) ) ;
pDest + + ;
}
}
2024-08-22 20:16:40 +08:00
static void dwc2_tx_fifo_empty_procecss ( uint8_t busid , uint8_t ep_idx )
2022-07-28 21:25:29 +08:00
{
uint32_t len ;
uint32_t len32b ;
uint32_t fifoemptymsk ;
2024-08-22 20:16:40 +08:00
len = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len - g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len ;
if ( len > g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps ) {
len = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps ;
2022-07-28 21:25:29 +08:00
}
len32b = ( len + 3U ) / 4U ;
while ( ( ( USB_OTG_INEP ( ep_idx ) - > DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV ) > = len32b ) & &
2024-08-22 20:16:40 +08:00
( g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len < g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len ) & & ( g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len ! = 0U ) ) {
2022-07-28 21:25:29 +08:00
/* Write the FIFO */
2024-08-22 20:16:40 +08:00
len = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len - g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len ;
if ( len > g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps ) {
len = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps ;
2022-07-28 21:25:29 +08:00
}
2024-09-26 21:22:36 +08:00
if ( g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_type = = USB_ENDPOINT_TYPE_ISOCHRONOUS ) {
if ( ( USB_OTG_DEV - > DSTS & ( 1U < < 8 ) ) = = 0U ) {
USB_OTG_INEP ( ep_idx ) - > DIEPCTL & = ~ USB_OTG_DIEPCTL_SD0PID_SEVNFRM ;
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_SODDFRM ;
} else {
USB_OTG_INEP ( ep_idx ) - > DIEPCTL & = ~ USB_OTG_DIEPCTL_SODDFRM ;
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_SD0PID_SEVNFRM ;
}
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ & = ~ ( USB_OTG_DIEPTSIZ_MULCNT ) ;
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ | = ( USB_OTG_DIEPTSIZ_MULCNT & ( 1U < < 29 ) ) ;
}
2022-10-25 23:12:19 +08:00
2024-08-22 20:16:40 +08:00
dwc2_ep_write ( busid , ep_idx , g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_buf , len ) ;
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_buf + = len ;
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len + = len ;
2022-07-28 21:25:29 +08:00
}
2024-08-22 20:16:40 +08:00
if ( g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len < = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len ) {
2022-07-28 21:25:29 +08:00
fifoemptymsk = ( uint32_t ) ( 0x1UL < < ( ep_idx & 0x0f ) ) ;
USB_OTG_DEV - > DIEPEMPMSK & = ~ fifoemptymsk ;
}
}
2022-06-14 22:05:48 +08:00
/**
2022-06-15 20:50:59 +08:00
* @ brief dwc2_get_glb_intstatus : return the global USB interrupt status
2022-06-14 22:05:48 +08:00
* @ retval status
*/
2024-08-22 20:16:40 +08:00
static inline uint32_t dwc2_get_glb_intstatus ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
uint32_t tmpreg ;
tmpreg = USB_OTG_GLB - > GINTSTS ;
tmpreg & = USB_OTG_GLB - > GINTMSK ;
return tmpreg ;
}
/**
2022-06-15 20:50:59 +08:00
* @ brief dwc2_get_outeps_intstatus : return the USB device OUT endpoints interrupt status
2022-06-14 22:05:48 +08:00
* @ retval status
*/
2024-08-22 20:16:40 +08:00
static inline uint32_t dwc2_get_outeps_intstatus ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
uint32_t tmpreg ;
tmpreg = USB_OTG_DEV - > DAINT ;
tmpreg & = USB_OTG_DEV - > DAINTMSK ;
return ( ( tmpreg & 0xffff0000U ) > > 16 ) ;
}
/**
2022-06-15 20:50:59 +08:00
* @ brief dwc2_get_ineps_intstatus : return the USB device IN endpoints interrupt status
2022-06-14 22:05:48 +08:00
* @ retval status
*/
2024-08-22 20:16:40 +08:00
static inline uint32_t dwc2_get_ineps_intstatus ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
uint32_t tmpreg ;
tmpreg = USB_OTG_DEV - > DAINT ;
tmpreg & = USB_OTG_DEV - > DAINTMSK ;
return ( ( tmpreg & 0xFFFFU ) ) ;
}
/**
* @ brief Returns Device OUT EP Interrupt register
* @ param epnum endpoint number
* This parameter can be a value from 0 to 15
* @ retval Device OUT EP Interrupt register
*/
2024-08-22 20:16:40 +08:00
static inline uint32_t dwc2_get_outep_intstatus ( uint8_t busid , uint8_t epnum )
2022-06-14 22:05:48 +08:00
{
uint32_t tmpreg ;
tmpreg = USB_OTG_OUTEP ( ( uint32_t ) epnum ) - > DOEPINT ;
2024-07-18 10:50:49 +08:00
USB_OTG_OUTEP ( ( uint32_t ) epnum ) - > DOEPINT = tmpreg ;
tmpreg = tmpreg & USB_OTG_DEV - > DOEPMSK ;
2022-06-14 22:05:48 +08:00
return tmpreg ;
}
/**
* @ brief Returns Device IN EP Interrupt register
* @ param epnum endpoint number
* This parameter can be a value from 0 to 15
* @ retval Device IN EP Interrupt register
*/
2024-08-22 20:16:40 +08:00
static inline uint32_t dwc2_get_inep_intstatus ( uint8_t busid , uint8_t epnum )
2022-06-14 22:05:48 +08:00
{
uint32_t tmpreg , msk , emp ;
msk = USB_OTG_DEV - > DIEPMSK ;
emp = USB_OTG_DEV - > DIEPEMPMSK ;
2024-12-16 20:53:52 +08:00
msk | = ( ( emp > > ( epnum & 0x0F ) ) & 0x1U ) < < 7 ;
2024-07-18 10:50:49 +08:00
tmpreg = USB_OTG_INEP ( ( uint32_t ) epnum ) - > DIEPINT ;
USB_OTG_INEP ( ( uint32_t ) epnum ) - > DIEPINT = tmpreg ;
tmpreg = tmpreg & msk ;
2022-06-14 22:05:48 +08:00
return tmpreg ;
}
2024-02-06 19:51:50 +08:00
int usb_dc_init ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
int ret ;
2023-06-21 20:51:10 +08:00
uint8_t fsphy_type ;
uint8_t hsphy_type ;
uint8_t dma_support ;
uint8_t endpoints ;
2024-03-21 23:07:07 +08:00
uint32_t fifo_num ;
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
memset ( & g_dwc2_udc [ busid ] , 0 , sizeof ( struct dwc2_udc ) ) ;
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
usb_dc_low_level_init ( busid ) ;
2022-06-14 22:05:48 +08:00
2023-06-21 20:51:10 +08:00
/*
Full - Speed PHY Interface Type ( FSPhyType )
2 ' b00 : Full - speed interface not supported
2 ' b01 : Dedicated full - speed interface
2 ' b10 : FS pins shared with UTMI + pins
2 ' b11 : FS pins shared with ULPI pins
High - Speed PHY Interface Type ( HSPhyType )
2 ' b00 : High - Speed interface not supported
2 ' b01 : UTMI +
2 ' b10 : ULPI
2 ' b11 : UTMI + and ULPI
Architecture ( OtgArch )
2 ' b00 : Slave - Only
2 ' b01 : External DMA
2 ' b10 : Internal DMA
Others : Reserved
*/
fsphy_type = ( ( USB_OTG_GLB - > GHWCFG2 & ( 0x03 < < 8 ) ) > > 8 ) ;
hsphy_type = ( ( USB_OTG_GLB - > GHWCFG2 & ( 0x03 < < 6 ) ) > > 6 ) ;
dma_support = ( ( USB_OTG_GLB - > GHWCFG2 & ( 0x03 < < 3 ) ) > > 3 ) ;
endpoints = ( ( USB_OTG_GLB - > GHWCFG2 & ( 0x0f < < 10 ) ) > > 10 ) + 1 ;
USB_LOG_INFO ( " ========== dwc2 udc params ========== \r \n " ) ;
2025-03-28 22:39:30 +08:00
USB_LOG_INFO ( " CID:%08x \r \n " , ( unsigned int ) USB_OTG_GLB - > CID ) ;
USB_LOG_INFO ( " GSNPSID:%08x \r \n " , ( unsigned int ) USB_OTG_GLB - > GSNPSID ) ;
USB_LOG_INFO ( " GHWCFG1:%08x \r \n " , ( unsigned int ) USB_OTG_GLB - > GHWCFG1 ) ;
USB_LOG_INFO ( " GHWCFG2:%08x \r \n " , ( unsigned int ) USB_OTG_GLB - > GHWCFG2 ) ;
USB_LOG_INFO ( " GHWCFG3:%08x \r \n " , ( unsigned int ) USB_OTG_GLB - > GHWCFG3 ) ;
USB_LOG_INFO ( " GHWCFG4:%08x \r \n " , ( unsigned int ) USB_OTG_GLB - > GHWCFG4 ) ;
2023-06-21 20:51:10 +08:00
USB_LOG_INFO ( " dwc2 fsphy type:%d, hsphy type:%d, dma support:%d \r \n " , fsphy_type , hsphy_type , dma_support ) ;
2024-03-21 23:07:07 +08:00
USB_LOG_INFO ( " dwc2 has %d endpoints and dfifo depth(32-bit words) is %d, default config: %d endpoints \r \n " , endpoints , ( USB_OTG_GLB - > GHWCFG3 > > 16 ) , CONFIG_USBDEV_EP_NUM ) ;
2023-06-21 20:51:10 +08:00
USB_LOG_INFO ( " ================================= \r \n " ) ;
2025-05-06 22:34:41 +08:00
USB_ASSERT_MSG ( endpoints > = CONFIG_USBDEV_EP_NUM , " dwc2 has less endpoints than config, please check " ) ;
2023-12-26 20:11:23 +08:00
2025-05-12 21:06:50 +08:00
g_dwc2_udc [ busid ] . GSNPSID = USB_OTG_GLB - > GSNPSID ;
2022-06-14 22:05:48 +08:00
USB_OTG_DEV - > DCTL | = USB_OTG_DCTL_SDIS ;
USB_OTG_GLB - > GAHBCFG & = ~ USB_OTG_GAHBCFG_GINT ;
2023-11-26 22:19:21 +08:00
/* This is vendor register */
2024-02-18 19:36:20 +08:00
USB_OTG_GLB - > GCCFG = usbd_get_dwc2_gccfg_conf ( USBD_BASE ) ;
2023-11-26 22:19:21 +08:00
2024-08-22 20:16:40 +08:00
ret = dwc2_core_init ( busid ) ;
2022-06-14 22:05:48 +08:00
/* Force Device Mode*/
2024-08-22 20:16:40 +08:00
dwc2_set_mode ( busid , USB_OTG_MODE_DEVICE ) ;
2023-11-26 22:19:21 +08:00
2022-06-14 22:05:48 +08:00
for ( uint8_t i = 0U ; i < 15U ; i + + ) {
USB_OTG_GLB - > DIEPTXF [ i ] = 0U ;
}
/* Restart the Phy Clock */
USB_OTG_PCGCCTL = 0U ;
2023-12-29 20:59:50 +08:00
/* Device speed configuration */
USB_OTG_DEV - > DCFG & = ~ USB_OTG_DCFG_DSPD ;
2022-06-14 22:05:48 +08:00
# if defined(CONFIG_USB_HS)
USB_OTG_DEV - > DCFG | = USB_OTG_SPEED_HIGH ;
2022-07-28 21:25:29 +08:00
# else
2023-12-29 20:59:50 +08:00
if ( hsphy_type = = 0 ) {
USB_OTG_DEV - > DCFG | = USB_OTG_SPEED_FULL ;
} else {
USB_OTG_DEV - > DCFG | = USB_OTG_SPEED_HIGH_IN_FULL ;
}
2022-06-14 22:05:48 +08:00
# endif
/* Clear all pending Device Interrupts */
USB_OTG_DEV - > DIEPMSK = 0U ;
USB_OTG_DEV - > DOEPMSK = 0U ;
USB_OTG_DEV - > DAINTMSK = 0U ;
/* Disable all interrupts. */
USB_OTG_GLB - > GINTMSK = 0U ;
/* Clear any pending interrupts */
USB_OTG_GLB - > GINTSTS = 0xBFFFFFFFU ;
/* Enable interrupts matching to the Device mode ONLY */
2022-10-05 17:14:11 +08:00
USB_OTG_GLB - > GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM |
2023-06-22 13:40:07 +08:00
USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT |
2024-09-26 21:22:36 +08:00
USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM ;
2023-06-22 13:40:07 +08:00
2022-07-28 21:25:29 +08:00
# ifdef CONFIG_USB_DWC2_DMA_ENABLE
2025-05-06 22:34:41 +08:00
USB_ASSERT_MSG ( ( ( USB_OTG_GLB - > GHWCFG2 & ( 0x3U < < 3 ) ) > > 3 ) = = 2 , " This dwc2 version does not support dma mode, so stop working " ) ;
2023-05-26 20:37:23 +08:00
2023-09-07 12:43:30 +08:00
USB_OTG_DEV - > DCFG & = ~ USB_OTG_DCFG_DESCDMA ;
2024-09-08 18:36:03 +08:00
USB_OTG_GLB - > GAHBCFG & = ~ USB_OTG_GAHBCFG_HBSTLEN ;
2024-03-20 21:53:22 +08:00
USB_OTG_GLB - > GAHBCFG | = ( USB_OTG_GAHBCFG_DMAEN | USB_OTG_GAHBCFG_HBSTLEN_4 ) ;
2022-07-28 21:25:29 +08:00
# else
USB_OTG_GLB - > GINTMSK | = USB_OTG_GINTMSK_RXFLVLM ;
# endif
2022-06-14 22:05:48 +08:00
# if CONFIG_DWC2_VBUS_SENSING
USB_OTG_GLB - > GINTMSK | = ( USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_SRQIM ) ;
# endif
2025-05-10 21:26:53 +08:00
# ifdef CONFIG_USBDEV_SOF_ENABLE
2022-06-14 22:05:48 +08:00
USB_OTG_GLB - > GINTMSK | = USB_OTG_GINTMSK_SOFM ;
# endif
2024-03-21 23:07:07 +08:00
USB_OTG_GLB - > GRXFSIZ = ( CONFIG_USB_DWC2_RXALL_FIFO_SIZE ) ;
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
dwc2_set_txfifo ( busid , 0 , CONFIG_USB_DWC2_TX0_FIFO_SIZE ) ;
dwc2_set_txfifo ( busid , 1 , CONFIG_USB_DWC2_TX1_FIFO_SIZE ) ;
dwc2_set_txfifo ( busid , 2 , CONFIG_USB_DWC2_TX2_FIFO_SIZE ) ;
dwc2_set_txfifo ( busid , 3 , CONFIG_USB_DWC2_TX3_FIFO_SIZE ) ;
2024-03-21 23:07:07 +08:00
fifo_num = CONFIG_USB_DWC2_RXALL_FIFO_SIZE ;
fifo_num + = CONFIG_USB_DWC2_TX0_FIFO_SIZE ;
fifo_num + = CONFIG_USB_DWC2_TX1_FIFO_SIZE ;
fifo_num + = CONFIG_USB_DWC2_TX2_FIFO_SIZE ;
fifo_num + = CONFIG_USB_DWC2_TX3_FIFO_SIZE ;
2023-12-21 20:23:54 +08:00
# if CONFIG_USBDEV_EP_NUM > 4
2024-08-22 20:16:40 +08:00
dwc2_set_txfifo ( busid , 4 , CONFIG_USB_DWC2_TX4_FIFO_SIZE ) ;
2024-03-21 23:07:07 +08:00
fifo_num + = CONFIG_USB_DWC2_TX4_FIFO_SIZE ;
2022-06-14 22:05:48 +08:00
# endif
2023-12-21 20:23:54 +08:00
# if CONFIG_USBDEV_EP_NUM > 5
2024-08-22 20:16:40 +08:00
dwc2_set_txfifo ( busid , 5 , CONFIG_USB_DWC2_TX5_FIFO_SIZE ) ;
2024-03-21 23:07:07 +08:00
fifo_num + = CONFIG_USB_DWC2_TX5_FIFO_SIZE ;
2023-09-07 12:43:30 +08:00
# endif
2023-12-21 20:23:54 +08:00
# if CONFIG_USBDEV_EP_NUM > 6
2024-08-22 20:16:40 +08:00
dwc2_set_txfifo ( busid , 6 , CONFIG_USB_DWC2_TX6_FIFO_SIZE ) ;
2024-03-21 23:07:07 +08:00
fifo_num + = CONFIG_USB_DWC2_TX6_FIFO_SIZE ;
2023-09-07 12:43:30 +08:00
# endif
2023-12-21 20:23:54 +08:00
# if CONFIG_USBDEV_EP_NUM > 7
2024-08-22 20:16:40 +08:00
dwc2_set_txfifo ( busid , 7 , CONFIG_USB_DWC2_TX7_FIFO_SIZE ) ;
2024-03-21 23:07:07 +08:00
fifo_num + = CONFIG_USB_DWC2_TX7_FIFO_SIZE ;
2023-09-07 12:43:30 +08:00
# endif
2023-12-21 20:23:54 +08:00
# if CONFIG_USBDEV_EP_NUM > 8
2024-08-22 20:16:40 +08:00
dwc2_set_txfifo ( busid , 8 , CONFIG_USB_DWC2_TX8_FIFO_SIZE ) ;
2024-03-21 23:07:07 +08:00
fifo_num + = CONFIG_USB_DWC2_TX8_FIFO_SIZE ;
2022-06-14 22:05:48 +08:00
# endif
2024-03-21 23:07:07 +08:00
2025-05-06 22:34:41 +08:00
USB_ASSERT_MSG ( fifo_num < = ( USB_OTG_GLB - > GHWCFG3 > > 16 ) , " Your fifo config is overflow, please check " ) ;
2024-05-15 23:07:46 +08:00
/* xxx32 chips do not follow (USB_OTG_GLB->GHWCFG3 >> 16) if hsphy_type is zero, they use 1.25KB(320 DWORD) */
2025-05-06 22:34:41 +08:00
USB_ASSERT_MSG ( ! ( ( hsphy_type = = 0 ) & & ( fifo_num > 320 ) ) , " Your fifo config is larger than 320 , please check " ) ;
2024-05-15 23:07:46 +08:00
2024-08-22 20:16:40 +08:00
ret = dwc2_flush_txfifo ( busid , 0x10U ) ;
ret = dwc2_flush_rxfifo ( busid ) ;
2024-03-20 21:53:22 +08:00
2022-06-14 22:05:48 +08:00
USB_OTG_GLB - > GAHBCFG | = USB_OTG_GAHBCFG_GINT ;
USB_OTG_DEV - > DCTL & = ~ USB_OTG_DCTL_SDIS ;
return ret ;
}
2024-02-06 19:51:50 +08:00
int usb_dc_deinit ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
2024-03-20 21:53:22 +08:00
USB_OTG_GLB - > GAHBCFG | = USB_OTG_GAHBCFG_GINT ;
USB_OTG_DEV - > DCTL | = USB_OTG_DCTL_SDIS ;
2022-06-14 22:05:48 +08:00
/* Clear Pending interrupt */
for ( uint8_t i = 0U ; i < 15U ; i + + ) {
USB_OTG_INEP ( i ) - > DIEPINT = 0xFB7FU ;
USB_OTG_OUTEP ( i ) - > DOEPINT = 0xFB7FU ;
}
/* Clear interrupt masks */
USB_OTG_DEV - > DIEPMSK = 0U ;
USB_OTG_DEV - > DOEPMSK = 0U ;
USB_OTG_DEV - > DAINTMSK = 0U ;
/* Flush the FIFO */
2024-08-22 20:16:40 +08:00
dwc2_flush_txfifo ( busid , 0x10U ) ;
dwc2_flush_rxfifo ( busid ) ;
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
usb_dc_low_level_deinit ( busid ) ;
2022-06-14 22:05:48 +08:00
return 0 ;
}
2024-02-06 19:51:50 +08:00
int usbd_set_address ( uint8_t busid , const uint8_t addr )
2022-06-14 22:05:48 +08:00
{
USB_OTG_DEV - > DCFG & = ~ ( USB_OTG_DCFG_DAD ) ;
USB_OTG_DEV - > DCFG | = ( ( uint32_t ) addr < < 4 ) & USB_OTG_DCFG_DAD ;
return 0 ;
}
2024-07-26 22:01:12 +08:00
int usbd_set_remote_wakeup ( uint8_t busid )
{
if ( ! ( USB_OTG_DEV - > DSTS & USB_OTG_DSTS_SUSPSTS ) ) {
return - 1 ;
}
USB_OTG_DEV - > DCTL | = USB_OTG_DCTL_RWUSIG ;
usbd_dwc2_delay_ms ( 10 ) ;
USB_OTG_DEV - > DCTL & = ~ USB_OTG_DCTL_RWUSIG ;
return 0 ;
}
2024-04-29 11:35:29 +08:00
uint8_t usbd_get_port_speed ( uint8_t busid )
2022-11-18 22:26:09 +08:00
{
uint8_t speed ;
uint32_t DevEnumSpeed = USB_OTG_DEV - > DSTS & USB_OTG_DSTS_ENUMSPD ;
if ( DevEnumSpeed = = DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ ) {
speed = USB_SPEED_HIGH ;
} else if ( ( DevEnumSpeed = = DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ ) | |
( DevEnumSpeed = = DSTS_ENUMSPD_FS_PHY_48MHZ ) ) {
speed = USB_SPEED_FULL ;
} else {
speed = USB_SPEED_FULL ;
}
return speed ;
}
2024-02-06 19:51:50 +08:00
int usbd_ep_open ( uint8_t busid , const struct usb_endpoint_descriptor * ep )
2022-06-14 22:05:48 +08:00
{
2023-12-10 22:32:39 +08:00
uint8_t ep_idx = USB_EP_GET_IDX ( ep - > bEndpointAddress ) ;
2022-06-14 22:05:48 +08:00
2025-05-09 21:44:51 +08:00
USB_ASSERT_MSG ( ep_idx < CONFIG_USBDEV_EP_NUM , " Ep addr %02x overflow " , ep - > bEndpointAddress ) ;
2022-06-14 22:05:48 +08:00
2023-12-10 22:32:39 +08:00
if ( USB_EP_DIR_IS_OUT ( ep - > bEndpointAddress ) ) {
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_mps = USB_GET_MAXPACKETSIZE ( ep - > wMaxPacketSize ) ;
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_type = USB_GET_ENDPOINT_TYPE ( ep - > bmAttributes ) ;
2022-06-14 22:05:48 +08:00
USB_OTG_DEV - > DAINTMSK | = USB_OTG_DAINTMSK_OEPM & ( uint32_t ) ( 1UL < < ( 16 + ep_idx ) ) ;
2023-06-22 13:40:07 +08:00
if ( ( USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & USB_OTG_DOEPCTL_USBAEP ) = = 0 ) {
2023-12-10 22:32:39 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = ( USB_GET_MAXPACKETSIZE ( ep - > wMaxPacketSize ) & USB_OTG_DOEPCTL_MPSIZ ) |
( ( uint32_t ) USB_GET_ENDPOINT_TYPE ( ep - > bmAttributes ) < < 18 ) |
2023-06-22 13:40:07 +08:00
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
USB_OTG_DOEPCTL_USBAEP ;
2022-06-14 22:05:48 +08:00
}
} else {
2024-04-03 15:44:43 +08:00
uint16_t fifo_size ;
if ( ep_idx = = 0 ) {
fifo_size = ( USB_OTG_GLB - > DIEPTXF0_HNPTXFSIZ > > 16 ) ;
} else {
fifo_size = ( USB_OTG_GLB - > DIEPTXF [ ep_idx - 1U ] > > 16 ) ;
}
2025-05-09 21:44:51 +08:00
USB_ASSERT_MSG ( ( fifo_size * 4 ) > = USB_GET_MAXPACKETSIZE ( ep - > wMaxPacketSize ) , " Ep addr %02x fifo overflow " , ep - > bEndpointAddress ) ;
2024-04-29 11:35:29 +08:00
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps = USB_GET_MAXPACKETSIZE ( ep - > wMaxPacketSize ) ;
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_type = USB_GET_ENDPOINT_TYPE ( ep - > bmAttributes ) ;
2022-06-14 22:05:48 +08:00
USB_OTG_DEV - > DAINTMSK | = USB_OTG_DAINTMSK_IEPM & ( uint32_t ) ( 1UL < < ep_idx ) ;
2023-06-22 13:40:07 +08:00
if ( ( USB_OTG_INEP ( ep_idx ) - > DIEPCTL & USB_OTG_DIEPCTL_USBAEP ) = = 0 ) {
2023-12-10 22:32:39 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = ( USB_GET_MAXPACKETSIZE ( ep - > wMaxPacketSize ) & USB_OTG_DIEPCTL_MPSIZ ) |
( ( uint32_t ) USB_GET_ENDPOINT_TYPE ( ep - > bmAttributes ) < < 18 ) | ( ep_idx < < 22 ) |
2023-06-22 13:40:07 +08:00
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
USB_OTG_DIEPCTL_USBAEP ;
}
2024-08-22 20:16:40 +08:00
dwc2_flush_txfifo ( busid , ep_idx ) ;
2022-06-14 22:05:48 +08:00
}
return 0 ;
}
2024-02-06 19:51:50 +08:00
int usbd_ep_close ( uint8_t busid , const uint8_t ep )
2022-06-14 22:05:48 +08:00
{
2022-10-05 17:14:11 +08:00
uint8_t ep_idx = USB_EP_GET_IDX ( ep ) ;
2023-06-22 13:40:07 +08:00
volatile uint32_t count = 0U ;
2022-10-05 17:14:11 +08:00
if ( USB_EP_DIR_IS_OUT ( ep ) ) {
2023-06-22 13:40:07 +08:00
if ( USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & USB_OTG_DOEPCTL_EPENA ) {
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = USB_OTG_DOEPCTL_SNAK ;
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = USB_OTG_DOEPCTL_EPDIS ;
/* Wait for endpoint disabled interrupt */
count = 0 ;
do {
if ( + + count > 50000 ) {
break ;
}
} while ( ( USB_OTG_OUTEP ( ep_idx ) - > DOEPINT & USB_OTG_DOEPINT_EPDISD ) ! = USB_OTG_DOEPINT_EPDISD ) ;
/* Clear and unmask endpoint disabled interrupt */
2024-11-21 20:57:24 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPINT = USB_OTG_DOEPINT_EPDISD ;
2023-06-22 13:40:07 +08:00
}
2022-10-05 17:14:11 +08:00
USB_OTG_DEV - > DEACHMSK & = ~ ( USB_OTG_DAINTMSK_OEPM & ( ( uint32_t ) ( 1UL < < ( ep_idx & 0x07 ) ) < < 16 ) ) ;
USB_OTG_DEV - > DAINTMSK & = ~ ( USB_OTG_DAINTMSK_OEPM & ( ( uint32_t ) ( 1UL < < ( ep_idx & 0x07 ) ) < < 16 ) ) ;
2023-06-30 22:18:33 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL = 0 ;
2022-10-05 17:14:11 +08:00
} else {
2023-06-22 13:40:07 +08:00
if ( USB_OTG_INEP ( ep_idx ) - > DIEPCTL & USB_OTG_DIEPCTL_EPENA ) {
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_SNAK ;
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_EPDIS ;
/* Wait for endpoint disabled interrupt */
count = 0 ;
do {
if ( + + count > 50000 ) {
break ;
}
} while ( ( USB_OTG_INEP ( ep_idx ) - > DIEPINT & USB_OTG_DIEPINT_EPDISD ) ! = USB_OTG_DIEPINT_EPDISD ) ;
/* Clear and unmask endpoint disabled interrupt */
2024-11-21 20:57:24 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPINT = USB_OTG_DIEPINT_EPDISD ;
2023-06-22 13:40:07 +08:00
}
2023-09-07 12:43:30 +08:00
2022-10-05 17:14:11 +08:00
USB_OTG_DEV - > DEACHMSK & = ~ ( USB_OTG_DAINTMSK_IEPM & ( uint32_t ) ( 1UL < < ( ep_idx & 0x07 ) ) ) ;
USB_OTG_DEV - > DAINTMSK & = ~ ( USB_OTG_DAINTMSK_IEPM & ( uint32_t ) ( 1UL < < ( ep_idx & 0x07 ) ) ) ;
2023-06-30 22:18:33 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL = 0 ;
2022-10-05 17:14:11 +08:00
}
2022-06-14 22:05:48 +08:00
return 0 ;
}
2024-02-06 19:51:50 +08:00
int usbd_ep_set_stall ( uint8_t busid , const uint8_t ep )
2022-06-14 22:05:48 +08:00
{
uint8_t ep_idx = USB_EP_GET_IDX ( ep ) ;
if ( USB_EP_DIR_IS_OUT ( ep ) ) {
if ( ( ( USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & USB_OTG_DOEPCTL_EPENA ) = = 0U ) & & ( ep_idx ! = 0U ) ) {
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & = ~ ( USB_OTG_DOEPCTL_EPDIS ) ;
}
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = USB_OTG_DOEPCTL_STALL ;
} else {
if ( ( ( USB_OTG_INEP ( ep_idx ) - > DIEPCTL & USB_OTG_DIEPCTL_EPENA ) = = 0U ) & & ( ep_idx ! = 0U ) ) {
USB_OTG_INEP ( ep_idx ) - > DIEPCTL & = ~ ( USB_OTG_DIEPCTL_EPDIS ) ;
}
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_STALL ;
}
2022-07-28 21:25:29 +08:00
# ifdef CONFIG_USB_DWC2_DMA_ENABLE
if ( ep_idx = = 0 ) {
2024-08-22 20:16:40 +08:00
dwc2_ep0_start_read_setup ( busid , ( uint8_t * ) & g_dwc2_udc [ busid ] . setup ) ;
2022-07-28 21:25:29 +08:00
}
# endif
2022-06-14 22:05:48 +08:00
return 0 ;
}
2024-02-06 19:51:50 +08:00
int usbd_ep_clear_stall ( uint8_t busid , const uint8_t ep )
2022-06-14 22:05:48 +08:00
{
uint8_t ep_idx = USB_EP_GET_IDX ( ep ) ;
if ( USB_EP_DIR_IS_OUT ( ep ) ) {
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & = ~ USB_OTG_DOEPCTL_STALL ;
2024-08-22 20:16:40 +08:00
if ( ( g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_type = = USB_ENDPOINT_TYPE_INTERRUPT ) | |
( g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_type = = USB_ENDPOINT_TYPE_BULK ) ) {
2022-06-14 22:05:48 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = USB_OTG_DOEPCTL_SD0PID_SEVNFRM ; /* DATA0 */
}
} else {
USB_OTG_INEP ( ep_idx ) - > DIEPCTL & = ~ USB_OTG_DIEPCTL_STALL ;
2024-08-22 20:16:40 +08:00
if ( ( g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_type = = USB_ENDPOINT_TYPE_INTERRUPT ) | |
( g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_type = = USB_ENDPOINT_TYPE_BULK ) ) {
2022-06-14 22:05:48 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_SD0PID_SEVNFRM ; /* DATA0 */
}
}
return 0 ;
}
2024-02-06 19:51:50 +08:00
int usbd_ep_is_stalled ( uint8_t busid , const uint8_t ep , uint8_t * stalled )
2022-06-14 22:05:48 +08:00
{
2024-07-08 21:50:00 +08:00
uint8_t ep_idx = USB_EP_GET_IDX ( ep ) ;
2022-06-14 22:05:48 +08:00
if ( USB_EP_DIR_IS_OUT ( ep ) ) {
2024-09-26 21:22:36 +08:00
if ( USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & USB_OTG_DOEPCTL_STALL ) {
2024-07-08 21:50:00 +08:00
* stalled = 1 ;
} else {
* stalled = 0 ;
}
2022-06-14 22:05:48 +08:00
} else {
2024-09-26 21:22:36 +08:00
if ( USB_OTG_INEP ( ep_idx ) - > DIEPCTL & USB_OTG_DIEPCTL_STALL ) {
2024-07-08 21:50:00 +08:00
* stalled = 1 ;
} else {
* stalled = 0 ;
}
2022-06-14 22:05:48 +08:00
}
return 0 ;
}
2024-02-06 19:51:50 +08:00
int usbd_ep_start_write ( uint8_t busid , const uint8_t ep , const uint8_t * data , uint32_t data_len )
2022-06-14 22:05:48 +08:00
{
uint8_t ep_idx = USB_EP_GET_IDX ( ep ) ;
2022-07-28 21:25:29 +08:00
uint32_t pktcnt = 0 ;
2022-06-14 22:05:48 +08:00
2025-05-06 22:34:41 +08:00
USB_ASSERT_MSG ( ! ( ( uint32_t ) data % 0x04 ) , " dwc2 data must be 4-byte aligned " ) ;
2022-06-14 22:05:48 +08:00
if ( ! data & & data_len ) {
return - 1 ;
}
2025-05-06 22:34:41 +08:00
2023-06-30 22:18:33 +08:00
if ( ep_idx & & ! ( USB_OTG_INEP ( ep_idx ) - > DIEPCTL & USB_OTG_DIEPCTL_MPSIZ ) ) {
2025-05-09 21:44:51 +08:00
return - 2 ;
2022-07-28 21:25:29 +08:00
}
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_buf = ( uint8_t * ) data ;
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len = data_len ;
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len = 0 ;
2022-06-14 22:05:48 +08:00
2022-07-28 21:25:29 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ & = ~ ( USB_OTG_DIEPTSIZ_PKTCNT ) ;
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ & = ~ ( USB_OTG_DIEPTSIZ_XFRSIZ ) ;
2022-06-14 22:05:48 +08:00
2022-07-28 21:25:29 +08:00
if ( data_len = = 0 ) {
2022-06-14 22:05:48 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ | = ( USB_OTG_DIEPTSIZ_PKTCNT & ( 1U < < 19 ) ) ;
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = ( USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA ) ;
return 0 ;
}
2022-07-28 21:25:29 +08:00
if ( ep_idx = = 0 ) {
2024-08-22 20:16:40 +08:00
if ( data_len > g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps ) {
data_len = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps ;
2022-06-14 22:05:48 +08:00
}
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len = data_len ;
2022-07-28 21:25:29 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ | = ( USB_OTG_DIEPTSIZ_PKTCNT & ( 1U < < 19 ) ) ;
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ | = ( USB_OTG_DIEPTSIZ_XFRSIZ & data_len ) ;
} else {
2024-08-22 20:16:40 +08:00
pktcnt = ( uint16_t ) ( ( data_len + g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps - 1U ) / g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_mps ) ;
2022-06-14 22:05:48 +08:00
2022-07-28 21:25:29 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ | = ( USB_OTG_DIEPTSIZ_PKTCNT & ( pktcnt < < 19 ) ) ;
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ | = ( USB_OTG_DIEPTSIZ_XFRSIZ & data_len ) ;
2022-06-14 22:05:48 +08:00
}
2024-08-22 20:16:40 +08:00
if ( g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . ep_type = = USB_ENDPOINT_TYPE_ISOCHRONOUS ) {
2022-08-21 13:03:26 +08:00
if ( ( USB_OTG_DEV - > DSTS & ( 1U < < 8 ) ) = = 0U ) {
2023-06-22 13:40:07 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL & = ~ USB_OTG_DIEPCTL_SD0PID_SEVNFRM ;
2022-08-21 13:03:26 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_SODDFRM ;
} else {
2023-06-22 13:40:07 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL & = ~ USB_OTG_DIEPCTL_SODDFRM ;
2022-08-21 13:03:26 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = USB_OTG_DIEPCTL_SD0PID_SEVNFRM ;
}
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ & = ~ ( USB_OTG_DIEPTSIZ_MULCNT ) ;
USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ | = ( USB_OTG_DIEPTSIZ_MULCNT & ( 1U < < 29 ) ) ;
}
2022-12-22 22:30:14 +08:00
# ifdef CONFIG_USB_DWC2_DMA_ENABLE
USB_OTG_INEP ( ep_idx ) - > DIEPDMA = ( uint32_t ) data ;
2022-07-28 21:25:29 +08:00
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = ( USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA ) ;
# else
USB_OTG_INEP ( ep_idx ) - > DIEPCTL | = ( USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA ) ;
/* Enable the Tx FIFO Empty Interrupt for this EP */
if ( data_len > 0U ) {
USB_OTG_DEV - > DIEPEMPMSK | = 1UL < < ( ep_idx & 0x0f ) ;
2022-06-14 22:05:48 +08:00
}
2022-07-28 21:25:29 +08:00
# endif
2022-06-14 22:05:48 +08:00
return 0 ;
}
2024-02-06 19:51:50 +08:00
int usbd_ep_start_read ( uint8_t busid , const uint8_t ep , uint8_t * data , uint32_t data_len )
2022-06-14 22:05:48 +08:00
{
uint8_t ep_idx = USB_EP_GET_IDX ( ep ) ;
2022-07-28 21:25:29 +08:00
uint32_t pktcnt = 0 ;
2022-06-14 22:05:48 +08:00
2025-05-06 22:34:41 +08:00
USB_ASSERT_MSG ( ! ( ( uint32_t ) data % 0x04 ) , " dwc2 data must be 4-byte aligned " ) ;
2022-07-28 21:25:29 +08:00
if ( ! data & & data_len ) {
2022-06-14 22:05:48 +08:00
return - 1 ;
}
2025-05-06 22:34:41 +08:00
2023-06-30 22:18:33 +08:00
if ( ep_idx & & ! ( USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & USB_OTG_DOEPCTL_MPSIZ ) ) {
2025-05-09 21:44:51 +08:00
return - 2 ;
2022-08-20 20:28:11 +08:00
}
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_buf = ( uint8_t * ) data ;
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_len = data_len ;
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . actual_xfer_len = 0 ;
2022-06-14 22:05:48 +08:00
2022-07-28 21:25:29 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ & = ~ ( USB_OTG_DOEPTSIZ_PKTCNT ) ;
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ & = ~ ( USB_OTG_DOEPTSIZ_XFRSIZ ) ;
if ( data_len = = 0 ) {
2022-08-18 21:49:36 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ | = ( USB_OTG_DOEPTSIZ_PKTCNT & ( 1 < < 19 ) ) ;
2024-08-22 20:16:40 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ | = ( USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_mps ) ;
2022-07-28 21:25:29 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = ( USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA ) ;
return 0 ;
}
2022-06-14 22:05:48 +08:00
2022-07-28 21:25:29 +08:00
if ( ep_idx = = 0 ) {
2024-08-22 20:16:40 +08:00
if ( data_len > g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_mps ) {
data_len = g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_mps ;
2022-07-28 21:25:29 +08:00
}
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_len = data_len ;
2022-07-28 21:25:29 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ | = ( USB_OTG_DOEPTSIZ_PKTCNT & ( 1U < < 19 ) ) ;
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ | = ( USB_OTG_DOEPTSIZ_XFRSIZ & data_len ) ;
} else {
2024-08-22 20:16:40 +08:00
pktcnt = ( uint16_t ) ( ( data_len + g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_mps - 1U ) / g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_mps ) ;
2022-06-14 22:05:48 +08:00
2022-07-28 21:25:29 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ | = ( USB_OTG_DOEPTSIZ_PKTCNT & ( pktcnt < < 19 ) ) ;
USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ | = ( USB_OTG_DOEPTSIZ_XFRSIZ & data_len ) ;
2022-06-14 22:05:48 +08:00
}
2022-07-28 21:25:29 +08:00
# ifdef CONFIG_USB_DWC2_DMA_ENABLE
USB_OTG_OUTEP ( ep_idx ) - > DOEPDMA = ( uint32_t ) data ;
2022-12-22 22:30:14 +08:00
# endif
2024-08-22 20:16:40 +08:00
if ( g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . ep_type = = USB_ENDPOINT_TYPE_ISOCHRONOUS ) {
2022-08-21 13:03:26 +08:00
if ( ( USB_OTG_DEV - > DSTS & ( 1U < < 8 ) ) = = 0U ) {
2023-06-22 13:40:07 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & = ~ USB_OTG_DOEPCTL_SD0PID_SEVNFRM ;
2023-04-23 22:50:23 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = USB_OTG_DOEPCTL_SODDFRM ;
2022-08-21 13:03:26 +08:00
} else {
2023-06-22 13:40:07 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL & = ~ USB_OTG_DOEPCTL_SODDFRM ;
2023-04-23 22:50:23 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = USB_OTG_DOEPCTL_SD0PID_SEVNFRM ;
2022-08-21 13:03:26 +08:00
}
}
2022-07-28 21:25:29 +08:00
USB_OTG_OUTEP ( ep_idx ) - > DOEPCTL | = ( USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA ) ;
2022-06-14 22:05:48 +08:00
return 0 ;
}
2024-02-18 19:36:20 +08:00
void USBD_IRQHandler ( uint8_t busid )
2022-06-14 22:05:48 +08:00
{
2025-04-30 21:37:50 +08:00
uint32_t gint_status , temp , ep_idx , ep_intr , epint , read_count ;
2024-08-22 20:16:40 +08:00
gint_status = dwc2_get_glb_intstatus ( busid ) ;
2022-06-14 22:05:48 +08:00
if ( ( USB_OTG_GLB - > GINTSTS & 0x1U ) = = USB_OTG_MODE_DEVICE ) {
/* Avoid spurious interrupt */
if ( gint_status = = 0 ) {
return ;
}
2022-07-28 21:25:29 +08:00
# ifndef CONFIG_USB_DWC2_DMA_ENABLE
2022-06-14 22:05:48 +08:00
/* Handle RxQLevel Interrupt */
if ( gint_status & USB_OTG_GINTSTS_RXFLVL ) {
USB_MASK_INTERRUPT ( USB_OTG_GLB , USB_OTG_GINTSTS_RXFLVL ) ;
temp = USB_OTG_GLB - > GRXSTSP ;
2022-07-28 21:25:29 +08:00
ep_idx = temp & USB_OTG_GRXSTSP_EPNUM ;
2022-06-14 22:05:48 +08:00
if ( ( ( temp & USB_OTG_GRXSTSP_PKTSTS ) > > USB_OTG_GRXSTSP_PKTSTS_Pos ) = = STS_DATA_UPDT ) {
2022-07-28 21:25:29 +08:00
read_count = ( temp & USB_OTG_GRXSTSP_BCNT ) > > 4 ;
if ( read_count ! = 0 ) {
2024-08-22 20:16:40 +08:00
dwc2_ep_read ( busid , g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_buf , read_count ) ;
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_buf + = read_count ;
2022-06-14 22:05:48 +08:00
}
} else if ( ( ( temp & USB_OTG_GRXSTSP_PKTSTS ) > > USB_OTG_GRXSTSP_PKTSTS_Pos ) = = STS_SETUP_UPDT ) {
2022-07-28 21:25:29 +08:00
read_count = ( temp & USB_OTG_GRXSTSP_BCNT ) > > 4 ;
2024-08-22 20:16:40 +08:00
dwc2_ep_read ( busid , ( uint8_t * ) & g_dwc2_udc [ busid ] . setup , read_count ) ;
2022-06-14 22:05:48 +08:00
} else {
/* ... */
}
USB_UNMASK_INTERRUPT ( USB_OTG_GLB , USB_OTG_GINTSTS_RXFLVL ) ;
}
2022-07-28 21:25:29 +08:00
# endif
2022-06-14 22:05:48 +08:00
if ( gint_status & USB_OTG_GINTSTS_OEPINT ) {
2022-07-28 21:25:29 +08:00
ep_idx = 0 ;
2024-08-22 20:16:40 +08:00
ep_intr = dwc2_get_outeps_intstatus ( busid ) ;
2022-06-14 22:05:48 +08:00
while ( ep_intr ! = 0U ) {
if ( ( ep_intr & 0x1U ) ! = 0U ) {
2024-08-22 20:16:40 +08:00
epint = dwc2_get_outep_intstatus ( busid , ep_idx ) ;
2022-06-14 22:05:48 +08:00
if ( ( epint & USB_OTG_DOEPINT_XFRC ) = = USB_OTG_DOEPINT_XFRC ) {
2022-07-28 21:25:29 +08:00
if ( ep_idx = = 0 ) {
2024-08-22 20:16:40 +08:00
if ( g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_len = = 0 ) {
2022-07-28 21:25:29 +08:00
/* Out status, start reading setup */
2024-08-22 20:16:40 +08:00
dwc2_ep0_start_read_setup ( busid , ( uint8_t * ) & g_dwc2_udc [ busid ] . setup ) ;
2022-07-28 21:25:29 +08:00
} else {
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . actual_xfer_len = g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_len - ( ( USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ ) & USB_OTG_DOEPTSIZ_XFRSIZ ) ;
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_len = 0 ;
usbd_event_ep_out_complete_handler ( busid , 0x00 , g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . actual_xfer_len ) ;
2022-07-28 21:25:29 +08:00
}
} else {
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . actual_xfer_len = g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_len - ( ( USB_OTG_OUTEP ( ep_idx ) - > DOEPTSIZ ) & USB_OTG_DOEPTSIZ_XFRSIZ ) ;
g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . xfer_len = 0 ;
usbd_event_ep_out_complete_handler ( busid , ep_idx , g_dwc2_udc [ busid ] . out_ep [ ep_idx ] . actual_xfer_len ) ;
2022-06-14 22:05:48 +08:00
}
}
2022-07-28 21:25:29 +08:00
if ( ( epint & USB_OTG_DOEPINT_STUP ) = = USB_OTG_DOEPINT_STUP ) {
2024-08-22 20:16:40 +08:00
usbd_event_ep0_setup_complete_handler ( busid , ( uint8_t * ) & g_dwc2_udc [ busid ] . setup ) ;
2022-07-28 21:25:29 +08:00
}
2022-06-14 22:05:48 +08:00
}
ep_intr > > = 1U ;
2022-07-28 21:25:29 +08:00
ep_idx + + ;
2022-06-14 22:05:48 +08:00
}
}
if ( gint_status & USB_OTG_GINTSTS_IEPINT ) {
2022-07-28 21:25:29 +08:00
ep_idx = 0U ;
2024-08-22 20:16:40 +08:00
ep_intr = dwc2_get_ineps_intstatus ( busid ) ;
2022-06-14 22:05:48 +08:00
while ( ep_intr ! = 0U ) {
if ( ( ep_intr & 0x1U ) ! = 0U ) {
2024-08-22 20:16:40 +08:00
epint = dwc2_get_inep_intstatus ( busid , ep_idx ) ;
2022-06-14 22:05:48 +08:00
if ( ( epint & USB_OTG_DIEPINT_XFRC ) = = USB_OTG_DIEPINT_XFRC ) {
2022-07-28 21:25:29 +08:00
if ( ep_idx = = 0 ) {
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len - ( ( USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ ) & USB_OTG_DIEPTSIZ_XFRSIZ ) ;
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len = 0 ;
usbd_event_ep_in_complete_handler ( busid , 0x80 , g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len ) ;
2022-07-28 21:25:29 +08:00
2024-08-22 20:16:40 +08:00
if ( g_dwc2_udc [ busid ] . setup . wLength & & ( ( g_dwc2_udc [ busid ] . setup . bmRequestType & USB_REQUEST_DIR_MASK ) = = USB_REQUEST_DIR_OUT ) ) {
2022-07-28 21:25:29 +08:00
/* In status, start reading setup */
2024-08-22 20:16:40 +08:00
dwc2_ep0_start_read_setup ( busid , ( uint8_t * ) & g_dwc2_udc [ busid ] . setup ) ;
} else if ( g_dwc2_udc [ busid ] . setup . wLength = = 0 ) {
2022-07-28 21:25:29 +08:00
/* In status, start reading setup */
2024-08-22 20:16:40 +08:00
dwc2_ep0_start_read_setup ( busid , ( uint8_t * ) & g_dwc2_udc [ busid ] . setup ) ;
2022-07-28 21:25:29 +08:00
}
2022-06-14 22:05:48 +08:00
} else {
2024-08-22 20:16:40 +08:00
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len = g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len - ( ( USB_OTG_INEP ( ep_idx ) - > DIEPTSIZ ) & USB_OTG_DIEPTSIZ_XFRSIZ ) ;
g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . xfer_len = 0 ;
usbd_event_ep_in_complete_handler ( busid , ep_idx | 0x80 , g_dwc2_udc [ busid ] . in_ep [ ep_idx ] . actual_xfer_len ) ;
2022-06-14 22:05:48 +08:00
}
}
2022-07-28 21:25:29 +08:00
if ( ( epint & USB_OTG_DIEPINT_TXFE ) = = USB_OTG_DIEPINT_TXFE ) {
2024-08-22 20:16:40 +08:00
dwc2_tx_fifo_empty_procecss ( busid , ep_idx ) ;
2022-07-28 21:25:29 +08:00
}
2022-06-14 22:05:48 +08:00
}
ep_intr > > = 1U ;
2022-07-28 21:25:29 +08:00
ep_idx + + ;
2022-06-14 22:05:48 +08:00
}
}
if ( gint_status & USB_OTG_GINTSTS_USBRST ) {
2024-08-27 14:16:03 +08:00
USB_OTG_GLB - > GINTSTS = USB_OTG_GINTSTS_USBRST ;
2022-06-14 22:05:48 +08:00
USB_OTG_DEV - > DCTL & = ~ USB_OTG_DCTL_RWUSIG ;
2024-08-22 20:16:40 +08:00
dwc2_flush_txfifo ( busid , 0x10U ) ;
dwc2_flush_rxfifo ( busid ) ;
2022-07-28 21:25:29 +08:00
2023-12-21 20:23:54 +08:00
for ( uint8_t i = 0U ; i < CONFIG_USBDEV_EP_NUM ; i + + ) {
2022-10-25 22:26:55 +08:00
if ( i = = 0U ) {
USB_OTG_INEP ( i ) - > DIEPCTL = USB_OTG_DIEPCTL_SNAK ;
USB_OTG_OUTEP ( i ) - > DOEPCTL = USB_OTG_DOEPCTL_SNAK ;
} else {
2023-06-22 13:40:07 +08:00
if ( USB_OTG_INEP ( i ) - > DIEPCTL & USB_OTG_DIEPCTL_EPENA ) {
USB_OTG_INEP ( i ) - > DIEPCTL = ( USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK ) ;
} else {
USB_OTG_INEP ( i ) - > DIEPCTL = 0 ;
}
if ( USB_OTG_OUTEP ( i ) - > DOEPCTL & USB_OTG_DOEPCTL_EPENA ) {
USB_OTG_OUTEP ( i ) - > DOEPCTL = ( USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK ) ;
} else {
USB_OTG_OUTEP ( i ) - > DOEPCTL = 0 ;
}
2022-10-25 22:26:55 +08:00
}
USB_OTG_INEP ( i ) - > DIEPTSIZ = 0U ;
2023-06-22 13:40:07 +08:00
USB_OTG_INEP ( i ) - > DIEPINT = 0xFBFFU ;
2022-10-25 22:26:55 +08:00
USB_OTG_OUTEP ( i ) - > DOEPTSIZ = 0U ;
2023-06-22 13:40:07 +08:00
USB_OTG_OUTEP ( i ) - > DOEPINT = 0xFBFFU ;
2022-06-14 22:05:48 +08:00
}
2022-10-25 22:26:55 +08:00
2022-06-14 22:05:48 +08:00
USB_OTG_DEV - > DAINTMSK | = 0x10001U ;
2022-07-28 21:25:29 +08:00
USB_OTG_DEV - > DOEPMSK = USB_OTG_DOEPMSK_STUPM |
USB_OTG_DOEPMSK_XFRCM ;
USB_OTG_DEV - > DIEPMSK = USB_OTG_DIEPMSK_XFRCM ;
2022-06-14 22:05:48 +08:00
2024-08-22 20:16:40 +08:00
memset ( & g_dwc2_udc [ busid ] , 0 , sizeof ( struct dwc2_udc ) ) ;
usbd_event_reset_handler ( busid ) ;
2022-07-28 21:25:29 +08:00
/* Start reading setup */
2024-08-22 20:16:40 +08:00
dwc2_ep0_start_read_setup ( busid , ( uint8_t * ) & g_dwc2_udc [ busid ] . setup ) ;
2022-06-14 22:05:48 +08:00
}
if ( gint_status & USB_OTG_GINTSTS_ENUMDNE ) {
2024-11-21 20:57:24 +08:00
USB_OTG_GLB - > GINTSTS = USB_OTG_GINTSTS_ENUMDNE ;
2024-08-22 20:16:40 +08:00
dwc2_set_turnaroundtime ( busid , SystemCoreClock , dwc2_get_devspeed ( busid ) ) ;
2022-07-28 21:25:29 +08:00
2022-06-14 22:05:48 +08:00
USB_OTG_DEV - > DCTL | = USB_OTG_DCTL_CGINAK ;
}
2023-06-22 13:40:07 +08:00
if ( gint_status & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT ) {
2024-11-21 20:57:24 +08:00
USB_OTG_GLB - > GINTSTS = USB_OTG_GINTSTS_PXFR_INCOMPISOOUT ;
2023-06-22 13:40:07 +08:00
}
if ( gint_status & USB_OTG_GINTSTS_IISOIXFR ) {
2024-11-21 20:57:24 +08:00
USB_OTG_GLB - > GINTSTS = USB_OTG_GINTSTS_IISOIXFR ;
2023-06-22 13:40:07 +08:00
}
2025-05-10 21:26:53 +08:00
# ifdef CONFIG_USBDEV_SOF_ENABLE
2022-06-14 22:05:48 +08:00
if ( gint_status & USB_OTG_GINTSTS_SOF ) {
2024-08-27 14:16:03 +08:00
USB_OTG_GLB - > GINTSTS = USB_OTG_GINTSTS_SOF ;
2025-05-10 21:26:53 +08:00
usbd_event_sof_handler ( busid ) ;
2022-06-14 22:05:48 +08:00
}
2025-05-10 21:26:53 +08:00
# endif
2022-06-14 22:05:48 +08:00
if ( gint_status & USB_OTG_GINTSTS_USBSUSP ) {
2024-08-27 14:16:03 +08:00
USB_OTG_GLB - > GINTSTS = USB_OTG_GINTSTS_USBSUSP ;
2024-08-22 20:16:40 +08:00
usbd_event_suspend_handler ( busid ) ;
2022-06-14 22:05:48 +08:00
}
2022-10-05 17:14:11 +08:00
if ( gint_status & USB_OTG_GINTSTS_WKUINT ) {
2024-08-27 14:16:03 +08:00
USB_OTG_GLB - > GINTSTS = USB_OTG_GINTSTS_WKUINT ;
2024-08-22 20:16:40 +08:00
usbd_event_resume_handler ( busid ) ;
2022-10-05 17:14:11 +08:00
}
2022-06-14 22:05:48 +08:00
if ( gint_status & USB_OTG_GINTSTS_OTGINT ) {
temp = USB_OTG_GLB - > GOTGINT ;
if ( ( temp & USB_OTG_GOTGINT_SEDET ) = = USB_OTG_GOTGINT_SEDET ) {
} else {
}
USB_OTG_GLB - > GOTGINT | = temp ;
}
}
}