uses to rtos to send run signals to update threads. there are 5 rtos timers - 2 single shots and 3 periodic.

Dependencies:   TextLCD mbed-rtos mbed

main.cpp

Committer:
xueliz
Date:
2014-10-08
Revision:
1:2b24d90fedc2
Parent:
0:6cf7cd633acf

File content as of revision 1:2b24d90fedc2:

#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
int first_run_ss = 1, first_run_MM = 1;
char input = 'z';           // protected by input_mutex

// functions
void manage_signals(void const *i);
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);

// create RtosTimer manager 
RtosTimer * disp_signal;
RtosTimer * mm_signal;
RtosTimer * ss_init;
RtosTimer * MM_init; 
RtosTimer * ss_signal;
RtosTimer * MM_signal;

// create thread pointers
Thread * mm_thread;
Thread * ss_thread;
Thread * MM_thread;
Thread * disp_thread;

int main() {
    
    // init threads
    mm_thread = new Thread(update_mm);                // update mm[]
    ss_thread = new Thread(update_ss);                // update ss[]
    MM_thread = new Thread(update_MM);                // update MM[]
    disp_thread = new Thread(update_display);         // display LCD

    // rtos manager
    disp_signal = new RtosTimer(manage_signals, osTimerPeriodic, (void *)0);
    mm_signal = new RtosTimer(manage_signals, osTimerPeriodic, (void *)1);
    ss_init = new RtosTimer(manage_signals, osTimerOnce, (void *)2);
    MM_init = new RtosTimer(manage_signals, osTimerOnce, (void *)3);
    ss_signal = new RtosTimer(manage_signals, osTimerPeriodic, (void *)12);
    MM_signal = new RtosTimer(manage_signals, osTimerPeriodic, (void *)13);
    
    // set initial time to 00:00:00
    disp_thread->signal_set(RUN);

    // listen for commands
    Thread cmds(process_commands);                    
        
    while (1) {

        input_mutex.lock(); // lock input mutex
        
        // start
        if (input == 's' && !run_status) {            
            disp_signal->start(10);
            mm_signal->start(mm_wait);
            ss_init->start(ss_wait);
            MM_init->start(MM_wait);
            first_run_ss = 1;
            first_run_MM = 1;
            run_status = 1;
        }
        
        // pause
        if (input == 'p' && run_status) {
            run_status = 0;
            ss_wait = 1000 - 100*mm[1] - 10*mm[0];
            MM_wait = 60000 - 10000*ss[1] - 1000*ss[0] - 100*mm[1] - 10*mm[0];
            disp_signal->stop();
            mm_signal->stop();
            ss_init->stop();
            MM_init->stop();
            ss_signal->stop();
            MM_signal->stop();
        }
        
        // reset
        if (input == 'r' && !run_status) {
            for (int i=0;i<2;i++) {
                mm[i] = 0;
                ss[i] = 0;
                MM[i] = 0;
            }
            disp_thread->signal_set(RUN);
            ss_wait = 1000;
            MM_wait = 60000;
        }
        input_mutex.unlock(); // unlock input mutex
        cmds.signal_set(RUN);
    }
}

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) {
    while (1) {
        Thread::signal_wait(RUN,osWaitForever);    
        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) {
    while (1) {
        Thread::signal_wait(RUN,osWaitForever);    
        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) {
    while (1) {
        Thread::signal_wait(RUN,osWaitForever);
        if (first_run_ss) {
            ss_wait = 1000;
            ss_signal->start(ss_wait);
            first_run_ss = 0;
        }
        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();
    }
}

void update_MM(void const *args) {
    while (1) {
        Thread::signal_wait(RUN,osWaitForever);
        if (first_run_MM) {
            MM_wait = 60000;
            MM_signal->start(MM_wait);
            first_run_MM = 0;
        }
        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();
    }
}

void manage_signals(void const *i) {
    if (!(int)i) disp_thread->signal_set(RUN);
    if ((int)i==1) mm_thread->signal_set(RUN);
    if ((int)i%10==2) ss_thread->signal_set(RUN);
    if ((int)i%10==3) MM_thread->signal_set(RUN);
}