Advertisement
Guest User

Tone_multipin.cpp

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