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 an 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 typedef uint32_t mpsl_subscribable_hw_event_t; 59 60 /** @brief MPSL Front End Module event. */ 61 typedef struct 62 { 63 /** Type of event source. */ 64 mpsl_fem_event_type_t type; 65 /** Implementation of the event. */ 66 union 67 { 68 /** Parameters when type is @ref MPSL_FEM_EVENT_TYPE_TIMER. */ 69 struct 70 { 71 /** Pointer to a 1-us resolution timer instance. */ 72 NRF_TIMER_Type * p_timer_instance; 73 74 /** Counter period parameters */ 75 struct 76 { 77 /** Timer value when the Front End Module can start preparing PA/LNA. */ 78 uint32_t start; 79 /** Timer value at which the PA/LNA have to be prepared. Radio operation shall start at this point. */ 80 uint32_t end; 81 /** Time interval in which the timer should start and end. */ 82 } counter_period; 83 84 /** Mask of the compare channels that can be used by the Front End Module to schedule its own tasks. */ 85 uint8_t compare_channel_mask; 86 /** Event generated by the timer, used in case of type equal to @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_TIMER. */ 87 } timer; 88 89 /** Parameters when type is @ref MPSL_FEM_EVENT_TYPE_GENERIC. */ 90 struct 91 { 92 /** Event triggerring required FEM operation. */ 93 mpsl_subscribable_hw_event_t event; 94 /** Generic event, used in case of type equal to @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_GENERIC. */ 95 } generic; 96 } event; 97 98 #if defined(NRF52_SERIES) 99 /** False to ignore the PPI channel below and use the one set by application. True to use the PPI channel below. */ 100 bool override_ppi; 101 /** PPI channel to be used for this event. */ 102 uint8_t ppi_ch_id; 103 #endif 104 } mpsl_fem_event_t; 105 106 /** TX power, dBm. */ 107 typedef int8_t mpsl_tx_power_t; 108 109 /** 110 * @brief Represents data needed to set the FEM gain. 111 */ 112 typedef struct 113 { 114 int8_t gain_db; // !< Gain in dB. 115 uint8_t private_setting; // !< Setting of the Front-End Module. The interpretation of this field is specific 116 // for a given Front-End Module implementation. 117 } mpsl_fem_gain_t; 118 119 /** @brief Represents components of tx_power to be applied for stages on transmit path. */ 120 typedef struct 121 { 122 /** TX power to be applied to the RADIO peripheral. */ 123 mpsl_tx_power_t radio_tx_power; 124 125 /** Data needed to set the FEM gain. */ 126 mpsl_fem_gain_t fem; 127 } mpsl_tx_power_split_t; 128 129 /** @brief Disable Front End Module. 130 * 131 * Some Front End Module devices can be explicitly disabled after PA and LNA activities are 132 * finished to preserve power. 133 * 134 * This function is intended to disable Front End Module shortly after radio operations are 135 * finished and the protocol does not expect more radio activities in short future, or passes 136 * radio control to other protocols in the system. 137 * 138 * Front End Module disabling process is synchronous and immediate. 139 * 140 * @retval 0 141 * @retval -NRF_EPERM FEM is configured to enable PA or LNA. 142 */ 143 int32_t mpsl_fem_disable(void); 144 145 /** @brief Sets up PA using the provided events for the upcoming radio transmission. 146 * 147 * Multiple configurations can be provided by repeating calls to this function 148 * (that is, you can set the activate and the deactivate events in multiple calls, 149 * and the configuration is preserved between calls). 150 * 151 * The order of calls of this function and its `lna` counterpart must match the 152 * order of radio operations. 153 * I.e. if you want to listen first and then send the frame, you need first to 154 * issue @ref mpsl_fem_lna_configuration_set and only after @ref mpsl_fem_pa_configuration_set. 155 * 156 * If a @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_TIMER timer event is 157 * provided, the PA will be configured to activate or deactivate at the 158 * application-configured time gap before the timer instance reaches the given 159 * register_value. The time gap is set via the corresponding configuration setter 160 * of the selected Front End Module. 161 * 162 * If a @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_GENERIC event is provided, 163 * the PA will be configured to activate or deactivate when an event occurs. 164 * 165 * The function sets up the PPIs and the GPIOTE channel to activate PA for the 166 * upcoming radio transmission. The PA pin will be active until deactivated, 167 * which can happen either by encountering a configured deactivation event or by 168 * using @ref mpsl_fem_deactivate_now. 169 * 170 * @param[in] p_activate_event Pointer to the activation event structure. 171 * @param[in] p_deactivate_event Pointer to the deactivation event structure. 172 * 173 * @pre To activate PA, the corresponding configuration setter of the selected 174 * Front End Module must have been called first. 175 * 176 * @note If a timer event is provided, the caller of this function is responsible 177 * for starting the timer and configuring its shorts. 178 * Moreover, the caller is responsible for stopping the timer no earlier than 179 * the compare channel of the lowest ID among the provided ones does expire. 180 * 181 * @note The activation event can be only of type 182 * @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_TIMER. 183 * Using other activation event type leads to undefined module behavior. 184 * 185 * @retval 0 PA activation setup is successful. 186 * @retval -NRF_EPERM PA is currently disabled. 187 * @retval -NRF_EINVAL PA activation setup could not be performed due to 188 * invalid or missing configuration parameters 189 * in p_activate_event or p_deactivate_event, or both. 190 */ 191 int32_t mpsl_fem_pa_configuration_set(const mpsl_fem_event_t * const p_activate_event, 192 const mpsl_fem_event_t * const p_deactivate_event); 193 194 /** @brief Clears up the configuration provided by the @ref mpsl_fem_pa_configuration_set function. 195 * 196 * @retval 0 PA activation setup purge is successful. 197 * @retval -NRF_EPERM PA is currently disabled. 198 */ 199 int32_t mpsl_fem_pa_configuration_clear(void); 200 201 /** @brief Sets up LNA using the provided event for the upcoming radio reception. 202 * 203 * Multiple configurations can be provided by repeating calls to this function 204 * (that is, you can set the activate and the deactivate event in multiple calls, 205 * and the configuration is preserved between calls). 206 * 207 * The order of calls of this function and its `pa` counterpart must match the 208 * order of radio operations. I.e. if you want to listen first and then send the 209 * frame, you need first to issue @ref mpsl_fem_lna_configuration_set and only 210 * after @ref mpsl_fem_pa_configuration_set. 211 * 212 * If a @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_TIMER timer event is 213 * provided, the LNA will be configured to activate or deactivate at the 214 * application-configured time gap before the timer instance reaches the given 215 * register_value. The time gap is set via the corresponding configuration setter 216 * of the selected Front End Module. 217 * 218 * If a @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_GENERIC event is provided, 219 * the LNA will be configured to activate or deactivate when an event occurs. 220 * 221 * The function sets up the PPIs and the GPIOTE channel to activate LNA for the 222 * upcoming radio transmission. The LNA pin will be active until deactivated, 223 * which can happen either by encountering a configured deactivation event or by 224 * using @ref mpsl_fem_deactivate_now. 225 * 226 * @param[in] p_activate_event Pointer to the activation event structure. 227 * @param[in] p_deactivate_event Pointer to the deactivation event structure. 228 * 229 * @pre To activate LNA, the corresponding configuration setter of the selected 230 * Front End Module must have been called first. 231 * 232 * @note If a timer event is provided, the caller of this function is responsible 233 * for starting the timer and configuring its shorts. 234 * Moreover, the caller is responsible for stopping the timer no earlier than 235 * the compare channel of the lowest ID among the provided ones does expire. 236 * 237 * @note The activation event can be only of type 238 * @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_TIMER. Using other activation 239 * event type leads to undefined module behavior. 240 * 241 * @retval 0 LNA activation setup is successful. 242 * @retval -NRF_EPERM LNA is currently disabled. 243 * @retval -NRF_EINVAL LNA activation setup could not be performed due to 244 * invalid or missing configuration parameters 245 * in p_activate_event or p_deactivate_event, or both. 246 */ 247 int32_t mpsl_fem_lna_configuration_set(const mpsl_fem_event_t * const p_activate_event, 248 const mpsl_fem_event_t * const p_deactivate_event); 249 250 /** @brief Clears up the configuration provided by the @ref mpsl_fem_lna_configuration_set function. 251 * 252 * @retval 0 LNA activate setup purge is successful. 253 * @retval -NRF_EPERM LNA is currently disabled. 254 */ 255 int32_t mpsl_fem_lna_configuration_clear(void); 256 257 /** @brief Deactivates PA/LNA with immediate effect. 258 * 259 * Deactivates PA/LNA with immediate effect - contrary to 260 * @ref mpsl_fem_lna_configuration_clear or @ref mpsl_fem_pa_configuration_clear, 261 * which both just set up the infrastructure for events which shall disable the PA/LNA. 262 * 263 * @param[in] type Whether to deactivate imeediately PA, LNA, or both (see @ref mpsl_fem_functionality_t). 264 */ 265 void mpsl_fem_deactivate_now(mpsl_fem_functionality_t type); 266 267 /** @brief Instruct Front End Module to disable PA and LNA as soon as possible 268 * using the group following the event. 269 * 270 * @param[in] event An event which is triggered when the abort condition occurs. 271 * (See doc for @ref mpsl_subscribable_hw_event_t type.) 272 * @param[in] group (D)PPI Group which shall be disabled when the abort event is triggered. 273 * 274 * @retval 0 Setting of the abort sequence path is successful. 275 * @retval -NRF_EPERM Setting of the abort sequence path could not be performed. 276 */ 277 int32_t mpsl_fem_abort_set(mpsl_subscribable_hw_event_t event, uint32_t group); 278 279 /** @brief Adds one more PPI channel to the PPI Group prepared by the 280 * @ref mpsl_fem_abort_set function. 281 * 282 * @param[in] channel_to_add (D)PPI channel to add to the (D)PPI group. 283 * @param[in] group The said PPI group. 284 * 285 * @retval 0 Setting of the abort sequence path is successful. 286 * @retval -NRF_EPERM Setting of the abort sequence path could not be performed. 287 */ 288 int32_t mpsl_fem_abort_extend(uint32_t channel_to_add, uint32_t group); 289 290 /** @brief Removes one PPI channel from the PPI Group prepared by the 291 * @ref mpsl_fem_abort_set function. 292 * 293 * @param[in] channel_to_remove (D)PPI channel to remove from the (D)PPI group. 294 * @param[in] group The said PPI group. 295 * 296 * @retval 0 Setting of the abort sequence path is successful. 297 * @retval -NRF_EPERM Setting of the abort sequence path could not be performed. 298 */ 299 int32_t mpsl_fem_abort_reduce(uint32_t channel_to_remove, uint32_t group); 300 301 /** @brief Clears up the configuration provided by the @ref mpsl_fem_abort_set 302 * function. 303 * 304 * @retval 0 Clearing of the abort sequence path is successful. 305 * @retval -NRF_EPERM Clearing was not done - the possible reason is that there was nothing to clear. 306 */ 307 int32_t mpsl_fem_abort_clear(void); 308 309 /** @brief Cleans up the configured PA/LNA hardware resources. 310 * 311 * The function resets the hardware that has been set up for the PA/LNA 312 * activation. The PA and LNA module control configuration parameters 313 * are not deleted. 314 * The function is intended to be called after the radio DISABLED signal. 315 */ 316 void mpsl_fem_cleanup(void); 317 318 /** @brief Splits transmit power value into components to be applied on each stage on transmit path. 319 * 320 * @note If the exact value of @p power cannot be achieved, this function attempts to use less 321 * power to not exceed constraint. 322 * 323 * @param[in] power TX power requested for transmission on air. 324 * @param[out] p_tx_power_split Components of tx_power to be applied for stages on transmit path. 325 * If requested @p power is too high, the split will be set to 326 * a value representing maximum achievable power. If the requested 327 * @p power is too low, the split will be set to a value representing 328 * minimum achievable power. 329 */ 330 void mpsl_fem_tx_power_split(const mpsl_tx_power_t power, 331 mpsl_tx_power_split_t *const p_tx_power_split); 332 333 /** @brief Sets PA gain. 334 * 335 * @note The gain set by this function will be applied to radio transmissions 336 * following the call. If the function is called during radio transmission 337 * or during ramp-up for transmission it is unspecified if the gain is applied. 338 * 339 * @param[in] gain Gain in dB to be set. 340 * 341 * @retval 0 Gain has been set successfully. 342 * @retval -NRF_EINVAL Gain could not be set. Provided @p gain is invalid. 343 */ 344 int32_t mpsl_fem_pa_gain_set(const mpsl_fem_gain_t * p_gain); 345 346 /** @brief Checks if the PA signaling is configured and enabled, and gets 347 * the configured gain in dB. 348 * 349 * @param[out] p_gain The configured gain in dB if PA is configured and enabled. 350 * If there is no PA present or the PA does not affect 351 * the signal gain, returns 0 dB. 352 */ 353 void mpsl_fem_pa_is_configured(int8_t * const p_gain); 354 355 /** @brief Prepares the Front End Module to switch to the Power Down state. 356 * 357 * @deprecated This function is deprecated. Use @ref mpsl_fem_disable instead. 358 * 359 * This function makes sure the Front End Module shall be switched off in the 360 * appropriate time, using the hardware timer and its compare channel. 361 * The timer is owned by the protocol and must be started by the protocol. 362 * The timer stops after matching the provided compare channel (the call sets the short). 363 * 364 * @param[in] p_instance Timer instance that is used to schedule the transition to the Power Down state. 365 * @param[in] compare_channel Compare channel to hold a value for the timer. 366 * @param[in] ppi_id ID of the PPI channel used to switch to the Power Down state. 367 * @param[in] event_addr Address of the event which shall trigger the Timer start. 368 * 369 * @retval true Whether the scheduling of the transition was successful. 370 * @retval false Whether the scheduling of the transition was not successful. 371 */ 372 bool mpsl_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, 373 uint32_t compare_channel, 374 uint32_t ppi_id, 375 uint32_t event_addr); 376 377 #endif // MPSL_FEM_PROTOCOL_API_H__ 378 379 /**@} */ 380