Dependencies:   TextLCD mbed-rtos mbed

main.cpp

Committer:
jfields
Date:
2014-10-07
Revision:
0:486f8caec6c8

File content as of revision 0:486f8caec6c8:

#include "mbed.h"
#include "rtos.h"
#include "TextLCD.h"

#define RUN 0x1 

TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2);
Serial pc (USBTX, USBRX);
DigitalOut myled(LED1);

// mutexes
Mutex mm_mutex;         // protects mm[]
Mutex ss_mutex;         // protects ss[]
Mutex MM_mutex;         // protects MM[]
Mutex input_mutex;      // protects input

// global vars
int mm [] = {0, 0};         // protected by mm_mutex
int ss [] = {0, 0};         // protected by ss_mutex
int MM [] = {0, 0};         // protected by MM_mutex
int mm_wait = 10;           // doesn't need mutex
int ss_wait = 1000;         // doesn't need mutex
int MM_wait = 60000;        // doesn't need mutex
int run_status = 0;         // doesn't need mutex
char input = 'z';           // protected by input_mutex
int need_reset_ss = 0;
int need_reset_MM = 0;

// functions
void update_display(void const *args);
void update_mm(void const *args);
void update_ss(void const *args);
void update_MM(void const *args);
void process_commands(void const *args);
void ss_reset_func(void const *args);
void MM_reset_func(void const *args);
void disp0();

// init timer threads
RtosTimer disp_thread(update_display, osTimerPeriodic);
RtosTimer mm_thread(update_mm, osTimerPeriodic);
RtosTimer ss_thread(update_ss, osTimerPeriodic);
RtosTimer MM_thread(update_MM, osTimerPeriodic);

// init threads
Thread ss_reset_thread(ss_reset_func);
Thread MM_reset_thread(MM_reset_func);
Thread cmds(process_commands);              // listen for keyboard inputs

int main() {
    
    // set initial time to 00:00:00
    disp0();    
    
    while (1) {
        
        input_mutex.lock(); // lock input mutex
        
        // start
        if (input == 's' && !run_status) {
            run_status = 1;
            disp_thread.start(10);
            mm_thread.start(mm_wait);
            ss_thread.start(ss_wait);
            MM_thread.start(MM_wait);
        }
        
        // pause
        if (input == 'p' && run_status) {
            run_status = 0;
            disp_thread.stop();
            mm_thread.stop();
            ss_thread.stop();
            MM_thread.stop();
            ss_wait = ss_wait - 100*mm[1] - 10*mm[0];
            MM_wait = MM_wait - 10000*ss[1] - 1000*ss[0] - 100*mm[1] - 10*mm[0];
            need_reset_ss = 1;
            need_reset_MM = 1;
        }
        
        // reset
        if (input == 'r' && !run_status) {
            for (int i=0;i<2;i++) {
                mm[i] = 0;
                ss[i] = 0;
                MM[i] = 0;
            }
            disp0();
            ss_wait = 1000;
            MM_wait = 60000;
            need_reset_ss = 0;
            need_reset_MM = 0;
        }
        input_mutex.unlock(); // unlock input mutex
        cmds.signal_set(RUN);
    }
}

void disp0() {
    lcd.printf("%d%d:%d%d:%d%d\n\n", MM[1], MM[0],ss[1],ss[0],mm[1],mm[0]);
}

void process_commands(void const *args) {
    while (1) {
        input_mutex.lock();
        input = pc.getc();
        input_mutex.unlock();
        Thread::signal_wait(RUN,osWaitForever);
    }
}

void update_display(void const *args) {
    
    mm_mutex.lock();
    ss_mutex.lock();
    MM_mutex.lock();
    
    lcd.printf("%d%d:%d%d:%d%d\n\n", MM[1], MM[0],ss[1],ss[0],mm[1],mm[0]);
    
    MM_mutex.unlock();
    ss_mutex.unlock();
    mm_mutex.unlock();

}

void update_mm(void const *args) {
    
    mm_mutex.lock();
    mm[0]++;
    if (mm[0] > 9) {
        mm[0] = 0;
        mm[1]++;
    }
    if (mm[1] > 9) {
        mm[0] = 0;
        mm[1] = 0;
    }
    mm_mutex.unlock();
    
}

void update_ss(void const *args) {
    
    ss_mutex.lock();
    ss[0]++;
    if (ss[0] > 9) {
        ss[0] = 0;
        ss[1]++;
    }
    if (ss[1] > 5) {
        ss[0] = 0;
        ss[1] = 0;
    }
    ss_mutex.unlock();
    if (need_reset_ss) ss_reset_thread.signal_set(RUN);
}

void update_MM(void const *args) {

    MM_mutex.lock();
    MM[0]++;
    if (MM[0] > 9) {
        MM[0] = 0;
        MM[1]++;
    }
    if (MM[1] > 5) {
        MM[0] = 0;
        MM[1] = 0;
    }
    MM_mutex.unlock();
    if (need_reset_MM) MM_reset_thread.signal_set(RUN);
}

void ss_reset_func(void const *args) {
    Thread::signal_wait(RUN,osWaitForever);
    ss_thread.stop();
    need_reset_ss = 0;
    ss_wait = 10000;
    ss_thread.start(ss_wait);
}    

void MM_reset_func(void const *args) {
    Thread::signal_wait(RUN,osWaitForever);
    MM_thread.stop();
    need_reset_MM = 0;
    MM_wait = 60000;
    MM_thread.start(MM_wait);
}