1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/stm32/periph_timer: Support timers with channels != 4

The assumption that all STM32 timers have exactly four channels no
longer holds. E.g. the STM32L4 has the following general purpose timers:

- TIM2: 32 bit, 4 channels
- TIM15: 16 bit, 2 channels
- TIM16: 16 bit, 1 channel

Hence, a new field is added to the timer configuration to also contain
the number of timer channels. Due to alignment the `struct` previously
was padded by 16 bit, so adding another 8 bit field doesn't increase
its size.

For backward compatibility, a value of `0` is considered as alias for
`TIMER_CHANNEL_NUMOF` (or 4), so that the number of timer channels
only needs to be set when the timer is different from the typical 4
channel timer. This helps backward compatibility.
This commit is contained in:
Marian Buschsieweke 2023-05-30 12:55:29 +02:00
parent e690ef4c12
commit 7c0a4b8390
No known key found for this signature in database
GPG Key ID: CB8E3238CE715A94
2 changed files with 22 additions and 5 deletions

View File

@ -30,7 +30,7 @@ extern "C" {
#endif
/**
* @brief All STM timers have 4 capture-compare channels
* @brief All STM timers have at most 4 capture-compare channels
*/
#define TIMER_CHANNEL_NUMOF (4U)
@ -53,6 +53,8 @@ typedef struct {
uint32_t rcc_mask; /**< corresponding bit in the RCC register */
uint8_t bus; /**< APBx bus the timer is clock from */
uint8_t irqn; /**< global IRQ channel */
uint8_t channel_numof; /**< number of channels, 0 is alias for
@ref TIMER_CHANNEL_NUMOF */
} timer_conf_t;
#ifdef __cplusplus

View File

@ -36,6 +36,21 @@ static inline TIM_TypeDef *dev(tim_t tim)
return timer_config[tim].dev;
}
/**
* @brief Get the number of channels of the timer device
*/
static unsigned channel_numof(tim_t tim)
{
if (timer_config[tim].channel_numof) {
return timer_config[tim].channel_numof;
}
/* backwards compatibility with older periph_conf.h files when all STM32
* had exactly 4 channels */
return TIMER_CHANNEL_NUMOF;
}
#ifdef MODULE_PERIPH_TIMER_PERIODIC
/**
@ -121,7 +136,7 @@ int timer_init(tim_t tim, uint32_t freq, timer_cb_t cb, void *arg)
int timer_set_absolute(tim_t tim, int channel, unsigned int value)
{
if (channel >= (int)TIMER_CHANNEL_NUMOF) {
if ((unsigned)channel >= channel_numof(tim)) {
return -1;
}
@ -150,7 +165,7 @@ int timer_set(tim_t tim, int channel, unsigned int timeout)
{
unsigned value = (dev(tim)->CNT + timeout) & timer_config[tim].max;
if (channel >= (int)TIMER_CHANNEL_NUMOF) {
if ((unsigned)channel >= channel_numof(tim)) {
return -1;
}
@ -188,7 +203,7 @@ int timer_set(tim_t tim, int channel, unsigned int timeout)
#ifdef MODULE_PERIPH_TIMER_PERIODIC
int timer_set_periodic(tim_t tim, int channel, unsigned int value, uint8_t flags)
{
if (channel >= (int)TIMER_CHANNEL_NUMOF) {
if ((unsigned)channel >= channel_numof(tim)) {
return -1;
}
@ -227,7 +242,7 @@ int timer_set_periodic(tim_t tim, int channel, unsigned int value, uint8_t flags
int timer_clear(tim_t tim, int channel)
{
if (channel >= (int)TIMER_CHANNEL_NUMOF) {
if ((unsigned)channel >= channel_numof(tim)) {
return -1;
}