/** * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @file * * @defgroup nrf_sdh SoftDevice Handler * @{ * @ingroup app_common * @brief API for initializing and disabling the SoftDevice. */ #ifndef NRF_SDH_H__ #define NRF_SDH_H__ #include #include "sdk_config.h" #include "sdk_errors.h" #include "nrf_section_iter.h" #ifdef __cplusplus extern "C" { #endif /** * @name Softdevice Handler dispatch models * @{ * @ingroup nrf_sdh */ /**@brief SoftDevice events are passed to the application from the interrupt context. */ #define NRF_SDH_DISPATCH_MODEL_INTERRUPT 0 /**@brief SoftDevice events are passed to the application using @ref app_scheduler. * * @note @ref app_scheduler must be initialized before enabling the SoftDevice handler. */ #define NRF_SDH_DISPATCH_MODEL_APPSH 1 /**@brief SoftDevice events are polled manually using @ref nrf_sdh_evts_poll(). * * @note In this mode, a user application can also implement SD_EVT_IRQHandler() to receive a * notification about incoming events. */ #define NRF_SDH_DISPATCH_MODEL_POLLING 2 /** @} */ /** * @name SoftDevice Handler state change requests * @{ * @ingroup nrf_sdh */ /**@brief SoftDevice Handler state requests. */ typedef enum { NRF_SDH_EVT_ENABLE_REQUEST, //!< Request to enable the SoftDevice. NRF_SDH_EVT_DISABLE_REQUEST, //!< Request to disable the SoftDevice. } nrf_sdh_req_evt_t; /**@brief SoftDevice Handler state request handler. * * @retval true If ready for the SoftDevice to change state. * @retval false If not ready for the SoftDevice to change state. * If false is returned, the state change is aborted. */ typedef bool (*nrf_sdh_req_evt_handler_t)(nrf_sdh_req_evt_t request, void * p_context); /**@brief SoftDevice Handler state request observer. */ typedef struct { nrf_sdh_req_evt_handler_t handler; //!< Request handler. void * p_context; //!< A parameter to the handler function. } const nrf_sdh_req_observer_t; /**@brief Macro for registering a SoftDevice state change request observer. * * An observer of SoftDevice state change requests receives requests to change the state of the * SoftDevice from enabled to disabled and vice versa. These requests may or may not be acknowledged * by the observer, depending on the value returned by its request handler function. Thus, a * request observer has the capability to defer the change of state of the SoftDevice. If it does * so, it has the responsibility to call @ref nrf_sdh_request_continue when it is ready to let the * SoftDevice change its state. If such capability is not necessary and you only need to be informed * about changes of the SoftDevice state, use the @ref NRF_SDH_STATE_OBSERVER macro instead. * * @note This macro places the observer in a section named "sdh_req_observers". * * @param[in] _observer Name of the observer. * @param[in] _prio Priority of the observer's event handler. * The smaller the number, the higher the priority. * @hideinitializer */ #define NRF_SDH_REQUEST_OBSERVER(_observer, _prio) \ STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \ STATIC_ASSERT(_prio < NRF_SDH_REQ_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \ /*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \ NRF_SECTION_SET_ITEM_REGISTER(sdh_req_observers, _prio, nrf_sdh_req_observer_t const _observer) /** @} */ /** * @name SoftDevice Handler state events * @{ * @ingroup nrf_sdh */ /**@brief SoftDevice Handler state events. */ typedef enum { NRF_SDH_EVT_STATE_ENABLE_PREPARE, //!< SoftDevice is going to be enabled. NRF_SDH_EVT_STATE_ENABLED, //!< SoftDevice is enabled. NRF_SDH_EVT_STATE_DISABLE_PREPARE, //!< SoftDevice is going to be disabled. NRF_SDH_EVT_STATE_DISABLED, //!< SoftDevice is disabled. } nrf_sdh_state_evt_t; /**@brief SoftDevice Handler state event handler. */ typedef void (*nrf_sdh_state_evt_handler_t)(nrf_sdh_state_evt_t state, void * p_context); /**@brief SoftDevice Handler state observer. */ typedef struct { nrf_sdh_state_evt_handler_t handler; //!< State event handler. void * p_context; //!< A parameter to the event handler. } const nrf_sdh_state_observer_t; /**@brief Macro for registering a SoftDevice state observer. * * A SoftDevice state observer receives events when the SoftDevice state has changed or is * about to change. These events are only meant to inform the state observer, which, contrary * to a state change request observer, does not have the capability to defer the change of state. * If such capability is required, use the @ref NRF_SDH_REQUEST_OBSERVER macro instead. * * This macro places the observer in a section named "sdh_state_observers". * * @param[in] _observer Name of the observer. * @param[in] _prio Priority of the observer's event handler. * The smaller the number, the higher the priority. * @hideinitializer */ #define NRF_SDH_STATE_OBSERVER(_observer, _prio) \ STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \ STATIC_ASSERT(_prio < NRF_SDH_STATE_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \ /*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \ NRF_SECTION_SET_ITEM_REGISTER(sdh_state_observers, _prio, static nrf_sdh_state_observer_t const _observer) /** @} */ /** * @name SoftDevice stack events * @{ * @ingroup nrf_sdh */ /**@brief SoftDevice stack event handler. */ typedef void (*nrf_sdh_stack_evt_handler_t)(void * p_evt); /**@brief SoftDevice stack event observer. */ typedef struct { nrf_sdh_stack_evt_handler_t handler; //!< SoftDevice event handler. void * p_context; //!< A parameter to the event handler. } const nrf_sdh_stack_observer_t; /**@brief Macro for registering a SoftDevice stack events observer. * * A SoftDevice stack event observer receives all events from the SoftDevice. These events can be * either BLE, ANT, or SoC events. If you need to receive BLE, ANT, or SoC events separately, use the * @ref NRF_SDH_BLE_OBSERVER, @ref NRF_SDH_ANT_OBSERVER, or @ref NRF_SDH_SOC_OBSERVER macros * respectively. * * @note This macro places the observer in a section named "sdh_stack_observers". * * @param[in] _observer Name of the observer. * @param[in] _prio Priority of the observer's event handler. * The smaller the number, the higher the priority. ** @hideinitializer */ #define NRF_SDH_STACK_OBSERVER(_observer, _prio) \ STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \ STATIC_ASSERT(_prio < NRF_SDH_STACK_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \ /*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \ NRF_SECTION_SET_ITEM_REGISTER(sdh_stack_observers, _prio, static nrf_sdh_stack_observer_t const _observer) /** @} */ /**@brief Function for requesting to enable the SoftDevice. * * This function issues a @ref NRF_SDH_EVT_ENABLE_REQUEST request to all observers that * were registered using the @ref NRF_SDH_REQUEST_OBSERVER macro. The observers may or * may not acknowledge the request. If all observers acknowledge the request, the * SoftDevice will be enabled. Otherwise, the process will be stopped and the observers * that did not acknowledge have the responsibility to restart it by calling * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state. * * @retval NRF_SUCCESS The process is started. * @retval NRF_ERROR_INVALID_STATE The SoftDevice is already enabled. */ ret_code_t nrf_sdh_enable_request(void); /**@brief Function for requesting to disable the SoftDevice. * * This function issues a @ref NRF_SDH_EVT_DISABLE_REQUEST request to all observers that * were registered using the @ref NRF_SDH_REQUEST_OBSERVER macro. The observers may or * may not acknowledge the request. If all observers acknowledge the request, the * SoftDevice will be disabled. Otherwise, the process will be stopped and the observers * that did not acknowledge have the responsibility to restart it by calling * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state. * * @retval NRF_SUCCESS The process is started. * @retval NRF_ERROR_INVALID_STATE The SoftDevice is already disabled. */ ret_code_t nrf_sdh_disable_request(void); /**@brief Function for restarting the SoftDevice Enable/Disable process. * * Modules which did not acknowledge a @ref NRF_SDH_EVT_ENABLE_REQUEST or * @ref NRF_SDH_EVT_DISABLE_REQUEST request must call this function to restart the * SoftDevice state change process. * * @retval NRF_SUCCESS The process is restarted. * @retval NRF_ERROR_INVALID_STATE No state change request was pending. */ ret_code_t nrf_sdh_request_continue(void); /**@brief Function for retrieving the SoftDevice state. * * @retval true If the SoftDevice is enabled. * @retval false If the SoftDevice is disabled. */ bool nrf_sdh_is_enabled(void); /**@brief Function for stopping the incoming stack events. * * This function disables the SoftDevice interrupt. To resume polling for events, * call @ref nrf_sdh_resume. */ void nrf_sdh_suspend(void); /**@brief Function for resuming polling incoming events from the SoftDevice. */ void nrf_sdh_resume(void); /**@brief Function for retrieving the information about the module state. * * @retval true The SoftDevice handler is paused, and it will not fetch events from the stack. * @retval false The SoftDevice handler is running, and it will fetch and dispatch events from * the stack to the registered stack observers. */ bool nrf_sdh_is_suspended(void); /**@brief Function for polling stack events from the SoftDevice. * * The events are passed to the application using the registered event handlers. * * @note @ref NRF_SDH_DISPATCH_MODEL_POLLING must be selected to use this function. */ void nrf_sdh_evts_poll(void); #ifdef __cplusplus } #endif #endif // NRF_SDH_H__ /** @} */