![]() |
Mozzi
alpha 0.01.1f
sound synthesis library for Arduino
|
00001 /* 00002 FlexiTimer2.h - Using timer2 with a configurable resolution 00003 Wim Leers <work@wimleers.com> 00004 00005 Based on MsTimer2 00006 Javier Valencia <javiervalencia80@gmail.com> 00007 00008 History: 00009 16/Dec/2011 - Added Teensy/Teensy++ support (bperrybap) 00010 note: teensy uses timer4 instead of timer2 00011 25/April/10 - Based on MsTimer2 V0.5 (from 29/May/09) 00012 00013 This library is free software; you can redistribute it and/or 00014 modify it under the terms of the GNU Lesser General Public 00015 License as published by the Free Software Foundation; either 00016 version 2.1 of the License, or (at your option) any later version. 00017 00018 This library is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 Lesser General Public License for more details. 00022 00023 You should have received a copy of the GNU Lesser General Public 00024 License along with this library; if not, write to the Free Software 00025 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00026 */ 00027 00028 #include <FlexiTimer2.h> 00029 00030 unsigned long FlexiTimer2::time_units; 00031 void (*FlexiTimer2::func)(); 00032 volatile unsigned long FlexiTimer2::count; 00033 volatile char FlexiTimer2::overflowing; 00034 volatile unsigned int FlexiTimer2::tcnt2; 00035 00036 void FlexiTimer2::set(unsigned long ms, void (*f)()) 00037 { 00038 FlexiTimer2::set(ms, 0.001, f); 00039 } 00040 00041 00047 void FlexiTimer2::set(unsigned long units, double resolution, void (*f)()) 00048 { 00049 float prescaler = 0.0; 00050 00051 if (units == 0) 00052 time_units = 1; 00053 else 00054 time_units = units; 00055 00056 func = f; 00057 00058 #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__) 00059 00060 TIMSK2 &= ~(1<<TOIE2); 00061 TCCR2A &= ~((1<<WGM21) | (1<<WGM20)); 00062 TCCR2B &= ~(1<<WGM22); 00063 ASSR &= ~(1<<AS2); 00064 TIMSK2 &= ~(1<<OCIE2A); 00065 00066 if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) 00067 { // prescaler set to 64 00068 TCCR2B |= (1<<CS22); 00069 TCCR2B &= ~((1<<CS21) | (1<<CS20)); 00070 prescaler = 64.0; 00071 } 00072 else if (F_CPU < 1000000UL) 00073 { // prescaler set to 8 00074 TCCR2B |= (1<<CS21); 00075 TCCR2B &= ~((1<<CS22) | (1<<CS20)); 00076 prescaler = 8.0; 00077 } 00078 else 00079 { // F_CPU > 16Mhz, prescaler set to 128 00080 TCCR2B |= ((1<<CS22) | (1<<CS20)); 00081 TCCR2B &= ~(1<<CS21); 00082 prescaler = 128.0; 00083 } 00084 #elif defined (__AVR_ATmega8__) 00085 TIMSK &= ~(1<<TOIE2); 00086 TCCR2 &= ~((1<<WGM21) | (1<<WGM20)); 00087 TIMSK &= ~(1<<OCIE2); 00088 ASSR &= ~(1<<AS2); 00089 00090 if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) 00091 { // prescaler set to 64 00092 TCCR2 |= (1<<CS22); 00093 TCCR2 &= ~((1<<CS21) | (1<<CS20)); 00094 prescaler = 64.0; 00095 } 00096 else if (F_CPU < 1000000UL) 00097 { // prescaler set to 8 00098 TCCR2 |= (1<<CS21); 00099 TCCR2 &= ~((1<<CS22) | (1<<CS20)); 00100 prescaler = 8.0; 00101 } 00102 else 00103 { // F_CPU > 16Mhz, prescaler set to 128 00104 TCCR2 |= ((1<<CS22) && (1<<CS20)); 00105 TCCR2 &= ~(1<<CS21); 00106 prescaler = 128.0; 00107 } 00108 #elif defined (__AVR_ATmega128__) 00109 TIMSK &= ~(1<<TOIE2); 00110 TCCR2 &= ~((1<<WGM21) | (1<<WGM20)); 00111 TIMSK &= ~(1<<OCIE2); 00112 00113 if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) 00114 { // prescaler set to 64 00115 TCCR2 |= ((1<<CS21) | (1<<CS20)); 00116 TCCR2 &= ~(1<<CS22); 00117 prescaler = 64.0; 00118 } 00119 else if (F_CPU < 1000000UL) 00120 { // prescaler set to 8 00121 TCCR2 |= (1<<CS21); 00122 TCCR2 &= ~((1<<CS22) | (1<<CS20)); 00123 prescaler = 8.0; 00124 } 00125 else 00126 { // F_CPU > 16Mhz, prescaler set to 256 00127 TCCR2 |= (1<<CS22); 00128 TCCR2 &= ~((1<<CS21) | (1<<CS20)); 00129 prescaler = 256.0; 00130 } 00131 #elif defined (__AVR_ATmega32U4__) 00132 TCCR4B = 0; 00133 TCCR4A = 0; 00134 TCCR4C = 0; 00135 TCCR4D = 0; 00136 TCCR4E = 0; 00137 if (F_CPU >= 16000000L) 00138 { 00139 TCCR4B = (1<<CS43) | (1<<PSR4); 00140 prescaler = 128.0; 00141 } 00142 else if (F_CPU >= 8000000L) 00143 { 00144 TCCR4B = (1<<CS42) | (1<<CS41) | (1<<CS40) | (1<<PSR4); 00145 prescaler = 64.0; 00146 } 00147 else if (F_CPU >= 4000000L) 00148 { 00149 TCCR4B = (1<<CS42) | (1<<CS41) | (1<<PSR4); 00150 prescaler = 32.0; 00151 } 00152 else if (F_CPU >= 2000000L) 00153 { 00154 TCCR4B = (1<<CS42) | (1<<CS40) | (1<<PSR4); 00155 prescaler = 16.0; 00156 } 00157 else if (F_CPU >= 1000000L) 00158 { 00159 TCCR4B = (1<<CS42) | (1<<PSR4); 00160 prescaler = 8.0; 00161 } 00162 else if (F_CPU >= 500000L) 00163 { 00164 TCCR4B = (1<<CS41) | (1<<CS40) | (1<<PSR4); 00165 prescaler = 4.0; 00166 } 00167 else 00168 { 00169 TCCR4B = (1<<CS41) | (1<<PSR4); 00170 prescaler = 2.0; 00171 } 00172 tcnt2 = (int)((float)F_CPU * resolution / prescaler) - 1; 00173 OCR4C = tcnt2; 00174 return; 00175 #else 00176 #error Unsupported CPU type 00177 #endif 00178 00179 tcnt2 = 256 - (int)((float)F_CPU * resolution / prescaler); 00180 } 00181 00182 void FlexiTimer2::start() 00183 { 00184 count = 0; 00185 overflowing = 0; 00186 #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__) 00187 00188 TCNT2 = tcnt2; 00189 TIMSK2 |= (1<<TOIE2); 00190 #elif defined (__AVR_ATmega128__) 00191 00192 TCNT2 = tcnt2; 00193 TIMSK |= (1<<TOIE2); 00194 #elif defined (__AVR_ATmega8__) 00195 00196 TCNT2 = tcnt2; 00197 TIMSK |= (1<<TOIE2); 00198 #elif defined (__AVR_ATmega32U4__) 00199 00200 TIFR4 = (1<<TOV4); 00201 TCNT4 = 0; 00202 TIMSK4 = (1<<TOIE4); 00203 #endif 00204 } 00205 00206 void FlexiTimer2::stop() 00207 { 00208 #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__) 00209 TIMSK2 &= ~(1<<TOIE2); 00210 #elif defined (__AVR_ATmega128__) 00211 00212 TIMSK &= ~(1<<TOIE2); 00213 #elif defined (__AVR_ATmega8__) 00214 00215 TIMSK &= ~(1<<TOIE2); 00216 #elif defined (__AVR_ATmega32U4__) 00217 00218 TIMSK4 = 0; 00219 #endif 00220 } 00221 00222 void FlexiTimer2::_overflow() 00223 { 00224 count += 1; 00225 00226 if (count >= time_units && !overflowing) 00227 { 00228 overflowing = 1; 00229 count = 0;//count - time_units; // subtract time_uints to catch missed overflows 00230 // set to 0 if you don't want this. 00231 (*func)(); 00232 overflowing = 0; 00233 } 00234 } 00235 #if defined (__AVR_ATmega32U4__) 00236 ISR(TIMER4_OVF_vect) 00237 { 00238 #else 00239 ISR(TIMER2_OVF_vect) 00240 { 00241 #endif 00242 #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__) 00243 TCNT2 = FlexiTimer2::tcnt2; 00244 #elif defined (__AVR_ATmega128__) 00245 00246 TCNT2 = FlexiTimer2::tcnt2; 00247 #elif defined (__AVR_ATmega8__) 00248 00249 TCNT2 = FlexiTimer2::tcnt2; 00250 #elif defined (__AVR_ATmega32U4__) 00251 // not necessary on 32u4's high speed timer4 00252 #endif 00253 00254 FlexiTimer2::_overflow(); 00255 } 00256