receiver/main.c

changeset 11
69c2a1408619
parent 10
6d6e982bbc41
child 15
7d4c0c816465
--- a/receiver/main.c	Fri Nov 18 08:42:24 2011 +0100
+++ b/receiver/main.c	Fri Nov 18 12:03:07 2011 +0100
@@ -9,20 +9,12 @@
 #include "main.h"
 
 #include "driver/rs232.h"
-//#include "driver/manchester.h"
+#include "util/delay.h"
 
-volatile uint8_t datalen = 0;
-char data[10]; // 8 bytes data buffer + string termination
 
 static char buffer[RS232_BUFSIZE+1];
 static uint8_t buffer_len;
 
-volatile uint8_t bitbuf_len = 0;
-volatile uint16_t bitbuf = 0;
-volatile uint16_t bitbuf_out = 0;
-volatile uint8_t bitbuf_out_len = 0;
-volatile uint8_t timeout = 0;
-volatile uint8_t lastbit = 0;
 
 
 
@@ -57,172 +49,112 @@
 }
 
 
-#define PULSE_IN        PIND
-#define PULSE_BIT       2
+#define PULSE_PORT      PORTD
+#define PULSE_BIT       PD2
 
-#define TIMER_DIVISOR   8
-#define VALUE_100US     0.47e-4
-#define TIMER_100US     0xff - (uint8_t)(VALUE_100US * F_CPU/TIMER_DIVISOR)
+volatile uint16_t data = 0;
+volatile uint8_t data_len = 0;
+volatile uint8_t bitbuf_len = 0;
+volatile uint16_t bitbuf = 0;
 
 ISR ( INT0_vect ) {
-    writeBit(GICR, INT0, 0); // disable INT0 interrupt
-    // Startsignal erkannt, ab hier den Timer0 starten,
-    // der liest dann alle 100µs den Zustand ein und schreibt das
+    writeBit(PORTD, 5, 1);
+    GICR &= ~_BV(INT0) ; // Disable INT0
+    // Startsignal erkannt, ab hier den Timer2 starten,
+    // der liest dann alle 50µs den Zustand ein und schreibt das
     // empfangene Bit in den Puffer
-    lastbit = 0b10000001; // initialize
-
-    TCNT0 = TIMER_100US;
-    TIMSK |= 1<<TOIE0; //enable timer0 interrupt
+    bitbuf = 0; // init
+    bitbuf_len = 0b10000000; // init 1 pulse received
+    TCNT2 = 0;
+    TIMSK |= _BV(OCIE2); //enable timer2 interrupt
+    writeBit(PORTD, 5, 0);
 }
 
-ISR ( TIMER0_OVF_vect ) {
-    uint8_t sr = SREG;
-    TCNT0 = TIMER_100US; // reset timer for next bit time
+
+ISR ( TIMER2_COMP_vect ) {
     writeBit(PORTD, 4, 0);
-    // read the current bit value, store it to 16bit buffer
-    if ( (PULSE_IN & _BV(PULSE_BIT)) == 0 ) {
-//RS232_putc('L');
+
+    uint8_t clock;
+    uint8_t state;
+    uint8_t state2;
+    if ((bitbuf_len & 0b10000000) == 0) clock = 0; else clock = 0xff;
+    if ((bitbuf_len & 0b01000000) == 0) state = 0; else state = 0xff;
+    if ((PIN(PULSE_PORT) & _BV(PULSE_BIT)) == 0) state2 = 0; else state2 = 0xff;
 
-        if ( (lastbit & 1) == 1) {
-            // bit cleared, second block
-            // insert bit
-            bitbuf |= 1;
-            bitbuf = bitbuf << 1;
-            bitbuf_len++;
-            lastbit = 0; // set block number0 & signal state to 0
+    if (clock) {
+        // second pulse of bit
+        bitbuf_len &= ~_BV(7); // switch clock to low
+        if ((state==state2) & state2) {
+            // two cycles high: packet end received
+            data_len = (bitbuf_len & 0b00111111);
+            if (data_len == 13) PORTD ^= _BV(6); // debug sync output on program packets
+            TIMSK &= ~_BV(OCIE2); //disable timer2 interrupt
+            GICR |= _BV(INT0) ; // Enable INT0
+            data = bitbuf; // output data
         } else {
-            // bit cleared, first block
-            lastbit = 1; // set block number1 & signal state to 0
+            bitbuf_len++; // increment bit counter
+            bitbuf = bitbuf << 1; // shift bits
+            if (state2 == 0) bitbuf |= 1; // receive logic one
         }
     } else {
-//RS232_putc('H');
-        if ( (lastbit & 1) == 1) {
-            // bit set, second block
-            if ( (lastbit & _BV(7)) == 0) {
-                // insert zero bit
-                bitbuf = bitbuf << 1;
-                bitbuf_len++;
-                lastbit = 0b10000000; // set block number0 & signal state to 1
-            } else {
-                // no change, transmission END!
-                lastbit = 0xff;
-            }
+        // first pulse of bit
+        bitbuf_len |= _BV(7); // switch clock to high
+        if (state2) {
+            bitbuf_len |= _BV(6); // store new state
         } else {
-            // bit set, first block
-            lastbit = 0b10000001; // set block number1 & signal state to 1
+            bitbuf_len &= ~_BV(6); // store new state
         }
     }
-    if ( (bitbuf_len == 16) | (lastbit == 0xFF) ) {
-        // 16 bits full or transmission end
-        // export to uart
-        writeBit(TIMSK, TOIE0, 0); // disable timer0 interrupt
-        if (bitbuf > 0) {
-            bitbuf_out = bitbuf;
-            bitbuf_out_len = bitbuf_len;
-        }
-        bitbuf = 0;
-        bitbuf_len = 0;
-        GICR |= _BV(INT0); // Enable INT0
-    }
+
 
     writeBit(PORTD, 4, 1);
-    SREG = sr;
-}
-
-volatile uint16_t pulse_counter = 0;
-volatile uint8_t measure_progress = 0;
-volatile uint16_t car_id = 0;
-ISR(TIMER2_OVF_vect) {
-    TCNT2 = 0xF5;
-    pulse_counter++;
 }
 
-ISR (INT1_vect) {
-    // measure pulse width
-    //RS232_putc('x');
-    if (measure_progress == 0) {
-        // start measuring
-        TCNT2 = 0xF5;
-        pulse_counter = 0;
-        measure_progress = 1;
-        // set INT1 to rising edge (stops current measurement)
-        //MCUCR |= _BV(ISC10);
-        writeBit(PORTD, 4, 1);
-    } else {
-        // stop measuring
-        car_id = pulse_counter;
-        measure_progress = 0;
-        // set INT1 to falling edge (initiates next measurement)
-        //MCUCR &= ~_BV(ISC10);
-        writeBit(PORTD, 4, 0);
-    }
-}
 
 
 int main(void)
 {
-  uint i;
-char s[30];
-
-    TCCR0 = 0;			//timer off
-    //TCCR0 = (1<<CS00);			//divide by 1
-    TCCR0 = (1<<CS01);			//divide by 8
-    //TCCR0 = (1<<CS01) | (1<<CS00);			//divide by 64
-    //TCCR0 = (1<<CS02);			//divide by 256
-    //TCCR0 = (1<<CS02) | (1<<CS00);			//divide by 1024
+    uint8_t i;
+    unsigned char s[30];
 
-    //TIMSK = 1<<TOIE0;			//enable timer interrupt
-    // Timer will be enabled on INT0
+    // setup data bit timer
+    TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match
+    OCR2 = TIMER2_50US;
+    TIMSK |= 1<<OCIE2; //enable timer2 interrupt
 
-    // configure timer2 for pulse measurement
-    //TCCR2 = (1<<CS21); // divide 8
-    TCCR2 = (1<<CS20); // divide 1
-    TIMSK = 1<<TOIE2;
-
-    // configure INT0+1 for falling edge
-    // INT2 on every edge
-    //MCUCR = _BV(ISC00)  | _BV(ISC11);
-    MCUCR = _BV(ISC11);
-//    GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0/1
-    GICR = _BV(INT1) ; // Enable INT1
+    MCUCR = _BV(ISC00); // falling edge
+    GICR = _BV(INT0) ; // Enable INT0
 
     writeBit(DDRD, 4, 1);
+    writeBit(DDRD, 5, 1);
+    writeBit(DDRD, 6, 1);
 
 
     RS232_init(); // initialize RS232 interface
-    RS232_puts_p(PSTR("INIT OK\n"));
+    RS232_puts_p(PSTR("CarreraShark 1.0 - INIT OK\n"));
+    //RS232_puts_p(PSTR("Receiving one complete cycle:\n"));
 
+    sei();
     i = 0;
-    
-    sei();
     while (1) {
         // main loop
 
-        if (car_id != 0) {
-          itoa( car_id, s, 10);
-          car_id = 0;
-          RS232_puts( s );
-          RS232_putc('\n');
-            
+        if (data != 0) {
+            if (data_len > 5) {
+                if (data_len == 13) { // sync to first packet
+                    i = 1;
+                    RS232_puts("\n");
+                } else if (i!=0) i++;
+                if (i>0) {
+                    itoa( data, s, 16);
+                    data = 0;
+                    RS232_puts("0x");
+                    RS232_puts( s );
+                    RS232_putc(' ');
+                }
+            }
+            //if (i==10) for (;;);
         }
-    /*cli();
-    i = rc5_data; // read two bytes from interrupt !
-    rc5_data = 0;
-    sei();
-    if (i) {
-      itoa( i, s, 10);
-      RS232_puts( s );
-    } */
-/*
-        if (p_len < 0xFF) p_len++;
-        if( (p_bit ^ PULSE_IN) & 1<<PULSE_BIT ){		// change detect
-            p_bit = ~p_bit;				// 0x00 -> 0xFF -> 0x00
-            itoa( p_len, s, 10);
-            RS232_puts(s);
-            RS232_puts_p(PSTR("\n"));
-            p_len = 0;
-        }
-*/
     } // main loop end
 };
 

mercurial