Microduino

Dependencies:   mbed

Fork of Io_moon by Li Weiyi

Committer:
lixianyu
Date:
Fri Jun 24 02:06:43 2016 +0000
Revision:
1:e34100dd6532
Parent:
0:740c1eb2df13
?Arduino??????????0~255??????LPC824????????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lixianyu 0:740c1eb2df13 1 /*
lixianyu 0:740c1eb2df13 2 * SimpleTimer.cpp
lixianyu 0:740c1eb2df13 3 *
lixianyu 0:740c1eb2df13 4 * SimpleTimer - A timer library for Arduino.
lixianyu 0:740c1eb2df13 5 * Author: mromani@ottotecnica.com
lixianyu 0:740c1eb2df13 6 * Copyright (c) 2010 OTTOTECNICA Italy
lixianyu 0:740c1eb2df13 7 *
lixianyu 0:740c1eb2df13 8 * This library is free software; you can redistribute it
lixianyu 0:740c1eb2df13 9 * and/or modify it under the terms of the GNU Lesser
lixianyu 0:740c1eb2df13 10 * General Public License as published by the Free Software
lixianyu 0:740c1eb2df13 11 * Foundation; either version 2.1 of the License, or (at
lixianyu 0:740c1eb2df13 12 * your option) any later version.
lixianyu 0:740c1eb2df13 13 *
lixianyu 0:740c1eb2df13 14 * This library is distributed in the hope that it will
lixianyu 0:740c1eb2df13 15 * be useful, but WITHOUT ANY WARRANTY; without even the
lixianyu 0:740c1eb2df13 16 * implied warranty of MERCHANTABILITY or FITNESS FOR A
lixianyu 0:740c1eb2df13 17 * PARTICULAR PURPOSE. See the GNU Lesser General Public
lixianyu 0:740c1eb2df13 18 * License for more details.
lixianyu 0:740c1eb2df13 19 *
lixianyu 0:740c1eb2df13 20 * You should have received a copy of the GNU Lesser
lixianyu 0:740c1eb2df13 21 * General Public License along with this library; if not,
lixianyu 0:740c1eb2df13 22 * write to the Free Software Foundation, Inc.,
lixianyu 0:740c1eb2df13 23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
lixianyu 0:740c1eb2df13 24 */
lixianyu 0:740c1eb2df13 25
lixianyu 0:740c1eb2df13 26
lixianyu 0:740c1eb2df13 27 #include "SimpleTimer.h"
lixianyu 0:740c1eb2df13 28
lixianyu 0:740c1eb2df13 29 Timer g_SimpleTimer;
lixianyu 0:740c1eb2df13 30 // Select time function:
lixianyu 0:740c1eb2df13 31 //static inline unsigned long elapsed() { return micros(); }
lixianyu 0:740c1eb2df13 32 //static inline uint32_t elapsed() { return g_SimpleTimer.read_ms(); }
lixianyu 0:740c1eb2df13 33
lixianyu 0:740c1eb2df13 34
lixianyu 0:740c1eb2df13 35 SimpleTimer::SimpleTimer() {
lixianyu 0:740c1eb2df13 36 g_SimpleTimer.start();
lixianyu 0:740c1eb2df13 37 uint32_t current_millis = g_SimpleTimer.read_ms();
lixianyu 0:740c1eb2df13 38
lixianyu 0:740c1eb2df13 39 for (int i = 0; i < MAX_TIMERS; i++) {
lixianyu 0:740c1eb2df13 40 enabled[i] = false;
lixianyu 0:740c1eb2df13 41 callbacks[i] = 0; // if the callback pointer is zero, the slot is free, i.e. doesn't "contain" any timer
lixianyu 0:740c1eb2df13 42 prev_millis[i] = current_millis;
lixianyu 0:740c1eb2df13 43 numRuns[i] = 0;
lixianyu 0:740c1eb2df13 44 }
lixianyu 0:740c1eb2df13 45
lixianyu 0:740c1eb2df13 46 numTimers = 0;
lixianyu 0:740c1eb2df13 47 }
lixianyu 0:740c1eb2df13 48
lixianyu 0:740c1eb2df13 49
lixianyu 0:740c1eb2df13 50 void SimpleTimer::run() {
lixianyu 0:740c1eb2df13 51 int i;
lixianyu 0:740c1eb2df13 52 uint32_t current_millis;
lixianyu 0:740c1eb2df13 53
lixianyu 0:740c1eb2df13 54 // get current time
lixianyu 0:740c1eb2df13 55 current_millis = g_SimpleTimer.read_ms();
lixianyu 0:740c1eb2df13 56
lixianyu 0:740c1eb2df13 57 for (i = 0; i < MAX_TIMERS; i++) {
lixianyu 0:740c1eb2df13 58
lixianyu 0:740c1eb2df13 59 toBeCalled[i] = DEFCALL_DONTRUN;
lixianyu 0:740c1eb2df13 60
lixianyu 0:740c1eb2df13 61 // no callback == no timer, i.e. jump over empty slots
lixianyu 0:740c1eb2df13 62 if (callbacks[i]) {
lixianyu 0:740c1eb2df13 63 current_millis = g_SimpleTimer.read_ms(); //LiXianyu added.
lixianyu 0:740c1eb2df13 64 // is it time to process this timer ?
lixianyu 0:740c1eb2df13 65 // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
lixianyu 0:740c1eb2df13 66
lixianyu 0:740c1eb2df13 67 if (current_millis - prev_millis[i] >= delays[i]) {
lixianyu 0:740c1eb2df13 68
lixianyu 0:740c1eb2df13 69 // update time
lixianyu 0:740c1eb2df13 70 //prev_millis[i] = current_millis;
lixianyu 0:740c1eb2df13 71 //prev_millis[i] += delays[i];
lixianyu 0:740c1eb2df13 72 prev_millis[i] = g_SimpleTimer.read_ms(); // LiXianyu added.
lixianyu 0:740c1eb2df13 73
lixianyu 0:740c1eb2df13 74 // check if the timer callback has to be executed
lixianyu 0:740c1eb2df13 75 if (enabled[i]) {
lixianyu 0:740c1eb2df13 76
lixianyu 0:740c1eb2df13 77 // "run forever" timers must always be executed
lixianyu 0:740c1eb2df13 78 if (maxNumRuns[i] == RUN_FOREVER) {
lixianyu 0:740c1eb2df13 79 toBeCalled[i] = DEFCALL_RUNONLY;
lixianyu 0:740c1eb2df13 80 //(*callbacks[i])();
lixianyu 0:740c1eb2df13 81 }
lixianyu 0:740c1eb2df13 82 // other timers get executed the specified number of times
lixianyu 0:740c1eb2df13 83 else if (numRuns[i] < maxNumRuns[i]) {
lixianyu 0:740c1eb2df13 84 toBeCalled[i] = DEFCALL_RUNONLY;
lixianyu 0:740c1eb2df13 85 numRuns[i]++;
lixianyu 0:740c1eb2df13 86
lixianyu 0:740c1eb2df13 87 // after the last run, delete the timer
lixianyu 0:740c1eb2df13 88 if (numRuns[i] >= maxNumRuns[i]) {
lixianyu 0:740c1eb2df13 89 toBeCalled[i] = DEFCALL_RUNANDDEL;
lixianyu 0:740c1eb2df13 90 //(*callbacks[i])();
lixianyu 0:740c1eb2df13 91 }
lixianyu 0:740c1eb2df13 92 }
lixianyu 0:740c1eb2df13 93 }
lixianyu 0:740c1eb2df13 94 }
lixianyu 0:740c1eb2df13 95 }
lixianyu 0:740c1eb2df13 96 }
lixianyu 0:740c1eb2df13 97
lixianyu 0:740c1eb2df13 98 for (i = 0; i < MAX_TIMERS; i++) {
lixianyu 0:740c1eb2df13 99 switch(toBeCalled[i]) {
lixianyu 0:740c1eb2df13 100 case DEFCALL_DONTRUN:
lixianyu 0:740c1eb2df13 101 break;
lixianyu 0:740c1eb2df13 102
lixianyu 0:740c1eb2df13 103 case DEFCALL_RUNONLY:
lixianyu 0:740c1eb2df13 104 (*callbacks[i])();
lixianyu 0:740c1eb2df13 105 break;
lixianyu 0:740c1eb2df13 106
lixianyu 0:740c1eb2df13 107 case DEFCALL_RUNANDDEL:
lixianyu 0:740c1eb2df13 108 (*callbacks[i])();
lixianyu 0:740c1eb2df13 109 deleteTimer(i);
lixianyu 0:740c1eb2df13 110 break;
lixianyu 0:740c1eb2df13 111 }
lixianyu 0:740c1eb2df13 112 //prev_millis[i] = g_SimpleTimer.read_ms(); // LiXianyu added.
lixianyu 0:740c1eb2df13 113 }
lixianyu 0:740c1eb2df13 114 }
lixianyu 0:740c1eb2df13 115
lixianyu 0:740c1eb2df13 116
lixianyu 0:740c1eb2df13 117 // find the first available slot
lixianyu 0:740c1eb2df13 118 // return -1 if none found
lixianyu 0:740c1eb2df13 119 int SimpleTimer::findFirstFreeSlot() {
lixianyu 0:740c1eb2df13 120 int i;
lixianyu 0:740c1eb2df13 121
lixianyu 0:740c1eb2df13 122 // all slots are used
lixianyu 0:740c1eb2df13 123 if (numTimers >= MAX_TIMERS) {
lixianyu 0:740c1eb2df13 124 return -1;
lixianyu 0:740c1eb2df13 125 }
lixianyu 0:740c1eb2df13 126
lixianyu 0:740c1eb2df13 127 // return the first slot with no callback (i.e. free)
lixianyu 0:740c1eb2df13 128 for (i = 0; i < MAX_TIMERS; i++) {
lixianyu 0:740c1eb2df13 129 if (callbacks[i] == 0) {
lixianyu 0:740c1eb2df13 130 return i;
lixianyu 0:740c1eb2df13 131 }
lixianyu 0:740c1eb2df13 132 }
lixianyu 0:740c1eb2df13 133
lixianyu 0:740c1eb2df13 134 // no free slots found
lixianyu 0:740c1eb2df13 135 return -1;
lixianyu 0:740c1eb2df13 136 }
lixianyu 0:740c1eb2df13 137
lixianyu 0:740c1eb2df13 138
lixianyu 0:740c1eb2df13 139 int SimpleTimer::setTimer(uint32_t d, timer_callback f, int n) {
lixianyu 0:740c1eb2df13 140 int freeTimer;
lixianyu 0:740c1eb2df13 141
lixianyu 0:740c1eb2df13 142 freeTimer = findFirstFreeSlot();
lixianyu 0:740c1eb2df13 143 if (freeTimer < 0) {
lixianyu 0:740c1eb2df13 144 return -1;
lixianyu 0:740c1eb2df13 145 }
lixianyu 0:740c1eb2df13 146
lixianyu 0:740c1eb2df13 147 if (f == NULL) {
lixianyu 0:740c1eb2df13 148 return -1;
lixianyu 0:740c1eb2df13 149 }
lixianyu 0:740c1eb2df13 150
lixianyu 0:740c1eb2df13 151 delays[freeTimer] = d;
lixianyu 0:740c1eb2df13 152 callbacks[freeTimer] = f;
lixianyu 0:740c1eb2df13 153 maxNumRuns[freeTimer] = n;
lixianyu 0:740c1eb2df13 154 enabled[freeTimer] = true;
lixianyu 0:740c1eb2df13 155 prev_millis[freeTimer] = g_SimpleTimer.read_ms();
lixianyu 0:740c1eb2df13 156
lixianyu 0:740c1eb2df13 157 numTimers++;
lixianyu 0:740c1eb2df13 158
lixianyu 0:740c1eb2df13 159 return freeTimer;
lixianyu 0:740c1eb2df13 160 }
lixianyu 0:740c1eb2df13 161
lixianyu 0:740c1eb2df13 162
lixianyu 0:740c1eb2df13 163 int SimpleTimer::setInterval(uint32_t d, timer_callback f) {
lixianyu 0:740c1eb2df13 164 return setTimer(d, f, RUN_FOREVER);
lixianyu 0:740c1eb2df13 165 }
lixianyu 0:740c1eb2df13 166
lixianyu 0:740c1eb2df13 167
lixianyu 0:740c1eb2df13 168 int SimpleTimer::setTimeout(uint32_t d, timer_callback f) {
lixianyu 0:740c1eb2df13 169 return setTimer(d, f, RUN_ONCE);
lixianyu 0:740c1eb2df13 170 }
lixianyu 0:740c1eb2df13 171
lixianyu 0:740c1eb2df13 172
lixianyu 0:740c1eb2df13 173 void SimpleTimer::deleteTimer(int timerId) {
lixianyu 0:740c1eb2df13 174 if (timerId >= MAX_TIMERS) {
lixianyu 0:740c1eb2df13 175 return;
lixianyu 0:740c1eb2df13 176 }
lixianyu 0:740c1eb2df13 177
lixianyu 0:740c1eb2df13 178 // nothing to delete if no timers are in use
lixianyu 0:740c1eb2df13 179 if (numTimers == 0) {
lixianyu 0:740c1eb2df13 180 return;
lixianyu 0:740c1eb2df13 181 }
lixianyu 0:740c1eb2df13 182
lixianyu 0:740c1eb2df13 183 // don't decrease the number of timers if the
lixianyu 0:740c1eb2df13 184 // specified slot is already empty
lixianyu 0:740c1eb2df13 185 if (callbacks[timerId] != NULL) {
lixianyu 0:740c1eb2df13 186 callbacks[timerId] = 0;
lixianyu 0:740c1eb2df13 187 enabled[timerId] = false;
lixianyu 0:740c1eb2df13 188 toBeCalled[timerId] = DEFCALL_DONTRUN;
lixianyu 0:740c1eb2df13 189 delays[timerId] = 0;
lixianyu 0:740c1eb2df13 190 numRuns[timerId] = 0;
lixianyu 0:740c1eb2df13 191
lixianyu 0:740c1eb2df13 192 // update number of timers
lixianyu 0:740c1eb2df13 193 numTimers--;
lixianyu 0:740c1eb2df13 194 }
lixianyu 0:740c1eb2df13 195 }
lixianyu 0:740c1eb2df13 196
lixianyu 0:740c1eb2df13 197 // function contributed by code@rowansimms.com
lixianyu 0:740c1eb2df13 198 void SimpleTimer::restartTimer(int numTimer) {
lixianyu 0:740c1eb2df13 199 if (numTimer >= MAX_TIMERS) {
lixianyu 0:740c1eb2df13 200 return;
lixianyu 0:740c1eb2df13 201 }
lixianyu 0:740c1eb2df13 202
lixianyu 0:740c1eb2df13 203 prev_millis[numTimer] = g_SimpleTimer.read_ms();
lixianyu 0:740c1eb2df13 204 }
lixianyu 0:740c1eb2df13 205
lixianyu 0:740c1eb2df13 206
lixianyu 0:740c1eb2df13 207 bool SimpleTimer::isEnabled(int numTimer) {
lixianyu 0:740c1eb2df13 208 if (numTimer >= MAX_TIMERS) {
lixianyu 0:740c1eb2df13 209 return false;
lixianyu 0:740c1eb2df13 210 }
lixianyu 0:740c1eb2df13 211
lixianyu 0:740c1eb2df13 212 return enabled[numTimer];
lixianyu 0:740c1eb2df13 213 }
lixianyu 0:740c1eb2df13 214
lixianyu 0:740c1eb2df13 215
lixianyu 0:740c1eb2df13 216 void SimpleTimer::enable(int numTimer) {
lixianyu 0:740c1eb2df13 217 if (numTimer >= MAX_TIMERS) {
lixianyu 0:740c1eb2df13 218 return;
lixianyu 0:740c1eb2df13 219 }
lixianyu 0:740c1eb2df13 220
lixianyu 0:740c1eb2df13 221 enabled[numTimer] = true;
lixianyu 0:740c1eb2df13 222 }
lixianyu 0:740c1eb2df13 223
lixianyu 0:740c1eb2df13 224
lixianyu 0:740c1eb2df13 225 void SimpleTimer::disable(int numTimer) {
lixianyu 0:740c1eb2df13 226 if (numTimer >= MAX_TIMERS) {
lixianyu 0:740c1eb2df13 227 return;
lixianyu 0:740c1eb2df13 228 }
lixianyu 0:740c1eb2df13 229
lixianyu 0:740c1eb2df13 230 enabled[numTimer] = false;
lixianyu 0:740c1eb2df13 231 }
lixianyu 0:740c1eb2df13 232
lixianyu 0:740c1eb2df13 233
lixianyu 0:740c1eb2df13 234 void SimpleTimer::toggle(int numTimer) {
lixianyu 0:740c1eb2df13 235 if (numTimer >= MAX_TIMERS) {
lixianyu 0:740c1eb2df13 236 return;
lixianyu 0:740c1eb2df13 237 }
lixianyu 0:740c1eb2df13 238
lixianyu 0:740c1eb2df13 239 enabled[numTimer] = !enabled[numTimer];
lixianyu 0:740c1eb2df13 240 }
lixianyu 0:740c1eb2df13 241
lixianyu 0:740c1eb2df13 242
lixianyu 0:740c1eb2df13 243 int SimpleTimer::getNumTimers() {
lixianyu 0:740c1eb2df13 244 return numTimers;
lixianyu 0:740c1eb2df13 245 }