Dependencies:   4DGL mbed

Revision:
0:dbe4ead20087
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Apr 22 00:44:46 2011 +0000
@@ -0,0 +1,273 @@
+#include "mbed.h"
+#include "TFT_4DGL.h"
+
+TFT_4DGL ecran(p13,p14,p15); // serial tx, serial rx, reset pin;
+CAN can(p30, p29);
+DigitalOut led(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+DigitalIn switch_left(p16);
+DigitalIn switch_right(p17);
+Ticker tiktok;
+Ticker can_tok;
+Timer timer;
+int last_seen[10];
+int last_state[2];
+enum boards {
+    CUTOFF,
+    TELEMETRY,
+    MAIN_OUTPUT,
+    MAIN_INPUT,
+    BPS,
+    DATA_LOGGER,
+    TRITIUM
+};
+enum modes {
+    HEARTBEAT,
+    DEMO,
+    FULL_CAN
+};
+char mode = DEMO;
+int speed = 0;
+int percent = 0;
+char s[40][50];
+char needs_update[40];
+int current = 0;
+int j = 0;
+
+void display_can();
+
+int next() {
+    int old = current;
+    current = (current + 1) % 40;
+    return old;
+}
+void demo_update() {
+    char buffer[20];
+    
+    // Speed
+    sprintf(buffer, "%02d", speed);
+    speed = (speed + 1) % 100;
+    ecran.text_mode(1);
+    ecran.graphic_string(buffer, 80, 0, FONT_8X8, WHITE, 5, 5);
+    ecran.graphic_string("Kph", 160, 0, FONT_8X8, WHITE, 2, 2);
+    
+    // Mode
+    if (speed < 25)
+        ecran.graphic_string("P", 0, 0, FONT_8X8, 0xFF0000, 5, 5);
+    else if (speed < 50)
+        ecran.graphic_string("N", 0, 0, FONT_8X8, 0x0000FF, 5, 5);
+    else if (speed < 75)
+        ecran.graphic_string("D", 0, 0, FONT_8X8, 0x00FF00, 5, 5);
+    else
+        ecran.graphic_string("R", 0, 0, FONT_8X8, 0xFF00FF, 5, 5);
+    
+    // Battery
+    percent = (percent + 2) % 100;
+    ecran.pen_size(0);
+    ecran.rectangle(11, 61, (int)(percent * 2.2)+11, 79, 0xFF0000);
+    ecran.rectangle((int)(percent * 2.2)+11, 61, 229, 79, 0x000000);
+    ecran.graphic_string("Battery:", 10, 90, FONT_8X8, WHITE, 2, 2) ;
+    sprintf(buffer, "%02d%%", percent);
+    ecran.graphic_string(buffer, 140, 90, FONT_8X8, WHITE, 2, 2) ;
+    
+    // Logo
+    ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
+    
+    // LED
+    led = !led;
+}
+
+void update() {
+    
+    // Packets
+    ecran.text_mode(1);
+    for(int i = 0; i < 40; i++) {
+        if (needs_update[i]) {
+            needs_update[i] = 0;
+            ecran.text_string(s[i], 0, i, FONT_8X8, WHITE);
+        }
+    }
+    // LED
+    led = !led;
+}
+void heartbeat_update() {
+    ecran.text_mode(1);
+    int t = timer.read_ms();
+    char buffer[255];
+    // Title
+    sprintf(buffer, "Board:      Last Seen (ms)");
+    ecran.text_string(buffer, 0, 0, FONT_8X8, WHITE);
+    // Cutoff
+    sprintf(buffer, "Cutoff:     %d", t - last_seen[CUTOFF]);
+    if (t - last_seen[CUTOFF] > 1000)
+        ecran.text_string(buffer, 0, 2, FONT_8X8, RED);
+    else
+        ecran.text_string(buffer, 0, 2, FONT_8X8, GREEN);
+    // Telemetry
+    sprintf(buffer, "Telemetry   %d", t - last_seen[TELEMETRY]);
+    if (t - last_seen[TELEMETRY] > 1000)
+        ecran.text_string(buffer, 0, 4, FONT_8X8, RED);
+    else
+        ecran.text_string(buffer, 0, 4, FONT_8X8, GREEN);
+    // Main Output
+    sprintf(buffer, "MainOutput  %d", t - last_seen[MAIN_OUTPUT]);
+    if (t - last_seen[MAIN_OUTPUT] > 1000)
+        ecran.text_string(buffer, 0, 6, FONT_8X8, RED);
+    else
+        ecran.text_string(buffer, 0, 6, FONT_8X8, GREEN);
+    // Main Input
+    sprintf(buffer, "MainInput   %d", t - last_seen[MAIN_INPUT]);
+    if (t - last_seen[MAIN_INPUT] > 1000)
+        ecran.text_string(buffer, 0, 8, FONT_8X8, RED);
+    else
+        ecran.text_string(buffer, 0, 8, FONT_8X8, GREEN);
+    // BPS
+    sprintf(buffer, "BPS:        %d", t - last_seen[BPS]);
+    if (t - last_seen[BPS] > 1000)
+        ecran.text_string(buffer, 0, 10, FONT_8X8, RED);
+    else
+        ecran.text_string(buffer, 0, 10, FONT_8X8, GREEN);
+    // Data Logger
+    sprintf(buffer, "DataLogger: %d", t - last_seen[DATA_LOGGER]);
+    if (t - last_seen[DATA_LOGGER] > 1000)
+        ecran.text_string(buffer, 0, 12, FONT_8X8, RED);
+    else
+        ecran.text_string(buffer, 0, 12, FONT_8X8, GREEN);
+    // Tritium
+    sprintf(buffer, "Tritium     %d", t - last_seen[TRITIUM]);
+    if (t - last_seen[TRITIUM] > 1000)
+        ecran.text_string(buffer, 0, 14, FONT_8X8, RED);
+    else
+        ecran.text_string(buffer, 0, 14, FONT_8X8, GREEN);             
+    // LED
+    led = !led;
+}
+
+void display_heartbeats();
+void set_demo() {
+    ecran.cls();
+    ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
+    // Top bar
+    ecran.pen_size(SOLID);
+    ecran.rectangle(0, 40, 240, 42, 0xEEEEEE);
+    
+    // Battery bar
+    ecran.pen_size(1);
+    ecran.rectangle(10, 60, 230, 80, 0xFF0000);
+    tiktok.detach();
+    tiktok.attach(&demo_update, 0.5);
+    mode = DEMO;
+}
+void set_full() {
+    tiktok.detach();
+    tiktok.attach(&update, 0.5);
+    mode = FULL_CAN;
+    ecran.cls();
+    ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
+}
+void set_heartbeat() {
+    tiktok.detach();
+    tiktok.attach(&heartbeat_update, 0.5);
+    mode = HEARTBEAT;
+    ecran.cls();
+    ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
+}
+
+int main() {
+    can.frequency(1000000);
+    switch_left.mode(PullUp);
+    switch_right.mode(PullUp);
+    for (int i = 0; i < 40; i++) {
+        needs_update[i] = 0;
+        s[i][0] = '\0';
+    }
+    ecran.baudrate(115200);
+    timer.start();
+    
+    // Logo
+    ecran.graphic_string("CalSol GFX 2011", 110, 310, FONT_8X8, WHITE, 1, 1);
+    sprintf(s[next()], "Initializing...");
+    
+    tiktok.attach(&update, 0.5);
+    CANMessage msg;    
+    while(1) {
+        int left = switch_left;
+        int right = switch_right;
+        led4 = left;
+        led3 = right;
+        if (last_state[0] != left) {
+            if (left)
+                set_demo();
+            else
+                set_heartbeat();
+            last_state[0] = left;
+        }
+        if (last_state[1] != right) {
+            if (right) 
+                set_demo();
+            else
+                set_full();
+            last_state[1] = right;
+        }
+        if (mode == FULL_CAN)
+            display_can();
+        else if (mode == HEARTBEAT)
+            display_heartbeats();
+    }
+}
+
+void display_heartbeats() {
+    CANMessage msg;
+    int t = timer.read_ms();
+    if (can.read(msg)) {
+        switch(msg.id) {
+            case 0x41:
+                last_seen[BPS] = t;
+                break;
+            case 0x42:
+                last_seen[CUTOFF] = t;
+                break;
+            case 0x43:
+                last_seen[MAIN_OUTPUT] = t;
+                break;
+            case 0x44:
+                last_seen[MAIN_INPUT] = t;
+                break;
+            case 0x45:
+                last_seen[TELEMETRY] = t;
+                break;
+            case 0x46:
+                last_seen[DATA_LOGGER] = t;
+                break;
+            case 0x400:
+                last_seen[TRITIUM] = t;
+                break;
+        }
+        led2 = !led2;
+    }
+}
+
+void display_can() {
+    CANMessage msg;
+    if (can.read(msg)) {
+        int current_index = next();
+        char *current_line = s[current_index];
+        needs_update[current_index] = 1;
+        if (((msg.id & 0x7FF) >= 0x100) && ((msg.id & 0x7FF) <= 0x12F)) {
+            int pack_num = (msg.id & 0x30) >> 4;
+            if ((msg.id & 0xF) <= 0xB) {
+                sprintf(current_line, "Volt %d/%d: %f", pack_num, (msg.id & 0xF), *((float*)msg.data));
+            } else {
+                sprintf(current_line, "Temp %d/%d: %f", pack_num, (msg.id & 0xF) - 0xB, *((float*)msg.data));
+            }
+        } else {
+            sprintf(current_line, "%X(%d):", msg.id & 0x7FF, msg.len);
+            for (int i = 0; i < msg.len; i++) {
+                sprintf(current_line + strlen(current_line), "%2X ", msg.data[i]);
+            }
+        }
+        led2 = !led2;
+    }
+}
\ No newline at end of file