#ifndef __JABYENGINE_HIGH_RES_TIMER_HPP__ #define __JABYENGINE_HIGH_RES_TIMER_HPP__ #include "../jabyengine_defines.hpp" #include #include namespace JabyEngine { struct CPUTicks { static constexpr double Frequency_Hz = 33868800.0; static constexpr double Frequency_Hz_Div8 = (Frequency_Hz/8.0); template static constexpr T ticks_per_ns(double CPU_Frequency_Hz, double time = 1.0) { return static_cast((time/CPU_Frequency_Hz)*1000.0*1000.0*1000.0); } template static constexpr T ticks_per_us(double CPU_Frequency_Hz, double time = 1.0) { return static_cast(((time*1000.0)/ticks_per_ns(CPU_Frequency_Hz))); } template static constexpr T ticks_per_ms(double CPU_Frequency_Hz, double time = 1.0) { return static_cast(((time*1000.0*1000.0)/ticks_per_ns(CPU_Frequency_Hz))); } }; class HighResTime { public: class TimeStamp { private: uint16_t counter_10ms_value; uint16_t fraction; constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(fraction) { } constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) { return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100); } constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) { return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms); } public: constexpr size_t microseconds_to(const TimeStamp& end) const { return TimeStamp::to_us((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); } constexpr size_t milliseconds_to(const TimeStamp& end) const { return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); } friend class HighResTime; }; __friends: static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us(CPUTicks::Frequency_Hz_Div8, 100.0); static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 1.0); static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 10.0); static volatile uint16_t global_counter_10ms; public: HighResTime() = delete; ~HighResTime() = delete; static void enable() { Interrupt::enable_irq(Interrupt::Timer2); } static void disable() { Interrupt::disable_irq(Interrupt::Timer2); } static TimeStamp get_time_stamp() { return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); } }; } #endif //!__JABYENGINE_HIGH_RES_TIMER_HPP__