mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
Fixup 7122, new startWaveformCycles more aptly named startWaveformClockCycles (like in rest of core API for this type of use). (#7218)
Fix/clarify comments. Fix redundancies in Tone, end Tone waveform on exact period limit for proper sound. Fix redundancies in wiring_pwmExtend Servo to map in-use pins, Tone already has this.
This commit is contained in:
parent
4ca69bc21d
commit
ea1fdb210f
@ -22,14 +22,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "user_interface.h"
|
|
||||||
#include "core_esp8266_waveform.h"
|
#include "core_esp8266_waveform.h"
|
||||||
|
#include "user_interface.h"
|
||||||
|
|
||||||
// Which pins have a tone running on them?
|
// Which pins have a tone running on them?
|
||||||
static uint32_t _toneMap = 0;
|
static uint32_t _toneMap = 0;
|
||||||
|
|
||||||
|
|
||||||
static void _startTone(uint8_t _pin, uint32_t high, uint32_t low, unsigned long duration) {
|
static void _startTone(uint8_t _pin, uint32_t high, uint32_t low, uint32_t duration) {
|
||||||
if (_pin > 16) {
|
if (_pin > 16) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -39,7 +39,10 @@ static void _startTone(uint8_t _pin, uint32_t high, uint32_t low, unsigned long
|
|||||||
high = std::max(high, (uint32_t)microsecondsToClockCycles(25)); // new 20KHz maximum tone frequency,
|
high = std::max(high, (uint32_t)microsecondsToClockCycles(25)); // new 20KHz maximum tone frequency,
|
||||||
low = std::max(low, (uint32_t)microsecondsToClockCycles(25)); // (25us high + 25us low period = 20KHz)
|
low = std::max(low, (uint32_t)microsecondsToClockCycles(25)); // (25us high + 25us low period = 20KHz)
|
||||||
|
|
||||||
if (startWaveformCycles(_pin, high, low, microsecondsToClockCycles(duration * 1000))) {
|
duration = microsecondsToClockCycles(duration * 1000UL);
|
||||||
|
duration += high + low - 1;
|
||||||
|
duration -= duration % (high + low);
|
||||||
|
if (startWaveformClockCycles(_pin, high, low, duration)) {
|
||||||
_toneMap |= 1 << _pin;
|
_toneMap |= 1 << _pin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,7 +52,7 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) {
|
|||||||
if (frequency == 0) {
|
if (frequency == 0) {
|
||||||
noTone(_pin);
|
noTone(_pin);
|
||||||
} else {
|
} else {
|
||||||
uint32_t period = (1000000L * system_get_cpu_freq()) / frequency;
|
uint32_t period = microsecondsToClockCycles(1000000UL) / frequency;
|
||||||
uint32_t high = period / 2;
|
uint32_t high = period / 2;
|
||||||
uint32_t low = period - high;
|
uint32_t low = period - high;
|
||||||
_startTone(_pin, high, low, duration);
|
_startTone(_pin, high, low, duration);
|
||||||
@ -63,7 +66,7 @@ void tone(uint8_t _pin, double frequency, unsigned long duration) {
|
|||||||
if (frequency < 1.0) { // FP means no exact comparisons
|
if (frequency < 1.0) { // FP means no exact comparisons
|
||||||
noTone(_pin);
|
noTone(_pin);
|
||||||
} else {
|
} else {
|
||||||
double period = (1000000.0L * system_get_cpu_freq()) / frequency;
|
double period = (double)microsecondsToClockCycles(1000000UL) / frequency;
|
||||||
uint32_t high = (uint32_t)((period / 2.0) + 0.5);
|
uint32_t high = (uint32_t)((period / 2.0) + 0.5);
|
||||||
uint32_t low = (uint32_t)(period + 0.5) - high;
|
uint32_t low = (uint32_t)(period + 0.5) - high;
|
||||||
_startTone(_pin, high, low, duration);
|
_startTone(_pin, high, low, duration);
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
Copyright (c) 2018 Earle F. Philhower, III. All rights reserved.
|
Copyright (c) 2018 Earle F. Philhower, III. All rights reserved.
|
||||||
|
|
||||||
The core idea is to have a programmable waveform generator with a unique
|
The core idea is to have a programmable waveform generator with a unique
|
||||||
high and low period (defined in microseconds). TIMER1 is set to 1-shot
|
high and low period (defined in microseconds or CPU clock cycles). TIMER1 is
|
||||||
mode and is always loaded with the time until the next edge of any live
|
set to 1-shot mode and is always loaded with the time until the next edge
|
||||||
waveforms.
|
of any live waveforms.
|
||||||
|
|
||||||
Up to one waveform generator per pin supported.
|
Up to one waveform generator per pin supported.
|
||||||
|
|
||||||
Each waveform generator is synchronized to the ESP cycle counter, not the
|
Each waveform generator is synchronized to the ESP clock cycle counter, not the
|
||||||
timer. This allows for removing interrupt jitter and delay as the counter
|
timer. This allows for removing interrupt jitter and delay as the counter
|
||||||
always increments once per 80MHz clock. Changes to a waveform are
|
always increments once per 80MHz clock. Changes to a waveform are
|
||||||
contiguous and only take effect on the next waveform transition,
|
contiguous and only take effect on the next waveform transition,
|
||||||
@ -19,8 +19,9 @@
|
|||||||
|
|
||||||
This replaces older tone(), analogWrite(), and the Servo classes.
|
This replaces older tone(), analogWrite(), and the Servo classes.
|
||||||
|
|
||||||
Everywhere in the code where "cycles" is used, it means ESP.getCycleTime()
|
Everywhere in the code where "cycles" is used, it means ESP.getCycleCount()
|
||||||
cycles, not TIMER1 cycles (which may be 2 CPU clocks @ 160MHz).
|
clock cycle count, or an interval measured in CPU clock cycles, but not TIMER1
|
||||||
|
cycles (which may be 2 CPU clock cycles @ 160MHz).
|
||||||
|
|
||||||
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
|
||||||
@ -112,10 +113,10 @@ void setTimer1Callback(uint32_t (*fn)()) {
|
|||||||
// waveform smoothly on next low->high transition. For immediate change, stopWaveform()
|
// waveform smoothly on next low->high transition. For immediate change, stopWaveform()
|
||||||
// first, then it will immediately begin.
|
// first, then it will immediately begin.
|
||||||
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS) {
|
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS) {
|
||||||
return startWaveformCycles(pin, microsecondsToClockCycles(timeHighUS), microsecondsToClockCycles(timeLowUS), microsecondsToClockCycles(runTimeUS));
|
return startWaveformClockCycles(pin, microsecondsToClockCycles(timeHighUS), microsecondsToClockCycles(timeLowUS), microsecondsToClockCycles(runTimeUS));
|
||||||
}
|
}
|
||||||
|
|
||||||
int startWaveformCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles) {
|
int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles) {
|
||||||
if ((pin > 16) || isFlashInterfacePin(pin)) {
|
if ((pin > 16) || isFlashInterfacePin(pin)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
Copyright (c) 2018 Earle F. Philhower, III. All rights reserved.
|
Copyright (c) 2018 Earle F. Philhower, III. All rights reserved.
|
||||||
|
|
||||||
The core idea is to have a programmable waveform generator with a unique
|
The core idea is to have a programmable waveform generator with a unique
|
||||||
high and low period (defined in microseconds). TIMER1 is set to 1-shot
|
high and low period (defined in microseconds or CPU clock cycles). TIMER1 is
|
||||||
mode and is always loaded with the time until the next edge of any live
|
set to 1-shot mode and is always loaded with the time until the next edge
|
||||||
waveforms.
|
of any live waveforms.
|
||||||
|
|
||||||
Up to one waveform generator per pin supported.
|
Up to one waveform generator per pin supported.
|
||||||
|
|
||||||
Each waveform generator is synchronized to the ESP cycle counter, not the
|
Each waveform generator is synchronized to the ESP clock cycle counter, not the
|
||||||
timer. This allows for removing interrupt jitter and delay as the counter
|
timer. This allows for removing interrupt jitter and delay as the counter
|
||||||
always increments once per 80MHz clock. Changes to a waveform are
|
always increments once per 80MHz clock. Changes to a waveform are
|
||||||
contiguous and only take effect on the next waveform transition,
|
contiguous and only take effect on the next waveform transition,
|
||||||
@ -19,8 +19,9 @@
|
|||||||
|
|
||||||
This replaces older tone(), analogWrite(), and the Servo classes.
|
This replaces older tone(), analogWrite(), and the Servo classes.
|
||||||
|
|
||||||
Everywhere in the code where "cycles" is used, it means ESP.getCycleTime()
|
Everywhere in the code where "cycles" is used, it means ESP.getCycleCount()
|
||||||
cycles, not TIMER1 cycles (which may be 2 CPU clocks @ 160MHz).
|
clock cycle count, or an interval measured in CPU clock cycles, but not TIMER1
|
||||||
|
cycles (which may be 2 CPU clock cycles @ 160MHz).
|
||||||
|
|
||||||
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
|
||||||
@ -50,8 +51,10 @@ extern "C" {
|
|||||||
// If runtimeUS > 0 then automatically stop it after that many usecs.
|
// If runtimeUS > 0 then automatically stop it after that many usecs.
|
||||||
// Returns true or false on success or failure.
|
// Returns true or false on success or failure.
|
||||||
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS);
|
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS);
|
||||||
// Same as above, but pass in CPU clock cycles instead of microseconds
|
// Start or change a waveform of the specified high and low CPU clock cycles on specific pin.
|
||||||
int startWaveformCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles);
|
// If runtimeCycles > 0 then automatically stop it after that many CPU clock cycles.
|
||||||
|
// Returns true or false on success or failure.
|
||||||
|
int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles);
|
||||||
// Stop a waveform, if any, on the specified pin.
|
// Stop a waveform, if any, on the specified pin.
|
||||||
// Returns true or false on success or failure.
|
// Returns true or false on success or failure.
|
||||||
int stopWaveform(uint8_t pin);
|
int stopWaveform(uint8_t pin);
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "core_esp8266_waveform.h"
|
#include "core_esp8266_waveform.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "user_interface.h"
|
|
||||||
|
|
||||||
static uint32_t analogMap = 0;
|
static uint32_t analogMap = 0;
|
||||||
static int32_t analogScale = PWMRANGE;
|
static int32_t analogScale = PWMRANGE;
|
||||||
@ -51,7 +50,7 @@ extern void __analogWrite(uint8_t pin, int val) {
|
|||||||
if (pin > 16) {
|
if (pin > 16) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t analogPeriod = (1000000L * system_get_cpu_freq()) / analogFreq;
|
uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq;
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
val = 0;
|
val = 0;
|
||||||
} else if (val > analogScale) {
|
} else if (val > analogScale) {
|
||||||
@ -63,13 +62,11 @@ extern void __analogWrite(uint8_t pin, int val) {
|
|||||||
uint32_t low = analogPeriod - high;
|
uint32_t low = analogPeriod - high;
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);
|
||||||
if (low == 0) {
|
if (low == 0) {
|
||||||
stopWaveform(pin);
|
|
||||||
digitalWrite(pin, HIGH);
|
digitalWrite(pin, HIGH);
|
||||||
} else if (high == 0) {
|
} else if (high == 0) {
|
||||||
stopWaveform(pin);
|
|
||||||
digitalWrite(pin, LOW);
|
digitalWrite(pin, LOW);
|
||||||
} else {
|
} else {
|
||||||
if (startWaveformCycles(pin, high, low, 0)) {
|
if (startWaveformClockCycles(pin, high, low, 0)) {
|
||||||
analogMap |= (1 << pin);
|
analogMap |= (1 << pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||||||
#include <Servo.h>
|
#include <Servo.h>
|
||||||
#include "core_esp8266_waveform.h"
|
#include "core_esp8266_waveform.h"
|
||||||
|
|
||||||
|
uint32_t Servo::_servoMap = 0;
|
||||||
|
|
||||||
// similiar to map but will have increased accuracy that provides a more
|
// similiar to map but will have increased accuracy that provides a more
|
||||||
// symetric api (call it and use result to reverse will provide the original value)
|
// symetric api (call it and use result to reverse will provide the original value)
|
||||||
int improved_map(int value, int minIn, int maxIn, int minOut, int maxOut)
|
int improved_map(int value, int minIn, int maxIn, int minOut, int maxOut)
|
||||||
@ -82,6 +84,7 @@ uint8_t Servo::attach(int pin, uint16_t minUs, uint16_t maxUs)
|
|||||||
void Servo::detach()
|
void Servo::detach()
|
||||||
{
|
{
|
||||||
if (_attached) {
|
if (_attached) {
|
||||||
|
_servoMap &= ~(1 << _pin);
|
||||||
stopWaveform(_pin);
|
stopWaveform(_pin);
|
||||||
_attached = false;
|
_attached = false;
|
||||||
digitalWrite(_pin, LOW);
|
digitalWrite(_pin, LOW);
|
||||||
@ -105,7 +108,10 @@ void Servo::writeMicroseconds(int value)
|
|||||||
{
|
{
|
||||||
_valueUs = value;
|
_valueUs = value;
|
||||||
if (_attached) {
|
if (_attached) {
|
||||||
startWaveform(_pin, _valueUs, REFRESH_INTERVAL - _valueUs, 0);
|
_servoMap &= ~(1 << _pin);
|
||||||
|
if (startWaveform(_pin, _valueUs, REFRESH_INTERVAL - _valueUs, 0)) {
|
||||||
|
_servoMap |= (1 << _pin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
|
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
|
||||||
bool attached(); // return true if this servo is attached, otherwise false
|
bool attached(); // return true if this servo is attached, otherwise false
|
||||||
private:
|
private:
|
||||||
|
static uint32_t _servoMap;
|
||||||
bool _attached;
|
bool _attached;
|
||||||
uint8_t _pin;
|
uint8_t _pin;
|
||||||
uint16_t _minUs;
|
uint16_t _minUs;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user