Statistics
| Branch: | Revision:

root / arduino-1.0 / hardware / arduino / cores / arduino / Tone.cpp @ 58d82c77

History | View | Annotate | Download (14 KB)

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