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.

AM335X USB DMA question

Hi All:

        We are  using AM335X   in our project and have looked at the starterware examples. We use one of the USB controller of the AM335X  as a USB bulk device. The cppi  DMA mode is to be used, We are using the  Cppi41DmaModeSet function  in  the file of cppi41dma.c  of staterware to set the working mode of the CPPI DMA controller. However,  it seems doesn't work , we can't change the DMA working mode to be RNDIS or GRNDIS ,but only theTRANSPARENT mode( default mode ) can be used. 

      We checked the  Cppi41DmaModeSet  function  in  the file of cppi41dma.c  of staterware carefully, the Registers and Base address used in this fuction seems diffetent with the the Registers of the USB module listed and descripted  in the datasheet of AM335X.  The differences bewteen the esample code and the datasheet are as follow:

    The usbInstance->otgBaseAddress is  initialized to the base address of USBSS In the Cppi41DmaInit function, in the Cppi41DmaModeSet  function. usbInstance->otgBaseAddress  is  used as the base address of the USB0CTRL Register and USB0MODE Register , but we can't find USB0CTRL Register and USB0MODE Register  in the Registers list of USBSS , however,  we find these registers in the Registers list of USB0_CTRL  and USB1_CTRL .  In additon, the USB0MODE Register (USB_0_MODE) appeared  in the Cppi41DmaModeSet  function is not used for DMA working mode setting but for IDDIG, PHY_TEST and LOOPBACK setting accordding to the datasheet of the USB0_CTRL in AM335X. For DMA working mode setting, there seems exist two registers as USB0TXMODE register and USB0 RXMODE register in the registers list of USB0_CTRL.

    Now , we are confused by the example code in starerware and the datasheet of AM335x,  Although we have do  a lot of  code debugging work , it still doesn't work.

Can anyone from TI  help us to solve this problem?

Best Regards

Y tck

  • Can anyone help us?

  • IMHO Cppi41DmaModeSet code is completely wrong!

    Naming register as in TRM, the ones to be configured are: USB0CTRL USB0TXMODE USB0RXMODE and USB0GENRNDISEPx.

    All these registers are part of USB0 registers block (aka USB0_CTRL), so the base address to be used would be 0x47401000 and not otgBaseAddress (0x47400000).

    Global RNDIS must be set/reset in USB0CTRL register, as is.

    TX/RX EPs configuration must be done setting USB0TXMODE and USB0RXMODE registers: using USB0MODE reg here seems a nonsense...

    Configuration of USB0GENRNDISEPx seems hard-coded just for first EP (USB_0_GEN_RNDIS_SIZE_EP1), all other EPs are ignored...

    I wonder how it can work... ...if works.

    I would suggest to rewrite it by yourself. And try to ask help on Starterware forum, too.

    Regards,

    Max


  •     Thank you for answering our question.  In fact , before asking this question in TI E2E Community,  We have already tried to rewrite the Cppi41DmaModeSet  function, using registers of USB1CTRL USB1TXMODE USB1RXMODE and USB1GENRNDISEPx . Currently in our project ,  we just use RX and TX endpoint 1 of USB1 module for data receiving and transmitting. However , The rewritten Cppi41DmaModeSet function still dosen't work . The Cppi41DmaModeSet code is as follow:

    void Cppi41DmaModeSet(unsigned short usbDevInst, endpointInfo *epInfo)
    {

        unsigned int rxModeReg;
        /* Enable RNDIS from Global Level */
        if (epInfo->dmaMode == CPDMA_MODE_SET_RNDIS)
        {
            HWREG(0x47401800 + 0x14)|= CPDMA_MODE_ENABLE_GLOBAL_RNDIS;    
            
        }    
        /* Disable RNDIS from Global Level     */
        else
        {
            HWREG(0x47401800 + 0x14)&= ~CPDMA_MODE_ENABLE_GLOBAL_RNDIS;
        }

        /*Set the mode for RX and TX channel */
        if(epInfo->direction == CPDMA_DIR_TX)
        {
            HWREG(0x47401800 + 0x70)|= 0x00000003;  //EP1  GRNDIS TX MODE
        }    
        else
        {
            HWREG(0x47401800 + 0x74)|=0x00000003;   //EP1  GRNDIS RX MODE
                        
        }
        /* For GRNDIS mode, set the maximum packet length */
        if (epInfo->dmaMode == CPDMA_MODE_SET_GRNDIS)
        {
            if(usbDevInst == 0)
            {
                HWREG(0x47401000 + 0x80) = GRNDIS_MAX_PACKET_LENGTH;
            }
            else if(usbDevInst == 1)
            {
                HWREG(0x47401800 + 0x80) = GRNDIS_MAX_PACKET_LENGTH;

            }
        }
    }

        In Cppi41DmaModeSet function, 0x47401800 is the base address of USB1 module, 0x14  0x70  0x74  0x80 are the  offset address of USB1CTRL USB1TXMODE USB1RXMODE and USB1GENRNDISEPx ,  other MACRO definitions used in the function are not changed.

        Unfortunately , the rewritten function  of Cppi41DmaModeSet still doesn't work , it seems any change to any  register  used in this function doesn't  make any response when running the program. Now We suspect that there may be something  error in the register list of USB0/1 module of AM335X datasheet. Could you tell me whether my doubt  is right or wrong?  If there is a new version of AM335X , Could you give me a copy?  Thanks!

       Best regards,

    Y tck


  • Do you mean a new version of AM335x TRM doc? A do not think registers are wrong.

    I cannot help too much, I played with Starterware just a few hours some months ago, but PSP Linux kernel uses same registers definition as TRM, and seems working. BTW kernel uses just TRANSPARENT and GRNDIS modes, and last one only if pkt size is multiple of 64 (except some ad-hoc cases in peripheral mode for rx channels).

    Of course function logic is wrong, 'cause enabling/disabling RNDIS at global level cannot be handled by EP-specific configuration, but if I do not think this is the point.

    In Starterware, comparing 2.0.0.5 with 2.0.0.7 versions, I've noticed that in several examples (dev_msc, host_msc), they moved TX channels configuration from GRNDIS to TRANSPARENT. Maybe if someone at TI can say way, this could help you. Are you able to run Starterware examples as they are?

    Also note this detail here: In the current implantation, GRNDIS mode will not work if the packet size is larger than 512 bytes.

    Regards


  • You guys are way beyond me in USB DMA detail, but have you seen the Silicon Advisory 1.0.13 on p. 16 of http://www.ti.com/litv/pdf/sprz360b ?

    Hence we have been running (in Linux) without USB DMA and the delta is not too bad (at least documented in this version of the PSP: http://processors.wiki.ti.com/index.php/AM335x-PSP_04.06.00.06_Features_and_Performance_Guide#USB_MSC_.28MUSB.29_Host_mode_VFAT_File_System_Performance )

     

     

     

  • Joe, thanks for outlining the silicon issue. I already know about it (I'm working on USB and AM335x since several months), but I do not think it's the case of Ytck: in my understanding he is using just a single endpoint.

    Yeah, not using DMA will be fine if performances are not so critical for you product. But as you can see host MSC PIO read performances are less than half DMA ones. In general performances depend on a lot of parameters: host/peripheral role, implemented USB classes and functions, device at the other side of cable, etc... DMA can help. And it also offloads the cpu. BTW if you look at PSP 4.6.0.8 performances seem even worst than 4.6.0.6 (only DMA avail).

    For my project USB performances are really critical. And it was already in an advanced state when Silicon Advisory came out. Now I'm digging around, but...

  • Max,thank you for your answer, but the  problem still exists.  I have downloaded the  Starterware 2.0.0.7 version, and I find that  the Cppi41DmaModeSet function in  cppi41dma.c has no change, it's still completely wrong. Just like you,  I also find that in  evm335x examples, dev_msc, host_msc, the TX channels DMA configuration have been changed from GRNDIS to TRANSPARENT ,  Why they do that?  Maybe the GRNDIS mode of CPPI DMA could never work actually? Maybe some example codes of starterware haven't  been tested strictly?  How could I contact someone work  in TI that can solve my question?

    In addtion,  I have set the maxium packet size of the Rx and Tx endpoint 1  as 512 bytes, I think that could meet the requirement of  the"GRNDIS mode will not work if the packet size is larger than 512 bytes", or maybe the “packet size” in this sentence has some other meaning ? Thack you for help!

    Best regards

    Y tck

  • Can anybody help me?

  • Bump. Any new insight into this issue?

  • Hi

    Joe, would you please help me to get this doc http://www.ti.com/litv/pdf/sprz360bas you mentioned here, thanks in advance.

    Yes, the performance of DMA mode is just equals to PIO mode, so I guess CPPI41 DMA work pretty none :-)

  • Hi Everyone ,

    My apologies for taking so long.

    There are some documentation gaps in the AM335x documentation. At places the register description is wrong and the MUSB controller section is incomplete.

    Please refer the following post for the link  to download the DM814x TRM . This controller has the same register offsets as AM335x. 

    http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/204049.aspx

    With regard to your query on DMA mode being changed  in the latest StarterWare release , this was done to circumvent an silicon issue which popped up in GRNDIS mode. As an example, when the controller was being configured as an MSC device ( this seems to be your case)  Tx can be performed using GRNDIS mode but Rx needs to be done using the TRANSPARENT DMA mode.  

     

  • Thanks Vineeth, I have gotten the document, thanks!

  • Lit # changed to http://www.ti.com/litv/pdf/sprz360c

    Probably bad idea for me to post direct links anyway.  You can always go to the product page and download the latest:

    http://www.ti.com/product/am3358