target/avr/asuro_avr_irrc5.c

Go to the documentation of this file.
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 }

Generated on Fri May 12 10:11:15 2006 for simsuro by  doxygen 1.4.6