306 lines
13 KiB
C
306 lines
13 KiB
C
|
/**
|
||
|
* Copyright (c) 2017 - 2018, 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 <stdbool.h>
|
||
|
#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__
|
||
|
|
||
|
/** @} */
|