forked from Elektron2016/key_copy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetakom.c
119 lines (100 loc) · 3.17 KB
/
metakom.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
* metakom.c
*
* Created: 30.01.2016 2:13:32
* Author: Elektron
*/
#include <avr/io.h>
#include <util/delay.h>
#include "metakom.h"
#define MK_PORT PORTC
#define MK_DDR DDRC
#define MK_LINE 0
#define ADC0 0b00000000
#define ADC1 0b00000001
#define ADC2 0b00000010
#define ADC3 0b00000011
#define ADC4 0b00000100
#define ADC5 0b00000101
#define ADC6 0b00000110
#define ADC7 0b00000111
#define ADC8 0b00001000
#define AVG_U_SUM 100
#define AVG_T_SUM 100
uint8_t mk_code[9];
void mk_init()
{
ADCSRA = (1 << ADEN) // ðàçðåøåíèå ÀÖÏ
|(1 << ADSC) // çàïóñê ïðåîáðàçîâàíèÿ
|(1 << ADATE) // íåïðåðûâíûé ðåæèì ðàáîòû ÀÖÏ
|(0 << ADPS2)|(1 << ADPS1)|(1 << ADPS0) // ïðåääåëèòåëü íà 8 (÷àñòîòà ÀÖÏ 148kHz)
|(0 << ADIE); // çàïðåò ïðåðûâàíèÿ
ADCSRB = (0 << ADTS2)|(0 << ADTS1)|(0 << ADTS0); // íåïðåðûâíûé ðåæèì ðàáîòû ÀÖÏ
ADMUX = (0 << REFS1)|(1 << REFS0) // îïîðíîå íàïðÿæåíèå AVCC
|(1 << ADLAR) // ñìåùåíèå ðåçóëüòàòà (âëåâî ïðè 1, ÷èòàåì 8 áèò èç ADCH)
|(ADC0); // âõîä ADC0
}
uint8_t mk_crc(uint8_t* data)
{
for(uint8_t i=0;i<4;i++) data[i] = 0; //î÷èùàåì ìàññèâ êîäà êëþ÷à
if((mk_code[0] & 0xE0) != 0b01000000) return MK_NO_KEY; //ïðîâåðÿåì íàëè÷èå ñòàðòîâîãî ñëîâà
for(uint8_t i=0;i<8;i++) //ïðîâåðÿåì ñîâïàäåíèå äâóõ êîïèé êîäà êëþ÷à
if(((mk_code[i/8]<<(i%8)) & 0x80) != ((mk_code[(i+35)/8]<<((i+35)%8)) & 0x80)) return MK_NO_KEY;
for(uint8_t i=0;i<32;i++) //êîïèðóåì êîä êëþ÷à â ìàññèâ
if(mk_code[(i+3)/8] & 0x80>>((i+3)%8)) data[i/8] |= 0x80>>(i%8);
for(uint8_t i=0;i<4;i++){ //ïðîâåðÿåì ÷åòíîñòü
uint8_t parity = 0;
for(uint8_t j=0;j<7;j++){
if(data[i] & 0x80>>j) parity ^= 0x01;
}
if((data[i] & 0x01) != parity) return MK_NO_KEY;
}
return MK_READ_OK;
}
uint8_t mk_read(uint8_t* data)
{
uint16_t sum = 0;
uint8_t avg_t = 0, avg_u = 0, temp = 0;
for(uint8_t i=0;i<9;i++)mk_code[i] = 0; //÷èñòèì ìàññèâ ïðèåìà
for(uint8_t i=0;i<AVG_U_SUM;i++){ //îïðåäåëÿåì ñðåäíåå íàïðÿæåíèå
sum += ADCH;
_delay_us(10);
}
avg_u = sum / AVG_U_SUM;
sum = 0;
for(uint8_t u=0,i=0;i<AVG_T_SUM;i++){ //îïðåäåëÿåì äëèòåëüíîñòü öèêëà ãåíåðàòîðà êëþ÷à
for(uint8_t t=0;t<200;t++){
if(ADCH < avg_u && u){sum += t; u = 0;break;}
if(ADCH > avg_u && !u){sum += t; u = 1;break;}
_delay_us(4);
}
}
avg_t = sum / AVG_T_SUM;
if(avg_t < 5 || avg_t > 23) return MK_NO_KEY;
for(uint8_t i=0;i<255;i++){ //æäåì ñèíõðîíèçèðóþùèé áèò
uint8_t t;
_delay_us(10);
if(ADCH >= avg_u) continue;
for (t=0;t<100;t++){
_delay_us(10);
if(ADCH > avg_u) break;
}
if(t > avg_t) {temp = 1;break;}
}
if(temp == 0) return MK_NO_KEY;
for(uint8_t i=0;i<70;i++){ //ïèøåì â áóôåð ïðèåìà ñòàðòîâîå ñëîâî è êîä êëþ÷à äâàæäû
uint8_t t;
for (t=0;t<=150;t++){
if(ADCH < avg_u) break;
_delay_us(4);
}
if(t == 150) return MK_NO_KEY;
if(t > avg_t) mk_code[i/8] |= 0x80>>(i%8);
for (t=0;t<=150;t++){
if(ADCH > avg_u) break;
_delay_us(4);
}
if(t == 150) return MK_NO_KEY;
}
return mk_crc(data);
}