inital checkin
authorunknown author <unknown@example.com>
Thu, 23 Apr 2009 15:15:19 +0000 (15:15 +0000)
committerunknown author <unknown@example.com>
Thu, 23 Apr 2009 15:15:19 +0000 (15:15 +0000)
firmware/Makefile [new file with mode: 0755]
firmware/README [new file with mode: 0644]
firmware/tuer.pde [new file with mode: 0644]
mifare-read.c [new file with mode: 0644]
reader.pl [new file with mode: 0755]
tuerschlitten.pl [new file with mode: 0755]

diff --git a/firmware/Makefile b/firmware/Makefile
new file mode 100755 (executable)
index 0000000..9ff5f58
--- /dev/null
@@ -0,0 +1,209 @@
+## see README file
+
+TARGET = tuer
+INSTALL_DIR = /flash/realraum/firmware/arduino
+PORT = /dev/ttyUSB0
+UPLOAD_RATE = 19200
+AVRDUDE_PROGRAMMER = stk500v1
+MCU = atmega168
+F_CPU = 16000000
+
+############################################################################
+# Below here nothing should be changed...
+
+ARDUINO = $(INSTALL_DIR)/hardware/cores/arduino
+AVR_TOOLS_PATH = /usr/bin
+SRC =  $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
+$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
+$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
+$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c
+CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/Print.cpp $(ARDUINO)/WMath.cpp
+FORMAT = ihex
+
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# Place -I options here
+CINCS = -I$(ARDUINO)
+CXXINCS = -I$(ARDUINO)
+
+# Compiler flag to set the C Standard level.
+# c89   - "ANSI" C
+# gnu89 - c89 plus GCC extensions
+# c99   - ISO C99 standard (not yet fully implemented)
+# gnu99 - c99 plus GCC extensions
+CSTANDARD = -std=gnu99
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 
+LDFLAGS = -lm
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -V -F -C $(INSTALL_DIR)/hardware/tools/avrdude.conf \
+-p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+-b $(UPLOAD_RATE)
+
+# Program settings
+CC = $(AVR_TOOLS_PATH)/avr-gcc
+CXX = $(AVR_TOOLS_PATH)/avr-g++
+OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy
+OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
+AR  = $(AVR_TOOLS_PATH)/avr-ar
+SIZE = $(AVR_TOOLS_PATH)/avr-size
+NM = $(AVR_TOOLS_PATH)/avr-nm
+AVRDUDE = $(AVR_TOOLS_PATH)/avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) 
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: applet_files build sizeafter
+
+build: elf hex 
+
+applet_files: $(TARGET).pde
+       # Here is the "preprocessing".
+       # It creates a .cpp file based with the same name as the .pde file.
+       # On top of the new .cpp file comes the WProgram.h header.
+       # At the end there is a generic main() function attached.
+       # Then the .cpp file will be compiled. Errors during compile will
+       # refer to this new, automatically generated, file. 
+       # Not the original .pde file you actually edit...
+       test -d applet || mkdir applet
+       echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+       cat $(TARGET).pde >> applet/$(TARGET).cpp
+       cat $(ARDUINO)/main.cxx >> applet/$(TARGET).cpp
+
+elf: applet/$(TARGET).elf
+hex: applet/$(TARGET).hex
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss 
+sym: applet/$(TARGET).sym
+
+# Program the device.  
+upload: applet/$(TARGET).hex
+       $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+       # Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) applet/$(TARGET).hex
+ELFSIZE = $(SIZE)  applet/$(TARGET).elf
+sizebefore:
+       @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
+
+sizeafter:
+       @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi
+
+
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT=$(OBJCOPY) --debugging \
+--change-section-address .data-0x800000 \
+--change-section-address .bss-0x800000 \
+--change-section-address .noinit-0x800000 \
+--change-section-address .eeprom-0x810000 
+
+
+coff: applet/$(TARGET).elf
+       $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+       $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf $(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym
+
+.elf.hex:
+       $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+       -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+       --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+       $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+       $(NM) -n $< > $@
+
+       # Link: create ELF output file from library.
+applet/$(TARGET).elf: $(TARGET).pde applet/core.a 
+       $(CC) $(ALL_CFLAGS) -o $@ applet/$(TARGET).cpp -L. applet/core.a $(LDFLAGS)
+
+applet/core.a: $(OBJ)
+       @for i in $(OBJ); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done
+
+
+
+# Compile: create object files from C++ source files.
+.cpp.o:
+       $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ 
+
+# Compile: create object files from C source files.
+.c.o:
+       $(CC) -c $(ALL_CFLAGS) $< -o $@ 
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+       $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+       $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+# Target: clean project.
+clean:
+       $(REMOVE) applet/$(TARGET).hex applet/$(TARGET).eep applet/$(TARGET).cof applet/$(TARGET).elf \
+       applet/$(TARGET).map applet/$(TARGET).sym applet/$(TARGET).lss applet/core.a \
+       $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+
+depend:
+       if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+       then \
+               sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+                       $(MAKEFILE).$$$$ && \
+               $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+       fi
+       echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+               >> $(MAKEFILE); \
+       $(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY:        all build elf hex eep lss sym program coff extcoff clean depend applet_files sizebefore sizeafter
diff --git a/firmware/README b/firmware/README
new file mode 100644 (file)
index 0000000..916af03
--- /dev/null
@@ -0,0 +1,19 @@
+Realraum tuer instructions:
+
+1. install avr-gcc and tools:
+    $ sudo aptitude install gcc-avr avr-libc avrdude
+
+2. download arduino:
+    $ wget http://arduino.googlecode.com/files/arduino-0013-linux2.tgz
+
+3. unpack and add link:
+    $ tar -xzf arduino-0013-linux2.tgz
+    $ ln -s arduino-0013 arduino
+    
+4. update Makefile variables INSTALL_DIR and PORT to your needs
+
+5. build it
+    $ make
+
+6. flash it (press reset)
+    $ make upload 
diff --git a/firmware/tuer.pde b/firmware/tuer.pde
new file mode 100644 (file)
index 0000000..1808c88
--- /dev/null
@@ -0,0 +1,478 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+//********************************************************************//
+
+#define HEARTBEAT_PIN 15 // blinking led indicating that system is active
+#define HEARTBEAT_DURATION 10 // *10 ms, duration of heartbeat pulse
+#define HEARTBEAT_DELAY 200   // *10 ms, 1/heartbeat-frequency
+int heartbeat_cnt = 0;                    
+        
+#define LEDS_ON 0xFC
+#define LEDS_OFF 0x00
+
+#define LEDS_GREEN_COMMON_PIN 16
+#define LEDS_RED_COMMON_PIN 17 
+#define LED_DELAY 50 // *2 ms, between led shifts
+int led_delay_cnt = 0;
+byte next_led = 0;
+
+#define LIMIT_OPENED_PIN 18 // A4: limit switch for open
+#define LIMIT_CLOSED_PIN 19 // A5: limit switch for close
+
+#define MANUAL_OPEN_PIN 12  // keys for manual open and close
+#define MANUAL_CLOSE_PIN 13 // 
+
+#define IDLE 0      // close and open may be called
+#define OPENING 1   // opening, only 's' command is allowed
+#define CLOSING 2   // closing, onyl 's' command is allowed
+#define WAIT 3      // wait some time after open or close and hold last step
+#define ERROR 4     // an error occured
+
+#define CMD_OPEN 'o'
+#define CMD_CLOSE 'c'
+#define CMD_STATUS 's'
+#define CMD_RESET 'r'
+
+#define STEPPER_OFF 0x30
+byte current_state = IDLE;  // current state of internal state machine
+byte next_step = 0;         // step counter 0 .. 3
+#define MOVING_TIMEOUT 1600 // *2 ms, in case limit switches don't work stop and report an error
+int timeout_cnt = 0;        // counts up to MOVING_TIMEOUT
+
+//********************************************************************//
+
+void init_limits()
+{
+  pinMode(LIMIT_OPENED_PIN, INPUT);      // set pin to input
+  digitalWrite(LIMIT_OPENED_PIN, HIGH);  // turn on pullup resistors  
+
+  pinMode(LIMIT_CLOSED_PIN, INPUT);      // set pin to input
+  digitalWrite(LIMIT_CLOSED_PIN, HIGH);  // turn on pullup resistors  
+}
+
+boolean is_opened()
+{
+  if(digitalRead(LIMIT_OPENED_PIN))
+     return false;
+     
+  return true;
+}
+
+boolean is_closed()
+{
+  if(digitalRead(LIMIT_CLOSED_PIN))
+     return false;
+     
+  return true;
+}
+
+//**********//
+
+void init_manual()
+{
+  pinMode(MANUAL_OPEN_PIN, INPUT);      // set pin to input
+  digitalWrite(MANUAL_OPEN_PIN, HIGH);  // turn on pullup resistors  
+
+  pinMode(MANUAL_CLOSE_PIN, INPUT);     // set pin to input
+  digitalWrite(MANUAL_CLOSE_PIN, HIGH); // turn on pullup resistors  
+}
+
+boolean manual_open()
+{
+  if(digitalRead(MANUAL_OPEN_PIN))
+     return false;
+     
+  return true;
+}
+
+boolean manual_close()
+{
+  if(digitalRead(MANUAL_CLOSE_PIN))
+     return false;
+     
+  return true;
+}
+
+//********************************************************************//
+
+void reset_stepper()
+{
+  next_step = 0;
+  PORTB = STEPPER_OFF;
+  timeout_cnt = 0;
+}
+
+void init_stepper()
+{
+  DDRB = 0x0F; // set PortB 3:0 as output
+  reset_stepper();
+}
+
+byte step_table(byte step)
+{
+  switch(step) { // 0011 xxxx, manual keys pull-ups stay active
+  case 0: return 0x33;
+  case 1: return 0x36;
+  case 2: return 0x3C;
+  case 3: return 0x39;
+  }
+  return STEPPER_OFF;
+}
+
+//**********//
+
+void reset_leds()
+{
+  led_delay_cnt = 0;
+  next_led = 0;
+  PORTD = LEDS_OFF;
+  digitalWrite(LEDS_GREEN_COMMON_PIN, HIGH);
+  digitalWrite(LEDS_RED_COMMON_PIN, HIGH);
+}
+
+void init_leds()
+{
+  DDRD = 0xFC;
+  pinMode(LEDS_GREEN_COMMON_PIN, OUTPUT);
+  pinMode(LEDS_RED_COMMON_PIN, OUTPUT);
+  reset_leds();
+}
+
+byte led_table(byte led)
+{
+  switch(led) {  // xxxx xx00, leave RxD and TxD to 0
+  case 0: return 0x04;
+  case 1: return 0x08;
+  case 2: return 0x10;
+  case 3: return 0x20;
+  case 4: return 0x40;
+  case 5: return 0x80; 
+  }
+  return LEDS_OFF;
+}
+
+void leds_green()
+{
+  digitalWrite(LEDS_GREEN_COMMON_PIN, LOW);
+  digitalWrite(LEDS_RED_COMMON_PIN, HIGH);
+}
+
+void leds_red()
+{
+  digitalWrite(LEDS_GREEN_COMMON_PIN, HIGH);
+  digitalWrite(LEDS_RED_COMMON_PIN, LOW);
+}
+
+void leds_toggle()
+{
+  if(digitalRead(LEDS_GREEN_COMMON_PIN) == HIGH) {
+    digitalWrite(LEDS_GREEN_COMMON_PIN, LOW);
+    digitalWrite(LEDS_RED_COMMON_PIN, HIGH);
+  }
+  else {
+    digitalWrite(LEDS_GREEN_COMMON_PIN, HIGH);
+    digitalWrite(LEDS_RED_COMMON_PIN, LOW);
+  }
+}
+
+//**********//
+
+void start_step_timer()
+{
+  // timer 1: 2 ms, between stepper output state changes
+  TCCR1A = 0;                    // prescaler 1:256, WGM = 4 (CTC)
+  TCCR1B = 1<<WGM12 | 1<<CS12;   // 
+  OCR1A = 124;        // (1+124)*256 = 32000 -> 2 ms @ 16 MHz
+  TCNT1 = 0;          // reseting timer
+  TIMSK1 = 1<<OCIE1A; // enable Interrupt
+}
+
+void start_wait_timer()
+{
+  // timer1: 250 ms, minimal delay between subsequent open/close
+  TCCR1A = 0;         // prescaler 1:256, WGM = 0 (normal)
+  TCCR1B = 1<<CS12;   // 
+  OCR1A = 15624;      // (1+15624)*256 = 4000000 -> 250 ms @ 16 MHz
+  TCNT1 = 0;          // reseting timer
+  TIMSK1 = 1<<OCIE1A; // enable Interrupt
+}
+
+void start_error_timer()
+{
+  // timer1: 500 ms, blinking leds with 1 Hz
+  TCCR1A = 0;                  // prescaler 1:256, WGM = 4 (CTC)
+  TCCR1B = 1<<WGM12 | 1<<CS12; // 
+  OCR1A = 31249;      // (1+31249)*256 = 8000000 -> 500 ms @ 16 MHz
+  TCNT1 = 0;          // reseting timer
+  TIMSK1 = 1<<OCIE1A; // enable Interrupt
+}
+
+void stop_timer() // stop the timer
+{
+  // timer1
+  TCCR1B = 0; // no clock source
+  TIMSK1 = 0; // disable timer interrupt
+}
+
+ISR(TIMER1_COMPA_vect)
+{
+      // check if limit switch is active
+  if((current_state == OPENING && is_opened()) ||
+     (current_state == CLOSING && is_closed())) 
+  {
+    stop_timer();
+    reset_leds();
+    if(current_state == OPENING)
+      leds_green();
+    else
+      leds_red();
+    PORTD = LEDS_ON;
+    current_state = WAIT;
+    start_wait_timer();
+    return;
+  }
+      
+  if(current_state == OPENING || current_state == CLOSING) {
+    timeout_cnt++;
+    if(timeout_cnt >= MOVING_TIMEOUT) {
+      reset_stepper();
+      stop_timer();
+      current_state = ERROR;
+      Serial.println("Error: open/close took too long!");
+      start_error_timer();
+      leds_green();
+      PORTD = LEDS_ON;
+    }
+  }
+
+  if(current_state == OPENING) { // next step (open)
+    PORTB = step_table(next_step);
+    next_step++;
+    if(next_step >= 4)
+      next_step = 0;
+  }
+  else if(current_state == CLOSING) { // next step (close)
+    PORTB = step_table(next_step);
+    if(next_step == 0)
+      next_step = 3;
+    else
+      next_step--;
+  }
+  else if(current_state == WAIT) { // wait after last open/close finished -> idle
+    stop_timer();
+    reset_stepper();
+    current_state = IDLE;
+    return;
+  }
+  else if(current_state == ERROR) {
+    leds_toggle();
+    return;
+  }
+  else { // timer is useless stop it
+    stop_timer();
+    return;
+  }
+
+  led_delay_cnt++;
+  if(led_delay_cnt >= LED_DELAY) {
+    led_delay_cnt = 0;    
+
+    PORTD = led_table(next_led);
+
+    if(current_state == OPENING) {
+      if(next_led == 0)
+        next_led = 5;
+      else
+        next_led--;
+    }
+    else if(current_state == CLOSING) {
+      next_led++;
+      if(next_led >= 6)
+        next_led = 0;
+    }
+  }
+}
+
+//********************************************************************//
+
+void reset_heartbeat()
+{
+  digitalWrite(HEARTBEAT_PIN, HIGH);
+  heartbeat_cnt = 0;
+}
+
+void heartbeat_on()
+{
+  digitalWrite(HEARTBEAT_PIN, LOW);
+}
+
+void heartbeat_off()
+{
+  digitalWrite(HEARTBEAT_PIN, HIGH);
+}
+
+void init_heartbeat()
+{
+  pinMode(HEARTBEAT_PIN, OUTPUT);
+  reset_heartbeat();
+  // timer 2: ~10 ms, timebase for heartbeat signal
+  TCCR2A = 1<<WGM21;                    // prescaler 1:1024, WGM = 2 (CTC)
+  TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20; // 
+  OCR2A = 155;        // (1+155)*1024 = 159744 -> ~10 ms @ 16 MHz
+  TCNT2 = 0;          // reseting timer
+  TIMSK2 = 1<<OCIE2A; // enable Interrupt
+  heartbeat_on();
+}
+
+// while running this gets called every ~10ms
+ISR(TIMER2_COMPA_vect)
+{
+  heartbeat_cnt++;
+  if(heartbeat_cnt == HEARTBEAT_DURATION)
+    heartbeat_off();
+  else if(heartbeat_cnt >= HEARTBEAT_DELAY) {
+    heartbeat_on();
+    heartbeat_cnt = 0;
+  }
+}
+
+//********************************************************************//
+
+void reset_after_error()
+{
+  stop_timer();
+  reset_leds();
+
+  leds_red();
+  if(is_closed()) {
+    current_state = IDLE;
+    PORTD = LEDS_ON;
+  }
+  else {
+    current_state = CLOSING;
+    start_step_timer();
+  }
+  Serial.println("Ok, closing now");
+}
+
+void start_open()
+{
+  if(is_opened()) {
+    Serial.println("Already open");
+    return;
+  }
+
+  reset_stepper();
+  reset_leds();
+  leds_green();
+  current_state = OPENING;
+  start_step_timer();
+  Serial.println("Ok");
+}
+
+void start_close()
+{
+  if(is_closed()) {
+    Serial.println("Already closed");
+    return;
+  }
+    
+  reset_stepper();
+  reset_leds();
+  leds_red();
+  current_state = CLOSING;
+  start_step_timer();
+  Serial.println("Ok");
+}
+
+void print_status()
+{
+  Serial.print("Status: ");
+  if(is_opened())
+    Serial.print("opened");
+  else if(is_closed())
+    Serial.print("closed");
+  else
+    Serial.print("<->");
+
+  switch(current_state) {
+  case IDLE: Serial.println(", idle"); break;
+  case OPENING: Serial.println(", opening"); break;
+  case CLOSING: Serial.println(", closing"); break;
+  case WAIT: Serial.println(", waiting"); break;
+  default: Serial.println(", <undefined state>"); break;
+  }
+  
+}
+
+//**********//
+
+void setup()
+{
+  init_limits();
+  init_stepper();
+  init_leds();
+  init_heartbeat();
+
+  Serial.begin(9600);
+
+  current_state = IDLE;
+
+      // make sure door is locked after reset
+  leds_red();
+  if(is_closed())
+    PORTD = LEDS_ON;
+  else {
+    current_state = CLOSING;
+    start_step_timer();
+  }
+}
+
+void loop()
+{
+  if(Serial.available()) {
+    char command = Serial.read();
+
+    if(current_state == ERROR && command != CMD_RESET) {
+      Serial.println("Error: last open/close operation took to long!");
+    }
+    else if (command == CMD_RESET) {
+      reset_after_error();
+    }
+    else if (command == CMD_OPEN) {
+      if(current_state == IDLE) 
+        start_open();
+      else
+        Serial.println("Error: Operation in progress");
+    }
+    else if (command == CMD_CLOSE) {
+      if(current_state == IDLE) 
+        start_close();
+      else
+        Serial.println("Error: Operation in progress");
+    }
+    else if (command == CMD_STATUS)
+      print_status();
+    else
+      Serial.println("Error: unknown command");
+  }
+  if(manual_open() && !is_opened() && current_state == IDLE) {
+    Serial.println("open forced manually");
+    start_open();
+  }
+  if(manual_close() && !is_closed() && current_state == IDLE) {
+    Serial.println("close forced manually");
+    start_close();
+  }
+  if (current_state == IDLE) {
+    if(is_opened()) {
+      leds_green();
+      PORTD = LEDS_ON;
+    }
+    if(is_closed()) {
+      leds_red();
+      PORTD = LEDS_ON;
+    }
+  }
+}
diff --git a/mifare-read.c b/mifare-read.c
new file mode 100644 (file)
index 0000000..7bfb50c
--- /dev/null
@@ -0,0 +1,177 @@
+/* mifare-tool - a small command-line tool for librfid mifare testing
+ *
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 
+ *  as published by the Free Software Foundation
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_scan.h>
+#include <librfid/rfid_reader.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_protocol.h>
+
+#include <librfid/rfid_protocol_mifare_classic.h>
+#include <librfid/rfid_protocol_mifare_ul.h>
+
+//#include <librfid/rfid_access_mifare_classic.h>
+
+struct rfid_reader_handle *rh = NULL;
+struct rfid_layer2_handle *l2h = NULL;
+struct rfid_protocol_handle *ph = NULL;
+
+
+void sigHandler(int sig)
+{
+  printf("sig handler called\n");
+
+/*   rfid_protocol_close(ph); */
+/*   rfid_protocol_fini(ph); */
+
+  rfid_layer2_close(l2h);
+  rfid_layer2_fini(l2h);
+
+  rfid_reader_close(rh);
+  exit(0);
+}
+
+int l2_init(int layer2)
+{
+       int rc;
+
+       l2h = rfid_layer2_init(rh, layer2);
+       if (!l2h) {
+               fprintf(stderr, "error during layer2(%d)_init (0=14a,1=14b,3=15)\n",layer2);
+               return -1;
+       }
+
+       rc = rfid_layer2_open(l2h);
+       if (rc < 0) {
+               fprintf(stderr, "error during layer2_open\n");
+               return rc;
+       }
+
+       return 0;
+}
+
+int l3_init(int protocol)
+{
+       ph = rfid_protocol_init(l2h, protocol);
+       if (!ph) {
+               fprintf(stderr, "error during protocol_init\n");
+               return -1;
+       }
+       if (rfid_protocol_open(ph) < 0) {
+               fprintf(stderr, "error during protocol_open\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int mifare_cl_auth(unsigned char *key, int page)
+{
+       int rc;
+
+       rc = mfcl_set_key(ph, key);
+       if (rc < 0) {
+               fprintf(stderr, "key format error\n");
+               return rc;
+       }
+       rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, page);
+       if (rc < 0) {
+               fprintf(stderr, "mifare auth error\n");
+               return rc;
+       } else 
+//             printf("mifare auth succeeded!\n");
+
+       return 0;
+}
+
+static void mifare_l3(void)
+{
+       while (l2_init(RFID_LAYER2_ISO14443A) < 0) ;
+
+//     printf("ISO14443-3A anticollision succeeded\n");
+//     while (l3_init(RFID_PROTOCOL_MIFARE_CLASSIC) < 0) ;
+
+//     printf("Mifare card available\n");
+}
+
+void print_hex(const unsigned char* buffer, int length)
+{
+  int i;
+
+  if(length <= 0) return;
+  for(i=0; i<length; ++i) {
+    printf("0x%02X ", buffer[i]);
+    if(i && !((i+1)%8)) printf(" ");
+    if(i && !((i+1)%16)) printf("\n");
+  }
+}
+
+int main(int argc, char **argv)
+{
+       int len, rc, c, option_index = 0;
+       unsigned int page,uid,uid_len;
+       //char key[MIFARE_CL_KEY_LEN];
+       //char buf[MIFARE_CL_PAGE_SIZE];
+
+  (void) signal(SIGHUP, sigHandler);
+  (void) signal(SIGINT, sigHandler);
+  (void) signal(SIGTERM, sigHandler);
+
+/* init */
+
+       //memcpy(key, MIFARE_CL_KEYA_DEFAULT_INFINEON, MIFARE_CL_KEY_LEN);
+
+//     printf("initializing librfid\n");
+       rfid_init();
+
+       rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
+       if (!rh) {
+               fprintf(stderr, "No OpenPCD found\n");
+               exit(1);
+       }
+
+/* reading serial */
+
+  page = 0; //page 0
+
+  //len = MIFARE_CL_PAGE_SIZE;
+  mifare_l3();
+/*   if (mifare_cl_auth(key, page) < 0) */
+/*     exit(1); */
+  
+  uid_len=sizeof(uid);
+  uid=0;
+  if(rfid_layer2_getopt(l2h,RFID_OPT_LAYER2_UID,&uid,&uid_len)>=0)
+    printf("UID=%08X (len=%u)\n",uid,uid_len);
+  fflush(stdout);
+
+//  rfid_layer2_close(l2h);
+//  rfid_layer2_fini(l2h);
+
+       rfid_reader_close(rh);
+       exit(0);
+}
+
diff --git a/reader.pl b/reader.pl
new file mode 100755 (executable)
index 0000000..6a417f4
--- /dev/null
+++ b/reader.pl
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use strict;
+my $fh;
+
+my $keys;
+my %good;
+my $status = 'c';
+
+open $keys,'/flash/realraum/keys';
+while (<$keys>)
+{
+       my ($code,$comment) = split /\s/,$_,2;
+       $good{$code}=$comment;
+}
+
+while (sleep 1)
+{
+  open $fh,'/flash/realraum/a.out 0 2>&1 |';
+  while (<$fh>)
+  {
+       next unless /UID/;
+       my ($id) = /UID=(\S+)\s+/;
+       if ($good{$id})
+       {
+               my $newstat;
+               if ($status eq 'o')
+               {
+                       $newstat='c';
+
+               } else {
+                       $newstat = 'o';
+               }
+               print "$newstat: $good{$id}";
+               system ( "echo -n $newstat > /dev/ttyUSB0");
+               $status = $newstat;
+       } else {
+               print "boese\n";
+       }
+  }
+
+}
diff --git a/tuerschlitten.pl b/tuerschlitten.pl
new file mode 100755 (executable)
index 0000000..b78660e
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/perl
+
+use strict;
+