#define RX 2
#define swPin 5
volatile byte level=255;
volatile unsigned long last, len;
byte p_level;
unsigned long p_len, p_len_prev;
struct
{
byte state;
unsigned long TE;
byte pre_count, data[8], dat_bit;
} keeloq;
void setbit(byte *data, byte n)
{
data[n/8]|=1<<(n%8);
}
#define KL_MIN_PRE_COUNT 4
#define KL_MAX_TE 500
#define KL_MIN_TE 300
#define KL_MAX_BITS 64
void process_keeloq()
{
switch(keeloq.state)
{
case 0:
if(p_level) break;
keeloq.state=1;
keeloq.pre_count=0;
break;
case 1: //pre+hdr
if(p_len>=KL_MIN_TE && p_len<=KL_MAX_TE) keeloq.pre_count++;
else if(!p_level && p_len>=KL_MIN_TE*10 && p_len<=KL_MAX_TE*10 && keeloq.pre_count>=KL_MIN_PRE_COUNT)
{
keeloq.TE=p_len/10;
keeloq.state=2;
keeloq.dat_bit=0;
keeloq.data[0]=0x00;
keeloq.data[1]=0x00;
keeloq.data[2]=0x00;
keeloq.data[3]=0x00;
keeloq.data[4]=0x00;
keeloq.data[5]=0x00;
keeloq.data[6]=0x00;
keeloq.data[7]=0x00;
}
else
{
keeloq.state=0;
break;
}
break;
case 2: //dat
if(!p_level) break;
if(p_len<keeloq.TE/2 || p_len>keeloq.TE*3)
{
keeloq.state=0;
break;
}
if(p_len<=keeloq.TE+keeloq.TE/2) setbit(keeloq.data, keeloq.dat_bit);
if(++keeloq.dat_bit==KL_MAX_BITS) keeloq.state=100;
break;
}
}
void dump_hex(byte *buf, byte bits)
{
byte a;
for(a=0; a<(bits+7)/8; a++)
{
if(buf[a]<=0x0f) Serial.print('0');
Serial.print(buf[a], HEX);
Serial.print(" ");
}
Serial.println("");
}
void rx_int()
{
if(level!=255) return;
len=micros()-last;
last=micros();
if(digitalRead(RX)==HIGH) level=0;
else level=1;
}
void setup()
{
pinMode(swPin, OUTPUT);
digitalWrite(swPin, HIGH);
attachInterrupt(0, rx_int, CHANGE);
Serial.begin(115200);
while(!Serial);
Serial.println("LOGGER START");
Serial.println("");
interrupts();
}
byte a;
void loop()
{
if(level!=255)
{
noInterrupts();
p_level=level;
p_len=len;
len=0;
level=255;
interrupts();
process_keeloq();
p_len_prev=p_len;
}
if(keeloq.state==100)
{
Serial.print("KEELOQ: ");
dump_hex(keeloq.data, 64);
keeloq.state=0;
}
}
#define swPin 5
volatile byte level=255;
volatile unsigned long last, len;
byte p_level;
unsigned long p_len, p_len_prev;
struct
{
byte state;
unsigned long TE;
byte pre_count, data[8], dat_bit;
} keeloq;
void setbit(byte *data, byte n)
{
data[n/8]|=1<<(n%8);
}
#define KL_MIN_PRE_COUNT 4
#define KL_MAX_TE 500
#define KL_MIN_TE 300
#define KL_MAX_BITS 64
void process_keeloq()
{
switch(keeloq.state)
{
case 0:
if(p_level) break;
keeloq.state=1;
keeloq.pre_count=0;
break;
case 1: //pre+hdr
if(p_len>=KL_MIN_TE && p_len<=KL_MAX_TE) keeloq.pre_count++;
else if(!p_level && p_len>=KL_MIN_TE*10 && p_len<=KL_MAX_TE*10 && keeloq.pre_count>=KL_MIN_PRE_COUNT)
{
keeloq.TE=p_len/10;
keeloq.state=2;
keeloq.dat_bit=0;
keeloq.data[0]=0x00;
keeloq.data[1]=0x00;
keeloq.data[2]=0x00;
keeloq.data[3]=0x00;
keeloq.data[4]=0x00;
keeloq.data[5]=0x00;
keeloq.data[6]=0x00;
keeloq.data[7]=0x00;
}
else
{
keeloq.state=0;
break;
}
break;
case 2: //dat
if(!p_level) break;
if(p_len<keeloq.TE/2 || p_len>keeloq.TE*3)
{
keeloq.state=0;
break;
}
if(p_len<=keeloq.TE+keeloq.TE/2) setbit(keeloq.data, keeloq.dat_bit);
if(++keeloq.dat_bit==KL_MAX_BITS) keeloq.state=100;
break;
}
}
void dump_hex(byte *buf, byte bits)
{
byte a;
for(a=0; a<(bits+7)/8; a++)
{
if(buf[a]<=0x0f) Serial.print('0');
Serial.print(buf[a], HEX);
Serial.print(" ");
}
Serial.println("");
}
void rx_int()
{
if(level!=255) return;
len=micros()-last;
last=micros();
if(digitalRead(RX)==HIGH) level=0;
else level=1;
}
void setup()
{
pinMode(swPin, OUTPUT);
digitalWrite(swPin, HIGH);
attachInterrupt(0, rx_int, CHANGE);
Serial.begin(115200);
while(!Serial);
Serial.println("LOGGER START");
Serial.println("");
interrupts();
}
byte a;
void loop()
{
if(level!=255)
{
noInterrupts();
p_level=level;
p_len=len;
len=0;
level=255;
interrupts();
process_keeloq();
p_len_prev=p_len;
}
if(keeloq.state==100)
{
Serial.print("KEELOQ: ");
dump_hex(keeloq.data, 64);
keeloq.state=0;
}
}