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 diff --git a/drivers/ieee802154/CMakeLists.txt b/drivers/ieee802154/CMakeLists.txt index 8ff4797352a8e..86b1ff24c1576 100644 --- a/drivers/ieee802154/CMakeLists.txt +++ b/drivers/ieee802154/CMakeLists.txt @@ -1,11 +1,14 @@ # 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) +zephyr_library_sources_ifdef(CONFIG_IEEE802154_EFR32 ieee802154_efr32.c) diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index bbcba5086cef0..62e09ad32ea9d 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -35,6 +35,8 @@ source "drivers/ieee802154/Kconfig.cc13xx_cc26xx" source "drivers/ieee802154/Kconfig.rf2xx" +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..728865d354e5e --- /dev/null +++ b/drivers/ieee802154/Kconfig.efr32 @@ -0,0 +1,42 @@ +# 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 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..4cb7113ba80df --- /dev/null +++ b/drivers/ieee802154/ieee802154_efr32.c @@ -0,0 +1,608 @@ +/* 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 = 256, + 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]; + + u16_t rx_buf_size; + + 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; + + RAIL_RxPacketHandle_t packet_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) +{ + return irq_lock(); +} + +void CORE_ExitCritical(CORE_irqState_t irqState) +{ + (void)irqState; + + irq_unlock(irqState); +} + +CORE_irqState_t CORE_EnterAtomic(void) +{ + return irq_lock(); +} + +void CORE_ExitAtomic(CORE_irqState_t irqState) +{ + (void)irqState; + + 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, + enum ieee802154_tx_mode mode, + struct net_pkt *pkt, + struct net_buf *frag) +{ + struct efr32_context *efr32 = dev->driver_data; + + u8_t payload_len = frag->len; + u8_t *payload = frag->data; + 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); + //status = RAIL_StartTx(efr32->rail_handle, efr32->channel, tx_opts, NULL); + + if (status != RAIL_STATUS_NO_ERROR) + { + LOG_ERR("Cannot start tx, error %i", status); + return -EIO; + } + + 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); + + 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 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); + } +} + +static int efr32_init(struct device *dev) +{ + struct efr32_context *efr32 = dev->driver_data; + + RAIL_Status_t status; + + static const 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); + 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); + + 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; + } + + 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_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; + } + + status = RAIL_InitTxPowerCurves(&txPowerCurvesConfig); + + if (status != RAIL_STATUS_NO_ERROR) + { + return -EIO; + } + + status = RAIL_ConfigTxPower(efr32->rail_handle, &txPowerConfig); + + efr32_set_txpower(dev, 0); + + 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) +{ + 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 = { + .iface_api.init = efr32_iface_init, + .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, + device_pm_control_nop, + &efr32_data, + NULL, + CONFIG_IEEE802154_EFR32_INIT_PRIO, + &efr32_radio_api, + L2, + L2_CTX_TYPE, + MTU); 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 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/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/common/soc.c b/soc/arm/silabs_exx32/common/soc.c index 5c1115007a50f..d7cff9f74bca0 100644 --- a/soc/arm/silabs_exx32/common/soc.c +++ b/soc/arm/silabs_exx32/common/soc.c @@ -148,6 +148,14 @@ static int silabs_exx32_init(struct device *arg) dcdc_init(); #endif +#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 */ clock_init(); 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.defconfig.efr32mg12p b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p index e3ff948b9b633..ac790cd509a99 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.defconfig.efr32mg12p @@ -28,3 +28,20 @@ config SOC_FLASH_GECKO config SPI_GECKO default y depends on SPI + +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 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 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