int getheader () { unsigned int code, gob; /* look for startcode */ startcode (); code = getbits (PSC_LENGTH); gob = getbits (5); if (gob == SE_CODE) return 0; if (gob == 0) { if (trace) { fprintf (trace_file, "\nPSC: "); printbits ((code << (5 + gob)), 22, 22); } getpicturehdr (); if (syntax_arith_coding) /* reset decoder after receiving */ decoder_reset (); /* fixed length PSC string */ } else { if (trace) { fprintf (trace_file, "\nGBSC: "); printbits ((code << (5 + gob)), 22, 22); } } return gob + 1; }
void ir_receive_init( void ) { /*** Configure Timer A ***/ TACTL = TASSEL_SMCLK /* SMCLK clock source */ /* No clock divider */ | MC_STOP /* Timer stopped for now */ /* Don't reset the timer */ | TAIE /* Interrupt enabled */; /* Clear the timer */ TAR = 0; /* Set up CCR1 to trigger off the comparator */ TACCTL1 = CM_POS /* Trigger on positive edges */ | CCIS_0 /* CCI0A trigger source (COMP) */ | SCS /* Synchronize with timer clock */ | CAP /* Capture mode */ | CCIE; /* Interrupt enabled */ /* Set P1.2 to be the CCR1 input CCI0A */ /* Page 57 of the MSP430F2234 datasheet */ P1DIR &= ~0x04; P1SEL |= 0x04; /* Make the PD1,2,3 signals low outputs, so they are clamped when */ /* their analogue channels are deselected. This prevents photocurrent */ /* from flowing into the battery measurement input. Insane! */ P2DIR |= 0x0f; P2OUT &= 0xf0; /*** Bias resistor config ***/ bias_comms(); decoder_reset(); /* Start the timer */ timera_en(); }
static inline void decoder_newdata( uint16_t period ) { uint8_t sym; /* Check that the frequency reaches the minimum */ if( period < (period_lut[0] - RANGE) ) { decoder_reset(); return; } for( sym=0; sym < NFREQ; sym++ ) if( period < (period_lut[sym] + RANGE) ) break; if( sym == NFREQ ) { /* Invalid frequency - reset the decoder */ decoder_reset(); return; } /* Ignore repeated symbols */ if( sym == last_sym ) return; /*** Decode the symbol ***/ if( sym == 0 ) { cb_pos = 0; curbyte = 0; last_sym = 0; return; } /* Remove the step over the last symbol */ if( sym > last_sym ) { last_sym = sym; sym--; } else last_sym = sym; /* Start of the byte? */ sym--; curbyte |= sym << (cb_pos * NBITS); cb_pos++; if( cb_pos == SYMBOLS_PER_BYTE ) { static uint8_t checksum; static bool escaped = FALSE; /* We now have a full byte */ cb_pos = 0; if( curbyte == 0x7e ) { /* Start of frame */ d_pos = 0; checksum = 0; data[0] = 0x7e; escaped = FALSE; } else if( data[0] == 0x7e ) { if( curbyte == 0x7d ) { escaped = TRUE; return; } else if( escaped ) { curbyte ^= 0x20; escaped = FALSE; } data[d_pos] = curbyte; /* data[1] is the length if we've got that far */ if( d_pos > 1 && d_pos == (data[1] + 2) ) { /* Frame reception complete -- check the checksum */ if( checksum == curbyte ) net_rx_proc_incoming( data+2, data[1] ); } else checksum_add( checksum, curbyte ); } if( data[0] == 0x7e ) d_pos = (d_pos==(DATA_LEN-1))?0:(d_pos+1); } }
interrupt (TIMERA1_VECTOR) timer_a_isr(void) { uint16_t taiv_l = TAIV; /* Number of times the timer has wrapped since the last edge */ static uint8_t nwraps = 0; switch( taiv_l ) { /* CCR1: */ case 0x02: { /* Previous periods */ static int16_t prev[AVERAGE]; /* Position in the prev buffer */ static uint8_t pos = 0; /* The last recorded period */ static uint16_t last_period = 0; uint16_t reading = TACCR1; /* The last TACCR1 reading: */ static uint16_t last_taccr1 = 0; uint32_t sum = 0; uint8_t i; /* The timer may have wrapped around since the last event */ if( nwraps == 0 ) reading -= last_taccr1; else if( nwraps == 1 ) /* The timer wrapper - compensate */ reading = ((uint32_t)(reading) + 0xffff) - last_taccr1; last_taccr1 = TACCR1; /* Currently triggering on positive edges: */ reading >>= 1; /* Reset the receiver if the recorded period was too long */ if( nwraps > 1 || reading > (MAX_PERIOD + RANGE) ) { /* Lost the signal */ decoder_reset(); last_period = 0; } /*** Determine whether we've reached a stable period ***/ /* Store the difference between this period and the last recorded */ prev[pos] = reading - last_period; pos = (pos == AVERAGE-1)?0:pos+1; /* Sum the absolute values of the last AVERAGE derivatives */ for(i=0; i<AVERAGE; i++) if( prev[i] < 0 ) sum += (-prev[i]); else sum += prev[i]; /* Only accept this frequency if it's stable */ if( sum < STABLE_THRESH ) { /* Got a stable frequency */ /* It might be the same as the last, but we can't tell until it's been decoded as a symbol */ decoder_newdata( reading ); debug_symbol_lock(); } else { debug_symbol_nolock(); } last_period = reading; nwraps = 0; break; } /* Timer overflow */ case 0x0A: { nwraps++; break; } default: /* Should never get here. */ nop(); } }