Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
LoRaPHYKR920.cpp
00001 /** 00002 * @file LoRaPHYKR920.cpp 00003 * 00004 * @brief Implements LoRaPHY for Korean 920 MHz band 00005 * 00006 * \code 00007 * ______ _ 00008 * / _____) _ | | 00009 * ( (____ _____ ____ _| |_ _____ ____| |__ 00010 * \____ \| ___ | (_ _) ___ |/ ___) _ \ 00011 * _____) ) ____| | | || |_| ____( (___| | | | 00012 * (______/|_____)_|_|_| \__)_____)\____)_| |_| 00013 * (C)2013 Semtech 00014 * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00015 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00016 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00017 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00018 * embedded.connectivity.solutions=============== 00019 * 00020 * \endcode 00021 * 00022 * 00023 * License: Revised BSD License, see LICENSE.TXT file include in the project 00024 * 00025 * Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 00026 * 00027 * Copyright (c) 2017, Arm Limited and affiliates. 00028 * SPDX-License-Identifier: BSD-3-Clause 00029 * 00030 */ 00031 00032 #include "LoRaPHYKR920.h" 00033 #include "lora_phy_ds.h" 00034 00035 00036 /*! 00037 * Number of default channels 00038 */ 00039 #define KR920_NUMB_DEFAULT_CHANNELS 3 00040 00041 /*! 00042 * Number of channels to apply for the CF list 00043 */ 00044 #define KR920_NUMB_CHANNELS_CF_LIST 5 00045 00046 /*! 00047 * Minimal datarate that can be used by the node 00048 */ 00049 #define KR920_TX_MIN_DATARATE DR_0 00050 00051 /*! 00052 * Maximal datarate that can be used by the node 00053 */ 00054 #define KR920_TX_MAX_DATARATE DR_5 00055 00056 /*! 00057 * Minimal datarate that can be used by the node 00058 */ 00059 #define KR920_RX_MIN_DATARATE DR_0 00060 00061 /*! 00062 * Maximal datarate that can be used by the node 00063 */ 00064 #define KR920_RX_MAX_DATARATE DR_5 00065 00066 /*! 00067 * Default datarate used by the node 00068 */ 00069 #define KR920_DEFAULT_DATARATE DR_0 00070 00071 /*! 00072 * Minimal Rx1 receive datarate offset 00073 */ 00074 #define KR920_MIN_RX1_DR_OFFSET 0 00075 00076 /*! 00077 * Maximal Rx1 receive datarate offset 00078 */ 00079 #define KR920_MAX_RX1_DR_OFFSET 5 00080 00081 /*! 00082 * Default Rx1 receive datarate offset 00083 */ 00084 #define KR920_DEFAULT_RX1_DR_OFFSET 0 00085 00086 /*! 00087 * Minimal Tx output power that can be used by the node 00088 */ 00089 #define KR920_MIN_TX_POWER TX_POWER_7 00090 00091 /*! 00092 * Maximal Tx output power that can be used by the node 00093 */ 00094 #define KR920_MAX_TX_POWER TX_POWER_0 00095 00096 /*! 00097 * Default Tx output power used by the node 00098 */ 00099 #define KR920_DEFAULT_TX_POWER TX_POWER_0 00100 00101 /*! 00102 * Default Max EIRP for frequency 920.9 MHz - 921.9 MHz 00103 */ 00104 #define KR920_DEFAULT_MAX_EIRP_LOW 10.0f 00105 00106 /*! 00107 * Default Max EIRP for frequency 922.1 MHz - 923.3 MHz 00108 */ 00109 #define KR920_DEFAULT_MAX_EIRP_HIGH 14.0f 00110 00111 /*! 00112 * Default antenna gain 00113 */ 00114 #define KR920_DEFAULT_ANTENNA_GAIN 2.15f 00115 00116 /*! 00117 * ADR Ack limit 00118 */ 00119 #define KR920_ADR_ACK_LIMIT 64 00120 00121 /*! 00122 * ADR Ack delay 00123 */ 00124 #define KR920_ADR_ACK_DELAY 32 00125 00126 /*! 00127 * Enabled or disabled the duty cycle 00128 */ 00129 #define KR920_DUTY_CYCLE_ENABLED 0 00130 00131 /*! 00132 * Maximum RX window duration 00133 */ 00134 #define KR920_MAX_RX_WINDOW 4000 00135 00136 /*! 00137 * Receive delay 1 00138 */ 00139 #define KR920_RECEIVE_DELAY1 1000 00140 00141 /*! 00142 * Receive delay 2 00143 */ 00144 #define KR920_RECEIVE_DELAY2 2000 00145 00146 /*! 00147 * Join accept delay 1 00148 */ 00149 #define KR920_JOIN_ACCEPT_DELAY1 5000 00150 00151 /*! 00152 * Join accept delay 2 00153 */ 00154 #define KR920_JOIN_ACCEPT_DELAY2 6000 00155 00156 /*! 00157 * Maximum frame counter gap 00158 */ 00159 #define KR920_MAX_FCNT_GAP 16384 00160 00161 /*! 00162 * Ack timeout 00163 */ 00164 #define KR920_ACKTIMEOUT 2000 00165 00166 /*! 00167 * Random ack timeout limits 00168 */ 00169 #define KR920_ACK_TIMEOUT_RND 1000 00170 00171 #if ( KR920_DEFAULT_DATARATE > DR_5 ) 00172 #error "A default DR higher than DR_5 may lead to connectivity loss." 00173 #endif 00174 00175 /*! 00176 * Second reception window channel frequency definition. 00177 */ 00178 #define KR920_RX_WND_2_FREQ 921900000 00179 00180 /*! 00181 * Second reception window channel datarate definition. 00182 */ 00183 #define KR920_RX_WND_2_DR DR_0 00184 00185 /*! 00186 * Band 0 definition 00187 * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } 00188 */ 00189 static const band_t KR920_BAND0 = { 1 , KR920_MAX_TX_POWER, 0, 0, 0 }; // 100.0 % 00190 00191 /*! 00192 * LoRaMac default channel 1 00193 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } 00194 */ 00195 static const channel_params_t KR920_LC1 = { 922100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; 00196 00197 /*! 00198 * LoRaMac default channel 2 00199 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } 00200 */ 00201 static const channel_params_t KR920_LC2 = { 922300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; 00202 00203 /*! 00204 * LoRaMac default channel 3 00205 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } 00206 */ 00207 static const channel_params_t KR920_LC3 = { 922500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; 00208 00209 /*! 00210 * LoRaMac channels which are allowed for the join procedure 00211 */ 00212 #define KR920_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) 00213 00214 /*! 00215 * RSSI threshold for a free channel [dBm] 00216 */ 00217 #define KR920_RSSI_FREE_TH -65 00218 00219 /*! 00220 * Specifies the time the node performs a carrier sense 00221 */ 00222 #define KR920_CARRIER_SENSE_TIME 6 00223 00224 /*! 00225 * Data rates table definition 00226 */ 00227 static const uint8_t datarates_KR920 [] = { 12, 11, 10, 9, 8, 7 }; 00228 00229 /*! 00230 * Bandwidths table definition in Hz 00231 */ 00232 static const uint32_t bandwidths_KR920 [] = { 125000, 125000, 125000, 125000, 125000, 125000 }; 00233 00234 /*! 00235 * Maximum payload with respect to the datarate index. Can operate with and without a repeater. 00236 */ 00237 static const uint8_t max_payloads_KR920 [] = { 51, 51, 51, 115, 242, 242 }; 00238 00239 /*! 00240 * Maximum payload with respect to the datarate index. Can operate with repeater. 00241 */ 00242 static const uint8_t max_payloads_with_repeater_KR920 [] = { 51, 51, 51, 115, 222, 222 }; 00243 00244 LoRaPHYKR920::LoRaPHYKR920() 00245 { 00246 bands[0] = KR920_BAND0 ; 00247 00248 // Channels 00249 channels[0] = KR920_LC1 ; 00250 channels[0].band = 0; 00251 channels[1] = KR920_LC2 ; 00252 channels[1].band = 0; 00253 channels[2] = KR920_LC3 ; 00254 channels[2].band = 0; 00255 00256 // Initialize the channels default mask 00257 default_channel_mask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 00258 // Update the channels mask 00259 copy_channel_mask(channel_mask, default_channel_mask, KR920_CHANNEL_MASK_SIZE); 00260 00261 // set default channels 00262 phy_params.channels.channel_list = channels; 00263 phy_params.channels.channel_list_size = KR920_MAX_NB_CHANNELS; 00264 phy_params.channels.mask = channel_mask; 00265 phy_params.channels.default_mask = default_channel_mask; 00266 phy_params.channels.mask_size = KR920_CHANNEL_MASK_SIZE; 00267 00268 // set bands for KR920 spectrum 00269 phy_params.bands.table = (void *) bands; 00270 phy_params.bands.size = KR920_MAX_NB_BANDS; 00271 00272 // set bandwidths available in KR920 spectrum 00273 phy_params.bandwidths.table = (void *) bandwidths_KR920 ; 00274 phy_params.bandwidths.size = 6; 00275 00276 // set data rates available in KR920 spectrum 00277 phy_params.datarates.table = (void *) datarates_KR920 ; 00278 phy_params.datarates.size = 6; 00279 00280 // set payload sizes with respect to data rates 00281 phy_params.payloads.table = (void *) max_payloads_KR920 ; 00282 phy_params.payloads.size = 6; 00283 phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_KR920 ; 00284 phy_params.payloads_with_repeater.size = 6; 00285 00286 // dwell time setting 00287 phy_params.ul_dwell_time_setting = 0; 00288 phy_params.dl_dwell_time_setting = 0; 00289 00290 // set initial and default parameters 00291 phy_params.duty_cycle_enabled = KR920_DUTY_CYCLE_ENABLED; 00292 phy_params.accept_tx_param_setup_req = false; 00293 phy_params.fsk_supported = false; 00294 phy_params.cflist_supported = true; 00295 phy_params.dl_channel_req_supported = true; 00296 phy_params.custom_channelplans_supported = true; 00297 phy_params.default_channel_cnt = KR920_NUMB_DEFAULT_CHANNELS; 00298 phy_params.max_channel_cnt = KR920_MAX_NB_CHANNELS; 00299 phy_params.cflist_channel_cnt = KR920_NUMB_CHANNELS_CF_LIST; 00300 phy_params.min_tx_datarate = KR920_TX_MIN_DATARATE; 00301 phy_params.max_tx_datarate = KR920_TX_MAX_DATARATE; 00302 phy_params.min_rx_datarate = KR920_RX_MIN_DATARATE; 00303 phy_params.max_rx_datarate = KR920_RX_MAX_DATARATE; 00304 phy_params.default_datarate = KR920_DEFAULT_DATARATE; 00305 phy_params.default_max_datarate = KR920_TX_MAX_DATARATE; 00306 phy_params.min_rx1_dr_offset = KR920_MIN_RX1_DR_OFFSET; 00307 phy_params.max_rx1_dr_offset = KR920_MAX_RX1_DR_OFFSET; 00308 phy_params.default_rx1_dr_offset = KR920_DEFAULT_RX1_DR_OFFSET; 00309 phy_params.min_tx_power = KR920_MIN_TX_POWER; 00310 phy_params.max_tx_power = KR920_MAX_TX_POWER; 00311 phy_params.default_tx_power = KR920_DEFAULT_TX_POWER; 00312 phy_params.default_max_eirp = KR920_DEFAULT_MAX_EIRP_HIGH; 00313 phy_params.default_antenna_gain = KR920_DEFAULT_ANTENNA_GAIN; 00314 phy_params.adr_ack_limit = KR920_ADR_ACK_LIMIT; 00315 phy_params.adr_ack_delay = KR920_ADR_ACK_DELAY; 00316 phy_params.max_rx_window = KR920_MAX_RX_WINDOW; 00317 phy_params.recv_delay1 = KR920_RECEIVE_DELAY1; 00318 phy_params.recv_delay2 = KR920_RECEIVE_DELAY2; 00319 phy_params.join_channel_mask = KR920_JOIN_CHANNELS; 00320 phy_params.join_accept_delay1 = KR920_JOIN_ACCEPT_DELAY1; 00321 phy_params.join_accept_delay2 = KR920_JOIN_ACCEPT_DELAY2; 00322 phy_params.max_fcnt_gap = KR920_MAX_FCNT_GAP; 00323 phy_params.ack_timeout = KR920_ACKTIMEOUT; 00324 phy_params.ack_timeout_rnd = KR920_ACK_TIMEOUT_RND; 00325 phy_params.rx_window2_datarate = KR920_RX_WND_2_DR; 00326 phy_params.rx_window2_frequency = KR920_RX_WND_2_FREQ; 00327 } 00328 00329 LoRaPHYKR920::~LoRaPHYKR920() 00330 { 00331 } 00332 00333 int8_t LoRaPHYKR920::get_max_eirp(uint32_t freq) 00334 { 00335 if (freq >= 922100000) {// Limit to 14dBm 00336 return KR920_DEFAULT_MAX_EIRP_HIGH; 00337 } 00338 00339 // Limit to 10dBm 00340 return KR920_DEFAULT_MAX_EIRP_LOW; 00341 } 00342 00343 00344 bool LoRaPHYKR920::verify_frequency_for_band(uint32_t freq, uint8_t band) const 00345 { 00346 uint32_t tmp_freq = freq; 00347 00348 _radio->lock(); 00349 00350 if (_radio->check_rf_frequency(tmp_freq) == false) { 00351 _radio->unlock(); 00352 return false; 00353 } 00354 00355 _radio->unlock(); 00356 00357 // Verify if the frequency is valid. The frequency must be in a specified 00358 // range and can be set to specific values. 00359 if ((tmp_freq >= 920900000) && (tmp_freq <=923300000)) { 00360 // Range ok, check for specific value 00361 tmp_freq -= 920900000; 00362 if ((tmp_freq % 200000) == 0) { 00363 return true; 00364 } 00365 } 00366 00367 return false; 00368 } 00369 00370 bool LoRaPHYKR920::tx_config(tx_config_params_t* config, int8_t* tx_power, 00371 lorawan_time_t* tx_toa) 00372 { 00373 int8_t phy_dr = datarates_KR920 [config->datarate]; 00374 00375 if (config->tx_power > bands[channels[config->channel].band].max_tx_pwr) { 00376 config->tx_power = bands[channels[config->channel].band].max_tx_pwr; 00377 } 00378 00379 uint32_t bandwidth = get_bandwidth(config->datarate); 00380 float max_eirp = get_max_eirp(channels[config->channel].frequency); 00381 int8_t phy_tx_power = 0; 00382 00383 // Take the minimum between the max_eirp and txConfig->MaxEirp. 00384 // The value of txConfig->MaxEirp could have changed during runtime, e.g. due to a MAC command. 00385 max_eirp = MIN(config->max_eirp, max_eirp); 00386 00387 // Calculate physical TX power 00388 phy_tx_power = compute_tx_power(config->tx_power, max_eirp, config->antenna_gain); 00389 00390 // Setup the radio frequency 00391 _radio->lock(); 00392 00393 _radio->set_channel(channels[config->channel].frequency); 00394 00395 _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, 00396 false, true, 0, 0, false, 3000 ); 00397 00398 // Setup maximum payload lenght of the radio driver 00399 _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); 00400 // Get the time-on-air of the next tx frame 00401 *tx_toa =_radio->time_on_air(MODEM_LORA, config->pkt_len); 00402 00403 _radio->unlock(); 00404 00405 *tx_power = config->tx_power; 00406 return true; 00407 } 00408 00409 lorawan_status_t LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, 00410 uint8_t* channel, lorawan_time_t* time, 00411 lorawan_time_t* aggregate_timeoff) 00412 { 00413 uint8_t next_channel_idx = 0; 00414 uint8_t nb_enabled_channels = 0; 00415 uint8_t delay_tx = 0; 00416 uint8_t enabled_channels[KR920_MAX_NB_CHANNELS] = {0}; 00417 lorawan_time_t nextTxDelay = 0; 00418 00419 if (num_active_channels(channel_mask, 0, 1) == 0) { 00420 // Reactivate default channels 00421 channel_mask[0] |= LC(1) + LC(2) + LC(3); 00422 } 00423 00424 if (params->aggregate_timeoff <= _lora_time->get_elapsed_time(params->last_aggregate_tx_time)) { 00425 // Reset Aggregated time off 00426 *aggregate_timeoff = 0; 00427 00428 // Update bands Time OFF 00429 nextTxDelay = update_band_timeoff(params->joined, params->dc_enabled, 00430 bands, KR920_MAX_NB_BANDS); 00431 00432 // Search how many channels are enabled 00433 nb_enabled_channels = enabled_channel_count(params->current_datarate, 00434 channel_mask, 00435 enabled_channels, &delay_tx); 00436 } else { 00437 delay_tx++; 00438 nextTxDelay = params->aggregate_timeoff - _lora_time->get_elapsed_time(params->last_aggregate_tx_time); 00439 } 00440 00441 if (nb_enabled_channels > 0) { 00442 00443 for (uint8_t i = 0, j = get_random(0, nb_enabled_channels - 1); 00444 i < KR920_MAX_NB_CHANNELS; i++) { 00445 next_channel_idx = enabled_channels[j]; 00446 j = ( j + 1 ) % nb_enabled_channels; 00447 00448 // Perform carrier sense for KR920_CARRIER_SENSE_TIME 00449 // If the channel is free, we can stop the LBT mechanism 00450 _radio->lock(); 00451 00452 if (_radio->perform_carrier_sense(MODEM_LORA, 00453 channels[next_channel_idx].frequency, 00454 KR920_RSSI_FREE_TH, 00455 KR920_CARRIER_SENSE_TIME ) == true) { 00456 // Free channel found 00457 *channel = next_channel_idx; 00458 *time = 0; 00459 _radio->unlock(); 00460 return LORAWAN_STATUS_OK; 00461 } 00462 00463 _radio->unlock(); 00464 } 00465 00466 return LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND; 00467 00468 } else { 00469 00470 if (delay_tx > 0) { 00471 // Delay transmission due to AggregatedTimeOff or to a band time off 00472 *time = nextTxDelay; 00473 return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; 00474 } 00475 00476 // Datarate not supported by any channel, restore defaults 00477 channel_mask[0] |= LC(1) + LC(2) + LC(3); 00478 *time = 0; 00479 return LORAWAN_STATUS_NO_CHANNEL_FOUND; 00480 } 00481 } 00482 00483 void LoRaPHYKR920::set_tx_cont_mode(cw_mode_params_t * params, uint32_t given_frequency) 00484 { 00485 (void)given_frequency; 00486 00487 if (params->tx_power > bands[channels[params->channel ].band].max_tx_pwr) { 00488 params->tx_power = bands[channels[params->channel ].band].max_tx_pwr; 00489 } 00490 00491 float max_eirp = get_max_eirp(channels[params->channel ].frequency); 00492 int8_t phy_tx_power = 0; 00493 uint32_t frequency = channels[params->channel ].frequency; 00494 00495 // Take the minimum between the max_eirp and params->max_eirp. 00496 // The value of params->max_eirp could have changed during runtime, 00497 // e.g. due to a MAC command. 00498 max_eirp = MIN (params->max_eirp , max_eirp); 00499 00500 // Calculate physical TX power 00501 phy_tx_power = compute_tx_power(params->tx_power , max_eirp, params->antenna_gain ); 00502 00503 _radio->lock(); 00504 _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout ); 00505 _radio->unlock(); 00506 } 00507
Generated on Tue Aug 9 2022 00:37:10 by
1.7.2