# HG changeset patch # User Malte Bayer # Date 1323186352 -3600 # Node ID c36bf33489f9cb8d64df553a17782556ff9da1a2 # Parent 4b186b5ce1458ab2b8c740a99d93deac8650a936 added 16bit response to track switch diff -r 4b186b5ce145 -r c36bf33489f9 trackswitch/main.c --- a/trackswitch/main.c Tue Dec 06 11:04:33 2011 +0100 +++ b/trackswitch/main.c Tue Dec 06 16:45:52 2011 +0100 @@ -17,6 +17,8 @@ #define PULSE_PORT PORTD #define PULSE_BIT PD2 +#define RESPONSE_PORT PORTD +#define RESPONSE_PIN PD5 #define SOLENOID_A_PORT PORTB #define SOLENOID_B_PORT PORTB @@ -38,6 +40,49 @@ volatile uint16_t car0_new, car0_old; volatile uint16_t car1_new, car1_old; +volatile uint8_t response = 0; +uint8_t self_id = 2; // TODO - muss ermittelt werden und systemweit eindeutig sein + +void send_response(uint16_t data) { + /* frame format: + 1 startbit + 2 car id + 3 car id + 4 car id + 5 track change status bit 1 + 6 track change status bit 2 + 7 sender id + 8 sender id + 9 sender id + 9 sender id + 10 device type + 11 device type + 12 device type + 13 device type + 14 reserved + 15 reserved + 16 stopbit + */ + uint8_t index = 16; // bit count maximum + uint8_t enable = DDR(RESPONSE_PORT) | _BV(RESPONSE_PIN); + uint8_t disable = DDR(RESPONSE_PORT) & ~_BV(RESPONSE_PIN); + data |= 0b100000000000001; // make sure start/stop bits are set + data = 0b1010101010101011; + while (index != 0) { + if ((data & 1) != 0) { + DDR(RESPONSE_PORT) = enable; // enable response output + } else { + DDR(RESPONSE_PORT) = disable; // disable response output + } + data = data >> 1; // next bit prepare + index--; // decrement index + _delay_us(49); // bit valid phase + } + // finally be sure to release the bus! + DDR(RESPONSE_PORT) = disable; // disable response output +} + + ISR ( INT0_vect ) { GICR &= ~_BV(INT0) ; // Disable INT0 // Startsignal erkannt, ab hier den Timer2 starten, @@ -72,6 +117,14 @@ clock = (bitbuf >> 6) & 0b00000111; car_speed[clock] = (bitbuf >> 1) & 0x0F; car_switch[clock] = (bitbuf >> 5) & 1; + // current response for this car? + if (response != 0) { + if ( ((response & 0b00001110) >> 1) == clock) { + // add our ID to response: + send_response(response | self_id << 6); + response = 0; + } + } } @@ -153,6 +206,7 @@ + int main(void) { uint8_t car0_state, car1_state; @@ -188,19 +242,29 @@ //OSCCAL = 0xa0; // internal oscillator @ 4 mhz.... doesnt work accurate! RS232_init(); // initialize RS232 interface - RS232_puts_p(PSTR("Freeslot TrackSwitch v1.1\n")); + RS232_puts_p(PSTR("Freeslot TrackSwitch v1.2\n")); sei(); DDR(SOLENOID_A_PORT) |= _BV(SOLENOID_A_PIN); DDR(SOLENOID_B_PORT) |= _BV(SOLENOID_B_PIN); + DDR(RESPONSE_PORT) &= ~_BV(RESPONSE_PIN); // switch response off + RESPONSE_PORT &= ~_BV(RESPONSE_PIN); // switch response off + while (1) { // main loop + /* + 0 = AA + 1 = AB + 2 = BB + 3 = BA + */ if (car0 != car0_state) { car0_state = car0; if ( (car0_state != 0) && (car_switch[car0_state-1] == 0) && (car_speed[car0_state-1]>0) ) { + response = (1 | ((car0_state-1)<<1) | (1 << 4)); // trigger solenoid A RS232_putc('A'); RS232_putc('B'); @@ -213,6 +277,7 @@ solenoid_delay(); } if (car0_state != 0) { + response = (1 | ((car0_state-1)<<1)); RS232_putc('A'); RS232_putc('A'); RS232_putc('0'+car0_state); @@ -224,7 +289,8 @@ if (car1 != car1_state) { car1_state = car1; if ( (car1_state != 0) && (car_switch[car1_state-1] == 0) && (car_speed[car1_state-1]>0) ) { - // trigger solenoid A + response = (1 | ((car1_state-1)<<1) | (3 << 4)); + // trigger solenoid B RS232_putc('B'); RS232_putc('A'); RS232_putc('0'+car1_state); @@ -236,6 +302,7 @@ solenoid_delay(); } if (car1_state != 0) { + response = (1 | ((car1_state-1)<<1) | (2 << 4)); RS232_putc('B'); RS232_putc('B'); RS232_putc('0'+car1_state);