commit dc472500b5d9e2baef332e74a0ff124280767c6d
Author: Tom Mullins <tmullins@andrew.cmu.edu>
Date:   Wed Nov 28 21:31:51 2012 -0500

    Added LED blinking, and other fixes

diff --git a/mainbox/Makefile b/mainbox/Makefile
index 5ff5605..1198ad6 100644
--- a/mainbox/Makefile
+++ b/mainbox/Makefile
@@ -1,5 +1,5 @@
 SRC=main.c tool.c
-HDR=tool.h
+HDR=tool.h ../tooltron_mb.h
 
 FLAGS=-O2 -g -Wall -I.. `pkg-config --cflags --libs libmodbus`
 
diff --git a/mainbox/tool.c b/mainbox/tool.c
index 9845ade..8786eb9 100644
--- a/mainbox/tool.c
+++ b/mainbox/tool.c
@@ -58,16 +58,19 @@ static void tool_read_user(struct tool_t *tool) {
 static void tool_grant_access(struct tool_t *tool) {
   printf("Granting access to %08x on %s\n", tool->user, tool->name);
   tool_write_coil(MB_COIL_EN, 1);
+  tool->state = TS_ON;
 }
 
 static void tool_deny_access(struct tool_t *tool) {
   printf("Denying access to %08x on %s\n", tool->user, tool->name);
   tool_write_coil(MB_COIL_EN, 0);
+  tool->state = TS_OFF;
 }
 
 void tool_request_disable(struct tool_t *tool) {
   printf("Requesting disable on %s\n", tool->name);
   tool_write_coil(MB_COIL_REQ_DIS, 1);
+  tool->state = TS_REQ_DIS;
 }
 
 void tool_poll(struct tool_t *tool) {
@@ -77,15 +80,14 @@ void tool_poll(struct tool_t *tool) {
     fprintf(stderr, "modbus_set_slave: %s\n", modbus_strerror(errno));
   }
 
-  tool_read_user(tool);
-  printf("%08x\n", tool->user);
-  return;
-
   if (modbus_read_bits(ctx, 0, N_COILS, status) == -1) {
     fprintf(stderr, "modbus_read_bits: %s\n", modbus_strerror(errno));
     return;
   }
 
+  printf("new:%d en:%d req_dis:%d init:%d\n", status[MB_COIL_NEW],
+      status[MB_COIL_EN], status[MB_COIL_REQ_DIS], status[MB_COIL_INIT]);
+
   if (!status[MB_COIL_INIT]) {
     tool->state = TS_INIT;
   }
@@ -100,11 +102,12 @@ void tool_poll(struct tool_t *tool) {
       if (status[MB_COIL_NEW]) {
         tool_read_user(tool);
         // TODO check actual credentials
-        if (rand() & 1) {
+        printf("user:%08x\n", tool->user);
+        //if (rand() & 1) {
           tool_grant_access(tool);
-        } else {
+        /*} else {
           tool_deny_access(tool);
-        }
+        }*/
       }
       break;
 
diff --git a/toolbox/led.c b/toolbox/led.c
new file mode 100644
index 0000000..3cfec7f
--- /dev/null
+++ b/toolbox/led.c
@@ -0,0 +1,55 @@
+#include "led.h"
+#include <avr/io.h>
+
+#define PRESCALE 64
+#define CLOCK_SEL 3
+
+/* F_CPU / PRESCALE = OCR * 1000 + ERROR */
+#define OCR (F_CPU / PRESCALE / 1000UL)
+#define ERROR (F_CPU / PRESCALE - OCR * 1000UL)
+
+char count;
+uint16_t period;
+
+uint16_t ms;
+uint16_t error;
+
+static void blink() {
+  count--;
+  if (count % 2) {
+    led_yellow();
+  } else {
+    led_off();
+  }
+}
+
+ISR(TIMER0_COMPA_vect) {
+  error += ERROR;
+  if (error >= 1000) {
+    error -= 1000;
+  } else {
+    ms++;
+    if (ms == period) {
+      blink();
+      if (count = 0) {
+        TCCR0B = 0;
+      }
+      ms = 0;
+    }
+  }
+}
+
+void led_blink_start(unsigned int period_ms, char n_times) {
+  led_yellow();
+  ms = 0;
+  error = 0;
+  count = n_times*2-1;
+  period = period_ms;
+  OCR0A = OCR;
+  TCCR0A = _BV(WGM01);
+  TCCR0B = CLOCK_SEL;
+}
+
+char led_blink_done() {
+  return count == 0;
+}
diff --git a/toolbox/led.h b/toolbox/led.h
index 79587a2..ce15651 100644
--- a/toolbox/led.h
+++ b/toolbox/led.h
@@ -9,4 +9,10 @@ static inline void led_red() {PORTC = (PORTC & ~_BV(PC0)) | _BV(PC1);}
 static inline void led_yellow() {PORTC |= _BV(PC1) | _BV(PC0);}
 static inline void led_green() {PORTC = (PORTC & ~_BV(PC1)) | _BV(PC0);}
 
+/* Starts LED blinking */ 
+void led_blink_start(unsigned int period_ms, char n_times);
+
+/* Returns nonzero if blinking has finished */
+char led_blink_done();
+
 #endif
diff --git a/toolbox/main.c b/toolbox/main.c
index f2e498d..f7f68f8 100644
--- a/toolbox/main.c
+++ b/toolbox/main.c
@@ -57,6 +57,8 @@ static void tool_main() {
       if (get_coil(MB_COIL_EN)) {
         tool_enable();
         toolstate = TS_ON;
+      } else if (!get_coil(MB_COIL_NEW)) {
+        toolstate = TS_OFF;
       }
       break;
 
@@ -84,10 +86,11 @@ static void tool_main() {
       } else 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;
+        if (led_blink_done()) {
+          set_coil(MB_COIL_EN, 0);
+          tool_disable();
+          toolstate = TS_OFF;
+        }
       }
       break;
 
@@ -99,6 +102,7 @@ static void tool_main() {
         toolstate = TS_REQ_DIS;
       } else if (!rfid_check_serno(current_user)) {
         toolstate = TS_MISSING_ID;
+        led_blink_start();
       }
       break;
 
@@ -109,6 +113,8 @@ static void tool_main() {
 eMBErrorCode eMBRegCoilsCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils,
     eMBRegisterMode mode) {
 
+  addr--;
+
   if (addr+n_coils > N_COILS) {
     return MB_ENOREG;
   }
@@ -153,7 +159,7 @@ eMBErrorCode eMBRegCoilsCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils,
 
   } else if (mode == MB_REG_READ) {
 
-    reg_buf[0] = (coils >> (addr-1)) & ((1 << n_coils) - 1);
+    reg_buf[0] = (coils >> addr) & ((1 << n_coils) - 1);
     return MB_ENOERR;
 
   }
@@ -167,6 +173,8 @@ eMBErrorCode eMBRegDiscreteCB(UCHAR *reg_buf, USHORT addr, USHORT n_coils) {
 
 eMBErrorCode eMBRegInputCB(UCHAR *reg_buf, USHORT addr, USHORT n_regs) {
 
+  addr--;
+
   switch (addr) {
 
     case MB_INP_SERNOL:
@@ -226,7 +234,7 @@ int main() {
       rfid_get_serno(current_user);
       rfid_start_read();
     }
-    //tool_main();
+    tool_main();
     eMBPoll();
     _delay_ms(50);
   }
diff --git a/tooltron_mb.h b/tooltron_mb.h
index de76103..2ad1ca8 100644
--- a/tooltron_mb.h
+++ b/tooltron_mb.h
@@ -6,11 +6,11 @@
  */
 
 /* Serial number from rfid reader, or 0 if there is no rfid tag present */
-#define MB_INP_SERNOL  1
-#define MB_INP_SERNOH  2
+#define MB_INP_SERNOL  0
+#define MB_INP_SERNOH  1
 
 /* Value from current sensor */
-#define MB_INP_CURRENT 3
+#define MB_INP_CURRENT 2
 
 /*
  * Coils, 1 bit read/write
@@ -18,21 +18,21 @@
 
 /* When 1, there is a new rfid tag in the tool. Automatically cleared when the
  * main box writes to MB_COIL_EN */
-#define MB_COIL_NEW     1
+#define MB_COIL_NEW     0
 
 /* When 1, the tool receives power. Write 1 or 0 to grant or deny an access
  * request, respectively. If the tool is running, write 0 to immediately shut
  * off the tool */
-#define MB_COIL_EN      2
+#define MB_COIL_EN      1
 
 /* Write 1 to request that the tool is disabled soon (what that means will be
  * determined later) */
-#define MB_COIL_REQ_DIS 3
+#define MB_COIL_REQ_DIS 2
 
 /* When 1, tool has been properly initialized. When 0, tool has lost power and
  * the main box should rewrite values for current limits (to be implemented
  * later) */
-#define MB_COIL_INIT    4
+#define MB_COIL_INIT    3
 
 /* Number of coils */
 #define N_COILS 4
