--- 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 };