55 } |
47 } |
56 } |
48 } |
57 } |
49 } |
58 |
50 |
59 |
51 |
60 #define PULSE_IN PIND |
52 #define PULSE_PORT PORTD |
61 #define PULSE_BIT 2 |
53 #define PULSE_BIT PD2 |
62 |
54 |
63 #define TIMER_DIVISOR 8 |
55 volatile uint16_t data = 0; |
64 #define VALUE_100US 0.47e-4 |
56 volatile uint8_t data_len = 0; |
65 #define TIMER_100US 0xff - (uint8_t)(VALUE_100US * F_CPU/TIMER_DIVISOR) |
57 volatile uint8_t bitbuf_len = 0; |
|
58 volatile uint16_t bitbuf = 0; |
66 |
59 |
67 ISR ( INT0_vect ) { |
60 ISR ( INT0_vect ) { |
68 writeBit(GICR, INT0, 0); // disable INT0 interrupt |
61 writeBit(PORTD, 5, 1); |
69 // Startsignal erkannt, ab hier den Timer0 starten, |
62 GICR &= ~_BV(INT0) ; // Disable INT0 |
70 // der liest dann alle 100µs den Zustand ein und schreibt das |
63 // Startsignal erkannt, ab hier den Timer2 starten, |
|
64 // der liest dann alle 50µs den Zustand ein und schreibt das |
71 // empfangene Bit in den Puffer |
65 // empfangene Bit in den Puffer |
72 lastbit = 0b10000001; // initialize |
66 bitbuf = 0; // init |
73 |
67 bitbuf_len = 0b10000000; // init 1 pulse received |
74 TCNT0 = TIMER_100US; |
68 TCNT2 = 0; |
75 TIMSK |= 1<<TOIE0; //enable timer0 interrupt |
69 TIMSK |= _BV(OCIE2); //enable timer2 interrupt |
|
70 writeBit(PORTD, 5, 0); |
76 } |
71 } |
77 |
72 |
78 ISR ( TIMER0_OVF_vect ) { |
73 |
79 uint8_t sr = SREG; |
74 ISR ( TIMER2_COMP_vect ) { |
80 TCNT0 = TIMER_100US; // reset timer for next bit time |
|
81 writeBit(PORTD, 4, 0); |
75 writeBit(PORTD, 4, 0); |
82 // read the current bit value, store it to 16bit buffer |
|
83 if ( (PULSE_IN & _BV(PULSE_BIT)) == 0 ) { |
|
84 //RS232_putc('L'); |
|
85 |
76 |
86 if ( (lastbit & 1) == 1) { |
77 uint8_t clock; |
87 // bit cleared, second block |
78 uint8_t state; |
88 // insert bit |
79 uint8_t state2; |
89 bitbuf |= 1; |
80 if ((bitbuf_len & 0b10000000) == 0) clock = 0; else clock = 0xff; |
90 bitbuf = bitbuf << 1; |
81 if ((bitbuf_len & 0b01000000) == 0) state = 0; else state = 0xff; |
91 bitbuf_len++; |
82 if ((PIN(PULSE_PORT) & _BV(PULSE_BIT)) == 0) state2 = 0; else state2 = 0xff; |
92 lastbit = 0; // set block number0 & signal state to 0 |
83 |
|
84 if (clock) { |
|
85 // second pulse of bit |
|
86 bitbuf_len &= ~_BV(7); // switch clock to low |
|
87 if ((state==state2) & state2) { |
|
88 // two cycles high: packet end received |
|
89 data_len = (bitbuf_len & 0b00111111); |
|
90 if (data_len == 13) PORTD ^= _BV(6); // debug sync output on program packets |
|
91 TIMSK &= ~_BV(OCIE2); //disable timer2 interrupt |
|
92 GICR |= _BV(INT0) ; // Enable INT0 |
|
93 data = bitbuf; // output data |
93 } else { |
94 } else { |
94 // bit cleared, first block |
95 bitbuf_len++; // increment bit counter |
95 lastbit = 1; // set block number1 & signal state to 0 |
96 bitbuf = bitbuf << 1; // shift bits |
|
97 if (state2 == 0) bitbuf |= 1; // receive logic one |
96 } |
98 } |
97 } else { |
99 } else { |
98 //RS232_putc('H'); |
100 // first pulse of bit |
99 if ( (lastbit & 1) == 1) { |
101 bitbuf_len |= _BV(7); // switch clock to high |
100 // bit set, second block |
102 if (state2) { |
101 if ( (lastbit & _BV(7)) == 0) { |
103 bitbuf_len |= _BV(6); // store new state |
102 // insert zero bit |
|
103 bitbuf = bitbuf << 1; |
|
104 bitbuf_len++; |
|
105 lastbit = 0b10000000; // set block number0 & signal state to 1 |
|
106 } else { |
|
107 // no change, transmission END! |
|
108 lastbit = 0xff; |
|
109 } |
|
110 } else { |
104 } else { |
111 // bit set, first block |
105 bitbuf_len &= ~_BV(6); // store new state |
112 lastbit = 0b10000001; // set block number1 & signal state to 1 |
|
113 } |
106 } |
114 } |
107 } |
115 if ( (bitbuf_len == 16) | (lastbit == 0xFF) ) { |
108 |
116 // 16 bits full or transmission end |
|
117 // export to uart |
|
118 writeBit(TIMSK, TOIE0, 0); // disable timer0 interrupt |
|
119 if (bitbuf > 0) { |
|
120 bitbuf_out = bitbuf; |
|
121 bitbuf_out_len = bitbuf_len; |
|
122 } |
|
123 bitbuf = 0; |
|
124 bitbuf_len = 0; |
|
125 GICR |= _BV(INT0); // Enable INT0 |
|
126 } |
|
127 |
109 |
128 writeBit(PORTD, 4, 1); |
110 writeBit(PORTD, 4, 1); |
129 SREG = sr; |
|
130 } |
111 } |
131 |
112 |
132 volatile uint16_t pulse_counter = 0; |
|
133 volatile uint8_t measure_progress = 0; |
|
134 volatile uint16_t car_id = 0; |
|
135 ISR(TIMER2_OVF_vect) { |
|
136 TCNT2 = 0xF5; |
|
137 pulse_counter++; |
|
138 } |
|
139 |
|
140 ISR (INT1_vect) { |
|
141 // measure pulse width |
|
142 //RS232_putc('x'); |
|
143 if (measure_progress == 0) { |
|
144 // start measuring |
|
145 TCNT2 = 0xF5; |
|
146 pulse_counter = 0; |
|
147 measure_progress = 1; |
|
148 // set INT1 to rising edge (stops current measurement) |
|
149 //MCUCR |= _BV(ISC10); |
|
150 writeBit(PORTD, 4, 1); |
|
151 } else { |
|
152 // stop measuring |
|
153 car_id = pulse_counter; |
|
154 measure_progress = 0; |
|
155 // set INT1 to falling edge (initiates next measurement) |
|
156 //MCUCR &= ~_BV(ISC10); |
|
157 writeBit(PORTD, 4, 0); |
|
158 } |
|
159 } |
|
160 |
113 |
161 |
114 |
162 int main(void) |
115 int main(void) |
163 { |
116 { |
164 uint i; |
117 uint8_t i; |
165 char s[30]; |
118 unsigned char s[30]; |
166 |
119 |
167 TCCR0 = 0; //timer off |
120 // setup data bit timer |
168 //TCCR0 = (1<<CS00); //divide by 1 |
121 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match |
169 TCCR0 = (1<<CS01); //divide by 8 |
122 OCR2 = TIMER2_50US; |
170 //TCCR0 = (1<<CS01) | (1<<CS00); //divide by 64 |
123 TIMSK |= 1<<OCIE2; //enable timer2 interrupt |
171 //TCCR0 = (1<<CS02); //divide by 256 |
|
172 //TCCR0 = (1<<CS02) | (1<<CS00); //divide by 1024 |
|
173 |
124 |
174 //TIMSK = 1<<TOIE0; //enable timer interrupt |
125 MCUCR = _BV(ISC00); // falling edge |
175 // Timer will be enabled on INT0 |
126 GICR = _BV(INT0) ; // Enable INT0 |
176 |
|
177 // configure timer2 for pulse measurement |
|
178 //TCCR2 = (1<<CS21); // divide 8 |
|
179 TCCR2 = (1<<CS20); // divide 1 |
|
180 TIMSK = 1<<TOIE2; |
|
181 |
|
182 // configure INT0+1 for falling edge |
|
183 // INT2 on every edge |
|
184 //MCUCR = _BV(ISC00) | _BV(ISC11); |
|
185 MCUCR = _BV(ISC11); |
|
186 // GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0/1 |
|
187 GICR = _BV(INT1) ; // Enable INT1 |
|
188 |
127 |
189 writeBit(DDRD, 4, 1); |
128 writeBit(DDRD, 4, 1); |
|
129 writeBit(DDRD, 5, 1); |
|
130 writeBit(DDRD, 6, 1); |
190 |
131 |
191 |
132 |
192 RS232_init(); // initialize RS232 interface |
133 RS232_init(); // initialize RS232 interface |
193 RS232_puts_p(PSTR("INIT OK\n")); |
134 RS232_puts_p(PSTR("CarreraShark 1.0 - INIT OK\n")); |
|
135 //RS232_puts_p(PSTR("Receiving one complete cycle:\n")); |
194 |
136 |
|
137 sei(); |
195 i = 0; |
138 i = 0; |
196 |
|
197 sei(); |
|
198 while (1) { |
139 while (1) { |
199 // main loop |
140 // main loop |
200 |
141 |
201 if (car_id != 0) { |
142 if (data != 0) { |
202 itoa( car_id, s, 10); |
143 if (data_len > 5) { |
203 car_id = 0; |
144 if (data_len == 13) { // sync to first packet |
204 RS232_puts( s ); |
145 i = 1; |
205 RS232_putc('\n'); |
146 RS232_puts("\n"); |
206 |
147 } else if (i!=0) i++; |
|
148 if (i>0) { |
|
149 itoa( data, s, 16); |
|
150 data = 0; |
|
151 RS232_puts("0x"); |
|
152 RS232_puts( s ); |
|
153 RS232_putc(' '); |
|
154 } |
|
155 } |
|
156 //if (i==10) for (;;); |
207 } |
157 } |
208 /*cli(); |
|
209 i = rc5_data; // read two bytes from interrupt ! |
|
210 rc5_data = 0; |
|
211 sei(); |
|
212 if (i) { |
|
213 itoa( i, s, 10); |
|
214 RS232_puts( s ); |
|
215 } */ |
|
216 /* |
|
217 if (p_len < 0xFF) p_len++; |
|
218 if( (p_bit ^ PULSE_IN) & 1<<PULSE_BIT ){ // change detect |
|
219 p_bit = ~p_bit; // 0x00 -> 0xFF -> 0x00 |
|
220 itoa( p_len, s, 10); |
|
221 RS232_puts(s); |
|
222 RS232_puts_p(PSTR("\n")); |
|
223 p_len = 0; |
|
224 } |
|
225 */ |
|
226 } // main loop end |
158 } // main loop end |
227 }; |
159 }; |
228 |
160 |