我使用STM32CubeMx生成了Custom Hid的工程,三个端点,0,81,01.配置好后,设备的枚举正常。
我用上位机,向01发送数据,上位机返回成功。mcu也收到了,mcu设置的buffer里有传来的数据。
但是有一个问题,按理说我应该收到一个回调函数,在数据接受完后调用到我自己的程序。而我始终得不到这个回调。
USB的中断函数如下(有点长,抱歉),我理解接受完后,会调用HAL_PCD_DataOutStageCallback回调,在测试中,发现始终调用不到。
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;
}
}
}
|
|