cherry-embedded / CherryUSB

CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP
https://cherryusb.cherry-embedded.org
Apache License 2.0
1.29k stars 273 forks source link

stm32H7使用dwc2接口 传输64字节ok 传输65字节错误 #60

Closed lansongyi closed 1 year ago

lansongyi commented 2 years ago

对比官方库PCD_WriteEmptyTxFifo函数和dwc2_tx_fifo_empty_procecss,发现处理不一致,将dwc2_tx_fifo_empty_procecss中的处理方式改为和PCD_WriteEmptyTxFifo完全一致后,问题修复。 加油,老板

lansongyi commented 2 years ago

官方代码: //static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef hpcd, uint32_t epnum) //{ // USB_OTG_GlobalTypeDef USBx = hpcd->Instance; // uint32_t USBx_BASE = (uint32_t)USBx; // USB_OTG_EPTypeDef ep; // uint32_t len; // uint32_t len32b; // uint32_t fifoemptymsk; // // ep = &hpcd->IN_ep[epnum]; // // if (ep->xfer_count > ep->xfer_len) // { // return HAL_ERROR; // } // // len = ep->xfer_len - ep->xfer_count; // // if (len > ep->maxpacket) // { // len = ep->maxpacket; // } // // len32b = (len + 3U) / 4U; // // while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) && // (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U)) // { // / Write the FIFO */ // len = ep->xfer_len - ep->xfer_count; // // if (len > ep->maxpacket) // { // len = ep->maxpacket; // } // len32b = (len + 3U) / 4U; // // (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len, // (uint8_t)hpcd->Init.dma_enable); // // ep->xfer_buff += len; // ep->xfer_count += len; // } // // if (ep->xfer_len <= ep->xfer_count) // { // fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); // USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; // } // // return HAL_OK; //}

//dwc2_tx_fifo_empty_procecss 修改后代码 static void dwc2_tx_fifo_empty_procecss(uint8_t ep_idx) { uint32_t len; uint32_t len32b; uint32_t fifoemptymsk;

//lsy added
if (g_dwc2_udc.in_ep[ep_idx].actual_xfer_len > g_dwc2_udc.in_ep[ep_idx].xfer_len)
{
   return;
}
len = g_dwc2_udc.in_ep[ep_idx].xfer_len-g_dwc2_udc.in_ep[ep_idx].actual_xfer_len;

if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps)
{
    len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
}

len32b = (len + 3U) / 4U;

while (((USB_OTG_INEP(ep_idx)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&(g_dwc2_udc.in_ep[ep_idx].actual_xfer_len < g_dwc2_udc.in_ep[ep_idx].xfer_len) && (g_dwc2_udc.in_ep[ep_idx].xfer_len != 0U))
{
    /* Write the FIFO */
    len = g_dwc2_udc.in_ep[ep_idx].xfer_len-g_dwc2_udc.in_ep[ep_idx].actual_xfer_len;

    if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps)
    {
        len = g_dwc2_udc.in_ep[ep_idx].ep_mps;
    }

    dwc2_ep_write(ep_idx, g_dwc2_udc.in_ep[ep_idx].xfer_buf, len);

    g_dwc2_udc.in_ep[ep_idx].xfer_buf += len;
    g_dwc2_udc.in_ep[ep_idx].actual_xfer_len += len;

    if(ep_idx==1)
           USB_LOG_RAW("fifo_empty:%d,%d,%d\r\n",len32b,(USB_OTG_INEP(ep_idx)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV),g_dwc2_udc.in_ep[ep_idx].actual_xfer_len);
}

if(ep_idx==1)
          USB_LOG_RAW("fifo_out:%d,%d\r\n",(USB_OTG_INEP(ep_idx)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV),g_dwc2_udc.in_ep[ep_idx].actual_xfer_len);

if (g_dwc2_udc.in_ep[ep_idx].xfer_len <= g_dwc2_udc.in_ep[ep_idx].actual_xfer_len)
{
    fifoemptymsk = (uint32_t)(0x1UL << (ep_idx & 0x0f));
    USB_OTG_DEV->DIEPEMPMSK &= ~fifoemptymsk;
}

}

sakumisu commented 2 years ago

我测试不加没有问题

sakumisu commented 2 years ago

默认case是2K

lansongyi commented 2 years ago

嗯 主要差别在len = g_dwc2_udc.in_ep[ep_idx].xfer_len-g_dwc2_udc.in_ep[ep_idx].actual_xfer_len;

lansongyi commented 2 years ago

64的整数倍发送 比如4k 我试了发100Mbyte也没问题 发非整数倍时 发送几次后就会挂掉 无法发送 明天给你搞个log看看

sakumisu commented 2 years ago

不过代码确实有点问题,已经改了,我fifo功能用的不多,基本是dma

sakumisu commented 1 year ago

有需要再重开