Modifying Tone.cpp to use register-based (not CPU-based) #ifdefs.

This commit is contained in:
David A. Mellis 2010-11-08 23:09:29 -05:00
parent 5e028ea09d
commit 9b42d2dc03
1 changed files with 99 additions and 20 deletions

View File

@ -28,7 +28,7 @@ Version Modified By Date Comments
09/11/25 Changed pin toggle method to XOR
09/11/25 Fixed timer0 from being excluded
0006 D Mellis 09/12/29 Replaced objects with functions
0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register
*************************************************/
#include <avr/interrupt.h>
@ -36,7 +36,7 @@ Version Modified By Date Comments
#include "wiring.h"
#include "pins_arduino.h"
#if defined(__AVR_ATmega8__)
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
#define TCCR2A TCCR2
#define TCCR2B TCCR2
#define COM2A1 COM21
@ -66,19 +66,26 @@ volatile long timer2_toggle_count;
volatile uint8_t *timer2_pin_port;
volatile uint8_t timer2_pin_mask;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#if defined(TIMSK3)
volatile long timer3_toggle_count;
volatile uint8_t *timer3_pin_port;
volatile uint8_t timer3_pin_mask;
#endif
#if defined(TIMSK4)
volatile long timer4_toggle_count;
volatile uint8_t *timer4_pin_port;
volatile uint8_t timer4_pin_mask;
#endif
#if defined(TIMSK5)
volatile long timer5_toggle_count;
volatile uint8_t *timer5_pin_port;
volatile uint8_t timer5_pin_mask;
#endif
// MLS: This does not make sense, the 3 options are the same
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define AVAILABLE_TONE_PINS 1
@ -133,7 +140,7 @@ static int8_t toneBegin(uint8_t _pin)
// whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
switch (_timer)
{
#if !defined(__AVR_ATmega8__)
#if defined(TCCR0A) && defined(TCCR0B)
case 0:
// 8 bit timer
TCCR0A = 0;
@ -143,8 +150,9 @@ static int8_t toneBegin(uint8_t _pin)
timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer0_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#endif
#if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12)
case 1:
// 16 bit timer
TCCR1A = 0;
@ -154,6 +162,9 @@ static int8_t toneBegin(uint8_t _pin)
timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer1_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR2A) && defined(TCCR2B)
case 2:
// 8 bit timer
TCCR2A = 0;
@ -163,8 +174,9 @@ static int8_t toneBegin(uint8_t _pin)
timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer2_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3)
case 3:
// 16 bit timer
TCCR3A = 0;
@ -174,15 +186,27 @@ static int8_t toneBegin(uint8_t _pin)
timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer3_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4)
case 4:
// 16 bit timer
TCCR4A = 0;
TCCR4B = 0;
bitWrite(TCCR4B, WGM42, 1);
#if defined(WGM42)
bitWrite(TCCR4B, WGM42, 1);
#elif defined(CS43)
#warning this may not be correct
// atmega32u4
bitWrite(TCCR4B, CS43, 1);
#endif
bitWrite(TCCR4B, CS40, 1);
timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer4_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5)
case 5:
// 16 bit timer
TCCR5A = 0;
@ -192,7 +216,7 @@ static int8_t toneBegin(uint8_t _pin)
timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
timer5_pin_mask = digitalPinToBitMask(_pin);
break;
#endif
#endif
}
}
@ -258,12 +282,22 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
}
}
#if !defined(__AVR_ATmega8__)
#if defined(TCCR0B)
if (_timer == 0)
{
TCCR0B = prescalarbits;
}
else
#endif
#if defined(TCCR2B)
{
TCCR2B = prescalarbits;
}
#else
{
// dummy place holder to make the above ifdefs work
}
#endif
}
else
{
@ -278,12 +312,20 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
}
if (_timer == 1)
{
#if defined(TCCR1B)
TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#endif
}
#if defined(TCCR3B)
else if (_timer == 3)
TCCR3B = (TCCR3B & 0b11111000) | prescalarbits;
#endif
#if defined(TCCR4B)
else if (_timer == 4)
TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
#endif
#if defined(TCCR5B)
else if (_timer == 5)
TCCR5B = (TCCR5B & 0b11111000) | prescalarbits;
#endif
@ -307,7 +349,7 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
switch (_timer)
{
#if !defined(__AVR_ATmega8__)
#if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A)
case 0:
OCR0A = ocr;
timer0_toggle_count = toggle_count;
@ -316,27 +358,43 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
#endif
case 1:
#if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A)
OCR1A = ocr;
timer1_toggle_count = toggle_count;
bitWrite(TIMSK1, OCIE1A, 1);
#elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A)
// this combination is for at least the ATmega32
OCR1A = ocr;
timer1_toggle_count = toggle_count;
bitWrite(TIMSK, OCIE1A, 1);
#endif
break;
#if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A)
case 2:
OCR2A = ocr;
timer2_toggle_count = toggle_count;
bitWrite(TIMSK2, OCIE2A, 1);
break;
#endif
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#if defined(TIMSK3)
case 3:
OCR3A = ocr;
timer3_toggle_count = toggle_count;
bitWrite(TIMSK3, OCIE3A, 1);
break;
#endif
#if defined(TIMSK4)
case 4:
OCR4A = ocr;
timer4_toggle_count = toggle_count;
bitWrite(TIMSK4, OCIE4A, 1);
break;
#endif
#if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A)
case 5:
OCR5A = ocr;
timer5_toggle_count = toggle_count;
@ -356,27 +414,48 @@ void disableTimer(uint8_t _timer)
{
switch (_timer)
{
#if !defined(__AVR_ATmega8__)
case 0:
TIMSK0 = 0;
#if defined(TIMSK0)
TIMSK0 = 0;
#elif defined(TIMSK)
TIMSK = 0; // atmega32
#endif
break;
#endif
#if defined(TIMSK1) && defined(OCIE1A)
case 1:
bitWrite(TIMSK1, OCIE1A, 0);
break;
#endif
case 2:
bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt
TCCR2A = (1 << WGM20);
TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22);
OCR2A = 0;
#if defined(TIMSK2) && defined(OCIE2A)
bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt
#endif
#if defined(TCCR2A) && defined(WGM20)
TCCR2A = (1 << WGM20);
#endif
#if defined(TCCR2B) && defined(CS22)
TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22);
#endif
#if defined(OCR2A)
OCR2A = 0;
#endif
break;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#if defined(TIMSK3)
case 3:
TIMSK3 = 0;
break;
#endif
#if defined(TIMSK4)
case 4:
TIMSK4 = 0;
break;
#endif
#if defined(TIMSK5)
case 5:
TIMSK5 = 0;
break;