Hello,
i tried to enter in a low power mode from a interrupt subrutine, but i can`t return. I read in the datasheet about that, but i don´t know what i'm doing wrong. In this code, i want to blink a LED on p1.0 while timer 1 is running and variable "i" is less than 10. When i = 10, i enter to a low power mode (PM2) on the ISR of timer 1, and i try to wake up clearing a bit on port 2 using its ISR. But i can´t return. Any help? Thank you!
#include "ioCC2530.h"
/************************************************/
void contador_on(void);
void contador_off(void);
/**************************************************/
unsigned char i=0;
void main(void)
{
unsigned long y,x=0;
P1 &=~0x01;
P1DIR |= 0x01;
P1 |= 0x01;
PICTL |= 0x08; // Interrupción por flanco de bajada en puerto 2
P2IEN |= 0x01; // Interrupcion habilitada en el p2.0
IEN2 |= 0x02; // Habilitadas las interrupciones para puerto 2
IEN0 |= 0x80; // Habilitadas las interupciones (máscara general off)*/
contador_on();
for(;;){
for(y=0;y<20000;y++) // Toggle a LED on p1.0
P1 &=~0x01;
asm("NOP");
// OTRAS ACCIONES
for(y=0;y<20000;y++)
P1 |= 0x01;
}
}
void contador_on(void) // Inicialize and activation of timer 1
{
T1CNTL |= 0x00; // Reset del contador mediante escritura registro
T1CTL |= 0x0C; // Tick frecuency / 128
T1CTL |= 0x01; // Se activa el contador del timer
TIMIF |= 0x40; // Máscara OFF de interrupción por overflow de timer 1
IEN1 |= 0x02; // Habilitadas las interrupciones para timer 1
IEN0 |= 0x80; // Habilitadas las interupciones (máscara general off)
}
void contador_off(void) // Stop the timer 1
{
T1CTL &=~ 0x0F; // Se desactiva el contador del timer
T1CNTL |= 0x00; // Reset del contador mediante escritura registro
TIMIF &=~ 0x40; // Máscara ON de interrupción por overflow de timer 1
IEN1 &=~ 0x02; // Deshabilitadas las interrupciones para timer 1
}
#pragma vector = 0x33 // 0x33 -> vector interrupcion para puerto 2 en evento pin entrada
__interrupt __root void P2_ISR(void)
{
P2IFG &=~ 0x01; // Puesta a cero del flag de interrupc P2IFG.bit0
IRCON2 &=~ 0x01; // Puesta a cero del flag de interrupc IRCON2.P2IF
//contador_off();
IRCON &=~ 0x02; // Puesta a cero del flag de interrupc IRCON.T1IF
if (i >= 10){
SLEEPCMD &=~ 0x03;
contador_on();
P1 |= 0x01;
}
i=0; // Reinicio contador para desactivación
}
#pragma vector = 0x4B // 0x4B -> vector interrupcion para timer 1 por desbordamiento
__interrupt __root void timer1_ISR(void)
{
IRCON &=~ 0x02; // Puesta a cero del flag de interrupc
T1STAT &=~ 0x20; // Puesta a cero del flag de overflow del timer 1
i++;
if(i >= 10){
contador_off();
P1 &=~0x01;
SLEEPCMD |= 0x02;
PCON = 0x01;
asm("NOP");
asm("NOP");
asm("NOP");
}
}