volatileuint8_t*timer0_pin_port;volatileuint8_ttimer0_pin_mask;volatileuint8_t*timer1_pin_port;volatileuint8_ttimer1_pin_mask;volatileuint8_t*timer2_pin_port;volatileuint8_ttimer2_pin_mask;#define AVAILABLE_TONE_PINS 1
// Leave timer 0 to last.
constuint8_tPROGMEMtone_pin_to_timer_PGM[]={2/*, 1, 0 */};staticuint8_ttone_pins[AVAILABLE_TONE_PINS]={255/*, 255, 255 */};staticint8_ttoneBegin(uint8_t_pin){int8_t_timer=-1;// if we're already using the pin, the timer should be configured.
for(inti=0;i<AVAILABLE_TONE_PINS;i++){if(tone_pins[i]==_pin){returnpgm_read_byte(tone_pin_to_timer_PGM+i);}}// search for an unused timer.
for(inti=0;i<AVAILABLE_TONE_PINS;i++){if(tone_pins[i]==255){tone_pins[i]=_pin;_timer=pgm_read_byte(tone_pin_to_timer_PGM+i);break;}}if(_timer!=-1){// Set timer specific stuff
// All timers in CTC mode
// 8 bit timers will require changing prescalar values,
// whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
switch(_timer){case0:// 8 bit timer
TCCR0A=0;TCCR0B=0;bitWrite(TCCR0A,WGM01,1);bitWrite(TCCR0B,CS00,1);timer0_pin_port=portOutputRegister(digitalPinToPort(_pin));timer0_pin_mask=digitalPinToBitMask(_pin);break;case1:// 16 bit timer
TCCR1A=0;TCCR1B=0;bitWrite(TCCR1B,WGM12,1);bitWrite(TCCR1B,CS10,1);timer1_pin_port=portOutputRegister(digitalPinToPort(_pin));timer1_pin_mask=digitalPinToBitMask(_pin);break;case2:// 8 bit timer
TCCR2A=0;TCCR2B=0;bitWrite(TCCR2A,WGM21,1);bitWrite(TCCR2B,CS20,1);timer2_pin_port=portOutputRegister(digitalPinToPort(_pin));timer2_pin_mask=digitalPinToBitMask(_pin);break;}}return_timer;}
staticint8_ttoneBegin(uint8_t_pin){int8_t_timer=-1;// if we're already using the pin, the timer should be configured.
for(inti=0;i<AVAILABLE_TONE_PINS;i++){if(tone_pins[i]==_pin){returnpgm_read_byte(tone_pin_to_timer_PGM+i);}}
// search for an unused timer.
for(inti=0;i<AVAILABLE_TONE_PINS;i++){if(tone_pins[i]==255){tone_pins[i]=_pin;_timer=pgm_read_byte(tone_pin_to_timer_PGM+i);break;}}
if(_timer!=-1){// Set timer specific stuff
// All timers in CTC mode
// 8 bit timers will require changing prescalar values,
// whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
switch(_timer){case0:// 8 bit timer
TCCR0A=0;TCCR0B=0;bitWrite(TCCR0A,WGM01,1);bitWrite(TCCR0B,CS00,1);timer0_pin_port=portOutputRegister(digitalPinToPort(_pin));timer0_pin_mask=digitalPinToBitMask(_pin);break;case1:// 16 bit timer
TCCR1A=0;TCCR1B=0;bitWrite(TCCR1B,WGM12,1);bitWrite(TCCR1B,CS10,1);timer1_pin_port=portOutputRegister(digitalPinToPort(_pin));timer1_pin_mask=digitalPinToBitMask(_pin);break;case2:// 8 bit timer
TCCR2A=0;TCCR2B=0;bitWrite(TCCR2A,WGM21,1);bitWrite(TCCR2B,CS20,1);timer2_pin_port=portOutputRegister(digitalPinToPort(_pin));timer2_pin_mask=digitalPinToBitMask(_pin);break;}}