318 lines
13 KiB
C
318 lines
13 KiB
C
/*
|
|
* Copyright (c) 2020 - 2023, Nordic Semiconductor ASA
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*
|
|
* 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 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.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @brief Module that provides the timer service for the 802.15.4 driver.
|
|
*
|
|
* The @b timer module allows scheduling future actions to happen. Object of type
|
|
* @ref nrf_802154_sl_timer_t (and related functions) is responsible for this feature.
|
|
*/
|
|
|
|
#ifndef NRF_802154_SL_TIMER_H_
|
|
#define NRF_802154_SL_TIMER_H_
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @defgroup nrf_802154_sl_timer Timer Service
|
|
* @{
|
|
* @ingroup nrf_802154_sl_timer
|
|
* @brief The Timer Service for the 802.15.4 driver.
|
|
*
|
|
*/
|
|
|
|
/**@brief Number of array elements required by @ref nrf_802154_sl_timer_priv_placeholder_t. */
|
|
#define NRF_802154_SL_TIMER_PRIV_SIZE 2U
|
|
|
|
/**@brief Type of result returned by timer-related functions.
|
|
*
|
|
* Possible values:
|
|
* @ref NRF_802154_SL_TIMER_RET_SUCCESS
|
|
* @ref NRF_802154_SL_TIMER_RET_TOO_LATE
|
|
* @ref NRF_802154_SL_TIMER_RET_TOO_DISTANT
|
|
* @ref NRF_802154_SL_TIMER_RET_NO_RESOURCES
|
|
* @ref NRF_802154_SL_TIMER_RET_INACTIVE
|
|
* @ref NRF_802154_SL_TIMER_RET_BAD_REQUEST
|
|
*/
|
|
typedef uint32_t nrf_802154_sl_timer_ret_t;
|
|
|
|
/**@brief Operation performed successfully. */
|
|
#define NRF_802154_SL_TIMER_RET_SUCCESS 0U
|
|
|
|
/**@brief Passed invalid parameters to a call.
|
|
* This result may occur if the user filled incorrect values in the request
|
|
* object or given feature is not supported yet
|
|
*/
|
|
#define NRF_802154_SL_TIMER_RET_BAD_REQUEST 1U
|
|
|
|
/**@brief Operation was requested too late to be performed in requested time. */
|
|
#define NRF_802154_SL_TIMER_RET_TOO_LATE 2U
|
|
|
|
/**@brief The trigger time for the requested operation is too distant.
|
|
*
|
|
* Some platforms have a limitation to how far in the future operation can be
|
|
* scheduled. This result may happen for @ref nrf_802154_sl_timer_add with
|
|
* @ref nrf_802154_sl_timer_t::trigger_time containing a value too far from `now`.
|
|
*/
|
|
#define NRF_802154_SL_TIMER_RET_TOO_DISTANT 3U
|
|
|
|
/**@brief There were no available resources required to schedule requested activity.
|
|
*
|
|
* This result may happen for @ref nrf_802154_sl_timer_add with
|
|
* @ref nrf_802154_sl_timer_t::action_type containing
|
|
* @ref NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE. To trigger hardware task by the timer,
|
|
* some hardware resources like PPI/DPPI channels, EGU channels, timer compare channels
|
|
* (implementation dependent) were needed, but they were unavailable.
|
|
*/
|
|
#define NRF_802154_SL_TIMER_RET_NO_RESOURCES 4U
|
|
|
|
/**@brief The timer was inactive at the moment of requested operation. */
|
|
#define NRF_802154_SL_TIMER_RET_INACTIVE 5U
|
|
|
|
/**@brief Type representing a timer. */
|
|
typedef struct nrf_802154_sl_timer_s nrf_802154_sl_timer_t;
|
|
|
|
/**@brief Type of callback function pointer to be called when timer triggers. */
|
|
typedef void (* nrf_802154_sl_timer_callback_t)(nrf_802154_sl_timer_t * p_timer);
|
|
|
|
/**@brief Action types to be performed when a timer triggers.
|
|
*
|
|
* This is a bitmask with possible masks:
|
|
* @ref NRF_802154_SL_TIMER_ACTION_TYPE_CALLBACK
|
|
* @ref NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE
|
|
*/
|
|
typedef uint8_t nrf_802154_sl_timer_action_type_t;
|
|
|
|
/**@brief Timer action type mask allowing a callback to be called. */
|
|
#define NRF_802154_SL_TIMER_ACTION_TYPE_CALLBACK (1U << 0)
|
|
/**@brief Timer action type mask allowing triggering a hardware task. */
|
|
#define NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE (1U << 1)
|
|
|
|
/**
|
|
* @brief Special value that indicates that (D)PPI configuration is incomplete.
|
|
*/
|
|
#define NRF_802154_SL_TIMER_INVALID_PPI_CHANNEL UINT32_MAX
|
|
|
|
/**@brief Structure that represents private fields of a timer required by the implementation. */
|
|
typedef struct
|
|
{
|
|
uint64_t placeholder[NRF_802154_SL_TIMER_PRIV_SIZE];
|
|
} nrf_802154_sl_timer_priv_placeholder_t;
|
|
|
|
struct nrf_802154_sl_timer_s
|
|
{
|
|
/**@brief Private fields required by the implementation.
|
|
*
|
|
* Must be at the beginning of the structure.
|
|
*/
|
|
nrf_802154_sl_timer_priv_placeholder_t priv;
|
|
|
|
/**@brief The timestamp in microseconds at which the timer should be triggered.
|
|
*
|
|
* The callback will be called no earlier than at given @p trigger_time, but may be delayed
|
|
* due to processing time taken by other ISRs.
|
|
*/
|
|
uint64_t trigger_time;
|
|
|
|
/**@brief User-provided data.
|
|
*
|
|
* User preparing a timer can store any data within this field. Timer module does not
|
|
* process this data.
|
|
*/
|
|
union
|
|
{
|
|
void * p_pointer;
|
|
const void * p_cpointer;
|
|
} user_data;
|
|
|
|
/**@brief Action type to be performed when the timer triggers.
|
|
*
|
|
* Depending on value bits set in this bitmask, appropriate fields of @c action is valid.
|
|
*/
|
|
nrf_802154_sl_timer_action_type_t action_type;
|
|
|
|
struct
|
|
{
|
|
/**@brief Parameters applicable when @c action_type contains
|
|
* @ref NRF_802154_SL_TIMER_ACTION_TYPE_CALLBACK */
|
|
struct
|
|
{
|
|
/**@brief Callback to be called when the timer triggers.
|
|
*
|
|
* The callback is called within an ISR. Please take into account possible
|
|
* latency between moment of trigger and moment when the callback gets called.
|
|
*/
|
|
nrf_802154_sl_timer_callback_t callback;
|
|
} callback;
|
|
|
|
/**@brief Parameters applicable when @c action_type contains
|
|
* @ref NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE */
|
|
struct
|
|
{
|
|
/**@brief Identifier of (D)PPI channel to be triggered at @c trigger_time.
|
|
*
|
|
* The API user is responsible for creating all necessary hardware bindings between
|
|
* provided (D)PPI channel and the requested task, as well as necessary configuration
|
|
* of these resources. Moreover, the API user must keep the hardware bindings enabled
|
|
* and functional until the requested hardware task is triggered or until the timer
|
|
* is successfully removed.
|
|
*
|
|
* A special value of @ref NRF_802154_SL_TIMER_INVALID_PPI_CHANNEL can be set. In this
|
|
* case, the binding creation is postponed and the user is required to use the
|
|
* @ref nrf_802154_sl_timer_update_ppi to complete the configuration. Must do so
|
|
* before @c trigger_time expires.
|
|
*/
|
|
uint32_t ppi_channel;
|
|
} hardware;
|
|
} action;
|
|
};
|
|
|
|
/**@brief Initializes the timer module. */
|
|
void nrf_802154_sl_timer_module_init(void);
|
|
|
|
/**@brief Uninitializes the timer module. */
|
|
void nrf_802154_sl_timer_module_uninit(void);
|
|
|
|
/**@brief Gets current time.
|
|
*
|
|
* @return Time in microseconds.
|
|
*/
|
|
uint64_t nrf_802154_sl_timer_current_time_get(void);
|
|
|
|
/**@brief Initializes a timer instance.
|
|
*
|
|
* This function plays a role of a constructor. It should be called once
|
|
* per timer instance before any other API call related to given
|
|
* timer instance. Calling any other API related to a timer
|
|
* instance before call to @ref nrf_802154_sl_timer_init or
|
|
* calling @ref nrf_802154_sl_timer_init more than once is an
|
|
* undefined behavior.
|
|
*
|
|
* @param p_timer Pointer to a timer instance to be initialized.
|
|
*/
|
|
void nrf_802154_sl_timer_init(nrf_802154_sl_timer_t * p_timer);
|
|
|
|
/**@brief De-initializes a timer instance.
|
|
*
|
|
* This function plays a role of a destructor.
|
|
*
|
|
* @param p_timer Pointer to a timer instance to be de-initialized.
|
|
*/
|
|
void nrf_802154_sl_timer_deinit(nrf_802154_sl_timer_t * p_timer);
|
|
|
|
/**@brief Adds a timer to the active timers list.
|
|
*
|
|
* This function adds the timer pointed by @p p_timer parameter to an active timers
|
|
* list. Before call to @ref nrf_802154_sl_timer_add the timer must fill
|
|
* public fields of timer object instance in the following way:
|
|
* - @ref nrf_802154_sl_timer_t::trigger_time is set up to the moment when the timer
|
|
* is expected to trigger
|
|
* - Optionally @ref nrf_802154_sl_timer_t::user_data may be set, to user-dependent value.
|
|
* - @ref nrf_802154_sl_timer_t::action_type is set according to requested action.
|
|
* - Depending on value written to @ref nrf_802154_sl_timer_t::action_type
|
|
* matching fields of @ref nrf_802154_sl_timer_t::action must be filled.
|
|
*
|
|
* When this function succeeds the timer module takes ownership of the timer instance.
|
|
* A user is forbidden to modify the structure until the callback is called or
|
|
* @ref nrf_802154_sl_timer_remove is successfully called. Modification of timer owned by the
|
|
* timer service results in an undefined behavior. In particular the user
|
|
* is forbidden to set a new value of @ref nrf_802154_sl_timer_t::trigger_time as long as the
|
|
* timer is owned by the timer service.
|
|
*
|
|
* Please note that if @ref nrf_802154_sl_timer_t::trigger_time is in the past or very near in
|
|
* the future, the timer is scheduled and will fire as soon as possible but not earlier than
|
|
* given by @ref nrf_802154_sl_timer_t::trigger_time.
|
|
*
|
|
* @param p_timer Pointer to a timer instance to add to active timers list.
|
|
*
|
|
* @retval NRF_802154_SL_TIMER_RET_SUCCESS
|
|
* Function succeeded. The timer is sussessfully added. The requested action is
|
|
* scheduled to happen.
|
|
* @retval NRF_802154_SL_TIMER_RET_NO_RESOURCES
|
|
* The requested hardware task can't be bound to the timer due to lack of hardware resources.
|
|
* @retval NRF_802154_SL_TIMER_RET_BAD_REQUEST
|
|
* A user passed unsupported or invalid parameters in @p p_timer.
|
|
*/
|
|
nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_add(nrf_802154_sl_timer_t * p_timer);
|
|
|
|
/**@brief Removes a timer from the active timers list.
|
|
*
|
|
* @param p_timer Pointer to a timer instance to be removed from the active timers list.
|
|
*
|
|
* @retval NRF_802154_SL_TIMER_RET_SUCCESS
|
|
* The timer was running and it has been successfully removed from active timers list.
|
|
* The requested action (either callback or hardware task trigger) will not happen.
|
|
* @retval NRF_802154_SL_TIMER_RET_INACTIVE
|
|
* The timer was not running at the moment of the call and is not in the active timers list.
|
|
* Nothing can be implied about the completion of the timer's requested action, without
|
|
* checking external conditions. It is up to the caller to detect if requested action
|
|
* (either callback, hardware task or both) has already been executed, is currently
|
|
* in progress or yet remains to be executed.
|
|
*/
|
|
nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_remove(nrf_802154_sl_timer_t * p_timer);
|
|
|
|
/**@brief Updates the (D)PPI channel to be triggered.
|
|
*
|
|
* @param p_timer Pointer to a timer instance to be updated.
|
|
* @param ppi_chn Identifier of (D)PPI channel to be triggered at @c trigger_time.
|
|
*
|
|
* @retval NRF_802154_SL_TIMER_RET_SUCCESS
|
|
* The (D)PPI channel was updated and it was done on time, i.e. before specified
|
|
* trigger time.
|
|
* @retval NRF_802154_SL_TIMER_RET_TOO_LATE
|
|
* It has been detected that the timer has already fired and because of this the update
|
|
* could not complete at all or did not complete on time. Nevertheless, the (D)PPI may
|
|
* have been triggered, but it cannot be stated reliably.
|
|
* @retval NRF_802154_SL_TIMER_RET_BAD_REQUEST
|
|
* A user passed invalid parameters in @p p_timer, e.g. @c action_type does not contain
|
|
* @ref NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE.
|
|
*/
|
|
nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_update_ppi(nrf_802154_sl_timer_t * p_timer,
|
|
uint32_t ppi_chn);
|
|
|
|
/**
|
|
*@}
|
|
**/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* NRF_802154_SL_TIMER_H_ */
|