BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
LoRaPHYUS915Hybrid.cpp
Go to the documentation of this file.
00001 /** 00002 * @file LoRaPHYUS915Hybrid.cpp 00003 * 00004 * @brief Implements LoRaPHY for US 915 MHz Hybrid 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 "LoRaPHYUS915Hybrid.h" 00033 #include "lora_phy_ds.h" 00034 00035 /*! 00036 * Minimal datarate that can be used by the node 00037 */ 00038 #define US915_HYBRID_TX_MIN_DATARATE DR_0 00039 00040 /*! 00041 * Maximal datarate that can be used by the node 00042 */ 00043 #define US915_HYBRID_TX_MAX_DATARATE DR_4 00044 00045 /*! 00046 * Minimal datarate that can be used by the node 00047 */ 00048 #define US915_HYBRID_RX_MIN_DATARATE DR_8 00049 00050 /*! 00051 * Maximal datarate that can be used by the node 00052 */ 00053 #define US915_HYBRID_RX_MAX_DATARATE DR_13 00054 00055 /*! 00056 * Default datarate used by the node 00057 */ 00058 #define US915_HYBRID_DEFAULT_DATARATE DR_0 00059 00060 /*! 00061 * Minimal Rx1 receive datarate offset 00062 */ 00063 #define US915_HYBRID_MIN_RX1_DR_OFFSET 0 00064 00065 /*! 00066 * Maximal Rx1 receive datarate offset 00067 */ 00068 #define US915_HYBRID_MAX_RX1_DR_OFFSET 3 00069 00070 /*! 00071 * Default Rx1 receive datarate offset 00072 */ 00073 #define US915_HYBRID_DEFAULT_RX1_DR_OFFSET 0 00074 00075 /*! 00076 * Minimal Tx output power that can be used by the node 00077 */ 00078 #define US915_HYBRID_MIN_TX_POWER TX_POWER_10 00079 00080 /*! 00081 * Maximal Tx output power that can be used by the node 00082 */ 00083 #define US915_HYBRID_MAX_TX_POWER TX_POWER_0 00084 00085 /*! 00086 * Default Tx output power used by the node 00087 */ 00088 #define US915_HYBRID_DEFAULT_TX_POWER TX_POWER_0 00089 00090 /*! 00091 * Default Max ERP 00092 */ 00093 #define US915_HYBRID_DEFAULT_MAX_ERP 30.0f 00094 00095 /*! 00096 * ADR Ack limit 00097 */ 00098 #define US915_HYBRID_ADR_ACK_LIMIT 64 00099 00100 /*! 00101 * ADR Ack delay 00102 */ 00103 #define US915_HYBRID_ADR_ACK_DELAY 32 00104 00105 /*! 00106 * Enabled or disabled the duty cycle 00107 */ 00108 #define US915_HYBRID_DUTY_CYCLE_ENABLED 0 00109 00110 /*! 00111 * Maximum RX window duration 00112 */ 00113 #define US915_HYBRID_MAX_RX_WINDOW 3000 00114 00115 /*! 00116 * Receive delay 1 00117 */ 00118 #define US915_HYBRID_RECEIVE_DELAY1 1000 00119 00120 /*! 00121 * Receive delay 2 00122 */ 00123 #define US915_HYBRID_RECEIVE_DELAY2 2000 00124 00125 /*! 00126 * Join accept delay 1 00127 */ 00128 #define US915_HYBRID_JOIN_ACCEPT_DELAY1 5000 00129 00130 /*! 00131 * Join accept delay 2 00132 */ 00133 #define US915_HYBRID_JOIN_ACCEPT_DELAY2 6000 00134 00135 /*! 00136 * Maximum frame counter gap 00137 */ 00138 #define US915_HYBRID_MAX_FCNT_GAP 16384 00139 00140 /*! 00141 * Ack timeout 00142 */ 00143 #define US915_HYBRID_ACKTIMEOUT 2000 00144 00145 /*! 00146 * Random ack timeout limits 00147 */ 00148 #define US915_HYBRID_ACK_TIMEOUT_RND 1000 00149 00150 /*! 00151 * Second reception window channel frequency definition. 00152 */ 00153 #define US915_HYBRID_RX_WND_2_FREQ 923300000 00154 00155 /*! 00156 * Second reception window channel datarate definition. 00157 */ 00158 #define US915_HYBRID_RX_WND_2_DR DR_8 00159 00160 /*! 00161 * Band 0 definition 00162 * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } 00163 */ 00164 static const band_t US915_HYBRID_BAND0 = { 1, US915_HYBRID_MAX_TX_POWER, 0, 0, 0 }; // 100.0 % 00165 00166 /*! 00167 * Defines the first channel for RX window 1 for US band 00168 */ 00169 #define US915_HYBRID_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 ) 00170 00171 /*! 00172 * Defines the last channel for RX window 1 for US band 00173 */ 00174 #define US915_HYBRID_LAST_RX1_CHANNEL ( (uint32_t) 927500000 ) 00175 00176 /*! 00177 * Defines the step width of the channels for RX window 1 00178 */ 00179 #define US915_HYBRID_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 ) 00180 00181 /*! 00182 * Data rates table definition 00183 */ 00184 static const uint8_t datarates_US915_HYBRID [] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; 00185 00186 /*! 00187 * Bandwidths table definition in Hz 00188 */ 00189 static const uint32_t bandwidths_US915_HYBRID [] = { 125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; 00190 00191 /*! 00192 * Up/Down link data rates offset definition 00193 */ 00194 static const int8_t datarate_offsets_US915_HYBRID [5][4] = 00195 { 00196 { DR_10, DR_9 , DR_8 , DR_8 }, // DR_0 00197 { DR_11, DR_10, DR_9 , DR_8 }, // DR_1 00198 { DR_12, DR_11, DR_10, DR_9 }, // DR_2 00199 { DR_13, DR_12, DR_11, DR_10 }, // DR_3 00200 { DR_13, DR_13, DR_12, DR_11 }, // DR_4 00201 }; 00202 00203 /*! 00204 * Maximum payload with respect to the datarate index. Cannot operate with repeater. 00205 */ 00206 static const uint8_t max_payloads_US915_HYBRID [] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; 00207 00208 /*! 00209 * Maximum payload with respect to the datarate index. Can operate with repeater. 00210 */ 00211 static const uint8_t max_payloads_with_repeater_US915_HYBRID [] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; 00212 00213 LoRaPHYUS915Hybrid::LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time) 00214 : LoRaPHY(lora_time) 00215 { 00216 bands[0] = US915_HYBRID_BAND0 ; 00217 00218 // Channels 00219 // 125 kHz channels 00220 for (uint8_t i = 0; i < US915_HYBRID_MAX_NB_CHANNELS - 8; i++) { 00221 channels[i].frequency = 902300000 + i * 200000; 00222 channels[i].dr_range.value = ( DR_3 << 4 ) | DR_0; 00223 channels[i].band = 0; 00224 } 00225 00226 // 500 kHz channels 00227 for (uint8_t i = US915_HYBRID_MAX_NB_CHANNELS - 8; i < US915_HYBRID_MAX_NB_CHANNELS; i++) { 00228 channels[i].frequency = 903000000 + (i - (US915_HYBRID_MAX_NB_CHANNELS - 8)) * 1600000; 00229 channels[i].dr_range.value = ( DR_4 << 4 ) | DR_4; 00230 channels[i].band = 0; 00231 } 00232 00233 // ChannelsMask 00234 default_channel_mask[0] = 0x00FF; 00235 default_channel_mask[1] = 0x0000; 00236 default_channel_mask[2] = 0x0000; 00237 default_channel_mask[3] = 0x0000; 00238 default_channel_mask[4] = 0x0001; 00239 00240 memset(channel_mask, 0, sizeof(channel_mask)); 00241 memset(current_channel_mask, 0, sizeof(current_channel_mask)); 00242 00243 // Copy channels default mask 00244 copy_channel_mask(channel_mask, default_channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); 00245 00246 // Copy into channels mask remaining 00247 copy_channel_mask(current_channel_mask, channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); 00248 00249 // set default channels 00250 phy_params.channels.channel_list = channels; 00251 phy_params.channels.channel_list_size = US915_HYBRID_MAX_NB_CHANNELS; 00252 phy_params.channels.mask = channel_mask; 00253 phy_params.channels.default_mask = default_channel_mask; 00254 phy_params.channels.mask_size = US915_HYBRID_CHANNEL_MASK_SIZE; 00255 00256 // set bands for US915_HYBRID spectrum 00257 phy_params.bands.table = (void *) bands; 00258 phy_params.bands.size = US915_HYBRID_MAX_NB_BANDS; 00259 00260 // set bandwidths available in US915_HYBRID spectrum 00261 phy_params.bandwidths.table = (void *) bandwidths_US915_HYBRID ; 00262 phy_params.bandwidths.size = 16; 00263 00264 // set data rates available in US915_HYBRID spectrum 00265 phy_params.datarates.table = (void *) datarates_US915_HYBRID ; 00266 phy_params.datarates.size = 16; 00267 00268 // set payload sizes with respect to data rates 00269 phy_params.payloads.table = (void *) max_payloads_US915_HYBRID ; 00270 phy_params.payloads.size = 16; 00271 phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_US915_HYBRID ; 00272 phy_params.payloads_with_repeater.size = 16; 00273 00274 // dwell time setting 00275 phy_params.ul_dwell_time_setting = 0; 00276 phy_params.dl_dwell_time_setting = 0; 00277 00278 // set initial and default parameters 00279 phy_params.duty_cycle_enabled = US915_HYBRID_DUTY_CYCLE_ENABLED; 00280 phy_params.accept_tx_param_setup_req = false; 00281 phy_params.fsk_supported = false; 00282 phy_params.cflist_supported = false; 00283 phy_params.dl_channel_req_supported = false; 00284 phy_params.custom_channelplans_supported = false; 00285 phy_params.default_channel_cnt = US915_HYBRID_MAX_NB_CHANNELS; 00286 phy_params.max_channel_cnt = US915_HYBRID_MAX_NB_CHANNELS; 00287 phy_params.cflist_channel_cnt = 0; 00288 phy_params.min_tx_datarate = US915_HYBRID_TX_MIN_DATARATE; 00289 phy_params.max_tx_datarate = US915_HYBRID_TX_MAX_DATARATE; 00290 phy_params.min_rx_datarate = US915_HYBRID_RX_MIN_DATARATE; 00291 phy_params.max_rx_datarate = US915_HYBRID_RX_MAX_DATARATE; 00292 phy_params.default_datarate = US915_HYBRID_DEFAULT_DATARATE; 00293 phy_params.default_max_datarate = US915_HYBRID_TX_MAX_DATARATE; 00294 phy_params.min_rx1_dr_offset = US915_HYBRID_MIN_RX1_DR_OFFSET; 00295 phy_params.max_rx1_dr_offset = US915_HYBRID_MAX_RX1_DR_OFFSET; 00296 phy_params.default_rx1_dr_offset = US915_HYBRID_DEFAULT_RX1_DR_OFFSET; 00297 phy_params.min_tx_power = US915_HYBRID_MIN_TX_POWER; 00298 phy_params.max_tx_power = US915_HYBRID_MAX_TX_POWER; 00299 phy_params.default_tx_power = US915_HYBRID_DEFAULT_TX_POWER; 00300 phy_params.default_max_eirp = 0; 00301 phy_params.default_antenna_gain = 0; 00302 phy_params.adr_ack_limit = US915_HYBRID_ADR_ACK_LIMIT; 00303 phy_params.adr_ack_delay = US915_HYBRID_ADR_ACK_DELAY; 00304 phy_params.max_rx_window = US915_HYBRID_MAX_RX_WINDOW; 00305 phy_params.recv_delay1 = US915_HYBRID_RECEIVE_DELAY1; 00306 phy_params.recv_delay2 = US915_HYBRID_RECEIVE_DELAY2; 00307 00308 phy_params.join_accept_delay1 = US915_HYBRID_JOIN_ACCEPT_DELAY1; 00309 phy_params.join_accept_delay2 = US915_HYBRID_JOIN_ACCEPT_DELAY2; 00310 phy_params.max_fcnt_gap = US915_HYBRID_MAX_FCNT_GAP; 00311 phy_params.ack_timeout = US915_HYBRID_ACKTIMEOUT; 00312 phy_params.ack_timeout_rnd = US915_HYBRID_ACK_TIMEOUT_RND; 00313 phy_params.rx_window2_datarate = US915_HYBRID_RX_WND_2_DR; 00314 phy_params.rx_window2_frequency = US915_HYBRID_RX_WND_2_FREQ; 00315 } 00316 00317 LoRaPHYUS915Hybrid::~LoRaPHYUS915Hybrid() 00318 { 00319 } 00320 00321 void LoRaPHYUS915Hybrid::restore_default_channels() 00322 { 00323 // Copy channels default mask 00324 copy_channel_mask(channel_mask, default_channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); 00325 00326 for (uint8_t i = 0; i < US915_HYBRID_CHANNEL_MASK_SIZE; i++) { 00327 // Copy-And the channels mask 00328 current_channel_mask[i] &= channel_mask[i]; 00329 } 00330 } 00331 00332 bool LoRaPHYUS915Hybrid::get_next_ADR(bool restore_channel_mask, int8_t& dr_out, 00333 int8_t& tx_power_out, uint32_t& adr_ack_cnt) 00334 { 00335 bool adrAckReq = false; 00336 00337 uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay; 00338 00339 if (dr_out == phy_params.min_tx_datarate) { 00340 adr_ack_cnt = 0; 00341 return adrAckReq; 00342 } 00343 00344 if (adr_ack_cnt < phy_params.adr_ack_limit) { 00345 return adrAckReq; 00346 } 00347 00348 // ADR ack counter is larger than ADR-ACK-LIMIT 00349 adrAckReq = true; 00350 tx_power_out = phy_params.max_tx_power; 00351 00352 00353 if (adr_ack_cnt >= ack_limit_plus_delay) { 00354 if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) { 00355 // Decrease the datarate 00356 dr_out = get_next_lower_tx_datarate(dr_out); 00357 00358 if (dr_out == phy_params.min_tx_datarate) { 00359 // We must set adrAckReq to false as soon as we reach the lowest datarate 00360 adrAckReq = false; 00361 if (restore_channel_mask) { 00362 // Re-enable default channels 00363 reenable_500khz_channels(channel_mask[4], channel_mask); 00364 } 00365 } 00366 } 00367 } 00368 00369 return adrAckReq; 00370 } 00371 00372 bool LoRaPHYUS915Hybrid::rx_config(rx_config_params_t * config, int8_t* datarate) 00373 { 00374 int8_t dr = config->datarate ; 00375 uint8_t max_payload = 0; 00376 int8_t phy_dr = 0; 00377 uint32_t frequency = config->frequency ; 00378 00379 _radio->lock(); 00380 00381 if (_radio->get_status() != RF_IDLE) { 00382 00383 _radio->unlock(); 00384 return false; 00385 00386 } 00387 00388 _radio->unlock(); 00389 00390 if (config->rx_slot == RX_SLOT_WIN_1 ) { 00391 // Apply window 1 frequency 00392 frequency = US915_HYBRID_FIRST_RX1_CHANNEL + (config->channel % 8) * US915_HYBRID_STEPWIDTH_RX1_CHANNEL; 00393 } 00394 00395 // Read the physical datarate from the datarates table 00396 phy_dr = datarates_US915_HYBRID [dr]; 00397 00398 _radio->lock(); 00399 00400 _radio->set_channel( frequency ); 00401 00402 // Radio configuration 00403 _radio->set_rx_config(MODEM_LORA, config->bandwidth , phy_dr, 1, 0, 8, 00404 config->window_timeout , false, 0, false, 0, 0, true, 00405 config->is_rx_continuous ); 00406 00407 _radio->unlock(); 00408 00409 if (config->is_repeater_supported == true) { 00410 max_payload = max_payloads_with_repeater_US915_HYBRID [dr]; 00411 } else { 00412 max_payload = max_payloads_US915_HYBRID [dr]; 00413 } 00414 00415 _radio->lock(); 00416 _radio->set_max_payload_length(MODEM_LORA, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); 00417 _radio->unlock(); 00418 00419 *datarate = (uint8_t) dr; 00420 return true; 00421 } 00422 00423 bool LoRaPHYUS915Hybrid::tx_config(tx_config_params_t* config, int8_t* tx_power, 00424 lorawan_time_t* tx_toa) 00425 { 00426 int8_t phy_dr = datarates_US915_HYBRID [config->datarate]; 00427 00428 int8_t tx_power_limited = limit_tx_power(config->tx_power, 00429 bands[channels[config->channel].band].max_tx_pwr, 00430 config->datarate); 00431 00432 uint32_t bandwidth = get_bandwidth (config->datarate); 00433 int8_t phy_tx_power = 0; 00434 00435 // Calculate physical TX power 00436 phy_tx_power = compute_tx_power(tx_power_limited, US915_HYBRID_DEFAULT_MAX_ERP, 0); 00437 00438 _radio->lock(); 00439 00440 _radio->set_channel( channels[config->channel].frequency ); 00441 00442 _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, 00443 false, true, 0, 0, false, 3000); 00444 00445 // Setup maximum payload lenght of the radio driver 00446 _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); 00447 00448 // Get the time-on-air of the next tx frame 00449 *tx_toa = _radio->time_on_air(MODEM_LORA, config->pkt_len); 00450 00451 _radio->unlock(); 00452 *tx_power = tx_power_limited; 00453 00454 return true; 00455 } 00456 00457 uint8_t LoRaPHYUS915Hybrid::link_ADR_request(adr_req_params_t* params, 00458 int8_t* dr_out, int8_t* tx_power_out, 00459 uint8_t* nb_rep_out, 00460 uint8_t* nb_bytes_parsed) 00461 { 00462 uint8_t status = 0x07; 00463 link_adr_params_t adr_settings; 00464 uint8_t next_idx = 0; 00465 uint8_t bytes_processed = 0; 00466 uint16_t temp_channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE] = {0, 0, 0, 0, 0}; 00467 00468 verify_adr_params_t verify_params; 00469 00470 // Initialize local copy of channels mask 00471 copy_channel_mask(temp_channel_mask, channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); 00472 00473 while (bytes_processed < params->payload_size) { 00474 next_idx = parse_link_ADR_req(&(params->payload [bytes_processed]), 00475 &adr_settings); 00476 00477 if (next_idx == 0) { 00478 break; // break loop, since no more request has been found 00479 } 00480 00481 // Update bytes processed 00482 bytes_processed += next_idx; 00483 00484 // Revert status, as we only check the last ADR request for the channel mask KO 00485 status = 0x07; 00486 00487 if (adr_settings.ch_mask_ctrl == 6) { 00488 // Enable all 125 kHz channels 00489 temp_channel_mask[0] = 0xFFFF; 00490 temp_channel_mask[1] = 0xFFFF; 00491 temp_channel_mask[2] = 0xFFFF; 00492 temp_channel_mask[3] = 0xFFFF; 00493 // Apply chMask to channels 64 to 71 00494 temp_channel_mask[4] = adr_settings.channel_mask; 00495 } else if( adr_settings.ch_mask_ctrl == 7 ) { 00496 // Disable all 125 kHz channels 00497 temp_channel_mask[0] = 0x0000; 00498 temp_channel_mask[1] = 0x0000; 00499 temp_channel_mask[2] = 0x0000; 00500 temp_channel_mask[3] = 0x0000; 00501 // Apply chMask to channels 64 to 71 00502 temp_channel_mask[4] = adr_settings.channel_mask; 00503 } else if( adr_settings.ch_mask_ctrl == 5 ) { 00504 // RFU 00505 status &= 0xFE; // Channel mask KO 00506 } else { 00507 temp_channel_mask[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; 00508 } 00509 } 00510 00511 // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels 00512 if ((adr_settings.datarate < DR_4) && 00513 (num_active_channels( temp_channel_mask, 0, 4 ) < 2)) { 00514 status &= 0xFE; // Channel mask KO 00515 } 00516 00517 if( validate_channel_mask(temp_channel_mask ) == false) { 00518 status &= 0xFE; // Channel mask KO 00519 } 00520 00521 verify_params.status = status; 00522 verify_params.adr_enabled = params->adr_enabled ; 00523 verify_params.datarate = adr_settings.datarate; 00524 verify_params.tx_power = adr_settings.tx_power; 00525 verify_params.nb_rep = adr_settings.nb_rep; 00526 verify_params.current_datarate = params->current_datarate ; 00527 verify_params.current_tx_power = params->current_tx_power ; 00528 verify_params.current_nb_rep = params->current_nb_rep ; 00529 verify_params.channel_mask = temp_channel_mask; 00530 00531 00532 // Verify the parameters and update, if necessary 00533 status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, 00534 &adr_settings.tx_power, &adr_settings.nb_rep); 00535 00536 // Update channelsMask if everything is correct 00537 if (status == 0x07) { 00538 // Copy Mask 00539 copy_channel_mask(channel_mask, temp_channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); 00540 00541 current_channel_mask[0] &= channel_mask[0]; 00542 current_channel_mask[1] &= channel_mask[1]; 00543 current_channel_mask[2] &= channel_mask[2]; 00544 current_channel_mask[3] &= channel_mask[3]; 00545 current_channel_mask[4] = channel_mask[4]; 00546 } 00547 00548 // Update status variables 00549 *dr_out = adr_settings.datarate; 00550 *tx_power_out = adr_settings.tx_power; 00551 *nb_rep_out = adr_settings.nb_rep; 00552 *nb_bytes_parsed = bytes_processed; 00553 00554 return status; 00555 } 00556 00557 uint8_t LoRaPHYUS915Hybrid::accept_rx_param_setup_req(rx_param_setup_req_t* params) 00558 { 00559 uint8_t status = 0x07; 00560 uint32_t freq = params->frequency; 00561 00562 // Verify radio frequency 00563 if ((_radio->check_rf_frequency(freq) == false) 00564 || (freq < US915_HYBRID_FIRST_RX1_CHANNEL) 00565 || (freq > US915_HYBRID_LAST_RX1_CHANNEL) 00566 || (((freq - ( uint32_t ) US915_HYBRID_FIRST_RX1_CHANNEL) % (uint32_t) US915_HYBRID_STEPWIDTH_RX1_CHANNEL) != 0)) { 00567 status &= 0xFE; // Channel frequency KO 00568 } 00569 00570 // Verify datarate 00571 if (val_in_range(params->datarate, US915_HYBRID_RX_MIN_DATARATE, US915_HYBRID_RX_MAX_DATARATE) == 0) { 00572 status &= 0xFD; // Datarate KO 00573 } 00574 00575 if ((val_in_range(params->datarate, DR_5, DR_7) == 1) 00576 || (params->datarate > DR_13)) { 00577 status &= 0xFD; // Datarate KO 00578 } 00579 00580 // Verify datarate offset 00581 if (val_in_range(params->dr_offset, US915_HYBRID_MIN_RX1_DR_OFFSET, US915_HYBRID_MAX_RX1_DR_OFFSET) == 0) { 00582 status &= 0xFB; // Rx1DrOffset range KO 00583 } 00584 00585 return status; 00586 } 00587 00588 int8_t LoRaPHYUS915Hybrid::get_alternate_DR(uint8_t nb_trials) 00589 { 00590 int8_t datarate = 0; 00591 00592 // Re-enable 500 kHz default channels 00593 reenable_500khz_channels(channel_mask[4], channel_mask); 00594 00595 if ((nb_trials & 0x01) == 0x01) { 00596 datarate = DR_4; 00597 } else { 00598 datarate = DR_0; 00599 } 00600 00601 return datarate; 00602 } 00603 00604 bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, 00605 uint8_t* channel, lorawan_time_t* time, 00606 lorawan_time_t* aggregate_timeOff) 00607 { 00608 uint8_t nb_enabled_channels = 0; 00609 uint8_t delay_tx = 0; 00610 uint8_t enabled_channels[US915_HYBRID_MAX_NB_CHANNELS] = {0}; 00611 lorawan_time_t next_tx_delay = 0; 00612 00613 // Count 125kHz channels 00614 if (num_active_channels(current_channel_mask, 0, 4) == 0) { 00615 // Reactivate default channels 00616 copy_channel_mask(current_channel_mask, channel_mask, 4); 00617 } 00618 00619 // Check other channels 00620 if (params->current_datarate >= DR_4) { 00621 if ((current_channel_mask[4] & 0x00FF ) == 0) { 00622 current_channel_mask[4] = channel_mask[4]; 00623 } 00624 } 00625 00626 if (params->aggregate_timeoff <= _lora_time.get_elapsed_time( params->last_aggregate_tx_time)) { 00627 // Reset Aggregated time off 00628 *aggregate_timeOff = 0; 00629 00630 // Update bands Time OFF 00631 next_tx_delay = update_band_timeoff(params->joined, 00632 params->dc_enabled, bands, 00633 US915_HYBRID_MAX_NB_BANDS); 00634 00635 // Search how many channels are enabled 00636 nb_enabled_channels = enabled_channel_count(params->joined, 00637 params->current_datarate, 00638 current_channel_mask, 00639 enabled_channels, &delay_tx); 00640 } else { 00641 delay_tx++; 00642 next_tx_delay = params->aggregate_timeoff - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); 00643 } 00644 00645 if (nb_enabled_channels > 0) { 00646 00647 // We found a valid channel 00648 *channel = enabled_channels[get_random(0, nb_enabled_channels - 1)]; 00649 // Disable the channel in the mask 00650 disable_channel(current_channel_mask, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8); 00651 00652 *time = 0; 00653 return true; 00654 00655 } else { 00656 00657 if (delay_tx > 0) { 00658 // Delay transmission due to AggregatedTimeOff or to a band time off 00659 *time = next_tx_delay; 00660 return true; 00661 } 00662 00663 // Datarate not supported by any channel 00664 *time = 0; 00665 return false; 00666 } 00667 } 00668 00669 void LoRaPHYUS915Hybrid::set_tx_cont_mode(cw_mode_params_t * params, uint32_t given_frequency) 00670 { 00671 (void)given_frequency; 00672 00673 int8_t tx_power_limited = limit_tx_power(params->tx_power , 00674 bands[channels[params->channel ].band].max_tx_pwr, 00675 params->datarate ); 00676 00677 int8_t phy_tx_power = 0; 00678 uint32_t frequency = channels[params->channel ].frequency; 00679 00680 // Calculate physical TX power 00681 phy_tx_power = compute_tx_power(tx_power_limited, US915_HYBRID_DEFAULT_MAX_ERP, 0); 00682 00683 _radio->lock(); 00684 _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout ); 00685 _radio->unlock(); 00686 } 00687 00688 uint8_t LoRaPHYUS915Hybrid::apply_DR_offset(int8_t dr, int8_t drOffset) 00689 { 00690 int8_t datarate = datarate_offsets_US915_HYBRID [dr][drOffset]; 00691 00692 if (datarate < 0) { 00693 datarate = DR_0; 00694 } 00695 00696 return datarate; 00697 } 00698 00699 00700 void LoRaPHYUS915Hybrid::reenable_500khz_channels(uint16_t mask, uint16_t* channelsMask) 00701 { 00702 uint16_t blockMask = mask; 00703 00704 for (uint8_t i = 0, j = 0; i < 4; i++, j += 2) { 00705 channelsMask[i] = 0; 00706 if ((blockMask & (1 << j)) != 0) { 00707 channelsMask[i] |= 0x00FF; 00708 } 00709 00710 if ((blockMask & (1 << (j + 1))) != 0) { 00711 channelsMask[i] |= 0xFF00; 00712 } 00713 } 00714 00715 channelsMask[4] = blockMask; 00716 } 00717 00718 int8_t LoRaPHYUS915Hybrid::limit_tx_power(int8_t txPower, int8_t maxBandTxPower, 00719 int8_t datarate) 00720 { 00721 int8_t txPowerResult = txPower; 00722 00723 // Limit tx power to the band max 00724 txPowerResult = MAX(txPower, maxBandTxPower); 00725 00726 if (datarate == DR_4) { 00727 00728 // Limit tx power to max 26dBm 00729 txPowerResult = MAX(txPower, TX_POWER_2); 00730 00731 } else { 00732 00733 if (num_active_channels(channel_mask, 0, 4) < 50) { 00734 // Limit tx power to max 21dBm 00735 txPowerResult = MAX(txPower, TX_POWER_5); 00736 } 00737 } 00738 00739 return txPowerResult; 00740 } 00741 00742 bool LoRaPHYUS915Hybrid::validate_channel_mask(uint16_t* channel_masks) 00743 { 00744 bool mask_state = false; 00745 00746 uint16_t block1 = 0; 00747 uint16_t block2 = 0; 00748 uint8_t index = 0; 00749 uint16_t temp_channel_masks[US915_HYBRID_CHANNEL_MASK_SIZE]; 00750 00751 // Copy channels mask to not change the input 00752 for (uint8_t i = 0; i < 4; i++) { 00753 temp_channel_masks[i] = channel_masks[i]; 00754 } 00755 00756 for(uint8_t i = 0; i < 4; i++) { 00757 block1 = temp_channel_masks[i] & 0x00FF; 00758 block2 = temp_channel_masks[i] & 0xFF00; 00759 00760 if (count_bits(block1, 16) > 5) { 00761 00762 temp_channel_masks[i] &= block1; 00763 temp_channel_masks[4] = 1 << ( i * 2 ); 00764 mask_state = true; 00765 index = i; 00766 break; 00767 00768 } else if( count_bits( block2, 16 ) > 5 ) { 00769 00770 temp_channel_masks[i] &= block2; 00771 temp_channel_masks[4] = 1 << ( i * 2 + 1 ); 00772 mask_state = true; 00773 index = i; 00774 break; 00775 00776 } 00777 } 00778 00779 // Do change the channel mask, if we have found a valid block. 00780 if (mask_state == true) { 00781 // Copy channels mask back again 00782 for (uint8_t i = 0; i < 4; i++) { 00783 channel_masks[i] = temp_channel_masks[i]; 00784 00785 if (i != index) { 00786 channel_masks[i] = 0; 00787 } 00788 } 00789 00790 channel_masks[4] = temp_channel_masks[4]; 00791 } 00792 00793 return mask_state; 00794 }
Generated on Tue Jul 12 2022 12:21:59 by
