/***************************************************************************//** * @file * @brief The main header file for the RAIL library. It describes the external * APIs available to a RAIL user ******************************************************************************* * # License * Copyright 2020 Silicon Laboratories Inc. www.silabs.com ******************************************************************************* * * SPDX-License-Identifier: Zlib * * The licensor of this software is Silicon Laboratories Inc. * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * ******************************************************************************/ #ifndef __RAIL_H__ #define __RAIL_H__ #include // For memcpy() // Get the RAIL-specific structures and types #include "rail_types.h" #include "rail_assert_error_codes.h" #ifdef __cplusplus extern "C" { #endif /** * @addtogroup RAIL_API RAIL API * @brief This is the primary API layer for the Radio Abstraction Interface * Layer (RAIL). * @{ */ /** * @defgroup Chip_Specific Chip-Specific * @brief Chip-Specific RAIL APIs, types, and information */ /** * @defgroup Protocol_Specific Protocol-specific * @brief Protocol-Specific RAIL APIs */ /****************************************************************************** * General Radio Operation *****************************************************************************/ /** * @addtogroup General * @brief Basic APIs to set up and interact with the RAIL library * @{ */ /** * Get the version information for the compiled RAIL library. * * @param[out] version A non-NULL pointer to \ref RAIL_Version_t structure to * populate with version information. * @param[in] verbose Populate \ref RAIL_Version_t struct with verbose * information. * @return Status code indicating success of the function call. * * The version information contains a major version number, a minor version * number, and a rev (revision) number. */ RAIL_Status_t RAIL_GetVersion(RAIL_Version_t *version, bool verbose); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * A global pointer to the head of a linked list of state buffers * \ref RAIL_Init() can use. * * RAIL internally provides one statically-allocated RAM state buffer * for a single protocol and two for dynamic multiprotocol. If your * application needs more, they can be provided via \ref * RAIL_AddStateBuffer3() or \ref RAIL_AddStateBuffer4(), which use * internal buffers, or the more general \ref RAIL_AddStateBuffer(). * * This symbol is WEAK in the RAIL library in case an application wants * to allocate and provide its own buffers. However, this use is highly * discouraged. */ extern RAIL_StateBufferEntry_t *RAIL_StateBufferHead; /** * Get the run-time size of the radio's state buffer. * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Size, in bytes, of the radio's internal state buffer. * If the handle is invalid, 0 is returned. * * See \ref RAIL_STATE_BUFFER_BYTES for a compile-time estimated size * definition, which may be larger than what this function returns. */ uint32_t RAIL_GetStateBufferSize(RAIL_Handle_t genericRailHandle); /** * Add an app-provided state buffer to the \ref RAIL_StateBufferHead list. * * @param[in] genericRailHandle A generic RAIL instance handle. * @param[in] newEntry A pointer to a \ref RAIL_StateBufferEntry_t to * add to the liked list of state buffers headed by * \ref RAIL_StateBufferHead. Both the \ref RAIL_StateBufferEntry_t * to which this parameter points and the \ref * RAIL_StateBufferEntry_t::buffer to which that points must be * allocated in RAM and persist indefinitely beyond this call. * @return Status code indicating success of the function call. * An error should be returned if the entry's * \ref RAIL_StateBufferEntry_t::bufferBytes is too small or * the RAIL_StateBufferEntry_t::buffer pointer seems invalid. * * RAIL's internal \ref RAIL_StateBufferHead should prove * sufficient for most applications, providing one (single protocol) * or two (dynamic multiprotocol) buffers preallocated in RAM for * use by \ref RAIL_Init(). This function exists for dynamic * multiprotocol applications that needs more than two protocols, or * that prefer to dynamically allocate RAIL state buffers just prior * to calling \ref RAIL_Init() rather than having them statically * allocated in RAM. */ RAIL_Status_t RAIL_AddStateBuffer(RAIL_Handle_t genericRailHandle, RAIL_StateBufferEntry_t *newEntry); #endif//DOXYGEN_SHOULD_SKIP_THIS /** * Add a 3rd multiprotocol internal state buffer for use by \ref RAIL_Init(). * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * An error is returned if the 3rd state buffer was previously added * or this isn't the RAIL multiprotocol library. */ RAIL_Status_t RAIL_AddStateBuffer3(RAIL_Handle_t genericRailHandle); /** * Add a 4th multiprotocol internal state buffer for use by \ref RAIL_Init(). * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * An error is returned if the 4th state buffer was previously added. * or this isn't the RAIL multiprotocol library. */ RAIL_Status_t RAIL_AddStateBuffer4(RAIL_Handle_t genericRailHandle); /** * Allocate a DMA channel for RAIL to work with. * * @param[in] channel The DMA channel to use when copying memory. If a value of * \ref RAIL_DMA_INVALID is passed, RAIL will stop using any DMA channel. * @return Status code indicating success of the function call. * * To use this API, the application must initialize the DMA engine * on the chip and allocate a DMA channel. This channel will be used * periodically to copy memory more efficiently. Call this function * before \ref RAIL_Init() to have the most benefit. If the application needs * to take back control of the DMA channel that RAIL is using, this API may be * called with a channel of \ref RAIL_DMA_INVALID to tell RAIL to stop using DMA. * * @warning To allocate and use a DMA channel for RAIL to work with when * TrustZone is enabled and LDMA is configured as secure peripheral, the * secure application must initialize the DMA engine and call this API. The * non-secure application must provide a non-NULL * \ref RAIL_TZ_Config_t::radioPerformM2mLdmaCallback to * \ref RAIL_TZ_InitNonSecure(). * To take back control of the DMA channel when TrustZone is enabled and LDMA * is configured as secure peripheral, the secure application must call this * API with a channel of \ref RAIL_DMA_INVALID. The non-secure application * must provide a NULL \ref RAIL_TZ_Config_t::radioPerformM2mLdmaCallback to * \ref RAIL_TZ_InitNonSecure(). */ RAIL_Status_t RAIL_UseDma(uint8_t channel); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * Load the first image \ref RAIL_SEQ_IMAGE_1 into the radio sequencer during * RAIL initialization. * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * * This function must only be called from within the RAIL callback context of * \ref RAILCb_RadioSequencerImageLoad(). Otherwise, the function returns \ref * RAIL_STATUS_INVALID_STATE. */ RAIL_Status_t RAIL_LoadSequencerImage1(RAIL_Handle_t genericRailHandle); /** * Load the second image \ref RAIL_SEQ_IMAGE_2 into the radio sequencer during * RAIL initialization. * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * * This function must only be called from within the RAIL callback context of * \ref RAILCb_RadioSequencerImageLoad(). Otherwise, the function returns \ref * RAIL_STATUS_INVALID_STATE. On platforms where \ref RAIL_SEQ_IMAGE_COUNT < 2, * the function returns with \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_LoadSequencerImage2(RAIL_Handle_t genericRailHandle); /** * Callback used to load the radio sequencer image during RAIL initialization. * This function is optional to implement. * * @return Status code indicating success of the function call. * * This callback is used by RAIL to load a radio sequencer image during \ref * RAIL_Init() via an API such as \ref RAIL_LoadSequencerImage1(). If this * function is not implemented, a default image will be loaded. On some * platforms, (in particular EFR32xG24), not implementing this function may * result in a larger overall code size due to unused sequencer images not * being dead stripped. * * @note If this function is implemented without a call to an image loading API * such as \ref RAIL_LoadSequencerImage1(), an assert will occur during * RAIL initialization. Similarly, if an image is loaded that is * unsupported by the platform, an assert will occur. */ RAIL_Status_t RAILCb_RadioSequencerImageLoad(void); /** * Load the OFDM and OQPSK image into the software modem (SFM) sequencer during * RAIL initialization. * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * * This function must only be called from within the RAIL callback context of * \ref RAILCb_LoadSfmSequencer(). Otherwise, the function returns \ref * RAIL_STATUS_INVALID_STATE. */ RAIL_Status_t RAIL_LoadSfmSunOfdmOqpsk(RAIL_Handle_t genericRailHandle); /** * Load the OFDM image into the software modem (SFM) sequencer during * RAIL initialization. * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * * This function must only be called from within the RAIL callback context of * \ref RAILCb_LoadSfmSequencer(). Otherwise, the function returns \ref * RAIL_STATUS_INVALID_STATE. */ RAIL_Status_t RAIL_LoadSfmSunOfdm(RAIL_Handle_t genericRailHandle); /** * Load the empty image into the software modem (SFM) sequencer during * RAIL initialization. * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * * This function must only be called from within the RAIL callback context of * \ref RAILCb_LoadSfmSequencer(). Otherwise, the function returns \ref * RAIL_STATUS_INVALID_STATE. */ RAIL_Status_t RAIL_LoadSfmEmpty(RAIL_Handle_t genericRailHandle); /** * Callback used to load the software modem (SFM) sequencer image during RAIL * initialization. This function is optional to implement. * * @return Status code indicating success of the function call. * * This callback is used by RAIL to load a software modem sequencer image * during \ref RAIL_Init() via an API such as \ref RFHAL_LoadSfmSunOfdmOqpsk(). * If this function is not implemented, a default image including OFDM and * OQPSK modulations will be loaded. * * @note If this function is implemented without a call to an image loading API * such as \ref RFHAL_LoadSfmSunOfdmOqpsk(), an assert will occur during RAIL * initialization. Similarly, if an image is loaded that is unsupported by * the platform, an assert will occur. */ RAIL_Status_t RAILCb_LoadSfmSequencer(void); #endif //DOXYGEN_SHOULD_SKIP_THIS /** * Reads out device specific data that may be needed by RAIL * and populates appropriate data structures in the library. * * @param[in] genericRailHandle A generic RAIL instance handle. * @return Status code indicating success of the function call. * * @note This function must be called before calling \ref RAIL_Init() * on any platforms that require this data * and should not be called inside a critical section. * This function does nothing on EFR32 Series 2 devices. */ RAIL_Status_t RAIL_CopyDeviceInfo(RAIL_Handle_t genericRailHandle); /** * Initialize RAIL. * * @param[in] railCfg The configuration for setting up the protocol. * @param[in] cb A callback that notifies the application when the radio is * finished initializing and is ready for further configuration. This * callback is useful for potential transceiver products that require a * power up sequence before further configuration is available. After the * callback fires, the radio is ready for additional configuration before * transmit and receive operations. * @return Handle for initialized rail instance or NULL if an * invalid value was passed in the railCfg. * * @note Call this function only once per protocol. If called * again, it will do nothing and return NULL. \ref RAIL_CopyDeviceInfo() * should be called once before calling this function for * Silicon Labs Series 3 devices. */ RAIL_Handle_t RAIL_Init(const RAIL_Config_t *railCfg, RAIL_InitCompleteCallbackPtr_t cb); /** * Get RAIL initialization status. * * @return true if the radio has finished initializing and * false otherwise. * * RAIL APIs, e.g., \ref RAIL_GetTime(), which work only if \ref RAIL_Init() has been called, * can use \ref RAIL_IsInitialized() to determine whether RAIL has been initialized or not. */ bool RAIL_IsInitialized(void); /** * Collect entropy from the radio if available. * * @param[in] railHandle A RAIL instance handle. * @param[out] buffer A non-NULL pointer to the buffer to write the collected entropy. * @param[in] bytes The number of bytes to fill in the input buffer. * @return The number of bytes of entropy collected. For * radios that don't support entropy collection, the function returns 0. * Values less than the requested amount may also be returned on platforms * that use entropy pools to collect random data periodically. * * Attempts to fill the provided buffer with the requested number of bytes of * entropy. If the requested number of bytes can't be provided, as many * bytes as possible will be filled and returned. For radios * that do not support this function, 0 bytes are always returned. For * information about the specific mechanism for gathering entropy, see * documentation for the chip family. */ uint16_t RAIL_GetRadioEntropy(RAIL_Handle_t railHandle, uint8_t *buffer, uint16_t bytes); /** @} */ // end of group General /****************************************************************************** * PTI *****************************************************************************/ /** * @addtogroup PTI PTI Packet Trace * @brief Basic APIs to set up and interact with PTI settings * @{ */ /** * Configure PTI pin locations, serial protocols, and baud rates. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] ptiConfig A non-NULL pointer to the PTI configuration structure * to use. * @return Status code indicating success of the function call. * * This method must be called before \ref RAIL_EnablePti() is called. * There is only one PTI configuration that can be active on a * radio, regardless of the number of protocols (unless the application * updates the configuration upon a protocol switch -- RAIL does not * save the configuration in a protocol RAIL instance). * * PTI should be configured only when the radio is off (idle). * * @note On EFR32 platforms GPIO configuration must be unlocked * (see GPIO->LOCK register) to configure or use PTI. * * @warning As this function relies on GPIO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if GPIO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_ConfigPti(RAIL_Handle_t railHandle, const RAIL_PtiConfig_t *ptiConfig); /** * Get the currently-active PTI configuration. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[out] ptiConfig A non-NULL pointer to the configuration structure * to be filled in with the active PTI configuration. * @return RAIL status indicating success of the function call. * * Although most combinations of configurations can be set, it is safest * to call this method after configuration to confirm which values were * actually set. This function always returns the active PTI configuration * on the radio regardless of the active protocol. */ RAIL_Status_t RAIL_GetPtiConfig(RAIL_Handle_t railHandle, RAIL_PtiConfig_t *ptiConfig); /** * Enable Packet Trace Interface (PTI) output of packet data. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] enable PTI is enabled if true; disabled if false. * @return Status code indicating success of the function call. * * Similarly to having only one PTI configuration per radio, * PTI can only be enabled or disabled for all protocols. It cannot * be individually set to enabled and disabled per protocol * (unless the application switches it when the protocol switches -- * RAIL does not save this state in a protocol RAIL instance). * * PTI should be enabled or disabled only when the radio is off (idle). * * @warning On EFR32 platforms GPIO configuration must be unlocked * (see GPIO->LOCK register) to configure or use PTI, otherwise a fault * or assert might occur. * If GPIO configuration locking is desired, PTI must be disabled * beforehand either with this function or with \ref RAIL_ConfigPti() * using \ref RAIL_PTI_MODE_DISABLED. * * @warning As this function relies on GPIO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if GPIO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_EnablePti(RAIL_Handle_t railHandle, bool enable); /** * Set a protocol that RAIL outputs on PTI. * * @param[in] railHandle A RAIL instance handle. * @param[in] protocol The enumeration representing which protocol the app is using. * @return Status code indicating success of the function call. * * The protocol is output via PTI for each packet. * Before any protocol is set, the default value is \ref * RAIL_PTI_PROTOCOL_CUSTOM. Use one of the enumeration values so that * the Network Analyzer can decode the packet. * * @note This function cannot be called unless the radio is currently in the * \ref RAIL_RF_STATE_IDLE or \ref RAIL_RF_STATE_INACTIVE states. For this * reason, call this function early on before starting radio * operations and not changed later. */ RAIL_Status_t RAIL_SetPtiProtocol(RAIL_Handle_t railHandle, RAIL_PtiProtocol_t protocol); /** * Get the protocol that RAIL outputs on PTI. * * @param[in] railHandle A RAIL instance handle. * @return PTI protocol in use. */ RAIL_PtiProtocol_t RAIL_GetPtiProtocol(RAIL_Handle_t railHandle); /** @} */ // end of group PTI /****************************************************************************** * Antenna Control *****************************************************************************/ /** * @addtogroup Antenna_Control Antenna Control * @brief Basic APIs to control the antenna functionality * @{ */ /** * Configure antenna path and pin locations. * * @warning This API must be called before any TX or RX occurs. Otherwise, * the antenna configurations for those functions will not take effect. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] config A pointer to a configuration structure applied to the relevant Antenna * Configuration registers. A NULL configuration will produce undefined behavior. * @return Status code indicating success of the function call. * * This function informs RAIL how to select each antenna, but not when. * Antenna selection for receive is controlled by the * \ref RAIL_RX_OPTION_ANTENNA0 and * \ref RAIL_RX_OPTION_ANTENNA1 options * (and the \ref RAIL_RX_OPTION_ANTENNA_AUTO combination). * Antenna selection for transmit is controlled by the * \ref RAIL_TX_OPTION_ANTENNA0 and * \ref RAIL_TX_OPTION_ANTENNA1 options. * * There is only one antenna configuration can be active on a * radio, regardless of the number of protocols (unless the application * updates the configuration upon a protocol switch -- * RAIL does not save this configuration in a protocol RAIL instance). */ RAIL_Status_t RAIL_ConfigAntenna(RAIL_Handle_t railHandle, const RAIL_AntennaConfig_t *config); /** * Get the default RF path. * * @param[in] railHandle A RAIL instance handle. * @param[out] rfPath A pointer to RF path updated by the function. * @return Status code indicating success of the function call. * * If multiple protocols are used, this function returns * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is * not active. In that case, the caller must attempt to re-call this function later, * for example when \ref RAIL_EVENT_CONFIG_SCHEDULED trigger. */ RAIL_Status_t RAIL_GetRfPath(RAIL_Handle_t railHandle, RAIL_AntennaSel_t *rfPath); /** @} */ // end of group Antenna_Control /****************************************************************************** * Radio Configuration *****************************************************************************/ /// @addtogroup Radio_Configuration Radio Configuration /// @brief Routines for setting up and querying radio configuration information. /// /// These routines allow for runtime flexibility in the radio /// configuration. Some of the parameters, however, are meant to be generated /// from the radio calculator in Simplicity Studio. The basic code to configure /// the radio from this calculator output looks like the example below. /// @code{.c} /// // Associate a specific channel configuration with a particular RAIL instance and /// // load the settings that correspond to the first usable channel. /// RAIL_ConfigChannels(railHandle, channelConfigs[0]); /// @endcode /// /// For more information about the types of parameters that can be changed in /// the other functions and how to use them, see their individual documentation. /// /// @{ /** * Load a static radio configuration. * * @param[in] railHandle A RAIL instance handle. * @param[in] config A radio configuration array (pointer). * @return Status code indicating success of the function call. * * The configuration passed into this function should be auto-generated * and not manually created or edited. By default, do not call this function * in RAIL 2.x and later unless instructed by Silicon Labs because it * may bypass updating certain RAIL state. In RAIL 2.x and later, the * RAIL_ConfigChannels function applies the default radio configuration * automatically. */ RAIL_Status_t RAIL_ConfigRadio(RAIL_Handle_t railHandle, RAIL_RadioConfig_t config); /** * Modify the currently configured fixed frame length in bytes. * * @param[in] railHandle A RAIL instance handle. * @param[in] length The expected fixed frame length. A value of 0 is infinite. * A value of \ref RAIL_SETFIXEDLENGTH_INVALID restores the frame's length back to * the length specified by the default frame type configuration. * @return The new frame length configured into the hardware * for use: 0 if in infinite mode, or \ref RAIL_SETFIXEDLENGTH_INVALID if the frame * length has not yet been overridden by a valid value. * * Sets the fixed-length configuration for transmit and receive. * Be careful when using this function in receive and transmit as this * function changes the default frame configuration and remains in force until * it is called again with an input value of \ref RAIL_SETFIXEDLENGTH_INVALID. This * function will override any fixed or variable length settings from a radio * configuration. */ uint16_t RAIL_SetFixedLength(RAIL_Handle_t railHandle, uint16_t length); /** * Configure the channels supported by this device. * * @param[in] railHandle A RAIL instance handle. * @param[in] config A pointer to the channel configuration for your device. * This pointer will be cached in the library so it must * exist for the runtime of the application. Typically, this should be * what is stored in Flash by the configuration tool. * @param[in] cb A pointer to a function called whenever a radio * configuration change occurs. May be NULL if do not need a callback. * @return The first available channel in the configuration. * * When configuring channels on EFR32, the radio tuner is reconfigured * based on the frequency and channel spacing in the channel configuration. * * @note config can be NULL to simply register or unregister the cb callback * function when using RAIL internal protocol-specific radio configuration * APIs for BLE, IEEE 802.15.4, or Z-Wave, which lack callback specification. * In this use case, 0 is returned. */ uint16_t RAIL_ConfigChannels(RAIL_Handle_t railHandle, const RAIL_ChannelConfig_t *config, RAIL_RadioConfigChangedCallback_t cb); /** * Configure the channels supported by this device. * * @param[in] railHandle A RAIL instance handle. * @param[in] config A pointer to the channel configuration for your device. * This pointer will be cached in the library so it must * exist for the runtime of the application. Typically, this should be * what is stored in Flash by the configuration tool. * @param[in] cb A pointer to a function called whenever a radio * configuration change occurs. May be NULL if do not need a callback. * @return Status code indicating success of the function call. * * @note Unlike \ref RAIL_ConfigChannels(), this function only caches the * configuration and does not prepare any channel in the configuration. That * action is deferred to the next call to a RAIL API where channel is passed * as a parameter, namely * \ref RAIL_PrepareChannel(), \ref RAIL_StartTx(), * \ref RAIL_StartScheduledTx(), \ref RAIL_StartCcaCsmaTx(), * \ref RAIL_StartCcaLbtTx(), \ref RAIL_StartScheduledCcaCsmaTx(), * \ref RAIL_StartScheduledCcaLbtTx(), \ref RAIL_StartRx(), * \ref RAIL_ScheduleRx(), \ref RAIL_StartAverageRssi(), * \ref RAIL_StartTxStream(). * * @note config can be NULL to simply register or unregister the cb callback * function when using RAIL internal protocol-specific radio configuration * APIs for BLE, IEEE 802.15.4, or Z-Wave, which lack callback specification. */ RAIL_Status_t RAIL_ConfigChannelsAlt(RAIL_Handle_t railHandle, const RAIL_ChannelConfig_t *config, RAIL_RadioConfigChangedCallback_t cb); /** * Get verbose listing of channel metadata for the current channel configuration. * * @param[in] railHandle A RAIL instance handle. * @param[out] channelMetadata A pointer to an app-allocated array that * will be populated with channel metadata. * @param[in,out] length A pointer to the number of entries available * in the channelMetadata array. * This value will be updated to the number of channels written to the array, * not to exceed the length number passed in. * @param[in] minChannel Minimum channel number about which to collect data. * @param[in] maxChannel Maximum channel number about which to collect data. * @return Status code indicating success of the function call. * \ref RAIL_STATUS_INVALID_PARAMETER means that, * based on the currently active radio configuration, there are more * channels to write than there is space provided in the allocated * channelMetadata. However, the channel metadata that was written is valid. * \ref RAIL_STATUS_INVALID_STATE indicates that the channel configuration * has not been configured. \ref RAIL_STATUS_NO_ERROR indicates complete * success. */ RAIL_Status_t RAIL_GetChannelMetadata(RAIL_Handle_t railHandle, RAIL_ChannelMetadata_t *channelMetadata, uint16_t *length, uint16_t minChannel, uint16_t maxChannel); /** * Check whether the channel exists in the current RAIL channel configuration. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel A channel number to check. * @return \ref RAIL_STATUS_NO_ERROR if channel exists or \ref * RAIL_STATUS_INVALID_PARAMETER if the given channel does not exist. */ RAIL_Status_t RAIL_IsValidChannel(RAIL_Handle_t railHandle, uint16_t channel); /** * Cause radio settings associated with a particular channel to be applied to * hardware. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The channel to prepare for use. * @return \ref RAIL_STATUS_NO_ERROR on success or * \ref RAIL_STATUS_INVALID_PARAMETER if the given channel does not have an * associated channel configuration entry. * * This function walks the current \ref RAIL_ChannelConfig_t::configs list * and applies the configuration associated with the specified channel if * found. * This function manually changes channels without starting a TX or RX * operation. * * When successful, the radio is idled. * When unsuccessful, the radio state will not be altered. */ RAIL_Status_t RAIL_PrepareChannel(RAIL_Handle_t railHandle, uint16_t channel); /** * Return the most-recently requested RAIL channel. * * @param[in] railHandle A RAIL instance handle. * @param[out] channel A pointer to the channel for which RAIL was * most-recently configured. * @return \ref RAIL_STATUS_NO_ERROR on success or * \ref RAIL_STATUS_INVALID_CALL if the radio is not configured for any channel * or \ref RAIL_STATUS_INVALID_PARAMETER if channel parameter is NULL. * * This function returns the channel most recently specified in API calls that * pass in a channel to tune to, namely \ref RAIL_PrepareChannel(), * \ref RAIL_StartTx(), \ref RAIL_StartScheduledTx(), \ref RAIL_StartCcaCsmaTx(), * \ref RAIL_StartCcaLbtTx(), \ref RAIL_StartScheduledCcaCsmaTx(), * \ref RAIL_StartScheduledCcaLbtTx(), \ref RAIL_StartRx(), \ref RAIL_ScheduleRx(), * \ref RAIL_StartAverageRssi(), \ref RAIL_StartTxStream(), \ref RAIL_StartTxStreamAlt(). * It doesn't follow changes RAIL performs implicitly during channel hopping * and mode switch. */ RAIL_Status_t RAIL_GetChannel(RAIL_Handle_t railHandle, uint16_t *channel); /** * Return the RAIL channel to which the radio is currently tuned. * * @param[in] railHandle A RAIL instance handle. * @param[out] channel A pointer to the currently-tuned channel. * @return \ref RAIL_STATUS_NO_ERROR on success or * \ref RAIL_STATUS_INVALID_CALL if the radio is not configured for any channel * or \ref RAIL_STATUS_INVALID_PARAMETER if channel parameter is NULL. * * This function returns the channel to which the radio is currently tuned if * the specified RAIL handle is active. It returns the channel to which it * will be tuned during the next protocol switch if the handle is inactive. * The channel returned may be different than what \ref RAIL_GetChannel * returns when channel hopping or mode switch are involved. */ RAIL_Status_t RAIL_GetChannelAlt(RAIL_Handle_t railHandle, uint16_t *channel); /** * Return the symbol rate for the current PHY. * * @param[in] railHandle A RAIL instance handle. * @return The symbol rate in symbols per second or 0. * * The symbol rate is the rate of symbol changes over the air. For non-DSSS * PHYs, this is the same as the baudrate. For DSSS PHYs, it is the baudrate * divided by the length of a chipping sequence. For more information, * see the modem calculator documentation. If the rate cannot be * calculated, this function returns 0. */ uint32_t RAIL_GetSymbolRate(RAIL_Handle_t railHandle); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * Calculate the symbol rate for the current PHY. * * @param[in] railHandle A RAIL instance handle. * @return The symbol rate in symbols per second or 0. * * This function calculates the symbol rate when the radio configuration does * not include that information. In general, this function should be * implemented automatically in the radio configuration as a stub. */ uint32_t RAILCb_CalcSymbolRate(RAIL_Handle_t railHandle); #endif//DOXYGEN_SHOULD_SKIP_THIS /** * Return the bit rate for the current PHY. * * @param[in] railHandle A RAIL instance handle. * @return The bit rate in bits per second or 0. * * The bit rate is the effective over-the-air data rate. It does not account * for extra spreading for forward error correction, and so on, but * accounts for modulation schemes, DSSS, and other configurations. For more * information, see the modem calculator documentation. If the rate cannot be * calculated, this function returns 0. */ uint32_t RAIL_GetBitRate(RAIL_Handle_t railHandle); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * Calculate the bit rate for the current PHY. * * @param[in] railHandle A RAIL instance handle. * @return The bit rate in bits per second or 0. * * This function calculates the bit rate when the radio configuration does * not include that information. In general, this function should be * implemented automatically in the radio configuration as a stub. */ uint32_t RAILCb_CalcBitRate(RAIL_Handle_t railHandle); #endif//DOXYGEN_SHOULD_SKIP_THIS /** * Set the PA capacitor tune value for transmit and receive. * * @param[in] railHandle A RAIL instance handle. * @param[in] txPaCtuneValue PA Ctune value for TX mode. * @param[in] rxPaCtuneValue PA Ctune value for RX mode. * @return Status code indicating success of the function call. * * Tunes the impedance of the transmit * and receive modes by changing the amount of capacitance at * the PA output. * Changes made to the TX Power configuration, e.g., calling \ref RAIL_ConfigTxPower, * will undo changes made to PA capacitor tune value for transmit and receive * via \ref RAIL_SetPaCTune. * * @note This function does nothing on EFR32 Series 2 devices. */ RAIL_Status_t RAIL_SetPaCTune(RAIL_Handle_t railHandle, uint8_t txPaCtuneValue, uint8_t rxPaCtuneValue); /** * Get the sync words and their length. * * @param[in] railHandle A RAIL instance handle. * @param[out] syncWordConfig An application-provided non-NULL pointer to store * \ref RAIL_SyncWordConfig_t sync word information. * @return Status code indicating success of the function call. **/ RAIL_Status_t RAIL_GetSyncWords(RAIL_Handle_t railHandle, RAIL_SyncWordConfig_t *syncWordConfig); /** * Set the selected sync words and their length. * * @param[in] railHandle A RAIL instance handle. * @param[in] syncWordConfig A non-NULL pointer to \ref RAIL_SyncWordConfig_t * specifying the sync words and their length. * The desired length should be between 2 and 32 bits inclusive, however it is * recommended to not change the length below what the PHY sync word length is * configured to be. Changing the sync word length, especially to that which is * lower than the default length, may result in a decrease in packet reception * rate or may not work at all. * Other values will result in \ref RAIL_STATUS_INVALID_PARAMETER. The default * sync word continues to be valid. * @return Status code indicating success of the function call. * * When the custom sync word(s) applied by this API are no longer needed, or to * revert to default sync word, calling \ref RAIL_ConfigChannels() will re-establish * the sync words specified in the radio configuration. * * This function will return \ref RAIL_STATUS_INVALID_STATE if called when BLE * has been enabled for this railHandle. When changing sync words in BLE mode, * use \ref RAIL_BLE_ConfigChannelRadioParams() instead. * * @note If multiple protocols share the same radio configuration, the user * should not set custom sync words in any of those protocols as these * sync words could leak into the other protocol sharing the same radio * configuration. **/ RAIL_Status_t RAIL_ConfigSyncWords(RAIL_Handle_t railHandle, const RAIL_SyncWordConfig_t *syncWordConfig); /** * Sets the whitening initialization value. * * @param[in] railHandle A RAIL instance handle. * @return The whitening initialization value currently being used. */ uint16_t RAIL_GetWhiteningInitVal(RAIL_Handle_t railHandle); /** * Returns the CRC initialization value. * * @param[in] railHandle A RAIL instance handle. * @return The CRC initialization value currently being used. */ uint32_t RAIL_GetCrcInitVal(RAIL_Handle_t railHandle); /** * Sets the whitening initialization value. * * @param[in] railHandle A RAIL instance handle. * @param[in] whiteInit A whitening initialization value. * @return Status code indicating success of the function call. * * Use this function to override the whitening initialization value * defined by the current PHY's radio configuration. The new value * will persist until this function is called again, \ref * RAIL_ResetWhiteningInitVal() is called, or the PHY is * changed. * * @note Overriding a PHY's whitening initialization value * will break communication with peers unless they effect * a similar change. * * @warning This API must not be used when either 802.15.4 * or BLE modes are enabled. */ RAIL_Status_t RAIL_SetWhiteningInitVal(RAIL_Handle_t railHandle, uint16_t whiteInit); /** * Sets the CRC initialization value. * * @param[in] railHandle A RAIL instance handle. * @param[in] crcInit A CRC initialization value. * @return Status code indicating success of the function call. * * Use this function to override the CRC initialization value * defined by the current PHY's radio configuration. The new value * will persist until this function is called again, \ref * RAIL_ResetCrcInitVal() is called, or the PHY is changed. * * @note Overriding a PHY's CRC initialization value * will break communication with peers unless they effect * a similar change. * * @warning This API must not be used when either 802.15.4 * or BLE modes are enabled. */ RAIL_Status_t RAIL_SetCrcInitVal(RAIL_Handle_t railHandle, uint32_t crcInit); /** * Restores the whitening initialization value to its initial setting * from the Radio Configurator. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * Can use this function after using \ref RAIL_SetWhiteningInitVal(). */ RAIL_Status_t RAIL_ResetWhiteningInitVal(RAIL_Handle_t railHandle); /** * Restores the CRC initialization value to its initial setting from * the Radio Configurator. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * Can use this function after using \ref RAIL_SetCrcInitVal(). */ RAIL_Status_t RAIL_ResetCrcInitVal(RAIL_Handle_t railHandle); /** @} */ // end of group Radio_Configuration /****************************************************************************** * Timing Information *****************************************************************************/ /// @addtogroup System_Timing System Timing /// @brief Functionality related to the RAIL timer and general system time. /// /// These functions can be used to get information about the current system time /// or to manipulate the RAIL timer. /// /// The system time returned by \ref RAIL_GetTime() is in the same timebase that is /// used throughout RAIL. Any callbacks or structures that provide a timestamp, /// such as \ref RAIL_RxPacketDetails_t::timeReceived, will use the same timebase /// as will any APIs that accept an absolute time for scheduling their action. /// Throughout the documentation, the timebase is referred to as the RAIL /// timebase. The timebase is currently a value in microseconds from \ref /// RAIL_Init() time, which means that it will wrap every 1.19 hours. /// (`(2^32 - 1) / (3600 sec/hr * 1000000 us/sec)`). /// /// The provided timer is hardware-backed and interrupt-driven. It can be used /// for timing any event in the system, but is especially helpful for /// timing protocol-based state machines and other systems that interact with /// the radio. To avoid processing the expiration in interrupt /// context, leave the cb parameter passed to \ref RAIL_SetTimer() as NULL and poll /// for expiration with the \ref RAIL_IsTimerExpired() function. See below for an /// example of the interrupt driven method of interacting with the timer. /// @code{.c} /// void timerCb(RAIL_Handle_t cbArg) /// { /// // Timer callback action /// } /// /// void main(void) /// { /// // Initialize RAIL ... /// /// // Set up a timer for 1 ms from now /// RAIL_SetTimer(railHandle, 1000, RAIL_TIME_RELATIVE, &timerCb); /// /// // Run main loop /// while(1); /// } /// @endcode /// /// If multiple software timers are needed to be run off of the one available /// hardware timer, enable a software multiplexing layer within RAIL /// using the \ref RAIL_ConfigMultiTimer() function. This will allow you to /// set up as many timers as you want using the RAIL_*MultiTimer() functions. /// See the example below for using the multitimer functionality. /// @code{.c} /// // Declare timer structures in global space or somewhere that will exist /// // until the callback has fired /// RAIL_MultiTimer_t tmr1, tmr2; /// /// void timerCb(RAIL_MultiTimer_t *tmr, /// RAIL_Time_t expectedTimeOfEvent, /// void *cbArg) /// { /// if (tmr == tmr1) { /// // Timer 1 action /// } else { /// // Timer 2 action /// } /// } /// /// void main(void) /// { /// // Initialize RAIL ... /// /// RAIL_ConfigMultiTimer(true); /// /// // Set up one timer for 1 ms from now and one at time 2000000 in the RAIL /// // timebase /// RAIL_SetMultiTimer(&tmr1, 1000, RAIL_TIME_RELATIVE, &timerCb, NULL); /// RAIL_SetMultiTimer(&tmr2, 2000000, RAIL_TIME_ABSOLUTE, &timerCb, NULL); /// /// // Run main loop /// while(1); /// } /// @endcode /// /// @{ /** * Get the current RAIL time. * * @return The RAIL time in microseconds. Note that this wraps * after about 1.19 hours since it's stored in a 32 bit value. * * Returns the current time in the RAIL timebase (microseconds). It can be * used to compare with packet timestamps or to schedule transmits. */ RAIL_Time_t RAIL_GetTime(void); /** * Set the current RAIL time. * * @param[in] time Set the RAIL timebase to this value in microseconds. * @return Status code indicating the success of the function call. * * @warning Use this API only for testing purposes or in * very limited circumstances during RAIL Timer Synchronization. * Undefined behavior can result by calling it in multiprotocol or * when the radio is not idle or timed events are active. Applications * using \ref RAIL_GetTime() may not be designed for discontinuous * changes to the RAIL time base. */ RAIL_Status_t RAIL_SetTime(RAIL_Time_t time); /** * Blocking delay routine for a specified number of microseconds. * * @param[in] microseconds Delay duration in microseconds. * @return Status code indicating success of the function call. * * Use this RAIL API only for short blocking delays because it has less overhead * than calling RAIL_GetTime() in a loop. * * @note Passing large delay values may give unpredictable results or trigger * the Watchdog reset. * \n Also, this function will start the clocks required for the RAIL timebase if they * are not running, except between \ref RAIL_Sleep() and \ref RAIL_Wake() * where the timer must remain stopped. * \n Interrupts are not disabled during the delay, so the delay may be longer if an * interrupt extends beyond the delay duration. */ RAIL_Status_t RAIL_DelayUs(RAIL_Time_t microseconds); /** * Schedule a timer to expire using the RAIL timebase. * * @param[in] railHandle A RAIL instance handle. * @param[in] time The timer's expiration time in the RAIL timebase. * @param[in] mode Indicates whether the time argument is an absolute * RAIL time or relative to the current RAIL time. Specifying mode * \ref RAIL_TIME_DISABLED is the same as calling \ref RAIL_CancelTimer(). * @param[in] cb A pointer to a callback function that RAIL will call * when the timer expires. May be NULL if no callback is desired. * @return \ref RAIL_STATUS_NO_ERROR on success and * \ref RAIL_STATUS_INVALID_PARAMETER if the timer can't be scheduled. * * Configures a timer to expire after a period in the RAIL timebase. * This timer can be used to implement low-level protocol features. * * @warning Attempting to schedule the timer when it is * still running from a previous request is bad practice, unless the cb * callback is identical to that used in the previous request, in which case * the timer is rescheduled to the new time. Note that if the original timer * expires as it is being rescheduled, the callback may or may not occur. It * is generally good practice to cancel a running timer before rescheduling * it to minimize ambiguity. */ RAIL_Status_t RAIL_SetTimer(RAIL_Handle_t railHandle, RAIL_Time_t time, RAIL_TimeMode_t mode, RAIL_TimerCallback_t cb); /** * Return the absolute time that the RAIL timer was configured to expire. * * @param[in] railHandle A RAIL instance handle. * @return The absolute time that this timer was set to expire. * * Provides the absolute time regardless of the \ref RAIL_TimeMode_t that * was passed into \ref RAIL_SetTimer(). Note that the time might be in the * past if the timer has already expired. The return value is undefined if the * timer was never set. */ RAIL_Time_t RAIL_GetTimer(RAIL_Handle_t railHandle); /** * Stop the currently scheduled RAIL timer. * * @param[in] railHandle A RAIL instance handle. * @return \ref RAIL_STATUS_NO_ERROR on success and * \ref RAIL_STATUS_INVALID_CALL if the timer is not running. * * Cancels the timer. If this function is called before the timer expires, * the cb callback specified in the earlier RAIL_SetTimer() call will never * be called. */ RAIL_Status_t RAIL_CancelTimer(RAIL_Handle_t railHandle); /** * Check whether the RAIL timer has expired. * * @param[in] railHandle A RAIL instance handle. * @return true if the previously scheduled timer has expired and false * otherwise. * * Polling with this function is an alternative to the callback. */ bool RAIL_IsTimerExpired(RAIL_Handle_t railHandle); /** * Check whether the RAIL timer is currently running. * * @param[in] railHandle A RAIL instance handle. * @return true if the timer is running and false if * the timer has expired or was never set. */ bool RAIL_IsTimerRunning(RAIL_Handle_t railHandle); /** * Configure the RAIL software timer feature. * * @param[in] enable Enables/disables the RAIL multitimer. * @return true if the multitimer was successfully enabled/disabled, false * otherwise. * * Turning this on will add a software timer layer above the physical RAIL timer * so that the user can have as many timers as desired. It is not necessary to * call this function if the MultiTimer APIs are not used. * * @note This function must be called before calling \ref RAIL_SetMultiTimer(). * This function is a no-op on multiprotocol as this layer is already used * under the hood. * Do not call this function while the RAIL timer is running. * Call \ref RAIL_IsTimerRunning() before enabling/disabling the multitimer. * If the multitimer is not needed, do not call this function to * allow the multitimer code to be dead stripped. If the multitimer is * enabled for use, the multitimer and timer APIs can both be used. * However, no timer can be in use while this function is being called. */ bool RAIL_ConfigMultiTimer(bool enable); /** * Start a multitimer instance. * * @param[in,out] tmr A pointer to the timer instance to start. * @param[in] expirationTime A time when the timer is set to expire. * @param[in] expirationMode Select mode of expirationTime. See \ref * RAIL_TimeMode_t. * @param[in] callback A function to call on timer expiry. See \ref * RAIL_MultiTimerCallback_t. May be NULL if no callback is desired. * @param[in] cbArg An extra callback function parameter for the user application. * @return * \ref RAIL_STATUS_NO_ERROR on success.@n * \ref RAIL_STATUS_INVALID_PARAMETER if tmr has an illegal value or if * timeout is in the past. * * @note It is legal to start an already running timer. If this is done, * the timer will first be stopped before the new configuration is applied. * If expirationTime is 0, the callback is called immediately. */ RAIL_Status_t RAIL_SetMultiTimer(RAIL_MultiTimer_t *tmr, RAIL_Time_t expirationTime, RAIL_TimeMode_t expirationMode, RAIL_MultiTimerCallback_t callback, void *cbArg); /** * Stop the currently scheduled RAIL multitimer. * * @param[in,out] tmr A pointer to a RAIL timer instance. * @return true if the timer was successfully canceled; * false if the timer was not running. * * Cancels the timer. If this function is called before the timer expires, * the cb callback specified in the earlier \ref RAIL_SetTimer() call will never * be called. */ bool RAIL_CancelMultiTimer(RAIL_MultiTimer_t *tmr); /** * Check if a given timer is running. * * @param[in] tmr A pointer to the timer instance. * @return true if the timer is running; false if the timer is not running * or tmr is not a timer instance. */ bool RAIL_IsMultiTimerRunning(RAIL_MultiTimer_t *tmr); /** * Check if a given timer has expired. * * @param[in] tmr A pointer to the timer instance. * @return true if the timer has expired or tmr is not a timer instance; * false if the timer is running. */ bool RAIL_IsMultiTimerExpired(RAIL_MultiTimer_t *tmr); /** * Get time left before a given timer instance expires. * * @param[in] tmr A pointer to the timer instance to query. * @param[in] timeMode Indicates how the function provides the time * remaining. By choosing \ref * RAIL_TimeMode_t::RAIL_TIME_ABSOLUTE, the function returns the * absolute expiration time, and by choosing \ref * RAIL_TimeMode_t::RAIL_TIME_DELAY, the function returns the * amount of time remaining before the timer's expiration. * @return * Time left expressed in RAIL's time units. * 0 if the timer is not running or has already expired. */ RAIL_Time_t RAIL_GetMultiTimer(RAIL_MultiTimer_t *tmr, RAIL_TimeMode_t timeMode); /** @} */ // end of group System_Timing /****************************************************************************** * Sleep APIs *****************************************************************************/ /// @addtogroup Sleep /// @brief These APIs help when putting the system to an EM2/EM3/EM4 sleep /// states where the high frequency clock is disabled. /// @{ /// /// The RAIL library has its own timebase and the ability to schedule operations /// into the future. When going to any power mode that disables the HF clock /// used for the radio (EM2/EM3/EM4), it is important that this timebase is /// synchronized to a running LFCLK and the chip is set to wake up before the /// next scheduled event. /// If RAIL has not been configured to use the power manager, /// \ref RAIL_Sleep() and \ref RAIL_Wake() must be called for performing this /// synchronization. /// If RAIL has been configured to use the power manager, /// \ref RAIL_InitPowerManager(), it will automatically perform timer /// synchronization based on the selected \ref RAIL_TimerSyncConfig_t. Calls to /// \ref RAIL_Sleep() and \ref RAIL_Wake() are unsupported in such a scenario. /// /// Following example code snippets demonstrate synchronizing the timebase /// with and without timer synchronization: /// /// Sleep with timer synchronization: /// /// When sleeping with timer synchronization, you must first get the required /// LFCLK up and running and leave it running across sleep so that the high /// frequency clock that drives the RAIL time base can be synchronized to it. /// The \ref RAIL_Sleep() API will also set up a wake event on the timer to wake /// up wakeupProcessTime before the next timer event so that it can run successfully. /// See the \ref efr32_main sections on Low-Frequency Clocks and RAIL Timer /// Synchronization for more setup details. /// /// This is useful when maintaining packet timestamps /// across sleep or use the scheduled RX/TX APIs while sleeping in between. It /// does take more time and code to do the synchronization. If your /// application does not need this, it should be avoided. /// /// Example (without Power Manager): /// @code{.c} /// #include "rail.h" /// /// extern RAIL_Handle_t railHandle; /// // Wakeup time for your crystal/board/chip combination /// extern uint32_t wakeupProcessTime; /// /// void main(void) /// { /// RAIL_Status_t status; /// bool shouldSleep = false; /// /// // This function depends on your board/chip but it must enable the LFCLK /// // you intend to use for RTCC sync before we configure sleep as that function /// // will attempt to auto detect the clock. /// BoardSetupLFCLK() /// /// // Configure sleep for timer synchronization /// RAIL_TimerSyncConfig_t timerSyncConfig = RAIL_TIMER_SYNC_DEFAULT; /// status = RAIL_ConfigSleepAlt(railHandle, &timerSyncConfig); /// assert(status == RAIL_STATUS_NO_ERROR); /// /// // Application main loop /// while(1) { /// // ... do normal app stuff and set shouldSleep to true when we want to /// // sleep /// if (shouldSleep) { /// bool sleepAllowed = false; /// /// // Go critical to assess sleep decisions /// CORE_ENTER_CRITICAL(); /// if (RAIL_Sleep(wakeupProcessTime, &sleepAllowed) != RAIL_STATUS_NO_ERROR) { /// printf("Error trying to go to sleep!"); /// CORE_EXIT_CRITICAL(); /// continue; /// } /// if (sleepAllowed) { /// // Go to sleep /// } /// // Wakeup and sync the RAIL timebase back up /// RAIL_Wake(0); /// CORE_EXIT_CRITICAL(); /// } /// } /// } /// @endcode /// /// Example (with Power Manager): /// @code{.c} /// #include "rail.h" /// #include "sl_power_manager.h" /// /// extern RAIL_Handle_t railHandle; /// /// void main(void) /// { /// RAIL_Status_t status; /// bool shouldSleep = false; /// /// // This function depends on your board/chip but it must enable the LFCLK /// // you intend to use for RTCC sync before we configure sleep as that function /// // will attempt to auto detect the clock. /// BoardSetupLFCLK(); /// // Configure sleep for timer synchronization /// RAIL_TimerSyncConfig_t timerSyncConfig = RAIL_TIMER_SYNC_DEFAULT; /// status = RAIL_ConfigSleepAlt(railHandle, &timerSyncConfig); /// assert(status == RAIL_STATUS_NO_ERROR); /// // Initialize application-level power manager service /// sl_power_manager_init(); /// // Initialize RAIL library's use of the power manager /// RAIL_InitPowerManager(); /// /// // Application main loop /// while(1) { /// // ... do normal app stuff and set shouldSleep to true when we want to /// // sleep /// if (shouldSleep) { /// // Let the CPU go to sleep if the system allows it. /// sl_power_manager_sleep(); /// } /// } /// } /// @endcode /// /// RAIL APIs such as, \ref RAIL_StartScheduledTx(), \ref RAIL_ScheduleRx(), /// \ref RAIL_SetTimer(), \ref RAIL_SetMultiTimer() can be used to schedule periodic /// wakeups to perform a scheduled operation. The call to /// sl_power_manager_sleep() in the main loop ensures that the device sleeps /// until the scheduled operation is due. /// Upon completion, each instantaneous or scheduled RX/TX operation will /// indicate radio busy to the power manager to allow the application to /// service the RAIL event and perform subsequent operations before going to /// sleep. Therefore, it is important that the application idle the radio by either /// calling \ref RAIL_Idle() or \ref RAIL_YieldRadio(). /// If the radio transitions to RX after an RX or TX operation, /// always call \ref RAIL_Idle() in order transition to a lower sleep state. /// If the radio transitions to idle after an RX or TX operation, /// \ref RAIL_YieldRadio() should suffice in indicating to the power manager /// that the radio is no longer busy and the device can sleep. /// /// The following example shows scheduling periodic TX on getting a TX completion /// event: /// @code{.c} /// void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events) /// { /// // Omitting other event handlers /// if (events & RAIL_EVENTS_TX_COMPLETION) { /// // Schedule the next TX. /// RAIL_ScheduleTxConfig_t config = { /// .when = (RAIL_Time_t)parameters->startTime, /// .mode = (RAIL_TimeMode_t)parameters->startTimeMode /// }; /// (void)RAIL_StartScheduledTx(railHandle, channel, 0, &config, NULL); /// } /// } /// @endcode /// /// @note The above code assumes that RAIL automatic state transitions after TX /// are idle. Use \ref RAIL_SetTxTransitions() to ensure the right state /// transitions are used. Radio must be idle for the device to enter EM2 or lower /// energy mode. /// /// @note When using the power manager, usage of \ref RAIL_YieldRadio() in /// single protocol RAIL is similar to its usage in multiprotocol RAIL. /// See \ref rail_radio_scheduler_yield for more details. /// /// @note Back to back scheduled operations do not require an explicit call to /// \ref RAIL_YieldRadio() if the radio transitions to idle. /// /// Sleep without timer synchronization: /// /// When sleeping without timer synchronization, you are free to enable only the /// LFCLKs and wake sources required by the application. RAIL will not attempt /// to configure any wake events and may miss anything that occurs over sleep. /// /// This is useful when your application does not care about /// packet timestamps or scheduling operations accurately over sleep. /// /// Example (without Power Manager): /// @code{.c} /// #include "rail.h" /// /// extern RAIL_Handle_t railHandle; /// /// void main(void) /// { /// RAIL_Status_t status; /// bool shouldSleep = false; /// /// // Configure sleep for no timer synchronization /// RAIL_TimerSyncConfig_t timerSyncConfig = { /// .sleep = RAIL_SLEEP_CONFIG_TIMERSYNC_DISABLED, /// }; /// status = RAIL_ConfigSleepAlt(railHandle, &timerSyncConfig); /// assert(status == RAIL_STATUS_NO_ERROR); /// /// // Application main loop /// while(1) { /// // ... do normal app stuff and set shouldSleep to true when we want to /// // sleep /// if (shouldSleep) { /// bool sleepAllowed = false; /// uint32_t sleepTime = 0; /// /// // Go critical to assess sleep decisions /// CORE_ENTER_CRITICAL(); /// if (RAIL_Sleep(0, &sleepAllowed) != RAIL_STATUS_NO_ERROR) { /// printf("Error trying to go to sleep!"); /// CORE_EXIT_CRITICAL(); /// continue; /// } /// if (sleepAllowed) { /// // Go to sleep and optionally update sleepTime to the correct value /// // in microseconds /// } /// // Wakeup and sync the RAIL timebase back up /// RAIL_Wake(sleepTime); /// CORE_EXIT_CRITICAL(); /// } /// } /// } /// @endcode /// /// Example (with Power Manager): /// @code{.c} /// #include "rail.h" /// #include "sl_power_manager.h" /// /// extern RAIL_Handle_t railHandle; /// /// void main(void) /// { /// RAIL_Status_t status; /// bool shouldSleep = false; /// /// // This function depends on your board/chip but it must enable the LFCLK /// // you intend to use for RTCC sync before we configure sleep as that function /// // will attempt to auto detect the clock. /// BoardSetupLFCLK(); /// // Configure sleep for no timer synchronization /// RAIL_TimerSyncConfig_t timerSyncConfig = { /// .sleep = RAIL_SLEEP_CONFIG_TIMERSYNC_DISABLED, /// }; /// status = RAIL_ConfigSleepAlt(railHandle, &timerSyncConfig); /// assert(status == RAIL_STATUS_NO_ERROR); /// // Initialize application-level power manager service /// sl_power_manager_init(); /// // Initialize RAIL library's use of the power manager /// RAIL_InitPowerManager(); /// /// // Application main loop /// while(1) { /// // ... do normal app stuff and set shouldSleep to true when we want to /// // sleep /// if (shouldSleep) { /// // Let the CPU go to sleep if the system allows it. /// sl_power_manager_sleep(); /// } /// } /// } /// @endcode /** * Configure RAIL timer synchronization. This function is optional to implement. * * @param[in,out] timerSyncConfig A pointer to the \ref RAIL_TimerSyncConfig_t * structure containing the configuration parameters for timer sync. The * \ref RAIL_TimerSyncConfig_t::sleep field is ignored in this call. * * This function is called during \ref RAIL_ConfigSleep() to allow an application * to configure the PRS and RTCC channels used for timer sync to values other * than their defaults. The default channels are populated in timerSyncConfig and * can be overwritten by the application. If this function is not implemented by the * application, a default implementation from within the RAIL library will be used * that simply maintains the default channel values in timerSyncConfig. * For example: * @code{.c} * void RAILCb_ConfigSleepTimerSync(RAIL_TimerSyncConfig_t *timerSyncConfig) * { * timerSyncConfig->prsChannel = MY_TIMERSYNC_PRS_CHANNEL; * timerSyncConfig->rtccChannel = MY_TIMERSYNC_RTCC_CHANNEL; * } * @endcode * * If an unsupported channel is selected by the application, \ref RAIL_ConfigSleep() * will return \ref RAIL_STATUS_INVALID_PARAMETER. */ void RAILCb_ConfigSleepTimerSync(RAIL_TimerSyncConfig_t *timerSyncConfig); /** * Initialize RAIL timer synchronization. * * @param[in] railHandle A RAIL instance handle. * @param[in] sleepConfig A sleep configuration. * @return Status code indicating success of the function call. * * @warning As this function relies on PRS and SYSRTC access and RAIL is meant * to run in TrustZone non-secure world, it is not supported if PRS or SYSRTC * are configured as secure peripheral and sleepConfig is set to * \ref RAIL_SleepConfig_t::RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED. It will * return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_ConfigSleep(RAIL_Handle_t railHandle, RAIL_SleepConfig_t sleepConfig); /** * Initialize RAIL timer synchronization. * * @param[in] railHandle A RAIL instance handle. * @param[in] syncConfig A non-NULL pointer to the timer synchronization configuration. * @return Status code indicating success of the function call. * * The default structure used to enable timer synchronization across sleep is * \ref RAIL_TIMER_SYNC_DEFAULT. * * @warning As this function relies on PRS and SYSRTC access and RAIL is meant * to run in TrustZone non-secure world, it is not supported if PRS or SYSRTC * are configured as secure peripheral and syncConfig->sleep is set to * \ref RAIL_SleepConfig_t::RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED. It will * return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_ConfigSleepAlt(RAIL_Handle_t railHandle, const RAIL_TimerSyncConfig_t *syncConfig); /** * Stop the RAIL timer(s) and prepare RAIL for sleep. * * @param[in] wakeupProcessTime Time in microseconds that the application * and hardware need to recover from sleep state. * @param[out] deepSleepAllowed A pointer to boolean that will be set * true if system can go to deep sleep or false if system must not go * to deep sleep (EM2 or lower energy modes). * @return Status code indicating success of the function call. * * @warning The active RAIL configuration must be idle to enable sleep. * * @note This API must not be called if RAIL Power Manager is initialized. */ RAIL_Status_t RAIL_Sleep(uint16_t wakeupProcessTime, bool *deepSleepAllowed); /** * Wake RAIL from sleep and restart the RAIL timer(s). * * @param[in] elapsedTime Add this sleep duration in microseconds * to the RAIL timer(s) before restarting it(them). * @return Status code indicating success of the function call. * * If the timer sync was enabled by \ref RAIL_ConfigSleep(), synchronize the RAIL * timer(s) using an alternate timer. Otherwise, add elapsedTime to the RAIL * timer(s). * * @note This API must not be called if RAIL Power Manager is initialized. */ RAIL_Status_t RAIL_Wake(RAIL_Time_t elapsedTime); /** * Initialize RAIL Power Manager. * * @return Status code indicating success of the function call. * * @note This function must be called only when the application is built * and initialized with Power Manager plugin and when the radio is idle. * RAIL will perform timer synchronization, upon transitioning from EM2 or * lower to EM1 or higher energy mode or vice-versa, in the Power Manager EM * transition callback. * * @warning Since EM transition callbacks are not called in a deterministic * order, it is suggested to not call any RAIL time dependent APIs * in an EM transition callback. * * @warning As this function relies on EMU access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if EMU is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_InitPowerManager(void); /** * Stop the RAIL Power Manager. * * @return Status code indicating success of the function call. * * @note The active RAIL configuration must be idle to disable radio * power manager and there should be no outstanding requirements by * radio power manager. */ RAIL_Status_t RAIL_DeinitPowerManager(void); /** @} */ // end of group Sleep /****************************************************************************** * Events *****************************************************************************/ /** * @addtogroup Events * @brief APIs related to events * @{ */ /** * Configure radio events. * * @param[in] railHandle A RAIL instance handle. * @param[in] mask A bitmask of events to configure. * @param[in] events A bitmask of events to trigger \ref RAIL_Config_t::eventsCallback. * @return Status code indicating success of the function call. * * Sets up which radio interrupts generate a RAIL event. The full list of * events is in \ref RAIL_Events_t. */ RAIL_Status_t RAIL_ConfigEvents(RAIL_Handle_t railHandle, RAIL_Events_t mask, RAIL_Events_t events); /** @} */ // end of group Events /****************************************************************************** * Data Management *****************************************************************************/ /// @addtogroup Data_Management Data Management /// @brief Data management functions /// /// These functions allow the application to choose how data is presented to /// the application. RAIL provides data in a packet-based method or in a /// FIFO-based method. As originally conceived, /// \ref RAIL_DataMethod_t::PACKET_MODE was designed for handling packets /// that fit within RAIL's FIFOs while \ref RAIL_DataMethod_t::FIFO_MODE /// was designed for handling packets larger than RAIL's FIFOs could hold. /// Conceptually it is still useful to think of these modes this way, but /// functionally their distinction has become blurred by improvements in /// RAIL's flexibility -- applications now have much more control over both /// receive and transmit FIFO sizes, and the FIFO-management and threshold /// APIs and related events are no longer restricted to \ref /// RAIL_DataMethod_t::FIFO_MODE operation but can be used in \ref /// RAIL_DataMethod_t::PACKET_MODE too. /// /// The application can configure RAIL data management through \ref /// RAIL_ConfigData(). This function allows the application to specify the type /// of radio data (\ref RAIL_TxDataSource_t and \ref RAIL_RxDataSource_t) and /// the method of interacting with data (\ref RAIL_DataMethod_t). By default, /// RAIL configures TX and RX both with packet data source and \ref /// RAIL_DataMethod_t::PACKET_MODE. /// /// For transmit, \ref RAIL_DataMethod_t::PACKET_MODE and \ref /// RAIL_DataMethod_t::FIFO_MODE are functionally the same: /// - When not actively transmitting, load a packet's initial transmit /// data using \ref RAIL_WriteTxFifo() with reset set to true. Alternatively /// this data copying can be avoided by changing the transmit FIFO to an /// already-loaded section of memory with \ref RAIL_SetTxFifo(). /// - When actively transmitting, load remaining transmit data with /// \ref RAIL_WriteTxFifo() with reset set to false. /// - If transmit packets exceed the FIFO size, set the transmit FIFO /// threshold through \ref RAIL_SetTxFifoThreshold(). The \ref /// RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_TX_FIFO_ALMOST_EMPTY /// will occur telling the application to load more TX packet data, if /// needed, to prevent a \ref RAIL_EVENT_TX_UNDERFLOW event from occurring. /// One can get how much space is available in the transmit FIFO for more /// transmit data through \ref RAIL_GetTxFifoSpaceAvailable(). /// - After transmit completes, the transmit FIFO can be manually reset /// with \ref RAIL_ResetFifo(), but this should rarely be necessary. /// /// The transmit FIFO is specified by the application and its size is /// the value returned from the most recent call to \ref RAIL_SetTxFifo(). /// The transmit FIFO is edge-based in that it only provides the \ref /// RAIL_EVENT_TX_FIFO_ALMOST_EMPTY event once when the threshold is crossed /// in the emptying direction. /// /// For receive, the distinction between \ref RAIL_DataMethod_t::PACKET_MODE /// and \ref RAIL_DataMethod_t::FIFO_MODE basically boils down to how /// unsuccessfully-received packets are handled. In \ref /// RAIL_DataMethod_t::PACKET_MODE, data from such packets is automatically /// rolled back as if the packet was never received, while in \ref /// RAIL_DataMethod_t::FIFO_MODE, rollback does not occur putting more onus /// on the application to deal with that data. /// /// In receive \ref RAIL_DataMethod_t::PACKET_MODE data management: /// - Packet lengths are determined from the Radio Configurator configuration /// and can be read out at the end using \ref RAIL_GetRxPacketInfo(). /// - Received packet data is made available on successful packet completion /// via \ref RAIL_Config_t::eventsCallback with \ref /// RAIL_EVENT_RX_PACKET_RECEIVED which can then use \ref RAIL_GetRxPacketInfo() /// and \ref RAIL_GetRxPacketDetailsAlt() to access packet information and /// \ref RAIL_PeekRxPacket() to access packet data. /// - FILTERED, ABORTED, or FRAMEERROR received packet data is automatically /// rolled back (dropped) without the application needing to worry about /// consuming it. /// The application can choose to not even be bothered with the events /// related to such packets: \ref RAIL_EVENT_RX_ADDRESS_FILTERED, /// \ref RAIL_EVENT_RX_PACKET_ABORTED, or \ref RAIL_EVENT_RX_FRAME_ERROR. /// /// In receive \ref RAIL_DataMethod_t::FIFO_MODE data management: /// - Packet Lengths are determined from the Radio Configurator configuration /// or by application knowledge of packet payload structure. /// - Received data can be retrieved prior to packet completion through /// \ref RAIL_ReadRxFifo() and is never rolled back on FILTERED, ABORTED, or /// FRAMEERROR packets. The application should enable and handle these /// events so it can flush any packet data it's already retrieved. /// - After packet completion, remaining packet data for FILTERED, ABORTED, /// or FRAMEERROR packets remains in the FIFO and the appropriate event is /// triggered to the user. This data may be consumed in the callback unlike /// in packet mode where it is automatically rolled back. At the end of the /// callback all remaining data in the FIFO will be cleaned up as usual. /// Keep in mind that \ref RAIL_GetRxPacketDetailsAlt() provides full packet /// detailed information only for successfully received packets. /// /// Common receive data management features: /// - Set the receive FIFO threshold through \ref RAIL_SetRxFifoThreshold(). The /// \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL /// will occur telling the application to consume some RX packet data to /// prevent a \ref RAIL_EVENT_RX_FIFO_OVERFLOW event from occurring. /// - Get receive FIFO count information through /// \ref RAIL_GetRxPacketInfo(\ref RAIL_RX_PACKET_HANDLE_NEWEST) /// (or \ref RAIL_GetRxFifoBytesAvailable()). /// - After receive completes and all its data has been consumed, the receive /// FIFO can be manually reset with \ref RAIL_ResetFifo(), though this should /// rarely be necessary and should only be done with the radio idle. /// /// When trying to determine an appropriate threshold, the application needs /// to know the size of each FIFO. The default receive FIFO is internal to RAIL /// with a size of 512 bytes. This can be changed, however, using /// \ref RAIL_SetRxFifo() and the default may be removed entirely by calling /// this from the \ref RAILCb_SetupRxFifo() callback. The receive FIFO event is /// level-based in that the \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL event will /// constantly pend if the threshold is exceeded. This normally means that /// inside this event's callback, the application should empty enough of the FIFO /// to go under the threshold. To defer reading the FIFO to main context, the /// application can disable or re-enable the receive FIFO threshold event using /// \ref RAIL_ConfigEvents() with the mask \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL. /// /// The receive FIFO can store multiple packets and processing of a packet can /// be deferred from the RAIL event callback to main-loop processing /// by using \ref RAIL_HoldRxPacket() in the event callback and /// \ref RAIL_ReleaseRxPacket() in the main-loop. /// On some platforms, the receive FIFO is supplemented by an internal /// fixed-size packet metadata FIFO that limits the number of packets /// RAIL and applications can hold onto for deferred processing. /// See chip-specific documentation, such as \ref efr32_main, for more /// information. /// /// @note When using multiprotocol the receive FIFO is reset /// prior to a protocol switch so held packets will be lost if not processed /// before then. /// /// While \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL occurs solely based on the /// state of the receive FIFO used for packet data, both /// \ref RAIL_EVENT_RX_FIFO_FULL and \ref RAIL_EVENT_RX_FIFO_OVERFLOW /// can occur coincident with packet completion when either that or the /// internal packet metadata FIFO fills or overflows. /// \ref RAIL_EVENT_RX_FIFO_FULL informs the application it should /// immediately process and free up the oldest packets/data to make room /// for new packets/data, reducing the possibility of packet/data loss /// and \ref RAIL_EVENT_RX_FIFO_OVERFLOW. /// /// Before a packet is fully received you can always use \ref /// RAIL_PeekRxPacket() to look at the contents. In FIFO mode, you may also /// consume its data with \ref RAIL_ReadRxFifo(). Remember that none of these /// APIs will read across a packet boundary (even in FIFO mode) so you will /// need to handle each received packet individually. /// /// While RAIL defaults to \ref RAIL_DataMethod_t::PACKET_MODE, the /// application can explicitly initialize RAIL for \ref /// RAIL_DataMethod_t::PACKET_MODE in the following manner: /// @code{.c} /// extern RAIL_Handle_t railHandle; /// /// void configRailForPacketModeOperation(void) /// { /// RAIL_DataConfig_t railDataConfig = { /// .txSource = TX_PACKET_DATA, /// .rxSource = RX_PACKET_DATA, /// .txMethod = PACKET_MODE, /// .rxMethod = PACKET_MODE, /// }; /// /// (void) RAIL_ConfigData(railHandle, &railDataConfig); /// /// // Events that can occur in Packet Mode: /// // RAIL_EVENT_TX_PACKET_SENT /// // RAIL_EVENT_RX_PACKET_RECEIVED /// // and optionally (packet data automatically dropped): /// // RAIL_EVENT_RX_ADDRESS_FILTERED /// // RAIL_EVENT_RX_PACKET_ABORTED /// // RAIL_EVENT_RX_FRAME_ERROR /// // and if enabled: /// // RAIL_EVENT_TX_UNDERFLOW /// // RAIL_EVENT_TXACK_UNDERFLOW /// // RAIL_EVENT_TX_FIFO_ALMOST_EMPTY /// // RAIL_EVENT_RX_FIFO_ALMOST_FULL /// } /// @endcode /// /// Initializing RAIL for \ref RAIL_DataMethod_t::FIFO_MODE requires a few /// more function calls: /// @code{.c} /// extern RAIL_Handle_t railHandle; /// /// void config_rail_for_fifo_mode_operation(void) /// { /// RAIL_DataConfig_t railDataConfig = { /// .txSource = TX_PACKET_DATA, /// .rxSource = RX_PACKET_DATA, /// .txMethod = FIFO_MODE, /// .rxMethod = FIFO_MODE, /// }; /// /// (void) RAIL_ConfigData(railHandle, &railDataConfig); /// /// // Gets the size of the FIFOs. /// // Assume that the transmit and receive FIFOs are the same size /// uint16_t fifoSize = RAIL_GetTxFifoSpaceAvailable(railHandle); /// /// // Sets the transmit and receive FIFO thresholds. /// // For this example, set the threshold in the middle of each FIFO. /// (void) RAIL_SetRxFifoThreshold(railHandle, fifoSize / 2); /// (void) RAIL_SetTxFifoThreshold(railHandle, fifoSize / 2); /// /// // Events that can occur in FIFO mode: /// // RAIL_EVENT_TX_FIFO_ALMOST_EMPTY /// // RAIL_EVENT_TX_UNDERFLOW /// // RAIL_EVENT_TXACK_UNDERFLOW /// // RAIL_EVENT_TX_PACKET_SENT /// // RAIL_EVENT_RX_FIFO_ALMOST_FULL /// // RAIL_EVENT_RX_FIFO_OVERFLOW /// // RAIL_EVENT_RX_ADDRESS_FILTERED /// // RAIL_EVENT_RX_PACKET_ABORTED /// // RAIL_EVENT_RX_FRAME_ERROR /// // RAIL_EVENT_RX_PACKET_RECEIVED /// } /// @endcode /// /// On receive, an application can use a different \ref RAIL_RxDataSource_t that /// is only compatible with \ref RAIL_DataMethod_t::FIFO_MODE. All that differs /// from the FIFO mode example above is the RAIL_DataConfig_t::rxSource setting. /// IQ data samples are taken at the hardware's oversample rate and the amount /// of data can easily overwhelm the CPU processing time. The sample rate /// depends on the chosen PHY, as determined by the data rate and the decimation /// chain. It is not recommended to use the IQ data source with sample /// rates above 300 k samples/second because the CPU might not be able to keep up /// with the data stream. Depending on the application and the needed CPU /// bandwidth, slower data rates may be required. On EFR32xG22 and later /// platforms, it is recommended to reset the RX buffer before initiating a /// receive for all modes except \ref RAIL_RxDataSource_t::RX_PACKET_DATA since /// the RX buffer has to be 32-bit aligned. If the buffer is not reset /// but is 32-bit aligned, capture is performed on the remaining space available. /// If the buffer is not reset and is not 32-bit aligned, then /// RAIL_ConfigData() returns \ref RAIL_STATUS_INVALID_STATE. /// @code{.c} /// // Reset RX buffer (EFR32xG22 and later platforms) /// RAIL_ResetFifo(railHandle, false, true); /// /// // IQ data is provided into the receive FIFO. /// RAIL_DataConfig_t railDataConfig = { /// .txSource = TX_PACKET_DATA, /// .rxSource = RX_IQDATA_FILTLSB, /// .txMethod = FIFO_MODE, /// .rxMethod = FIFO_MODE, /// }; /// /// // IQ data comes in the following format when reading out of the FIFO: /// //------------------------------------ /// // I[LSB] | I[MSB] | Q[LSB] | Q[MSB] | /// //------------------------------------ /// @endcode /// /// @{ /** * RAIL data management configuration * * @param[in] railHandle A RAIL instance handle. * @param[in] dataConfig A pointer to a non-NULL RAIL data configuration structure. * @return Status code indicating success of the function call. * * This function configures how RAIL manages data. The application can * configure RAIL to receive data in a packet-based or FIFO-based manner. * \ref RAIL_DataMethod_t::FIFO_MODE is necessary to receive packets larger * than the radio's receive FIFO. It is also required for receive data * sources other than \ref RAIL_RxDataSource_t::RX_PACKET_DATA. * * Generally with \ref RAIL_DataMethod_t::FIFO_MODE, the application sets * appropriate FIFO thresholds via \ref RAIL_SetTxFifoThreshold() and * \ref RAIL_SetRxFifoThreshold() and then enables and handles the * \ref RAIL_EVENT_TX_FIFO_ALMOST_EMPTY event callback (to feed more packet * data via \ref RAIL_WriteTxFifo() before the FIFO underflows) and the \ref * RAIL_EVENT_RX_FIFO_ALMOST_FULL event callback (to consume packet data * via \ref RAIL_ReadRxFifo() before the receive FIFO overflows). * * When configuring TX for \ref RAIL_DataMethod_t::FIFO_MODE, this * function resets the transmit FIFO. When configuring TX or RX for * \ref RAIL_DataMethod_t::PACKET_MODE, this function will reset * the corresponding FIFO thresholds such that they won't trigger the * \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL or \ref RAIL_EVENT_TX_FIFO_ALMOST_EMPTY * events. * * When \ref RAIL_DataConfig_t::rxMethod is set to \ref * RAIL_DataMethod_t::FIFO_MODE, the radio won't drop packet data of * aborted or CRC error packets, but will present it to the application * to deal with accordingly. On completion of erroneous packets, the * \ref RAIL_Config_t::eventsCallback with \ref RAIL_EVENT_RX_PACKET_ABORTED, * \ref RAIL_EVENT_RX_FRAME_ERROR, or \ref RAIL_EVENT_RX_ADDRESS_FILTERED will * tell the application it can drop any data it read via \ref RAIL_ReadRxFifo() during reception. * For CRC error packets when the \ref RAIL_RX_OPTION_IGNORE_CRC_ERRORS * RX option is in effect, the application should check for that from the * \ref RAIL_RxPacketStatus_t obtained by calling \ref RAIL_GetRxPacketInfo(). * RAIL will automatically flush any remaining packet data after reporting * one of these packet completion events or the application can explicitly * flush it by calling \ref RAIL_ReleaseRxPacket(). * * When \ref RAIL_DataConfig_t::rxMethod is set to \ref * RAIL_DataMethod_t::PACKET_MODE, the radio will roll back (drop) all packet * data associated with aborted packets including those with CRC errors * (unless configured to ignore CRC errors via the * \ref RAIL_RX_OPTION_IGNORE_CRC_ERRORS RX option). The application will * never have to deal with packet data from these packets. * In either mode, the application can set RX options as needed. * * When \ref RAIL_DataConfig_t::rxSource is set to a value other than * \ref RX_PACKET_DATA and \ref RAIL_Config_t::eventsCallback * \ref RAIL_EVENT_RX_FIFO_OVERFLOW is enabled RX will be terminated * if a RX FIFO overflow occurs. If \ref RAIL_EVENT_RX_FIFO_OVERFLOW * is not enabled, data will be discarded until the overflow condition * is resolved. To continue capturing data RX must be restarted using * \ref RAIL_StartRx(). * */ RAIL_Status_t RAIL_ConfigData(RAIL_Handle_t railHandle, const RAIL_DataConfig_t *dataConfig); /** * Write data to the transmit FIFO previously established by RAIL_SetTxFifo(). * * @param[in] railHandle A RAIL instance handle. * @param[in] dataPtr A pointer to transmit data. * @param[in] writeLength A number of bytes to write to the transmit FIFO. * @param[in] reset If true, resets transmit FIFO before writing the data. * @return The number of bytes written to the transmit FIFO. * * This function copies writeLength bytes of data from the provided dataPtr into the * transmit FIFO previously established by \ref RAIL_SetTxFifo() or \ref RAIL_Init(). * If the requested writeLength exceeds the current number of bytes open * in the transmit FIFO, the function only writes until the transmit FIFO * is full. The function returns the number of bytes written to the transmit * FIFO or returns zero if railHandle is NULL or if the transmit FIFO is full. * * @note The protocol's packet configuration, as set up by the radio * configurator or via \ref RAIL_SetFixedLength(), determines how many * bytes of data are consumed from the transmit FIFO for a successful transmit * operation, not the writeLength value passed in. If not enough data has * been put into the transmit FIFO, a \ref RAIL_EVENT_TX_UNDERFLOW event will * occur. If too much data is put into the transmit FIFO, the extra data will * either become the first bytes * sent in a subsequent packet, or will be thrown away if the FIFO gets * reset prior to the next transmit. In general, the proper number of * packet bytes to put into the transmit FIFO are all payload bytes except * for any CRC bytes, which the packet configuration causes to be sent * automatically. * * @note This function does not utilize a critical section but, depending on the * application, calling it within a critical section could be appropriate. */ uint16_t RAIL_WriteTxFifo(RAIL_Handle_t railHandle, const uint8_t *dataPtr, uint16_t writeLength, bool reset); /** * Set the address of the transmit FIFO, a circular buffer used for TX data, * possibly pre-populated with transmit data. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] addr An appropriately-aligned (see below) pointer to a read-write memory * location in RAM used as the transmit FIFO. This memory must persist until the next * call to this function or \ref RAIL_SetTxFifoAlt. * @param[in] initLength A number of initial bytes already in the transmit FIFO. * @param[in] size A desired size of the transmit FIFO in bytes. * @return The transmit FIFO size in bytes, 0 if an error occurs. * * This function sets the memory location for the transmit FIFO. \ref RAIL_SetTxFifo or * \ref RAIL_SetTxFifoAlt must be called at least once before any transmit operations occur. * * FIFO size can be determined by the return value of this function. The * chosen size is determined based on the available FIFO sizes supported by the * hardware. Similarly, some hardware has stricter FIFO alignment requirements; * 32-bit alignment provides the maximum portability across all RAIL platforms. * For more on supported FIFO sizes and alignments, see chip-specific * documentation, such as \ref efr32_main. The returned FIFO size will be the * closest allowed size less than or equal to the passed in size parameter, * unless the size parameter is smaller than the minimum FIFO size, in that case * 0 is returned. If the initLength parameter is larger than the returned * size, the FIFO will be filled up to its size. * * A user may write to the custom memory location directly before calling this * function, or use \ref RAIL_WriteTxFifo() to write to the memory location after * calling this function. Users must specify the initLength for * previously-written memory to be set in the transmit FIFO. * * This function reserves the block of RAM starting at addr with a length of the * returned FIFO size, which is used internally as a circular buffer for the * transmit FIFO. It must be able to hold the entire FIFO size. The caller must * guarantee that the custom FIFO remains intact and unchanged (except via calls * to \ref RAIL_WriteTxFifo()) until the next call to this function. * * @note The protocol's packet configuration, as set up by the radio * configurator or via RAIL_SetFixedLength(), determines how many * bytes of data are consumed from the transmit FIFO for a successful transmit * operation, not the initLength value passed in. If not enough data has * been put into the transmit FIFO, a \ref RAIL_EVENT_TX_UNDERFLOW event will * occur. If too much data is put into the transmit FIFO, the extra data * will either become the first bytes * sent in a subsequent packet, or will be thrown away if the FIFO gets * reset prior to the next transmit. In general, the proper number of * packet bytes to put into the transmit FIFO are all payload bytes except * for any CRC bytes which the packet configuration causes to be sent * automatically. */ uint16_t RAIL_SetTxFifo(RAIL_Handle_t railHandle, uint8_t *addr, uint16_t initLength, uint16_t size); /** * Set the address of the transmit FIFO, a circular buffer used for TX data which * can start at offset distance from the FIFO base address. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] addr An appropriately-aligned (see \ref RAIL_SetTxFifo description) * pointer to a read-write memory location in RAM used as the transmit FIFO. This memory * must persist until the next call to this function or \ref RAIL_SetTxFifo. * @param[in] startOffset A number of bytes defining the start position of the TX data * from the transmit FIFO base address, only valid if initLength is not 0. * @param[in] initLength The number of valid bytes already in the transmit FIFO after startOffset. * @param[in] size A desired size of the transmit FIFO in bytes. * @return The transmit FIFO size in bytes, 0 if an error occurs. * * This function is similar to \ref RAIL_SetTxFifo except a startOffset can be specified * to indicate where the transmit packet data starts. This allows an application to * place unaligned initial packet data within the aligned transmit FIFO (initLength > 0). * Specifying a startOffset will not reduce the FIFO threshold or affect * \ref RAIL_GetTxFifoSpaceAvailable(). * \ref RAIL_SetTxFifo or \ref RAIL_SetTxFifoAlt must be called at least once before any transmit * operations occur. * FIFO size handling is quite same as \ref RAIL_SetTxFifo. Only difference is that if the * initLength plus startOffset parameters are larger than the returned size, the FIFO * will be filled up to its size from startOffset. * Note that the startOffset is essentially forgotten after the next transmit -- * i.e. it applies onto to the next transmit operation, and is not re-established when * the transmit FIFO is reset. */ uint16_t RAIL_SetTxFifoAlt(RAIL_Handle_t railHandle, uint8_t *addr, uint16_t startOffset, uint16_t initLength, uint16_t size); /** * Set the address of the receive FIFO, a circular buffer used for receive data. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] addr A pointer to a read-write memory location in RAM used as * the receive FIFO. This memory must persist until the next call to this * function. * @param[in,out] size A pointer to the desired size of the receive * FIFO in bytes. This will be updated with the actual size during the * function call. * @return Status code indicating success of the function call. * * This function sets the memory location for the receive FIFO. It * must be called at least once before any receive operations occur. * * @note After it is called, any prior receive FIFO is orphaned. To avoid * orphaning the default internal 512-byte receive FIFO so it does * not unnecessarily consume RAM resources in your application, * implement \ref RAILCb_SetupRxFifo() to call this function. * * FIFO size can be determined by the return value of this function. The * chosen size is determined based on the available FIFO sizes supported by the * hardware. Similarly, some hardware has stricter FIFO alignment requirements; * 32-bit alignment provides the maximum portability across all RAIL platforms. * For more on supported FIFO sizes and alignments, see chip-specific * documentation, such as \ref efr32_main. The returned FIFO size will be the * closest allowed size less than or equal to the passed in size parameter, * unless the size parameter is smaller than the minimum FIFO size. * * This function reserves the block of RAM starting at addr with a length * of size, which is used internally as a circular buffer for the receive FIFO. * It must be able to hold the entire FIFO size. The caller must guarantee that * the custom FIFO remains intact and unchanged (except via incoming packet data * being written) until the next call to this function. * * In multiprotocol, RAIL currently shares one receive FIFO across all * protocols. This function will return \ref RAIL_STATUS_INVALID_STATE if the * requested \ref RAIL_Handle_t is not active. */ RAIL_Status_t RAIL_SetRxFifo(RAIL_Handle_t railHandle, uint8_t *addr, uint16_t *size); /// Set up the receive FIFO to use. This function is optional to implement. /// /// @param[in] railHandle A RAIL instance handle. /// @return Status code indicating success of the function call. /// /// This callback is called during the \ref RAIL_Init() process to set up the FIFO /// to use for received packets. If not implemented by the application, /// a default implementation from within the RAIL library will be used to /// initialize an internal default 512-byte receive FIFO. /// /// If this function returns an error, the RAIL_Init() process will fail. /// /// During this function, the application should generally call /// \ref RAIL_SetRxFifo(). If that does not happen, the application needs to /// set up the receive FIFO via a call to \ref RAIL_SetRxFifo() before attempting /// to receive any packets. An example implementation may look like the following: /// @code{.c} /// #define RX_FIFO_BYTES 1024 /// static __ALIGNED(RAIL_FIFO_ALIGNMENT) uint8_t rxFifo[RX_FIFO_BYTES]; /// /// RAIL_Status_t RAILCb_SetupRxFifo(RAIL_Handle_t railHandle) /// { /// uint16_t rxFifoBytes = RX_FIFO_BYTES; /// RAIL_Status_t status = RAIL_SetRxFifo(railHandle, &rxFifo[0], &rxFifoBytes); /// if (rxFifoBytes != RX_FIFO_BYTES) { /// // We set up an incorrect FIFO size /// return RAIL_STATUS_INVALID_PARAMETER; /// } /// if (status == RAIL_STATUS_INVALID_STATE) { /// // Allow failures due to multiprotocol /// return RAIL_STATUS_NO_ERROR; /// } /// return status; /// } /// @endcode RAIL_Status_t RAILCb_SetupRxFifo(RAIL_Handle_t railHandle); /** * Read packet data from RAIL's receive FIFO. * * @param[in] railHandle A RAIL instance handle. * @param[out] dataPtr An application-provided pointer to store data. * If NULL, the data is thrown away rather than copied out. * @param[in] readLength A number of packet bytes to read from the FIFO. * @return The number of packet bytes read from the receive FIFO. * * This function reads packet data from the head of receive FIFO and * writes it to the provided dataPtr. It does not permit reading more * data than is available in the FIFO, nor does it permit reading more * data than remains in the oldest unreleased packet. * * Because this function does not have a critical section, use it * only in one context or make sure function calls are protected to prevent * buffer corruption. * * @warning This function is intended for use only with \ref * RAIL_DataMethod_t::FIFO_MODE and should never be called in \ref * RAIL_DataMethod_t::PACKET_MODE where it could lead to receive FIFO * corruption. * * @note When reading data from an arriving packet that is not yet complete, * keep in mind its data is highly suspect because it has not yet passed * any CRC integrity checking. Also note that the packet could be aborted, * canceled, or fail momentarily, invalidating its data in Packet mode. * Furthermore, there is a small chance towards the end of packet reception * that the receive FIFO could include not only packet data received so far, * but also some raw radio-appended info detail bytes that RAIL's * packet-completion processing will subsequently deal with. It's up to the * application to know its packet format well enough to avoid reading this * info because it will corrupt the packet's details and possibly corrupt the * receive FIFO. */ uint16_t RAIL_ReadRxFifo(RAIL_Handle_t railHandle, uint8_t *dataPtr, uint16_t readLength); /** * Configure the RAIL transmit FIFO almost empty threshold. * * @param[in] railHandle A RAIL instance handle. * @param[in] txThreshold The threshold below which the * \ref RAIL_EVENT_TX_FIFO_ALMOST_EMPTY event will fire. * @return Configured transmit FIFO threshold value. * * This function configures the threshold for the transmit FIFO. When the * number of bytes in the transmit FIFO falls below the configured threshold, * \ref RAIL_Config_t::eventsCallback will fire with \ref * RAIL_EVENT_TX_FIFO_ALMOST_EMPTY set. * The txThreshold value should be smaller than or equal to the transmit * FIFO size; higher values will be pegged to the FIFO size. * A value of 0 or \ref RAIL_FIFO_THRESHOLD_DISABLED will disable the * threshold, returning \ref RAIL_FIFO_THRESHOLD_DISABLED. */ uint16_t RAIL_SetTxFifoThreshold(RAIL_Handle_t railHandle, uint16_t txThreshold); /** * Configure the RAIL receive FIFO almost full threshold. * * @param[in] railHandle A RAIL instance handle. * @param[in] rxThreshold The threshold above which the * \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL event will fire. * @return Configured receive FIFO threshold value. * * This function configures the threshold for the receive FIFO. When the * number of bytes of packet data in the receive FIFO exceeds the * configured threshold, \ref RAIL_Config_t::eventsCallback will keep * firing with \ref RAIL_EVENT_RX_FIFO_ALMOST_FULL set as long as the * number of bytes in the receive FIFO exceeds the configured threshold * value. The rxThreshold value should be smaller than the receive FIFO * size; anything else, including a value of * \ref RAIL_FIFO_THRESHOLD_DISABLED, will disable the threshold, * returning \ref RAIL_FIFO_THRESHOLD_DISABLED. * * @note To avoid sticking in the event handler (even in idle state): * 1. Disable the event (via the config events API or the * \ref RAIL_FIFO_THRESHOLD_DISABLED parameter). * 2. Increase FIFO threshold. * 3. Read the FIFO (that's not an option in * \ref RAIL_DataMethod_t::PACKET_MODE) in the event handler. */ uint16_t RAIL_SetRxFifoThreshold(RAIL_Handle_t railHandle, uint16_t rxThreshold); /** * Get the RAIL transmit FIFO almost empty threshold value. * * @param[in] railHandle A RAIL instance handle. * @return Configured TX Threshold value in bytes. * * Retrieves the configured TX threshold value. */ uint16_t RAIL_GetTxFifoThreshold(RAIL_Handle_t railHandle); /** * Get the RAIL receive FIFO almost full threshold value. * * @param[in] railHandle A RAIL instance handle. * @return Configured RX Threshold value in bytes. * * Retrieves the configured RX threshold value. */ uint16_t RAIL_GetRxFifoThreshold(RAIL_Handle_t railHandle); /** * Reset the RAIL transmit and/or receive FIFOs. * * @param[in] railHandle A RAIL instance handle. * @param[in] txFifo If true, reset the transmit FIFO. * @param[in] rxFifo If true, reset the receive FIFO and its internal metadata FIFO. * @return Status code indicating success of the function call. * * This function can reset each FIFO independently. * The application should not reset the receive FIFO while receiving a frame, * nor should it reset the transmit FIFO while transmitting a frame. */ RAIL_Status_t RAIL_ResetFifo(RAIL_Handle_t railHandle, bool txFifo, bool rxFifo); /** * Get the number of bytes used in the receive FIFO. * Only use this function in RX \ref RAIL_DataMethod_t::FIFO_MODE. * Apps should use \ref RAIL_GetRxPacketInfo() instead. * * @param[in] railHandle A RAIL instance handle. * @return Number of bytes used in the receive FIFO. * * This function indicates how much packet-related data exists in the receive * FIFO that could be read. * * @note The number of bytes returned may not just reflect the current * packet's data but could also include raw appended info bytes added * after successful packet reception and bytes from subsequently received * packets. It is up to the app to never try to consume more than the * packet's actual data when using the value returned here in a subsequent * call to \ref RAIL_ReadRxFifo(), otherwise the receive FIFO will be corrupted. */ uint16_t RAIL_GetRxFifoBytesAvailable(RAIL_Handle_t railHandle); /** * Get the number of bytes unused in the transmit FIFO. * * @param[in] railHandle A RAIL instance handle. * @return Number of bytes unused in the transmit FIFO. * * This function indicates how much space is available in the transmit FIFO * for writing additional packet data. */ uint16_t RAIL_GetTxFifoSpaceAvailable(RAIL_Handle_t railHandle); /** @} */ // end of group Data_Management /****************************************************************************** * State Transitions *****************************************************************************/ /** * @addtogroup State_Transitions State Transitions * @{ */ /** * Configure RAIL automatic state transitions after RX. * * @param[in] railHandle A RAIL instance handle. * @param[in] transitions A pointer to the state transitions to apply after reception. * @return Status code indicating success of the function call. * * This function fails if unsupported transitions are passed in or if the * radio is currently in the RX state. Success can transition to TX, RX, or * IDLE, while error can transition to RX or IDLE. The timings of state * transitions from the RX state are not guaranteed when packets are longer * than 16 seconds on-air. */ RAIL_Status_t RAIL_SetRxTransitions(RAIL_Handle_t railHandle, const RAIL_StateTransitions_t *transitions); /** * Get the current RAIL automatic state transitions after RX. * * @param[in] railHandle A RAIL instance handle. * @param[out] transitions A pointer to the state transitions that RAIL applies after receive. * @return Status code indicating a success of the function call. * * Retrieves the current state transitions after RX and stores them in the * transitions argument. */ RAIL_Status_t RAIL_GetRxTransitions(RAIL_Handle_t railHandle, RAIL_StateTransitions_t *transitions); /** * Configure RAIL automatic state transitions after TX. * * @param[in] railHandle A RAIL instance handle. * @param[in] transitions A pointer to the state transitions to apply after transmission. * @return Status code indicating a success of the function call. * * This function fails if unsupported transitions are passed in or if the * radio is currently in the TX state. Success and error can each transition * to RX or IDLE only, not TX. For the ability to run repeated transmits, see * \ref RAIL_SetNextTxRepeat(). Calling this function will clear any repeated * transmissions set up by \ref RAIL_SetNextTxRepeat(). */ RAIL_Status_t RAIL_SetTxTransitions(RAIL_Handle_t railHandle, const RAIL_StateTransitions_t *transitions); /** * Get the current RAIL automatic state transitions after TX. * * @param[in] railHandle A RAIL instance handle. * @param[out] transitions A pointer to the state transitions that RAIL applies after transmission. * @return Status code indicating a success of the function call. * * Retrieves the current state transitions after TX and stores them in the * transitions argument. */ RAIL_Status_t RAIL_GetTxTransitions(RAIL_Handle_t railHandle, RAIL_StateTransitions_t *transitions); /** * Set up automatic repeated transmits after the next transmit. * * @param[in] railHandle A RAIL instance handle. * @param[in] repeatConfig A pointer to the configuration structure for repeated transmits. * @return Status code indicating a success of the function call. * * Repeated transmits will occur after an application-initiated transmit caused * by calling one of the \ref Packet_TX APIs. The repetition will only occur * after the first application-initiated transmit after this function is * called. Future repeated transmits must be requested by calling this function * again. * * Each repeated transmit that occurs will have full \ref PTI information, and * will receive events such as \ref RAIL_EVENT_TX_PACKET_SENT as normal. * * If a TX error occurs during the repetition, the process will abort and the * TX error transition from \ref RAIL_SetTxTransitions() will be used. If the * repetition completes successfully, then the TX success transition from * \ref RAIL_SetTxTransitions() will be used. * * Use \ref RAIL_GetTxPacketsRemaining() if need to know how many transmit * completion events are expected before the repeating sequence is done, or * how many were not performed due to a transmit error. * * Any call to \ref RAIL_Idle(), \ref RAIL_StopTx(), or \ref * RAIL_SetTxTransitions() will clear the pending * repeated transmits. The state will also be cleared by another call to this * function. A DMP switch will clear this * state only if the initial transmit triggering the repeated transmits has * started. * * One can change the repeated transmit configuration by re-calling * this function with new parameters as long as that occurs prior to * calling a \ref Packet_TX API. Passing a \ref * RAIL_TxRepeatConfig_t::iterations count of 0 will prevent the next * transmit from repeating. * * The application is responsible for populating the transmit data to be used * by the repeated transmits via \ref RAIL_SetTxFifo() or \ref RAIL_WriteTxFifo(). * Data will be transmitted from the transmit FIFO. If the transmit FIFO does * not have sufficient data to transmit, a TX error will be caused and a \ref * RAIL_EVENT_TX_UNDERFLOW will occur. In order to avoid an underflow, the * application should queue data to be transmitted as early as possible. * Consider using \ref RAIL_TX_OPTION_RESEND if the same packet data is to * be repeated: then the transmit FIFO only needs to be set/written once. * * Do not call this function after starting a transmit operation via a \ref * Packet_TX API call or * before processing the final transmit completion event of a prior transmit. * This function will fail to (re)configure the repetition if a transmit of any * kind is ongoing, including during the time between an initial transmit and * the end of a previously-configured repetition. * * @note Use the compile time symbol \ref RAIL_SUPPORTS_TX_TO_TX or the runtime * call \ref RAIL_SupportsTxToTx() to check whether the platform supports * this feature. */ RAIL_Status_t RAIL_SetNextTxRepeat(RAIL_Handle_t railHandle, const RAIL_TxRepeatConfig_t *repeatConfig); /** * Get the number of transmits remaining in a repeat operation. * Must only be called from within event callback context when handling * one of the \ref RAIL_EVENTS_TX_COMPLETION events. * * @param[in] railHandle A RAIL instance handle. * @return transmits remaining as described below. * * If the TX completion event is \ref RAIL_EVENT_TX_PACKET_SENT the * returned value indicates how many more such events are expected * before the repeat transmit operation is done. Due to interrupt * latency and timing, this may be an overcount if greater than 0 * but is guaranteed to be accurate when 0. * * If the TX completion event is an error, the returned value indicates * the number of requested transmits that were not performed. For * \ref RAIL_EVENT_TX_ABORTED and \ref RAIL_EVENT_TX_UNDERFLOW the * count does not include the failing transmit itself. For the other * errors where a transmit never started or was blocked, the count * would include the failing transmit, which may be one higher than * the configured \ref RAIL_TxRepeatConfig_t::iterations if it was * the original transmit that was blocked. * * If an infinite repeat was configured, this will return \ref * RAIL_TX_REPEAT_INFINITE_ITERATIONS. */ uint16_t RAIL_GetTxPacketsRemaining(RAIL_Handle_t railHandle); /** * Configure RAIL automatic state transition timing. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] timings A pointer to the timings used to configure the RAIL state * machine. This structure is updated with the actual times that were * set, if an input timing is invalid. * @return Status code indicating a success of the function call. * * The timings given are close to the actual transition time. However, * a still uncharacterized software overhead occurs. Also, timings are not * always adhered to when using an automatic transition after an error, due to * the cleanup required to recover from the error. */ RAIL_Status_t RAIL_SetStateTiming(RAIL_Handle_t railHandle, RAIL_StateTiming_t *timings); /** * Place the radio into an idle state. * * @param[in] railHandle A RAIL instance handle. * @param[in] mode The method for shutting down the radio. * @param[in] wait Whether this function should wait for the radio to reach * idle before returning. * @return \ref RAIL_STATUS_NO_ERROR if the radio has idled by the time this * function returns, or \ref RAIL_STATUS_SUSPENDED if it is still in the * process of idling. * * This function is used to remove the radio from TX and RX states. How these * states are left is defined by the mode parameter. * * In multiprotocol, this API will also cause the radio to be yielded so that * other tasks can be run. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_Idle(RAIL_Handle_t railHandle, RAIL_IdleMode_t mode, bool wait); /** * Get the current radio state. * * @param[in] railHandle A RAIL instance handle. * @return An enumeration for the current radio state. * * Returns the state of the radio as a bitmask containing: * \ref RAIL_RF_STATE_IDLE, \ref RAIL_RF_STATE_RX, \ref RAIL_RF_STATE_TX, * and \ref RAIL_RF_STATE_ACTIVE. \ref RAIL_RF_STATE_IDLE, \ref * RAIL_RF_STATE_RX, and \ref RAIL_RF_STATE_TX bits are mutually exclusive. * The radio can transition through intermediate states, * which are not reported but are instead considered part of the state * most closely associated. For example, when the radio is warming up * or shutting down the transmitter or receiver, this function returns * \ref RAIL_RF_STATE_TX or \ref RAIL_RF_STATE_RX, respectively. * When transitioning directly from RX to TX or vice-versa, this function * returns the earlier state. * * @note For a more detailed radio state, see \ref RAIL_GetRadioStateDetail(). */ RAIL_RadioState_t RAIL_GetRadioState(RAIL_Handle_t railHandle); /** * Get the detailed current radio state. * * @param[in] railHandle A RAIL instance handle. * @return An enumeration for the current detailed radio state. * * Returns the state of the radio as a bitmask. The three core radio states * IDLE, RX, and TX are represented by mutually exclusive bits \ref * RAIL_RF_STATE_DETAIL_IDLE_STATE, \ref RAIL_RF_STATE_DETAIL_RX_STATE, and * \ref RAIL_RF_STATE_DETAIL_TX_STATE respectively. If the radio is * transitioning between these three states, the returned bitmask will have * \ref RAIL_RF_STATE_DETAIL_TRANSITION set along with a bit corresponding to * the destination core radio state. If, while in the receive state, the radio * is actively receiving a packet, \ref RAIL_RF_STATE_DETAIL_ACTIVE will be set; * otherwise, this bit will be clear. If frame detection is disabled, \ref * RAIL_RF_STATE_DETAIL_NO_FRAMES in the returned state bitmask will be set; * otherwise, this bit will be clear. If the radio is performing an LBT/CSMA * operation (e.g., a backoff period) \ref RAIL_RF_STATE_DETAIL_LBT in the * returned state bitmask will be set; otherwise, this bit will be clear. * * For the most part, the more detailed radio states returned by this API * correspond to radio states returned by \ref RAIL_GetRadioState() as follows: * * \ref RAIL_RadioStateDetail_t \ref RAIL_RadioState_t * RAIL_RF_STATE_DETAIL_INACTIVE RAIL_RF_STATE_INACTIVE * RAIL_RF_STATE_DETAIL_IDLE_STATE * | RAIL_STATE_DETAIL_TRANSITION If RX overflow or leaving RX unforced: * RAIL_RF_STATE_RX * Else if leaving TX unforced: * RAIL_RF_STATE_TX * Else: * RAIL_RF_STATE_IDLE * RAIL_RF_STATE_DETAIL_IDLE_STATE RAIL_RF_STATE_IDLE * RAIL_RF_STATE_DETAIL_IDLE_STATE * | RAIL_STATE_DETAIL_LBT RAIL_RF_STATE_TX * RAIL_RF_STATE_DETAIL_RX_STATE * | RAIL_STATE_DETAIL_TRANSITION If leaving TX: * RAIL_RF_STATE_TX * Else: * RAIL_RF_STATE_RX * RAIL_RF_STATE_DETAIL_RX_STATE * | RAIL_RF_STATE_DETAIL_TRANSITION * | RAIL_RF_STATE_DETAIL_NO_FRAMES If leaving TX: * RAIL_RF_STATE_TX * Else: * RAIL_RF_STATE_RX * RAIL_RF_STATE_DETAIL_RX_STATE RAIL_RF_STATE_RX * RAIL_RF_STATE_DETAIL_RX_STATE * | RAIL_RF_STATE_DETAIL_NO_FRAMES RAIL_RF_STATE_RX * RAIL_RF_STATE_DETAIL_RX_STATE * | RAIL_RF_STATE_DETAIL_LBT RAIL_RF_STATE_RX * RAIL_RF_STATE_DETAIL_RX_STATE * | RAIL_RF_STATE_DETAIL_NO_FRAMES * | RAIL_RF_STATE_DETAIL_LBT RAIL_RF_STATE_RX * RAIL_RF_STATE_DETAIL_RX_STATE * | RAIL_RF_STATE_DETAIL_ACTIVE RAIL_RF_STATE_RX_ACTIVE * RAIL_RF_STATE_DETAIL_TX_STATE * | RAIL_RF_STATE_TRANSITION If leaving RX: * RAIL_RF_STATE_RX * Else: * RAIL_RF_STATE_TX * RAIL_RF_STATE_DETAIL_TX_STATE * | RAIL_RF_STATE_ACTIVE RAIL_RF_STATE_TX_ACTIVE */ RAIL_RadioStateDetail_t RAIL_GetRadioStateDetail(RAIL_Handle_t railHandle); /** * Enable/disable caching of synth calibration value. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable A boolean to enable or disable caching of synth calibration. * @return Status code indicating success of the function call. * * Once enabled, the sequencer will start caching synth calibration values for * channels and apply them instead of performing calibration on every state * transition and channel change. * This will increase the transition time for the first time calibration is * performed. Subsequent state transitions will be faster. The cache size is 2. * \ref RAIL_IEEE802154_SUPPORTS_RX_CHANNEL_SWITCHING internally uses this feature * and there is no need to enable/disable it. This function returns * \ref RAIL_STATUS_INVALID_STATE if we try to disable it while * \ref RAIL_IEEE802154_SUPPORTS_RX_CHANNEL_SWITCHING is enabled. * * @note This function will improve the minimum timings that can be achieved in * \ref RAIL_StateTiming_t::idleToRx, \ref RAIL_StateTiming_t::idleToTx, * \ref RAIL_StateTiming_t::rxToTx, \ref RAIL_StateTiming_t::txToRx and * \ref RAIL_StateTiming_t::txToTx. A call to \ref RAIL_SetStateTiming() * is needed to achieve lower transition times. * * @note On a protocol switch the cache is cleared, so it is not suitable for * applications where a protocol switch happens frequently, like with * Dynamic Multiprotocol. */ RAIL_Status_t RAIL_EnableCacheSynthCal(RAIL_Handle_t railHandle, bool enable); /** @} */ // end of group State_Transitions /****************************************************************************** * Transmit *****************************************************************************/ /** * @addtogroup Transmit * @brief APIs related to transmitting data packets * @{ */ /// @addtogroup PA Power Amplifier (PA) /// @brief APIs for interacting with one of the on chip PAs. /// /// These APIs let you configure the on-chip PA to get the appropriate output /// power. /// /// These are the function types: /// 1) Configuration functions: These functions set and get configuration /// for the PA. In this case, "configuration" refers to a) indicating /// which PA to use, b) the voltage supplied by your board to the PA, /// and c) the ramp time over which to ramp the PA up to its full /// power. /// 2) Power-setting functions: These functions consume the actual /// values written to the PA registers and write them appropriately. /// These values are referred to as "(raw) power levels". The range of /// acceptable values for these functions depends on which PA is /// currently active. The higher the power level set, the higher /// the dBm power output by the radio. However, the mapping /// between dBm and these power levels can vary greatly between /// modules/boards. /// 3) Conversion functions: These functions convert /// between the "power levels" discussed previously and the /// dBm values output by the radio. Continue reading for more information /// about unit conversion. /// /// The accuracy of the radio output power is application-specific. /// For some protocols or channels, the protocol itself or /// legal limitations require applications to know exactly what power /// they're transmitting at, in dBm. Other applications do not have /// these restrictions, and users determine power level(s) /// that fit their criteria for the trade-off between radio range and /// power savings, regardless of what dBm power that maps to. /// /// \ref RAIL_ConvertRawToDbm() and \ref RAIL_ConvertDbmToRaw(), /// which convert between the dBm power and the raw power levels, /// provide a solution that fits all these applications. /// The levels of customization are outlined below: /// 1) No customization needed: for a given dBm value, the result /// of \ref RAIL_ConvertDbmToRaw() provides an appropriate /// raw power level that, when written to the registers via /// \ref RAIL_SetTxPower(), causes the radio to output at that /// dBm power. In this case, no action is needed by the user, /// the WEAK versions of the conversion functions can be used /// and the default include paths in pa_conversions_efr32.h can /// be used. /// 2) The mapping of power level to dBm is not ideal, but the /// level of precision is sufficient: In pa_conversions_efr32.c, /// the WEAK versions of the conversion functions work by using /// 8-segment piecewise linear curves to convert between dBm /// and power levels for PA's with hundreds of power levels /// and simple mapping tables for use with PA's with only a few /// levels. If this method is sufficiently precise, but the mapping /// between power levels and dBm is incorrect, /// copy pa_curves_efr32.h into a new file, updating the segments /// to form a better fit (_DCDC_CURVES or _VBAT_CURVES defines) and /// then add the RAIL_PA_CURVES define to your build with the path /// to the new file. /// 3) A different level of precision is needed and the fit is bad: /// If the piecewise-linear line segment fit is not appropriate for /// your solution, the functions in pa_conversions_efr32.c can be /// totally rewritten, as long as \ref RAIL_ConvertDbmToRaw() and /// \ref RAIL_ConvertRawToDbm() have the same signatures. It is completely /// acceptable to re-write these in a way that makes the /// pa_curves_efr32.h and pa_curve_types_efr32.h files referenced in /// pa_conversions_efr32.h unnecessary. Those files are needed solely /// for the provided conversion methods. /// 4) dBm values are not necessary: If the application does not require /// dBm values at all, overwrite \ref /// RAIL_ConvertDbmToRaw() and \ref RAIL_ConvertRawToDbm() with smaller functions /// (i.e., return 0 or whatever was input). These functions are called /// from within the RAIL library, so they can never be deadstripped, /// but making them as small as possible is the best way to reduce code /// size. From there, call \ref RAIL_SetTxPower(), without /// converting from a dBm value. To stop the library from coercing the /// power based on channels, overwrite \ref RAIL_ConvertRawToDbm() /// to always return 0 and overwrite \ref RAIL_ConvertDbmToRaw() to /// always return 255. /// /// The following is example code that shows how to initialize your PA /// @code{.c} /// #include "pa_conversions_efr32.h" /// /// // A macro RAIL_TX_POWER_CURVES_CONFIG is used as the curve /// // structures used by the provided conversion functions. /// RAIL_TxPowerCurvesConfigAlt_t tx_power_curves_config = RAIL_TX_POWER_CURVES_CONFIG; /// // Saves those curves /// // to be referenced when the conversion functions are called. /// RAIL_InitTxPowerCurves(rail_handle, &tx_power_curves_config); /// /// // Declares the structure used to configure the PA. /// RAIL_TxPowerConfig_t txPowerConfig = { /// .mode = RAIL_TX_POWER_MODE_2P4_HP, /// .voltage = 3300, /// .rampTime = 10, /// }; /// /// // Initializes the PA. Here, it is assumed that 'railHandle' is a valid RAIL_Handle_t /// // that has already been initialized. /// RAIL_ConfigTxPower(railHandle, &txPowerConfig); /// /// // Picks a dBm power to use: 100 deci-dBm = 10 dBm. See docs on RAIL_TxPower_t. /// RAIL_TxPower_t power = 100; /// /// // Gets the config written by RAIL_ConfigTxPower() to confirm what was actually set. /// RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); /// /// // RAIL_ConvertDbmToRaw() is the default weak version, /// // or the customer version, if overwritten. /// RAIL_TxPowerLevel_t powerLevel /// = RAIL_ConvertDbmToRaw(railHandle, txPowerConfig.mode, power); /// /// // Writes the result of the conversion to the PA power registers in terms /// // of raw power levels. /// RAIL_SetTxPower(railHandle, powerLevel); /// @endcode /// /// @note All lines following "RAIL_TxPower_t power = 100;" can be /// replaced with the provided utility function, \ref RAIL_SetTxPowerDbm(). /// However, the full example here was provided for clarity. See the /// documentation on \ref RAIL_SetTxPowerDbm() for more details. /// /// @{ /** * Initialize TX power settings. * * @param[in] railHandle A RAIL instance handle. * @param[in] config A pointer to a power config with the desired initial settings * for the TX amplifier. * @return Status code indicating success of the function call. * * These settings include the selection between the multiple TX amplifiers, * voltage supplied to the TX power amplifier, and ramp times. This must * be called before any transmit occurs or \ref RAIL_SetTxPower() is called. * While this function should always be called during initialization, * it can also be called any time if these settings need to change to adapt * to a different application/protocol. This API also resets TX power to * \ref RAIL_TX_POWER_LEVEL_INVALID, so \ref RAIL_SetTxPower() must be called * afterwards. * * At times, certain combinations of configurations cannot be achieved. * This API attempts to get as close as possible to the requested settings. The * following "RAIL_GetTxPower..." API can be used to determine what values were set. A * change in \ref RAIL_TxPowerConfig_t::rampTime may affect the minimum timings * that can be achieved in \ref RAIL_StateTiming_t::idleToTx and * \ref RAIL_StateTiming_t::rxToTx. Call \ref RAIL_SetStateTiming() again to * check whether these times have changed. */ RAIL_Status_t RAIL_ConfigTxPower(RAIL_Handle_t railHandle, const RAIL_TxPowerConfig_t *config); /** * Get the TX power settings currently used in the amplifier. * * @param[in] railHandle A RAIL instance handle. * @param[out] config A non-NULL pointer to a \ref * RAIL_TxPowerConfig_t structure filled in by the function. * @return Status code indicating success of the function call. * * Note that this API does not return the current TX power, which is separately * managed by the \ref RAIL_GetTxPower() / \ref RAIL_SetTxPower() APIs. Use this API * to determine which values were set as a result of * \ref RAIL_ConfigTxPower(). */ RAIL_Status_t RAIL_GetTxPowerConfig(RAIL_Handle_t railHandle, RAIL_TxPowerConfig_t *config); /** * Set the TX power in units of raw units (see \ref rail_chip_specific.h for * value ranges). * * @param[in] railHandle A RAIL instance handle. * @param[in] powerLevel Power in radio-specific \ref RAIL_TxPowerLevel_t units. * @return Status code indicating success of the function call. * * To convert between decibels and the integer values that the * registers take, call \ref RAIL_ConvertDbmToRaw(). * A weak version of this function, which works well with our boards is provided. However, * customers using a custom board need to characterize * radio operation on that board and override the function to convert * appropriately from the desired dB values to raw integer values. * * Depending on the configuration used in \ref RAIL_ConfigTxPower(), not all * power levels are achievable. This API will get as close as possible to * the desired power without exceeding it, and calling \ref RAIL_GetTxPower() is * the only way to know the exact value written. * * Calling this function before configuring the PA (i.e., before a successful * call to \ref RAIL_ConfigTxPower()) will return an error. */ RAIL_Status_t RAIL_SetTxPower(RAIL_Handle_t railHandle, RAIL_TxPowerLevel_t powerLevel); /** * Return the current power setting of the PA. * * @param[in] railHandle A RAIL instance handle. * @return The radio-specific \ref RAIL_TxPowerLevel_t value of the current * transmit power. * * This API returns the raw value that was set by \ref RAIL_SetTxPower(). * A weak version of \ref RAIL_ConvertRawToDbm() that works * with Silicon Labs boards to convert the raw values into actual output dBm values is provided. * However, customers using a custom board need to * re-characterize the relationship between raw and decibel values and rewrite * the provided function. * * Calling this function before configuring the PA (i.e., before a successful * call to \ref RAIL_ConfigTxPower()) will return error \ref * RAIL_TX_POWER_LEVEL_INVALID. */ RAIL_TxPowerLevel_t RAIL_GetTxPower(RAIL_Handle_t railHandle); /** * Convert raw values written to registers to decibel value (in units of * deci-dBm). * * @param[in] railHandle A RAIL instance handle. * @param[in] mode PA mode for which to convert. * @param[in] powerLevel A raw amplifier register value to be converted to * deci-dBm. * @return raw amplifier values converted to units of deci-dBm. * * A weak version of this function is provided that is tuned * to provide accurate values for our boards. For a * custom board, the relationship between what is written to the TX amplifier * and the actual output power should be re-characterized and implemented in an * overriding version of \ref RAIL_ConvertRawToDbm(). For minimum code size and * best speed, use only raw values with the \ref RAIL_SetTxPower() API and override this * function with a smaller function. In the weak version provided with the RAIL * library, railHandle is only used to indicate to the user from where the * function was called, so it is okay to use either a real protocol handle, or one * of the radio-generic ones, such as \ref RAIL_EFR32_HANDLE. * * Although the implementation of this function may change, the signature * must be as declared here. */ RAIL_TxPower_t RAIL_ConvertRawToDbm(RAIL_Handle_t railHandle, RAIL_TxPowerMode_t mode, RAIL_TxPowerLevel_t powerLevel); /** * Convert the desired decibel value (in units of deci-dBm) * to raw integer values used by the TX amplifier registers. * * @param[in] railHandle A RAIL instance handle. * @param[in] mode PA mode for which to do the conversion. * @param[in] power Desired dBm value in units of deci-dBm. * @return deci-dBm value converted to a raw * integer value that can be used directly with \ref RAIL_SetTxPower(). * * A weak version of this function is provided that is tuned * to provide accurate values for our boards. For a * custom board, the relationship between what is written to the TX amplifier * and the actual output power should be characterized and implemented in an * overriding version of \ref RAIL_ConvertDbmToRaw(). For minimum code size and * best speed use only raw values with the \ref RAIL_SetTxPower() API and override this * function with a smaller function. In the weak version provided with the RAIL * library, railHandle is only used to indicate to the user from where the * function was called, so it is okay to use either a real protocol handle, or one * of the radio-generic ones, such as \ref RAIL_EFR32_HANDLE. * * Although the implementation of this function may change, the signature * must be as declared here. */ RAIL_TxPowerLevel_t RAIL_ConvertDbmToRaw(RAIL_Handle_t railHandle, RAIL_TxPowerMode_t mode, RAIL_TxPower_t power); /** * Converts the desired decibel value (in units of deci-dBm) * to a \ref RAIL_TxPowerSettingEntry_t. * * @param[in] railHandle A RAIL instance handle. * @param[in] mode PA mode for which the conversion is to be done. * @param[in] power Desired dBm value in units of deci-dBm. * @param[out] pPowerSettingInfo A non-NULL pointer to the * \ref RAIL_TxPowerSettingEntry_t structure to be filled in with the * converted value. * @return Status code indicating success of function call. * * A weak version of this function is provided that is tuned * to provide accurate values for our boards. For a * custom board, the relationship between what is written to the TX amplifier * and the actual output power should be characterized and implemented in an * overriding version of \ref RAIL_ConvertDbmToPowerSettingEntry(). * In the weak version provided with the RAIL * library, railHandle is only used to indicate to the user from where the * function was called, so it is okay to use either a real protocol handle, or one * of the radio-generic ones, such as \ref RAIL_EFR32_HANDLE. * * Although the implementation of this function may change, the signature * must be as declared here. */ RAIL_Status_t RAIL_ConvertDbmToPowerSettingEntry(RAIL_Handle_t railHandle, RAIL_TxPowerMode_t mode, RAIL_TxPower_t power, RAIL_TxPowerSettingEntry_t *pPowerSettingInfo); struct RAIL_TxPowerCurvesConfigAlt; /// Verify the TX Power Curves on modules. /// /// @param[in] config A pointer to TX Power Curves to use on this module. /// @return Status code indicating success of function call. /// /// This function only needs to be called when using a module and has no /// effect otherwise. Transmit will not work before this function is called. RAIL_Status_t RAIL_VerifyTxPowerCurves(const struct RAIL_TxPowerCurvesConfigAlt *config); /// Set the TX power in terms of deci-dBm instead of raw power level. /// /// @param[in] railHandle A RAIL instance handle. /// @param[in] power A desired deci-dBm power to be set. /// @return Status code indicating success of the function call. /// /// This is a utility function for user convenience. Normally, to set TX /// power in dBm, do the following: /// @code{.c} /// RAIL_TxPower_t power = 100; // 100 deci-dBm, 10 dBm /// RAIL_TxPowerConfig_t txPowerConfig; /// RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); /// // RAIL_ConvertDbmToRaw() will be the weak version provided by Silicon Labs /// // by default, or the customer version, if overwritten. /// RAIL_TxPowerLevel_t powerLevel /// = RAIL_ConvertDbmToRaw(railHandle, txPowerConfig.mode, power); /// RAIL_SetTxPower(railHandle, powerLevel); /// @endcode /// /// This function wraps all those calls in a single function with power passed in /// as a parameter. /// RAIL_Status_t RAIL_SetTxPowerDbm(RAIL_Handle_t railHandle, RAIL_TxPower_t power); /// Get the TX power in terms of deci-dBm instead of raw power level. /// /// @param[in] railHandle A RAIL instance handle. /// @return The current output power in deci-dBm. /// /// This is a utility function for user convenience. Normally, to get TX /// power in dBm, do the following: /// @code{.c} /// RAIL_TxPowerLevel_t powerLevel = RAIL_GetTxPower(railHandle); /// RAIL_TxPowerConfig_t txPowerConfig; /// RAIL_GetTxPowerConfig(railHandle, &txPowerConfig); /// // RAIL_ConvertRawToDbm() will be the weak version provided by Silicon Labs /// // by default, or the customer version, if overwritten. /// RAIL_TxPower_t power /// = RAIL_ConvertRawToDbm(railHandle, txPowerConfig.mode, powerLevel); /// return power; /// @endcode /// /// This function wraps all those calls in a single function with power returned /// as the result. /// RAIL_TxPower_t RAIL_GetTxPowerDbm(RAIL_Handle_t railHandle); /** * Get the TX PA power setting table and related values. * * @param[in] railHandle A RAIL instance handle. * @param[in] mode PA mode for which to get the powersetting table. * @param[out] minPower A pointer to a \ref RAIL_TxPower_t. * @param[out] maxPower A pointer to a \ref RAIL_TxPower_t. * @param[out] step A pointer to a \ref RAIL_TxPowerLevel_t, but in deci-dBm units. * @return Power setting table start address. When NULL is returned all out params * above won't be set. * * The number of entries in the table can be calculated based on output * minPower, maxPower, and step parameters. * For example, for minPower = 115 (11.5 dBm), maxPower = 300 (30 dBm), * and step = 1 (0.1 dBm), the number of entries in table would be 186. */ const RAIL_PaPowerSetting_t *RAIL_GetPowerSettingTable(RAIL_Handle_t railHandle, RAIL_TxPowerMode_t mode, RAIL_TxPower_t *minPower, RAIL_TxPower_t *maxPower, RAIL_TxPowerLevel_t *step); /** * Set the TX PA power setting used to configure the PA hardware for the PA output * power determined by \ref RAIL_SetTxPowerDbm(). * * @param[in] railHandle A RAIL instance handle. * @param[in] paPowerSetting The desired PA power setting. * @param[in] minPowerDbm The minimum power in dBm that the PA can output. * @param[in] maxPowerDbm The maximum power in dBm that the PA can output. * @param[in] currentPowerDbm The corresponding output power in dBm for this power setting. * @return Status code indicating success of the function call. */ RAIL_Status_t RAIL_SetPaPowerSetting(RAIL_Handle_t railHandle, RAIL_PaPowerSetting_t paPowerSetting, RAIL_TxPower_t minPowerDbm, RAIL_TxPower_t maxPowerDbm, RAIL_TxPower_t currentPowerDbm); /** * Get the TX PA power setting, which is used to configure power configurations * when the dBm to paPowerSetting mapping table mode is used. * * @param[in] railHandle A RAIL instance handle. * @return The current PA power setting. */ RAIL_PaPowerSetting_t RAIL_GetPaPowerSetting(RAIL_Handle_t railHandle); /** * Enable automatic switching between PAs internally to the RAIL library. * * @param[in] railHandle A real RAIL instance handle. * @param[in] enable Enable or disable PA Auto Mode. * @return Status code indicating success of the function call. * * While PA Automode is enabled, the PA will be chosen and set automatically whenever * \ref RAIL_SetTxPowerDbm() is called or whenever powers are coerced automatically, * internally to the RAIL library during a channel change. While PA Auto Mode * is enabled, users cannot call \ref RAIL_ConfigTxPower() or * \ref RAIL_SetTxPower(). When entering auto mode, \ref RAIL_SetTxPowerDbm() must * be called to specify the desired power. When leaving auto mode, * \ref RAIL_ConfigTxPower() as well as one of \ref RAIL_SetTxPower() or * \ref RAIL_SetTxPowerDbm() must be called to re-specify the desired PA and power * level combination. * * @note: Power conversion curves must be initialized before calling this function. * That is, \ref RAIL_ConvertDbmToRaw() and \ref RAIL_ConvertRawToDbm() most both be * able to operate properly to ensure that PA Auto Mode functions correctly. * See the PA Conversions plugin or AN1127 for more details. */ RAIL_Status_t RAIL_EnablePaAutoMode(RAIL_Handle_t railHandle, bool enable); /** * Query status of PA Auto Mode. * * @param[in] railHandle A real RAIL instance handle. * @return Indicator of whether Auto Mode is enabled (true) or not (false). */ bool RAIL_IsPaAutoModeEnabled(RAIL_Handle_t railHandle); /** * Callback that decides which PA and power level should be * used while in PA auto mode. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] power A pointer to the dBm output power (in deci-dBm, 10*dBm) * being requested. The value this points to when the function returns * will be applied to the radio. * @param[out] mode A pointer to the \ref RAIL_TxPowerMode_t to be used to * achieve the requested power. The value this points to when the function * returns will be applied to the radio. * @param[in] chCfgEntry A pointer to a \ref RAIL_ChannelConfigEntry_t. * While switching channels, it will be the entry RAIL is switch *to*, * during a call to \ref RAIL_SetTxPowerDbm(), it will be the entry * RAIL is *already on*. Can be NULL if a channel configuration * was not set or no valid channels are present. * @return Status code indicating success of the function call. If this * is anything except \ref RAIL_STATUS_NO_ERROR, neither PA's nor their * powers will be configured automatically. * * Whatever values mode and powerLevel point to when this function return * will be applied to the PA hardware and used for transmits. * * @note The mode and power level provided by this function depends on the * \ref RAIL_PaAutoModeConfig provided for the radio. The \ref RAIL_PaAutoModeConfig * definition for a radio should tend to cover all the bands supported by the radio * and cover the full range of power in each to find a valid entry for requested power * for a specific band. */ RAIL_Status_t RAILCb_PaAutoModeDecision(RAIL_Handle_t railHandle, RAIL_TxPower_t *power, RAIL_TxPowerMode_t *mode, const RAIL_ChannelConfigEntry_t *chCfgEntry); /** @} */ // end of group PA /// @addtogroup Packet_TX Packet Transmit /// @brief APIs which initiate a packet transmission in RAIL. /// /// When using any of these functions, the data to be transmitted must have been /// previously written to the transmit FIFO via \ref RAIL_SetTxFifo() and/or /// \ref RAIL_WriteTxFifo(). /// /// @{ /** * Start a transmit. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel Define the channel to transmit on. * @param[in] options TX options to be applied to this transmit only. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this transmit appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. If successfully * initiated, transmit completion or failure will be reported by a later * \ref RAIL_Config_t::eventsCallback with the appropriate \ref RAIL_Events_t. * * The transmit process will begin immediately or as soon as a packet being * received has finished. The data to be transmitted must have been previously * established via \ref RAIL_SetTxFifo() and/or \ref RAIL_WriteTxFifo(). * * Returns an error if a previous transmit is still in progress. * If changing channels, any ongoing packet reception is aborted. * * In multiprotocol, ensure that the radio is properly yielded after this * operation completes. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_StartTx(RAIL_Handle_t railHandle, uint16_t channel, RAIL_TxOptions_t options, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Schedule sending a packet. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The channel to transmit on. * @param[in] options TX options to be applied to this transmit only. * @param[in] config A pointer to the \ref RAIL_ScheduleTxConfig_t * structure indicating when and how the transmit should occur. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this transmit appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. If successfully * initiated, a transmit completion or failure will be reported by a later * \ref RAIL_Config_t::eventsCallback with the appropriate \ref RAIL_Events_t. * * The transmit process will begin at the scheduled time. The data to be * transmitted must have been previously established via \ref RAIL_SetTxFifo() * and/or \ref RAIL_WriteTxFifo(). * The time (in microseconds) and whether that time is absolute or * relative is specified using the \ref RAIL_ScheduleTxConfig_t structure. * What to do if a scheduled transmit fires in * the middle of receiving a packet is also specified in this structure. * * Returns an error if a previous transmit is still in progress. * If changing channels, the channel is changed immediately and * will abort any ongoing packet reception. * * In multiprotocol, ensure that the radio is properly yielded after this * operation completes. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_StartScheduledTx(RAIL_Handle_t railHandle, uint16_t channel, RAIL_TxOptions_t options, const RAIL_ScheduleTxConfig_t *config, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Start a transmit using CSMA. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The channel to transmit on. * @param[in] options TX options to be applied to this transmit only. * @param[in] csmaConfig A pointer to the RAIL_CsmaConfig_t structure * describing the CSMA parameters to use for this transmit. * \n In multiprotocol this must point to global or heap storage that remains * valid after the API returns until the transmit is actually started. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this transmit appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. If successfully * initiated, a transmit completion or failure will be reported by a later * \ref RAIL_Config_t::eventsCallback with the appropriate \ref RAIL_Events_t. * * Perform the Carrier Sense Multiple Access (CSMA) algorithm, and if * the channel is deemed clear (RSSI below the specified threshold), it will * commence transmission. The data to be transmitted must have been previously * established via \ref RAIL_SetTxFifo() and/or \ref RAIL_WriteTxFifo(). * Packets can be received during CSMA backoff periods if receive is active * throughout the CSMA process. This will happen either by starting the CSMA * process while receive is already active, or if the \ref * RAIL_CsmaConfig_t::ccaBackoff time is less than the RAIL_StateTiming_t::idleToRx * time. If the \ref RAIL_CsmaConfig_t::ccaBackoff time is greater than the * \ref RAIL_StateTiming_t::idleToRx time, receive will only be active during * CSMA's clear channel assessments. * * If the CSMA algorithm deems the channel busy, the \ref RAIL_Config_t::eventsCallback * occurs with \ref RAIL_EVENT_TX_CHANNEL_BUSY, and the contents * of the transmit FIFO remain intact. * * Returns an error if a previous transmit is still in progress. * If changing channels, the channel is changed immediately and any ongoing * packet reception is aborted. * * Returns an error if a scheduled RX is still in progress. * * In multiprotocol, ensure that the radio is properly yielded after this * operation completes. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_StartCcaCsmaTx(RAIL_Handle_t railHandle, uint16_t channel, RAIL_TxOptions_t options, const RAIL_CsmaConfig_t *csmaConfig, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Start a transmit using LBT. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The channel to transmit on. * @param[in] options TX options to be applied to this transmit only. * @param[in] lbtConfig A pointer to the \ref RAIL_LbtConfig_t structure * describing the LBT parameters to use for this transmit. * \n In multiprotocol this must point to global or heap storage that remains * valid after the API returns until the transmit is actually started. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this transmit appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. If successfully * initiated, a transmit completion or failure will be reported by a later * \ref RAIL_Config_t::eventsCallback with the appropriate \ref RAIL_Events_t. * * Performs the Listen Before Talk (LBT) algorithm, and if the channel * is deemed clear (RSSI below the specified threshold), it will commence * transmission. The data to be transmitted must have been previously established * via \ref RAIL_SetTxFifo() and/or \ref RAIL_WriteTxFifo(). * Packets can be received during LBT backoff periods if receive is active * throughout the LBT process. This will happen either by starting the LBT * process while receive is already active, or if the \ref * RAIL_LbtConfig_t::lbtBackoff time is less than the \ref RAIL_StateTiming_t::idleToRx * time. If the \ref RAIL_LbtConfig_t::lbtBackoff time is greater than the * \ref RAIL_StateTiming_t::idleToRx time, receive will only be active during * LBT's clear channel assessments. * * If the LBT algorithm deems the channel busy, the \ref RAIL_Config_t::eventsCallback occurs with * \ref RAIL_EVENT_TX_CHANNEL_BUSY, and the contents * of the transmit FIFO remain intact. * * Returns an error if a previous transmit is still in progress. * If changing channels, the channel is changed immediately and any ongoing * packet reception is aborted. * * Returns an error if a scheduled RX is still in progress. * * In multiprotocol, ensure that the radio is properly yielded after this * operation completes. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_StartCcaLbtTx(RAIL_Handle_t railHandle, uint16_t channel, RAIL_TxOptions_t options, const RAIL_LbtConfig_t *lbtConfig, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Schedule a transmit using CSMA. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The channel to transmit on. * @param[in] options TX options to be applied to this transmit only. * @param[in] scheduleTxConfig A pointer to the \ref RAIL_ScheduleTxConfig_t * structure describing the CSMA parameters to use for this transmit. * @param[in] csmaConfig A pointer to the \ref RAIL_CsmaConfig_t structure * describing the CSMA parameters to use for this transmit. * \n In multiprotocol this must point to global or heap storage that remains * valid after the API returns until the transmit is actually started. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this transmit appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. If successfully * initiated, a transmit completion or failure will be reported by a later * \ref RAIL_Config_t::eventsCallback with the appropriate \ref RAIL_Events_t. * * Internally, the RAIL library needs a PRS channel for this feature. * It will allocate an available PRS channel to use and hold onto that * channel for future use. If no PRS channel is available, the function * returns with \ref RAIL_STATUS_INVALID_CALL. * * This is a scheduled variation of \ref RAIL_StartCcaCsmaTx(); refer to * that function for CSMA details. * * Returns an error if a previous transmit is still in progress. * If changing channels, the channel is changed immediately and any ongoing * packet reception is aborted. * * Returns an error if a scheduled RX is still in progress. * * In multiprotocol, ensure that the radio is properly yielded after this * operation completes. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_StartScheduledCcaCsmaTx(RAIL_Handle_t railHandle, uint16_t channel, RAIL_TxOptions_t options, const RAIL_ScheduleTxConfig_t *scheduleTxConfig, const RAIL_CsmaConfig_t *csmaConfig, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Schedule a transmit using LBT. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The channel to transmit on. * @param[in] options TX options to be applied to this transmit only. * @param[in] scheduleTxConfig A pointer to the \ref RAIL_ScheduleTxConfig_t * structure describing the CSMA parameters to use for this transmit. * @param[in] lbtConfig A pointer to the \ref RAIL_LbtConfig_t structure * describing the LBT parameters to use for this transmit. * \n In multiprotocol this must point to global or heap storage that remains * valid after the API returns until the transmit is actually started. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this transmit appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. If successfully * initiated, a transmit completion or failure will be reported by a later * \ref RAIL_Config_t::eventsCallback with the appropriate \ref RAIL_Events_t. * * Internally, the RAIL library needs a PRS channel for this feature. * It will allocate an available PRS channel to use and hold onto that * channel for future use. If no PRS channel is available, the function * returns with \ref RAIL_STATUS_INVALID_CALL. * * This is a scheduled variation of \ref RAIL_StartCcaLbtTx; refer to * that function for LBT details. * * Returns an error if a previous transmit is still in progress. * If changing channels, the channel is changed immediately and any ongoing * packet reception is aborted. * * Returns an error if a scheduled RX is still in progress. * * In multiprotocol, ensure that the radio is properly yielded after this * operation completes. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_StartScheduledCcaLbtTx(RAIL_Handle_t railHandle, uint16_t channel, RAIL_TxOptions_t options, const RAIL_ScheduleTxConfig_t *scheduleTxConfig, const RAIL_LbtConfig_t *lbtConfig, const RAIL_SchedulerInfo_t *schedulerInfo); /** @} */ // end of group Packet_TX /** * Stop an active or pending transmit. * * @param[in] railHandle A RAIL instance handle. * @param[in] mode Specifies the type(s) of transmit to stop. * @return \ref RAIL_STATUS_NO_ERROR if the transmit was successfully * stopped or \ref RAIL_STATUS_INVALID_STATE if there is no transmit * operation to stop. * * @note When mode includes \ref RAIL_STOP_MODE_ACTIVE, this can also stop * an active Auto-Ack transmit. When an active transmit is stopped, \ref * RAIL_EVENT_TX_ABORTED or \ref RAIL_EVENT_TXACK_ABORTED should occur. * When mode includes \ref RAIL_STOP_MODE_PENDING this can also stop * a \ref RAIL_TX_OPTION_CCA_ONLY transmit operation. When a pending * transmit is stopped, \ref RAIL_EVENT_TX_BLOCKED should occur. */ RAIL_Status_t RAIL_StopTx(RAIL_Handle_t railHandle, RAIL_StopMode_t mode); /** * Set the CCA threshold in dBm. * * @param[in] railHandle A RAIL instance handle. * @param[in] ccaThresholdDbm The CCA threshold in dBm. * @return Status code indicating success of the function call. * * Unlike \ref RAIL_StartCcaCsmaTx() or \ref RAIL_StartCcaLbtTx(), which can cause a * transmit, this function only modifies the CCA threshold. A possible * use case for this function involves setting the CCA threshold to invalid RSSI * of -128 which blocks transmission by preventing clear channel assessments * from succeeding. */ RAIL_Status_t RAIL_SetCcaThreshold(RAIL_Handle_t railHandle, int8_t ccaThresholdDbm); /** * Get detailed information about the last packet transmitted. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails An application-provided pointer to store * RAIL_TxPacketDetails_t corresponding to the transmit event. * The isAck and timeSent fields totalPacketBytes and timePosition * must be initialized prior to each call: * - isAck true to obtain details about the most recent Ack transmit, * false to obtain details about the most recent app-initiated transmit. * - totalPacketBytes with the total number of bytes of the transmitted * packet for RAIL to use when calculating the specified timestamp. * This should account for all bytes sent over the air after the * Preamble and Sync word(s), including CRC bytes. * - timePosition with a \ref RAIL_PacketTimePosition_t value specifying * the packet position to put in the timeSent field on return. * This field will also be updated with the actual position corresponding * to the timeSent value filled in. * @return \ref RAIL_STATUS_NO_ERROR if pPacketDetails was filled in, * or an appropriate error code otherwise. * * @note Consider using \ref RAIL_GetTxPacketDetailsAlt2 for smaller code size. * * This function can only be called from callback context for either * \ref RAIL_EVENT_TX_PACKET_SENT or \ref RAIL_EVENT_TXACK_PACKET_SENT * events. */ RAIL_Status_t RAIL_GetTxPacketDetails(RAIL_Handle_t railHandle, RAIL_TxPacketDetails_t *pPacketDetails); /** * Get detailed information about the last packet transmitted. * * @param[in] railHandle A RAIL instance handle. * @param[in] isAck true to obtain details about the most recent Ack transmit. * false to obtain details about the most recent app-initiated transmit. * @param[out] pPacketTime An application-provided non-NULL pointer to store a * RAIL_Time_t corresponding to the transmit event. This will be populated * with a timestamp corresponding to an arbitrary location in the packet. Call * \ref RAIL_GetTxTimePreambleStart, \ref RAIL_GetTxTimeSyncWordEnd, or * \ref RAIL_GetTxTimeFrameEnd to adjust the timestamp for different locations * in the packet. * @return \ref RAIL_STATUS_NO_ERROR if pPacketTime was filled in, * or an appropriate error code otherwise. * * @note Consider using \ref RAIL_GetTxPacketDetailsAlt2 to pass in * a \ref RAIL_PacketTimeStamp_t structure instead of a \ref RAIL_Time_t * structure, particularly when \ref RAIL_PacketTimePosition_t information * is needed or useful. * * This function can only be called from callback context for either * \ref RAIL_EVENT_TX_PACKET_SENT or \ref RAIL_EVENT_TXACK_PACKET_SENT * events. */ RAIL_Status_t RAIL_GetTxPacketDetailsAlt(RAIL_Handle_t railHandle, bool isAck, RAIL_Time_t *pPacketTime); /** * Get detailed information about the last packet transmitted. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails An application-provided pointer to store * \ref RAIL_TxPacketDetails_t corresponding to the transmit event. * The isAck field must be initialized prior to each call: * - isAck true to obtain details about the most recent Ack transmit, * false to obtain details about the most recent app-initiated transmit. * The timeSent field packetTime will be populated with a timestamp * corresponding to a default location in the packet. The timeSent field * timePosition will be populated with a \ref RAIL_PacketTimePosition_t value * specifying that default packet location. * Call \ref RAIL_GetTxTimePreambleStartAlt(), * \ref RAIL_GetTxTimeSyncWordEndAlt(), or \ref RAIL_GetTxTimeFrameEndAlt() to * adjust the timestamp for different locations in the packet. * @return \ref RAIL_STATUS_NO_ERROR if pPacketDetails was filled in, * or an appropriate error code otherwise. * * This function can only be called from callback context for either * \ref RAIL_EVENT_TX_PACKET_SENT or \ref RAIL_EVENT_TXACK_PACKET_SENT * events. */ RAIL_Status_t RAIL_GetTxPacketDetailsAlt2(RAIL_Handle_t railHandle, RAIL_TxPacketDetails_t *pPacketDetails); /** * Adjust a RAIL TX completion timestamp to refer to the start of the * preamble. Also used to retrieve the \ref RAIL_EVENT_TX_STARTED * timestamp. * * @param[in] railHandle A RAIL instance handle. * @param[in] totalPacketBytes The total number of bytes of the transmitted * packet for RAIL to use when adjusting the provided timestamp. This * should account for all bytes transmitted over the air after the Preamble * and Sync word(s), including CRC bytes. Pass \ref RAIL_TX_STARTED_BYTES * to retrieve the start-of-normal-TX timestamp (see below). * @param[in,out] pPacketTime This points to the \ref RAIL_Time_t returned * from a previous call to \ref RAIL_GetTxPacketDetailsAlt() for this same * packet. That time will be updated with the time that the preamble for * this packet started on air. * Must be non-NULL. * @return \ref RAIL_STATUS_NO_ERROR if pPacketTime was successfully * determined or an appropriate error code otherwise. * * When used for timestamp adjustment, call this function in the * same transmit-complete event-handling context as * \ref RAIL_GetTxPacketDetailsAlt() is called. * * This function may be called when handling the \ref RAIL_EVENT_TX_STARTED * event to retrieve that event's start-of-normal-TX timestamp. (Ack * transmits currently have no equivalent event or associated timestamp.) * In this case, totalPacketBytes must be \ref RAIL_TX_STARTED_BYTES, and * pPacketTime is an output-only parameter filled in with that time (so no * need to initialize it beforehand by calling \ref * RAIL_GetTxPacketDetailsAlt()). * */ RAIL_Status_t RAIL_GetTxTimePreambleStart(RAIL_Handle_t railHandle, uint16_t totalPacketBytes, RAIL_Time_t *pPacketTime); /** * Adjust a RAIL TX completion timestamp to refer to the start of the * preamble. Also used to retrieve the \ref RAIL_EVENT_TX_STARTED * timestamp. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails A non-NULL pointer to the details that were returned from * a previous call to \ref RAIL_GetTxPacketDetailsAlt2() for this same packet. * The application must update the timeSent field totalPacketBytes to be * the total number of bytes of the sent packet for RAIL to use when * calculating the specified timestamp. This should account for all bytes * transmitted over the air after the Preamble and Sync word(s), including CRC * bytes. Pass \ref RAIL_TX_STARTED_BYTES to retrieve the start-of-normal-TX * timestamp (see below). After this function, the timeSent field packetTime * will be updated with the time that the preamble for this packet started on air. * @return \ref RAIL_STATUS_NO_ERROR if the packet time was successfully * calculated, or an appropriate error code otherwise. * * When used for timestamp adjustment, call this function in the * same transmit-complete event-handling context as * \ref RAIL_GetTxPacketDetailsAlt2() is called. * * This function may be called when handling the \ref RAIL_EVENT_TX_STARTED * event to retrieve that event's start-of-normal-TX timestamp. (Ack * transmits currently have no equivalent event or associated timestamp.) * In this case, the timeSent field totalPacketBytes must be * \ref RAIL_TX_STARTED_BYTES, and the timeSent field packetTime is an * output-only parameter filled in with that time (so no need to initialize * it beforehand by calling \ref RAIL_GetTxPacketDetailsAlt2()). * */ RAIL_Status_t RAIL_GetTxTimePreambleStartAlt(RAIL_Handle_t railHandle, RAIL_TxPacketDetails_t *pPacketDetails); /** * Adjust a RAIL TX timestamp to refer to the end of the sync word. * * @param[in] railHandle A RAIL instance handle. * @param[in] totalPacketBytes The total number of bytes of the transmitted * packet for RAIL to use when calculating the specified timestamp. This * should account for all bytes transmitted over the air after the Preamble * and Sync word(s), including CRC bytes. * @param[in,out] pPacketTime The time that was returned in a * \ref RAIL_Time_t from a previous call to \ref RAIL_GetTxPacketDetailsAlt() * for this same packet. After this function, the time at that location will * be updated with the time that the sync word for this packet finished on * air. Must be non-NULL. * @return \ref RAIL_STATUS_NO_ERROR if pPacketTime was successfully calculated, * or an appropriate error code otherwise. * * Call the timestamp adjustment function in the same * transmit-complete event-handling context as * \ref RAIL_GetTxPacketDetailsAlt() is called. */ RAIL_Status_t RAIL_GetTxTimeSyncWordEnd(RAIL_Handle_t railHandle, uint16_t totalPacketBytes, RAIL_Time_t *pPacketTime); /** * Adjust a RAIL TX timestamp to refer to the end of the sync word. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails A non-NULL pointer to the details that were returned from * a previous call to \ref RAIL_GetTxPacketDetailsAlt2() for this same packet. * The application must update the timeSent field totalPacketBytes to be * the total number of bytes of the sent packet for RAIL to use when * calculating the specified timestamp. This should account for all bytes * transmitted over the air after the Preamble and Sync word(s), including CRC * bytes. After this function, the timeSent field packetTime * will be updated with the time that the sync word for this packet finished on * air. * @return \ref RAIL_STATUS_NO_ERROR if the packet time was successfully * calculated, or an appropriate error code otherwise. * * Call the timestamp adjustment function in the same * transmit-complete event-handling context as * \ref RAIL_GetTxPacketDetailsAlt2() is called. */ RAIL_Status_t RAIL_GetTxTimeSyncWordEndAlt(RAIL_Handle_t railHandle, RAIL_TxPacketDetails_t *pPacketDetails); /** * Adjust a RAIL TX timestamp to refer to the end of frame. * * @param[in] railHandle A RAIL instance handle. * @param[in] totalPacketBytes The total number of bytes of the transmitted * packet for RAIL to use when calculating the specified timestamp. This * should account for all bytes transmitted over the air after the Preamble * and Sync word(s), including CRC bytes. * @param[in,out] pPacketTime The time that was returned in a * \ref RAIL_Time_t from a previous call to \ref RAIL_GetTxPacketDetailsAlt() * for this same packet. After this function, the time at that location will * be updated with the time that this packet finished on air. Must be * non-NULL. * @return \ref RAIL_STATUS_NO_ERROR if pPacketTime was successfully calculated, * or an appropriate error code otherwise. * * Call the timestamp adjustment function in the same * transmit-complete event-handling context as * \ref RAIL_GetTxPacketDetailsAlt() is called. */ RAIL_Status_t RAIL_GetTxTimeFrameEnd(RAIL_Handle_t railHandle, uint16_t totalPacketBytes, RAIL_Time_t *pPacketTime); /** * Adjust a RAIL TX timestamp to refer to the end of frame. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails A non-NULL pointer to the details that were returned from * a previous call to \ref RAIL_GetTxPacketDetailsAlt2() for this same packet. * The application must update the timeSent field totalPacketBytes to be * the total number of bytes of the sent packet for RAIL to use when * calculating the specified timestamp. This should account for all bytes * transmitted over the air after the Preamble and Sync word(s), including CRC * bytes. After this function, the timeSent field packetTime * will be updated with the time that this packet finished on air. * @return \ref RAIL_STATUS_NO_ERROR if the packet time was successfully * calculated, or an appropriate error code otherwise. * * Call the timestamp adjustment function in the same * transmit-complete event-handling context as * \ref RAIL_GetTxPacketDetailsAlt2() is called. */ RAIL_Status_t RAIL_GetTxTimeFrameEndAlt(RAIL_Handle_t railHandle, RAIL_TxPacketDetails_t *pPacketDetails); /** * Prevent the radio from starting a transmit. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable Enable/Disable TX hold off. * @return Status code indicating success of the function call. * * Enable TX hold off to prevent the radio from starting any transmits. * Disable TX hold off to allow the radio to transmit again. * Attempting to transmit with the TX hold off enabled will result in * \ref RAIL_EVENT_TX_BLOCKED and/or \ref RAIL_EVENT_TXACK_BLOCKED * events. * * @note This function does not affect a transmit that has already started. * To stop an already-started transmission, use \ref RAIL_Idle() with * \ref RAIL_IDLE_ABORT. */ RAIL_Status_t RAIL_EnableTxHoldOff(RAIL_Handle_t railHandle, bool enable); /** * Check whether or not TX hold off is enabled. * * @param[in] railHandle A RAIL instance handle. * @return true if TX hold off is enabled, false otherwise. * * TX hold off can be enabled/disabled using \ref RAIL_EnableTxHoldOff(). * Attempting to transmit with the TX hold off enabled will block the * transmission and result in \ref RAIL_EVENT_TX_BLOCKED * and/or \ref RAIL_EVENT_TXACK_BLOCKED events. */ bool RAIL_IsTxHoldOffEnabled(RAIL_Handle_t railHandle); /** * Set an alternate transmitter preamble length. * * @param[in] railHandle A RAIL instance handle. * @param[in] length The desired preamble length, in bits. * @return Status code indicating success of the function call. * * To cause a transmission to use this alternate preamble length, * specify \ref RAIL_TX_OPTION_ALT_PREAMBLE_LEN in the txOptions * parameter passed to the respective RAIL transmit API. * * @note Attempting to set a preamble length of 0xFFFF bits will result in * \ref RAIL_STATUS_INVALID_PARAMETER. **/ RAIL_Status_t RAIL_SetTxAltPreambleLength(RAIL_Handle_t railHandle, uint16_t length); /** @} */ // end of group Transmit /****************************************************************************** * Receive *****************************************************************************/ /** * @addtogroup Receive * @brief APIs related to packet receive * @{ */ /** * Configure receive options. * * @param[in] railHandle A RAIL instance handle. * @param[in] mask A bitmask containing which options should be modified. * @param[in] options A bitmask containing desired configuration settings. * Bit positions for each option are found in the \ref RAIL_RxOptions_t. * @return Status code indicating success of the function call. * * Configure the radio receive flow based on the list of available options. * Only the options indicated by the mask parameter will be affected. Pass * \ref RAIL_RX_OPTIONS_ALL to set all parameters. * The previous settings may affect the current frame if a packet is * received during this configuration. */ RAIL_Status_t RAIL_ConfigRxOptions(RAIL_Handle_t railHandle, RAIL_RxOptions_t mask, RAIL_RxOptions_t options); /** * Include the code necessary for frame type based length decoding. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * This function must be called before \ref RAIL_ConfigChannels() to allow configurations * using a frame type based length setup. It is called by default * in the \ref RAILCb_ConfigFrameTypeLength() API which can be overridden to save * code space. */ RAIL_Status_t RAIL_IncludeFrameTypeLength(RAIL_Handle_t railHandle); /** * Handle frame type length. * * @param[in] railHandle A RAIL instance handle. * @param[in] frameType A pointer to a frame type configuration structure. * * This function is implemented in the radio configuration. * Currently, the frame type passed in only handles packet length decoding. If * NULL is passed into this function, it clears any currently configured * frame type settings. This will either be implemented as an empty function in * the radio configuration if it is not needed, to assist in dead code * elimination. */ void RAILCb_ConfigFrameTypeLength(RAIL_Handle_t railHandle, const RAIL_FrameType_t *frameType); /** * Start the receiver on a specific channel. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The channel to listen on. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this receive appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. * * This is a non-blocking function. Whenever a packet is received, \ref RAIL_Config_t::eventsCallback * will fire with \ref RAIL_EVENT_RX_PACKET_RECEIVED set. If you call * this while not idle but with a different channel, any ongoing * receive or transmit operation will be aborted. */ RAIL_Status_t RAIL_StartRx(RAIL_Handle_t railHandle, uint16_t channel, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Schedule a receive window for some future time. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel A channel to listen on. * @param[in] cfg A pointer to a configuration structure to define the receive window. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this receive appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. * * This API immediately changes the channel and schedules receive to start * at the specified time and end at the given end time. If you do not specify * an end time, you may call this API later with an end time as long as you set * the start time to disabled. You can also terminate the receive * operation immediately using the \ref RAIL_Idle() function. Note that relative * end times are always relative to the start unless no start time is * specified. If changing channels, the channel is changed immediately and * will abort any ongoing packet transmission or reception. * * Returns an error if a CSMA or LBT transmit is still in progress. * * In multiprotocol, ensure that you properly yield the radio after this * call. See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_ScheduleRx(RAIL_Handle_t railHandle, uint16_t channel, const RAIL_ScheduleRxConfig_t *cfg, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Enable automatic PRS LNA bypass for external FEM. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] enable Enable/Disable automatic PRS LNA bypass. * @param[in] pPrsLnaBypassConfig A pointer to an automatic PRS LNA bypass * configuration structure. It must be non-NULL to enable the feature. * @return Status code indicating success of the function call. * * If automatic PRS LNA bypass is enabled on chip that supports the feature * (\ref RAIL_SUPPORTS_PRS_LNA_BYPASS), a level is generated on a PRS channel * when the received power exceed a threshold. It is turned off after frame * reception or after timeout if no frame has been detected. * * @warning As this function relies on PRS access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if PRS is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_EnablePrsLnaBypass(RAIL_Handle_t railHandle, bool enable, const RAIL_PrsLnaBypassConfig_t *pPrsLnaBypassConfig); /****************************************************************************** * Packet Information (RX) *****************************************************************************/ /// @addtogroup Packet_Information Packet Information /// @brief APIs to get information about received packets. /// /// After receiving a packet, RAIL will trigger a /// \ref RAIL_EVENT_RX_PACKET_RECEIVED event. At that point, there is a variety /// of information available to the application about the received packet. The /// following example code assumes that the /// \ref RAIL_RX_OPTION_REMOVE_APPENDED_INFO is not used, and the application /// wants as much data about the packet as possible. /// @code{.c} /// // Get all information about a received packet. /// RAIL_Status_t status; /// RAIL_RxPacketInfo_t rxInfo; /// RAIL_RxPacketDetails_t rxDetails; /// RAIL_RxPacketHandle_t rxHandle /// = RAIL_GetRxPacketInfo(railHandle, RAIL_RX_PACKET_HANDLE_NEWEST, &rxInfo); /// assert(rxHandle != RAIL_RX_PACKET_HANDLE_INVALID); /// status = RAIL_GetRxPacketDetailsAlt(railHandle, rxHandle, &rxDetails); /// assert(status == RAIL_STATUS_NO_ERROR); /// if (rxDetails.timeReceived.timePosition == RAIL_PACKET_TIME_INVALID) { /// return; // No timestamp available for this packet /// } /// // CRC_BYTES only needs to be added when not using RAIL_RX_OPTION_STORE_CRC /// rxDetails.timeReceived.totalPacketBytes = rxInfo.packetBytes + CRC_BYTES; /// // Choose the function which gives the desired timestamp /// status = RAIL_GetRxTimeFrameEndAlt(railHandle, &rxDetails); /// assert(status == RAIL_STATUS_NO_ERROR); /// // Now all fields of rxInfo and rxDetails have been populated correctly /// @endcode /// /// @{ /** * Get basic information about a pending or received packet. * * @param[in] railHandle A RAIL instance handle. * @param[in] packetHandle A packet handle for the unreleased packet as * returned from a previous call, or sentinel values * \ref RAIL_RX_PACKET_HANDLE_OLDEST, * \ref RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE or * \ref RAIL_RX_PACKET_HANDLE_NEWEST. * @param[out] pPacketInfo A non-NULL pointer to a \ref RAIL_RxPacketInfo_t * to store info for the requested packet. * @return The packet handle for the requested packet: * if packetHandle was one of the sentinel values, returns the actual * packet handle for that packet, otherwise returns packetHandle. * It may return \ref RAIL_RX_PACKET_HANDLE_INVALID to indicate an error. * * This function can be used in any RX mode. It does not free any receive FIFO * or internal receive resources. If used in receive * \ref RAIL_DataMethod_t::FIFO_MODE, the * value in \ref RAIL_RxPacketInfo_t::packetBytes will only return the data * remaining in the FIFO. Any data read via earlier calls to * \ref RAIL_ReadRxFifo() is not included. * * @note When getting information about an arriving packet that is not yet complete, * (i.e., pPacketInfo->packetStatus == \ref RAIL_RX_PACKET_RECEIVING), keep * in mind its data is highly suspect because it has not yet passed any CRC * integrity checking. Also note that the packet could be aborted, canceled, or * fail momentarily, invalidating its data in Packet mode. Furthermore, there * is a small chance towards the end of packet reception that the filled-in * \ref RAIL_RxPacketInfo_t could include not only packet data received so far, * but also some raw radio-appended info detail bytes that RAIL's * packet-completion processing will subsequently deal with. It's up to the * application to know its packet format well enough to avoid confusing such * info as packet data. */ RAIL_RxPacketHandle_t RAIL_GetRxPacketInfo(RAIL_Handle_t railHandle, RAIL_RxPacketHandle_t packetHandle, RAIL_RxPacketInfo_t *pPacketInfo); /** * Get information about the live incoming packet (if any). * Differs from \ref RAIL_GetRxPacketInfo() by only returning information * about a packet actively being received, something which even the * \ref RAIL_RX_PACKET_HANDLE_NEWEST may not represent if there are * completed but unprocessed packets in the receive FIFO. * * @param[in] railHandle A RAIL instance handle. * @param[out] pPacketInfo A non-NULL pointer to store \ref RAIL_RxPacketInfo_t * for the incoming packet. * @return Status code indicating success of the function call. * * This function can only be called from callback context, e.g., * when handling \ref RAIL_EVENT_RX_FILTER_PASSED or * \ref RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND. * It must not be used with receive \ref RAIL_DataMethod_t::FIFO_MODE * if any portion of an incoming packet has already been extracted from * the receive FIFO. * * @note The incomplete data of an arriving packet is highly suspect because * it has not yet passed any CRC integrity checking. Also note that the * packet could be aborted, canceled, or fail momentarily, invalidating * its data in Packet mode. Furthermore, there is a small chance towards * the end of packet reception that the filled-in \ref RAIL_RxPacketInfo_t * could include not only packet data received so far, but also some raw * radio-appended info detail bytes that RAIL's packet-completion * processing will subsequently deal with. It's up to the application to * know its packet format well enough to avoid confusing such info as * packet data. */ RAIL_Status_t RAIL_GetRxIncomingPacketInfo(RAIL_Handle_t railHandle, RAIL_RxPacketInfo_t *pPacketInfo); /** * Copy a full packet to a user-specified contiguous buffer. * * @param[out] pDest A non-NULL application-provided pointer to a buffer of at * least pPacketInfo->packetBytes in size to store the packet data * contiguously. This buffer must never overlay RAIL's receive FIFO buffer. * Exactly pPacketInfo->packetBytes of packet data will be written into it. * @param[in] pPacketInfo A non-NULL pointer to the * \ref RAIL_RxPacketInfo_t for the requested packet. * * @note This is a convenience helper function, which * is intended to be expedient. As a result, it does not * check the validity of its arguments, * so don't pass either as NULL, and don't * pass a pDest pointer to a buffer that's too small for the packet's data. * @note If only a portion of the packet is needed, use \ref RAIL_PeekRxPacket() * instead. */ static inline void RAIL_CopyRxPacket(uint8_t *pDest, const RAIL_RxPacketInfo_t *pPacketInfo) { (void)memcpy(pDest, pPacketInfo->firstPortionData, pPacketInfo->firstPortionBytes); if (pPacketInfo->lastPortionData != NULL) { uint16_t size = pPacketInfo->packetBytes - pPacketInfo->firstPortionBytes; (void)memcpy(pDest + pPacketInfo->firstPortionBytes, pPacketInfo->lastPortionData, size); } } /** * Get detailed information about a received packet. * This function can be used in any RX mode; it does not free any receive FIFO * or internal receive resources. * * @param[in] railHandle A RAIL instance handle. * @param[in] packetHandle A packet handle for the unreleased packet as * returned from a previous call to RAIL_GetRxPacketInfo() or * RAIL_HoldRxPacket(), or sentinel values \ref RAIL_RX_PACKET_HANDLE_OLDEST, * \ref RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE * or \ref RAIL_RX_PACKET_HANDLE_NEWEST. * @param[in,out] pPacketDetails An application-provided non-NULL pointer to * store \ref RAIL_RxPacketDetails_t for the requested packet. * For \ref RAIL_RxPacketStatus_t RAIL_RX_PACKET_READY_ packets, * the timeReceived fields totalPacketBytes and timePosition must be * initialized prior to each call: * - totalPacketBytes with the total number of bytes of the received * packet for RAIL to use when calculating the specified timestamp. * This should account for all bytes received over the air after the * Preamble and Sync word(s), including CRC bytes. * - timePosition with a \ref RAIL_PacketTimePosition_t value specifying * the packet position to put in the timeReceived field on return. * This field will also be updated with the actual position corresponding * to the timeReceived value filled in. * @return \ref RAIL_STATUS_NO_ERROR if pPacketDetails was filled in, * or an appropriate error code otherwise. * * @note Certain details are always available, while others are only available * if the \ref RAIL_RxOptions_t \ref RAIL_RX_OPTION_REMOVE_APPENDED_INFO * option is not in effect and the received packet's * \ref RAIL_RxPacketStatus_t is among the RAIL_RX_PACKET_READY_ set. * See \ref RAIL_RxPacketDetails_t for clarification. * * @note Consider using \ref RAIL_GetRxPacketDetailsAlt for smaller code size. */ RAIL_Status_t RAIL_GetRxPacketDetails(RAIL_Handle_t railHandle, RAIL_RxPacketHandle_t packetHandle, RAIL_RxPacketDetails_t *pPacketDetails); /** * Get detailed information about a received packet. * This function can be used in any RX mode; it does not free any receive FIFO * or receive internal resources. * * @param[in] railHandle A RAIL instance handle. * @param[in] packetHandle A packet handle for the unreleased packet as * returned from a previous call to \ref RAIL_GetRxPacketInfo() or * \ref RAIL_HoldRxPacket(), or sentinel values \ref RAIL_RX_PACKET_HANDLE_OLDEST * \ref RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE or * \ref RAIL_RX_PACKET_HANDLE_NEWEST. * @param[out] pPacketDetails A non-NULL application-provided pointer to * store \ref RAIL_RxPacketDetails_t for the requested packet. * For \ref RAIL_RxPacketStatus_t RAIL_RX_PACKET_READY_ packets, * the timeReceived field packetTime will be populated with a timestamp * corresponding to a default location in the packet. The timeReceived field * timePosition will be populated with a \ref RAIL_PacketTimePosition_t value * specifying that default packet location. Call * \ref RAIL_GetRxTimePreambleStart(), \ref RAIL_GetRxTimeSyncWordEnd(), or * \ref RAIL_GetRxTimeFrameEnd() to adjust that timestamp for different * locations in the packet. * @return \ref RAIL_STATUS_NO_ERROR if pPacketDetails was filled in, * or an appropriate error code otherwise. * * This alternative API allows for smaller code size by deadstripping the * timestamp adjustment algorithms which are not in use. * * @note Certain details are always available, while others are only available * if the \ref RAIL_RxOptions_t \ref RAIL_RX_OPTION_REMOVE_APPENDED_INFO * option is not in effect and the received packet's * \ref RAIL_RxPacketStatus_t is among the RAIL_RX_PACKET_READY_ set. * See \ref RAIL_RxPacketDetails_t for clarification. * * @note This function should be called soon (no more than a minute) after * packet reception for the packet timestamp information to be valid. */ RAIL_Status_t RAIL_GetRxPacketDetailsAlt(RAIL_Handle_t railHandle, RAIL_RxPacketHandle_t packetHandle, RAIL_RxPacketDetails_t *pPacketDetails); /** * Adjust a RAIL RX timestamp to refer to the start of the preamble. * * @param[in] railHandle A RAIL instance handle. * @param[in] totalPacketBytes The total number of bytes of the received packet * for RAIL to use when calculating the specified timestamp. This should * account for all bytes received over the air after the Preamble and Sync * word(s), including CRC bytes. * @param[in,out] pPacketTime A pointer to the time that was returned in the * \ref RAIL_PacketTimeStamp_t::packetTime field of * \ref RAIL_RxPacketDetails_t::timeReceived from a previous call to * \ref RAIL_GetRxPacketDetailsAlt for this same packet. After this * function, the time at that location will be updated with the time that the * preamble for this packet started on air. Must be non-NULL. * @return \ref RAIL_STATUS_NO_ERROR if pPacketTime was successfully calculated, * or an appropriate error code otherwise. * * Call this API while the given railHandle is active, or it will * return an error code of \ref RAIL_STATUS_INVALID_STATE. Note that this API * may return incorrect timestamps when sub-phys are in use. Prefer * \ref RAIL_GetRxTimePreambleStartAlt in those situations. See * \ref RAIL_RxPacketDetails_t::subPhyId for more details. */ RAIL_Status_t RAIL_GetRxTimePreambleStart(RAIL_Handle_t railHandle, uint16_t totalPacketBytes, RAIL_Time_t *pPacketTime); /** * Adjust a RAIL RX timestamp to refer to the start of the preamble. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails A non-NULL pointer to the details that were returned from * a previous call to \ref RAIL_GetRxPacketDetailsAlt() for this same packet. * The application must update the timeReceived field totalPacketBytes to be * the total number of bytes of the received packet for RAIL to use when * calculating the specified timestamp. This should account for all bytes * received over the air after the Preamble and Sync word(s), including CRC * bytes. After this function, the timeReceived field packetTime will be * updated with the time that the preamble for this packet started on air. * @return \ref RAIL_STATUS_NO_ERROR if the packet time was successfully * calculated, or an appropriate error code otherwise. */ RAIL_Status_t RAIL_GetRxTimePreambleStartAlt(RAIL_Handle_t railHandle, RAIL_RxPacketDetails_t *pPacketDetails); /** * Adjust a RAIL RX timestamp to refer to the end of the sync word. * * @param[in] railHandle A RAIL instance handle. * @param[in] totalPacketBytes The total number of bytes of the received packet * for RAIL to use when calculating the specified timestamp. This should * account for all bytes received over the air after the Preamble and Sync * word(s), including CRC bytes. * @param[in,out] pPacketTime A pointer to the time that was returned in the * \ref RAIL_PacketTimeStamp_t::packetTime field of * \ref RAIL_RxPacketDetails_t::timeReceived from a previous call to * \ref RAIL_GetRxPacketDetailsAlt for this same packet. After this * function, the time at that location will be updated with the time that the * sync word for this packet finished on air. Must be non-NULL. * @return \ref RAIL_STATUS_NO_ERROR if pPacketTime was successfully calculated, * or an appropriate error code otherwise. * * Call this API while the given railHandle is active, or it will * return an error code of \ref RAIL_STATUS_INVALID_STATE. Note that this API * may return incorrect timestamps when sub-phys are in use. Prefer * \ref RAIL_GetRxTimePreambleStartAlt in those situations. See * \ref RAIL_RxPacketDetails_t::subPhyId for more details. */ RAIL_Status_t RAIL_GetRxTimeSyncWordEnd(RAIL_Handle_t railHandle, uint16_t totalPacketBytes, RAIL_Time_t *pPacketTime); /** * Adjust a RAIL RX timestamp to refer to the end of the sync word. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails A non-NULL pointer to the details that were returned from * a previous call to \ref RAIL_GetRxPacketDetailsAlt() for this same packet. * The application must update the timeReceived field totalPacketBytes to be * the total number of bytes of the received packet for RAIL to use when * calculating the specified timestamp. This should account for all bytes * received over the air after the Preamble and Sync word(s), including CRC * bytes. After this function, the timeReceived field packetTime will be * updated with the time that the sync word for this packet finished on air. * @return \ref RAIL_STATUS_NO_ERROR if the packet time was successfully * calculated, or an appropriate error code otherwise. */ RAIL_Status_t RAIL_GetRxTimeSyncWordEndAlt(RAIL_Handle_t railHandle, RAIL_RxPacketDetails_t *pPacketDetails); /** * Adjust a RAIL RX timestamp to refer to the end of frame. * * @param[in] railHandle A RAIL instance handle. * @param[in] totalPacketBytes The total number of bytes of the received packet * for RAIL to use when calculating the specified timestamp. This should * account for all bytes received over the air after the Preamble and Sync * word(s), including CRC bytes. * @param[in,out] pPacketTime A pointer to the time that was returned in the * \ref RAIL_PacketTimeStamp_t::packetTime field of * \ref RAIL_RxPacketDetails_t::timeReceived from a previous call to * \ref RAIL_GetRxPacketDetailsAlt for this same packet. After this * function, the time at that location will be updated with the time that this * packet finished on air. Must be non-NULL. * @return \ref RAIL_STATUS_NO_ERROR if pPacketTime was successfully calculated, * or an appropriate error code otherwise. * * Call this API while the given railHandle is active, or it will * return an error code of \ref RAIL_STATUS_INVALID_STATE. Note that this API * may return incorrect timestamps when sub-phys are in use. Prefer * \ref RAIL_GetRxTimePreambleStartAlt in those situations. See * \ref RAIL_RxPacketDetails_t::subPhyId for more details. */ RAIL_Status_t RAIL_GetRxTimeFrameEnd(RAIL_Handle_t railHandle, uint16_t totalPacketBytes, RAIL_Time_t *pPacketTime); /** * Adjust a RAIL RX timestamp to refer to the end of frame. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] pPacketDetails A non-NULL pointer to the details that were returned from * a previous call to \ref RAIL_GetRxPacketDetailsAlt() for this same packet. * The application must update the timeReceived field totalPacketBytes to be * the total number of bytes of the received packet for RAIL to use when * calculating the specified timestamp. This should account for all bytes * received over the air after the Preamble and Sync word(s), including CRC * bytes. After this function, the timeReceived field packetTime will be * updated with the time that the packet finished on air. * @return \ref RAIL_STATUS_NO_ERROR if the packet time was successfully * calculated, or an appropriate error code otherwise. */ RAIL_Status_t RAIL_GetRxTimeFrameEndAlt(RAIL_Handle_t railHandle, RAIL_RxPacketDetails_t *pPacketDetails); /** @} */ // end of group Packet_Information /** * Place a temporary hold on this packet's data in the receive * FIFO and internal packet metadata FIFO. * * This function can only be called from within RAIL callback context. * It can be used in any RX mode. * * Normally, when RAIL issues its callback indicating a packet is ready * or aborted, it expects the application's callback to retrieve and * copy (or discard) the packet's information and data, and will free * the packet data and metadata after the callback returns. This function * tells RAIL to hold onto those resources in the receive FIFO and internal * metadata FIFO after the callback returns in case the application wants to * defer processing the packet to a later time, e.g., outside of callback * context. * * @param[in] railHandle A RAIL instance handle. * @return The packet handle for the packet associated with the callback, * \ref RAIL_RX_PACKET_HANDLE_INVALID if no such packet yet exists or * railHandle is not active. * * @note When using multiprotocol the receive FIFO and internal receive * metadata FIFO are reset during protocol switches losing any held packets. * It is best to avoid using \ref RAIL_HoldRxPacket in DMP or to at least * invalidate any held packet handles and related \ref RAIL_RxPacketInfo_t * information when the \ref RAIL_EVENT_CONFIG_UNSCHEDULED occurs. */ RAIL_RxPacketHandle_t RAIL_HoldRxPacket(RAIL_Handle_t railHandle); /** * Copy 'len' bytes of packet data starting from 'offset' from the * receive FIFO. Those bytes remain valid for re-peeking. * * @param[in] railHandle A RAIL instance handle. * @param[in] packetHandle A packet handle as returned from a previous * \ref RAIL_GetRxPacketInfo() or \ref RAIL_HoldRxPacket() call, or * sentinel values \ref RAIL_RX_PACKET_HANDLE_OLDEST, * \ref RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE * or \ref RAIL_RX_PACKET_HANDLE_NEWEST. * @param[out] pDst A pointer to the location where the received bytes will * be copied. If NULL, no copying occurs. * @param[in] len A number of packet data bytes to copy. * @param[in] offset A byte offset within remaining packet data from which * to copy. * @return Number of packet bytes copied. * * @note Peek does not permit peeking beyond the requested packet's * available packet data (though there is a small chance it might * for a \ref RAIL_RX_PACKET_HANDLE_NEWEST packet at the very end of * still being received). Nor can one peek into already-consumed data read * by \ref RAIL_ReadRxFifo(). len and offset are relative to the remaining data * available in the packet, if any was already consumed by \ref RAIL_ReadRxFifo(). */ uint16_t RAIL_PeekRxPacket(RAIL_Handle_t railHandle, RAIL_RxPacketHandle_t packetHandle, uint8_t *pDst, uint16_t len, uint16_t offset); /** * Release RAIL's resources for a packet previously held in the receive FIFO * and internal receive metadata FIFO. * * This function must be called for any packet previously held via * \ref RAIL_HoldRxPacket(). It may optionally be called within a * callback context to release RAIL resources sooner than at * callback completion time when not holding the packet. * This function can be used in any RX mode. * * @param[in] railHandle A RAIL instance handle. * @param[in] packetHandle A packet handle as returned from a previous * \ref RAIL_HoldRxPacket() call, or sentinel values * \ref RAIL_RX_PACKET_HANDLE_OLDEST, * \ref RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE * or \ref RAIL_RX_PACKET_HANDLE_NEWEST. * The latter might be used within RAIL callback context to explicitly * release the packet associated with the callback early, before it's * released automatically by RAIL on callback return (unless explicitly * held). * @return \ref RAIL_STATUS_NO_ERROR if the held packet was released * or an appropriate error code otherwise. */ RAIL_Status_t RAIL_ReleaseRxPacket(RAIL_Handle_t railHandle, RAIL_RxPacketHandle_t packetHandle); /** * Return the current raw RSSI. * * @param[in] railHandle A RAIL instance handle. * @param[in] wait if false returns instant RSSI with no checks. * @return \ref RAIL_RSSI_INVALID if the receiver is disabled and an RSSI * value can't be obtained. Otherwise, return the RSSI in quarter dBm, dbm*4. * * Gets the current RSSI value. This value represents the current energy of the * channel. It can change rapidly and will be low if no RF energy is * in the current channel. The function from the value reported to dBm is an * offset dependent on the PHY and the PCB layout. Characterize the * RSSI received on your hardware and apply an offset in the application to * account for board and PHY parameters. When 'wait' is false, the radio needs * to be currently in RX and have been in there for a sufficient amount of time * for a fresh RSSI value to be read and returned. Otherwise, the RSSI is * considered stale and \ref RAIL_RSSI_INVALID is returned instead. When 'wait' * is true, if the radio is transitioning to or already in RX, this function * will wait for a valid RSSI to be read and return it. Otherwise, if the radio * is in or transitions to IDLE or TX, \ref RAIL_RSSI_INVALID will be returned. * On low datarate PHYs, this function can take a significantly longer time when * wait is true. * * In multiprotocol, this function returns \ref RAIL_RSSI_INVALID * immediately if railHandle is not the currently active \ref RAIL_Handle_t. * Additionally, 'wait' should never be set 'true' in multiprotocol * as the wait time is not consistent, so scheduling a scheduler * slot cannot be done accurately. Rather if waiting for a valid RSSI is * desired, use \ref RAIL_GetRssiAlt instead to apply a bounded time period. * * @note If RX Antenna Diversity is enabled via \ref RAIL_ConfigRxOptions(), * pass true for the wait parameter otherwise it's very likely * \ref RAIL_RSSI_INVALID will be returned. * * @note If RX channel hopping is turned on, do not use this API. * Instead, see RAIL_GetChannelHoppingRssi(). * * @note When 'wait' is false, this API is equivalent to \ref RAIL_GetRssiAlt * with 'waitTimeout' set to \ref RAIL_GET_RSSI_NO_WAIT. When 'wait' is * true, this API is equivalent to \ref RAIL_GetRssiAlt with 'waitTimeout' * set to \ref RAIL_GET_RSSI_WAIT_WITHOUT_TIMEOUT. Consider using * \ref RAIL_GetRssiAlt if a bounded maximum wait timeout is desired. */ int16_t RAIL_GetRssi(RAIL_Handle_t railHandle, bool wait); /** * Return the current raw RSSI in quarter-dBm within a definitive time period. * * @param[in] railHandle A RAIL instance handle. * @param[in] waitTimeout Sets the maximum time in microseconds to wait for a valid RSSI. * If equal to \ref RAIL_GET_RSSI_NO_WAIT returns instant RSSI with no checks. * If equal to \ref RAIL_GET_RSSI_WAIT_WITHOUT_TIMEOUT waits for a valid RSSI * with no maximum timeout. * @return \ref RAIL_RSSI_INVALID if the receiver is disabled and an RSSI * value can't be obtained. Otherwise, return the RSSI in quarter dBm (dBm*4). * * Gets the current RSSI value. This value represents the current energy of the * channel. It can change rapidly, and will be low if no RF energy is * in the current channel. The function from the value reported to dBm is an * offset dependent on the PHY and the PCB layout. Characterize the * RSSI received on your hardware and apply an offset in the application to * account for board and PHY parameters. If a value of \ref RAIL_GET_RSSI_NO_WAIT * is given for waitTimeout, the radio needs to be currently in RX and have been * in there for a sufficient amount of time for a fresh RSSI value to be read and * returned. Otherwise the RSSI is considered stale and \ref RAIL_RSSI_INVALID is * returned instead. For non-zero values of waitTimeout, if the radio is * transitioning to or already in RX, this function will wait a maximum time equal * to waitTimeout (or indefinitely if waitTimeout is set to * \ref RAIL_GET_RSSI_WAIT_WITHOUT_TIMEOUT) for a valid RSSI to be read and return * it. Otherwise, if the waitTimeout is reached, or the radio is in or transitions * to IDLE or TX, \ref RAIL_RSSI_INVALID will be returned. On low datarate PHYs, * this function can take a significantly longer time when waitTimeout is non-zero. * * In multiprotocol, this function returns \ref RAIL_RSSI_INVALID * immediately if railHandle is not the currently active \ref RAIL_Handle_t. * Additionally, waitTimeout should never be set to a value other than * \ref RAIL_GET_RSSI_NO_WAIT in multiprotocol as the integration between this * feature and the radio scheduler has not been implemented. * * @note If RX Antenna Diversity is enabled via \ref RAIL_ConfigRxOptions(), * pass true for the wait parameter otherwise it's very likely * \ref RAIL_RSSI_INVALID will be returned. * * @note If RX Antenna Diversity is enabled via \ref RAIL_ConfigRxOptions(), * the RSSI value returned could come from either antenna and vary between antennas. * * @note If RX channel hopping is turned on, do not use this API. * Instead, see \ref RAIL_GetChannelHoppingRssi(). */ int16_t RAIL_GetRssiAlt(RAIL_Handle_t railHandle, RAIL_Time_t waitTimeout); /** * Start the RSSI averaging over a specified time in us. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel The physical channel to set. * @param[in] averagingTimeUs Averaging time in microseconds. * @param[in] schedulerInfo A pointer to information to allow the radio scheduler to place * this operation appropriately. This is only used in multiprotocol version of * RAIL and may be set to NULL in all other versions. * @return Status code indicating success of the function call. * * Starts a non-blocking hardware-based RSSI averaging mechanism. Only a single * instance of RSSI averaging can be run at any time and the radio must be idle * to start. * * In multiprotocol, this is a scheduled event. It will start when railHandle * becomes active. railHandle needs to stay active until the averaging * completes. If the averaging is interrupted, calls to * \ref RAIL_GetAverageRssi() will return \ref RAIL_RSSI_INVALID. * * Also in multiprotocol, the user is required to call \ref RAIL_YieldRadio() * after this event completes (i.e., when \ref RAIL_EVENT_RSSI_AVERAGE_DONE * occurs). * * @note If the radio is idled while RSSI averaging is still in effect, a * \ref RAIL_EVENT_RSSI_AVERAGE_DONE event may not occur and * \ref RAIL_IsAverageRssiReady() may never return true. * * @note Completion of RSSI averaging, marked by RAIL event * \ref RAIL_EVENT_RSSI_AVERAGE_DONE, will return the radio to idle state. */ RAIL_Status_t RAIL_StartAverageRssi(RAIL_Handle_t railHandle, uint16_t channel, RAIL_Time_t averagingTimeUs, const RAIL_SchedulerInfo_t *schedulerInfo); /** * Query whether the RSSI averaging is done. * * @param[in] railHandle A RAIL instance handle. * @return true if done and false otherwise. * * This function can be used to poll for completion of the RSSI averaging * to avoid relying on an interrupt-based callback. * * @note If the radio is idled while RSSI averaging is still in effect, * this function may never return true. */ bool RAIL_IsAverageRssiReady(RAIL_Handle_t railHandle); /** * Get the RSSI in quarter-dBm averaged over a specified time in microseconds. * * @param[in] railHandle A RAIL instance handle. * @return The RSSI in quarter-dBm (dBm * 4), or \ref RAIL_RSSI_INVALID * if the receiver is disabled or an an RSSI value couldn't be obtained. * * Gets the hardware RSSI average after issuing \ref RAIL_StartAverageRssi(). * Use after \ref RAIL_StartAverageRssi(). */ int16_t RAIL_GetAverageRssi(RAIL_Handle_t railHandle); /** * Set the RSSI offset. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] rssiOffset desired dB offset to be added to the RSSI measurements. * @return Status code indicating success of the function call. * \ref RAIL_STATUS_INVALID_CALL if called with radio-generic handle, such * as \ref RAIL_EFR32_HANDLE, after RAIL initialization. * \ref RAIL_STATUS_INVALID_PARAMETER if the RSSI offset is deemed large * enough to cause the RSSI readings to underflow or overflow. * * Adds an offset to the RSSI in dBm. This offset affects all functionality that * depends on RSSI values, such as CCA functions. Do not modify the offset * dynamically during packet reception. This function * can only be called while the radio is off, or in the case of multiprotocol, * on an inactive protocol. * * @note: If RAIL has not been initialized, a radio-generic handle, * such as \ref RAIL_EFR32_HANDLE, can be used to set a radio's RSSI offset * applied to all protocols on that radio. * * @note: Setting a large rssiOffset may still cause the RSSI readings to * underflow. If that happens, the RSSI value returned by * \ref RAIL_GetRssi(), \ref RAIL_GetAverageRssi(), * \ref RAIL_GetChannelHoppingRssi() etc. will be \ref RAIL_RSSI_LOWEST. * * @note: During \ref Rx_Channel_Hopping this API will not update the * RSSI offset immediately if channel hopping has already been configured. * A subsequent call to \ref RAIL_ZWAVE_ConfigRxChannelHopping() or * \ref RAIL_ConfigRxChannelHopping() is required for the new RSSI offset to * take effect. */ RAIL_Status_t RAIL_SetRssiOffset(RAIL_Handle_t railHandle, int8_t rssiOffset); /** * Get the radio or protocol RSSI offset in dB. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return The RSSI offset in dB corresponding to the railHandle. * * @note: A radio-generic handle, such as \ref RAIL_EFR32_HANDLE, can be used to * get the radio's RSSI offset otherwise this will return the RSSI offset * value associated with the RAIL protocol instance handle, exclusive of any * radio RSSI offset correction, if any. */ int8_t RAIL_GetRssiOffset(RAIL_Handle_t railHandle); /** * Set the RSSI detection threshold in dBm to trigger * \ref RAIL_EVENT_DETECT_RSSI_THRESHOLD. * * @param[in] railHandle A RAIL instance handle. * @param[in] rssiThresholdDbm desired RSSI threshold in dBm over which the event * \ref RAIL_EVENT_DETECT_RSSI_THRESHOLD is triggered. * @return Status code indicating success of the function call. * Returns \ref RAIL_STATUS_INVALID_STATE in multiprotocol, * if the requested railHandle is not active. * Returns \ref RAIL_STATUS_INVALID_CALL if called on parts on which this function * is not supported. * * When in receive, RSSI is sampled and if it exceeds the threshold, * \ref RAIL_EVENT_DETECT_RSSI_THRESHOLD is triggered. * * @note: If the radio is idled or this function is called with rssiThresholdDbm as * \ref RAIL_RSSI_INVALID_DBM while RSSI detect is still in effect, a * \ref RAIL_EVENT_DETECT_RSSI_THRESHOLD may not occur and the detection is disabled. * If the RSSI is already above threshold when this function is called then * \ref RAIL_EVENT_DETECT_RSSI_THRESHOLD will occur. * Once the RSSI goes over the configured threshold and * \ref RAIL_EVENT_DETECT_RSSI_THRESHOLD occurs, this function needs to be * called again to reactivate the RSSI threshold detection. * * This function is only available on EFR32 Series 2 Sub-GHz parts EFR32xG23 and EFR32xG25. */ RAIL_Status_t RAIL_SetRssiDetectThreshold(RAIL_Handle_t railHandle, int8_t rssiThresholdDbm); /** * Get the RSSI detection threshold in dBm. * * @param[in] railHandle a RAIL instance handle. * @return The RSSI threshold in dBm corresponding to the railHandle. * * @note: The function returns \ref RAIL_RSSI_INVALID_DBM when * \ref RAIL_SetRssiDetectThreshold() is not supported or disabled. * In multiprotocol, the function returns \ref RAIL_RSSI_INVALID_DBM if railHandle * is not active. * * This function is only available on EFR32 Series 2 Sub-GHz parts EFR32xG23 and EFR32xG25. */ int8_t RAIL_GetRssiDetectThreshold(RAIL_Handle_t railHandle); /** * Return the RSSI associated with the incoming packet. * * @param[in] railHandle A RAIL instance handle. * @return The RSSI on the incoming packet in dBm, * or \ref RAIL_RSSI_INVALID_DBM if not available. * * This function can only be called from callback context, e.g., * when handling \ref RAIL_EVENT_RX_FILTER_PASSED or * \ref RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND. */ int8_t RAIL_GetRxIncomingPacketRssi(RAIL_Handle_t railHandle); /** * Set up a callback function capable of converting a RX packet's LQI value * before being consumed by application code. * * @param[in] railHandle A RAIL instance handle. * @param[in] cb A callback of type \ref RAIL_ConvertLqiCallback_t that is * called before the RX packet LQI value is loaded into the \ref * RAIL_RxPacketDetails_t structure for application consumption. * @return Status code indicating success of the function call. */ RAIL_Status_t RAIL_ConvertLqi(RAIL_Handle_t railHandle, RAIL_ConvertLqiCallback_t cb); /****************************************************************************** * Address Filtering (RX) *****************************************************************************/ /** * @addtogroup Address_Filtering Address Filtering * @brief Configuration APIs for receive packet address filtering. * * The address filtering code examines the packet as follows. * * | `Bytes: 0 - 255` | `0 - 8` | `0 - 255` | `0 - 8` | `Variable` | * |:----------------:|----------:|----------:|----------:|:----------:| * | `Data_0` | `Field_0` | `Data_1` | `Field_1` | `Data_2` | * * In the above structure, anything listed as Data_# is an optional section of * bytes that RAIL will not process for address filtering. The Field_# segments * reference specific sections in the packet that will each be interpreted * as an address during address filtering. The application may submit up to * four addresses to attempt to match each field segment and each address may * have a size of up to 8 bytes. To set up address filtering, first configure * the locations and length of the addresses in the packet. Next, configure * which combinations of matches in Field_0 and Field_1 should constitute an * address match. Last, enter addresses into tables for each field and * enable them. The first two of these are part of the \ref RAIL_AddrConfig_t * structure while the second part is configured at runtime using the * \ref RAIL_SetAddressFilterAddress() API. A brief description of each * configuration is listed below. * * The offsets and sizes of the fields * are assumed fixed for the RAIL address filter. To set them, specify * arrays for these values in the sizes and offsets entries in the * \ref RAIL_AddrConfig_t structure. A size of zero indicates that a field is * disabled. The start offset for a field is relative to the previous start * offset and, if you're using frame type decoding, the first start offset is * relative to the end of the byte containing the frame type. * * Configuring which combinations of Field_0 and Field_1 constitute a match is * the most complex portion of the address filter. The easiest way to think * about this is with a truth table. If you consider each of the four possible * address entries in a field, you can have a match on any one of those or a * match for none of them. This is shown in the 5x5 truth table below where * Field_0 matches are the rows and Field_1 matches are the columns. * * | | No Match | Address 0 | Address 1 | Address 2 | Address 3 | * |----------------|----------|-----------|-----------|-----------|-----------| * | __No Match__ | bit 0 | bit 1 | bit 2 | bit 3 | bit 4 | * | __Address 0__ | bit 5 | bit 6 | bit 7 | bit 8 | bit 9 | * | __Address 1__ | bit 10 | bit 11 | bit 12 | bit 13 | bit 14 | * | __Address 2__ | bit 15 | bit 16 | bit 17 | bit 18 | bit 19 | * | __Address 3__ | bit 20 | bit 21 | bit 22 | bit 23 | bit 24 | * * Because this is only 25 bits, it can be represented in one 32-bit integer * where 1 indicates a filter pass and 0 indicates a filter fail. This is the * \ref RAIL_AddrConfig_t::matchTable field and is used during * filtering. For common simple configurations, two defines are provided with * the truth tables as shown below. The first is \ref * ADDRCONFIG_MATCH_TABLE_SINGLE_FIELD, which can be used if only using * one address field (either field). If using two fields and want to * force in the same address entry in each field, use the second define: \ref * ADDRCONFIG_MATCH_TABLE_DOUBLE_FIELD. For more complex systems, * create a valid custom table. * * @note Address filtering does not function reliably with PHYs that use a data * rate greater than 500 kbps. If this is a requirement, filtering must * currently be done by the application. * * @{ */ /** * Configure address filtering. * * @param[in] railHandle A RAIL instance handle. * @param[in] addrConfig A pointer to the configuration structure, which defines how * addresses are set up in your packets. May be NULL to reset address filtering. * @return Status code indicating success of the function call. * * You must call this function to set up address filtering. You may call it * multiple times but all previous information is wiped out each time you call * and any configured addresses must be reset. */ RAIL_Status_t RAIL_ConfigAddressFilter(RAIL_Handle_t railHandle, const RAIL_AddrConfig_t *addrConfig); /** * Enable address filtering. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable An argument to indicate whether or not to enable address * filtering. * @return true if address filtering was enabled to start with and false * otherwise. * * Only allow packets through that pass the current address filtering * configuration. This does not reset or change the configuration so you can * set that up before turning on this feature. */ bool RAIL_EnableAddressFilter(RAIL_Handle_t railHandle, bool enable); /** * Return whether address filtering is currently enabled. * * @param[in] railHandle A RAIL instance handle. * @return true if address filtering is enabled and false otherwise. */ bool RAIL_IsAddressFilterEnabled(RAIL_Handle_t railHandle); /** * Reset the address filtering configuration. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * Resets all structures related to address filtering. This does not disable * address filtering. It leaves the radio in a state where no packets * pass filtering. */ RAIL_Status_t RAIL_ResetAddressFilter(RAIL_Handle_t railHandle); /** * Set an address for filtering in hardware. * * @param[in] railHandle A RAIL instance handle. * @param[in] field Indicates an address field for this address. * @param[in] index Indicates a match entry for this address for a * given field. * @param[in] value A pointer to the address data. This must be at least as * long as the size specified in \ref RAIL_ConfigAddressFilter(). The first byte, * value[0], will be compared to the first byte received over the air for this * address field. * @param[in] enable A boolean to indicate whether this address should be * enabled immediately. * @return Status code indicating success of the function call. * * This function loads the given address into hardware for filtering and * starts filtering if you set the enable parameter to true. Otherwise, * call \ref RAIL_EnableAddressFilterAddress() to turn it on later. */ RAIL_Status_t RAIL_SetAddressFilterAddress(RAIL_Handle_t railHandle, uint8_t field, uint8_t index, const uint8_t *value, bool enable); /** * Set an address bit mask for filtering in hardware. * * @param[in] railHandle A RAIL instance handle. * @param[in] field Indicates an address field for this address bit mask. * @param[in] bitMask A pointer to the address bitmask. This must be at least * as long as the size specified in \ref RAIL_ConfigAddressFilter(). The first * byte, bitMask[0], will be applied to the first byte received over the air * for this address field. Bits set to 1 in the bit mask indicate which bit * positions in the incoming packet to compare against the stored addresses * during address filtering. Bits set to 0 indicate which bit positions to * ignore in the incoming packet during address filtering. This bit mask is * applied to all address entries. * @return Status code indicating success of the function call. * * This function loads the given address bit mask into hardware for use when * address filtering is enabled. All bits in the stored address bit mask are * set to 1 during hardware initialization and when either \ref * RAIL_ConfigAddressFilter() or \ref RAIL_ResetAddressFilter() are called. * * @note This feature/API is not supported on the EFR32xG21. * Use the compile time symbol \ref * RAIL_SUPPORTS_ADDR_FILTER_ADDRESS_BIT_MASK or the runtime call \ref * RAIL_SupportsAddrFilterAddressBitMask() to check whether the platform * supports this feature. */ RAIL_Status_t RAIL_SetAddressFilterAddressMask(RAIL_Handle_t railHandle, uint8_t field, const uint8_t *bitMask); /** * Enable address filtering for the specified address. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable An argument to indicate whether or not to enable address * filtering. * @param[in] field Indicates an address for the address. * @param[in] index Indicates a match entry in the given field you want to enable. * @return Status code indicating success of the function call. */ RAIL_Status_t RAIL_EnableAddressFilterAddress(RAIL_Handle_t railHandle, bool enable, uint8_t field, uint8_t index); /** @} */ // end of group Address_Filtering /** @} */ // end of group Receive /****************************************************************************** * Auto-Acking *****************************************************************************/ /// @addtogroup Auto_Ack Auto-Ack /// @brief APIs for configuring Auto-Ack functionality /// /// These APIs configure the radio for automatic acknowledgment /// features. Auto-Ack inherently changes how the underlying state machine /// behaves so users should not modify \ref RAIL_SetRxTransitions() and /// \ref RAIL_SetTxTransitions() while using Auto-Ack features. /// @code{.c} /// // Go to RX after Ack operation. /// RAIL_AutoAckConfig_t autoAckConfig = { /// .enable = true, /// .ackTimeout = 1000, /// .rxTransitions = { /// .success = RAIL_RF_STATE_RX, /// .error = RAIL_RF_STATE_RX /// }, /// .txTransitions = { /// .success = RAIL_RF_STATE_RX, /// .error = RAIL_RF_STATE_RX, /// }, /// }; /// /// RAIL_Status_t status = RAIL_ConfigAutoAck(railHandle, &autoAckConfig); /// /// uint8_t ackData[] = {0x05, 0x02, 0x10, 0x00}; /// /// RAIL_Status_t status = RAIL_WriteAutoAckFifo(railHandle, /// ackData, /// sizeof(ackData)); /// @endcode /// /// The acknowledgment transmits based on the frame format configured via /// the Radio Configurator. For example, if the frame format is using a variable /// length scheme, the Ack will be sent according to that scheme. If a 10-byte /// packet is loaded into the Ack, but the variable length field of the Ack /// payload specifies a length of 5, only 5 bytes will transmit for the Ack. /// The converse is also true, if the frame length is configured to be a fixed /// 10-byte packet but only 5 bytes are loaded into the Ack buffer, a TX /// underflow occurs during the Ack transmit. /// /// Unlike in non-Auto-Ack mode, Auto-Ack mode will always return to a single /// state after all Ack sequences complete, regardless of whether /// the Ack was successfully received/sent or not. See the documentation /// of \ref RAIL_ConfigAutoAck() for configuration information. To /// suspend automatic acknowledgment of a series of packets after transmit /// or receive call \ref RAIL_PauseTxAutoAck() or \ref RAIL_PauseRxAutoAck() respectively /// with the pause parameter set to true. When Auto-Acking is paused, after /// receiving or transmitting a packet (regardless of success), the radio /// transitions to the same state it would use while Acking. To return to /// normal state transition logic outside of Acking, call \ref /// RAIL_ConfigAutoAck() with the \ref RAIL_AutoAckConfig_t::enable field false /// and specify the desired transitions in the \ref /// RAIL_AutoAckConfig_t::rxTransitions and RAIL_AutoAckConfig_t::txTransitions /// fields. To get out of a paused state and resume Auto-Acking, call \ref /// RAIL_PauseTxAutoAck() and/or \ref RAIL_PauseRxAutoAck() with the pause parameter /// set to false. /// /// Applications can cancel the transmission of an Ack with \ref /// RAIL_CancelAutoAck(). Conversely, applications can control if a transmit /// operation should wait for an Ack after transmitting by using /// the \ref RAIL_TX_OPTION_WAIT_FOR_ACK option. /// /// When \ref Antenna_Control is used for multiple antennas, Acks are /// transmitted on the antenna that was selected to receive the packet /// being acknowledged. When receiving an Ack, the /// \ref RAIL_RxOptions_t antenna options are used just like for any other /// receive. /// /// If the Ack payload is dynamic, the application must call \ref /// RAIL_WriteAutoAckFifo() with the appropriate Ack payload after the /// application processes the receive. RAIL can Auto-Ack from the normal /// transmit buffer if \ref RAIL_UseTxFifoForAutoAck() is called before the radio /// transmits the Ack. Ensure the transmit buffer contains data loaded by \ref /// RAIL_WriteTxFifo(). /// /// Standard-based protocols that contain Auto-Ack functionality are normally /// configured in the protocol-specific configuration function. For example, /// \ref RAIL_IEEE802154_Init() provides Auto-Ack configuration parameters in \ref /// RAIL_IEEE802154_Config_t and should only be configured through that /// function. It is not advisable to call both \ref RAIL_IEEE802154_Init() and \ref /// RAIL_ConfigAutoAck(). However, Ack modification functions are still valid to /// use with protocol-specific Acks. To cancel an IEEE 802.15.4 Ack transmit, /// use \ref RAIL_CancelAutoAck(). /// /// @{ /// Configure and enable automatic acknowledgment. /// /// @param[in] railHandle A RAIL instance handle. /// @param[in] config A pointer to an Auto-Ack configuration structure. /// @return Status code indicating success of the function call. /// /// Configures the RAIL state machine for hardware-accelerated automatic /// acknowledgment. Ack timing parameters are defined in the configuration /// structure. /// /// While Auto-Acking is enabled, do not call the following RAIL functions: /// - \ref RAIL_SetRxTransitions() /// - \ref RAIL_SetTxTransitions() /// /// When Auto-Acking is enabled, only one state transition can be defined /// (without notion of success or error). /// Thus if you are enabling Auto-Ack (i.e., config->enable field is true) /// the "error" states of config->rxTransitions and config->txTransitions are ignored. /// After all Ack sequences, (success or fail) the state machine will return /// the radio to the "success" state, which can be either /// \ref RAIL_RF_STATE_RX or \ref RAIL_RF_STATE_IDLE (returning to /// \ref RAIL_RF_STATE_TX is not supported). /// Alternatively when Auto-Acking is disabled (i.e., config->enable field is /// false), transitions are reconfigured using all fields of config->rxTransitions /// and config->txTransitions. When disabling, the "ackTimeout" field isn't used. /// /// If you need information about the /// actual success of the Ack sequence, use RAIL events such as /// \ref RAIL_EVENT_TXACK_PACKET_SENT to make sure an Ack was sent, or /// \ref RAIL_EVENT_RX_ACK_TIMEOUT to make sure that an Ack was received /// within the specified timeout. /// /// To set a certain turnaround time (i.e., txToRx and rxToTx /// in \ref RAIL_StateTiming_t), make txToRx lower than /// desired to ensure you get to RX in time to receive the Ack. /// Silicon Labs recommends setting 10 us lower than desired: /// @code{.c} /// void setAutoAckStateTimings(void) /// { /// RAIL_StateTiming_t timings; /// /// // User is already in Auto-Ack and wants a turnaround of 192 us. /// timings.rxToTx = 192; /// timings.txToRx = 192 - 10; /// /// // Set other fields of timings... /// timings.idleToRx = 100; /// timings.idleToTx = 100; /// timings.rxSearchTimeout = 0; /// timings.txToRxSearchTimeout = 0; /// /// RAIL_SetStateTiming(railHandle, &timings); /// } /// @endcode /// /// @note Auto-Acking may not be enabled while RX Channel Hopping is enabled, /// or when BLE is enabled. /// RAIL_Status_t RAIL_ConfigAutoAck(RAIL_Handle_t railHandle, const RAIL_AutoAckConfig_t *config); /** * Return the enable status of the Auto-Ack feature. * * @param[in] railHandle A RAIL instance handle. * @return true if Auto-Ack is enabled, false if disabled. */ bool RAIL_IsAutoAckEnabled(RAIL_Handle_t railHandle); /** * Load the Auto-Ack buffer with Ack data. * * @param[in] railHandle A RAIL instance handle. * @param[in] ackData A pointer to Ack data to transmit. * This may be NULL, in which case it's assumed the data has already * been emplaced into the Ack buffer and RAIL just needs to be told * how many bytes are there. Use \ref RAIL_GetAutoAckFifo() to get * the address of RAIL's Auto-Ack buffer in RAM and its size. * @param[in] ackDataLen The number of bytes in Ack data. * @return Status code indicating success of the function call. * * If the Ack buffer is available for updates, load the Ack buffer with data. * If it is not available, \ref RAIL_STATUS_INVALID_STATE is returned. * If ackDataLen exceeds \ref RAIL_AUTOACK_MAX_LENGTH then * \ref RAIL_STATUS_INVALID_PARAMETER will be returned and nothing is * written to the Ack buffer (unless ackData is NULL in which case this * indicates the application has already likely corrupted RAM). */ RAIL_Status_t RAIL_WriteAutoAckFifo(RAIL_Handle_t railHandle, const uint8_t *ackData, uint16_t ackDataLen); /** * Get the address and size of the Auto-Ack transmit buffer for direct access. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] ackBuffer A pointer to a uint8_t pointer that will be * updated to the RAM base address of the Auto-Ack FIFO buffer. * @param[in,out] ackBufferBytes A pointer to a uint16_t that will be * updated to the size of the Auto-Ack FIFO buffer, in bytes, * currently \ref RAIL_AUTOACK_MAX_LENGTH. * @return Status code indicating success of the function call. * * Applications can use this to more flexibly write Auto-Ack data into * the buffer directly and in pieces, passing NULL ackData parameter to * \ref RAIL_WriteAutoAckFifo() or \ref RAIL_IEEE802154_WriteEnhAck() * to inform RAIL of its final length. */ RAIL_Status_t RAIL_GetAutoAckFifo(RAIL_Handle_t railHandle, uint8_t **ackBuffer, uint16_t *ackBufferBytes); /** * Pause/resume RX Auto-Ack functionality. * * @param[in] railHandle A RAIL instance handle. * @param[in] pause Pause or resume RX Auto-Acking. * @return Status code indicating success of the function call. * * When RX Auto-Acking is paused, the radio transitions to * \ref RAIL_AutoAckConfig_t::rxTransitions's * \ref RAIL_StateTransitions_t::success state after receiving a packet and * does not transmit an Ack. When RX Auto-Ack is resumed, the radio resumes * automatically Acking every successfully received packet. */ RAIL_Status_t RAIL_PauseRxAutoAck(RAIL_Handle_t railHandle, bool pause); /** * Return whether the RX Auto-Ack is paused. * * @param[in] railHandle A RAIL instance handle. * @return true if RX Auto-Ack is paused, false if not paused. */ bool RAIL_IsRxAutoAckPaused(RAIL_Handle_t railHandle); /** * Pause/resume TX Auto-Ack functionality. * * @param[in] railHandle A RAIL instance handle. * @param[in] pause Pause or resume TX Auto-Acking. * @return Status code indicating success of the function call. * * When TX Auto-Acking is paused, the radio transitions to * \ref RAIL_AutoAckConfig_t::txTransitions's * \ref RAIL_StateTransitions_t::success state after transmitting a packet and * does not wait for an Ack. When TX Auto-Ack is resumed, the radio resumes * automatically waiting for an Ack after a successful transmit. */ RAIL_Status_t RAIL_PauseTxAutoAck(RAIL_Handle_t railHandle, bool pause); /** * Return whether the TX Auto-Ack is paused. * * @param[in] railHandle A RAIL instance handle. * @return true if TX Auto-Ack is paused, false if not paused. */ bool RAIL_IsTxAutoAckPaused(RAIL_Handle_t railHandle); /** * Modify the upcoming Ack to use the transmit FIFO. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. The call will * fail if it is too late to modify the outgoing Ack. * * This function allows the application to use the normal transmit FIFO as * the data source for the upcoming Ack. The Ack modification to use the * transmit FIFO only applies to one Ack transmission. * * This function only returns true if the following conditions are met: * - Radio has not already decided to use the Ack buffer AND * - Radio is either looking for sync, receiving the packet after sync, or in * the \ref RAIL_StateTiming_t::rxToTx turnaround before the Ack is sent. * * @note The transmit FIFO must not be used for Auto-Ack when IEEE 802.15.4, * Z-Wave, or BLE protocols are active. */ RAIL_Status_t RAIL_UseTxFifoForAutoAck(RAIL_Handle_t railHandle); /** * Cancel the upcoming Ack. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. This call will * fail if it is too late to modify the outgoing Ack. * * This function allows the application to cancel the upcoming automatic * acknowledgment. * * This function only returns true if the following conditions are met: * - Radio has not already decided to transmit the Ack, and * - Radio is either looking for sync, receiving the packet after sync or in * the \ref RAIL_StateTiming_t::rxToTx turnaround before the Ack is sent. */ RAIL_Status_t RAIL_CancelAutoAck(RAIL_Handle_t railHandle); /** * Return whether the radio is currently waiting for an Ack. * * @param[in] railHandle A RAIL instance handle. * @return true if radio is waiting for Ack, false if radio is not waiting for * an Ack. * * This function allows the application to query whether the radio is currently * waiting for an Ack after a transmit operation. */ bool RAIL_IsAutoAckWaitingForAck(RAIL_Handle_t railHandle); /** @} */ // end of group Auto_Ack /****************************************************************************** * Calibration *****************************************************************************/ /// @addtogroup Calibration /// @brief APIs for calibrating the radio /// @{ /// /// These APIs calibrate the radio. The RAIL library /// determines which calibrations are necessary. Calibrations can /// be enabled/disabled with the \ref RAIL_CalMask_t parameter. /// /// Some calibrations produce values that can be saved and reapplied to /// avoid repeating the calibration process. /// /// Calibrations can either be run with \ref RAIL_Calibrate(), or with the /// individual chip-specific calibration routines. An example for running code /// with \ref RAIL_Calibrate() looks like the following: /// @code{.c} /// static RAIL_CalValues_t calValues = RAIL_CALVALUES_UNINIT; /// static volatile bool calibrateRadio = false; /// /// void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events) /// { /// // Omitting other event handlers /// if (events & RAIL_EVENT_CAL_NEEDED) { /// calibrateRadio = true; /// } /// } /// /// void main(void) /// { /// // Initialize RAIL ... /// /// // Application main loop /// while (1) { /// ... /// if (calibrateRadio) { /// // Run all pending calibrations, and save the results /// RAIL_Calibrate(railHandle, &calValues, RAIL_CAL_ALL_PENDING); /// calibrateRadio = false; /// } /// ... /// } /// } /// @endcode /// /// Alternatively, if the image rejection calibration for your radio can be /// determined ahead of time, such as by running the calibration on a separate /// firmware image on each chip, the following calibration process will /// result in smaller code. /// @code{.c} /// static RAIL_IrCalValues_t irCalValues = { /// .rxIrCalValues = { /// RX_IRCAL_VALUE_RF_PATH0, /// RX_IRCAL_VALUE_RF_PATH1, /// }, /// .txIrCalValues = { /// .dcOffsetIQ = TX_IRCAL_DC_OFFSET_IQ, /// .phiEpsilon = TX_IRCAL_PHI_EPSILON, /// }, /// }; /// /// void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events) /// { /// // Omitting other event handlers /// if (events & RAIL_EVENT_CAL_NEEDED) { /// RAIL_CalMask_t pendingCals = RAIL_GetPendingCal(railHandle); /// // Disable the radio if we have to do an offline calibration /// if (pendingCals & RAIL_CAL_TEMP_VC0) { /// (void) RAIL_CalibrateTemp(railHandle); /// } /// if (pendingCals & RAIL_CAL_ONETIME_IRCAL) { /// (void) RAIL_ApplyIrCalibrationAlt(rail_handle, &ir_cal_values, RAIL_ANTENNA_AUTO); /// } /// } /// } /// @endcode /** * Initialize RAIL calibration. * * @param[in] railHandle A RAIL instance handle. * @param[in] calEnable A bitmask that indicates which calibrations * to enable for a callback notification. * The exact meaning of these bits is radio-specific. * @return Status code indicating success of the function call. * * Calibration initialization provides the calibration settings that * correspond to the current radio configuration. */ RAIL_Status_t RAIL_ConfigCal(RAIL_Handle_t railHandle, RAIL_CalMask_t calEnable); /** * Start the calibration process. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] calValues A pointer to a structure of calibration values to apply. * If a valid calibration structure is provided and the structure * contains valid calibration values, those values will be applied to the * hardware and the RAIL library will cache those values for use again later. * If a valid calibration structure is provided and the structure * contains a calibration value of \ref RAIL_CAL_INVALID_VALUE for the * desired calibration, the desired calibration will run, the calibration * values structure will be updated with a valid calibration value, and the * RAIL library will cache that value for use again later. * If a NULL pointer is provided, the desired calibration will run * and the RAIL library will cache that value for use again later. However, * the valid calibration value will not be returned to the application. * @param[in] calForce A mask to force specific calibration(s) to execute. * To run all pending calibrations, use the value \ref RAIL_CAL_ALL_PENDING. * Only the calibrations specified will run, even if not enabled during * initialization. * @return Status code indicating success of the function call. * * If calibrations were performed previously and the application saves the * calibration values (i.e., call this function with a calibration values * structure containing calibration values of \ref RAIL_CAL_INVALID_VALUE * before a reset), the application can later bypass the time it would normally * take to recalibrate hardware by reusing previous calibration values (i.e., * call this function with a calibration values structure containing valid * calibration values after a reset). * * Silicon Labs recommends calling this function from the application main loop. * * If multiple protocols are used, this function will make the given railHandle * active, if not already, and perform calibration. If called during a protocol * switch, to perform an IR calibration for the first time, it will * return \ref RAIL_STATUS_INVALID_STATE, in which case the application must * defer calibration until after the protocol switch is complete. * * @note Instead of this function, consider using the individual calibration-specific * functions. Using the individual functions will allow for better * dead-stripping if not all calibrations are run. * @note Some calibrations should only be executed when the radio is IDLE. See * chip-specific documentation for more details. */ RAIL_Status_t RAIL_Calibrate(RAIL_Handle_t railHandle, RAIL_CalValues_t *calValues, RAIL_CalMask_t calForce); /** * Return the current set of pending calibrations. * * @param[in] railHandle A RAIL instance handle. * @return A mask of all pending calibrations that the user has been asked to * perform. * * This function returns a full set of pending calibrations. The only way * to clear pending calibrations is to perform them using the \ref * RAIL_Calibrate() API with the appropriate list of calibrations. */ RAIL_CalMask_t RAIL_GetPendingCal(RAIL_Handle_t railHandle); /** * Apply a given image rejection calibration value. * * @param[in] railHandle A RAIL instance handle. * @param[in] imageRejection The image rejection value to apply. * @return Status code indicating success of the function call. * * Take an image rejection calibration value and apply it. This value should be * determined from a previous run of \ref RAIL_CalibrateIr on the same * physical device with the same radio configuration. The imageRejection value * will also be stored to the \ref RAIL_ChannelConfigEntry_t::attr, if possible. * * If multiple protocols are used, this function will return * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is * not active. In that case, the caller must attempt to re-call this function later. * * @deprecated Please use \ref RAIL_ApplyIrCalibrationAlt instead. */ RAIL_Status_t RAIL_ApplyIrCalibration(RAIL_Handle_t railHandle, uint32_t imageRejection); /** * Apply given image rejection calibration values. * * @param[in] railHandle A RAIL instance handle. * @param[in] imageRejection A pointer to the image rejection values to apply. * @param[in] rfPath RF path(s) to calibrate. * @return Status code indicating success of the function call. * * Take image rejection calibration values and apply them. These values should be * determined from a previous run of \ref RAIL_CalibrateIrAlt() on the same * physical device with the same radio configuration. The imageRejection values * will also be stored to the \ref RAIL_ChannelConfigEntry_t::attr, if possible. * * @note: To make sure the imageRejection values are stored/configured correctly, * \ref RAIL_ConfigAntenna() should be called before calling this API. * * If multiple protocols are used, this function will return * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is * not active. In that case, the caller must attempt to re-call this function later. */ RAIL_Status_t RAIL_ApplyIrCalibrationAlt(RAIL_Handle_t railHandle, RAIL_IrCalValues_t *imageRejection, RAIL_AntennaSel_t rfPath); /** * Run the image rejection calibration. * * @param[in] railHandle A RAIL instance handle. * @param[out] imageRejection The result of the image rejection calibration. * @return Status code indicating success of the function call. * * Run the image rejection calibration and apply the resulting value. If the * imageRejection parameter is not NULL, store the value at that * location. The imageRejection value will also be stored to the * \ref RAIL_ChannelConfigEntry_t::attr, if possible. This is a long-running * calibration that adds significant code space when run and can be run with a * separate firmware image on each device to save code space in the * final image. Silicon Labs recommends calling this function from the * application main loop. * * If multiple protocols are used, this function will make the given railHandle * active, if not already, and perform calibration. If called during a protocol * switch, it will return \ref RAIL_STATUS_INVALID_STATE. In this case, * \ref RAIL_ApplyIrCalibration may be called to apply a previously determined * IR calibration value, or the app must defer calibration until the * protocol switch is complete. * * @deprecated Please use \ref RAIL_CalibrateIrAlt instead. */ RAIL_Status_t RAIL_CalibrateIr(RAIL_Handle_t railHandle, uint32_t *imageRejection); /** * Run the image rejection calibration. * * @param[in] railHandle A RAIL instance handle. * @param[out] imageRejection A pointer to the image rejection results. * @param[in] rfPath RF path(s) to calibrate. * @return Status code indicating success of the function call. * * Run the image rejection calibration and apply the resulting values. If the * imageRejection parameter is not NULL, store the values at that * location. The imageRejection values will also be stored to the * \ref RAIL_ChannelConfigEntry_t::attr, if possible. This is a long-running * calibration that adds significant code space when run and can be run with a * separate firmware image on each device to save code space in the * final image. Silicon Labs recommends calling this function from the * application main loop. * * @note: To make sure the imageRejection values are stored/configured correctly, * \ref RAIL_ConfigAntenna() should be called before calling this API. * * If multiple protocols are used, this function will return * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is * not active. In that case, the caller must attempt to re-call this function later. */ RAIL_Status_t RAIL_CalibrateIrAlt(RAIL_Handle_t railHandle, RAIL_IrCalValues_t *imageRejection, RAIL_AntennaSel_t rfPath); /** * Run the temperature calibration. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * Run the temperature calibration, which needs to recalibrate the synth if * the temperature crosses 0C or the temperature delta since the last * calibration exceeds 70C while in receive. RAIL will run the VCO calibration * automatically upon entering receive or transmit states, so the application * can omit this calibration if the stack re-enters receive or transmit with * enough frequency to avoid reaching the temperature delta. If the application * does not calibrate for temperature, it's possible to miss receive packets due * to a drift in the carrier frequency. * * If multiple protocols are used, this function will return * \ref RAIL_STATUS_INVALID_STATE if it is called and the given railHandle is * not active. In that case, the calibration will be automatically performed * next time the radio enters receive. * * @note If RX channel hopping is enabled this function may trigger a * channel hop, which can result in \ref * RAIL_EVENT_RX_CHANNEL_HOPPING_COMPLETE occuring before it returns. */ RAIL_Status_t RAIL_CalibrateTemp(RAIL_Handle_t railHandle); /** * Performs HFXO compensation. * * @param[in] railHandle A RAIL instance handle. * @param[out] crystalPPMError A pointer for RAIL to store the current * deviation that has been corrected, measured in PPM. May be NULL. * @return Status code indicating the result of the function call. * * Compute the PPM correction using the thermistor value available when * \ref RAIL_EVENT_THERMISTOR_DONE occurs, after * \ref RAIL_StartThermistorMeasurement() call. * Then correct the RF frequency as well as TX and RX sampling. * * This function calls the following RAIL functions in sequence saving having * to call them individually: * - \ref RAIL_ConvertThermistorImpedance() * - \ref RAIL_ComputeHFXOPPMError() * - \ref RAIL_CompensateHFXO() * * @note This function makes the radio idle. */ RAIL_Status_t RAIL_CalibrateHFXO(RAIL_Handle_t railHandle, int8_t *crystalPPMError); /** * Enable/disable the PA calibration. * * @param[in] enable Enables/disables the PA calibration. * * Enabling will ensure that the PA power remains constant chip-to-chip. * This feature is enabled by default on Series-2 platforms. * * On EFR32xG21 and EFR32xG24 platforms, particularly the 20 dBm variants, * it is recommended to keep this feature enabled in order to utilize the * chip-specific calibrations designated for the chip. * * The chip-specific define SL_RAIL_UTIL_PA_CALIBRATION_ENABLE in the * \ref rail_util_pa plugin also enables/disables PA calibrations * on initialization, which can override the default state of the feature. * * @note Call this function before \ref RAIL_ConfigTxPower() if this * feature is not desired. */ void RAIL_EnablePaCal(bool enable); /** @} */ // end of group Calibration /****************************************************************************** * RF Sense Structures *****************************************************************************/ /** * @addtogroup Rf_Sense RF Sense * @{ */ /** * Start/stop the RF Sense functionality in Energy Detection Mode for use * during low-energy sleep modes. * * @param[in] railHandle A RAIL instance handle. * @param[in] band The frequency band(s) on which to sense the RF energy. * To stop RF Sense, specify \ref RAIL_RFSENSE_OFF. * @param[in] senseTime The time (in microseconds) the RF energy must be * continually detected to be considered "sensed". * @param[in] cb \ref RAIL_RfSense_CallbackPtr_t is called when the RF is * sensed. Set NULL if using \ref RAIL_EVENT_RF_SENSED or polling via * \ref RAIL_IsRfSensed(). * @return The actual senseTime used, which may be different than * requested due to limitations of the hardware. If 0, RF sense was * disabled or could not be enabled (no callback or event will be issued). * * Some EFR32 radios have the ability to sense the presence of RF energy above -20 dBm * within either or both the 2.4 GHz and Sub-GHz bands and trigger an event * if that energy is continuously present for certain durations of time. An * application can check when RF energy is sensed either by enabling the event * \ref RAIL_EVENT_RF_SENSED, by polling on the \ref RAIL_IsRfSensed() API, or * by using the cb callback. * * @note After RF energy has been sensed, the RF Sense is automatically * disabled and \ref RAIL_StartRfSense() must be called again to reactivate it. * If RF energy has not been sensed and to manually disable RF Sense, * \ref RAIL_StartRfSense() must be called with band specified as * \ref RAIL_RFSENSE_OFF or with senseTime set to 0 microseconds. * * @note Packet reception is not guaranteed to work correctly once RF Sense is * enabled, both in single protocol and multiprotocol RAIL. * To be safe, an application should turn this on only after idling * the radio to stop receive and turn it off before attempting to restart * receive. Since EM4 sleep causes the chip to come up through the reset * vector any wake from EM4 must also shut off RF Sense to ensure proper * receive functionality. * * @warning For some radios, RF Sense functionality is only guaranteed within * a specified temperature range. * See chip-specific documentation for more details. */ RAIL_Time_t RAIL_StartRfSense(RAIL_Handle_t railHandle, RAIL_RfSenseBand_t band, RAIL_Time_t senseTime, RAIL_RfSense_CallbackPtr_t cb); /// Start/stop the RF Sense functionality in Selective(OOK Based) Mode for use /// during low-energy sleep modes. /// /// @param[in] railHandle A RAIL instance handle. /// @param[in] config A pointer to a \ref RAIL_RfSenseSelectiveOokConfig_t /// which holds the RFSENSE configuration for Selective(OOK) mode. /// @return Status code indicating success of the function call. /// /// Some radios support Selective RF energy detection (OOK mode) where the /// user can program the radio to look for a particular sync word pattern /// (1-4 bytes) sent using OOK and wake only when that is detected. /// See chip-specific documentation for more details. /// /// The following code gives an example of how to use RF Sense functionality /// in Selective(OOK Based) Mode. /// @code{.c} /// // Sync word length in bytes, 1-4 bytes. /// #define NUM_SYNC_WORD_BYTES (2U) /// // Sync word value. /// #define SYNC_WORD (0xB16FU) /// // Desired RF band /// RAIL_RfSenseBand_t rfBand = RAIL_RFSENSE_2_4GHZ; /// /// // Configure the transmitting node for sending the wakeup packet. /// RAIL_Idle(railHandle, RAIL_IDLE_ABORT, true); /// RAIL_ConfigRfSenseSelectiveOokWakeupPhy(railHandle); /// RAIL_SetRfSenseSelectiveOokWakeupPayload(railHandle, NUM_SYNC_WORD_BYTES, SYNC_WORD); /// RAIL_StartTx(railHandle, channel, RAIL_TX_OPTIONS_DEFAULT, NULL); /// /// // Configure the receiving node (EFR32xG22) for RF Sense. /// RAIL_RfSenseSelectiveOokConfig_t config = { /// .band = rfBand, /// .syncWordNumBytes = NUM_SYNC_WORD_BYTES, /// .syncWord = SYNC_WORD, /// .cb = NULL // Use RAIL_EVENT_RF_SENSED event or poll RAIL_IsRfSensed() /// }; /// RAIL_StartSelectiveOokRfSense(railHandle, &config); /// @endcode /// /// @note After RF energy has been sensed, the RF Sense is automatically /// disabled and \ref RAIL_StartSelectiveOokRfSense() must be called again to /// reactivate. If RF energy has not been sensed and to manually disable /// RF Sense, \ref RAIL_StartSelectiveOokRfSense() must be called with band /// specified as \ref RAIL_RFSENSE_OFF or with /// \ref RAIL_RfSenseSelectiveOokConfig_t as NULL. /// /// @note Packet reception is not guaranteed to work correctly once RF Sense is /// enabled, both in single protocol and multiprotocol RAIL. /// To be safe, an application should turn this on only after idling /// the radio to stop receive and turn it off before attempting to restart /// receive. Since EM4 sleep causes the chip to come up through the reset /// vector any wake from EM4 must also shut off RF Sense to ensure proper /// receive functionality. /// RAIL_Status_t RAIL_StartSelectiveOokRfSense(RAIL_Handle_t railHandle, RAIL_RfSenseSelectiveOokConfig_t *config); /** * Switch to RF Sense Selective(OOK) PHY. * * @param[in] railHandle A handle for RAIL instance. * @return Status code indicating success of the function call. * * This function switches to the RFSENSE Selective(OOK) PHY for transmitting a * packet to wake up a chip that supports Selective RF energy detection (OOK * mode). You may only call this function while the radio is idle. While the * radio is configured for this PHY, receive functionality should not be used. * * @note The user must also set up the transmit FIFO, via * \ref RAIL_SetRfSenseSelectiveOokWakeupPayload, post this function call to * include the first byte as the Preamble byte, followed by the * Sync word (1-4 bytes). * See chip-specific documentation for more details. */ RAIL_Status_t RAIL_ConfigRfSenseSelectiveOokWakeupPhy(RAIL_Handle_t railHandle); /** * Set the transmit payload for waking up a node configured for * RF Sense Selective(OOK). * * @param[in] railHandle A handle for RAIL instance. * @param[in] numSyncwordBytes Sync word length in bytes, 1-4 bytes. * @param[in] syncword Sync word value. * @return Status code indicating success of the function call. * * @note You must call this function after the chip has been set up with the * RF Sense Selective(OOK) PHY, using \ref RAIL_ConfigRfSenseSelectiveOokWakeupPhy. */ RAIL_Status_t RAIL_SetRfSenseSelectiveOokWakeupPayload(RAIL_Handle_t railHandle, uint8_t numSyncwordBytes, uint32_t syncword); /** * Check whether the RF was sensed. * * @param[in] railHandle A RAIL instance handle. * @return true if RF was sensed since the last call to \ref RAIL_StartRfSense(). * false otherwise. * * This function is useful if \ref RAIL_StartRfSense() is called with a NULL * callback. It is generally used after EM4 reboot but can be used any time. */ bool RAIL_IsRfSensed(RAIL_Handle_t railHandle); /** @} */ // end of group Rf_Sense /****************************************************************************** * RX Channel Hopping *****************************************************************************/ /** * @addtogroup Rx_Channel_Hopping RX Channel Hopping * @brief Hardware accelerated hopping between channels while waiting for a * packet in receive. * @{ * * Channel hopping provides a hardware accelerated method for * scanning across multiple channels quickly, as part of a receive protocol. * While it is possible to call \ref RAIL_StartRx() on different channels, * back to back, and listen on many channels sequentially in that way, the * time it takes to switch channels with that method may be too long for some * protocols. This API pre-computes necessary channel change operations * for a given list of channels, so that the radio can move from channel * to channel much faster. Additionally, it leads to more succinct code * as channel changes will be done implicitly, without requiring numerous calls * to \ref RAIL_StartRx(). Currently, while this feature is enabled, the radio * will hop channels in the given sequence each time it enters RX. * Note that RX Channel hopping and EFR32xG25's concurrent mode / collision * detection are mutually exclusive. * * The channel hopping buffer requires \ref RAIL_CHANNEL_HOPPING_BUFFER_SIZE_PER_CHANNEL * number of 32-bit words of overhead per channel, plus 3 words overall plus the * twice the size of the \ref RAIL_ChannelConfig_t::phyConfigDeltaSubtract * of the whole radio configuration, plus the twice the sum of the sizes of all * the \ref RAIL_ChannelConfigEntry_t::phyConfigDeltaAdd in all the channel * hopping channels. * * The following code gives an example of how to use * the RX Channel Hopping API. * @code{.c} * #define CHANNEL_HOPPING_NUMBER_OF_CHANNELS 4 * #define CHANNEL_HOPPING_BUFFER_SIZE do { \ * 3 + \ * (RAIL_CHANNEL_HOPPING_BUFFER_SIZE_PER_CHANNEL \ * * CHANNEL_HOPPING_NUMBER_OF_CHANNELS) + \ * 2 * (SIZEOF_UINT32_DELTA_SUBTRACT + \ * SIZEOF_UINT32_DELTA_ADD_0 + \ * SIZEOF_UINT32_DELTA_ADD_1 + \ * SIZEOF_UINT32_DELTA_ADD_2 + \ * SIZEOF_UINT32_DELTA_ADD_3) \ * } while (0) * * RAIL_RxChannelHoppingConfigEntry_t channelHoppingEntries[CHANNEL_HOPPING_NUMBER_OF_CHANNELS]; * uint32_t channelHoppingBuffer[CHANNEL_HOPPING_BUFFER_SIZE]; * * RAIL_RxChannelHoppingConfig_t channelHoppingConfig = { * .buffer = channelHoppingBuffer, * .bufferLength = CHANNEL_HOPPING_BUFFER_SIZE, * .numberOfChannels = CHANNEL_HOPPING_NUMBER_OF_CHANNELS, * .entries = channelHoppingEntries * }; * * channelHoppingEntries[0].channel = 1; * channelHoppingEntries[1].channel = 2; * channelHoppingEntries[2].channel = 3; * * RAIL_ConfigRxChannelHopping(railHandle, &channelHoppingConfig); * RAIL_EnableRxChannelHopping(railHandle, true, true) * @endcode */ /** * Configure RX channel hopping. * * @param[in] railHandle A RAIL instance handle. * @param[in] config A pointer to the configuration parameters for RX Channel Hopping. * @return Status code indicating success of the function call. * * Configure channel hopping channels, conditions, and parameters. This * API must be called before \ref RAIL_EnableRxChannelHopping(). This API must * never be called while the radio is on with RX Duty Cycle or Channel * Hopping enabled. * * @note Use the compile time symbol \ref RAIL_SUPPORTS_CHANNEL_HOPPING or * the runtime call \ref RAIL_SupportsChannelHopping() to check whether * the platform supports this feature. * * @note Calling this function will overwrite any settings configured with * \ref RAIL_ConfigRxDutyCycle(). */ RAIL_Status_t RAIL_ConfigRxChannelHopping(RAIL_Handle_t railHandle, RAIL_RxChannelHoppingConfig_t *config); /** * Enable RX channel hopping. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable Enable (true) or disable (false) RX Channel Hopping. * @param[in] reset Start from the first channel of the channel hopping * sequence (true) or from wherever hopping left off last time the code * left RX. * @return Status code indicating success of the function call. * * Enable or disable Channel Hopping. Additionally, specify whether hopping * should be reset to start from the first channel index, or continue * from the channel last hopped to. The radio should not be on when * this API is called. \ref RAIL_ConfigRxChannelHopping() must be called * successfully before this API is called. * * @note Use the compile time symbol \ref RAIL_SUPPORTS_CHANNEL_HOPPING or * the runtime call \ref RAIL_SupportsChannelHopping() to check whether * the platform supports this feature. * * @note RX Channel Hopping may not be enabled while Auto-Acking is enabled. * * @note Calling this function will overwrite any settings configured with * \ref RAIL_EnableRxDutyCycle(). */ RAIL_Status_t RAIL_EnableRxChannelHopping(RAIL_Handle_t railHandle, bool enable, bool reset); /** * Manually trigger an Rx channel hop. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * This function facilitates a manual hop when using \ref * RAIL_RX_CHANNEL_HOPPING_MODE_MANUAL. (It will also trigger a hop * in other automatic hop modes as well, so use with caution.) * * @note This function may cause \ref RAIL_EVENT_RX_CHANNEL_HOPPING_COMPLETE * to occur before it returns. */ RAIL_Status_t RAIL_TriggerRxChannelHop(RAIL_Handle_t railHandle); /** * Get RSSI in deci-dBm of one channel in the channel hopping sequence, during * channel hopping. * * @param[in] railHandle A RAIL instance handle. * @param[in] channelIndex Index in the channel hopping sequence of the * channel of interest. * @return Latest RSSI in deci-dBm for the channel at the specified index. * * @note Use the compile time symbol \ref RAIL_SUPPORTS_CHANNEL_HOPPING or * the runtime call \ref RAIL_SupportsChannelHopping() to check whether * the platform supports this feature. * * @note In multiprotocol, this function returns \ref RAIL_RSSI_INVALID * immediately if railHandle is not the currently active \ref RAIL_Handle_t. * * @note \ref RAIL_ConfigRxChannelHopping() must be called successfully * before this API is called. * * @note When the Z-Wave protocol is active, running * \ref RAIL_GetChannelHoppingRssi() on the 9.6 kbps PHY returns the RSSI * measurement of the 40kpbs PHY. This is because the 9.6 kbps PHY has * trouble with RSSI measurements on EFR32xG2x family of chips. */ int16_t RAIL_GetChannelHoppingRssi(RAIL_Handle_t railHandle, uint8_t channelIndex); /// Configure RX duty cycle mode. /// /// @param[in] railHandle A RAIL instance handle. /// @param[in] config A non-NULL pointer to a configuration structure specifying duty cycle parameters. /// @return Status code indicating success of the function call. /// /// Configure RX duty cycle mode. With this mode enabled, every time the radio /// enters RX, it will duty cycle on and off to save power. The duty cycle /// ratio can be altered dynamically and intelligently by the hardware by /// staying on longer if a preamble or other packet segments are detected in /// the air. This API must never be called while the radio is on with RX Duty /// Cycle or Channel Hopping enabled. /// For short delays (in the order of microseconds), /// \ref RAIL_RxDutyCycleConfig_t::delay, this can be used to save receive /// current while having little impact on the radio performance, for protocols /// with long preambles. For long delays (in the order of milliseconds or higher) /// the chip can be put into EM2 energy mode before re-entering RX, /// to save extra power, with some application hooks as shown below. /// /// @code{.c} /// #include "rail.h" /// /// extern RAIL_Handle_t railHandle; /// RAIL_Time_t periodicWakeupUs; /// /// volatile bool dutyCycleEnd = true; /// /// void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events) /// { /// // Omitting other event handlers /// if (events & RAIL_EVENT_RX_DUTY_CYCLE_RX_END) { /// dutyCycleEnd = true; /// } /// } /// /// void main(void) /// { /// RAIL_Status_t status; /// bool shouldSleep = false; /// /// initializeRail(); // Call RAIL_Init() and such /// /// // This function depends on your board/chip but it must enable the LFCLK /// // you intend to use for RTCC sync before we configure sleep as that /// // function will attempt to auto detect the clock. /// BoardSetupLFCLK(); /// // Initialize Power Manager module /// sl_power_manager_init(); /// // Initialize RAIL Power Manager /// RAIL_InitPowerManager(); /// /// // Configure sleep for timer synchronization /// RAIL_TimerSyncConfig_t timerSyncConfig = RAIL_TIMER_SYNC_DEFAULT; /// status = RAIL_ConfigSleep(railHandle, &timerSyncConfig); /// assert(status == RAIL_STATUS_NO_ERROR); /// /// // Configure RX duty-cycling /// RAIL_RxDutyCycleConfig_t duty_cycle_config = { /// .mode = RAIL_RX_CHANNEL_HOPPING_MODE_PREAMBLE_SENSE, /// .parameter = DUTY_CYCLE_ON_TIME, /// .delay_us = DUTY_CYCLE_OFF_TIME, /// .delay_mode = RAIL_RX_CHANNEL_HOPPING_DELAY_MODE_STATIC, /// .options = RAIL_RX_CHANNEL_HOPPING_OPTIONS_NONE, /// }; /// status = RAIL_ConfigRxDutyCycle(rail_handle, &duty_cycle_config); /// assert(status == RAIL_STATUS_NO_ERROR); /// status = RAIL_EnableRxDutyCycle(rail_handle, true); /// assert(status == RAIL_STATUS_NO_ERROR); /// /// // Application main loop /// while (1) { /// if (dutyCycleEnd) { /// dutyCycleEnd = false; /// // Schedule the next receive. /// RAIL_ScheduleRxConfig_t rxConfig = { /// .start = periodicWakeupUs, /// .startMode = RAIL_TIME_DELAY, /// .end = 0U, /// .endMode = RAIL_TIME_DISABLED, /// .rxTransitionEndSchedule = 0U, /// .hardWindowEnd = 0U /// }; /// RAIL_Idle(railHandle, RAIL_IDLE_ABORT, true); /// RAIL_StartScheduledRx(railHandle, channel, &rxConfig, NULL); /// } /// // ... do normal app stuff and set shouldSleep when we want to sleep /// if (shouldSleep) { /// // Let the CPU go to sleep if the system allows it. /// sl_power_manager_sleep(); /// } /// } /// } /// @endcode /// /// @note Use the compile time symbol \ref RAIL_SUPPORTS_CHANNEL_HOPPING or /// the runtime call \ref RAIL_SupportsChannelHopping() to check whether /// the platform supports this feature. /// /// @note Calling this function will overwrite any settings configured with /// \ref RAIL_ConfigRxChannelHopping(). /// RAIL_Status_t RAIL_ConfigRxDutyCycle(RAIL_Handle_t railHandle, const RAIL_RxDutyCycleConfig_t *config); /** * Enable RX duty cycle mode. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable Enable (true) or disable (false) RX Duty Cycling. * @return Status code indicating success of the function call. * * Enable or disable RX duty cycle mode. After this is called, the radio * will begin duty cycling each time it enters RX, based on the * configuration passed to \ref RAIL_ConfigRxDutyCycle(). This API must not * be called while the radio is on. * * @note Use the compile time symbol \ref RAIL_SUPPORTS_CHANNEL_HOPPING or * the runtime call \ref RAIL_SupportsChannelHopping() to check whether * the platform supports this feature. * * @note Calling this function will overwrite any settings configured with * \ref RAIL_EnableRxChannelHopping(). */ RAIL_Status_t RAIL_EnableRxDutyCycle(RAIL_Handle_t railHandle, bool enable); /** * Get the default RX duty cycle configuration. * * @param[in] railHandle A RAIL instance handle. * @param[out] config An application-provided non-NULL pointer to store * the default RX duty cycle configuration. * @return Status code indicating success of the function call. * Note that \ref RAIL_STATUS_INVALID_PARAMETER will be returned if the current * channel's radio configuration does not support the requested information. * * To save power during RX, an application may want to go to low power as long as * possible by periodically waking up and trying to * "sense" if there are any incoming packets. This API returns the recommended * RX duty cycle configuration, so the application can enter low power mode * periodically without missing packets. To wake up * earlier, the application can reduce the delay parameter. * Note that these value might be different if any configuration / channel has * changed. **/ RAIL_Status_t RAIL_GetDefaultRxDutyCycleConfig(RAIL_Handle_t railHandle, RAIL_RxDutyCycleConfig_t *config); /** @} */ // end of group Rx_Channel_Hopping /****************************************************************************** * Multiprotocol-Specific Functions *****************************************************************************/ /** * @addtogroup Multiprotocol * @brief Multiprotocol scheduler APIs to support multiple time-sliced PHYs. * @{ */ /** * Yield the radio to other configurations. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * This function is used to indicate that the previous transmit or scheduled * receive operation has completed. It must be used in multiprotocol RAIL because * the scheduler assumes that any transmit or receive operation that is started * can go on indefinitely based on state transitions and your protocol. * RAIL will not allow a lower priority tasks to run until this is called so it * can negatively impact performance of those protocols if this is omitted or * delayed. It is also possible to call the \ref RAIL_Idle() API to * both terminate the operation and idle the radio. In single protocol RAIL * this API does nothing, however, if RAIL Power Manager is initialized, * calling \ref RAIL_YieldRadio() after scheduled TX/RX and instantaneous TX * completion, is required, to indicate to the Power Manager that the the radio * is no longer busy and can be idled for sleeping. * * See \ref rail_radio_scheduler_yield for more details. */ RAIL_Status_t RAIL_YieldRadio(RAIL_Handle_t railHandle); /** * Get the status of the RAIL scheduler. * * @param[in] railHandle A RAIL instance handle. * @return \ref RAIL_SchedulerStatus_t status. * * This function can only be called from a callback context after the * \ref RAIL_EVENT_SCHEDULER_STATUS event occurs. */ RAIL_SchedulerStatus_t RAIL_GetSchedulerStatus(RAIL_Handle_t railHandle); /** * Get the status of the RAIL scheduler, specific to the radio operation, * along with \ref RAIL_Status_t returned by RAIL API invoked by the * RAIL scheduler. * * @param[in] railHandle A RAIL instance handle. * @param[out] pSchedulerStatus An application-provided pointer to store * \ref RAIL_SchedulerStatus_t status. Can be NULL as long as pRailStatus * is not NULL. * @param[out] pRailStatus An application-provided pointer to store * \ref RAIL_Status_t of the RAIL API invoked by the RAIL scheduler. * Can be NULL as long as pSchedulerStatus is not NULL. * @return Status code indicating success of the function call. * * This function can only be called from a callback context after the * \ref RAIL_EVENT_SCHEDULER_STATUS event occurs. */ RAIL_Status_t RAIL_GetSchedulerStatusAlt(RAIL_Handle_t railHandle, RAIL_SchedulerStatus_t *pSchedulerStatus, RAIL_Status_t *pRailStatus); /** * Change the priority of a specified task type in multiprotocol. * * @param[in] railHandle A RAIL instance handle. * @param[in] priority Desired new priority for the railHandle's active task * @param[in] taskType Type of task whose priority should be updated * @return Status code indicating success of the function call. * * While the application can use this function however it likes, a major use * case is being able to increase an infinite receive priority while receiving * a packet. In other words, a given \ref RAIL_Handle_t can maintain a very low * priority background receive, but upon getting a * \ref RAIL_EVENT_RX_SYNC1_DETECT_SHIFT or * \ref RAIL_EVENT_RX_SYNC2_DETECT_SHIFT event, the app can call this function * to increase the background RX priority to lower the risk another protocol * might preempt during packet reception. */ RAIL_Status_t RAIL_SetTaskPriority(RAIL_Handle_t railHandle, uint8_t priority, RAIL_TaskType_t taskType); /** * Get time needed to switch between protocols. * * @return \ref RAIL_Time_t Time needed to switch between protocols. */ RAIL_Time_t RAIL_GetTransitionTime(void); /** * Set time needed to switch between protocols. Call this API * only once, before any protocol is initialized via * \ref RAIL_Init(). Changing this value during normal operation * can result in improper scheduling behavior. * * @param[in] transitionTime Time needed to switch between protocols. */ void RAIL_SetTransitionTime(RAIL_Time_t transitionTime); /** @} */ // end of group Multiprotocol /****************************************************************************** * Diagnostic *****************************************************************************/ /** * @addtogroup Diagnostic * @brief APIs for diagnostic and test chip modes * @{ */ /** * Configure direct mode for RAIL. * * @param[in] railHandle A RAIL instance handle. * @param[in] directModeConfig A pointer to a configuration structure to specify direct mode * parameters. Default configuration will be used if NULL is passed. * @return \ref RAIL_STATUS_NO_ERROR on success and an error code on failure. * * This API configures direct mode and should be called before * calling \ref RAIL_EnableDirectMode(). If this function is not called, the * following default \ref RAIL_DirectModeConfig_t configuration will be used: \n * @code{.c} * RAIL_DirectModeConfig_t defaultConfig = { * .syncRx = false, * .syncTx = false, * .doutPort = SL_GPIO_PORT_A, * .doutPin = 5, * .dinPort = SL_GPIO_PORT_A, * .dinPin = 7, * .dclkPort = SL_GPIO_PORT_A, * .dclkPin = 6, * }; * @endcode * * @warning This API is not safe to use in a multiprotocol app. */ RAIL_Status_t RAIL_ConfigDirectMode(RAIL_Handle_t railHandle, const RAIL_DirectModeConfig_t *directModeConfig); /** * Enable or disable direct mode for RAIL. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable Whether or not to enable direct mode for TX and RX. * @return \ref RAIL_STATUS_NO_ERROR on success and an error code on failure. * * See \ref RAIL_EnableDirectModeAlt() for more detailed function * description. * * @warning New applications should consider using \ref RAIL_EnableDirectModeAlt() for * this functionality. * * @note This feature is only available on certain devices. * \ref RAIL_SupportsDirectMode() can be used to check if a particular * device supports this feature or not. * * @warning As this function relies on GPIO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if GPIO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_EnableDirectMode(RAIL_Handle_t railHandle, bool enable); /** * Enable or disable direct mode for RAIL. * * @param[in] railHandle A RAIL instance handle. * @param[in] enableDirectTx Enable direct mode for data being transmitted out * of the radio. * @param[in] enableDirectRx Enable direct mode for data being received from * the radio. * @return \ref RAIL_STATUS_NO_ERROR on success or an error code on failure. * * This API enables or disables the modem and GPIOs for direct mode operation. * see \ref RAIL_ConfigDirectMode() for information on selecting the * correct hardware configuration. If direct mode is enabled, * packets are output and input directly to the radio via GPIO * and RAIL packet handling is ignored. * * @note This feature is only available on certain chips. * \ref RAIL_SupportsDirectMode() can be used to check if a particular * chip supports this feature or not. * * @warning This API is not safe to use in a multiprotocol app. * * @warning As this function relies on GPIO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if GPIO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_EnableDirectModeAlt(RAIL_Handle_t railHandle, bool enableDirectTx, bool enableDirectRx); /** * Get the radio subsystem clock frequency in Hz. * * @param[in] railHandle A RAIL instance handle. * @return Radio subsystem clock frequency in Hz. */ uint32_t RAIL_GetRadioClockFreqHz(RAIL_Handle_t railHandle); /** * Set the crystal tuning. * * @param[in] railHandle A RAIL instance handle. * @param[in] tune A chip-dependent crystal capacitor bank tuning parameter. * @return Status code indicating success of the function call. * * Tunes the crystal that the radio depends on to change the location of the * center frequency for transmitting and receiving. This function will only * succeed if the radio is idle at the time of the call. * * @note This function proportionally affects the entire chip's timing * across all its peripherals, including radio tuning and channel spacing. * It is recommended to call this function only when HFXO is not being used, * as it can cause disturbance on the HFXO frequency. * A separate function, \ref RAIL_SetFreqOffset(), can be used to adjust * just the radio tuner without disturbing channel spacing or other chip * peripheral timing. * @note This API sets CTUNEXIANA and internally * CTUNEXOANA = CTUNEXIANA + delta where delta is set or changed by * \ref RAIL_SetTuneDelta(). The default delta may not be 0 on some devices. */ RAIL_Status_t RAIL_SetTune(RAIL_Handle_t railHandle, uint32_t tune); /** * Get the crystal tuning. * * @param[in] railHandle A RAIL instance handle. * @return A chip-dependent crystal capacitor bank tuning parameter. * * Retrieves the current tuning value used by the crystal that the radio * depends on. * @note This is the CTUNEXIANA value. */ uint32_t RAIL_GetTune(RAIL_Handle_t railHandle); /** * Set the crystal tuning delta. * * @param[in] railHandle A RAIL instance handle. * @param[in] delta A chip-dependent crystal capacitor bank tuning delta. * @return Status code indicating success of the function call. * * Set the CTUNEXOANA delta for \ref RAIL_SetTune() to use: * CTUNEXOANA = CTUNEXIANA + delta (subject to field-size limitations). * This function does not change CTUNE values; * call \ref RAIL_SetTune() to put a new delta into effect. */ RAIL_Status_t RAIL_SetTuneDelta(RAIL_Handle_t railHandle, int32_t delta); /** * Get the crystal tuning delta. * * @param[in] railHandle A RAIL instance handle. * @return A chip-dependent crystal capacitor bank tuning delta. * * Retrieves the current tuning delta used by \ref RAIL_SetTune(). * @note The default delta if \ref RAIL_SetTuneDelta() has never been called * is device-dependent and may not be 0. */ int32_t RAIL_GetTuneDelta(RAIL_Handle_t railHandle); /** * Get the frequency offset. * * @param[in] railHandle A RAIL instance handle. * @return The measured frequency offset on a received packet. * The units are described in the \ref RAIL_FrequencyOffset_t * documentation. If this returns \ref RAIL_FREQUENCY_OFFSET_INVALID, * it was called while the radio wasn't active and there is no way * to get the frequency offset. * * Retrieves the measured frequency offset used during the previous * received packet, which includes the current radio frequency offset * (see \ref RAIL_SetFreqOffset()). If the chip has not been in RX, * it returns the nominal radio frequency offset. * * @note Changing to any non-idle radio state after reception can cause this * value to be overwritten so it is safest to capture during packet reception. */ RAIL_FrequencyOffset_t RAIL_GetRxFreqOffset(RAIL_Handle_t railHandle); /** * Set the nominal radio frequency offset. * * @param[in] railHandle A RAIL instance handle. * @param[in] freqOffset \ref RAIL_FrequencyOffset_t parameter (signed, 2's * complement). * @return Status code indicating success of the function call. * * This function is used to adjust the radio's tuning frequency slightly up or down. * It might be used in conjunction with \ref RAIL_GetRxFreqOffset() after * receiving a packet from a peer to adjust the tuner to better match the * peer's tuned frequency. * * @note Unlike \ref RAIL_SetTune(), which affects the entire chip's * timing including radio tuning and channel spacing, this function * only affects radio tuning without disturbing channel spacing or * other chip peripheral timing. */ RAIL_Status_t RAIL_SetFreqOffset(RAIL_Handle_t railHandle, RAIL_FrequencyOffset_t freqOffset); /** * Start transmitting a stream on a certain channel. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel A channel on which to emit a stream. * @param[in] mode Choose the stream mode (PN9, and so on). * @return Status code indicating success of the function call. * * Begins streaming onto the given channel. The sources can either be an * unmodulated carrier wave or an encoded stream of bits from a PN9 source. * All ongoing radio operations will be stopped before transmission begins. */ RAIL_Status_t RAIL_StartTxStream(RAIL_Handle_t railHandle, uint16_t channel, RAIL_StreamMode_t mode); /** * Start transmitting a stream on a certain channel with the ability to select * an antenna. * * @param[in] railHandle A RAIL instance handle. * @param[in] channel A channel on which to emit a stream. * @param[in] mode Choose the stream mode (PN9, and so on). * @param[in] options Choose the TX Antenna option. * Takes only \ref RAIL_TX_OPTION_ANTENNA0, \ref RAIL_TX_OPTION_ANTENNA1, * \ref RAIL_TX_OPTIONS_DEFAULT or \ref RAIL_TX_OPTIONS_NONE from the * \ref RAIL_TxOptions_t. If some other value is used then, transmission * is possible on any antenna. * @return Status code indicating success of the function call. * * Begins streaming onto the given channel. The sources can either be an * unmodulated carrier wave or an encoded stream of bits from a PN9 source. * All ongoing radio operations will be stopped before transmission begins. */ RAIL_Status_t RAIL_StartTxStreamAlt(RAIL_Handle_t railHandle, uint16_t channel, RAIL_StreamMode_t mode, RAIL_TxOptions_t options); /** * Stop stream transmission and idle the radio. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call. * * Halts the transmission started by \ref RAIL_StartTxStream(). */ RAIL_Status_t RAIL_StopTxStream(RAIL_Handle_t railHandle); /** * Stop infinite preamble transmission started and start transmitting the rest * of the packet. * * @param[in] railHandle A RAIL instance handle. * @return Status code indicating success of the function call: * \ref RAIL_STATUS_NO_ERROR if infinite preamble was stopped; * \ref RAIL_STATUS_INVALID_CALL if the radio isn't configured for infinite * preamble; * \ref RAIL_STATUS_INVALID_STATE if the radio isn't transmitting. * * This function is only useful for radio configurations that specify an * infinite preamble. Call this API only after \ref RAIL_EVENT_TX_STARTED * has occurred and the radio is transmitting. */ RAIL_Status_t RAIL_StopInfinitePreambleTx(RAIL_Handle_t railHandle); /** * Configure the verification of radio memory contents. * * @param[in] railHandle A RAIL instance handle. * @param[in,out] configVerify A pointer to a configuration structure made available to * RAIL to perform radio state verification. This structure must be * allocated in application global read-write memory. RAIL may modify * fields within or referenced by this structure during its operation. * @param[in] radioConfig A radio configuration (pointer) that is to be used as a * white list for verifying memory contents. * @param[in] cb A callback that notifies the application of a mismatch in * expected vs actual memory contents. A NULL parameter may be passed in * if a callback is not needed by the application. * @return \ref RAIL_STATUS_NO_ERROR if setup of the verification feature * successfully occurred. * \ref RAIL_STATUS_INVALID_PARAMETER is returned if the provided railHandle * or configVerify structures are invalid. */ RAIL_Status_t RAIL_ConfigVerification(RAIL_Handle_t railHandle, RAIL_VerifyConfig_t *configVerify, RAIL_RadioConfig_t radioConfig, RAIL_VerifyCallbackPtr_t cb); /** * Verify radio memory contents. * * @param[in,out] configVerify A pointer to the configuration structure * previously established by \ref RAIL_ConfigVerification(). * @param[in] durationUs The duration (in microseconds) for how long memory * verification should occur before returning to the application. A value of * \ref RAIL_VERIFY_DURATION_MAX indicates that all memory contents should be * verified before returning to the application. * @param[in] restart This flag only has meaning if a previous call of this * function returned \ref RAIL_STATUS_SUSPENDED. By restarting (true), the * verification process starts over from the beginning, or by resuming * where verification left off after being suspended (false), verification * can proceed towards completion. * @return \ref RAIL_STATUS_NO_ERROR if the contents of all applicable * memory locations have been verified. * \ref RAIL_STATUS_SUSPENDED is returned if the provided test duration * expired but the time was not sufficient to verify all memory contents. * By calling \ref RAIL_Verify() again, further verification will commence. * \ref RAIL_STATUS_INVALID_PARAMETER is returned if the provided * verifyConfig structure pointer is not configured for use by the active * RAIL handle. * \ref RAIL_STATUS_INVALID_STATE is returned if any of the verified * memory contents are different from their reference values. */ RAIL_Status_t RAIL_Verify(RAIL_VerifyConfig_t *configVerify, uint32_t durationUs, bool restart); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * Enable radio state change interrupt. * * @param[in] railHandle A RAIL instance handle. * @param[in] enable Enable/disable Radio state change interrupt. * @return Status code indicating success of the function call. Returns * \ref RAIL_STATUS_NO_ERROR once the interrupt has been enabled or disabled. * * @note If enabled, state change events are reported through the separate * \ref RAILCb_RadioStateChanged() callback. */ RAIL_Status_t RAIL_EnableRadioStateChanged(RAIL_Handle_t railHandle, bool enable); /** * Callback on radio state changes. * * @param[in] state The current radio state. */ void RAILCb_RadioStateChanged(uint8_t state); /** * Get the current radio state. * * @param[in] railHandle A RAIL instance handle. * @return An enumeration, \ref RAIL_RadioStateEfr32_t, for the current radio * state. * */ RAIL_RadioStateEfr32_t RAIL_GetRadioStateAlt(RAIL_Handle_t railHandle); #endif//DOXYGEN_SHOULD_SKIP_THIS /** @} */ // end of group Diagnostic /****************************************************************************** * Front End Module Voltage Detection (VDET) *****************************************************************************/ /** * @addtogroup VDET Front End Module Voltage Detection * @brief APIs for configuring and detecting a voltage from a Front End Module (VDET). * * The rail_util_vdet plugin lets customers measure an output voltage from their attached * Front End Module at a specific time in a Tx packet. This information allows * optimizations to power configuration, and monitoring FEM performance. * * @note VDET is only supported with EFR32xG25 devices. * @{ */ /** * Configure the VDET plugin. * * @param[in] genericRailHandle A radio-generic RAIL handle. * @param[in] config A pointer to a \ref RAIL_VdetConfig_t struct that contains * configuration data for the VDET. * @return \ref RAIL_Status_t * \retval RAIL_STATUS_NO_ERROR - All went well * \retval RAIL_STATUS_INVALID_STATE - VDET is enabled. Must be disabled first. * \retval RAIL_STATUS_INVALID_PARAMETER - mode/resolution/delayUs out-of-bounds. * * @warning As this function relies on GPIO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if GPIO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_ConfigVdet(RAIL_Handle_t genericRailHandle, const RAIL_VdetConfig_t *config); /** * Get the VDET plugin configuration. * * @param[in] genericRailHandle A radio-generic RAIL handle. * @param[out] config A pointer to a \ref RAIL_VdetConfig_t struct that will * return configuration data for the VDET. * @return \ref RAIL_Status_t * \retval RAIL_STATUS_NO_ERROR - All went well. */ RAIL_Status_t RAIL_GetVdetConfig(RAIL_Handle_t genericRailHandle, RAIL_VdetConfig_t *config); /** * Enable the VDET plugin. * * @param[in] genericRailHandle A RAIL instance handle. * @param[in] enable Enable or disable \ref RAIL_VDET_MODE_AUTOMATIC mode captures. * Begins measurement if in \ref RAIL_VDET_MODE_IMMEDIATE. * @return \ref RAIL_Status_t * \retval RAIL_STATUS_NO_ERROR - All went well, VDET is enabled or disabled. * \retval RAIL_STATUS_INVALID_STATE - VDET has not been configured or VDET was not idle. * VDET is disabled. * * @warning As this function relies on HFXO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if HFXO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_EnableVdet(RAIL_Handle_t genericRailHandle, bool enable); /** * Check if the VDET plugin is enabled. * * @param[in] genericRailHandle A RAIL instance handle. * @return bool */ bool RAIL_IsVdetEnabled(RAIL_Handle_t genericRailHandle); /** * Get VDET measurement. A processed measurement in millivolts. * * @param[in] genericRailHandle A RAIL instance handle. * @param[out] pVdetMv A pointer to a uint32_t for returning the measurement. * @return \ref RAIL_Status_t * \retval RAIL_STATUS_NO_ERROR - All went well, value in *pVdetMv is valid. * \retval RAIL_STATUS_INVALID_CALL - VDET is in progress, wait until * VDET capture is complete and try again. * \retval RAIL_STATUS_INVALID_STATE - VDET is not enabled or valid. Wait until next packet and try reading again.\n * \ref RAIL_VDET_MODE_AUTOMATIC - Wait until next packet and try reading again.\n * \ref RAIL_VDET_MODE_IMMEDIATE - Resend \ref RAIL_EnableVdet().\n * \retval RAIL_STATUS_INVALID_PARAMETER - In \ref RAIL_VDET_MODE_IMMEDIATE, resend \ref RAIL_EnableVdet().\n * \retval RAIL_STATUS_SUSPENDED - Blocked by AuxADC contention. Wait until next packet and try reading again. * * @warning As this function relies on HFXO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if HFXO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_GetVdet(RAIL_Handle_t genericRailHandle, uint32_t *pVdetMv); /** @} */ // end of group VDET /****************************************************************************** * Thermal Protection *****************************************************************************/ /** * @addtogroup Thermal_Protection Thermal Protection * @{ */ /** * Enable or disable the thermal protection if \ref RAIL_SUPPORTS_THERMAL_PROTECTION * is defined and update the temperature threshold and cool down hysteresis preventing or * allowing transmissions. * * @param[in] genericRailHandle A radio-generic RAIL handle. * @param[in] chipTempConfig A pointer to a \ref RAIL_ChipTempConfig_t that contains * the configuration to be applied. * @return Status code indicating the result of the function call. * Returns \ref RAIL_STATUS_INVALID_PARAMETER if enable field from \ref RAIL_ChipTempConfig_t * is set to false when an EFF is present on the board. * * When the temperature threshold minus a precise number of degrees * specified by the cool down hysteresis parameter is exceeded, * any future transmits are blocked until the temperature decreases below that limit. * Besides, if the temperature threshold is exceeded, any active transmit is aborted. * * By default the threshold is set to \ref RAIL_CHIP_TEMP_THRESHOLD_MAX and * the cool down hysteresis is set to \ref RAIL_CHIP_TEMP_COOLDOWN_DEFAULT. * * @note The thermal protection is automatically enabled when an EFF is present * on the board. There is no use in calling this API in this case. */ RAIL_Status_t RAIL_ConfigThermalProtection(RAIL_Handle_t genericRailHandle, const RAIL_ChipTempConfig_t *chipTempConfig); /** * Get the current thermal configuration parameter and status. * * @param[in] genericRailHandle A radio-generic RAIL handle. * @param[out] chipTempConfig A non-NULL pointer to a \ref RAIL_ChipTempConfig_t that will * be updated with the current configuration. * @return Status code indicating the result of the function call. */ RAIL_Status_t RAIL_GetThermalProtection(RAIL_Handle_t genericRailHandle, RAIL_ChipTempConfig_t *chipTempConfig); /** Number of temperature values provided for HFXO metrics */ #define RAIL_HFXO_TEMP_MEASURE_COUNT (1U) /** Total number of temperature values provided by \ref RAIL_GetTemperature(). */ #define RAIL_TEMP_MEASURE_COUNT (RAIL_CHIP_TEMP_MEASURE_COUNT \ + RAIL_HFXO_TEMP_MEASURE_COUNT) /** * Get the different temperature measurements in Kelvin done by sequencer or host. * * @param[in] railHandle A RAIL instance handle. * @param[out] tempBuffer The address of the array that will contain temperatures. * This array must have at least \ref RAIL_TEMP_MEASURE_COUNT entries. * @param[in] reset true to reset the temperature statistics, false otherwise. * @return Status code indicating success of the function call. * * Temperatures, in Kelvin, are stored in tempBuffer such as: * - tempBuffer[0] is the chip temperature * - tempBuffer[1] is the minimal chip temperature * - tempBuffer[2] is the maximal chip temperature * * Values that are not populated yet or incorrect are set to 0. * * If \ref RAIL_SUPPORTS_HFXO_COMPENSATION * tempBuffer[3] is the HFXO temperature */ RAIL_Status_t RAIL_GetTemperature(RAIL_Handle_t railHandle, int16_t tempBuffer[RAIL_TEMP_MEASURE_COUNT], bool reset); /** @} */ // end of group Thermal_Protection /****************************************************************************** * Retiming *****************************************************************************/ /** * @addtogroup Retiming * @{ * @brief EFR32-specific retiming capability. * * The EFR product families have many digital and analog modules that can run * in parallel with a radio. These combinations can cause interference and * degradation on the radio RX sensitivity. Retiming can * modify the clocking of the digital modules to reduce the interference. */ /** * Configure retiming options. * * @param[in] railHandle A handle of RAIL instance. * @param[in] mask A bitmask containing which options should be modified. * @param[in] options A bitmask containing desired configuration settings. * Bit positions for each option are found in the \ref RAIL_RetimeOptions_t. * @return Status code indicating success of the function call. */ RAIL_Status_t RAIL_ConfigRetimeOptions(RAIL_Handle_t railHandle, RAIL_RetimeOptions_t mask, RAIL_RetimeOptions_t options); /** * Get the currently configured retiming option. * * @param[in] railHandle A handle of RAIL instance. * @param[out] pOptions A pointer to configured retiming options * bitmask indicating which are enabled. * @return Status code indicating success of the function call. */ RAIL_Status_t RAIL_GetRetimeOptions(RAIL_Handle_t railHandle, RAIL_RetimeOptions_t *pOptions); /** * Indicate that the DCDC peripheral bus clock enable has changed allowing * RAIL to react accordingly. * * @return Status code indicating success of the function call. * * @note This should be called after DCDC has been enabled or disabled. */ RAIL_Status_t RAIL_ChangedDcdc(void); /** @} */ // end of group Retiming #ifndef DOXYGEN_SHOULD_SKIP_THIS /****************************************************************************** * Debug *****************************************************************************/ /** * @addtogroup Debug * @brief APIs for debugging * @{ */ /** * Configure the debug mode for the radio library. Do not use this function * unless instructed by Silicon Labs. * * @param[in] railHandle A RAIL instance handle. * @param[in] debugMode Debug mode to enter. * @return Status code indicating success of the function call. */ RAIL_Status_t RAIL_SetDebugMode(RAIL_Handle_t railHandle, uint32_t debugMode); /** * Return the debug mode for the radio library. Do not use this function * unless instructed by Silicon Labs. * * @param[in] railHandle A RAIL instance handle. * @return Debug mode for the radio library. */ uint32_t RAIL_GetDebugMode(RAIL_Handle_t railHandle); /** * Override the radio base frequency. * * @param[in] railHandle A RAIL instance handle. * @param[in] freq A desired frequency in Hz. * @return Status code indicating success of the function call. * * Sets the radio to transmit at the frequency given. This function can only * be used while in \ref RAIL_DEBUG_MODE_FREQ_OVERRIDE. The given frequency * needs to be close to the base frequency of the current PHY. After this * call, a full reset is needed to restore normal RAIL operation. */ RAIL_Status_t RAIL_OverrideDebugFrequency(RAIL_Handle_t railHandle, uint32_t freq); /** * Get the size of the radio's multiprotocol scheduler state buffer. * * @param[in] genericRailHandle A radio-generic RAIL handle. * @return Size, in bytes, of the radio's internal scheduler state buffer. * Zero is returned if the handle is invalid or this is the singleprotocol * library. */ uint32_t RAIL_GetSchedBufferSize(RAIL_Handle_t genericRailHandle); /** @} */ // end of group Debug #endif//DOXYGEN_SHOULD_SKIP_THIS /****************************************************************************** * Assertion Callback *****************************************************************************/ /** * @addtogroup Assertions * @brief Callbacks called by assertions * * The assertion framework was implemented to not only * assert that certain conditions are true in a block of code, but also * to handle them more appropriately. In previous implementations, * the behavior upon a failed assert was to hang in a while(1) loop. * However, with the callback, each assert is given a unique error code so that * they can be handled on a more case-by-case basis. For documentation on each * of the errors, see the rail_assert_error_codes.h file. * \ref RAIL_ASSERT_ERROR_MESSAGES[errorCode] gives the explanation of the error. * With asserts built into the library, users can choose how to handle each * error inside the callback. * * @{ */ /** * Callback called upon failed assertion. * * @param[in] railHandle A RAIL instance handle. * @param[in] errorCode Value passed in by the calling assertion API indicating * the RAIL assertion that failed. */ void RAILCb_AssertFailed(RAIL_Handle_t railHandle, RAIL_AssertErrorCodes_t errorCode); /** @} */ // end of group Assertions /****************************************************************************** * External_Thermistor *****************************************************************************/ /** * @addtogroup External_Thermistor External Thermistor * @brief APIs to measure temperature using an external thermistor * * This feature allows reading the temperature via an external thermistor on * chips that support it. This will require connecting the necessary components * and configuring the pins as required. * * @{ */ /** * Start a thermistor measurement. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return Status code indicating success of the function call. * Returns \ref RAIL_STATUS_INVALID_STATE if the thermistor is started while the * radio is transmitting. * * To get the thermistor impedance, call the * function \ref RAIL_GetThermistorImpedance(). On platforms having * \ref RAIL_SUPPORTS_EXTERNAL_THERMISTOR, this function reconfigures * GPIO_THMSW_EN_PIN located in GPIO_THMSW_EN_PORT. * To locate this pin, refer to the data sheet or appropriate header files * of the device. For proper operation, \ref RAIL_Init() must be called before * using this function. * * @note When an EFF is attached, this function must not be called during * transmit. * * @warning This API is not safe to use in a multiprotocol app. * * @warning As this function relies on EMU, GPIO and HFXO access and RAIL is * meant to run in TrustZone non-secure world, it is not supported if EMU, * GPIO or HFXO are configured as secure peripheral and it will return * \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_StartThermistorMeasurement(RAIL_Handle_t railHandle); /** * Get the thermistor impedance measurement and return \ref * RAIL_INVALID_THERMISTOR_VALUE if the thermistor is not properly * configured or the thermistor measurement is not ready. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[out] thermistorImpedance A pointer to a uint32_t updated * with the current thermistor impedance measurement in Ohms. * @return Status code indicating success of the function call. * * @note This function is already called in \ref RAIL_CalibrateHFXO(). * It does not need to be manually called during the compensation sequence. */ RAIL_Status_t RAIL_GetThermistorImpedance(RAIL_Handle_t railHandle, uint32_t *thermistorImpedance); /** * Convert the thermistor impedance into temperature, in Celsius. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] thermistorImpedance Current thermistor impedance measurement in * Ohms. * @param[out] thermistorTemperatureC A non-NULL pointer to an int16_t updated * with the current thermistor temperature in eighth of Celsius degrees. * @return Status code indicating success of the function call. * * A version of this function is provided in the \ref rail_util_thermistor * plugin for Silicon Labs radio boards. For custom boards this function can be * modified and re-implemented as needed. * * @note This plugin is mandatory on EFR32xG25 platform. */ RAIL_Status_t RAIL_ConvertThermistorImpedance(RAIL_Handle_t railHandle, uint32_t thermistorImpedance, int16_t *thermistorTemperatureC); /** * Compute the crystal PPM deviation from the thermistor temperature. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] crystalTemperatureC Current crystal temperature, in Celsius. * @param[out] crystalPPMError A non-NULL pointer to an int8_t updated * with the current ppm error in ppm units. * @return Status code indicating success of the function call. * * This function is provided in the rail_util_thermistor plugin to get * accurate values from our boards thermistor. For a custom board, this * function could be modified and re-implemented for other needs. * * @note This plugin is mandatory on EFR32xG25 platform. */ RAIL_Status_t RAIL_ComputeHFXOPPMError(RAIL_Handle_t railHandle, int16_t crystalTemperatureC, int8_t *crystalPPMError); /** * Configure the GPIO for thermistor usage. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] pHfxoThermistorConfig A non-NULL pointer to the thermistor configuration * indicating the GPIO port and pin to use. * @return Status code indicating the result of the function call. * * @note The port and pin that must be passed in \ref RAIL_HFXOThermistorConfig_t * are GPIO_THMSW_EN_PORT and GPIO_THMSW_EN_PIN respectively. * * @warning As this function relies on GPIO access and RAIL is meant to run in * TrustZone non-secure world, it is not supported if GPIO is configured as * secure peripheral and it will return \ref RAIL_STATUS_INVALID_CALL. */ RAIL_Status_t RAIL_ConfigHFXOThermistor(RAIL_Handle_t railHandle, const RAIL_HFXOThermistorConfig_t *pHfxoThermistorConfig); /** * Configure the temperature parameters for HFXO compensation. * * @param[in] railHandle A RAIL instance handle. * @param[in] pHfxoCompensationConfig A non-NULL pointer to HFXO compensation parameters * indicating the temperature variations used to trigger a compensation. * @return Status code indicating the result of the function call. * * @note This function must be called after \ref RAIL_ConfigHFXOThermistor() to succeed. * * In \ref RAIL_HFXOCompensationConfig_t, deltaNominal and * deltaCritical define the temperature variation triggering * a new compensation. * The field zoneTemperatureC defines the temperature separating * the nominal case (below) from the critical one (above). * * When enabled and either deltaNominal or deltaCritical * are exceeded, RAIL raises * event \ref RAIL_EVENT_CAL_NEEDED with \ref RAIL_CAL_TEMP_HFXO bit set. * The API \ref RAIL_StartThermistorMeasurement() must be called afterwards. * The latter will raise \ref RAIL_EVENT_THERMISTOR_DONE with calibration bit * \ref RAIL_CAL_COMPENSATE_HFXO set and a call to \ref RAIL_CalibrateHFXO() must follow. * * @note Set deltaNominal and deltaCritical to 0 to perform * compensation after each transmit. */ RAIL_Status_t RAIL_ConfigHFXOCompensation(RAIL_Handle_t railHandle, const RAIL_HFXOCompensationConfig_t *pHfxoCompensationConfig); /** * Get the temperature parameters for HFXO compensation. * * @param[in] railHandle A RAIL instance handle. * @param[out] pHfxoCompensationConfig A non-NULL pointer to HFXO * compensation parameters filled in by the function. * @return Status code indicating the result of the function call. */ RAIL_Status_t RAIL_GetHFXOCompensationConfig(RAIL_Handle_t railHandle, RAIL_HFXOCompensationConfig_t *pHfxoCompensationConfig); /** * Compute a frequency offset and compensate HFXO accordingly. * * @param[in] railHandle A RAIL instance handle. * @param[in] crystalPPMError The current ppm error. Positive values indicate * the HFXO frequency is too high; negative values indicate it's too low. * @return Status code indicating success of the function call. * * @note This function only works for platforms having * \ref RAIL_SUPPORTS_EXTERNAL_THERMISTOR alongside \ref RAIL_SUPPORTS_HFXO_COMPENSATION. */ RAIL_Status_t RAIL_CompensateHFXO(RAIL_Handle_t railHandle, int8_t crystalPPMError); /** @} */ // end of group External_Thermistor /****************************************************************************** * TrustZone *****************************************************************************/ /** * @addtogroup TrustZone * @brief APIs to use RAIL with TrustZone enabled and peripherals configured * as secure. * * RAIL internally accesses CMU, EMU, GPIO, LDMA, HFXO, PRS and SYSRTC. * If some of them are configured as secure peripherals, some RAIL code must be * executed as secure code. To do so, callbacks gathered in * \ref RAIL_TZ_Config_t must be implemented and passed to RAIL through * \ref RAIL_TZ_InitNonSecure(). Each callback must do the non-secure/secure * transition, call \ref RAIL_TZ_CheckPeripheralsSecureStates() and then call * the corresponding RAIL API from secure world: * * | Secure peripheral | Callbacks to implement | * |-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| * | CMU | \ref RAIL_TZ_Config_t::changedDcdcCallback, \ref RAIL_TZ_Config_t::configAntennaGpioCallback, \ref RAIL_TZ_Config_t::radioClockEnableCallback, \ref RAIL_TZ_Config_t::getRadioClockFreqHzCallback, \ref RAIL_TZ_Config_t::rfecaClockEnableCallback, \ref RAIL_TZ_Config_t::rfecaIsClockEnabledCallback | * | EMU | \ref RAIL_TZ_Config_t::readInternalTemperatureCallback, \ref RAIL_TZ_Config_t::enableSecureRadioIrqsCallback, \ref RAIL_TZ_Config_t::disableSecureRadioIrqsCallback | * | GPIO | \ref RAIL_TZ_Config_t::configAntennaGpioCallback | * | LDMA | \ref RAIL_TZ_Config_t::radioPerformM2mLdmaCallback | * | HFXO | \ref RAIL_TZ_Config_t::configureHfxoCallback | * * RAIL internally calls platform functions that access CMU, EMU, GPIO, LDMA * HFXO and PRS. * If some of them are configured as secure peripherals, some functions must be * executed as secure code. To do so, those functions are prepended with weak * symbols and must be overwritten to do the non-secure/secure transition and * call the corresponding platform function from secure world: * * | Secure peripheral | Platform functions to overwrite | * |-------------------|-----------------------------------------------------------------------------------------------| * | CMU | CMU_ClockEnable, EMU_DCDCSetPFMXTimeoutMaxCtrl (DCDC access: SL_TRUSTZONE_PERIPHERAL_DCDC_S) | * | HFXO | CMU_HFXOCTuneSet, CMU_HFXOCTuneGet, CMU_HFXOCoreBiasCurrentCalibrate | * | PRS | PRS_SourceAsyncSignalSet, PRS_GetFreeChannel, PRS_ConnectConsumer, PRS_PinOutput, PRS_Combine | * * When there is a combination of secure and non-secure peripherals, defines * must be added in secure application slcp file so non-secure peripherals can * properly accessed by secure code. Example with only CMU non-secure: * * @code{.slcp} * define: * - name: SL_TRUSTZONE_PERIPHERAL_CMU_S * value: 0 * condition: [trustzone_secure] * - name: SL_TRUSTZONE_PERIPHERAL_EMU_S * value: 1 * condition: [trustzone_secure] * - name: SL_TRUSTZONE_PERIPHERAL_GPIO_S * value: 1 * condition: [trustzone_secure] * - name: SL_TRUSTZONE_PERIPHERAL_LDMA_S * value: 1 * condition: [trustzone_secure] * - name: SL_TRUSTZONE_PERIPHERAL_HFXO0_S * value: 1 * condition: [trustzone_secure] * - name: SL_TRUSTZONE_PERIPHERAL_PRS_S * value: 1 * condition: [trustzone_secure] * - name: SL_TRUSTZONE_PERIPHERAL_SYSRTC_S * value: 1 * condition: [trustzone_secure] * @endcode * * Some RAIL API are not suppoted with EMU, GPIO, LDMA, HFXO, PRS or SYSRTC * configured secure: * * | Secure peripheral | Unsupported RAIL API/features | * |-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| * | EMU | \ref RAIL_StartThermistorMeasurement(), \ref RAIL_InitPowerManager() | * | GPIO | \ref RAIL_EnableDirectMode(), \ref RAIL_EnableDirectModeAlt(), \ref RAIL_EnablePti(), \ref RAIL_ConfigPti(), \ref RAIL_ConfigHFXOThermistor(), \ref RAIL_StartThermistorMeasurement(), \ref RAIL_ConfigVdet() | * | LDMA | \ref RAIL_IEEE802154_SUPPORTS_RX_CHANNEL_SWITCHING (\ref RAIL_IEEE802154_ConfigRxChannelSwitching() and \ref RAIL_RX_OPTION_CHANNEL_SWITCHING) | * | HFXO | \ref RAIL_StartThermistorMeasurement(), \ref RAIL_EnableVdet(), \ref RAIL_GetVdet() | * | PRS | \ref RAIL_EnablePrsLnaBypass() | * | SYSRTC | \ref RAIL_ConfigSleep() with \ref RAIL_SleepConfig_t::RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED, \ref RAIL_ConfigSleepAlt() with \ref RAIL_SleepConfig_t::RAIL_SLEEP_CONFIG_TIMERSYNC_ENABLED | * * @{ */ /** * Init RAIL TrustZone feature for non-secure world * * @param[in] pTzConfig A non-NULL pointer to a \ref RAIL_TZ_Config_t * structure. * @return Status code indicating success of the function call. * * @note This function must only be called from non-secure world (only if * TrustZone is activated) on platforms having * \ref RAIL_SUPPORTS_TRUSTZONE_SECURE_PERIPHERALS. It must be called * before \ref RAIL_Init() and it must be called again with updated * \ref RAIL_TZ_Config_t if peripherals secure configuration has changed. */ RAIL_Status_t RAIL_TZ_InitNonSecure(const RAIL_TZ_Config_t *pTzConfig); /** * Init RAIL TrustZone feature for secure world * * @return Status code indicating success of the function call. * * @note This function must only be called from secure world (only if TrustZone * is activated) on platforms having * \ref RAIL_SUPPORTS_TRUSTZONE_SECURE_PERIPHERALS. It must be called * before starting the non-secure application. */ RAIL_Status_t RAIL_TZ_InitSecure(void); /** * Check the secure state of peripherals used by RAIL. * * @return Status code indicating success of the function call. * * @note This function must only be called from secure world and it must be * called at the beginning of each RAIL TrustZone callbacks * (\ref RAIL_TZ_Config_t) secure code to avoid secure fault. */ RAIL_Status_t RAIL_TZ_CheckPeripheralsSecureStates(void); /** * Enable radio clocks. * * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when CMU is * configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_RadioClockEnable(void); /** * Enable RFECA clocks. * * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when CMU is * configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_RfecaClockEnable(void); /** * Indicate whether RFECA clocks are enabled. * * @return true if RFECA clocks are enabled; false otherwise * * @note This function must only be called from secure world when CMU is * configured as secure TrustZone peripheral. * */ bool RAIL_TZ_RfecaIsClockEnabled(void); /** * Read the internal temperature. * * @param[out] internalTemperatureKelvin A pointer to the internal temperature * in Kelvin. * @param[in] enableTemperatureInterrupts Indicate whether temperature * interrupts are enabled. * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when EMU is * configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_ReadInternalTemperature(uint16_t *internalTemperatureKelvin, bool enableTemperatureInterrupts); /** * Enable secure peripheral interrupts needed by the radio. * * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when EMU is * configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_EnableSecureRadioIrqs(void); /** * Disable secure peripheral interrupts needed by the radio. * * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when EMU is * configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_DisableSecureRadioIrqs(void); /** * Perform ldma transfer for the radio. * * @param[in] pDest A pointer to the destination data. * @param[in] pSrc A pointer to the source data. * @param[in] numWords Number of words to transfer. * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when LDMA is * configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_RadioPerformM2mLdma(uint32_t *pDest, const uint32_t *pSrc, uint32_t numWords); /** * Configure HFXO. * * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when HFXO is * configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_ConfigureHfxo(void); /** * Set GPIO for antenna config. * * @param[in] config A pointer to a configuration structure applied to the relevant Antenna * Configuration registers. A NULL configuration will produce undefined behavior. * @return Status code indicating success of the function call. * * @note This function must only be called from secure world when CMU or GPIO * are configured as secure TrustZone peripheral. * */ RAIL_Status_t RAIL_TZ_ConfigAntennaGpio(const RAIL_AntennaConfig_t *config); /** @} */ // end of group TrustZone /****************************************************************************** * Features *****************************************************************************/ /** * @addtogroup Features * @{ */ /** * Indicate whether RAIL supports 2.4 GHz band operation on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the 2.4 GHz band is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_2P4GHZ_BAND. */ bool RAIL_Supports2p4GHzBand(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports SubGHz band operation on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the SubGHz band is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_SUBGHZ_BAND. */ bool RAIL_SupportsSubGHzBand(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports dual 2.4 GHz and SubGHz band operation. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the dual band is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_DUAL_BAND. */ bool RAIL_SupportsDualBand(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports bit masked address filtering. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if bit masked address filtering is supported; false otherwise. * * Runtime refinement of compile-time * \ref RAIL_SUPPORTS_ADDR_FILTER_ADDRESS_BIT_MASK. */ bool RAIL_SupportsAddrFilterAddressBitMask(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports address filter mask information * for incoming packets in * \ref RAIL_RxPacketInfo_t::filterMask and * \ref RAIL_IEEE802154_Address_t::filterMask. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if address filter information is supported; false otherwise * (in which case \ref RAIL_RxPacketInfo_t::filterMask value is undefined). * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_ADDR_FILTER_MASK. */ bool RAIL_SupportsAddrFilterMask(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports alternate TX power settings. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if alternate TX power settings are supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_SUPPORTS_ALTERNATE_TX_POWER. */ bool RAIL_SupportsAlternateTxPower(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports antenna diversity. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if antenna diversity is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_ANTENNA_DIVERSITY. * * @note Certain radio configurations may not support this feature even * if the chip in general claims to support it. */ bool RAIL_SupportsAntennaDiversity(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports internal RF path diversity. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if RF path diversity is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_PATH_DIVERSITY. * * @note Certain radio configurations may not support this feature even * if the chip in general claims to support it. */ bool RAIL_SupportsPathDiversity(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports AUXADC measurements on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if AUXADC measurements are supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_AUXADC. */ bool RAIL_SupportsAuxAdc(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports channel hopping on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if channel hopping is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_CHANNEL_HOPPING. */ bool RAIL_SupportsChannelHopping(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports direct mode. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if direct mode is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_SUPPORTS_DIRECT_MODE. */ bool RAIL_SupportsDirectMode(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports dual sync words. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if dual sync words are supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_DUAL_SYNC_WORDS. * * @note Certain radio configurations may not support this feature even * if the chip in general claims to support it. */ bool RAIL_SupportsDualSyncWords(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports start to start TX repeats. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if start to start TX repeats are supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_SUPPORTS_TX_REPEAT_START_TO_START. */ bool RAIL_SupportsTxRepeatStartToStart(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports VDET. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if VDET is supported; false otherwise. */ bool RAIL_SupportsVdet(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports thermistor measurements on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if thermistor measurements are supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_EXTERNAL_THERMISTOR. */ bool RAIL_SupportsExternalThermistor(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports HFXO compensation on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if HFXO compensation is supported and * \ref RAIL_ConfigHFXOThermistor() has been successfully called; * false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_HFXO_COMPENSATION. */ bool RAIL_SupportsHFXOCompensation(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports MFM protocol. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if MFM protocol is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_MFM. */ bool RAIL_SupportsMfm(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports OFDM band operation on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if OFDM operation is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_OFDM_PA. */ bool RAIL_SupportsOFDMPA(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports a high-precision LFRCO. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if high-precision LFRCO is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_PRECISION_LFRCO. */ bool RAIL_SupportsPrecisionLFRCO(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports radio entropy. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if radio entropy is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_RADIO_ENTROPY. */ bool RAIL_SupportsRadioEntropy(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports RFSENSE Energy Detection Mode on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if RFSENSE Energy Detection Mode is supported; false otherwise. * * Runtime refinement of compile-time * \ref RAIL_SUPPORTS_RFSENSE_ENERGY_DETECTION. */ bool RAIL_SupportsRfSenseEnergyDetection(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports RFSENSE Selective(OOK) Mode on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if RFSENSE Selective(OOK) Mode is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_RFSENSE_SELECTIVE_OOK. */ bool RAIL_SupportsRfSenseSelectiveOok(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports configurable RSSI threshold * set by \ref RAIL_SetRssiDetectThreshold(). * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if setting configurable RSSI is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_RSSI_DETECT_THRESHOLD. */ bool RAIL_SupportsRssiDetectThreshold(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports RX direct mode data to FIFO. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if direct mode data to FIFO is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_SUPPORTS_RX_DIRECT_MODE_DATA_TO_FIFO. */ bool RAIL_SupportsRxDirectModeDataToFifo(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports raw RX data * sources other than \ref RAIL_RxDataSource_t::RX_PACKET_DATA. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if direct mode is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_RX_RAW_DATA. */ bool RAIL_SupportsRxRawData(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports SQ-based PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the SQ-based PHY is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_SQ_PHY. */ bool RAIL_SupportsSQPhy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports a particular power mode (PA). * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in] powerMode The power mode to check if supported. * @param[out] pMaxPowerLevel A pointer to a \ref RAIL_TxPowerLevel_t that * if non-NULL will be filled in with the power mode's highest power level * allowed if this function returns true. * @return true if the powerMode is supported; false otherwise. * * This function has no compile-time equivalent. * * @note Consider using \ref RAIL_SupportsTxPowerModeAlt to also get the power * mode's lowest allowed power level. */ bool RAIL_SupportsTxPowerMode(RAIL_Handle_t railHandle, RAIL_TxPowerMode_t powerMode, RAIL_TxPowerLevel_t *pMaxPowerLevel); /** * Indicate whether this chip supports a particular power mode (PA) and * provides the maximum and minimum power level for that power mode * if supported by the chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @param[in,out] powerMode A pointer to PA power mode to check if supported. * If \ref RAIL_TX_POWER_MODE_2P4GIG_HIGHEST or \ref * RAIL_TX_POWER_MODE_SUBGIG_HIGHEST is passed in, it will be updated * to the highest corresponding PA available on the chip. * @param[out] maxPowerLevel A pointer to a \ref RAIL_TxPowerLevel_t that * if non-NULL will be filled in with the power mode's highest power level * allowed if this function returns true. * @param[out] minPowerLevel A pointer to a \ref RAIL_TxPowerLevel_t that * if non-NULL will be filled in with the power mode's lowest power level * allowed if this function returns true. * @return true if powerMode is supported; false otherwise. * * This function has no compile-time equivalent. */ bool RAIL_SupportsTxPowerModeAlt(RAIL_Handle_t railHandle, RAIL_TxPowerMode_t *powerMode, RAIL_TxPowerLevel_t *maxPowerLevel, RAIL_TxPowerLevel_t *minPowerLevel); /** * Indicate whether this chip supports automatic TX to TX transitions. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if TX to TX transitions are supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_TX_TO_TX. */ bool RAIL_SupportsTxToTx(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports the BLE protocol on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_PROTOCOL_BLE. */ bool RAIL_SupportsProtocolBLE(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE 1 Mbps Non-Viterbi PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE 1 Mbps Non-Viterbi is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_1MBPS_NON_VITERBI. */ bool RAIL_BLE_Supports1MbpsNonViterbi(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE 1 Mbps Viterbi PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE 1 Mbps Viterbi is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_1MBPS_VITERBI. */ bool RAIL_BLE_Supports1MbpsViterbi(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE 1 Mbps operation. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE 1 Mbps operation is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_1MBPS. */ static inline bool RAIL_BLE_Supports1Mbps(RAIL_Handle_t railHandle) { bool temp = RAIL_BLE_Supports1MbpsViterbi(railHandle); // Required for MISRA compliance return (RAIL_BLE_Supports1MbpsNonViterbi(railHandle) || temp); } /** * Indicate whether this chip supports BLE 2 Mbps Non-Viterbi PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE 2 Mbps Non-Viterbi is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_2MBPS_NON_VITERBI. */ bool RAIL_BLE_Supports2MbpsNonViterbi(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE 2 Mbps Viterbi PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE 2 Mbps Viterbi is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_2MBPS_VITERBI. */ bool RAIL_BLE_Supports2MbpsViterbi(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE 2 Mbps operation. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE 2 Mbps operation is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_2MBPS. */ static inline bool RAIL_BLE_Supports2Mbps(RAIL_Handle_t railHandle) { bool temp = RAIL_BLE_Supports2MbpsViterbi(railHandle); // Required for MISRA compliance return (RAIL_BLE_Supports2MbpsNonViterbi(railHandle) || temp); } /** * Indicate whether this chip supports BLE Antenna Switching needed for * Angle-of-Arrival receives or Angle-of-Departure transmits. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE Antenna Switching is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_ANTENNA_SWITCHING. */ bool RAIL_BLE_SupportsAntennaSwitching(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE Coded PHY used for Long-Range. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE Coded PHY is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_CODED_PHY. */ bool RAIL_BLE_SupportsCodedPhy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE CTE (Constant Tone Extension) * needed for Angle-of-Arrival/Departure transmits. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE CTE is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_CTE. */ bool RAIL_BLE_SupportsCte(RAIL_Handle_t railHandle); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * Indicate whether this chip supports BLE CS. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE CS is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_CS. */ bool RAIL_BLE_SupportsCs(RAIL_Handle_t railHandle); #endif//DOXYGEN_SHOULD_SKIP_THIS /** * Indicate whether this chip supports BLE IQ Sampling needed for * Angle-of-Arrival/Departure receives. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE IQ Sampling is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_IQ_SAMPLING. */ bool RAIL_BLE_SupportsIQSampling(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE PHY switch to RX * functionality, which is used to switch BLE PHYs at a specific time * to receive auxiliary packets. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE PHY switch to RX is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_PHY_SWITCH_TO_RX. */ bool RAIL_BLE_SupportsPhySwitchToRx(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the Quuppa PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the Quuppa is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_QUUPPA. */ bool RAIL_BLE_SupportsQuuppa(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE signal identifier. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if signal identifier is supported; false otherwise. */ bool RAIL_BLE_SupportsSignalIdentifier(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports BLE Simulscan PHY used for simultaneous * BLE 1 Mbps and Coded PHY reception. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if BLE Simulscan PHY is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_BLE_SUPPORTS_SIMULSCAN_PHY. */ bool RAIL_BLE_SupportsSimulscanPhy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the IEEE 802.15.4 protocol. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the 802.15.4 protocol is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_PROTOCOL_IEEE802154. */ bool RAIL_SupportsProtocolIEEE802154(RAIL_Handle_t railHandle); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * Indicate whether this chip supports the IEEE 802.15.4 2 Mbps PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the 802.15.4 2 Mbps PHY is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_IEEE802154_SUPPORTS_2MBPS_PHY. */ bool RAIL_IEEE802154_Supports2MbpsPhy(RAIL_Handle_t railHandle); #endif //DOXYGEN_SHOULD_SKIP_THIS /** * Indicate whether this chip supports the IEEE 802.15.4 Wi-Fi Coexistence PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the 802.15.4 COEX PHY is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_IEEE802154_SUPPORTS_COEX_PHY. */ bool RAIL_IEEE802154_SupportsCoexPhy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the IEEE 802.15.4 2.4 GHz band variant. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if IEEE 802.15.4 2.4 GHz band variant is supported; * false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_IEEE802154_BAND_2P4. */ bool RAIL_SupportsIEEE802154Band2P4(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the thermal protection. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if thermal protection is supported; * false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_THERMAL_PROTECTION. */ bool RAIL_SupportsThermalProtection(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the IEEE 802.15.4 2.4 RX channel switching. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if IEEE 802.15.4 2.4 GHz RX channel switching is supported; * false otherwise. * * Runtime refinement of compile-time \ref RAIL_IEEE802154_SUPPORTS_RX_CHANNEL_SWITCHING. */ bool RAIL_IEEE802154_SupportsRxChannelSwitching(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the IEEE 802.15.4 PHY with custom settings. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the 802.15.4 PHY with custom settings is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_IEEE802154_SUPPORTS_CUSTOM1_PHY. */ bool RAIL_IEEE802154_SupportsCustom1Phy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the IEEE 802.15.4 * front end module optimized PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if a front end module is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_IEEE802154_SUPPORTS_FEM_PHY. */ bool RAIL_IEEE802154_SupportsFemPhy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports canceling the frame-pending lookup * event \ref RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND when the radio * transitions to a state that renders the the reporting of this event moot * (i.e., too late for the stack to influence the outgoing Ack). * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if canceling the lookup event is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_CANCEL_FRAME_PENDING_LOOKUP. */ bool RAIL_IEEE802154_SupportsCancelFramePendingLookup(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports early triggering of the frame-pending * lookup event \ref RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND * just after MAC address fields have been received. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if early triggering is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_EARLY_FRAME_PENDING_LOOKUP. */ bool RAIL_IEEE802154_SupportsEarlyFramePendingLookup(RAIL_Handle_t railHandle); /** * Indicate whether RAIL supports dual PA mode on this chip. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the dual PA mode is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_IEEE802154_SUPPORTS_DUAL_PA_CONFIG. */ bool RAIL_IEEE802154_SupportsDualPaConfig(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4E-2012 Enhanced Acking. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if 802.15.4E Enhanced Acking is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_E_ENHANCED_ACK. */ bool RAIL_IEEE802154_SupportsEEnhancedAck(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4E-2012 Multipurpose frame * reception. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if Multipurpose frame reception is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_E_MULTIPURPOSE_FRAMES. */ bool RAIL_IEEE802154_SupportsEMultipurposeFrames(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the IEEE 802.15.4E-2012 feature * subset needed for Zigbee R22 GB868. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if 802.15.4E GB868 subset is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_E_SUBSET_GB868. */ bool RAIL_IEEE802154_SupportsESubsetGB868(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4G-2012 reception and * transmission of frames with 4-byte CRC. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if 802.15.4G 4-byte CRC is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_G_4BYTE_CRC. */ bool RAIL_IEEE802154_SupportsG4ByteCrc(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4G dynamic FEC. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if dynamic FEC is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_G_DYNFEC. */ bool RAIL_IEEE802154_SupportsGDynFec(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports Wi-SUN. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if Wi-SUN is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_SUPPORTS_PROTOCOL_WI_SUN. */ bool RAIL_SupportsProtocolWiSUN(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports Wi-SUN mode switching. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if Wi-SUN mode switching is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_G_MODESWITCH. */ bool RAIL_IEEE802154_SupportsGModeSwitch(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4G-2012 feature * subset needed for Zigbee R22 GB868. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if 802.15.4G GB868 subset is supported; false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868. */ bool RAIL_IEEE802154_SupportsGSubsetGB868(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4G-2012 reception * of unwhitened frames. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if 802.15.4G unwhitened frame reception is supported; * false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_RX. */ bool RAIL_IEEE802154_SupportsGUnwhitenedRx(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4G-2012 transmission * of unwhitened frames. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if 802.15.4G unwhitened frame transmit is supported; * false otherwise. * * Runtime refinement of compile-time \ref * RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_TX. */ bool RAIL_IEEE802154_SupportsGUnwhitenedTx(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports WMBUS simultaneous M2O RX of T and C modes. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the WMBUS simultaneous M2O RX of T and C modes is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_WMBUS_SUPPORTS_SIMULTANEOUS_T_C_RX. */ bool RAIL_WMBUS_SupportsSimultaneousTCRx(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the Z-Wave protocol. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the Z-Wave protocol is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_PROTOCOL_ZWAVE. */ bool RAIL_SupportsProtocolZWave(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the Z-Wave concurrent PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the Z-Wave concurrent PHY is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_ZWAVE_SUPPORTS_CONC_PHY. */ bool RAIL_ZWAVE_SupportsConcPhy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports the Z-Wave energy detect PHY. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if the Z-Wave energy detect PHY is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_ZWAVE_SUPPORTS_ED_PHY. */ bool RAIL_ZWAVE_SupportsEnergyDetectPhy(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports Z-Wave Region in PTI. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if ZWAVE Region in PTI is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_ZWAVE_SUPPORTS_REGION_PTI. */ bool RAIL_ZWAVE_SupportsRegionPti(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports IEEE 802.15.4 signal identifier. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if signal identifier is supported; false otherwise. */ bool RAIL_IEEE802154_SupportsSignalIdentifier(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports fast RX-to-RX. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if fast RX-to-RX is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_FAST_RX2RX. */ bool RAIL_SupportsFastRx2Rx(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports collision detection. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if collision detection is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_COLLISION_DETECTION. */ bool RAIL_SupportsCollisionDetection(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports Sidewalk protocol. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if Sidewalk protocol is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_PROTOCOL_SIDEWALK. */ bool RAIL_SupportsProtocolSidewalk(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports TrustZone secure configuration of * peripherals used by RAIL. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if secure mode is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_TRUSTZONE_SECURE_PERIPHERALS. */ bool RAIL_SupportsTrustZoneSecurePeripherals(RAIL_Handle_t railHandle); /** * Indicate whether this chip supports automatic PRS LNA bypass for external * FEM. * * @param[in] railHandle A radio-generic or real RAIL instance handle. * @return true if automatic PRS LNA bypass is supported; false otherwise. * * Runtime refinement of compile-time \ref RAIL_SUPPORTS_PRS_LNA_BYPASS. */ bool RAIL_SupportsPrsLnaBypass(RAIL_Handle_t railHandle); /** @} */ // end of group Features /** @} */ // end of group RAIL_API #ifdef __cplusplus } #endif #endif // __RAIL_H__