24#include "boards/board_traits.h"
25#include <avr/interrupt.h>
40#define REGISTER_TIMER_COMPARE_ISR_METHOD(TIMER_NUM, HANDLER, CALLBACK) \
41 ISR(CAT3(TIMER, TIMER_NUM, _COMPA_vect)) \
43 timer::isr_handler::check_timer<TIMER_NUM>(); \
44 interrupt::CallbackHandler<void (HANDLER::*)(), CALLBACK>::call(); \
54#define REGISTER_TIMER_COMPARE_ISR_FUNCTION(TIMER_NUM, CALLBACK) \
55 ISR(CAT3(TIMER, TIMER_NUM, _COMPA_vect)) \
57 timer::isr_handler::check_timer<TIMER_NUM>(); \
58 interrupt::CallbackHandler<void (*)(), CALLBACK>::call(); \
67#define REGISTER_TIMER_COMPARE_ISR_EMPTY(TIMER_NUM) \
68 extern "C" void CAT3(TIMER, TIMER_NUM, _COMPA_vect)(void) NAKED_SIGNAL; \
69 void CAT3(TIMER, TIMER_NUM, _COMPA_vect)(void) \
71 timer::isr_handler::check_timer<TIMER_NUM>(); \
72 __asm__ __volatile__("reti" ::); \
83#define REGISTER_TIMER_OVERFLOW_ISR_METHOD(TIMER_NUM, HANDLER, CALLBACK) \
84 ISR(CAT3(TIMER, TIMER_NUM, _OVF_vect)) \
86 timer::isr_handler::check_timer<TIMER_NUM>(); \
87 interrupt::CallbackHandler<void (HANDLER::*)(), CALLBACK>::call(); \
97#define REGISTER_TIMER_OVERFLOW_ISR_FUNCTION(TIMER_NUM, CALLBACK) \
98 ISR(CAT3(TIMER, TIMER_NUM, _OVF_vect)) \
100 timer::isr_handler::check_timer<TIMER_NUM>(); \
101 interrupt::CallbackHandler<void (*)(), CALLBACK>::call(); \
110#define REGISTER_TIMER_OVERFLOW_ISR_EMPTY(TIMER_NUM) \
111 extern "C" void CAT3(TIMER, TIMER_NUM, _OVF_vect)(void) NAKED_SIGNAL; \
112 void CAT3(TIMER, TIMER_NUM, _OVF_vect)(void) \
114 timer::isr_handler::check_timer<TIMER_NUM>(); \
115 __asm__ __volatile__("reti" ::); \
126#define REGISTER_TIMER_CAPTURE_ISR_METHOD(TIMER_NUM, HANDLER, CALLBACK) \
127 ISR(CAT3(TIMER, TIMER_NUM, _CAPT_vect)) \
129 timer::isr_handler::timer_capture_method<TIMER_NUM, HANDLER, CALLBACK>(); \
139#define REGISTER_TIMER_CAPTURE_ISR_FUNCTION(TIMER_NUM, CALLBACK) \
140 ISR(CAT3(TIMER, TIMER_NUM, _CAPT_vect)) \
142 timer::isr_handler::timer_capture_function<TIMER_NUM, CALLBACK>(); \
151#define REGISTER_TIMER_CAPTURE_ISR_EMPTY(TIMER_NUM) \
152 extern "C" void CAT3(TIMER, TIMER_NUM, _CAPT_vect)(void) NAKED_SIGNAL; \
153 void CAT3(TIMER, TIMER_NUM, _CAPT_vect)(void) \
155 timer::isr_handler::check_timer_capture<TIMER_NUM>(); \
156 __asm__ __volatile__("reti" ::); \
166#define DECL_TIMER_ISR_HANDLERS_FRIEND \
167 friend struct timer::isr_handler; \
168 DECL_TIMER_COMP_FRIENDS \
169 DECL_TIMER_OVF_FRIENDS \
170 DECL_TIMER_CAPT_FRIENDS
231 OVERFLOW = board_traits::TimerInterrupt::OVERFLOW,
310 using TRAIT = board_traits::Timer_trait<NTIMER>;
311 using PRESCALERS_TRAIT =
typename TRAIT::PRESCALERS_TRAIT;
319 using TYPE =
typename TRAIT::TYPE;
343 return best_tick_prescaler(PRESCALERS_TRAIT::ALL_PRESCALERS, us_per_tick);
359 return uint32_t(ticks) *
bits::BV16(uint8_t(prescaler)) / INST_PER_US;
392 return best_prescaler(PRESCALERS_TRAIT::ALL_PRESCALERS, us);
408 return F_CPU /
bits::BV16(uint8_t(prescaler));
425 return (
TYPE) prescaler_quotient(prescaler, us) - 1;
447 return prescaler_is_adequate(prescaler_quotient(prescaler, us));
463 return best_frequency_prescaler(PRESCALERS_TRAIT::ALL_PRESCALERS, pwm_frequency * (
PWM_MAX + 1UL));
495 return best_frequency_prescaler(PRESCALERS_TRAIT::ALL_PRESCALERS, pwm_frequency * (2UL *
PWM_MAX));
571 return best_frequency_prescaler(PRESCALERS_TRAIT::ALL_PRESCALERS, pwm_frequency * (TRAIT::MAX_PWM + 1UL));
593 return F_CPU /
bits::BV16(uint8_t(prescaler)) / counter;
615 return F_CPU /
bits::BV16(uint8_t(prescaler)) / pwm_frequency;
619 static constexpr uint32_t prescaler_quotient(
PRESCALER prescaler, uint32_t us)
621 return (INST_PER_US * us) /
bits::BV16(uint8_t(prescaler));
624 static constexpr uint32_t prescaler_remainder(
PRESCALER prescaler, uint32_t us)
626 return (INST_PER_US * us) %
bits::BV16(uint8_t(prescaler));
629 static constexpr bool prescaler_is_adequate(uint32_t quotient)
631 return (quotient > 1) && (quotient < TRAIT::MAX_COUNTER);
634 template<
size_t N>
static constexpr PRESCALER best_prescaler(
const PRESCALER (&prescalers)[N], uint32_t us)
640 uint32_t smallest_remainder = UINT32_MAX;
641 uint32_t largest_quotient = 0;
643 for (
size_t i = 0; i < N; ++i)
646 uint32_t quotient = prescaler_quotient(prescaler, us);
647 if (prescaler_is_adequate(quotient))
649 uint32_t remainder = prescaler_remainder(prescaler, us);
650 if (remainder > smallest_remainder)
continue;
651 if ((remainder == smallest_remainder) && (quotient <= largest_quotient))
continue;
653 smallest_remainder = remainder;
654 largest_quotient = quotient;
660 static constexpr bool prescaler_is_adequate_for_frequency(
PRESCALER prescaler, uint32_t freq)
662 return (F_CPU / (uint32_t)
bits::BV16(uint8_t(prescaler))) > freq;
666 static constexpr PRESCALER best_frequency_prescaler(
const PRESCALER (&prescalers)[N], uint32_t freq)
669 for (
size_t i = 0; i < N; ++i)
671 PRESCALER prescaler = prescalers[N - 1 - i];
672 if (prescaler_is_adequate_for_frequency(prescaler, freq))
return prescaler;
675 return prescalers[N - 1];
678 static constexpr bool prescaler_is_adequate_for_tick(
PRESCALER prescaler, uint32_t us)
680 return (prescaler_quotient(prescaler, us) >= 1);
683 template<
size_t N>
static constexpr PRESCALER best_tick_prescaler(
const PRESCALER (&prescalers)[N], uint32_t us)
686 for (
size_t i = 0; i < N; ++i)
688 PRESCALER prescaler = prescalers[N - 1 - i];
689 if (prescaler_is_adequate_for_tick(prescaler, us))
return prescaler;
692 return prescalers[N - 1];
704 template<board::Timer NTIMER_>
class Timer
712 using TRAIT = board_traits::Timer_trait<NTIMER>;
713 using PRESCALERS_TRAIT =
typename TRAIT::PRESCALERS_TRAIT;
725 using TYPE =
typename TRAIT::TYPE;
767 : tccra_{timer_mode_TCCRA(timer_mode)},
768 tccrb_{uint8_t(timer_mode_TCCRB(timer_mode) | TRAIT::TCCRB_prescaler(prescaler))},
769 timsk_{TRAIT::TIMSK_int_mask(uint8_t(interrupts))}
787 timsk_ = TRAIT::TIMSK_int_mask(uint8_t(interrupts));
789 if (TRAIT::TCCRB)
utils::set_mask((
volatile uint8_t&) TRAIT::TIMSK_, TRAIT::TIMSK_MASK, timsk_);
806 timsk_ |= TRAIT::TIMSK_int_mask(uint8_t(interrupts));
808 if (TRAIT::TCCRB)
utils::set_mask((
volatile uint8_t&) TRAIT::TIMSK_, TRAIT::TIMSK_MASK, timsk_);
824 timsk_ &=
bits::COMPL(TRAIT::TIMSK_int_mask(uint8_t(interrupts)));
826 if (TRAIT::TCCRB)
utils::set_mask((
volatile uint8_t&) TRAIT::TIMSK_, TRAIT::TIMSK_MASK, timsk_);
840 uint8_t mask = TRAIT::TIMSK_int_mask(uint8_t(interrupts));
841 return (TRAIT::TIMSK_ & mask) == mask;
854 static_assert(TRAIT::ICES_TCCRB != 0,
"TIMER must support Input Capture");
857 if (TRAIT::TCCRB) TRAIT::TCCRB = tccrb_;
865 static_assert(TRAIT::ICES_TCCRB != 0,
"TIMER must support Input Capture");
878 static_assert(TRAIT::ICNC_TCCRB != 0,
"TIMER must support Input Capture");
880 tccrb_ |= TRAIT::ICNC_TCCRB;
882 tccrb_ &= ~TRAIT::ICNC_TCCRB;
884 if (TRAIT::TCCRB) TRAIT::TCCRB = tccrb_;
893 static_assert(TRAIT::ICNC_TCCRB != 0,
"TIMER must support Input Capture");
894 return TRAIT::TCCRB & TRAIT::ICNC_TCCRB;
903 utils::set_mask(tccra_, TRAIT::MODE_MASK_TCCRA, timer_mode_TCCRA(timer_mode));
904 utils::set_mask(tccrb_, TRAIT::MODE_MASK_TCCRB, timer_mode_TCCRB(timer_mode));
908 if (!TRAIT::TCCRA.is_no_reg()) TRAIT::TCCRA = tccra_;
909 TRAIT::TCCRB = tccrb_;
921 return timer_mode(tccra_, tccrb_);
930 utils::set_mask(tccrb_, TRAIT::CS_MASK_TCCRB, TRAIT::TCCRB_prescaler(prescaler));
932 if (TRAIT::TCCRB) TRAIT::TCCRB = tccrb_;
968 if (!TRAIT::TCCRA.is_no_reg()) TRAIT::TCCRA = tccra_;
969 TRAIT::TCCRB = tccrb_;
972 if (!TRAIT::CTC_MAX.is_no_reg()) TRAIT::CTC_MAX = max;
975 utils::set_mask((
volatile uint8_t&) TRAIT::TIMSK_, TRAIT::TIMSK_MASK, timsk_);
989 if (
sizeof(
TYPE) > 1)
1007 TRAIT::TCNT =
ticks;
1019 if (
sizeof(
TYPE) > 1)
1020 synchronized return ticks_();
1066 utils::set_mask((
volatile uint8_t&) TRAIT::TIMSK_, TRAIT::TIMSK_MASK, uint8_t(0));
1099 utils::set_mask((
volatile uint8_t&) TRAIT::TIMSK_, TRAIT::TIMSK_MASK, timsk_);
1110 return (TRAIT::TIMSK_ & TRAIT::TIMSK_MASK) == 0;
1141 if (TRAIT::TCCRB) TRAIT::TCCRB = tccrb_ & uint8_t(~TRAIT::CS_MASK_TCCRB);
1172 TRAIT::TCCRB = tccrb_;
1187 synchronized end_();
1205 utils::set_mask((
volatile uint8_t&) TRAIT::TIMSK_, TRAIT::TIMSK_MASK, uint8_t(0));
1217 static_assert(COM < TRAIT::COM_COUNT,
"COM must exist for TIMER");
1218 using COM_TRAIT = board_traits::Timer_COM_trait<NTIMER, COM>;
1234 static_assert(COM < TRAIT::COM_COUNT,
"COM must exist for TIMER");
1235 using COM_TRAIT = board_traits::Timer_COM_trait<NTIMER, COM>;
1239 utils::set_mask((
volatile uint8_t&) TRAIT::TCCRA, COM_TRAIT::COM_MASK, tccra_);
1241 utils::set_mask((
volatile uint8_t&) TRAIT::TCCRA, COM_TRAIT::COM_MASK,
1243 COM_TRAIT::OCR = max;
1249 Timer(uint8_t tccra, uint8_t tccrb, uint8_t timsk = 0) : tccra_{tccra}, tccrb_{tccrb}, timsk_{timsk} {}
1251 template<u
int8_t COM>
static constexpr uint8_t convert_COM(
TimerOutputMode output_mode)
1253 using COM_TRAIT = board_traits::Timer_COM_trait<NTIMER, COM>;
1257 return COM_TRAIT::COM_NORMAL;
1262 return (TRAIT::TIMSK_int_mask(UINT8_MAX) & TRAIT::TIMSK_int_mask(uint8_t(
interrupt)))
1263 == TRAIT::TIMSK_int_mask(uint8_t(
interrupt));
1266 static constexpr uint8_t timer_mode_TCCRA(
TimerMode timer_mode)
1273 static constexpr uint8_t timer_mode_TCCRB(
TimerMode timer_mode)
1281 static constexpr bool is_timer_mode(
TimerMode mode, uint8_t TCCRA, uint8_t TCCRB)
1286 static constexpr TimerMode timer_mode(uint8_t TCCRA, uint8_t TCCRB)
1312 template<board::Timer NTIMER_>
static constexpr board::Timer check_timer()
1314 using TRAIT = board_traits::Timer_trait<NTIMER_>;
1315 static_assert(TRAIT::PRESCALERS != board_traits::TimerPrescalers::PRESCALERS_NONE,
1316 "TIMER_NUM must be an actual Timer in target MCU");
1320 template<u
int8_t TIMER_NUM_>
static constexpr board::Timer check_timer()
1323 return check_timer<NTIMER>();
1326 template<u
int8_t TIMER_NUM_>
static constexpr board::Timer check_timer_capture()
1328 constexpr board::Timer NTIMER = check_timer<TIMER_NUM_>();
1329 static_assert(board_traits::Timer_trait<NTIMER>::ICES_TCCRB != 0,
1330 "TIMER_NUM must be Timer supporting capture");
1334 template<u
int8_t TIMER_NUM_,
typename T,
typename HANDLER_,
void (HANDLER_::*CALLBACK_)(T)>
1335 static void timer_capture_method_helper()
1337 static constexpr board::Timer NTIMER = check_timer_capture<TIMER_NUM_>();
1338 using TRAIT = board_traits::Timer_trait<NTIMER>;
1339 static_assert(
sizeof(
typename TRAIT::TYPE) ==
sizeof(T),
1340 "CALLBACK argument is not the proper type (should be same as Timer bits size)");
1341 T capture = TRAIT::ICR;
1342 interrupt::CallbackHandler<void (HANDLER_::*)(T), CALLBACK_>::call(capture);
1345 template<u
int8_t TIMER_NUM_,
typename HANDLER_,
void (HANDLER_::*CALLBACK_)(u
int8_t)>
1346 static void timer_capture_method()
1348 timer_capture_method_helper<TIMER_NUM_, uint8_t, HANDLER_, CALLBACK_>();
1351 template<u
int8_t TIMER_NUM_,
typename HANDLER_,
void (HANDLER_::*CALLBACK_)(u
int16_t)>
1352 static void timer_capture_method()
1354 timer_capture_method_helper<TIMER_NUM_, uint16_t, HANDLER_, CALLBACK_>();
1357 template<u
int8_t TIMER_NUM_,
typename T,
void (*CALLBACK_)(T)>
static void timer_capture_function_helper()
1359 static constexpr board::Timer NTIMER = check_timer_capture<TIMER_NUM_>();
1360 using TRAIT = board_traits::Timer_trait<NTIMER>;
1361 static_assert(
sizeof(
typename TRAIT::TYPE) ==
sizeof(T),
1362 "CALLBACK argument is not the proper type (should be same as Timer bits size)");
1363 T capture = TRAIT::ICR;
1367 template<u
int8_t TIMER_NUM_,
void (*CALLBACK_)(u
int8_t)>
static void timer_capture_function()
1369 timer_capture_function_helper<TIMER_NUM_, uint8_t, CALLBACK_>();
1372 template<u
int8_t TIMER_NUM_,
void (*CALLBACK_)(u
int16_t)>
static void timer_capture_function()
1374 timer_capture_function_helper<TIMER_NUM_, uint16_t, CALLBACK_>();
General API to handle an AVR timer.
void set_output_mode(TimerOutputMode mode)
Change the output mode for this timer; this enables connection between this timer to one of its assoc...
TYPE ticks()
Return the current counter value for this timer.
void set_capture_noise_canceller(bool cancel_noise)
Set or clear the noise canceller for input capture on this timer.
void set_max(TYPE max)
Change the maximum value for this timer, in relation to one of its associated digital output pins.
Timer(TimerMode timer_mode, PRESCALER prescaler, TimerInterrupt interrupts=TimerInterrupt(0))
Construct a new Timer handler and initialize its mode.
static constexpr const board::Timer NTIMER
The Board timer used by this Timer.
void enable_interrupts(TimerInterrupt interrupts)
Add new interrupts to be enabled to the current list of interrupts that must be triggered by this tim...
void suspend_interrupts()
Temporarily suspend this timer: the timer does not generate any interrupt any longer.
void begin(TYPE max=0)
Start this timer in the currently selected mode, with the provided prescaler value and max value.
void disable_interrupts(TimerInterrupt interrupts)
Remove interrupts from the current list of enabled interrupts triggered by this timer.
void reset_(TYPE ticks=0)
Reset current counter to ticks .
bool are_interrupts_enabled(TimerInterrupt interrupts) const
Test if interrupts are currently enabled for this timers.
typename TRAIT::TYPE TYPE
The type of this timer's counter (either uint8_t or uint16_t).
void suspend_interrupts_()
Temporarily suspend this timer: the timer does not generate any interrupt any longer.
void suspend_timer_()
Suspend this timer, ie stop this timer counting (ticks() will not change then).
void resume_interrupts()
Resume this timer if it was previously suspended: the timer's counter is reset and the timer starts g...
TYPE ticks_()
Return the current counter value for this timer.
void reset(TYPE ticks=0)
Reset current counter to ticks .
static constexpr const TYPE TIMER_MAX
The maximum value that can be set to this timer's counter.
typename PRESCALERS_TRAIT::TYPE PRESCALER
The enum type listing all available precaler values for this timer.
void end_()
Completely stop this timer: timer interrupts are disabled and counter is stopped.
void resume_timer_()
Resume this timer, ie restart counting (ticks() will start changing again).
bool has_capture_noise_canceller() const
Tell whether noise canceller for this timer's input capture is active or not.
void suspend_timer()
Suspend this timer, ie stop this timer counting (ticks() will not change then).
TimerMode get_timer_mode() const
Get current time mode.
void set_input_capture(TimerInputCapture input_capture)
Set the input capture mode for this timer.
void end()
Completely stop this timer: timer interrupts are disabled and counter is stopped.
static constexpr const TYPE PWM_MAX
The maximum value that can be set to this timer's counter in PWM mode.
void set_prescaler(PRESCALER prescaler)
Change prescaler for this timer.
TimerInputCapture input_capture() const
Return the current TimerInputCapture used by this timer.
void begin_(TYPE max=0)
Start this timer in the currently selected mode, with the provided prescaler value and max value.
static constexpr const board::DigitalPin ICP_PIN
The pin that is used for Input Capture feature, if supported by this timer, or board::DigitalPin::NON...
void set_interrupts(TimerInterrupt interrupts=TimerInterrupt(0))
Set the list of interrupts that must be triggered by this timer.
bool is_interrupt_suspended()
Check if this timer interrupts are currently suspended, i.e.
void set_timer_mode(TimerMode timer_mode)
Change timer mode.
void resume_interrupts_()
Resume this timer if it was previously suspended: the timer's counter is reset and the timer starts g...
void resume_timer()
Resume this timer, ie restart counting (ticks() will start changing again).
General API for handling AVR interrupt vectors.
static constexpr uint8_t COMPL(uint8_t value)
Return the uint8_t 2-complement of a byte.
static constexpr uint16_t BV16(uint8_t bit)
Create a uint16_t bitmask for the given bit number.
DigitalPin
Defines all available digital input/output pins of the target MCU.
Timer
Defines all timers available for target MCU.
Defines API to handle AVR interruptions.
Defines all API to manipulate AVR Timers.
constexpr TimerInterrupt operator|(TimerInterrupt i1, TimerInterrupt i2)
Combine 2 timer interrupts for use with Timer.set_interrupts().
TimerOutputMode
Defines the "connection" between this timer and specific PWM output pins.
@ TOGGLE
Pin is toggled on Compare Match.
@ NON_INVERTING
Pin is cleared on Compare Match.
@ INVERTING
Pin is set on Compare Match.
@ DISCONNECTED
No connection for this pin: pin is unaffected by timer operation.
TimerMode
Defines the mode of operation of a timer.
@ NORMAL
Timer "Normal" mode: counter is incremented up to maximum value (0xFF for 8-bits Timer,...
@ CTC
Timer "Clear Timer on Compare match" mode: counter is incremented until it reaches "TOP" (OCRxA regis...
@ FAST_PWM
Timer "Fast Phase Width Modulation" mode: counter is incremented until it reaches MAX value (0xFF for...
@ PHASE_CORRECT_PWM
Timer "Phase Correct Pulse Width Modulation" mode: counter is incremented until MAX (0xFF for 8-bits ...
TimerInputCapture
Defines the type of input capture we want for a timer.
@ FALLING_EDGE
Input capture needed on falling edge of ICP pin.
@ RISING_EDGE
Input capture needed on rising edge of ICP pin.
TimerInterrupt
Defines the interrupts that can be handled by a timer.
@ OVERFLOW
This interrupt occurs when the counter overflows it maximum value.
@ OUTPUT_COMPARE_C
This interrupt occurs when the counter reached OCRC.
@ OUTPUT_COMPARE_A
This interrupt occurs when the counter reached OCRA.
@ OUTPUT_COMPARE_B
This interrupt occurs when the counter reached OCRB.
@ INPUT_CAPTURE
This interrupt occurs during input capture, i.e.
constexpr bool is_mask_equal(T actual, T mask, T expected)
Common utility to check if 2 values are equal according to a mask.
void set_mask(volatile T ®, T mask, T value)
Common utility to force a part of the value of a register, designated by a bit mask.
Defines a set of calculation methods for the given NTIMER_ The behavior of these methods is specific ...
static constexpr uint16_t PWM_ICR_counter(PRESCALER prescaler, uint16_t pwm_frequency)
Computes the ideal counter TOP value to use for this timer, when used in timer::PulseTimer,...
static constexpr PRESCALER tick_prescaler(uint32_t us_per_tick)
Computes the ideal prescaler to use for this timer, in order to generate timer ticks of us_per_tick m...
static constexpr PRESCALER PhaseCorrectPWM_prescaler(uint16_t pwm_frequency)
Computes the ideal prescaler value to use for this timer, in TimerMode::PHASE_CORRECT_PWM mode,...
static constexpr PRESCALER PWM_ICR_prescaler(uint16_t pwm_frequency)
Computes the ideal prescaler value to use for this timer, when used in timer::PulseTimer,...
static constexpr PRESCALER FastPWM_prescaler(uint16_t pwm_frequency)
Computes the ideal prescaler value to use for this timer, in TimerMode::FAST_PWM mode,...
static constexpr TYPE PulseTimer_value(PRESCALER prescaler, uint16_t period_us)
Computes the ideal value to use for this timer, when used in timer::PulseTimer, in order to produce a...
static constexpr uint32_t ticks_to_us(PRESCALER prescaler, TYPE ticks)
Computes the number of microseconds reached for a given number of ticks with a given prescaler.
static constexpr TYPE CTC_counter(PRESCALER prescaler, uint32_t us)
Computes the value of counter to use for this timer, in TimerMode::CTC mode, with prescaler,...
typename TRAIT::TYPE TYPE
The timer type: either uint8_t or uint16_t; this is defined and not changeable for each Timer.
typename PRESCALERS_TRAIT::TYPE PRESCALER
The type (enum) of the possible prescaler values for this timer; this is defined and not changeable f...
static constexpr uint16_t PhaseCorrectPWM_frequency(PRESCALER prescaler)
Computes the frequency at which this timer would perform, in TimerMode::PHASE_CORRECT_PWM mode,...
static constexpr const TYPE PWM_MAX
The maximum value you can use for this timer in PWM modes: using this value will set PWM duty as 100%...
static constexpr uint16_t PWM_ICR_frequency(PRESCALER prescaler, uint16_t counter)
Computes the frequency at which this timer would perform, when used in timer::PulseTimer,...
static constexpr PRESCALER CTC_prescaler(uint32_t us)
Computes the ideal prescaler value to use for this timer, in TimerMode::CTC mode, in order to be able...
static constexpr uint16_t FastPWM_frequency(PRESCALER prescaler)
Computes the frequency at which this timer would perform, in TimerMode::FAST_PWM mode,...
static constexpr const board::Timer NTIMER
The timer for which calculation methods are provided.
static constexpr uint32_t CTC_frequency(PRESCALER prescaler)
Computes the frequency at which this timer would perform, in TimerMode::CTC mode, if it was using pre...
static constexpr bool is_adequate_for_CTC(PRESCALER prescaler, uint32_t us)
Verifies that the given prescaler prescaler is suitable for this timer in TimerMode::CTC in order to ...
static constexpr PRESCALER PulseTimer_prescaler(uint16_t max_pulse_width_us, uint16_t pulse_frequency)
Computes the ideal prescaler value to use for this timer, when used in timer::PulseTimer,...
static constexpr TYPE us_to_ticks(PRESCALER prescaler, uint32_t us)
Computes the number of ticks needed for reaching the given us microseconds with a given prescaler.
General utilities API that have broad application in programs.