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.

TMS320F28379D: WAIT_BOOT Mode

Part Number: TMS320F28379D
Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

Hello everyone.

I'm developing SW for F28379D. I have two projects - one project for CPU1 and the other is for CPU2. Both projects are to reside in Flash memory. CPU2 must be started by command from CPU1, just like it is in Concerto MCU. So program flow for CPU2 is supposed to be like this: BOOTROM -> IDLE (Waiting for START command from CPU1) -> START (void main (void)). CPU1 in its turn has such flow: BOOTROM -> void main (void) -> Preparations -> Command to CPU2 to start.

As i have understood, CPU2 must be started in WAIT_BOOT mode to hit such program flow. During emulation (I use F28379D launchpad for debug) i set the register at memory address of CPU2 0x0D00 to "0x025A". This means that CPU2 must enter IDLE mode after bootrom is done. That's ok.

But when CPU1 performs "IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);" function, it returns STATUS_FAIL. The reason why this funciton breaks down is in IPCBOOTSTS register. After CPU2 completes its bootrom it sets IPCBOOTSTS to 0x0D03. IPCBootCPU2 checks it like this:

    //
    // If CPU2 has already booted, return a fail to let the application
    // know that something is out of the ordinary.
    //
    bootStatus = IPCGetBootStatus() & 0x0000000F;

    if(bootStatus == C2_BOOTROM_BOOTSTS_C2TOC1_BOOT_CMD_ACK)
    {
        returnStatus = STATUS_FAIL;
        return returnStatus;
    }

The macro C2_BOOTROM_BOOTSTS_C2TOC1_BOOT_CMD_ACK is set to 3 in "F2837xD_Ipc_drivers.h", so i get STATUS_FAIL.

Could you please help me? What am i doing wrong?

  • Disona,

    CPU2 boot ROM is not resetting the boot status on debug reset runs. So what is happening is on the first run the boot status is set to 0x2, indicating that CPU2 boot ROM is ready to receive IPC command and on the second run the boot status is set as boot status |= 0x1, so this becomes 0x3 which conflicts with the status Boot command ACK.

    This is a change from C-boot ROM on Concerto and it was because we wanted to carry on the past error status between resets if user haven't had a chance to handle it and if the reset is happening because of the error status, we still have the information between resets. Also we are running out of status bits so we couldn't allocate a different value to boot command ack.

    In stand-alone mode once the device boots to application on CPU2, user code needs to set the boot status to 0x0 after reading it and taking any action needed.

    While debugging, you can have GEL script write 0x0 to boot status on target reset or have it reset manually.

    Also, there is another status bit that the code snippet that you put above is ignoring. The proper way to check if CPU2 has already booted or not is to check bit 31 of boot status is set, in addition to the check you have. if ((boot status & 0x80000000) && (boot status & 0x3)), then CPU2 has completed boot. But then again the application has to reset the boot status to 0x0 after it is done checking what happened during boot before the application started.

    The ROM source code for F2837xD is available in controLSuite and C2000Ware at below locations, you can load symbols using the provided ROM COFF files and check the behaviour.

    C:\ti\controlSUITE\libs\utilities\boot_rom\F2837x_revb\revb_rom_sources
    C:\ti\c2000\C2000Ware_1_00_02_00\libraries\boot_rom\f2837xd\revB\rom_sources

    Hope this helps.

    Best Regards
    Santosh Athuru
  • I'm sorry, Santosh, I'm not sure I have understood you.

    If i set "WAIT_BOOT" mode for CPU (I do it with GEL scripts, by the way), CPU2 enters "IDLE" loop after it finishes its bootrom. CPU1 must wake CPU2 up by setting some special bits (no matter here), but it cannot do with IPCBootCPU2(x) function because of some bitfiled vs. define conflict. It's true both for emulation and standalone mode. Is this correct? So it seems to me that WAIT_BOOT mode is somehow... not working correctly with IPCBootCPU() funciton.

    So if i need to stop CPU2 while CPU1 makes some preparations, you suggest to set "BOOT_TO_FLASH" for CPU2. When it finishes bootrom and goes to "void main (void)" i should place smth like

    int main_cpu2 (void) {
        // Tell CPU1 that we finished CPU2 bootrom and wait for aknowledge
        IPCLtoRFlagSet(IPC_FLAG20);
        while(IPCLtoRFlagBusy(IPC_FLAG20)){
        	// wait
        };
        //...

    and on the CPU1 side place smth like

        // Wait for CPU2 to finish his boot, and then aknowledge
        while(IPCRtoLFlagBusy(IPC_FLAG20) == 0){
        	// wait
        };
        IPCRtoLFlagAcknowledge(IPC_FLAG20);
        //...

  • Disona,

    sorry for the confusion, let me explain below. In short the boot rom status from CPU2 boot ROM is not reset in CPU2 boot ROM (unless CPU2 boot ROM is executed after an XRSn or POR). So in between debug resets and run, the CPU1 could be reading a stale status from CPU2 boot ROM.

    Disona said:

    If i set "WAIT_BOOT" mode for CPU (I do it with GEL scripts, by the way), CPU2 enters "IDLE" loop after it finishes its bootrom. 

    This is fine. Note that CPU2 by default enters wait boot. Also please add a write of 0x0 to location 0x0000_0002 (section 3.9.10.2 of device TRM) before you set the WAIT BOOT from GEL script. In stand-alone runs this location is supposed to be cleared by applications after it is read.

    Disona said:

    CPU1 must wake CPU2 up by setting some special bits (no matter here), but it cannot do with IPCBootCPU2(x) function because of some bitfiled vs. define conflict. It's true both for emulation and standalone mode. Is this correct? So it seems to me that WAIT_BOOT mode is somehow... not working correctly with IPCBootCPU() funciton.

    You are right, the IPCBootCPU2(x), should have been written different, the C2_BOOTROM_BOOTSTS_CTOM_BOOT_CMD_ACK is only valid if bit 31 (MSB) is also set in the boot status.

    Can you change the IPCBootCPU2(x) function as below on your CPU1 side to below? You can optimize the below logic as you see fit. Before returning failure I'm checking for bit 31 being set or not. If it is also set then return failure and if not then don't return failure but continue.

    Once you get to the CPU2 application, copy the boot status value at location 0x0000_0002(section 3.9.10.2 of device TRM) to a local/global variable and clear the boot status (location 0x0000_0002, as defined in section 3.9.10.2) , so the stale status will not be remaining RAM. This is cleared by boot ROM only on a POR or XRSn. This is the change from Concerto C28x Boot ROM and it is done so to help applications know about the boot ROM status in between non XRSn/POR resets.

    once you take care of this the IPCBOOTCPU2(x) should function proper in both stand-alone and emulation runs.

    --------

    //

    // If CPU2 has already booted, return a fail to let the application
    // know that something is out of the ordinary.
    //
    bootStatus = IPCGetBootStatus() & 0x0000000F;

    if(bootStatus == C2_BOOTROM_BOOTSTS_C2TOC1_BOOT_CMD_ACK)

    {

    bootStatus = ((uint32_t)(IPCGetBootStatus() & 0x80000000)) >> 31U; //check if MSB is set as well

    if(bootStatus)

       {

           returnStatus = STATUS_FAIL;

            return returnStatus;

      }
    }

    -----

    Disona said:
    So if i need to stop CPU2 while CPU1 makes some preparations, you suggest to set "BOOT_TO_FLASH" for CPU2. When it finishes bootrom and goes to "void main (void)" i should place smth like

    Adding another level of sync in the application after sending the boot mode command from CPU1 is needed if CPU1 is doing any more set up after sending the boot mode command. Both the applications can use sync mechanisms like you put depending on the application needs. 

    Please let me know if above suggestions solve the problem you are seeing.

    Best Regards

    Santosh Athuru

  • Thank you very much.
    That's what i needed.
  • Thanks for confirming, I've flagged the IPC driverlib call for fix.

    Best Regards
    Santosh Athuru