]> git.donarmstrong.com Git - qmk_firmware.git/blob - protocol/usb_hid/arduino-1.0.1/cores/arduino/Tone.cpp
Change TOP_DIR to TMK_DIR in makefiles
[qmk_firmware.git] / protocol / usb_hid / arduino-1.0.1 / cores / arduino / Tone.cpp
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