blackbox/main.c

changeset 6
2405aff29a51
parent 5
7319de27d44a
child 7
f4e250d5402b
equal deleted inserted replaced
5:7319de27d44a 6:2405aff29a51
22 char data[10]; // 8 bytes data buffer + string termination 22 char data[10]; // 8 bytes data buffer + string termination
23 23
24 static char buffer[RS232_BUFSIZE+1]; 24 static char buffer[RS232_BUFSIZE+1];
25 static uint8_t buffer_len; 25 static uint8_t buffer_len;
26 26
27 // USART0 RX interrupt 27
28 volatile uint16_t transmit_buffer;
29 volatile uint16_t transmit_buffer_queue;
30 volatile uint8_t transmit_len;
31 volatile uint8_t transmit_len_next;
32 volatile uint8_t transmit_len_queue;
33
34 volatile uint16_t response;
35 volatile uint8_t timer0_delay;
36
37
28 ISR ( USART_RXC_vect ) { 38 ISR ( USART_RXC_vect ) {
29 char c = UDR; 39 char c = UDR;
30 40
31 // check for buffer overflow 41 // check for buffer overflow
32 if (buffer_len==sizeof(buffer)) { 42 if (buffer_len==sizeof(buffer)) {
62 } 72 }
63 } 73 }
64 } 74 }
65 75
66 76
67 volatile uint16_t transmit_buffer; 77
68 volatile uint16_t transmit_buffer_queue; 78 int insert_queue(uint16_t tmp, uint8_t len) {
69 volatile uint8_t transmit_len; 79 if (transmit_buffer_queue == 0) {
70 volatile uint8_t transmit_len_next; 80 transmit_buffer_queue = tmp;
71 volatile uint8_t transmit_len_queue; 81 transmit_len_queue = len;
82 return 1;
83 }
84 return 0;
85 }
86
87
88 int do_controller(uint8_t controller) {
89 // read controller X speed & encode controller data packet
90 uint16_t tmp;
91 switch (controller) {
92 case 0:
93 tmp = ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1;
94 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER1_SW)) != 0) tmp |= (1<<5);
95 break;
96 case 1:
97 tmp = ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1;
98 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER2_SW)) != 0) tmp |= (1<<5);
99 break;
100 case 2:
101 tmp = ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1;
102 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER3_SW)) != 0) tmp |= (1<<5);
103 break;
104 case 3:
105 tmp = ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1;
106 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER4_SW)) != 0) tmp |= (1<<5);
107 break;
108 case 4: tmp = (1<<5); break; // todo regler 5
109 case 5: tmp = (1<<5); break; // todo regler 6
110 }
111 tmp |= 0b1000000000 | (controller << 6);
112 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter
113
114 return insert_queue(tmp, 9);
115 }
116
117 uint8_t mirror( uint8_t n ) {
118 n = ((n >> 1) & 0x55) | ((n << 1) & 0xaa);
119 n = ((n >> 2) & 0x33) | ((n << 2) & 0xcc);
120 n = ((n >> 4) & 0x0f) | ((n << 4) & 0xf0);
121 return n;
122 }
123
124 int do_program(uint8_t controller, uint8_t command, uint8_t parameter) {
125 // send program data packet
126 uint16_t tmp;
127 parameter = mirror(parameter);
128 controller = mirror(controller);
129 command = mirror(command);
130 tmp = 0b1000000000000 | (parameter << 4) | command | (controller >> 5);
131 return insert_queue(tmp, 12);
132 }
133
134 int do_active(void) {
135 // send controller active data packet
136 uint16_t tmp = 0b10000000;
137 if ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b11000001;
138 if ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10100001;
139 if ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10010001;
140 if ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10001001;
141 // todo: regler 5 und 6
142 // todo: wenn Daten enpfangen wurden hier eine Quittierung senden anstatt dem Active Word
143
144 return insert_queue(tmp, 7);
145 }
146
147 int do_pace_ghost(void) {
148 // send ghost and pacecar data packet
149 // todo: at the moment, both disabled!
150 uint16_t tmp = 0b1111100000;
151 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter
152 // todo: PC, NH, TK, (KFR, FR)
153
154 return insert_queue(tmp, 9);
155 }
156
157 ISR ( TIMER1_COMPA_vect ) {
158 // trigger packet transfer:
159 transmit_len = transmit_len_next;
160 LED(2,2);
161
162 // here is some more time to do something else...
163 }
164
72 ISR ( TIMER2_COMP_vect ) { 165 ISR ( TIMER2_COMP_vect ) {
73 //OCR2 = TIMER2_50US; // make sure that timer2 is 50µs !!! 166 //OCR2 = TIMER2_50US; // make sure that timer2 is 50µs !!!
74 // data packet timer 100µs pro bit... 167 // data packet timer 100µs pro bit...
75 if (transmit_len >= 0xFE) { 168 if (transmit_len >= 0xFE) {
76 if (transmit_len != 0xFF) { 169 if (transmit_len != 0xFF) {
77 RAIL_POWER_PORT |= _BV(RAIL_POWER); // end of transmission 170 RAIL_POWER_PORT |= _BV(RAIL_POWER); // end of transmission
78 transmit_len = 0xFF; 171 transmit_len = 0xFF;
79 transmit_buffer = transmit_buffer_queue; 172 transmit_buffer = transmit_buffer_queue;
80 transmit_buffer_queue = 0; 173 transmit_buffer_queue = 0;
81 transmit_len_next = transmit_len_queue; 174 transmit_len_next = transmit_len_queue;
175
176 // start the response receiver timer
177 // TODO: only on 8 timeslots, not on every transmission
178 // TODO: give slot number to timer - then store the transmission to 8 slots array
179 TCNT0 = TIMER0_250US;
180 timer0_delay = TIMER0_2300NS;
181 response = 0;
182 TIMSK |= _BV(TOIE0);
183
82 } 184 }
83 } else { 185 } else {
84 uint16_t bit = (1<<(transmit_len & 0b01111111)); 186 uint16_t bit = (1<<(transmit_len & 0b01111111));
85 uint16_t clock; 187 uint16_t clock;
86 if ((transmit_len & 0b10000000) == 0) clock = 0; else clock = 0xffff; 188 if ((transmit_len & 0b10000000) == 0) clock = 0; else clock = 0xffff;
96 transmit_len &= 0b01111111; // reset clock 198 transmit_len &= 0b01111111; // reset clock
97 //if (transmit_len != 0) transmit_len--; // next bit 199 //if (transmit_len != 0) transmit_len--; // next bit
98 if (transmit_len == 0) transmit_len = 0xFE; else transmit_len--; // next bit 200 if (transmit_len == 0) transmit_len = 0xFE; else transmit_len--; // next bit
99 } 201 }
100 } 202 }
101 } 203
102 204 LED(3,2);
103 int insert_queue(uint16_t tmp, uint8_t len) { 205 }
104 if (transmit_buffer_queue == 0) { 206
105 transmit_buffer_queue = tmp; 207
106 transmit_len_queue = len; 208 ISR ( TIMER0_OVF_vect ) {
107 return 1; 209 // TODO: last bit should be set by the sender, not from us!
108 } 210 TCNT0 = TIMER0_250US;
109 return 0; 211 LED(1,2);
110 } 212 if (timer0_delay == 0) {
111 213 RAIL_POWER_PORT &= ~_BV(RAIL_POWER); // pull rails low
112 214 _delay_us(25); // wait some cycles
113 int do_controller(uint8_t controller) { 215 if ((PIN(RAIL_POWER_PORT) & _BV(RAIL_POWER)) == 0) { // check for logic zero
114 // read controller X speed & encode controller data packet 216 if (response == 0) {
115 uint16_t tmp; 217 // there is no start bit, so stop the timer and cancel response receiving
116 switch (controller) { 218 TIMSK &= ~_BV(TOIE0);
117 case 0: 219 } else {
118 tmp = ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1; 220 // we received a logic low
119 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER1_SW)) != 0) tmp |= (1<<5); 221 response = response << 1;
120 break; 222 }
121 case 1: 223 } else {
122 tmp = ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1; 224 // okay, we have logic high
123 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER2_SW)) != 0) tmp |= (1<<5); 225 response = response << 1;
124 break; 226 response |= 1;
125 case 2: 227 }
126 tmp = ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1; 228 _delay_us(23); // wait some cycles
127 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER3_SW)) != 0) tmp |= (1<<5); 229 RAIL_POWER_PORT |= _BV(RAIL_POWER); // restore rails power
128 break; 230 } else timer0_delay--; // 2.3 ms delay not reached yet
129 case 3:
130 tmp = ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) & 0xF) << 1;
131 if ( (PIN(CONTROLLER_PORT) & _BV(CONTROLLER4_SW)) != 0) tmp |= (1<<5);
132 break;
133 case 4: tmp = (1<<5); break; // todo regler 5
134 case 5: tmp = (1<<5); break; // todo regler 6
135 }
136 tmp |= 0b1000000000 | (controller << 6);
137 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter
138
139 return insert_queue(tmp, 9);
140 }
141
142 uint8_t mirror( uint8_t n ) {
143 n = ((n >> 1) & 0x55) | ((n << 1) & 0xaa);
144 n = ((n >> 2) & 0x33) | ((n << 2) & 0xcc);
145 n = ((n >> 4) & 0x0f) | ((n << 4) & 0xf0);
146 return n;
147 }
148
149 int do_program(uint8_t controller, uint8_t command, uint8_t parameter) {
150 // send program data packet
151 uint16_t tmp;
152 parameter = mirror(parameter);
153 controller = mirror(controller);
154 command = mirror(command);
155 tmp = 0b1000000000000 | (parameter << 4) | command | (controller >> 5);
156 return insert_queue(tmp, 12);
157 }
158
159 int do_active(void) {
160 // send controller active data packet
161 uint16_t tmp = 0b10000000;
162 if ((getADC(CONTROLLER1_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b11000001;
163 if ((getADC(CONTROLLER2_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10100001;
164 if ((getADC(CONTROLLER3_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10010001;
165 if ((getADC(CONTROLLER4_SPEED) / CONTROLLER_DIVISOR) > 0) tmp |= 0b10001001;
166 // todo: regler 5 und 6
167 // todo: wenn Daten enpfangen wurden hier eine Quittierung senden anstatt dem Active Word
168
169 return insert_queue(tmp, 7);
170 }
171
172 int do_pace_ghost(void) {
173 // send ghost and pacecar data packet
174 // todo: at the moment, both disabled!
175 uint16_t tmp = 0b1111100000;
176 if ( (PIN(SW_FUEL_PORT) & _BV(SW_FUEL)) != 0) tmp |= 1; // benzinstand aktiv - tankmodusschalter
177 // todo: PC, NH, TK, (KFR, FR)
178
179 return insert_queue(tmp, 9);
180 }
181
182 ISR ( TIMER1_COMPA_vect ) {
183 //OCR2 = 0xFF; // make sure that timer2 is synced to timer1, give enough cycles to prepare
184 LED(4,2);
185 // trigger packet transfer:
186 transmit_len = transmit_len_next;
187
188 // here is some more time to do something else...
189 } 231 }
190 232
191 233
192 int main(void) 234 int main(void)
193 { 235 {
214 packet_index++; 256 packet_index++;
215 program_count--; 257 program_count--;
216 } 258 }
217 } else { 259 } else {
218 // output idle command 260 // output idle command
219 if (do_program(7, 19, 0)) packet_index++; // reset 261 //if (do_program(7, 19, 0)) packet_index++; // reset
262 if (do_program(7, 20, 15)) packet_index++; // reset / pitstop detect
220 } 263 }
221 break; 264 break;
222 case 2: 265 case 2:
223 if (do_pace_ghost()) packet_index++; 266 if (do_pace_ghost()) packet_index++;
224 break; 267 break;

mercurial