1 /*
2 * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35 /**
36 * @file Definitions of utils used in the nRF 802.15.4 Service Layer.
37 *
38 */
39
40 #ifndef NRF_802154_SL_UTILS_H__
41 #define NRF_802154_SL_UTILS_H__
42
43 #include <stdbool.h>
44 #include <stdint.h>
45 #include <stdbool.h>
46 #include "nrfx.h"
47
48 /**@brief RTC clock frequency. */
49 #define NRF_802154_SL_RTC_FREQUENCY 32768UL
50
51 /**@brief Defines the number of microseconds in one second. */
52 #define NRF_802154_SL_US_PER_S 1000000ULL
53
54 /**@brief Number of microseconds in one RTC tick (rounded up). */
55 #define NRF_802154_SL_US_PER_TICK NRF_802154_SL_RTC_TICKS_TO_US(1)
56
57 /**@brief Number of bits to shift RTC_FREQUENCY and US_PER_S to achieve the division by greatest common divisor. */
58 #define NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS 6
59
60 /**@brief Ceil division helper. */
61 #define NRF_802154_SL_DIVIDE_AND_CEIL(A, B) (((A) + (B)-1) / (B))
62
63 /**@brief Defines the conversion of RTC ticks to microseconds (us). */
64 #define NRF_802154_SL_RTC_TICKS_TO_US(ticks) \
65 NRF_802154_SL_DIVIDE_AND_CEIL( \
66 (ticks) * (NRF_802154_SL_US_PER_S >> NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS), \
67 (NRF_802154_SL_RTC_FREQUENCY >> NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS))
68
69 /**@brief Converts microseconds (us) to RTC ticks.
70 *
71 * @param time Time is us to be converted to RTC ticks.
72 * @param round_up Round up resulting value, otherwise the result is rounded down.
73 *
74 * @return Time converted to RTC ticks.
75 */
76 uint64_t NRF_802154_SL_US_TO_RTC_TICKS(uint64_t time, bool round_up);
77
78 /**@brief Type holding MCU critical section state.
79 *
80 * Variable of this type is required to hold state saved by @ref nrf_802154_sl_mcu_critical_enter
81 * and restored by @ref nrf_802154_sl_mcu_critical_exit.
82 */
83 typedef uint32_t nrf_802154_sl_mcu_critical_state_t;
84
85 /**@brief Enters critical section on MCU level.
86 *
87 * Use @ref nrf_802154_sl_mcu_critical_exit complementary. Consider following code:
88 * @code
89 * nrf_802154_sl_mcu_critical_state_t mcu_cs;
90 * nrf_802154_sl_mcu_critical_enter(mcu_cs);
91 * // do your critical stuff as fast as possible
92 * nrf_802154_sl_mcu_critical_exit(mcu_cs);
93 * @endcode
94 *
95 * @param mcu_critical_state Variable of @ref nrf_802154_sl_mcu_critical_state_t where current
96 * state of MCU level critical section will be stored.
97 */
98 #define nrf_802154_sl_mcu_critical_enter(mcu_critical_state) \
99 do \
100 { \
101 (mcu_critical_state) = __get_PRIMASK(); \
102 __disable_irq(); \
103 } \
104 while (0)
105
106 /**@brief Exits critical section on MCU level.
107 *
108 * This shall be used complementary to @ref nrf_802154_sl_mcu_critical_enter.
109 *
110 * @param mcu_critical_state Variable of @ref nrf_802154_sl_mcu_critical_state_t where
111 * state of MCU level critical section is stored by
112 * former call to @ref nrf_802154_sl_mcu_critical_enter
113 */
114 #define nrf_802154_sl_mcu_critical_exit(mcu_critical_state) \
115 do \
116 { \
117 __set_PRIMASK(mcu_critical_state); \
118 } \
119 while (0)
120
121 /**
122 * @brief Checks if the given time is in the future.
123 *
124 * The value of @p now is assumed to be based on a 64-bit time source that never overflows.
125 * These assumptions are met, for example, by @ref nrf_802154_sl_timer_current_time_get().
126 *
127 * @param[in] now Current time.
128 * @param[in] t0 The time value to be checked.
129 *
130 * @retval true Given time @p t0 is in future (compared to given @p now).
131 * @retval false Given time @p t0 is not in future (compared to given @p now).
132 */
nrf_802154_sl_time64_is_in_future(uint64_t now,uint64_t t0)133 static inline bool nrf_802154_sl_time64_is_in_future(uint64_t now, uint64_t t0)
134 {
135 return now < t0;
136 }
137
138 #endif // NRF_802154_SL_UTILS_H__
139