This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Setup bulk enpoint

Hello, 

I am working on writing a driver for the peripheral side of the USB:

* I am not using Linux

* Using Full Speed

* I am not using DMA

* I am able to enumerate the device, show it in Windows as CDC Serial, open terminal (PuTTY) and receive data from the device (Bulk IN transfer working OK), this is a constant behavior, it works every time.

* I am using different endpoints for OUT and IN transfers.

My problem is with Bulk OUT transfers.

I am configuring the endpoints after a reset is detected (just as the Bulk IN EP), I'm setting the RXMAXP to 64, RXFIFOSZ to 3, RXFIFOADDR 8 (it's EP1), checking FULLFIFO bit and if it is set, then I FLUSHFIFO. I am doing this in the order shown in the Datasheet.

When I send one character from the PC, I get the interrupt for EP1, I read the RXCOUNT (after setting INDEX to 1 or the corresponding EP number) and it gives me a very big number.

I have tried switching enpoints (trying in EP2 and EP3 and configuring RXFIFOADD accordingly) and same problem, I am able to transmit data no matter what EP for IN transfer I am using but not able to receive data.

Can someone point me to the right direction to get Bulk OUT transfers working?

Thanks in advance,

- Esaias

  • Hi Esaias,

    In my driver, I configured the FIFO size before enumeration. The rest of the endpoint configuration is done when SET_CONFIGURATION request is received during enumeration.

    This is the function to call when SET_CONFIGURATION request is received.

    STATUS USBDrv_ConfigureEndpoint(USBDRV_ENDPOINT endpoint, UINT8 direction,
      UINT8 transferType, UINT16 packetSize, BOOL dmaEnable)
    {
     UINT16 csr = 0;

     switch (direction)
     {
     case USB_DIR_OUT:
      REG_WRITE(ENDPOINT_STS_CTL_REGs[endpoint]->RXMAXP, packetSize);

      {
       if (transferType == USBPIPE_ISOCH)
       {
        csr |= RXCSR_P_ISO;
       }
       else if (transferType == USBPIPE_INT)
       {
        /* Disable the transmission of NYET handshakes in high-speed mode */
        csr |= RXCSR_P_DISNYET;
       }

       if (is_dma_capable() && (dmaEnable == TRUE))
       {
        csr |= RXCSR_P_DMAEN;
       }

       /* Ensure the data toggle starts in the correct state */
       csr |= RXCSR_P_CLRDATATOG;

       /* If there are any data packets in the FIFO, they should be flushed. */
       if (REG_TEST_BIT(ENDPOINT_STS_CTL_REGs[endpoint]->RXCSR, RXCSR_P_RXPKTRDY))
       {
        csr |= RXCSR_P_FLUSHFIFO;
       }
      }

      REG_WRITE(ENDPOINT_STS_CTL_REGs[endpoint]->RXCSR, csr);

    #if 0 /* NOTE: It may be necessary to set this bit twice in succession if double buffering is enabled. */
      REG_WRITE(ENDPOINT_STS_CTL_REGs[endpoint]->RXCSR, csr);
    #endif

      break;

     case USB_DIR_IN:
      REG_WRITE(ENDPOINT_STS_CTL_REGs[endpoint]->TXMAXP, packetSize);

      {
       if (transferType == USBPIPE_ISOCH)
       {
        csr |= TXCSR_P_ISO;
       }
       else if (transferType == USBPIPE_INT)
       {
        /* Enable the continuous toggle of the data toggle bit ? */
        /*csr |= TXCSR_P_FRCDATATOG;*/
       }

       csr |= TXCSR_P_MODE;

       if (is_dma_capable() && (dmaEnable == TRUE))
       {
        csr |= (TXCSR_P_DMAEN | TXCSR_P_DMAMODE);
       }

       /* Ensure the data toggle starts in the correct state */
       csr |= TXCSR_P_CLRDATATOG;

       /* If there are any data packets in the FIFO, they should be flushed. */
       if (REG_TEST_BIT(ENDPOINT_STS_CTL_REGs[endpoint]->TXCSR, TXCSR_P_FIFONOTEMPTY))
       {
        csr |= TXCSR_P_FLUSHFIFO;
       }
      }

      REG_WRITE(ENDPOINT_STS_CTL_REGs[endpoint]->TXCSR, csr);

    #if 0 /* NOTE: It may be necessary to set this bit twice in succession if double buffering is enabled. */
      REG_WRITE(ENDPOINT_STS_CTL_REGs[endpoint]->TXCSR, csr);
    #endif

      break;

     default:
      assert(0);
     }

     return (OK);
    }

    rgds,

    kc Wong