Dependencies:   4DGL mbed

main.cpp

Committer:
kagelump
Date:
2011-04-22
Revision:
0:dbe4ead20087

File content as of revision 0:dbe4ead20087:

#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;
    }
}