The London Hackspace Bandwidth meter, now works over ethernet.

Dependencies:   EthernetInterface LPD8806 Tiny-HTTPD mbed-rtos mbed BonjourLib

Revision:
0:0e7057b49904
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vfd.cpp	Fri May 30 03:56:10 2014 +0000
@@ -0,0 +1,261 @@
+/*
+ * The VFD code
+ *
+ * for a futuba M204LD01AA
+ * 
+ *
+ * p27 -> input, busy
+ * p28 -> serial data in
+ * p29 -> clock 
+ * p30 -> latch
+ *
+ *
+ */
+
+#include "mbed.h"
+#include "vfd.h"
+//#include "Stream.h"
+//#include "FunctionPointer.h"
+
+// InturruptIn busy_intr(p27)
+
+DigitalIn  vfd_p_busy(p27);
+DigitalOut vfd_p_data(p28);
+DigitalOut vfd_p_clock(p29);
+DigitalOut vfd_p_latch(p30);
+
+/* current state */
+int  c_data;
+bool c_a0;
+bool c_blank;
+
+bool vfd_dead = 0;
+
+void vfd_shift_clock(void) {
+        vfd_p_clock = 0;
+        wait_us(10);
+        vfd_p_clock = 1;
+        wait_us(10);
+}
+
+void vfd_doit(int data, int mode, int wr, int ss, int reset) {
+    int i, bit;
+    
+    vfd_p_data = 0; // nc
+    vfd_shift_clock();
+    vfd_p_data = 0; // nc
+    vfd_shift_clock();
+
+    vfd_p_data = reset; // reset, 0 = in reset
+    vfd_shift_clock();
+
+    vfd_p_data = c_blank; // Blank, 0 = blanked
+    vfd_shift_clock();
+    
+    vfd_p_data = ss; // SS, clockish
+    vfd_shift_clock();
+
+    vfd_p_data = 1; // rd
+    vfd_shift_clock();
+
+    vfd_p_data = mode; // A0, data/command
+    vfd_shift_clock();
+
+    vfd_p_data = wr; // WR
+    vfd_shift_clock();
+
+    for (i = 0 ; i < 8; i++) {
+        bit = (data & (1 << i)) >> i;
+        vfd_p_data = bit;
+        vfd_shift_clock();
+    }
+        
+    vfd_p_latch = 0;
+    wait_us(10);
+    vfd_p_latch = 1;
+    wait_us(10);
+}
+
+/* mode == 1 if command */
+void vfd_send(int data, int mode, int force)
+{
+    data = data & 0xff;
+    c_data = data;
+    c_blank = 1;
+
+//    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)
+    {
+        wait_ms(4); // should loop, 3.1 ms is max according to the data sheet.
+        if (vfd_p_busy)
+        {
+            printf("still busy :(\r\n");
+            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, 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);
+
+    if (vfd_p_busy)
+        printf("post2, busy: %d\r\n", vfd_p_busy.read());
+
+    // loop and wait for not busy
+    while (vfd_p_busy) {
+        wait_us(250);
+        printf("post-while, busy: %d\r\n", vfd_p_busy.read());
+    }
+}
+
+void vfd_command(int data, int force) {
+    vfd_send(data, 1, force);
+}
+
+void vfd_data(int data) {
+    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
+    vfd_data(0);    // h pos
+}
+
+void vfd_blank(void) {
+    /* blank */
+}
+
+void vfd_show(void) {
+    /* 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(4); // 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");
+        if (vfd_p_busy) {
+            printf("Also still busy, marking as dead\r\n");
+            vfd_dead = 1;
+        } else {
+            vfd_init();    
+        }
+        wait_ms(10);
+    } else {
+        if (!vfd_dead)
+            vfd_init();
+    }
+}
+
+void vfd_reset_cmd(void) {
+    vfd_command(0xff, 1);
+}
+
+void send_text(const char *s) {
+    int i; char c;
+
+    for (i = 0, c=s[i]; c != 0;  i++, c=s[i])
+        vfd_data(c);
+}
+
+void text_centered(const char *s, int hpos) {
+
+    vfd_pos((20 / 2) - (strlen(s)) / 2, hpos);
+    send_text(s);
+}
+
+void logo(void) {
+    const char line0[] = "Welcome to";
+    const char line2[] = "London Hackspace";
+
+    text_centered(line0, 0);
+    text_centered(line2, 2);        
+}
+
+/*
+class Vfd : Public Stream {
+    public:
+    
+        
+}
+*/
+
+