118 template<board::Timer NTIMER_, typename Calculator<NTIMER_>::PRESCALER PRESCALER_>
119 class PulseTimer16 :
public Timer<NTIMER_>
126 using TRAIT =
typename PARENT::TRAIT;
127 static_assert(TRAIT::IS_16BITS,
"TIMER must be a 16 bits timer");
131 using TPRESCALER =
typename CALCULATOR::PRESCALER;
132 static constexpr const TPRESCALER PRESCALER = PRESCALER_;
134 explicit PulseTimer16(uint16_t pulse_frequency) :
Timer<NTIMER>{TCCRA_MASK(), TCCRB_MASK()}
136 TRAIT::ICR = CALCULATOR::PWM_ICR_counter(PRESCALER, pulse_frequency);
140 static constexpr uint8_t TCCRA_MASK()
143 return TRAIT::F_PWM_ICR_TCCRA;
145 static constexpr uint8_t TCCRB_MASK()
148 return TRAIT::F_PWM_ICR_TCCRB | TRAIT::TCCRB_prescaler(PRESCALER);
152 template<board::Timer NTIMER_, typename Calculator<NTIMER_>::PRESCALER PRESCALER_>
153 class PulseTimer8 :
public Timer<NTIMER_>
160 using TRAIT =
typename PARENT::TRAIT;
161 static_assert(!TRAIT::IS_16BITS,
"TIMER must be an 8 bits timer");
165 using TPRESCALER =
typename CALCULATOR::PRESCALER;
166 static constexpr const TPRESCALER PRESCALER = PRESCALER_;
168 explicit PulseTimer8(uint16_t pulse_frequency)
169 :
Timer<NTIMER>{TCCRA_MASK(), TCCRB_MASK(), TIMSK_int_mask()}, MAX{OVERFLOW_COUNTER(pulse_frequency)}
179 if (count_ == MAX) count_ = 0;
180 return (count_ == 0);
183 static constexpr uint8_t TCCRA_MASK()
188 static constexpr uint8_t TCCRB_MASK()
191 return TRAIT::TCCRB_prescaler(PRESCALER);
193 static constexpr uint8_t TIMSK_int_mask()
195 return TRAIT::TIMSK_int_mask(uint8_t(TimerInterrupt::OVERFLOW | TimerInterrupt::OUTPUT_COMPARE_A
196 | TimerInterrupt::OUTPUT_COMPARE_B));
198 static constexpr uint8_t OVERFLOW_COUNTER(uint16_t pulse_frequency)
200 return F_CPU / TRAIT::MAX_COUNTER /
bits::BV16(uint8_t(PRESCALER)) / pulse_frequency;
206 friend struct isr_handler_pulse;
243 template<board::Timer NTIMER_, typename timer::Calculator<NTIMER_>::PRESCALER PRESCALER_,
244 typename T =
typename board_traits::Timer_trait<NTIMER_>::TYPE>
247 static_assert(types_traits::is_uint8_or_uint16<T>(),
"T must be either uint8_t or uint16_t");
259 template<board::Timer NTIMER_, typename timer::Calculator<NTIMER_>::PRESCALER PRESCALER_>
260 class PulseTimer<NTIMER_, PRESCALER_, uint8_t> :
public timer::PulseTimer8<NTIMER_, PRESCALER_>
266 template<board::Timer NTIMER_, typename timer::Calculator<NTIMER_>::PRESCALER PRESCALER_>
267 class PulseTimer<NTIMER_, PRESCALER_, uint16_t> :
public timer::PulseTimer16<NTIMER_, PRESCALER_>
276 struct isr_handler_pulse
278 template<u
int8_t TIMER_NUM_, board::PWMPin PIN_, u
int8_t COM_NUM_>
281 constexpr board::Timer NTIMER = isr_handler::check_timer<TIMER_NUM_>();
282 using TRAIT = board_traits::Timer_trait<NTIMER>;
283 static_assert(!TRAIT::IS_16BITS,
"TIMER_NUM must be an 8 bits Timer");
284 using PINT = board_traits::Timer_COM_trait<NTIMER, COM_NUM_>;
285 static_assert(PIN_ == PINT::PIN_OCR,
"PIN must be connected to TIMER_NUM OCxA/OCxB");
289 template<u
int8_t TIMER_NUM_,
typename timer::Calculator<(board::Timer) TIMER_NUM_>::PRESCALER PRESCALER_,
290 board::PWMPin PIN_, u
int8_t COM_NUM_>
291 static void pulse_timer_overflow()
293 static constexpr board::Timer NTIMER = pulse_timer_check<TIMER_NUM_, PIN_, COM_NUM_>();
294 using PT = timer::PulseTimer8<NTIMER, PRESCALER_>;
295 if (interrupt::HandlerHolder<PT>::handler()->overflow())
297 using PWMTRAIT = board_traits::PWMPin_trait<PIN_>;
302 template<u
int8_t TIMER_NUM_,
typename timer::Calculator<(board::Timer) TIMER_NUM_>::PRESCALER PRESCALER_,
303 board::PWMPin PINA_, u
int8_t COMA_NUM_, board::PWMPin PINB_, u
int8_t COMB_NUM_>
304 static void pulse_timer_overflow()
306 static constexpr board::Timer NTIMER = pulse_timer_check<TIMER_NUM_, PINA_, COMA_NUM_>();
307 pulse_timer_check<TIMER_NUM_, PINB_, COMB_NUM_>();
308 using PT = timer::PulseTimer8<NTIMER, PRESCALER_>;
309 if (interrupt::HandlerHolder<PT>::handler()->overflow())
311 using PINTA = board_traits::Timer_COM_trait<NTIMER, COMA_NUM_>;
312 using PINTB = board_traits::Timer_COM_trait<NTIMER, COMB_NUM_>;
315 using PWMTRAIT = board_traits::PWMPin_trait<PINA_>;
320 using PWMTRAIT = board_traits::PWMPin_trait<PINB_>;
326 template<u
int8_t TIMER_NUM_, u
int8_t COM_NUM_, board::PWMPin PIN_>
static void pulse_timer_compare()
328 static constexpr board::Timer NTIMER = pulse_timer_check<TIMER_NUM_, PIN_, COM_NUM_>();
329 using PINT = board_traits::Timer_COM_trait<NTIMER, COM_NUM_>;
330 static_assert(PIN_ == PINT::PIN_OCR,
"PIN must be connected to TIMER_NUM OCxA/OCxB");
331 using PWMTRAIT = board_traits::PWMPin_trait<PIN_>;