00001 /** @file 00002 * 00003 * AVR implementation of IR-RC5 decoding. Based on the c't-Bot version created 00004 * by Benjamin Benz (bbe@heise.de). 00005 * 00006 * @author Denis Martin 00007 * 00008 * This program is free software; you can redistribute it and/or modify it under 00009 * the terms of the GNU General Public License as published by the Free Software 00010 * Foundation; either version 2 of the License, or (at your option) any later 00011 * version. 00012 * This program is distributed in the hope that it will be useful, but WITHOUT 00013 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00015 * details. You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, Inc., 00017 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "asuro.h" 00021 00022 #define AS_IR_SAMPLES_PER_BIT 8 ///< 8 samples per bit 00023 #define AS_IR_SAMPLES_PER_BIT_EARLY 6 ///< edge not before the 6th sample 00024 #define AS_IR_SAMPLES_PER_BIT_LATE 10 ///< edge after 10 samples at the latest 00025 00026 /** 00027 * The start bit is only valid after 200 samples with unchanged edge. 00028 * According to Benz, this should be 50x1.778ms, but since we have an 8-bit 00029 * counter for the samples, we are satisfied with about the half of it. 00030 */ 00031 #define AS_IR_PAUSE_SAMPLES 200 00032 00033 #define AS_IR_PORT PORTD ///< port D 00034 #define AS_IR_DDR DDRD ///< IO direction port D 00035 #define AS_IR_PINR PIND ///< input port D 00036 #define AS_IR_PIN PD0 ///< IO pin on port D 00037 00038 volatile unsigned short AS_ir_data = 0; ///< last completely read RC5 packet 00039 00040 /** @name private variables to the ISR */ 00041 //@{ 00042 char AS_ir_lastsample = 0; ///< last read sample 00043 unsigned char AS_ir_bittimer = 0; ///< call counter for AS_isr_irrc5() 00044 unsigned short AS_ir_data_tmp = 0; ///< RC5 bit stream 00045 char AS_ir_bitcount = 0; ///< number of read bits 00046 //@} 00047 00048 /** 00049 * ISR for receiving IR-RC5 commands 00050 * 00051 * called about every 222.2us 00052 */ 00053 void AS_isr_irrc5(void) { 00054 // read a sample 00055 char sample = 1; 00056 if (AS_IRRX_SAMPLE) sample = 0; 00057 00058 // increase bittimer - the timer stops at 255 00059 if (AS_ir_bittimer < 255) AS_ir_bittimer++; 00060 00061 if (AS_ir_lastsample != sample) { 00062 // edge detected 00063 // start bit? 00064 if (AS_ir_bitcount == 0) { 00065 if (sample && (AS_ir_bittimer > AS_IR_PAUSE_SAMPLES) ) { 00066 // save start bit 00067 AS_ir_data_tmp = 1; 00068 AS_ir_bitcount++; 00069 00070 } else { 00071 // error 00072 AS_ir_data_tmp = 0; 00073 00074 } 00075 00076 // bittimer reset 00077 AS_ir_bittimer = 0; 00078 00079 // bits 2..14: only consider edges within bits 00080 } else { 00081 if (AS_ir_bittimer >= AS_IR_SAMPLES_PER_BIT_EARLY) { 00082 if (AS_ir_bittimer <= AS_IR_SAMPLES_PER_BIT_LATE){ 00083 // save bit 00084 AS_ir_data_tmp = (AS_ir_data_tmp << 1) | sample; 00085 AS_ir_bitcount++; 00086 00087 } else { 00088 // too late, trop packet 00089 AS_ir_bitcount = 0; 00090 00091 } 00092 00093 // bittimer-reset 00094 AS_ir_bittimer = 0; 00095 } 00096 } 00097 00098 } else { 00099 // no edge within bit time? 00100 if (AS_ir_bittimer > AS_IR_SAMPLES_PER_BIT_LATE) { 00101 // 14 bits read? 00102 if (AS_ir_bitcount == 14) { 00103 AS_ir_data = AS_ir_data_tmp; 00104 } 00105 00106 // drop packet 00107 AS_ir_bitcount = 0; 00108 } 00109 } 00110 00111 // save sample in sample buffer 00112 AS_ir_lastsample = sample; 00113 } 00114 00115 /** 00116 * Read the last IR-RC5 code received. This will flush the input, thus 00117 * subsequent calls will return 0 or a new value. 00118 * 00119 * @return Last IR RC5 code received 00120 */ 00121 inline unsigned short AS_Irrc5Read(void) { 00122 unsigned short rv = AS_ir_data; 00123 AS_ir_data = 0; 00124 return rv; 00125 }