2 #include <avr/interrupt.h>
3 #include <util/atomic.h>
4 #include <util/delay.h>
8 // which pin is the zener diode connected to
9 #define read_scx_pin() (PINB & _BV(PB2))
11 // how many consecutive readings have to be the same in order to
12 // accept the pin value
13 #define DENOISE_COUNT 4
16 #error "F_CPU not defined. Set F_CPU in Makefile."
19 #define STEP (F_CPU/115200) // duration of one bit
20 #define BYTE_PAUSE_MAX (20*STEP) // inter-packet length threshold
25 TCCR1B = _BV(CS10); // run at F_CPU clock, no prescaling
28 // read the value until it is stable, i.e. until DENOISE_COUNT consecutive
29 // readings give the same value
30 static unsigned char read_scx_pin_denoised()
32 unsigned char prev, count;
35 prev = read_scx_pin();
37 while (count < DENOISE_COUNT) {
38 unsigned char curr = read_scx_pin();
49 // how long we waited for the start bit
50 static unsigned char long_byte_wait;
52 static unsigned char read_scx_byte()
54 unsigned short curr_time, prev_time, interval;
55 unsigned char data, i, toolong = 0, step;
58 // wait for 0, distinguish between inter- and intra-packet wait times
62 while (read_scx_pin_denoised()) {
64 if (curr_time - prev_time > BYTE_PAUSE_MAX)
68 ATOMIC_BLOCK(ATOMIC_FORCEON) {
69 // wait for 1 (end of the first start-bit),
70 // remember the length of the start bit
71 // in order to distinguish between car and other packets
72 prev_time = curr_time = TCNT1;
75 while (!read_scx_pin_denoised()) { // wait for 1
77 interval = curr_time - prev_time;
79 if (interval >= 4*STEP) { // start bit too long
81 uart_tx_byte(0x12, 0);
90 // start bit too short
91 if (interval < 3*STEP/4) {
92 uart_tx_byte(0x10, 0);
96 // car packets are at 57600 baud, start bit is twice as long
97 step = interval > (3*STEP/2) ? 2*STEP : STEP;
99 // advance into the middle of the next bit
100 curr_time += step / 2;
102 // start bit detected, now read the eight data bits
104 for (i = 0; i < 8; i++) {
106 while (TCNT1 - curr_time < step)
108 data |= read_scx_pin_denoised() ? 0x80 : 0;
113 while (TCNT1 - curr_time < step)
116 if (!read_scx_pin_denoised()) // no stop bit?
117 uart_tx_byte(0x13, 0); // report error, but return data anyway
122 extern unsigned char version[], version_len;
124 static void print_version()
128 for (i = 0; i < version_len; i++)
129 uart_tx_byte(version[i], 0);
134 unsigned char count = 0, pkt_len = 0;
147 unsigned char byte = read_scx_byte();
149 uart_tx_byte(byte, 0);
152 count &= 0x7F; // avoid overflow
154 // try to synchronize with the packet start
155 // - we need this in order to determine the packet length
156 // and in order to add 0x05 end byte after the packet
157 if (byte == 0x55 && long_byte_wait)
161 if (byte >= 0x40 && byte <= 0x45) { // car pkt
168 if (count == pkt_len) {
169 uart_tx_byte(0x05, 0); // SEB interface compatibility