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.

Changing Boot Mode configuration on TMS320F28377D

Other Parts Discussed in Thread: TMS320F28377D

Programming or erasing (running any flash API functions) of flash on CPU2 is not possible on TMS320F28377D MCU if the flash of CPU1 is not programmed with the proper application. If the flash of CPU1 is blank, then the device is trying to boot from flash which does not contain any valid code and hence ends up hitting an illegal opcode resulting in the flag C1_BOOTROM_IN_AN_ITRAP being set. This can be read from the location 0x2C (TRM Page 541). If I program customer application file, I am able to call flash API functions for CPU2. Otherwise, the Program Counter does not move when I am trying to execute code on CPU2. 

In the Technical Reference Manual, it is described that it is possible to avoid booting from flash by writing into the address 0xD00 either EMU_KEY value to other than 0x5A or to change the EMU_BMODE = 0x02 (WAIT BOOT) but it does not seem to help. I am trying to modify EMU_KEY or EMU_BMODE immediately after entering debug mode through CPU1 by writing 0x000000AA into DC_STRBS.

  • Hi Avinash,

      In the Technical Reference Manual, it is described that it is possible to avoid booting from flash by writing into the address 0xD00 either EMU_KEY value to other than 0x5A or to change the EMU_BMODE = 0x02 (WAIT BOOT) but it does not seem to help. I am trying to modify EMU_KEY or EMU_BMODE immediately after entering debug mode through CPU1 by writing 0x000000AA into DC_STRBS.

    Please note that this is only applicable for debug purpose. Idea here is to BOOT the device (as per BOOTPIN settings) then update the value into this location, reset the device and re-run the BOOTROM code to emulate the required bootmode for debug. This is not applicable for Ist time boot.

    Regards,

    Vivek Singh

  • Hi Vivek,

    I have tried what you proposed but still doesn't work. After initialization, by default, boots into flash (0xD00 = 0x5A03). Then, I modify this value to 0x5A02. After which I am resetting the device (tried in two different ways).

    1. If I only toggle RESET pin, then I am still able to read the value I wrote (0x5A02). However, the C1_BOOTROM_IN_AN_ITRAP flag is still set (read from addr. 0x2C) and I am unable to execute any code on CPU2. Just to be sure, I re-initialized 0x2C to 0 and it remains 0 even after reset which means boot did not happen after writing.

    2. If I also re-initialze the complete init sequence (TSRT, ICEPICK_INIT,etc) then the address 0xD00 becomes 0x5A03.

    I am not sure if there is a way to re-run the BOOTROM code after resetting the device according to step 1.

    Regards,

    Avinassh.

  • Hi Vivek,

    I just wanted to add an update. If I do not stop the core and then change 0xD00 = 0x5A02, then I could see that C1_BOOTROM_IN_AN_ITRAP flag is not anymore set (when 0xD00 = 0x5A03, the flag is set but when I change 0xD00 = 0x5A02, the flag is not set anymore). I am not sure if the core is always polling boot mode at 0xD00 for modifications. But anyways, neither did that help me to get the code running on CPU2.

    If the CPU1 is programmed, reading the DBGSTAT register on CPU2 has IDLE_FLAG set to 0 and after executing code, EXSM is set to 0 (normal execution).
    In case if the CPU is blank, reading the DBGSTAT register has IDLE_FLAG set to 1 and after executing code, EXSM is set to 1 (execution stops due to break).

    Is there an option to know at what stage the BOOTROM process is currently in and a procedure to stop BOOTROM execution from flash?

    Regards,

    Avinassh.

  • Avinaash,

    I did not understand following statement -

    If I do not stop the core and then change 0xD00 = 0x5A02, then I could see that C1_BOOTROM_IN_AN_ITRAP flag is not anymore set

    How are you setting this location without halting the CPU?

    Please note that CPU2 is put in IDLE_MODE by CPU2 BOOT_CODE and to wake-up CPU2 from IDLE, an interrupt need to be given to CPU2 (which generally is IPC interrupt from CPU1). In your CPU1 application, an interrupt may be getting generated to CPU2 hence it's out of IDLE mode but if no application code then CPU2 will remain in IDLE MODE. So what you are observing is expected.

    Is there an option to know at what stage the BOOTROM process is currently in and a procedure to stop BOOTROM execution from flash?

    Yes, you need to use the "Wait" Boot mode (GPIO72 = 1, GPIO84 = 0) to prevent CPU1 from jumping to Flash.

    Are you using CCS or some other tool?

    Regards,

    Vivek Singh

  • Hi Vivek,

    I am using the same process as writing to RAM except that I am changing the address 0xD00 before I write 0x000080FF into LD_MF_REG_0 register because to me, it made sense that the processor should run in order to take effect of the new boot mode.

    To me, it looked like it was working because if I stop the CPU1 and then change the boot mode, then the flag at 0x2C remains same. I tried clearing them. Then, it remains cleared even after toggling RESET pin. So, it looked like the boot process was never re-run. But if boot mode was modified without stopping CPU1, then the flags at 0x2C gets updated as if the CPU1 is running polling at boot mode locations looking for changes.

    I am already aware of controlling through GPIO pins but unfortunately, at this board, both these pins are connected to high and there are not test points available to change their values. So, I would need to stop jumping to flash by software.

    We are not using CCS debugger. I am using our own debugger from Promik. We provide flashing solutions.

    Note! The only thing I am trying to achieve is to program CPU2 even when CPU1 is blank. If you think the procedure I am trying is not best suited for it, please suggest me some other alternative methods. Would generating an IPC interrupt from CPU1 alone let me run code on CPU2? Because for me, it is not clear why I am unable to run code on CPU2 when CPU1 is blank. Is it because I am not generating IPC interrupt from CPU1 or is it because I am allowing to boot from flash of CPU1 and it hits illegal opcode and crashes?

    Regards,

    Avinassh.

  • Hi Avinassh,

    When CPU1 Flash is blank and BOOTMODE is set for BOOT to Flash then device will be go through reset cycles hence after every reset it'll check the BOOTMODE setting and if value @0xD00 is set for Wait BOOT then it'll not jump to Flash.

    Note! The only thing I am trying to achieve is to program CPU2 even when CPU1 is blank. If you think the procedure I am trying is not best suited for it, please suggest me some other alternative methods. Would generating an IPC interrupt from CPU1 alone let me run code on CPU2? Because for me, it is not clear why I am unable to run code on CPU2 when CPU1 is blank. Is it because I am not generating IPC interrupt from CPU1 or is it because I am allowing to boot from flash of CPU1 and it hits illegal opcode and crashes?

    You don't have to load the code into CPU1 to program the CPU2 but need to wake-up the CPU2 from IDLE mode to perform any operation on CPU2. You can try following steps and see if this helps -

    • Connect to CPU1
    • Connect to CPU2
    • Reset CPU1 (debug reset)
    • Change the value @0xD00 so that CPU1 remain in Wait Mode.
    • Run CPU1.
    • Wake-up CPU2 (this can be done in following way)
      • Halt CPU1 and run into IPC Flash register to generate
      • In CPU2 write into IFR register to generate interrupt

    Now you should be able to run the CPU2 and load the application.

    Regards,

    Vivek Singh

  • Hi Avinaash,

    Were you able to get it working?

    Vivek Singh
  • Hi Vivek,

    No. The issue is still not resolved. I had no time to try the procedure you propsed.I had a few doubts in your procedure mainly to perform a debug request. I still do not know the procedure to read SSR register for performing system reset. Please see below for procedure.

    But, since we were running out of time, we implemented in such a way that CPU1 needs to be programmed first with proper application before programming CPU2.

    I was told about the procedure to perform a system reset  as follows:

    "How do you do a system reset?"

    That depends on what you mean by system reset.  You can reset the debug logic via TLR.  You may be able to do a CPU reset.  You may be able to do a device level reset if the device has an ICEPick router.  But you cannot do something like a board level reset or power on reset.

    To do a CPU reset on the C28x, you follow this basic procedure:

       Set the reset bit in MF1

       Execute a single step on the core (required to actually do the reset)

       Check SSR until you see the reset acknowledged

       Clear the reset bit in MF1

    and the register indexes as follows:

    C28x Register indexes:

       0    XAR0    (32-bit)

       1    XAR1    (32-bit)

       2    XAR2    (32-bit)

       3    XAR3    (32-bit)

       4    XAR4    (32-bit)

       5    XAR5    (32-bit)

       6    XAR6    (32-bit)

       7    XAR7    (32-bit)

       14   SP      (22-bit)

       320  IC      (22-bit)

       6    RPC     (22-bit)

       224  ACC     (32-bit)

       256  P       (32-bit)

       160  XT      (32-bit)

       192  ST0     (16-bit)

       11   ST1     (16-bit)

       12   IER     (16-bit)

       13   IFR     (16-bit)

       9    DBGIER  (16-bit)

       10   DP      (16-bit)

       8    ORIFR   (16-bit)

       (indexes are decimal values)