Skip to content

Commit

Permalink
Merge pull request #20144 from maribu/periph_timer_query_freq-kinetis
Browse files Browse the repository at this point in the history
cpu/kinetis: implement periph_timer_query_freqs
  • Loading branch information
maribu authored Dec 8, 2023
2 parents 481e3a9 + f52e20c commit 5d05caa
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
1 change: 1 addition & 0 deletions cpu/kinetis/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ config CPU_COMMON_KINETIS
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_PM
select HAS_PERIPH_TIMER_QUERY_FREQS

# enable kinetis periph drivers if available
imply MODULE_PERIPH_ICS
Expand Down
1 change: 1 addition & 0 deletions cpu/kinetis/Makefile.features
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FEATURES_PROVIDED += periph_cpuid
FEATURES_PROVIDED += periph_pm
FEATURES_PROVIDED += periph_timer_query_freqs

# TRNG driver is not implemented for mkw41z models
_KINETIS_CPU_MODELS_WITHOUT_HWRNG += mkw41z256vht4 mkw41z512vht4
Expand Down
5 changes: 5 additions & 0 deletions cpu/kinetis/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ typedef uint32_t spi_cs_t;
*/
#define PERIPH_TIMER_PROVIDES_SET

/**
* @brief Only a single channel supported by the driver/hardware
*/
#define TIMER_CHANNEL_NUMOF 1

/**
* @name Kinetis power mode configuration
* @{
Expand Down
54 changes: 52 additions & 2 deletions cpu/kinetis/periph/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@

#include <stdlib.h>

#include "cpu.h"
#include "bit.h"
#include "bitarithm.h"
#include "board.h"
#include "periph_conf.h"
#include "cpu.h"
#include "macros/utils.h"
#include "periph/timer.h"
#include "periph_conf.h"

#ifdef PIT_LTMR64H_LTH_MASK
/* The KW41Z PIT module provides only one IRQ for all PIT channels combined. */
Expand Down Expand Up @@ -611,6 +613,54 @@ static inline void lptmr_irq_handler(tim_t tim)
#endif
/* ****** Common timer API functions ****** */

uword_t timer_query_freqs_numof(tim_t dev)
{
assert(dev < TIMER_NUMOF);

switch (_timer_variant(dev)) {
case TIMER_PIT:
return UINT32_MAX;
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
case TIMER_LPTMR:
/* 16 different pre-scaler values + bypassing the pre-scaler is
* supported, resulting in 17 possible frequencies. However, RIOT's
* timer API doesn't allow specifying frequencies below 1 Hz, so
* we possible have fewer options */
{
uword_t max_shifts = bitarithm_msb(lptmr_config[_lptmr_index(dev)].base_freq) + 1;
return MIN(max_shifts, 17);
}
#endif
default:
assert(0);
return 0;
}
}

uint32_t timer_query_freqs(tim_t dev, uword_t index)
{
assert(dev < TIMER_NUMOF);

switch (_timer_variant(dev)) {
case TIMER_PIT:
if (index == UINT32_MAX) {
return 0;
}
return PIT_BASECLOCK / (index + 1);
#ifdef KINETIS_BOARD_HAVE_CONFIGURED_LPTMR
case TIMER_LPTMR:
if (index >= 17) {
return 0;
}

return lptmr_config[_lptmr_index(dev)].base_freq >> index;
#endif
default:
assert(0);
return 0;
}
}

int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg)
{
if ((unsigned int)dev >= TIMER_NUMOF) {
Expand Down

0 comments on commit 5d05caa

Please sign in to comment.