IRremote
sam.cpp
Go to the documentation of this file.
1 // Support routines for SAM processor boards
2 
3 #include "IRremote.h"
4 
5 #if defined(ARDUINO_ARCH_SAMD)
6 
7 // "Idiot check"
8 #ifdef USE_DEFAULT_ENABLE_IR_IN
9 #error Must undef USE_DEFAULT_ENABLE_IR_IN
10 #endif
11 
12 //+=============================================================================
13 // ATSAMD Timer setup & IRQ functions
14 //
15 
16 // following based on setup from GitHub jdneo/timerInterrupt.ino
17 
18 static void setTimerFrequency(int frequencyHz) {
19  int compareValue = (SYSCLOCK / (TIMER_PRESCALER_DIV * frequencyHz)) - 1;
20  //Serial.println(compareValue);
21  TcCount16* TC = (TcCount16*) TC3;
22  // Make sure the count is in a proportional position to where it was
23  // to prevent any jitter or disconnect when changing the compare value.
24  TC->COUNT.reg = map(TC->COUNT.reg, 0, TC->CC[0].reg, 0, compareValue);
25  TC->CC[0].reg = compareValue;
26  //Serial.print("COUNT.reg ");
27  //Serial.println(TC->COUNT.reg);
28  //Serial.print("CC[0].reg ");
29  //Serial.println(TC->CC[0].reg);
30  while (TC->STATUS.bit.SYNCBUSY == 1)
31  ;
32 }
33 
34 static void startTimer() {
35  REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3);
36  while (GCLK->STATUS.bit.SYNCBUSY == 1)
37  ; // wait for sync
38 
39  TcCount16* TC = (TcCount16*) TC3;
40 
41  // The TC should be disabled before the TC is reset in order to avoid undefined behavior.
42  TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
43  // When write-synchronization is ongoing for a register, any subsequent write attempts to this register will be discarded, and an error will be reported.
44  while (TC->STATUS.bit.SYNCBUSY == 1); // wait for sync
45  // Reset TCx
46  TC->CTRLA.reg = TC_CTRLA_SWRST;
47  // When writing a ‘1’ to the CTRLA.SWRST bit it will immediately read as ‘1’.
48  // CTRL.SWRST will be cleared by hardware when the peripheral has been reset.
49  while (TC->CTRLA.bit.SWRST)
50  ;
51 
52  // Use the 16-bit timer
53  // Use match mode so that the timer counter resets when the count matches the compare register
54  // Set prescaler to 64
55  TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV64 | TC_CTRLA_ENABLE;
56 
57  setTimerFrequency(1000000 / USECPERTICK);
58 
59  // Enable the compare interrupt
60  TC->INTENSET.reg = 0;
61  TC->INTENSET.bit.MC0 = 1;
62 
63  NVIC_EnableIRQ (TC3_IRQn);
64 
65 }
66 
67 //+=============================================================================
68 // initialization
69 //
70 
71 void IRrecv::enableIRIn() {
72  // Interrupt Service Routine - Fires every 50uS
73  //Serial.println("Starting timer");
74  startTimer();
75  //Serial.println("Started timer");
76 
77  // Initialize state machine variables
79  irparams.rawlen = 0;
80 
81  // Set pin modes
82  pinMode(irparams.recvpin, INPUT);
83 }
84 
85 void IRrecv::disableIRIn() {
86  TC3->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
87 }
88 
89 void irs(); // Defined in IRRemote as ISR(TIMER_INTR_NAME)
90 
91 void TC3_Handler(void) {
92  TcCount16* TC = (TcCount16*) TC3;
93  // If this interrupt is due to the compare register matching the timer count
94  // we toggle the LED.
95  if (TC->INTFLAG.bit.MC0 == 1) {
96  TC->INTFLAG.bit.MC0 = 1;
97  irs();
98  }
99 }
100 
101 #endif // defined(ARDUINO_ARCH_SAMD)
IRrecv::disableIRIn
void disableIRIn()
Disable IR reception.
Definition: irRecv.cpp:185
IRrecv::enableIRIn
void enableIRIn()
Enable IR reception.
Definition: irRecv.cpp:160
irparams_t::recvpin
uint8_t recvpin
Pin connected to IR data from detector.
Definition: IRremoteInt.h:42
irparams_t::rcvstate
uint8_t rcvstate
State Machine state.
Definition: IRremoteInt.h:41
SYSCLOCK
#define SYSCLOCK
Clock frequency to be used for timing.
Definition: IRremoteBoardDefs.h:349
irparams
volatile irparams_t irparams
Allow all parts of the code access to the ISR data NB.
USECPERTICK
#define USECPERTICK
Definition: IRremoteBoardDefs.h:166
IRremote.h
Public API to the library.
irparams_t::rawlen
unsigned int rawlen
counter of entries in rawbuf
Definition: IRremoteInt.h:45
IR_REC_STATE_IDLE
#define IR_REC_STATE_IDLE
Definition: IRremoteInt.h:52