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.

C6747 USB0 Device operation

Other Parts Discussed in Thread: OMAP-L137, TS3USB221, DA8XX

Hi,
I am using OMAP-L137 witch C6747 DSP processor, and I would like to operate USB OTG as device, I have probably initialized it wrong or not done something because I can't get USB host to detect device (USB host is standard PC). 

From my work with USB I know I should turn on Pull up on D+ or D- line (regardless if it full speed or low speed device) and after that host should try to enumerate device. I can't get info how to enable those Pull up. 

I tried USB initialization according to examples from sprufm9b.pdf and forced USB to Device mode, but still SESSION bit is not set in DEVCTL of USB register and processor is waiting for session to begin. 

Any help would be appreciated, I can copy paste source code if its needed. 

  • Hi,Zegeye.

    Thank you for your last response.With your help,I have figured out my problem last time.

    I'm now trying to use CPPI DMA to increase my transmission speed.I didn't plug dsp to PC,so there is no enumeration process.And I just configured DMA for EP1 Tx .

    I follow the sample code in sprufm9f to creat a simple program to transmit 64bytes data from main memory to EP1 FIFO in transparent mode.

    But when I plug my descriptor to the queue by writing my HPD's address to CTRLD of queue 16,it seems it doesn't work.

    The TXPKTRDY of PERI_TXCSR for EP1 doesn't set.And when I open the registers window, I find that a bit  corresponding to queue 16 of PEND0 is set.

    I'm now wondering in normal case whether TXPKTRDY is autosetted if DMA has completed the transaction.Any qusetion is that in what condition can  a queue enter into pend state.

    Thank you very much.

    Best regards, Jun.

     

  • Fellow up:

    usbRegisters->QCTRL[16].CTRLD=(Uint32)&cppi_desc[0] | 0x2;

    The value of (Uint32)&cppi_desc[0] | 0x2 is 0xC0020002, but when I read CTRLD by printf of from the registers window, the value is 0xC0020003.

    I don't know why.

  • Hi,

    Glad to hear of your progress.

    Would you please give me a bit more detail about your setup?

    Are you connected to some kind of a host that would not require enumeration ... ?

    I am not sure of your setup. Give me more details on it. Can not for sure say what is not working; DMA not moving data or Host not issuing Request. I can not tell.

    So, give me some info on your setup and high level description what you are attempting to do.

    Best regards, Zegeye

  • Hi,

    I need to look into this. Don't know why bit 0 gets set. I think it should not.

    The bottom 5 bits hold the Descriptor size and 2 signifies a 32-Byte Descriptor and 3 signifies a 36-Byte Descriptor.

    Btw, reading from the queue is going to pop it off; I think you are aware of this but wanted to just point out. Will get back with you if this is an expected behavior or is a problem.

    Best regards, Zegeye

  • Hi, Zegeye

    I just want to bulid a program to test how to use CPPI DMA, so I didn't plug DSP to any host. Is that right?

    typedef struct CPPIDesc
    {
        Uint32            HPDword0;
        Uint32            HPDword1;
        Uint32            HPDword2;
        Uint32            HPDword3buffLength;
        void *            HPDword4buffAdd;
        struct CPPIDesc * HPDword5nextHBDptr;
        Uint32            HPDword6orgBuffLength;
        void *            HPDword7orgBuffAdd;
    } T_CPPIDesc;

    #pragma DATA_ALIGN (cppi_desc, 32);
    T_CPPIDesc cppi_desc[CPPI_NUM_DESC];  /**< HPD/HBD descriptors */
      
    Uint32 cppi_linkram0[CPPI_NUM_DESC]; /**< reserve memory for linking ram */
    Uint32 cppi_linkram1[CPPI_NUM_DESC];

    Uint8   usbtx_msg[64] = { 1,2,3,4,5,6,7,8,9,0,
           1,2,3,4,5,6,7,8,9,0,
           1,2,3,4,5,6,7,8,9,0,
           1,2,3,4,5,6,7,8,9,0,
           1,2,3,4,5,6,7,8,9,0,
           1,2,3,4,5,6,7,8,9,0,
           1,2,3,4};


    int main()
    {
     CSL_Status        result;
     ICR |=0xFF;
     IER &= ~0xFF;//clear interrupt enable register

     PLL0_CKEN=0x00000011;
     while ( PLL0_CKSTAT == 0) {;}//ckstat

     //初始化USB
     result=CSL_usbIntcTest();


     status = USB_connectDev(CSL_USB0);

     
           /***************************************************************//**
              configure transparent DMA transfers
            *******************************************************************/
             usbRegisters->CTRLR &= ~0x00000010;  // Global RNDIS disable
             usbRegisters->MODE = 0;  // all endpoints in transparent DMA mode

            /***************************************************************//**
              configure Queue Manager and Linking RAM
            *******************************************************************/
            usbRegisters->QMGR.LRAM0BASE = (Uint32)cppi_linkram0;      
            usbRegisters->QMGR.LRAM0SIZE = CPPI_NUM_DESC;   
            usbRegisters->QMGR.LRAM1BASE = (Uint32)cppi_linkram1; 
            usbRegisters->QMEMREGION[0].QMEMRBASE = (Uint32)cppi_desc;
            usbRegisters->QMEMREGION[0].QMEMRCTRL = 0 ;  /**< 32 descriptors, size = 32 bytes, index = 0 */
               

            /***************************************************************//**
              configure the CPPI scheduler: only one Tx EP is used (EP1-IN)
              enable scheduler
            *******************************************************************/
            usbRegisters->DMA_SCHED.ENTRY[0] = 0x00000001;  // endpoint 1 transmit: 1 credit
            usbRegisters->DMA_SCHED.DMA_SCHED_CTRL = 0x80000000;        
            /***************************************************************//**
              enable DMA for transmit endpoint 1, use queue 24 for completion
            *******************************************************************/
            usbRegisters->DMA_CTRL[0].TXGCR=(0x80000000 | 24);  

            /***************************************************************//**
              setup HPD for a single transfer
              @note: strlen(usb_msg) <= max_packet_size
            *******************************************************************/

            cppi_desc[0].HPDword0 = 0x80000000 | sizeof(usbtx_msg);
            cppi_desc[0].HPDword1 = 0x00000000;      // source = EP1
            cppi_desc[0].HPDword2 = 0x14004000 | 24; // 24 = completion queue
            cppi_desc[0].HPDword3buffLength =
            cppi_desc[0].HPDword6orgBuffLength = sizeof(usbtx_msg);
            cppi_desc[0].HPDword4buffAdd =
            cppi_desc[0].HPDword7orgBuffAdd = usbtx_msg;
            cppi_desc[0].HPDword5nextHBDptr = NULL;


            /***************************************************************//**
              configure endpoint for DMA and enqueue HPD
            *******************************************************************/
            usbRegisters->EPCSR[1].TXCSR.PERI_TXCSR &= 0x7FFF;
            usbRegisters->EPCSR[1].TXCSR.PERI_TXCSR |= 0x1400;
            usbRegisters->QCTRL[16].CTRLD=(Uint32)&cppi_desc[0] | 0x2;


    // usb_isr();

       usbRegisters->INDEX = 1;

    while (1)
    {

       printf("TXCSR is %x\n", usbRegisters->TXCSR.PERI_TXCSR);
       printf("QSTATUSA is %x\n",usbRegisters->QSTAT[16].QSTATA);
       printf("QSTATUSB is %x\n",usbRegisters->QSTAT[16].QSTATB); 
       printf("QSTATUSC is %x\n",usbRegisters->QSTAT[16].QSTATC);
    }

    }

    Is this right?

    Thank you very much.

    Best regards, Jun.

     

     

  • Hi,

    My thinking here is that you will need to get the Host side going. At the minimum the Reset Bus Condition from the Host would configure many registers, both memory mapped and not memory mapped, to their default settings.

    The sample code on the PRG is proven to work and should work well. Make sure the memory alignment restricitions are followed.

    Since you already have your code working via CPU mode, you have already done the bulk of the work to get your DMA code part working.

    Best regards, Zegeye

  • Hi,

    I have found out that we do internally round up the value enterd by one and your observation is correct. This makes the size of the Descriptor Size field to be read as 3. In other words, the size field will increase by 1 when read.

    You do not need to worry about this. Liike I mentioned above, remember that reading from a Queue will result in poping action.

    Best regards, Zegeye

  • Hi, Zegeye.

    Thank you for your last response.

    As you suggested ,this time I add the emulation process to the program. After the enumeration ,I initialize the CPPI DMA and configure EP2 RX for DMA mode.

    Then I run the PC side control panel to send data to DSP.I can see that data is continuously sent to the DSP sucessfully and I didn't receive EP2 RX interrupt which maybe meant DMA was working .

    But there was no data in the rxbuffer in main memory.

    Also ,I found the PEND0 of queue 15 which i used as RX SUBMIT queue was set.

    Can you tell me in what condition a queue entered into pending state?

    Thank you very much.

    Best regards,Jun.

     

     

     

     

  • Hi Jun,

    The reason PEND0.15 bit is set is because you probably are using this queue as your submit queue and you have pushed a Buffer Descriptor in that queue. See a bit more details on this below. Regardless, since the issue you are having could be anywhere it is best that you address this one at a time. You should not be expecting to see core interrupt or your code should not use core endpoints interrupt when using DMA. However, you will need to assoicate endpoint 2 with the DMA. You need to go through cppiDmaInit function. It is not much. My thinking is that some where within your code some initialization part is not right.

    Please consult Table 26 for alloction of Queues. You would will need to use Queues 26 and 27 as a Completion Queues for a Receive Transfer if you desire to receive an Interrupt. Note that these DMA interrupts can not be masked nor status bit exist for them. That is the reason why for using these dedicated queues when need to have the DMA generate interrupt.

    See section 2.8.9, CPPI DMA Transfer Interrupt Handling, as to how DMA Interrupt is generated. Same info above but also discussed within the user's guide.

    The Pending bit get set when packet is loaded on the queue and they get cleared when it is offloaded from the queue. One way to check if receive transfer has completed, if not using the completion queues or have not enabled interrupt at the CPU level is to use this register and poll on to the bit field corresponding to that particular queue. You could also attempt to pop the receive completion queue and if you gent a non-zero value on your poping action, then it means that you have packet available. Of-course poping is going to remove the Descriptor Address from the Queue and you need to use the address you popped off to identify the buffer as to where the data has been loaded onto.

    Couple of questions.

    What are the queues you are using for Submission (I think you are using Queue 15 from your question above) and for Completion?

    Btw, what size data are you trying to move? Pls start with small size data till you get the code going?

    Please take time to go line by line as to what is performed on cppiDmaInit function and let me know if you have any question.

    Once you have initialized your DMA, it is also good to see as to how you have initialized your Host Packet Descriptors (this applies for Tx only) and Host Buffer Descriptors.

    Finally you will need to enable the DMA. Have you configured the Core registers properly? See enableCoreRxDMA function on page 90. Btw, you will need to do the same for Tx Operation. See enableCoreTxDMA function on the same page.

    In Summary, the DMA part of the code is not much. Just make sure that you have proper association of the DMA with the particular Endpoint in use, DMA Schedular is configured and enabled, Packet and Buffer Descriptors are allocated and submitted, and lastly DMA is enabled.

    Best regards, Zegeye

     

     

  • Hi,Zegeye

    Thank you for your patience.

    I'm using Queue 15 for submission and Queue 26 for completion.And I just tried to transfer 608 bytes data .Also I tried smaller count of bytes,but it doesn't work.

    I read through the sample code and have several questions indeed.

    usbRegs->QMEMREGION[chan_num].QMEMRCTRL=(REG0START_INDEX<<16) | (DESC_SIZE<<8) | REG_SIZE;

    For the line above ,shall REG0START_INDEX  be 0 ?

    usbRegs->DMA_SCHED.ENTRY[0]= (0x80808080 | (chan_num | (chan_num << 8) | (chan_num << 16) | (chan_num << 24)));

    usbRegs->DMA_CTRL[chan_num].RXHPCRA=(rxSubmitQ | (rxSubmitQ<<16));

    If I only use EP2 for RX,then the chan_num  shall be 1 ?

    usbRegs->QMGR.LRAM0SIZE = LINKRAM0SIZE/4;

    Why LINKRAM0SIZE  shoule be devided by 4?

    I configured my Host buffer descriptor as follow:

            cppi_desc[0].HPDword0 = 0;
            cppi_desc[0].HPDword1 = 0;      //
            cppi_desc[0].HPDword2 = 0x00004000 | USBRX_COMPLETIONQUEUE; // 26 = completion queue
            cppi_desc[0].HPDword3buffLength =
            cppi_desc[0].HPDword6orgBuffLength = 256;
            cppi_desc[0].HPDword4buffAdd =
            cppi_desc[0].HPDword7orgBuffAdd = rxBuffer0;
            cppi_desc[0].HPDword5nextHBDptr = &cppi_desc[1];

    I follow the sample code of enableCoreRxDMA function as follow:

            usbRegisters->EPCSR[2].RXCSR.PERI_RXCSR &= 0x77FF;
            usbRegisters->EPCSR[2].RXCSR.PERI_RXCSR |= 0x2000;

    I configure RXGCR as follow:

        usbRegisters->DMA_CTRL[1].RXGCR=(0x80000000 | USBRX_COMPLETIONQUEUE);

    But when I watch the Registers Window,RXGCR is 0x80000000 not 0x80000000 | USBRX_COMPLETIONQUEUE.

    I'm using RNDIS mode and Rxmaxp of EP2 is 512.

    Sorry to trouble you those times .Thank you very much.

    Best regards,Jun.

     

     

     

     

  • Hi,

    It seems that you are not fully programming the DMA properly. I think I see some inconsistencies. Anyway, here it goes.

    Some of the data is coming from your question and some I am assuming to complete your question.

    Data I picked from your question:

    You are trying to Move Data In using Endpoint 2.

    The Size of the Data you are Transferring is 608 Bytes.

    Since you are receiving you have choosen Queue 15 as your Submit Queue and Queue 26 are your Completion Queue.

    You are using a Single Region (Region 0)

    You have allocated a Data Buffer, pointed by rxBuffer0.

     

    Assume:

    The Total # of Descriptors you are created are 32 (this is the minimum you can create). 32 => 2^(5+REG_SIZE) => REG_SIZE=0

    The Minimum Size of a Descriptor is 32 Bytes. 32 => 2^(5+DESC_SIZE) => DESC_SIZE=0

    Further Assume that these Descriptors are Allocated with the following assumptions: First 16 Descriptors are for Receive and Bottom 16 Descriptors are For Transmit.

    Assume you have allocated Data Buffer for the Queue Manager to use as a Scratch PAD RAM. This should be a minimum of 4 times the # of Descriptors.

    =>LINKRAM0SIZE=32 (Total # of Descriptors to be handled within the 1st LinkRAM Region).

    =>LINKRAMBUFFER=32*4=128Bytes.

     

     

     

    // Define a Region (REGION0) to store Descriptors: Note: You have the capability of using upto 16 Regions (REGION[0-15]) but most of the time for most applications Single Region Suffix.

    // Make sure Region Created is aligned on the size of Descriptor or Multiple Size of Descriptor.

     

    #pragma DATA_ALIGN(region0DescriptorSpace, 32);

    HostPacketDesc region0DescriptorSpace[32];                              //The 32 here is the min size that is supported. Allocating 32x32=1024 Bytes of Data Buffer for Descriptors.

     

    What the above means that:

    Region0Descrptor[0] to [15] are allocated for Receive

    Region0Descrptor[16] to [31] are allocated for Transmit

     

     

    // Define a Region for Queue Manager to use as a Scratch PAD RAM (a maximum of two Regions can be created with no regard to how the partition is made).

    // For each Descriptor Defined, Queue Manager requires a 4 Byte Memory.

    // Linking RAM should be 32-bit Aligned.

     

    #DEFINE LINKRAM0SIZE=4*32 // Size of Buffer for Linking Descriptors to be used by the Queue Manager is 4 x of the # of Descriptor Defined

    #pragma DATA_ALIGN(queueMgrLinkRam0, 32);

    Uint8 queueMgrLinkRam0[LINKRAM0SIZE]; // Allocate Scratch PAD RAM enough (4*32) for the Descriptors defined.

     

     

    usbRegs->QMGR.LRAM0BASE = (Uint32)queueMgrLinkRam0; // Init Starting Address for Linking RAM0

    usbRegs->QMGR.LRAM0SIZE = LINKRAM0SIZE/4; // Size of Linking RAM is entered in terms of the # of Descriptors/Offsets that can be accomodated even though the 4 x of the # of Descriptors size of memory is allocated.

     

     

    endpoint=2

    chan_num = endpoint – 1

    DEC_SIZE=0

    REG_SIZE=0

     

    Since it is assumed that Region 0 size is good enough for 32 Descriptors and since the allocated Scratch PAD RAM (LinkingRAM) is good enough for exactly 32 Descriptors we need to let the Queue Manager knows the starting offset/index it is supposed to use when linking Descriptors defined within Memory Region 0 and that would be Offset 0 in this case. You can assign any offset from 0 to 31. However, since you are assigning a START offset you need to insure that enough space is available for the remaining 31 Descriptors.

    REG0START_INDEX = 0

    usbRegs->QMEMREGION[chan_num].QMEMRBASE=(Uint32)region0DescriptorSpace;

    usbRegs->QMEMREGION[chan_num].QMEMRCTRL=(REG0START_INDEX<<16) | (DESC_SIZE<<8) | REG_SIZE;

     

     

    The Scheduler is also an indirect Priority assignment. The more credit you assign for a Channel/Endpoint the more it is going to be serviced. In your case you are servicing a Single Endpoint and performing only a Receive Transfer. There are tons of possible ways of assigning credit for this task. Since you only have a single Endpoint performing a Single Receive Transfer, the minimum # of entry needed is 1. Since we have defined Transmit Descriptors too, let us assume here that you will be Endpoint 2 IN and Endpoint 2 OUT endpoints and let us assign equal probability for both. This means that the # of entries to be programmed will be 2 (programmed one less) and channel number associated will be channel #1 Receive and channel # 1 Transmit. Since we are programming for two Entries and each Word can accommodate up to 4 entries, we need to program only Word 0.

     

    Last Entry is going to be 1.

    entry0_channel = chan_num;  // chan_num = ep-1 and in this case let’s configure EPn Receive here.

    entry0_rxtx = 1; // 0/1=>Tx/Rx; Receive

    entry1_channel = chan_num;  // chan_num = ep-1 and in this case let’s configure EPn Transmit here.

    Entry1_rxtx = 0; // 0/1=>Tx/Rx; Transmit

     

    usbRegs->DMA_SCHED.ENTRY[0]= (0x00000080 | (chan_num | (chan_num << 8));  // Same Endpoint/Channel is to be used for both Transmit and Receive

    usbRegs->DMA_SCHED.DMA_SCHED_CTRL=0x80000001;  // Scheculear is Enabled and number of Credits entered is for 2 entries (programmed one minus)

     

     

    Assuming that you will be using a Single Descriptor, i.e., the entire 608 bytes of data is going to a single contiguous buffer, for Receive Operation, you will need to initialize one of your Buffer Descriptors (have allocated 15 of them) to be a Buffer Descriptor.

     

    Assume:

    Uint8 rxBuffer0[610]; Allocate 610 Bytes only need space for 608 Bytes

            cppi_desc[0].HPDword0 = 0;     // For Buffer Descriptor this is Reserved
            cppi_desc[0].HPDword1 = 0; 
        // For Buffer Descriptor this is Reserved
            cppi_desc[0].HPDword2 = 0x00004000 | USBRX_COMPLETIONQUEUE; // 26 = completion queue
        // For Buffer Descriptor High 16 bit is Reserved. Descriptor is Located On-Chip and Only ONE Single QM exists (so this is always ZERO0 and bottom 12 bits program with Completion Queue which is Queue 26
            cppi_desc[0].HPDword3buffLength = 610;
        // This should be >= 608 for your case. Always allocate at least one more byte if using a Single Descriptor.
            cppi_desc[0].HPDword6orgBuffLength = cppi_desc[0].HPDword3buffLength;
        // Unless the receive data is going to be moved by some offset value, this should remain the same or more than Word 3 Length.
            cppi_desc[0].HPDword4buffAdd = (Uint32)rxBuffer0;
        // This is the Address of the data buffer length you entered @ Word 3
            cppi_desc[0].HPDword7orgBuffAdd = cppi_desc[0].HPDword4buffAdd;
        // Similar reason as Word 6.
            cppi_desc[0].HPDword5nextHBDptr = 0;
        // This is a SINGLE Descriptor setup, not chained. The whole 608 bytes of data is to be received within a single data buffer (the assumption we based above). If want multiple Descriptors, then you can do that. But the last Descriptor should be terminated with a NULL and the size of the data entered for each buffer descriptor should correspond with the size of data you desire to be entered at that buffer location. Also make sure the address of the buffer is not the same for each Buffer Descriptor. If so, you will be overwriting data.

    You will need to configure the Configuration Register prior to enabling it. You usually use a single Receive Submit Queue for all of the packets to be received and all are programmed with the same Queue #. So, program it on the order shown below.

                usbRegs->DMA_CTRL[chan_num].RXHPCRA=(rxSubmitQ | (rxSubmitQ<<16)); // Rx Channel 0 Host Pkt Cfg Reg A Offset 0x180C

                usbRegs->DMA_CTRL[chan_num].RXHPCRB=(rxSubmitQ | (rxSubmitQ<<16)); // Rx Channel 0 Host Pkt Cfg Reg B Offset 0x1810

        usbRegisters->DMA_CTRL[1].RXGCR=(0x81000000 | USBRX_COMPLETIONQUEUE);    // For Buffer Descriptor this is Reserved

     Hope this helps.

    Best regards, Zegeye

  • Hi,

    For a Buffer Descriptor DWORD5 is going to be written by the Port and value written by a user will not have any effiect.

    The above comment where cppi_desc[0].HPDword5nextHBDptr = 0; does not apply to Buffer Descriptor. As a user, you will need to push more Descriptors within your submit Queue and based on the length of the data buffer referenced by the Descriptor, the port will make use of as many buffer descriptors required to satisfy the data transfer size.

    For the above example, you can submit a single Descriptor by writing the address of the Descriptor within the submit queue. Since you have not initialized any other buffer descripor you can not submit additional descriptor. The initialization is similar to the above descriptor initialization. However, you will not need to link the Descriptors and if you do, that is fine. The port will overwrite it.

    Once you get the above working, I suggest you change the data buffer size referenced by the 1st Descriptor to be less than the data transfer size so that the port uses a minimum of 2 buffer descriptors to complete the transfer. Use 2 buffer descriptors where each buffer descriptor describes two data buffers with size equal to 350 Bytes each.

    Best regards, Zegeye 

  • Hi,Zegeye.

    Are you still there?Do you have any communication tools like MSN or can i contact you by skype?

    I think the code for CPPI DMA is not much .I follow the step in the reference and the suggestion you answered for me .

    But I can't find the problem and I catch some strange phenomena.

    Thank you very much.

    Best regards,Jun.

  • Hi Jun,

    Sorry to hear that it is still not working.

    This is a working code and others have been successful with it and there must be something overlooked that it is not working.

    Please supply me with the actual values you are programming. Please pick this values, not from your code, but from the Memory Window of CCS.

    Need Memory Region[0] address.

    Need Descriptors.

    Let me know how you submit Desciptors, this part of code was missing above.

    Best regards, Zegeye

  • Hello.

    I have a question mainly to Kanas, I think.

    How you solved the problem when the controller stops generating interrupts at EPx? Because I write USB driver for omap-l138 and have the same stuff. Small amounts of data go normally in and out, but when I transmitt relatively large amount of bytes (over dozens of KB) during some IN-transfer the controller sends a packet and next interrupt from it never comes even when I restart the debugger. Only after the whole prossessor is restarted USB interrupts appear. After interrupts dissapear UNDERRUN bit and sometimes also FIFOFULL and RXREADY are set.

    Thanks.

  • Hi,

    I think the controller is stalled and the only way you would get out of it is by either handling the stall condition or by resetting the controller. I think what is happening is that you are running out of resource. Make sure you allocate enough free buffer descriptors to handle incoming data and you have submitted these descriptors. A single Descriptor can handle a transfer size of 4M Bytes, which is much less than dozens of KB. So, you should not have an issue with Descriptor resource where many developers fail short. Try using a Single Descriptor setup and move on to multiple descriptor setup.

    If enough resource is available and the controller is unable to accept the data, because FIFO is full and the external host is sending data faster than you are servicing it, it will NAK the request.

    It would be great to also observe the bus condition with some king of a bus analyzer to better understand the issue.

    Best regards, Zegeye

  • Hello.

    Thanks for quick ansewring, but it is not exactly my case. I have a USB deivce (on omap-l138) and a general PC as a host running a simple test application, which first writes to the device some amount of bytes and then reads the same amount. Similar application is on the processor. USB device runs at Full speed, transfer type is bulk. I use ARM side to operate the controller and for now I'm NOT using DMA.

    The situation is like this: when I transfer relatively small amount of bytes (e. g. 100-1000 packets of 500 bytes) all transfers go well, but when I try to transfer more (e.g 10000 packets of 500 bytes) the controller reads and then sends back somewhat 1000-2000 packets and then stops generating interrupts. After this I observe the controller registers content and always have UNDERRUN bit set and sometimes FIFOFULL and RXREADY bits. Also INTRRX and INTRTX registers (I use them to handle the interrupt) have bits set related to the used endpoints - sometimes only for RX or TX endpoint, sometimes for both. So interrupt event on the endpoints seemingly had occured but interrupt was not propagated to the CPU. At the same time ARM Int. Controller seems to be configured properly and all interrupts are enabled.

    Maybe the controller is somewhat overhelmed with data and I should try DMA for the operation. Still my application now is relatively simple, so I think I have enough time to service interrupts.

    Thanks and best regards.

  • Hi,

    OK. What is your setting of CTRLR[UINT] bit?

    Best regards, Zegeye

  • Hi,

    OK. What is your setting of CTRLR[UINT] bit?

    Best regards, Zegeye

  • Hello.

    CTRL[UINT] bit is set to 1.

    One potential source of the problem maybe be that I use USB Stack from IAR PowerPac OS and only implement lower level procedures that operates the controller hardware according to PowerPac documentation. Since I have no source code of PowerPac USB, only binary libs, I only approximatly know how it works. E. g. for transfering a packet I use a PowerPac function, to which number of bytes and a pointer to the data buffer are passed, and it in turn organizes the transfer (splits the packet if it is larger than MaxPacketSize of the endpoint, etc.) and calls routines that operate the controller.

    Activity on the bus for each data packet is as follows:

    • IN-DATA empty packet from host to device            (this I don't know what for)
    • OUT-DATA packet from host to device with data  (the host writes data to the device as it should)
    • OUT-DATA empty packet from device to host
    • IN-DATA packet from device to host with data       (the device returns data to the host)
    • <and then the same for next packet>

    I discovered that the sutiation I described in the post above happens when packets larger than MaxPacketSize are transfered. When I transfer packets smaller than MaxPacketSize and so there is no packet splitting, all transactions go well. But small amount of large packets are also transmitted properly.

    Thanks.

  • Hi,

    On your previous reply, you used previous prost to reply and the information is going to be tough to follow. Please reply to the last post.

    For convienience reasons, I have copied your reply below and will follow up with mine. Thanks for your understanding.

    ------------------------------ Start ------------------

    Hello.

    CTRL[UINT] bit is set to 1.

    One potential source of the problem maybe be that I use USB Stack from IAR PowerPac OS and only implement lower level procedures that operates the controller hardware according to PowerPac documentation. Since I have no source code of PowerPac USB, only binary libs, I only approximatly know how it works. E. g. for transfering a packet I use a PowerPac function, to which number of bytes and a poiner to the data buffer are passed, and it in turn organizes the transfer (split the packet if it is larger than MaxPacketSize of the endpoint, etc.) and calls routines that operate the controller.

    Activity on the bus for each data packet is as follows:

    • IN-DATA empty packet from host to device            (this I don't know what for)
    • OUT-DATA packet from host to device with data  (the host writes data to the device as it should)
    • OUT-DATA empty packet from device to host        (this may be ACK from the device)
    • IN-DATA packet from device to host with data       (the device returns data to the host)
    • <and then the same for next packet>

    I discovered that the sutiation I described in the post above happens when packets larger than MaxPacketSize are transfered. When I transfer packets smaller than MaxPacketSize and so there is no packet splitting, all transactions go well. But small amount of large packets are also transmitted properly.

    Thanks.

    ------------------------------ end -------------------

    Can we do the followings?

    Let's us either perform a read only or a write only transfer. The Underrun and the FIFOFULL bits are set on IN and OUT transactions respectively.

    For the Underrun condition to exist, the Host has requested data from the c6747 device and the application has not furnished the data by the time the request came. So, the device will send a null packet to the Host and sets the Underrun bit. The application needs to clear this bit and loads data into the FIFO and set the TXPKTRDY bit field to continue. You might want to use Double Buffering to insure that you are not missing a request. Do this and see if that clears the Underrun condition.

    FIFOFULL bit get set when the host sends data and previous sent data is still residing within the FIFO and there is no room for the newly sent data. When the application reads/services the received data it will clear automatically. Double Buffering also helps here allowing you some additional time in between servicing.

    You should not touch the DataToggle bit once you enabled the endpoint.

    Just to reiterate. Perform only a Read or Write transfer and let us see how it behaves. When it stops functioning, get the info on the PERI_TX/RXCSR, TX/RXMAXP, etc register settings.

    Best regards, Zegeye

     

  • Hi,Zegeye

     

    I'm now developing a host on 6747 usb2.0 module .I'd like to achieve a host which can communicate with a mouse.

    I now can't make 6747 entry into host mode even i pull down the USB_ID pin. The DEVCTL reigsters is 0x99 and there is no power in VBUS.

    Please help me to find out the error of my understanding .

    To configure the USB2.0 controller to work in host mode,I should keep USB_ID pin low.Then the conttroller will automatically entry into host mode and drive the 

    USB0_DRVBUS pin high to enable power logic to source power to VBUS.

    Is my understanding right?Is there anyting s/w should do to enter into host mode?

     

    Sorry to trouble you. Thank you very much.

    Best regards,Jun

     

  • Hi,

    I have the same board and I'm new on it. now I want config anad init the usb but I can't i used the same code that u had said but when i compile the codes i recieved a lot of error!

    can you please help me by this?

    best regards,

    tahereh vaezi

  • Hi,Zygeye

    I have figured out my problem.

    BootCfg->CFGCHIP2 |=(0x1<<13);// 00= > Override PHY Values act as host.

     

     

  • Hi all,

    I have a problem with USB. I run ti examples but my pc(win xp) configure the usb as unknown device! what should i do?

    in addition i'm new and i'm working on an EVM OMAP-L137 

    best regards

    Tahereh Vaezi

  • Hi Jun,

    It seems that the core has not assumed the role of a Host.

    Like you mentioned, you need to insure that the USB_ID pin is driven low.

    Assuming that the USB  Controller and PHY are initialized properly, when you set the DEVCTL.SESSION bit, you will force the controller to sample the state of the USB ID pin. If the USB ID is drivne low, it will then attempt to enable the external power source on your board by driving USB_DRVVBUS high. This will also generate an interrupt if the associated enable bit is set/enabled.

    The USB Controller will continually monitor the voltage of the VBUS pin (via the PHY) and it expects for the power to be > 4.4 V (idealy it has to be >=  4.75V to account for the drop on voltage).

    It will also update the DEVCTL and POWER registers bit fields.

    Having said that, the value you are observing (DEVCTL = 0x99 is displaying a Device Mode operation) is contradicting with the above. Most likely you are overriding the PHY configuration. Make sure you are not overriding it. See CFGCHIP2 Register definition.

     BootCfg->CFGCHIP2 |= 0x00008000;      // Hold PHY in Reset
     // Drive Reset for few clock cycles
     for (i=0; i<50; i++);
     // RESET: Release PHY from Reset
     BootCfg->CFGCHIP2 &= 0xFFFF7FFF;   // Release PHY from Reset

     // OTGMODE
     BootCfg->CFGCHIP2 &= 0xFFFF9FFF; // 00=> Do Not Override PHY Values

     // PHYPWDN
     BootCfg->CFGCHIP2 &= 0xFFFFFBFF; // 1/0 => PowerdDown/ NormalOperation
     // OTGPWRDN
     BootCfg->CFGCHIP2 &= 0xFFFFFDFF; // 1/0 => PowerDown/ NormalOperation
     // DATAPOL
     BootCfg->CFGCHIP2 |= 0x00000100; // 1/0 => Noraml/ Reversed
     // SESNDEN
     BootCfg->CFGCHIP2 |= 0x00000020; // 1/0 => NormalOperation/ SessionEnd
     // VBDTCTEN
     BootCfg->CFGCHIP2 |= 0x00000010; // 1/0 => VBUS Comparator Enable/ Disable

    /* Configure PHY PLL use and Select Source
    */
     // REF_FREQ[3:0]
     BootCfg->CFGCHIP2 |= 0x00000002; // 0010b => 24MHz Input Source

     // USB2PHYCLKMUX
     BootCfg->CFGCHIP2 |= 0x00000800; // 1/0 => Internal/External(Pin) Select Internal Clock Sorce on QT, TBD for Silicon

     // PHY_PLLON
     BootCfg->CFGCHIP2 |= 0x00000040; // 1/0 => On/ Off

    Best regards, Zegeye

     

     

  • Hi Tahereh,

    This is a loaded question. Can't say where you are having a problem.

    It seems that you have done the initialization part correctly. The PC is recognizing you as a target.

    Question is are you respoinding to the request from the PC? Probably not.

    Start by insuring that your target is configured as a Device. See DEVCTL register setting.

    Check if you are getting a RESET interrupt. This will also insure that you are configured as a Device.

    The user does not need to do much to insure Endpoint 0 resource has been furnished. This is because the h/w by default has all the required resource available and if the host starts issuing request right after invoking a Bus Reset, the h/w is ready to accept the request.

    Once the request is accpeted, the c6747 device will generate an Endpoint 0 interrupt and your applciation should respond to the Host request.

    Where exactly are you having a problem?

    Best regards, Zegeye

  • Hi Zegeye,

    I can't understand what's the problem!

    is there any example only for usb detection? do the USB need any driver to install in pc?

    Tahereh Vaezi,

  • Tahereh,

    On what platform are you experiencing the issue - BIOS/Linux?  If Linux pl. do mention the version or better move the latest released version.

    Pl. ensure that you have correctly configured the USB port when compiling the platform.  I assume you are using the standard L137 EVM.

    regards

    swami

  • Hi Tahereh,

    No, there is no driver that is needed to be installed on a PC?

    We do not have a sample program other than a sample guide that we supply with the User's Guide.

    By detection, do you mean an actual detection or enumeration? I think you have already passed on your detection phase. In stead of assuming, it might be best to reconfirm the stages you have confirmed working. You will have to break it down as to where you are having a problem. You might be doing this already but it does not hurt to mention it. You will need to work on this gradually small step at a time.

    Were you able to get a RESET interrrupt? (This confirms that the Device detection has been done by the PC/Host.)

    If Yes, then, were you able to get an Endpoint 0 Interrupt?

    If you get these two interrupts, you can use this as an indication that you will need to work on your software.

    Having said that, please let me know at what stage you are in so that we can better assist you with your issue.

    Best regards, Zegeye

  • Hi

    I run the "usbdevmsc" example and I can connect to the board and now I can detect the SD CARD.

    Thanks,

    Tahereh Vaezi

  • Yan said:

     

    I am trying on the same thing and having similar problems on C6745 custom board. The first problem is that the usb_isr isn't called when I plug in the usb to usb0. 

    One difference is that I am using internal PLL clock from 24M xtal, so my USB2PHYCLKMUX = 1.

    My tcf file has

    bios.HWI.instance("HWI_INT6").interruptSelectNumber = 19;

    bios.HWI.instance("HWI_INT6").fxn = prog.extern("usb_isr");

    My usb_init and usb_isr are at http://docs.google.com/View?id=ddskp47r_35gwz3qhhs

     

    Hello Yan:

    I'v got the same problem ,and I don't know how to deal with the interrupts with USB module,I can't access  http://docs.google.com/View?id=ddskp47r_35gwz3qhhs,

    so please send me your code ,I wanna it as a reference.Thank you!

    Best regards

    Calm

  • Hello Kanas,you've got usb as a device running on evmomapl137 dsp side,right?

    Would please send me a copy of your code,cause I got stuck in bus enumeration.Thanks a lot!

    My email address is:

    calm.sanny@gmail.com

    Best regards

    Calm

  • Zegeye Alemu said:

    Hi Tahereh,

    No, there is no driver that is needed to be installed on a PC?

    We do not have a sample program other than a sample guide that we supply with the User's Guide.

    By detection, do you mean an actual detection or enumeration? I think you have already passed on your detection phase. In stead of assuming, it might be best to reconfirm the stages you have confirmed working. You will have to break it down as to where you are having a problem. You might be doing this already but it does not hurt to mention it. You will need to work on this gradually small step at a time.

    Were you able to get a RESET interrrupt? (This confirms that the Device detection has been done by the PC/Host.)

    If Yes, then, were you able to get an Endpoint 0 Interrupt?

    If you get these two interrupts, you can use this as an indication that you will need to work on your software.

    Having said that, please let me know at what stage you are in so that we can better assist you with your issue.

    Best regards, Zegeye

     

    Hello Zegeye:

    I'v been trying to make the usb2.0 OTG port work as a devie for a peroid of time.But I got stuck at the enumeration stage,I can guarantee  that mu initialization is right!

    I just don't know how to enable globle Interrupt and map USB interrupt to the correct Event,and how to handle my usb_isr?Cause the TI USB2.0 User Guide don't talk about

    these ,hope you can answer my quesion!Besides how to read and write FIFO,User Guide did't talk it either!

    Best regards

    Calm

     

  • Hi Calm,

    Are you having two part questions, one being USB enumeration and other being interrupt handling? You will need to be very specific with your questions. It is very general.

    General Interrupt handling is not discussed within the USB User's Guide. It is discussed within the CPU Guide. See the DSP Megamodule Reference, chapter 7, http://focus.ti.com/lit/ug/sprufk5a/sprufk5a.pdf. As far the part that is related to the USB peripheral, it is discussed within the USB User's Guide. See Initialization routine displaying the steps required to configure Interrupt from the USB Controller side. 1. Decide whether to handle interrupt in PDR mode or Non-PDR Mode. See CTRLR.UINT register. 2. Based on the above, then you need to program INTSMASK(SET/CLR)R registers at the wrapper level and INT(USB/TX/RX)E registers at the core level. Note that you can use polling method, by polling interrupt flag registers INTMASKEDR/INTSRCR registers and work on polling part until you get your interrupt handler working.

    If your question has to do with USB enumeration, let me know at what stage you are stuck. We have a thorough discussion on enumeration within the User's Guide. Sections 2.7.1.1 and section 2.7.2.1 discuss control transfer operation on both peripheral/device and host roles operations. http://focus.ti.com/lit/ug/sprufm9h/sprufm9h.pdf.

    Let me know if you need more info to get you going.

    Best regards, Zegeye

  • Zegeye Alemu said:

    Hi Calm,

    Are you having two part questions, one being USB enumeration and other being interrupt handling? You will need to be very specific with your questions. It is very general.

    General Interrupt handling is not discussed within the USB User's Guide. It is discussed within the CPU Guide. See the DSP Megamodule Reference, chapter 7, http://focus.ti.com/lit/ug/sprufk5a/sprufk5a.pdf. As far the part that is related to the USB peripheral, it is discussed within the USB User's Guide. See Initialization routine displaying the steps required to configure Interrupt from the USB Controller side. 1. Decide whether to handle interrupt in PDR mode or Non-PDR Mode. See CTRLR.UINT register. 2. Based on the above, then you need to program INTSMASK(SET/CLR)R registers at the wrapper level and INT(USB/TX/RX)E registers at the core level. Note that you can use polling method, by polling interrupt flag registers INTMASKEDR/INTSRCR registers and work on polling part until you get your interrupt handler working.

    If your question has to do with USB enumeration, let me know at what stage you are stuck. We have a thorough discussion on enumeration within the User's Guide. Sections 2.7.1.1 and section 2.7.2.1 discuss control transfer operation on both peripheral/device and host roles operations. http://focus.ti.com/lit/ug/sprufm9h/sprufm9h.pdf.

    Let me know if you need more info to get you going.

    Best regards, Zegeye

    Hi Zegeye,

    Thanks for your hits.I'm still working on interrupt handling today,and I got some useful tricks to myself,although I dind't see Reset interrrupt at all.

    Situation went like this,I run the initailization routine as the User's Guide and then plug usb wires when initailization finished,then I got unknown device from my pc(Win xp),

    then I use USBView to see the device,It says DeviceFailedEnumeration.

    Then I go to see the registers in CCS,the DEVCTL is 0x99,it indicated the device is in session,right?

    Then I check the INTSRCR,it is 0x00050000,this really puzzled me!If I got a EP0 interrupt,wouldn't  be 0x01?And the INTRUSB is 0xFF,did a reset interupt occured?

    Pl. give me some suggestions,as how to enable global interrupt of DSP in order to Handle USB Core interrupts,I just know USB0_INT maps to Event 19 and occupy INT_6,

    I do wanna know what exactly to do to receive a reset interrupt correctly?

    Best regards

    Calm

     

  • Krzysztof Kanas said:

    Hi, I finaly figured out my problem, if anyone is interested. I was using old code example - after switching to new one everyting runs fine.

    Code from

    sprugc5.pdf

    void usb_init2()
    {
    Uint16 I;
    CSL_SyscfgRegsOvly BootCfg = (CSL_SyscfgRegsOvly)(CSL_SYSCFG_0_REGS);

    CSL_Usb_otgRegsOvly usbRegs = (CSL_Usb_otgRegsOvly)CSL_USB_0_REGS;
    // **************************************************************************
    // Configure DRVVBUS Pin to be used for USB; Muxed with GPIO4[15]=Bank4 GP15
    // PINMUX9[4]=1 and PINMUX9[7]=0
    // **************************************************************************
    // MAKE SURE WRITE ACCESS KEY IS INITIALIZED PRIOR TO ACCESSING ANY OF THE
    // BOOTCFG REGISTERS.
    BootCfg->KICK0R = 0x83e70b13; // Write Access Key 0
    BootCfg->KICK1R = 0x95A4F1E0; // Write Access Key 1
    BootCfg->PINMUX9 |= (0x1 << 4); // Set bit4 Pinmux9 for USB Use
    BootCfg->PINMUX9&= 0xFFFFFF7F; // Clear bit 7 Pinmux9 for USB Use
    // Reset the USB controller:
    usbRegs->CTRLR |= 0x00000001;
    // RESET: Hold PHY in Reset
    BootCfg->CFGCHIP2 |= 0x00008000; // Hold PHY in Reset
    // Drive Reset for few clock cycles
    for (I=0; I < 50; I++);
    // RESET: Release PHY from Reset
    BootCfg->CFGCHIP2&= 0xFFFF7FFF; // Release PHY from Reset
    /* Configure PHY with the Desired Operation */
    // OTGMODE
    BootCfg->CFGCHIP2&= 0xFFFF9FFF; // 00= > Do Not Override PHY Values Device Host operation
    // PHYPWDN
    BootCfg->CFGCHIP2&= 0xFFFFFBFF; // 1/0 = > PowerdDown/ NormalOperation 1 00 0000 0000
    // OTGPWRDN
    BootCfg->CFGCHIP2&= 0xFFFFFDFF; // 1/0 = > PowerDown/ NormalOperation 10 0000 0000
    // DATAPOL
    BootCfg->CFGCHIP2 |= 0x00000100; // 1/0 = > Normal/ Reversed
    // SESNDEN
    BootCfg->CFGCHIP2 |= 0x00000020; // 1/0 = > NormalOperation/ SessionEnd
    // VBDTCTEN
    BootCfg->CFGCHIP2 |= 0x00000010; // 1/0 = > VBUS Comparator Enable/ Disable
    /* Configure PHY PLL use and Select Source */
    // REF_FREQ[3:0]
    BootCfg->CFGCHIP2 |= 0x00000002; // 0010b = > 24MHz Input Source
    // USB2PHYCLKMUX: Select External Source
    BootCfg->CFGCHIP2&= 0xFFFFF7FF; // 1/0 = > Internal/External(Pin)
    // PHY_PLLON: On Simulation PHY PLL is OFF
    BootCfg->CFGCHIP2 |= 0x00000040; // 1/0 = > On/ Off
    /* Wait Until PHY Clock is Good */
    while ((BootCfg->CFGCHIP2 & 0x00020000) == 0); // Wait Until PHY Clock is Good.


    // Enable high-speed
    CSL_FINS(usbRegs->POWER,USB_OTG_POWER_HSEN,1);

    // Enable Interrupts
    // Enable interrupts in OTG block
    usbRegs->CTRLR&= 0xFFFFFFF7; // Enable PDR2.0 Interrupt
    usbRegs->INTRTXE = 0x1F; // Enable All Core Tx Endpoin Tx/Rx interrupt
    usbRegs->INTRRXE = 0x1E; // Enable All Core Rx Endpoin
    // Enable all interrupts in OTG block
    usbRegs->INTMSKSETR = 0x01FF1E1F;
    // Enable all USB interrupts in MUSBMHDRC
    usbRegs->INTRUSBE = 0xFF;
    // Enable SUSPENDM so that suspend can be seen UTMI signal
    CSL_FINS(usbRegs->POWER,USB_OTG_POWER_ENSUSPM,1);
    //Clear all pending interrupts
    usbRegs->INTCLRR = usbRegs->INTSRCR;
    CSL_FINS(usbRegs->POWER,USB_OTG_POWER_SOFTCONN,1);
    CSL_FINS(usbRegs->DEVCTL,USB_OTG_DEVCTL_SESSION,1);
    // Invalidate access key by writing bogus value to avoid inadvertent write.

    }


    New code from

    sprufm9b.pdf

     

    void usb_init3()
    {
    Uint16 I;
    volatile Uint32 value =0;
    CSL_SyscfgRegsOvly BootCfg = (CSL_SyscfgRegsOvly)(CSL_SYSCFG_0_REGS);

    CSL_Usb_otgRegsOvly usbRegs = (CSL_Usb_otgRegsOvly)CSL_USB_0_REGS;
    // **************************************************************************
    // Configure DRVVBUS Pin to be used for USB; Muxed with GPIO4[15]=Bank4 GP15
    // PINMUX9[4]=1 and PINMUX9[7]=0
    // **************************************************************************
    // MAKE SURE WRITE ACCESS KEY IS INITIALIZED PRIOR TO ACCESSING ANY OF THE
    // BOOTCFG REGISTERS.
    BootCfg->KICK0R = 0x83e70b13; // Write Access Key 0
    BootCfg->KICK1R = 0x95A4F1E0; // Write Access Key 1
    BootCfg->PINMUX9 |= (0x1 << 4); // Set bit4 Pinmux9 for USB Use
    BootCfg->PINMUX9&= 0xFFFFFF7F; // Clear bit 7 Pinmux9 for USB Use

    // Reset the USB controller:
    usbRegs->CTRLR |= 0x00000001;
    //Wait until controller is finished with Reset. When done, it will clear the RESET bit field.
    while ((usbRegs->CTRLR & 0x1) == 1);
    // RESET: Hold PHY in Reset
    BootCfg->CFGCHIP2 |= 0x00008000; // Hold PHY in Reset
    // Drive Reset for few clock cycles
    for (I=0; I < 50; I++);
    // RESET: Release PHY from Reset
    BootCfg->CFGCHIP2 &= 0xFFFF7FFF; // Release PHY from Reset
    /* Configure PHY with the Desired Operation */
    // OTGMODE
    BootCfg->CFGCHIP2 &= 0xFFFF9FFF; // 00= > Do Not Override PHY Values
    BootCfg->CFGCHIP2 |= (0x2<<13); // 00= > Override PHY Values act as device
    // PHYPWDN
    BootCfg->CFGCHIP2 &= 0xFFFFFBFF; // 1/0 = > PowerdDown/ NormalOperation
    // OTGPWRDN
    BootCfg->CFGCHIP2 &= 0xFFFFFDFF; // 1/0 = > PowerDown/ NormalOperation
    // DATAPOL
    BootCfg->CFGCHIP2 |= 0x00000100; // 1/0 = > Normal/ Reversed
    // SESNDEN
    BootCfg->CFGCHIP2 |= 0x00000020; // 1/0 = > NormalOperation/ SessionEnd
    // VBDTCTEN
    BootCfg->CFGCHIP2 |= 0x00000010; // 1/0 = > VBUS Comparator Enable/ Disable * Configure PHY PLL use and Select Source */
    // REF_FREQ[3:0]
    BootCfg->CFGCHIP2 |= 0x00000002; // 0010b = > 24MHz Input Source
    // USB2PHYCLKMUX: Select External Source
    BootCfg->CFGCHIP2 &= 0xFFFFF7FF; // 1/0 = > Internal/External(Pin)
    // PHY_PLLON: On Simulation PHY PLL is OFF
    BootCfg->CFGCHIP2 |= 0x00000040; // 1/0 = > On/ Off



    /* Wait Until PHY Clock is Good */
    while ((BootCfg->CFGCHIP2 & 0x00020000) == 0); // Wait Until PHY Clock is Good.
    #ifndef HS_ENABLE
    // Disable high-speed
    CSL_FINS(usbRegs->POWER,USB_OTG_POWER_HSEN,0);
    #else
    // Enable high-speed
    CSL_FINS(usbRegs->POWER,USB_OTG_POWER_HSEN,1);
    #endif
    // Enable Interrupts
    // Enable interrupts in OTG block
    usbRegs->CTRLR &= 0xFFFFFFF7; // Enable PDR2.0 Interrupt
    usbRegs->INTRTXE = 0x1F; // Enable All Core Tx Endpoints Interrupts + EP0 Tx/Rx interrupt
    usbRegs->INTRRXE = 0x1E; // Enable All Core Rx Endpoints Interrupts
    // Enable all interrupts in OTG block
    usbRegs->INTMSKSETR = 0x01FF1E1F;
    // Enable all USB interrupts in MUSBMHDRC
    usbRegs->INTRUSBE = 0xFF;
    // Enable SUSPENDM so that suspend can be seen UTMI signal
    CSL_FINS(usbRegs->POWER,USB_OTG_POWER_ENSUSPM,1);
    //Clear all pending interrupts
    usbRegs->INTCLRR = usbRegs->INTSRCR;

    // Set softconn bit
    CSL_FINS(usbRegs->POWER,USB_OTG_POWER_SOFTCONN,1);
    while ((usbRegs->DEVCTL & 0x01) == 0); //Stay here until controller goes in Session.
    }

     

    Hi,Kanas,

    I try to use the function usb_int3(),but I got blow errors

    [usb_init.c] "C:\Program Files\Texas Instruments\C6000 Code Generation Tools 6.1.9\bin\cl6x" -g -pdsw225 -fr"E:/Calm/OMAP-L137/ICETEK-OMAPL137-KB-V1.1/project/evmomapl137_v1/dsp/tests/usb0_reg2/Debug" -d"_DEBUG" -mv6740 -@"Debug.lkf" "usb_init.c"
    "usb_init.c", line 33: error: expected a field name
    "usb_init.c", line 34: error: expected a field name
    "usb_init.c", line 35: error: expected a field name
    "usb_init.c", line 36: error: expected a field name

    And probably related to

    CSL_SyscfgRegsOvly BootCfg = (CSL_SyscfgRegsOvly)(CSL_SYSCFG_0_REGS);
    CSL_Usb_otgRegsOvly usbRegs = (CSL_Usb_otgRegsOvly)(CSL_USB_0_REGS);

    Any suggestions please?

    Best regards

    Calm

     

  • Hi,Zeyege,

    I do wonder why my question is not answered yet?

    I try BIOSUSB for the last two days,I'm happy to see Jungo is incorporated with TI,and they have really developed an awesome

    component for TI DSP dev kit.I try to modify the source code of BIOSUSB to suit my own apply,but find it hard,cause Jungo has

    encapsulated all the things about interface descriptors and endpoint descriptors and all the other device and configuration descriptors

    too well,they just take everything too well!

    My apply is to usb usb2.0 on OMAPL137 to do data exchange with PC,all I need is two endpoints of bulk,of course endpoint0 to do enumeration

    process first.I got stuck on tht stage of EP0 interrupt,my INTSRCR is 0x00050000,and INTRUSB is 0x00.I wonder why TI don't provide a usb firmware of

    OMAPL137 usb2.0,if so,it is really good news to developers.

    By the way,Jungo's MSC and HID demos are great,but leave too little things to the developers,hope you can work out a solution for our solutions!

    Best regards

    Calm

     

  • Calm,

    At this point in time BIOSUSB does not have the capabality to support custom class development.  If you need further assistance on top of BIOSUSB w.r.t custom class develoopment pl. contact your local TI FAE.

    regards

    swami

  • Hi Calm,

    Sorry you did not make much progress and your question is still open.

    Your question was very general. I repeatedly asked if you had a USB question vs Interrupt question. It seems that you are having issue on both. You will need to read the User's Guides and ask specific questions.

    For e.g., if you read my previous response, I already discussed about handling interrupt at the core level (non-PDR mode) or in PDR mode which is controlled by CTRLR.UINT bit. If you handle interrupt at PDR level, you should not use the core interrupt flags. You only need to enable Interrupt at the core level. You do not want to read any interrupt flag because you might perform the read and clear interrupt. Since in your configuration you have enabled PDR mode of interrupt handling the core interrupt has already been read onto the top level registers like INTSRCR, INTMSKEDR (if corresponding bits are enabled), etc which forced the core interrupt bit fields to be cleared.

    The 5 within the INTSRCR is informing you that you have received a RESET and SUSPEND interrupt. If you have not setup your interrupt handler, you can use polling method to start with USB part of your development. I will have someone reply to your question in mapping the USB Interrupt with the DSP Handler. This type of questions should not be posted as USB related issues. It seems to me that the Host has seen your device and it has Resetted your USB peripheral. Your code should service that interrupt (since your interrupt handler is not working) in polling method. You call your RESET handler function and you clear the interrupt by writing onto INTCLRR register. You have got your initialization part working, so try to get the SETUP stage of the first enumeration request going. Once you get this going, the rest is very similar to this task and it will get easier.

    You need to be able to understand with the steps required to implement the USB protocol. This is clearly communicated within the User's Guide. If you are having a pb or question with part of the information, please feel free to ask.

    I will forward for others to reply on your interrupt handing part of your question.

    Best regards, Zegeye

     

     

  • Calm,

    For the interrupt-specific question, you may want to consider creating a new post in the BIOS forum.

    -Tommy

  • Hi,

    You probably have a CSL build that is not compatible with the code. You can easily fix the problem by doing the followings:

    You can expand the include directory within your project and eye ball the right header file. There will be a handful CSL header files with the word 'boot' associated with them. Open up those files and observe if they contain the Boot Configuration Registers. You will see the structure definition there.

    Same for the USB2.0.

    Here is an example of the header files and how you can re-declare the BootCfg and ubRegs pointers definitions.

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Here is an example for USB2.0

    /**************************************************************************\
    * Register Overlay Structure
    \**************************************************************************/
    typedef struct  {
      volatile Uint32 REVR;
      volatile Uint32 CTRLR;
      volatile Uint32 STATR;
      volatile Uint32 EMUR;
      volatile Uint32 RNDISR;
       :

       :

      CSL_Usb_otgQmemregionRegs QMEMREGION[8];
      volatile Uint8 RSVD19[3968];
      CSL_Usb_otgQctrlRegs QCTRL[64];
      volatile Uint8 RSVD21[1024];
      CSL_Usb_otgQstatRegs QSTAT[64];
    } CSL_Usb_otgRegs;

    CSL_Usb_otgRegs *usbRegs= (CSL_Usb_otgRegs *)(0x01E00000);

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Here is an example for the Boot Configuration file.

     

    /**************************************************************************\
    * Register Overlay Structure
    \**************************************************************************/
    typedef struct  {
        volatile Uint32 REVID;
        volatile Uint8 RSVD0[4];
        volatile Uint32 DIEIDR0;
        volatile Uint32 DIEIDR1;
        volatile Uint32 DIEIDR2;
        volatile Uint32 DIEIDR3;
        volatile Uint32 DEVIDR0;
        volatile Uint32 DEVIDR1;
        volatile Uint32 BOOTCFG;
        volatile Uint32 CHIPREVIDR;
        volatile Uint32 FEATUREENR;
        volatile Uint32 L2ROMDIV;
        volatile Uint8 RSVD1[8];
        volatile Uint32 KICK0R;
        volatile Uint32 KICK1R;
        volatile Uint32 HOST0CFG;
            :

            :

        volatile Uint32 CFGCHIP2;
        volatile Uint32 CFGCHIP3;
        volatile Uint32 CFGCHIP4;
        volatile Uint32 DFTMMARGINR0;
        volatile Uint32 DFTMMARGINR1;
        volatile Uint32 DFTMPOWER;
        volatile Uint32 DFTRESERVED;
    } CSL_BootcfgRegs;

    CSL_BootcfgRegs *BootCfg = (CSL_BootcfgRegs *)(0x01C14000);

     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    The above should remove your errors.

    Best regards, Zegeye

  • Hi,swami,

    I'm really sorry to hear that BIOSUSB is just going here,not having the capabality to support custom class development.

    Now I'm back on the journey of implementing the usb protocal by writing usb firmware on OMAPL137,and I do make little

    progress.

    By the way,does the local TI FAE provide support on such development?

    regards

    Calm

  • Hi Zeyege,

    Thanks for your reply.I'm happy to tell you that I change my code as Kanas's usb_init3(),and it turns out to work.

    Now the INTSRCR is 0x000D0001,and I thought that I've got a Setup Packet received by the EP0 fifo,am i right?

    You just mention the PDR and non-PDR,but I can't find more detailed info in the User's Guide,what does PDR mean?

    If I get my firmware work under PDR mode,then it has nothing to do with the DSP interrupt handling,thus I will just write a

    while(1) and call my dispacher,right?

    I will review the User's Guide again,below is my code that doesn't work,hope you can figure out my problem:

    void usb0_init()
    {
     // Initial of USB2.0 OTG of OMAPL137
     Uint16 i;
     Int32 pinmux;
     pinmux = PINMUX9;
     // Configure the DRVVBUS Pin for USB
     // Note Privilege Key is first
     KICK0R = 0x83E70B13;
     KICK1R = 0x95A4F1E0;
     PINMUX9 = (pinmux & 0xFFFFFF0F) | 0x10;   // Pinmux for DRVVBUS 

     // Rest the USB Controller
     USB0_CTRLR = 0x00000001;
     
     // Wait until controller is finished with Reset
     while((USB0_CTRLR & 0x1) == 1);
     
     // Reset: Hold PHY in Reset
     CFGCHIP2 |= 0x00008000;  // Hold PHY in Reset
     // Drive Reset for a while
     for (i=0; i<50; i++);
     // Reset: Release PHY from Reset
     CFGCHIP2 &= 0xFFFF7FFFF; // Release PHY from Reset
     
     // Configure PHY with Desired Operation
     // OTGMODE
     CFGCHIP2 &= 0xFFFF9FFF;  // Do Not Override PHU Values
     // PHYPWDN
     CFGCHIP2 &= 0xFFFFFBFF;  // 1/0 PowerDown/ NormalOperation
     // OTGPWDN
     CFGCHIP2 &= 0xFFFFFDFF;  // PowerDown/ NormalOperation
     // DATAPOL
     CFGCHIP2 |= 0x00000100;  // Normal/ Reversed
     // SESNDEN
     CFGCHIP2 |= 0x00000020;  // NormalOperation/ SessionEnd
     // VBDTCTEN
     CFGCHIP2 |= 0x00000010;  // VBUS Comparator Enable/ Disable
     
     // Configure PHY PLL use and Select Source
     // REF_FREQ[3:0]
     CFGCHIP2 |= 0x00000002;  // 0010b => 24MHz Input Source 
     // USB2PHYCLKMUX: Select Internal Source since I've got no External source
     CFGCHIP2 = (CFGCHIP2 & 0xFFFFF7FF) | 0x00000800;  // 1/0 => Internal/External(Pin)

     // PHY_PLLON: On Simulation PHY PLL is OFF
     CFGCHIP2 |= 0x00000040;  // 1/0 => On/ Off
     
     // Wait Until PHY Clock is Good
     while((CFGCHIP2 & 0x00020000) == 0);
     
     // enable high-speed negotiation
     #ifndef HS_ENABLE
       // Disable high-speed
       //CSL_PINS(USB0_POWER,USB0_POWER_HSEN,0);
       USB0_POWER = (USB0_POWER & 0xDF) | 0x20;
     #else
       // Enable high-speed
       //CSL_PINS(USB0_POWER,USB0_POWER_HSEN,1);
       USB0_POWER = (USB0_POWER & 0xDF) | 0x00;
     #endif
     
     // Enable Interrupts
     // Enable interrupts in OTG block
     USB0_CTRLR &= 0xFFFFFFF7;  // Enable PDR2.0 interrupt
     USB0_INTRRXE  = 0x1E;   // Enable All Core Rx Endpoints Interrupts + EP0 RX/TX interrupt
     USB0_INTRTXE  = 0x1F;   // Enable All Core Tx Endpoints Interrupts
     // Enable all interrupts in OTG block
     USB0_INTMSKSETR = 0x01FF1E1F;
     
     // Enable all USB interrupts in MUSBMHDRC
     USB0_INTRUSBE = 0xFF;
     
     // Enable SUSPENDM to that suspend can be seen UTMI signal
     //CSL_PINS(USB0_POWER,USB0_OTG_POWER_ENSUSPM,1);
     USB0_POWER = (USB0_POWER & 0xFE) | 0x01;
     
     // Clear all pending interrupts
     USB0_INTCLRR = USB0_INTSRCR;

     #if (_USB_PERIPHERAL_)  // defined if need to function as Peripheral
       // Set softconn bit
       //CSL_PINS(USB0_POWER,USB0_OTG_POWER_SOFTCONN,1);
       USB0_POWER = (USB0_POWER & 0xBF) | 0x40;  // bit 6
       while((USB0_DEVCTL & 0x01) == 0);  // Wait until controller goes in Session
     #else
       // Start a session
       //CSL_PINS(USB0_DEVCTL,USB0_OTG_DEVCTL_SESSION,1);
       USB0_DEVCTL = (USB0_DEVCTL & 0xFE) | 0x01;
     #endif 
    }

    although I've got a right code,I wonder what is  wrong with mine?I didn't use cslr.

    regards

    Calm

  • Hi Zegeye,

    I've got the code work by just kicking out a header file "evmomapl137.h",but I don't know the detailed reason.

    Is there some conflicts?

    Thanks anyway!

    regards

    Calm

  • tlee said:

    Calm,

    For the interrupt-specific question, you may want to consider creating a new post in the BIOS forum.

    -Tommy

     

    Hi Tommy,

    Thanks for your hits.I will post the prob in the BIOS forum.

    -Calm

     

  • Calm,

    Working with a FAE would enable you to make progress but getting the required support from internal TI teams.  Though I am not perview to BIOSUSB development plans I would definitely recommend you to work with the FAE to get access to any information that would simplify your developoment.  Writing firmware ground up is a tedious task and TI does provide you with reference software (in u-boot and Linux kernel) to enable such development.  On the other hand if you could get access to (by working with the FAE) to some sort of custom class enablement over BIOSUSB I belive this would address your immediate needs.  Pl. explore whether such possibility exists.

    regards

    swami 

  • swami said:

    Calm,

    Working with a FAE would enable you to make progress but getting the required support from internal TI teams.  Though I am not perview to BIOSUSB development plans I would definitely recommend you to work with the FAE to get access to any information that would simplify your developoment.  Writing firmware ground up is a tedious task and TI does provide you with reference software (in u-boot and Linux kernel) to enable such development.  On the other hand if you could get access to (by working with the FAE) to some sort of custom class enablement over BIOSUSB I belive this would address your immediate needs.  Pl. explore whether such possibility exists.

    regards

    swami 

     

    Hi swami,

    I will try my best to finish the tedious task,writing usb firmware for the OMAPL137,and I will try to contact FAE.

    Honestly,I don't know exactly what FAE mean,but thanks anyway,I wil try!

    regards

    Calm

     

  • Calm,

    FAE- Field Application Engineer/Local TI Sales/Marketing contact

    regards

    swami

  • Hi ,Zegeye.

      I'm still working cppi dma of 6747 usb module .I try to use ep2 as a bulk recevie endpoint to receive data from pc .

    When i configure the cppi dma ,I can't get it work .

    I found that when I set RX_ERROR_HANDLING bit of RXGCR registers,there were starvation errors.

    When I clear it, PC side can continually send packet to dsp,but dsp seems to drop the packet because lack of descriptor.

    So my question is that how to configure the descriptor.

    My configuration is as follow ,is this right?

           cppi_desc[0].HPDword0 = 0;
            cppi_desc[0].HPDword1 = 0;      //
            cppi_desc[0].HPDword2 = 0x00000000 | USBRX_COMPLETIONQUEUE;
            cppi_desc[0].HPDword3buffLength =        
            cppi_desc[0].HPDword6orgBuffLength = 512;
            cppi_desc[0].HPDword4buffAdd =
            cppi_desc[0].HPDword7orgBuffAdd = (Uint32)rxBuffer0;
            cppi_desc[0].HPDword5nextHBDptr = 0;

    If I put descriptor in sdam ,is it  in-chip?

    And I noticed that ,in the guidance pdf of 6747 usb 2.0 on page 84,there is the example code.

    There is a remark saying that "Rx submit queue are assigned by H/W but they are not port specfic."

    So shall i assign submit queue in S/W?

    That's all .Thank you very much.

    Best regards,Jun