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