This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to bootload a C6747 DSP/BIOS applicaion from a SPI0 flash?

Other Parts Discussed in Thread: TPS3820

Hello,

Before creating a DSP/BIOS application I ported the  evm6747 LED example applicaction (with modified LED IO and removal of all printfs). I copied the PINMUX and PSC configuration code from the GEL file (I midified the evm6747 gel file to fit our custom board) and called it from the main function. The program worked with program load by the emulator. Then I generated AIS image and flashed it with the SPI flash application. After setting the boot config pins to SPI0 boot I power cycled the target and everything worked fine.

Then, I wrote my DSP/BIOS application, added the PINMUX & PSC configuration code in the beginning of the main function and created AIS image. Then I tried to boot it from the SPI0 as described previously and nothing worked.

Is there a way to bootload with the chip bootloader while the emulator is connected and put a breakpoint somewhere BEFORE the bootloader jumps to my code to check if it was loaded right to the memory?

How can I debug an application that I bootloaded from the SPI0 flash?

Is it necessary to use a secondary bootloader for applications that execute from the SDRAM? If the answer is yes, where can I find information about a secondary bootloader for C6747?

 

  • E.S. said:
    Then, I wrote my DSP/BIOS application, added the PINMUX & PSC configuration code in the beginning of the main function and created AIS image. Then I tried to boot it from the SPI0 as described previously and nothing worked.

    Did you adapt the led test code to work with DSP/BIOS? Did you test the app you are referring that uses DSP/BIOS running with the emulator (not booting)?

    Did you follow the procedure that is at this page?

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

  • I made a DSP/BIOS application with a task that blinks the LED (we have only one LED on board) using the TSK_sleep function for delays. The source code is given below:

    #include <std.h>
    #include <tsk.h>

    // CSL headers
    #include <ti/psp/cslr/cslr_gpio.h>
    #include <ti/psp/cslr/cslr_syscfg_C6747.h>
    #include <ti/psp/cslr/soc_C6747.h>
    #include <ti/psp/cslr/cslr_psc_C6747.h>


    CSL_SyscfgRegsOvly   sysRegs  = (CSL_SyscfgRegsOvly)(CSL_SYSCFG_0_REGS);
    CSL_PscRegsOvly  psc1Regs = (CSL_PscRegsOvly)(CSL_PSC_1_REGS);
    CSL_GpioRegsOvly  gpioRegs = (CSL_GpioRegsOvly)(CSL_GPIO_0_REGS);


    Void led_task()
    {
     gpioRegs->BANK[GP4].DIR&=~GP4P12;
     for(;;)
     {
      gpioRegs->BANK[GP4].SET_DATA=GP4P12;
      TSK_sleep(500);  
      gpioRegs->BANK[GP4].CLR_DATA=GP4P12;
      TSK_sleep(500);  
     }
    }

    I also added the PINMUX configuration and PSC configuration functions copied from the GEL file in the beginning of main function:

    /*Enable Function for PSC0*/

    void PSC0_lPSC_enable(unsigned int PD, unsigned int LPSC_num) {

     *(unsigned int*) (PSC0_MDCTL+4*LPSC_num) = (*(unsigned int*) (PSC0_MDCTL+4*LPSC_num) & 0xFFFFFFE0) | 0x0003;
     PSC0_PTCMD = 0x1<<PD;
     while( (PSC0_PTSTAT & (0x1<<PD) ) !=0) ; /*Wait for power state transition to finish*/
     while( (*(unsigned int*)(PSC0_MDSTAT+4 * LPSC_num) & 0x1F) !=0x3);
    }

    /*Enable Function for PSC1*/

    void PSC1_lPSC_enable(unsigned int PD, unsigned int LPSC_num) {

     *(unsigned int*) (PSC1_MDCTL+4*LPSC_num) = (*(unsigned int*) (PSC1_MDCTL+4*LPSC_num) & 0xFFFFFFE0) | 0x0003;
     PSC1_PTCMD = 0x1<<PD;
     while( (PSC1_PTSTAT & (0x1<<PD) ) !=0) ; /*Wait for power state transition to finish*/
     while( (*(unsigned int*)(PSC1_MDSTAT+4 * LPSC_num) & 0x1F) !=0x3);
    }

    void Setup_System_Config( )
    {

        KICK0R = 0x83e70b13;  // Kick0 register + data (unlock)
        KICK1R = 0x95a4f1e0;  // Kick1 register + data (unlock)

        PINMUX0  = 0x11111188;  // EMIFB, Check EMU0/RTCK
        PINMUX1  = 0x11111111;  // EMIFB
        PINMUX2  = 0x11111111;  // EMIFB
        PINMUX3  = 0x11111111;  // EMIFB
        PINMUX4  = 0x11111111;  // EMIFB
        PINMUX5  = 0x11111111;  // EMIFB
        PINMUX6  = 0x11111111;  // EMIFB
        PINMUX7  = 0x11111111;  // EMIFB, SPI0
        PINMUX8  = 0x88811111;  // UART2, McASP1, I2C0, I2C1
        PINMUX9  = 0x82882881;  // RMII CLK, McASP0, USB_DRVVBUS, UART2
        PINMUX10 = 0x88888888;  // RMII/ McASP0
        PINMUX11 = 0x82281188;  // McASP1, UART1, McASP0, MDIO (last 2 digits 0x22 for MDIO instead of GPIO)
        PINMUX12 = 0x88888888;  // McASP0 / McASP1
        PINMUX13 = 0x11822888;  // SD / McASP1
        PINMUX14 = 0x11111111;  // SD / EMIFA
        PINMUX15 = 0x11111111;  // SD / EMIFA
        PINMUX16 = 0x11111111;  // SD / EMIFA
        PINMUX17 = 0x81181111;  // EMIFA
        PINMUX18 = 0x11111118;  // EMIFA
        PINMUX19 = 0x00000001;  // EMIFA

        CFGCHIP2 |= 0x00001000; // Enable USB1 clock
    }

     void Setup_Psc_All_On( )
    {
       // PSC0
       PSC0_lPSC_enable(0, 0);
       PSC0_lPSC_enable(0, 1);
       PSC0_lPSC_enable(0, 2);
       PSC0_lPSC_enable(0, 3);  // EMIFA
       PSC0_lPSC_enable(0, 4);
       PSC0_lPSC_enable(0, 5);
       PSC0_lPSC_enable(0, 6);
       PSC0_lPSC_enable(0, 8);
       PSC0_lPSC_enable(0, 9);
       PSC0_lPSC_enable(0, 10);
       PSC0_lPSC_enable(0, 11);
       PSC0_lPSC_enable(0, 12);
       PSC0_lPSC_enable(0, 13);

     // PSC1
       PSC1_lPSC_enable(0, 1);
       PSC1_lPSC_enable(0, 2);
       PSC1_lPSC_enable(0, 3);
     PSC1_lPSC_enable(0, 4);
       PSC1_lPSC_enable(0, 5);
       PSC1_lPSC_enable(0, 6);  // EMIFB
       PSC1_lPSC_enable(0, 7);
       PSC1_lPSC_enable(0, 8);
       PSC1_lPSC_enable(0, 9);
       PSC1_lPSC_enable(0, 10);
       PSC1_lPSC_enable(0, 11);
       PSC1_lPSC_enable(0, 12);
       PSC1_lPSC_enable(0, 13);
       PSC1_lPSC_enable(0, 16);
       PSC1_lPSC_enable(0, 17);
       PSC1_lPSC_enable(0, 20);
       PSC1_lPSC_enable(0, 21);
       PSC1_lPSC_enable(0, 24);
       PSC1_lPSC_enable(0, 25);
       PSC1_lPSC_enable(0, 26);
       PSC1_lPSC_enable(0, 31);
    }

    #endif


    void main()
    {
    #ifdef _BOOTABLE
     Setup_System_Config( );
     Setup_Psc_All_On( );
    #endif
    }

    The code runs perfectly when I download it with the emulator, but when I create a .bin file with AISgen, flash it according to the flashing procedure with spiflash_writer_dsp.out, set the boot config pins to SPI0 flash boot, and try to reboot it, nothing works. I also connected the emulator while power is on, did the connect of the emulator (yes, with the GEL file, and looked into the memory area that was supposed to contain the _c_int00 code and it wasn't there.

    I also built a modified PSP led example (it is the same as original, but toggles the pin that controls the LED on my board, instead of blinking the four LEDS of the evm6747 board), loaded it with the emulator and tested it. Then I made an AIS image and flashed it. Afterwards I set the boot config pins to SPI0 configuration and booted the target board successfully.

     

     

  • E.S. said:
    I also built a modified PSP led example (it is the same as original, but toggles the pin that controls the LED on my board, instead of blinking the four LEDS of the evm6747 board), loaded it with the emulator and tested it. Then I made an AIS image and flashed it. Afterwards I set the boot config pins to SPI0 configuration and booted the target board successfully.

    By this last statement I understand that everything worked when you adapted the PSP example. That is good news and I would say that it is the best way to go.

    Just with the code you used, I can not see anything wrong. Usually, when it works with the emulator and it does not work with the boot is because there is some initialization issue. So you could compare the PSP example with yours and see what other functions it is calling. But again, if you where able to make it work with the PSP example, my suggestion is to do that.

  • Ok, I will do it. Now to some related issues:

    1. Is the on-chip bootloader capable of loading a program (or program segments) into SDRAM (provided that the EMIFB configuration given to the AIS generator is as the same as generated by the GEL)?

    2. How can I debug a program bootloaded from the SPI0 flash?

    3. Maybe still I am doing something wrong. Is it possible to provide a sample DSP/BIOS application for the evm6747 board that blinks a LED and boots form SPI FLASH? Maybe I misconfigured something and it will save me a lot of time. I also have the evm6747 evaluation board so I can test it there and port to my board afterwards. 

    Thanks for your help

  • E.S. said:
    1. Is the on-chip bootloader capable of loading a program (or program segments) into SDRAM (provided that the EMIFB configuration given to the AIS generator is as the same as generated by the GEL)?

    Yes, as long as the EMIF is initialized it can.

    E.S. said:
    2. How can I debug a program bootloaded from the SPI0 flash?

    You can not debug from SPI flash because it is not memory mapped - it does not use EMIF, but SPI.

    E.S. said:
    3. Maybe still I am doing something wrong. Is it possible to provide a sample DSP/BIOS application for the evm6747 board that blinks a LED and boots form SPI FLASH? Maybe I misconfigured something and it will save me a lot of time. I also have the evm6747 evaluation board so I can test it there and port to my board afterwards.

     I do not have it. I will see if someone has it and can send to you. In the meantime, check and compare the initializations'.

  • Well, first thing first:

    1. I think, that my question about debugging a bootloaded from SPI0 program was misunderstood. What is I am really interested in is an address in the bootloader of the instruction that branches to the downloaded code. Then I can stop the processor just before it branches to the application code and verify that the beginning of the code (the _c_int00 funcion in the .sysinit memory section) is really there. Is the source code of the D800K001 bootloader published somewhere?

    2. My findings:

    2.1 The PSP LED example application does not bootload into the IRAM memory area (located at 0x11800000). It is mapped to run from the L3_CBA_RAM memory area (located 0x80000000). This thing avoids IRAM memory usage restriction of the bootloader.

    Using the DK800K001 Bootloader said:
    · Memory Usage: The bootloader uses 16 KB of DSP L2 RAM starting from 0x11800000 for multiple purposes. This memory should not be used by any initialized section of the user application.
    · Decompression Heap: When the compression option is used, the bootloader uses 64 KB of DSP L2 RAM starting from 0x11830000 to allocate heap for the decompression routine. This memory should not be used by any initialized section of the user application.

    The DSP/BIOS default memory configuration maps the program to the start of IRAM which violates these restrictions.

    I will continue in my next post.

  • Please find attached the project that blinks the LEDs and uses DSP/BIOS on the EVM. I was able to generate the ais and boot with this project. I used the configurations and procedures at page: http://tiexpressdsp.com/index.php/Flashing_the_C6747_EVM#Prerequisites

    The only thing that I changed from the default tcf file was to add a heap. I also put a bigger delay between the LEDs blinking to be able to see them. Just put at the same place you have your BSL original LED project so the paths match.

     

    E.S. said:
    1. I think, that my question about debugging a bootloaded from SPI0 program was misunderstood. What is I am really interested in is an address in the bootloader of the instruction that branches to the downloaded code. Then I can stop the processor just before it branches to the application code and verify that the beginning of the code (the _c_int00 funcion in the .sysinit memory section) is really there. Is the source code of the D800K001 bootloader published somewhere?

     You can boot and let the program run, then connect with the emulator, open you project, and do File-> Load Symbols-> Load Symbols Only (point to the .out of your project). After that you can do Debug-> Restart or Go main to see if your program is loaded or not.

    The bootloader code is not open source. 

    led_bios_boot.zip
  • OK, I succeeded to boot your LED application on the evm6747board. Then I ported it to my board (different PINMUX initialization, 50MHz oscillator instead of 20MHz and different pin for the LED) and booted it  successfully.

    Then I changed the software loop delays in the program to TSK_sleep delays and the program got stuck in the delay. After a quick look in the DSP/BIOS configuration I found that the CLK properties (in Scheduling) must be adapted to my parameters. After doing that the program startted to run properly from emulator load but got stuck when it was bootloaded. I commented out all the initializations in the GEL file and connected the emulator. The program stopped somewhere in the middle. Then I continued execution and the LED started to blink.

    I power-cycled the target, with SPI0 boot configuration and emulator hooked into the circuit. Then I connected the emulator with all initialization commented out and loaded the symbols. The program stopped somewhere. I issued CPU reset command and the emulator stopped at the entry to the bootloader. Then I issued a go command and the bootloaded program started to run successfully.

    Is something missing regarding Timer1 (the one used by DSP BIOS) clocking, that need to be done in main, so it will work properly?

  • E.S. said:
    OK, I succeeded to boot your LED application on the evm6747board. Then I ported it to my board (different PINMUX initialization, 50MHz oscillator instead of 20MHz and different pin for the LED) and booted it  successfully.

    Glad to hear that.

    E.S. said:
    Then I changed the software loop delays in the program to TSK_sleep delays and the program got stuck in the delay. After a quick look in the DSP/BIOS configuration I found that the CLK properties (in Scheduling) must be adapted to my parameters. After doing that the program startted to run properly from emulator load but got stuck when it was bootloaded.

    Does that happen using the EVM as well? If you can reproduce it in the EVM is easier for us to help. If you can not, we can try to guess, but it could be something very particular with your hardware.

    E.S. said:
    commented out all the initializations in the GEL file and connected the emulator.

    Make sure that you remove the GEL file from the CCS Setup (right click on the DSP core, select properties and remove the GEL file - you can put it back after) and save the configuration. When you connect with the emulator, if there is a GEL file associated with that configuration, it will run automatically.

    E.S. said:
    The program stopped somewhere in the middle. Then I continued execution and the LED started to blink.

    stopped somewhere in the middle? If you are with the emulator, can't you see where it its?  When it gets stuck you can try "View"-> "Call Stack". Or you could get the address and look at the map file to see if you can locate what is loaded there.

    What do you mean "Then I continued execution" ? You mean you run the program? There are some SW_BREAKPOINT instructions in the code, but they will only be called before the LEDs blink in case there is some failure.

     

    E.S. said:
    Is something missing regarding Timer1 (the one used by DSP BIOS) clocking, that need to be done in main, so it will work properly?

     Hard to say at this point.

    Make sure that ledbioscfg.h is included in the file you call TSK_sleep - not sure if it will make any difference but you could try.

     

    Just fyi, about your prior inquire - 16K of internal RAM for the bootloader, I searched and here is what I found out:

    the bootloader may at max use 32 bytes from start of L2 RAM. However, it is designed to be patchable, where more functionality (or bug fixes) may be added to it at run time through a patch. 16 KB of L2 (including 32 bytes used by the bootloader) is reserved to be used by this patch or by a secondary boot loader. That's the reason we recommend this area not to be used by initialized sections of user application. For example, RBL does not support decompression by default. This feature is added through a patch, which is included automatically in AIS by AISgen tool when decompression option is selected. As of today we have only one patch. So, unless you enable decompression, 16K L2 is not used by boot loader. 

  • OK, everything works now.

    Mariana, please check your example application. I think you didn't check the Reset Timer and TIMMODE checkbox in the DSP/BIOS CLK - Clock Manager Properties configuration window. Also, there might be a bug in the configuration editor that doesn't save it properly.

    Together with that problem, I also had a problem with our Voltage Monitor/ Reset Generator chip. The chip is TI TPS3820-33DBVT. It has watchdog timeout period of 112-310 mS. So short programs(like the ones without DSP/BIOS) were loaded and started properly, but the long programs didn't finish bootload because of a reset from the TPS3820 chip.

    The TPS3820 chip generated the reset signal despite the fact that the WDI input of it was connected to a port that was configured as input at RESET(!) . It means that the C6747 port pin, configured as input, is not pure input. It presents load, or pulls the pin up strong enough to kill the autonomous weak watchdog trigger signal, generated inside the TPS3820.

    So, Mariana, thanks a lot for your efforts. I'm sure, that all the material given in this thread, together with the bootloader internal insights will be a great help for anyone, that starts with the C6747.