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: CPU2 execution speed ~10x slower than CPU1 when running identical code from FLASH

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hello,

I am running the same code on CPU1 and CPU2 of the F28379D, and both are configured to execute from FLASH. The code mainly generates three sine waves and runs a 3-Phase SRF PLL routine.

  • On CPU1, the SRF PLL routine takes about 140 Clock cycles.

  • On CPU2, the same routine takes about 1300 Clock cycles.

Setup details:

  • A 10 kHz timer interrupt triggers the execution on both CPUs - Timer0 in CPU1 and Timer1 in CPU2.

  • Inside the ISR, the code performs the sine-wave generation and runs the 3-Phase SRF PLL.

  • The exact same code is used on both CPUs.

Issue:
CPU2 is approximately 10× slower than CPU1, even though both are running from FLASH with the same code and ISR setup.

Question:
What could cause CPU2 to execute much slower than CPU1 when both are running identical code from FLASH? Are there any specific memory configuration or wait-state considerations for CPU2 when executing from FLASH?

ISR routine in CPU1

__interrupt void timer0_isr(void)
{
    // Execute control algorithms
    // Toggle GPIO 22
    HWREG(GPIODATA_BASE + GPIO_O_GPATOGGLE) |= (uint32_t) 0x400000U;

    theta = theta + (TWO_PI * 50.0f * ISR_TIME_PERIOD);

    if (theta > TWO_PI) theta -= TWO_PI;

    Vgrid.Va = Vm * __cos(theta);
    Vgrid.Vb = Vm * __cos(theta-(TWO_PI / 3.0f));
    Vgrid.Vc = Vm * __cos(theta+(TWO_PI / 3.0f));
    
    Vgrid.Vab = Vgrid.Va - Vgrid.Vb;
    Vgrid.Vbc = Vgrid.Vb - Vgrid.Vc;

    SRF_PLL_MACRO(Vgrid);

    // Cleanup
    // Clear flag in timer module (optional - but better to do this)
    HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TCR) |= 0x8000U;
    // Clear ACK bit in PIEACK register
    HWREGH(PIECTRL_BASE + PIE_O_ACK) |= (uint16_t) 0x1U;
}

ISR routine in CPU2

__interrupt void timer1_isr(void)
{
    // Execute control algorithms
    // Toggle GPIO 52
    GpioDataRegs.GPBTOGGLE.bit.GPIO52 = 1;

    theta = theta + (TWO_PI * 50.0f * ISR_TIME_PERIOD);

    if (theta > TWO_PI) theta -= TWO_PI;

    Vgrid.Va = Vm * __cos(theta);
    Vgrid.Vb = Vm * __cos(theta-(TWO_PI / 3.0f));
    Vgrid.Vc = Vm * __cos(theta+(TWO_PI / 3.0f));
    
    Vgrid.Vab = Vgrid.Va - Vgrid.Vb;
    Vgrid.Vbc = Vgrid.Vb - Vgrid.Vc;

    SRF_PLL_MACRO(Vgrid);


    // Cleanup
    // Clear flag in timer module
    CpuTimer1Regs.TCR.bit.TIF = 1;
}

FLASH linker CMD files for both the CPU's are as below

2837xD_FLASH_lnk_cpu1.cmd file

MEMORY
{
PAGE 0 :  /* Program Memory */
          /* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
          /* BEGIN is used for the "boot to Flash" bootloader mode   */

   BEGIN           	: origin = 0x080000, length = 0x000002
   RAMM0           	: origin = 0x000123, length = 0x0002DD
   RAMD0           	: origin = 0x00B000, length = 0x000800
   RAMLS0          	: origin = 0x008000, length = 0x000800
   RAMLS1          	: origin = 0x008800, length = 0x000800
   RAMLS2      		: origin = 0x009000, length = 0x000800
   RAMLS3      		: origin = 0x009800, length = 0x000800
   RAMLS4      		: origin = 0x00A000, length = 0x000800
   RAMGS14          : origin = 0x01A000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
   RAMGS15          : origin = 0x01B000, length = 0x000FF8     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */

//   RAMGS15_RSVD     : origin = 0x01BFF8, length = 0x000008    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

   RESET           	: origin = 0x3FFFC0, length = 0x000002

   /* Flash sectors */
   FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
   FLASHB           : origin = 0x082000, length = 0x002000	/* on-chip Flash */
   FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
   FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
   FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
   FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
   FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
   FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
   FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
   FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
   FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
   FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
   FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
   FLASHN           : origin = 0x0BE000, length = 0x001FF0	/* on-chip Flash */

//   FLASHN_RSVD     : origin = 0x0BFFF0, length = 0x000010    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

PAGE 1 : /* Data Memory */
         /* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */

   BOOT_RSVD       : origin = 0x000002, length = 0x000121     /* Part of M0, BOOT rom will use this for stack */
   RAMM1           : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 */
//   RAMM1_RSVD      : origin = 0x0007F8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
   RAMD1           : origin = 0x00B800, length = 0x000800

   RAMLS5      : origin = 0x00A800, length = 0x000800

   RAMGS0      : origin = 0x00C000, length = 0x001000
   RAMGS1      : origin = 0x00D000, length = 0x001000
   RAMGS2      : origin = 0x00E000, length = 0x001000
   RAMGS3      : origin = 0x00F000, length = 0x001000
   RAMGS4      : origin = 0x010000, length = 0x001000
   RAMGS5      : origin = 0x011000, length = 0x001000
   RAMGS6      : origin = 0x012000, length = 0x001000
   RAMGS7      : origin = 0x013000, length = 0x001000
   RAMGS8      : origin = 0x014000, length = 0x001000
   RAMGS9      : origin = 0x015000, length = 0x001000
   RAMGS10     : origin = 0x016000, length = 0x001000

//   RAMGS11     : origin = 0x017000, length = 0x000FF8   /* Uncomment for F28374D, F28376D devices */

//   RAMGS11_RSVD : origin = 0x017FF8, length = 0x000008    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

   RAMGS11     : origin = 0x017000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
   RAMGS12     : origin = 0x018000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
   RAMGS13     : origin = 0x019000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */

   CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
   CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
}

SECTIONS
{
   /* Allocate program areas: */
   .cinit              : > FLASHB      PAGE = 0, ALIGN(8)
   .text               : >> FLASHB | FLASHC | FLASHD | FLASHE      PAGE = 0, ALIGN(8)
   codestart           : > BEGIN       PAGE = 0, ALIGN(8)
   /* Allocate uninitalized data sections: */
   .stack              : > RAMM1       PAGE = 1
   .switch             : > FLASHB      PAGE = 0, ALIGN(8)
   .reset              : > RESET,      PAGE = 0, TYPE = DSECT /* not used, */

#if defined(__TI_EABI__)
   .init_array         : > FLASHB,       PAGE = 0,       ALIGN(8)
   .bss                : > RAMLS5,       PAGE = 1
   .bss:output         : > RAMLS3,       PAGE = 0
   .bss:cio            : > RAMLS5,       PAGE = 1
   .data               : > RAMLS5,       PAGE = 1
   .sysmem             : > RAMLS5,       PAGE = 1
   /* Initalized sections go in Flash */
   .const              : > FLASHF,       PAGE = 0,       ALIGN(8)
#else
   .pinit              : > FLASHB,       PAGE = 0,       ALIGN(8)
   .ebss               : >> RAMLS5 | RAMGS0 | RAMGS1,    PAGE = 1
   .esysmem            : > RAMLS5,       PAGE = 1
   .cio                : > RAMLS5,       PAGE = 1
   /* Initalized sections go in Flash */
   .econst             : >> FLASHF      PAGE = 0, ALIGN(8)
#endif

   Filter_RegsFile     : > RAMGS0,	   PAGE = 1

   SHARERAMGS0		: > RAMGS0,		PAGE = 1
   SHARERAMGS1		: > RAMGS1,		PAGE = 1
   SHARERAMGS2		: > RAMGS2,		PAGE = 1
   ramgs0           : > RAMGS0,     PAGE = 1
   ramgs1           : > RAMGS1,     PAGE = 1

#ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        #if defined(__TI_EABI__)
            .TI.ramfunc : {} LOAD = FLASHD,
                                 RUN = RAMLS0,
                                 LOAD_START(RamfuncsLoadStart),
                                 LOAD_SIZE(RamfuncsLoadSize),
                                 LOAD_END(RamfuncsLoadEnd),
                                 RUN_START(RamfuncsRunStart),
                                 RUN_SIZE(RamfuncsRunSize),
                                 RUN_END(RamfuncsRunEnd),
                                 PAGE = 0, ALIGN(8)
        #else
            .TI.ramfunc : {} LOAD = FLASHD,
                             RUN = RAMLS0,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_SIZE(_RamfuncsLoadSize),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             RUN_SIZE(_RamfuncsRunSize),
                             RUN_END(_RamfuncsRunEnd),
                             PAGE = 0, ALIGN(8)
        #endif
    #else
   ramfuncs            : LOAD = FLASHD,
                         RUN = RAMLS0,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_SIZE(_RamfuncsLoadSize),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         RUN_SIZE(_RamfuncsRunSize),
                         RUN_END(_RamfuncsRunEnd),
                         PAGE = 0, ALIGN(8)
    #endif

#endif

   /* The following section definitions are required when using the IPC API Drivers */
    GROUP : > CPU1TOCPU2RAM, PAGE = 1
    {
        PUTBUFFER
        PUTWRITEIDX
        GETREADIDX
    }

    GROUP : > CPU2TOCPU1RAM, PAGE = 1
    {
        GETBUFFER :    TYPE = DSECT
        GETWRITEIDX :  TYPE = DSECT
        PUTREADIDX :   TYPE = DSECT
    }

   /* The following section definition are for SDFM examples */
   Filter1_RegsFile : > RAMGS1,	PAGE = 1, fill=0x1111
   Filter2_RegsFile : > RAMGS2,	PAGE = 1, fill=0x2222
   Filter3_RegsFile : > RAMGS3,	PAGE = 1, fill=0x3333
   Filter4_RegsFile : > RAMGS4,	PAGE = 1, fill=0x4444
   Difference_RegsFile : >RAMGS5, 	PAGE = 1, fill=0x3333
}

/*
//===========================================================================
// End of file.
//===========================================================================
*/

2837xD_FLASH_lnk_cpu2.cmd file

MEMORY
{
PAGE 0 :
   /* BEGIN is used for the "boot to SARAM" bootloader mode   */

   BEGIN           	: origin = 0x080000, length = 0x000002
   RAMM0           	: origin = 0x0000A2, length = 0x00035E
   RAMD0           	: origin = 0x00B000, length = 0x000800
   RAMLS0          	: origin = 0x008000, length = 0x000800
   RAMLS1          	: origin = 0x008800, length = 0x000800
   RAMLS2      		: origin = 0x009000, length = 0x000800
   RAMLS3      		: origin = 0x009800, length = 0x000800
   RAMLS4      		: origin = 0x00A000, length = 0x000800
   RAMGS14          : origin = 0x01A000, length = 0x001000     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */
   RAMGS15          : origin = 0x01B000, length = 0x000FF8     /* Only Available on F28379D, F28377D, F28375D devices. Remove line on other devices. */

//   RAMGS15_RSVD     : origin = 0x01BFF8, length = 0x000008    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

   RESET       		: origin = 0x3FFFC0, length = 0x000002

   /* Flash sectors */
   FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
   FLASHB           : origin = 0x082000, length = 0x002000	/* on-chip Flash */
   FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
   FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
   FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
   FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
   FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
   FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
   FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
   FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
   FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
   FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
   FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
   FLASHN           : origin = 0x0BE000, length = 0x001FF0	/* on-chip Flash */

//   FLASHN_RSVD     : origin = 0x0BFFF0, length = 0x000010    /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */

PAGE 1 :

   BOOT_RSVD       : origin = 0x000002, length = 0x0000A0     /* Part of M0, BOOT rom will use this for stack */
   RAMM1           : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 */
//   RAMM1_RSVD      : origin = 0x0007F8, length = 0x000008     /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
   RAMD1           : origin = 0x00B800, length = 0x000800

   RAMLS5          : origin = 0x00A800, length = 0x000800

   RAMGS0          : origin = 0x00C000, length = 0x001000
   RAMGS1          : origin = 0x00D000, length = 0x001000
   RAMGS2          : origin = 0x00E000, length = 0x001000
   CPU2TOCPU1RAM   : origin = 0x03F800, length = 0x000400
   CPU1TOCPU2RAM   : origin = 0x03FC00, length = 0x000400
}

SECTIONS
{
   /* Allocate program areas: */
   .cinit              : > FLASHB      PAGE = 0, ALIGN(8)
   //.text               : > FLASHB      PAGE = 0, ALIGN(8)
   .text               : >> FLASHB | FLASHC | FLASHD | FLASHE      PAGE = 0, ALIGN(8)
   codestart           : > BEGIN       PAGE = 0, ALIGN(8)

   /* Allocate uninitalized data sections: */
   .stack              : > RAMM1        PAGE = 1

   /* Initalized sections go in Flash */
   .switch             : > FLASHB      PAGE = 0, ALIGN(8)
   .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */
   
#if defined(__TI_EABI__)
   .init_array         : > FLASHB,       PAGE = 0,       ALIGN(8)
   .bss                : > RAMLS5,       PAGE = 1
   .bss:output         : > RAMLS3,       PAGE = 0
   .bss:cio            : > RAMLS5,       PAGE = 1
   .data               : > RAMLS5,       PAGE = 1
   .sysmem             : > RAMLS5,       PAGE = 1
   /* Initalized sections go in Flash */
   .const              : > FLASHF,       PAGE = 0,       ALIGN(8)
#else
   .pinit              : > FLASHB,       PAGE = 0,       ALIGN(8)
   //.ebss               : >> RAMLS5 | RAMGS0 | RAMGS1,    PAGE = 1
   .ebss               : >> RAMLS5,    PAGE = 1
   .esysmem            : > RAMLS5,       PAGE = 1
   .cio                : > RAMLS5,       PAGE = 1
   /* Initalized sections go in Flash */
   .econst             : >> FLASHF       PAGE = 0, ALIGN(8)
#endif

   SHARERAMGS0		: > RAMGS0,		PAGE = 1
   SHARERAMGS1		: > RAMGS1,		PAGE = 1
   SHARERAMGS2		: > RAMGS2,		PAGE = 1

#ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        #if defined(__TI_EABI__)
            .TI.ramfunc : {} LOAD = FLASHD,
                                 RUN = RAMLS0,
                                 LOAD_START(RamfuncsLoadStart),
                                 LOAD_SIZE(RamfuncsLoadSize),
                                 LOAD_END(RamfuncsLoadEnd),
                                 RUN_START(RamfuncsRunStart),
                                 RUN_SIZE(RamfuncsRunSize),
                                 RUN_END(RamfuncsRunEnd),
                                 PAGE = 0, ALIGN(8)
        #else
            .TI.ramfunc : {} LOAD = FLASHD,
                             RUN = RAMLS0,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_SIZE(_RamfuncsLoadSize),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             RUN_SIZE(_RamfuncsRunSize),
                             RUN_END(_RamfuncsRunEnd),
                             PAGE = 0, ALIGN(8)
        #endif
    #else
   ramfuncs            : LOAD = FLASHD,
                         RUN = RAMLS0,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_SIZE(_RamfuncsLoadSize),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         RUN_SIZE(_RamfuncsRunSize),
                         RUN_END(_RamfuncsRunEnd),
                         PAGE = 0, ALIGN(8)
    #endif
#endif

   /* The following section definitions are required when using the IPC API Drivers */
    GROUP : > CPU2TOCPU1RAM, PAGE = 1
    {
        PUTBUFFER
        PUTWRITEIDX
        GETREADIDX
    }

    GROUP : > CPU1TOCPU2RAM, PAGE = 1
    {
        GETBUFFER :    TYPE = DSECT
        GETWRITEIDX :  TYPE = DSECT
        PUTREADIDX :   TYPE = DSECT
    }
}

/*
//===========================================================================
// End of file.
//===========================================================================
*/

I have also attached the full project file here for your reference.

Timer_Example.zip

Thank you

Vijaymahantesh V Surkod

  • Hello,

    Let me look into this and get back to you with a response.

    Best Regards,

    Delaney

  • Hello,

    A gentle reminder.

    Best Regards,

    Vijaymahantesh V Surkod

  • Hello,

    Apologies for the delay. 

    CPU2 is approximately 10× slower than CPU1

    Do you mean:

    1. The ISR execution time itself is 10 times slower (the CPU is slower to execute the ISR code) OR
    2. The CPU timer is triggering the ISR 10 times slower on CPU2 even though the CPU timer frequencies are configured to be identical?

    Best Regards,

    Delaney

  • Hello,

    Here’s a detailed explanation, along with an additional issue I observed while drafting this reply.

    For CPU1

    • A 10 kHz timer (TIMER0) interrupt triggers the execution timer0_isr in CPU1.

    • And a 1 Hz timer (TIMER2) interrupt triggers the execution timer1_isr in CPU1.

    So, the entire code for CPU1 is as below. 

    //#############################################################################
    //
    // Toggle GPIO pins 22,52 and 97 using timers
    // CPU1 controls GPIO 22 and 97
    // CPU2 controls GPIO 52
    // CPU1 uses Timer 0 and Timer 1 for toggling pins
    // CPU2 uses Timer 1 for toggling pin
    //
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    #include "UserDefinedVariables_CPU1.h"
    #include "MVariables_Inits_CPU1.h"
    #include "MVariables_CPU1.h"
    #include "MainISRFns_MACRO_CPU1.h"
    
    float32_t theta = 0.0f;
    float32_t Vm = 325.0f;
    
    //------------------------STRUCT VARIABLE-------------------//
    SRF_PLL Vgrid = SRF_PLL_DEFAULTS;
    
    
    __interrupt void timer0_isr(void)
    {
        // Execute control algorithms
        // SET GPIO 22
        HWREG(GPIODATA_BASE + GPIO_O_GPASET) |= (uint32_t) 0x400000U;
    
        theta = theta + (TWO_PI * 50.0f * ISR_TIME_PERIOD);
    
        if (theta > TWO_PI) theta -= TWO_PI;
    
        Vgrid.Va = Vm * __cos(theta);
        Vgrid.Vb = Vm * __cos(theta-(TWO_PI / 3.0f));
        Vgrid.Vc = Vm * __cos(theta+(TWO_PI / 3.0f));
        
        Vgrid.Vab = Vgrid.Va - Vgrid.Vb;
        Vgrid.Vbc = Vgrid.Vb - Vgrid.Vc;
    
        SRF_PLL_MACRO(Vgrid);
    
        // CLEAR GPIO 22
        HWREG(GPIODATA_BASE + GPIO_O_GPACLEAR) |= (uint32_t) 0x400000U;
    
        // Cleanup
        // Clear flag in timer module (optional - but better to do this)
        HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TCR) |= 0x8000U;
        // Clear ACK bit in PIEACK register
        HWREGH(PIECTRL_BASE + PIE_O_ACK) |= (uint16_t) 0x1U;
    }
    
    __interrupt void timer1_isr(void)
    {
        // Execute control algorithms
        // Toggle GPIO 22
        HWREG(GPIODATA_BASE + GPIO_O_GPDTOGGLE) |= (uint32_t) 0x2U;
    
        // Cleanup
        // Clear flag in timer module
        HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= 0x8000U;
    }
    
    
    //
    // Main
    //
    void main(void)
    {
        // Initialize device
        Device_init();
    
        // Disable interrupts and clear them at the CPU
        // Initialize PIE module
        Interrupt_initModule();
    
        // Initialize PIE Vector Table
        Interrupt_initVectorTable();
    
        // Enable clock to Timer 0 and Timer 1
        EALLOW;
        HWREG(CPUSYS_BASE + SYSCTL_O_PCLKCR0) |= (uint32_t) 0x18U;
        EDIS;
    
        // Configure Timer 0 and Timer 1
        // Stop the timers
        HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0x10U;
        HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0x10U;
        
        // Load the period value
        // Timer 0 = 100 micro-sec interval - (20000-1)
        // Timer 1 = 1 sec interval
        HWREG(CPUTIMER0_BASE + CPUTIMER_O_PRD) = 20000-1;
        HWREG(CPUTIMER1_BASE + CPUTIMER_O_PRD) = 200000000-1;
    
    
        // Load optional pre-scale value
        HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TPR) = 0x00;
        HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TPR) = 0x01;
    
        // Set the mode of running
        HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0x0800U;
        HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0x0800U;
    
        // Enable Timer Interrupts
        HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0xC000U;
        HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0xC000U;
    
        // Reload period and prescale
        HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0x0020U;
        HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) |= (uint16_t) 0x0020U;
    
        // Register ISRs for Timer 0 and Timer 1
        Interrupt_register(INT_TIMER0, &timer0_isr);
        Interrupt_register(INT_TIMER1, &timer1_isr);
    
    
        // Configure the PIE module for Timer 0 - INT1.7
        HWREGH(PIECTRL_BASE + PIE_O_IER1) |= (uint16_t) 0x40U;
    
        // Enable the global interrupts and configure IER
        // Enable Timer 0 Interrupt
        IER |= 0x01U;
        // Enable Timer 1 Interrupt
        IER |= 0x1000U;
        EINT;
    
    
        // Configure GPIO pins 22, 52 and 97
        EALLOW;
        // Pin 22
        HWREG(GPIOCTRL_BASE + GPIO_O_GPAMUX2) &= 0xFFFFCFFFU;
        HWREG(GPIOCTRL_BASE + GPIO_O_GPADIR) |= (uint32_t) 0x400000U;
    
        // Pin 52
        HWREG(GPIOCTRL_BASE + GPIO_O_GPBMUX2) &= 0xFFFFFCFFU;
        HWREG(GPIOCTRL_BASE + GPIO_O_GPBDIR) |= (uint32_t) 0x100000U;
        HWREGH(GPIOCTRL_BASE + GPIO_O_GPBCSEL3) |= (uint32_t) 0x2000U;
    
        // Pin 97
        HWREG(GPIOCTRL_BASE + GPIO_O_GPDGMUX1) &= 0xFFFFFFF3U;
        HWREG(GPIOCTRL_BASE + GPIO_O_GPDDIR) |= (uint32_t) 0x2U;
        EDIS;
        
        // Start the Timers
        HWREGH(CPUTIMER0_BASE + CPUTIMER_O_TCR) &= 0xFFEFU;
        HWREGH(CPUTIMER1_BASE + CPUTIMER_O_TCR) &= 0xFFEFU;
    
    
        // Infinite loop
        while(1){}
    
    }
    
    //
    // End of File
    //
    

    with the pre-defined symbols in the CPU1 project properties, as shown in the picture below

    CPU1 project - Build configurations

    CPU1 project files.

    For CPU2

    • A 10 kHz timer (TIMER1) interrupt triggers the execution timer1_isr in CPU2.

    So, the entire code for CPU2 is as below. 

    //#############################################################################
    //
    // Toggle GPIO pins 22,52 and 97 using timers
    // CPU1 controls GPIO 22 and 97
    // CPU2 controls GPIO 52
    // CPU1 uses Timer 0 and Timer 1 for toggling pins
    // CPU2 uses Timer 1 for toggling pin
    //
    //#############################################################################
    
    //
    // Included Files
    //
    #include "F28x_Project.h"
    #include "driverlib.h"
    #include "device.h"
    
    #include "UserDefinedVariables_CPU2.h"
    #include "MVariables_Inits_CPU2.h"
    #include "MVariables_CPU2.h"
    #include "MainISRFns_MACRO_CPU2.h"
    
    float32_t theta = 0.0f;
    float32_t Vm = 325.0f;
    
    //------------------------STRUCT VARIABLE-------------------//
    SRF_PLL Vgrid = SRF_PLL_DEFAULTS;
    
    
    __interrupt void timer1_isr(void)
    {
        // Execute control algorithms
        // SET GPIO 52
        GpioDataRegs.GPBSET.bit.GPIO52 = 1;
    
        theta = theta + (TWO_PI * 50.0f * ISR_TIME_PERIOD);
    
        if (theta > TWO_PI) theta -= TWO_PI;
    
        Vgrid.Va = Vm * __cos(theta);
        Vgrid.Vb = Vm * __cos(theta-(TWO_PI / 3.0f));
        Vgrid.Vc = Vm * __cos(theta+(TWO_PI / 3.0f));
        
        Vgrid.Vab = Vgrid.Va - Vgrid.Vb;
        Vgrid.Vbc = Vgrid.Vb - Vgrid.Vc;
    
        SRF_PLL_MACRO(Vgrid);
    
        // CLEAR GPIO 52
        GpioDataRegs.GPBCLEAR.bit.GPIO52 = 1;
    
    
        // Cleanup
        // Clear flag in timer module
        CpuTimer1Regs.TCR.bit.TIF = 1;
    }
    //
    // Main
    //
    void main(void)
    {
         
        // Disable interrupts and clear them at the CPU
        // Initialize PIE module
        InitPieCtrl();
        IER = 0x0000;
        IFR = 0x0000;
    
        // Initialize PIE Vector Table
        InitPieVectTable();
    
        // Enable clock to Timer 1
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.CPUTIMER1 = 1;
        EDIS;
    
        // Configure Timer 0 and Timer 1
        // Stop the timers
        CpuTimer1Regs.TCR.bit.TSS = 1;
     
        // Load the period value
        // Timer 1 = 100 micro-sec interval - (20000-1)
        CpuTimer1Regs.PRD.all = 20000-1;
    
        // Load optional pre-scale value
        CpuTimer1Regs.TPR.all = 0;
    
        // Set the mode of running
        CpuTimer1Regs.TCR.bit.FREE = 1;
    
        // Enable Timer Interrupts
        CpuTimer1Regs.TCR.bit.TIE = 1;
    
        // Reload period and prescale
        CpuTimer1Regs.TCR.bit.TRB = 1;
    
        // Register ISRs for Timer 0 and Timer 1
        EALLOW;
        PieVectTable.TIMER1_INT = &timer1_isr;
        EDIS;
    
        // Enable the global interrupts and configure IER
        // Enable Timer 1 Interrupt
        IER |= 0x1000U;
        EINT;
    
       
        // Start the Timers
        CpuTimer1Regs.TCR.bit.TSS = 0;
    
        // Infinite loop
        while(1){}
    
    }
    
    //
    // End of File
    //
    

    with the pre-defined symbols in the CPU2 project properties, as shown in the picture below

    CPU2 project - Build configurations

    CPU2 project files.

    Now, coming to the issue - 

    Issue-1

    a) When I debug the CPU1 project - (CPU2 is disconnected and no code is loaded into CPU2) - The CPU1-TIMER0 ISR runs at 10kHz (100us) and the ISR execution time is around 1.15us. I verified this by setting GPIO22 at the start of the CPU1-TIMER0 ISR and clearing GPIO22 just before the end of the CPU1-TIMER0 ISR. The time between the two rising edges of GPIO22 is 100us, and the time between the rising edge and the falling edge of GPIO22 is 1.15us. I also used breakpoints to view the ISR execution clock cycles, and it shows around 226 clock cycles.

    Now, in order to load the CPU2 code, I follow the steps below

    1) I connect the target for CPU2 (by that I mean right-click on C28xx_CPU2 and connect the target). 

    2) Halt the CPU1

    3) Then click on C28xx_CPU2 and then go to Run -> Load -> Load Program and then choose the ".out" file from the CPU2 FLASH folder.

    4) Then I click on C28xx_CPU1 and RUN the CPU1

    Now, when I finish step 4, the CPU1-TIMER0 ISR is triggered at 500Hz (as I set GPIO22 at the start of the CPU1-TIMER0 ISR and clear GPIO22 just before the end of the CPU1-TIMER0 ISR), the time between the two rising edges of GPIO22 becomes 2000us, and the time between the rising edge and the falling edge of GPIO22 is 22.6us. I also used breakpoints to view the ISR execution clock cycles, and again, it shows around 228 clock cycles.

    Issue-2

    b) Now, I run the CPU2 (CPU1 is running), in CPU2-TIMER1 ISR, I set the GPIO52 at the entry point of the ISR, and then clear it just before the end of the CPU2-TIMER1 ISR. I have below issues

    b.1) I am not sure why GPIO52 is not setting and clearing (I don't see anything in the oscilloscope - I have configured the core select register in CPU1 and given access to CPU2). Due to this, I am unable to see whether the CPU2-TIMER1 ISR is triggered at 100us or not.

    b.2) When I look at the CPU2-TIMER1 ISR execution clock cycles using breakpoints, it shows 2304 clock cycles. 

    My initial question was regarding the execution cycles of the TIMER ISR. If I set a breakpoint at the start and end of the CPU1-TIMER0 ISR and examine the clock cycles, it shows 226 clock cycles. However, when I set a breakpoint at the start and end of the CPU2-TIMER1 ISR and examine the clock cycles, it shows 2304 clock cycles. However, I now have additional issues as described above.

    Thank you

    Vijaymahantesh V Surkod

  • Hello,

    I will look into what you have sent and get back to you.

    Best Regards,

    Delaney

  • Hello,

    Apologies again for the delay. One thing that comes to mind is the ownership of GPIO22, only one CPU can have ownership of a GPIO at a time. Can you try using a different GPIO for CPU2 like below and see if that solves the issue?

    We have an example in C2000ware showing a GPIO toggling on both CPU1 and CPU2 (path below). Can you check that your code follows the same steps to initialize the GPIOs on each core?

    [C2000ware install]/driverlib/f2837xd/examples/dual/led/led_ex1_blinky_cpu1 & led_ex1_blinky_cpu2

    Best Regards,

    Delaney