Hello
I have written following code for decoding NEC IR data.
This code works fine but sometimes it stuck somewhere and I need to reset the msp430g2102.
I have used timer A0 in capture mode and enable interrupts at both edges.
Can any one let me know why is it stuck sometimes?
Complete code is in attached file .
Thanks
manish
#include<msp430g2102.h>
// IR pulse timing constants in microseconds
#define HP_MIN 8500 // Header pulse minimum duration
#define HP_MAX 9500 // Header pulse maximum duration
#define HPL_MIN 4100 // Header pulse low minimum duration
#define HPL_MAX 4800 // Header pulse low maximum duration
#define RPT_MIN 1900 // Repeat pulse minimum duration
#define RPT_MAX 2500 // Repeat pulse minimum duration
#define BP_MIN 450 // Bit pulse minimum duration
#define BP_MAX 650 // Bit pulse maximum duration
#define ONE_MIN 2000 // Logical one minumum duration
#define ONE_MAX 2500 // Logical one maxumum duration
#define ZERO_MIN 1000 // Logical zero minumum duration
#define ZERO_MAX 1300 // Logical zero maxumum duration
#define FALSE 0
#define TRUE (!FALSE)
#define IR_REPEAT 0xFF00 // Special repeat code
#define MAX_DATA_BITS 32 // NEC protocol provides for 32 bits of data
#define PIN_IR BIT1 // This must be TA0.0
#define PIN_PS_ON BIT4 // LED1 on the Launchpad
#define BUTTON_POWER 0X04FB00FF // This is a code for the button to toggle the LED
static volatile unsigned long data;
void ir_init(void)
{
_BIC_SR(GIE); //DISABLE THE GLOBLE INTERRUTS
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz to measure pulses in microseconds
DCOCTL = CALDCO_1MHZ;
P1DIR &= ~PIN_IR; // Set IR detector pin to input
P1OUT |= PIN_IR; // Set resistor to pull-up
P1REN |= PIN_IR; // Enable resistor
P1SEL |= PIN_IR; // set IR detector pin to peripheral function
TACTL = TASSEL_2 | ID_0 | MC_2; // SMCLK, Continuous mode, Input divider /1
TACCTL0 = CM_3 | CCIS_0 | CAP | CCIE; // Capture on both edges, Capture Input Select CCI0A, Capture mode, Capture interrupt enable
_BIS_SR(GIE); //ENABLE THE GLOBLE INTERRUTS
}
void Re_start_timer()
{
TACTL |= TACLR;
TACTL = TASSEL_2 | ID_0 | MC_2; // SMCLK, Continuous mode, Input divider /1
TACCTL0 = CM_3 | CCIS_0 | CAP | CCIE; // Capture on both edges, Capture Input Select CCI0A, Capture mode, Capture interrupt enable
}
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop the Watchdog timer
P1DIR = PIN_PS_ON; // LED1 to output
ir_init(); // Initialize IR detection
while(1)
// Loop forever
{
// Set a breakpoint on the next line and add a watch for the data variable to see the IR code received
if (data == BUTTON_POWER) // If remote power button is pressed
{
P1OUT ^= PIN_PS_ON; // Toggle LED1
}
}
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)
{
static unsigned char hp, hr; //header pulse received, header received
static unsigned char br; // bits received
static unsigned char pulse=FALSE; // pulse in progress
static volatile unsigned char ready = FALSE; // data ready
static unsigned int pw=0, bw=0; // pulse width, bit width
unsigned int i = TAIV; // Read TAIV to clear CCIFG
// Is this the beginning or the end of the pulse?
if (!pulse)
// start of the pulse
{
bw=TACCR0;
// reset Timer
//TACTL |= TACLR;
Re_start_timer();
pulse=TRUE;
// Has the header pulse just been received?
if (hp)
{
// Is the header duration in range?
if (bw>HPL_MIN && bw<HPL_MAX)
{
hr=TRUE;
br=0;
data=0;
ready=FALSE;
}
// is it a repeat code?
else if (bw>RPT_MIN && bw<RPT_MAX)
{
data=IR_REPEAT;
hr=FALSE;
ready=TRUE;
}
}
// Was there a bit pulse before, and also has the header been received?
if(hr && pw>BP_MIN && pw<BP_MAX)
{
if (bw>ONE_MIN && bw<ONE_MAX)
{
data<<=1;
data++;
br++;
}
else if (bw>ZERO_MIN && bw<ZERO_MAX)
{
data<<=1;
br++;
}
if (br==MAX_DATA_BITS)
{
hr=FALSE;
ready=TRUE;
}
}
hp=FALSE;
}
else
// end of the pulse
{
pw=TACCR0;
pulse=FALSE;
// Is this a header pulse?
if (pw>HP_MIN && pw<HP_MAX)
{
// set Header Pulse Received flag
hp=TRUE;
// Reset timer
Re_start_timer();
}
else
{
hp=FALSE;
}
}
if (ready)
{
ready = FALSE;
}
}