1 #ifdef PLATFORM_ESP8266
2 #include "ESP8266_hwTimer.h"
4 void inline hwTimer::nullCallback(void) {}
6 void (*hwTimer::callbackTick
)() = &nullCallback
;
7 void (*hwTimer::callbackTock
)() = &nullCallback
;
9 volatile uint32_t hwTimer::HWtimerInterval
= TimerIntervalUSDefault
;
10 volatile bool hwTimer::isTick
= false;
11 volatile int32_t hwTimer::PhaseShift
= 0;
12 volatile int32_t hwTimer::FreqOffset
= 0;
13 bool hwTimer::running
= false;
14 uint32_t hwTimer::NextTimeout
;
16 #define HWTIMER_TICKS_PER_US 5
17 #define HWTIMER_PRESCALER (clockCyclesPerMicrosecond() / HWTIMER_TICKS_PER_US)
30 timer0_detachInterrupt();
35 void ICACHE_RAM_ATTR
hwTimer::resume()
40 timer0_attachInterrupt(hwTimer::callback
);
41 // The STM32 timer fires tock() ASAP after enabling, so mimic that behavior
42 // tock() should always be the first event to maintain consistency
44 // Fire the timer in 2us to get it started close to now
45 NextTimeout
= ESP
.getCycleCount() + (2 * HWTIMER_TICKS_PER_US
* HWTIMER_PRESCALER
);
46 timer0_write(NextTimeout
);
53 void hwTimer::updateInterval(uint32_t newTimerInterval
)
55 // timer should not be running when updateInterval() is called
56 hwTimer::HWtimerInterval
= newTimerInterval
* (HWTIMER_TICKS_PER_US
* HWTIMER_PRESCALER
);
59 void ICACHE_RAM_ATTR
hwTimer::resetFreqOffset()
64 void ICACHE_RAM_ATTR
hwTimer::incFreqOffset()
69 void ICACHE_RAM_ATTR
hwTimer::decFreqOffset()
74 void ICACHE_RAM_ATTR
hwTimer::phaseShift(int32_t newPhaseShift
)
76 int32_t minVal
= -(hwTimer::HWtimerInterval
>> 2);
77 int32_t maxVal
= (hwTimer::HWtimerInterval
>> 2);
79 // phase shift is in microseconds
80 hwTimer::PhaseShift
= constrain(newPhaseShift
, minVal
, maxVal
) * (HWTIMER_TICKS_PER_US
* HWTIMER_PRESCALER
);
83 void ICACHE_RAM_ATTR
hwTimer::callback()
90 NextTimeout
+= (hwTimer::HWtimerInterval
>> 1) + (FreqOffset
* HWTIMER_PRESCALER
);
93 timer0_write(NextTimeout
);
94 hwTimer::callbackTick();
98 NextTimeout
+= hwTimer::PhaseShift
;
99 timer0_write(NextTimeout
);
100 hwTimer::PhaseShift
= 0;
101 hwTimer::callbackTock();
103 hwTimer::isTick
= !hwTimer::isTick
;