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 #include <nrfx.h>
36 #include "nrf_errno.h"
37 #include <stdbool.h>
38 #include <stdint.h>
39
40 #include "nrf_802154_fal.h"
41 #include "nrf_802154_types.h"
42
43 #include "protocol/mpsl_fem_protocol_api.h"
44
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49 /**@brief Macro to get the number of elements in an array.
50 *
51 * @param[in] X Array.
52 */
53 #define NUMELTS(X) (sizeof((X)) / sizeof(X[0]))
54
55 /**
56 * Converts TX power integer values to RADIO TX power allowed values.
57 *
58 * @param[in] integer_tx_power TX power integer value.
59 *
60 * @retval RADIO TX power allowed value.
61 */
to_radio_tx_power_convert(int8_t integer_tx_power)62 static nrf_radio_txpower_t to_radio_tx_power_convert(int8_t integer_tx_power)
63 {
64 static const nrf_radio_txpower_t allowed_values[] =
65 {
66 #if defined(RADIO_TXPOWER_TXPOWER_Neg40dBm)
67 NRF_RADIO_TXPOWER_NEG40DBM, /**< -40 dBm. */
68 #endif
69 NRF_RADIO_TXPOWER_NEG20DBM, /**< -20 dBm. */
70 NRF_RADIO_TXPOWER_NEG16DBM, /**< -16 dBm. */
71 NRF_RADIO_TXPOWER_NEG12DBM, /**< -12 dBm. */
72 NRF_RADIO_TXPOWER_NEG8DBM, /**< -8 dBm. */
73 NRF_RADIO_TXPOWER_NEG4DBM, /**< -4 dBm. */
74 NRF_RADIO_TXPOWER_0DBM, /**< 0 dBm. */
75 #if defined(RADIO_TXPOWER_TXPOWER_Pos2dBm)
76 NRF_RADIO_TXPOWER_POS2DBM, /**< 2 dBm. */
77 #endif
78 #if defined(RADIO_TXPOWER_TXPOWER_Pos3dBm)
79 NRF_RADIO_TXPOWER_POS3DBM, /**< 3 dBm. */
80 #endif
81 #if defined(RADIO_TXPOWER_TXPOWER_Pos4dBm)
82 NRF_RADIO_TXPOWER_POS4DBM, /**< 4 dBm. */
83 #endif
84 #if defined(RADIO_TXPOWER_TXPOWER_Pos5dBm)
85 NRF_RADIO_TXPOWER_POS5DBM, /**< 5 dBm. */
86 #endif
87 #if defined(RADIO_TXPOWER_TXPOWER_Pos6dBm)
88 NRF_RADIO_TXPOWER_POS6DBM, /**< 6 dBm. */
89 #endif
90 #if defined(RADIO_TXPOWER_TXPOWER_Pos7dBm)
91 NRF_RADIO_TXPOWER_POS7DBM, /**< 7 dBm. */
92 #endif
93 #if defined(RADIO_TXPOWER_TXPOWER_Pos8dBm)
94 NRF_RADIO_TXPOWER_POS8DBM, /**< 8 dBm. */
95 #endif
96 };
97
98 for (uint32_t i = NUMELTS(allowed_values) - 1; i > 0; i--)
99 {
100 if (integer_tx_power >= (int8_t)allowed_values[i])
101 {
102 return allowed_values[i];
103 }
104 }
105
106 return allowed_values[0];
107 }
108
mpsl_fem_disable(void)109 int32_t mpsl_fem_disable(void)
110 {
111 return 0;
112 }
113
mpsl_fem_pa_configuration_set(const mpsl_fem_event_t * const p_activate_event,const mpsl_fem_event_t * const p_deactivate_event)114 int32_t mpsl_fem_pa_configuration_set(const mpsl_fem_event_t * const p_activate_event,
115 const mpsl_fem_event_t * const p_deactivate_event)
116 {
117 (void)p_activate_event;
118 (void)p_deactivate_event;
119
120 return -NRF_EPERM;
121 }
122
mpsl_fem_pa_configuration_clear(void)123 int32_t mpsl_fem_pa_configuration_clear(void)
124 {
125 return -NRF_EPERM;
126 }
127
mpsl_fem_lna_configuration_set(const mpsl_fem_event_t * const p_activate_event,const mpsl_fem_event_t * const p_deactivate_event)128 int32_t mpsl_fem_lna_configuration_set(const mpsl_fem_event_t * const p_activate_event,
129 const mpsl_fem_event_t * const p_deactivate_event)
130 {
131 (void)p_activate_event;
132 (void)p_deactivate_event;
133
134 return -NRF_EPERM;
135 }
136
mpsl_fem_lna_configuration_clear(void)137 int32_t mpsl_fem_lna_configuration_clear(void)
138 {
139 return -NRF_EPERM;
140 }
141
mpsl_fem_deactivate_now(mpsl_fem_functionality_t type)142 void mpsl_fem_deactivate_now(mpsl_fem_functionality_t type)
143 {
144 (void)type;
145 }
146
mpsl_fem_abort_set(uint32_t event,uint32_t group)147 int32_t mpsl_fem_abort_set(uint32_t event, uint32_t group)
148 {
149 return -NRF_EPERM;
150 }
151
mpsl_fem_abort_extend(uint32_t channel_to_add,uint32_t group)152 int32_t mpsl_fem_abort_extend(uint32_t channel_to_add, uint32_t group)
153 {
154 (void)channel_to_add;
155 (void)group;
156 return 0;
157 }
158
mpsl_fem_abort_reduce(uint32_t channel_to_remove,uint32_t group)159 int32_t mpsl_fem_abort_reduce(uint32_t channel_to_remove, uint32_t group)
160 {
161 (void)channel_to_remove;
162 (void)group;
163 return 0;
164 }
165
mpsl_fem_abort_clear(void)166 int32_t mpsl_fem_abort_clear(void)
167 {
168 return -NRF_EPERM;
169 }
170
mpsl_fem_cleanup(void)171 void mpsl_fem_cleanup(void)
172 {
173 // Intentionally empty
174 }
175
mpsl_fem_tx_power_split(const mpsl_tx_power_t power,mpsl_tx_power_split_t * const p_tx_power_split)176 void mpsl_fem_tx_power_split(const mpsl_tx_power_t power,
177 mpsl_tx_power_split_t * const p_tx_power_split)
178 {
179 p_tx_power_split->radio_tx_power = to_radio_tx_power_convert(power);
180 p_tx_power_split->fem.gain_db = 0;
181 p_tx_power_split->fem.private_setting = 0;
182 }
183
mpsl_fem_pa_gain_set(const mpsl_fem_gain_t * p_gain)184 int32_t mpsl_fem_pa_gain_set(const mpsl_fem_gain_t * p_gain)
185 {
186 (void)p_gain;
187
188 return 0;
189 }
190
mpsl_fem_pa_is_configured(int8_t * const p_gain)191 void mpsl_fem_pa_is_configured(int8_t * const p_gain)
192 {
193 (void)p_gain;
194 }
195
mpsl_fem_prepare_powerdown(NRF_TIMER_Type * p_instance,uint32_t compare_channel,uint32_t ppi_id,uint32_t event_addr)196 bool mpsl_fem_prepare_powerdown(NRF_TIMER_Type * p_instance,
197 uint32_t compare_channel,
198 uint32_t ppi_id,
199 uint32_t event_addr)
200 {
201 (void)p_instance;
202 (void)compare_channel;
203 (void)ppi_id;
204
205 return false;
206 }
207
mpsl_fem_device_config_254_apply_get(void)208 bool mpsl_fem_device_config_254_apply_get(void)
209 {
210 return false;
211 }
212
nrf_802154_fal_tx_power_split(const uint8_t channel,const int8_t power,nrf_802154_fal_tx_power_split_t * const p_tx_power_split)213 int8_t nrf_802154_fal_tx_power_split(const uint8_t channel,
214 const int8_t power,
215 nrf_802154_fal_tx_power_split_t * const p_tx_power_split)
216 {
217 (void)channel;
218
219 p_tx_power_split->radio_tx_power = to_radio_tx_power_convert(power);
220 p_tx_power_split->fem.gain_db = 0;
221 p_tx_power_split->fem.private_setting = 0;
222
223 return p_tx_power_split->radio_tx_power;
224 }
225
226 #ifdef __cplusplus
227 }
228 #endif
229