Thu, 07 Jul 2016 12:23:34 +0200
added missing sanguino files
2 | 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 "Arduino.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 |