added initial trackswitch code, data rx and car id detect working

Tue, 29 Nov 2011 13:42:29 +0100

author
Malte Bayer <mbayer@neo-soft.org>
date
Tue, 29 Nov 2011 13:42:29 +0100
changeset 19
40a309c9c135
parent 18
cc2274b92647
child 20
e333cf0e4d84

added initial trackswitch code, data rx and car id detect working

trackswitch/Makefile file | annotate | diff | comparison | revisions
trackswitch/driver file | annotate | diff | comparison | revisions
trackswitch/main.c file | annotate | diff | comparison | revisions
trackswitch/main.h file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trackswitch/Makefile	Tue Nov 29 13:42:29 2011 +0100
@@ -0,0 +1,93 @@
+PRG=main
+
+MCU=atmega8
+FUSES=-U lfuse:w:0xAE:m -U hfuse:w:0xd9:m
+#FUSES=-U lfuse:w:0x83:m -U hfuse:w:0xd9:m
+    BOOTFUSES=-U lfuse:w:0xff:m -U hfuse:w:0xce:m
+
+#F_CPU=4185600
+#F_CPU = 14318000
+
+F_CPU = 8000000
+BAUD=38400
+
+ISP_BAUD = 115200
+
+#SRC = main.c seriald.c driver/ADC.c driver/clock.c driver/timer.c
+#SRC = main.c driver/rs232.c driver/manchester.c
+SRC = main.c driver/rs232.c
+
+###################################################################
+# You possibly do not need to change settings below this marker
+###################################################################
+
+# Binaries to be used
+# You may add the path to them if they are not in the PATH variable.
+CC      = avr-gcc
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+AVRDUDE = avrdude
+PERL    = perl
+
+# Optional library search path
+LIBS =
+
+# Compiler options for all c source files
+CFLAGS += -g -Wall -mmcu=$(MCU) -DBAUD=$(BAUD) -DF_CPU=$(F_CPU)UL -std=gnu99 
+CFLAGS += -funsigned-char
+CFLAGS += -funsigned-bitfields
+CFLAGS += -fpack-struct
+CFLAGS += -fshort-enums
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -Wundef
+#CFLAGS += -save-temps
+
+# optimize for size
+CFLAGS += -Os
+# dont optimize
+#CFLAGS += -O0
+
+# Linker options
+LDFLAGS = -Wl,-Map,$(PRG).map
+
+# Enable floating-point support in printf
+#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm
+
+###################################################################
+# TARGET DEFINITIONS:
+
+
+all: code
+
+code: $(PRG).hex
+
+$(PRG).elf: $(SRC:.c=.o)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+%.lst: %.elf
+	$(OBJDUMP) -h -S $< > $@
+
+%.hex: %.elf
+	$(OBJCOPY) -j .text -j .data -O ihex $< $@
+	rm $(PRG).elf
+	rm $(PRG).map
+
+program: code
+	$(AVRDUDE) -c stk500v2 -b $(ISP_BAUD) -i 1 -p $(MCU) -V -U flash:w:$(PRG).hex:i
+
+fuse:
+	$(AVRDUDE) -c stk500 -p $(MCU) -V $(FUSES)
+
+clean:
+	rm -rf *.o *.elf *.elf.src *.s *.i
+	rm -rf driver/*.o
+
+upgrade: code
+	$(RESETCOMMAND)
+	./bootloader -d $(NETDEV) -b $(UPGRADE_BAUD) -p $(PRG).hex
+
+bootloader: bootload.hex
+	$(AVRDUDE) -p $(MCU) -c stk500 -V -U flash:w:bootload.hex:i
+
+bootfuses:
+	$(AVRDUDE) -p $(MCU) -c stk500 $(BOOTFUSES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trackswitch/driver	Tue Nov 29 13:42:29 2011 +0100
@@ -0,0 +1,1 @@
+../blackbox/driver
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trackswitch/main.c	Tue Nov 29 13:42:29 2011 +0100
@@ -0,0 +1,215 @@
+#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 "driver/rs232.h"
+#include "util/delay.h"
+
+
+ISR ( USART_RXC_vect ) {
+}
+
+#define PULSE_PORT      PORTD
+#define PULSE_BIT       PD2
+
+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 ) {
+    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
+        } 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
+        }
+    }
+
+}
+
+
+uint16_t car0_new, car0_old;
+uint16_t car1_new, car1_old;
+volatile uint16_t car0, car1;
+ISR (TIMER1_OVF_vect) {
+    // reset both car counters to overflow
+    car0_old = 0xffff;
+    car1_old = 0xffff;
+}
+
+ISR (INT1_vect) {
+    // car0 detector
+    uint16_t tmp = 0;
+    car0_new = TCNT1; // get current counter
+    if (car0_old < car0_new) {
+        // calculate difference
+        if (car0 == 0) tmp = car0_new-car0_old;
+        if ( (tmp > 54) && (tmp < 74) ) car0 = 1;
+        if ( (tmp > 118) && (tmp < 138) ) car0 = 2;
+        if ( (tmp > 186) && (tmp < 206) ) car0 = 3;
+        if ( (tmp > 246) && (tmp < 266) ) car0 = 4;
+    }
+    car0_old = car0_new;
+}
+
+ISR (TIMER1_CAPT_vect) {
+    // car1 detector
+    uint16_t tmp = 0;
+    car1_new = TCNT1; // get current counter
+    if (car1_old < car1_new) {
+        // calculate difference
+        if (car1 == 0) tmp = car1_new-car1_old;
+        if ( (tmp > 54) && (tmp < 74) ) car1 = 1;
+        if ( (tmp > 118) && (tmp < 138) ) car1 = 2;
+        if ( (tmp > 186) && (tmp < 206) ) car1 = 3;
+        if ( (tmp > 246) && (tmp < 266) ) car1 = 4;
+    }
+    car1_old = car1_new;
+}
+
+#define OSC_OFFSET 0
+
+int main(void)
+{
+    uint16_t i, data_tmp;
+    uint8_t tmp, datalen_tmp;
+    unsigned char s[30];
+
+    
+    uint8_t car_speed[8];
+    uint8_t car_switch[8];
+    uint8_t car_switch_old[8];
+
+    // setup data bit timer2
+    TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match
+    OCR2 = TIMER2_50US+OSC_OFFSET; // insert OSC_OFFSET
+
+    // initialize timer1 for IR signal detection
+    TCCR1B = _BV(CS01) | _BV(ICNC1) | _BV(ICES1); // 1mhz clock, enable ICP on rising edge
+
+    // enable both external interrupts
+    // int 0 = data RX
+    // int 1 = car0 input
+    MCUCR = _BV(ISC00) | _BV(ISC01) | _BV(ISC10) | _BV(ISC11); // INT0/1 rising edge
+    GICR = _BV(INT0) | _BV(INT1) ; // Enable INT0 + INT1
+
+    // enable timer interrupts
+    TIMSK = _BV(OCIE2) | _BV(TOIE1) | _BV(TICIE1); //enable timer1+2
+
+    // oscillator calibration
+    // atmega8@1mhz = 0xac
+    // @4mhz = ca 0xa0
+    //OSCCAL = 0xa0;
+    //OSCCAL = 0x9A;
+    //OSCCAL = 0xa0; // internal oscillator @ 4 mhz.... doesnt work accurate!
+
+    RS232_init(); // initialize RS232 interface
+    RS232_puts_p(PSTR("Freeslot TrackSwitch Ready\n"));
+    sei();
+
+    DDR(PORTC) = 0b00011100;
+
+    i = 0;
+    while (1) {
+        // main loop
+
+        // keep the data of all available cars (0..7) up to date
+        if (data != 0) {
+            data_tmp = data;
+            datalen_tmp = data_len;
+            if (datalen_tmp >= 5) {
+                if (datalen_tmp == 13) { // sync to first packet
+                    i = 1;
+                } else i++;
+                if (datalen_tmp == 10) { // controller data packet
+                    tmp = (data_tmp >> 6) & 0b111;
+                    if (tmp < 6) {
+                        car_speed[tmp] = (data_tmp >> 1) & 0x0F;
+                        car_switch[tmp] = (data_tmp >> 5) & 1;
+                    }
+                }
+            }
+        }
+
+        for (i=0; i<6; i++) {
+            if (car_switch[i] != car_switch_old[i]) {
+                RS232_putc('0'+i);
+                RS232_putc('0'+car_switch[i]);
+                RS232_putc('\n');
+            }
+            car_switch_old[i] = car_switch[i];
+        }
+
+
+/*
+        i = get_car(_BV(PD3));
+        if (i > 0) {
+            itoa ( i , s, 10);
+            RS232_puts(s);
+            RS232_putc('\n');
+        }
+        _delay_ms(50);
+*/
+
+        if (car0 > 0) {
+            itoa ( car0 , s, 10);
+            car0 = 0;
+            RS232_putc('A');
+            RS232_puts(s);
+            RS232_putc('\n');
+        }
+
+        if (car1 > 0) {
+            itoa ( car1 , s, 10);
+            car1 = 0;
+            RS232_putc('B');
+            RS232_puts(s);
+            RS232_putc('\n');
+        }
+
+    } // main loop end
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trackswitch/main.h	Tue Nov 29 13:42:29 2011 +0100
@@ -0,0 +1,1 @@
+../blackbox/main.h
\ No newline at end of file

mercurial