1 /* 2 * Copyright (c) 2020 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 */ 6 7 /** 8 * @file mpsl_fem_protocol_api.h 9 * 10 * @defgroup mpsl_fem MPSL Protocol interface for Power Amplifier (PA) and Low Noise Amplifier (LNA). 11 * @ingroup mpsl 12 * 13 * This module provides the interface for the protocols to use PA, LNA, or both 14 * in the radio transmission and the radio reception. Refer to the README.rst 15 * for the details. 16 * 17 * @{ 18 */ 19 20 #ifndef MPSL_FEM_PROTOCOL_API_H__ 21 #define MPSL_FEM_PROTOCOL_API_H__ 22 23 #include <stdint.h> 24 #include <stdbool.h> 25 26 #include <nrf.h> 27 #include "nrf_errno.h" 28 29 /** @brief PA and LNA functionality types. */ 30 typedef enum 31 { 32 MPSL_FEM_PA = 1 << 0, /**< PA Functionality. */ 33 MPSL_FEM_LNA = 1 << 1, /**< LNA Functionality. */ 34 MPSL_FEM_ALL = MPSL_FEM_PA | MPSL_FEM_LNA /**< Both PA and LNA Functionalities. */ 35 } mpsl_fem_functionality_t; 36 37 /** @brief PA and LNA activation event types. */ 38 typedef enum 39 { 40 MPSL_FEM_EVENT_TYPE_TIMER, /**< Timer Event type. */ 41 MPSL_FEM_EVENT_TYPE_GENERIC /**< Generic Event type. */ 42 } mpsl_fem_event_type_t; 43 44 /** @brief Type representing a multiple-subscribable hardware event. 45 * 46 * For nRF52 series this is an address of an event within a peripheral. This 47 * event can be written to @c EEP register of a PPI channel, to make the 48 * PPI channel be driven by the event. For nRF52 series an event can be 49 * published to multiple PPI channels by hardware design, which makes it possible 50 * for multiple tasks to subscribe to it. 51 * 52 * For nRF53 series, this is a number of a DPPI channel which is configured 53 * in such a way that certain event publishes to the DPPI channel and the 54 * DPPI channel is enabled. Ensuring above is responsibility of a user 55 * of the provided API. Multiple tasks can then subscribe to the DPPI channel 56 * (by hardware design), thus indirectly to the event. 57 */ 58 #ifdef PPI_PRESENT 59 typedef uint32_t mpsl_subscribable_hw_event_t; 60 #else 61 typedef uint8_t mpsl_subscribable_hw_event_t; 62 #endif 63 64 /** @brief MPSL Front End Module event. */ 65 typedef struct 66 { 67 /** Type of event source. */ 68 mpsl_fem_event_type_t type; 69 /** Implementation of the event. */ 70 union 71 { 72 /** Parameters when type is @ref MPSL_FEM_EVENT_TYPE_TIMER. */ 73 struct 74 { 75 /** Pointer to a 1-us resolution timer instance. */ 76 NRF_TIMER_Type * p_timer_instance; 77 78 /** Counter period parameters */ 79 struct 80 { 81 /** Timer value when the Front End Module can start preparing PA/LNA. */ 82 uint32_t start; 83 /** Timer value at which the PA/LNA have to be prepared. Radio operation shall start at this point. */ 84 uint32_t end; 85 /** Time interval in which the timer should start and end. */ 86 } counter_period; 87 88 /** Mask of the compare channels that can be used by the Front End Module to schedule its own tasks. */ 89 uint8_t compare_channel_mask; 90 /** Event generated by the timer, used in case of type equal to @ref MPSL_FEM_EVENT_TYPE_TIMER. */ 91 } timer; 92 93 /** Parameters when type is @ref MPSL_FEM_EVENT_TYPE_GENERIC. */ 94 struct 95 { 96 /** Event triggering required FEM operation. */ 97 mpsl_subscribable_hw_event_t event; 98 /** Generic event, used in case of type equal to @ref MPSL_FEM_EVENT_TYPE_GENERIC. */ 99 } generic; 100 } event; 101 102 #if defined(NRF52_SERIES) 103 /** False to ignore the PPI channel below and use the one set by application. True to use the PPI channel below. */ 104 bool override_ppi; 105 /** PPI channel to be used for this event. */ 106 uint8_t ppi_ch_id; 107 #endif 108 } mpsl_fem_event_t; 109 110 /** TX power, dBm. */ 111 typedef int8_t mpsl_tx_power_t; 112 113 /** Type for PA power control to be applied to Front-End Module, depending on its type. 114 * 115 * The meaning of this type is FEM type-specific. 116 */ 117 typedef uint8_t mpsl_fem_pa_power_control_t; 118 119 120 /** @brief Represents components of tx_power to be applied for stages on transmit path. */ 121 typedef struct 122 { 123 /** TX power to be applied to the RADIO peripheral. */ 124 mpsl_tx_power_t radio_tx_power; 125 126 /** FEM PA power control.*/ 127 mpsl_fem_pa_power_control_t fem_pa_power_control; 128 } mpsl_tx_power_split_t; 129 130 /** @brief PA setup is required before starting a transmission. 131 * 132 * This flag applies to @ref mpsl_fem_caps_t::flags. 133 * 134 * If it is set, then @ref mpsl_fem_pa_configuration_set must be called before transmission starts. 135 */ 136 #define MPSL_FEM_CAPS_FLAG_PA_SETUP_REQUIRED (1U << 0) 137 138 /** @brief LNA setup is required before starting a reception. 139 * 140 * This flag applies to @ref mpsl_fem_caps_t::flags. 141 * 142 * If it is set, then @ref mpsl_fem_lna_configuration_set must be called before reception starts. 143 */ 144 #define MPSL_FEM_CAPS_FLAG_LNA_SETUP_REQUIRED (1U << 1) 145 146 /** @brief Structure representing capabilities and characteristics of the FEM in use. */ 147 typedef struct 148 { 149 /** Flags informing about the FEM in use. 150 * 151 * The following flags apply: 152 * @ref MPSL_FEM_CAPS_FLAG_PA_SETUP_REQUIRED, @ref MPSL_FEM_CAPS_FLAG_LNA_SETUP_REQUIRED 153 */ 154 uint32_t flags; 155 } mpsl_fem_caps_t; 156 157 /** @brief Gets the capabilities of the FEM in use. 158 * 159 * @param[out] p_caps Pointer to the capabilities structure to be filled in. 160 */ 161 void mpsl_fem_caps_get(mpsl_fem_caps_t * p_caps); 162 163 /** @brief Enable Front End Module. 164 * 165 * Some Front End Module devices should be explicitly enabled before they can be configured 166 * for radio operation. This function is intended to enable Front End Module shortly before 167 * radio operations are started. 168 * 169 * After the Front End Module performed all it's operations complementary @ref mpsl_fem_disable 170 * function should be called. 171 */ 172 void mpsl_fem_enable(void); 173 174 /** @brief Disable Front End Module. 175 * 176 * Some Front End Module devices can be explicitly disabled after PA and LNA activities are 177 * finished to preserve power. 178 * 179 * This function is intended to disable Front End Module shortly after radio operations are 180 * finished and the protocol does not expect more radio activities in short future, or passes 181 * radio control to other protocols in the system. 182 * 183 * Front End Module disabling process is synchronous and immediate. 184 * 185 * @retval 0 186 * @retval -NRF_EPERM FEM is configured to enable PA or LNA. 187 */ 188 int32_t mpsl_fem_disable(void); 189 190 /** @brief Sets up PA using the provided events for the upcoming radio transmission. 191 * 192 * Multiple configurations can be provided by repeating calls to this function 193 * (that is, you can set the activate and the deactivate events in multiple calls, 194 * and the configuration is preserved between calls). 195 * 196 * The order of calls of this function and its `lna` counterpart must match the 197 * order of radio operations. 198 * I.e. if you want to listen first and then send the frame, you need first to 199 * issue @ref mpsl_fem_lna_configuration_set and only after @ref mpsl_fem_pa_configuration_set. 200 * 201 * If a @ref MPSL_FEM_EVENT_TYPE_TIMER timer event is 202 * provided, the PA will be configured to activate or deactivate at the 203 * application-configured time gap before the timer instance reaches the given 204 * register_value. The time gap is set via the corresponding configuration setter 205 * of the selected Front End Module. 206 * 207 * If a @ref MPSL_FEM_EVENT_TYPE_GENERIC event is provided, 208 * the PA will be configured to activate or deactivate when an event occurs. 209 * 210 * The function sets up the PPIs and the GPIOTE channel to activate PA for the 211 * upcoming radio transmission. The PA pin will be active until deactivated, 212 * which can happen either by encountering a configured deactivation event or by 213 * using @ref mpsl_fem_deactivate_now. 214 * 215 * @param[in] p_activate_event Pointer to the activation event structure. 216 * @param[in] p_deactivate_event Pointer to the deactivation event structure. 217 * 218 * @pre To activate PA, the corresponding configuration setter of the selected 219 * Front End Module must have been called first. 220 * 221 * @note If a timer event is provided, the caller of this function is responsible 222 * for starting the timer and configuring its shorts. 223 * Moreover, the caller is responsible for stopping the timer no earlier than 224 * the compare channel of the lowest ID among the provided ones does expire. 225 * 226 * @note The activation event can be only of type 227 * @ref MPSL_FEM_EVENT_TYPE_TIMER. 228 * Using other activation event type leads to undefined module behavior. 229 * 230 * @retval 0 PA activation setup is successful. 231 * @retval -NRF_EPERM PA is currently disabled. 232 * @retval -NRF_EINVAL PA activation setup could not be performed due to 233 * invalid or missing configuration parameters 234 * in p_activate_event or p_deactivate_event, or both. 235 */ 236 int32_t mpsl_fem_pa_configuration_set(const mpsl_fem_event_t * const p_activate_event, 237 const mpsl_fem_event_t * const p_deactivate_event); 238 239 /** @brief Clears up the configuration provided by the @ref mpsl_fem_pa_configuration_set function. 240 * 241 * @retval 0 PA activation setup purge is successful. 242 * @retval -NRF_EPERM PA is currently disabled. 243 */ 244 int32_t mpsl_fem_pa_configuration_clear(void); 245 246 /** @brief Sets up LNA using the provided event for the upcoming radio reception. 247 * 248 * Multiple configurations can be provided by repeating calls to this function 249 * (that is, you can set the activate and the deactivate event in multiple calls, 250 * and the configuration is preserved between calls). 251 * 252 * The order of calls of this function and its `pa` counterpart must match the 253 * order of radio operations. I.e. if you want to listen first and then send the 254 * frame, you need first to issue @ref mpsl_fem_lna_configuration_set and only 255 * after @ref mpsl_fem_pa_configuration_set. 256 * 257 * If a @ref MPSL_FEM_EVENT_TYPE_TIMER timer event is 258 * provided, the LNA will be configured to activate or deactivate at the 259 * application-configured time gap before the timer instance reaches the given 260 * register_value. The time gap is set via the corresponding configuration setter 261 * of the selected Front End Module. 262 * 263 * If a @ref MPSL_FEM_EVENT_TYPE_GENERIC event is provided, 264 * the LNA will be configured to activate or deactivate when an event occurs. 265 * 266 * The function sets up the PPIs and the GPIOTE channel to activate LNA for the 267 * upcoming radio transmission. The LNA pin will be active until deactivated, 268 * which can happen either by encountering a configured deactivation event or by 269 * using @ref mpsl_fem_deactivate_now. 270 * 271 * @param[in] p_activate_event Pointer to the activation event structure. 272 * @param[in] p_deactivate_event Pointer to the deactivation event structure. 273 * 274 * @pre To activate LNA, the corresponding configuration setter of the selected 275 * Front End Module must have been called first. 276 * 277 * @note If a timer event is provided, the caller of this function is responsible 278 * for starting the timer and configuring its shorts. 279 * Moreover, the caller is responsible for stopping the timer no earlier than 280 * the compare channel of the lowest ID among the provided ones does expire. 281 * 282 * @note The activation event can be only of type 283 * @ref MPSL_FEM_EVENT_TYPE_TIMER. Using other activation 284 * event type leads to undefined module behavior. 285 * 286 * @retval 0 LNA activation setup is successful. 287 * @retval -NRF_EPERM LNA is currently disabled. 288 * @retval -NRF_EINVAL LNA activation setup could not be performed due to 289 * invalid or missing configuration parameters 290 * in p_activate_event or p_deactivate_event, or both. 291 */ 292 int32_t mpsl_fem_lna_configuration_set(const mpsl_fem_event_t * const p_activate_event, 293 const mpsl_fem_event_t * const p_deactivate_event); 294 295 /** @brief Clears up the configuration provided by the @ref mpsl_fem_lna_configuration_set function. 296 * 297 * @retval 0 LNA activate setup purge is successful. 298 * @retval -NRF_EPERM LNA is currently disabled. 299 */ 300 int32_t mpsl_fem_lna_configuration_clear(void); 301 302 /** @brief Deactivates PA/LNA with immediate effect. 303 * 304 * Deactivates PA/LNA with immediate effect - contrary to 305 * @ref mpsl_fem_lna_configuration_clear or @ref mpsl_fem_pa_configuration_clear, 306 * which both just set up the infrastructure for events which shall disable the PA/LNA. 307 * 308 * @param[in] type Whether to deactivate imeediately PA, LNA, or both (see @ref mpsl_fem_functionality_t). 309 */ 310 void mpsl_fem_deactivate_now(mpsl_fem_functionality_t type); 311 312 /** @brief Instruct Front End Module to disable PA and LNA as soon as possible 313 * using the group following the event. 314 * 315 * @param[in] event An event which is triggered when the abort condition occurs. 316 * (See doc for @ref mpsl_subscribable_hw_event_t type.) 317 * @param[in] group (D)PPI Group which shall be disabled when the abort event is triggered. 318 * 319 * @retval 0 Setting of the abort sequence path is successful. 320 * @retval -NRF_EPERM Setting of the abort sequence path could not be performed. 321 */ 322 int32_t mpsl_fem_abort_set(mpsl_subscribable_hw_event_t event, uint32_t group); 323 324 /** @brief Adds one more PPI channel to the PPI Group prepared by the 325 * @ref mpsl_fem_abort_set function. 326 * 327 * @param[in] channel_to_add (D)PPI channel to add to the (D)PPI group. 328 * @param[in] group The said PPI group. 329 * 330 * @retval 0 Setting of the abort sequence path is successful. 331 * @retval -NRF_EPERM Setting of the abort sequence path could not be performed. 332 */ 333 int32_t mpsl_fem_abort_extend(uint32_t channel_to_add, uint32_t group); 334 335 /** @brief Removes one PPI channel from the PPI Group prepared by the 336 * @ref mpsl_fem_abort_set function. 337 * 338 * @param[in] channel_to_remove (D)PPI channel to remove from the (D)PPI group. 339 * @param[in] group The said PPI group. 340 * 341 * @retval 0 Setting of the abort sequence path is successful. 342 * @retval -NRF_EPERM Setting of the abort sequence path could not be performed. 343 */ 344 int32_t mpsl_fem_abort_reduce(uint32_t channel_to_remove, uint32_t group); 345 346 /** @brief Clears up the configuration provided by the @ref mpsl_fem_abort_set 347 * function. 348 * 349 * @retval 0 Clearing of the abort sequence path is successful. 350 * @retval -NRF_EPERM Clearing was not done - the possible reason is that there was nothing to clear. 351 */ 352 int32_t mpsl_fem_abort_clear(void); 353 354 /** @brief Cleans up the configured PA/LNA hardware resources. 355 * 356 * The function resets the hardware that has been set up for the PA/LNA 357 * activation. The PA and LNA module control configuration parameters 358 * are not deleted. 359 * The function is intended to be called after the radio DISABLED signal. 360 */ 361 void mpsl_fem_cleanup(void); 362 363 /** @brief Splits transmit power value into components to be applied on each stage on transmit path. 364 * 365 * @note If the exact value of @p power cannot be achieved, this function attempts to either use 366 * available level lower than the requested level to not exceed constraint, or use the lowest 367 * available level greater than the requested level, depending on @p tx_power_ceiling. 368 * 369 * @param[in] power TX power requested for transmission on air. 370 * @param[out] p_tx_power_split Components of tx_power to be applied for stages on transmit path. 371 * If requested @p power is too high, the split will be set to 372 * a value representing maximum achievable power. If the requested 373 * @p power is too low, the split will be set to a value representing 374 * minimum achievable power. 375 * @param[in] freq_mhz Frequency in MHz to calculate the split for. 376 * @param[in] tx_power_ceiling Flag to get ceiling or floor of requested transmit power level. 377 * 378 * @return The power in dBm that will be achieved if values returned through @p p_tx_power_split 379 * are applied. 380 */ 381 int8_t mpsl_fem_tx_power_split(const mpsl_tx_power_t power, 382 mpsl_tx_power_split_t * const p_tx_power_split, 383 uint16_t freq_mhz, 384 bool tx_power_ceiling); 385 386 /** @brief Sets the PA power control. 387 * 388 * Setting the PA power control informs the FEM implementation how the PA is to be controlled 389 * before the next transmission. 390 * 391 * The PA power control set by this function is to be applied to control signals or 392 * parameters. What signals and parameters are controlled and how does it happen depends on 393 * implementation of given FEM. The meaning of @p pa_power_control parameter is 394 * fully FEM type-dependent. For FEM type-independent protocol implementation please 395 * use the function @ref mpsl_fem_tx_power_split and provide outcome of this function 396 * returned by the parameter @c p_tx_power_split to the call to @ref mpsl_fem_pa_power_control_set. 397 * For applications intended for testing the FEM itself when @ref mpsl_fem_tx_power_split is not used 398 * you must make the @p pa_power_control parameter on your own. 399 * 400 * @note The PA power control set by this function will be applied to radio transmissions 401 * following the call. If the function is called during radio transmission 402 * or during ramp-up for transmission it is unspecified if the control is applied. 403 * 404 * @param[in] pa_power_control PA power control to be applied to the FEM. 405 * 406 * @retval 0 PA power control has been applied successfully. 407 * @retval -NRF_EINVAL PA power control could not be applied. Provided @p pa_power_control is invalid. 408 */ 409 int32_t mpsl_fem_pa_power_control_set(mpsl_fem_pa_power_control_t pa_power_control); 410 411 /** @brief Prepares the Front End Module to switch to the Power Down state. 412 * 413 * @deprecated This function is deprecated. Use @ref mpsl_fem_disable instead. 414 * 415 * This function makes sure the Front End Module shall be switched off in the 416 * appropriate time, using the hardware timer and its compare channel. 417 * The timer is owned by the protocol and must be started by the protocol. 418 * The timer stops after matching the provided compare channel (the call sets the short). 419 * 420 * @param[in] p_instance Timer instance that is used to schedule the transition to the Power Down state. 421 * @param[in] compare_channel Compare channel to hold a value for the timer. 422 * @param[in] ppi_id ID of the PPI channel used to switch to the Power Down state. 423 * @param[in] event_addr Address of the event which shall trigger the Timer start. 424 * 425 * @retval true Whether the scheduling of the transition was successful. 426 * @retval false Whether the scheduling of the transition was not successful. 427 */ 428 bool mpsl_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, 429 uint32_t compare_channel, 430 uint32_t ppi_id, 431 uint32_t event_addr); 432 433 #endif // MPSL_FEM_PROTOCOL_API_H__ 434 435 /**@} */ 436