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(LoRaWANTimeHandler &lora_time) 00245 : LoRaPHY(lora_time) 00246 { 00247 bands[0] = KR920_BAND0 ; 00248 00249 // Channels 00250 channels[0] = KR920_LC1 ; 00251 channels[1] = KR920_LC2 ; 00252 channels[2] = KR920_LC3 ; 00253 00254 // Initialize the channels default mask 00255 default_channel_mask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); 00256 // Update the channels mask 00257 copy_channel_mask(channel_mask, default_channel_mask, KR920_CHANNEL_MASK_SIZE); 00258 00259 // set default channels 00260 phy_params.channels.channel_list = channels; 00261 phy_params.channels.channel_list_size = KR920_MAX_NB_CHANNELS; 00262 phy_params.channels.mask = channel_mask; 00263 phy_params.channels.default_mask = default_channel_mask; 00264 phy_params.channels.mask_size = KR920_CHANNEL_MASK_SIZE; 00265 00266 // set bands for KR920 spectrum 00267 phy_params.bands.table = (void *) bands; 00268 phy_params.bands.size = KR920_MAX_NB_BANDS; 00269 00270 // set bandwidths available in KR920 spectrum 00271 phy_params.bandwidths.table = (void *) bandwidths_KR920 ; 00272 phy_params.bandwidths.size = 6; 00273 00274 // set data rates available in KR920 spectrum 00275 phy_params.datarates.table = (void *) datarates_KR920 ; 00276 phy_params.datarates.size = 6; 00277 00278 // set payload sizes with respect to data rates 00279 phy_params.payloads.table = (void *) max_payloads_KR920 ; 00280 phy_params.payloads.size = 6; 00281 phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_KR920 ; 00282 phy_params.payloads_with_repeater.size = 6; 00283 00284 // dwell time setting 00285 phy_params.ul_dwell_time_setting = 0; 00286 phy_params.dl_dwell_time_setting = 0; 00287 00288 // set initial and default parameters 00289 phy_params.duty_cycle_enabled = KR920_DUTY_CYCLE_ENABLED; 00290 phy_params.accept_tx_param_setup_req = false; 00291 phy_params.fsk_supported = false; 00292 phy_params.cflist_supported = true; 00293 phy_params.dl_channel_req_supported = true; 00294 phy_params.custom_channelplans_supported = true; 00295 phy_params.default_channel_cnt = KR920_NUMB_DEFAULT_CHANNELS; 00296 phy_params.max_channel_cnt = KR920_MAX_NB_CHANNELS; 00297 phy_params.cflist_channel_cnt = KR920_NUMB_CHANNELS_CF_LIST; 00298 phy_params.min_tx_datarate = KR920_TX_MIN_DATARATE; 00299 phy_params.max_tx_datarate = KR920_TX_MAX_DATARATE; 00300 phy_params.min_rx_datarate = KR920_RX_MIN_DATARATE; 00301 phy_params.max_rx_datarate = KR920_RX_MAX_DATARATE; 00302 phy_params.default_datarate = KR920_DEFAULT_DATARATE; 00303 phy_params.default_max_datarate = KR920_TX_MAX_DATARATE; 00304 phy_params.min_rx1_dr_offset = KR920_MIN_RX1_DR_OFFSET; 00305 phy_params.max_rx1_dr_offset = KR920_MAX_RX1_DR_OFFSET; 00306 phy_params.default_rx1_dr_offset = KR920_DEFAULT_RX1_DR_OFFSET; 00307 phy_params.min_tx_power = KR920_MIN_TX_POWER; 00308 phy_params.max_tx_power = KR920_MAX_TX_POWER; 00309 phy_params.default_tx_power = KR920_DEFAULT_TX_POWER; 00310 phy_params.default_max_eirp = KR920_DEFAULT_MAX_EIRP_HIGH; 00311 phy_params.default_antenna_gain = KR920_DEFAULT_ANTENNA_GAIN; 00312 phy_params.adr_ack_limit = KR920_ADR_ACK_LIMIT; 00313 phy_params.adr_ack_delay = KR920_ADR_ACK_DELAY; 00314 phy_params.max_rx_window = KR920_MAX_RX_WINDOW; 00315 phy_params.recv_delay1 = KR920_RECEIVE_DELAY1; 00316 phy_params.recv_delay2 = KR920_RECEIVE_DELAY2; 00317 phy_params.join_channel_mask = KR920_JOIN_CHANNELS; 00318 phy_params.join_accept_delay1 = KR920_JOIN_ACCEPT_DELAY1; 00319 phy_params.join_accept_delay2 = KR920_JOIN_ACCEPT_DELAY2; 00320 phy_params.max_fcnt_gap = KR920_MAX_FCNT_GAP; 00321 phy_params.ack_timeout = KR920_ACKTIMEOUT; 00322 phy_params.ack_timeout_rnd = KR920_ACK_TIMEOUT_RND; 00323 phy_params.rx_window2_datarate = KR920_RX_WND_2_DR; 00324 phy_params.rx_window2_frequency = KR920_RX_WND_2_FREQ; 00325 } 00326 00327 LoRaPHYKR920::~LoRaPHYKR920() 00328 { 00329 } 00330 00331 int8_t LoRaPHYKR920::get_max_eirp(uint32_t freq) 00332 { 00333 if (freq >= 922100000) {// Limit to 14dBm 00334 return KR920_DEFAULT_MAX_EIRP_HIGH; 00335 } 00336 00337 // Limit to 10dBm 00338 return KR920_DEFAULT_MAX_EIRP_LOW; 00339 } 00340 00341 00342 bool LoRaPHYKR920::verify_frequency(uint32_t freq) 00343 { 00344 uint32_t tmp_freq = freq; 00345 00346 _radio->lock(); 00347 00348 if (_radio->check_rf_frequency(tmp_freq) == false) { 00349 _radio->unlock(); 00350 return false; 00351 } 00352 00353 _radio->unlock(); 00354 00355 // Verify if the frequency is valid. The frequency must be in a specified 00356 // range and can be set to specific values. 00357 if ((tmp_freq >= 920900000) && (tmp_freq <=923300000)) { 00358 // Range ok, check for specific value 00359 tmp_freq -= 920900000; 00360 if ((tmp_freq % 200000) == 0) { 00361 return true; 00362 } 00363 } 00364 00365 return false; 00366 } 00367 00368 bool LoRaPHYKR920::tx_config(tx_config_params_t* config, int8_t* tx_power, 00369 lorawan_time_t* tx_toa) 00370 { 00371 int8_t phy_dr = datarates_KR920 [config->datarate]; 00372 00373 if (config->tx_power > bands[channels[config->channel].band].max_tx_pwr) { 00374 config->tx_power = bands[channels[config->channel].band].max_tx_pwr; 00375 } 00376 00377 uint32_t bandwidth = get_bandwidth(config->datarate); 00378 float max_eirp = get_max_eirp(channels[config->channel].frequency); 00379 int8_t phy_tx_power = 0; 00380 00381 // Take the minimum between the max_eirp and txConfig->MaxEirp. 00382 // The value of txConfig->MaxEirp could have changed during runtime, e.g. due to a MAC command. 00383 max_eirp = MIN(config->max_eirp, max_eirp); 00384 00385 // Calculate physical TX power 00386 phy_tx_power = compute_tx_power(config->tx_power, max_eirp, config->antenna_gain); 00387 00388 // Setup the radio frequency 00389 _radio->lock(); 00390 00391 _radio->set_channel(channels[config->channel].frequency); 00392 00393 _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, 00394 false, true, 0, 0, false, 3000 ); 00395 00396 // Setup maximum payload lenght of the radio driver 00397 _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); 00398 // Get the time-on-air of the next tx frame 00399 *tx_toa =_radio->time_on_air(MODEM_LORA, config->pkt_len); 00400 00401 _radio->unlock(); 00402 00403 *tx_power = config->tx_power; 00404 return true; 00405 } 00406 00407 lorawan_status_t LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, 00408 uint8_t* channel, lorawan_time_t* time, 00409 lorawan_time_t* aggregate_timeoff) 00410 { 00411 uint8_t next_channel_idx = 0; 00412 uint8_t nb_enabled_channels = 0; 00413 uint8_t delay_tx = 0; 00414 uint8_t enabled_channels[KR920_MAX_NB_CHANNELS] = {0}; 00415 lorawan_time_t nextTxDelay = 0; 00416 00417 if (num_active_channels(channel_mask, 0, 1) == 0) { 00418 // Reactivate default channels 00419 channel_mask[0] |= LC(1) + LC(2) + LC(3); 00420 } 00421 00422 if (params->aggregate_timeoff <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { 00423 // Reset Aggregated time off 00424 *aggregate_timeoff = 0; 00425 00426 // Update bands Time OFF 00427 nextTxDelay = update_band_timeoff(params->joined, params->dc_enabled, 00428 bands, KR920_MAX_NB_BANDS); 00429 00430 // Search how many channels are enabled 00431 nb_enabled_channels = enabled_channel_count(params->joined, params->current_datarate, 00432 channel_mask, 00433 enabled_channels, &delay_tx); 00434 } else { 00435 delay_tx++; 00436 nextTxDelay = params->aggregate_timeoff - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); 00437 } 00438 00439 if (nb_enabled_channels > 0) { 00440 00441 for (uint8_t i = 0, j = get_random(0, nb_enabled_channels - 1); 00442 i < KR920_MAX_NB_CHANNELS; i++) { 00443 next_channel_idx = enabled_channels[j]; 00444 j = ( j + 1 ) % nb_enabled_channels; 00445 00446 // Perform carrier sense for KR920_CARRIER_SENSE_TIME 00447 // If the channel is free, we can stop the LBT mechanism 00448 _radio->lock(); 00449 00450 if (_radio->perform_carrier_sense(MODEM_LORA, 00451 channels[next_channel_idx].frequency, 00452 KR920_RSSI_FREE_TH, 00453 KR920_CARRIER_SENSE_TIME ) == true) { 00454 // Free channel found 00455 *channel = next_channel_idx; 00456 *time = 0; 00457 _radio->unlock(); 00458 return LORAWAN_STATUS_OK; 00459 } 00460 00461 _radio->unlock(); 00462 } 00463 00464 return LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND; 00465 00466 } else { 00467 00468 if (delay_tx > 0) { 00469 // Delay transmission due to AggregatedTimeOff or to a band time off 00470 *time = nextTxDelay; 00471 return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; 00472 } 00473 00474 // Datarate not supported by any channel, restore defaults 00475 channel_mask[0] |= LC(1) + LC(2) + LC(3); 00476 *time = 0; 00477 return LORAWAN_STATUS_NO_CHANNEL_FOUND; 00478 } 00479 } 00480 00481 void LoRaPHYKR920::set_tx_cont_mode(cw_mode_params_t * params, uint32_t given_frequency) 00482 { 00483 (void)given_frequency; 00484 00485 if (params->tx_power > bands[channels[params->channel ].band].max_tx_pwr) { 00486 params->tx_power = bands[channels[params->channel ].band].max_tx_pwr; 00487 } 00488 00489 float max_eirp = get_max_eirp(channels[params->channel ].frequency); 00490 int8_t phy_tx_power = 0; 00491 uint32_t frequency = channels[params->channel ].frequency; 00492 00493 // Take the minimum between the max_eirp and params->max_eirp. 00494 // The value of params->max_eirp could have changed during runtime, 00495 // e.g. due to a MAC command. 00496 max_eirp = MIN (params->max_eirp , max_eirp); 00497 00498 // Calculate physical TX power 00499 phy_tx_power = compute_tx_power(params->tx_power , max_eirp, params->antenna_gain ); 00500 00501 _radio->lock(); 00502 _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout ); 00503 _radio->unlock(); 00504 } 00505
Generated on Tue Jul 12 2022 14:23:52 by
