The London Hackspace Bandwidth meter, now works over ethernet.
Dependencies: EthernetInterface LPD8806 Tiny-HTTPD mbed-rtos mbed BonjourLib
Diff: vfd.cpp
- Revision:
- 0:0e7057b49904
diff -r 000000000000 -r 0e7057b49904 vfd.cpp --- /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: + + +} +*/ + +