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.

how does usb cppi dma work?

Other Parts Discussed in Thread: OMAPL138

Can anyone tell me how does usb cppi dma work?

How to register it's rx interrupt?

  • Hi,
    I presume that you are using either C6748or OMAPL138 processor.

    Did you have install starterware package ?

    We have implemented the DMA for USB2.0 in starterware package.
    Driver:
    C:\ti\OMAPL138_StarterWare_1_10_04_01\drivers\cppi41dma.c

    Example:
    C:\ti\OMAPL138_StarterWare_1_10_04_01\examples\lcdkOMAPL138\usb_host_msc.c

    By default, "DMA_MODE" has been enabled in starterware USB examples.

    If you are using some other processor, please let me know.
  • Yes,I use c6748 and I have install its startereware package.I have read the cppi41dma.c file, but I am confused. I want to add cppidma to usb_dev_bulk.

    Please help me,thanks.

  • Hi,
    Current DMA implementation is only for USB mass storage device, if interested you can write and enable DMA support on your own for USB dev bulk.

    processors.wiki.ti.com/.../StarterWare_USB

  • The usb_dev_bulk in the starterware is not support DMA!!!!
  • When I add CPPIDMA's functionality to usb_dev_bulk,I've had a  problem,In the host,I use usb_bulk_write() to send data,but when it sends a number of data, it will be blocked and no longer send data! My code is as follows:

    static void
    HandleEndpoints(void *pvInstance, unsigned int ulStatus, unsigned int ulIndex)
    {
        const tUSBDBulkDevice *psBulkInst;
        tBulkInstance *psInst;

        ASSERT(pvInstance != 0);

        //
        // Determine if the serial device is in single or composite mode because
        // the meaning of ulIndex is different in both cases.
        //
        psBulkInst = (const tUSBDBulkDevice *)pvInstance;
        psInst = psBulkInst->psPrivateBulkData;


    #ifdef DMA_MODE
        unsigned int pendReg=0;

        // Get the Starvation interrupt status
        CppiDmaGetINTD0Status(g_USBInstance[ulIndex].uiUSBInstance);

        // Get the DMA Interrupt status
        pendReg = CppiDmaGetPendStatus(g_USBInstance[ulIndex].uiUSBInstance);

    #endif

        //
        // Handler for the bulk OUT data endpoint.
        //
        if(ulStatus & (0x10000 << USB_EP_TO_INDEX(psInst->ucOUTEndpoint)) ||
                (pendReg & CPDMA_RX_PENDING))
        {

    #ifdef DMA_MODE
            ProcessDataFromHost_DMAMODE(pvInstance, ulStatus, ulIndex, pendReg);
    #else
            ProcessDataFromHost(pvInstance, ulStatus, ulIndex);
    #endif

        }

        //
        // Handler for the bulk IN data endpoint.
        //
        if(ulStatus & (1 << USB_EP_TO_INDEX(psInst->ucINEndpoint)) ||
                (pendReg & CPDMA_TX_PENDING))
        {

    #ifndef DMA_MODE
            ProcessDataToHost_DMAMODE(pvInstance, ulStatus, ulIndex, pendReg);
    #else
            ProcessDataToHost(pvInstance, ulStatus, ulIndex);
    #endif
        }
    }

    static tBoolean
    ProcessDataFromHost_DMAMODE(const tUSBDBulkDevice *psDevice, unsigned int ulStatus,
                                                                unsigned int ulIndex,unsigned int pendReg)
    {
        unsigned int rxBuffer;
        unsigned int ulEPStatus;
        tBulkInstance *psInst;
        tUSBBuffer *psBuffer;

        // Get a pointer to our instance data.
        psInst = psDevice->psPrivateBulkData;
        psBuffer = (tUSBBuffer *)psDevice->pvRxCBData;

        // Get the endpoint status to see why we were called.
        ulEPStatus = USBEndpointStatus(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint);

        //Clear the status bits.
        USBDevEndpointStatusClear(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint, ulEPStatus);

        enableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);

        //During receive operation, we need to wait in loop till we recive all data
        while(CppiDmaGetPendStatus(g_USBInstance[ulIndex].uiUSBInstance) & CPDMA_RX_PENDING)
        {
            rxBuffer = dmaRxCompletion(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);

            psBuffer->pfnCallback(psBuffer->pvCBData,USB_EVENT_RX_AVAILABLE,512,rxBuffer);

    #if 0
            times++;
            UARTPuts("times:", -1);
            UARTPutHexNum(times);
            UARTPuts("\r\n", -1);

            *((char *)rxBuffer+20) = 0;

            UARTPuts("rxBuffer:", -1);
            UARTPuts((char *)rxBuffer+8, -1);
            UARTPuts("\r\n", -1);
    #endif

            //
            //Load another BD to the receive queue
            //
            doDmaRxTransfer(g_USBInstance[ulIndex].uiUSBInstance, MAX_TRANSFER_SIZE,
                (unsigned char *)rxBuffer, psInst->ucOUTEndpoint);
        }

        USBDevEndpointDataAck(psInst->ulUSBBase, psInst->ucOUTEndpoint,true);

        return (true);
    }

    Can anyone help me? thanks.

  • Hi,
    Did you check that where it at hang ?
    If you pause the code then you would see the line where it would hang.
    Please make sure that you have setup everything (DMA,interrupts etc.,) properly.
  • Thank you ! I have resolve my problem!

  • Sounds good.
    Thanks for your update.
    Could you tell us what you have changed to fix the problem so that other community members would get benefited.