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.
I am using the same source code to initialize TIMER0 for both cores (CPU1 and CPU2). I am able to initialize, start and service the TIMER0 interrupt for CPU1 (master core) but for CPU2 (slave core), I see it always hitting the ISR for TIMER0 after the TIMER0 is started and Global Interrupts are enabled. I'm not sure why such different behavior is observed with same logic for different cores?
I am clear on the following:
1. Each core is having its timer instances (TIMER0, TIMER1 & TIMER2)
2. TIMER2 is dedicated for TI-RTOS (if used) and can be used as a normal timer module in case of a non-RTOS application.
3. There is no inter-dependency between CPU cores for their individual timer modules.
Can someone please help me figure out what could be going wrong with TIMER0 of CPU2?
Regards.
Sumit Panse
Hi Sumit,
I see it always hitting the ISR for TIMER0 after the TIMER0 is started and Global Interrupts are enabled
Can you please provide more context behind this? The subject line states that Timer 0 on CPU2 is not serviced but here you are saying that the ISR is entered for TIMER0. Is the issue that the ISR is invoked right after you start the timer and not after the timer has finished counting?
Best Regards,
Marlyn
Hi Marlyn,
Sorry, my bad for the subject line. Yes, you got it right, ISR is invoked right after timer is started.
Regards,
Sumit Panse
Hi Sumit,
Thank you for the clarification! Are you using driverlib or bit field code?
I modified the 'ipc_ex1_gpio_toggle' example found in C2000Ware to start timer0 at the same time in both CPU1/CPU2. The interrupt should occur every time the timer is finished: C:\ti\c2000\C2000Ware_4_00_00_00\device_support\f2837xd\examples\dual\ipc_gpio_toggle
Could you please try this if you are using bitfield? If not, let me know and I can generate something in driverlib.
CPU1:
// // Included Files // #include "F28x_Project.h" #include "F2837xD_Ipc_drivers.h" __interrupt void cpu_timer0_isr(void); // // Main // void main(void) { // // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the F2837xD_SysCtrl.c file. // InitSysCtrl(); #ifdef _STANDALONE #ifdef _FLASH // // Send boot command to allow the CPU2 application to begin execution // IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH); #else // // Send boot command to allow the CPU2 application to begin execution // IPCBootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM); #endif #endif // // Clear all __interrupts and initialize PIE vector table: // 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 F2837xD_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 F2837xD_DefaultIsr.c. // This function is found in F2837xD_PieVect.c. // InitPieVectTable(); // // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. // EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.TIMER0_INT = &cpu_timer0_isr; EDIS; // This is needed to disable write to EALLOW protected registers // // Initialize the Device Peripheral. This function can be // found in F2837xD_CpuTimers.c // InitCpuTimers(); // For this example, only initialize the Cpu Timers // // Configure CPU-Timer 0 to __interrupt every 500 milliseconds: // 60MHz CPU Freq, 50 millisecond Period (in uSeconds) // ConfigCpuTimer(&CpuTimer0, 60, 500000); // // 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 = 0x4001; // // Enable CPU INT1 which is connected to CPU-Timer 0: // IER |= M_INT1; // // Enable TINT0 in the PIE: Group 1 __interrupt 7 // PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global __interrupt INTM ERTM; // Enable Global realtime __interrupt DBGM while (IpcRegs.IPCSTS.bit.IPC17 == 0); IpcRegs.IPCACK.bit.IPC17 = 1; CpuTimer0Regs.TCR.bit.TSS = 0; // // Step 6. IDLE loop. Just sit and loop forever (optional): // for(;;); } // // cpu_timer0_isr - CPU Timer0 ISR that toggles GPIO32 once per 500ms // __interrupt void cpu_timer0_isr(void) { CpuTimer0.InterruptCount++; // // Acknowledge this __interrupt to receive more __interrupts from group 1 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; } // // End of file //
CPU2:
// // Included Files // #include "F28x_Project.h" #include "F2837xD_Ipc_drivers.h" __interrupt void cpu_timer0_isr(void); // // Main // void main(void) { // // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the F2837xD_SysCtrl.c file. // // InitSysCtrl(); // // Clear all __interrupts and initialize PIE vector table: // 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 F2837xD_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 F2837xD_DefaultIsr.c. // This function is found in F2837xD_PieVect.c. // InitPieVectTable(); // // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. // EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.TIMER0_INT = &cpu_timer0_isr; EDIS; // This is needed to disable write to EALLOW protected registers // // Initialize the Device Peripheral. This function can be // found in F2837xD_CpuTimers.c // InitCpuTimers(); // For this example, only initialize the Cpu Timers // // Configure CPU-Timer 0 to __interrupt every 500 milliseconds: // 60MHz CPU Freq, 50 millisecond Period (in uSeconds) // ConfigCpuTimer(&CpuTimer0, 60, 500000); // // 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 = 0x4001; // // Enable CPU INT1 which is connected to CPU-Timer 0: // IER |= M_INT1; // // Enable TINT0 in the PIE: Group 1 __interrupt 7 // PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global __interrupt INTM ERTM; // Enable Global realtime __interrupt DBGM IpcRegs.IPCSET.bit.IPC17 = 1; CpuTimer0Regs.TCR.bit.TSS = 0; // // Step 6. IDLE loop. Just sit and loop forever (optional): // for(;;); } // // cpu_timer0_isr - CPU Timer0 ISR that toggles GPIO32 once per 500ms // __interrupt void cpu_timer0_isr(void) { CpuTimer0.InterruptCount++; // // Acknowledge this __interrupt to receive more __interrupts from group 1 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; }
Best Regards,
Marlyn