uses Rtostimer separate threads check for reset

Dependencies:   TextLCD mbed-rtos mbed

Revision:
0:486f8caec6c8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Oct 07 21:15:30 2014 +0000
@@ -0,0 +1,188 @@
+#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);
+}