car004f/main.c

changeset 147
f66c5b3b3ed2
child 148
08cb88614d69
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/car004f/main.c	Sat Dec 21 21:01:55 2013 +0100
@@ -0,0 +1,176 @@
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#include <avr/wdt.h>
+#include <avr/eeprom.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <avr/pgmspace.h>
+
+#include "main.h"
+#include "util/delay.h"
+
+
+ISR ( USART_RXC_vect ) {
+}
+
+#define PULSE_PORT      PORTD
+#define PULSE_BIT       PD2
+
+#define RESPONSE_PORT   PORTC
+#define RESPONSE_PIN    PC1
+
+volatile uint16_t data = 0;
+volatile uint8_t data_len = 0;
+volatile uint8_t bitbuf_len = 0;
+volatile uint16_t bitbuf = 0;
+volatile uint8_t car_speed[8];
+volatile uint8_t car_switch[8];
+volatile uint8_t my_id; // Die ID des Autos!
+
+uint8_t my_switch;
+uint8_t my_speed;
+uint8_t light_mode;
+
+ISR ( INT0_vect ) {
+    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
+    bitbuf = 0; // init
+    bitbuf_len = 0b10000000; // init 1 pulse received
+    TCNT2 = 0;
+    TIMSK |= _BV(OCIE2); //enable timer2 interrupt
+}
+
+ISR ( TIMER2_COMP_vect ) {
+    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 = 0xff; else state2 = 0;
+
+    if (clock) {
+        bitbuf_len &= ~_BV(7); // switch clock to low
+        // second pulse of bit
+        if ((state==state2) & state2) {
+            // two cycles high: packet end received
+            data_len = (bitbuf_len & 0b00111111);
+            TIMSK &= ~_BV(OCIE2); //disable timer2 interrupt
+            GICR |= _BV(INT0) ; // Enable INT0
+
+            //data = bitbuf; // output data
+            // write data of controllers to array
+            if (data_len == 10) { // controller data packet
+                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;
+                    }
+                }
+                */
+            }
+
+
+        } else {
+            bitbuf_len++; // increment bit counter
+            bitbuf = bitbuf << 1; // shift bits
+            if (state2 == 0) bitbuf |= 1; // receive logic one
+        }
+    } else {
+        bitbuf_len |= _BV(7); // switch clock to high
+        // first pulse of bit
+        if (state2) {
+            bitbuf_len |= _BV(6); // store new state
+        } else {
+            bitbuf_len &= ~_BV(6); // store new state
+        }
+    }
+}
+
+ISR (TIMER1_OVF_vect) {
+}
+
+ISR (INT1_vect) {
+}
+
+#define LIGHT_PORT      PORTC
+#define LIGHT_FRONT     2
+#define LIGHT_BRAKE     4
+
+#define IR_PORT         PORTB
+#define IR_LED          3
+
+
+#define LIGHT_MODES     1       // anzahl der lichtmodi (ohne den modus "aus")
+
+
+
+int main(void)
+{
+    uint8_t car0_state, car1_state;
+
+    // setup data bit timer2
+    TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match
+    OCR2 = TIMER2_50US;
+
+
+    // enable both external interrupts
+    // int 0 = data RX
+    MCUCR = _BV(ISC00) | _BV(ISC01) | _BV(ISC10) | _BV(ISC11); // INT0/1 rising edge
+    GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0 + INT1
+
+    // oscillator calibration
+    // atmega8@1mhz = 0xac
+    // @4mhz = ca 0xa0
+    //OSCCAL = 0xa0;
+    //OSCCAL = 0x9A;
+    //OSCCAL = 0xa0; // internal oscillator @ 4 mhz.... doesnt work accurate!
+    sei();
+
+    DDR(LIGHT_PORT) |= (_BV(LIGHT_FRONT) | _BV(LIGHT_BRAKE));
+
+    //defaults (from eeprom!)
+    my_id = 1;
+    light_mode = 0;
+
+    while (1) {
+        // main loop
+
+        // Light cycle if switch pressed without speed
+        if (my_speed == 0) {
+            if (my_switch != car_switch[my_id]) {
+                my_switch = car_switch[my_id];
+                if (my_switch != 0) {
+                    // cycle light
+                    if (light_mode == LIGHT_MODES) light_mode = 0; else light_mode++;
+                }
+            }
+        }
+
+        switch (light_mode) {
+            case 0:
+                LIGHT_PORT &= ~_BV(LIGHT_FRONT); // switch lights off
+                break;
+            case 1:
+                LIGHT_PORT |= _BV(LIGHT_FRONT); // switch lights on
+                break;
+        }
+
+        _delay_ms(100);
+        LIGHT_PORT |= _BV(LIGHT_BRAKE); // brake light on
+        _delay_ms(100);
+        LIGHT_PORT &= ~_BV(LIGHT_BRAKE); // brake light off
+        
+
+
+
+    } // main loop end
+};
+

mercurial