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; } }