void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
{
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
uint32_t i = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
uint32_t fifoemptymsk = 0U, temp = 0U;
USB_OTG_EPTypeDef *ep;
uint32_t hclk = 180000000U;
/* ensure that we are in device mode */
if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
{
/* avoid spurious interrupt */
if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
{
return;
}
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
{
/* incorrect mode, acknowledge the interrupt */
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
}
printf("before \r\n");
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
{
epnum = 0U;
printf("after \r\n");
/* Read in the device interrupt bits */
ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
printf("outep ep_intr = %x \r\n",ep_intr);
while ( ep_intr )
{
if (ep_intr & 0x1U)
{
printf("num = %d\r\n",epnum);
epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
{
CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
if(hpcd->Init.dma_enable == 1U)
{
hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;
}
HAL_PCD_DataOutStageCallback(hpcd, epnum);
if(hpcd->Init.dma_enable == 1U)
{
if((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
{
/* this is ZLP, so prepare EP0 for next setup */
USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
}
}
}
if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
{
/* Inform the upper layer that a setup packet is available */
HAL_PCD_SetupStageCallback(hpcd);
CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
}
if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
{
CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
}
#ifdef USB_OTG_DOEPINT_OTEPSPR
/* Clear Status Phase Received interrupt */
if(( epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
{
CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
}
#endif /* USB_OTG_DOEPINT_OTEPSPR */
}
epnum++;
ep_intr >>= 1U;
}
}
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
{
printf("USB_OTG_GINTSTS_IEPINT \r\n");
/* Read in the device interrupt bits */
ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
epnum = 0U;
while ( ep_intr )
{
printf("epnum = %d\r\n",epnum);
if (ep_intr & 0x1U) /* In ITR */
{
epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
{
fifoemptymsk = 0x1U << epnum;
USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
if (hpcd->Init.dma_enable == 1U)
{
hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
}
HAL_PCD_DataInStageCallback(hpcd, epnum);
if (hpcd->Init.dma_enable == 1U)
{
/* this is ZLP, so prepare EP0 for next setup */
if((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
{
/* prepare to rx more setup packets */
USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
}
}
}
if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
{
CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
}
if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
{
CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
}
if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
{
CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
}
if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
{
CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
}
if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
{
PCD_WriteEmptyTxFifo(hpcd , epnum);
}
}
epnum++;
ep_intr >>= 1U;
}
}
/* Handle Resume Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
{
printf("USB_OTG_GINTSTS_WKUINT \r\n");
/* Clear the Remote Wake-up Signaling */
USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
#ifdef USB_OTG_GLPMCFG_LPMEN
if(hpcd->LPM_State == LPM_L1)
{
hpcd->LPM_State = LPM_L0;
HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
}
else
#endif /* USB_OTG_GLPMCFG_LPMEN */
{
HAL_PCD_ResumeCallback(hpcd);
}
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
}
/* Handle Suspend Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
{
printf("USB_OTG_GINTSTS_USBSUSP \r\n");
if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
{
HAL_PCD_SuspendCallback(hpcd);
}
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
}
#ifdef USB_OTG_GLPMCFG_LPMEN
/* Handle LPM Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
{
printf("USB_OTG_GINTSTS_LPMINT \r\n");
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
if( hpcd->LPM_State == LPM_L0)
{
hpcd->LPM_State = LPM_L1;
hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
}
else
{
HAL_PCD_SuspendCallback(hpcd);
}
}
#endif /* USB_OTG_GLPMCFG_LPMEN */
/* Handle Reset Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
{
printf("USB_OTG_GINTSTS_USBRST \r\n");
USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
USB_FlushTxFifo(hpcd->Instance , 0x10U);
for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
{
USBx_INEP(i)->DIEPINT = 0xFFU;
USBx_OUTEP(i)->DOEPINT = 0xFFU;
}
USBx_DEVICE->DAINT = 0xFFFFFFFFU;
USBx_DEVICE->DAINTMSK |= 0x10001U;
if(hpcd->Init.use_dedicated_ep1)
{
USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
}
else
{
#ifdef USB_OTG_DOEPINT_OTEPSPR
USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_OTEPSPRM);
#else
USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
#endif /* USB_OTG_DOEPINT_OTEPSPR */
USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
}
/* Set Default Address to 0 */
USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
/* setup EP0 to receive SETUP packets */
USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
}
/* Handle Enumeration done Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
{
printf("USB_OTG_GINTSTS_ENUMDNE \r\n");
USB_ActivateSetup(hpcd->Instance);
hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH)
{
hpcd->Init.speed = USB_OTG_SPEED_HIGH;
hpcd->Init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE ;
hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_HS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else
{
hpcd->Init.speed = USB_OTG_SPEED_FULL;
hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
/* 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 */
/* Get hclk frequency value */
hclk = HAL_RCC_GetHCLKFreq();
if((hclk >= 14200000U)&&(hclk < 15000000U))
{
/* hclk Clock Range between 14.2-15 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0xFU << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 15000000U)&&(hclk < 16000000U))
{
/* hclk Clock Range between 15-16 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0xEU << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 16000000U)&&(hclk < 17200000U))
{
/* hclk Clock Range between 16-17.2 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0xDU << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 17200000U)&&(hclk < 18500000U))
{
/* hclk Clock Range between 17.2-18.5 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0xCU << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 18500000U)&&(hclk < 20000000U))
{
/* hclk Clock Range between 18.5-20 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0xBU << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 20000000U)&&(hclk < 21800000U))
{
/* hclk Clock Range between 20-21.8 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0xAU << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 21800000U)&&(hclk < 24000000U))
{
/* hclk Clock Range between 21.8-24 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0x9U << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 24000000U)&&(hclk < 27700000U))
{
/* hclk Clock Range between 24-27.7 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0x8U << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else if((hclk >= 27700000U)&&(hclk < 32000000U))
{
/* hclk Clock Range between 27.7-32 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0x7U << 10U) & USB_OTG_GUSBCFG_TRDT);
}
else /* if(hclk >= 32000000) */
{
/* hclk Clock Range between 32-180 MHz */
hpcd->Instance->GUSBCFG |= (uint32_t)((0x6U << 10U) & USB_OTG_GUSBCFG_TRDT);
}
}
HAL_PCD_ResetCallback(hpcd);
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
}
/* Handle RxQLevel Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
{
printf("USB_OTG_GINTSTS_RXFLVL \r\n");
USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
temp = USBx->GRXSTSP;
ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_DATA_UPDT)
{
if((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
{
USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
}
}
else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_SETUP_UPDT)
{
USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
}
USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
}
/* Handle SOF Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
{
printf("USB_OTG_GINTSTS_SOF \r\n");
HAL_PCD_SOFCallback(hpcd);
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
}
/* Handle Incomplete ISO IN Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
{
printf("USB_OTG_GINTSTS_IISOIXFR \r\n");
HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
}
/* Handle Incomplete ISO OUT Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
{
printf("USB_OTG_GINTSTS_PXFR_INCOMPISOOUT \r\n");
HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
}
/* Handle Connection event Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
{
printf("USB_OTG_GINTSTS_SRQINT \r\n");
HAL_PCD_ConnectCallback(hpcd);
__HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
}
/* Handle Disconnection event Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
{
printf("USB_OTG_GINTSTS_OTGINT \r\n");
temp = hpcd->Instance->GOTGINT;
if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
{
HAL_PCD_DisconnectCallback(hpcd);
}
hpcd->Instance->GOTGINT |= temp;
}
}
} |