added response receiver timer

Tue, 15 Nov 2011 12:51:04 +0100

author
Malte Bayer <mbayer@neo-soft.org>
date
Tue, 15 Nov 2011 12:51:04 +0100
changeset 6
2405aff29a51
parent 5
7319de27d44a
child 7
f4e250d5402b

added response receiver timer

blackbox/lowlevel.c file | annotate | diff | comparison | revisions
blackbox/main.c file | annotate | diff | comparison | revisions
blackbox/main.h file | annotate | diff | comparison | revisions
--- a/blackbox/lowlevel.c	Tue Nov 15 10:47:16 2011 +0100
+++ b/blackbox/lowlevel.c	Tue Nov 15 12:51:04 2011 +0100
@@ -75,7 +75,10 @@
     LED(4, 0); _delay_ms(50);
     LED(5, 0); _delay_ms(50);
 
-    //TCCR0 = (1<<CS01); //divide by 8
+
+    // setup response receiver timer
+    TCCR0 = (1<<CS01); //divide by 8
+    // interrupt enable + tcnt0 set in timer2
 
 
     // setup data bit timer
--- a/blackbox/main.c	Tue Nov 15 10:47:16 2011 +0100
+++ b/blackbox/main.c	Tue Nov 15 12:51:04 2011 +0100
@@ -24,7 +24,17 @@
 static char buffer[RS232_BUFSIZE+1];
 static uint8_t buffer_len;
 
-// USART0 RX interrupt
+
+volatile uint16_t transmit_buffer;
+volatile uint16_t transmit_buffer_queue;
+volatile uint8_t  transmit_len;
+volatile uint8_t  transmit_len_next;
+volatile uint8_t  transmit_len_queue;
+
+volatile uint16_t response;
+volatile uint8_t timer0_delay;
+
+
 ISR ( USART_RXC_vect ) {
     char c = UDR;
 
@@ -64,41 +74,6 @@
 }
 
 
-volatile uint16_t transmit_buffer;
-volatile uint16_t transmit_buffer_queue;
-volatile uint8_t  transmit_len;
-volatile uint8_t  transmit_len_next;
-volatile uint8_t  transmit_len_queue;
-ISR ( TIMER2_COMP_vect ) {
-    //OCR2 = TIMER2_50US; // make sure that timer2 is 50µs !!!
-    // data packet timer 100µs pro bit...
-    if (transmit_len >= 0xFE) {
-        if (transmit_len != 0xFF) {
-            RAIL_POWER_PORT |= _BV(RAIL_POWER); // end of transmission
-            transmit_len = 0xFF;
-            transmit_buffer = transmit_buffer_queue;
-            transmit_buffer_queue = 0;
-            transmit_len_next = transmit_len_queue;
-        }
-    } else {
-        uint16_t bit = (1<<(transmit_len & 0b01111111));
-        uint16_t clock;
-        if ((transmit_len & 0b10000000) == 0) clock = 0; else clock = 0xffff;
-        if ( ((transmit_buffer ^ clock) & bit) != 0 )
-            RAIL_POWER_PORT |= _BV(RAIL_POWER); else
-            RAIL_POWER_PORT &= ~_BV(RAIL_POWER);
-        if ( (transmit_len & 0b10000000) == 0 ) {
-            // block 0
-            //if (transmit_len == 0) transmit_len = 0xFF; else transmit_len |= 0b10000000; // set clock
-            transmit_len |= 0b10000000; // set clock
-        } else {
-            // block 1, output the current bit
-            transmit_len &= 0b01111111; // reset clock
-            //if (transmit_len != 0) transmit_len--; // next bit
-            if (transmit_len == 0) transmit_len = 0xFE; else transmit_len--; // next bit
-        }
-    }
-}
 
 int insert_queue(uint16_t tmp, uint8_t len) {
     if (transmit_buffer_queue == 0) {
@@ -180,14 +155,81 @@
 }
 
 ISR ( TIMER1_COMPA_vect ) {
-    //OCR2 = 0xFF; // make sure that timer2 is synced to timer1, give enough cycles to prepare
-    LED(4,2);
     // trigger packet transfer:
     transmit_len = transmit_len_next;
+    LED(2,2);
 
     // here is some more time to do something else...
 }
 
+ISR ( TIMER2_COMP_vect ) {
+    //OCR2 = TIMER2_50US; // make sure that timer2 is 50µs !!!
+    // data packet timer 100µs pro bit...
+    if (transmit_len >= 0xFE) {
+        if (transmit_len != 0xFF) {
+            RAIL_POWER_PORT |= _BV(RAIL_POWER); // end of transmission
+            transmit_len = 0xFF;
+            transmit_buffer = transmit_buffer_queue;
+            transmit_buffer_queue = 0;
+            transmit_len_next = transmit_len_queue;
+
+            // start the response receiver timer
+            // TODO: only on 8 timeslots, not on every transmission
+            // TODO: give slot number to timer - then store the transmission to 8 slots array
+            TCNT0 = TIMER0_250US;
+            timer0_delay = TIMER0_2300NS;
+            response = 0;
+            TIMSK |= _BV(TOIE0);
+
+        }
+    } else {
+        uint16_t bit = (1<<(transmit_len & 0b01111111));
+        uint16_t clock;
+        if ((transmit_len & 0b10000000) == 0) clock = 0; else clock = 0xffff;
+        if ( ((transmit_buffer ^ clock) & bit) != 0 )
+            RAIL_POWER_PORT |= _BV(RAIL_POWER); else
+            RAIL_POWER_PORT &= ~_BV(RAIL_POWER);
+        if ( (transmit_len & 0b10000000) == 0 ) {
+            // block 0
+            //if (transmit_len == 0) transmit_len = 0xFF; else transmit_len |= 0b10000000; // set clock
+            transmit_len |= 0b10000000; // set clock
+        } else {
+            // block 1, output the current bit
+            transmit_len &= 0b01111111; // reset clock
+            //if (transmit_len != 0) transmit_len--; // next bit
+            if (transmit_len == 0) transmit_len = 0xFE; else transmit_len--; // next bit
+        }
+    }
+
+    LED(3,2);
+}
+
+
+ISR ( TIMER0_OVF_vect ) {
+// TODO: last bit should be set by the sender, not from us!
+    TCNT0 = TIMER0_250US;
+    LED(1,2);
+    if (timer0_delay == 0) {
+        RAIL_POWER_PORT &= ~_BV(RAIL_POWER); // pull rails low
+        _delay_us(25); // wait some cycles
+        if ((PIN(RAIL_POWER_PORT) & _BV(RAIL_POWER)) == 0) { // check for logic zero
+            if (response == 0) {
+                // there is no start bit, so stop the timer and cancel response receiving
+                TIMSK &= ~_BV(TOIE0);
+            } else {
+                // we received a logic low
+                response = response << 1;
+            }
+        } else {
+            // okay, we have logic high
+            response = response << 1;
+            response |= 1;
+        }
+        _delay_us(23); // wait some cycles
+        RAIL_POWER_PORT |= _BV(RAIL_POWER); // restore rails power
+    } else timer0_delay--; // 2.3 ms delay not reached yet
+}
+
 
 int main(void)
 {
@@ -216,7 +258,8 @@
                     }
                 } else {
                     // output idle command
-                    if (do_program(7, 19, 0)) packet_index++; // reset
+                    //if (do_program(7, 19, 0)) packet_index++; // reset
+                    if (do_program(7, 20, 15)) packet_index++; // reset / pitstop detect
                 }
                 break;
             case 2:
--- a/blackbox/main.h	Tue Nov 15 10:47:16 2011 +0100
+++ b/blackbox/main.h	Tue Nov 15 12:51:04 2011 +0100
@@ -65,13 +65,18 @@
 #define TIMER_7500NS     0xffff - (uint16_t)(VALUE_7500NS * F_CPU/TIMER1_DIVISOR)
 */
 //#define TIMER_7500NS     (uint16_t)(VALUE_7500NS * F_CPU/TIMER1_DIVISOR)
-#define TIMER2_DIVISOR   8
-#define VALUE2_50US      0.50e-4
-#define TIMER2_50US      (uint8_t)(VALUE2_50US * F_CPU/TIMER2_DIVISOR)
+#define TIMER0_DIVISOR  8
+#define VALUE0_250US    0.25e-3
+#define TIMER0_250US    0xff - (uint8_t)(VALUE0_250US * F_CPU/TIMER0_DIVISOR)
+#define TIMER0_2300NS   (uint8_t)(2300/250)
 
-#define TIMER1_DIVISOR   8
-#define VALUE1_7500NS     0.75e-2
-#define TIMER1_7500NS     (uint16_t)(VALUE1_7500NS * F_CPU/TIMER1_DIVISOR)
+#define TIMER2_DIVISOR  8
+#define VALUE2_50US     0.50e-4
+#define TIMER2_50US     (uint8_t)(VALUE2_50US * F_CPU/TIMER2_DIVISOR)
+
+#define TIMER1_DIVISOR  8
+#define VALUE1_7500NS   0.75e-2
+#define TIMER1_7500NS   (uint16_t)(VALUE1_7500NS * F_CPU/TIMER1_DIVISOR)
 
 
 #define DDR(x) (*(&x - 1))      // address of data direction register of port x

mercurial