Skip to content

Commit 93c446e

Browse files
committed
Merge pull request #1581 from bjpirt/tone
Implementation of Tone library using timer1
2 parents 4f5f003 + 7beda37 commit 93c446e

File tree

1 file changed

+113
-39
lines changed

1 file changed

+113
-39
lines changed

cores/esp8266/Tone.cpp

+113-39
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,125 @@
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-
*************************************************/
1+
/*
2+
Tone.cpp
3+
4+
A Tone Generator Library for the ESP8266
5+
6+
Copyright (c) 2016 Ben Pirt. All rights reserved.
7+
This file is part of the esp8266 core for Arduino environment.
8+
9+
This library is free software; you can redistribute it and/or
10+
modify it under the terms of the GNU Lesser General Public
11+
License as published by the Free Software Foundation; either
12+
version 2.1 of the License, or (at your option) any later version.
13+
14+
This library is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
Lesser General Public License for more details.
18+
19+
You should have received a copy of the GNU Lesser General Public
20+
License along with this library; if not, write to the Free Software
21+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22+
*/
3423

3524
#include "Arduino.h"
3625
#include "pins_arduino.h"
3726

38-
/*
27+
#define AVAILABLE_TONE_PINS 1
28+
const uint8_t tone_timers[] = { 1 };
29+
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255, };
30+
static long toggle_counts[AVAILABLE_TONE_PINS] = { 0, };
31+
#define T1INDEX 0
32+
33+
void t1IntHandler();
34+
3935
static int8_t toneBegin(uint8_t _pin) {
40-
//TODO implement tone
41-
return 0;
36+
int8_t _index = -1;
37+
38+
// if we're already using the pin, reuse it.
39+
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
40+
if (tone_pins[i] == _pin) {
41+
return i;
42+
}
43+
}
44+
45+
// search for an unused timer.
46+
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
47+
if (tone_pins[i] == 255) {
48+
tone_pins[i] = _pin;
49+
_index = i;
50+
break;
51+
}
52+
}
53+
54+
return _index;
4255
}
43-
*/
4456

57+
// frequency (in hertz) and duration (in milliseconds).
4558
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) {
46-
//TODO implement tone
59+
int8_t _index;
60+
61+
_index = toneBegin(_pin);
62+
63+
if (_index >= 0) {
64+
// Set the pinMode as OUTPUT
65+
pinMode(_pin, OUTPUT);
66+
67+
// Calculate the toggle count
68+
if (duration > 0) {
69+
toggle_counts[_index] = 2 * frequency * duration / 1000;
70+
} else {
71+
toggle_counts[_index] = -1;
72+
}
73+
74+
// set up the interrupt frequency
75+
switch (tone_timers[_index]) {
76+
case 0:
77+
// Not currently supported
78+
break;
79+
80+
case 1:
81+
timer1_disable();
82+
timer1_isr_init();
83+
timer1_attachInterrupt(t1IntHandler);
84+
timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
85+
timer1_write((clockCyclesPerMicrosecond() * 500000) / frequency);
86+
break;
87+
}
88+
}
89+
}
90+
91+
void disableTimer(uint8_t _index) {
92+
tone_pins[_index] = 255;
93+
94+
switch (tone_timers[_index]) {
95+
case 0:
96+
// Not currently supported
97+
break;
98+
99+
case 1:
100+
timer1_disable();
101+
break;
102+
}
47103
}
48104

49105
void noTone(uint8_t _pin) {
50-
//TODO implement tone
106+
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
107+
if (tone_pins[i] == _pin) {
108+
tone_pins[i] = 255;
109+
disableTimer(i);
110+
break;
111+
}
112+
}
113+
digitalWrite(_pin, LOW);
114+
}
115+
116+
void t1IntHandler() {
117+
if (toggle_counts[T1INDEX] > 0){
118+
// toggle the pin
119+
digitalWrite(tone_pins[T1INDEX], toggle_counts[T1INDEX] % 2);
120+
toggle_counts[T1INDEX]--;
121+
}else{
122+
disableTimer(T1INDEX);
123+
digitalWrite(tone_pins[T1INDEX], LOW);
124+
}
51125
}

0 commit comments

Comments
 (0)