1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

Merge pull request #1581 from bjpirt/tone

Implementation of Tone library using timer1
This commit is contained in:
Ivan Grokhotkov 2016-02-13 13:25:52 +03:00
commit 93c446e782

View File

@ -1,8 +1,10 @@
/* Tone.cpp /*
Tone.cpp
A Tone Generator Library A Tone Generator Library for the ESP8266
Written by Brett Hagman Copyright (c) 2016 Ben Pirt. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -17,35 +19,107 @@
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Version Modified By Date Comments
------- ----------- -------- --------
0001 B Hagman 09/08/02 Initial coding
0002 B Hagman 09/08/18 Multiple pins
0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
0004 B Hagman 09/09/26 Fixed problems with ATmega8
0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
09/11/25 Changed pin toggle method to XOR
09/11/25 Fixed timer0 from being excluded
0006 D Mellis 09/12/29 Replaced objects with functions
0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register
0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY
*************************************************/
#include "Arduino.h" #include "Arduino.h"
#include "pins_arduino.h" #include "pins_arduino.h"
/* #define AVAILABLE_TONE_PINS 1
static int8_t toneBegin(uint8_t _pin) { const uint8_t tone_timers[] = { 1 };
//TODO implement tone static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255, };
return 0; static long toggle_counts[AVAILABLE_TONE_PINS] = { 0, };
} #define T1INDEX 0
*/
void t1IntHandler();
static int8_t toneBegin(uint8_t _pin) {
int8_t _index = -1;
// if we're already using the pin, reuse it.
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
if (tone_pins[i] == _pin) {
return i;
}
}
// search for an unused timer.
for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
if (tone_pins[i] == 255) {
tone_pins[i] = _pin;
_index = i;
break;
}
}
return _index;
}
// frequency (in hertz) and duration (in milliseconds).
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) { void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) {
//TODO implement tone int8_t _index;
_index = toneBegin(_pin);
if (_index >= 0) {
// Set the pinMode as OUTPUT
pinMode(_pin, OUTPUT);
// Calculate the toggle count
if (duration > 0) {
toggle_counts[_index] = 2 * frequency * duration / 1000;
} else {
toggle_counts[_index] = -1;
}
// set up the interrupt frequency
switch (tone_timers[_index]) {
case 0:
// Not currently supported
break;
case 1:
timer1_disable();
timer1_isr_init();
timer1_attachInterrupt(t1IntHandler);
timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
timer1_write((clockCyclesPerMicrosecond() * 500000) / frequency);
break;
}
}
}
void disableTimer(uint8_t _index) {
tone_pins[_index] = 255;
switch (tone_timers[_index]) {
case 0:
// Not currently supported
break;
case 1:
timer1_disable();
break;
}
} }
void noTone(uint8_t _pin) { void noTone(uint8_t _pin) {
//TODO implement tone for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
if (tone_pins[i] == _pin) {
tone_pins[i] = 255;
disableTimer(i);
break;
}
}
digitalWrite(_pin, LOW);
}
void t1IntHandler() {
if (toggle_counts[T1INDEX] > 0){
// toggle the pin
digitalWrite(tone_pins[T1INDEX], toggle_counts[T1INDEX] % 2);
toggle_counts[T1INDEX]--;
}else{
disableTimer(T1INDEX);
digitalWrite(tone_pins[T1INDEX], LOW);
}
} }