AnsweredAssumed Answered

issue met when using stm32_f105-07_f2_f4_usb-host-device_lib on STM32F405

Question asked by zhong.jaret on Oct 10, 2015

Hi,

I am using stm32_f105-07_f2_f4_usb-host-device_lib in my STM32F405 board.

       
  1. My device is recognized by the PC host as virtual com port
  2.    
  3. I am using dedicated EP1
  4.    
  5. I need transmit a large amount of data with high speed. This is why I transfer from stm32f103 to stm32f405 to utilize the USB HS mode.                                    

I am trying to use DCD_EP_Tx to transmit data to USB host directly. But the problem I meet is the data sent to PC host frequently get crashed. It looks like the new data will crash the old data before it is sent to PC HOST.

My question is that if there is any condition I can use before calling DCD_EP_Tx to make sure the old data is sent to PC host.

Like in STM32F013, I will implement the USB transmit this way:

if (GetEPTxStatus(ENDP1) == EP_TX_NAK)
{
        USB_SIL_Write(EP1_IN, InReport, 64);
        SetEPTxCount((EP1_IN & 0x7F), 64);
        SetEPTxValid(ENDP1);
        return 1;
}

 I am wondering if in STM32F405, we have a similar way.

 Below is my implementation of USB transmitting in STM32F405.

 void USB_send_packet(uint8_t * buf, uint16_t len)
{   
       int i = 0;

      /*see if the left FIFO length is larger than 512 bytes */
       while(DCD_GetTxFifoStatus(&USB_OTG_dev, CDC_IN_EP & 0x7F) < 128);

       while(g_tx_completed == 0); // g_tx_completed  is set 1 in EP1 TX COMPLTE ISR
       __disable_irq;
       g_tx_completed = 0;
       __enable_irq;


        // ep_in_buf is a global array being 512 byte long 
        memset(ep_in_buf, 0, sizeof(ep_in_buf));         
        memcpy(ep_in_buf, buf, len);
        DCD_EP_Tx(&USB_OTG_dev, CDC_IN_EP, ep_in_buf, len); // len is always 512
}

 uint8_t g_tx_completed = 1;
uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{

  USB_OTG_DIEPINTn_TypeDef  diepint;
  uint32_t fifoemptymsk, msk, emp;
  
  msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
  emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
  msk |= ((emp >> 1 ) & 0x1) << 7;
  diepint.d32  = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;  
  
  if ( diepint.b.xfercompl )
  {
    fifoemptymsk = 0x1 << 1;
    USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
    CLEAR_IN_EP_INTR(1, xfercompl);
    /* TX COMPLETE */
    g_tx_completed = 1;

    //USBD_DCD_INT_fops->DataInStage(pdev , 1);
  }
  if ( diepint.b.epdisabled )
  {
    CLEAR_IN_EP_INTR(1, epdisabled);
  }  
  if ( diepint.b.timeout )
  {
    CLEAR_IN_EP_INTR(1, timeout);
  }
  if (diepint.b.intktxfemp)
  {
    CLEAR_IN_EP_INTR(1, intktxfemp);
  }
  if (diepint.b.inepnakeff)
  {
    CLEAR_IN_EP_INTR(1, inepnakeff);
  }
  if (diepint.b.emptyintr)
  {
    DCD_WriteEmptyTxFifo(pdev , 1);
    CLEAR_IN_EP_INTR(1, emptyintr);
  }
  
  return 1;
}

Outcomes