The London Hackspace bandwidth meter

Dependencies:   LPD8806 MODSERIAL mbed picojson

See:

Revision:
4:7087ea3d13c1
Parent:
3:7fca72f96711
Child:
5:24172484b8c5
--- a/vfd.cpp	Thu Aug 23 00:17:04 2012 +0000
+++ b/vfd.cpp	Mon Aug 27 01:32:52 2012 +0000
@@ -14,6 +14,8 @@
 
 #include "mbed.h"
 #include "vfd.h"
+#include "Stream.h"
+#include "FunctionPointer.h"
 
 // InturruptIn busy_intr(p27)
 
@@ -27,6 +29,8 @@
 bool c_a0;
 bool c_blank;
 
+bool vfd_dead = 0;
+
 void vfd_shift_clock(void) {
         vfd_p_clock = 0;
         wait_us(100);
@@ -34,7 +38,7 @@
         wait_us(100);
 }
 
-void vfd_doit(int data, int mode, int wr, int ss) {
+void vfd_doit(int data, int mode, int wr, int ss, int reset) {
     int i, bit;
     
     vfd_p_data = 0; // nc
@@ -42,7 +46,7 @@
     vfd_p_data = 0; // nc
     vfd_shift_clock();
 
-    vfd_p_data = 1; // reset, 0 = in reset
+    vfd_p_data = reset; // reset, 0 = in reset
     vfd_shift_clock();
 
     vfd_p_data = c_blank; // Blank, 0 = blanked
@@ -73,14 +77,25 @@
 }
 
 /* mode == 1 if command */
-void vfd_send(int data, int mode)
+void vfd_send(int data, int mode, int force)
 {
     data = data & 0xff;
     c_data = data;
     c_blank = 1;
 
-    if (vfd_p_busy)
+    if (mode == 0)
+        printf("%02x ", data);
+
+    if (vfd_dead && ! force) {
+        printf("vfd dead (?), not sending.\r\n");
+        return;
+    }
+    if (force)
+        printf("forcing vfd for 0x%02x %d\r\n", data, mode);
+
+    if (vfd_p_busy) {
         printf("pre, busy: %d\r\n", vfd_p_busy.read());
+    }
     
     if (vfd_p_busy)
     {
@@ -88,23 +103,32 @@
         if (vfd_p_busy)
         {
             printf("still busy :(\r\n");
-            return;
+            printf("resetting\r\n");
+            if (!force)
+                vfd_reset();
+            if (vfd_p_busy) {
+                printf("still busy after reset!\r\n");
+                if (!force)
+                    return;
+            }
+            if (!force)
+                return;
         }
     }
     
     /* wr,ss */
-    vfd_doit(data, mode, 0, 0);
+    vfd_doit(data, mode, 0, 0, 1);
     wait_us(1);
-    vfd_doit(data, mode, 1, 0);
+    vfd_doit(data, mode, 1, 0, 1);
     wait_us(1);
-    vfd_doit(data, mode, 1, 1);
+    vfd_doit(data, mode, 1, 1, 1);
     wait_us(1);
 
     if (vfd_p_busy)
         printf("post1, busy: %d\r\n", vfd_p_busy.read());
 
-    vfd_doit(data, mode, 0, 0);
-    wait_ms(1); // loop and wait for not busy
+    vfd_doit(data, mode, 0, 0, 1);
+    wait_ms(4); // loop and wait for not busy
 
     if (vfd_p_busy)
         printf("post2, busy: %d\r\n", vfd_p_busy.read());
@@ -115,15 +139,20 @@
     }
 }
 
-void vfd_command(int data) {
-    vfd_send(data, 1);
+void vfd_command(int data, int force) {
+    vfd_send(data, 1, force);
 }
 
 void vfd_data(int data) {
-    vfd_send(data, 0);
+    if ((data & 0xff) == 0x7f) {
+        data = 0x20;
+        printf("changed data to %02x\r\n", data);
+    }
+    vfd_send(data, 0, 0);
 }
 
 void vfd_init(void) {
+    vfd_data(0x11); // normal mode
     vfd_data(0x0c); // clear
     vfd_data(0x1b); // esc
     vfd_data(0);    // v pos
@@ -138,4 +167,69 @@
     /* unblank */
 }
 
+void vfd_pos(int h, int v) {
+    if (v > 3 || v < 0)
+        return;
+    if (h > 19 || h < 0)
+        return;
+    vfd_data(0x1b);
+    vfd_data(v);
+    vfd_data(h);
+}
 
+void vfd_reset(void) {
+    int i, data, mode;
+
+    data = 0; mode = 1;
+
+    printf("reset sent, busy: %d\r\n", vfd_p_busy.read());
+
+    /* everything low, includeing reset */
+    for (i = 0 ; i < 16; i++) {
+        vfd_p_data = 0;
+        vfd_shift_clock();
+    }
+    vfd_p_latch = 0;
+    wait_us(10);
+    vfd_p_latch = 1;
+
+    vfd_doit(data, mode, 0, 0, 1);
+    wait_us(1);
+    vfd_doit(data, mode, 1, 0, 1);
+    wait_us(1);
+    vfd_doit(data, mode, 1, 1, 1);
+    wait_us(1);
+
+    if (vfd_p_busy)
+        printf("post1, busy: %d\r\n", vfd_p_busy.read());
+
+    vfd_doit(data, mode, 0, 0, 1);
+    wait_ms(1); // loop and wait for not busy
+
+    printf("reset sent, busy: %d\r\n", vfd_p_busy.read());
+    wait_ms(10);
+    if (vfd_p_busy) {
+        printf("still busy, not calling vfd_init()\r\n");
+        vfd_reset_cmd();
+        printf("post reset_cmd\r\n");
+        vfd_dead = 1;
+        wait_ms(10);
+    } else {
+        if (!vfd_dead)
+            vfd_init();
+    }
+}
+
+void vfd_reset_cmd(void) {
+    vfd_command(0xff, 1);
+}
+
+/*
+class Vfd : Public Stream {
+    public:
+    
+        
+}
+*/
+
+