Main Page | File List | Globals

ir.c

Go to the documentation of this file.
00001 //
00002 // C Implementation: ir for robot and station
00003 //
00004 // Description:
00005 //
00006 //
00007 // Author: Leonhard Klein <leoklein@gmx.net>, (C) 2004
00008 #include "ir.h"
00009 #include <avr/interrupt.h>
00010 #include <avr/eeprom.h>
00011 
00012 #define IRON   (PORTB |= _BV(PB4))
00013 #define IROFF  (PORTB &= ~_BV(PB4))
00014 #define IRTOGGLE (PORTB ^= _BV(PB4))
00015 
00016 u16 irtime;
00017 s16 irbit;
00018 
00019 volatile irdatatype irrbuf;                                              //< here the received irpulse is stored
00020 volatile u08 irrstring[IRMSLENGTH];                                      //< here the received irdatas are stored
00021 
00022 volatile u08 *irsbuf;                                                    
00023 volatile u08 *senddata;                                                  
00024 volatile u08 pulsevalid;
00025 volatile u08 stringvalid;
00026 volatile u08 sendready;
00027 
00028 irdatatype cmp_target[IRKEYS];
00029 
00030 
00031 u08 ir_to_val(irdatatype data) {
00032   u08 i, ibitcount, r, rb;
00033 #define DATA(x) (data[x>>3]&(1<<(7-(x%8))))
00034   r = 0;
00035   rb = 0;
00036   ibitcount = 0;
00037   irerror=0;
00038   i = 12; while (DATA(i)!=0) i++;                                                   // find '0'
00039   for (; i < (data[0]*8)+1; i++) {
00040     if (DATA(i)) ibitcount++;                                                      // count '1'
00041     else {
00042       if (ibitcount >= 2) {
00043         if ((rb == 8)) {
00044           for (i=0;i<=7;i++) if (r & (1 << i)) rb++;
00045           irerror = ((rb%2)^(ibitcount <= 4));
00046           return r;
00047         }
00048         r |= (1<<rb++)*(ibitcount > 4);
00049       }
00050       ibitcount = 0;
00051     }
00052   }
00053   irerror = 2;
00054   return r;
00055 }
00056 
00057 u08 *val_to_ir(u08 dat) {
00058   u08 i;
00059   static irdatatype irdata;
00060   irdata[0] = 12;
00061   irdata[1] = 0xFF;
00062   irdata[2] = 0xF0;
00063   irdata[11] = 0x00;
00064   for (i=0; i<8; i++)
00065     if ((dat & _BV(i)) == 0)
00066       irdata[i + 3] = 0xE0; //0b1110 0000
00067     else {
00068       irdata[i + 3] = 0xFC; //0b1111 1100
00069       irdata[11] ^= 0xFF;
00070     }
00071   irdata[11]=(irdata[11]==0xFF)?0xE0:0xFC; //gerade: 0, ungerade: 1
00072   return irdata;
00073 }
00074 
00075 void do_ir() {
00076 #define IRSBUF(x) (irsbuf[x>>3]&(1<<(7-(x%8))))
00077   static u08 irbiton;
00078   u08 i;
00079   if (modus == ir_s) {
00080     if (irtime++ >= irbittime) {
00081       irtime = 0;
00082       irbiton = (IRSBUF(irbit) != 0);
00083       irbit++;
00084     }
00085     if (irbiton)
00086       IRTOGGLE;
00087     else
00088       IROFF;
00089     if (irbit == irsbuf[0]*8) {
00090       TCCR0 = _BV(CS01);
00091       modus = oldmodus;
00092     }
00093   } else                                                  /* receive */
00094     if (irtime++ >= irbittime) {
00095       irtime=0;
00096       if (ISIRON) {
00097         irbiton = 0;
00098         irrbuf[irbit>>3] |= (1<<(7-(irbit % 8)));
00099       } else {
00100         if (irbiton++ == 20) {
00101           irrbuf[0] = (irbit>>3)-1;
00102           irbit = (IRMLENGTH<<3)+3;
00103         }
00104       }
00105       irbit++;
00106       if (irbit > (IRMLENGTH<<3)) {
00107         pulsevalid = 1;
00108         i = ir_to_val(irrbuf);
00109         if ((!irerror) & (irrbuf[0] < 15)) {
00110           if (irrstring[0] < IRMSLENGTH) irrstring[0]++;  /* irrstring[0]=0 : Empty -> first increment */
00111           irrstring[irrstring[0]] = i;
00112           if (!i) stringvalid = 1;
00113         }
00114         TCCR0 = _BV(CS01);
00115         modus = oldmodus;
00116       }
00117     }
00118 }
00119 void ir_send(u08 *irbuf_) {                                       
00120   if ((modus == ir_s)|(modus == ir_r)) return;
00121   irsbuf = irbuf_;
00122   TCCR0 = _BV(CS00);                                              /* prescaler = 0 */
00123   TCNT0 = 255;
00124   irbit = 0;
00125   irtime = irbittime;
00126   TCCR2 = 0;
00127   oldmodus = modus;
00128   modus = ir_s;
00129 }
00130 void start_ir_r() {
00131   if ((modus == ir_s)|(modus == ir_r)) return;
00132   TCCR0 = _BV(CS00);
00133   TCNT0 = 255;
00134   for (irbit=1;irbit < IRMLENGTH;irbit++)
00135     irrbuf[irbit] = 0x00;
00136   irrbuf[0]=IRMLENGTH;
00137   irbit = 8;
00138   irtime = 0;
00139   TCCR2 = 0;
00140   oldmodus = modus;
00141   modus = ir_r;
00142 }
00143 void ir_string_send(u08 *se) {
00144   senddata=se;
00145   oldmodus2 = modus;
00146   modus = irstring_s;
00147   sendready = 0;
00148   WAITIR;
00149 }
00150 void do_ir_string() {
00151   static u16 timeir;
00152   u08 data;
00153   if (timeir > IRDATABYTETIME) {
00154     sendready = 1;
00155     modus = oldmodus2;
00156     timeir = IRDATABYTETIME-1;
00157     return;
00158   }
00159   if (timeir++ == IRDATABYTETIME) {
00160     data = senddata[0];
00161     ir_send(val_to_ir(data));
00162     if (data != 0) timeir = 0;
00163     senddata++;
00164   }
00165 }
00166 u08 ir_comp(irdatatype cmp_target, irdatatype read_ir) {
00167   u08 i = 127;
00168   u08 i2;
00169   for (i2=8;i2<=(cmp_target[0]<<3);i2++)
00170     if (cmp_target[i2 >> 3] & (1 << (i2 % 8)))
00171           if (read_ir[i2 >> 3] & (1 << (i2 % 8))) i++; else i--;
00172   return i;
00173 }
00174 #ifdef STATION
00175 void ir_and(irdatatype res, irdatatype and2) {
00176   u08 i;
00177   for (i=1;i<=res[0];i++) {
00178     res[i] &= and2[i];
00179   }
00180 }
00181 #endif

Generated on Wed Feb 2 20:03:50 2005 for Robot by doxygen 1.3.6