Commenting formatting

move ISR macros to ISR header
This commit is contained in:
Bluechip
2015-06-20 17:54:18 +01:00
parent 7b8444a305
commit 5d994880b9
2 changed files with 362 additions and 294 deletions

View File

@@ -220,14 +220,4 @@ public:
VIRTUAL void space(int usec); VIRTUAL void space(int usec);
} ; } ;
//------------------------------------------------------------------------------
// Some useful constants
#define USECPERTICK 50 // microseconds per clock interrupt tick
#define RAWBUF 100 // Length of raw duration buffer
// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.
#define MARK_EXCESS 100
#endif #endif

View File

@@ -1,23 +1,34 @@
/* //******************************************************************************
* IRremote // IRremote
* Version 0.1 July, 2009 // Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff // Copyright 2009 Ken Shirriff
* For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
* //
* Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers // Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
* //
* Interrupt code based on NECIRrcv by Joe Knapp // Interrupt code based on NECIRrcv by Joe Knapp
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
* Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ // Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
* //
* JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) // JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
* Whynter A/C ARC-110WD added by Francesco Meschia // Whynter A/C ARC-110WD added by Francesco Meschia
*/ //******************************************************************************
#ifndef IRremoteint_h #ifndef IRremoteint_h
#define IRremoteint_h #define IRremoteint_h
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Include the right Arduino header
//
#if defined(ARDUINO) && (ARDUINO >= 100)
# include <Arduino.h>
#else
# include <WProgram.h>
#endif
//------------------------------------------------------------------------------
// This handles definition and access to global variables
//
#ifdef IR_GLOBAL #ifdef IR_GLOBAL
# define EXTERN # define EXTERN
#else #else
@@ -25,227 +36,274 @@
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if defined(ARDUINO) && ARDUINO >= 100 // Information for the Interrupt Service Routine
#include <Arduino.h> //
#define RAWBUF 100 // Maximum length of raw duration buffer
typedef
struct {
// The fields are ordered to reduce memory over caused by struct-padding
uint8_t rcvstate; // State Machine state
uint8_t recvpin; // Pin connected to IR data from detector
uint8_t blinkflag; // true -> enable blinking of pin 13 on IR processing
uint8_t rawlen; // counter of entries in rawbuf
unsigned int timer; // State timer, counts 50uS ticks.
unsigned int rawbuf[RAWBUF]; // raw data
uint8_t overflow; // Raw buffer overflow occurred
}
irparams_t;
// ISR State-Machine : Receiver States
#define STATE_IDLE 2
#define STATE_MARK 3
#define STATE_SPACE 4
#define STATE_STOP 5
#define STATE_OVERFLOW 6
// Allow all parts of the code access to the ISR data
// NB. The data can be changed by the ISR at any time, even mid-function
// Therefore we declare it as "volatile" to stop the compiler/CPU caching it
EXTERN volatile irparams_t irparams;
//------------------------------------------------------------------------------
// Defines for blinking the LED
//
#if defined(CORE_LED0_PIN)
# define BLINKLED CORE_LED0_PIN
# define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
# define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
# define BLINKLED 13
# define BLINKLED_ON() (PORTB |= B10000000)
# define BLINKLED_OFF() (PORTB &= B01111111)
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
# define BLINKLED 0
# define BLINKLED_ON() (PORTD |= B00000001)
# define BLINKLED_OFF() (PORTD &= B11111110)
#else #else
#include <WProgram.h> # define BLINKLED 13
#define BLINKLED_ON() (PORTB |= B00100000)
# define BLINKLED_OFF() (PORTB &= B11011111)
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// define which timer to use // CPU Frequency
//
#ifdef F_CPU
# define SYSCLOCK F_CPU // main Arduino clock
#else
# define SYSCLOCK 16000000 // main Arduino clock
#endif
//------------------------------------------------------------------------------
// Defines for setting and clearing register bits
//
#ifndef cbi
# define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
# define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
//------------------------------------------------------------------------------
// Pulse parms are ((X*50)-100) for the Mark and ((X*50)+100) for the Space.
// First MARK is the one after the long gap
// Pulse parameters in uSec
//
// Due to sensor lag, when received, Marks tend to be 100us too long and
// Spaces tend to be 100us too short
#define MARK_EXCESS 100
// microseconds per clock interrupt tick
#define USECPERTICK 50
// Upper and Lower percentage tolerances in measurements
#define TOLERANCE 25
#define LTOL (1.0 - (TOLERANCE/100.))
#define UTOL (1.0 + (TOLERANCE/100.))
// Minimum gap between IR transmissions
#define _GAP 5000
#define GAP_TICKS (_GAP/USECPERTICK)
#define TICKS_LOW(us) ((int)(((us)*LTOL/USECPERTICK)))
#define TICKS_HIGH(us) ((int)(((us)*UTOL/USECPERTICK + 1)))
//------------------------------------------------------------------------------
// IR detector output is active low
//
#define MARK 0
#define SPACE 1
//------------------------------------------------------------------------------
// Define which timer to use
//
// Uncomment the timer you wish to use on your board.
// If you are using another library which uses timer2, you have options to
// switch IRremote to use a different timer.
// //
// Uncomment the timer you wish to use on your board. If you
// are using another library which uses timer2, you have options
// to switch IRremote to use a different timer.
// Arduino Mega // Arduino Mega
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//#define IR_USE_TIMER1 // tx = pin 11 //#define IR_USE_TIMER1 // tx = pin 11
#define IR_USE_TIMER2 // tx = pin 9 #define IR_USE_TIMER2 // tx = pin 9
//#define IR_USE_TIMER3 // tx = pin 5 //#define IR_USE_TIMER3 // tx = pin 5
//#define IR_USE_TIMER4 // tx = pin 6 //#define IR_USE_TIMER4 // tx = pin 6
//#define IR_USE_TIMER5 // tx = pin 46 //#define IR_USE_TIMER5 // tx = pin 46
// Teensy 1.0 // Teensy 1.0
#elif defined(__AVR_AT90USB162__) #elif defined(__AVR_AT90USB162__)
#define IR_USE_TIMER1 // tx = pin 17 #define IR_USE_TIMER1 // tx = pin 17
// Teensy 2.0 // Teensy 2.0
#elif defined(__AVR_ATmega32U4__) #elif defined(__AVR_ATmega32U4__)
//#define IR_USE_TIMER1 // tx = pin 14 //#define IR_USE_TIMER1 // tx = pin 14
//#define IR_USE_TIMER3 // tx = pin 9 //#define IR_USE_TIMER3 // tx = pin 9
#define IR_USE_TIMER4_HS // tx = pin 10 #define IR_USE_TIMER4_HS // tx = pin 10
// Teensy 3.0 // Teensy 3.0
#elif defined(__MK20DX128__) #elif defined(__MK20DX128__)
#define IR_USE_TIMER_CMT // tx = pin 5 #define IR_USE_TIMER_CMT // tx = pin 5
// Teensy++ 1.0 & 2.0 // Teensy++ 1.0 & 2.0
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
//#define IR_USE_TIMER1 // tx = pin 25 //#define IR_USE_TIMER1 // tx = pin 25
#define IR_USE_TIMER2 // tx = pin 1 #define IR_USE_TIMER2 // tx = pin 1
//#define IR_USE_TIMER3 // tx = pin 16 //#define IR_USE_TIMER3 // tx = pin 16
// Sanguino // Sanguino
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
//#define IR_USE_TIMER1 // tx = pin 13 //#define IR_USE_TIMER1 // tx = pin 13
#define IR_USE_TIMER2 // tx = pin 14 #define IR_USE_TIMER2 // tx = pin 14
// Atmega8 // Atmega8
#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
#define IR_USE_TIMER1 // tx = pin 9 #define IR_USE_TIMER1 // tx = pin 9
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
#else #else
//#define IR_USE_TIMER1 // tx = pin 9 //#define IR_USE_TIMER1 // tx = pin 9
#define IR_USE_TIMER2 // tx = pin 3 #define IR_USE_TIMER2 // tx = pin 3
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifdef F_CPU // Defines for Timer
#define SYSCLOCK F_CPU // main Arduino clock
#else
#define SYSCLOCK 16000000 // main Arduino clock
#endif
//------------------------------------------------------------------------------ //---------------------------------------------------------
#define ERR 0 // Timer2 (8 bits)
#define DECODED 1 //
//------------------------------------------------------------------------------
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
//------------------------------------------------------------------------------
// 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 TOLERANCE 25 // percent tolerance in measurements
#define LTOL (1.0 - TOLERANCE/100.)
#define UTOL (1.0 + TOLERANCE/100.)
#define _GAP 5000 // Minimum map between transmissions
#define GAP_TICKS (_GAP/USECPERTICK)
#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
// receiver states
#define STATE_IDLE 2
#define STATE_MARK 3
#define STATE_SPACE 4
#define STATE_STOP 5
// information for the interrupt handler
typedef struct {
uint8_t recvpin; // pin for IR data from detector
uint8_t rcvstate; // state machine
uint8_t blinkflag; // TRUE to enable blinking of pin 13 on IR processing
unsigned int timer; // state timer, counts 50uS ticks.
unsigned int rawbuf[RAWBUF]; // raw data
uint8_t rawlen; // counter of entries in rawbuf
}
irparams_t;
// Defined in IRremote.cpp
EXTERN volatile irparams_t irparams;
// IR detector output is active low
#define MARK 0
#define SPACE 1
#define TOPBIT 0x80000000
// defines for timer2 (8 bits)
#if defined(IR_USE_TIMER2) #if defined(IR_USE_TIMER2)
#define TIMER_RESET #define TIMER_RESET
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
#define TIMER_DISABLE_INTR (TIMSK2 = 0) #define TIMER_DISABLE_INTR (TIMSK2 = 0)
#define TIMER_INTR_NAME TIMER2_COMPA_vect #define TIMER_INTR_NAME TIMER2_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \ #define TIMER_CONFIG_KHZ(val) ({ \
const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR2A = _BV(WGM20); \ TCCR2A = _BV(WGM20); \
TCCR2B = _BV(WGM22) | _BV(CS20); \ TCCR2B = _BV(WGM22) | _BV(CS20); \
OCR2A = pwmval; \ OCR2A = pwmval; \
OCR2B = pwmval / 3; \ OCR2B = pwmval / 3; \
}) })
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
//-----------------
#if (TIMER_COUNT_TOP < 256) #if (TIMER_COUNT_TOP < 256)
#define TIMER_CONFIG_NORMAL() ({ \ # define TIMER_CONFIG_NORMAL() ({ \
TCCR2A = _BV(WGM21); \ TCCR2A = _BV(WGM21); \
TCCR2B = _BV(CS20); \ TCCR2B = _BV(CS20); \
OCR2A = TIMER_COUNT_TOP; \ OCR2A = TIMER_COUNT_TOP; \
TCNT2 = 0; \ TCNT2 = 0; \
}) })
#else #else
#define TIMER_CONFIG_NORMAL() ({ \ # define TIMER_CONFIG_NORMAL() ({ \
TCCR2A = _BV(WGM21); \ TCCR2A = _BV(WGM21); \
TCCR2B = _BV(CS21); \ TCCR2B = _BV(CS21); \
OCR2A = TIMER_COUNT_TOP / 8; \ OCR2A = TIMER_COUNT_TOP / 8; \
TCNT2 = 0; \ TCNT2 = 0; \
}) })
#endif #endif
//-----------------
#if defined(CORE_OC2B_PIN) #if defined(CORE_OC2B_PIN)
#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */ # define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 9 /* Arduino Mega */ # define TIMER_PWM_PIN 9 // Arduino Mega
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN 14 /* Sanguino */ # define TIMER_PWM_PIN 14 // Sanguino
#else #else
#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ # define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
#endif #endif
//---------------------------------------------------------
// defines for timer1 (16 bits) // Timer1 (16 bits)
//
#elif defined(IR_USE_TIMER1) #elif defined(IR_USE_TIMER1)
#define TIMER_RESET #define TIMER_RESET
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) #define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) #define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
//-----------------
#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) # define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A))
#define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) # define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A))
#else #else
#define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) # define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
#define TIMER_DISABLE_INTR (TIMSK1 = 0) # define TIMER_DISABLE_INTR (TIMSK1 = 0)
#endif #endif
#define TIMER_INTR_NAME TIMER1_COMPA_vect
//-----------------
#define TIMER_INTR_NAME TIMER1_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \ #define TIMER_CONFIG_KHZ(val) ({ \
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR1A = _BV(WGM11); \ TCCR1A = _BV(WGM11); \
TCCR1B = _BV(WGM13) | _BV(CS10); \ TCCR1B = _BV(WGM13) | _BV(CS10); \
ICR1 = pwmval; \ ICR1 = pwmval; \
OCR1A = pwmval / 3; \ OCR1A = pwmval / 3; \
}) })
#define TIMER_CONFIG_NORMAL() ({ \ #define TIMER_CONFIG_NORMAL() ({ \
TCCR1A = 0; \ TCCR1A = 0; \
TCCR1B = _BV(WGM12) | _BV(CS10); \ TCCR1B = _BV(WGM12) | _BV(CS10); \
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
TCNT1 = 0; \ TCNT1 = 0; \
}) })
//-----------------
#if defined(CORE_OC1A_PIN) #if defined(CORE_OC1A_PIN)
#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */ # define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 11 /* Arduino Mega */ # define TIMER_PWM_PIN 11 // Arduino Mega
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
#define TIMER_PWM_PIN 13 /* Sanguino */ # define TIMER_PWM_PIN 13 // Sanguino
#else #else
#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ # define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
#endif #endif
//---------------------------------------------------------
// defines for timer3 (16 bits) // Timer3 (16 bits)
//
#elif defined(IR_USE_TIMER3) #elif defined(IR_USE_TIMER3)
#define TIMER_RESET #define TIMER_RESET
#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) #define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) #define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) #define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
#define TIMER_DISABLE_INTR (TIMSK3 = 0) #define TIMER_DISABLE_INTR (TIMSK3 = 0)
#define TIMER_INTR_NAME TIMER3_COMPA_vect #define TIMER_INTR_NAME TIMER3_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \ #define TIMER_CONFIG_KHZ(val) ({ \
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR3A = _BV(WGM31); \ TCCR3A = _BV(WGM31); \
@@ -253,69 +311,81 @@ EXTERN volatile irparams_t irparams;
ICR3 = pwmval; \ ICR3 = pwmval; \
OCR3A = pwmval / 3; \ OCR3A = pwmval / 3; \
}) })
#define TIMER_CONFIG_NORMAL() ({ \ #define TIMER_CONFIG_NORMAL() ({ \
TCCR3A = 0; \ TCCR3A = 0; \
TCCR3B = _BV(WGM32) | _BV(CS30); \ TCCR3B = _BV(WGM32) | _BV(CS30); \
OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
TCNT3 = 0; \ TCNT3 = 0; \
}) })
//-----------------
#if defined(CORE_OC3A_PIN) #if defined(CORE_OC3A_PIN)
#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */ # define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 5 /* Arduino Mega */ # define TIMER_PWM_PIN 5 // Arduino Mega
#else #else
#error "Please add OC3A pin number here\n" # error "Please add OC3A pin number here\n"
#endif #endif
//---------------------------------------------------------
// defines for timer4 (10 bits, high speed option) // Timer4 (10 bits, high speed option)
//
#elif defined(IR_USE_TIMER4_HS) #elif defined(IR_USE_TIMER4_HS)
#define TIMER_RESET #define TIMER_RESET
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) #define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
#define TIMER_DISABLE_INTR (TIMSK4 = 0) #define TIMER_DISABLE_INTR (TIMSK4 = 0)
#define TIMER_INTR_NAME TIMER4_OVF_vect #define TIMER_INTR_NAME TIMER4_OVF_vect
#define TIMER_CONFIG_KHZ(val) ({ \ #define TIMER_CONFIG_KHZ(val) ({ \
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR4A = (1<<PWM4A); \ TCCR4A = (1<<PWM4A); \
TCCR4B = _BV(CS40); \ TCCR4B = _BV(CS40); \
TCCR4C = 0; \ TCCR4C = 0; \
TCCR4D = (1<<WGM40); \ TCCR4D = (1<<WGM40); \
TCCR4E = 0; \ TCCR4E = 0; \
TC4H = pwmval >> 8; \ TC4H = pwmval >> 8; \
OCR4C = pwmval; \ OCR4C = pwmval; \
TC4H = (pwmval / 3) >> 8; \ TC4H = (pwmval / 3) >> 8; \
OCR4A = (pwmval / 3) & 255; \ OCR4A = (pwmval / 3) & 255; \
}) })
#define TIMER_CONFIG_NORMAL() ({ \ #define TIMER_CONFIG_NORMAL() ({ \
TCCR4A = 0; \ TCCR4A = 0; \
TCCR4B = _BV(CS40); \ TCCR4B = _BV(CS40); \
TCCR4C = 0; \ TCCR4C = 0; \
TCCR4D = 0; \ TCCR4D = 0; \
TCCR4E = 0; \ TCCR4E = 0; \
TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
TC4H = 0; \ TC4H = 0; \
TCNT4 = 0; \ TCNT4 = 0; \
}) })
//-----------------
#if defined(CORE_OC4A_PIN) #if defined(CORE_OC4A_PIN)
#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */ # define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy
#elif defined(__AVR_ATmega32U4__) #elif defined(__AVR_ATmega32U4__)
#define TIMER_PWM_PIN 13 /* Leonardo */ # define TIMER_PWM_PIN 13 // Leonardo
#else #else
#error "Please add OC4A pin number here\n" # error "Please add OC4A pin number here\n"
#endif #endif
//---------------------------------------------------------
// defines for timer4 (16 bits) // Timer4 (16 bits)
//
#elif defined(IR_USE_TIMER4) #elif defined(IR_USE_TIMER4)
#define TIMER_RESET #define TIMER_RESET
#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) #define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
#define TIMER_DISABLE_INTR (TIMSK4 = 0) #define TIMER_DISABLE_INTR (TIMSK4 = 0)
#define TIMER_INTR_NAME TIMER4_COMPA_vect #define TIMER_INTR_NAME TIMER4_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \ #define TIMER_CONFIG_KHZ(val) ({ \
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR4A = _BV(WGM41); \ TCCR4A = _BV(WGM41); \
@@ -323,29 +393,35 @@ EXTERN volatile irparams_t irparams;
ICR4 = pwmval; \ ICR4 = pwmval; \
OCR4A = pwmval / 3; \ OCR4A = pwmval / 3; \
}) })
#define TIMER_CONFIG_NORMAL() ({ \ #define TIMER_CONFIG_NORMAL() ({ \
TCCR4A = 0; \ TCCR4A = 0; \
TCCR4B = _BV(WGM42) | _BV(CS40); \ TCCR4B = _BV(WGM42) | _BV(CS40); \
OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
TCNT4 = 0; \ TCNT4 = 0; \
}) })
//-----------------
#if defined(CORE_OC4A_PIN) #if defined(CORE_OC4A_PIN)
#define TIMER_PWM_PIN CORE_OC4A_PIN # define TIMER_PWM_PIN CORE_OC4A_PIN
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 6 /* Arduino Mega */ # define TIMER_PWM_PIN 6 // Arduino Mega
#else #else
#error "Please add OC4A pin number here\n" # error "Please add OC4A pin number here\n"
#endif #endif
//---------------------------------------------------------
// defines for timer5 (16 bits) // Timer5 (16 bits)
//
#elif defined(IR_USE_TIMER5) #elif defined(IR_USE_TIMER5)
#define TIMER_RESET #define TIMER_RESET
#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) #define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) #define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) #define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
#define TIMER_DISABLE_INTR (TIMSK5 = 0) #define TIMER_DISABLE_INTR (TIMSK5 = 0)
#define TIMER_INTR_NAME TIMER5_COMPA_vect #define TIMER_INTR_NAME TIMER5_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \ #define TIMER_CONFIG_KHZ(val) ({ \
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR5A = _BV(WGM51); \ TCCR5A = _BV(WGM51); \
@@ -353,91 +429,93 @@ EXTERN volatile irparams_t irparams;
ICR5 = pwmval; \ ICR5 = pwmval; \
OCR5A = pwmval / 3; \ OCR5A = pwmval / 3; \
}) })
#define TIMER_CONFIG_NORMAL() ({ \ #define TIMER_CONFIG_NORMAL() ({ \
TCCR5A = 0; \ TCCR5A = 0; \
TCCR5B = _BV(WGM52) | _BV(CS50); \ TCCR5B = _BV(WGM52) | _BV(CS50); \
OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
TCNT5 = 0; \ TCNT5 = 0; \
}) })
//-----------------
#if defined(CORE_OC5A_PIN) #if defined(CORE_OC5A_PIN)
#define TIMER_PWM_PIN CORE_OC5A_PIN # define TIMER_PWM_PIN CORE_OC5A_PIN
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define TIMER_PWM_PIN 46 /* Arduino Mega */ # define TIMER_PWM_PIN 46 // Arduino Mega
#else #else
#error "Please add OC5A pin number here\n" # error "Please add OC5A pin number here\n"
#endif #endif
//---------------------------------------------------------
// defines for special carrier modulator timer // Special carrier modulator timer
//
#elif defined(IR_USE_TIMER_CMT) #elif defined(IR_USE_TIMER_CMT)
#define TIMER_RESET ({ \
uint8_t tmp = CMT_MSC; \ #define TIMER_RESET ({ \
CMT_CMD2 = 30; \ uint8_t tmp = CMT_MSC; \
CMT_CMD2 = 30; \
}) })
#define TIMER_ENABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_DSE|PORT_PCR_SRE
#define TIMER_DISABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE #define TIMER_ENABLE_PWM do { \
#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \
#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) } while(0)
#define TIMER_INTR_NAME cmt_isr
#define TIMER_DISABLE_PWM do { \
CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \
} while(0)
#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT)
#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT)
#define TIMER_INTR_NAME cmt_isr
//-----------------
#ifdef ISR #ifdef ISR
#undef ISR # undef ISR
#endif #endif
#define ISR(f) void f(void) #define ISR(f) void f(void)
#if F_BUS == 48000000
#define CMT_PPS_VAL 5 //-----------------
#if (F_BUS == 48000000)
# define CMT_PPS_VAL 5
#else #else
#define CMT_PPS_VAL 2 # define CMT_PPS_VAL 2
#endif
#define TIMER_CONFIG_KHZ(val) ({ \
SIM_SCGC4 |= SIM_SCGC4_CMT; \
SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \
CMT_PPS = CMT_PPS_VAL; \
CMT_CGH1 = 2667 / val; \
CMT_CGL1 = 5333 / val; \
CMT_CMD1 = 0; \
CMT_CMD2 = 30; \
CMT_CMD3 = 0; \
CMT_CMD4 = 0; \
CMT_OC = 0x60; \
CMT_MSC = 0x01; \
})
#define TIMER_CONFIG_NORMAL() ({ \
SIM_SCGC4 |= SIM_SCGC4_CMT; \
CMT_PPS = CMT_PPS_VAL; \
CMT_CGH1 = 1; \
CMT_CGL1 = 1; \
CMT_CMD1 = 0; \
CMT_CMD2 = 30; \
CMT_CMD3 = 0; \
CMT_CMD4 = 19; \
CMT_OC = 0; \
CMT_MSC = 0x03; \
})
#define TIMER_PWM_PIN 5
#else // unknown timer
#error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
#endif #endif
//-----------------
#define TIMER_CONFIG_KHZ(val) ({ \
SIM_SCGC4 |= SIM_SCGC4_CMT; \
SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \
CMT_PPS = CMT_PPS_VAL; \
CMT_CGH1 = 2667 / val; \
CMT_CGL1 = 5333 / val; \
CMT_CMD1 = 0; \
CMT_CMD2 = 30; \
CMT_CMD3 = 0; \
CMT_CMD4 = 0; \
CMT_OC = 0x60; \
CMT_MSC = 0x01; \
})
// defines for blinking the LED #define TIMER_CONFIG_NORMAL() ({ \
#if defined(CORE_LED0_PIN) SIM_SCGC4 |= SIM_SCGC4_CMT; \
#define BLINKLED CORE_LED0_PIN CMT_PPS = CMT_PPS_VAL; \
#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH)) CMT_CGH1 = 1; \
#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW)) CMT_CGL1 = 1; \
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) CMT_CMD1 = 0; \
#define BLINKLED 13 CMT_CMD2 = 30 \
#define BLINKLED_ON() (PORTB |= B10000000) CMT_CMD3 = 0; \
#define BLINKLED_OFF() (PORTB &= B01111111) CMT_CMD4 = 19; \
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) CMT_OC = 0; \
#define BLINKLED 0 CMT_MSC = 0x03; \
#define BLINKLED_ON() (PORTD |= B00000001) })
#define BLINKLED_OFF() (PORTD &= B11111110)
#define TIMER_PWM_PIN 5
//---------------------------------------------------------
// Unknown Timer
//
#else #else
#define BLINKLED 13 # error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
#define BLINKLED_ON() (PORTB |= B00100000)
#define BLINKLED_OFF() (PORTB &= B11011111)
#endif #endif
#endif #endif // IRremoteint_h