From b3989bc11fcd7042b75ea2f9769971516618f5f6 Mon Sep 17 00:00:00 2001 From: Jue Date: Mon, 17 Oct 2022 23:07:54 +0200 Subject: [PATCH 1/5] cpu/efm32: remove ADC defintion for CPUs without ADC Gecko Series 2 is shipped with a new IADC peripheral which is backed by its own emlib driver. --- cpu/efm32/include/periph_cpu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpu/efm32/include/periph_cpu.h b/cpu/efm32/include/periph_cpu.h index 91961945ee..8df5ecada2 100644 --- a/cpu/efm32/include/periph_cpu.h +++ b/cpu/efm32/include/periph_cpu.h @@ -41,6 +41,7 @@ extern "C" { #endif +#if (defined(ADC_COUNT) && (ADC_COUNT > 0)) || defined(DOXYGEN) /** * @brief Internal macro for combining ADC resolution (x) with number of * shifts (y). @@ -90,6 +91,7 @@ typedef struct { ADC_Ref_TypeDef reference; /**< channel voltage reference */ ADC_AcqTime_TypeDef acq_time; /**< channel acquisition time */ } adc_chan_conf_t; +#endif /** * @brief Length of CPU ID in octets. From bc51071d44629e34bdf2d34dce59fdb59450009d Mon Sep 17 00:00:00 2001 From: Jue Date: Mon, 17 Oct 2022 23:04:49 +0200 Subject: [PATCH 2/5] cpu/efm32: define EFM power modes for pm_layered --- cpu/efm32/include/periph_cpu.h | 9 +++++++++ cpu/efm32/periph/pm.c | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cpu/efm32/include/periph_cpu.h b/cpu/efm32/include/periph_cpu.h index 8df5ecada2..f574feb178 100644 --- a/cpu/efm32/include/periph_cpu.h +++ b/cpu/efm32/include/periph_cpu.h @@ -455,6 +455,15 @@ typedef struct { */ #define PM_NUM_MODES (3U) +/** + * @name Available power modes + * @{ + */ +#define EFM32_PM_MODE_EM3 (0U) /**< CPU sleeps, peripherals in EM3 domain are active */ +#define EFM32_PM_MODE_EM2 (1U) /**< CPU sleeps, peripherals in EM2 + EM3 domain are active */ +#define EFM32_PM_MODE_EM1 (2U) /**< CPU sleeps, all peripherals are active */ +/** @} */ + /** * @name Watchdog timer (WDT) configuration * @{ diff --git a/cpu/efm32/periph/pm.c b/cpu/efm32/periph/pm.c index 4a9aaef707..122d4e93a7 100644 --- a/cpu/efm32/periph/pm.c +++ b/cpu/efm32/periph/pm.c @@ -25,14 +25,15 @@ void pm_set(unsigned mode) { switch (mode) { - case 0: + case EFM32_PM_MODE_EM3: /* after exiting EM3, clocks are restored */ EMU_EnterEM3(true); break; - case 1: + case EFM32_PM_MODE_EM2: /* after exiting EM2, clocks are restored */ EMU_EnterEM2(true); break; + case EFM32_PM_MODE_EM1: default: /* wait for next event or interrupt */ EMU_EnterEM1(); From f6016d39998e4690f7167472b2e2c3247951fc48 Mon Sep 17 00:00:00 2001 From: Jue Date: Mon, 17 Oct 2022 23:01:01 +0200 Subject: [PATCH 3/5] cpu/efm32: keep debug unit active during EM2 when DEVELHELP is active --- cpu/efm32/cpu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpu/efm32/cpu.c b/cpu/efm32/cpu.c index 5ae8f8ec0d..02c98fed20 100644 --- a/cpu/efm32/cpu.c +++ b/cpu/efm32/cpu.c @@ -26,6 +26,7 @@ #include "em_chip.h" #include "em_cmu.h" +#include "em_dbg.h" #include "em_emu.h" /** @@ -160,6 +161,11 @@ static void pm_init(void) EMU_EM4Init(&init_em4); #endif + +#if defined(DEVELHELP) && defined(EMU_CTRL_EM2DBGEN) + /* make sure to keep the debug unit active in develhelp */ + DBG_EM2DebugEnable(true); +#endif } #endif From 68625e5aa9b340a6bc408ed8d69c715d1ff782b3 Mon Sep 17 00:00:00 2001 From: Jue Date: Mon, 17 Oct 2022 23:02:45 +0200 Subject: [PATCH 4/5] cpu/efm32/gpio: block power modes if IRQs are enabled --- cpu/efm32/periph/gpio.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/cpu/efm32/periph/gpio.c b/cpu/efm32/periph/gpio.c index 8cd492ed55..b2dd54e15f 100644 --- a/cpu/efm32/periph/gpio.c +++ b/cpu/efm32/periph/gpio.c @@ -22,8 +22,10 @@ */ #include "cpu.h" +#include "board.h" #include "periph/gpio.h" +#include "pm_layered.h" #include "em_gpio.h" @@ -115,7 +117,7 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, } /* just in case, disable the interrupt for this pin */ - GPIO_IntDisable(_pin_mask(pin)); + gpio_irq_disable(pin); /* store interrupt callback */ isr_ctx[_pin_num(pin)].cb = cb; @@ -123,7 +125,7 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, /* enable interrupts */ GPIO_ExtIntConfig(_port_num(pin), _pin_num(pin), _pin_num(pin), - flank & GPIO_RISING, flank & GPIO_FALLING, true); + flank & GPIO_RISING, flank & GPIO_FALLING, false); NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn); NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); @@ -131,17 +133,38 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, NVIC_EnableIRQ(GPIO_EVEN_IRQn); NVIC_EnableIRQ(GPIO_ODD_IRQn); + /* enable IRQ */ + gpio_irq_enable(pin); + return 0; } void gpio_irq_enable(gpio_t pin) { - GPIO_IntEnable(_pin_mask(pin)); + unsigned pin_extirq = _pin_mask(pin); + +#if IS_ACTIVE(MODULE_PM_LAYERED) && defined(GPIO_INT_PM_BLOCKER) + /* block pm mode if the irq is about to be enabled */ + if (!(GPIO_EnabledIntGet() & pin_extirq)) { + pm_block(GPIO_INT_PM_BLOCKER); + } +#endif + + GPIO_IntEnable(pin_extirq); } void gpio_irq_disable(gpio_t pin) { - GPIO_IntDisable(_pin_mask(pin)); + unsigned pin_extirq = _pin_mask(pin); + +#if IS_ACTIVE(MODULE_PM_LAYERED) && defined(GPIO_INT_PM_BLOCKER) + /* unblock pm mode if the irq is about to be disabled */ + if (GPIO_EnabledIntGet() & pin_extirq) { + pm_unblock(GPIO_INT_PM_BLOCKER); + } +#endif + + GPIO_IntDisable(pin_extirq); } /** From dc8fe697891a9d1f694aff8c2cf898529cd14e85 Mon Sep 17 00:00:00 2001 From: Juergen Fitschen Date: Tue, 18 Oct 2022 17:16:52 +0200 Subject: [PATCH 5/5] cpu/efm32: satisfy vera++ --- cpu/efm32/cpu.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/cpu/efm32/cpu.c b/cpu/efm32/cpu.c index 02c98fed20..3e004c906f 100644 --- a/cpu/efm32/cpu.c +++ b/cpu/efm32/cpu.c @@ -107,13 +107,14 @@ static void clk_init(void) #endif /* initialize LFXO with board-specific parameters before switching */ - if (CLOCK_LFA == cmuSelect_LFXO || CLOCK_LFB == cmuSelect_LFXO || #if defined(_SILICON_LABS_32B_SERIES_1) - CLOCK_LFE == cmuSelect_LFXO) + if (CLOCK_LFA == cmuSelect_LFXO || + CLOCK_LFB == cmuSelect_LFXO || + CLOCK_LFE == cmuSelect_LFXO) { #else - false) + if (CLOCK_LFA == cmuSelect_LFXO || + CLOCK_LFB == cmuSelect_LFXO) { #endif - { CMU_LFXOInit_TypeDef init_lfxo = CMU_LFXOINIT; CMU_LFXOInit(&init_lfxo); @@ -131,13 +132,14 @@ static void clk_init(void) #endif /* disable the LFRCO if external crystal is used */ - if (CLOCK_LFA == cmuSelect_LFXO && CLOCK_LFB == cmuSelect_LFXO && #if defined(_SILICON_LABS_32B_SERIES_1) - CLOCK_LFE == cmuSelect_LFXO) + if (CLOCK_LFA == cmuSelect_LFXO && + CLOCK_LFB == cmuSelect_LFXO && + CLOCK_LFE == cmuSelect_LFXO) { #else - true) + if (CLOCK_LFA == cmuSelect_LFXO && + CLOCK_LFB == cmuSelect_LFXO) { #endif - { CMU_OscillatorEnable(cmuOsc_LFRCO, false, false); } }