Dave Byman

LPC4357 Bulk IN Endpoint Hangs

Discussion created by Dave Byman on Jun 13, 2017
Latest reply on Jun 19, 2017 by jeremyzhou

I am using libusbdev on a custom board with the LPC4357.  I am using USB0 with one Bulk IN endpoint and one Bulk OUT endpoint.  Sometimes the USB will run fine and send data continuously for several days but randomly I experience a hang.  I call libusbdev_QueueSendReq() to send a packet on the IN endpoint and it returns LPC_OK.  After this I check libusbdev_QueueSendDone() continuously until it returns 0.  (My code for these functions is shown below.)  When the hang occurs pUSB->txBuffLen is never changed from the initial packet size of 880 bytes, indicating the packet was never sent.  

 

I have also confirmed with a USB analyzer that the last packet attempted before the hang was never sent.  The analyzer sees the normal number on NAKs after the last successful packet and then goes silent with no reported errors or further NAKs.

 

Because the USB ROM code is not easily accessible for debugging I am at a loss for where to look next.

 

libisbdev_QueueSendReq:

/* Queue the given buffer for transmision to USB host application. */
ErrorCode_t libusbdev_QueueSendReq(uint8_t *pBuf, uint32_t buf_len)
{
     LUSB_CTRL_T *pUSB = (LUSB_CTRL_T *) &g_lusb;
     ErrorCode_t ret = ERR_FAILED;

     /* Check if a write request is pending */
     if (pUSB->pTxBuf == 0) {
          /* Queue the write request */
          pUSB->pTxBuf = pBuf;
          pUSB->txBuffLen = buf_len;

          uint32_t bytes_written = USBD_API->hw->WriteEP(pUSB->hUsb, LUSB_IN_EP, pBuf, buf_len);
          if( bytes_written == buf_len )
          {
               ret = LPC_OK;
          }
     }

     return ret;
}

 

libusbdev_QueueSendDone:

/* Check if queued send is done. */
int32_t libusbdev_QueueSendDone(void)
{
LUSB_CTRL_T *pUSB = (LUSB_CTRL_T *) &g_lusb;
/* return remaining length */
return pUSB->txBuffLen;
}

 

App Code:

// queue send request 
if(libusbdev_QueueSendReq((uint8_t*)(usb_tx_buffer), g.txUSBPacket[g.txUSBTail].sz) == LPC_OK)
{
     while(libusbdev_QueueSendDone() != 0) osThreadYield(); // <--- hangs here as libusbdev_QueueSendDone() always returns 880 bytes
}

 

USB0 Registers after the hang (in case this is useful)

 

USB0 registers

Outcomes