6 #ifndef __ALARMCLOCK_H__
7 #define __ALARMCLOCK_H__
15 #ifndef TICKS_PER_SECOND
17 #define TICKS_PER_SECOND 100UL
20 #define seconds2ticks(tm) ( (tm) * TICKS_PER_SECOND )
21 #define ticks2seconds(tm) ( (tm) / TICKS_PER_SECOND )
23 #define decis2ticks(tm) ( (tm) * TICKS_PER_SECOND / 10 )
24 #define ticks2decis(tm) ( (tm) * 10UL / TICKS_PER_SECOND )
26 #define centis2ticks(tm) ( (tm) * TICKS_PER_SECOND / 100 )
27 #define ticks2centis(tm) ( (tm) * 100UL / TICKS_PER_SECOND )
29 #define millis2ticks(tm) ( (tm) * TICKS_PER_SECOND / 1000 )
30 #define ticks2millis(tm) ( (tm) * 1000UL / TICKS_PER_SECOND )
38 void cancel(
Alarm& item);
42 bool isready ()
const {
43 return ready.select() != 0;
48 while( runsingle()==
true ) {
68 void add(
Alarm& item);
70 uint32_t get(
const Alarm& item)
const;
72 uint32_t next ()
const {
74 return n != 0 ? n->tick : 0;
77 Alarm* first ()
const {
78 return (
Alarm*)select();
82 void correct (uint32_t ticks) {
86 uint32_t nextticks = n->tick-1;
87 n->tick -= nextticks < ticks ? nextticks : ticks;
95 extern void callback(
void);
96 extern void rtccallback(
void);
105 #define TIMER1_RESOLUTION 65536UL // Timer1 is 16 bit
109 const unsigned long cycles = (F_CPU / 2000000) * (1000000 / TICKS_PER_SECOND);
110 unsigned short pwmPeriod;
111 unsigned char clockSelectBits;
113 if (cycles < TIMER1_RESOLUTION) {
114 clockSelectBits = _BV(CS10);
115 pwmPeriod = (
unsigned short)cycles;
117 else if (cycles < TIMER1_RESOLUTION * 8) {
118 clockSelectBits = _BV(CS11);
119 pwmPeriod = cycles / 8;
121 else if (cycles < TIMER1_RESOLUTION * 64) {
122 clockSelectBits = _BV(CS11) | _BV(CS10);
123 pwmPeriod = cycles / 64;
125 else if (cycles < TIMER1_RESOLUTION * 256) {
126 clockSelectBits = _BV(CS12);
127 pwmPeriod = cycles / 256;
129 else if (cycles < TIMER1_RESOLUTION * 1024) {
130 clockSelectBits = _BV(CS12) | _BV(CS10);
131 pwmPeriod = cycles / 1024;
134 clockSelectBits = _BV(CS12) | _BV(CS10);
135 pwmPeriod = TIMER1_RESOLUTION - 1;
139 TCCR1B = _BV(WGM13) | clockSelectBits;
141 #ifdef ARDUINO_ARCH_STM32F1
143 Timer2.setMode(TIMER_CH2,TIMER_OUTPUT_COMPARE);
144 Timer2.setPeriod(1000000 / TICKS_PER_SECOND);
145 Timer2.setCompare(TIMER_CH2, 1);
151 #if defined ARDUINO_AVR_ATmega32 || defined(__AVR_ATmega128__)
152 TIMSK &= ~_BV(TOIE1);
153 #elif defined(ARDUINO_ARCH_AVR)
154 TIMSK1 &= ~_BV(TOIE1);
155 #elif defined(ARDUINO_ARCH_STM32F1)
156 Timer2.detachInterrupt(TIMER_CH2);
161 #if defined ARDUINO_AVR_ATmega32|| defined(__AVR_ATmega128__)
163 #elif defined(ARDUINO_ARCH_AVR)
164 TIMSK1 |= _BV(TOIE1);
165 #elif defined(ARDUINO_ARCH_STM32F1)
166 Timer2.attachInterrupt(TIMER_CH2,callback);
170 void add(
Alarm& item) {
171 AlarmClock::add(item);
174 void add(
Alarm& item,uint32_t millis) {
175 item.tick = (millis2ticks(millis));
187 #if defined(ARDUINO_ARCH_STM32F1) && defined(_RTCLOCK_H_)
194 static RTC& instance();
197 #if defined ARDUINO_AVR_ATmega32
198 TIMSK &= ~(1<<TOIE2);
201 TCCR2 = (1<<CS22)|(1<<CS20);
202 while (ASSR & (1<<TCN2UB));
205 #elif defined(__AVR_ATmega128__)
206 TIMSK &= ~(1<<TOIE2);
209 TCCR2 = (1<<CS22)|(1<<CS20);
210 while (ASSR & (1<<TCN0UB));
213 #elif defined(ARDUINO_ARCH_AVR)
218 TCCR2B = (1<<CS22)|(1<<CS20);
219 while (ASSR & ((1<<TCN2UB)|(1<<TCR2BUB)));
222 #elif defined(ARDUINO_ARCH_STM32F1) && defined(_RTCLOCK_H_)
223 rt = RTClock(RTCSEL_LSE);
224 rt.attachSecondsInterrupt(rtccallback);
226 #warning "RTC not supported"
231 uint32_t getCurrentMillis () {
232 #ifdef ARDUINO_ARCH_AVR
233 return (TCNT2 * 1000) / 255;
239 uint32_t getCounter (
bool resetovrflow) {
240 if( resetovrflow ==
true ) {
243 #ifdef ARDUINO_ARCH_AVR
244 return (256 * ovrfl) + TCNT2;
245 #elif defined(ARDUINO_ARCH_STM32F1) && defined(_RTCLOCK_H_)
246 return rtc_get_count();
257 if( select() != 0 ) {
258 DDEC((uint16_t)((
Alarm*)select())->tick);
263 void add(
Alarm& item) {
264 AlarmClock::add(item);
267 void add(
Alarm& item,uint32_t millis) {
268 millis += getCurrentMillis();
269 item.tick = (millis / 1000);
273 void add(
RTCAlarm& item,uint32_t millis) {
275 millis += getCurrentMillis();
276 item.tick = (millis / 1000);
277 item.millis = millis % 1000;