libopencm3/lib/stm32/common/timer_common_all.c

2055 lines
63 KiB
C

/** @addtogroup timer_file
@author @htmlonly &copy; @endhtmlonly 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
@author @htmlonly &copy; @endhtmlonly 2011 Stephen Caudle <scaudle@doceme.com>
@section tim_common Notes for All Timers
This library supports the General Purpose and Advanced Control Timers for
the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics.
The STM32 series have four general purpose timers (2-5), while some have
an additional two advanced timers (1,8), and some have two basic timers (6,7).
Some of the larger devices have additional general purpose timers (9-14).
@todo Add timer DMA burst settings
@section tim_api_ex Basic TIMER handling API.
Enable the timer clock first. The timer mode sets the clock division ratio,
the count alignment (edge or centred) and count direction. Finally enable the timer.
The timer output compare block produces a signal that can be configured for
output to a pin or passed to other peripherals for use as a trigger. In all cases
the output compare mode must be set to define how the output responds to a compare
match, and the output must be enabled. If output to a pin is required, enable the
appropriate GPIO clock and set the pin to alternate output mode.
Example: Timer 2 with 2x clock divide, edge aligned and up counting.
@code
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM2EN);
timer_reset(TIM2);
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT_MUL_2,
TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
...
timer_set_period(TIM2, 1000);
timer_enable_counter(TIM2);
@endcode
Example: Timer 1 with PWM output, no clock divide and centre alignment. Set the
Output Compare mode to PWM and enable the output of channel 1. Note that for the
advanced timers the break functionality must be enabled before the signal will
appear at the output, even though break is not being used. This is in addition to
the normal output enable. Enable the alternate function clock (APB2 only) and port A
clock. Set ports A8 and A9 (timer 1 channel 1 compare outputs) to alternate function
push-pull outputs where the PWM output will appear.
@code
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8 | GPIO9);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN);
timer_reset(TIM1);
timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_CENTER_1, TIM_CR1_DIR_UP);
timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM2);
timer_enable_oc_output(TIM1, TIM_OC1);
timer_enable_break_main_output(TIM1);
timer_set_oc_value(TIM1, TIM_OC1, 200);
timer_set_period(TIM1, 1000);
timer_enable_counter(TIM1);
@endcode
@todo input capture example
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org>
* Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Basic TIMER handling API.
*
* Examples:
* timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2,
* TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP);
*/
/**@{*/
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/rcc.h>
#define ADVANCED_TIMERS (defined(TIM1_BASE) || defined(TIM8_BASE))
/*---------------------------------------------------------------------------*/
/** @brief Reset a Timer.
The counter and all its associated configuration registers
are placed in the reset condition. The reset is effected via the RCC peripheral reset
system.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
(TIM9 .. TIM14 not yet supported here).
*/
void timer_reset(u32 timer_peripheral)
{
switch (timer_peripheral) {
#if defined(TIM1_BASE)
case TIM1:
rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST);
rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST);
break;
#endif
case TIM2:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST);
break;
case TIM3:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST);
break;
case TIM4:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST);
break;
#if defined(TIM5_BASE)
case TIM5:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST);
break;
#endif
case TIM6:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST);
break;
case TIM7:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST);
break;
#if defined(TIM8_BASE)
case TIM8:
rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST);
rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST);
break;
#endif
/* These timers are not supported in libopencm3 yet */
/*
case TIM9:
rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST);
rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST);
break;
case TIM10:
rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST);
rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST);
break;
case TIM11:
rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST);
rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST);
break;
case TIM12:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST);
break;
case TIM13:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST);
break;
case TIM14:
rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST);
rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST);
break;
*/
}
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Interrupts for a Timer
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be set
*/
void timer_enable_irq(u32 timer_peripheral, u32 irq)
{
TIM_DIER(timer_peripheral) |= irq;
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Interrupts for a Timer.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] irq Unsigned int32. @ref tim_irq_enable. Logical OR of all interrupt enable bits to be cleared
*/
void timer_disable_irq(u32 timer_peripheral, u32 irq)
{
TIM_DIER(timer_peripheral) &= ~irq;
}
/*---------------------------------------------------------------------------*/
/** @brief Return Interrupt Source.
Returns true if the specified interrupt flag (UIF, TIF or CCxIF, with BIF or COMIF
for advanced timers) was set and the interrupt was enabled. If the specified flag
is not an interrupt flag, the function returns false.
@todo Timers 6-7, 9-14 have fewer interrupts, but invalid flags are not caught here.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values.
@returns boolean: flag set.
*/
bool timer_interrupt_source(u32 timer_peripheral, u32 flag)
{
/* flag not set or interrupt disabled or not an interrupt source */
if (((TIM_SR(timer_peripheral) & TIM_DIER(timer_peripheral) & flag) == 0) ||
(flag > TIM_SR_BIF)) return false;
/* Only an interrupt source for advanced timers */
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((flag == TIM_SR_BIF) || (flag == TIM_SR_COMIF))
return ((timer_peripheral == TIM1) || (timer_peripheral == TIM8));
#endif
return true;
}
/*---------------------------------------------------------------------------*/
/** @brief Read a Status Flag.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values.
@returns boolean: flag set.
*/
bool timer_get_flag(u32 timer_peripheral, u32 flag)
{
if ((TIM_SR(timer_peripheral) & flag) != 0) {
return true;
}
return false;
}
/*---------------------------------------------------------------------------*/
/** @brief Clear a Status Flag.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] flag Unsigned int32. @ref tim_sr_values. Status register flag.
*/
void timer_clear_flag(u32 timer_peripheral, u32 flag)
{
TIM_SR(timer_peripheral) &= ~flag;
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Timer Mode.
The modes are:
@li Clock divider ratio (to form the sampling clock for the input filters,
and the dead-time clock in the advanced timers 1 and 8)
@li Edge/centre alignment
@li Count direction
The alignment and count direction are effective only for timers 1 to 5 and 8
while the clock divider ratio is effective for all timers except 6,7
The remaining timers are limited hardware timers which do not support these mode
settings.
@note: When center alignment mode is selected, count direction is controlled by
hardware and cannot be written. The count direction setting has no effect
in this case.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base (TIM1, TIM2 ... TIM5, TIM8)
@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr
@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms
@param[in] direction Unsigned int32. Count direction in bit 4,: @ref tim_x_cr1_dir
*/
void timer_set_mode(u32 timer_peripheral, u32 clock_div,
u32 alignment, u32 direction)
{
u32 cr1;
cr1 = TIM_CR1(timer_peripheral);
cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | TIM_CR1_CMS_MASK | TIM_CR1_DIR_DOWN);
cr1 |= clock_div | alignment | direction;
TIM_CR1(timer_peripheral) = cr1;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Input Filter and Dead-time Clock Divider Ratio.
This forms the sampling clock for the input filters and the dead-time clock
in the advanced timers 1 and 8, by division from the timer clock.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] clock_div Unsigned int32. Clock Divider Ratio in bits 8,9: @ref tim_x_cr1_cdr
*/
void timer_set_clock_division(u32 timer_peripheral, u32 clock_div)
{
clock_div &= TIM_CR1_CKD_CK_INT_MASK;
TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK;
TIM_CR1(timer_peripheral) |= clock_div;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Auto-Reload Buffering.
During counter operation this causes the counter to be loaded from its
auto-reload register only at the next update event.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_enable_preload(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE;
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Auto-Reload Buffering.
This causes the counter to be loaded immediately with a new count value when the
auto-reload register is written, so that the new value becomes effective for the
current count cycle rather than for the cycle following an update event.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_disable_preload(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE;
}
/*---------------------------------------------------------------------------*/
/** @brief Specify the counter alignment mode.
The mode can be edge aligned or centered.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] alignment Unsigned int32. Alignment bits in 5,6: @ref tim_x_cr1_cms
*/
void timer_set_alignment(u32 timer_peripheral, u32 alignment)
{
alignment &= TIM_CR1_CMS_MASK;
TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK;
TIM_CR1(timer_peripheral) |= alignment;
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Timer to Count Up.
This has no effect if the timer is set to center aligned.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_direction_up(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN;
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Timer to Count Down.
This has no effect if the timer is set to center aligned.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_direction_down(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable the Timer for One Cycle and Stop.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_one_shot_mode(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_OPM;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable the Timer to Run Continuously.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_continuous_mode(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM;
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Timer to Generate Update IRQ or DMA on any Event.
The events which will generate an interrupt or DMA request can be
@li a counter underflow/overflow,
@li a forced update,
@li an event from the slave mode controller.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_update_on_any(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS;
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Timer to Generate Update IRQ or DMA only from Under/Overflow Events.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_update_on_overflow(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_URS;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Timer Update Events.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_enable_update_event(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS;
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Timer Update Events.
Update events are not generated and the shadow registers keep their values.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_disable_update_event(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable the timer to start counting.
This should be called after the timer initial configuration has been completed.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_enable_counter(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) |= TIM_CR1_CEN;
}
/*---------------------------------------------------------------------------*/
/** @brief Stop the timer from counting.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_disable_counter(u32 timer_peripheral)
{
TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Timer Output Idle States High.
This determines the value of the timer output compare when it enters idle state.
@sa @ref timer_set_oc_idle_state_set
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois.
If several settings are to be made, use the logical OR of the output control values.
*/
void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK;
#else
(void)timer_peripheral;
(void)outputs;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Set Timer Output Idle States Low.
This determines the value of the timer output compare when it enters idle state.
@sa @ref timer_set_oc_idle_state_unset
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] outputs Unsigned int32. Timer Output Idle State Controls @ref tim_x_cr2_ois
*/
void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK);
#else
(void)timer_peripheral;
(void)outputs;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Set Timer 1 Input to XOR of Three Channels.
The first timer capture input is formed from the XOR of the first three timer input
channels 1, 2, 3.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_set_ti1_ch123_xor(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Timer 1 Input to Channel 1.
The first timer capture input is taken from the timer input channel 1 only.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_set_ti1_ch1(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S;
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Master Mode
This sets the Trigger Output TRGO for synchronizing with slave timers or passing as
an internal trigger to the ADC or DAC.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] mode Unsigned int32. Master Mode @ref tim_mastermode
*/
void timer_set_master_mode(u32 timer_peripheral, u32 mode)
{
TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK;
TIM_CR2(timer_peripheral) |= mode;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Timer DMA Requests on Capture/Compare Events.
Capture/compare events will cause DMA requests to be generated.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_set_dma_on_compare_event(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Timer DMA Requests on Update Events.
Update events will cause DMA requests to be generated.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_set_dma_on_update_event(u32 timer_peripheral)
{
TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS;
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Timer Capture/Compare Control Update with Trigger.
If the capture/compare control bits CCxE, CCxNE and OCxM are set to be
preloaded, they are updated by software generating the COMG event (@ref
timer_generate_event) or when a rising edge occurs on the trigger input TRGI.
@note This setting is only valid for the advanced timer channels with complementary
outputs.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Timer Capture/Compare Control Update with Trigger.
If the capture/compare control bits CCxE, CCxNE and OCxM are set to be
preloaded, they are updated by software generating the COMG event (@ref
timer_generate_event).
@note This setting is only valid for the advanced timer channels with complementary
outputs.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Timer Capture/Compare Control Preload.
The capture/compare control bits CCxE, CCxNE and OCxM are set to be preloaded
when a COM event occurs.
@note This setting is only valid for the advanced timer channels with complementary
outputs.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Timer Capture/Compare Control Preload.
The capture/compare control bits CCxE, CCxNE and OCxM preload is disabled.
@note This setting is only valid for the advanced timer channels with complementary
outputs.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
*/
void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Value for the Timer Prescaler.
The timer clock is prescaled by the 16 bit scale value plus 1.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] value Unsigned int32. Prescaler values 0...0xFFFF.
*/
void timer_set_prescaler(u32 timer_peripheral, u32 value)
{
TIM_PSC(timer_peripheral) = value;
}
/*---------------------------------------------------------------------------*/
/** @brief Set the Value for the Timer Repetition Counter.
A timer update event is generated only after the specified number of repeat
count cycles have been completed.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] value Unsigned int32. Repetition values 0...0xFF.
*/
void timer_set_repetition_counter(u32 timer_peripheral, u32 value)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_RCR(timer_peripheral) = value;
#else
(void)timer_peripheral;
(void)value;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Set Period
Specify the timer period in the auto-reload register.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] period Unsigned int32. Period in counter clock ticks.
*/
void timer_set_period(u32 timer_peripheral, u32 period)
{
TIM_ARR(timer_peripheral) = period;
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Enable the Output Compare Clear Function
When this is enabled, the output compare signal is cleared when a high is detected
on the external trigger input. This works in the output compare and PWM modes only
(not forced mode).
The output compare signal remains off until the next update event.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
*/
void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE;
break;
case TIM_OC2:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE;
break;
case TIM_OC3:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE;
break;
case TIM_OC4:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as oc clear enable only applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Disable the Output Compare Clear Function
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
*/
void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE;
break;
case TIM_OC2:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE;
break;
case TIM_OC3:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE;
break;
case TIM_OC4:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as oc clear enable only applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Enable the Output Compare Fast Mode
When this is enabled, the output compare signal is forced to the compare state
by a trigger input, independently of the compare match. This speeds up the
setting of the output compare to 3 clock cycles as opposed to at least 5 in the
slow mode. This works in the PWM1 and PWM2 modes only.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
*/
void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE;
break;
case TIM_OC2:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE;
break;
case TIM_OC3:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE;
break;
case TIM_OC4:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as fast enable only applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Enable the Output Compare Slow Mode
This disables the fast compare mode and the output compare depends on the
counter and compare register values.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
*/
void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE;
break;
case TIM_OC2:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE;
break;
case TIM_OC3:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE;
break;
case TIM_OC4:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Set Output Compare Mode
Specifies how the comparator output will respond to a compare match. The mode can be:
@li Frozen - the output does not respond to a match.
@li Active - the output assumes the active state on the first match.
@li Inactive - the output assumes the inactive state on the first match.
@li Toggle - The output switches between active and inactive states on each match.
@li Force inactive. The output is forced low regardless of the compare state.
@li Force active. The output is forced high regardless of the compare state.
@li PWM1 - The output is active when the counter is less than the compare register contents
and inactive otherwise.
@li PWM2 - The output is inactive when the counter is less than the compare register contents
and active otherwise.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
@param[in] oc_mode enum ::tim_oc_mode. OC mode designators.
TIM_OCM_FROZEN, TIM_OCM_ACTIVE, TIM_OCM_INACTIVE, TIM_OCM_TOGGLE,
TIM_OCM_FORCE_LOW, TIM_OCM_FORCE_HIGH, TIM_OCM_PWM1, TIM_OCM_PWM2
*/
void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id,
enum tim_oc_mode oc_mode)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK;
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK;
switch (oc_mode) {
case TIM_OCM_FROZEN:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN;
break;
case TIM_OCM_ACTIVE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE;
break;
case TIM_OCM_INACTIVE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE;
break;
case TIM_OCM_TOGGLE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE;
break;
case TIM_OCM_FORCE_LOW:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW;
break;
case TIM_OCM_FORCE_HIGH:
TIM_CCMR1(timer_peripheral) |=
TIM_CCMR1_OC1M_FORCE_HIGH;
break;
case TIM_OCM_PWM1:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1;
break;
case TIM_OCM_PWM2:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2;
break;
}
break;
case TIM_OC2:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK;
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT;
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK;
switch (oc_mode) {
case TIM_OCM_FROZEN:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN;
break;
case TIM_OCM_ACTIVE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE;
break;
case TIM_OCM_INACTIVE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE;
break;
case TIM_OCM_TOGGLE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE;
break;
case TIM_OCM_FORCE_LOW:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW;
break;
case TIM_OCM_FORCE_HIGH:
TIM_CCMR1(timer_peripheral) |=
TIM_CCMR1_OC2M_FORCE_HIGH;
break;
case TIM_OCM_PWM1:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1;
break;
case TIM_OCM_PWM2:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2;
break;
}
break;
case TIM_OC3:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK;
TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK;
switch (oc_mode) {
case TIM_OCM_FROZEN:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN;
break;
case TIM_OCM_ACTIVE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE;
break;
case TIM_OCM_INACTIVE:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE;
break;
case TIM_OCM_TOGGLE:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE;
break;
case TIM_OCM_FORCE_LOW:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW;
break;
case TIM_OCM_FORCE_HIGH:
TIM_CCMR2(timer_peripheral) |=
TIM_CCMR2_OC3M_FORCE_HIGH;
break;
case TIM_OCM_PWM1:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1;
break;
case TIM_OCM_PWM2:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2;
break;
}
break;
case TIM_OC4:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK;
TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT;
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK;
switch (oc_mode) {
case TIM_OCM_FROZEN:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN;
break;
case TIM_OCM_ACTIVE:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE;
break;
case TIM_OCM_INACTIVE:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE;
break;
case TIM_OCM_TOGGLE:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE;
break;
case TIM_OCM_FORCE_LOW:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW;
break;
case TIM_OCM_FORCE_HIGH:
TIM_CCMR2(timer_peripheral) |=
TIM_CCMR2_OC4M_FORCE_HIGH;
break;
case TIM_OCM_PWM1:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1;
break;
case TIM_OCM_PWM2:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2;
break;
}
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Enable the Output Compare Preload Register
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
*/
void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE;
break;
case TIM_OC2:
TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE;
break;
case TIM_OC3:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE;
break;
case TIM_OC4:
TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Disable the Output Compare Preload Register
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action)
*/
void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE;
break;
case TIM_OC2:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE;
break;
case TIM_OC3:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE;
break;
case TIM_OC4:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Set the Output Polarity High
The polarity of the channel output is set active high.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
*/
void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P;
break;
case TIM_OC2:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P;
break;
case TIM_OC3:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P;
break;
case TIM_OC4:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to TIM1 and TIM8 only. */
break;
}
/* Acting for TIM1 and TIM8 only from here onwards. */
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
return;
#else
return;
#endif
switch (oc_id) {
case TIM_OC1N:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP;
break;
case TIM_OC2N:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP;
break;
case TIM_OC3N:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP;
break;
case TIM_OC1:
case TIM_OC2:
case TIM_OC3:
case TIM_OC4:
/* Ignoring as this option was already set above. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Set the Output Polarity Low
The polarity of the channel output is set active low.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
*/
void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P;
break;
case TIM_OC2:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P;
break;
case TIM_OC3:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P;
break;
case TIM_OC4:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to TIM1 and TIM8 only. */
break;
}
/* Acting for TIM1 and TIM8 only from here onwards. */
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
return;
#else
return;
#endif
switch (oc_id) {
case TIM_OC1N:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP;
break;
case TIM_OC2N:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP;
break;
case TIM_OC3N:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP;
break;
case TIM_OC1:
case TIM_OC2:
case TIM_OC3:
case TIM_OC4:
/* Ignoring as this option was already set above. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Enable the Output Compare
The channel output compare functionality is enabled.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
*/
void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E;
break;
case TIM_OC2:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E;
break;
case TIM_OC3:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E;
break;
case TIM_OC4:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to TIM1 and TIM8 only. */
break;
}
/* Acting for TIM1 and TIM8 only from here onwards. */
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
return;
#else
return;
#endif
switch (oc_id) {
case TIM_OC1N:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE;
break;
case TIM_OC2N:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE;
break;
case TIM_OC3N:
TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE;
break;
case TIM_OC1:
case TIM_OC2:
case TIM_OC3:
case TIM_OC4:
/* Ignoring as this option was already set above. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Disable the Output Compare
The channel output compare functionality is disabled.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
*/
void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E;
break;
case TIM_OC2:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E;
break;
case TIM_OC3:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E;
break;
case TIM_OC4:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to TIM1 and TIM8 only. */
break;
}
/* Acting for TIM1 and TIM8 only from here onwards. */
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
return;
#else
return;
#endif
switch (oc_id) {
case TIM_OC1N:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE;
break;
case TIM_OC2N:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE;
break;
case TIM_OC3N:
TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE;
break;
case TIM_OC1:
case TIM_OC2:
case TIM_OC3:
case TIM_OC4:
/* Ignoring as this option was already set above. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Timer set Output Compare Idle State High
@sa Similar function suitable for multiple OC idle state settings
@ref timer_set_output_idle_state
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
*/
void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
/* Acting for TIM1 and TIM8 only. */
if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
return;
switch (oc_id) {
case TIM_OC1:
TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1;
break;
case TIM_OC1N:
TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N;
break;
case TIM_OC2:
TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2;
break;
case TIM_OC2N:
TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N;
break;
case TIM_OC3:
TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3;
break;
case TIM_OC3N:
TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N;
break;
case TIM_OC4:
TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4;
break;
}
#else
(void)timer_peripheral;
(void)oc_id;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Set Output Compare Idle State Low
@sa Similar function suitable for multiple OC idle state settings
@ref timer_reset_output_idle_state
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (only for advanced timers 1 and 8)
*/
void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
/* Acting for TIM1 and TIM8 only. */
if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8))
return;
switch (oc_id) {
case TIM_OC1:
TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1;
break;
case TIM_OC1N:
TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N;
break;
case TIM_OC2:
TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2;
break;
case TIM_OC2N:
TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N;
break;
case TIM_OC3:
TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3;
break;
case TIM_OC3N:
TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N;
break;
case TIM_OC4:
TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4;
break;
}
#else
(void)timer_peripheral;
(void)oc_id;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Timer Set Output Compare Value
This is a convenience function to set the OC preload register value for loading
to the compare register.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
(TIM9 .. TIM14 not yet supported here).
@param[in] oc_id enum ::tim_oc_id OC channel designators
TIM_OCx where x=1..4, TIM_OCxN where x=1..3 (no action taken)
@param[in] value Unsigned int32. Compare value.
*/
void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value)
{
switch (oc_id) {
case TIM_OC1:
TIM_CCR1(timer_peripheral) = value;
break;
case TIM_OC2:
TIM_CCR2(timer_peripheral) = value;
break;
case TIM_OC3:
TIM_CCR3(timer_peripheral) = value;
break;
case TIM_OC4:
TIM_CCR4(timer_peripheral) = value;
break;
case TIM_OC1N:
case TIM_OC2N:
case TIM_OC3N:
/* Ignoring as this option applies to the whole channel. */
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Output in Break
Enables the output in the Break feature of an advanced timer. This does not
enable the break functionality itself but only sets the Master Output Enable in
the Break and Deadtime Register.
@note This setting is only valid for the advanced timers.
@note It is necessary to call this function to enable the output on an advanced
timer <b>even if break or deadtime features are not being used</b>.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_enable_break_main_output(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Output in Break
Disables the output in the Break feature of an advanced timer. This clears
the Master Output Enable in the Break and Deadtime Register.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_disable_break_main_output(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Automatic Output in Break
Enables the automatic output feature of the Break function of an advanced
timer so that the output is re-enabled at the next update event following a
break event.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_enable_break_automatic_output(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Automatic Output in Break
Disables the automatic output feature of the Break function of an advanced
timer so that the output is re-enabled at the next update event following a
break event.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_disable_break_automatic_output(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Activate Break when Input High
Sets the break function to activate when the break input becomes high.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_set_break_polarity_high(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Activate Break when Input Low
Sets the break function to activate when the break input becomes low.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_set_break_polarity_low(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Break
Enables the break function of an advanced timer.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_enable_break(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Break
Disables the break function of an advanced timer.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_disable_break(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Off-State in Run Mode
Enables the off-state in run mode for the break function of an advanced
timer in which the complementary outputs have been configured. It has no effect
if no complementary output is present. When the capture-compare output is
disabled while the complementary output is enabled, the output is set to its
inactive level as defined by the output polarity.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Off-State in Run Mode
Disables the off-state in run mode for the break function of an advanced
timer in which the complementary outputs have been configured. It has no effect
if no complementary output is present. When the capture-compare output is
disabled, the output is also disabled.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Off-State in Idle Mode
Enables the off-state in idle mode for the break function of an advanced
timer. When the master output is disabled the output is set to its
inactive level as defined by the output polarity.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Off-State in Idle Mode
Disables the off-state in idle mode for the break function of an advanced
timer. When the master output is disabled the output is also disabled.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
*/
void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI;
#else
(void)timer_peripheral;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Set Lock Bits
Set the lock bits for an advanced timer. Three levels of lock providing
protection against software errors. Once written they cannot be changed until a
timer reset has occurred.
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
@param[in] lock Unsigned int32. Lock specification @ref tim_lock
*/
void timer_set_break_lock(u32 timer_peripheral, u32 lock)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= lock;
#else
(void)timer_peripheral;
(void)lock;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Set Deadtime
The deadtime and sampling clock (DTSC) is set in the clock division ratio part of the
timer mode settings. The deadtime count is an 8 bit value defined in terms of the
number of DTSC cycles:
@li Bit 7 = 0, deadtime = bits(6:0)
@li Bits 7:6 = 10, deadtime = 2x(64+bits(5:0))
@li Bits 7:5 = 110, deadtime = 8x(32+bits(5:0))
@li Bits 7:5 = 111, deadtime = 16x(32+bits(5:0))
@note This setting is only valid for the advanced timers.
@param[in] timer_peripheral Unsigned int32. Timer register address base TIM1 or TIM8
@param[in] deadtime Unsigned int32. Deadtime count specification as defined above.
*/
void timer_set_deadtime(u32 timer_peripheral, u32 deadtime)
{
#if (defined(TIM1_BASE) || defined(TIM8_BASE))
if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8))
TIM_BDTR(timer_peripheral) |= deadtime;
#else
(void)timer_peripheral;
(void)deadtime;
#endif
}
/*---------------------------------------------------------------------------*/
/** @brief Force generate a timer event.
The event specification consists of 8 possible events that can be forced on the
timer. The forced events are automatically cleared by hardware. The UG event is
useful to cause shadow registers to be preloaded before the timer is started to
avoid uncertainties in the first cycle in case an update event may never be
generated.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] event Unsigned int32. Event specification @ref tim_event_gen
*/
void timer_generate_event(u32 timer_peripheral, u32 event)
{
TIM_EGR(timer_peripheral) |= event;
}
/*---------------------------------------------------------------------------*/
/** @brief Read Counter
Read back the value of a timer's counter register contents
@param[in] timer_peripheral Unsigned int32. Timer register address base
@returns Unsigned int32. Counter value.
*/
u32 timer_get_counter(u32 timer_peripheral)
{
return TIM_CNT(timer_peripheral);
}
/*---------------------------------------------------------------------------*/
/** @brief Set Counter
Set the value of a timer's counter register contents.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] count Unsigned int32. Counter value.
*/
void timer_set_counter(u32 timer_peripheral, u32 count)
{
TIM_CNT(timer_peripheral) = count;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Input Capture Filter Parameters
Set the input filter parameters for an input channel, specifying:
@li the frequency of sampling from the Deadtime and Sampling clock
(@see @ref timer_set_clock_division)
@li the number of events that must occur before a transition is considered valid.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] ic ::tim_ic_id. Input Capture channel designator.
@param[in] flt ::tim_ic_filter. Input Capture Filter identifier.
*/
void timer_ic_set_filter(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_filter flt)
{
switch (ic) {
case TIM_IC1:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1F_MASK;
TIM_CCMR1(timer_peripheral) |= flt << 4;
break;
case TIM_IC2:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2F_MASK;
TIM_CCMR1(timer_peripheral) |= flt << 12;
break;
case TIM_IC3:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3F_MASK;
TIM_CCMR2(timer_peripheral) |= flt << 4;
break;
case TIM_IC4:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4F_MASK;
TIM_CCMR2(timer_peripheral) |= flt << 12;
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Set Input Capture Prescaler
Set the number of events between each capture.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] ic ::tim_ic_id. Input Capture channel designator.
@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler.
*/
void timer_ic_set_prescaler(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_psc psc)
{
switch (ic) {
case TIM_IC1:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC1PSC_MASK;
TIM_CCMR1(timer_peripheral) |= psc << 2;
break;
case TIM_IC2:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_IC2PSC_MASK;
TIM_CCMR1(timer_peripheral) |= psc << 10;
break;
case TIM_IC3:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC3PSC_MASK;
TIM_CCMR2(timer_peripheral) |= psc << 4;
break;
case TIM_IC4:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_IC4PSC_MASK;
TIM_CCMR2(timer_peripheral) |= psc << 10;
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Set Capture/Compare Channel Direction/Input
The Capture/Compare channel is defined as output (compare) or input with the input
mapping specified:
@li channel is configured as output
@li channel is configured as input and mapped on corresponding input
@li channel is configured as input and mapped on alternate input
(TI2 for channel 1, TI1 for channel 2, TI4 for channel 3, TI3 for channel 4)
@li channel is configured as input and is mapped on TRC (requires an
internal trigger input selected through TS bit
@note not all combinations of the input and channel are valid, see datasheets.
@note these parameters are writable only when the channel is off.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] ic ::tim_ic_id. Input Capture channel designator.
@param[in] in ::tim_ic_input. Input Capture channel direction and source input.
*/
void timer_ic_set_input(u32 timer_peripheral, enum tim_ic_id ic, enum tim_ic_input in)
{
in &= 3;
if (((ic == TIM_IC2) || (ic == TIM_IC4)) &&
((in == TIM_IC_IN_TI1) || (in == TIM_IC_IN_TI2))) {
/* Input select bits are flipped for these combinations */
in ^= 3;
}
switch (ic) {
case TIM_IC1:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK;
TIM_CCMR1(timer_peripheral) |= in;
break;
case TIM_IC2:
TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK;
TIM_CCMR1(timer_peripheral) |= in << 8;
break;
case TIM_IC3:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK;
TIM_CCMR2(timer_peripheral) |= in;
break;
case TIM_IC4:
TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK;
TIM_CCMR2(timer_peripheral) |= in << 8;
break;
}
}
/*---------------------------------------------------------------------------*/
/** @brief Enable Timer Input Capture
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] ic ::tim_ic_id. Input Capture channel designator.
*/
void timer_ic_enable(u32 timer_peripheral, enum tim_ic_id ic)
{
TIM_CCER(timer_peripheral) |= (0x1 << (ic * 4));
}
/*---------------------------------------------------------------------------*/
/** @brief Disable Timer Input Capture
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] ic ::tim_ic_id. Input Capture channel designator.
*/
void timer_ic_disable(u32 timer_peripheral, enum tim_ic_id ic)
{
TIM_CCER(timer_peripheral) &= ~(0x1 << (ic * 4));
}
/*---------------------------------------------------------------------------*/
/** @brief Set External Trigger Filter Parameters for Slave
Set the input filter parameters for the external trigger, specifying:
@li the frequency of sampling from the Deadtime and Sampling clock
(@see @ref timer_set_clock_division)
@li the number of events that must occur before a transition is considered valid.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] flt ::tim_ic_filter. Input Capture Filter identifier.
*/
void timer_slave_set_filter(u32 timer_peripheral, enum tim_ic_filter flt)
{
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETF_MASK;
TIM_SMCR(timer_peripheral) |= flt << 8;
}
/*---------------------------------------------------------------------------*/
/** @brief Set External Trigger Prescaler for Slave
Set the external trigger frequency division ratio.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] psc ::tim_ic_psc. Input Capture sample clock prescaler.
*/
void timer_slave_set_prescaler(u32 timer_peripheral, enum tim_ic_psc psc)
{
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETPS_MASK;
TIM_SMCR(timer_peripheral) |= psc << 12;
}
/*---------------------------------------------------------------------------*/
/** @brief Set External Trigger Polarity for Slave
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] pol ::tim_et_pol. Slave External Trigger polarity.
*/
void timer_slave_set_polarity(u32 timer_peripheral, enum tim_et_pol pol)
{
if (pol)
TIM_SMCR(timer_peripheral) |= TIM_SMCR_ETP;
else
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_ETP;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Slave Mode
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] mode Unsigned int8. Slave mode @ref tim_sms
*/
void timer_slave_set_mode(u32 timer_peripheral, u8 mode)
{
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_SMS_MASK;
TIM_SMCR(timer_peripheral) |= mode;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Slave Trigger Source
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] trigger Unsigned int8. Slave trigger source @ref tim_ts
*/
void timer_slave_set_trigger(u32 timer_peripheral, u8 trigger)
{
TIM_SMCR(timer_peripheral) &= ~TIM_SMCR_TS_MASK;
TIM_SMCR(timer_peripheral) |= trigger;
}
/* TODO Timer DMA burst */
/**@}*/