diff --git a/LowLevel.h b/LowLevel.h index 1b3b0c7..19943f1 100644 --- a/LowLevel.h +++ b/LowLevel.h @@ -21,6 +21,43 @@ #define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) +#if defined (__AVR_ATtiny85__) +#define CLEARINTERRUPT GIFR |= (1 << INTF0) +#include "UserTimer.h" //ATtiny-support based on TinyCore1 Arduino-core for ATtiny at http://github.com/Coding-Badly/TinyCore1.git +__attribute__((always_inline)) static inline void UserTimer_Init( void ) +{ + UserTimer_SetToPowerup(); + UserTimer_SetWaveformGenerationMode(UserTimer_(CTC_OCR)); +} +__attribute__((always_inline)) static inline void UserTimer_Run(short skipTicks) +{ + UserTimer_SetCount(0); + UserTimer_SetOutputCompareMatchAndClear(skipTicks); + UserTimer_ClockSelect(UserTimer_(Prescale_Value_64)); +} +#define UserTimer_Stop() UserTimer_ClockSelect(UserTimer_(Stopped)) + +#elif defined (__AVR_ATmega328P__) +#define CLEARINTERRUPT EIFR |= (1 << INTF0) +#define USERTIMER_COMPA_vect TIMER1_COMPA_vect + +__attribute__((always_inline)) static inline void UserTimer_Init( void ) +{ + TCCR1A = 0; + TCCR1B = 0; + // enable timer compare interrupt + TIMSK1 |= (1 << OCIE1A); +} +__attribute__((always_inline)) static inline void UserTimer_Run(short skipTicks) +{ + TCNT1 = 0; + OCR1A = skipTicks; + // turn on CTC mode with 64 prescaler + TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); +} +#define UserTimer_Stop() TCCR1B = 0 +#endif + #elif defined(__MK20DX128__) || defined(__MK20DX256__) #define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) #define PIN_TO_BITMASK(pin) (1) @@ -110,7 +147,7 @@ public: inline void attachInterrupt(void (*handler)(), int mode) { - EIFR |= (1 << INTF0); // clear any pending interrupt (we want to call the handler only for interrupts happending after it is attached) + CLEARINTERRUPT; // clear any pending interrupt (we want to call the handler only for interrupts happending after it is attached) ::attachInterrupt(interruptNumber_, handler, mode); } inline void detachInterrupt() { ::detachInterrupt(interruptNumber_); } diff --git a/OneWireSlave.cpp b/OneWireSlave.cpp index 01ba65e..851b3a2 100644 --- a/OneWireSlave.cpp +++ b/OneWireSlave.cpp @@ -31,7 +31,6 @@ OneWireSlave OWSlave; byte OneWireSlave::rom_[8]; byte OneWireSlave::scratchpad_[8]; Pin OneWireSlave::pin_; -byte OneWireSlave::tccr1bEnable_; unsigned long OneWireSlave::resetStart_; unsigned long OneWireSlave::lastReset_; @@ -69,9 +68,9 @@ void(*OneWireSlave::singleBitSentCallback_)(bool error); void(*OneWireSlave::logCallback_)(const char* message); -ISR(TIMER1_COMPA_vect) // timer1 interrupt +ISR(USERTIMER_COMPA_vect) // timer1 interrupt { - TCCR1B = 0; // disable clock + UserTimer_Stop(); // disable clock void(*event)() = timerEvent; timerEvent = 0; event(); @@ -99,10 +98,7 @@ void OneWireSlave::begin(const byte* rom, byte pinNumber) pin_.writeLow(); // make sure the internal pull-up resistor is disabled // prepare hardware timer - TCCR1A = 0; - TCCR1B = 0; - TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt - tccr1bEnable_ = (1 << WGM12) | (1 << CS11) | (1 << CS10); // turn on CTC mode with 64 prescaler + UserTimer_Init(); // start 1-wire activity beginWaitReset_(); @@ -241,15 +237,13 @@ void OneWireSlave::setTimerEvent_(short delayMicroSeconds, void(*handler)()) short skipTicks = (delayMicroSeconds - 3) / 4; // round the micro seconds delay to a number of ticks to skip (4us per tick, so 4us must skip 0 tick, 8us must skip 1 tick, etc.) if (skipTicks < 1) skipTicks = 1; - TCNT1 = 0; - OCR1A = skipTicks; timerEvent = handler; - TCCR1B = tccr1bEnable_; + UserTimer_Run(skipTicks); } void OneWireSlave::disableTimer_() { - TCCR1B = 0; + UserTimer_Stop(); } void OneWireSlave::onEnterInterrupt_() diff --git a/OneWireSlave.h b/OneWireSlave.h index e0cd742..88073e0 100644 --- a/OneWireSlave.h +++ b/OneWireSlave.h @@ -103,7 +103,6 @@ private: static byte rom_[8]; static byte scratchpad_[8]; static Pin pin_; - static byte tccr1bEnable_; static unsigned long resetStart_; static unsigned long lastReset_;