Home | History | Annotate | Download | only in arduino
      1 /* Tone.cpp
      2 
      3   A Tone Generator Library
      4 
      5   Written by Brett Hagman
      6 
      7   This library is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU Lesser General Public
      9   License as published by the Free Software Foundation; either
     10   version 2.1 of the License, or (at your option) any later version.
     11 
     12   This library is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15   Lesser General Public License for more details.
     16 
     17   You should have received a copy of the GNU Lesser General Public
     18   License along with this library; if not, write to the Free Software
     19   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 
     21 Version Modified By Date     Comments
     22 ------- ----------- -------- --------
     23 0001    B Hagman    09/08/02 Initial coding
     24 0002    B Hagman    09/08/18 Multiple pins
     25 0003    B Hagman    09/08/18 Moved initialization from constructor to begin()
     26 0004    B Hagman    09/09/26 Fixed problems with ATmega8
     27 0005    B Hagman    09/11/23 Scanned prescalars for best fit on 8 bit timers
     28                     09/11/25 Changed pin toggle method to XOR
     29                     09/11/25 Fixed timer0 from being excluded
     30 0006    D Mellis    09/12/29 Replaced objects with functions
     31 0007    M Sproul    10/08/29 Changed #ifdefs from cpu to register
     32 *************************************************/
     33 
     34 #include <avr/interrupt.h>
     35 #include <avr/pgmspace.h>
     36 #include "wiring.h"
     37 #include "pins_arduino.h"
     38 
     39 #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
     40 #define TCCR2A TCCR2
     41 #define TCCR2B TCCR2
     42 #define COM2A1 COM21
     43 #define COM2A0 COM20
     44 #define OCR2A OCR2
     45 #define TIMSK2 TIMSK
     46 #define OCIE2A OCIE2
     47 #define TIMER2_COMPA_vect TIMER2_COMP_vect
     48 #define TIMSK1 TIMSK
     49 #endif
     50 
     51 // timerx_toggle_count:
     52 //  > 0 - duration specified
     53 //  = 0 - stopped
     54 //  < 0 - infinitely (until stop() method called, or new play() called)
     55 
     56 #if !defined(__AVR_ATmega8__)
     57 volatile long timer0_toggle_count;
     58 volatile uint8_t *timer0_pin_port;
     59 volatile uint8_t timer0_pin_mask;
     60 #endif
     61 
     62 volatile long timer1_toggle_count;
     63 volatile uint8_t *timer1_pin_port;
     64 volatile uint8_t timer1_pin_mask;
     65 volatile long timer2_toggle_count;
     66 volatile uint8_t *timer2_pin_port;
     67 volatile uint8_t timer2_pin_mask;
     68 
     69 #if defined(TIMSK3)
     70 volatile long timer3_toggle_count;
     71 volatile uint8_t *timer3_pin_port;
     72 volatile uint8_t timer3_pin_mask;
     73 #endif
     74 
     75 #if defined(TIMSK4)
     76 volatile long timer4_toggle_count;
     77 volatile uint8_t *timer4_pin_port;
     78 volatile uint8_t timer4_pin_mask;
     79 #endif
     80 
     81 #if defined(TIMSK5)
     82 volatile long timer5_toggle_count;
     83 volatile uint8_t *timer5_pin_port;
     84 volatile uint8_t timer5_pin_mask;
     85 #endif
     86 
     87 
     88 // MLS: This does not make sense, the 3 options are the same
     89 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
     90 
     91 #define AVAILABLE_TONE_PINS 1
     92 
     93 const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
     94 static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };
     95 
     96 #elif defined(__AVR_ATmega8__)
     97 
     98 #define AVAILABLE_TONE_PINS 1
     99 
    100 const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
    101 static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
    102 
    103 #else
    104 
    105 #define AVAILABLE_TONE_PINS 1
    106 
    107 // Leave timer 0 to last.
    108 const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
    109 static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };
    110 
    111 #endif
    112 
    113 
    114 
    115 static int8_t toneBegin(uint8_t _pin)
    116 {
    117   int8_t _timer = -1;
    118 
    119   // if we're already using the pin, the timer should be configured.
    120   for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
    121     if (tone_pins[i] == _pin) {
    122       return pgm_read_byte(tone_pin_to_timer_PGM + i);
    123     }
    124   }
    125 
    126   // search for an unused timer.
    127   for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
    128     if (tone_pins[i] == 255) {
    129       tone_pins[i] = _pin;
    130       _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
    131       break;
    132     }
    133   }
    134 
    135   if (_timer != -1)
    136   {
    137     // Set timer specific stuff
    138     // All timers in CTC mode
    139     // 8 bit timers will require changing prescalar values,
    140     // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
    141     switch (_timer)
    142     {
    143       #if defined(TCCR0A) && defined(TCCR0B)
    144       case 0:
    145         // 8 bit timer
    146         TCCR0A = 0;
    147         TCCR0B = 0;
    148         bitWrite(TCCR0A, WGM01, 1);
    149         bitWrite(TCCR0B, CS00, 1);
    150         timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
    151         timer0_pin_mask = digitalPinToBitMask(_pin);
    152         break;
    153       #endif
    154 
    155       #if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12)
    156       case 1:
    157         // 16 bit timer
    158         TCCR1A = 0;
    159         TCCR1B = 0;
    160         bitWrite(TCCR1B, WGM12, 1);
    161         bitWrite(TCCR1B, CS10, 1);
    162         timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
    163         timer1_pin_mask = digitalPinToBitMask(_pin);
    164         break;
    165       #endif
    166 
    167       #if defined(TCCR2A) && defined(TCCR2B)
    168       case 2:
    169         // 8 bit timer
    170         TCCR2A = 0;
    171         TCCR2B = 0;
    172         bitWrite(TCCR2A, WGM21, 1);
    173         bitWrite(TCCR2B, CS20, 1);
    174         timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
    175         timer2_pin_mask = digitalPinToBitMask(_pin);
    176         break;
    177       #endif
    178 
    179       #if defined(TCCR3A) && defined(TCCR3B) &&  defined(TIMSK3)
    180       case 3:
    181         // 16 bit timer
    182         TCCR3A = 0;
    183         TCCR3B = 0;
    184         bitWrite(TCCR3B, WGM32, 1);
    185         bitWrite(TCCR3B, CS30, 1);
    186         timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
    187         timer3_pin_mask = digitalPinToBitMask(_pin);
    188         break;
    189       #endif
    190 
    191       #if defined(TCCR4A) && defined(TCCR4B) &&  defined(TIMSK4)
    192       case 4:
    193         // 16 bit timer
    194         TCCR4A = 0;
    195         TCCR4B = 0;
    196         #if defined(WGM42)
    197           bitWrite(TCCR4B, WGM42, 1);
    198         #elif defined(CS43)
    199           #warning this may not be correct
    200           // atmega32u4
    201           bitWrite(TCCR4B, CS43, 1);
    202         #endif
    203         bitWrite(TCCR4B, CS40, 1);
    204         timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
    205         timer4_pin_mask = digitalPinToBitMask(_pin);
    206         break;
    207       #endif
    208 
    209       #if defined(TCCR5A) && defined(TCCR5B) &&  defined(TIMSK5)
    210       case 5:
    211         // 16 bit timer
    212         TCCR5A = 0;
    213         TCCR5B = 0;
    214         bitWrite(TCCR5B, WGM52, 1);
    215         bitWrite(TCCR5B, CS50, 1);
    216         timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
    217         timer5_pin_mask = digitalPinToBitMask(_pin);
    218         break;
    219       #endif
    220     }
    221   }
    222 
    223   return _timer;
    224 }
    225 
    226 
    227 
    228 // frequency (in hertz) and duration (in milliseconds).
    229 
    230 void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
    231 {
    232   uint8_t prescalarbits = 0b001;
    233   long toggle_count = 0;
    234   uint32_t ocr = 0;
    235   int8_t _timer;
    236 
    237   _timer = toneBegin(_pin);
    238 
    239   if (_timer >= 0)
    240   {
    241     // Set the pinMode as OUTPUT
    242     pinMode(_pin, OUTPUT);
    243 
    244     // if we are using an 8 bit timer, scan through prescalars to find the best fit
    245     if (_timer == 0 || _timer == 2)
    246     {
    247       ocr = F_CPU / frequency / 2 - 1;
    248       prescalarbits = 0b001;  // ck/1: same for both timers
    249       if (ocr > 255)
    250       {
    251         ocr = F_CPU / frequency / 2 / 8 - 1;
    252         prescalarbits = 0b010;  // ck/8: same for both timers
    253 
    254         if (_timer == 2 && ocr > 255)
    255         {
    256           ocr = F_CPU / frequency / 2 / 32 - 1;
    257           prescalarbits = 0b011;
    258         }
    259 
    260         if (ocr > 255)
    261         {
    262           ocr = F_CPU / frequency / 2 / 64 - 1;
    263           prescalarbits = _timer == 0 ? 0b011 : 0b100;
    264 
    265           if (_timer == 2 && ocr > 255)
    266           {
    267             ocr = F_CPU / frequency / 2 / 128 - 1;
    268             prescalarbits = 0b101;
    269           }
    270 
    271           if (ocr > 255)
    272           {
    273             ocr = F_CPU / frequency / 2 / 256 - 1;
    274             prescalarbits = _timer == 0 ? 0b100 : 0b110;
    275             if (ocr > 255)
    276             {
    277               // can't do any better than /1024
    278               ocr = F_CPU / frequency / 2 / 1024 - 1;
    279               prescalarbits = _timer == 0 ? 0b101 : 0b111;
    280             }
    281           }
    282         }
    283       }
    284 
    285 #if defined(TCCR0B)
    286       if (_timer == 0)
    287       {
    288         TCCR0B = prescalarbits;
    289       }
    290       else
    291 #endif
    292 #if defined(TCCR2B)
    293       {
    294         TCCR2B = prescalarbits;
    295       }
    296 #else
    297       {
    298         // dummy place holder to make the above ifdefs work
    299       }
    300 #endif
    301     }
    302     else
    303     {
    304       // two choices for the 16 bit timers: ck/1 or ck/64
    305       ocr = F_CPU / frequency / 2 - 1;
    306 
    307       prescalarbits = 0b001;
    308       if (ocr > 0xffff)
    309       {
    310         ocr = F_CPU / frequency / 2 / 64 - 1;
    311         prescalarbits = 0b011;
    312       }
    313 
    314       if (_timer == 1)
    315       {
    316 #if defined(TCCR1B)
    317         TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
    318 #endif
    319       }
    320 #if defined(TCCR3B)
    321       else if (_timer == 3)
    322         TCCR3B = (TCCR3B & 0b11111000) | prescalarbits;
    323 #endif
    324 #if defined(TCCR4B)
    325       else if (_timer == 4)
    326         TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
    327 #endif
    328 #if defined(TCCR5B)
    329       else if (_timer == 5)
    330         TCCR5B = (TCCR5B & 0b11111000) | prescalarbits;
    331 #endif
    332 
    333     }
    334 
    335 
    336     // Calculate the toggle count
    337     if (duration > 0)
    338     {
    339       toggle_count = 2 * frequency * duration / 1000;
    340     }
    341     else
    342     {
    343       toggle_count = -1;
    344     }
    345 
    346     // Set the OCR for the given timer,
    347     // set the toggle count,
    348     // then turn on the interrupts
    349     switch (_timer)
    350     {
    351 
    352 #if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A)
    353       case 0:
    354         OCR0A = ocr;
    355         timer0_toggle_count = toggle_count;
    356         bitWrite(TIMSK0, OCIE0A, 1);
    357         break;
    358 #endif
    359 
    360       case 1:
    361 #if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A)
    362         OCR1A = ocr;
    363         timer1_toggle_count = toggle_count;
    364         bitWrite(TIMSK1, OCIE1A, 1);
    365 #elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A)
    366         // this combination is for at least the ATmega32
    367         OCR1A = ocr;
    368         timer1_toggle_count = toggle_count;
    369         bitWrite(TIMSK, OCIE1A, 1);
    370 #endif
    371         break;
    372 
    373 #if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A)
    374       case 2:
    375         OCR2A = ocr;
    376         timer2_toggle_count = toggle_count;
    377         bitWrite(TIMSK2, OCIE2A, 1);
    378         break;
    379 #endif
    380 
    381 #if defined(TIMSK3)
    382       case 3:
    383         OCR3A = ocr;
    384         timer3_toggle_count = toggle_count;
    385         bitWrite(TIMSK3, OCIE3A, 1);
    386         break;
    387 #endif
    388 
    389 #if defined(TIMSK4)
    390       case 4:
    391         OCR4A = ocr;
    392         timer4_toggle_count = toggle_count;
    393         bitWrite(TIMSK4, OCIE4A, 1);
    394         break;
    395 #endif
    396 
    397 #if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A)
    398       case 5:
    399         OCR5A = ocr;
    400         timer5_toggle_count = toggle_count;
    401         bitWrite(TIMSK5, OCIE5A, 1);
    402         break;
    403 #endif
    404 
    405     }
    406   }
    407 }
    408 
    409 
    410 // XXX: this function only works properly for timer 2 (the only one we use
    411 // currently).  for the others, it should end the tone, but won't restore
    412 // proper PWM functionality for the timer.
    413 void disableTimer(uint8_t _timer)
    414 {
    415   switch (_timer)
    416   {
    417     case 0:
    418       #if defined(TIMSK0)
    419         TIMSK0 = 0;
    420       #elif defined(TIMSK)
    421         TIMSK = 0; // atmega32
    422       #endif
    423       break;
    424 
    425 #if defined(TIMSK1) && defined(OCIE1A)
    426     case 1:
    427       bitWrite(TIMSK1, OCIE1A, 0);
    428       break;
    429 #endif
    430 
    431     case 2:
    432       #if defined(TIMSK2) && defined(OCIE2A)
    433         bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt
    434       #endif
    435       #if defined(TCCR2A) && defined(WGM20)
    436         TCCR2A = (1 << WGM20);
    437       #endif
    438       #if defined(TCCR2B) && defined(CS22)
    439         TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22);
    440       #endif
    441       #if defined(OCR2A)
    442         OCR2A = 0;
    443       #endif
    444       break;
    445 
    446 #if defined(TIMSK3)
    447     case 3:
    448       TIMSK3 = 0;
    449       break;
    450 #endif
    451 
    452 #if defined(TIMSK4)
    453     case 4:
    454       TIMSK4 = 0;
    455       break;
    456 #endif
    457 
    458 #if defined(TIMSK5)
    459     case 5:
    460       TIMSK5 = 0;
    461       break;
    462 #endif
    463   }
    464 }
    465 
    466 
    467 void noTone(uint8_t _pin)
    468 {
    469   int8_t _timer = -1;
    470 
    471   for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
    472     if (tone_pins[i] == _pin) {
    473       _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
    474       tone_pins[i] = 255;
    475     }
    476   }
    477 
    478   disableTimer(_timer);
    479 
    480   digitalWrite(_pin, 0);
    481 }
    482 
    483 #if 0
    484 #if !defined(__AVR_ATmega8__)
    485 ISR(TIMER0_COMPA_vect)
    486 {
    487   if (timer0_toggle_count != 0)
    488   {
    489     // toggle the pin
    490     *timer0_pin_port ^= timer0_pin_mask;
    491 
    492     if (timer0_toggle_count > 0)
    493       timer0_toggle_count--;
    494   }
    495   else
    496   {
    497     disableTimer(0);
    498     *timer0_pin_port &= ~(timer0_pin_mask);  // keep pin low after stop
    499   }
    500 }
    501 #endif
    502 
    503 
    504 ISR(TIMER1_COMPA_vect)
    505 {
    506   if (timer1_toggle_count != 0)
    507   {
    508     // toggle the pin
    509     *timer1_pin_port ^= timer1_pin_mask;
    510 
    511     if (timer1_toggle_count > 0)
    512       timer1_toggle_count--;
    513   }
    514   else
    515   {
    516     disableTimer(1);
    517     *timer1_pin_port &= ~(timer1_pin_mask);  // keep pin low after stop
    518   }
    519 }
    520 #endif
    521 
    522 
    523 ISR(TIMER2_COMPA_vect)
    524 {
    525 
    526   if (timer2_toggle_count != 0)
    527   {
    528     // toggle the pin
    529     *timer2_pin_port ^= timer2_pin_mask;
    530 
    531     if (timer2_toggle_count > 0)
    532       timer2_toggle_count--;
    533   }
    534   else
    535   {
    536     // need to call noTone() so that the tone_pins[] entry is reset, so the
    537     // timer gets initialized next time we call tone().
    538     // XXX: this assumes timer 2 is always the first one used.
    539     noTone(tone_pins[0]);
    540 //    disableTimer(2);
    541 //    *timer2_pin_port &= ~(timer2_pin_mask);  // keep pin low after stop
    542   }
    543 }
    544 
    545 
    546 
    547 //#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    548 #if 0
    549 
    550 ISR(TIMER3_COMPA_vect)
    551 {
    552   if (timer3_toggle_count != 0)
    553   {
    554     // toggle the pin
    555     *timer3_pin_port ^= timer3_pin_mask;
    556 
    557     if (timer3_toggle_count > 0)
    558       timer3_toggle_count--;
    559   }
    560   else
    561   {
    562     disableTimer(3);
    563     *timer3_pin_port &= ~(timer3_pin_mask);  // keep pin low after stop
    564   }
    565 }
    566 
    567 ISR(TIMER4_COMPA_vect)
    568 {
    569   if (timer4_toggle_count != 0)
    570   {
    571     // toggle the pin
    572     *timer4_pin_port ^= timer4_pin_mask;
    573 
    574     if (timer4_toggle_count > 0)
    575       timer4_toggle_count--;
    576   }
    577   else
    578   {
    579     disableTimer(4);
    580     *timer4_pin_port &= ~(timer4_pin_mask);  // keep pin low after stop
    581   }
    582 }
    583 
    584 ISR(TIMER5_COMPA_vect)
    585 {
    586   if (timer5_toggle_count != 0)
    587   {
    588     // toggle the pin
    589     *timer5_pin_port ^= timer5_pin_mask;
    590 
    591     if (timer5_toggle_count > 0)
    592       timer5_toggle_count--;
    593   }
    594   else
    595   {
    596     disableTimer(5);
    597     *timer5_pin_port &= ~(timer5_pin_mask);  // keep pin low after stop
    598   }
    599 }
    600 
    601 #endif
    602