From 352d9424ffbb0d39e69f6d85578409ddb0b30f06 Mon Sep 17 00:00:00 2001 From: Endre Karlson Date: Fri, 9 Nov 2018 09:08:12 +0100 Subject: [PATCH 01/11] boards: efr32mg_sltb004a: Fix device name typos Chose the wrong device name here. Signed-off-by: Endre Karlson --- boards/arm/efr32mg_sltb004a/board.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/efr32mg_sltb004a/board.cmake b/boards/arm/efr32mg_sltb004a/board.cmake index b5ec3e8a69070..94e24e1ee3175 100644 --- a/boards/arm/efr32mg_sltb004a/board.cmake +++ b/boards/arm/efr32mg_sltb004a/board.cmake @@ -2,5 +2,5 @@ # # SPDX-License-Identifier: Apache-2.0 # -board_runner_args(jlink "--device=EFM32MG12BxxxF1024") +board_runner_args(jlink "--device=EFR32MG12PxxxF1024") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) From 13e450f6de30f45cad56848f822e76789d569a3b Mon Sep 17 00:00:00 2001 From: Endre Karlson Date: Thu, 8 Nov 2018 13:48:12 +0100 Subject: [PATCH 02/11] arm: silabs: Enable DCDC before setting up clk This enables DCDC for Silabs devices before initializing the clock. Signed-off-by: Endre Karlson --- .../efr32mg_sltb004a_defconfig | 2 ++ ext/hal/silabs/gecko/CMakeLists.txt | 2 +- soc/arm/silabs_exx32/Kconfig | 30 +++++++++++++++++-- soc/arm/silabs_exx32/common/soc.c | 28 +++++++++++++++++ soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc | 2 +- 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a_defconfig b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a_defconfig index 8829b67a917be..70d2564427ce0 100644 --- a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a_defconfig +++ b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a_defconfig @@ -11,3 +11,5 @@ CONFIG_CORTEX_M_SYSTICK=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=38400000 CONFIG_CMU_HFCLK_HFRCO=y +CONFIG_SOC_GECKO_EMU_DCDC=y +CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON=y diff --git a/ext/hal/silabs/gecko/CMakeLists.txt b/ext/hal/silabs/gecko/CMakeLists.txt index a95085d1457b1..e494d35ee25ea 100644 --- a/ext/hal/silabs/gecko/CMakeLists.txt +++ b/ext/hal/silabs/gecko/CMakeLists.txt @@ -24,7 +24,7 @@ zephyr_compile_definitions( zephyr_sources( emlib/src/em_system.c) zephyr_sources_ifdef(CONFIG_HAS_CMU emlib/src/em_cmu.c) -zephyr_sources_ifdef(CONFIG_HAS_EMU emlib/src/em_emu.c) +zephyr_sources_ifdef(CONFIG_SOC_GECKO_EMU emlib/src/em_emu.c) zephyr_sources_ifdef(CONFIG_GPIO_GECKO emlib/src/em_gpio.c) zephyr_sources_ifdef(CONFIG_UART_GECKO emlib/src/em_usart.c) zephyr_sources_ifdef(CONFIG_LEUART_GECKO emlib/src/em_leuart.c) diff --git a/soc/arm/silabs_exx32/Kconfig b/soc/arm/silabs_exx32/Kconfig index 746458687407d..60e8d25d8ee34 100644 --- a/soc/arm/silabs_exx32/Kconfig +++ b/soc/arm/silabs_exx32/Kconfig @@ -29,10 +29,36 @@ config SOC_PART_NUMBER that you should not set directly. The part number selection choice defines the default value for this string. -config HAS_EMU +config SOC_GECKO_EMU_DCDC + bool "Enable SoC DC/DC regulator" + select SOC_GECKO_EMU + help + Enable the on chip DC/DC regulator + + +choice SOC_GECKO_DCDC_MODE + prompt "DC/DC mode" + depends on SOC_GECKO_EMU_DCDC + help + Select power configuration mode of the on chip DC/DC converter. + + config SOC_GECKO_EMU_DCDC_MODE_UNCONFIGURED + bool "Initial / Uconfigured" + + config SOC_GECKO_EMU_DCDC_MODE_ON + bool "DC/DC On" + + config SOC_GECKO_EMU_DCDC_MODE_OFF + bool "DC/DC Off" + + config SOC_GECKO_EMU_DCDC_MODE_BYPASS + bool "Bypass" +endchoice + +config SOC_GECKO_EMU bool help - Set if the energy management unit (EMU) is present in the SoC. + Set if the energy management unit (EMU) is used. config HAS_CMU bool diff --git a/soc/arm/silabs_exx32/common/soc.c b/soc/arm/silabs_exx32/common/soc.c index f74caa5a40b4a..22aa34d6212c0 100644 --- a/soc/arm/silabs_exx32/common/soc.c +++ b/soc/arm/silabs_exx32/common/soc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,25 @@ static ALWAYS_INLINE void clkInit(void) #endif } +#ifdef CONFIG_SOC_GECKO_EMU_DCDC +static ALWAYS_INLINE void dcdc_init(void) +{ +#if defined(CONFIG_SOC_GECKO_EMU_DCDC_MODE_UNCONFIGURED) + /* Nothing to do, leave DC/DC converter in unconfigured, safe state. */ +#elif defined(CONFIG_SOC_GECKO_EMU_DCDC_MODE_ON) || defined(CONFIG_SOC_GECKO_EMU_DCDC_MODE_BYPASS) + EMU_DCDCInit_TypeDef init_cfg = EMU_DCDCINIT_DEFAULT; +#if defined(CONFIG_SOC_GECKO_EMU_DCDC_MODE_BYPASS) + init_cfg.dcdcMode = emuDcdcMode_Bypass; +#endif + EMU_DCDCInit(&init_cfg); +#elif defined(CONFIG_SOC_GECKO_EMU_DCDC_MODE_OFF) + EMU_DCDCPowerOff(); +#else +#error "Unsupported power configuration mode of the on chip DC/DC converter." +#endif +} +#endif + /** * @brief Perform basic hardware initialization * @@ -92,6 +112,14 @@ static int silabs_exx32_init(struct device *arg) _ClearFaults(); +#ifdef CONFIG_SOC_GECKO_EMU_DCDC + /* + * Initialize DCDC before attempting to set clock, HFXO for example + * requires this + */ + dcdc_init(); +#endif + /* Initialize system clock according to CONFIG_CMU settings */ clkInit(); diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc index 731092b163b96..24cea0b1878e7 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.soc @@ -13,7 +13,7 @@ config SOC_EFR32MG12P bool "SOC_EFR32MG12P" select HAS_SILABS_GECKO select HAS_CMU - select HAS_EMU + select SOC_GECKO_EMU endchoice From 8712f586850c81bff2189ef5cd07159573dda3b2 Mon Sep 17 00:00:00 2001 From: Endre Karlson Date: Sun, 4 Nov 2018 01:08:19 +0100 Subject: [PATCH 03/11] Add flash page support for OT * Set flash page size * Set erase block size on efr32mg * Enable flash page support --- drivers/flash/Kconfig.gecko | 1 + dts/arm/silabs/efr32mg.dtsi | 1 + soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/drivers/flash/Kconfig.gecko b/drivers/flash/Kconfig.gecko index 626bbe1271b2a..10a80b932ea64 100644 --- a/drivers/flash/Kconfig.gecko +++ b/drivers/flash/Kconfig.gecko @@ -8,6 +8,7 @@ config SOC_FLASH_GECKO bool "Silicon Labs Gecko flash driver" depends on FLASH && SOC_FAMILY_EXX32 select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_EFR32MG12P help Enable Silicon Labs Gecko series internal flash driver. diff --git a/dts/arm/silabs/efr32mg.dtsi b/dts/arm/silabs/efr32mg.dtsi index 02afec7b4d833..58ae96b27332e 100644 --- a/dts/arm/silabs/efr32mg.dtsi +++ b/dts/arm/silabs/efr32mg.dtsi @@ -32,6 +32,7 @@ compatible = "soc-nv-flash"; label = "FLASH_0"; write-block-size = <4>; + erase-block-size = <4096>; }; }; diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p index 7d96eeb764dc4..ca84eaefc298c 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p @@ -44,6 +44,11 @@ if FLASH config SOC_FLASH_GECKO default y +config FLASH_PAGE_SIZE + hex + default 0x800 + + endif # FLASH endif # SOC_EFR32MG12P From f3604cb24e39c45dd7df08fe00001bb7b82ef5bc Mon Sep 17 00:00:00 2001 From: Endre Karlson Date: Mon, 5 Nov 2018 13:25:48 +0100 Subject: [PATCH 04/11] OpenThread support needs this to be set --- .../efr32mg12p/Kconfig.defconfig.efr32mg12p | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p index ca84eaefc298c..23deda4d1d671 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p @@ -51,4 +51,19 @@ config FLASH_PAGE_SIZE endif # FLASH +if NETWORKING + +if !NET_L2_OPENTHREAD +config NET_L2_IEEE802154 + def_bool y +endif # NET_L2_OPENTHREAD + +config IEEE802154_EFR + def_bool y + +config NET_CONFIG_IEEE802154_DEV_NAME + default IEEE802154_EFR_DRV_NAME + +endif # NETWORKING + endif # SOC_EFR32MG12P From 73dea66ebe16bc5267e3463be6cce23eadd38e78 Mon Sep 17 00:00:00 2001 From: Endre Karlson Date: Wed, 7 Nov 2018 14:31:06 +0100 Subject: [PATCH 05/11] Add Silabs EFR32 802.15.4 driver --- drivers/ieee802154/CMakeLists.txt | 2 + drivers/ieee802154/Kconfig | 2 + drivers/ieee802154/Kconfig.efr32 | 43 ++ drivers/ieee802154/ieee802154_efr32.c | 572 ++++++++++++++++++++++++++ ext/hal/silabs/CMakeLists.txt | 2 +- ext/lib/CMakeLists.txt | 1 + ext/lib/radio/.gitignore | 1 + ext/lib/radio/CMakeLists.txt | 12 + 8 files changed, 634 insertions(+), 1 deletion(-) create mode 100644 drivers/ieee802154/Kconfig.efr32 create mode 100644 drivers/ieee802154/ieee802154_efr32.c create mode 100644 ext/lib/radio/.gitignore create mode 100644 ext/lib/radio/CMakeLists.txt diff --git a/drivers/ieee802154/CMakeLists.txt b/drivers/ieee802154/CMakeLists.txt index ffe199c40a082..374be23450189 100644 --- a/drivers/ieee802154/CMakeLists.txt +++ b/drivers/ieee802154/CMakeLists.txt @@ -4,6 +4,8 @@ zephyr_sources_ifdef(CONFIG_IEEE802154_UPIPE ieee802154_uart_pipe.c) zephyr_sources_ifdef(CONFIG_IEEE802154_MCR20A ieee802154_mcr20a.c) zephyr_sources_ifdef(CONFIG_IEEE802154_NRF5 ieee802154_nrf5.c) zephyr_sources_ifdef(CONFIG_IEEE802154_CC1200 ieee802154_cc1200.c) +zephyr_sources_ifdef(CONFIG_IEEE802154_EFR32 ieee802154_efr32.c) + if(CONFIG_NET_L2_OPENTHREAD) # This driver calls DEVICE_INIT with the context of openthread. The diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index 009b62aefb406..bac82d3dba812 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -34,6 +34,8 @@ source "drivers/ieee802154/Kconfig.nrf5" source "drivers/ieee802154/Kconfig.cc1200" +source "drivers/ieee802154/Kconfig.efr32" + menuconfig IEEE802154_UPIPE bool "UART PIPE fake radio driver support for QEMU" depends on (BOARD_QEMU_X86 || BOARD_QEMU_CORTEX_M3) && NETWORKING diff --git a/drivers/ieee802154/Kconfig.efr32 b/drivers/ieee802154/Kconfig.efr32 new file mode 100644 index 0000000000000..ca3c05ef567d2 --- /dev/null +++ b/drivers/ieee802154/Kconfig.efr32 @@ -0,0 +1,43 @@ +# Kconfig.efr32 - EFR32 Options +# +# +# Copyright (c) 2018 Evry ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +menuconfig IEEE802154_EFR32 + bool "Silabs EFR32 Driver support" + depends on NETWORKING + select NEWLIB_LIBC + select HAS_SILABS_RAIL + +config HAS_SILABS_RAIL + bool "Enable Silabs RAIL SDK" + default n + depends on IEEE802154_EFR32 + +if IEEE802154_EFR32 + +config IEEE802154_EFR32_DRV_NAME + string "Silabs EFR32 Driver's name" + default "EFR32" + help + This option sets the driver name. Do not change it unless + you know what you are doing. + +config IEEE802154_EFR32_RX_STACK_SIZE + int "Driver's internal RX thread stack size" + default 6400 + help + This option sets the driver's stack size for its internal RX thread. + The default value should be sufficient, but in case it proves to be + a too little one, this option makes it easy to play with the size. + +config IEEE802154_EFR32_INIT_PRIO + int "EFR32 initialization priority" + default 80 + help + Set the initialization priority number. + +endif diff --git a/drivers/ieee802154/ieee802154_efr32.c b/drivers/ieee802154/ieee802154_efr32.c new file mode 100644 index 0000000000000..7b34ad9dbd663 --- /dev/null +++ b/drivers/ieee802154/ieee802154_efr32.c @@ -0,0 +1,572 @@ +/* ieee802154_efr32.c - Silabs EFR32 driver */ + +/* + * Copyright (c) 2018 Evry ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define LOG_MODULE_NAME ieee802154_efr32 +#define LOG_LEVEL CONFIG_IEEE802154_LOG_LEVEL + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rail_types.h" +#include "em_core.h" +#include "em_system.h" + +#include "rail.h" +#include "rail_ieee802154.h" +#include "pa_conversions_efr32.h" + +#if defined(CONFIG_NET_L2_OPENTHREAD) +#include +#endif + +#define RADIO_CONFIG_XTAL_FREQUENCY 38400000UL + +RAIL_DECLARE_TX_POWER_VBAT_CURVES(piecewiseSegments, curvesSg, curves24Hp, curves24Lp); + +#define ACK_TIMEOUT K_MSEC(10) + +enum EfrState +{ + EFR32_STATE_RX, + EFR32_STATE_TX, + EFR32_STATE_DISABLED, + EFR32_STATE_CCA, + EFR32_STATE_SLEEP, +}; + +static enum EfrState efr_state; + +enum +{ + IEEE802154_MAX_LENGTH = 127, + EFR32_FCS_LENGTH = 2, +}; + +struct efr32_context +{ + struct net_if *iface; + u8_t mac_addr[8]; + + u8_t rx_buf[IEEE802154_MAX_LENGTH]; + u8_t tx_buf[IEEE802154_MAX_LENGTH]; + + K_THREAD_STACK_MEMBER(rx_stack, + CONFIG_IEEE802154_EFR32_RX_STACK_SIZE); + struct k_thread rx_thread; + + /* CCA complete sempahore. Unlocked when CCA is complete. */ + struct k_sem cca_wait; + /* RX synchronization semaphore. Unlocked when frame has been + * received. + */ + struct k_sem rx_wait; + /* TX synchronization semaphore. Unlocked when frame has been + * sent or CCA failed. + */ + struct k_sem tx_wait; + + /* TX result. Set to 1 on success, 0 otherwise. */ + bool tx_success; + + u8_t channel; + + RAIL_Handle_t rail_handle; +}; + +static struct efr32_context efr32_data; + +static const RAIL_CsmaConfig_t rail_csma_config = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA; + +const RAIL_IEEE802154_Config_t rail_ieee802154_config = { + .addresses = NULL, + .ackConfig = { + .enable = true, + .ackTimeout = 894, + .rxTransitions = { + RAIL_RF_STATE_RX, + RAIL_RF_STATE_RX, + }, + .txTransitions = { + RAIL_RF_STATE_RX, + RAIL_RF_STATE_RX, + }}, + .timings = { + .idleToRx = 100, + .idleToRx = 192 - 10, + .idleToTx = 100, + .rxToTx = 192, + .rxSearchTimeout = 0, + .txToRxSearchTimeout = 0, + }, + .framesMask = RAIL_IEEE802154_ACCEPT_STANDARD_FRAMES, + .promiscuousMode = false, + .isPanCoordinator = false, +}; + +CORE_irqState_t CORE_EnterCritical(void) +{ + LOG_DBG("Enter crit"); + return irq_lock(); +} + +void CORE_ExitCritical(CORE_irqState_t irqState) +{ + (void)irqState; + + LOG_DBG("Exit crit"); + + irq_unlock(irqState); +} + +CORE_irqState_t CORE_EnterAtomic(void) +{ + LOG_DBG("Enter atomic"); + return irq_lock(); +} + +void CORE_ExitAtomic(CORE_irqState_t irqState) +{ + (void)irqState; + + LOG_DBG("Exit atomic"); + + irq_unlock(irqState); +} + +static void efr32_rail_cb(RAIL_Handle_t rail_handle, RAIL_Events_t a_events); + +static RAIL_Config_t s_rail_config = { + .eventsCallback = &efr32_rail_cb, + .protocol = NULL, + .scheduler = NULL, +}; + +static inline u8_t *get_mac(struct device *dev) +{ + uint64_t uniqueID = SYSTEM_GetUnique(); + uint8_t *mac = (uint8_t *)&uniqueID; + return mac; +} + +static void efr32_iface_init(struct net_if *iface) +{ + struct device *dev = net_if_get_device(iface); + struct efr32_context *efr32 = dev->driver_data; + u8_t *mac = get_mac(dev); + + net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154); + efr32->iface = iface; + ieee802154_init(iface); +} + +static enum ieee802154_hw_caps efr32_get_capabilities(struct device *dev) +{ + return IEEE802154_HW_FCS | + IEEE802154_HW_2_4_GHZ | + IEEE802154_HW_FILTER | + IEEE802154_HW_TX_RX_ACK | + IEEE802154_HW_CSMA; +} + +/* RAIL handles this in tx() */ +static int efr32_cca(struct device *dev) +{ + return 0; +} + +static int efr32_set_channel(struct device *dev, u16_t channel) +{ + struct efr32_context *efr32 = dev->driver_data; + + RAIL_Status_t status; + status = RAIL_PrepareChannel(efr32->rail_handle, channel); + + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + efr32->channel = channel; + + return 0; +} + +static int efr32_set_pan_id(struct device *dev, u16_t pan_id) +{ + struct efr32_context *efr32 = dev->driver_data; + + RAIL_Status_t status; + status = RAIL_IEEE802154_SetPanId(efr32->rail_handle, pan_id, 0); + + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + return 0; +} + +static int efr32_set_short_addr(struct device *dev, u16_t short_addr) +{ + struct efr32_context *efr32 = dev->driver_data; + + RAIL_Status_t status; + status = RAIL_IEEE802154_SetShortAddress(efr32->rail_handle, short_addr, 0); + + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + return 0; +} + +static int efr32_set_ieee_addr(struct device *dev, const u8_t *ieee_addr) +{ + struct efr32_context *efr32 = dev->driver_data; + + RAIL_Status_t status; + status = RAIL_IEEE802154_SetLongAddress(efr32->rail_handle, ieee_addr, 0); + + if (status != RAIL_STATUS_NO_ERROR) + { + LOG_ERR("Error setting address via RAIL"); + return -EIO; + } + + return 0; +} + +static int efr32_filter(struct device *dev, + bool set, + enum ieee802154_filter_type type, + const struct ieee802154_filter *filter) +{ + LOG_DBG("Applying filter %u", type); + + if (!set) + { + return -ENOTSUP; + } + + if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) + { + return efr32_set_ieee_addr(dev, filter->ieee_addr); + } + else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) + { + return efr32_set_short_addr(dev, filter->short_addr); + } + else if (type == IEEE802154_FILTER_TYPE_PAN_ID) + { + return efr32_set_pan_id(dev, filter->pan_id); + } + + return -ENOTSUP; +} + +static int efr32_set_txpower(struct device *dev, s16_t dbm) +{ + struct efr32_context *efr32 = dev->driver_data; + + RAIL_Status_t status; + status = RAIL_SetTxPower(efr32->rail_handle, (RAIL_TxPower_t)dbm * 10); + + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + return 0; +} + +static int efr32_start(struct device *dev) +{ + struct efr32_context *efr32 = dev->driver_data; + ARG_UNUSED(efr32); + + efr_state = EFR32_STATE_SLEEP; + + LOG_DBG("EFR32 802154 radio started"); + + return 0; +} + +static int efr32_stop(struct device *dev) +{ + struct efr32_context *efr32 = dev->driver_data; + ARG_UNUSED(efr32); + + efr_state = EFR32_STATE_DISABLED; + + LOG_DBG("EFR32 802154 radio stopped"); + + return 0; +} + +static int efr32_tx(struct device *dev, struct net_pkt *pkt, + struct net_buf *frag) +{ + struct efr32_context *efr32 = dev->driver_data; + + u8_t payload_len = net_pkt_ll_reserve(pkt) + frag->len; + u8_t *payload = frag->data - net_pkt_ll_reserve(pkt); + u16_t written; + + RAIL_TxOptions_t tx_opts = RAIL_TX_OPTIONS_NONE; + RAIL_Status_t status; + + LOG_DBG("rx %p (%u)", payload, payload_len); + + efr32->tx_success = false; + + memcpy(efr32->tx_buf + 1, payload, payload_len); + efr32->tx_buf[0] = payload_len + EFR32_FCS_LENGTH; + + /* Reset semaphore in case ACK was received after timeout */ + k_sem_reset(&efr32->tx_wait); + + RAIL_Idle(efr32->rail_handle, RAIL_IDLE_ABORT, true); + + written = RAIL_WriteTxFifo(efr32->rail_handle, efr32->tx_buf, payload_len, true); + status = RAIL_StartCcaCsmaTx(efr32->rail_handle, efr32->channel, tx_opts, &rail_csma_config, NULL); + + if (status != RAIL_STATUS_NO_ERROR) + { + LOG_ERR("Cannot start tx, error %i", status); + return -EIO; + } + + LOG_DBG("Sending frame"); + + if (k_sem_take(&efr32->tx_wait, ACK_TIMEOUT)) + { + LOG_DBG("ACK not received"); + return -EIO; + } + + LOG_DBG("Result: %d", efr32->tx_success); + + return efr32->tx_success ? 0 : -EBUSY; +} + +/* + Continously runs and tries to fetch packets.. +*/ +static void efr32_rx(int arg) +{ + struct device *dev = INT_TO_POINTER(arg); + struct efr32_context *efr32 = dev->driver_data; + + while (1) + { + LOG_DBG("Waiting for RX free"); + k_sem_take(&efr32->rx_wait, K_FOREVER); + + RAIL_Idle(efr32->rail_handle, RAIL_IDLE_ABORT, true); + RAIL_StartRx(efr32->rail_handle, efr32->channel, NULL); + } +} + +static int efr32_init(struct device *dev) +{ + struct efr32_context *efr32 = dev->driver_data; + + RAIL_Status_t status; + + RAIL_DataConfig_t rail_data_config = { + TX_PACKET_DATA, + RX_PACKET_DATA, + PACKET_MODE, + PACKET_MODE, + }; + + RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = {curves24Hp, curvesSg, curves24Lp, piecewiseSegments}; + + RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, 1800, 10}; + + efr32->rail_handle = RAIL_Init(&s_rail_config, NULL); + + k_sem_init(&efr32->rx_wait, 0, 1); + k_sem_init(&efr32->tx_wait, 0, 1); + + if (efr32->rail_handle == NULL) + { + LOG_ERR("Unable to init"); + return -EIO; + } + + status = RAIL_ConfigData(efr32->rail_handle, &rail_data_config); + if (status != RAIL_STATUS_NO_ERROR) + { + LOG_ERR("Error with config data."); + return -EIO; + } + + status = RAIL_ConfigCal(efr32->rail_handle, RAIL_CAL_ALL); + if (status != RAIL_STATUS_NO_ERROR) + { + LOG_ERR("Error with config cal."); + return -EIO; + } + + status = RAIL_IEEE802154_Config2p4GHzRadio(efr32->rail_handle); + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + status = RAIL_IEEE802154_Init(efr32->rail_handle, &rail_ieee802154_config); + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + status = RAIL_ConfigEvents(efr32->rail_handle, RAIL_EVENTS_ALL, + RAIL_EVENT_RX_ACK_TIMEOUT | // + RAIL_EVENT_TX_PACKET_SENT | // + RAIL_EVENT_RX_PACKET_RECEIVED | // + RAIL_EVENT_TX_CHANNEL_BUSY | // + RAIL_EVENT_TX_ABORTED | // + RAIL_EVENT_TX_BLOCKED | // + RAIL_EVENT_TX_UNDERFLOW | // + RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND | // + RAIL_EVENT_CAL_NEEDED // + ); + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + status = RAIL_InitTxPowerCurves(&txPowerCurvesConfig); + + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + status = RAIL_ConfigTxPower(efr32->rail_handle, &txPowerConfig); + + efr32_set_txpower(dev, 0); + + RAIL_SetTxFifo(efr32->rail_handle, efr32->tx_buf, 0, sizeof(efr32->tx_buf)); + + k_thread_create(&efr32->rx_thread, efr32->rx_stack, + CONFIG_IEEE802154_EFR32_RX_STACK_SIZE, + (k_thread_entry_t)efr32_rx, + dev, NULL, NULL, K_PRIO_COOP(2), 0, 0); + + LOG_DBG("Init done!"); + return 0; +} + +static void efr32_received() +{ + // RAIL_RxPacketHandle_t packetHandle = RAIL_RX_PACKET_HANDLE_INVALID; + // RAIL_RxPacketInfo_t packetInfo; + // RAIL_RxPacketDetails_t packetDetails; + + // RAIL_Status_t status; + // uint16_t length; + + // packetHandle = RAIL_GetRxPacketInfo(efr32_data.rail_handle, RAIL_RX_PACKET_HANDLE_OLDEST, &packetInfo); +} + +static void efr32_rail_cb(RAIL_Handle_t rail_handle, RAIL_Events_t events) +{ + /* + RAIL_EVENT_RX_ACK_TIMEOUT | // + RAIL_EVENT_TX_PACKET_SENT | // + RAIL_EVENT_RX_PACKET_RECEIVED | // + RAIL_EVENT_TX_CHANNEL_BUSY | // + RAIL_EVENT_TX_ABORTED | // + RAIL_EVENT_TX_BLOCKED | // + RAIL_EVENT_TX_UNDERFLOW | // + RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND | // + RAIL_EVENT_CAL_NEEDED //*/ + LOG_DBG("Processing events %llu", events); + + size_t index = 0; + do + { + switch (index) + { + case RAIL_EVENT_RX_ACK_TIMEOUT: + LOG_DBG("RX AutoAck occurred"); + break; + case RAIL_EVENT_TX_ABORTED: + LOG_DBG("TX was aborted"); + break; + case RAIL_EVENT_TX_BLOCKED: + LOG_DBG("TX is blocked"); + break; + case RAIL_EVENT_TX_UNDERFLOW: + LOG_DBG("TX is underflow"); + break; + case RAIL_EVENT_TX_PACKET_SENT: + LOG_DBG("TX packet sent"); + break; + case RAIL_EVENT_RX_PACKET_RECEIVED: + LOG_DBG("Received packet frame"); + efr32_received(); + break; + } + events = events >> 1; + index += 1; + } while (events != 0); +} + +static struct ieee802154_radio_api efr32_radio_api = { + .iface_api.init = efr32_iface_init, + .iface_api.send = ieee802154_radio_send, + + .get_capabilities = efr32_get_capabilities, + .cca = efr32_cca, + .set_channel = efr32_set_channel, + .filter = efr32_filter, + .set_txpower = efr32_set_txpower, + .start = efr32_start, + .stop = efr32_stop, + .tx = efr32_tx, +}; + +#if defined(CONFIG_NET_L2_IEEE802154) + +#define L2 IEEE802154_L2 +#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(IEEE802154_L2) +#define MTU 125 + +#elif defined(CONFIG_NET_L2_OPENTHREAD) +#define L2 OPENTHREAD_L2 +#define L2_CTX_TYPE NET_L2_GET_CTX_TYPE(OPENTHREAD_L2) +#define MTU 1280 + +#endif + +NET_DEVICE_INIT( + efr32, + CONFIG_IEEE802154_EFR32_DRV_NAME, + efr32_init, + &efr32_data, + NULL, + CONFIG_IEEE802154_EFR32_INIT_PRIO, + &efr32_radio_api, + L2, + L2_CTX_TYPE, + MTU); diff --git a/ext/hal/silabs/CMakeLists.txt b/ext/hal/silabs/CMakeLists.txt index 132447d7714fc..44392076e4e60 100644 --- a/ext/hal/silabs/CMakeLists.txt +++ b/ext/hal/silabs/CMakeLists.txt @@ -1 +1 @@ -add_subdirectory_ifdef(CONFIG_HAS_SILABS_GECKO gecko) +add_subdirectory_ifdef(CONFIG_HAS_SILABS_GECKO gecko) \ No newline at end of file diff --git a/ext/lib/CMakeLists.txt b/ext/lib/CMakeLists.txt index 4e0dc1dfd43fe..fde073e8af5bc 100644 --- a/ext/lib/CMakeLists.txt +++ b/ext/lib/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(crypto) add_subdirectory(encoding) add_subdirectory(ipc) add_subdirectory(mgmt) +add_subdirectory(radio) add_subdirectory_ifdef(CONFIG_FNMATCH fnmatch) diff --git a/ext/lib/radio/.gitignore b/ext/lib/radio/.gitignore new file mode 100644 index 0000000000000..ed619a48c342a --- /dev/null +++ b/ext/lib/radio/.gitignore @@ -0,0 +1 @@ +silabs_rail/ diff --git a/ext/lib/radio/CMakeLists.txt b/ext/lib/radio/CMakeLists.txt new file mode 100644 index 0000000000000..a05ba4334b392 --- /dev/null +++ b/ext/lib/radio/CMakeLists.txt @@ -0,0 +1,12 @@ +if (CONFIG_HAS_SILABS_RAIL) + zephyr_include_directories(silabs_rail/v2.3/platform/emlib/inc) + zephyr_include_directories(silabs_rail/chip/efr32) + zephyr_include_directories(silabs_rail/common) + zephyr_include_directories(silabs_rail/protocol/ieee802154) + zephyr_include_directories(silabs_rail/plugin/pa-conversions) + + add_library(silabs_rail STATIC IMPORTED GLOBAL) + set_target_properties(silabs_rail PROPERTIES IMPORTED_LOCATION + ${ZEPHYR_BASE}/ext/lib/radio/silabs_rail/autogen/librail_release/librail_efr32xg12_gcc_release.a) + zephyr_append_cmake_library(silabs_rail) +endif() \ No newline at end of file From c025b21202a8f06c8241b2c0cebc00679a073df7 Mon Sep 17 00:00:00 2001 From: Thomas Li Fredriksen Date: Mon, 26 Nov 2018 16:05:56 +0100 Subject: [PATCH 06/11] drivers: ieee802154: EFR32 support TX/RX --- drivers/ieee802154/ieee802154_efr32.c | 161 ++++++++++++++++---------- 1 file changed, 98 insertions(+), 63 deletions(-) diff --git a/drivers/ieee802154/ieee802154_efr32.c b/drivers/ieee802154/ieee802154_efr32.c index 7b34ad9dbd663..ba28099a7867d 100644 --- a/drivers/ieee802154/ieee802154_efr32.c +++ b/drivers/ieee802154/ieee802154_efr32.c @@ -54,7 +54,7 @@ static enum EfrState efr_state; enum { - IEEE802154_MAX_LENGTH = 127, + IEEE802154_MAX_LENGTH = 256, EFR32_FCS_LENGTH = 2, }; @@ -66,6 +66,8 @@ struct efr32_context u8_t rx_buf[IEEE802154_MAX_LENGTH]; u8_t tx_buf[IEEE802154_MAX_LENGTH]; + u16_t rx_buf_size; + K_THREAD_STACK_MEMBER(rx_stack, CONFIG_IEEE802154_EFR32_RX_STACK_SIZE); struct k_thread rx_thread; @@ -87,6 +89,8 @@ struct efr32_context u8_t channel; RAIL_Handle_t rail_handle; + + RAIL_RxPacketHandle_t packet_handle; }; static struct efr32_context efr32_data; @@ -121,7 +125,6 @@ const RAIL_IEEE802154_Config_t rail_ieee802154_config = { CORE_irqState_t CORE_EnterCritical(void) { - LOG_DBG("Enter crit"); return irq_lock(); } @@ -129,14 +132,11 @@ void CORE_ExitCritical(CORE_irqState_t irqState) { (void)irqState; - LOG_DBG("Exit crit"); - irq_unlock(irqState); } CORE_irqState_t CORE_EnterAtomic(void) { - LOG_DBG("Enter atomic"); return irq_lock(); } @@ -144,8 +144,6 @@ void CORE_ExitAtomic(CORE_irqState_t irqState) { (void)irqState; - LOG_DBG("Exit atomic"); - irq_unlock(irqState); } @@ -345,7 +343,9 @@ static int efr32_tx(struct device *dev, struct net_pkt *pkt, RAIL_Idle(efr32->rail_handle, RAIL_IDLE_ABORT, true); written = RAIL_WriteTxFifo(efr32->rail_handle, efr32->tx_buf, payload_len, true); - status = RAIL_StartCcaCsmaTx(efr32->rail_handle, efr32->channel, tx_opts, &rail_csma_config, NULL); + status = RAIL_StartCcaCsmaTx(efr32->rail_handle, efr32->channel, + tx_opts, &rail_csma_config, NULL); + //status = RAIL_StartTx(efr32->rail_handle, efr32->channel, tx_opts, NULL); if (status != RAIL_STATUS_NO_ERROR) { @@ -353,13 +353,16 @@ static int efr32_tx(struct device *dev, struct net_pkt *pkt, return -EIO; } - LOG_DBG("Sending frame"); + LOG_DBG("Sending frame: channel=%d, written=%u", efr32->channel, written); + k_sem_give(&efr32->rx_wait); +#if 1 if (k_sem_take(&efr32->tx_wait, ACK_TIMEOUT)) { LOG_DBG("ACK not received"); return -EIO; } +#endif LOG_DBG("Result: %d", efr32->tx_success); @@ -376,9 +379,11 @@ static void efr32_rx(int arg) while (1) { - LOG_DBG("Waiting for RX free"); + LOG_DBG("Waiting for frame"); k_sem_take(&efr32->rx_wait, K_FOREVER); + LOG_DBG("Frame received!"); + RAIL_Idle(efr32->rail_handle, RAIL_IDLE_ABORT, true); RAIL_StartRx(efr32->rail_handle, efr32->channel, NULL); } @@ -390,7 +395,7 @@ static int efr32_init(struct device *dev) RAIL_Status_t status; - RAIL_DataConfig_t rail_data_config = { + static const RAIL_DataConfig_t rail_data_config = { TX_PACKET_DATA, RX_PACKET_DATA, PACKET_MODE, @@ -402,6 +407,8 @@ static int efr32_init(struct device *dev) RAIL_TxPowerConfig_t txPowerConfig = {RAIL_TX_POWER_MODE_2P4_HP, 1800, 10}; efr32->rail_handle = RAIL_Init(&s_rail_config, NULL); + efr32->packet_handle = RAIL_RX_PACKET_HANDLE_INVALID; + efr32->rx_buf_size = sizeof(efr32->rx_buf); k_sem_init(&efr32->rx_wait, 0, 1); k_sem_init(&efr32->tx_wait, 0, 1); @@ -419,6 +426,7 @@ static int efr32_init(struct device *dev) return -EIO; } + status = RAIL_ConfigCal(efr32->rail_handle, RAIL_CAL_ALL); if (status != RAIL_STATUS_NO_ERROR) { @@ -438,17 +446,22 @@ static int efr32_init(struct device *dev) return -EIO; } + RAIL_SetTxFifo(efr32->rail_handle, efr32->tx_buf, 0, sizeof(efr32->tx_buf)); + RAIL_SetRxFifo(efr32->rail_handle, efr32->rx_buf, &efr32->rx_buf_size); + + RAIL_SetTxFifoThreshold(efr32->rail_handle, (size_t) (0.9 * sizeof(efr32->tx_buf))); + RAIL_SetRxFifoThreshold(efr32->rail_handle, (size_t) (0.9 * efr32->rx_buf_size)); + status = RAIL_ConfigEvents(efr32->rail_handle, RAIL_EVENTS_ALL, - RAIL_EVENT_RX_ACK_TIMEOUT | // - RAIL_EVENT_TX_PACKET_SENT | // - RAIL_EVENT_RX_PACKET_RECEIVED | // - RAIL_EVENT_TX_CHANNEL_BUSY | // - RAIL_EVENT_TX_ABORTED | // - RAIL_EVENT_TX_BLOCKED | // - RAIL_EVENT_TX_UNDERFLOW | // - RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND | // - RAIL_EVENT_CAL_NEEDED // - ); + RAIL_EVENTS_RX_COMPLETION + | RAIL_EVENTS_TX_COMPLETION + | RAIL_EVENTS_TXACK_COMPLETION + | RAIL_EVENT_RX_ACK_TIMEOUT + | RAIL_EVENT_TX_FIFO_ALMOST_EMPTY + | RAIL_EVENT_RX_FIFO_ALMOST_FULL + | RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND + | RAIL_EVENT_CAL_NEEDED + ); if (status != RAIL_STATUS_NO_ERROR) { return -EIO; @@ -465,8 +478,6 @@ static int efr32_init(struct device *dev) efr32_set_txpower(dev, 0); - RAIL_SetTxFifo(efr32->rail_handle, efr32->tx_buf, 0, sizeof(efr32->tx_buf)); - k_thread_create(&efr32->rx_thread, efr32->rx_stack, CONFIG_IEEE802154_EFR32_RX_STACK_SIZE, (k_thread_entry_t)efr32_rx, @@ -490,46 +501,70 @@ static void efr32_received() static void efr32_rail_cb(RAIL_Handle_t rail_handle, RAIL_Events_t events) { - /* - RAIL_EVENT_RX_ACK_TIMEOUT | // - RAIL_EVENT_TX_PACKET_SENT | // - RAIL_EVENT_RX_PACKET_RECEIVED | // - RAIL_EVENT_TX_CHANNEL_BUSY | // - RAIL_EVENT_TX_ABORTED | // - RAIL_EVENT_TX_BLOCKED | // - RAIL_EVENT_TX_UNDERFLOW | // - RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND | // - RAIL_EVENT_CAL_NEEDED //*/ - LOG_DBG("Processing events %llu", events); - - size_t index = 0; - do - { - switch (index) - { - case RAIL_EVENT_RX_ACK_TIMEOUT: - LOG_DBG("RX AutoAck occurred"); - break; - case RAIL_EVENT_TX_ABORTED: - LOG_DBG("TX was aborted"); - break; - case RAIL_EVENT_TX_BLOCKED: - LOG_DBG("TX is blocked"); - break; - case RAIL_EVENT_TX_UNDERFLOW: - LOG_DBG("TX is underflow"); - break; - case RAIL_EVENT_TX_PACKET_SENT: - LOG_DBG("TX packet sent"); - break; - case RAIL_EVENT_RX_PACKET_RECEIVED: - LOG_DBG("Received packet frame"); - efr32_received(); - break; - } - events = events >> 1; - index += 1; - } while (events != 0); + LOG_DBG("Processing events 0x%llX", events); + + if (events & RAIL_EVENT_RX_PACKET_RECEIVED) { + LOG_DBG("Received packet frame"); + efr32_received(); + } + if (events & RAIL_EVENT_RX_PACKET_ABORTED) { + LOG_DBG("RX packet aborted"); + } + if (events & RAIL_EVENT_RX_FRAME_ERROR) { + LOG_DBG("RX frame error"); + } + if (events & RAIL_EVENT_RX_FIFO_OVERFLOW) { + LOG_DBG("RX FIFO overflow"); + } + if (events & RAIL_EVENT_RX_ADDRESS_FILTERED) { + LOG_DBG("RX Address filtered"); + } + + if (events & RAIL_EVENT_TX_PACKET_SENT) { + LOG_DBG("TX packet sent"); + } + if (events & RAIL_EVENT_TX_ABORTED) { + LOG_DBG("TX was aborted"); + } + if (events & RAIL_EVENT_TX_BLOCKED) { + LOG_DBG("TX is blocked"); + } + if (events & RAIL_EVENT_TX_UNDERFLOW) { + LOG_DBG("TX is underflow"); + } + if (events & RAIL_EVENT_TX_CHANNEL_BUSY) { + LOG_DBG("TX channel busy"); + } + + if (events & RAIL_EVENT_TXACK_PACKET_SENT) { + LOG_DBG("TXACK packet sent"); + } + if (events & RAIL_EVENT_TXACK_ABORTED) { + LOG_DBG("TXACK aborted"); + } + if (events & RAIL_EVENT_TXACK_BLOCKED) { + LOG_DBG("TXACK blocked"); + } + if (events & RAIL_EVENT_TXACK_UNDERFLOW) { + LOG_DBG("TXACK underflow"); + } + + if (events & RAIL_EVENT_TX_FIFO_ALMOST_EMPTY) { + LOG_DBG("TX FIFO almost empty"); + } + if (events & RAIL_EVENT_RX_FIFO_ALMOST_FULL) { + LOG_DBG("RX FIFO almost full"); + } + if (events & RAIL_EVENT_RX_ACK_TIMEOUT) { + LOG_DBG("RX AutoAck occurred"); + } + if (events & RAIL_EVENT_CAL_NEEDED) { + LOG_DBG("Calibration needed"); + RAIL_Calibrate(rail_handle, NULL, RAIL_CAL_ALL_PENDING); + } + if (events & RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND) { + LOG_DBG("IEEE802154 Data request command"); + } } static struct ieee802154_radio_api efr32_radio_api = { From 3800057cf062143f88c9d732925665b424ee4400 Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Fri, 10 Apr 2020 00:07:11 +0200 Subject: [PATCH 07/11] Kconfig: support third party binary blobs Add a Kconfig option that allows user to opt-in for using third party software that is released in a form of a binary blob for which no source code is available. Signed-off-by: Piotr Mienkowski --- Kconfig.zephyr | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 6668933a56864..1c0f20cf9ca54 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -37,6 +37,12 @@ osource "$(TOOLCHAIN_KCONFIG_DIR)/Kconfig" menu "Build and Link Features" +config THIRD_PARTY_BINARY_BLOBS + bool "Allow third party binary blobs" + help + Allow linking with third party software that is released in a form of + a binary blob for which no source code is available. + menu "Linker Options" choice From 138069832833a64f6f10984ff5a83e0cf2c3fa07 Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Fri, 10 Apr 2020 00:19:59 +0200 Subject: [PATCH 08/11] west.yml: Update hal_silabs This commit updates west.yml to point hal_silabs module to SiLabs HAL with support for RAIL (Radio Abstraction Interface Layer). Signed-off-by: Piotr Mienkowski --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 24d71338c46ef..0ed90f1510bf6 100644 --- a/west.yml +++ b/west.yml @@ -62,7 +62,7 @@ manifest: revision: 03c8819ac3105cc2aee295a8d330de0e665b705f path: modules/hal/microchip - name: hal_silabs - revision: 78da967feeac0d51219ef733cc3ccf643336589f + revision: pull/6/head path: modules/hal/silabs - name: hal_st revision: fa481784b3c49780f18d50bafe00390ccb62b2ec From a8bb87ba48885b9de3ead141204e1e76fdeaf191 Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Tue, 7 Apr 2020 22:19:04 +0200 Subject: [PATCH 09/11] soc: silabs_exx32: Add support for RAIL This commit adds SoC support for Silicon Labs Radio Abstraction Interface Layer (RAIL) library. Signed-off-by: Piotr Mienkowski --- soc/arm/silabs_exx32/Kconfig | 28 +++++++++++++++++++ .../silabs_exx32/efr32bg13p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32fg1p/Kconfig.series | 1 + .../silabs_exx32/efr32mg12p/Kconfig.series | 1 + 4 files changed, 31 insertions(+) diff --git a/soc/arm/silabs_exx32/Kconfig b/soc/arm/silabs_exx32/Kconfig index 65ba2985ce8c8..d7e86053193b0 100644 --- a/soc/arm/silabs_exx32/Kconfig +++ b/soc/arm/silabs_exx32/Kconfig @@ -102,6 +102,34 @@ config SOC_GECKO_TRNG help Set if the SoC has a True Random Number Generator (TRNG) module. +config SOC_GECKO_HAS_RAIL_LIB + bool + help + If enabled, indicates that SoC supports RAIL radio library. + +menuconfig SOC_GECKO_RAIL_LIB + bool "Enable RAIL radio library" + depends on THIRD_PARTY_BINARY_BLOBS + depends on SOC_GECKO_HAS_RAIL_LIB + select SOC_GECKO_CORE + select SOC_GECKO_EMU + help + Enable RAIL radio library. + +if SOC_GECKO_RAIL_LIB + +config APP_LINK_WITH_RAIL_LIB + bool "Link 'app' with RAIL Library" + help + Add RAIL header files to the application include path. If the option + is not selected the RAIL library will be available only within Zephyr, + e.g. can be used by Zephyr drivers. + +config SOC_GECKO_RAIL_LIB_IEEE802154 + bool "Enable support for IEEE 802.15.4 protocol" + +endif # SOC_GECKO_RAIL_LIB + config SOC_GECKO_EMU_DCDC bool "Enable SoC DC/DC regulator" select SOC_GECKO_EMU diff --git a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series index 5d078c5406cb3..df5cefcc1f14b 100644 --- a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series @@ -17,6 +17,7 @@ config SOC_SERIES_EFR32BG13P select HAS_SYS_POWER_STATE_SLEEP_2 select HAS_SYS_POWER_STATE_SLEEP_3 select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION + select SOC_GECKO_HAS_RAIL_LIB select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO diff --git a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series index 6fac80dce0727..42c19c47b056a 100644 --- a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series @@ -17,6 +17,7 @@ config SOC_SERIES_EFR32FG1P select HAS_SYS_POWER_STATE_SLEEP_3 select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION select SOC_GECKO_HAS_HFRCO_FREQRANGE + select SOC_GECKO_HAS_RAIL_LIB select SOC_GECKO_CMU select SOC_GECKO_GPIO select SOC_GECKO_HAS_ERRATA_RTCC_E201 diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series index be9aab29f7411..40e1ddb190cb2 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series @@ -18,6 +18,7 @@ config SOC_SERIES_EFR32MG12P select HAS_SYS_POWER_STATE_SLEEP_3 select SOC_GECKO_HAS_INDIVIDUAL_PIN_LOCATION select SOC_GECKO_HAS_HFRCO_FREQRANGE + select SOC_GECKO_HAS_RAIL_LIB select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO From 9f8349f7dc3d46715ce27b2a1081d6b5308127a6 Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Fri, 10 Apr 2020 01:38:15 +0200 Subject: [PATCH 10/11] drivers: ieee802154: build the driver as a Zephyr lib Align ieee802154 with other Zephyr drivers and build it as a Zephyr library. Signed-off-by: Piotr Mienkowski --- drivers/ieee802154/CMakeLists.txt | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/ieee802154/CMakeLists.txt b/drivers/ieee802154/CMakeLists.txt index 8ff4797352a8e..3a3861375f8b6 100644 --- a/drivers/ieee802154/CMakeLists.txt +++ b/drivers/ieee802154/CMakeLists.txt @@ -1,11 +1,13 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_sources_ifdef(CONFIG_IEEE802154_CC2520 ieee802154_cc2520.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_KW41Z ieee802154_kw41z.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_UPIPE ieee802154_uart_pipe.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_MCR20A ieee802154_mcr20a.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_NRF5 ieee802154_nrf5.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_CC1200 ieee802154_cc1200.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_CC13XX_CC26XX ieee802154_cc13xx_cc26xx.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx.c) -zephyr_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx_iface.c) +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_IEEE802154_CC2520 ieee802154_cc2520.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_KW41Z ieee802154_kw41z.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_UPIPE ieee802154_uart_pipe.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_MCR20A ieee802154_mcr20a.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_NRF5 ieee802154_nrf5.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_CC1200 ieee802154_cc1200.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_CC13XX_CC26XX ieee802154_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx.c) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx_iface.c) From 9cf4840435c0e28939b7fe0c52f418a626d68b63 Mon Sep 17 00:00:00 2001 From: Markus Becker Date: Mon, 13 Apr 2020 22:02:39 +0200 Subject: [PATCH 11/11] Update EFR32 radio driver --- drivers/ieee802154/Kconfig.efr32 | 1 - drivers/ieee802154/ieee802154_efr32.c | 13 +++++++------ samples/net/sockets/echo_server/overlay-efr32.conf | 9 +++++++++ .../efr32mg12p/Kconfig.defconfig.efr32mg12p | 4 ++-- 4 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 samples/net/sockets/echo_server/overlay-efr32.conf diff --git a/drivers/ieee802154/Kconfig.efr32 b/drivers/ieee802154/Kconfig.efr32 index ca3c05ef567d2..728865d354e5e 100644 --- a/drivers/ieee802154/Kconfig.efr32 +++ b/drivers/ieee802154/Kconfig.efr32 @@ -9,7 +9,6 @@ menuconfig IEEE802154_EFR32 bool "Silabs EFR32 Driver support" depends on NETWORKING - select NEWLIB_LIBC select HAS_SILABS_RAIL config HAS_SILABS_RAIL diff --git a/drivers/ieee802154/ieee802154_efr32.c b/drivers/ieee802154/ieee802154_efr32.c index ba28099a7867d..4cb7113ba80df 100644 --- a/drivers/ieee802154/ieee802154_efr32.c +++ b/drivers/ieee802154/ieee802154_efr32.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include +#include #include #include "rail_types.h" @@ -318,13 +318,15 @@ static int efr32_stop(struct device *dev) return 0; } -static int efr32_tx(struct device *dev, struct net_pkt *pkt, +static int efr32_tx(struct device *dev, + enum ieee802154_tx_mode mode, + struct net_pkt *pkt, struct net_buf *frag) { struct efr32_context *efr32 = dev->driver_data; - u8_t payload_len = net_pkt_ll_reserve(pkt) + frag->len; - u8_t *payload = frag->data - net_pkt_ll_reserve(pkt); + u8_t payload_len = frag->len; + u8_t *payload = frag->data; u16_t written; RAIL_TxOptions_t tx_opts = RAIL_TX_OPTIONS_NONE; @@ -569,8 +571,6 @@ static void efr32_rail_cb(RAIL_Handle_t rail_handle, RAIL_Events_t events) static struct ieee802154_radio_api efr32_radio_api = { .iface_api.init = efr32_iface_init, - .iface_api.send = ieee802154_radio_send, - .get_capabilities = efr32_get_capabilities, .cca = efr32_cca, .set_channel = efr32_set_channel, @@ -598,6 +598,7 @@ NET_DEVICE_INIT( efr32, CONFIG_IEEE802154_EFR32_DRV_NAME, efr32_init, + device_pm_control_nop, &efr32_data, NULL, CONFIG_IEEE802154_EFR32_INIT_PRIO, diff --git a/samples/net/sockets/echo_server/overlay-efr32.conf b/samples/net/sockets/echo_server/overlay-efr32.conf new file mode 100644 index 0000000000000..9c3ba0b44a479 --- /dev/null +++ b/samples/net/sockets/echo_server/overlay-efr32.conf @@ -0,0 +1,9 @@ +CONFIG_IEEE802154_EFR32=y + +CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::2" +#CONFIG_NET_CONFIG_IEEE802154_DEV_NAME="cc2520" + +CONFIG_SOC_GECKO_RAIL_LIB=y +CONFIG_THIRD_PARTY_BINARY_BLOBS=y +CONFIG_SOC_GECKO_RAIL_LIB_IEEE802154=y +CONFIG_APP_LINK_WITH_RAIL_LIB=y diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p index bd578c3992392..ac790cd509a99 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p @@ -34,12 +34,12 @@ if NETWORKING if !NET_L2_OPENTHREAD config NET_L2_IEEE802154 - default y + def_bool y endif # NET_L2_OPENTHREAD config IEEE802154_EFR - default y + def_bool y config NET_CONFIG_IEEE802154_DEV_NAME default IEEE802154_EFR_DRV_NAME