TMS320F28P659DK-Q1: ECAP and AD in CPU2 don't work

Part Number: TMS320F28P659DK-Q1
Other Parts Discussed in Thread: C2000WARE

I'm migrating my ECU project from an F28377D to an F28P659, 
but the capture and AD sometimes work and sometimes don't,
depending on the order in which the CPUs enter the debugger,
and also in standalone mode. I tried changing the boot sequences,
initialization orders, and locks to start the CPUs, but without success.
I don't feel confident in this new microcomputer.
I would like the manufacturer to explain the initialization sequence,
so I have no doubt that the peripheral will work as programmed.
Here is the sequence I used in main, CPU1, and CPU2:

//
// Main CPU1
//
void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    InitSysCtrl();
    InitPeripheralClocks();
    Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
    DINT;                                       // Disable CPU interrupts
    InitPieCtrl();                              // Initialize the PIE control registers to their default state
    IER = 0x0000;                               // Disable CPU interrupts
    IFR = 0x0000;                               // Clear all CPU interrupt flags:
    InitPieVectTable();                         // Initialize the PIE vector table

    EALLOW;
    DevCfgRegs.CPUSEL0.bit.EPWM1 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM2 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM3 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM4 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM5 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM6 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM7 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM8 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM9 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM10 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM11 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM12 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM13 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM14 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM15 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM16 = 1;
    DevCfgRegs.CPUSEL11.bit.ADC_A = 1;
    DevCfgRegs.CPUSEL11.bit.ADC_B = 1;
    DevCfgRegs.CPUSEL11.bit.ADC_C = 1;
    DevCfgRegs.CPUSEL1.bit.ECAP1 = 1;
    DevCfgRegs.CPUSEL1.bit.ECAP2 = 1;
    EDIS;
    //
    // Transfer ownership of EPWM1 and ADCA to CPU02
    //
    EALLOW;


    // To CPU2 from FLASH

    // Give Memory Access to Flash Bank 3 and 4, Tab Table 3-454 pg 714, spruiz1.pdf
    //
    DevCfgRegs.BANKMUXSEL.bit.BANK3 = 0x3;      // 11: Flash Bank is allowed to access from CPU2.
    DevCfgRegs.BANKMUXSEL.bit.BANK4 = 0x3;      // 11: Flash Bank is allowed to access from CPU2.


    //DevCfgRegs.CPU2RESCTL.all = 0xA5A50001;     // CPU2 is held in reset, Tab 3-510 pg 782, spruiz1.pdf
    //
    // Give Memory Access to GS.. SARAM to CPU02, Tab 3-541 pg 838, spruiz1a.pdf
    //
    MemCfgRegs.GSxMSEL.bit.MSEL_GS0 = 1;        // 1: CPU2 is controller for this memory.
    MemCfgRegs.GSxMSEL.bit.MSEL_GS1 = 0;        // 0: CPU1 is controller for this memory.
    MemCfgRegs.GSxMSEL.bit.MSEL_GS2 = 0;        // 0: CPU1 is controller for this memory.
    MemCfgRegs.GSxMSEL.bit.MSEL_GS3 = 1;        // 1: CPU2 is controller for this memory.
    MemCfgRegs.GSxMSEL.bit.MSEL_GS4 = 1;        // 1: CPU2 is controller for this memory.
    //DevCfgRegs.CPU2RESCTL.all = 0xA5A50000;     // CPU2 reset is deactivated, Tab 3-510 pg 782, spruiz1.pdf
    EDIS;

    //
    // Initialize GPIO and configure the GPIO pin as a push-pull output
    //
    Device_initGPIO();
    SetupInputXBAR5();                  // Setup the ADCs sync.

    Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCACK.all = 0xFFFFFFFF;    //IPCRtoLFlagAcknowledge(IPC_FLAG_ALL);

    DELAY_US(100);
    //
    // to CPU2 from FLASH
    //
    Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_BANK3_SECTOR0);

 

    // Setup only the GP I/O for SPI functionality
    // This function is found in F2837xD_Spi.c
    //
    InitSpiGpio();
    //
    // Initialize the Device Peripheral.
    //
    InitCpuTimers();                    // This function initializes the Cpu Timers.

    InitSpi();                          // This function initializes the SPI(s) to a known state.

    //InitEPwm();                         // This function initializes the EPwm(s) to a known state. (CPU2 only)

    InitECapGpio();                     // This function initializes the eCAP(s) IO to a known state.

    //InitECap();                         // This function initializes the eCAP(s) IO to a known state.

    InitSci();                          // This function initializes the SCI(s) to a known state.

    //ConfigureADC();                     // Configure the ADCs and power them up.

    //SetupADCSoftwareSync();             // Setup the ADCs for software conversions.

    //SetupInputXBAR5();                  // Setup the ADCs sync.

    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
    ConfigCpuTimer(&CpuTimer0, 200, 400);    // Read ADC.
    ConfigCpuTimer(&CpuTimer1, 200, 1000);   // Time Base. Timer for Datalogger.
    ConfigCpuTimer(&CpuTimer2, 200, 50);//125);    // Buzzer.

    CpuTimer1Regs.PRD.all = 0xFFFFFFFF;      // Free run for datalogger.
    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xS_cputimervars.h), the below
    // settings must also be updated.
    //
    CpuTimer0Regs.TCR.all = 0x4000;
    CpuTimer1Regs.TCR.all = 0x4000;
    CpuTimer2Regs.TCR.all = 0x4000;

    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
    IER |= M_INT1;
    IER |= M_INT4;
    IER |= M_INT8;
    IER |= M_INT9;
    IER |= M_INT11;
    IER |= M_INT13;
    IER |= M_INT14;

    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    //
    // Enable eCAP1 INTn in the PIE: Group 4 interrupt 1
    //
    //PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
    //
    // Enable eCAP2 INTn in the PIE: Group 4 interrupt 2
    //
    //PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
    //
    // Enable eCAP3 INTn in the PIE: Group 4 interrupt 3
    //
    PieCtrlRegs.PIEIER4.bit.INTx3 = 1;
    //
    // Enable eCAP4 INTn in the PIE: Group 4 interrupt 4
    //
    PieCtrlRegs.PIEIER4.bit.INTx4 = 1;

    ////
    //// Enable eCAP5 INTn in the PIE: Group 4 interrupt 5
    ////
    //    PieCtrlRegs.PIEIER4.bit.INTx5 = 1;

    //
    // Enable eCAP6 INTn in the PIE: Group 4 interrupt 6
    //
    PieCtrlRegs.PIEIER4.bit.INTx6 = 1;

    //
    // Enable SCI-A RX INTn in the PIE: Group 9 interrupt 1
    //
    PieCtrlRegs.PIEIER9.bit.INTx1 = 1;

    //
    // Enable SCI-A TX INTn in the PIE: Group 9 interrupt 2
    //
    PieCtrlRegs.PIEIER9.bit.INTx2 = 1;

    //
    // Enable SCI-B RX INTn in the PIE: PIE Group 8 interrupt 3
    //
    PieCtrlRegs.PIEIER9.bit.INTx3 = 1;

    //
    // Enable SCI-B TX INTn in the PIE: Group 8 interrupt 4
    //
    PieCtrlRegs.PIEIER9.bit.INTx4 = 1;

    PieCtrlRegs.PIEIER1.bit.INTx14 = 1;         // IPC1 ISR

    Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCACK.all = 0xFFFFFFFF;
    DELAY_US(5000);
    Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCSET.bit.IPC8 = 1;    // Inform CPU2
    while(!Cpu1toCpu2IpcRegs.CPU2TOCPU1IPCSTS.bit.IPC9); // Wait for CPU2 to set IPC9 //Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCFLG.bit.IPC9;
    Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCACK.bit.IPC9 = 1;

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
    EINT;
    ERTM;

    gBufferEEProm.GRAM.VAR.TPS_Cal = 1;
    LoadBufferToCPU2();

    IPCLtoRFlagSet(IPC_FLAG10);

    //GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
    //DELAY_US(1000 * 500);                   // ON delay
    Init();

    //
    // Loop Forever
    //
    for(;;)
    {
        /**/

//
// Main CPU2
//
void main(void)
{

    InitSysCtrl();                              // Initialize System Control:
    //DisablePeripheralClocks();
    DINT;                                       // Disable CPU interrupts
    InitPieCtrl();                              // Initialize the PIE control registers to their default state
    IER = 0x0000;                               // Disable CPU interrupts
    IFR = 0x0000;                               // Clear all CPU interrupt flags:
    InitPieVectTable();                         // Initialize the PIE vector table
    //Tab 3-9 pg 178, spruiz1.pdf
    DELAY_US(100);

    //
    // Wait until Shared RAM is available.
    //
    DELAY_US(10000);
    while((MemCfgRegs.GSxMSEL.bit.MSEL_GS0 != 1) ||
          (MemCfgRegs.GSxMSEL.bit.MSEL_GS3 != 1) ||
          (MemCfgRegs.GSxMSEL.bit.MSEL_GS4 != 1))
    {
    }
    IPCLtoRFlagSet(IPC_FLAG9);                  // Inform CPU1
    while(IPCRtoLFlagBusy(IPC_FLAG8) == 0);     // Wait for CPU1 to set IPC8
    IPCRtoLFlagAcknowledge(IPC_FLAG8);
    //while(IPCLtoRFlagBusy(IPC_FLAG9));
    //
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in F2837xS_CpuTimers.c
    //
    InitCpuTimers();                    // This function initializes the Cpu Timers.

    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    InitEPwm();                         // This function initializes the EPwm(s) to a known state.
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    //InitECap();                         // This function initializes the eCAP(s) IO to a known state.

    //ConfigureADC();//InitADC();         // Configure the ADCs and power them up.

    //SetupADCSoftwareSync();             // Setup the ADCs for software conversions.

    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
    //ConfigCpuTimer(&CpuTimer0, 200, 400);    // Free run for Fast Squirt.
    CpuTimer0Regs.TCR.bit.FREE = 1;     // Timer Free Run Enabled
    CpuTimer0Regs.TCR.bit.TIE = 0;      // 0 = Disable/ 1 = Enable Timer Interrupt
    //CpuTimer0Regs.TIM.all             // Counter.
    //
    // Reset interrupt counter:
    //
    CpuTimer0.InterruptCount = 0;

    ConfigCpuTimer(&CpuTimer1, 200, 1000);   // Time Base. Timer for Datalogger.
    ConfigCpuTimer(&CpuTimer2, 200, 125);    // Buzzer.

    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xD_cputimervars.h), the below
    // settings must also be updated.
    //
    CpuTimer0Regs.TCR.all = 0x4040;
    CpuTimer1Regs.TCR.all = 0x4000;
    CpuTimer2Regs.TCR.all = 0x4000;

    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
    IER |= M_INT1;
    IER |= M_INT3;
    IER |= M_INT4;
    //IER |= M_INT9;
    IER |= M_INT11;
    IER |= M_INT13;
    IER |= M_INT14;
    //
    // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
    //
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx4 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx5 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx6 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx7 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx8 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx9 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx10 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx11 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx12 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx13 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx14 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx15 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx16 = 1;
    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    //
    // Enable eCAP1 INTn in the PIE: Group 4 interrupt 1
    //
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
    //
    // Enable eCAP2 INTn in the PIE: Group 4 interrupt 2
    //
    PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
    //
    // Enable eCAP5 INTn in the PIE: Group 4 interrupt 5
    //
    //    PieCtrlRegs.PIEIER4.bit.INTx5 = 1;
    //
    // Enable eCAP6 INTn in the PIE: Group 4 interrupt 6
    //
    //    PieCtrlRegs.PIEIER4.bit.INTx6 = 1;
    //
    // Enable SCIRXINTA INTn in the PIE: Group 9 interrupt 1
    //
    //    PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
    //
    // Enable SCITXINTA INTn in the PIE: Group 9 interrupt 2
    //
    //    PieCtrlRegs.PIEIER9.bit.INTx2 = 2;
    //
    // Enable global Interrupts and higher priority real-time debug events:

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //

    InitECap();

    ConfigureADC();                     // Configure the ADCs and power them up.

    SetupADCSoftwareSync();             // Setup the ADCs for software conversions.

    EINT;
    ERTM;

    //gTimerPOR = TIME_POR;

    gWriteBufferC2.ECU2Ready = 0;

    gFlagPOR_IG = 1;

    //
    // Loop Forever
    //
    for(;;)
    {
        /**/

best regards.

Marcelo.

 




  • Hi Marcelo,

    Can you explain your issue a little more? When you say it sometimes works and sometimes doesn't can you explain what you see when the project does work and what you see when it doesn't (any possible errors)?

    Also for multi-core projects there is a specific sequence in regards to the CPU's entering the debugger that has to occur for the project to run as expected. Please see and attempt the following:

    Step 1 — Launch dual-core projectless debug session (using your .ccxml)

    Step 2 — Connect CPU1 → Halt

    Step 3 — Connect CPU2 → Halt

    Step 4 — Load CPU1 .out file FIRST

    Step 5 — FREE-RUN CPU1

    Step 6 — Load CPU2 .out file

    Step 7 — FREE-RUN CPU2

    CPU1 has to run first to assign the proper RAM's and Flash Banks to CPU2, allocate all peripherals to CPU2 that is needed, and boot CPU2. I see that you are doing all three within CPU1 but they seem to be out of order from the above mentioned. Can you reorder them to match the above?

    I also see that you are configuring some peripherals within the CPU1 code. If these peripherals have been granted to CPU2, CPU1 cannot configure them after this. It will be up to CPU2 to configure. 

    I would also recommend adding a IPC_sync(); function call after Booting CPU2 and clearing all IPC flags. This will act as a handshake between both cores

    Lastly I would recommend looking at a few of our multi-core examples within our SDK which can be found at C2000Ware\driverlib\f28p65x\examples\c28x_dual. Particularly the can_cpu1_allocate_to_cpu2 which shows how to properly assign a peripheral from CPU1 to CPU2 and ipc_ex1_basic_c28x which shows basic multicore project setup. 

  • Hi AJ, let me show you how the final version of the two main files (CPU1 and CPU2) ended up working. Note that I moved the initialization of Capture 1 and 2 and the ADCs to CPU2, and I also added the IPC flag synchronization. I’d just like you to take a look and see if there’s anything I should improve. Thanks.

    //
    // Main CPU1
    //
    void main(void)
    {
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Assign RAMs and Flash banks to CPU2.
    // In the default CPU2 linker cmd files, GS4, FLASH_BANK3 and FLASH_BANK4
    // are used for allocating various CPU2 sections.
    // In case CPU2 needs additional RAM or Flash regions, CPU1 needs to assign
    // its ownership to CPU2 using the following functions :
    // - MemCfg_setGSRAMControllerSel for GSRAM
    // - SysCtl_allocateDxRAM for DRAM
    // - SysCtl_allocateFlashBank for Flash
    //
    MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS0, MEMCFG_GSRAMCONTROLLER_CPU2);
    MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS1, MEMCFG_GSRAMCONTROLLER_CPU1);
    MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS2, MEMCFG_GSRAMCONTROLLER_CPU1);
    MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS3, MEMCFG_GSRAMCONTROLLER_CPU2);
    MemCfg_setGSRAMControllerSel(MEMCFG_SECT_GS4, MEMCFG_GSRAMCONTROLLER_CPU2);

    // EDIS;
    //IPC_claimFlashSemaphore(IPC_FLASHSEM_OWNER_CPU1);
    SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK0, SYSCTL_CPUSEL_CPU1);
    SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK1, SYSCTL_CPUSEL_CPU1);
    SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK2, SYSCTL_CPUSEL_CPU1);
    SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK3, SYSCTL_CPUSEL_CPU2);
    SysCtl_allocateFlashBank(SYSCTL_FLASH_BANK4, SYSCTL_CPUSEL_CPU2);

    //
    // Boot CPU2 core
    //

    Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_BANK3_SECTOR0);

    //
    // Sincroniza CPU1 e CPU2
    //
    IPC_sync(IPC_CPU1_L_CPU2_R, IPC_FLAG8);
    IPC_sync(IPC_CPU1_L_CPU2_R, IPC_FLAG9);
    IPC_sync(IPC_CPU1_L_CPU2_R, IPC_FLAG10);

    //
    // Initialize GPIO and configure the GPIO pin as a push-pull output
    //
    Device_initGPIO();

    // Setup only the GP I/O for SPI functionality
    // This function is found in F2837xD_Spi.c
    //
    InitSpiGpio();

    //
    // Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;
    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xS_PieCtrl.c file.
    //
    InitPieCtrl();

    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
    IER = 0x0000;
    IFR = 0x0000;

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    InitPieVectTable();

    //
    // Initialize the Device Peripheral.
    //
    InitCpuTimers(); // This function initializes the Cpu Timers.

    InitSpi(); // This function initializes the SPI(s) to a known state.

    //InitEPwm(); // This function initializes the EPwm(s) to a known state. (CPU2 only)

    InitECapGpio(); // This function initializes the eCAP(s) IO to a known state.

    InitECap(); // This function initializes the eCAP(s) IO to a known state CAP 3,4,5 and 6.

    InitSci(); // This function initializes the SCI(s) to a known state.

    SetupInputXBAR5(); // Setup the ADCs sync.

    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
    ConfigCpuTimer(&CpuTimer0, 200, 400); // Read ADC.
    ConfigCpuTimer(&CpuTimer1, 200, 1000); // Time Base. Timer for Datalogger.
    ConfigCpuTimer(&CpuTimer2, 200, 50);//125); // Buzzer.

    CpuTimer1Regs.PRD.all = 0xFFFFFFFF; // Free run for datalogger.
    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xS_cputimervars.h), the below
    // settings must also be updated.
    //
    CpuTimer0Regs.TCR.all = 0x4000;
    CpuTimer1Regs.TCR.all = 0x4000;
    CpuTimer2Regs.TCR.all = 0x4000;

    //
    // Transfer ownership of EPWM1 and ADCA to CPU02
    //
    EALLOW;
    DevCfgRegs.CPUSEL0.bit.EPWM1 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM2 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM3 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM4 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM5 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM6 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM7 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM8 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM9 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM10 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM11 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM12 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM13 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM14 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM15 = 1;
    DevCfgRegs.CPUSEL0.bit.EPWM16 = 1;
    DevCfgRegs.CPUSEL11.bit.ADC_A = 1;
    DevCfgRegs.CPUSEL11.bit.ADC_B = 1;
    DevCfgRegs.CPUSEL11.bit.ADC_C = 1;
    DevCfgRegs.CPUSEL1.bit.ECAP1 = 1;
    DevCfgRegs.CPUSEL1.bit.ECAP2 = 1;
    EDIS;
    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
    IER |= M_INT1;
    IER |= M_INT4;
    IER |= M_INT8;
    IER |= M_INT9;
    IER |= M_INT11;
    IER |= M_INT13;
    IER |= M_INT14;

    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    //
    // Enable eCAP1 INTn in the PIE: Group 4 interrupt 1
    //
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
    //
    // Enable eCAP2 INTn in the PIE: Group 4 interrupt 2
    //
    PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
    //
    // Enable eCAP3 INTn in the PIE: Group 4 interrupt 3
    //
    PieCtrlRegs.PIEIER4.bit.INTx3 = 1;
    //
    // Enable eCAP4 INTn in the PIE: Group 4 interrupt 4
    //
    PieCtrlRegs.PIEIER4.bit.INTx4 = 1;

    ////
    //// Enable eCAP5 INTn in the PIE: Group 4 interrupt 5
    ////
    // PieCtrlRegs.PIEIER4.bit.INTx5 = 1;

    //
    // Enable eCAP6 INTn in the PIE: Group 4 interrupt 6
    //
    PieCtrlRegs.PIEIER4.bit.INTx6 = 1;

    //
    // Enable SCI-A RX INTn in the PIE: Group 9 interrupt 1
    //
    PieCtrlRegs.PIEIER9.bit.INTx1 = 1;

    //
    // Enable SCI-A TX INTn in the PIE: Group 9 interrupt 2
    //
    PieCtrlRegs.PIEIER9.bit.INTx2 = 1;

    //
    // Enable SCI-B RX INTn in the PIE: PIE Group 8 interrupt 3
    //
    PieCtrlRegs.PIEIER9.bit.INTx3 = 1;

    //
    // Enable SCI-B TX INTn in the PIE: Group 8 interrupt 4
    //
    PieCtrlRegs.PIEIER9.bit.INTx4 = 1;

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    gBufferEEProm.GRAM.VAR.TPS_Cal = 1;
    LoadBufferToCPU2();

    IPCLtoRFlagSet(IPC_FLAG10);

    //GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;
    //DELAY_US(1000 * 500); // ON delay
    Init();

    Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCSET.bit.IPC8 = 1; // Inform CPU2
    while(!Cpu1toCpu2IpcRegs.CPU2TOCPU1IPCSTS.bit.IPC9); // Wait for CPU2 to set IPC9 //Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCFLG.bit.IPC9;
    Cpu1toCpu2IpcRegs.CPU1TOCPU2IPCACK.bit.IPC9 = 1;

    //
    // Loop Forever
    //
    for(;;)
    {
    /**/
    //TOGGLE_PORT_OSC = 1;

    //
    // Main CPU2
    //
    void main(void)
    {

    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;
    //
    // Wait until Shared RAM is available.
    //
    DELAY_US(10000);
    //
    // Wait until Shared RAM is available.
    //
    while((MemCfgRegs.GSxMSEL.bit.MSEL_GS0 != 1) ||
    (MemCfgRegs.GSxMSEL.bit.MSEL_GS3 != 1) ||
    (MemCfgRegs.GSxMSEL.bit.MSEL_GS4 != 1))
    {

    }
    IPC_sync(IPC_CPU2_L_CPU1_R, IPC_FLAG8);
    IPC_sync(IPC_CPU2_L_CPU1_R, IPC_FLAG9);
    IPC_sync(IPC_CPU2_L_CPU1_R, IPC_FLAG10);
    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xS_PieCtrl.c file.
    //
    InitPieCtrl();

    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
    IER = 0x0000;
    IFR = 0x0000;

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example. This is useful for debug purposes.
    // The shell ISR routines are found in F2837xS_DefaultIsr.c.
    // This function is found in F2837xS_PieVect.c.
    //
    InitPieVectTable();
    //Tab 3-9 pg 178, spruiz1.pdf
    DELAY_US(100);
    //
    // At 200MHz, execution wait-states for external oscillator is 4. Modify the
    // wait-states when the system clock frequency is changed.
    //
    Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, 4);

    IPCLtoRFlagSet(IPC_FLAG9); // Inform CPU1
    while(IPCRtoLFlagBusy(IPC_FLAG8) == 0); // Wait for CPU1 to set IPC8
    IPCRtoLFlagAcknowledge(IPC_FLAG8);

    //
    // Step 4. Initialize the Device Peripheral. This function can be
    // found in F2837xS_CpuTimers.c
    //
    InitCpuTimers(); // This function initializes the Cpu Timers.

    InitEPwm(); // This function initializes the EPwm(s) to a known state.

    InitECap(); // This function initializes the eCAP(s) IO to a known state. Capture 1 and 2 only.

    ConfigureADC(); // Configure the ADCs and power them up.

    SetupADCSoftwareSync(); // Setup the ADCs for software conversions.

    //
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 200MHz CPU Freq, 1 second Period (in uSeconds)
    //
    //ConfigCpuTimer(&CpuTimer0, 200, 400); // Free run for Fast Squirt.
    CpuTimer0Regs.TCR.bit.FREE = 1; // Timer Free Run Enabled
    CpuTimer0Regs.TCR.bit.TIE = 0; // 0 = Disable/ 1 = Enable Timer Interrupt
    //CpuTimer0Regs.TIM.all // Counter.
    //
    // Reset interrupt counter:
    //
    CpuTimer0.InterruptCount = 0;

    ConfigCpuTimer(&CpuTimer1, 200, 1000); // Time Base. Timer for Datalogger.
    ConfigCpuTimer(&CpuTimer2, 200, 125); // Buzzer.

    //
    // To ensure precise timing, use write-only instructions to write to the
    // entire register. Therefore, if any of the configuration bits are changed in
    // ConfigCpuTimer and InitCpuTimers (in F2837xD_cputimervars.h), the below
    // settings must also be updated.
    //
    CpuTimer0Regs.TCR.all = 0x4000;
    CpuTimer1Regs.TCR.all = 0x4000;
    CpuTimer2Regs.TCR.all = 0x4000;


    //
    // Enable the PIE block
    //
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;

    //
    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
    //
    IER |= M_INT1;
    IER |= M_INT3;
    IER |= M_INT4;
    //IER |= M_INT9;
    IER |= M_INT11;
    IER |= M_INT13;
    IER |= M_INT14;
    //
    // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
    //
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx4 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx5 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx6 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx7 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx8 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx9 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx10 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx11 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx12 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx13 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx14 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx15 = 1;
    PieCtrlRegs.PIEIER3.bit.INTx16 = 1;
    //
    // Enable TINT0 in the PIE: Group 1 interrupt 7
    //
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    //
    // Enable eCAP1 INTn in the PIE: Group 4 interrupt 1
    //
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
    //
    // Enable eCAP2 INTn in the PIE: Group 4 interrupt 2
    //
    PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
    //
    // Enable eCAP5 INTn in the PIE: Group 4 interrupt 5
    //
    // PieCtrlRegs.PIEIER4.bit.INTx5 = 1;
    //
    // Enable eCAP6 INTn in the PIE: Group 4 interrupt 6
    //
    // PieCtrlRegs.PIEIER4.bit.INTx6 = 1;
    //
    // Enable SCIRXINTA INTn in the PIE: Group 9 interrupt 1
    //
    // PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
    //
    // Enable SCITXINTA INTn in the PIE: Group 9 interrupt 2
    //
    // PieCtrlRegs.PIEIER9.bit.INTx2 = 2;
    //
    // Enable global Interrupts and higher priority real-time debug events:

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //

    ECap1Regs.ECCLR.bit.CEVT1 = 1;
    ECap1Regs.ECCLR.bit.INT = 1;
    ECap1Regs.ECCTL2.bit.REARM = 1;

    EINT;
    ERTM;

    //gTimerPOR = TIME_POR;

    gWriteBufferC2.ECU2Ready = 0;

    gFlagPOR_IG = 1;

    //
    // Loop Forever
    //
    for(;;)
    {
    /**/