/* rc5dec.c 0.2.0 - Interrupt driven RC5 decoder for Atmel AVR \u013eC's. Website: http://markh.de/rc5dec/ Copyright (C) 2003 Mark Haemmerling This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Preconfigured for INT1 (PD3) and Timer/Counter0. */ #include //#include #include #include // set your clock speed here #define XTAL 8000000 // you may have to experiment a little with this // in case of heavy disturbance, try values around 60 // try to use odd values (for symmetrical level detection) #define RC5RESAMPLE 25 // this autoconfigures all timer values: #if XTAL < 285000 # define PRESCALEDIV 1 # define TIMERCR (1< ((uint8_t) (RC5RESAMPLE/2))); if (rc5_first_half == 2) { // this is a timeout, cancel operation goto rc5_cancel; } else if (rc5_first_half == 1) { // this sample is taken in the first half of the bit (1/4 bit time) first_level = level; // save current level if (level) MCUCR &= ~( 1 << ISC10);// cbi(MCUCR, ISC10); // currently at high level, wait for falling edge else MCUCR |= ( 1 << ISC10);//sbi(MCUCR, ISC10); // currently at low level, wait for rising edge rc5_first_half = 2; // special code, means: next ovf int is a timeout GICR |= ( 1 << INT1);//sbi(GICR, INT1); // much better: wait for edge ;) TCNT0 = RC5TIMERCANCEL; // at timer ovf (in around 1/2 bit time) we should get a timeout } else { // this sample is taken in the second half of the bit (3/4 bit time) TCNT0 = RC5TIMERFIRST; // next sample at first half (1/4 bit time) of next bit rc5_first_half = 1; if (first_level != level) { // levels differ -> valid manchester encoded bit detected if (!rc5_bit) { // this is the first bit, reset values rc5_temp = 0; rc5_shift = 0x8000; } if (!level) rc5_temp |= rc5_shift; // low level (low-active) so store a '1' else if (rc5_bit < 2) goto rc5_cancel; // high level ('0' bit) as startbit -> error if (++rc5_bit == 14) { // reception complete, stop operation rc5_code = rc5_temp; goto rc5_cancel; } if (rc5_shift == 0x0100) rc5_shift = 0x0020; else rc5_shift >>= 1; } else { // error in manchester stream -> cancel operation goto rc5_cancel; } } return; rc5_cancel: MCUCR &= ~( 1 << ISC10); //cbi(MCUCR, ISC10); // falling edge GICR |= ( 1 << INT1); //sbi(GICR, INT1); // ext. int. enabled GIFR = (1<