receiver/main.c

changeset 11
69c2a1408619
parent 10
6d6e982bbc41
child 15
7d4c0c816465
equal deleted inserted replaced
10:6d6e982bbc41 11:69c2a1408619
7 #include <avr/pgmspace.h> 7 #include <avr/pgmspace.h>
8 8
9 #include "main.h" 9 #include "main.h"
10 10
11 #include "driver/rs232.h" 11 #include "driver/rs232.h"
12 //#include "driver/manchester.h" 12 #include "util/delay.h"
13 13
14 volatile uint8_t datalen = 0;
15 char data[10]; // 8 bytes data buffer + string termination
16 14
17 static char buffer[RS232_BUFSIZE+1]; 15 static char buffer[RS232_BUFSIZE+1];
18 static uint8_t buffer_len; 16 static uint8_t buffer_len;
19 17
20 volatile uint8_t bitbuf_len = 0;
21 volatile uint16_t bitbuf = 0;
22 volatile uint16_t bitbuf_out = 0;
23 volatile uint8_t bitbuf_out_len = 0;
24 volatile uint8_t timeout = 0;
25 volatile uint8_t lastbit = 0;
26 18
27 19
28 20
29 // USART0 RX interrupt 21 // USART0 RX interrupt
30 ISR ( USART_RXC_vect ) { 22 ISR ( USART_RXC_vect ) {
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

mercurial