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.

CCS/TMS320F28377D: CPU1 flash standalone and CPU2 flash code stuck during BOOT ROM flow [RAM & FLASH execution are OK]

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hi.

I stumbled in a situation where my RAM and FLASH code, started by emulator and loaded in CPU1+CLA and CPU2+CLA, running well but unfortunately when I loading it in FLASH_STANDALONE mode CPU1/CPU2 code stuck! I tried to understand this strange behavior because I loaded a previous FLASH STANDALONE code and this works well. Recently, my actual code is raised in dimension (.text extension in .cmd linker file) while it was debugged in RAM. So, I decided to find the new CPU1 FLASH STAND_ALONE stuck condition by the use of GPIO Test Point motion. Anyway, I follow this post

https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/735910?tisearch=e2e-sitesearch&keymatch=2837x%20CPU2%20doesn%27t%20boot

and I realized that my C2000Ware support was crossed. Now my code using the new “F2837xD_Ipc_Driver_Util.c” with few TI changing;

The salient beginning structure in my code, excluded comment, is:

CPU1:

void main(void)
{
    InitSysCtrl_CPU1();

#ifdef _STANDALONE
#ifdef _FLASH
IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
#else
IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM);
#endif
#endif

#ifdef _FLASH
   InitFlash();
#endif

    DINT;

    InitPieCtrl();

    IER = 0x0000;
    IFR = 0x0000;

    EALLOW;
    PieVectTable.ADCA1_INT = &ADCA_ISR_CPU1;
    PieVectTable.ADCD1_INT = &ADCD_ISR_CPU1;
    PieVectTable.TIMER0_INT = &AD7490_SPI_timer0_isr;
    PieVectTable.EPWM1_INT = &Loop_Epwm1_ISR_CPU1;
    PieVectTable.CANA0_INT = &CanA0_isr;
    PieVectTable.CANB0_INT = &CanB0_isr;

    IER |= M_INT1;
    IER |= M_INT3;
    IER |= M_INT9;
    EDIS;

    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    PieCtrlRegs.PIEIER9.bit.INTx5 = 1;
    PieCtrlRegs.PIEIER9.bit.INTx7 = 1;

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
    PieCtrlRegs.PIEACK.all = 0xFFFF;

    EINT;
    ERTM;

    //  *** WATCHDOG SETTINGS ***
    DisableDog();                       // JUST DO IT in InitSysCtrl_CPU1();

    System_Config_CPU1();

    Init_Vars_CPU1();

    // Spin here until CPU02 is ready
    while(IPCRtoLFlagBusy(IPC_FLAG17) == 0);

    // DEBUG CODE IN FLASH STAND_ALONE MODE
    do
    {
        DELAY_US(100);
        GpioDataRegs.GPCCLEAR.bit.GPIO76 = 1;
        DELAY_US(100);
        GpioDataRegs.GPCSET.bit.GPIO76 = 1;
    }
    while(1); // END DEBUG CODE

    // BACKGROUND LOOP
    for(;;)
    { …

void System_Config_CPU1(void)
{
    Init_GPIO_CPU1();
    Setup_PWM_CPU1();

    EALLOW;
    ClkCfgRegs.XCLKOUTDIVSEL.bit.XCLKOUTDIV = 2; // CPLDCLK = 50MHz
    EDIS;

    InitCpuTimers();            
    Setup_Timer0_CPU1();        

    SPI_A_Init();
    SPI_C_Init();

    AD7490_Init();
    MCP23S17_Init(MCP23S17_ALL_PORT_IN, MCP23S17_ALL_PORT_OUT,  0x00,   0x00);

    DMA_Init_CPU1();

    Init_Uart_A();
    Init_Uart_B();

    CANInit(CANA_BASE);
    CANInit(CANB_BASE);
    Setup_CAN_A();
    Setup_CAN_B();
    CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);
    CANIntEnable(CANA_BASE,CAN_INT_IE0 | CAN_INT_STATUS);
    CANGlobalIntEnable(CANB_BASE, CAN_GLB_INT_CANINT0);
    CANIntEnable(CANB_BASE,CAN_INT_IE0 | CAN_INT_STATUS);

    DAC_Init(DACA);
    DAC_Init(DACB);
    DAC_Init(DACC);

    I2CB_Init();

    ConfigureADC_CPU1();

    Setup_ADC_CPU1();

    // Setup Shared Global RAM
    Setup_SharedRAM();

    Cla1Regs.MIER.all = 0;
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.CLA1 = 1;
    EDIS;

    CLA1_ConfigMemory();
    CLA1_Init();
}

void Setup_SharedRAM(void)
{
    // Give CPU02 Memory Access to GSRAM15
    do
    {
        EALLOW;
        MemCfgRegs.GSxMSEL.bit.MSEL_GS15 = 1;
        EDIS;
    }
    while(MemCfgRegs.GSxMSEL.bit.MSEL_GS15 == 0);
}

CPU2:

#ifdef _FLASH
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadSize;
extern Uint16 RamfuncsRunStart;
#endif

void main(void)
{
    #ifdef _FLASH
      memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif

    InitSysCtrl_CPU2();

#ifdef _FLASH
   InitFlash();
#endif

    DINT;

    InitPieCtrl();

    IER = 0x0000;
    IFR = 0x0000;

    EALLOW;
    PieVectTable.ADCC1_INT = &ADCC_ISR_CPU2;
    PieVectTable.EPWM7_INT = &Loop_Epwm7_ISR_CPU2;

    IER |= M_INT1;
    IER |= M_INT3;
    EDIS;

    PieCtrlRegs.PIEIER1.bit.INTx3 = 1;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx7 = 1;

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;

    PieCtrlRegs.PIEACK.all = 0xFFFF;
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

    // Wait until Shared RAM is available
    while(MemCfgRegs.GSxMSEL.bit.MSEL_GS15 == 0);

    // Unblock CPU1 Code Execution
    do
    {
        IPCLtoRFlagSet(IPC_FLAG17);
    } while(IpcRegs.IPCFLG.bit.IPC17 == 0);

    // DEBUG CODE IN FLASH STAND_ALONE
    do
    {
        GpioDataRegs.GPCSET.bit.GPIO81 = 1; // TP E38
        DELAY_US(100);
        GpioDataRegs.GPCCLEAR.bit.GPIO81 = 1;
        DELAY_US(100);
    } while(1); // END DEBUG CODE

    System_Config_CPU2();

    Init_Vars_CPU2();

//  *** WATCHDOG SETTINGS ***
    DisableDog();

    // BACKGROUND LOOP
    for(;;)
    {

In conclusion, if I load CPU1 FLASH STAND_ALONE code and CPU2 FLASH code and then using script “EMU Boot Mode Select -> EMU_BOOT_FLASH” whit CPU2/CPU1 run command, I didn’t see CPU1&CPU2 TP toggling: I have introducing an infinite loop to force TP toggling to observe FLASH STAND_ALONE code activity also whit emulator disconnected and DIP switch BM0&BM1 setted to 1 (3V3 verified whit multimeter/oscilloscope). If I stopped CPU1 code I see it looping in IPCBootCPU2(), specifically:

    //

   // Wait until CPU02 control system boot ROM is ready to receive
   // CPU01 to CPU02 INT1 interrupts.
   //

   do
   {
       bootStatus = IPCGetBootStatus() & C2_BOOTROM_BOOTSTS_SYSTEM_READY;
   } while ((bootStatus != C2_BOOTROM_BOOTSTS_SYSTEM_READY));

If I stop CPU2 and force IPCBOOTSTS = 2, than CPU1 and CPU2 starting to move on !

Why Boot ROM sequence didn’t change CPU2 IPCBOOTSTS correctly ?

Thanks for your support.

Diego

  • Diego

    C2_BOOTROM_BOOTSTS_SYSTEM_READY isn't set when you tell CPU2 to boot to flash. Only gets set when going to wait boot.

    Best regards
    Chris
  • Hi Chris,

    at long last, I found my fault... There wasn't a really issue about flash boot sequence in standalone mode startup. To found my problem, I turned my attention relatively the last portion of code where I used IQmath instructions: when I excluded that the whole code started to run well in flash standalone mode. The problem was due for a problem in my .cmd file where I pasted the same IQmath section definition used in RAM. So when I was connected with emulator, also in flash mode, reset event didn't occur and IQmath loaded in RAM was reachable. Unfortunately, when code was supposed to run in flash standalone mode in presence of startup reset, running code tried to access a IQmath.lib even though function wasn't present in a cleared RAM caused by reset condition...

    I loaded this function in FLASH and all started to work well as expected and tested in the other debug configuration.

    Thanks and regards.

    Diego