reorganizing project to more general synchronizer in preparation for export/delivery to RVK museum.
This commit is contained in:
206
synchronizer/libraries/MsTimer2/MsTimer2.cpp
Normal file
206
synchronizer/libraries/MsTimer2/MsTimer2.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
MsTimer2.h - Using timer2 with 1ms resolution
|
||||
Javier Valencia <javiervalencia80@gmail.com>
|
||||
|
||||
History:
|
||||
29/Dec/11 - V0.6 added support for ATmega32u4, AT90USB646, AT90USB1286 (paul@pjrc.com)
|
||||
some improvements added by Bill Perry
|
||||
note: uses timer4 on Atmega32u4
|
||||
29/May/09 - V0.5 added support for Atmega1280 (thanks to Manuel Negri)
|
||||
19/Mar/09 - V0.4 added support for ATmega328P (thanks to Jerome Despatis)
|
||||
11/Jun/08 - V0.3
|
||||
changes to allow working with different CPU frequencies
|
||||
added support for ATMega128 (using timer2)
|
||||
compatible with ATMega48/88/168/8
|
||||
10/May/08 - V0.2 added some security tests and volatile keywords
|
||||
9/May/08 - V0.1 released working on ATMEGA168 only
|
||||
|
||||
|
||||
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 <MsTimer2.h>
|
||||
|
||||
unsigned long MsTimer2::msecs;
|
||||
void (*MsTimer2::func)();
|
||||
volatile unsigned long MsTimer2::count;
|
||||
volatile char MsTimer2::overflowing;
|
||||
volatile unsigned int MsTimer2::tcnt2;
|
||||
|
||||
void MsTimer2::set(unsigned long ms, void (*f)()) {
|
||||
float prescaler = 0.0;
|
||||
|
||||
if (ms == 0)
|
||||
msecs = 1;
|
||||
else
|
||||
msecs = ms;
|
||||
|
||||
func = f;
|
||||
|
||||
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
TIMSK2 &= ~(1<<TOIE2);
|
||||
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
|
||||
TCCR2B &= ~(1<<WGM22);
|
||||
ASSR &= ~(1<<AS2);
|
||||
TIMSK2 &= ~(1<<OCIE2A);
|
||||
|
||||
if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
|
||||
TCCR2B |= (1<<CS22);
|
||||
TCCR2B &= ~((1<<CS21) | (1<<CS20));
|
||||
prescaler = 64.0;
|
||||
} else if (F_CPU < 1000000UL) { // prescaler set to 8
|
||||
TCCR2B |= (1<<CS21);
|
||||
TCCR2B &= ~((1<<CS22) | (1<<CS20));
|
||||
prescaler = 8.0;
|
||||
} else { // F_CPU > 16Mhz, prescaler set to 128
|
||||
TCCR2B |= ((1<<CS22) | (1<<CS20));
|
||||
TCCR2B &= ~(1<<CS21);
|
||||
prescaler = 128.0;
|
||||
}
|
||||
#elif defined (__AVR_ATmega8__)
|
||||
TIMSK &= ~(1<<TOIE2);
|
||||
TCCR2 &= ~((1<<WGM21) | (1<<WGM20));
|
||||
TIMSK &= ~(1<<OCIE2);
|
||||
ASSR &= ~(1<<AS2);
|
||||
|
||||
if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
|
||||
TCCR2 |= (1<<CS22);
|
||||
TCCR2 &= ~((1<<CS21) | (1<<CS20));
|
||||
prescaler = 64.0;
|
||||
} else if (F_CPU < 1000000UL) { // prescaler set to 8
|
||||
TCCR2 |= (1<<CS21);
|
||||
TCCR2 &= ~((1<<CS22) | (1<<CS20));
|
||||
prescaler = 8.0;
|
||||
} else { // F_CPU > 16Mhz, prescaler set to 128
|
||||
TCCR2 |= ((1<<CS22) && (1<<CS20));
|
||||
TCCR2 &= ~(1<<CS21);
|
||||
prescaler = 128.0;
|
||||
}
|
||||
#elif defined (__AVR_ATmega128__)
|
||||
TIMSK &= ~(1<<TOIE2);
|
||||
TCCR2 &= ~((1<<WGM21) | (1<<WGM20));
|
||||
TIMSK &= ~(1<<OCIE2);
|
||||
|
||||
if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
|
||||
TCCR2 |= ((1<<CS21) | (1<<CS20));
|
||||
TCCR2 &= ~(1<<CS22);
|
||||
prescaler = 64.0;
|
||||
} else if (F_CPU < 1000000UL) { // prescaler set to 8
|
||||
TCCR2 |= (1<<CS21);
|
||||
TCCR2 &= ~((1<<CS22) | (1<<CS20));
|
||||
prescaler = 8.0;
|
||||
} else { // F_CPU > 16Mhz, prescaler set to 256
|
||||
TCCR2 |= (1<<CS22);
|
||||
TCCR2 &= ~((1<<CS21) | (1<<CS20));
|
||||
prescaler = 256.0;
|
||||
}
|
||||
#elif defined (__AVR_ATmega32U4__)
|
||||
TCCR4B = 0;
|
||||
TCCR4A = 0;
|
||||
TCCR4C = 0;
|
||||
TCCR4D = 0;
|
||||
TCCR4E = 0;
|
||||
if (F_CPU >= 16000000L) {
|
||||
TCCR4B = (1<<CS43) | (1<<PSR4);
|
||||
prescaler = 128.0;
|
||||
} else if (F_CPU >= 8000000L) {
|
||||
TCCR4B = (1<<CS42) | (1<<CS41) | (1<<CS40) | (1<<PSR4);
|
||||
prescaler = 64.0;
|
||||
} else if (F_CPU >= 4000000L) {
|
||||
TCCR4B = (1<<CS42) | (1<<CS41) | (1<<PSR4);
|
||||
prescaler = 32.0;
|
||||
} else if (F_CPU >= 2000000L) {
|
||||
TCCR4B = (1<<CS42) | (1<<CS40) | (1<<PSR4);
|
||||
prescaler = 16.0;
|
||||
} else if (F_CPU >= 1000000L) {
|
||||
TCCR4B = (1<<CS42) | (1<<PSR4);
|
||||
prescaler = 8.0;
|
||||
} else if (F_CPU >= 500000L) {
|
||||
TCCR4B = (1<<CS41) | (1<<CS40) | (1<<PSR4);
|
||||
prescaler = 4.0;
|
||||
} else {
|
||||
TCCR4B = (1<<CS41) | (1<<PSR4);
|
||||
prescaler = 2.0;
|
||||
}
|
||||
tcnt2 = (int)((float)F_CPU * 0.001 / prescaler) - 1;
|
||||
OCR4C = tcnt2;
|
||||
return;
|
||||
#else
|
||||
#error Unsupported CPU type
|
||||
#endif
|
||||
|
||||
tcnt2 = 256 - (int)((float)F_CPU * 0.001 / prescaler);
|
||||
}
|
||||
|
||||
void MsTimer2::start() {
|
||||
count = 0;
|
||||
overflowing = 0;
|
||||
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
TCNT2 = tcnt2;
|
||||
TIMSK2 |= (1<<TOIE2);
|
||||
#elif defined (__AVR_ATmega128__)
|
||||
TCNT2 = tcnt2;
|
||||
TIMSK |= (1<<TOIE2);
|
||||
#elif defined (__AVR_ATmega8__)
|
||||
TCNT2 = tcnt2;
|
||||
TIMSK |= (1<<TOIE2);
|
||||
#elif defined (__AVR_ATmega32U4__)
|
||||
TIFR4 = (1<<TOV4);
|
||||
TCNT4 = 0;
|
||||
TIMSK4 = (1<<TOIE4);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MsTimer2::stop() {
|
||||
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
TIMSK2 &= ~(1<<TOIE2);
|
||||
#elif defined (__AVR_ATmega128__)
|
||||
TIMSK &= ~(1<<TOIE2);
|
||||
#elif defined (__AVR_ATmega8__)
|
||||
TIMSK &= ~(1<<TOIE2);
|
||||
#elif defined (__AVR_ATmega32U4__)
|
||||
TIMSK4 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MsTimer2::_overflow() {
|
||||
count += 1;
|
||||
|
||||
if (count >= msecs && !overflowing) {
|
||||
overflowing = 1;
|
||||
count = count - msecs; // subtract ms to catch missed overflows
|
||||
// set to 0 if you don't want this.
|
||||
(*func)();
|
||||
overflowing = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (__AVR_ATmega32U4__)
|
||||
ISR(TIMER4_OVF_vect) {
|
||||
#else
|
||||
ISR(TIMER2_OVF_vect) {
|
||||
#endif
|
||||
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
TCNT2 = MsTimer2::tcnt2;
|
||||
#elif defined (__AVR_ATmega128__)
|
||||
TCNT2 = MsTimer2::tcnt2;
|
||||
#elif defined (__AVR_ATmega8__)
|
||||
TCNT2 = MsTimer2::tcnt2;
|
||||
#elif defined (__AVR_ATmega32U4__)
|
||||
// not necessary on 32u4's high speed timer4
|
||||
#endif
|
||||
MsTimer2::_overflow();
|
||||
}
|
||||
|
||||
23
synchronizer/libraries/MsTimer2/MsTimer2.h
Normal file
23
synchronizer/libraries/MsTimer2/MsTimer2.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MsTimer2_h
|
||||
#define MsTimer2_h
|
||||
|
||||
#ifdef __AVR__
|
||||
#include <avr/interrupt.h>
|
||||
#else
|
||||
#error MsTimer2 library only works on AVR architecture
|
||||
#endif
|
||||
|
||||
namespace MsTimer2 {
|
||||
extern unsigned long msecs;
|
||||
extern void (*func)();
|
||||
extern volatile unsigned long count;
|
||||
extern volatile char overflowing;
|
||||
extern volatile unsigned int tcnt2;
|
||||
|
||||
void set(unsigned long ms, void (*f)());
|
||||
void start();
|
||||
void stop();
|
||||
void _overflow();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
char dummyvar; // to get Arduinoi IDE to include core headers properly
|
||||
|
||||
/*
|
||||
MsTimer2 is a small and very easy to use library to interface Timer2 with
|
||||
humans. It's called MsTimer2 because it "hardcodes" a resolution of 1
|
||||
millisecond on timer2
|
||||
For Details see: http://www.arduino.cc/playground/Main/MsTimer2
|
||||
*/
|
||||
#include <MsTimer2.h>
|
||||
|
||||
// Switch on LED on and off each half second
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
const int led_pin = LED_BUILTIN; // 1.0 built in LED pin var
|
||||
#else
|
||||
#if defined(CORE_LED0_PIN)
|
||||
const int led_pin = CORE_LED0_PIN; // 3rd party LED pin define
|
||||
#else
|
||||
const int led_pin = 13; // default to pin 13
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
void flash()
|
||||
{
|
||||
static boolean output = HIGH;
|
||||
|
||||
digitalWrite(led_pin, output);
|
||||
output = !output;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(led_pin, OUTPUT);
|
||||
|
||||
MsTimer2::set(500, flash); // 500ms period
|
||||
MsTimer2::start();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
4
synchronizer/libraries/MsTimer2/keywords.txt
Normal file
4
synchronizer/libraries/MsTimer2/keywords.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
MsTimer2 KEYWORD1
|
||||
set KEYWORD2
|
||||
start KEYWORD2
|
||||
stop KEYWORD2
|
||||
Reference in New Issue
Block a user