Microduino

Dependencies:   mbed

Fork of Io_moon by Li Weiyi

Revision:
0:740c1eb2df13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Blynk_v0_3_7/SimpleTimer/SimpleTimer.cpp	Thu Jun 23 11:16:14 2016 +0000
@@ -0,0 +1,245 @@
+/*
+ * SimpleTimer.cpp
+ *
+ * SimpleTimer - A timer library for Arduino.
+ * Author: mromani@ottotecnica.com
+ * Copyright (c) 2010 OTTOTECNICA Italy
+ *
+ * This library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser
+ * General Public License as published by the Free Software
+ * Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser
+ * General Public License along with this library; if not,
+ * write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include "SimpleTimer.h"
+
+Timer g_SimpleTimer;
+// Select time function:
+//static inline unsigned long elapsed() { return micros(); }
+//static inline uint32_t elapsed() { return g_SimpleTimer.read_ms(); }
+
+
+SimpleTimer::SimpleTimer() {
+    g_SimpleTimer.start();
+    uint32_t current_millis = g_SimpleTimer.read_ms();
+
+    for (int i = 0; i < MAX_TIMERS; i++) {
+        enabled[i] = false;
+        callbacks[i] = 0;                   // if the callback pointer is zero, the slot is free, i.e. doesn't "contain" any timer
+        prev_millis[i] = current_millis;
+        numRuns[i] = 0;
+    }
+
+    numTimers = 0;
+}
+
+
+void SimpleTimer::run() {
+    int i;
+    uint32_t current_millis;
+
+    // get current time
+    current_millis = g_SimpleTimer.read_ms();
+
+    for (i = 0; i < MAX_TIMERS; i++) {
+
+        toBeCalled[i] = DEFCALL_DONTRUN;
+
+        // no callback == no timer, i.e. jump over empty slots
+        if (callbacks[i]) {
+            current_millis = g_SimpleTimer.read_ms(); //LiXianyu added.
+            // is it time to process this timer ?
+            // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
+
+            if (current_millis - prev_millis[i] >= delays[i]) {
+
+                // update time
+                //prev_millis[i] = current_millis;
+                //prev_millis[i] += delays[i];
+                prev_millis[i] = g_SimpleTimer.read_ms(); // LiXianyu added.
+
+                // check if the timer callback has to be executed
+                if (enabled[i]) {
+
+                    // "run forever" timers must always be executed
+                    if (maxNumRuns[i] == RUN_FOREVER) {
+                        toBeCalled[i] = DEFCALL_RUNONLY;
+                        //(*callbacks[i])();
+                    }
+                    // other timers get executed the specified number of times
+                    else if (numRuns[i] < maxNumRuns[i]) {
+                        toBeCalled[i] = DEFCALL_RUNONLY;
+                        numRuns[i]++;
+
+                        // after the last run, delete the timer
+                        if (numRuns[i] >= maxNumRuns[i]) {
+                            toBeCalled[i] = DEFCALL_RUNANDDEL;
+                            //(*callbacks[i])();
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    for (i = 0; i < MAX_TIMERS; i++) {
+        switch(toBeCalled[i]) {
+            case DEFCALL_DONTRUN:
+                break;
+
+            case DEFCALL_RUNONLY:
+                (*callbacks[i])();
+                break;
+
+            case DEFCALL_RUNANDDEL:
+                (*callbacks[i])();
+                deleteTimer(i);
+                break;
+        }
+        //prev_millis[i] = g_SimpleTimer.read_ms(); // LiXianyu added.
+    }
+}
+
+
+// find the first available slot
+// return -1 if none found
+int SimpleTimer::findFirstFreeSlot() {
+    int i;
+
+    // all slots are used
+    if (numTimers >= MAX_TIMERS) {
+        return -1;
+    }
+
+    // return the first slot with no callback (i.e. free)
+    for (i = 0; i < MAX_TIMERS; i++) {
+        if (callbacks[i] == 0) {
+            return i;
+        }
+    }
+
+    // no free slots found
+    return -1;
+}
+
+
+int SimpleTimer::setTimer(uint32_t d, timer_callback f, int n) {
+    int freeTimer;
+
+    freeTimer = findFirstFreeSlot();
+    if (freeTimer < 0) {
+        return -1;
+    }
+
+    if (f == NULL) {
+        return -1;
+    }
+
+    delays[freeTimer] = d;
+    callbacks[freeTimer] = f;
+    maxNumRuns[freeTimer] = n;
+    enabled[freeTimer] = true;
+    prev_millis[freeTimer] = g_SimpleTimer.read_ms();
+
+    numTimers++;
+
+    return freeTimer;
+}
+
+
+int SimpleTimer::setInterval(uint32_t d, timer_callback f) {
+    return setTimer(d, f, RUN_FOREVER);
+}
+
+
+int SimpleTimer::setTimeout(uint32_t d, timer_callback f) {
+    return setTimer(d, f, RUN_ONCE);
+}
+
+
+void SimpleTimer::deleteTimer(int timerId) {
+    if (timerId >= MAX_TIMERS) {
+        return;
+    }
+
+    // nothing to delete if no timers are in use
+    if (numTimers == 0) {
+        return;
+    }
+
+    // don't decrease the number of timers if the
+    // specified slot is already empty
+    if (callbacks[timerId] != NULL) {
+        callbacks[timerId] = 0;
+        enabled[timerId] = false;
+        toBeCalled[timerId] = DEFCALL_DONTRUN;
+        delays[timerId] = 0;
+        numRuns[timerId] = 0;
+
+        // update number of timers
+        numTimers--;
+    }
+}
+
+// function contributed by code@rowansimms.com
+void SimpleTimer::restartTimer(int numTimer) {
+    if (numTimer >= MAX_TIMERS) {
+        return;
+    }
+
+    prev_millis[numTimer] = g_SimpleTimer.read_ms();
+}
+
+
+bool SimpleTimer::isEnabled(int numTimer) {
+    if (numTimer >= MAX_TIMERS) {
+        return false;
+    }
+
+    return enabled[numTimer];
+}
+
+
+void SimpleTimer::enable(int numTimer) {
+    if (numTimer >= MAX_TIMERS) {
+        return;
+    }
+
+    enabled[numTimer] = true;
+}
+
+
+void SimpleTimer::disable(int numTimer) {
+    if (numTimer >= MAX_TIMERS) {
+        return;
+    }
+
+    enabled[numTimer] = false;
+}
+
+
+void SimpleTimer::toggle(int numTimer) {
+    if (numTimer >= MAX_TIMERS) {
+        return;
+    }
+
+    enabled[numTimer] = !enabled[numTimer];
+}
+
+
+int SimpleTimer::getNumTimers() {
+    return numTimers;
+}