The London Hackspace bandwidth meter
Dependencies: LPD8806 MODSERIAL mbed picojson
See:
- https://github.com/londonhackspace/net-o-meter
- http://wiki.london.hackspace.org.uk/view/Projects/BandwidthMeter
vfd.cpp
- Committer:
- Jasper
- Date:
- 2012-10-21
- Revision:
- 5:24172484b8c5
- Parent:
- 4:7087ea3d13c1
File content as of revision 5:24172484b8c5:
/* * 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(100); vfd_p_clock = 1; wait_us(100); } 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); wait_ms(4); // loop and wait for not busy if (vfd_p_busy) printf("post2, busy: %d\r\n", vfd_p_busy.read()); 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(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: } */