BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
LoRaPHYCN470.cpp
Go to the documentation of this file.
00001 /** 00002 * @file LoRaPHYCN470.cpp 00003 * 00004 * @brief Implements LoRaPHY for Chinese 470 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 "LoRaPHYCN470.h" 00033 #include "lora_phy_ds.h" 00034 00035 /*! 00036 * Minimal datarate that can be used by the node 00037 */ 00038 #define CN470_TX_MIN_DATARATE DR_0 00039 00040 /*! 00041 * Maximal datarate that can be used by the node 00042 */ 00043 #define CN470_TX_MAX_DATARATE DR_5 00044 00045 /*! 00046 * Minimal datarate that can be used by the node 00047 */ 00048 #define CN470_RX_MIN_DATARATE DR_0 00049 00050 /*! 00051 * Maximal datarate that can be used by the node 00052 */ 00053 #define CN470_RX_MAX_DATARATE DR_5 00054 00055 /*! 00056 * Default datarate used by the node 00057 */ 00058 #define CN470_DEFAULT_DATARATE DR_0 00059 00060 /*! 00061 * Minimal Rx1 receive datarate offset 00062 */ 00063 #define CN470_MIN_RX1_DR_OFFSET 0 00064 00065 /*! 00066 * Maximal Rx1 receive datarate offset 00067 */ 00068 #define CN470_MAX_RX1_DR_OFFSET 3 00069 00070 /*! 00071 * Default Rx1 receive datarate offset 00072 */ 00073 #define CN470_DEFAULT_RX1_DR_OFFSET 0 00074 00075 /*! 00076 * Minimal Tx output power that can be used by the node 00077 */ 00078 #define CN470_MIN_TX_POWER TX_POWER_7 00079 00080 /*! 00081 * Maximal Tx output power that can be used by the node 00082 */ 00083 #define CN470_MAX_TX_POWER TX_POWER_0 00084 00085 /*! 00086 * Default Tx output power used by the node 00087 */ 00088 #define CN470_DEFAULT_TX_POWER TX_POWER_0 00089 00090 /*! 00091 * Default Max EIRP 00092 */ 00093 #define CN470_DEFAULT_MAX_EIRP 19.15f 00094 00095 /*! 00096 * Default antenna gain 00097 */ 00098 #define CN470_DEFAULT_ANTENNA_GAIN 2.15f 00099 00100 /*! 00101 * ADR Ack limit 00102 */ 00103 #define CN470_ADR_ACK_LIMIT 64 00104 00105 /*! 00106 * ADR Ack delay 00107 */ 00108 #define CN470_ADR_ACK_DELAY 32 00109 00110 /*! 00111 * Enabled or disabled the duty cycle 00112 */ 00113 #define CN470_DUTY_CYCLE_ENABLED 0 00114 00115 /*! 00116 * Maximum RX window duration 00117 */ 00118 #define CN470_MAX_RX_WINDOW 3000 00119 00120 /*! 00121 * Receive delay 1 00122 */ 00123 #define CN470_RECEIVE_DELAY1 1000 00124 00125 /*! 00126 * Receive delay 2 00127 */ 00128 #define CN470_RECEIVE_DELAY2 2000 00129 00130 /*! 00131 * Join accept delay 1 00132 */ 00133 #define CN470_JOIN_ACCEPT_DELAY1 5000 00134 00135 /*! 00136 * Join accept delay 2 00137 */ 00138 #define CN470_JOIN_ACCEPT_DELAY2 6000 00139 00140 /*! 00141 * Maximum frame counter gap 00142 */ 00143 #define CN470_MAX_FCNT_GAP 16384 00144 00145 /*! 00146 * Ack timeout 00147 */ 00148 #define CN470_ACKTIMEOUT 2000 00149 00150 /*! 00151 * Random ack timeout limits 00152 */ 00153 #define CN470_ACK_TIMEOUT_RND 1000 00154 00155 /*! 00156 * Second reception window channel frequency definition. 00157 */ 00158 #define CN470_RX_WND_2_FREQ 505300000 00159 00160 /*! 00161 * Second reception window channel datarate definition. 00162 */ 00163 #define CN470_RX_WND_2_DR DR_0 00164 00165 /*! 00166 * Band 0 definition 00167 * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } 00168 */ 00169 static const band_t CN470_BAND0 = {1, CN470_MAX_TX_POWER, 0, 0, 0}; // 100.0 % 00170 00171 /*! 00172 * Defines the first channel for RX window 1 for CN470 band 00173 */ 00174 #define CN470_FIRST_RX1_CHANNEL ((uint32_t) 500300000) 00175 00176 /*! 00177 * Defines the last channel for RX window 1 for CN470 band 00178 */ 00179 #define CN470_LAST_RX1_CHANNEL ((uint32_t) 509700000) 00180 00181 /*! 00182 * Defines the step width of the channels for RX window 1 00183 */ 00184 #define CN470_STEPWIDTH_RX1_CHANNEL ((uint32_t) 200000) 00185 00186 /*! 00187 * Data rates table definition 00188 */ 00189 static const uint8_t datarates_CN470 [] = {12, 11, 10, 9, 8, 7}; 00190 00191 /*! 00192 * Bandwidths table definition in Hz 00193 */ 00194 static const uint32_t bandwidths_CN470 [] = {125000, 125000, 125000, 125000, 125000, 125000}; 00195 00196 /*! 00197 * Maximum payload with respect to the datarate index. Cannot operate with repeater. 00198 */ 00199 static const uint8_t max_payloads_CN470 [] = {51, 51, 51, 115, 222, 222}; 00200 00201 /*! 00202 * Maximum payload with respect to the datarate index. Can operate with repeater. 00203 */ 00204 static const uint8_t max_payloads_with_repeater_CN470 [] = {51, 51, 51, 115, 222, 222}; 00205 00206 00207 LoRaPHYCN470::LoRaPHYCN470(LoRaWANTimeHandler &lora_time) 00208 : LoRaPHY(lora_time) 00209 { 00210 bands[0] = CN470_BAND0 ; 00211 00212 // Channels 00213 // 125 kHz channels 00214 for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ ) 00215 { 00216 channels[i].frequency = 470300000 + i * 200000; 00217 channels[i].dr_range.value = ( DR_5 << 4 ) | DR_0; 00218 channels[i].band = 0; 00219 } 00220 00221 // Initialize the channels default mask 00222 default_channel_mask[0] = 0xFFFF; 00223 default_channel_mask[1] = 0xFFFF; 00224 default_channel_mask[2] = 0xFFFF; 00225 default_channel_mask[3] = 0xFFFF; 00226 default_channel_mask[4] = 0xFFFF; 00227 default_channel_mask[5] = 0xFFFF; 00228 00229 // Update the channels mask 00230 copy_channel_mask(channel_mask, default_channel_mask, CN470_CHANNEL_MASK_SIZE); 00231 00232 // set default channels 00233 phy_params.channels.channel_list = channels; 00234 phy_params.channels.channel_list_size = CN470_MAX_NB_CHANNELS; 00235 phy_params.channels.mask = channel_mask; 00236 phy_params.channels.default_mask = default_channel_mask; 00237 phy_params.channels.mask_size = CN470_CHANNEL_MASK_SIZE; 00238 00239 // set bands for CN470 spectrum 00240 phy_params.bands.table = (void *) bands; 00241 phy_params.bands.size = CN470_MAX_NB_BANDS; 00242 00243 // set bandwidths available in CN470 spectrum 00244 phy_params.bandwidths.table = (void *) bandwidths_CN470 ; 00245 phy_params.bandwidths.size = 6; 00246 00247 // set data rates available in CN470 spectrum 00248 phy_params.datarates.table = (void *) datarates_CN470 ; 00249 phy_params.datarates.size = 6; 00250 00251 // set payload sizes with respect to data rates 00252 phy_params.payloads.table = (void *) max_payloads_CN470 ; 00253 phy_params.payloads.size = 6; 00254 phy_params.payloads_with_repeater.table = (void *)max_payloads_with_repeater_CN470 ; 00255 phy_params.payloads_with_repeater.size = 6; 00256 00257 // dwell time setting 00258 phy_params.ul_dwell_time_setting = 0; 00259 phy_params.dl_dwell_time_setting = 0; 00260 00261 // set initial and default parameters 00262 phy_params.duty_cycle_enabled = CN470_DUTY_CYCLE_ENABLED; 00263 00264 phy_params.accept_tx_param_setup_req = false; 00265 phy_params.fsk_supported = false; 00266 phy_params.cflist_supported = false; 00267 phy_params.dl_channel_req_supported = false; 00268 phy_params.custom_channelplans_supported = false; 00269 00270 phy_params.default_channel_cnt = CN470_MAX_NB_CHANNELS; 00271 phy_params.max_channel_cnt = CN470_MAX_NB_CHANNELS; 00272 phy_params.cflist_channel_cnt = 0; 00273 phy_params.min_tx_datarate = CN470_TX_MIN_DATARATE; 00274 phy_params.max_tx_datarate = CN470_TX_MAX_DATARATE; 00275 phy_params.min_rx_datarate = CN470_RX_MIN_DATARATE; 00276 phy_params.max_rx_datarate = CN470_RX_MAX_DATARATE; 00277 phy_params.default_datarate = CN470_DEFAULT_DATARATE; 00278 phy_params.default_max_datarate = CN470_TX_MAX_DATARATE; 00279 phy_params.min_rx1_dr_offset = CN470_MIN_RX1_DR_OFFSET; 00280 phy_params.max_rx1_dr_offset = CN470_MAX_RX1_DR_OFFSET; 00281 phy_params.default_rx1_dr_offset = CN470_DEFAULT_RX1_DR_OFFSET; 00282 phy_params.min_tx_power = CN470_MIN_TX_POWER; 00283 phy_params.max_tx_power = CN470_MAX_TX_POWER; 00284 phy_params.default_tx_power = CN470_DEFAULT_TX_POWER; 00285 phy_params.default_max_eirp = CN470_DEFAULT_MAX_EIRP; 00286 phy_params.default_antenna_gain = CN470_DEFAULT_ANTENNA_GAIN; 00287 phy_params.adr_ack_limit = CN470_ADR_ACK_LIMIT; 00288 phy_params.adr_ack_delay = CN470_ADR_ACK_DELAY; 00289 phy_params.max_rx_window = CN470_MAX_RX_WINDOW; 00290 phy_params.recv_delay1 = CN470_RECEIVE_DELAY1; 00291 phy_params.recv_delay2 = CN470_RECEIVE_DELAY2; 00292 00293 phy_params.join_accept_delay1 = CN470_JOIN_ACCEPT_DELAY1; 00294 phy_params.join_accept_delay2 = CN470_JOIN_ACCEPT_DELAY2; 00295 phy_params.max_fcnt_gap = CN470_MAX_FCNT_GAP; 00296 phy_params.ack_timeout = CN470_ACKTIMEOUT; 00297 phy_params.ack_timeout_rnd = CN470_ACK_TIMEOUT_RND; 00298 phy_params.rx_window2_datarate = CN470_RX_WND_2_DR; 00299 phy_params.rx_window2_frequency = CN470_RX_WND_2_FREQ; 00300 } 00301 00302 LoRaPHYCN470::~LoRaPHYCN470() 00303 { 00304 } 00305 00306 bool LoRaPHYCN470::rx_config(rx_config_params_t * config, int8_t* datarate) 00307 { 00308 int8_t dr = config->datarate ; 00309 uint8_t max_payload = 0; 00310 int8_t phy_dr = 0; 00311 uint32_t frequency = config->frequency ; 00312 00313 _radio->lock(); 00314 00315 if (_radio->get_status() != RF_IDLE) { 00316 _radio->unlock(); 00317 return false; 00318 } 00319 00320 _radio->unlock(); 00321 00322 if( config->rx_slot == RX_SLOT_WIN_1 ) 00323 { 00324 // Apply window 1 frequency 00325 frequency = CN470_FIRST_RX1_CHANNEL + (config->channel % 48) * CN470_STEPWIDTH_RX1_CHANNEL; 00326 } 00327 00328 // Read the physical datarate from the datarates table 00329 phy_dr = datarates_CN470 [dr]; 00330 00331 _radio->lock(); 00332 00333 _radio->set_channel(frequency); 00334 00335 // Radio configuration 00336 _radio->set_rx_config(MODEM_LORA, config->bandwidth , phy_dr, 1, 0, 8, 00337 config->window_timeout , false, 0, false, 0, 0, true, 00338 config->is_rx_continuous ); 00339 00340 _radio->unlock(); 00341 00342 if (config->is_repeater_supported == true) { 00343 max_payload = max_payloads_with_repeater_CN470 [dr]; 00344 } else { 00345 max_payload = max_payloads_CN470 [dr]; 00346 } 00347 00348 _radio->lock(); 00349 _radio->set_max_payload_length(MODEM_LORA, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); 00350 _radio->unlock(); 00351 00352 *datarate = (uint8_t) dr; 00353 return true; 00354 } 00355 00356 bool LoRaPHYCN470::tx_config(tx_config_params_t* config, int8_t* tx_power, 00357 lorawan_time_t* tx_toa) 00358 { 00359 int8_t phy_dr = datarates_CN470 [config->datarate]; 00360 00361 if (config->tx_power > bands[channels[config->channel].band].max_tx_pwr) { 00362 config->tx_power = bands[channels[config->channel].band].max_tx_pwr; 00363 } 00364 00365 int8_t phy_tx_power = 0; 00366 00367 // Calculate physical TX power 00368 phy_tx_power = compute_tx_power(config->tx_power, config->max_eirp, 00369 config->antenna_gain); 00370 00371 // acquire lock to radio 00372 _radio->lock(); 00373 00374 _radio->set_channel(channels[config->channel].frequency); 00375 00376 _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, 0, phy_dr, 1, 8, false, true, 00377 0, 0, false, 3000); 00378 // Setup maximum payload lenght of the radio driver 00379 _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); 00380 00381 // Get the time-on-air of the next tx frame 00382 *tx_toa = _radio->time_on_air(MODEM_LORA, config->pkt_len); 00383 00384 // release lock to radio 00385 _radio->unlock(); 00386 00387 *tx_power = config->tx_power; 00388 00389 return true; 00390 } 00391 00392 uint8_t LoRaPHYCN470::link_ADR_request(adr_req_params_t* params, 00393 int8_t* dr_out, int8_t* tx_power_out, 00394 uint8_t* nb_rep_out, 00395 uint8_t* nb_bytes_parsed) 00396 { 00397 uint8_t status = 0x07; 00398 link_adr_params_t adr_settings; 00399 uint8_t next_index = 0; 00400 uint8_t bytes_processed = 0; 00401 uint16_t temp_channel_masks[CN470_CHANNEL_MASK_SIZE] = {0, 0, 0, 0, 0, 0}; 00402 00403 verify_adr_params_t verify_params; 00404 00405 // Initialize local copy of channels mask 00406 copy_channel_mask(temp_channel_masks, channel_mask, CN470_CHANNEL_MASK_SIZE); 00407 00408 while(bytes_processed < params->payload_size) { 00409 00410 // Get ADR request parameters 00411 next_index = parse_link_ADR_req(&(params->payload [bytes_processed]), &adr_settings); 00412 00413 if (next_index == 0) { 00414 break; // break loop, since no more request has been found 00415 } 00416 00417 // Update bytes processed 00418 bytes_processed += next_index; 00419 00420 // Revert status, as we only check the last ADR request for the channel mask KO 00421 status = 0x07; 00422 00423 if (adr_settings.ch_mask_ctrl == 6) { 00424 00425 // Enable all 125 kHz channels 00426 temp_channel_masks[0] = 0xFFFF; 00427 temp_channel_masks[1] = 0xFFFF; 00428 temp_channel_masks[2] = 0xFFFF; 00429 temp_channel_masks[3] = 0xFFFF; 00430 temp_channel_masks[4] = 0xFFFF; 00431 temp_channel_masks[5] = 0xFFFF; 00432 00433 } else if( adr_settings.ch_mask_ctrl == 7 ) { 00434 00435 status &= 0xFE; // Channel mask KO 00436 00437 } else { 00438 00439 for (uint8_t i = 0; i < 16; i++) { 00440 00441 if (((adr_settings.channel_mask & (1 << i)) != 0 ) && 00442 (channels[adr_settings.ch_mask_ctrl * 16 + i].frequency == 0)) { 00443 // Trying to enable an undefined channel 00444 status &= 0xFE; // Channel mask KO 00445 } 00446 } 00447 00448 temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; 00449 } 00450 } 00451 00452 verify_params.status = status; 00453 verify_params.adr_enabled = params->adr_enabled ; 00454 verify_params.datarate = adr_settings.datarate; 00455 verify_params.tx_power = adr_settings.tx_power; 00456 verify_params.nb_rep = adr_settings.nb_rep; 00457 verify_params.current_datarate = params->current_datarate ; 00458 verify_params.current_tx_power = params->current_tx_power ; 00459 verify_params.current_nb_rep = params->current_nb_rep ; 00460 verify_params.channel_mask = temp_channel_masks; 00461 00462 00463 // Verify the parameters and update, if necessary 00464 status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, 00465 &adr_settings.tx_power, &adr_settings.nb_rep); 00466 00467 // Update channelsMask if everything is correct 00468 if (status == 0x07) { 00469 // Copy Mask 00470 copy_channel_mask(channel_mask, temp_channel_masks, CN470_CHANNEL_MASK_SIZE); 00471 } 00472 00473 // Update status variables 00474 *dr_out = adr_settings.datarate; 00475 *tx_power_out = adr_settings.tx_power; 00476 *nb_rep_out = adr_settings.nb_rep; 00477 *nb_bytes_parsed = bytes_processed; 00478 00479 return status; 00480 } 00481 00482 uint8_t LoRaPHYCN470::accept_rx_param_setup_req(rx_param_setup_req_t* params) 00483 { 00484 uint8_t status = 0x07; 00485 uint32_t freq = params->frequency; 00486 00487 // acquire radio lock 00488 _radio->lock(); 00489 00490 if ((_radio->check_rf_frequency(freq) == false) 00491 || (freq < CN470_FIRST_RX1_CHANNEL) 00492 || (freq > CN470_LAST_RX1_CHANNEL) 00493 || (((freq - (uint32_t) CN470_FIRST_RX1_CHANNEL) % (uint32_t) CN470_STEPWIDTH_RX1_CHANNEL) != 0)) { 00494 00495 status &= 0xFE; // Channel frequency KO 00496 } 00497 00498 // release radio lock 00499 _radio->unlock(); 00500 00501 // Verify datarate 00502 if (val_in_range(params->datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE) == 0) { 00503 status &= 0xFD; // Datarate KO 00504 } 00505 00506 // Verify datarate offset 00507 if (val_in_range(params->dr_offset, CN470_MIN_RX1_DR_OFFSET, CN470_MAX_RX1_DR_OFFSET) == 0) { 00508 status &= 0xFB; // Rx1DrOffset range KO 00509 } 00510 00511 return status; 00512 }
Generated on Tue Jul 12 2022 12:21:58 by
