From 4c97a278267166ef058d94f5452f9ca73fdb80ce Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Wed, 25 Oct 2023 16:51:19 +0200 Subject: [PATCH 01/14] cpu/sam0_common: implement freqm peripheral --- cpu/sam0_common/periph/freqm.c | 259 +++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 cpu/sam0_common/periph/freqm.c diff --git a/cpu/sam0_common/periph/freqm.c b/cpu/sam0_common/periph/freqm.c new file mode 100644 index 0000000000..4bea82909f --- /dev/null +++ b/cpu/sam0_common/periph/freqm.c @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2023 ML!PA Consulting GmbH + * + * 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 cpu_sam0_common + * @ingroup drivers_periph_freqm + * @{ + * + * @file freqm.c + * @brief Frequency meter driver implementation + * + * @author Urs Gompper + * + * @} + */ + +#include "periph/freqm.h" + +/* TODO: Remove defines when Microchip vendor files (which include these + * defines) get updated. + */ +/* FREQM_GCLK_ID_REF is defined in newer versions of vendor header files */ +#ifndef FREQM_GCLK_ID_REF +#define FREQM_GCLK_ID_REF (FREQM_GCLK_ID_MSR + 1) +#endif + +/* Channel Enable Mask */ +#define GCLK_PCHCTRL_CHEN_Msk (_U_(0x1) << GCLK_PCHCTRL_CHEN_Pos) +/* Enable Mask */ +#define FREQM_CTRLA_ENABLE_Msk (_U_(0x1) << FREQM_CTRLA_ENABLE_Pos) +/* Start Measurement Mask */ +#define FREQM_CTRLB_START_Msk (_U_(0x1) << FREQM_CTRLB_START_Pos) +/* Measurement Done Interrupt Enable Mask */ +#define FREQM_INTENSET_DONE_Msk (_U_(0x1) << FREQM_INTENSET_DONE_Pos) +/* Measurement Done Mask */ +#define FREQM_INTFLAG_DONE_Msk (_U_(0x1) << FREQM_INTFLAG_DONE_Pos) +/* FREQM Status Mask */ +#define FREQM_STATUS_BUSY_Msk (_U_(0x1) << FREQM_STATUS_BUSY_Pos) +/* Sticky Count Value Overflow Mask */ +#define FREQM_STATUS_OVF_Msk (_U_(0x1) << FREQM_STATUS_OVF_Pos) + +/* check if pin has peripheral function GCLK */ +static int _freqm_pin(gpio_t pin) +{ + for (unsigned i = 0; i < ARRAY_SIZE(gclk_io_pins); ++i) { + if (gclk_io_pins[i] == pin) { + return i; + } + } + + return -1; +} + +static void _gclk_connect(uint8_t id, uint8_t src, uint32_t flags) +{ + GCLK->GENCTRL[id].reg = GCLK_GENCTRL_SRC(src) | GCLK_GENCTRL_GENEN | flags | GCLK_GENCTRL_IDC; + while (GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(id)) {} +} + +static int _freqm_gpio_init(gpio_t msr_gpio_src, uint8_t *gclk_io_id) +{ + /* Check if selected pin has peripheral function GCLK */ + int index = _freqm_pin(msr_gpio_src); + + /* Fail assertion if pin has no peripheral function GCLK */ + assert(index > 0); + + /* Lookup which GCLK_IO[x] must be used */ + *gclk_io_id = gclk_io_ids[index]; + /* GCLK_IO[0] and GCLK_IO[1] can't be used here. They are associated with + GCLKGEN[0] and GCLKGEN[1] respectively. These in turn are used by + SAM0_GCLK_MAIN and SAM0_GCLK_32KHZ respectively */ + assert(*gclk_io_id > 1); + + /* Initialize GPIO as input */ + gpio_init(msr_gpio_src, GPIO_IN); + /* Enable peripheral function GCLK/IO on GPIO */ + gpio_init_mux(msr_gpio_src, GPIO_MUX_M); + /* Connect GCLK_IO[*gclk_io_id] with input pin */ + _gclk_connect(*gclk_io_id, GCLK_SOURCE_GCLKIN, 0); + + return 0; +} + +static void _freqm_clock_init(uint8_t pin, uint8_t gclk_src) +{ + /* Selection of the Generator and write Lock for FREQM_MSR */ + GCLK->PCHCTRL[FREQM_GCLK_ID_MSR].reg = GCLK_PCHCTRL_GEN(pin) | GCLK_PCHCTRL_CHEN_Msk; + /* Wait for synchronization */ + while ((GCLK->PCHCTRL[FREQM_GCLK_ID_MSR].reg & GCLK_PCHCTRL_CHEN_Msk) != + GCLK_PCHCTRL_CHEN_Msk) {} + + /* Selection of the Generator and write Lock for FREQM_REF */ + GCLK->PCHCTRL[FREQM_GCLK_ID_REF].reg = GCLK_PCHCTRL_GEN(gclk_src) | GCLK_PCHCTRL_CHEN_Msk; + /* Wait for synchronization */ + while ((GCLK->PCHCTRL[FREQM_GCLK_ID_REF].reg & GCLK_PCHCTRL_CHEN_Msk) != + GCLK_PCHCTRL_CHEN_Msk) {} +} + +static struct { + freqm_cb_t callback; + void *context; + freqm_t idx; + uint8_t period_cnt; +} freqm_obj; + +struct _sync_ctx { + mutex_t lock; /**< Mutex for blocking till measurement is done */ + uint32_t hz; /**< Measured frequency in Hz */ + bool overflow; /**< Overflow in FREQM counter */ +}; + +/** + * @brief Mutex for locking the FREQM device + */ +static mutex_t msr_lock = MUTEX_INIT; + +static void _freqm_enable(uint8_t refnum) +{ + mutex_lock(&msr_lock); + + /* Save refnum for frequency calculation */ + freqm_obj.period_cnt = refnum; + + FREQM->CFGA.reg = (uint16_t)(FREQM_CFGA_REFNUM(refnum)); + + /* Enable DONE Interrupt */ + FREQM->INTENSET.reg = FREQM_INTENSET_DONE_Msk; + + /* Enable FREQM */ + FREQM->CTRLA.reg = FREQM_CTRLA_ENABLE_Msk; + + /* Wait for Sync */ + while ((FREQM->SYNCBUSY.reg) != 0U) {} +} + +static void _freqm_disable(void) +{ + /* Disable DONE Interrupt */ + FREQM->INTENCLR.reg = FREQM_INTENCLR_MASK; + /* Disable FREQM */ + FREQM->CTRLA.reg &= ~FREQM_CTRLA_ENABLE_Msk; + /* Wait for Sync */ + while ((FREQM->SYNCBUSY.reg) != 0U) {} + + mutex_unlock(&msr_lock); +} + +bool _freqm_get_measurement(uint32_t *result) +{ + const freqm_config_t *config = &freqm_config[freqm_obj.idx]; + + /* Calculate measured frequency */ + uint64_t result_tmp = FREQM->VALUE.reg * (uint64_t)(sam0_gclk_freq(config->gclk_src)); + + result_tmp = result_tmp / freqm_obj.period_cnt; + *result = (uint32_t)result_tmp; + + /* Read overflow status */ + bool overflow_condition = ((int)FREQM->STATUS.reg & FREQM_STATUS_OVF_Msk); + + /* Clear overflow status */ + FREQM->STATUS.reg = FREQM_STATUS_OVF_Msk; + + return overflow_condition; +} + +uint32_t _us_to_ref_clock_counts(uint32_t period_us, uint8_t clock_id) +{ + uint64_t clk_cnt = (uint64_t)period_us * sam0_gclk_freq(clock_id) / US_PER_SEC; + + if (clk_cnt > UINT8_MAX) { + return UINT8_MAX; + } + else if (clk_cnt == 0) { + return 1; + } + else { + return clk_cnt; + } +} + +static void _sync_cb(uint32_t res, bool overflow, void *_ctx) +{ + struct _sync_ctx *ctx = _ctx; + + ctx->hz = res; + ctx->overflow = overflow; + mutex_unlock(&ctx->lock); +} + +int freqm_frequency_get(freqm_t idx, uint32_t *result, uint32_t period_us) +{ + struct _sync_ctx ctx = { .lock = MUTEX_INIT_LOCKED }; + + /* Invoke non-blocking FREQM measure function */ + freqm_frequency_get_async(idx, _sync_cb, &ctx, period_us); + + /* Block until measurement is done */ + mutex_lock(&ctx.lock); + + *result = ctx.hz; + return ctx.overflow ? -EOVERFLOW : 0; +} + +void freqm_frequency_get_async(freqm_t idx, freqm_cb_t freqm_cb, void *context, uint32_t period_us) +{ + const freqm_config_t *config = &freqm_config[idx]; + + uint8_t refnum = _us_to_ref_clock_counts(period_us, config->gclk_src); + + _freqm_enable(refnum); + + /* Register callback function */ + freqm_obj.callback = freqm_cb; + freqm_obj.context = context; + freqm_obj.idx = idx; + + /* Clear the Done Interrupt flag */ + FREQM->INTFLAG.reg = FREQM_INTFLAG_DONE_Msk; + + /* Start measurement */ + FREQM->CTRLB.reg = FREQM_CTRLB_START_Msk; +} + +void irq_freqm(void) +{ + /* Clear the Done Interrupt flag */ + FREQM->INTFLAG.reg = FREQM_INTFLAG_DONE_Msk; + + uint32_t result = 0; + + bool overflow_condition = _freqm_get_measurement(&result); + + /* Invoke the callback function */ + freqm_obj.callback(result, overflow_condition, freqm_obj.context); + + _freqm_disable(); +} + +void freqm_init(freqm_t idx) +{ + uint8_t gclk_io_id = 0; + const freqm_config_t *config = &freqm_config[idx]; + + /* Sanity check configuration */ + assert(config->gclk_src <= GCLK_GEN_NUM_MSB); + + _freqm_gpio_init(config->pin, &gclk_io_id); + _freqm_clock_init(gclk_io_id, config->gclk_src); + + /* Enable interrupt */ + NVIC_EnableIRQ(FREQM_IRQn); +} From afcd4801bd702474c15aa1a781a3f4e81a5c4243 Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Wed, 25 Oct 2023 16:52:33 +0200 Subject: [PATCH 02/14] drivers/include: add header definition for freqm --- drivers/include/periph/freqm.h | 100 +++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 drivers/include/periph/freqm.h diff --git a/drivers/include/periph/freqm.h b/drivers/include/periph/freqm.h new file mode 100644 index 0000000000..706114182e --- /dev/null +++ b/drivers/include/periph/freqm.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2023 ML!PA Consulting GmbH + * + * 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. + */ + +/** + * @defgroup drivers_periph_freqm FREQM + * @ingroup drivers_periph + * @brief FREQM peripheral driver interface + * + * This interface allows to configure and use the Frequency Meter (FREQM) + * peripheral. + * + * The Frequency Meter uses the frequency of a known reference clock to + * determine the frequency of a signal connected via GPIO. + * + * @{ + * + * @file + * @brief FREQM peripheral driver interface definitions + * + * @author Urs Gompper + */ + +#ifndef PERIPH_FREQM_H +#define PERIPH_FREQM_H + +#include +#include + +#include "periph_cpu.h" +#include "periph/gpio.h" +#include "time_units.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Frequency meter callback function. + * When a measurement is done the callbackfunction is called. + * + * @param result measured frequency in hz + * @param overflow overflow in sticky counter + * @param context pointer to user defined context data + */ +typedef void (*freqm_cb_t)(uint32_t result, bool overflow, void *context); + +/** + * @brief Define default Frequency meter type identifier + */ +#ifndef HAVE_FREQM_T +typedef uint_fast8_t freqm_t; +#endif + +/** + * @brief Initialize the frequency meter + * + * @param[in] idx index of the configuration + */ +void freqm_init(freqm_t idx); + +/** + * @brief Read number of periods of measured clock and calculate its frequency + * + * This function returns after triggering the measurement and calls + * @p freqm_callback , with the calculated result and @p context , when the + * measurement is done. + * + * @param[in] idx index of the configuration + * @param[in] freqm_cb callback function when measurement is ready + * @param[in] context context for the callback function + * @param[in] period_us measurement duration in microseconds + */ +void freqm_frequency_get_async(freqm_t idx, freqm_cb_t freqm_cb, void *context, + uint32_t period_us); + +/** + * @brief Read number of periods of measured clock and calculate its frequency + * + * This function uses a blocking mutex to wait for the measurement to finish. + * + * @param[in] idx index of the configuration + * @param[out] result calculated frequency + * @param[in] period_us measurement duration in microseconds + * + * @return -EOVERFLOW if FREQM sticky counter has an overflow + * @return 0 on success + */ +int freqm_frequency_get(freqm_t idx, uint32_t *result, uint32_t period_us); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* PERIPH_FREQM_H */ From 4a9ae47499857ebe0adcc1649f361ec91b973462 Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Wed, 25 Oct 2023 16:53:17 +0200 Subject: [PATCH 03/14] tests/periph: add test-application for peripheral freqm --- tests/periph/freqm/Makefile | 7 +++++ tests/periph/freqm/README.md | 14 ++++++++++ tests/periph/freqm/main.c | 52 ++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 tests/periph/freqm/Makefile create mode 100644 tests/periph/freqm/README.md create mode 100644 tests/periph/freqm/main.c diff --git a/tests/periph/freqm/Makefile b/tests/periph/freqm/Makefile new file mode 100644 index 0000000000..fe22b6f7ec --- /dev/null +++ b/tests/periph/freqm/Makefile @@ -0,0 +1,7 @@ +BOARD ?= same54-xpro + +include ../Makefile.periph_common + +USEMODULE += periph_freqm + +include $(RIOTBASE)/Makefile.include diff --git a/tests/periph/freqm/README.md b/tests/periph/freqm/README.md new file mode 100644 index 0000000000..ac40fd85ef --- /dev/null +++ b/tests/periph/freqm/README.md @@ -0,0 +1,14 @@ +Peripheral FREQM Test Application +===================================== + +This application tests the frequency meter (FREQM) functionality. This is done +by measuring the frequency of a clock, connected to a GPIO, with an internal +clock as reference. + +Expected Output on Success +-------------------------- + + main(): This is RIOT! (Version: ) + FREQM peripheral driver test + Measured clock frequency: Hz + Test run finished. diff --git a/tests/periph/freqm/main.c b/tests/periph/freqm/main.c new file mode 100644 index 0000000000..432957c971 --- /dev/null +++ b/tests/periph/freqm/main.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 ML!PA Consulting GmbH + * + * 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 tests + * @{ + * + * @file + * @brief Application to test functionality of the frequency meter + * peripheral + * + * @author Urs Gompper + * @} + */ + +#include +#include +#include +#include +#include + +#include "periph/freqm.h" + +int main(void) +{ + puts("FREQM peripheral driver test"); + + /* Initialize frequency meter peripheral */ + freqm_init(0); + + uint32_t period_us = UINT32_MAX; + uint32_t freq_hz = 0; + + /* Measure in blocking mode */ + if (!freqm_frequency_get(0, &freq_hz, period_us)) { + printf("Measured Clock Frequency: %ld Hz\n", freq_hz); + } + else { + puts("Overflow occurred to the FREQM value counter!"); + return EXIT_FAILURE; + } + + puts("Test run finished."); + + /* main thread exits */ + return 0; +} From 5479c7eb96f3a765b5ea11a18acaeaad27a2e649 Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Wed, 25 Oct 2023 17:03:16 +0200 Subject: [PATCH 04/14] cpu/samd5x: add conditional enabling of freqm peripheral --- cpu/samd5x/cpu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpu/samd5x/cpu.c b/cpu/samd5x/cpu.c index 0001b2e867..19f27beed3 100644 --- a/cpu/samd5x/cpu.c +++ b/cpu/samd5x/cpu.c @@ -325,6 +325,9 @@ void cpu_init(void) #ifdef MODULE_PERIPH_PM | MCLK_APBAMASK_PM #endif +#ifdef MODULE_PERIPH_FREQM + | MCLK_APBAMASK_FREQM +#endif #ifdef MODULE_PERIPH_GPIO_IRQ | MCLK_APBAMASK_EIC #endif From c2f7aa66f9652620550be93ac30fc20e3948e6b7 Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Wed, 25 Oct 2023 17:01:03 +0200 Subject: [PATCH 05/14] boards/same54-xpro: add periph_freqm to Makefile.features --- boards/same54-xpro/Makefile.features | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/same54-xpro/Makefile.features b/boards/same54-xpro/Makefile.features index 076663ed20..3e3491ebeb 100644 --- a/boards/same54-xpro/Makefile.features +++ b/boards/same54-xpro/Makefile.features @@ -14,6 +14,7 @@ FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_uart FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_usbdev +FEATURES_PROVIDED += periph_freqm # Put other features for this board (in alphabetical order) FEATURES_PROVIDED += riotboot From 82f803b7cfe82f766a2f4231a3412afd2d129e42 Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Wed, 25 Oct 2023 16:59:52 +0200 Subject: [PATCH 06/14] boards/same54-xpro: add freqm peripheral to Kconfig --- boards/same54-xpro/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/same54-xpro/Kconfig b/boards/same54-xpro/Kconfig index 8dbdbd0b54..e93ff58243 100644 --- a/boards/same54-xpro/Kconfig +++ b/boards/same54-xpro/Kconfig @@ -18,6 +18,7 @@ config BOARD_SAME54_XPRO select HAS_PERIPH_RTC select HAS_PERIPH_RTT select HAS_PERIPH_PWM + select HAS_PERIPH_FREQM select HAS_PERIPH_SDMMC select HAS_PERIPH_SPI select HAS_PERIPH_TIMER From 97bde07e0da7e6fa0a4e393342834854ced5b95a Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Wed, 25 Oct 2023 17:09:07 +0200 Subject: [PATCH 07/14] drivers/periph_common: add peripheral freqm to Kconfig --- drivers/periph_common/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/periph_common/Kconfig b/drivers/periph_common/Kconfig index 4db0969b8e..564a6283ad 100644 --- a/drivers/periph_common/Kconfig +++ b/drivers/periph_common/Kconfig @@ -139,6 +139,10 @@ config MODULE_PERIPH_RTT depends on HAS_PERIPH_RTT select MODULE_PERIPH_COMMON +config MODULE_PERIPH_FREQM + bool "Frequency Meter driver" + depends on HAS_PERIPH_FREQM + config MODULE_PERIPH_RTT_SET_COUNTER bool "rtc_set_counter() implementation in the RTT peripheral driver" depends on HAS_PERIPH_RTT_SET_COUNTER && MODULE_PERIPH_RTT From b1e31fbf611709f79f479347400935c78feee7cc Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Mon, 6 Nov 2023 08:40:53 +0100 Subject: [PATCH 08/14] cpu/samd5x: define GCLK pins --- cpu/samd5x/include/periph_cpu.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cpu/samd5x/include/periph_cpu.h b/cpu/samd5x/include/periph_cpu.h index f89b6ee498..8d98a8841c 100644 --- a/cpu/samd5x/include/periph_cpu.h +++ b/cpu/samd5x/include/periph_cpu.h @@ -198,6 +198,28 @@ static const gpio_t rtc_tamper_pins[RTC_NUM_OF_TAMPERS] = { GPIO_PIN(PC, 0), GPIO_PIN(PC, 1) }; +/** + * @brief Pins that have peripheral function GCLK + */ +static const gpio_t gclk_io_pins[] = { + GPIO_PIN(PA, 10), GPIO_PIN(PA, 11), GPIO_PIN(PA, 14), + GPIO_PIN(PA, 15), GPIO_PIN(PA, 16), GPIO_PIN(PA, 17), + GPIO_PIN(PA, 27), GPIO_PIN(PA, 30), GPIO_PIN(PB, 10), + GPIO_PIN(PB, 11), GPIO_PIN(PB, 12), GPIO_PIN(PB, 13), + GPIO_PIN(PB, 14), GPIO_PIN(PB, 15), GPIO_PIN(PB, 16), + GPIO_PIN(PB, 17), GPIO_PIN(PB, 18), GPIO_PIN(PB, 19), + GPIO_PIN(PB, 20), GPIO_PIN(PB, 21), GPIO_PIN(PB, 22), + GPIO_PIN(PB, 23) +}; + +/** + * @brief GCLK IDs of pins that have peripheral function GCLK - This maps + * directly to gclk_io_pins. + */ +static const uint8_t gclk_io_ids[] = { + 4, 5, 0, 1, 2, 3, 1, 0, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1 +}; + /** * @brief NVM User Page Mapping - Dedicated Entries * Config values will be applied at power-on. From 6849ef9827e455b9d9df93b7135f909b4186706e Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Mon, 6 Nov 2023 09:55:10 +0100 Subject: [PATCH 09/14] boards/same54-xpro: added FREQM peripheral configuration --- boards/same54-xpro/include/periph_conf.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/boards/same54-xpro/include/periph_conf.h b/boards/same54-xpro/include/periph_conf.h index ae85accbab..5a402d196b 100644 --- a/boards/same54-xpro/include/periph_conf.h +++ b/boards/same54-xpro/include/periph_conf.h @@ -406,6 +406,18 @@ static const sam0_common_gmac_config_t sam_gmac_config[] = { }; /** @} */ +/** + * @name FREQM peripheral configuration + * @{ + */ +static const freqm_config_t freqm_config[] = { + { + .pin = GPIO_PIN(PB, 17), + .gclk_src = SAM0_GCLK_32KHZ + } +}; +/** @} */ + #ifdef __cplusplus } #endif From f352609c5e41b98a6a05b88a081d259befce4885 Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Mon, 6 Nov 2023 10:03:15 +0100 Subject: [PATCH 10/14] cpu/sam0_common: added peripheral FREQM configuration declaration --- cpu/sam0_common/include/periph_cpu_common.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cpu/sam0_common/include/periph_cpu_common.h b/cpu/sam0_common/include/periph_cpu_common.h index 8f5e9cb47f..31b146a96e 100644 --- a/cpu/sam0_common/include/periph_cpu_common.h +++ b/cpu/sam0_common/include/periph_cpu_common.h @@ -945,6 +945,14 @@ typedef struct { */ #define WDT_HAS_INIT (1) +/** + * @brief Frequency meter configuration + */ +typedef struct { + gpio_t pin; /**< GPIO at which the frequency is to be measured */ + uint8_t gclk_src; /**< GCLK source select for reference */ +} freqm_config_t; + #if defined(REV_DMAC) || DOXYGEN /** * @name sam0 DMA peripheral From 12acc8dec9fa9a552f3bcb2ca6a7d583b2358eff Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Mon, 6 Nov 2023 10:38:01 +0100 Subject: [PATCH 11/14] cpu/samd5x: make GCLK definitions overwritable --- cpu/samd5x/include/periph_cpu.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cpu/samd5x/include/periph_cpu.h b/cpu/samd5x/include/periph_cpu.h index 8d98a8841c..450941af1f 100644 --- a/cpu/samd5x/include/periph_cpu.h +++ b/cpu/samd5x/include/periph_cpu.h @@ -70,13 +70,19 @@ enum { * @name SAMD5x GCLK definitions * @{ */ -enum { - SAM0_GCLK_MAIN = 0, /**< 120 MHz main clock */ - SAM0_GCLK_32KHZ, /**< 32 kHz clock */ - SAM0_GCLK_TIMER, /**< 4-8 MHz clock for xTimer */ - SAM0_GCLK_PERIPH, /**< 12-48 MHz (DFLL) clock */ - SAM0_GCLK_100MHZ, /**< 100MHz FDPLL clock */ -}; +#define SAM0_GCLK_MAIN 0 /**< 120 MHz main clock */ +#ifndef SAM0_GCLK_32KHZ +#define SAM0_GCLK_32KHZ 1 /**< 32 kHz clock */ +#endif +#ifndef SAM0_GCLK_TIMER +#define SAM0_GCLK_TIMER 2 /**< 4-8 MHz clock for xTimer */ +#endif +#ifndef SAM0_GCLK_PERIPH +#define SAM0_GCLK_PERIPH 3 /**< 12-48 MHz (DFLL) clock */ +#endif +#ifndef SAM0_GCLK_100MHZ +#define SAM0_GCLK_100MHZ 4 /**< 100MHz FDPLL clock */ +#endif /** @} */ /** From a2e4fa30fde3d6d0883637df69af15aa95381d20 Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Mon, 6 Nov 2023 10:39:14 +0100 Subject: [PATCH 12/14] boards/same54-xpro: overwrite GCLK definitions --- boards/same54-xpro/Makefile.include | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/same54-xpro/Makefile.include b/boards/same54-xpro/Makefile.include index 9e5bbf58a1..f8f1b33e90 100644 --- a/boards/same54-xpro/Makefile.include +++ b/boards/same54-xpro/Makefile.include @@ -3,4 +3,11 @@ # debugger. TTY_BOARD_FILTER := --model 'EDBG CMSIS-DAP' +# Overwrite GCLK definitions, so that GCLK_IO[2..7] can be connected to GPIOs. +# This way the frequency of signals, connected to these pins, can be measured +# with the FREQM peripheral. +CFLAGS += -DSAM0_GCLK_TIMER=8 +CFLAGS += -DSAM0_GCLK_PERIPH=9 +CFLAGS += -DSAM0_GCLK_100MHZ=10 + include $(RIOTMAKE)/boards/sam0.inc.mk From bfb3b5fe724c251f378fd20a60a5a1da5c76821e Mon Sep 17 00:00:00 2001 From: Urs Gompper Date: Thu, 23 Nov 2023 20:28:26 +0100 Subject: [PATCH 13/14] dist/tools/doccheck: add FREQM config to generic_exclude_pattern --- dist/tools/doccheck/generic_exclude_patterns | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/tools/doccheck/generic_exclude_patterns b/dist/tools/doccheck/generic_exclude_patterns index 45f56c164f..afd2c9c218 100644 --- a/dist/tools/doccheck/generic_exclude_patterns +++ b/dist/tools/doccheck/generic_exclude_patterns @@ -20,6 +20,7 @@ warning: Member EPD_BW_SPI_DISPLAY_UPDATE_OPTION_[A-Z0-9_]* \(macro definition\) warning: Member EPD_BW_SPI_WAIT_[A-Z0-9_]* \(macro definition\) of warning: Member F_CPU \(macro definition\) of warning: Member F_RC_OSCILLATOR \(macro definition\) of +warning: Member freqm_config\[\] \(variable\) of warning: Member FXOS8700_PARAM_ADDR \(macro definition\) of warning: Member FXOS8700_PARAM_I2C \(macro definition\) of warning: Member FXOS8700_PARAM_RENEW_INTERVAL \(macro definition\) of From b36e8e9d9d6518841bf22c235f024e3fae0be470 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 27 Nov 2023 16:56:14 +0100 Subject: [PATCH 14/14] kconfigs/Kconfig.features: define periph_freqm --- kconfigs/Kconfig.features | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kconfigs/Kconfig.features b/kconfigs/Kconfig.features index ab84f587a1..f3cc04a68f 100644 --- a/kconfigs/Kconfig.features +++ b/kconfigs/Kconfig.features @@ -258,6 +258,11 @@ config HAS_PERIPH_FLASHPAGE_RWEE help Indicates that the Flashpage peripheral is of the Read While Write. +config HAS_PERIPH_FREQM + bool + help + Indicates that a Frequency Meter peripheral is present. + config HAS_PERIPH_GPIO bool help