Skip to content

Commit

Permalink
Merge #19677
Browse files Browse the repository at this point in the history
19677: boards/nucleo-l432k: provide three periph_timer instances r=aabadie a=maribu

### Contribution description

- `cpu/stm32/periph_timer`: Generalize to also work with timers that do not have 4 channels
- `boards/common/stm32`: Add timer config for three timers based on TIM2, TIM15, and TIM16 (the three general-purpose timers of the STM32L4)
- `boards/nucleo-l432kc`: Make use of the new timer config


Co-authored-by: Marian Buschsieweke <marian.buschsieweke@ovgu.de>
  • Loading branch information
bors[bot] and maribu authored May 30, 2023
2 parents e690ef4 + 0051d41 commit a3a9453
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 6 deletions.
73 changes: 73 additions & 0 deletions boards/common/stm32/include/cfg_timer_tim2_tim15_tim16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2023 Otto-von-Guericke-Universität Magdeburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup boards_common_stm32
* @{
*
* @file
* @brief Common configuration for STM32 Timer peripheral based on TIM2,
* TIM15, and TIM16
*
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
*/

#ifndef CFG_TIMER_TIM2_TIM15_TIM16_H
#define CFG_TIMER_TIM2_TIM15_TIM16_H

#include "periph_cpu.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Please note: This likely needs some generalization for use in STM32 families
* other than L4. */
/**
* @name Timer configuration
* @{
*/
static const timer_conf_t timer_config[] = {
{
.dev = TIM2,
.max = 0xffffffff,
.rcc_mask = RCC_APB1ENR1_TIM2EN,
.bus = APB1,
.irqn = TIM2_IRQn
},
{
.dev = TIM15,
.max = 0x0000ffff,
.rcc_mask = RCC_APB2ENR_TIM15EN,
.bus = APB2,
.irqn = TIM1_BRK_TIM15_IRQn,
.channel_numof = 2,
},
{
.dev = TIM16,
.max = 0x0000ffff,
.rcc_mask = RCC_APB2ENR_TIM16EN,
.bus = APB2,
.irqn = TIM1_UP_TIM16_IRQn,
.channel_numof = 1,
},
};

#define TIMER_0_ISR isr_tim2 /**< IRQ of timer at idx 0 */
#define TIMER_1_ISR isr_tim1_brk_tim15 /**< IRQ of timer at idx 1 */
#define TIMER_2_ISR isr_tim1_up_tim16 /**< IRQ of timer at idx 2 */

#define TIMER_NUMOF ARRAY_SIZE(timer_config)
/** @} */

#ifdef __cplusplus
}
#endif

#endif /* CFG_TIMER_TIM2_TIM15_TIM16_H */
/** @} */
2 changes: 1 addition & 1 deletion boards/nucleo-l432kc/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "clk_conf.h"
#include "cfg_i2c1_pb6_pb7.h"
#include "cfg_rtt_default.h"
#include "cfg_timer_tim2.h"
#include "cfg_timer_tim2_tim15_tim16.h"

#ifdef __cplusplus
extern "C" {
Expand Down
4 changes: 3 additions & 1 deletion cpu/stm32/include/periph/cpu_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
Expand Down
23 changes: 19 additions & 4 deletions cpu/stm32/periph/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit a3a9453

Please sign in to comment.