Mozzi  alpha 0.01.1s
sound synthesis library for Arduino
 All Classes Functions
MozziTimer2.cpp
00001 /*
00002   MozziTimer2.cpp - Using timer 2 (or 4 on ATmega32U4) with a configurable interrupt rate.
00003 
00004   Copyright 2012 Tim Barrass
00005 
00006   This file is part of Mozzi.
00007 
00008   Combines the hardware compatibility of Flexitimer2/MsTimer2 with the
00009   precision and efficiency of TimerTwo library (unknown, from https://bitbucket.org/johnmccombs, 4/2/2012), 
00010   with other tweaks.
00011 
00012   FlexiTimer2
00013   Wim Leers <work@wimleers.com>
00014 
00015   Based on MsTimer2
00016   Javier Valencia <javiervalencia80@gmail.com>
00017 
00018   History:
00019     31/Jan/2013 (TB) - added " || defined(__AVR_ATmega644P__)" 
00020                 wherever __AVR_ATmega328P__ is included in a list
00021     25/Aug/2012 (TB) - Replaced scheme for setting up timers with
00022                 one based on TimerTwo library.
00023                 Kept precompiler directives selecting processor models.
00024     16/Dec/2011 - Added Teensy/Teensy++ support (bperrybap)
00025                                 note: teensy uses timer4 instead of timer2
00026     25/April/10 - Based on MsTimer2 V0.5 (from 29/May/09)
00027 
00028   This library is free software; you can redistribute it and/or
00029   modify it under the terms of the GNU Lesser General Public
00030   License as published by the Free Software Foundation; either
00031   version 2.1 of the License, or (at your option) any later version.
00032 
00033   This library is distributed in the hope that it will be useful,
00034   but WITHOUT ANY WARRANTY; without even the implied warranty of
00035   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00036   Lesser General Public License for more details.
00037 
00038   You should have received a copy of the GNU Lesser General Public
00039   License along with this library; if not, write to the Free Software
00040   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00041 */
00042 
00043 #include <MozziTimer2.h>
00044 #include <stdlib.h>
00045 
00046 
00047 bool MozziTimer2::start_;
00048 void (*MozziTimer2::f_)();
00049 unsigned MozziTimer2::period_;
00050 
00051 unsigned char MozziTimer2::set(unsigned int usec, void (*f)(), bool start)
00052 {
00053                 f_ = f;
00054                 start_ = start;
00055 
00056                 // assume F_CPU is a multiple of 1000000
00057                 // number of clock ticks to delay usec microseconds
00058                 unsigned long ticks = usec * (F_CPU/1000000);
00059 
00060                 unsigned char num_prescale_factors;
00061 
00062 #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega644P__)
00063 
00064                 // table by prescale = 2^n where n is the table index
00065                 num_prescale_factors = 11;
00066                 unsigned char * preScale;
00067                 preScale = (unsigned char*) calloc (num_prescale_factors, sizeof(unsigned char));
00068                 preScale[0] = (1 << CS20);
00069                 preScale[1] = 0;
00070                 preScale[2] = 0;
00071                 preScale[3] = (1 << CS21);
00072                 preScale[4] = 0;
00073                 preScale[5] = (1 << CS21) | (1 << CS20);
00074                 preScale[6] = (1 << CS22);
00075                 preScale[7] = (1 << CS22) | (1 << CS20);
00076                 preScale[8] = (1 << CS22) | (1 << CS21);
00077                 preScale[9] = 0;
00078                 preScale[10] = (1 << CS22) | (1 << CS21) | (1 << CS20);
00079 
00080                 // determine prescale factor and TOP/OCR2A value
00081                 // use minimum prescale factor
00082                 unsigned char ps, i;
00083                 for (i = 0; i < num_prescale_factors; i++)
00084                 {
00085                                 ps = preScale[i];
00086                                 if (ps && (ticks >> i) <= 256)
00087                                                 break;
00088                 }
00089 
00090                 //return error if usec is too large
00091                 if (i == num_prescale_factors)
00092                 {
00093                                 free (preScale);
00094                                 return false;
00095                 }
00096 
00097                 free (preScale);
00098 
00099                 period_ = ((long)(ticks >> i) * (1 << i))/ (F_CPU /1000000);
00100 
00101                 // disable timer 2 interrupts
00102                 TIMSK2 = 0;
00103 
00104                 // use system clock (clkI/O).
00105                 ASSR &= ~(1 << AS2);
00106 /* real
00107                 // Clear Timer on Compare Match (CTC) mode
00108                 TCCR2A = (1 << WGM21);
00109                 */
00110                 // test
00111                                 //TCCR2B = _BV(WGM23);        // set mode as phase and frequency correct pwm, stop the timer
00112                                 //TCCR2A = 0;                 // clear control register A
00113                  // TCCR2A = _BV(COM2B1) | _BV(WGM20) | _BV(WGM22);// | _BV(COM2A1); // fast pwm, Clear OC2B on Compare Match when up-counting. Set OC2B on Compare Match when down-counting. TOP = OCRA.  PWM pin cleared on 
00114                  // TCCR2B = ps;
00115                 // ken sherriff  
00116   TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);
00117   TCCR2B = _BV(WGM22) | _BV(CS22);
00118                   // end test
00119                   /*
00120                 // only need prescale bits in TCCR2B
00121                 TCCR2B = ps;
00122 */
00123 
00124 
00125 
00126                 // set TOP so timer period is (ticks >> i)
00127                 OCR2A = (ticks >> i) - 1;
00128 
00129                 return true;
00130 
00131 #elif defined (__AVR_ATmega8__) // same table as above, but shorter names and TCCR2 is different
00132 
00133                 // table by prescale = 2^n where n is the table index
00134                 num_prescale_factors = 11;
00135                 unsigned char * preScale;
00136                 preScale = (unsigned char*) calloc (num_prescale_factors, sizeof(unsigned char));
00137                 preScale[0] = (1 << CS20);
00138                 preScale[1] = 0;
00139                 preScale[2] = 0;
00140                 preScale[3] = (1 << CS21);
00141                 preScale[4] = 0;
00142                 preScale[5] = (1 << CS21) | (1 << CS20);
00143                 preScale[6] = (1 << CS22);
00144                 preScale[7] = (1 << CS22) | (1 << CS20);
00145                 preScale[8] = (1 << CS22) | (1 << CS21);
00146                 preScale[9] = 0;
00147                 preScale[10] = (1 << CS22) | (1 << CS21) | (1 << CS20);
00148 
00149                 // determine prescale factor and TOP/OCR2 value
00150                 // use minimum prescale factor
00151                 unsigned char ps, i;
00152                 for (i = 0; i < num_prescale_factors; i++)
00153                 {
00154                                 ps = preScale[i];
00155                                 if (ps && (ticks >> i) <= 256)
00156                                                 break;
00157                 }
00158 
00159                 //return error if usec is too large
00160                 if (i == num_prescale_factors)
00161                 {
00162                                 free (preScale);
00163                                 return false;
00164                 }
00165 
00166                 free (preScale);
00167 
00168                 period_ = ((long)(ticks >> i) * (1 << i))/ (F_CPU /1000000);
00169 
00170                 // disable timer 2 interrupts
00171                 TIMSK = 0;
00172 
00173                 // use system clock (clkI/O).
00174                 ASSR &= ~(1 << AS2);
00175 
00176                 // Clear Timer on Compare Match (CTC) mode and set prescale bits
00177                 TCCR2 = (1 << WGM21) | ps;
00178 
00179                 // set TOP so timer period is (ticks >> i)
00180                 OCR2 = (ticks >> i) - 1;
00181 
00182                 return true;
00183 
00184 #elif defined (__AVR_ATmega128__) // like 328 timer 0, with short names
00185 
00186                 // table by prescale = 2^n where n is the table index
00187                 num_prescale_factors = 11;
00188                 unsigned char * preScale;
00189                 preScale = (unsigned char*) calloc (num_prescale_factors, sizeof(unsigned char));
00190                 preScale[0] = (1 << CS00);
00191                 preScale[1] = 0;
00192                 preScale[2] = 0;
00193                 preScale[3] = (1 << CS01);
00194                 preScale[4] = 0;
00195                 preScale[5] = 0;
00196                 preScale[6] = (1 << CS01) | (1 << CS00);
00197                 preScale[7] = 0;
00198                 preScale[8] = (1 << CS02);
00199                 preScale[9] = 0;
00200                 preScale[10] = (1 << CS02) | (1 << CS00);
00201 
00202                 // determine prescale factor and TOP/OCR2 value
00203                 // use minimum prescale factor
00204                 unsigned char ps, i;
00205                 for (i = 0; i < num_prescale_factors; i++)
00206                 {
00207                                 ps = preScale[i];
00208                                 if (ps && (ticks >> i) <= 256)
00209                                                 break;
00210                 }
00211 
00212                 //return error if usec is too large
00213                 if (i == num_prescale_factors)
00214                 {
00215                                 free (preScale);
00216                                 return false;
00217                 }
00218 
00219                 free (preScale);
00220 
00221                 period_ = ((long)(ticks >> i) * (1 << i))/ (F_CPU /1000000);
00222 
00223                 // disable timer 2 interrupts
00224                 TIMSK = 0;
00225 
00226                 // use system clock (clkI/O).
00227                 ASSR &= ~(1 << AS0);
00228 
00229                 // Clear Timer on Compare Match (CTC) mode and set prescale bits
00230                 TCCR2 = (1 << WGM21) | ps;
00231 
00232                 // set TOP so timer period is (ticks >> i)
00233                 OCR2 = (ticks >> i) - 1;
00234 
00235                 return true;
00236 
00237 #elif defined (__AVR_ATmega32U4__)
00238 
00239                 TCCR4B = 0;
00240                 TCCR4A = 0;
00241                 TCCR4C = 0;
00242                 TCCR4D = 0;
00243                 TCCR4E = 0;
00244 
00245                 // table by prescale = 2^n where n is the table index
00246                 num_prescale_factors = 15;
00247                 unsigned char * preScale;
00248                 preScale = (unsigned char*) calloc (num_prescale_factors, sizeof(unsigned char));
00249                 preScale[0] = (1 << CS40);
00250                 preScale[1] = (1 << CS41);
00251                 preScale[2] = (1 << CS40) | (1 << CS41);
00252                 preScale[3] = (1 << CS42);
00253                 preScale[4] = (1 << CS40) | (1 << CS42);
00254                 preScale[5] = (1 << CS41) | (1 << CS42);
00255                 preScale[6] = (1 << CS40) | (1 << CS41) | (1 << CS42);
00256                 preScale[7] = (1 << CS43);
00257                 preScale[8] = (1 << CS40) | (1 << CS43);
00258                 preScale[9] = (1 << CS41) | (1 << CS43);
00259                 preScale[10] = (1 << CS40) | (1 << CS41) | (1 << CS43);
00260                 preScale[11] = (1 << CS42) | (1 << CS43);
00261                 preScale[12] = (1 << CS40) | (1 << CS42) | (1 << CS43);
00262                 preScale[13] = (1 << CS41) | (1 << CS42) | (1 << CS43);
00263                 preScale[14] = (1 << CS40) | (1 << CS41) | (1 << CS42) | (1 << CS43);
00264 
00265                 // determine prescale factor and TOP/OCR4C value
00266                 // use minimum prescale factor
00267                 unsigned char ps, i;
00268                 for (i = 0; i < num_prescale_factors; i++)
00269                 {
00270                                 ps = preScale[i];
00271                                 if (ps && (ticks >> i) <= 256)
00272                                                 break;
00273                 }
00274 
00275                 //return error if usec is too large
00276                 if (i == num_prescale_factors)
00277                 {
00278                                 free (preScale);
00279                                 return false;
00280                 }
00281 
00282                 free (preScale);
00283 
00284                 period_ = ((long)(ticks >> i) * (1 << i))/ (F_CPU /1000000);
00285 
00286                 // disable timer 4 interrupts
00287                 TIMSK4 = 0;
00288 
00289                 // set prescale bits in TCCR4B (not sure if/why PSR4 is needed, doc says it resets the prescaler)
00290                 TCCR4B = ps | (1<<PSR4);
00291 
00292                 // set TOP so timer period is (ticks >> i)
00293                 OCR4A = (ticks >> i) - 1;
00294 
00295                 return true;
00296 
00297 #else
00298 #error Unsupported CPU type
00299 #endif
00300 
00301 }
00302 
00303 
00304 
00305 void MozziTimer2::start()
00306 {
00307 #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega644P__)
00308 
00309                 TIMSK2 |= (1 << OCIE2A);
00310 
00311 #elif defined (__AVR_ATmega8__) || (__AVR_ATmega128__)
00312 
00313                 TIMSK |= (1 << OCIE2);
00314 
00315 #elif defined (__AVR_ATmega32U4__)
00316 
00317                 TIMSK4 |= (1 << OCIE4A);
00318 
00319 #endif
00320 }
00321 
00322 
00323 
00324 void MozziTimer2::stop()
00325 {
00326 #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega644P__)
00327 
00328                 TIMSK2 &=  ~(1 << OCIE2A);
00329 
00330 #elif defined (__AVR_ATmega8__) || (__AVR_ATmega128__)
00331 
00332                 TIMSK &= ~(1<<OCIE2);
00333 
00334 #elif defined (__AVR_ATmega32U4__)
00335 
00336                 TIMSK4 = 0;
00337 
00338 #endif
00339 }
00340 
00341 
00342 #if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega644P__)
00343 
00344 // interrupt service routine that wraps a user defined function supplied by attachInterrupt
00345 ISR(TIMER2_OVF_vect, ISR_NOBLOCK)
00346 {
00347                   (*MozziTimer2::f_)();
00348 }
00349 
00350 /*
00351 ISR(TIMER2_COMPA_vect, ISR_NOBLOCK) // ISR_NOBLOCK so it can be interrupted by Timer 1 (audio)
00352 {
00353                 // disable timer 2 interrupts
00354                 TIMSK2 = 0;
00355                 // call user function
00356                 (*MozziTimer2::f_)();
00357                 // in case f_ enabled interrupts
00358                 cli();
00359                 // clear counter if start_ is true
00360                 if (MozziTimer2::start_)
00361                 {
00362                                 // start counter
00363                                 TCNT2 = 0;
00364                                 // clear possible pending interrupt
00365                                 TIFR2 |= (1 << OCF2A);
00366                 }
00367                 // enable timer 2 COMPA interrupt
00368                 TIMSK2 |= (1 << OCIE2A);
00369 }
00370 
00371 */
00372 #elif defined (__AVR_ATmega8__) || (__AVR_ATmega128__)
00373 
00374 ISR(TIMER2_COMP_vect, ISR_NOBLOCK)
00375 {
00376                 // disable timer 2 interrupts
00377                 TIMSK = 0;
00378                 // call user function
00379                 (*MozziTimer2::f_)();
00380                 // in case f_ enabled interrupts
00381                 cli();
00382                 // clear counter if start_ is true
00383                 if (MozziTimer2::start_)
00384                 {
00385                                 // start counter
00386                                 TCNT2 = 0;
00387                                 // clear possible pending interrupt
00388                                 TIFR |= (1 << OCF2);
00389                 }
00390                 // enable timer 2 COMPA interrupt
00391                 TIMSK |= (1 << OCIE2);
00392 }
00393 
00394 
00395 #elif defined (__AVR_ATmega32U4__)
00396 
00397 ISR(TIMER4_COMPA_vect, ISR_NOBLOCK) // this all needs checking
00398 {
00399                 // disable timer 4 interrupts
00400                 TIMSK4 = 0;
00401                 // call user function
00402                 (*MozziTimer2::f_)();
00403                 // in case f_ enabled interrupts
00404                 cli();
00405                 // clear counter if start_ is true
00406                 if (MozziTimer2::start_)
00407                 {
00408                                 // start counter
00409                                 TCNT4 = 0;
00410                                 // clear possible pending interrupt
00411                                 TIFR4 |= (1 << OCF4A);
00412                 }
00413                 // enable timer 4 COMPA interrupt
00414                 TIMSK4 |= (1 << OCIE4A);
00415 }
00416 
00417 #endif
00418 
00419