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.

wakeup and GPIO6 interrupts

I have a problem using wakeup and GPIO6 interrupts.

I have experimented with the TI code - Example_280xHaltWake and everything works well.
In my setup I am using GPIO6 as an interrupt on power off AND power ON (falling and rising edge).
The desired behaviour is :

1 - observe interrupt on GPIO6 falling edge AND DSP goes into low power mode
2 - observe interrupt on GPIO6 rising edge
3 - observe wakeup interrupt

But I see the GPIO6 falling edge interrupt then execute the IDLE instruction and
then immediately the DSP wakes up.
So I see :

1 - GPIO6 Down
2 - Out Of IDLE
3 - WakeUp
4 - GPIO6 Up

However the DSP never sleeps. My initialization is given below.


Step 1
======

// GPIO-06 - PIN FUNCTION = Power_Good
   GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;  // 0=GPIO,  1=EPWM4A,  2=SYNCI,  3=SYNCO
   GpioCtrlRegs.GPADIR.bit.GPIO6 = 0;  // 1=OUTput,  0=INput

// signal qualification
   GpioCtrlRegs.GPAQSEL1.bit.GPIO6 = 2;         // XINT1 qual using 6 samples
   GpioCtrlRegs.GPACTRL.bit.QUALPRD0 = 0xff;    // sampling window is 510 * SYSCLKOUT
// end qualification 

   GpioIntRegs.GPIOLPMSEL.bit.GPIO6 = 1;        // Set to enable Lpm wake-up
   GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 6;    // Set GPIO 6 to be an Interrupt
// GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;         // uncomment if --> Set Low initially
// GpioDataRegs.GPASET.bit.GPIO6 = 1;  // uncomment if --> Set High initially


//EXTERNAL INTERRUPT ENABLES
   XIntruptRegs.XINT1CR.bit.POLARITY = 3;       // = 0b11 = Trigger on falling and rising edges
   XIntruptRegs.XINT1CR.bit.ENABLE = 1;


Step 2
======
   DINT; 
   //Initialize interrupts
   EALLOW;

   PieVectTable.XINT1 = powerISR;
   PieVectTable.WAKEINT = WakeUp;  
   EDIS;

// Enable the PIE
   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
 
   PieCtrlRegs.PIEIER1.bit.INTx4 = 1; //enable XINT1 for power_good
   PieCtrlRegs.PIEIER1.bit.INTx8 = 1; //enable WakeINT for power_good
   PieCtrlRegs.PIEIER8.bit.INTx1 = 1; //enable I2c interrupts
   PieCtrlRegs.PIEIER9.bit.INTx1 = 1; //enable SCIRXINTA
   PieCtrlRegs.PIEIER9.bit.INTx2 = 1; //enable SCITXINTA

   PieCtrlRegs.PIEIFR1.bit.INTx4 = 0; //clear any pending XINT1 interrupts
   PieCtrlRegs.PIEIFR1.bit.INTx8 = 0; //clear any pending WakeINT interrupts
   PieCtrlRegs.PIEIFR8.bit.INTx1 = 0; //clear any pending I2C interrupts
   PieCtrlRegs.PIEIFR9.bit.INTx1 = 0; //clear any SCI-A receive interrupts
   PieCtrlRegs.PIEIFR9.bit.INTx2 = 0; //clear any SCI-A transmit interrupts


Step 3
======

void interrupt powerISR(void) {
  
     if (POWER_GOOD == 0) {  //Power going down - falling edge
         SendDebugMessage("GPIO6 Down\r\n");
     
         DINT;
       
         if(SysCtrlRegs.PLLSTS.bit.MCLKSTS == 0)    {        
             EALLOW;
             SysCtrlRegs.LPMCR0.bit.LPM = HALT;
             EDIS;
             asm (" IDLE");  // halt
             SendDebugMessage("Out Of IDLE\r\n");
         }
         else
             SendDebugMessage("Can't HALT, operating in limp mode.\r\n");
      }
      else {                 //power is good
         DINT;
         IER |= M_INT1; // re-enable
         IER |= M_INT9;
         IER |= M_INT8;
         EINT;
  
         SendDebugMessage("GPIO6 Up\r\n");
      }

      PieCtrlRegs.PIEACK.bit.ACK1 = 1; // acknowledge this interrupt
}

void interrupt WakeUp(void) {
 
   DINT;
   IER = M_INT1; // re-enable
   IER |= M_INT9;
   IER |= M_INT8;
   EINT;
 
   SendDebugMessage("WakeUp\r\n");

   PieCtrlRegs.PIEACK.bit.ACK1 = 1; // acknowledge this interrupt
}

  • I am not exactly sure whether GPIO6 is going down then up properly when you test but if it isn't I would check for noise on that pin (there has been a post about noise on the wake pin recently).  If the external behaviour is GPIO6 down - GPIO6 up, then your program is working as it is coded (unfortunately not as you want it though).

    From your post, what I understand you want your program to do is the following:

    1 - GPIO6 Down

    2 - Out Of IDLE

    3 - GPIO6 Up

    4 - WakeUp

    but instead it is

    1 - GPIO6 Down
    2 - Out Of IDLE
    3 - WakeUp
    4 - GPIO6 Up

    What is happening is that when GPIO6 goes up both the wake int and XINT are triggered.  The PIE will then assign a priority to them.  You will have to look up which of XINT or WAKEUPINT has the highest priority.  If it is WAKEUPINT, then your code will always execute in this order.  You may be able to reorder them by some fancy enabling/disabling of interrupt enable flags but that is the only thing I can think of at this stage.


    Hopefully that helps,

     

    Tim


  • Thanks.

    Rather than trying to use one GPIO interrupt, we are going to try to separate the rising edge and falling edge into two separate GPIO inputs.

    From a software solution, that may be easier.

    Thanks-

  • Yes, that looks like an easier solution.  It will also alleviate any potential issues due to the same interrupt triggering whilst it is still running (which is what occurs above).

    Tim