The London Hackspace bandwidth meter

Dependencies:   LPD8806 MODSERIAL mbed picojson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vfd.cpp Source File

vfd.cpp

00001 /*
00002  * The VFD code
00003  *
00004  * for a futuba M204LD01AA
00005  * 
00006  *
00007  * p27 -> input, busy
00008  * p28 -> serial data in
00009  * p29 -> clock 
00010  * p30 -> latch
00011  *
00012  *
00013  */
00014 
00015 #include "mbed.h"
00016 #include "vfd.h"
00017 #include "Stream.h"
00018 #include "FunctionPointer.h"
00019 
00020 // InturruptIn busy_intr(p27)
00021 
00022 DigitalIn  vfd_p_busy(p27);
00023 DigitalOut vfd_p_data(p28);
00024 DigitalOut vfd_p_clock(p29);
00025 DigitalOut vfd_p_latch(p30);
00026 
00027 /* current state */
00028 int  c_data;
00029 bool c_a0;
00030 bool c_blank;
00031 
00032 bool vfd_dead = 0;
00033 
00034 void vfd_shift_clock(void) {
00035         vfd_p_clock = 0;
00036         wait_us(100);
00037         vfd_p_clock = 1;
00038         wait_us(100);
00039 }
00040 
00041 void vfd_doit(int data, int mode, int wr, int ss, int reset) {
00042     int i, bit;
00043     
00044     vfd_p_data = 0; // nc
00045     vfd_shift_clock();
00046     vfd_p_data = 0; // nc
00047     vfd_shift_clock();
00048 
00049     vfd_p_data = reset; // reset, 0 = in reset
00050     vfd_shift_clock();
00051 
00052     vfd_p_data = c_blank; // Blank, 0 = blanked
00053     vfd_shift_clock();
00054     
00055     vfd_p_data = ss; // SS, clockish
00056     vfd_shift_clock();
00057 
00058     vfd_p_data = 1; // rd
00059     vfd_shift_clock();
00060 
00061     vfd_p_data = mode; // A0, data/command
00062     vfd_shift_clock();
00063 
00064     vfd_p_data = wr; // WR
00065     vfd_shift_clock();
00066 
00067     for (i = 0 ; i < 8; i++) {
00068         bit = (data & (1 << i)) >> i;
00069         vfd_p_data = bit;
00070         vfd_shift_clock();
00071     }
00072         
00073     vfd_p_latch = 0;
00074     wait_us(10);
00075     vfd_p_latch = 1;
00076     wait_us(10);
00077 }
00078 
00079 /* mode == 1 if command */
00080 void vfd_send(int data, int mode, int force)
00081 {
00082     data = data & 0xff;
00083     c_data = data;
00084     c_blank = 1;
00085 
00086 //    if (mode == 0)
00087 //        printf("%02x ", data);
00088 
00089     if (vfd_dead && ! force) {
00090         printf("vfd dead (?), not sending.\r\n");
00091         return;
00092     }
00093     if (force)
00094         printf("forcing vfd for 0x%02x %d\r\n", data, mode);
00095 
00096     if (vfd_p_busy) {
00097         printf("pre, busy: %d\r\n", vfd_p_busy.read());
00098     }
00099     
00100     if (vfd_p_busy)
00101     {
00102         wait_ms(4); // should loop, 3.1 ms is max according to the data sheet.
00103         if (vfd_p_busy)
00104         {
00105             printf("still busy :(\r\n");
00106             printf("resetting\r\n");
00107             if (!force)
00108                 vfd_reset();
00109             if (vfd_p_busy) {
00110                 printf("still busy after reset!\r\n");
00111                 if (!force)
00112                     return;
00113             }
00114             if (!force)
00115                 return;
00116         }
00117     }
00118     
00119     /* wr,ss */
00120     vfd_doit(data, mode, 0, 0, 1);
00121     wait_us(1);
00122     vfd_doit(data, mode, 1, 0, 1);
00123     wait_us(1);
00124     vfd_doit(data, mode, 1, 1, 1);
00125     wait_us(1);
00126 
00127     if (vfd_p_busy)
00128         printf("post1, busy: %d\r\n", vfd_p_busy.read());
00129 
00130     vfd_doit(data, mode, 0, 0, 1);
00131     wait_ms(4); // loop and wait for not busy
00132 
00133     if (vfd_p_busy)
00134         printf("post2, busy: %d\r\n", vfd_p_busy.read());
00135 
00136     while (vfd_p_busy) {
00137         wait_us(250);
00138         printf("post-while, busy: %d\r\n", vfd_p_busy.read());
00139     }
00140 }
00141 
00142 void vfd_command(int data, int force) {
00143     vfd_send(data, 1, force);
00144 }
00145 
00146 void vfd_data(int data) {
00147     if ((data & 0xff) == 0x7f) {
00148         data = 0x20;
00149         printf("changed data to %02x\r\n", data);
00150     }
00151     vfd_send(data, 0, 0);
00152 }
00153 
00154 void vfd_init(void) {
00155     vfd_data(0x11); // normal mode
00156     vfd_data(0x0c); // clear
00157     vfd_data(0x1b); // esc
00158     vfd_data(0);    // v pos
00159     vfd_data(0);    // h pos
00160 }
00161 
00162 void vfd_blank(void) {
00163     /* blank */
00164 }
00165 
00166 void vfd_show(void) {
00167     /* unblank */
00168 }
00169 
00170 void vfd_pos(int h, int v) {
00171     if (v > 3 || v < 0)
00172         return;
00173     if (h > 19 || h < 0)
00174         return;
00175     vfd_data(0x1b);
00176     vfd_data(v);
00177     vfd_data(h);
00178 }
00179 
00180 void vfd_reset(void) {
00181     int i, data, mode;
00182 
00183     data = 0; mode = 1;
00184 
00185     printf("reset sent, busy: %d\r\n", vfd_p_busy.read());
00186 
00187     /* everything low, includeing reset */
00188     for (i = 0 ; i < 16; i++) {
00189         vfd_p_data = 0;
00190         vfd_shift_clock();
00191     }
00192     vfd_p_latch = 0;
00193     wait_us(10);
00194     vfd_p_latch = 1;
00195 
00196     vfd_doit(data, mode, 0, 0, 1);
00197     wait_us(1);
00198     vfd_doit(data, mode, 1, 0, 1);
00199     wait_us(1);
00200     vfd_doit(data, mode, 1, 1, 1);
00201     wait_us(1);
00202 
00203     if (vfd_p_busy)
00204         printf("post1, busy: %d\r\n", vfd_p_busy.read());
00205 
00206     vfd_doit(data, mode, 0, 0, 1);
00207     wait_ms(1); // loop and wait for not busy
00208 
00209     printf("reset sent, busy: %d\r\n", vfd_p_busy.read());
00210     wait_ms(10);
00211     if (vfd_p_busy) {
00212         printf("still busy, not calling vfd_init()\r\n");
00213         vfd_reset_cmd();
00214         printf("post reset_cmd\r\n");
00215         vfd_dead = 1;
00216         wait_ms(10);
00217     } else {
00218         if (!vfd_dead)
00219             vfd_init();
00220     }
00221 }
00222 
00223 void vfd_reset_cmd(void) {
00224     vfd_command(0xff, 1);
00225 }
00226 
00227 /*
00228 class Vfd : Public Stream {
00229     public:
00230     
00231         
00232 }
00233 */
00234 
00235