diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 0a16645d2..c27259c4a 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -177,11 +177,6 @@ void analogWriteFreq(uint32_t freq); void analogWriteResolution(int res); void analogWriteRange(uint32_t range); -unsigned long millis(void); -unsigned long micros(void); -uint64_t micros64(void); -void delay(unsigned long); -void delayMicroseconds(unsigned int us); unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index 4ad59e223..b3e187fc5 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -124,10 +124,13 @@ class EspClass { #if defined(F_CPU) || defined(CORE_MOCK) constexpr uint8_t getCpuFreqMHz() const { - return clockCyclesPerMicrosecond(); + return esp_get_cpu_freq_mhz(); } #else - uint8_t getCpuFreqMHz(); + uint8_t getCpuFreqMHz() const + { + return esp_get_cpu_freq_mhz(); + } #endif uint32_t getFlashChipId(); diff --git a/cores/esp8266/PolledTimeout.h b/cores/esp8266/PolledTimeout.h index 715564a8e..7eec547e4 100644 --- a/cores/esp8266/PolledTimeout.h +++ b/cores/esp8266/PolledTimeout.h @@ -4,7 +4,7 @@ /* PolledTimeout.h - Encapsulation of a polled Timeout - + Copyright (c) 2018 Daniel Salazar. All rights reserved. This file is part of the esp8266 core for Arduino environment. @@ -23,9 +23,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - -#include +#include // IRAM_ATTR +#include // std::numeric_limits +#include // std::is_unsigned +#include namespace esp8266 { @@ -70,13 +71,13 @@ struct TimeSourceMillis struct TimeSourceCycles { - // time policy based on ESP.getCycleCount() + // time policy based on esp_get_cycle_count() // this particular time measurement is intended to be called very often // (every loop, every yield) - using timeType = decltype(ESP.getCycleCount()); - static timeType time() {return ESP.getCycleCount();} - static constexpr timeType ticksPerSecond = ESP.getCpuFreqMHz() * 1000000UL; // 80'000'000 or 160'000'000 Hz + using timeType = decltype(esp_get_cycle_count()); + static timeType time() {return esp_get_cycle_count();} + static constexpr timeType ticksPerSecond = esp_get_cpu_freq_mhz() * 1000000UL; // 80'000'000 or 160'000'000 Hz static constexpr timeType ticksPerSecondMax = 160000000; // 160MHz }; @@ -161,13 +162,13 @@ public: return expiredRetrigger(); return expiredOneShot(); } - + IRAM_ATTR // fast operator bool() { - return expired(); + return expired(); } - + bool canExpire () const { return !_neverExpires; @@ -178,6 +179,7 @@ public: return _timeout != alwaysExpired; } + // Resets, will trigger after this new timeout. IRAM_ATTR // called from ISR void reset(const timeType newUserTimeout) { @@ -186,12 +188,30 @@ public: _neverExpires = (newUserTimeout < 0) || (newUserTimeout > timeMax()); } + // Resets, will trigger after the timeout previously set. IRAM_ATTR // called from ISR void reset() { _start = TimePolicyT::time(); } + // Resets to just expired so that on next poll the check will immediately trigger for the user, + // also change timeout (after next immediate trigger). + IRAM_ATTR // called from ISR + void resetAndSetExpired (const timeType newUserTimeout) + { + reset(newUserTimeout); + _start -= _timeout; + } + + // Resets to just expired so that on next poll the check will immediately trigger for the user. + IRAM_ATTR // called from ISR + void resetAndSetExpired () + { + reset(); + _start -= _timeout; + } + void resetToNeverExpires () { _timeout = alwaysExpired + 1; // because canWait() has precedence @@ -202,7 +222,7 @@ public: { return TimePolicyT::toUserUnit(_timeout); } - + static constexpr timeType timeMax() { return TimePolicyT::timeMax; @@ -235,14 +255,14 @@ protected: } return false; } - + IRAM_ATTR // fast bool expiredOneShot() const { // returns "always expired" or "has expired" return !canWait() || checkExpired(TimePolicyT::time()); } - + timeType _timeout; timeType _start; bool _neverExpires; @@ -259,14 +279,14 @@ using periodic = polledTimeout::timeoutTemplate /*__attribute__((deprecate using oneShotMs = polledTimeout::timeoutTemplate; using periodicMs = polledTimeout::timeoutTemplate; -// Time policy based on ESP.getCycleCount(), and intended to be called very often: +// Time policy based on esp_get_cycle_count(), and intended to be called very often: // "Fast" versions sacrifices time range for improved precision and reduced execution time (by 86%) -// (cpu cycles for ::expired(): 372 (millis()) vs 52 (ESP.getCycleCount())) +// (cpu cycles for ::expired(): 372 (millis()) vs 52 (esp_get_cycle_count())) // timeMax() values: // Ms: max is 26843 ms (26.8 s) // Us: max is 26843545 us (26.8 s) // Ns: max is 1073741823 ns ( 1.07 s) -// (time policy based on ESP.getCycleCount() is intended to be called very often) +// (time policy based on esp_get_cycle_count() is intended to be called very often) using oneShotFastMs = polledTimeout::timeoutTemplate; using periodicFastMs = polledTimeout::timeoutTemplate; diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index 5a2893a6e..6d6edf030 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -123,6 +123,29 @@ extern "C" { #endif void precache(void *f, uint32_t bytes); +unsigned long millis(void); +unsigned long micros(void); +uint64_t micros64(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int us); + +#if defined(F_CPU) || defined(CORE_MOCK) +#ifdef __cplusplus +constexpr +#else +inline +#endif +int esp_get_cpu_freq_mhz() +{ + return F_CPU / 1000000L; +} +#else +inline int esp_get_cpu_freq_mhz() +{ + return system_get_cpu_freq(); +} +#endif + #ifdef __cplusplus } diff --git a/tests/host/common/MockEsp.cpp b/tests/host/common/MockEsp.cpp index 5d2289a5f..2045523e8 100644 --- a/tests/host/common/MockEsp.cpp +++ b/tests/host/common/MockEsp.cpp @@ -208,7 +208,7 @@ uint32_t EspClass::getFlashChipSize(void) String EspClass::getFullVersion () { - return "host-emulation"; + return "emulation-on-host"; } uint32_t EspClass::getFreeContStack() @@ -221,6 +221,11 @@ void EspClass::resetFreeContStack() } uint32_t EspClass::getCycleCount() +{ + return esp_get_cycle_count(); +} + +uint32_t esp_get_cycle_count() { timeval t; gettimeofday(&t, NULL); diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index 4032d8893..eff32dd46 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -31,6 +31,29 @@ #define CORE_MOCK 1 +// + +#define ARDUINO 267 +#define ESP8266 1 +#define A0 0 +#define LED_BUILTIN 0 +#define F_CPU 80000000 +#define LWIP_OPEN_SRC +#define TCP_MSS 536 +#define LWIP_FEATURES 1 + +// + +#define D0 0 +#define D1 1 +#define D2 3 +#define D3 3 +#define D4 4 +#define D5 5 +#define D6 6 +#define D7 7 +#define D8 8 + // include host's STL before any other include file // because core definition like max() is in the way @@ -61,28 +84,10 @@ typedef uint32_t uint32; // -#define ARDUINO 267 -#define ESP8266 1 -#define A0 0 -#define LED_BUILTIN 0 -#define F_CPU 80000000 -#define LWIP_OPEN_SRC -#define TCP_MSS 536 -#define LWIP_FEATURES 1 +#include +#include -// - -#define D0 0 -#define D1 1 -#define D2 3 -#define D3 3 -#define D4 4 -#define D5 5 -#define D6 6 -#define D7 7 -#define D8 8 - -// +uint32_t esp_get_cycle_count(); #include