11 #include "driver/adc.h" |
11 #include "driver/adc.h" |
12 |
12 |
13 #include "main.h" |
13 #include "main.h" |
14 #include "lowlevel.h" |
14 #include "lowlevel.h" |
15 |
15 |
|
16 volatile uint8_t program_count = 0; |
|
17 volatile uint8_t program_id; |
|
18 volatile uint8_t program_command; |
|
19 volatile uint8_t program_parameter; |
|
20 |
16 volatile uint8_t datalen = 0; |
21 volatile uint8_t datalen = 0; |
17 char data[10]; // 8 bytes data buffer + string termination |
22 char data[10]; // 8 bytes data buffer + string termination |
18 |
23 |
19 static char buffer[RS232_BUFSIZE+1]; |
24 static char buffer[RS232_BUFSIZE+1]; |
20 static uint8_t buffer_len; |
25 static uint8_t buffer_len; |
21 |
|
22 |
26 |
23 // USART0 RX interrupt |
27 // USART0 RX interrupt |
24 ISR ( USART_RXC_vect ) { |
28 ISR ( USART_RXC_vect ) { |
25 char c = UDR; |
29 char c = UDR; |
26 |
30 |
27 // check for buffer overflow |
31 // check for buffer overflow |
28 if (buffer_len==sizeof(buffer)) { |
32 if (buffer_len==sizeof(buffer)) { |
29 buffer_len=0; |
33 buffer_len=0; |
30 if (c == 27) { |
|
31 // escape sequence, store to empty buffer |
|
32 buffer[buffer_len++] = c; |
|
33 } |
|
34 } else { |
34 } else { |
35 // collect characters until end of line |
35 // collect characters until end of line |
36 if (c == 27) { |
36 if ( (c==0x0A) ) { |
37 // escape sequence, clear buffer |
|
38 buffer_len = 0; |
|
39 buffer[buffer_len++] = c; |
|
40 } else if ( (c==0xff) && (buffer_len > 3) ) { |
|
41 buffer[buffer_len]=0; |
37 buffer[buffer_len]=0; |
42 |
38 |
43 // packet end received, parse the received packet |
39 // packet end received, parse the received packet |
|
40 switch (buffer[0]) { |
|
41 case 'P': // inject a program data word to the rails |
|
42 // TODO: at the moment only parameters 0..9 supported |
|
43 // needs to build a "human" parser |
|
44 program_id = buffer[3]-'0'; |
|
45 program_command = buffer[1]-'0'; |
|
46 program_parameter = buffer[2]-'0'; |
|
47 program_count = 0x02; // send commands twice |
|
48 RS232_puts_p(PSTR("Executing command: ")); |
|
49 /* |
|
50 RS232_putc(buffer[2]); |
|
51 RS232_putc(','); |
|
52 RS232_putc(buffer[3]); |
|
53 RS232_puts_p(PSTR(" for slot ")); |
|
54 RS232_putc(buffer[1]); |
|
55 */ |
|
56 RS232_putc('\n'); |
|
57 |
|
58 break; |
|
59 |
|
60 } |
44 |
61 |
45 // wait for the next packet |
62 // wait for the next packet |
46 buffer_len=0; |
63 buffer_len=0; |
47 } else { |
64 } else { |
48 buffer[buffer_len++]=c; |
65 buffer[buffer_len++]=c; |
124 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter |
141 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter |
125 |
142 |
126 return insert_queue(tmp, 9); |
143 return insert_queue(tmp, 9); |
127 } |
144 } |
128 |
145 |
129 unsigned char mirror( unsigned char n ) { |
146 uint8_t mirror( uint8_t n ) { |
130 // mirror all 8 bits |
|
131 n = ((n >> 1) & 0x55) | ((n << 1) & 0xaa); |
147 n = ((n >> 1) & 0x55) | ((n << 1) & 0xaa); |
132 n = ((n >> 2) & 0x33) | ((n << 2) & 0xcc); |
148 n = ((n >> 2) & 0x33) | ((n << 2) & 0xcc); |
133 n = ((n >> 4) & 0x0f) | ((n << 4) & 0xf0); |
149 n = ((n >> 4) & 0x0f) | ((n << 4) & 0xf0); |
134 return n; |
150 return n; |
135 } |
151 } |
136 |
152 |
137 |
153 |
|
154 |
138 int do_program(uint8_t controller, uint8_t command, uint8_t parameter) { |
155 int do_program(uint8_t controller, uint8_t command, uint8_t parameter) { |
139 // send program data packet |
156 // send program data packet |
140 uint16_t tmp; |
157 uint16_t tmp; |
141 tmp = 0b1000000000000 | (mirror(parameter) << 4) | mirror(command)| (mirror(controller) >> 5); |
158 parameter = mirror(parameter); |
142 |
159 controller = mirror(controller); |
|
160 command = mirror(command); |
|
161 tmp = 0b1000000000000 | (parameter << 4) | command | (controller >> 5); |
143 return insert_queue(tmp, 12); |
162 return insert_queue(tmp, 12); |
144 } |
163 } |
145 |
164 |
146 int do_active(void) { |
165 int do_active(void) { |
147 // send controller active data packet |
166 // send controller active data packet |
149 if ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b11000001; |
168 if ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b11000001; |
150 if ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10100001; |
169 if ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10100001; |
151 if ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10010001; |
170 if ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10010001; |
152 if ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10001001; |
171 if ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10001001; |
153 // todo: regler 5 und 6 |
172 // todo: regler 5 und 6 |
|
173 // todo: wenn Daten enpfangen wurden hier eine Quittierung senden anstatt dem Active Word |
154 |
174 |
155 return insert_queue(tmp, 7); |
175 return insert_queue(tmp, 7); |
156 } |
176 } |
157 |
177 |
158 int do_pace_ghost(void) { |
178 int do_pace_ghost(void) { |
183 uint8_t packet_index = 1; |
203 uint8_t packet_index = 1; |
184 |
204 |
185 |
205 |
186 init_hardware(); |
206 init_hardware(); |
187 |
207 |
188 itoa(TIMER2_50US, s, 10); |
|
189 RS232_puts(s); |
|
190 |
|
191 // switch on rails power |
208 // switch on rails power |
192 RAIL_POWER_PORT |= _BV(RAIL_POWER); |
209 RAIL_POWER_PORT |= _BV(RAIL_POWER); |
193 |
210 |
194 while (1) { |
211 while (1) { |
195 // check for short circuit on the rails |
212 // check for short circuit on the rails |
196 check_rails_shortcut(); |
213 check_rails_shortcut(); |
197 |
214 |
198 switch (packet_index) { |
215 switch (packet_index) { |
199 case 1: |
216 case 1: |
200 if (do_program(7, 19, 0)) packet_index++; // reset |
217 if (program_count > 0) { |
201 //do_program(7, 16, 3); // led an startampel |
218 // command in queue |
202 //do_program(0, 4, 0); // |
219 if (do_program(program_id, program_command, program_parameter)) { |
|
220 packet_index++; |
|
221 program_count--; |
|
222 itoa(transmit_buffer_queue, s, 2); |
|
223 RS232_puts(s); |
|
224 RS232_putc('\n'); |
|
225 } |
|
226 } else { |
|
227 // output idle command |
|
228 if (do_program(7, 19, 0)) packet_index++; // reset |
|
229 } |
203 break; |
230 break; |
204 case 2: |
231 case 2: |
205 if (do_pace_ghost()) packet_index++; |
232 if (do_pace_ghost()) packet_index++; |
206 break; |
233 break; |
207 case 3: |
234 case 3: |