00001
00002
00003
00004
00005
00006
00007
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;
00020 volatile u08 irrstring[IRMSLENGTH];
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++;
00039 for (; i < (data[0]*8)+1; i++) {
00040 if (DATA(i)) ibitcount++;
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;
00067 else {
00068 irdata[i + 3] = 0xFC;
00069 irdata[11] ^= 0xFF;
00070 }
00071 irdata[11]=(irdata[11]==0xFF)?0xE0:0xFC;
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
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]++;
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);
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