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 HPI bootload



We are having troubles with getting our HPI bootload working.  We verified that the HPI is working.  We can even use CCS and an emulator to verify that the host device is copying over the contents of the COFF file.

Here is the procedure from SPRAB04C  (Using the D800k001 Bootloader).

3.2 Host Port Interface (HPI) Boot
HPI boot happens from the HPI0 peripheral in 16-bit mode. The boot sequence to boot from HPI is listed
below:
• Bootloader interrupts the host by setting the HINT bit, in the HPIC register, to inform that it is ready and
that the host can start loading the application image to device memory.
• Host acknowledges this interrupt by clearing the HINT bit.
• Host loads the application image to device memory and writes application entry point to location
0x11800000 in device memory.
• Host interrupts bootloader by setting DSPINT bit in HPIC register to inform that loading of application
image is complete.
• Bootloader acknowledges host by clearing DSPINT bit.
• Bootloader reads application entry point (written by host) from address 0x11800000 and branches to it.

I have the host device run through these steps and halt just before the host sets the DSPINT bit.  I can connect to the C6747 and see that code is loaded and address 0x11800000 contains the address of _c_int00.  In fact, if I use the CCS disassembly window and set PC to the address stored in 0x11800000, click run, the program will execute.  But the program does not execute if we let the host continue by setting the DSPINT.  The host verifies that the DSP clears the DSPINT bit but after that it seems the program halts or crahses.

if I connect CCS to the C6747 after the host attempts to fully load and run the DSP, I can see that the address stored at 0x11800000 has been cleared to 0.

First, can someone verify that the correct procedure is indeed to write just the address at 0x11800000 and NOT a branch instruction to _c_int00? 

And if that is the correct procedure, what could we be doing wrong???  It seems like we're close - just the last step isn't working.

thanks!

Mike

  • Mike,

    During HPI boot the bootloader inside the ROM spins in effectively a while(1) loop waiting for the host to trigger the DSPINT bit. When it detects this bit being set, it then reads the branch address the host wrote, and then executes the branch to that address. It sounds like you have this part taken care of properly.

    When you connect to the target via CCS do you have a GEL file loaded? A significant number of "it runs fine from CCS but not standalone" cases I have worked with stem from the GEL file configuring something that the code does not properly manage. This may be a good starting point to see if your code requires a peripheral to be configured automatically (EMIF???).

  • Tim,

    Great suggestion.  When I remove the GEL and connect to the target, the code will not execute properly.  It only executes properly when the GEL script runs on connection to the target.   So what's the GEL doing that we need to do?

    Now, if I take the same .out file and use AISgen to create an "AIS bootable image", it works.  In this method, we use the SPI flash boot method and the dsp_spi_flash_writer program.  I simply use CCS to run the flash program, then set the boot pins for SPI flash boot, and reset the board.  Everything works, PLL settings, pinmux configurations, and sub-module power-ups.

    So why would this .out file work for flash boot but not for HPI boot?  Is there some extra step we need to do with the HPI bootload?  And when I say the same .out file, it's not exactly the same.  For the HPI bootload, we run the .out file through the strip6x utility to reduce the size of the .out file. This shouldn't matter, should it?

    This code runs entirely from L2 RAM.  Our target has SDRAM (via EMIFB) but this memory is currently not used.  The main function sets the PLL, configures the pinmux registers, and performs appropriate PSC calls.  So what are we missing??

    thanks!

    Mike

  • Hi Mike,

    Mike said:
    Great suggestion.  When I remove the GEL and connect to the target, the code will not execute properly.  It only executes properly when the GEL script runs on connection to the target.   So what's the GEL doing that we need to do?

    The gel does pinmux configs, PLL cofigs, EMIf, etc. You can actually copy the initializations made by the GEL and adapt them into your C code like suggested in the page:

    http://tiexpressdsp.com/index.php/Flashing_the_C6747_EVM

    Mike said:

    Now, if I take the same .out file and use AISgen to create an "AIS bootable image", it works.  In this method, we use the SPI flash boot method and the dsp_spi_flash_writer program.  I simply use CCS to run the flash program, then set the boot pins for SPI flash boot, and reset the board.  Everything works, PLL settings, pinmux configurations, and sub-module power-ups.

    So why would this .out file work for flash boot but not for HPI boot?  Is there some extra step we need to do with the HPI bootload?  And when I say the same .out file, it's not exactly the same.  For the HPI bootload, we run the .out file through the strip6x utility to reduce the size of the .out file. This shouldn't matter, should it?

    This code runs entirely from L2 RAM.  Our target has SDRAM (via EMIFB) but this memory is currently not used.  The main function sets the PLL, configures the pinmux registers, and performs appropriate PSC calls.  So what are we missing??

     When you make the ais file, I believe some configurations like PLL (maybe pin mux as well) are added by the app using AIS protocol, so the ais file will have more initializations indeed. So if your program does dot run in CSS without a GEL file then you need to double check your initializations. Also make sure that you do not have optimization set in the file that makes the initializations, specially PLL (see comments about optimization on page http://tiexpressdsp.com/index.php/Flashing_the_C6747_EVM)

     

     

  • Mariana and Tim,

    Thanks for your help.  This solved one problem but uncovered another.

    The problem with HPI bootload was the PLL configuration.  My function in main followed the procedure in sprufk4b to change the PLL multiplier (e.g. sect. 6.2.2.2).  I needed to follow the procedure to initialize PLL from PLL Power Down (e.g. 6.2.2.1) which is the condition on power-up reset.

    Getting this to work uncovered a secondary problem.  My UART1 peripheral was not operational.  I could create and initialize the peripheral, but when I called a GIO_write to UART1 (e.g. uartMdSubmitChan()), code execution would not return.  Actually I can step through the PSP source code of uartMdSubmitChan, but somewhere between the return of this function and the return to my application layer code, the program hangs.

    This does NOT happen when I use the GEL script  OnTargetConnect function.  Digging into this, I found when the GEL executes this script command, the code does not hang:

    PSC1_lPSC_enable(0, 12);

    Note that I do this same thing in main() with the following call:

      result = Psc_ModuleClkCtrl(Psc_DevId_1, CSL_PSC_UART1, TRUE);
    if (IOM_COMPLETED != result) {
    LOG_printf(&LOG_warning, "UART1 Module Enable Failure.");
    return;
    };

    I even replaced this code with the copy/paste version from the GEL script and it still didn't work. To make it work, I have to add module clk/pwr-on code into my program BEFORE code execution reaches main. So I added the GEL code to my function uart1_user_init() function, which is the init function called in my tconf file:

    
    
    bios.UDEV.instance("uart1").initFxn = prog.extern("uart1_user_init");
    I do it here since this code will get executed before program execution reaches main.  Here is that init function:
    void uart1_user_init()
    {
    #if 1
    #define PSC1_BASE 0x01E27000
    #define PSC1_MDCTL (PSC1_BASE+0xA00)
    #define PSC1_MDSTAT (PSC1_BASE+0x800)
    #define PSC1_PTCMD *(unsigned int*) (PSC1_BASE + 0x120)
    #define PSC1_PTSTAT *(unsigned int*) (PSC1_BASE + 0x128)

    *(unsigned int*) (PSC1_MDCTL+4*12) = (*(unsigned int*) (PSC1_MDCTL+4*12) & 0xFFFFFFE0) | 0x0003;
    PSC1_PTCMD = 0x1<<0;
    while( (PSC1_PTSTAT & (0x1<<0) ) !=0) ; /*Wait for power state transition to finish*/
    while( (*(unsigned int*)(PSC1_MDSTAT+4 * 12) & 0x1F) !=0x3);
    #endif
    Uart_init();
    uart1_params = Uart_PARAMS;
    uart1_params.hwiNumber = 8;
    uart1_params.opMode = Uart_OpMode_DMAINTERRUPT;
    }

    So the question is why do I have to do this??? Also note that my other peripherals do not need this provision. My application runs SPI1, McASP1, HPI, EDMA, and all of these
    peripherals get powered on in main. Even SPI1, which uses the same GIO_write() BIOS API, works fine when the power-on is performed in main().
    Is this a known issue and documented somewhere?


    If you want me to move this new issue to a different forum post, I can do this as it now seems unrelated to HPI bootload.

    thanks again,
    Mike