Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu/kinetis: implement periph_timer_query_freqs #20144

Merged
merged 1 commit into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
cpu/kinetis: implement periph_timer_query_freqs
  • Loading branch information
Marian Buschsieweke authored and maribu committed Dec 7, 2023
commit f52e20c24895dc77e03af3eca9813a99e9a98091
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 @@
*/
#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 Expand Up @@ -454,7 +459,7 @@
I2C_Type *i2c; /**< Pointer to hardware module registers */
gpio_t scl_pin; /**< SCL GPIO pin */
gpio_t sda_pin; /**< SDA GPIO pin */
uint32_t freq; /**< I2C module clock frequency, usually CLOCK_BUSCLOCK or CLOCK_CORECLOCK */

Check warning on line 462 in cpu/kinetis/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
i2c_speed_t speed; /**< Configured bus speed, actual speed may be lower but never higher */
IRQn_Type irqn; /**< IRQ number for this module */
uint32_t scl_pcr; /**< PORT module PCR setting for the SCL pin */
Expand Down Expand Up @@ -539,7 +544,7 @@
*/
typedef struct {
void *dev; /**< Pointer to module hardware registers */
uint32_t freq; /**< Module clock frequency, usually CLOCK_CORECLOCK or CLOCK_BUSCLOCK */

Check warning on line 547 in cpu/kinetis/include/periph_cpu.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
gpio_t pin_rx; /**< RX pin, GPIO_UNDEF disables RX */
gpio_t pin_tx; /**< TX pin */
#ifdef KINETIS_HAVE_PCR
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
Loading