2 Commits

Author SHA1 Message Date
Rafi Khan
e1768b4deb Added changelog info 2017-08-10 17:01:44 -06:00
Rafi Khan
679348568d merge #437 2017-08-10 16:57:54 -06:00
12 changed files with 347 additions and 136 deletions

View File

@@ -18,5 +18,7 @@ These are the active contributors of this project that you may contact if there
- [philipphenkel](https://github.com/philipphenkel): Active Contributor
- [MCUdude](https://github.com/MCUdude): Contributor
- [marcmerlin](https://github.com/marcmerlin): Contributor (ESP32 port)
- [bengtmartensson](https://github.com/bengtmartensson): Active Contributor
- [MrBryonMiller](https://github.com/MrBryonMiller): Contributor
Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed.

View File

@@ -24,7 +24,7 @@
# include "IRremoteInt.h"
#undef IR_GLOBAL
#ifndef IR_TIMER_USE_ESP32
#ifdef HAS_AVR_INTERRUPT_H
#include <avr/interrupt.h>
#endif
@@ -123,11 +123,7 @@ int MATCH_SPACE (int measured_ticks, int desired_us)
// As soon as first MARK arrives:
// Gap width is recorded; Ready is cleared; New logging starts
//
#ifdef IR_TIMER_USE_ESP32
void IRTimer()
#else
ISR (TIMER_INTR_NAME)
#endif
{
TIMER_RESET;
@@ -189,6 +185,7 @@ ISR (TIMER_INTR_NAME)
break;
}
#ifdef BLINKLED
// If requested, flash LED while receiving IR data
if (irparams.blinkflag) {
if (irdata == MARK)
@@ -197,4 +194,5 @@ ISR (TIMER_INTR_NAME)
else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on
else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on
}
#endif // BLINKLED
}

View File

@@ -259,7 +259,18 @@ class IRrecv
class IRsend
{
public:
IRsend () { }
#ifdef USE_SOFT_CARRIER
IRsend(int pin = SEND_PIN)
{
sendPin = pin;
}
#else
IRsend()
{
}
#endif
void custom_delay_usec (unsigned long uSecs);
void enableIROut (int khz) ;
@@ -270,7 +281,6 @@ class IRsend
//......................................................................
# if SEND_RC5
void sendRC5 (unsigned long data, int nbits) ;
void sendRC5ext (unsigned long addr, unsigned long cmd, boolean toggle);
# endif
# if SEND_RC6
void sendRC6 (unsigned long data, int nbits) ;
@@ -340,6 +350,20 @@ class IRsend
# if SEND_LEGO_PF
void sendLegoPowerFunctions (uint16_t data, bool repeat = true) ;
# endif
#ifdef USE_SOFT_CARRIER
private:
int sendPin;
unsigned int periodTime;
unsigned int periodOnTime;
void sleepMicros(unsigned long us);
void sleepUntilMicros(unsigned long targetTime);
#else
const int sendPin = SEND_PIN;
#endif
} ;
#endif

View File

@@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui
Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/).
## Version - 2.4.3
## Version - 2.4.0b
## Installation
1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page.
@@ -43,7 +43,7 @@ We are open to suggestions for adding support to new boards, however we highly r
| [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **6** | **1** |
| [ATtiny85](https://github.com/SpenceKonde/ATTinyCore) | **1** | **TINY0** |
| [ATmega8](https://github.com/MCUdude/MiniCore) | **9** | **1** |
| Atmega32u4 | 5, **9**, 13 | 1, 3, **4** |
| Atmega32u4 | 5, 9, **13** | 1, 3, **4** |
| [ATmega48, ATmega88, ATmega168, ATmega328](https://github.com/MCUdude/MiniCore) | **3**, 9 | 1, **2** |
| [ATmega1284](https://github.com/MCUdude/MightyCore) | 13, 14, 6 | 1, **2**, 3 |
| [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 13, **14** | 1, **2** |

View File

@@ -20,6 +20,32 @@
#ifndef boarddefs_h
#define boarddefs_h
// Define some defaults, that some boards may like to override
// (This is to avoid negative logic, ! DONT_... is just awkward.)
// This board has/needs the avr/interrupt.h
#define HAS_AVR_INTERRUPT_H
// Define if sending is supported
#define SENDING_SUPPORTED
// If defined, a standard enableIRIn function will be define.
// Undefine for boards supplying their own.
#define USE_DEFAULT_ENABLE_IR_IN
// Duty cycle in percent for sent signals. Presently takes effect only with USE_SOFT_CARRIER
#define DUTY_CYCLE 50
// If USE_SOFT_CARRIER, this amount (in micro seconds) is subtracted from the
// on-time of the pulses.
#define PULSE_CORRECTION 3
// digitalWrite is supposed to be slow. If this is an issue, define faster,
// board-dependent versions of these macros SENDPIN_ON(pin) and SENDPIN_OFF(pin).
// Portable, possibly slow, default definitions are given at the end of this file.
// If defining new versions, feel free to ignore the pin argument if it
// is not configurable on the current board.
//------------------------------------------------------------------------------
// Defines for blinking the LED
//
@@ -39,11 +65,31 @@
# define BLINKLED_ON() (PORTD |= B00000001)
# define BLINKLED_OFF() (PORTD &= B11111110)
// No system LED on ESP32, disable blinking
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
# define BLINKLED LED_BUILTIN
# define BLINKLED_ON() (digitalWrite(LED_BUILTIN, HIGH))
# define BLINKLED_OFF() (digitalWrite(LED_BUILTIN, LOW))
# define USE_SOFT_CARRIER
// Define to use spin wait instead of delayMicros()
//# define USE_SPIN_WAIT
# undef USE_DEFAULT_ENABLE_IR_IN
// The default pin used used for sending.
# define SEND_PIN 9
#elif defined(ESP32)
# define BLINKLED 255
# define BLINKLED_ON() 1
# define BLINKLED_OFF() 1
// No system LED on ESP32, disable blinking by NOT defining BLINKLED
// avr/interrupt.h is not present
# undef HAS_AVR_INTERRUPT_H
// Sending not implemented
# undef SENDING_SUPPORTED#
// Supply own enbleIRIn
# undef USE_DEFAULT_ENABLE_IR_IN
#else
# define BLINKLED 13
# define BLINKLED_ON() (PORTB |= B00100000)
@@ -85,8 +131,8 @@
// Teensy 2.0
#elif defined(__AVR_ATmega32U4__)
//#define IR_USE_TIMER1 // tx = pin 14
#define IR_USE_TIMER3 // tx = pin 9
//#define IR_USE_TIMER4_HS // tx = pin 10
//#define IR_USE_TIMER3 // tx = pin 9
#define IR_USE_TIMER4_HS // tx = pin 10
// Teensy 3.0 / Teensy 3.1
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
@@ -138,6 +184,10 @@
#elif defined(ESP32)
#define IR_TIMER_USE_ESP32
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
#define TIMER_PRESCALER_DIV 64
#else
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
// ATmega48, ATmega88, ATmega168, ATmega328
@@ -190,17 +240,17 @@
//-----------------
#if defined(CORE_OC2B_PIN)
# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy
# define SEND_PIN CORE_OC2B_PIN // Teensy
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
# define TIMER_PWM_PIN 9 // Arduino Mega
# define SEND_PIN 9 // Arduino Mega
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
|| defined(__AVR_ATmega164P__)
# define TIMER_PWM_PIN 14 // MightyCore
# define SEND_PIN 14 // MightyCore
#else
# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
# define SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
#endif // ATmega48, ATmega88, ATmega168, ATmega328
//---------------------------------------------------------
@@ -243,22 +293,22 @@
//-----------------
#if defined(CORE_OC1A_PIN)
# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy
# define SEND_PIN CORE_OC1A_PIN // Teensy
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
# define TIMER_PWM_PIN 11 // Arduino Mega
# define SEND_PIN 11 // Arduino Mega
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
# define TIMER_PWM_PIN 13 // MegaCore
# define SEND_PIN 13 // MegaCore
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__)
# define TIMER_PWM_PIN 13 // MightyCore
# define SEND_PIN 13 // MightyCore
#elif defined(__AVR_ATtiny84__)
# define TIMER_PWM_PIN 6
# define SEND_PIN 6
#else
# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
# define SEND_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
#endif // ATmega48, ATmega88, ATmega168, ATmega328
//---------------------------------------------------------
@@ -290,11 +340,11 @@
//-----------------
#if defined(CORE_OC3A_PIN)
# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy
# define SEND_PIN CORE_OC3A_PIN // Teensy
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
# define TIMER_PWM_PIN 5 // Arduino Mega
# define SEND_PIN 5 // Arduino Mega
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
# define TIMER_PWM_PIN 6 // MightyCore
# define SEND_PIN 6 // MightyCore
#else
# error "Please add OC3A pin number here\n"
#endif
@@ -338,9 +388,9 @@
//-----------------
#if defined(CORE_OC4A_PIN)
# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy
# define SEND_PIN CORE_OC4A_PIN // Teensy
#elif defined(__AVR_ATmega32U4__)
# define TIMER_PWM_PIN 13 // Leonardo
# define SEND_PIN 13 // Leonardo
#else
# error "Please add OC4A pin number here\n"
#endif
@@ -374,9 +424,9 @@
//-----------------
#if defined(CORE_OC4A_PIN)
# define TIMER_PWM_PIN CORE_OC4A_PIN
# define SEND_PIN CORE_OC4A_PIN
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
# define TIMER_PWM_PIN 6 // Arduino Mega
# define SEND_PIN 6 // Arduino Mega
#else
# error "Please add OC4A pin number here\n"
#endif
@@ -410,9 +460,9 @@
//-----------------
#if defined(CORE_OC5A_PIN)
# define TIMER_PWM_PIN CORE_OC5A_PIN
# define SEND_PIN CORE_OC5A_PIN
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
# define TIMER_PWM_PIN 46 // Arduino Mega
# define SEND_PIN 46 // Arduino Mega
#else
# error "Please add OC5A pin number here\n"
#endif
@@ -479,7 +529,7 @@
CMT_MSC = 0x03; \
})
#define TIMER_PWM_PIN 5
#define SEND_PIN 5
// defines for TPM1 timer on Teensy-LC
#elif defined(IR_USE_TIMER_TPM1)
@@ -509,7 +559,7 @@
FTM1_C0V = 0; \
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \
})
#define TIMER_PWM_PIN 16
#define SEND_PIN 16
// defines for timer_tiny0 (8 bits)
#elif defined(IR_USE_TIMER_TINY0)
@@ -543,7 +593,7 @@
})
#endif
#define TIMER_PWM_PIN 1 /* ATtiny85 */
#define SEND_PIN 1 /* ATtiny85 */
//---------------------------------------------------------
// ESP32 (ESP8266 should likely be added here too)
@@ -560,12 +610,29 @@
// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below
// https://github.com/ExploreEmbedded/ESP32_RMT
#elif defined(IR_TIMER_USE_ESP32)
#define TIMER_RESET
#define TIMER_ENABLE_PWM
#define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet");
#define TIMER_ENABLE_INTR
#define TIMER_DISABLE_INTR
#define TIMER_INTR_NAME
#define TIMER_RESET
#ifdef ISR
# undef ISR
#endif
#define ISR(f) void IRTimer()
#elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
// use timer 3 hardcoded at this time
#define TIMER_RESET
#define TIMER_ENABLE_PWM // Not presently used
#define TIMER_DISABLE_PWM
#define TIMER_ENABLE_INTR NVIC_EnableIRQ(TC3_IRQn) // Not presently used
#define TIMER_DISABLE_INTR NVIC_DisableIRQ(TC3_IRQn)
#define TIMER_INTR_NAME TC3_Handler // Not presently used
#define TIMER_CONFIG_KHZ(f)
#ifdef ISR
# undef ISR
#endif
#define ISR(f) void irs()
//---------------------------------------------------------
// Unknown Timer
@@ -574,4 +641,13 @@
# error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
#endif
// Provide default definitions, portable but possibly slower than necessary.
#ifndef SENDPIN_ON
#define SENDPIN_ON(pin) digitalWrite(pin, HIGH)
#endif
#ifndef SENDPIN_OFF
#define SENDPIN_OFF(pin) digitalWrite(pin, LOW)
#endif
#endif // ! boarddefs_h

View File

@@ -1,5 +1,5 @@
## 2.4.3
- Added Philips Extended RC-5 protocol support [PR #522] (https://github.com/z3t0/Arduino-IRremote/pull/522)
## 2.4.0 - 2017/08/10
- Cleanup of hardware dependencies. Merge in SAM support [PR #437](https://github.com/z3t0/Arduino-IRremote/pull/437)
## 2.3.3 - 2017/03/31
- Added ESP32 IR receive support [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/425)

39
esp32.cpp Normal file
View File

@@ -0,0 +1,39 @@
#ifdef ESP32
// This file contains functions specific to the ESP32.
#include "IRremote.h"
#include "IRremoteInt.h"
// "Idiot check"
#ifdef USE_DEFAULT_ENABLE_IR_IN
#error Must undef USE_DEFAULT_ENABLE_IR_IN
#endif
hw_timer_t *timer;
void IRTimer(); // defined in IRremote.cpp, masqueraded as ISR(TIMER_INTR_NAME)
//+=============================================================================
// initialization
//
void IRrecv::enableIRIn ( )
{
// Interrupt Service Routine - Fires every 50uS
// ESP32 has a proper API to setup timers, no weird chip macros needed
// simply call the readable API versions :)
// 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up
timer = timerBegin(1, 80, 1);
timerAttachInterrupt(timer, &IRTimer, 1);
// every 50ns, autoreload = true
timerAlarmWrite(timer, 50, true);
timerAlarmEnable(timer);
// Initialize state machine variables
irparams.rcvstate = STATE_IDLE;
irparams.rawlen = 0;
// Set pin modes
pinMode(irparams.recvpin, INPUT);
}
#endif // ESP32

View File

@@ -79,7 +79,7 @@ void dumpTIMER() {
void dumpTimerPin() {
Serial.print(F("IR Tx Pin: "));
Serial.println(TIMER_PWM_PIN);
Serial.println(SEND_PIN);
}
void dumpClock() {

View File

@@ -1,10 +1,5 @@
#include "IRremote.h"
#include "IRremoteInt.h"
#ifdef IR_TIMER_USE_ESP32
hw_timer_t *timer;
void IRTimer(); // defined in IRremote.cpp
#endif
//+=============================================================================
// Decodes the received IR message
@@ -120,19 +115,10 @@ IRrecv::IRrecv (int recvpin, int blinkpin)
//+=============================================================================
// initialization
//
#ifdef USE_DEFAULT_ENABLE_IR_IN
void IRrecv::enableIRIn ( )
{
// Interrupt Service Routine - Fires every 50uS
#ifdef ESP32
// ESP32 has a proper API to setup timers, no weird chip macros needed
// simply call the readable API versions :)
// 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up
timer = timerBegin(1, 80, 1);
timerAttachInterrupt(timer, &IRTimer, 1);
// every 50ns, autoreload = true
timerAlarmWrite(timer, 50, true);
timerAlarmEnable(timer);
#else
// Interrupt Service Routine - Fires every 50uS
cli();
// Setup pulse clock timer interrupt
// Prescale /8 (16M/8 = 0.5 microseconds per tick)
@@ -146,7 +132,6 @@ void IRrecv::enableIRIn ( )
TIMER_RESET;
sei(); // enable interrupts
#endif
// Initialize state machine variables
irparams.rcvstate = STATE_IDLE;
@@ -155,14 +140,17 @@ void IRrecv::enableIRIn ( )
// Set pin modes
pinMode(irparams.recvpin, INPUT);
}
#endif // USE_DEFAULT_ENABLE_IR_IN
//+=============================================================================
// Enable/disable blinking of pin 13 on IR processing
//
void IRrecv::blink13 (int blinkflag)
{
#ifdef BLINKLED
irparams.blinkflag = blinkflag;
if (blinkflag) pinMode(BLINKLED, OUTPUT) ;
#endif
}
//+=============================================================================

View File

@@ -1,6 +1,7 @@
#include "IRremote.h"
#include "IRremoteInt.h"
#ifdef SENDING_SUPPORTED
//+=============================================================================
void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz)
{
@@ -15,14 +16,59 @@ void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned in
space(0); // Always end with the LED off
}
#ifdef USE_SOFT_CARRIER
void inline IRsend::sleepMicros(unsigned long us)
{
#ifdef USE_SPIN_WAIT
sleepUntilMicros(micros() + us);
#else
if (us > 0U) // Is this necessary? (Official docu https://www.arduino.cc/en/Reference/DelayMicroseconds does not tell.)
delayMicroseconds((unsigned int) us);
#endif
}
void inline IRsend::sleepUntilMicros(unsigned long targetTime)
{
#ifdef USE_SPIN_WAIT
while (micros() < targetTime)
;
#else
unsigned long now = micros();
if (now < targetTime)
sleepMicros(targetTime - now);
#endif
}
#endif // USE_SOFT_CARRIER
//+=============================================================================
// Sends an IR mark for the specified number of microseconds.
// The mark output is modulated at the PWM frequency.
//
void IRsend::mark (unsigned int time)
void IRsend::mark(unsigned int time)
{
#ifdef USE_SOFT_CARRIER
unsigned long start = micros();
unsigned long stop = start + time;
if (stop + periodTime < start)
// Counter wrap-around, happens very seldomly, but CAN happen.
// Just give up instead of possibly damaging the hardware.
return;
unsigned long nextPeriodEnding = start;
unsigned long now = micros();
while (now < stop) {
SENDPIN_ON(sendPin);
sleepMicros(periodOnTime);
SENDPIN_OFF(sendPin);
nextPeriodEnding += periodTime;
sleepUntilMicros(nextPeriodEnding);
now = micros();
}
#else
TIMER_ENABLE_PWM; // Enable pin 3 PWM output
if (time > 0) custom_delay_usec(time);
#endif
}
//+=============================================================================
@@ -54,13 +100,16 @@ void IRsend::space (unsigned int time)
//
void IRsend::enableIROut (int khz)
{
// FIXME: implement ESP32 support, see IR_TIMER_USE_ESP32 in boarddefs.h
#ifndef ESP32
#ifdef USE_SOFT_CARRIER
periodTime = (1000U + khz/2) / khz; // = 1000/khz + 1/2 = round(1000.0/khz)
periodOnTime = periodTime * DUTY_CYCLE / 100U - PULSE_CORRECTION;
#endif
// 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
pinMode(sendPin, OUTPUT);
SENDPIN_OFF(sendPin); // When not sending, we want it low
// COM2A = 00: disconnect OC2A
// COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted
@@ -68,7 +117,6 @@ void IRsend::enableIROut (int khz)
// CS2 = 000: no prescaling
// The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A.
TIMER_CONFIG_KHZ(khz);
#endif
}
//+=============================================================================
@@ -88,3 +136,4 @@ void IRsend::custom_delay_usec(unsigned long uSecs) {
//}
}
#endif // SENDING_SUPPORTED

View File

@@ -78,73 +78,6 @@ void IRsend::sendRC5 (unsigned long data, int nbits)
space(0); // Always end with the LED off
}
void IRsend::sendRC5ext (unsigned long addr, unsigned long cmd, boolean toggle)
{
// Set IR carrier frequency
enableIROut(36);
unsigned long addressBits = 5;
unsigned long commandBits = 7;
unsigned long nbits = addressBits + commandBits;
// Start
mark(RC5_T1);
// Bit #6 of the command part, but inverted!
unsigned long cmdBit6 = (1UL << (commandBits-1)) & cmd;
if (cmdBit6) {
// Inverted (1 -> 0 = mark-to-space)
mark(RC5_T1);
space(RC5_T1);
} else {
space(RC5_T1);
mark(RC5_T1);
}
commandBits--;
// Toggle bit
static int toggleBit = 1;
if (toggle) {
if (toggleBit == 0) {
toggleBit = 1;
} else {
toggleBit = 0;
}
}
if (toggleBit) {
space(RC5_T1);
mark(RC5_T1);
} else {
mark(RC5_T1);
space(RC5_T1);
}
// Address
for (unsigned long mask = 1UL << (addressBits - 1); mask; mask >>= 1) {
if (addr & mask) {
space(RC5_T1); // 1 is space, then mark
mark(RC5_T1);
} else {
mark(RC5_T1);
space(RC5_T1);
}
}
// Command
for (unsigned long mask = 1UL << (commandBits - 1); mask; mask >>= 1) {
if (cmd & mask) {
space(RC5_T1); // 1 is space, then mark
mark(RC5_T1);
} else {
mark(RC5_T1);
space(RC5_T1);
}
}
space(0); // Always end with the LED off
}
#endif
//+=============================================================================

102
sam.cpp Normal file
View File

@@ -0,0 +1,102 @@
// Support routines for SAM processor boards
#include "IRremote.h"
#include "IRremoteInt.h"
#if defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
// "Idiot check"
#ifdef USE_DEFAULT_ENABLE_IR_IN
#error Must undef USE_DEFAULT_ENABLE_IR_IN
#endif
//+=============================================================================
// ATSAMD Timer setup & IRQ functions
//
// following based on setup from GitHub jdneo/timerInterrupt.ino
static void setTimerFrequency(int frequencyHz)
{
int compareValue = (SYSCLOCK / (TIMER_PRESCALER_DIV * frequencyHz)) - 1;
//Serial.println(compareValue);
TcCount16* TC = (TcCount16*) TC3;
// Make sure the count is in a proportional position to where it was
// to prevent any jitter or disconnect when changing the compare value.
TC->COUNT.reg = map(TC->COUNT.reg, 0, TC->CC[0].reg, 0, compareValue);
TC->CC[0].reg = compareValue;
//Serial.print("COUNT.reg ");
//Serial.println(TC->COUNT.reg);
//Serial.print("CC[0].reg ");
//Serial.println(TC->CC[0].reg);
while (TC->STATUS.bit.SYNCBUSY == 1);
}
static void startTimer()
{
REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3);
while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync
TcCount16* TC = (TcCount16*) TC3;
TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
// Use the 16-bit timer
TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
// Use match mode so that the timer counter resets when the count matches the compare register
TC->CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
// Set prescaler to 1024
//TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1024;
TC->CTRLA.reg |= TC_CTRLA_PRESCALER_DIV64;
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
setTimerFrequency(1000000 / USECPERTICK);
// Enable the compare interrupt
TC->INTENSET.reg = 0;
TC->INTENSET.bit.MC0 = 1;
NVIC_EnableIRQ(TC3_IRQn);
TC->CTRLA.reg |= TC_CTRLA_ENABLE;
while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
}
//+=============================================================================
// initialization
//
void IRrecv::enableIRIn()
{
// Interrupt Service Routine - Fires every 50uS
//Serial.println("Starting timer");
startTimer();
//Serial.println("Started timer");
// Initialize state machine variables
irparams.rcvstate = STATE_IDLE;
irparams.rawlen = 0;
// Set pin modes
pinMode(irparams.recvpin, INPUT);
}
void irs(); // Defined in IRRemote as ISR(TIMER_INTR_NAME)
void TC3_Handler(void)
{
TcCount16* TC = (TcCount16*) TC3;
// If this interrupt is due to the compare register matching the timer count
// we toggle the LED.
if (TC->INTFLAG.bit.MC0 == 1) {
TC->INTFLAG.bit.MC0 = 1;
irs();
}
}
#endif // defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)