+
+static unsigned char nsamples;
+static uint32_t samples;
+
+ISR(INT0_vect)
+{
+ /* ignore interrupts while a previous input is pending */
+ if(pending & 1) return;
+
+ /* IR going low */
+ ir_input = 0;
+ nsamples = 1; /* we're starting in the middle of the first bit which should be 01 (=1) */
+ samples = 0;
+ EIMSK &= 0xfe; /* disable further interrupts while decoding IR code */
+
+ TCNT0 = 96; /* reset the counter to half the range so it'll trigger in the middle of the current pulse */
+ TIFR0 |= 1 << OCF0A; /* clear pending interrupts */
+ TIMSK0 = 1 << OCIE0A; /* enable output compare interrupt */
+
+ //PORTB ^= 1;
+}
+
+ISR(TIMER0_COMPA_vect)
+{
+ static unsigned char err;
+
+ PORTB ^= 1;
+
+ samples = (samples << 1) | (~(PIND >> PD_IR) & 1);
+ if((++nsamples & 1) == 0) {
+ if((samples & 3) == 0 || (samples & 3) == 3) {
+ /* 00 or 11 are invalid sequences, we lost sync */
+ err = 1;
+ }
+
+ /* 01->1, 10->0 */
+ ir_input = (ir_input << 1) | (samples & 1);
+ }
+
+ if(nsamples >= 28) {
+ if(err) {
+ ir_input |= 0x8000;
+ }
+ pending |= 1;
+ err = 0;
+ TIMSK0 &= ~(1 << OCIE0A); /* disable the sampling interrupt */
+ EIMSK |= 1; /* re-enable the edge-detect interrupt for the next input */
+ }
+}
+
+ISR(INT1_vect)
+{
+ enable = (~PIND >> PD_ENSW) & 1;
+ pending |= 2;
+}