From 78626b2c49deb8f7d1583328a8118d433ffb36df Mon Sep 17 00:00:00 2001 From: Joshua Noble Date: Wed, 16 Jul 2014 10:41:38 -0700 Subject: [PATCH 1/2] updating IRRemote library --- libraries/RobotIRremote/IRremote.cpp | 353 +++++++++++++++++++--- libraries/RobotIRremote/IRremote.h | 38 ++- libraries/RobotIRremote/IRremoteInt.h | 99 ++++-- libraries/RobotIRremote/IRremoteTools.cpp | 4 +- 4 files changed, 412 insertions(+), 82 deletions(-) diff --git a/libraries/RobotIRremote/IRremote.cpp b/libraries/RobotIRremote/IRremote.cpp index fb76cb64db9..0b7092c9daa 100644 --- a/libraries/RobotIRremote/IRremote.cpp +++ b/libraries/RobotIRremote/IRremote.cpp @@ -69,8 +69,205 @@ int MATCH_SPACE(int measured_ticks, int desired_us) { int MATCH(int measured, int desired) {return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);} int MATCH_MARK(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us + MARK_EXCESS));} int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us - MARK_EXCESS));} +// Debugging versions are in IRremote.cpp #endif +void IRsend::sendNEC(unsigned long data, int nbits) +{ + enableIROut(38); + mark(NEC_HDR_MARK); + space(NEC_HDR_SPACE); + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(NEC_BIT_MARK); + space(NEC_ONE_SPACE); + } + else { + mark(NEC_BIT_MARK); + space(NEC_ZERO_SPACE); + } + data <<= 1; + } + mark(NEC_BIT_MARK); + space(0); +} + +void IRsend::sendSony(unsigned long data, int nbits) { + enableIROut(40); + mark(SONY_HDR_MARK); + space(SONY_HDR_SPACE); + data = data << (32 - nbits); + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(SONY_ONE_MARK); + space(SONY_HDR_SPACE); + } + else { + mark(SONY_ZERO_MARK); + space(SONY_HDR_SPACE); + } + data <<= 1; + } +} + +void IRsend::sendRaw(unsigned int buf[], int len, int hz) +{ + enableIROut(hz); + for (int i = 0; i < len; i++) { + if (i & 1) { + space(buf[i]); + } + else { + mark(buf[i]); + } + } + space(0); // Just to be sure +} + +// Note: first bit must be a one (start bit) +void IRsend::sendRC5(unsigned long data, int nbits) +{ + enableIROut(36); + data = data << (32 - nbits); + mark(RC5_T1); // First start bit + space(RC5_T1); // Second start bit + mark(RC5_T1); // Second start bit + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + space(RC5_T1); // 1 is space, then mark + mark(RC5_T1); + } + else { + mark(RC5_T1); + space(RC5_T1); + } + data <<= 1; + } + space(0); // Turn off at end +} + +// Caller needs to take care of flipping the toggle bit +void IRsend::sendRC6(unsigned long data, int nbits) +{ + enableIROut(36); + data = data << (32 - nbits); + mark(RC6_HDR_MARK); + space(RC6_HDR_SPACE); + mark(RC6_T1); // start bit + space(RC6_T1); + int t; + for (int i = 0; i < nbits; i++) { + if (i == 3) { + // double-wide trailer bit + t = 2 * RC6_T1; + } + else { + t = RC6_T1; + } + if (data & TOPBIT) { + mark(t); + space(t); + } + else { + space(t); + mark(t); + } + + data <<= 1; + } + space(0); // Turn off at end +} +void IRsend::sendPanasonic(unsigned int address, unsigned long data) { + enableIROut(35); + mark(PANASONIC_HDR_MARK); + space(PANASONIC_HDR_SPACE); + + for(int i=0;i<16;i++) + { + mark(PANASONIC_BIT_MARK); + if (address & 0x8000) { + space(PANASONIC_ONE_SPACE); + } else { + space(PANASONIC_ZERO_SPACE); + } + address <<= 1; + } + for (int i=0; i < 32; i++) { + mark(PANASONIC_BIT_MARK); + if (data & TOPBIT) { + space(PANASONIC_ONE_SPACE); + } else { + space(PANASONIC_ZERO_SPACE); + } + data <<= 1; + } + mark(PANASONIC_BIT_MARK); + space(0); +} +void IRsend::sendJVC(unsigned long data, int nbits, int repeat) +{ + enableIROut(38); + data = data << (32 - nbits); + if (!repeat){ + mark(JVC_HDR_MARK); + space(JVC_HDR_SPACE); + } + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(JVC_BIT_MARK); + space(JVC_ONE_SPACE); + } + else { + mark(JVC_BIT_MARK); + space(JVC_ZERO_SPACE); + } + data <<= 1; + } + mark(JVC_BIT_MARK); + space(0); +} +void IRsend::mark(int time) { + // Sends an IR mark for the specified number of microseconds. + // The mark output is modulated at the PWM frequency. + TIMER_ENABLE_PWM; // Enable pin 3 PWM output + delayMicroseconds(time); +} + +/* Leave pin off for time (given in microseconds) */ +void IRsend::space(int time) { + // Sends an IR space for the specified number of microseconds. + // A space is no output, so the PWM output is disabled. + TIMER_DISABLE_PWM; // Disable pin 3 PWM output + delayMicroseconds(time); +} + +void IRsend::enableIROut(int khz) { + // Enables IR output. The khz value controls the modulation frequency in kilohertz. + // The IR output will be on pin 3 (OC2B). + // This routine is designed for 36-40KHz; if you use it for other values, it's up to you + // to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.) + // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B + // controlling the duty cycle. + // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A) + // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin. + // A few hours staring at the ATmega documentation and this will all make sense. + // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details. + + + // Disable the Timer2 Interrupt (which is used for receiving IR) + TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt + + pinMode(TIMER_PWM_PIN, OUTPUT); + digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low + + // COM2A = 00: disconnect OC2A + // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted + // WGM2 = 101: phase-correct PWM with OCRA as top + // CS2 = 000: no prescaling + // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. + TIMER_CONFIG_KHZ(khz); +} + IRrecv::IRrecv(int recvpin) { irparams.recvpin = recvpin; @@ -199,66 +396,54 @@ int IRrecv::decode(decode_results *results) { if (irparams.rcvstate != STATE_STOP) { return ERR; } - #ifdef DEBUG Serial.println("Attempting NEC decode"); #endif if (decodeNEC(results)) { return DECODED; } -/* #ifdef DEBUG Serial.println("Attempting Sony decode"); #endif if (decodeSony(results)) { return DECODED; - }*/ -/* + } #ifdef DEBUG Serial.println("Attempting Sanyo decode"); #endif if (decodeSanyo(results)) { return DECODED; } - */ -/* #ifdef DEBUG Serial.println("Attempting Mitsubishi decode"); #endif if (decodeMitsubishi(results)) { return DECODED; - }*/ -/* + } #ifdef DEBUG Serial.println("Attempting RC5 decode"); #endif if (decodeRC5(results)) { return DECODED; } - */ -/* #ifdef DEBUG Serial.println("Attempting RC6 decode"); #endif if (decodeRC6(results)) { return DECODED; } - */ -/* #ifdef DEBUG Serial.println("Attempting Panasonic decode"); #endif if (decodePanasonic(results)) { return DECODED; } - */ -/* #ifdef DEBUG Serial.println("Attempting JVC decode"); #endif if (decodeJVC(results)) { return DECODED; - }*/ + } // decodeHash returns a hash on any input. // Thus, it needs to be last in the list. // If you add any decodes, add them before this. @@ -270,7 +455,6 @@ int IRrecv::decode(decode_results *results) { return ERR; } - // NECs have a repeat only 4 items long long IRrecv::decodeNEC(decode_results *results) { long data = 0; @@ -319,7 +503,7 @@ long IRrecv::decodeNEC(decode_results *results) { results->decode_type = NEC; return DECODED; } -/* + long IRrecv::decodeSony(decode_results *results) { long data = 0; if (irparams.rawlen < 2 * SONY_BITS + 2) { @@ -370,9 +554,8 @@ long IRrecv::decodeSony(decode_results *results) { results->value = data; results->decode_type = SONY; return DECODED; -}*/ +} -/* // I think this is a Sanyo decoder - serial = SA 8650B // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeSanyo(decode_results *results) { @@ -382,12 +565,12 @@ long IRrecv::decodeSanyo(decode_results *results) { } int offset = 0; // Skip first space // Initial space - // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay - //Serial.print("IR Gap: "); - //Serial.println( results->rawbuf[offset]); - //Serial.println( "test against:"); - //Serial.println(results->rawbuf[offset]); - + /* Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); + */ if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) { // Serial.print("IR Gap found: "); results->bits = 0; @@ -436,8 +619,7 @@ long IRrecv::decodeSanyo(decode_results *results) { results->decode_type = SANYO; return DECODED; } -*/ -/* + // Looks like Sony except for timings, 48 chars of data and time/space different long IRrecv::decodeMitsubishi(decode_results *results) { // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); @@ -447,21 +629,21 @@ long IRrecv::decodeMitsubishi(decode_results *results) { } int offset = 0; // Skip first space // Initial space - // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay - //Serial.print("IR Gap: "); - //Serial.println( results->rawbuf[offset]); - //Serial.println( "test against:"); - //Serial.println(results->rawbuf[offset]); - - // Not seeing double keys from Mitsubishi - //if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) { + /* Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); + */ + /* Not seeing double keys from Mitsubishi + if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) { // Serial.print("IR Gap found: "); - // results->bits = 0; - // results->value = REPEAT; - // results->decode_type = MITSUBISHI; - // return DECODED; - //} - + results->bits = 0; + results->value = REPEAT; + results->decode_type = MITSUBISHI; + return DECODED; + } + */ offset++; // Typical @@ -500,7 +682,7 @@ long IRrecv::decodeMitsubishi(decode_results *results) { results->value = data; results->decode_type = MITSUBISHI; return DECODED; -}*/ +} // Gets one undecoded level at a time from the raw buffer. @@ -548,7 +730,7 @@ int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) #endif return val; } -/* + long IRrecv::decodeRC5(decode_results *results) { if (irparams.rawlen < MIN_RC5_SAMPLES + 2) { return ERR; @@ -582,8 +764,8 @@ long IRrecv::decodeRC5(decode_results *results) { results->value = data; results->decode_type = RC5; return DECODED; -}*/ -/* +} + long IRrecv::decodeRC6(decode_results *results) { if (results->rawlen < MIN_RC6_SAMPLES) { return ERR; @@ -633,8 +815,7 @@ long IRrecv::decodeRC6(decode_results *results) { results->value = data; results->decode_type = RC6; return DECODED; -}*/ -/* +} long IRrecv::decodePanasonic(decode_results *results) { unsigned long long data = 0; int offset = 1; @@ -667,8 +848,7 @@ long IRrecv::decodePanasonic(decode_results *results) { results->decode_type = PANASONIC; results->bits = PANASONIC_BITS; return DECODED; -}*/ -/* +} long IRrecv::decodeJVC(decode_results *results) { long data = 0; int offset = 1; // Skip first space @@ -719,7 +899,7 @@ long IRrecv::decodeJVC(decode_results *results) { results->value = data; results->decode_type = JVC; return DECODED; -}*/ +} /* ----------------------------------------------------------------------- * hashdecode - decode an arbitrary IR code. @@ -775,3 +955,76 @@ long IRrecv::decodeHash(decode_results *results) { return DECODED; } +/* Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) + +The Dish send function needs to be repeated 4 times, and the Sharp function +has the necessary repeat built in because of the need to invert the signal. + +Sharp protocol documentation: +http://www.sbprojects.com/knowledge/ir/sharp.htm + +Here are the LIRC files that I found that seem to match the remote codes +from the oscilloscope: + +Sharp LCD TV: +http://lirc.sourceforge.net/remotes/sharp/GA538WJSA + +DISH NETWORK (echostar 301): +http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx + +For the DISH codes, only send the last for characters of the hex. +i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the +linked LIRC file. +*/ + +void IRsend::sendSharp(unsigned long data, int nbits) { + unsigned long invertdata = data ^ SHARP_TOGGLE_MASK; + enableIROut(38); + for (int i = 0; i < nbits; i++) { + if (data & 0x4000) { + mark(SHARP_BIT_MARK); + space(SHARP_ONE_SPACE); + } + else { + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + } + data <<= 1; + } + + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + delay(46); + for (int i = 0; i < nbits; i++) { + if (invertdata & 0x4000) { + mark(SHARP_BIT_MARK); + space(SHARP_ONE_SPACE); + } + else { + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + } + invertdata <<= 1; + } + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + delay(46); +} + +void IRsend::sendDISH(unsigned long data, int nbits) +{ + enableIROut(56); + mark(DISH_HDR_MARK); + space(DISH_HDR_SPACE); + for (int i = 0; i < nbits; i++) { + if (data & DISH_TOP_BIT) { + mark(DISH_BIT_MARK); + space(DISH_ONE_SPACE); + } + else { + mark(DISH_BIT_MARK); + space(DISH_ZERO_SPACE); + } + data <<= 1; + } +} diff --git a/libraries/RobotIRremote/IRremote.h b/libraries/RobotIRremote/IRremote.h index 56dc349b658..0e5fdf2cdc5 100644 --- a/libraries/RobotIRremote/IRremote.h +++ b/libraries/RobotIRremote/IRremote.h @@ -63,13 +63,13 @@ class IRrecv // These are called by decode int getRClevel(decode_results *results, int *offset, int *used, int t1); long decodeNEC(decode_results *results); - //long decodeSony(decode_results *results); - //long decodeSanyo(decode_results *results); - //long decodeMitsubishi(decode_results *results); - //long decodeRC5(decode_results *results); - //long decodeRC6(decode_results *results); - //long decodePanasonic(decode_results *results); - //long decodeJVC(decode_results *results); + long decodeSony(decode_results *results); + long decodeSanyo(decode_results *results); + long decodeMitsubishi(decode_results *results); + long decodeRC5(decode_results *results); + long decodeRC6(decode_results *results); + long decodePanasonic(decode_results *results); + long decodeJVC(decode_results *results); long decodeHash(decode_results *results); int compare(unsigned int oldval, unsigned int newval); @@ -82,6 +82,30 @@ class IRrecv #else #define VIRTUAL #endif + +class IRsend +{ +public: + IRsend() {} + void sendNEC(unsigned long data, int nbits); + void sendSony(unsigned long data, int nbits); + // Neither Sanyo nor Mitsubishi send is implemented yet + // void sendSanyo(unsigned long data, int nbits); + // void sendMitsubishi(unsigned long data, int nbits); + void sendRaw(unsigned int buf[], int len, int hz); + void sendRC5(unsigned long data, int nbits); + void sendRC6(unsigned long data, int nbits); + void sendDISH(unsigned long data, int nbits); + void sendSharp(unsigned long data, int nbits); + void sendPanasonic(unsigned int address, unsigned long data); + void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does. + // private: + void enableIROut(int khz); + VIRTUAL void mark(int usec); + VIRTUAL void space(int usec); +} +; + // Some useful constants #define USECPERTICK 50 // microseconds per clock interrupt tick diff --git a/libraries/RobotIRremote/IRremoteInt.h b/libraries/RobotIRremote/IRremoteInt.h index 0efdbddd397..f2d424e9300 100644 --- a/libraries/RobotIRremote/IRremoteInt.h +++ b/libraries/RobotIRremote/IRremoteInt.h @@ -28,6 +28,8 @@ // are using another library which uses timer2, you have options // to switch IRremote to use a different timer. +//#define __AVR_ATtinyX5__ + // Arduino Mega #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //#define IR_USE_TIMER1 // tx = pin 11 @@ -61,6 +63,25 @@ #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #define IR_USE_TIMER1 // tx = pin 9 +#elif defined( __AVR_ATtinyX4__ ) + #define IR_USE_TIMER1 // tx = pin 6 + +#elif defined( __AVR_ATtinyX5__ ) + + #ifndef cbi + #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) + #endif + #ifndef sbi + #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) + #endif + + #define CLKFUDGE 5 // fudge factor for clock interrupt overhead +#define CLK 256 // max value for clock (timer 2) +#define PRESCALE 8 // timer2 clock prescale + #define CLKSPERUSEC (SYSCLOCK/PRESCALE/1000000) // timer clocks per microsecond + + #define IR_ATTINY_85 // OCR1A, pin 6 + // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc #else //#define IR_USE_TIMER1 // tx = pin 9 @@ -90,24 +111,24 @@ // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap // pulse parameters in usec -#define NEC_HDR_MARK 9000 -#define NEC_HDR_SPACE 4500 -#define NEC_BIT_MARK 560 -#define NEC_ONE_SPACE 1600 -#define NEC_ZERO_SPACE 560 -#define NEC_RPT_SPACE 2250 - -#define SONY_HDR_MARK 2400 -#define SONY_HDR_SPACE 600 -#define SONY_ONE_MARK 1200 -#define SONY_ZERO_MARK 600 +#define NEC_HDR_MARK 9000 +#define NEC_HDR_SPACE 4500 +#define NEC_BIT_MARK 560 +#define NEC_ONE_SPACE 1600 +#define NEC_ZERO_SPACE 560 +#define NEC_RPT_SPACE 2250 + +#define SONY_HDR_MARK 2400 +#define SONY_HDR_SPACE 600 +#define SONY_ONE_MARK 1200 +#define SONY_ZERO_MARK 600 #define SONY_RPT_LENGTH 45000 #define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround // SA 8650B -#define SANYO_HDR_MARK 3500 // seen range 3500 -#define SANYO_HDR_SPACE 950 // seen 950 -#define SANYO_ONE_MARK 2400 // seen 2400 +#define SANYO_HDR_MARK 3500 // seen range 3500 +#define SANYO_HDR_SPACE 950 // seen 950 +#define SANYO_ONE_MARK 2400 // seen 2400 #define SANYO_ZERO_MARK 700 // seen 700 #define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround #define SANYO_RPT_LENGTH 45000 @@ -115,21 +136,21 @@ // Mitsubishi RM 75501 // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 -// #define MITSUBISHI_HDR_MARK 250 // seen range 3500 -#define MITSUBISHI_HDR_SPACE 350 // 7*50+100 -#define MITSUBISHI_ONE_MARK 1950 // 41*50-100 +// #define MITSUBISHI_HDR_MARK 250 // seen range 3500 +#define MITSUBISHI_HDR_SPACE 350 // 7*50+100 +#define MITSUBISHI_ONE_MARK 1950 // 41*50-100 #define MITSUBISHI_ZERO_MARK 750 // 17*50-100 // #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround // #define MITSUBISHI_RPT_LENGTH 45000 -#define RC5_T1 889 -#define RC5_RPT_LENGTH 46000 +#define RC5_T1 889 +#define RC5_RPT_LENGTH 46000 -#define RC6_HDR_MARK 2666 -#define RC6_HDR_SPACE 889 -#define RC6_T1 444 -#define RC6_RPT_LENGTH 46000 +#define RC6_HDR_MARK 2666 +#define RC6_HDR_SPACE 889 +#define RC6_T1 444 +#define RC6_RPT_LENGTH 46000 #define SHARP_BIT_MARK 245 #define SHARP_ONE_SPACE 1805 @@ -264,7 +285,13 @@ extern volatile irparams_t irparams; #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) #define TIMER_DISABLE_INTR (TIMSK1 = 0) #endif -#define TIMER_INTR_NAME TIMER1_COMPA_vect + +#if defined(__AVR_ATtinyX4__) + #define TIMER_INTR_NAME TIM1_COMPA_vect +#else // for attiny85 + #define TIMER_INTR_NAME TIMER1_COMPA_vect +#endif + #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR1A = _BV(WGM11); \ @@ -284,6 +311,8 @@ extern volatile irparams_t irparams; #define TIMER_PWM_PIN 11 /* Arduino Mega */ #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #define TIMER_PWM_PIN 13 /* Sanguino */ +#elif defined(__AVR_ATtinyX4__) +#define TIMER_PWM_PIN 6 /* ATTiny84 */ #else #define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ #endif @@ -418,6 +447,28 @@ extern volatile irparams_t irparams; #error "Please add OC5A pin number here\n" #endif +// defines for timer5 (16 bits) +#elif defined(IR_ATTINY_85) + +#define TIMER_RESET TCNT1 = (CLK - USECPERTICK*CLKSPERUSEC + CLKFUDGE) +#define TIMER_ENABLE_PWM TCCR1 |= _BV(COM0B1) // Enable pin 3 PWM output +#define TIMER_DISABLE_PWM TCCR1 &= ~(_BV(COM0B1)) // Disable pin 3 PWM output +#define TIMER_ENABLE_INTR //sbi(TIMSK,TOIE0); //Timer2 Overflow Interrupt Enable +#define TIMER_DISABLE_INTR TIMSK &= ~_BV(TOIE0) //Timer2 Overflow Interrupt +#define TIMER_INTR_NAME TIMER1_OVF_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 1000 / (val); \ + TCCR1 = _BV(CTC1) | _BV(CS13); \ + OCR1C = SYSCLOCK / 2 / pwmval / 1000; \ + OCR1A = OCR1A / 3; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR1 = _BV(CTC1) | _BV(CS13); \ + OCR1C = 24; \ + OCR1A = 0; \ +}) +#define TIMER_PWM_PIN 3 /* ATTiny85 */ #else // unknown timer #error "Internal code configuration error, no known IR_USE_TIMER# defined\n" diff --git a/libraries/RobotIRremote/IRremoteTools.cpp b/libraries/RobotIRremote/IRremoteTools.cpp index 4cd6d569e6c..9747eb3ee83 100644 --- a/libraries/RobotIRremote/IRremoteTools.cpp +++ b/libraries/RobotIRremote/IRremoteTools.cpp @@ -2,6 +2,7 @@ #include "IRremoteTools.h" #include +#ifdef AVR_ROBOT_CONTROL || AVR_ROBOT_MOTOR int RECV_PIN = TKD2; // the pin the IR receiver is connected to IRrecv irrecv(RECV_PIN); // an instance of the IR receiver object decode_results results; // container for received IR codes @@ -20,4 +21,5 @@ void resumeIRremote(){ unsigned long getIRresult(){ return results.value; -} \ No newline at end of file +} +#endif \ No newline at end of file From 138cf501ef57cc9a661ccde6d43152d591a5633d Mon Sep 17 00:00:00 2001 From: Joshua Noble Date: Wed, 16 Jul 2014 11:22:22 -0700 Subject: [PATCH 2/2] removing misleading comment --- libraries/RobotIRremote/IRremoteInt.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/RobotIRremote/IRremoteInt.h b/libraries/RobotIRremote/IRremoteInt.h index f2d424e9300..8352d635a37 100644 --- a/libraries/RobotIRremote/IRremoteInt.h +++ b/libraries/RobotIRremote/IRremoteInt.h @@ -28,8 +28,6 @@ // are using another library which uses timer2, you have options // to switch IRremote to use a different timer. -//#define __AVR_ATtinyX5__ - // Arduino Mega #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //#define IR_USE_TIMER1 // tx = pin 11