added 16bit response to track switch

Tue, 06 Dec 2011 16:45:52 +0100

author
Malte Bayer <mbayer@neo-soft.org>
date
Tue, 06 Dec 2011 16:45:52 +0100
changeset 40
c36bf33489f9
parent 39
4b186b5ce145
child 41
9857c18c5e64

added 16bit response to track switch

trackswitch/main.c file | annotate | diff | comparison | revisions
--- 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);

mercurial