Part Number: TMS320F28023
Other Parts Discussed in Thread: C2000WARE, CONTROLSUITE
Hi Champs,
I would like to the device to enter into and exit from low power mode, and the configuration and handler code shows below, can you please help to review the code? Is there any risk especially the disable and reenable interrupt ?
1. Initialize code:
//pieier_table is global array
volatile Uint16 pieier_table[12];
void init_f2802x_lpm(void)
{
int i = 0;
EALLOW;
// Configure the GPIO17 pin as:
// 00: GPIO17 - General purpose I/O 17 (default) (I/O)
// 01: SPISOMIA - SPI-A Slave output/Master input (I/O)
// 10: Reserved
// 11: TZ3 - Trip zone 3 (I)
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; //
GpioCtrlRegs.GPADIR.bit.GPIO17 = 0; // 0 - input mode; 1 - output mode
GpioIntRegs.GPIOLPMSEL.bit.GPIO17 = 1; // Choose GPIO8 pin for wakeup
EDIS;
// 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.WAKEINT = &f2802x_lpm_wake_isr;
EDIS;
com_data.sleep_mode_en = 0;
for(i=0;i<sizeof(pieier_table);i++)
{
pieier_table[i] = 0;
}
}
2. Background loop code:
void f2802x_lpm_handler(void)//runs in background loop
{
static TIMER_T tTime; //3S时间计时
App_TimeBase(S_BASE, &tTime);
if((com_data.sleep_mode_en == 1)&&(System.Compressor.OnOffState == OFF))
{
if(tTime.DelayTime >= 2)
{
save_and_dis_all_interrupts();
// Enable CPU INT1 which is connected to WakeInt:
IER |= M_INT1;
// Enable WAKEINT in the PIE: Group 1 interrupt 8
PieCtrlRegs.PIEIER1.bit.INTx8 = 1;
PieCtrlRegs.PIEACK.bit.ACK1 = 1;
// Enable global Interrupts:
EINT; // Enable Global interrupt INTM
// Write the LPM code value
EALLOW;
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 1) // Only enter low power mode when PLL is not in limp mode.
{
tTime.DelayTime = 0; //clear the timer
//GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
LED_OFF;
SysCtrlRegs.LPMCR0.bit.LPM = 0x0002; // LPM mode = Halt
}
EDIS;
// Force device into HALT
__asm(" IDLE"); // Device waits in IDLE until falling edge on GPIO0/XNMI pin
}
}
else
{
tTime.DelayTime = 0;
}
}
3. ISR code
__interrupt void f2802x_lpm_wake_isr(void)
{
//GpioDataRegs.GPATOGGLE.bit.GPIO1 = 1; // Toggle GPIO1 in the ISR - monitored with oscilloscope
recover_interrupts();
EALLOW;
PieCtrlRegs.PIEIER1.bit.INTx8 = 0;
EDIS;
PieCtrlRegs.PIEACK.bit.ACK1 = 1;
}
2 key functions:
void save_and_dis_all_interrupts(void)
{
EALLOW;
//Save all interrupt first
pieier_table[0] = PieCtrlRegs.PIEIER1.all;
pieier_table[1] = PieCtrlRegs.PIEIER2.all;
pieier_table[2] = PieCtrlRegs.PIEIER3.all;
pieier_table[3] = PieCtrlRegs.PIEIER4.all;
pieier_table[4] = PieCtrlRegs.PIEIER5.all;
pieier_table[5] = PieCtrlRegs.PIEIER6.all;
pieier_table[6] = PieCtrlRegs.PIEIER7.all;
pieier_table[7] = PieCtrlRegs.PIEIER8.all;
pieier_table[8] = PieCtrlRegs.PIEIER9.all;
pieier_table[9] = PieCtrlRegs.PIEIER10.all;
pieier_table[10] = PieCtrlRegs.PIEIER11.all;
pieier_table[11] = PieCtrlRegs.PIEIER12.all;
PieCtrlRegs.PIEIER1.all = 0;
PieCtrlRegs.PIEIER2.all = 0;
PieCtrlRegs.PIEIER3.all = 0;
PieCtrlRegs.PIEIER4.all = 0;
PieCtrlRegs.PIEIER5.all = 0;
PieCtrlRegs.PIEIER6.all = 0;
PieCtrlRegs.PIEIER7.all = 0;
PieCtrlRegs.PIEIER8.all = 0;
PieCtrlRegs.PIEIER9.all = 0;
PieCtrlRegs.PIEIER10.all = 0;
PieCtrlRegs.PIEIER11.all = 0;
PieCtrlRegs.PIEIER12.all = 0;
EDIS;
}
void recover_interrupts(void)
{
EALLOW;
PieCtrlRegs.PIEIER1.all = pieier_table[0] ;
PieCtrlRegs.PIEIER2.all = pieier_table[1] ;
PieCtrlRegs.PIEIER3.all = pieier_table[2] ;
PieCtrlRegs.PIEIER4.all = pieier_table[3] ;
PieCtrlRegs.PIEIER5.all = pieier_table[4] ;
PieCtrlRegs.PIEIER6.all = pieier_table[5] ;
PieCtrlRegs.PIEIER7.all = pieier_table[6] ;
PieCtrlRegs.PIEIER8.all = pieier_table[7] ;
PieCtrlRegs.PIEIER9.all = pieier_table[8] ;
PieCtrlRegs.PIEIER10.all = pieier_table[9] ;
PieCtrlRegs.PIEIER11.all = pieier_table[10];
PieCtrlRegs.PIEIER12.all = pieier_table[11];
EDIS;
}