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 * @brief 802.15.4 antenna diversity module. 37 */ 38 39 #ifndef NRF_802154_SL_ANT_DIV_H 40 #define NRF_802154_SL_ANT_DIV_H 41 42 #include <stdint.h> 43 #include <stdbool.h> 44 45 #include "nrfx.h" 46 47 /** 48 * @brief RSSI measurement results. 49 */ 50 #define NRF_802154_SL_ANT_DIV_RSSI_INVALID INT8_MAX 51 52 /** 53 * @brief Priority of TIMER IRQ. 54 */ 55 #define NRF_802154_SL_ANT_DIV_IRQ_PRIORITY 1 56 57 /** 58 * @brief Recommended value of time in microseconds between consecutive antenna switches. 59 * 60 * When antenna diversity interface operates in @ref NRF_802154_SL_ANT_DIV_MODE_AUTO mode, 61 * the antenna is toggled periodically in order to maximize the chance of receiving a frame 62 * preamble. The time between consecutive antenna toggles is configured through 63 * @ref nrf_802154_sl_ant_div_cfg_set function. The value specified by this macro is the 64 * recommended value of @p toggle_time parameter that should be set if no particular reasons 65 * for a different configuration exist. 66 */ 67 #define NRF_802154_SL_ANT_DIV_DEFAULT_TOGGLE_TIME_US 40 68 69 /** 70 * @brief Mode of the antenna diversity module. 71 * 72 * Possible values: 73 * - @ref NRF_802154_SL_ANT_DIV_MODE_DISABLED, 74 * - @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL, 75 * - @ref NRF_802154_SL_ANT_DIV_MODE_AUTO 76 */ 77 typedef uint8_t nrf_802154_sl_ant_div_mode_t; 78 79 #define NRF_802154_SL_ANT_DIV_MODE_DISABLED 0x00 // !< Antenna diversity is disabled - Antenna will not be controlled by sl_ant_div module. While in this mode, current antenna is unspecified. 80 #define NRF_802154_SL_ANT_DIV_MODE_MANUAL 0x01 // !< Antenna is selected manually 81 #define NRF_802154_SL_ANT_DIV_MODE_AUTO 0x02 // !< Antenna is selected automatically based on RSSI - not supported for transmission. 82 83 /** 84 * @brief Available antennas 85 * 86 * Possible values: 87 * - @ref NRF_802154_SL_ANT_DIV_ANTENNA_1, 88 * - @ref NRF_802154_SL_ANT_DIV_ANTENNA_2, 89 * - @ref NRF_802154_SL_ANT_DIV_ANTENNA_NONE 90 */ 91 typedef uint8_t nrf_802154_sl_ant_div_antenna_t; 92 93 #define NRF_802154_SL_ANT_DIV_ANTENNA_1 0x00 // !< First antenna 94 #define NRF_802154_SL_ANT_DIV_ANTENNA_2 0x01 // !< Second antenna 95 #define NRF_802154_SL_ANT_DIV_ANTENNA_NONE 0x02 // !< Used to indicate that antenna for the last reception was not selected via antenna diversity algorithm. 96 97 /** 98 * @brief Types of operations supported by antenna diversity module. 99 * 100 * Possible values: 101 * - @ref NRF_802154_SL_ANT_DIV_OP_RX, 102 * - @ref NRF_802154_SL_ANT_DIV_OP_TX 103 */ 104 typedef uint8_t nrf_802154_sl_ant_div_op_t; 105 106 #define NRF_802154_SL_ANT_DIV_OP_RX 0x00 // !< RX-related operations 107 #define NRF_802154_SL_ANT_DIV_OP_TX 0x01 // !< TX-related operations 108 109 /** 110 * @brief Configuration of the antenna diversity module. 111 * 112 * The following configuration parameters are to be set before 113 * @ref nrf_802154_sl_ant_div_init is called. 114 */ 115 typedef struct 116 { 117 /** 118 * @brief Pin used for antenna selection. 119 */ 120 uint8_t ant_sel_pin; 121 122 /** 123 * @brief Time in microseconds between antenna switches in @ref NRF_802154_SL_ANT_DIV_MODE_AUTO. 124 */ 125 uint8_t toggle_time; 126 127 /** 128 * @brief PPI channel instance used to connect TIMER event with antenna toggling task. 129 * 130 * Antenna diversity interface claims exclusive access to the provided PPI channel. 131 */ 132 uint8_t ppi_ch; 133 134 /** 135 * @brief GPIOTE channel instance used to toggle antenna when triggered with PPI. 136 * 137 * Antenna diversity interface claims exclusive access to the provided GPIOTE channel. 138 */ 139 uint8_t gpiote_ch; 140 141 /** 142 * @brief Timer instance used to measure time between consecutive antenna toggles. 143 * 144 * Antenna diversity interface claims exclusive access to the provided TIMER peripheral. 145 */ 146 NRF_TIMER_Type * p_timer; 147 } nrf_802154_sl_ant_div_cfg_t; 148 149 /** 150 * @} 151 * @defgroup nrf_802154_ant_div_cfg Antenna diversity configuration 152 * @{ 153 */ 154 155 /** 156 * @brief Configures the antenna diversity interface. 157 * 158 * @note This function must be called before @ref nrf_802154_sl_ant_div_init 159 * and can only be called once. 160 * 161 * @param[in] p_cfg Antenna diversity interface configuration. 162 */ 163 void nrf_802154_sl_ant_div_cfg_set(const nrf_802154_sl_ant_div_cfg_t * p_cfg); 164 165 /** 166 * @brief Gets the antenna diversity interface configuration. 167 * 168 * @param[out] p_cfg Antenna diversity interface configuration. 169 * 170 * @retval true The configuration was retrieved successfully. 171 * @retval false The configuration could not be retrieved. 172 */ 173 bool nrf_802154_sl_ant_div_cfg_get(nrf_802154_sl_ant_div_cfg_t * p_cfg); 174 175 /** 176 * @brief Sets the antenna diversity mode. 177 * 178 * @param[in] op Type of antenna diversity operations the mode should be changed for. 179 * @param[in] mode Antenna diversity mode to be set. 180 * 181 * @retval true Antenna diversity mode set successfully. 182 * @retval false Invalid antenna diversity mode or operation type passed as arguments. 183 */ 184 bool nrf_802154_sl_ant_div_cfg_mode_set(nrf_802154_sl_ant_div_op_t op, 185 nrf_802154_sl_ant_div_mode_t mode); 186 187 /** 188 * @brief Gets the antenna diversity mode. 189 * 190 * @param[in] op Type of antenna diversity operations the mode should be retrieved for. 191 * 192 * @return Current antenna diversity mode. 193 */ 194 nrf_802154_sl_ant_div_mode_t nrf_802154_sl_ant_div_cfg_mode_get(nrf_802154_sl_ant_div_op_t op); 195 196 /** 197 * @brief Selects antenna to be used in @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL mode. 198 * 199 * @note Takes effect only if antenna diversity mode is set to 200 * @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. See @ref nrf_802154_sl_ant_div_mode_set. 201 * 202 * @param[in] op Type of antenna diversity operations the antenna should be changed for. 203 * @param[in] antenna Antenna to be selected. 204 * 205 * @retval true Antenna selected successfully. 206 * @retval false Invalid antenna or operation type passed as arguments. 207 */ 208 bool nrf_802154_sl_ant_div_cfg_antenna_set(nrf_802154_sl_ant_div_op_t op, 209 nrf_802154_sl_ant_div_antenna_t antenna); 210 211 /** 212 * @brief Reads the currently used antenna. 213 * 214 * @note The antenna read by this function is currently used antenna only if antenna diversity 215 * mode is set to @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, currently used antenna 216 * may be different. @sa nrf_802154_sl_ant_div_mode_set 217 * 218 * @param[in] op Type of antenna diversity operations the antenna should be retrieved for. 219 * 220 * @return Currently selected antenna. 221 */ 222 nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_cfg_antenna_get( 223 nrf_802154_sl_ant_div_op_t op); 224 225 /** 226 * @} 227 * @defgroup nrf_802154_ant_div Antenna diversity API 228 * @{ 229 */ 230 231 /** 232 * @brief Initializes antenna diversity module. 233 * 234 * @note Before this function is called, antenna diversity interface must be configured with 235 * @ref nrf_802154_sl_ant_div_cfg_set. 236 * 237 * @retval true Initialization was successful. 238 * @retval false Initialization could not be performed due to unconfigured interface. 239 */ 240 bool nrf_802154_sl_ant_div_init(void); 241 242 /** 243 * @brief Selects an antenna to use. 244 * 245 * This function has no effect if called when antenna diversity module is toggling antenna, i.e.: 246 * - @ref NRF_802154_SL_ANT_DIV_MODE_AUTO is set 247 * - receiver is turned on 248 * - no PPDU is currently being received 249 * 250 * @param[in] antenna Antenna to be used. 251 * 252 * @retval true Antenna switched successfully. 253 * @retval false Invalid antenna passed to the function. 254 */ 255 bool nrf_802154_sl_ant_div_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna); 256 257 /** 258 * @brief Gets currently used antenna. 259 * 260 * @retval NRF_802154_SL_ANT_DIV_ANTENNA_1 If antenna 1 is used. 261 * @retval NRF_802154_SL_ANT_DIV_ANTENNA_2 If antenna 2 is used. 262 * @retval NRF_802154_SL_ANT_DIV_ANTENNA_NONE If the antenna diversity interface is not configured. 263 */ 264 nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_antenna_get(void); 265 266 /** 267 * @brief Gets which antenna was selected as best for the last reception. 268 * 269 * @note In three cases @ref NRF_802154_SL_ANT_DIV_ANTENNA_NONE may be returned: 270 * - No frame was received yet. 271 * - Last frame was received with antenna diversity auto mode disabled. 272 * - RSSI measurements didn't have enough time to finish during last frame reception 273 * and it is unspecified which antenna was selected. 274 * 275 * @return Antenna selected during last successful reception in automatic mode. 276 */ 277 nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_last_rx_best_antenna_get(void); 278 279 /** 280 * @brief Handles TIMER IRQ of the antenna diversity interface. 281 * 282 * This function should be called when the timer instance provided to the antenna diversity 283 * interface reports an interrupt. 284 */ 285 void nrf_802154_sl_ant_div_timer_irq_handle(void); 286 287 /** 288 * @} 289 * @defgroup nrf_802154_ant_div_callout Antenna diversity callouts 290 * @{ 291 */ 292 293 /** 294 * @brief Callout for RSSI measurement. 295 * 296 * RSSI needs to be settled already after enabling RX or switching antenna. 297 * 298 * @note This function must be called from critical section. 299 * 300 * @return Corrected measured RSSI value. 301 */ 302 extern int8_t nrf_802154_sl_ant_div_rssi_measure_get(void); 303 304 /** 305 * @} 306 * @defgroup nrf_802154_ant_div_notification Antenna diversity notifications 307 * @{ 308 */ 309 310 /** 311 * @brief Notification to be called when antenna diversity auto mode is enabled. 312 */ 313 void nrf_802154_sl_ant_div_rx_auto_mode_enable_notify(void); 314 315 /** 316 * @brief Notification to be called when antenna diversity auto mode is disabled. 317 */ 318 void nrf_802154_sl_ant_div_rx_auto_mode_disable_notify(void); 319 320 /** 321 * @brief Notification to be called when radio rx is started. 322 */ 323 void nrf_802154_sl_ant_div_rx_started_notify(void); 324 325 /** 326 * @brief Notification to be called when radio rx is aborted. 327 */ 328 void nrf_802154_sl_ant_div_rx_aborted_notify(void); 329 330 /** 331 * @brief Notification to be called when preamble is detected. 332 */ 333 void nrf_802154_sl_ant_div_rx_preamble_detected_notify(void); 334 335 /** 336 * @brief Notification to be called when frame start is detected during reception. 337 * 338 * @retval true RSSI measurements have finished and currently selected antenna is optimal for reception. 339 * @retval false RSSI measurements have not yet finished and currently selected antenna is random. 340 */ 341 bool nrf_802154_sl_ant_div_rx_frame_started_notify(void); 342 343 /** 344 * @brief Notification to be called when frame is received successfully. 345 */ 346 void nrf_802154_sl_ant_div_rx_frame_received_notify(void); 347 348 /** 349 * @brief Notification to be called when timeout expires after preamble detection. 350 */ 351 void nrf_802154_sl_ant_div_rx_preamble_timeout_notify(void); 352 353 /** 354 * @brief Notification to be called when energy detection procedure is requested. 355 * 356 * This notification will update the antenna and inform the caller for how long the energy 357 * detection operation should be scheduled. This notification should also be called 358 * after @ref nrf_802154_sl_ant_div_energy_detection_finished_notify requests repeating 359 * the energy detection procedure. In that case, p_ed_time value must be set to 0 360 * when passed to the function. 361 * 362 * @param[inout] p_ed_time Time of the energy detection procedure requested. Value will be updated with time for 363 * energy detection procedure on the current antenna. 364 */ 365 void nrf_802154_sl_ant_div_energy_detection_requested_notify(uint32_t * p_ed_time); 366 367 /** 368 * @brief Notification to be called when energy detection procedure is finished. 369 * This notification checks whether the procedure should be repeated on the second antenna. 370 * 371 * @retval true Energy detection should be repeated, antenna diversity module will switch the antenna when it is started. 372 * @retval false Energy detection is finished, the result can be reported as normally. 373 */ 374 bool nrf_802154_sl_ant_div_energy_detection_finished_notify(void); 375 376 /** 377 * @brief Notification to be called when energy detection procedure is aborted. 378 */ 379 void nrf_802154_sl_ant_div_energy_detection_aborted_notify(void); 380 381 /** 382 * @brief Notification to be called when txack operation is requested. 383 */ 384 void nrf_802154_sl_ant_div_txack_notify(void); 385 386 #endif // NRF_802154_SL_ANT_DIV_H 387