commit 12ea39cc64a8ebc9b7f3c176488a210d80684453
Author: Tom Mullins <tmullins@andrew.cmu.edu>
Date:   Wed Nov 14 21:50:18 2012 -0500

    Added actual control of tool

diff --git a/toolbox/main.c b/toolbox/main.c
index c9d9396..a1098ff 100644
--- a/toolbox/main.c
+++ b/toolbox/main.c
@@ -1,15 +1,98 @@
 #include <stdint.h>
+#include <string.h>
+#include <avr/io.h>
 #include <util/delay.h>
 #include "mb.h"
 #include "mbport.h"
 #include "tooltron_mb.h"
 #include "rfid.h"
 
+enum toolstate_t {
+  TS_INIT,
+  TS_OFF,
+  TS_WAIT_ACCESS,
+  TS_REQ_DIS,
+  TS_MISSING_ID,
+  TS_ON
+};
+
+static enum toolstate_t toolstate = TS_INIT;
 static char coils;
+static char current_user[RFID_SERNO_SIZE];
 
 static inline void set_coil(char coil, char bit) {
   coils |= (bit << coil);
 }
+static inline char get_coil(char coil) {
+  return (coils >> coil) & 1;
+}
+
+static inline void tool_init() {DDRA |= _BV(DDA1);}
+static inline void tool_enable() {PORTA |= _BV(PA1);}
+static inline void tool_disable() {PORTA &= _BV(PA1);}
+
+static void tool_main() {
+
+  switch (toolstate) {
+
+    case TS_INIT:
+      if (get_coil(MB_COIL_INIT)) {
+        set_coil(MB_COIL_NEW, 0);
+        set_coil(MB_COIL_EN, 0);
+        set_coil(MB_COIL_REQ_DIS, 0);
+        toolstate = TS_OFF;
+      }
+      break;
+
+    case TS_OFF:
+      if (rfid_nonzero()) {
+        rfid_get_serno(current_user);
+        set_coil(MB_COIL_NEW, 1);
+        toolstate = TS_WAIT_ACCESS;
+      }
+      break;
+
+    case TS_WAIT_ACCESS:
+      if (get_coil(MB_COIL_EN)) {
+        tool_enable();
+        toolstate = TS_ON;
+      }
+      break;
+
+    case TS_REQ_DIS:
+      // TODO blink yellow for 10 seconds or something
+      set_coil(MB_COIL_EN, 0);
+      tool_disable();
+      toolstate = TS_OFF;
+      break;
+
+    case TS_MISSING_ID:
+      if (rfid_check_serno(current_user)) {
+        toolstate = TS_ON;
+      } else {
+        // TODO blink yellow for 10 seconds or something
+        set_coil(MB_COIL_EN, 0);
+        tool_disable();
+        toolstate = TS_OFF;
+      }
+      break;
+
+    case TS_ON:
+      if (!get_coil(MB_COIL_EN)) {
+        tool_disable();
+        toolstate = TS_OFF;
+      }
+      if (get_coil(MB_COIL_REQ_DIS)) {
+        toolstate = TS_REQ_DIS;
+      }
+      if (!rfid_check_serno(current_user)) {
+        toolstate = TS_MISSING_ID;
+      }
+      break;
+
+  }
+
+}
 
 eMBErrorCode eMBRegCoilsCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils,
     eMBRegisterMode mode) {
@@ -40,7 +123,7 @@ eMBErrorCode eMBRegCoilsCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils,
         }
 
       case MB_COIL_REQ_DIS:
-        set_coil(MB_COIL_INIT, reg_buf[0] & 1);
+        set_coil(MB_COIL_REQ_DIS, reg_buf[0] & 1);
         reg_buf[0] >>= 1;
         n_coils--;
         if (n_coils == 0) {
@@ -73,7 +156,7 @@ eMBErrorCode eMBRegDiscreteCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils) {
 eMBErrorCode eMBRegInputCB(UCHAR *reg_buf, USHORT addr, USHORT n_regs) {
   char serno[RFID_SERNO_SIZE];
 
-  rfid_get_serno(serno);
+  memcpy(reg_buf, current_user, sizeof(current_user));
 
   switch (addr) {
 
@@ -119,19 +202,18 @@ eMBErrorCode eMBRegHoldingCB(UCHAR *reg_buf, USHORT addr, USHORT n_regs,
 }
 
 int main() {
+
+  tool_init();
   rfid_init();
 
   eMBInit(MB_RTU, SLAVE_ADDR, 0, MB_BAUD, MB_PAR_NONE);
   eMBEnable();
 
-  /* Set pin controlling relay to output */
-  DDRA |= _BV(DDA1);
-
   sei();
 
   while (1) {
     rfid_read();
-    /* TODO act on rfid input and coil state */
+    tool_main();
     eMBPoll();
     _delay_ms(200);
   }
diff --git a/toolbox/rfid.c b/toolbox/rfid.c
index 35ff932..4860d85 100644
--- a/toolbox/rfid.c
+++ b/toolbox/rfid.c
@@ -1,3 +1,4 @@
+#include <string.h>
 #include <util/delay.h>
 #include "rfid.h"
 #include "serial.h"
@@ -72,8 +73,19 @@ void rfid_read() {
 }
 
 void rfid_get_serno(char *buf) {
+  memcpy(buf, serno, sizeof(serno));
+}
+
+char rfid_check_serno(char *buf) {
+  return memcmp(buf, serno, sizeof(serno)) == 0;
+}
+
+char rfid_nonzero() {
   int i;
-  for (i = 0; i < RFID_SERNO_SIZE; i++) {
-    buf[i] = serno[i];
+  for (i = 0; i < sizeof(serno); i++) {
+    if (serno[i]) {
+      return 1;
+    }
   }
+  return 0;
 }
diff --git a/toolbox/rfid.h b/toolbox/rfid.h
index f3c235f..f890093 100644
--- a/toolbox/rfid.h
+++ b/toolbox/rfid.h
@@ -15,7 +15,7 @@
 /* Should be called before anything else */
 void rfid_init();
 
-/* Reads the serial number of an rfid tag into an internal buffer, accessbile
+/* Reads the serial number of an rfid tag into an internal buffer, accessible
  * with rfid_get_serno */
 void rfid_read();
 
@@ -28,4 +28,12 @@ void rfid_read_safe();
  * into serno, which should be at least RFID_SERNO_SIZE bytes */
 void rfid_get_serno(char *serno);
 
+/* Call this only after calling rfid_read. Returns 1 if serno matches the
+ * internal buffer of the most recently read serial number */
+char rfid_check_serno(char *serno);
+
+/* Call this only after calling rfid_read. Returns 1 if the internal buffer is
+ * nonzero, meaning a serial number was successfully read from an rfid tag */
+char rfid_nonzero();
+
 #endif
