Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rf_configuration.c Source File

rf_configuration.c

00001 /*
00002  * Copyright (c) 2018 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #if defined(MBED_CONF_NANOSTACK_CONFIGURATION) && DEVICE_SPI && DEVICE_INTERRUPTIN && defined(MBED_CONF_RTOS_PRESENT)
00018 
00019 #include "nanostack/platform/arm_hal_phy.h"
00020 #include "rf_configuration.h"
00021 
00022 
00023 // Note that F_XO and F_DIG depends on the used clock frequency
00024 #define F_XO    50000000
00025 #define F_DIG   25000000
00026 // Note that reference divider depends on REFDIV field in XO_RCO_CONF0 register
00027 #define REF_DIVIDER     1
00028 // Note that band selector depends on BS field in SYNT3 register
00029 #define BAND_SELECTOR   4
00030 #define DEF_2EXP33  8589934592
00031 #define DEF_2EXP20  1048576
00032 #define DEF_2EXP19  524288
00033 #define DEF_2EXP16  65536
00034 #define DEF_2EXP15  32768
00035 // Use multiplier for better resolution
00036 #define RESOLUTION_MULTIPLIER   1000000
00037 
00038 // RSSI_TH is a 8-bit register which can be converted to dBm using formula RSSI_TH-146
00039 #define MIN_RSSI_THRESHOLD  -146
00040 #define MAX_RSSI_THRESHOLD  109
00041 
00042 void rf_conf_calculate_datarate_registers(uint32_t datarate, uint16_t *datarate_mantissa, uint8_t *datarate_exponent)
00043 {
00044     uint64_t datarate_m = (uint64_t)datarate * DEF_2EXP33;
00045     uint8_t datarate_e = 1;
00046     while (datarate_m >= DEF_2EXP16) {
00047         datarate_e++;
00048         uint16_t var_2exp_datarate_e = (uint32_t)2 << (datarate_e - 1);
00049         datarate_m = (uint64_t)datarate * DEF_2EXP33;
00050         datarate_m = datarate_m / ((uint64_t)var_2exp_datarate_e * F_DIG);
00051         datarate_m -= DEF_2EXP16;
00052     }
00053     *datarate_mantissa = datarate_m;
00054     *datarate_exponent = datarate_e;
00055 }
00056 
00057 void rf_conf_calculate_base_frequency_registers(uint32_t frequency, uint8_t *synt3, uint8_t *synt2, uint8_t *synt1, uint8_t *synt0)
00058 {
00059     uint64_t freq_tmp = (uint64_t)frequency * RESOLUTION_MULTIPLIER;
00060     freq_tmp = (freq_tmp / (F_XO / ((BAND_SELECTOR / 2) * REF_DIVIDER)));
00061     freq_tmp *= DEF_2EXP20;
00062     freq_tmp /= RESOLUTION_MULTIPLIER;
00063     *synt3 = (uint8_t)(freq_tmp >> 24);
00064     *synt2 = (uint8_t)(freq_tmp >> 16);
00065     *synt1 = (uint8_t)(freq_tmp >> 8);
00066     *synt0 = (uint8_t)freq_tmp;
00067 }
00068 
00069 void rf_conf_calculate_deviation_registers(uint32_t deviation, uint8_t *fdev_m, uint8_t *fdev_e)
00070 {
00071     uint64_t fdev_m_tmp = 0xffff;
00072     uint8_t fdev_e_tmp = 1;
00073 
00074     while (fdev_m_tmp > 255) {
00075         fdev_e_tmp++;
00076         uint16_t var_2exp_datarate_e_minus_1 = (uint16_t)2 << ((fdev_e_tmp - 1) - 1);
00077         fdev_m_tmp = (uint64_t)deviation * RESOLUTION_MULTIPLIER;
00078         fdev_m_tmp = (((fdev_m_tmp / F_XO) * DEF_2EXP19 * BAND_SELECTOR * REF_DIVIDER * (8 / BAND_SELECTOR)) / var_2exp_datarate_e_minus_1);
00079         fdev_m_tmp += RESOLUTION_MULTIPLIER / 2;
00080         fdev_m_tmp /= RESOLUTION_MULTIPLIER;
00081         fdev_m_tmp -= 256;
00082     }
00083     *fdev_m = (uint8_t)fdev_m_tmp;
00084     *fdev_e = fdev_e_tmp;
00085 }
00086 
00087 int rf_conf_calculate_channel_spacing_registers(uint32_t channel_spacing, uint8_t *ch_space)
00088 {
00089     uint64_t ch_space_tmp = (uint64_t)channel_spacing * RESOLUTION_MULTIPLIER;
00090     ch_space_tmp /= F_XO;
00091     ch_space_tmp *= DEF_2EXP15;
00092     ch_space_tmp += RESOLUTION_MULTIPLIER / 2;
00093     ch_space_tmp /= RESOLUTION_MULTIPLIER;
00094     // Check if channel spacing is too high
00095     if (ch_space_tmp > 255) {
00096         return -1;
00097     }
00098     *ch_space = (uint8_t)ch_space_tmp;
00099     return 0;
00100 }
00101 
00102 /* Note: This function doesn't necessarily give the optimal RX filter settings.
00103  * When accurate chflt_m and chflt_e settings are needed they must be computed manually.
00104  * Function uses undefined values (900000, 852000, ...)
00105  * to find the chflt_m and chflt_e settings from the RX filter table (see. S2-LP datasheet).
00106  *
00107  *         E=0    E=1    E=2    E=3    E=4    E=5    E=6    E=7    E=8    E=9
00108  *  M=0  800.1  450.9  224.7  112.3   56.1   28.0   14.0    7.0    3.5    1.8
00109  *  M=1  795.1  425.9  212.4  106.2   53.0   26.5   13.3    6.6    3.3    1.7
00110  *  M=2  768.4  403.2  201.1  100.5   50.2   25.1   12.6    6.3    3.1    1.6
00111  *  M=3  736.8  380.8  190.0   95.0   47.4   23.7   11.9    5.9    3.0    1.5
00112  *  M=4  705.1  362.1  180.7   90.3   45.1   22.6   11.3    5.6    2.8    1.4
00113  *  M=5  670.9  341.7  170.6   85.3   42.6   21.3   10.6    5.3    2.7    1.3
00114  *  M=6  642.3  325.4  162.4   81.2   40.6   20.3   10.1    5.1    2.5    1.3
00115  *  M=7  586.7  294.5  147.1   73.5   36.7   18.4    9.2    4.6    2.3    1.2
00116  *  M=8  541.4  270.3  135.0   67.5   33.7   16.9    8.4    4.2    2.1    1.1
00117  */
00118 void rf_conf_calculate_rx_filter_bandwidth_registers(uint32_t rx_bandwidth, uint8_t *chflt_m, uint8_t *chflt_e)
00119 {
00120     uint8_t chflt_e_tmp = 0;
00121     uint8_t chflt_m_tmp = 0;
00122 
00123     while (rx_bandwidth < 900000u / (2 << chflt_e_tmp)) {
00124         chflt_e_tmp++;
00125     }
00126     uint32_t rx_bandwidth_tmp = rx_bandwidth;
00127     if (chflt_e_tmp > 0) {
00128         rx_bandwidth_tmp = rx_bandwidth * (2 << (chflt_e_tmp - 1));
00129     }
00130     if (852000 > rx_bandwidth_tmp) {
00131         chflt_m_tmp++;
00132     }
00133     if (806000 > rx_bandwidth_tmp) {
00134         chflt_m_tmp++;
00135     }
00136     if (760000 > rx_bandwidth_tmp) {
00137         chflt_m_tmp++;
00138     }
00139     if (724000 > rx_bandwidth_tmp) {
00140         chflt_m_tmp++;
00141     }
00142     if (682000 > rx_bandwidth_tmp) {
00143         chflt_m_tmp++;
00144     }
00145     if (650000 > rx_bandwidth_tmp) {
00146         chflt_m_tmp++;
00147     }
00148     if (588000 > rx_bandwidth_tmp) {
00149         chflt_m_tmp++;
00150     }
00151     if (542000 > rx_bandwidth_tmp) {
00152         chflt_m_tmp++;
00153     }
00154     *chflt_m = chflt_m_tmp;
00155     *chflt_e = chflt_e_tmp;
00156 }
00157 
00158 int16_t rf_conf_cca_threshold_percent_to_rssi(uint8_t percent)
00159 {
00160     uint8_t step = (MAX_RSSI_THRESHOLD-MIN_RSSI_THRESHOLD);
00161     return MIN_RSSI_THRESHOLD + (step * percent) / 100;
00162 }
00163 
00164 void rf_conf_calculate_rssi_threshold_registers(int16_t rssi_threshold, uint8_t *rssi_th)
00165 {
00166     *rssi_th = rssi_threshold + RSSI_OFFSET;
00167 }
00168 
00169 /*
00170  * Function calculates deviation from given parameters for 2FSK and 2GFSK modulations.
00171  * Calculated using formula Deviation=(modulation_index*datarate)/2
00172  */
00173 uint32_t rf_conf_calculate_deviation(phy_modulation_index_e modulation_index, uint32_t datarate)
00174 {
00175     uint32_t deviation = 0;
00176     if (modulation_index == MODULATION_INDEX_0_5) {
00177         deviation = datarate / 4;
00178     } else if (modulation_index == MODULATION_INDEX_1_0) {
00179         deviation = datarate / 2;
00180     }
00181     return deviation;
00182 }
00183 
00184 #endif // MBED_CONF_NANOSTACK_CONFIGURATION && DEVICE_SPI && DEVICE_INTERRUPTIN && defined(MBED_CONF_RTOS_PRESENT)
00185