From ebcd3d33a56a505f2f7112b0dacc1eae0a545898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Czarnecki?= Date: Mon, 19 Sep 2022 13:00:19 +0200 Subject: [PATCH 01/17] west.yml: hal_silabs: update hal version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This bumps the hal_silabs in order to add initial support for EFR32BG22 SoCs Signed-off-by: Paweł Czarnecki --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 947978cf5f148..0f75ef120c40e 100644 --- a/west.yml +++ b/west.yml @@ -120,7 +120,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 1ec8dd99aa4ac3e8632d2aa28a7438049bb27102 + revision: 9dcaa761258cfdfecaacc5a9f0af92f6535d74a3 path: modules/hal/silabs groups: - hal From 7f0aae131ce996a141aa76d0b383ba60310a6d3d Mon Sep 17 00:00:00 2001 From: Pawel Czarnecki Date: Mon, 24 Oct 2022 10:20:45 +0200 Subject: [PATCH 02/17] soc: arm: silabs: remove soc_gpio_configure wrapper It would be better to use GPIO_PinModeSet() functions directly in the drivers. Signed-off-by: Pawel Czarnecki --- drivers/ethernet/eth_gecko.c | 8 ++++++-- drivers/i2c/i2c_gecko.c | 4 ++-- drivers/serial/leuart_gecko.c | 6 ++++-- drivers/serial/uart_gecko.c | 12 ++++++++---- drivers/spi/spi_gecko.c | 9 ++++++--- soc/arm/silabs_exx32/common/CMakeLists.txt | 2 +- soc/arm/silabs_exx32/common/soc.c | 2 +- soc/arm/silabs_exx32/common/soc_gpio.c | 16 ---------------- soc/arm/silabs_exx32/common/soc_gpio.h | 6 ------ 9 files changed, 28 insertions(+), 37 deletions(-) delete mode 100644 soc/arm/silabs_exx32/common/soc_gpio.c diff --git a/drivers/ethernet/eth_gecko.c b/drivers/ethernet/eth_gecko.c index 4cae642192be3..a2590e86c02ea 100644 --- a/drivers/ethernet/eth_gecko.c +++ b/drivers/ethernet/eth_gecko.c @@ -441,8 +441,10 @@ static void eth_init_pins(const struct device *dev) eth->ROUTEPEN = 0; #if DT_INST_NODE_HAS_PROP(0, location_rmii) + struct soc_gpio_pin *pin; for (idx = 0; idx < ARRAY_SIZE(cfg->pin_list->rmii); idx++) - soc_gpio_configure(&cfg->pin_list->rmii[idx]); + pin = &cfg->pin_list->rmii[idx]; + GPIO_PinModeSet(pin->port, pin->pin, pin->mode, pin->out); eth->ROUTELOC1 |= (DT_INST_PROP(0, location_rmii) << _ETH_ROUTELOC1_RMIILOC_SHIFT); @@ -450,8 +452,10 @@ static void eth_init_pins(const struct device *dev) #endif #if DT_INST_NODE_HAS_PROP(0, location_mdio) + struct soc_gpio_pin *pin; for (idx = 0; idx < ARRAY_SIZE(cfg->pin_list->mdio); idx++) - soc_gpio_configure(&cfg->pin_list->mdio[idx]); + pin = &cfg->pin_list->mdio[idx]; + GPIO_PinModeSet(pin->port, pin->pin, pin->mode, pin->out); eth->ROUTELOC1 |= (DT_INST_PROP(0, location_mdio) << _ETH_ROUTELOC1_MDIOLOC_SHIFT); diff --git a/drivers/i2c/i2c_gecko.c b/drivers/i2c/i2c_gecko.c index 80eb2b147e2da..c77bea215b46b 100644 --- a/drivers/i2c/i2c_gecko.c +++ b/drivers/i2c/i2c_gecko.c @@ -50,8 +50,8 @@ void i2c_gecko_config_pins(const struct device *dev, I2C_TypeDef *base = DEV_BASE(dev); const struct i2c_gecko_config *config = dev->config; - soc_gpio_configure(pin_scl); - soc_gpio_configure(pin_sda); + GPIO_PinModeSet(pin_scl->port, pin_scl->pin, pin_scl->mode, pin_scl->out); + GPIO_PinModeSet(pin_sda->port, pin_sda->pin, pin_sda->mode, pin_sda->out); #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION base->ROUTEPEN = I2C_ROUTEPEN_SDAPEN | I2C_ROUTEPEN_SCLPEN; diff --git a/drivers/serial/leuart_gecko.c b/drivers/serial/leuart_gecko.c index 533b043b2baf4..cc89a56428d33 100644 --- a/drivers/serial/leuart_gecko.c +++ b/drivers/serial/leuart_gecko.c @@ -245,8 +245,10 @@ static void leuart_gecko_init_pins(const struct device *dev) const struct leuart_gecko_config *config = dev->config; LEUART_TypeDef *base = DEV_BASE(dev); - soc_gpio_configure(&config->pin_rx); - soc_gpio_configure(&config->pin_tx); + GPIO_PinModeSet(config->pin_rx.port, config->pin_rx.pin, + config->pin_rx.mode, config->pin_rx.out); + GPIO_PinModeSet(config->pin_tx.port, config->pin_tx.pin, + config->pin_tx.mode, config->pin_tx.out); #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION base->ROUTEPEN = LEUART_ROUTEPEN_RXPEN | LEUART_ROUTEPEN_TXPEN; diff --git a/drivers/serial/uart_gecko.c b/drivers/serial/uart_gecko.c index b08a059ad4b7e..5c431e16562c6 100644 --- a/drivers/serial/uart_gecko.c +++ b/drivers/serial/uart_gecko.c @@ -297,8 +297,10 @@ static void uart_gecko_init_pins(const struct device *dev) const struct uart_gecko_config *config = dev->config; /* Configure RX and TX */ - soc_gpio_configure(&config->pin_rx); - soc_gpio_configure(&config->pin_tx); + GPIO_PinModeSet(config->pin_rx.port, config->pin_rx.pin, + config->pin_rx.mode, config->pin_rx.out); + GPIO_PinModeSet(config->pin_tx.port, config->pin_tx.pin, + config->pin_tx.mode, config->pin_tx.out); #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION /* For SOCs with configurable pin locations (set in SOC Kconfig) */ @@ -325,8 +327,10 @@ static void uart_gecko_init_pins(const struct device *dev) #ifdef UART_GECKO_HW_FLOW_CONTROL /* Configure HW flow control (RTS, CTS) */ if (config->hw_flowcontrol) { - soc_gpio_configure(&config->pin_rts); - soc_gpio_configure(&config->pin_cts); + GPIO_PinModeSet(config->pin_rts.port, config->pin_rts.pin, + config->pin_rts.mode, config->pin_rts.out); + GPIO_PinModeSet(config->pin_cts.port, config->pin_cts.pin, + config->pin_cts.mode, config->pin_cts.out); #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION config->base->ROUTEPEN = diff --git a/drivers/spi/spi_gecko.c b/drivers/spi/spi_gecko.c index 195374dfdc0d2..187ae4212258d 100644 --- a/drivers/spi/spi_gecko.c +++ b/drivers/spi/spi_gecko.c @@ -188,9 +188,12 @@ static void spi_gecko_init_pins(const struct device *dev) { const struct spi_gecko_config *config = dev->config; - soc_gpio_configure(&config->pin_rx); - soc_gpio_configure(&config->pin_tx); - soc_gpio_configure(&config->pin_clk); + GPIO_PinModeSet(config->pin_rx.port, config->pin_rx.pin, + config->pin_rx.mode, config->pin_rx.out); + GPIO_PinModeSet(config->pin_tx.port, config->pin_tx.pin, + config->pin_tx.mode, config->pin_tx.out); + GPIO_PinModeSet(config->pin_clk.port, config->pin_clk.pin, + config->pin_clk.mode, config->pin_clk.out); /* disable all pins while configuring */ config->base->ROUTEPEN = 0; diff --git a/soc/arm/silabs_exx32/common/CMakeLists.txt b/soc/arm/silabs_exx32/common/CMakeLists.txt index 27ad42591ccf1..5e6a378823800 100644 --- a/soc/arm/silabs_exx32/common/CMakeLists.txt +++ b/soc/arm/silabs_exx32/common/CMakeLists.txt @@ -1,5 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_sources(soc.c soc_gpio.c) +zephyr_sources(soc.c) zephyr_sources_ifdef(CONFIG_PM soc_power.c) diff --git a/soc/arm/silabs_exx32/common/soc.c b/soc/arm/silabs_exx32/common/soc.c index f864f778b1e18..c7b4d4c491ff4 100644 --- a/soc/arm/silabs_exx32/common/soc.c +++ b/soc/arm/silabs_exx32/common/soc.c @@ -168,7 +168,7 @@ static void swo_init(void) #endif #endif /* _SILICON_LABS_32B_SERIES_2 */ - soc_gpio_configure(&pin_swo); + GPIO_PinModeSet(pin_swo.port, pin_swo.pin, pin_swo.mode, pin_swo.out); } #endif /* CONFIG_LOG_BACKEND_SWO */ diff --git a/soc/arm/silabs_exx32/common/soc_gpio.c b/soc/arm/silabs_exx32/common/soc_gpio.c deleted file mode 100644 index e38cad7f0a196..0000000000000 --- a/soc/arm/silabs_exx32/common/soc_gpio.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2017 Christian Taedcke - * SPDX-License-Identifier: Apache-2.0 - */ - -/** @file - * @brief Silabs EXX32 MCU family General Purpose Input Output (GPIO) - * module HAL driver. - */ - -#include "soc_gpio.h" - -void soc_gpio_configure(const struct soc_gpio_pin *pin) -{ - GPIO_PinModeSet(pin->port, pin->pin, pin->mode, pin->out); -} diff --git a/soc/arm/silabs_exx32/common/soc_gpio.h b/soc/arm/silabs_exx32/common/soc_gpio.h index 3519a0533f4ea..e030c3bc32eb7 100644 --- a/soc/arm/silabs_exx32/common/soc_gpio.h +++ b/soc/arm/silabs_exx32/common/soc_gpio.h @@ -25,12 +25,6 @@ struct soc_gpio_pin { unsigned int out; /** out register value */ }; -/** - * @brief Configure GPIO pin - * @param[in] pin configuration data - */ -void soc_gpio_configure(const struct soc_gpio_pin *pin); - #ifdef __cplusplus } #endif From 2110d9df82d7760895a12e4df2d7065399e8627c Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Wed, 7 Sep 2022 11:00:47 +0200 Subject: [PATCH 03/17] drivers: pinctrl: Add Silabs Gecko pin controller This commit adds initial support for gecko pinctrl driver Co-authored-by: Mateusz Sierszulski Signed-off-by: Filip Kokosinski --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.gecko | 11 ++ drivers/pinctrl/pinctrl_gecko.c | 103 ++++++++++++++++++ .../pinctrl/silabs,gecko-pinctrl.yaml | 79 ++++++++++++++ .../dt-bindings/pinctrl/gecko-pinctrl.h | 88 +++++++++++++++ 6 files changed, 283 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.gecko create mode 100644 drivers/pinctrl/pinctrl_gecko.c create mode 100644 dts/bindings/pinctrl/silabs,gecko-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index a6c8244c8800d..171dedc88c4e1 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -27,3 +27,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_XLNX_ZYNQ pinctrl_xlnx_zynq.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SMARTBOND pinctrl_smartbond.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_XMC4XXX pinctrl_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_S32 pinctrl_s32.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_GECKO pinctrl_gecko.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 0647150c80680..efc3a2b79f830 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -56,5 +56,6 @@ source "drivers/pinctrl/Kconfig.xlnx" source "drivers/pinctrl/Kconfig.smartbond" source "drivers/pinctrl/Kconfig.xmc4xxx" source "drivers/pinctrl/Kconfig.s32" +source "drivers/pinctrl/Kconfig.gecko" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.gecko b/drivers/pinctrl/Kconfig.gecko new file mode 100644 index 0000000000000..9bc09b9d8c00e --- /dev/null +++ b/drivers/pinctrl/Kconfig.gecko @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Silicon Labs +# SPDX-License-Identifier: Apache-2.0 +# TODO: copyright changes? + +config PINCTRL_GECKO + bool "Gecko pin controller driver" + default y + depends on DT_HAS_SILABS_GECKO_PINCTRL_ENABLED + select PINCTRL_STORE_REG + help + Gecko pin controller driver diff --git a/drivers/pinctrl/pinctrl_gecko.c b/drivers/pinctrl/pinctrl_gecko.c new file mode 100644 index 0000000000000..530044f753d9e --- /dev/null +++ b/drivers/pinctrl/pinctrl_gecko.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ +#ifdef CONFIG_UART_GECKO + struct soc_gpio_pin rxpin = {0}; + struct soc_gpio_pin txpin = {0}; + USART_TypeDef *base = (USART_TypeDef *)reg; + uint8_t loc; + int usart_num = USART_NUM(base); +#endif /* CONFIG_UART_GECKO */ + + for (uint8_t i = 0U; i < pin_cnt; i++) { + switch (GECKO_GET_FUN(pins[i])) { +#ifdef CONFIG_UART_GECKO + case GECKO_FUN_UART_RX: + rxpin.port = GECKO_GET_PORT(pins[i]); + rxpin.pin = GECKO_GET_PIN(pins[i]); + rxpin.mode = gpioModeInput; + rxpin.out = 1; + GPIO_PinModeSet(rxpin.port, rxpin.pin, rxpin.mode, + rxpin.out); + break; + case GECKO_FUN_UART_TX: + txpin.port = GECKO_GET_PORT(pins[i]); + txpin.pin = GECKO_GET_PIN(pins[i]); + txpin.mode = gpioModePushPull; + txpin.out = 1; + GPIO_PinModeSet(txpin.port, txpin.pin, txpin.mode, + txpin.out); + break; + case GECKO_FUN_UART_LOC: + loc = GECKO_GET_LOC(pins[i]); +#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION + /* For SOCs with configurable pin locations (set in SOC Kconfig) */ + base->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; + base->ROUTELOC0 = (loc << _USART_ROUTELOC0_TXLOC_SHIFT) | + (loc << _USART_ROUTELOC0_RXLOC_SHIFT); + base->ROUTELOC1 = _USART_ROUTELOC1_RESETVALUE; +#elif defined(USART_ROUTE_RXPEN) && defined(USART_ROUTE_TXPEN) + /* For olders SOCs with only one pin location */ + base->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | (loc << 8); +#elif defined(GPIO_USART_ROUTEEN_RXPEN) && defined(GPIO_USART_ROUTEEN_TXPEN) + GPIO->USARTROUTE[usart_num].ROUTEEN = + GPIO_USART_ROUTEEN_TXPEN | GPIO_USART_ROUTEEN_RXPEN; + GPIO->USARTROUTE[usart_num].TXROUTE = + (txpin.pin << _GPIO_USART_TXROUTE_PIN_SHIFT) | + (txpin.port << _GPIO_USART_TXROUTE_PORT_SHIFT); + GPIO->USARTROUTE[usart_num].RXROUTE = + (rxpin.pin << _GPIO_USART_RXROUTE_PIN_SHIFT) | + (rxpin.port << _GPIO_USART_RXROUTE_PORT_SHIFT); +#endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */ + +#ifdef UART_GECKO_HW_FLOW_CONTROL + /* Configure HW flow control (RTS, CTS) */ + if (config->hw_flowcontrol) { + GPIO_PinModeSet(config->pin_rts.port, + config->pin_rts.pin, + config->pin_rts.mode, + config->pin_rts.out); + GPIO_PinModeSet(config->pin_cts.port, + config->pin_cts.pin, + config->pin_cts.mode, + config->pin_cts.out); +#ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION + config->base->ROUTEPEN = + USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN | + USART_ROUTEPEN_RTSPEN | USART_ROUTEPEN_CTSPEN; + + config->base->ROUTELOC1 = + (config->loc_rts << _USART_ROUTELOC1_RTSLOC_SHIFT) | + (config->loc_cts << _USART_ROUTELOC1_CTSLOC_SHIFT); +#elif defined(GPIO_USART_ROUTEEN_RTSPEN) && defined(GPIO_USART_ROUTEEN_CTSPEN) + GPIO->USARTROUTE[usart_num].ROUTEEN = + GPIO_USART_ROUTEEN_TXPEN | GPIO_USART_ROUTEEN_RXPEN | + GPIO_USART_ROUTEPEN_RTSPEN | GPIO_USART_ROUTEPEN_CTSPEN; + + GPIO->USARTROUTE[usart_num].RTSROUTE = + (config->pin_rts.pin << _GPIO_USART_RTSROUTE_PIN_SHIFT) | + (config->pin_rts.port << _GPIO_USART_RTSROUTE_PORT_SHIFT); + GPIO->USARTROUTE[usart_num].CTSROUTE = + (config->pin_cts.pin << _GPIO_USART_CTSROUTE_PIN_SHIFT) | + (config->pin_cts.port << _GPIO_USART_CTSROUTE_PORT_SHIFT); +#endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */ + } +#endif /* UART_GECKO_HW_FLOW_CONTROL */ + break; +#endif /* CONFIG_UART_GECKO */ + default: + return -ENOTSUP; + } + } + + return 0; +} diff --git a/dts/bindings/pinctrl/silabs,gecko-pinctrl.yaml b/dts/bindings/pinctrl/silabs,gecko-pinctrl.yaml new file mode 100644 index 0000000000000..e986c39c14dda --- /dev/null +++ b/dts/bindings/pinctrl/silabs,gecko-pinctrl.yaml @@ -0,0 +1,79 @@ +# Copyright (c) 2022 Silicon Labs +# SPDX-License-Identifier: Apache-2.0 + +description: | + The Silabs pin controller is a singleton node responsible for controlling + pin function selection and pin properties. For example, you can use this + node to route UART0 RX to pin P0.1 and enable the pull-up resistor on the + pin. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as shown in this example: + + /* You can put this in places like a board-pinctrl.dtsi file in + * your board directory, or a devicetree overlay in your application. + */ + &pinctrl { + /* configuration for usart0 device, default state */ + usart0_default: usart0_default { + /* group 1 ('group1' name is arbitrary) */ + group1 { + /* configure P0.1 as UART_TX and P0.2 as UART_RTS */ + psels = , ; + }; + /* group 2 */ + group2 { + /* configure P0.3 as UART_RX and P0.4 as UART_CTS */ + psels = , ; + }; + }; + }; + + The 'usart0_default' child node encodes the pin configurations for a + particular state of a device; in this case, the default (that is, active) + state. You would specify the low-power configuration for the same device + in a separate child node. + + As shown, pin configurations are organized in groups within each child node. + Each group can specify a list of pin function selections in the 'psels' + property. The GECKO_PSEL macro is used to specify a pin function selection. + Available pin functions can be found in the + include/dt-bindings/pinctrl/gecko-pinctrl.h header file. + + To link this pin configuration with a device, use a pinctrl-N property + for some number N, like this example you could place in your board's DTS + file: + + #include "board-pinctrl.dtsi" + + &usart0 { + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + }; + +compatible: "silabs,gecko-pinctrl" + +include: base.yaml + +child-binding: + description: | + Silabs pin controller pin configuration state nodes. + include: pincfg-node.yaml + child-binding: + description: | + Silabs pin controller pin configuration group. + properties: + psels: + required: true + type: array + description: | + An array of pins sharing the same group properties. The pins should + be defined using the GECKO_PSEL utility macro that encodes the port, + pin and function. diff --git a/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h new file mode 100644 index 0000000000000..9eae1c945f91c --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/gecko-pinctrl.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Silicon Labs + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_GECKO_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_GECKO_PINCTRL_H_ + +/* + * The whole GECKO_pin configuration information is encoded in a 32-bit bitfield + * organized as follows: + * + * - 31..24: Pin function. + * - 23..16: Reserved. + * - 15..8: Port for UART_RX/UART_TX functions. + * - 7..0: Pin number for UART_RX/UART_TX functions. + * - 15..8: Reserved for UART_LOC function. + * - 7..0: Loc for UART_LOC function. + */ + +/** + * @name GECKO_pin configuration bit field positions and masks. + * @{ + */ + +/** Position of the function field. */ +#define GECKO_FUN_POS 24U +/** Mask for the function field. */ +#define GECKO_FUN_MSK 0xFFFU + +/** Position of the pin field. */ +#define GECKO_PIN_POS 0U +/** Mask for the pin field. */ +#define GECKO_PIN_MSK 0xFFU + +/** Position of the port field. */ +#define GECKO_PORT_POS 8U +/** Mask for the port field. */ +#define GECKO_PORT_MSK 0xFFU + +/** Position of the loc field. */ +#define GECKO_LOC_POS 0U +/** Mask for the pin field. */ +#define GECKO_LOC_MSK 0xFFU + +/** @} */ + +/** + * @name GECKO_pinctrl pin functions. + * @{ + */ + +/** UART TX */ +#define GECKO_FUN_UART_TX 0U +/** UART RX */ +#define GECKO_FUN_UART_RX 1U +/** UART RTS */ +#define GECKO_FUN_UART_RTS 2U +/** UART CTS */ +#define GECKO_FUN_UART_CTS 3U +/** UART LOCATION */ +#define GECKO_FUN_UART_LOC 4U + +/** @} */ + +/** + * @brief Utility macro to build GECKO psels property entry. + * + * @param fun Pin function configuration (see GECKO_FUNC_{name} macros). + * @param port Port (0 or 1). + * @param pin Pin (0..31). + */ +#define GECKO_PSEL(fun, port, pin) \ + (((GECKO_PORT_##port & GECKO_PORT_MSK) << GECKO_PORT_POS) | \ + ((GECKO_PIN(##pin##) & GECKO_PIN_MSK) << GECKO_PIN_POS) | \ + ((GECKO_FUN_##fun & GECKO_FUN_MSK) << GECKO_FUN_POS)) + +/** + * @brief Utility macro to build GECKO_psels property entry. + * + * @param fun Pin function configuration (see GECKO_FUNC_{name} macros). + * @param loc Location. + */ +#define GECKO_LOC(fun, loc) \ + (((GECKO_LOCATION(##loc##) & GECKO_LOC_MSK) << GECKO_LOC_POS) | \ + ((GECKO_FUN_##fun##_LOC & GECKO_FUN_MSK) << GECKO_FUN_POS)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_GECKO_PINCTRL_H_ */ From 6b16523e949a8ac8c5f27882dd678c6cf5aa68ac Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Wed, 7 Sep 2022 10:57:12 +0200 Subject: [PATCH 04/17] drivers: serial: uart_gecko: Make driver dependent on pinctrl This commit adds a series of driver-related changes to Gecko pinctrl. Co-authored-by: Mateusz Sierszulski Signed-off-by: Filip Kokosinski --- drivers/serial/uart_gecko.c | 86 ++++++++++++++++----- dts/bindings/serial/silabs,gecko-usart.yaml | 4 +- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/drivers/serial/uart_gecko.c b/drivers/serial/uart_gecko.c index 5c431e16562c6..aa93433af8561 100644 --- a/drivers/serial/uart_gecko.c +++ b/drivers/serial/uart_gecko.c @@ -9,18 +9,23 @@ #include #include #include -#include #include #include +#ifdef CONFIG_PINCTRL +#include +#else +#include +#endif /* CONFIG_PINCTRL */ + #define USART_PREFIX cmuClock_USART #define UART_PREFIX cmuClock_UART #define CLOCK_USART(id) _CONCAT(USART_PREFIX, id) #define CLOCK_UART(id) _CONCAT(UART_PREFIX, id) /* Helper define to determine if SOC supports hardware flow control */ -#if ((_SILICON_LABS_32B_SERIES > 0) || \ - (defined(_USART_ROUTEPEN_RTSPEN_MASK) && \ +#if ((_SILICON_LABS_32B_SERIES > 0) || \ + (defined(_USART_ROUTEPEN_RTSPEN_MASK) && \ defined(_USART_ROUTEPEN_CTSPEN_MASK))) #define HW_FLOWCONTROL_IS_SUPPORTED_BY_SOC #endif @@ -30,30 +35,30 @@ #define DT_DRV_COMPAT silabs_gecko_uart /* Has any enabled uart instance hw-flow-control enabled? */ -#define UART_GECKO_UART_HW_FLOW_CONTROL_ENABLED \ +#define UART_GECKO_UART_HW_FLOW_CONTROL_ENABLED \ DT_INST_FOREACH_STATUS_OKAY(HAS_HFC_OR) 0 #undef DT_DRV_COMPAT #define DT_DRV_COMPAT silabs_gecko_usart /* Has any enabled usart instance hw-flow-control enabled? */ -#define UART_GECKO_USART_HW_FLOW_CONTROL_ENABLED \ +#define UART_GECKO_USART_HW_FLOW_CONTROL_ENABLED \ DT_INST_FOREACH_STATUS_OKAY(HAS_HFC_OR) 0 -#if UART_GECKO_USART_HW_FLOW_CONTROL_ENABLED || \ +#if UART_GECKO_USART_HW_FLOW_CONTROL_ENABLED || \ UART_GECKO_UART_HW_FLOW_CONTROL_ENABLED #define UART_GECKO_HW_FLOW_CONTROL #endif /* Sanity check for hardware flow control */ -#if defined(UART_GECKO_HW_FLOW_CONTROL) && \ +#if defined(UART_GECKO_HW_FLOW_CONTROL) && \ (!(defined(HW_FLOWCONTROL_IS_SUPPORTED_BY_SOC))) -#error "Hardware flow control is activated for at least one UART/USART, \ +#error "Hardware flow control is activated for at least one UART/USART, \ but not supported by this SOC" #endif -#if defined(UART_GECKO_HW_FLOW_CONTROL) && \ - (!defined(CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION) && \ +#if defined(UART_GECKO_HW_FLOW_CONTROL) && \ + (!defined(CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION) && \ !defined(GPIO_USART_ROUTEEN_RTSPEN)) #error "Driver not supporting hardware flow control for this SOC" #endif @@ -61,31 +66,39 @@ but not supported by this SOC" /** * @brief Config struct for UART */ + struct uart_gecko_config { +#ifdef CONFIG_PINCTRL + const struct pinctrl_dev_config *pcfg; +#endif /* CONFIG_PINCTRL */ USART_TypeDef *base; CMU_Clock_TypeDef clock; uint32_t baud_rate; +#ifndef CONFIG_PINCTRL #ifdef UART_GECKO_HW_FLOW_CONTROL bool hw_flowcontrol; +#endif /* UART_GECKO_HW_FLOW_CONTROL */ #endif #ifdef CONFIG_UART_INTERRUPT_DRIVEN void (*irq_config_func)(const struct device *dev); -#endif +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifndef CONFIG_PINCTRL struct soc_gpio_pin pin_rx; struct soc_gpio_pin pin_tx; #ifdef UART_GECKO_HW_FLOW_CONTROL struct soc_gpio_pin pin_rts; struct soc_gpio_pin pin_cts; -#endif +#endif /* UART_GECKO_HW_FLOW_CONTROL */ #ifdef CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION uint8_t loc_rx; uint8_t loc_tx; #ifdef UART_GECKO_HW_FLOW_CONTROL uint8_t loc_rts; uint8_t loc_cts; -#endif -#else +#endif /* UART_GECKO_HW_FLOW_CONTROL */ +#else /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */ uint8_t loc; +#endif /* CONFIG_SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION */ #endif }; @@ -292,6 +305,7 @@ static void uart_gecko_isr(const struct device *dev) * * @param dev UART device to configure */ + #ifndef CONFIG_PINCTRL static void uart_gecko_init_pins(const struct device *dev) { const struct uart_gecko_config *config = dev->config; @@ -359,6 +373,7 @@ static void uart_gecko_init_pins(const struct device *dev) } #endif /* UART_GECKO_HW_FLOW_CONTROL */ } +#endif /* !CONFIG_PINCTRL */ /** * @brief Main initializer for UART @@ -368,7 +383,11 @@ static void uart_gecko_init_pins(const struct device *dev) */ static int uart_gecko_init(const struct device *dev) { +#ifdef CONFIG_PINCTRL + int err; +#endif /* CONFIG_PINCTRL */ const struct uart_gecko_config *config = dev->config; + USART_InitAsync_TypeDef usartInit = USART_INITASYNC_DEFAULT; /* The peripheral and gpio clock are already enabled from soc and gpio @@ -386,8 +405,15 @@ static int uart_gecko_init(const struct device *dev) #endif USART_InitAsync(config->base, &usartInit); +#ifdef CONFIG_PINCTRL + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } +#else /* Initialize USART pins */ uart_gecko_init_pins(dev); +#endif /* CONFIG_PINCTRL */ #ifdef CONFIG_UART_INTERRUPT_DRIVEN config->irq_config_func(dev); @@ -427,7 +453,7 @@ static const struct uart_driver_api uart_gecko_driver_api = { #define GECKO_UART_IRQ_HANDLER_FUNC(idx) \ .irq_config_func = uart_gecko_config_func_##idx, #define GECKO_UART_IRQ_HANDLER(idx) \ - static void uart_gecko_config_func_##idx(const struct device *dev) \ + static void uart_gecko_config_func_##idx(const struct device *dev) \ { \ IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, rx, irq), \ DT_INST_IRQ_BY_NAME(idx, rx, priority), \ @@ -572,7 +598,7 @@ DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT) #define GECKO_USART_IRQ_HANDLER_FUNC(idx) \ .irq_config_func = usart_gecko_config_func_##idx, #define GECKO_USART_IRQ_HANDLER(idx) \ - static void usart_gecko_config_func_##idx(const struct device *dev) \ + static void usart_gecko_config_func_##idx(const struct device *dev) \ { \ IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, rx, irq), \ DT_INST_IRQ_BY_NAME(idx, rx, priority), \ @@ -590,15 +616,38 @@ DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT) #define GECKO_USART_IRQ_HANDLER(idx) #endif +#ifdef CONFIG_PINCTRL +#define GECKO_USART_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ + GECKO_USART_IRQ_HANDLER_DECL(idx); \ + \ + static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ + .clock = CLOCK_USART(DT_INST_PROP(idx, peripheral_id)), \ + .baud_rate = DT_INST_PROP(idx, current_speed), \ + GECKO_USART_IRQ_HANDLER_FUNC(idx) \ + }; \ + \ + static struct uart_gecko_data usart_gecko_data_##idx; \ + \ + DEVICE_DT_INST_DEFINE(idx, &uart_gecko_init, NULL, \ + &usart_gecko_data_##idx, \ + &usart_gecko_cfg_##idx, PRE_KERNEL_1, \ + CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_gecko_driver_api); \ + \ + GECKO_USART_IRQ_HANDLER(idx) +#else #define GECKO_USART_INIT(idx) \ VALIDATE_GECKO_UART_RX_TX_PIN_LOCATIONS(idx); \ VALIDATE_GECKO_UART_RTS_CTS_PIN_LOCATIONS(idx); \ \ GECKO_USART_IRQ_HANDLER_DECL(idx); \ \ - static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ + static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ - .clock = CLOCK_USART(DT_INST_PROP(idx, peripheral_id)), \ + .clock = CLOCK_USART(DT_INST_PROP(idx, peripheral_id)), \ .baud_rate = DT_INST_PROP(idx, current_speed), \ GECKO_UART_HW_FLOW_CONTROL(idx) \ GECKO_UART_RX_TX_PINS(idx) \ @@ -617,5 +666,6 @@ DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT) &uart_gecko_driver_api); \ \ GECKO_USART_IRQ_HANDLER(idx) +#endif DT_INST_FOREACH_STATUS_OKAY(GECKO_USART_INIT) diff --git a/dts/bindings/serial/silabs,gecko-usart.yaml b/dts/bindings/serial/silabs,gecko-usart.yaml index 513272a7e990f..ac3003b0c2cf4 100644 --- a/dts/bindings/serial/silabs,gecko-usart.yaml +++ b/dts/bindings/serial/silabs,gecko-usart.yaml @@ -2,7 +2,7 @@ description: Gecko USART compatible: "silabs,gecko-usart" -include: uart-controller.yaml +include: [uart-controller.yaml, pinctrl-device.yaml] properties: reg: @@ -21,12 +21,10 @@ properties: location-rx: type: array - required: true description: RX pin configuration defined as location-tx: type: array - required: true description: TX pin configuration defined as location-rts: From 029782a653dff96ffd78e458e25d7a53a3a65615 Mon Sep 17 00:00:00 2001 From: Mateusz Sierszulski Date: Wed, 14 Sep 2022 13:56:25 +0200 Subject: [PATCH 05/17] drivers: counter: Add counter_gecko_stimer driver This commit adds initial support for Silabs Real-Time counter Co-authored-by: Filip Kokosinski Signed-off-by: Mateusz Sierszulski --- drivers/counter/CMakeLists.txt | 1 + drivers/counter/Kconfig.gecko | 9 + drivers/counter/counter_gecko_stimer.c | 291 ++++++++++++++++++++++ dts/bindings/rtc/silabs,gecko-stimer.yaml | 12 + 4 files changed, 313 insertions(+) create mode 100644 drivers/counter/counter_gecko_stimer.c create mode 100644 dts/bindings/rtc/silabs,gecko-stimer.yaml diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index 6dface13d9d4c..38ae41fbf9f51 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -5,6 +5,7 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_TIMER_TMR_CMSDK_APB timer_tmr_cmsdk_apb.c) zephyr_library_sources_ifdef(CONFIG_TIMER_DTMR_CMSDK_APB timer_dtmr_cmsdk_apb.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_GECKO_RTCC counter_gecko_rtcc.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_GECKO_STIMER counter_gecko_stimer.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_IMX_EPIT counter_imx_epit.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_CTIMER counter_mcux_ctimer.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_RTC counter_mcux_rtc.c) diff --git a/drivers/counter/Kconfig.gecko b/drivers/counter/Kconfig.gecko index 5724da51d59ca..bbe56d22a5612 100644 --- a/drivers/counter/Kconfig.gecko +++ b/drivers/counter/Kconfig.gecko @@ -12,3 +12,12 @@ config COUNTER_GECKO_RTCC help Enable counter driver based on RTCC module for Silicon Labs Gecko chips. + +config COUNTER_GECKO_STIMER + bool "Silicon Labs Gecko Counter Sleep Timer driver" + default y + depends on DT_HAS_SILABS_GECKO_STIMER_ENABLED + select SOC_GECKO_RTCC + help + Enable the counter driver for Sleep Timer module for Silicon Labs + Gecko chips. diff --git a/drivers/counter/counter_gecko_stimer.c b/drivers/counter/counter_gecko_stimer.c new file mode 100644 index 0000000000000..682d632e8876e --- /dev/null +++ b/drivers/counter/counter_gecko_stimer.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2021, Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT silabs_gecko_stimer + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +LOG_MODULE_REGISTER(counter_gecko, CONFIG_COUNTER_LOG_LEVEL); + +#define STIMER_MAX_VALUE (_RTCC_CNT_MASK) +#define STIMER_ALARM_NUM 2 + +struct counter_gecko_config { + struct counter_config_info info; + void (*irq_config)(void); + uint32_t prescaler; +}; + +struct counter_gecko_alarm_data { + counter_alarm_callback_t callback; + uint8_t chan_id; + uint32_t ticks; + struct device *dev; + void *user_data; +}; + +struct counter_gecko_top_data { + counter_top_callback_t callback; + uint32_t ticks; + struct device *dev; + void *user_data; +}; + +struct counter_gecko_data { + struct counter_gecko_alarm_data alarm[STIMER_ALARM_NUM]; + struct counter_gecko_top_data top_data; +}; + +static sl_sleeptimer_timer_handle_t alarm_timer[STIMER_ALARM_NUM]; +static sl_sleeptimer_timer_handle_t top_timer; + +#ifdef CONFIG_SOC_GECKO_HAS_ERRATA_RTCC_E201 +#define ERRATA_RTCC_E201_MESSAGE \ + "Errata RTCC_E201: In case RTCC prescaler != 1 the module does not " \ + "reset the counter value on CCV1 compare." +#endif + +static void alarm_callback(sl_sleeptimer_timer_handle_t *handle, void *data) +{ + struct counter_gecko_alarm_data *alarm_data = (struct counter_gecko_alarm_data *)data; + uint32_t count = + ((sl_sleeptimer_get_tick_count()) % + (((struct counter_gecko_data *const)(alarm_data->dev)->data)->top_data.ticks)); + + if (alarm_data->callback != NULL) { + alarm_data->callback( + alarm_data->dev, alarm_data->chan_id, count, + ((struct counter_alarm_cfg *)(alarm_data->user_data))->user_data); + } +} + +static void top_callback(sl_sleeptimer_timer_handle_t *handle, void *data) +{ + struct counter_gecko_top_data *top_data = (struct counter_gecko_top_data *)data; + + if (top_data->callback != NULL) { + top_data->callback(top_data->dev, + ((struct counter_top_cfg *)(top_data->user_data))->user_data); + } +} + +static int counter_gecko_get_value(const struct device *dev, uint32_t *ticks) +{ + struct counter_gecko_data *const dev_data = (struct counter_gecko_data *const)(dev)->data; + + *ticks = ((sl_sleeptimer_get_tick_count()) % (dev_data->top_data.ticks)); + + return 0; +} + +static int counter_gecko_start(const struct device *dev) +{ + ARG_UNUSED(dev); + + sl_status_t error_code; + bool is_top_timer_running = false; + + error_code = sl_sleeptimer_is_timer_running(&top_timer, &is_top_timer_running); + if ((error_code == SL_STATUS_OK) && (is_top_timer_running == true)) + return 0; + struct counter_gecko_data *const dev_data = (struct counter_gecko_data *const)(dev)->data; + + error_code = sl_sleeptimer_start_timer(&top_timer, dev_data->top_data.ticks, top_callback, + (void *)&dev_data->top_data, 0, 0); + return error_code; +} + +static int counter_gecko_stop(const struct device *dev) +{ + ARG_UNUSED(dev); + + sl_status_t error_code; + bool is_top_timer_running = false; + + error_code = sl_sleeptimer_is_timer_running(&top_timer, &is_top_timer_running); + if ((error_code == SL_STATUS_OK) && (is_top_timer_running == true)) { + sl_sleeptimer_stop_timer(&top_timer); + } + return error_code; +} + +static int counter_gecko_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) +{ + struct counter_gecko_data *const dev_data = (struct counter_gecko_data *const)(dev)->data; + sl_status_t error_code; + bool is_top_timer_running = false; + +#ifdef CONFIG_SOC_GECKO_HAS_ERRATA_RTCC_E201 + const struct counter_gecko_config *const dev_cfg = + (const struct counter_gecko_config *const)(dev)->config; + + if (dev_cfg->prescaler != 1) { + LOG_ERR(ERRATA_RTCC_E201_MESSAGE); + return -EINVAL; + } +#endif + + error_code = sl_sleeptimer_is_timer_running(&top_timer, &is_top_timer_running); + if ((error_code == SL_STATUS_OK) && (is_top_timer_running == true)) { + sl_sleeptimer_stop_timer(&top_timer); + } + + dev_data->top_data.callback = cfg->callback; + dev_data->top_data.ticks = cfg->ticks; + dev_data->top_data.dev = (struct device *)dev; + dev_data->top_data.user_data = (struct counter_top_cfg *)cfg; + + error_code = sl_sleeptimer_start_periodic_timer(&top_timer, cfg->ticks, top_callback, + (void *)&dev_data->top_data, 0, cfg->flags); + + return error_code; +} + +static uint32_t counter_gecko_get_top_value(const struct device *dev) +{ + struct counter_gecko_data *const dev_data = (struct counter_gecko_data *const)(dev)->data; + + return dev_data->top_data.ticks; +} + +static int counter_gecko_set_alarm(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + bool is_alarm_timer_running = false; + struct counter_gecko_data *const dev_data = (struct counter_gecko_data *const)(dev)->data; + sl_status_t error_code; + uint32_t now_ticks = 0; + uint32_t top_val = counter_gecko_get_top_value(dev); + + if ((top_val != 0) && (alarm_cfg->ticks > top_val)) { + return -EINVAL; + } + + if (chan_id >= STIMER_ALARM_NUM) { + printk("Alarm timer count exceeded\n"); + return -EINVAL; + } + + error_code = sl_sleeptimer_is_timer_running(&alarm_timer[chan_id], &is_alarm_timer_running); + if ((error_code == SL_STATUS_OK) && (is_alarm_timer_running == true)) { + sl_sleeptimer_stop_timer(&alarm_timer[chan_id]); + } + + if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) != 0) { + /* Absolute */ + error_code = counter_gecko_get_value(dev, &now_ticks); + if (now_ticks < alarm_cfg->ticks) { + dev_data->alarm[chan_id].ticks = top_val + (alarm_cfg->ticks - now_ticks); + } else { + dev_data->alarm[chan_id].ticks = + (top_val - (now_ticks - alarm_cfg->ticks)) % top_val; + } + + } else { + /* Relative */ + dev_data->alarm[chan_id].ticks = alarm_cfg->ticks; + } + + dev_data->alarm[chan_id].callback = alarm_cfg->callback; + dev_data->alarm[chan_id].chan_id = chan_id; + dev_data->alarm[chan_id].dev = (struct device *)dev; + dev_data->alarm[chan_id].user_data = (struct counter_alarm_cfg *)alarm_cfg; + + error_code = + sl_sleeptimer_start_timer(&alarm_timer[chan_id], dev_data->alarm[chan_id].ticks, + alarm_callback, (void *)&dev_data->alarm[chan_id], 0, 0); + + return 0; +} + +static int counter_gecko_cancel_alarm(const struct device *dev, uint8_t chan_id) +{ + struct counter_gecko_data *const dev_data = (struct counter_gecko_data *const)(dev)->data; + + if (chan_id >= STIMER_ALARM_NUM) { + LOG_DBG("Alarm timer count exceeded\n"); + return -EINVAL; + } + + sl_sleeptimer_stop_timer(&alarm_timer[chan_id]); + + dev_data->alarm[chan_id].callback = NULL; + dev_data->alarm[chan_id].user_data = NULL; + + LOG_DBG("cancel alarm: channel %u", chan_id); + + return 0; +} + +static uint32_t counter_gecko_get_pending_int(const struct device *dev) +{ + ARG_UNUSED(dev); + + return 0; +} + +static int counter_gecko_init(const struct device *dev) +{ + const struct counter_gecko_config *const dev_cfg = + (const struct counter_gecko_config *const)(dev)->config; + struct counter_gecko_data *const dev_data = (struct counter_gecko_data *const)(dev)->data; + + sl_sleeptimer_init(); + dev_data->top_data.ticks = STIMER_MAX_VALUE; + + /* Configure & enable module interrupts */ + dev_cfg->irq_config(); + + LOG_INF("Device %s initialized", (dev)->name); + + return 0; +} + +static const struct counter_driver_api counter_gecko_driver_api = { + .start = counter_gecko_start, + .stop = counter_gecko_stop, + .get_value = counter_gecko_get_value, + .set_alarm = counter_gecko_set_alarm, + .cancel_alarm = counter_gecko_cancel_alarm, + .set_top_value = counter_gecko_set_top_value, + .get_pending_int = counter_gecko_get_pending_int, + .get_top_value = counter_gecko_get_top_value, +}; + +BUILD_ASSERT((DT_INST_PROP(0, prescaler) > 0U) && (DT_INST_PROP(0, prescaler) <= 32768U)); + +static void counter_gecko_0_irq_config(void) +{ + IRQ_DIRECT_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), RTCC_IRQHandler, 0); + irq_enable(DT_INST_IRQN(0)); +} + +static const struct counter_gecko_config counter_gecko_0_config = { + .info = { + .max_top_value = STIMER_MAX_VALUE, + .freq = DT_INST_PROP(0, clock_frequency) / DT_INST_PROP(0, prescaler), + .flags = COUNTER_CONFIG_INFO_COUNT_UP, + .channels = STIMER_ALARM_NUM, + }, + .irq_config = counter_gecko_0_irq_config, + .prescaler = DT_INST_PROP(0, prescaler), +}; + +static struct counter_gecko_data counter_gecko_0_data; + +DEVICE_DT_INST_DEFINE(0, counter_gecko_init, NULL, &counter_gecko_0_data, &counter_gecko_0_config, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &counter_gecko_driver_api); diff --git a/dts/bindings/rtc/silabs,gecko-stimer.yaml b/dts/bindings/rtc/silabs,gecko-stimer.yaml new file mode 100644 index 0000000000000..272c27b97211c --- /dev/null +++ b/dts/bindings/rtc/silabs,gecko-stimer.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2021, Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +description: Silabs Gecko Sleep Timer (Real-Time Counter) + +compatible: "silabs,gecko-stimer" + +include: rtc.yaml + +properties: + reg: + required: true From 8f9c0c41e62b570e6b9791467a51f468ced8b936 Mon Sep 17 00:00:00 2001 From: Mateusz Sierszulski Date: Wed, 14 Sep 2022 13:59:57 +0200 Subject: [PATCH 06/17] samples: drivers: counter: support alarm sample in counter_gecko_stimer This commit adds sample support for the counter_gecko_stimer driver. Signed-off-by: Mateusz Sierszulski --- samples/drivers/counter/alarm/src/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index 8dfa5835969eb..c6ccb4adc5413 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -37,6 +37,10 @@ struct counter_alarm_cfg alarm_cfg; #define TIMER DT_NODELABEL(stm0) #elif defined(CONFIG_COUNTER_TIMER_GD32) #define TIMER DT_NODELABEL(timer0) +#elif defined(CONFIG_COUNTER_GECKO_RTCC) +#define TIMER DT_NODELABEL(rtcc0) +#elif defined(CONFIG_COUNTER_GECKO_STIMER) +#define TIMER DT_NODELABEL(stimer0) #endif static void test_counter_interrupt_fn(const struct device *counter_dev, From 587e897c5cdfd7dc0a66a20ebf05f8e7ae895b63 Mon Sep 17 00:00:00 2001 From: Mateusz Sierszulski Date: Wed, 14 Sep 2022 14:02:12 +0200 Subject: [PATCH 07/17] tests: drivers: counter: counter_basic_api support in counter_gecko_stimer This commit adds test support for the counter_gecko_stimer driver. Signed-off-by: Mateusz Sierszulski --- tests/drivers/counter/counter_basic_api/src/test_counter.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/drivers/counter/counter_basic_api/src/test_counter.c b/tests/drivers/counter/counter_basic_api/src/test_counter.c index 100e934f2711f..3d39f33733e2e 100644 --- a/tests/drivers/counter/counter_basic_api/src/test_counter.c +++ b/tests/drivers/counter/counter_basic_api/src/test_counter.c @@ -83,8 +83,13 @@ static const struct device *const devices[] = { #ifdef CONFIG_COUNTER_MCUX_LPC_RTC DEVS_FOR_DT_COMPAT(nxp_lpc_rtc) #endif +#ifdef CONFIG_COUNTER_GECKO_RTCC DEVS_FOR_DT_COMPAT(silabs_gecko_rtcc) DEVS_FOR_DT_COMPAT(st_stm32_rtc) +#endif +#ifdef CONFIG_COUNTER_GECKO_STIMER + DEVS_FOR_DT_COMPAT(silabs_gecko_stimer) +#endif #ifdef CONFIG_COUNTER_MCUX_PIT DEVS_FOR_DT_COMPAT(nxp_kinetis_pit) #endif From d04e58001971a1c3064b80a6d322a1100f5cb0e9 Mon Sep 17 00:00:00 2001 From: Pawel Czarnecki Date: Wed, 16 Nov 2022 11:33:59 +0100 Subject: [PATCH 08/17] drivers: gpio: gecko: initialize driver earlier Common GPIO driver needs to be initialized before e.g UART driver to ensure correct GPIO clock configuration when configuring UART pinout Signed-off-by: Pawel Czarnecki --- drivers/gpio/gpio_gecko.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio_gecko.c b/drivers/gpio/gpio_gecko.c index 8b3c482d1940a..f046a65fa9f84 100644 --- a/drivers/gpio/gpio_gecko.c +++ b/drivers/gpio/gpio_gecko.c @@ -366,7 +366,7 @@ DEVICE_DT_DEFINE(DT_INST(0, silabs_gecko_gpio), gpio_gecko_common_init, NULL, &gpio_gecko_common_data, &gpio_gecko_common_config, - POST_KERNEL, CONFIG_GPIO_GECKO_COMMON_INIT_PRIORITY, + PRE_KERNEL_1, CONFIG_GPIO_GECKO_COMMON_INIT_PRIORITY, &gpio_gecko_common_driver_api); static int gpio_gecko_common_init(const struct device *dev) From 323a4bd93350a86b34199b2a3d4498e2a9d1afda Mon Sep 17 00:00:00 2001 From: Pawel Czarnecki Date: Wed, 16 Nov 2022 11:38:49 +0100 Subject: [PATCH 09/17] drivers: gpio: gecko: enable GPIO clock Enable GPIO clock so that other drivers could configure their I/O pins Signed-off-by: Pawel Czarnecki --- drivers/gpio/gpio_gecko.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpio/gpio_gecko.c b/drivers/gpio/gpio_gecko.c index f046a65fa9f84..374db635b3482 100644 --- a/drivers/gpio/gpio_gecko.c +++ b/drivers/gpio/gpio_gecko.c @@ -11,6 +11,9 @@ #include #include #include +#ifdef CONFIG_SOC_GECKO_DEV_INIT +#include +#endif #include @@ -371,6 +374,9 @@ DEVICE_DT_DEFINE(DT_INST(0, silabs_gecko_gpio), static int gpio_gecko_common_init(const struct device *dev) { +#ifdef CONFIG_SOC_GECKO_DEV_INIT + CMU_ClockEnable(cmuClock_GPIO, true); +#endif gpio_gecko_common_data.count = 0; IRQ_CONNECT(GPIO_EVEN_IRQn, DT_IRQ_BY_NAME(DT_INST(0, silabs_gecko_gpio), gpio_even, priority), From 59dd2af5be7b01043d0dd360d84eb967ac564667 Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Wed, 7 Sep 2022 11:06:30 +0200 Subject: [PATCH 10/17] soc: silabs_exx32: Add support for SiLabs EFR32BG22 SoC This commit adds support for Silicon Labs EFR32BG22 SoC. Co-authored-by: Mateusz Sierszulski Signed-off-by: Filip Kokosinski --- CODEOWNERS | 1 + dts/arm/silabs/efr32bg22-pinctrl.dtsi | 29 +++ dts/arm/silabs/efr32bg22.dtsi | 170 ++++++++++++++++++ dts/arm/silabs/efr32bg22c224f512im40.dtsi | 23 +++ soc/arm/silabs_exx32/Kconfig | 16 ++ soc/arm/silabs_exx32/common/CMakeLists.txt | 1 + soc/arm/silabs_exx32/common/pinctrl_soc.h | 91 ++++++++++ soc/arm/silabs_exx32/common/soc.c | 63 ++++--- .../efr32bg22/Kconfig.defconfig.efr32bg22 | 16 ++ .../efr32bg22/Kconfig.defconfig.series | 23 +++ soc/arm/silabs_exx32/efr32bg22/Kconfig.series | 22 +++ soc/arm/silabs_exx32/efr32bg22/Kconfig.soc | 8 + soc/arm/silabs_exx32/efr32bg22/linker.ld | 14 ++ soc/arm/silabs_exx32/efr32bg22/soc.h | 22 +++ 14 files changed, 475 insertions(+), 24 deletions(-) create mode 100644 dts/arm/silabs/efr32bg22-pinctrl.dtsi create mode 100644 dts/arm/silabs/efr32bg22.dtsi create mode 100644 dts/arm/silabs/efr32bg22c224f512im40.dtsi create mode 100644 soc/arm/silabs_exx32/common/pinctrl_soc.h create mode 100644 soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.efr32bg22 create mode 100644 soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.series create mode 100644 soc/arm/silabs_exx32/efr32bg22/Kconfig.series create mode 100644 soc/arm/silabs_exx32/efr32bg22/Kconfig.soc create mode 100644 soc/arm/silabs_exx32/efr32bg22/linker.ld create mode 100644 soc/arm/silabs_exx32/efr32bg22/soc.h diff --git a/CODEOWNERS b/CODEOWNERS index c89779dbcbf54..882be5e062766 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -495,6 +495,7 @@ /dts/arm/silabs/efm32_pg_1b.dtsi @rdmeneze /dts/arm/silabs/efm32gg11b* @oanerer /dts/arm/silabs/efr32bg13p* @mnkp +/dts/arm/silabs/efr32bg22* @kgugala @fkokosinski @pczarnecki /dts/arm/silabs/efr32xg13p* @mnkp /dts/arm/silabs/efm32pg1b* @rdmeneze /dts/arm/silabs/efr32mg21* @l-alfred diff --git a/dts/arm/silabs/efr32bg22-pinctrl.dtsi b/dts/arm/silabs/efr32bg22-pinctrl.dtsi new file mode 100644 index 0000000000000..2f2a98b74e751 --- /dev/null +++ b/dts/arm/silabs/efr32bg22-pinctrl.dtsi @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* configuration for uart0 device, default state */ + usart0_default: usart0_default { + group1 { + /* configure PE.11 as UART_RX and PE.10 as UART_TX */ + psels = , + , + ; + }; + }; + + /* configuration for uart1 device, default state */ + usart1_default: usart1_default { + group1 { + /* configure PA.6 as UART_RX and PA.5 as UART_TX */ + psels = , + , + ; + }; + }; +}; diff --git a/dts/arm/silabs/efr32bg22.dtsi b/dts/arm/silabs/efr32bg22.dtsi new file mode 100644 index 0000000000000..a60c82af8f2ce --- /dev/null +++ b/dts/arm/silabs/efr32bg22.dtsi @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +/ { + chosen { + zephyr,flash-controller = &msc; + }; + + power-states { + standby: standby { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <50000>; + }; + }; + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m33"; + reg = <0>; + cpu-power-states = <&standby>; + }; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + }; + + soc { + msc: flash-controller@50030000 { + compatible = "silabs,gecko-flash-controller"; + reg = <0x50030000 0xC69>; + interrupts = <49 0>; + + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + write-block-size = <4>; + erase-block-size = <8192>; + }; + }; + + usart0: usart@5005c000 { + compatible = "silabs,gecko-usart"; + reg = <0x5005C000 0x400>; + interrupts = <13 0>, <14 0>; + interrupt-names = "rx", "tx"; + peripheral-id = <0>; + status = "disabled"; + }; + + usart1: usart@50060000 { + compatible = "silabs,gecko-usart"; + reg = <0x50060000 0x400>; + interrupts = <15 0>, <16 0>; + interrupt-names = "rx", "tx"; + peripheral-id = <1>; + status = "disabled"; + }; + + i2c0: i2c@5a010000 { + compatible = "silabs,gecko-i2c"; + clock-frequency = ; + reg = <0x5a010000 0x3044>; + interrupts = <27 0>; + status = "disabled"; + }; + + i2c1: i2c@50068000 { + compatible = "silabs,gecko-i2c"; + clock-frequency = ; + reg = <0x50068000 0x3044>; + interrupts = <28 0>; + status = "disabled"; + }; + + stimer0: stimer@58000000 { + compatible = "silabs,gecko-stimer"; + reg = <0x58000000 0x3054>; + interrupts = <12 0>; + clock-frequency = <32768>; + prescaler = <1>; + status = "disabled"; + }; + + gpio: gpio@5003c000 { + compatible = "silabs,gecko-gpio"; + reg = <0x5003C000 0x3660>; + interrupts = <10 2 18 2>; + interrupt-names = "GPIO_EVEN", "GPIO_ODD"; + + ranges; + #address-cells = <1>; + #size-cells = <1>; + + gpioa: gpio@5003c000 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C000 0x30>; + peripheral-id = <0>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiob: gpio@5003c030 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C030 0x30>; + peripheral-id = <1>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpioc: gpio@5003c060 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C060 0x30>; + peripheral-id = <2>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiod: gpio@5003c090 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C090 0x30>; + peripheral-id = <3>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpiof: gpio@5003c0c0 { + compatible = "silabs,gecko-gpio-port"; + reg = <0x5003C0C0 0x30>; + peripheral-id = <3>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + }; + }; +}; + +/ { + pinctrl: pin-controller { + /* Pin controller is a "virtual" device since SiLabs SoCs do pin + * control in a distributed way (GPIO registers and PSEL + * registers on each peripheral). + */ + compatible = "silabs,gecko-pinctrl"; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; diff --git a/dts/arm/silabs/efr32bg22c224f512im40.dtsi b/dts/arm/silabs/efr32bg22c224f512im40.dtsi new file mode 100644 index 0000000000000..b9d15de47344c --- /dev/null +++ b/dts/arm/silabs/efr32bg22c224f512im40.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + compatible = "silabs,efr32bg22c224f512im40", "silabs,efr32bg22", + "silabs,efr32", "simple-bus"; + }; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(32)>; +}; + +&flash0 { + reg = <0 DT_SIZE_K(512)>; +}; diff --git a/soc/arm/silabs_exx32/Kconfig b/soc/arm/silabs_exx32/Kconfig index 926308d28eaa8..8fde72bc3a426 100644 --- a/soc/arm/silabs_exx32/Kconfig +++ b/soc/arm/silabs_exx32/Kconfig @@ -134,6 +134,22 @@ choice SOC_GECKO_EMU_DCDC_MODE bool "Bypass" endchoice +config SOC_GECKO_DEV_INIT + bool + help + Use the device initialization routines from the device_init service + in Silicon Labs HAL. These routines initialize and tune HFXOs, + configures DPLLs and manages the Energy Management Unit. + + Disabling these services may negatively impact counter and timer + routines in EXX32 series SoCs. + +config COUNTER_GECKO_STIMER + bool + help + Enable counter driver based on RTCC module for Silicon Labs Gecko + chips. + config SOC_GECKO_CMU bool help diff --git a/soc/arm/silabs_exx32/common/CMakeLists.txt b/soc/arm/silabs_exx32/common/CMakeLists.txt index 5e6a378823800..34e7015db9558 100644 --- a/soc/arm/silabs_exx32/common/CMakeLists.txt +++ b/soc/arm/silabs_exx32/common/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_sources(soc.c) zephyr_sources_ifdef(CONFIG_PM soc_power.c) +zephyr_include_directories(.) diff --git a/soc/arm/silabs_exx32/common/pinctrl_soc.h b/soc/arm/silabs_exx32/common/pinctrl_soc.h new file mode 100644 index 0000000000000..7bbcdeab81ba4 --- /dev/null +++ b/soc/arm/silabs_exx32/common/pinctrl_soc.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022 Silicon Labs + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Silabs SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_ARM_SILABS_GECKO_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_SILABS_GECKO_COMMON_PINCTRL_SOC_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/** Type for gecko pin. */ +typedef uint32_t pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) (DT_PROP_BY_IDX(node_id, prop, idx)), + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + { \ + DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, psels, \ + Z_PINCTRL_STATE_PIN_INIT) \ + } + +/** + * @brief Utility macro to obtain pin function. + * + * @param pincfg Pin configuration bit field. + */ +#define GECKO_GET_FUN(pincfg) (((pincfg) >> GECKO_FUN_POS) & GECKO_FUN_MSK) + +/** + * @brief Utility macro to obtain port configuration. + * + * @param pincfg port configuration bit field. + */ +#define GECKO_GET_PORT(pincfg) (((pincfg) >> GECKO_PORT_POS) & GECKO_PORT_MSK) + +/** + * @brief Utility macro to obtain pin configuration. + * + * @param pincfg pin configuration bit field. + */ +#define GECKO_GET_PIN(pincfg) (((pincfg) >> GECKO_PIN_POS) & GECKO_PIN_MSK) + +/** + * @brief Utility macro to obtain location configuration. + * + * @param pincfg Loc configuration bit field. + */ +#define GECKO_GET_LOC(pincfg) (((pincfg) >> GECKO_LOC_POS) & GECKO_LOC_MSK) + +/** + * @brief Utility macro to obtain speed configuration. + * + * @param pincfg speed configuration bit field. + */ +#define GECKO_GET_SPEED(pincfg) (((pincfg) >> GECKO_SPEED_POS) & GECKO_SPEED_MSK) + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_SILABS_GECKO_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/arm/silabs_exx32/common/soc.c b/soc/arm/silabs_exx32/common/soc.c index c7b4d4c491ff4..7e02a42bcc722 100644 --- a/soc/arm/silabs_exx32/common/soc.c +++ b/soc/arm/silabs_exx32/common/soc.c @@ -9,16 +9,25 @@ * @brief Common SoC initialization for the EXX32 */ -#include +#include +#include #include -#include +#include +#include + +#include #include #include -#include -#include -#include +#include -#include +#ifdef CONFIG_SOC_GECKO_DEV_INIT +#include +#include +#include +#include +#include + +#endif LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); @@ -47,13 +56,13 @@ static ALWAYS_INLINE void clock_init(void) * See AN0016.2 */ if ((DEVINFO->MODULEINFO & DEVINFO_MODULEINFO_HFXOCALVAL) == - DEVINFO_MODULEINFO_HFXOCALVAL_VALID) { - hfxoInit.ctuneXoAna = (DEVINFO->MODXOCAL - & _DEVINFO_MODXOCAL_HFXOCTUNEXOANA_MASK) - >> _DEVINFO_MODXOCAL_HFXOCTUNEXOANA_SHIFT; - hfxoInit.ctuneXiAna = (DEVINFO->MODXOCAL - & _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK) - >> _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_SHIFT; + DEVINFO_MODULEINFO_HFXOCALVAL_VALID) { + hfxoInit.ctuneXoAna = + (DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXOANA_MASK) >> + _DEVINFO_MODXOCAL_HFXOCTUNEXOANA_SHIFT; + hfxoInit.ctuneXiAna = + (DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK) >> + _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_SHIFT; } CMU_HFXOInit(&hfxoInit); @@ -79,10 +88,10 @@ static ALWAYS_INLINE void clock_init(void) * See AN0016.2 */ if ((DEVINFO->MODULEINFO & DEVINFO_MODULEINFO_LFXOCALVAL) == - DEVINFO_MODULEINFO_LFXOCALVAL_VALID) { - lfxoInit.capTune = (DEVINFO->MODXOCAL - & _DEVINFO_MODXOCAL_LFXOCAPTUNE_MASK) - >> _DEVINFO_MODXOCAL_LFXOCAPTUNE_SHIFT; + DEVINFO_MODULEINFO_LFXOCALVAL_VALID) { + lfxoInit.capTune = + (DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_LFXOCAPTUNE_MASK) >> + _DEVINFO_MODXOCAL_LFXOCAPTUNE_SHIFT; } } @@ -115,11 +124,11 @@ static ALWAYS_INLINE void clock_init(void) #endif #if defined(_SILICON_LABS_32B_SERIES_2) - /* Enable the High Frequency Peripheral Clock */ - CMU_ClockEnable(cmuClock_PCLK, true); + /* Enable the High Frequency Peripheral Clock */ + CMU_ClockEnable(cmuClock_PCLK, true); #else - /* Enable the High Frequency Peripheral Clock */ - CMU_ClockEnable(cmuClock_HFPER, true); + /* Enable the High Frequency Peripheral Clock */ + CMU_ClockEnable(cmuClock_HFPER, true); #endif /* _SILICON_LABS_32B_SERIES_2 */ #if defined(CONFIG_GPIO_GECKO) || defined(CONFIG_LOG_BACKEND_SWO) @@ -161,8 +170,7 @@ static void swo_init(void) /* Enable Serial wire output pin */ GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN; /* Set SWO location */ - GPIO->ROUTELOC0 = - SWO_LOCATION << _GPIO_ROUTELOC0_SWVLOC_SHIFT; + GPIO->ROUTELOC0 = SWO_LOCATION << _GPIO_ROUTELOC0_SWVLOC_SHIFT; #else GPIO->ROUTE = GPIO_ROUTE_SWOPEN | (SWO_LOCATION << 8); #endif @@ -192,6 +200,13 @@ static int silabs_exx32_init(const struct device *arg) /* handle chip errata */ CHIP_Init(); +#ifdef CONFIG_SOC_GECKO_DEV_INIT + sl_device_init_dcdc(); + sl_device_init_hfxo(); + sl_device_init_dpll(); + sl_device_init_emu(); +#else + #ifdef CONFIG_SOC_GECKO_EMU_DCDC dcdc_init(); #endif @@ -209,7 +224,7 @@ static int silabs_exx32_init(const struct device *arg) /* Configure SWO debug output */ swo_init(); #endif - +#endif /* restore interrupt state */ irq_unlock(oldLevel); return 0; diff --git a/soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.efr32bg22 b/soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.efr32bg22 new file mode 100644 index 0000000000000..4b9da4d5fa956 --- /dev/null +++ b/soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.efr32bg22 @@ -0,0 +1,16 @@ +# Silicon Labs EFR32BG22 (Blue Gecko) MCU configuration options + +# Copyright (c) 2021 Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_GECKO + default y + +config I2C_GECKO + default n + +config SOC_FLASH_GECKO + default n + +config SPI_GECKO + default n diff --git a/soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.series b/soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.series new file mode 100644 index 0000000000000..0e496c19737ac --- /dev/null +++ b/soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.series @@ -0,0 +1,23 @@ +# Silicon Labs EFR32BG22 (Blue Gecko) MCU configuration options + +# Copyright (c) 2021 Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_EFR32BG22 + +config SOC_SERIES + default "efr32bg22" + +config SOC_PART_NUMBER + default "EFR32BG22C224F512IM40" if SOC_PART_NUMBER_EFR32BG22C224F512IM40 + +config NUM_IRQS + # must be >= the highest interrupt number used + default 60 + +config PM + select COUNTER + +source "soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.efr32bg22" + +endif # SOC_SERIES_EFR32BG22 diff --git a/soc/arm/silabs_exx32/efr32bg22/Kconfig.series b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series new file mode 100644 index 0000000000000..d4c67db65416c --- /dev/null +++ b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series @@ -0,0 +1,22 @@ +# Silicon Labs EFR32BG22 (Blue Gecko) MCU + +# Copyright (c) 2021 Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_EFR32BG22 + bool "EFR32BG22P Series MCU" + select ARM + select ARMV8_M_DSP + select ARM_TRUSTZONE_M + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select HAS_SILABS_GECKO + select HAS_SWO + select SOC_FAMILY_EXX32 + select SOC_GECKO_CMU + select SOC_GECKO_CORE + select SOC_GECKO_DEV_INIT + help + Enable support for EFR32BG22 Blue Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32bg22/Kconfig.soc b/soc/arm/silabs_exx32/efr32bg22/Kconfig.soc new file mode 100644 index 0000000000000..51c8f0b709293 --- /dev/null +++ b/soc/arm/silabs_exx32/efr32bg22/Kconfig.soc @@ -0,0 +1,8 @@ +# Silicon Labs EFR32BG22 (Blue Gecko) MCU series + +# Copyright (c) 2021 Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +config SOC_PART_NUMBER_EFR32BG22C224F512IM40 + bool + depends on SOC_SERIES_EFR32BG22 diff --git a/soc/arm/silabs_exx32/efr32bg22/linker.ld b/soc/arm/silabs_exx32/efr32bg22/linker.ld new file mode 100644 index 0000000000000..9fcfb60618db0 --- /dev/null +++ b/soc/arm/silabs_exx32/efr32bg22/linker.ld @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Linker command/script file + * + * This is the linker script for both standard images. + */ + +#include diff --git a/soc/arm/silabs_exx32/efr32bg22/soc.h b/soc/arm/silabs_exx32/efr32bg22/soc.h new file mode 100644 index 0000000000000..77b5a0012abf8 --- /dev/null +++ b/soc/arm/silabs_exx32/efr32bg22/soc.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Register access macros for the EFR32BG22 SoC + * + */ + +#ifndef EFR32BG22_SOC_H_ +#define EFR32BG22_SOC_H_ + +#ifndef _ASMLANGUAGE + +#include + +#endif /* !_ASMLANGUAGE */ + +#endif /* EFR32BG22_SOC_H_ */ From 852285db1798975fcae1adcf8c2ac297581605db Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Wed, 7 Sep 2022 11:07:50 +0200 Subject: [PATCH 11/17] boards: Add support for Silicon Labs EFR32BG22-SLTB010A board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for Silicon Labs efr32bg22_sltb010a boardo Co-authored-by: Mateusz Sierszulski Co-authored-by: Pawel Czarnecki Signed-off-by: Filip Kokosinski Signed-off-by: Paweł Czarnecki --- boards/arm/efr32bg_sltb010a/CMakeLists.txt | 7 + boards/arm/efr32bg_sltb010a/Kconfig | 12 ++ boards/arm/efr32bg_sltb010a/Kconfig.board | 9 + boards/arm/efr32bg_sltb010a/Kconfig.defconfig | 17 ++ boards/arm/efr32bg_sltb010a/board.c | 64 ++++++ boards/arm/efr32bg_sltb010a/board.cmake | 7 + .../efr32bg_sltb010a/doc/efr32bg_sltb010a.jpg | Bin 0 -> 22284 bytes boards/arm/efr32bg_sltb010a/doc/index.rst | 184 ++++++++++++++++++ .../silabs,gecko-wake-up-triggers.yaml | 15 ++ .../arm/efr32bg_sltb010a/efr32bg_sltb010a.dts | 117 +++++++++++ .../efr32bg_sltb010a/efr32bg_sltb010a.yaml | 18 ++ .../efr32bg_sltb010a_defconfig | 17 ++ .../arm/efr32bg_sltb010a/pre_dt_board.cmake | 5 + .../sl_device_init_hfxo_config.h | 14 ++ 14 files changed, 486 insertions(+) create mode 100644 boards/arm/efr32bg_sltb010a/CMakeLists.txt create mode 100644 boards/arm/efr32bg_sltb010a/Kconfig create mode 100644 boards/arm/efr32bg_sltb010a/Kconfig.board create mode 100644 boards/arm/efr32bg_sltb010a/Kconfig.defconfig create mode 100644 boards/arm/efr32bg_sltb010a/board.c create mode 100644 boards/arm/efr32bg_sltb010a/board.cmake create mode 100644 boards/arm/efr32bg_sltb010a/doc/efr32bg_sltb010a.jpg create mode 100644 boards/arm/efr32bg_sltb010a/doc/index.rst create mode 100644 boards/arm/efr32bg_sltb010a/dts/bindings/silabs,gecko-wake-up-triggers.yaml create mode 100644 boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.dts create mode 100644 boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.yaml create mode 100644 boards/arm/efr32bg_sltb010a/efr32bg_sltb010a_defconfig create mode 100644 boards/arm/efr32bg_sltb010a/pre_dt_board.cmake create mode 100644 boards/arm/efr32bg_sltb010a/sl_device_init_hfxo_config.h diff --git a/boards/arm/efr32bg_sltb010a/CMakeLists.txt b/boards/arm/efr32bg_sltb010a/CMakeLists.txt new file mode 100644 index 0000000000000..ca93e65ac913a --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2021 Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_UART_GECKO) + zephyr_library() + zephyr_library_sources(board.c) +endif() diff --git a/boards/arm/efr32bg_sltb010a/Kconfig b/boards/arm/efr32bg_sltb010a/Kconfig new file mode 100644 index 0000000000000..04050926c1f94 --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/Kconfig @@ -0,0 +1,12 @@ +# EFR32BG SLTB010A board + +# Copyright (c) 2022, Silicon Labs +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EFR32BG_SLTB010A + +module = BOARD_EFR32BG22 +module-str = Board Control +source "subsys/logging/Kconfig.template.log_config" + +endif # BOARD_EFR32BG_SLTB010A diff --git a/boards/arm/efr32bg_sltb010a/Kconfig.board b/boards/arm/efr32bg_sltb010a/Kconfig.board new file mode 100644 index 0000000000000..5f1fb42cdbffd --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/Kconfig.board @@ -0,0 +1,9 @@ +# EFR32BG SLTB010A board + +# Copyright (c) 2021, Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_EFR32BG_SLTB010A + bool "SiLabs EFR32BG-SLTB010A (Thunderboard BG22)" + depends on SOC_SERIES_EFR32BG22 + select SOC_PART_NUMBER_EFR32BG22C224F512IM40 diff --git a/boards/arm/efr32bg_sltb010a/Kconfig.defconfig b/boards/arm/efr32bg_sltb010a/Kconfig.defconfig new file mode 100644 index 0000000000000..6481b8838729d --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/Kconfig.defconfig @@ -0,0 +1,17 @@ +# EFR32BG SLTB010A board + +# Copyright (c) 2021, Sateesh Kotapati +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EFR32BG_SLTB010A + +config BOARD + default "efr32bg_sltb010a" + +config CMU_HFXO_FREQ + default 40000000 + +config CMU_LFXO_FREQ + default 32768 + +endif # BOARD_EFR32BG_SLTB010A diff --git a/boards/arm/efr32bg_sltb010a/board.c b/boards/arm/efr32bg_sltb010a/board.c new file mode 100644 index 0000000000000..9317acbdac3a7 --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/board.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#ifdef CONFIG_SOC_GECKO_DEV_INIT +#include "em_cmu.h" +#endif + +LOG_MODULE_REGISTER(efr32bg_sltb010a, CONFIG_BOARD_EFR32BG22_LOG_LEVEL); + +static int efr32bg_sltb010a_init_clocks(void); + +static int efr32bg_sltb010a_init(const struct device *dev) +{ + int ret; + +#ifdef CONFIG_SOC_GECKO_DEV_INIT + efr32bg_sltb010a_init_clocks(); +#endif + static struct gpio_dt_spec wake_up_gpio_dev = + GPIO_DT_SPEC_GET(DT_NODELABEL(wake_up_trigger), gpios); + + ARG_UNUSED(dev); + + if (!device_is_ready(wake_up_gpio_dev.port)) { + LOG_ERR("Wake-up GPIO device was not found!\n"); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&wake_up_gpio_dev, GPIO_OUTPUT_ACTIVE); + if (ret < 0) + return ret; + + return 0; +} + +#ifdef CONFIG_SOC_GECKO_DEV_INIT +static int efr32bg_sltb010a_init_clocks(void) +{ + CMU_ClockSelectSet(cmuClock_SYSCLK, cmuSelect_HFRCODPLL); +#if defined(_CMU_EM01GRPACLKCTRL_MASK) + CMU_ClockSelectSet(cmuClock_EM01GRPACLK, cmuSelect_HFRCODPLL); +#endif +#if defined(_CMU_EM01GRPBCLKCTRL_MASK) + CMU_ClockSelectSet(cmuClock_EM01GRPBCLK, cmuSelect_HFRCODPLL); +#endif + CMU_ClockSelectSet(cmuClock_EM23GRPACLK, cmuSelect_LFRCO); + CMU_ClockSelectSet(cmuClock_EM4GRPACLK, cmuSelect_LFRCO); +#if defined(RTCC_PRESENT) + CMU_ClockSelectSet(cmuClock_RTCC, cmuSelect_LFRCO); +#endif + CMU_ClockSelectSet(cmuClock_WDOG0, cmuSelect_LFRCO); + + return 0; +} +#endif + +/* needs to be done after GPIO driver init */ +SYS_INIT(efr32bg_sltb010a_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/boards/arm/efr32bg_sltb010a/board.cmake b/boards/arm/efr32bg_sltb010a/board.cmake new file mode 100644 index 0000000000000..8b497b295188b --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2021, Sateesh Kotapati +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(jlink "--device=EFR32BG22C224F512IM40" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/efr32bg_sltb010a/doc/efr32bg_sltb010a.jpg b/boards/arm/efr32bg_sltb010a/doc/efr32bg_sltb010a.jpg new file mode 100644 index 0000000000000000000000000000000000000000..26afd34be0b206ebae65e2d009c9fef0e606ea47 GIT binary patch literal 22284 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 literal 0 HcmV?d00001 diff --git a/boards/arm/efr32bg_sltb010a/doc/index.rst b/boards/arm/efr32bg_sltb010a/doc/index.rst new file mode 100644 index 0000000000000..974eef13ff616 --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/doc/index.rst @@ -0,0 +1,184 @@ +.. _efr32bg_sltb010a: + +EFR32BG-SLTB010A +################ + +Overview +******** + +The EFR32™ Blue Gecko Starter Kit EFR32BG-SLTB010A (a.k.a Thunderboard EFR32BG22) +contains a MCU from the EFR32BG family built on ARM® Cortex®-M33F +processor with low power capabilities. + +.. image:: ./efr32bg_sltb010a.jpg + :align: center + :alt: EFR32BG-SLTB010A + +Hardware +******** + +- EFR32BG22 Blue Gecko Wireless SoC with upto 76.8 MHz operating frequency +- ARM® Cortex® M33 core with 32 kB RAM and 512 kB Flash +- Macronix ultra low power 8-Mbit SPI flash (MX25R8035F) +- 2.4 GHz ceramic antenna for wireless transmission +- Silicon Labs Si7021 relative humidity and temperature sensor +- Silicon Labs Si1133 UV index and ambient light sensor +- Silicon Labs Si7210 hall effect sensor +- TDK InvenSense ICM-20648 6-axis inertial sensor +- One LED and one push button +- Power enable signals and isolation switches for ultra low power operation +- On-board SEGGER J-Link debugger for easy programming and debugging, which + includes a USB virtual COM port and Packet Trace Interface (PTI) +- Mini Simplicity connector for access to energy profiling and advanced wireless + network debugging +- Breakout pads for GPIO access and connection to external hardware +- Reset button +- Automatic switch-over between USB and battery power +- CR2032 coin cell holder and external battery connector + +For more information about the EFR32BG SoC and Thunderboard EFR32BG22 +(EFR32BG-SLTB010A) board: + +- `EFR32BG22 Website`_ +- `EFR32BG22 Datasheet`_ +- `EFR32xG22 Reference Manual`_ +- `EFR32BG22-SLTB010A Website`_ +- `EFR32BG22-SLTB010A User Guide`_ +- `EFR32BG22-SLTB010A Schematics`_ + +Supported Features +================== + +The efr32bg_sltb010a board configuration supports the following hardware features: + ++-----------+------------+-------------------------------------+ +| Interface | Controller | Driver/Component | ++===========+============+=====================================+ +| MPU | on-chip | memory protection unit | ++-----------+------------+-------------------------------------+ +| NVIC | on-chip | nested vector interrupt controller | ++-----------+------------+-------------------------------------+ +| SYSTICK | on-chip | systick | ++-----------+------------+-------------------------------------+ +| COUNTER | on-chip | stimer | ++-----------+------------+-------------------------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+-------------------------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+-------------------------------------+ +| UART | on-chip | serial | ++-----------+------------+-------------------------------------+ +| WATCHDOG | on-chip | watchdog | ++-----------+------------+-------------------------------------+ +| TRNG | on-chip | true random number generator | ++-----------+------------+-------------------------------------+ + +The default configuration can be found in the defconfig file: +``boards/arm/efr32bg_sltb010a/efr32bg_sltb010a_defconfig``. + +Other hardware features are currently not supported by the port. + +Connections and IOs +=================== + +The EFR32BG SoC has six gpio controllers (PORTA, PORTB, PORTC, PORTD, +PORTE and PORTF). + +In the following table, the column Name contains Pin names. For example, PE2 +means Pin number 2 on PORTE and #27 represents the location bitfield , as used +in the board's and microcontroller's datasheets and manuals. + ++------+-------------+-----------------------------------+ +| Name | Function | Usage | ++======+=============+===================================+ +| PB0 | GPIO | LED0 (RED) | ++------+-------------+-----------------------------------+ +| PB1 | GPIO | SW0 Push Button PB0 | ++------+-------------+-----------------------------------+ +| PA5 | UART_TX | UART TX Console VCOM_TX US1_TX #1 | ++------+-------------+-----------------------------------+ +| PA6 | UART_RX | UART RX Console VCOM_RX US1_RX #1 | ++------+-------------+-----------------------------------+ + +System Clock +============ + +The EFR32BG SoC is configured to use the 38.4 MHz external oscillator on the +board. + +Serial Port +=========== + +The EFR32BG22 SoC has two USARTs. +USART1 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +.. note:: + Before using the kit the first time, you should update the J-Link firmware + from `J-Link-Downloads`_ + +Flashing +======== + +The EFR32BG-SLTB010A includes an `J-Link`_ serial and debug adaptor built into the +board. The adaptor provides: + +- A USB connection to the host computer, which exposes a Mass Storage and a + USB Serial Port. +- A Serial Flash device, which implements the USB flash disk file storage. +- A physical UART connection which is relayed over interface USB Serial port. + +Flashing an application to EFR32BG-SLTB010A +------------------------------------------- + +The sample application :ref:`hello_world` is used for this example. +Build the Zephyr kernel and application: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: efr32bg_sltb010a + :goals: build + +Connect the EFR32BG-SLTB010A to your host computer using the USB port and you +should see a USB connection. + +Open a serial terminal (minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and you should be able to see on the corresponding Serial Port +the following message: + +.. code-block:: console + + Hello World! efr32bg_sltb010a + + +.. _EFR32BG22-SLTB010A Website: + https://www.silabs.com/development-tools/thunderboard/thunderboard-bg22-kit + +.. _EFR32BG22-SLTB010A User Guide: + https://www.silabs.com/documents/public/user-guides/ug415-sltb010a-user-guide.pdf + +.. _EFR32BG22-SLTB010A Schematics: + https://www.silabs.com/documents/public/schematic-files/BRD4184A-A01-schematic.pdf + +.. _EFR32BG22 Website: + https://www.silabs.com/wireless/bluetooth/efr32bg22-series-2-socs + +.. _EFR32BG22 Datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32bg22-datasheet.pdf + +.. _EFR32xG22 Reference Manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg22-rm.pdf + +.. _J-Link: + https://www.segger.com/jlink-debug-probes.html + +.. _J-Link-Downloads: + https://www.segger.com/downloads/jlink diff --git a/boards/arm/efr32bg_sltb010a/dts/bindings/silabs,gecko-wake-up-triggers.yaml b/boards/arm/efr32bg_sltb010a/dts/bindings/silabs,gecko-wake-up-triggers.yaml new file mode 100644 index 0000000000000..7a77b3409690b --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/dts/bindings/silabs,gecko-wake-up-triggers.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2022, Antmicro +# SPDX-License-Identifier: Apache-2.0 + +description: GPIO Wake Up Trigger for EFR32BG22 + +compatible: "silabs,gecko-wake-up-trigger" + +include: base.yaml + +properties: + gpios: + type: phandle-array + required: true + description: | + GPIO used as wake up trigger from EM4 sleep diff --git a/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.dts b/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.dts new file mode 100644 index 0000000000000..1ec30d47366cf --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.dts @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 Sateesh Kotapati + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "Silicon Labs EFR32BG SLTB010A (aka Thunderboard BG22)"; + compatible = "silabs,efr32bg_sltb010a", "silabs,efr32bg22"; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + sw0 = &button0; + }; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpiob GECKO_PIN(0) GPIO_ACTIVE_HIGH>; + label = "LED 0"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpiob GECKO_PIN(1) GPIO_ACTIVE_LOW>; + label = "User Push Button 0"; + }; + }; + + wake_up_trigger: gpio-wake-up { + compatible = "silabs,gecko-wake-up-trigger"; + gpios = <&gpioa GECKO_PIN(5) GPIO_ACTIVE_LOW>; + }; + +}; + +&cpu0 { + clock-frequency = <76800000>; +}; + +&usart1 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 32 kB for the bootloader */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0x00008000>; + read-only; + }; + + /* Reserve 220 kB for the application in slot 0 */ + slot0_partition: partition@8000 { + label = "image-0"; + reg = <0x0008000 0x00037000>; + }; + + /* Reserve 220 kB for the application in slot 1 */ + slot1_partition: partition@3f000 { + label = "image-1"; + reg = <0x0003f000 0x00037000>; + }; + + /* Reserve 32 kB for the scratch partition */ + scratch_partition: partition@76000 { + label = "image-scratch"; + reg = <0x00076000 0x00008000>; + }; + + /* Set 8Kb of storage at the end of the 512KB of flash */ + storage_partition: partition@7e000 { + label = "storage"; + reg = <0x0007e000 0x00002000>; + }; + + }; +}; + +&gpio { + location-swo = <0>; + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&stimer0 { + status = "okay"; +}; diff --git a/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.yaml b/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.yaml new file mode 100644 index 0000000000000..9297e70bbd4dd --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a.yaml @@ -0,0 +1,18 @@ +identifier: efr32bg_sltb010a +name: EFR32BG-SLTB010A +type: mcu +arch: arm +ram: 32 +flash: 512 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - counter + - gpio + - uart +testing: + ignore_tags: + - net + - bluetooth diff --git a/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a_defconfig b/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a_defconfig new file mode 100644 index 0000000000000..48e2be44c412e --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/efr32bg_sltb010a_defconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_SOC_SERIES_EFR32BG22=y +CONFIG_BOARD_EFR32BG_SLTB010A=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_CORTEX_M_SYSTICK=y +CONFIG_GPIO=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=76800000 +CONFIG_CMU_HFCLK_HFXO=y +CONFIG_SOC_GECKO_EMU_DCDC=y +CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_CMU_HFCLK_HFRCO=y +CONFIG_PINCTRL=y diff --git a/boards/arm/efr32bg_sltb010a/pre_dt_board.cmake b/boards/arm/efr32bg_sltb010a/pre_dt_board.cmake new file mode 100644 index 0000000000000..beb76b85552d1 --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/pre_dt_board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Linaro Limited +# SPDX-License-Identifier: Apache-2.0 + +# SPI is implemented via usart so node name isn't spi@... +list(APPEND EXTRA_DTC_FLAGS "-Wno-spi_bus_bridge") diff --git a/boards/arm/efr32bg_sltb010a/sl_device_init_hfxo_config.h b/boards/arm/efr32bg_sltb010a/sl_device_init_hfxo_config.h new file mode 100644 index 0000000000000..1b803c74f3d61 --- /dev/null +++ b/boards/arm/efr32bg_sltb010a/sl_device_init_hfxo_config.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2022 Antmicro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SL_DEVICE_INIT_HFXO_CONFIG_H +#define SL_DEVICE_INIT_HFXO_CONFIG_H + +#define SL_DEVICE_INIT_HFXO_MODE cmuHfxoOscMode_Crystal +#define SL_DEVICE_INIT_HFXO_FREQ 38400000 +#define SL_DEVICE_INIT_HFXO_CTUNE 120 + +#endif /* SL_DEVICE_INIT_HFXO_CONFIG_H */ From b1c991d2cb02868eb4e4b56fc5bda1fac1c52826 Mon Sep 17 00:00:00 2001 From: Pawel Czarnecki Date: Tue, 8 Nov 2022 08:34:38 +0100 Subject: [PATCH 12/17] dts: arm: silabs: efr32mg21: update peripheral reg addresses HAL update affects also EFR32MG21 SoC. Because of that we need to update the reg addresses in DTS. Signed-off-by: Pawel Czarnecki --- dts/arm/silabs/efr32mg21.dtsi | 60 +++++++++++----------- dts/arm/silabs/efr32mg21a020f1024im32.dtsi | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/dts/arm/silabs/efr32mg21.dtsi b/dts/arm/silabs/efr32mg21.dtsi index eb49c10a8ee54..369a1f436f222 100644 --- a/dts/arm/silabs/efr32mg21.dtsi +++ b/dts/arm/silabs/efr32mg21.dtsi @@ -41,9 +41,9 @@ }; soc { - msc: flash-controller@40030000 { + msc: flash-controller@50030000 { compatible = "silabs,gecko-flash-controller"; - reg = <0x40030000 0x31a4>; + reg = <0x50030000 0x31a4>; interrupts = <51 0>; #address-cells = <1>; @@ -56,65 +56,65 @@ }; }; - usart0: usart@40058000 { /* USART0 */ + usart0: usart@50058000 { /* USART0 */ compatible = "silabs,gecko-usart"; - reg = <0x40058000 0x400>; + reg = <0x50058000 0x400>; interrupts = <11 0>, <12 0>; interrupt-names = "rx", "tx"; peripheral-id = <0>; status = "disabled"; }; - usart1: usart@4005c000 { /* USART1 */ + usart1: usart@5005c000 { /* USART1 */ compatible = "silabs,gecko-usart"; - reg = <0x4005c000 0x400>; + reg = <0x5005c000 0x400>; interrupts = <13 0>, <14 0>; interrupt-names = "rx", "tx"; peripheral-id = <1>; status = "disabled"; }; - usart2: usart@40060000 { /* USART2 */ + usart2: usart@50060000 { /* USART2 */ compatible = "silabs,gecko-usart"; - reg = <0x40060000 0x400>; + reg = <0x50060000 0x400>; interrupts = <15 0>, <16 0>; interrupt-names = "rx", "tx"; peripheral-id = <2>; status = "disabled"; }; - i2c0: i2c@4a010000 { + i2c0: i2c@5a010000 { compatible = "silabs,gecko-i2c"; clock-frequency = ; #address-cells = <1>; #size-cells = <0>; - reg = <0x4a010000 0x400>; + reg = <0x5a010000 0x400>; interrupts = <27 0>; status = "disabled"; }; - i2c1: i2c@40068000 { + i2c1: i2c@50068000 { compatible = "silabs,gecko-i2c"; clock-frequency = ; #address-cells = <1>; #size-cells = <0>; - reg = <0x40068000 0x400>; + reg = <0x50068000 0x400>; interrupts = <28 0>; status = "disabled"; }; - rtcc0: rtcc@48000000 { + rtcc0: rtcc@58000000 { compatible = "silabs,gecko-rtcc"; - reg = <0x48000000 0x400>; + reg = <0x58000000 0x400>; interrupts = <10 0>; clock-frequency = <32768>; prescaler = <1>; status = "disabled"; }; - gpio: gpio@4003c300 { + gpio: gpio@5003c300 { compatible = "silabs,gecko-gpio"; - reg = <0x4003c300 0x3c00>; + reg = <0x5003c300 0x3c00>; interrupts = <26 2>, <25 2>; interrupt-names = "GPIO_EVEN", "GPIO_ODD"; @@ -122,36 +122,36 @@ #address-cells = <1>; #size-cells = <1>; - gpioa: gpio@4003c000 { + gpioa: gpio@5003c000 { compatible = "silabs,gecko-gpio-port"; - reg = <0x4003c000 0x30>; + reg = <0x5003c000 0x30>; peripheral-id = <0>; gpio-controller; #gpio-cells = <2>; status = "disabled"; }; - gpiob: gpio@4003c030 { + gpiob: gpio@5003c030 { compatible = "silabs,gecko-gpio-port"; - reg = <0x4003c030 0x30>; + reg = <0x5003c030 0x30>; peripheral-id = <1>; gpio-controller; #gpio-cells = <2>; status = "disabled"; }; - gpioc: gpio@4003c060 { + gpioc: gpio@5003c060 { compatible = "silabs,gecko-gpio-port"; - reg = <0x4003c060 0x30>; + reg = <0x5003c060 0x30>; peripheral-id = <2>; gpio-controller; #gpio-cells = <2>; status = "disabled"; }; - gpiod: gpio@4003c090 { + gpiod: gpio@5003c090 { compatible = "silabs,gecko-gpio-port"; - reg = <0x4003c090 0x30>; + reg = <0x5003c090 0x30>; peripheral-id = <3>; gpio-controller; #gpio-cells = <2>; @@ -159,25 +159,25 @@ }; }; - se: semailbox@4c000000 { + se: semailbox@5c000000 { compatible = "silabs,gecko-semailbox"; - reg = <0x4c000000 0x80>; + reg = <0x5c000000 0x80>; interrupts = <0 3>, <1 3>, <2 3>; interrupt-names = "SETAMPERHOST", "SEMBRX", "SEMBTX"; status = "okay"; }; - wdog0: wdog@4a018000 { + wdog0: wdog@5a018000 { compatible = "silabs,gecko-wdog"; - reg = <0x4a018000 0x2C>; + reg = <0x5a018000 0x2C>; peripheral-id = <0>; interrupts = <43 0>; status = "disabled"; }; - wdog1: wdog@4a01c000 { + wdog1: wdog@5a01c000 { compatible = "silabs,gecko-wdog"; - reg = <0x4a01c000 0x2C>; + reg = <0x5a01c000 0x2C>; peripheral-id = <1>; interrupts = <44 0>; status = "disabled"; diff --git a/dts/arm/silabs/efr32mg21a020f1024im32.dtsi b/dts/arm/silabs/efr32mg21a020f1024im32.dtsi index 75dfcc089ecaf..cdee65ff55040 100644 --- a/dts/arm/silabs/efr32mg21a020f1024im32.dtsi +++ b/dts/arm/silabs/efr32mg21a020f1024im32.dtsi @@ -15,7 +15,7 @@ soc { compatible = "silabs,efr32mg21a020f1024im32", "silabs,efr32mg21", "silabs,efr32", "simple-bus"; - flash-controller@40030000 { + flash-controller@50030000 { flash0: flash@0 { reg = <0 DT_SIZE_K(1024)>; }; From e53054da932a598d435f354525c636b77b816714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Czarnecki?= Date: Mon, 26 Sep 2022 07:00:24 +0200 Subject: [PATCH 13/17] drivers: gpio: gecko: stop using deprecated function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit change GPIO_IntConfig to GPIO_ExtIntConfig Signed-off-by: Paweł Czarnecki --- drivers/gpio/gpio_gecko.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio_gecko.c b/drivers/gpio/gpio_gecko.c index 374db635b3482..031cf26c6e406 100644 --- a/drivers/gpio/gpio_gecko.c +++ b/drivers/gpio/gpio_gecko.c @@ -294,7 +294,7 @@ static int gpio_gecko_pin_interrupt_configure(const struct device *dev, falling_edge = false; } /* default is GPIO_INT_TRIG_BOTH */ - GPIO_IntConfig(config->gpio_index, pin, + GPIO_ExtIntConfig(config->gpio_index, pin, pin, rising_edge, falling_edge, true); } From 55f522949d231ca2fdd032163112c4d5f53f305a Mon Sep 17 00:00:00 2001 From: Mateusz Sierszulski Date: Wed, 14 Sep 2022 09:13:22 +0200 Subject: [PATCH 14/17] drivers: hwinfo: Fix Gecko hwinfo driver building do not build hwinfo driver for this board - it does not have support for it Signed-off-by: Mateusz Sierszulski --- drivers/hwinfo/Kconfig | 2 +- drivers/hwinfo/hwinfo_gecko.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 42a3a2b7936fa..afe80944c329e 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -139,7 +139,7 @@ config HWINFO_PSOC6 config HWINFO_GECKO bool "GECKO hwinfo" default y - depends on SOC_FAMILY_EXX32 && !SOC_SERIES_EFR32MG21 + depends on SOC_FAMILY_EXX32 && !SOC_SERIES_EFR32MG21 && !SOC_SERIES_EFR32BG22 select SOC_GECKO_RMU help Enable Silabs GECKO hwinfo driver. diff --git a/drivers/hwinfo/hwinfo_gecko.c b/drivers/hwinfo/hwinfo_gecko.c index f12d57da1b2f4..42f0a1071ca20 100644 --- a/drivers/hwinfo/hwinfo_gecko.c +++ b/drivers/hwinfo/hwinfo_gecko.c @@ -37,25 +37,35 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) uint32_t flags = 0; uint32_t rmu_flags = RMU_ResetCauseGet(); +#ifdef RMU_RSTCAUSE_PORST if (rmu_flags & RMU_RSTCAUSE_PORST) { flags |= RESET_POR; } +#endif /* RMU_RSTCAUSE_PORST */ +#ifdef RMU_RSTCAUSE_EXTRST if (rmu_flags & RMU_RSTCAUSE_EXTRST) { flags |= RESET_PIN; } +#endif /* RMU_RSTCAUSE_EXTRST */ +#ifdef RMU_RSTCAUSE_SYSREQRST if (rmu_flags & RMU_RSTCAUSE_SYSREQRST) { flags |= RESET_SOFTWARE; } +#endif /* RMU_RSTCAUSE_SYSREQRST */ +#ifdef RMU_RSTCAUSE_LOCKUPRST if (rmu_flags & RMU_RSTCAUSE_LOCKUPRST) { flags |= RESET_CPU_LOCKUP; } +#endif /* RMU_RSTCAUSE_LOCKUPRST */ +#ifdef RMU_RSTCAUSE_WDOGRST if (rmu_flags & RMU_RSTCAUSE_WDOGRST) { flags |= RESET_WATCHDOG; } +#endif /* RMU_RSTCAUSE_WDOGRST */ #ifdef RMU_RSTCAUSE_EM4WURST if (rmu_flags & RMU_RSTCAUSE_EM4WURST) { From bfb9cd2bc7c1c8c49e2438ece5c609616ac7456f Mon Sep 17 00:00:00 2001 From: Pawel Czarnecki Date: Wed, 12 Oct 2022 12:05:10 +0200 Subject: [PATCH 15/17] drivers: watchdog: silabs: include zephyr/irq.h Add missing include Signed-off-by: Pawel Czarnecki --- drivers/watchdog/wdt_gecko.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/wdt_gecko.c b/drivers/watchdog/wdt_gecko.c index 02523dfeee2e7..52b6d36a650a0 100644 --- a/drivers/watchdog/wdt_gecko.c +++ b/drivers/watchdog/wdt_gecko.c @@ -9,6 +9,7 @@ #include #include +#include #include #include From ad93178a53ce8df3090906997a2b3c03a5e7e662 Mon Sep 17 00:00:00 2001 From: Pawel Czarnecki Date: Fri, 28 Oct 2022 10:50:28 +0200 Subject: [PATCH 16/17] dts: gpio: silabs: make peripheral-id optional peripheral-id property should be eventually removed entirely. For now set it as optional and allow skipping the usage in GPIO driver. Signed-off-by: Pawel Czarnecki --- drivers/gpio/gpio_gecko.c | 17 ++++++++++++++++- dts/arm/silabs/efr32bg22.dtsi | 5 ----- dts/bindings/gpio/silabs,gecko-gpio-port.yaml | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio_gecko.c b/drivers/gpio/gpio_gecko.c index 031cf26c6e406..906a09f211a28 100644 --- a/drivers/gpio/gpio_gecko.c +++ b/drivers/gpio/gpio_gecko.c @@ -22,6 +22,21 @@ CONFIG_GPIO_INIT_PRIORITY. #endif +#if DT_NODE_HAS_PROP(id, peripheral_id) +#define GET_GECKO_GPIO_INDEX(id) DT_INST_PROP(id, peripheral_id) +#else +#if defined(CONFIG_SOC_SERIES_EFR32BG22) || defined(CONFIG_SOC_SERIES_EFR32MG21) +#define GECKO_GPIO_PORT_ADDR_SPACE_SIZE sizeof(GPIO_PORT_TypeDef) +#else +#define GECKO_GPIO_PORT_ADDR_SPACE_SIZE sizeof(GPIO_P_TypeDef) +#endif /* defined(CONFIG_SOC_SERIES_EFM32HG) || defined(CONFIG_SOC_SERIES_EFM32WG) */ +/* Assumption for calculating gpio index: + * 1. Address space of the first GPIO port is the address space for GPIO port A + */ +#define GET_GECKO_GPIO_INDEX(id) (DT_INST_REG_ADDR(id) - DT_REG_ADDR(DT_NODELABEL(gpioa))) \ + / GECKO_GPIO_PORT_ADDR_SPACE_SIZE +#endif /* DT_NODE_HAS_PROP(id, peripheral_id) */ + /* * Macros to set the GPIO MODE registers * @@ -401,7 +416,7 @@ static const struct gpio_gecko_config gpio_gecko_port##idx##_config = { \ .common = { \ .port_pin_mask = (gpio_port_pins_t)(-1), \ }, \ - .gpio_index = DT_INST_PROP(idx, peripheral_id), \ + .gpio_index = GET_GECKO_GPIO_INDEX(idx), \ }; \ \ static struct gpio_gecko_data gpio_gecko_port##idx##_data; \ diff --git a/dts/arm/silabs/efr32bg22.dtsi b/dts/arm/silabs/efr32bg22.dtsi index a60c82af8f2ce..2e194e5967792 100644 --- a/dts/arm/silabs/efr32bg22.dtsi +++ b/dts/arm/silabs/efr32bg22.dtsi @@ -109,7 +109,6 @@ gpioa: gpio@5003c000 { compatible = "silabs,gecko-gpio-port"; reg = <0x5003C000 0x30>; - peripheral-id = <0>; gpio-controller; #gpio-cells = <2>; status = "disabled"; @@ -118,7 +117,6 @@ gpiob: gpio@5003c030 { compatible = "silabs,gecko-gpio-port"; reg = <0x5003C030 0x30>; - peripheral-id = <1>; gpio-controller; #gpio-cells = <2>; status = "disabled"; @@ -127,7 +125,6 @@ gpioc: gpio@5003c060 { compatible = "silabs,gecko-gpio-port"; reg = <0x5003C060 0x30>; - peripheral-id = <2>; gpio-controller; #gpio-cells = <2>; status = "disabled"; @@ -136,7 +133,6 @@ gpiod: gpio@5003c090 { compatible = "silabs,gecko-gpio-port"; reg = <0x5003C090 0x30>; - peripheral-id = <3>; gpio-controller; #gpio-cells = <2>; status = "disabled"; @@ -145,7 +141,6 @@ gpiof: gpio@5003c0c0 { compatible = "silabs,gecko-gpio-port"; reg = <0x5003C0C0 0x30>; - peripheral-id = <3>; gpio-controller; #gpio-cells = <2>; status = "disabled"; diff --git a/dts/bindings/gpio/silabs,gecko-gpio-port.yaml b/dts/bindings/gpio/silabs,gecko-gpio-port.yaml index 55cc4118aaf7b..21e4ad49d0fed 100644 --- a/dts/bindings/gpio/silabs,gecko-gpio-port.yaml +++ b/dts/bindings/gpio/silabs,gecko-gpio-port.yaml @@ -10,7 +10,7 @@ properties: peripheral-id: type: int - required: true + required: false description: peripheral ID "#gpio-cells": From 35e2e85c3bf5311ab347d7ada916c398b193c108 Mon Sep 17 00:00:00 2001 From: Pawel Czarnecki Date: Mon, 31 Oct 2022 09:43:19 +0100 Subject: [PATCH 17/17] dts: uart: silabs: make peripheral-id optional peripheral-id property should be eventually removed. For now set it as optional and allow skipping the usage in UART driver. Signed-off-by: Pawel Czarnecki --- drivers/serial/uart_gecko.c | 50 +++++++++++++++++++-- dts/arm/silabs/efr32bg22.dtsi | 2 - dts/bindings/serial/silabs,gecko-usart.yaml | 2 +- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/serial/uart_gecko.c b/drivers/serial/uart_gecko.c index aa93433af8561..2f0e077077d13 100644 --- a/drivers/serial/uart_gecko.c +++ b/drivers/serial/uart_gecko.c @@ -18,10 +18,54 @@ #include #endif /* CONFIG_PINCTRL */ +#if DT_NODE_HAS_PROP(id, peripheral_id) #define USART_PREFIX cmuClock_USART #define UART_PREFIX cmuClock_UART #define CLOCK_USART(id) _CONCAT(USART_PREFIX, id) #define CLOCK_UART(id) _CONCAT(UART_PREFIX, id) +#define GET_GECKO_USART_CLOCK(id) CLOCK_USART(DT_INST_PROP(id, peripheral_id)) +#define GET_GECKO_UART_CLOCK(id) CLOCK_UART(DT_INST_PROP(id, peripheral_id)) +#else +#if (USART_COUNT <= 2) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : -1) +#elif (USART_COUNT == 3) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : -1) +#elif (USART_COUNT == 4) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : ((ref) == USART3) ? cmuClock_USART3 \ + : -1) +#elif (USART_COUNT == 5) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : ((ref) == USART3) ? cmuClock_USART3 \ + : ((ref) == USART4) ? cmuClock_USART4 \ + : -1) +#elif (USART_COUNT == 6) +#define CLOCK_USART(ref) (((ref) == USART0) ? cmuClock_USART0 \ + : ((ref) == USART1) ? cmuClock_USART1 \ + : ((ref) == USART2) ? cmuClock_USART2 \ + : ((ref) == USART3) ? cmuClock_USART3 \ + : ((ref) == USART4) ? cmuClock_USART4 \ + : ((ref) == USART5) ? cmuClock_USART5 \ + : -1) +#else +#error "Undefined number of USARTs." +#endif /* USART_COUNT */ + +#define CLOCK_UART(ref) (((ref) == UART0) ? cmuClock_UART0 \ + : ((ref) == UART1) ? cmuClock_UART1 \ + : -1) +#define GET_GECKO_USART_CLOCK(id) CLOCK_USART((USART_TypeDef *)DT_INST_REG_ADDR(id)) +#define GET_GECKO_UART_CLOCK(id) CLOCK_UART((USART_TypeDef *)DT_INST_REG_ADDR(id)) +#endif /* DT_NODE_HAS_PROP(id, peripheral_id) */ /* Helper define to determine if SOC supports hardware flow control */ #if ((_SILICON_LABS_32B_SERIES > 0) || \ @@ -566,7 +610,7 @@ static const struct uart_driver_api uart_gecko_driver_api = { \ static const struct uart_gecko_config uart_gecko_cfg_##idx = { \ .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ - .clock = CLOCK_UART(DT_INST_PROP(idx, peripheral_id)), \ + .clock = GET_GECKO_UART_CLOCK(idx), \ .baud_rate = DT_INST_PROP(idx, current_speed), \ GECKO_UART_HW_FLOW_CONTROL(idx) \ GECKO_UART_RX_TX_PINS(idx) \ @@ -624,7 +668,7 @@ DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT) static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ - .clock = CLOCK_USART(DT_INST_PROP(idx, peripheral_id)), \ + .clock = GET_GECKO_USART_CLOCK(idx), \ .baud_rate = DT_INST_PROP(idx, current_speed), \ GECKO_USART_IRQ_HANDLER_FUNC(idx) \ }; \ @@ -647,7 +691,7 @@ DT_INST_FOREACH_STATUS_OKAY(GECKO_UART_INIT) \ static const struct uart_gecko_config usart_gecko_cfg_##idx = { \ .base = (USART_TypeDef *)DT_INST_REG_ADDR(idx), \ - .clock = CLOCK_USART(DT_INST_PROP(idx, peripheral_id)), \ + .clock = GET_GECKO_USART_CLOCK(idx), \ .baud_rate = DT_INST_PROP(idx, current_speed), \ GECKO_UART_HW_FLOW_CONTROL(idx) \ GECKO_UART_RX_TX_PINS(idx) \ diff --git a/dts/arm/silabs/efr32bg22.dtsi b/dts/arm/silabs/efr32bg22.dtsi index 2e194e5967792..93dccd5ec2a14 100644 --- a/dts/arm/silabs/efr32bg22.dtsi +++ b/dts/arm/silabs/efr32bg22.dtsi @@ -58,7 +58,6 @@ reg = <0x5005C000 0x400>; interrupts = <13 0>, <14 0>; interrupt-names = "rx", "tx"; - peripheral-id = <0>; status = "disabled"; }; @@ -67,7 +66,6 @@ reg = <0x50060000 0x400>; interrupts = <15 0>, <16 0>; interrupt-names = "rx", "tx"; - peripheral-id = <1>; status = "disabled"; }; diff --git a/dts/bindings/serial/silabs,gecko-usart.yaml b/dts/bindings/serial/silabs,gecko-usart.yaml index ac3003b0c2cf4..4f08ab88c19bc 100644 --- a/dts/bindings/serial/silabs,gecko-usart.yaml +++ b/dts/bindings/serial/silabs,gecko-usart.yaml @@ -13,7 +13,7 @@ properties: peripheral-id: type: int - required: true + required: false description: peripheral ID # Note: Not all SoC series support setting individual pin location. If this