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.

USB brings down device when booting from FLASH

Hi,

I use the C5515 and I want to realize USB communication.


I have 2 versions of USB code - let's call them custom and HID - which I've developped by taking USB-DMA-interrupt example code for the C5515 and adapting it to my own needs. If I run things by emulator (i.e. code composer studio) both versions work as they should.

But when I try the versions by booting from FLASH, I have the following behavior:

- the HID version works correctly
- the custom version brings down the C5515 at USB configuration/enumeration

What is strange is that in both versions I use quite the same enumeration firmware (except that I have different descriptors). The main difference in the code is after enumeration how to do data transmission : in HID version I write to FIFOs directly, in custom version i use CSL USB-DMA functions.

Do you know what might be wrong or missing with the custom version? Does it miss any device configuration? In main() I have the following to configure the C5515:

 

// clock setup

    IDLE_PCGCR = 0;
    IDLE_PCGCR_MSW = 0;
    CONFIG_MSW = 0x0;
    PLL_CNTL1 = 0x8BE8;
    PLL_CNTL2 = 0x8000;
    PLL_CNTL3 = 0x0806;
    PLL_CNTL4 = 0x0000;
    while ( (PLL_CNTL3 & 0x0008) == 0);
    CONFIG_MSW = 0x1;

// ...

    CSL_FINST(CSL_SYSCTRL_REGS->EBSR, SYS_EBSR_PPMODE, MODE6);
    CSL_FINST(CSL_SYSCTRL_REGS->EBSR, SYS_EBSR_SP1MODE, MODE2);
    CSL_FINST(CSL_SYSCTRL_REGS->EBSR, SYS_EBSR_SP0MODE, MODE2);


// ...

   gpio_handle = GPIO_open(&gpio_obj,&gpio_status);
    if((NULL == gpio_handle) || (CSL_SOK != gpio_status)) {
        return FALSE;
    }
    GPIO_reset(gpio_handle);
    gpio_handle->baseAddr->IODIR1 = 0x7000;        // enable write on pins 14:12
    gpio_status = GPIO_write (gpio_handle, CSL_GPIO_PIN13, 1);
    if (CSL_SOK != gpio_status) {
        return FALSE;
    }

// ... send some data on GPIO ...

// ...

// USB config...

// Initialize the Bulk Endpoint IN 1

// ... custom version
status = USB_initEndptObj(CSL_USB0, hEpObjArray[2], CSL_USB_IN_EP1, CSL_USB_INTR, 512, eventMask, NULL);

// ... HID version
status = USB_initEndptObj(CSL_USB0, hEpObjArray[2], CSL_USB_IN_EP1, CSL_USB_INTR, 64, eventMask, NULL);

// Initialize the Bulk Endpoint OUT 2

// ... custom version
status = USB_initEndptObj(CSL_USB0, hEpObjArray[3], CSL_USB_OUT_EP2, CSL_USB_INTR, 512, CSL_USB_EVENT_EOT, NULL);

// ... HID version

status = USB_initEndptObj(CSL_USB0, hEpObjArray[3], CSL_USB_OUT_EP2, CSL_USB_INTR, 64, CSL_USB_EVENT_EOT, NULL);

 

Do you need more code? Or any ideas what and how I could test and check?

Thank you for all your help.

Best regards,

Andreas

 

  • Andreas;

    Is your "customer code" able to pass the USB enumeration? Or after the successful enumeration, the data transfer failed?

    Regards

    Wen

  • Wen,

    When running from code composer studio, the "custom code" passes enumeration and data transfer is okay.
    When running from FLASH, enumeration fails. In fact, the DSP get's stopped somewhere in the init_usb function that is basically a copy from USB-DMA example code.

    Regards,

    Andreas

     

  • Andreas;

    The enumeration part of USB-DMA should be exactly the same as HID case, since endpoint0 will not use DMA to transfer data. Can you replace the USB_init part by the one from HID? And to see if this works.

    Regards

    Wen

  • Could this be another case where the setup in the GEL file must be coded into the firmware so that running from Flash starts with the same settings as running from the debugger?

  • Good point. Brian.

    Adriea; make sure the PLL is running at 60 Mhz or higher. Since your boot up from Flash, the PLL programming part must be done by a C program. 

    Regards

     

    Wen

  • Brian and Wen,

    as stated in my original posting: my program contains code to set up PLL to run at 120MHz before calling the init_usb function. I don't think this causes the problem since the same PLL setup code is used for the "custom" USB and for the HID USB.

    But I'm currently checking to replace "custom" enumeration with same settings as for HID (except for the descriptors). In order to reduce confusion : the HID enumeration uses DMA as well. It's just the data transfer in my HID USB code that writes to FIFOs without DMA.

    I think it might be a packet size, byte swap or memory space initialization issue that isn't obvious if running from ccs.

    Any further ideas? i might install a software USB analyzer to see where things hang...

    Andreas

     

  • Andreas,

    Are you calling CSL_init()?  I don't see it in your snippet.

    It seems like you're running the exact same code, but it works from CCS and not from Flash.  Any time the exact same code does not run from Flash, I suspect that GEL is handling some initialization that is missing from the Flash startup.  The PLL is not the only state that could be different.  You need to check everything relevant.  Memory space initialization could be one such thing.  You might also suspect the parameters that you're using to create the Flash image, or perhaps the linker model you're using when building the code, since the Flash loader is different than the debug loader.  Yet another suspect is the EMIF configuration if your FIFOs are physical hardware memory outside the DSP.

    On the other hand, your comments seem to indicate that you're not running exactly the same code in both places.  You should certainly try the exact same code in CCS to prove that it works.  But I might be confused by your "custom" versus HID comments.  Are you trying four different firmwares?  CCS custom class, CCS HID class, Flash custom class, Flash HID class?

    Have you tried breaking in to the debugger when running from Flash, so you can check the settings register bits for all relevant hardware?  For every peripheral that you use, USB, DMA, Timer, EMIF, etc., you should be fully versed in the desired settings for proper operation, and then you can check whether all of the settings are identical when running from Flash.

    I have actually been successful using the debugger to trace the entire Flash bootloader procedure until the point where my firmware starts.  This can be painstaking, but it should reveal why the same code does not produce the same results.

    P.S. Descriptors can be some of the most difficult aspects of USB development.  If you have a tool like USB Prober in Mac OS X, this can reveal a great deal about whether your descriptors are valid.  I think that Windows has a similar USB_Viewer.exe, or a similar name, but it is not quite as extensive as Apple's tool.

  • Hi Brian,

    Thank you for your detailed answer. I am running 2 different versions of firmware, "custom" and "HID". And I try them to run from either from CCS or from FLASH.
    I am perfectly aware of your first comment w.r.t. to system setup by GEL which might be lacking when running from FLASH. I will try to have a closer look at registers by using the debugger even when running from FLASH -- as you said. Thank you for this hint. Before I was thinking using the debugger when running from FLASH is impossible.;)

    But I have to correct myself : contrary to what I posted : enumeration works fine even when running from FLASH. It is the data transfer to brings down the DSP!

    Finally : in my CSL there's nothing such as CSL_init--I use C5515 which has different CSL from like C5509 or similar. But I've called USB_init. Maybe I'd have to add a call to DMA_init?!? I'll try...

    Best regards, and a lot of thanks for your help.

    Andreas

     

  • I've been checking the GEL file that I load in CCS:

    OnTargetConnect()
    {
        GEL_Reset();
        C5505_MapInit();
        ProgramPLL_120MHz_clksel0();
        GEL_TextOut("Target Connection Complete.\n");
    }

     

    I don't know what's the GEL_Reset() doing. All contents in ProgramPLL_120MHz_clksel0() are the same as in my C code. But I did not include any of the C5505_MapInit() in my C code. The C5505_MapInit() contains:

    /* Memory map based on MP/MC value=0 (BOOTM[2:0]=0).    */
    C5505_MapInit() {
        GEL_MapOn();
        GEL_MapReset();
        /*Program Space*/
        /* DARAM */
        GEL_MapAdd(0x0000C0,0,0x001F40,1,1);    /* DARAM0 */
        GEL_MapAdd(0x002000,0,0x002000,1,1);    /* DARAM1 */

    // ... long list of GEL_MapAdd ...
    }

    I don't know exactly what those GEL_MapOn(), GEL_MapReset and GEL_MapAdd's are doing but I suppose there here to prevent the debugger of accessing memory that doesn't exist.

    I've seen some other functions in the GEL file : Peripheral_Reset(), SDRAM_INIT() and SRAM_INIT(). But in fact there not called when I launch my program from CCS so I suppose there not of any meaning for my firmware? Or should I include those contents in my firmware as well?

    And last question : might there be some problem with the C5515/C5505 conflict with CSL and/or compilation? Since I have the C5515 but I provide the -v5505 flag for building.

     

    Thanks for all your help.

    Best regards,

    Andreas


  • Okay now it really becomes weird. I've been checking registers when running the same firmware once from CCS and once from FLASH.
    The main differences are:

     

    CCS
    ------
    CLKOFF = 0
    IFR1 = 0x0010
    IER1 = 0x169A
    USB registers:
    INTSRCR1 = 0x0002
    INDEX_TESTMODE = 0x06C8
    MAXPAYLOAD = 0x4
    CTRL1D24 = 0x0001

    CCS
    ------
    CLKOFF = 1
    IFR1 = 0x0000
    IER1 = 0x148A
    USB registers:
    INTSRCR1 = 0x0000
    INDEX_TESTMODE = 0x03FS
    MAXPAYLOAD = 0x3
    CTRL1D24 = 0x0000

     

    The strange thing is that when I:
    -> run from FLASH
    -> then connect to target via CCS (with all the GEL stuff commented out in the OnTargetConnect GEL function)
    -> run the target (because it has been stopped by debugger access)
    -> close CCS

    everything works fine!!! so what's going on here? is it my CCS and/or CGTools responsable for this strange behavior?
    CCS v4.1.0
    CGTools v.4.3.5

    Any ideas? I'm really stuck here. I appreciate any help.

    Thank you very much.

    Best regards,

    Andreas

     

  • Every peripheral register has a Reset value that is thoroughly documented.  But the interesting thing is that the ROM is responsible for loading your code from Flash, and the ROM changes certain peripheral settings in order to do its work.  Each bootloader source can have a different effect on the registers, e.g., EMIF might be enabled or it might be left disabled.  I broke down and stepped through the ROM code using the debugger, and made notes about the peripheral register settings that were changes (specific to the C5506), and then I made sure that my firmware sets every bit that needs to be different from the Reset value -or- the value set by the ROM bootloader.

    So far, my firmware seems to run the same from Flash or CCS, but I still have problems preventing me from completing the firmware, so I can't completely duplicate your scenario.

    Are you booting from USB or Flash?  I would expect that the ROM would leave the USB peripheral registers in their Reset state unless you've selected the USB bootloader.

  • Hi Brian,

    Thank you very much for your reply. I think after your good explanation I got the point  So... The thing I don't know is how to step through ROM code by debugger. For example, if I run the program from CCS it's the USB bootloader - am I right? But the just before I press the run button in CCS, the whole USB bootloader  code is already executed - no (since the whole program is already in RAM and PC points to _c_int00). And if I boot from FLASH, i simply turn on power and bootloader starts to do its work and a few ms later whole code is in RAM and peripherals are set up.

    So may I ask: how did you step through the ROM by debugger? Sorry if this question might be too "newbie" but I am still quite new to all the "low"-level programming.

    If you want I can provide you my usb communication code so you can better reproduce. I think the way I communicate with the device from a host app point of view might be problematic as well since I use usblib for the "custom" code and I do reads and writes (both on device and host) whereas for the HID code I only do reads on the host and writes on the device... But I am not too sure about this point.

    I really think - based on what I've seen and what you've written - boot from CCS and FLASH do different peripheral initializations and therefore - for HID it might be "sufficient" but for my "custom" protocol it is not and brings down the DSP.

    Anyway. Thank you so much for your help up to now - hope that I'll solve this problem asap.

    Best regards,

    Andreas

     

  • The debugger has a menu option that will Reset the Processor.  This electrically resets the TMS320 via your JTAG Emulator and the debugger ends up pointing to ROM code.  You can then examine the Reset defaults for all registers and step through the bootloader process.  Be prepared that it can be tough to do this without source code, but it's possible.  I do not recommend this as your first solution, but if all other avenues are exhausted then at least it's something to try.

    Meanwhile, you at least have some clues showing that the register bits are different in each scenario.  Therefore I would suggest that you add code to your firmware to ensure that the proper peripheral initialization is carried out.  Since the bootloader and GEL file setup all run before your firmware, then your firmware has the last word.  You should be able to override all peripheral settings in your firmware initialization before you start the USB or other main operations.

    I have the DSK5509 and a custom C5506 board of my own design, therefore I cannot run your C5515 USB firmware.  The High Speed USB peripheral on the C5515 is not code compatible with the Full Speed USB peripheral on the C5506/9A.  Thanks for the offer, though.

  • I finally found the problem: it was the MPORT being idled by default which can be found by inspecting Silicon Errata or by "reverse engineering" boot ROM.

    USB works well now when booting from FLASH.

  • Hello Andreas,

    Now, I am suffering a similar problem. I am trying to boot from flash on c5515usbstk and I started with booting uled and usb examples of USB Stick. I have added InitSystem() function to the code for pll setting.

    void InitSystem(void)
    {
    Uint16 i;
    // PLL set up from RTC
    // bypass PLL
    CONFIG_MSW = 0x0;

    #if (PLL_100M ==1)       //100M is selected
    PLL_CNTL2 = 0x8000;
    PLL_CNTL4 = 0x0000;
    PLL_CNTL3 = 0x0806;
    PLL_CNTL1 = 0x8BE8;

    #elif (PLL_12M ==1)
    PLL_CNTL2 = 0x8000;
    PLL_CNTL4 = 0x0200;
    PLL_CNTL3 = 0x0806;
    PLL_CNTL1 = 0x82ED;
    #elif (PLL_98M ==1)
    // 98.304 MHz
    PLL_CNTL2 = 0x8000;
    PLL_CNTL4 = 0x0000;
    PLL_CNTL3 = 0x0806;
    PLL_CNTL1 = 0x82ED;

    #endif

    while ( (PLL_CNTL3 & 0x0008) == 0);
    // Switch to PLL clk
    CONFIG_MSW = 0x1;

    // clock gating
    // enable all clocks
    IDLE_PCGCR = 0;
    IDLE_PCGCR_MSW = 0xFF84;

    // reset peripherals
    PER_RSTCOUNT = 0x02;
    PER_RESET = 0x00fb;
    for (i=0; i< 200; i++);

    }

    With the addition of this function uled example is booted and worked successfully. However, similar to your situation, when I add this function to the usb example, it does not work even in CCS debug mode. Stops at the same point with your program (usb init). I tried your suggestion enabling MPORT bu it didn't worked for my situation. Do you recommend any point of view for me? 

    Regards.

    Yusuf

  • Hi  everyone, Am facing similar problem.

    Actually am trying sample LED code to boot from c5535 EEPROM. I now the procedure to convert the .out file to .bin.

    Here i need is to include initialization part to sample lcd code. As you fixed this earlier by adding the initsystem() to main code. Can you please provide the total sample led program which having initialization to boot from EEPROM.

    Thanks,

    Kranthi.