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

drivers/periph_timer: add timer_query_freqs() #16349

Merged
merged 2 commits into from
Dec 5, 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
63 changes: 63 additions & 0 deletions drivers/include/periph/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <limits.h>
#include <stdint.h>

#include "architecture.h"
#include "periph_cpu.h"
#include "periph_conf.h"

Expand Down Expand Up @@ -232,6 +233,68 @@ void timer_start(tim_t dev);
*/
void timer_stop(tim_t dev);

/**
* @brief Get the number of different frequencies supported by the given
* timer
*
* If calling @ref timer_query_freqs_numof for the same timer with an index
* smaller this number, it hence MUST return a frequency (and not zero).
*
* @details This function is marked with attribute pure to tell the compiler
* that this function has no side affects and will return the same
* value when called with the same parameter. (E.g. to not call this
* function in every loop iteration when iterating over all
* supported frequencies.)
*/
__attribute__((pure))
uword_t timer_query_freqs_numof(tim_t dev);

/**
* @brief Get the number of timer channels for the given timer
*
* @details This function is marked with attribute pure to tell the compiler
* that this function has no side affects and will return the same
* value when called with the same timer as parameter.
* @details There is a weak default implementation that returns the value of
* `TIMER_CHANNEL_NUMOF`. For some MCUs the number of supported
* channels depends on @p dev - those are expected to provide there
* own implementation of this function.
*/
__attribute__((pure))
uword_t timer_query_channel_numof(tim_t dev);

/**
* @brief Iterate over supported frequencies
*
* @param dev Timer to get the next supported frequency of
* @param index Index of the frequency to get
* @return The @p index highest frequency supported by the timer
* @retval 0 @p index is too high
*
* @note Add `FEATURES_REQUIRED += periph_timer_query_freqs` to your `Makefile`.
*
* When called with a value of 0 for @p index, the highest supported frequency
* is returned. For a value 1 the second highest is returned, and so on. For
* values out of range, 0 is returned. A program hence can iterate over all
* supported frequencies using:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
* uint32_t freq:
* for (uword_t i; (freq = timer_query_freqs(dev, i)); i++) {
* work_with_frequency(freq);
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Or alternatively:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
* for (uword_t i; i < timer_query_freqs_numof(dev); i++) {
* work_with_frequency(timer_query_freqs(dev, i));
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
uint32_t timer_query_freqs(tim_t dev, uword_t index);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions drivers/periph_common/Kconfig.timer
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ config MODULE_PERIPH_INIT_TIMER_PERIODIC
depends on MODULE_PERIPH_TIMER_PERIODIC
default y if MODULE_PERIPH_INIT

config MODULE_PERIPH_TIMER_QUERY_FREQS
bool "Support for querying supported timer frequencies"
depends on HAS_PERIPH_TIMER_QUERY_FREQS

endif # MODULE_PERIPH_TIMER

endif # TEST_KCONFIG
Expand Down
9 changes: 9 additions & 0 deletions drivers/periph_common/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,12 @@ int timer_set(tim_t dev, int channel, unsigned int timeout)
return res;
}
#endif

#ifdef MODULE_PERIPH_TIMER_QUERY_FREQS
__attribute__((weak))
uword_t timer_query_channel_numof(tim_t dev)
{
(void)dev;
return TIMER_CHANNEL_NUMOF;
}
#endif
5 changes: 5 additions & 0 deletions kconfigs/Kconfig.features
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,11 @@ config HAS_PERIPH_TIMER_PERIODIC
Indicates that the Timer peripheral provides the periodic timeout
functionality.

config HAS_PERIPH_TIMER_QUERY_FREQS
bool
help
Indicates that the driver of the timer supports iterating over supported frequencies.

config HAS_PERIPH_UART
bool
help
Expand Down
1 change: 1 addition & 0 deletions makefiles/features_modules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ PERIPH_IGNORE_MODULES := \
periph_rtt_hw_rtc \
periph_rtt_hw_sys \
periph_spi_on_qspi \
periph_timer_query_freqs \
periph_uart_collision \
periph_uart_rxstart_irq \
periph_wdog \
Expand Down
11 changes: 11 additions & 0 deletions tests/periph/timer/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) 2020 HAW Hamburg
#
# 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.

config APPLICATION
bool
default y
depends on TEST_KCONFIG
imply MODULE_PERIPH_TIMER_QUERY_FREQS
1 change: 1 addition & 0 deletions tests/periph/timer/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include ../Makefile.periph_common

FEATURES_REQUIRED = periph_timer
FEATURES_OPTIONAL = periph_timer_query_freqs

BOARDS_TIMER_500kHz := \
atxmega-a1-xplained \
Expand Down
Loading
Loading