]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/safe/avr/fail.c
safe tinyos failure handling routines for avr-based motes
[tinyos-2.x.git] / tos / lib / safe / avr / fail.c
diff --git a/tos/lib/safe/avr/fail.c b/tos/lib/safe/avr/fail.c
new file mode 100644 (file)
index 0000000..f3bf47d
--- /dev/null
@@ -0,0 +1,188 @@
+#include <stdint.h>
+#include <avr/io.h>
+
+// #define SIMPLE_FAIL
+
+#ifndef SIMPLE_FAIL
+
+static void led_off_0 (void) 
+{ 
+  *(volatile unsigned char *)59U |= 1 << 0;
+}
+
+static void led_off_1 (void)  { 
+  *(volatile unsigned char *)59U |= 1 << 1;
+}
+
+static void led_off_2 (void)  {
+  *(volatile unsigned char *)59U |= 1 << 2;
+}
+
+static void led_on_0 (void) { 
+  *(volatile unsigned char *)59U &= ~(1 << 0);
+}
+
+static void led_on_1 (void) { 
+  *(volatile unsigned char *)59U &= ~(1 << 1);
+}
+
+static void led_on_2 (void) { 
+  *(volatile unsigned char *)59U &= ~(1 << 2);
+}
+
+static void delay (int len) 
+{
+  volatile int x, y;
+  for (x=0; x<len; x++) { 
+    for (y=0; y<1000; y++) { }
+  }
+}
+
+static void v_short_delay (void) { delay (10); }
+
+static void short_delay (void) { delay (80); }
+
+static void long_delay (void) { delay (800); }
+
+static void flicker (void)
+{
+    int i;
+    for (i=0; i<20; i++) {
+       delay (20);
+       led_off_0 ();
+       led_off_1 ();
+       led_off_2 ();
+       delay (20);
+       led_on_0 ();
+       led_on_1 ();
+       led_on_2 ();
+    }
+    led_off_0 ();
+    led_off_1 ();
+    led_off_2 ();
+}
+
+static void roll (void)
+{
+    int i;
+    for (i=0; i<10; i++) {
+       delay (30);
+       led_on_0 ();
+       led_off_2 ();
+       delay (30);
+       led_on_1 ();
+       led_off_0 ();
+       delay (30);
+       led_on_2 ();
+       led_off_1 ();
+    }
+    led_off_2 ();
+}
+           
+static void separator (void)
+{
+    led_off_0 ();
+    led_off_1 ();
+    led_off_2 ();
+    short_delay ();
+    led_on_0 ();
+    led_on_1 ();
+    led_on_2 ();
+    v_short_delay ();
+    led_off_0 ();
+    led_off_1 ();
+    led_off_2 ();
+    short_delay ();
+}
+
+static void display_b4 (int c) 
+{
+  switch (c) {
+  case 3:
+    led_on_2 ();
+  case 2:
+    led_on_1 ();
+  case 1:
+    led_on_0 ();
+  case 0:
+    long_delay ();
+    break;
+  default:
+    flicker ();
+  }
+  separator ();
+}
+
+static void display_int (const unsigned int x)
+{
+  int i = 14;
+  do {
+    display_b4 (0x3 & (x >> i));
+    i -= 2;
+  } while (i >= 0);
+}
+
+static void display_int_flid (const unsigned int x)
+{
+  roll ();
+  display_int (x);
+  roll ();
+}
+
+#endif // ndef SIMPLE_FAIL
+
+static inline void load_to_z_and_break (int value)
+{
+  asm volatile ("movw %0, %1" "\n\t"
+               "break"       "\n\t"
+               : "=z"(value)  : "r" (value));
+}
+
+void deputy_fail_noreturn_fast (const char* file, int flid, const char* func)
+{
+  asm volatile ("cli");
+  load_to_z_and_break (flid);
+  PORTA |= 7;
+
+#ifdef SIMPLE_FAIL
+
+  while (1) {
+    int i;
+    PORTA ^= 7;
+    for (i = 0; i < 10; i++) {
+      uint16_t dt = 50000;
+      /* loop takes 8 cycles. this is 1uS if running on an internal 8MHz
+        clock, and 1.09uS if running on the external crystal. */
+      asm volatile (
+                   "1: sbiw    %0,1\n"
+                   "   adiw    %0,1\n"
+                   "   sbiw    %0,1\n"
+                   "   brne    1b" : "+w" (dt));
+    }
+  }
+
+#else
+
+  while (1) {
+    display_int_flid (flid);
+  }
+
+#endif
+
+}
+
+void deputy_fail_mayreturn(const char *check, const char *text,
+                           const char* file, int line, const char* func)
+{
+    // I don't think this has any meaning without FLID transformation
+    // FLID transformation stores FLID in line variable
+    deputy_fail_noreturn_fast(file, line, func);
+}
+
+void deputy_fail_noreturn(const char *check, const char *text,
+                          const char* file, int line, const char* func)
+{
+    // I don't think this has any meaning without FLID transformation
+    // FLID transformation stores FLID in line variable
+    deputy_fail_noreturn_fast(file, line, func);
+}