mirror of
https://github.com/esphome/esphome.git
synced 2026-09-26 14:30:23 +00:00
On 32-bit targets GCC does not optimize 64-bit constant division into a multiply-by-reciprocal, emitting a call to __udivdi3 instead (~650-710 ns on Xtensa @ 240 MHz). Add micros_to_millis() which exploits 1000 = 8 * 125: a free right-shift by 3 followed by Euclidean decomposition with D=125, reducing the 64-bit division to a single 32-bit / 125U that GCC compiles to a multiply-by-reciprocal. Benchmarked at 258 ns per call on ESP32 classic — a 2.5-2.8x speedup. With ~21 millis() calls per loop iteration this saves ~9 us per loop.
43 lines
1.0 KiB
C++
43 lines
1.0 KiB
C++
#ifdef USE_RP2040
|
|
|
|
#include "core.h"
|
|
#include "esphome/core/defines.h"
|
|
#include "esphome/core/hal.h"
|
|
#include "esphome/core/helpers.h"
|
|
|
|
#include "hardware/timer.h"
|
|
#include "hardware/watchdog.h"
|
|
|
|
namespace esphome {
|
|
|
|
void HOT yield() { ::yield(); }
|
|
uint64_t millis_64() { return time_us_64() / 1000ULL; }
|
|
uint32_t HOT millis() { return micros_to_millis(time_us_64()); }
|
|
void HOT delay(uint32_t ms) { ::delay(ms); }
|
|
uint32_t HOT micros() { return ::micros(); }
|
|
void HOT delayMicroseconds(uint32_t us) { delay_microseconds_safe(us); }
|
|
void arch_restart() {
|
|
watchdog_reboot(0, 0, 10);
|
|
while (1) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
void arch_init() {
|
|
#if USE_RP2040_WATCHDOG_TIMEOUT > 0
|
|
watchdog_enable(USE_RP2040_WATCHDOG_TIMEOUT, false);
|
|
#endif
|
|
}
|
|
|
|
void HOT arch_feed_wdt() { watchdog_update(); }
|
|
|
|
uint8_t progmem_read_byte(const uint8_t *addr) {
|
|
return pgm_read_byte(addr); // NOLINT
|
|
}
|
|
uint32_t HOT arch_get_cpu_cycle_count() { return ulMainGetRunTimeCounterValue(); }
|
|
uint32_t arch_get_cpu_freq_hz() { return RP2040::f_cpu(); }
|
|
|
|
} // namespace esphome
|
|
|
|
#endif // USE_RP2040
|