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.
Dependencies: nRF51_Vdd TextLCD BME280
LoRaPHY.cpp
00001 /** 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2013 Semtech 00008 ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 embedded.connectivity.solutions=============== 00013 00014 License: Revised BSD License, see LICENSE.TXT file include in the project 00015 00016 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 00017 00018 00019 Copyright (c) 2017, Arm Limited and affiliates. 00020 00021 SPDX-License-Identifier: BSD-3-Clause 00022 */ 00023 00024 #include <stdbool.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include <stdint.h> 00028 #include <math.h> 00029 00030 #include "LoRaPHY.h" 00031 00032 #define BACKOFF_DC_1_HOUR 100 00033 #define BACKOFF_DC_10_HOURS 1000 00034 #define BACKOFF_DC_24_HOURS 10000 00035 00036 #define CHANNELS_IN_MASK 16 00037 00038 LoRaPHY::LoRaPHY() 00039 : _radio(NULL), 00040 _lora_time(NULL) 00041 { 00042 memset(&phy_params, 0, sizeof(phy_params)); 00043 } 00044 00045 LoRaPHY::~LoRaPHY() 00046 { 00047 _radio = NULL; 00048 } 00049 00050 void LoRaPHY::initialize(LoRaWANTimeHandler *lora_time) 00051 { 00052 _lora_time = lora_time; 00053 } 00054 00055 bool LoRaPHY::mask_bit_test(const uint16_t *mask, unsigned bit) 00056 { 00057 return mask[bit / 16] & (1U << (bit % 16)); 00058 } 00059 00060 void LoRaPHY::mask_bit_set(uint16_t *mask, unsigned bit) 00061 { 00062 mask[bit / 16] |= (1U << (bit % 16)); 00063 } 00064 00065 void LoRaPHY::mask_bit_clear(uint16_t *mask, unsigned bit) 00066 { 00067 mask[bit / 16] &= ~(1U << (bit % 16)); 00068 } 00069 00070 void LoRaPHY::set_radio_instance(LoRaRadio &radio) 00071 { 00072 _radio = &radio; 00073 } 00074 00075 void LoRaPHY::put_radio_to_sleep() 00076 { 00077 _radio->lock(); 00078 _radio->sleep(); 00079 _radio->unlock(); 00080 } 00081 00082 void LoRaPHY::put_radio_to_standby() 00083 { 00084 _radio->lock(); 00085 _radio->standby(); 00086 _radio->unlock(); 00087 } 00088 00089 void LoRaPHY::setup_public_network_mode(bool set) 00090 { 00091 _radio->lock(); 00092 _radio->set_public_network(set); 00093 _radio->unlock(); 00094 } 00095 00096 void LoRaPHY::handle_receive(void) 00097 { 00098 _radio->lock(); 00099 _radio->receive(); 00100 _radio->unlock(); 00101 } 00102 00103 // For DevNonce for example 00104 uint32_t LoRaPHY::get_radio_rng() 00105 { 00106 uint32_t rand; 00107 00108 _radio->lock(); 00109 rand = _radio->random(); 00110 _radio->unlock(); 00111 00112 return rand; 00113 } 00114 00115 void LoRaPHY::handle_send(uint8_t *buf, uint8_t size) 00116 { 00117 _radio->lock(); 00118 _radio->send(buf, size); 00119 _radio->unlock(); 00120 } 00121 00122 uint8_t LoRaPHY::request_new_channel(int8_t channel_id, channel_params_t *new_channel) 00123 { 00124 if (!phy_params.custom_channelplans_supported) { 00125 return 0; 00126 } 00127 00128 uint8_t status = 0x03; 00129 00130 if (new_channel->frequency == 0) { 00131 // Remove 00132 if (remove_channel(channel_id) == false) { 00133 status &= 0xFC; 00134 } 00135 } else { 00136 new_channel->band = lookup_band_for_frequency(new_channel->frequency); 00137 switch (add_channel(new_channel, channel_id)) { 00138 case LORAWAN_STATUS_OK: { 00139 break; 00140 } 00141 case LORAWAN_STATUS_FREQUENCY_INVALID: { 00142 status &= 0xFE; 00143 break; 00144 } 00145 case LORAWAN_STATUS_DATARATE_INVALID: { 00146 status &= 0xFD; 00147 break; 00148 } 00149 case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { 00150 status &= 0xFC; 00151 break; 00152 } 00153 default: { 00154 status &= 0xFC; 00155 break; 00156 } 00157 } 00158 } 00159 00160 return status; 00161 } 00162 00163 int32_t LoRaPHY::get_random(int32_t min, int32_t max) 00164 { 00165 return (int32_t) rand() % (max - min + 1) + min; 00166 } 00167 00168 bool LoRaPHY::verify_channel_DR(uint16_t *channel_mask, int8_t dr) 00169 { 00170 if (val_in_range(dr, phy_params.min_tx_datarate, 00171 phy_params.max_tx_datarate) == 0) { 00172 return false; 00173 } 00174 00175 for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { 00176 if (mask_bit_test(channel_mask, i)) { 00177 // Check datarate validity for enabled channels 00178 if (val_in_range(dr, (phy_params.channels.channel_list[i].dr_range.fields.min & 0x0F), 00179 (phy_params.channels.channel_list[i].dr_range.fields.max & 0x0F))) { 00180 // At least 1 channel has been found we can return OK. 00181 return true; 00182 } 00183 } 00184 } 00185 00186 return false; 00187 } 00188 00189 bool LoRaPHY::val_in_range(int8_t value, int8_t min, int8_t max) 00190 { 00191 if ((value >= min) && (value <= max)) { 00192 return true; 00193 } 00194 00195 return false; 00196 } 00197 00198 bool LoRaPHY::disable_channel(uint16_t *channel_mask, uint8_t id, 00199 uint8_t max_channels_num) 00200 { 00201 uint8_t index = id / 16; 00202 00203 if ((index > phy_params.channels.mask_size) || (id >= max_channels_num)) { 00204 return false; 00205 } 00206 00207 // Deactivate channel 00208 mask_bit_clear(channel_mask, id); 00209 00210 return true; 00211 } 00212 00213 uint8_t LoRaPHY::count_bits(uint16_t mask, uint8_t nbBits) 00214 { 00215 uint8_t nbActiveBits = 0; 00216 00217 for (uint8_t j = 0; j < nbBits; j++) { 00218 if (mask_bit_test(&mask, j)) { 00219 nbActiveBits++; 00220 } 00221 } 00222 00223 return nbActiveBits; 00224 } 00225 00226 uint8_t LoRaPHY::num_active_channels(uint16_t *channel_mask, uint8_t start_idx, 00227 uint8_t stop_idx) 00228 { 00229 uint8_t nb_channels = 0; 00230 00231 if (channel_mask == NULL) { 00232 return 0; 00233 } 00234 00235 for (uint8_t i = start_idx; i < stop_idx; i++) { 00236 nb_channels += count_bits(channel_mask[i], 16); 00237 } 00238 00239 return nb_channels; 00240 } 00241 00242 void LoRaPHY::copy_channel_mask(uint16_t *dest_mask, uint16_t *src_mask, uint8_t len) 00243 { 00244 if ((dest_mask != NULL) && (src_mask != NULL)) { 00245 for (uint8_t i = 0; i < len; i++) { 00246 dest_mask[i] = src_mask[i]; 00247 } 00248 } 00249 } 00250 00251 void LoRaPHY::set_last_tx_done(uint8_t channel, bool joined, lorawan_time_t last_tx_done_time) 00252 { 00253 band_t *band_table = (band_t *) phy_params.bands.table; 00254 channel_params_t *channel_list = phy_params.channels.channel_list; 00255 00256 if (joined == true) { 00257 band_table[channel_list[channel].band].last_tx_time = last_tx_done_time; 00258 return; 00259 } 00260 00261 band_table[channel_list[channel].band].last_tx_time = last_tx_done_time; 00262 band_table[channel_list[channel].band].last_join_tx_time = last_tx_done_time; 00263 00264 } 00265 00266 lorawan_time_t LoRaPHY::update_band_timeoff(bool joined, bool duty_cycle, 00267 band_t *bands, uint8_t nb_bands) 00268 { 00269 lorawan_time_t next_tx_delay = (lorawan_time_t)(-1); 00270 00271 // Update bands Time OFF 00272 for (uint8_t i = 0; i < nb_bands; i++) { 00273 if (MBED_CONF_LORA_DUTY_CYCLE_ON_JOIN && joined == false) { 00274 uint32_t txDoneTime = MAX(_lora_time->get_elapsed_time(bands[i].last_join_tx_time ), 00275 (duty_cycle == true) ? 00276 _lora_time->get_elapsed_time(bands[i].last_tx_time ) : 0); 00277 00278 if (bands[i].off_time <= txDoneTime) { 00279 bands[i].off_time = 0; 00280 } 00281 00282 if (bands[i].off_time != 0) { 00283 next_tx_delay = MIN(bands[i].off_time - txDoneTime, next_tx_delay); 00284 } 00285 } else { 00286 // if network has been joined 00287 if (duty_cycle == true) { 00288 00289 if (bands[i].off_time <= _lora_time->get_elapsed_time(bands[i].last_tx_time)) { 00290 bands[i].off_time = 0; 00291 } 00292 00293 if (bands[i].off_time != 0) { 00294 next_tx_delay = MIN(bands[i].off_time - _lora_time->get_elapsed_time(bands[i].last_tx_time ), 00295 next_tx_delay); 00296 } 00297 } else { 00298 // if duty cycle is not on 00299 next_tx_delay = 0; 00300 bands[i].off_time = 0; 00301 } 00302 } 00303 } 00304 00305 return next_tx_delay; 00306 } 00307 00308 uint8_t LoRaPHY::parse_link_ADR_req(const uint8_t *payload, 00309 link_adr_params_t *params) 00310 { 00311 uint8_t ret_index = 0; 00312 00313 if (payload[0] == SRV_MAC_LINK_ADR_REQ ) { 00314 00315 // Parse datarate and tx power 00316 params->datarate = payload[1]; 00317 params->tx_power = params->datarate & 0x0F; 00318 params->datarate = (params->datarate >> 4) & 0x0F; 00319 00320 // Parse ChMask 00321 params->channel_mask = (uint16_t) payload[2]; 00322 params->channel_mask |= (uint16_t) payload[3] << 8; 00323 00324 // Parse ChMaskCtrl and nbRep 00325 params->nb_rep = payload[4]; 00326 params->ch_mask_ctrl = (params->nb_rep >> 4) & 0x07; 00327 params->nb_rep &= 0x0F; 00328 00329 // LinkAdrReq has 4 bytes length + 1 byte CMD 00330 ret_index = 5; 00331 } 00332 00333 return ret_index; 00334 } 00335 00336 uint8_t LoRaPHY::verify_link_ADR_req(verify_adr_params_t *verify_params, 00337 int8_t *dr, int8_t *tx_pow, uint8_t *nb_rep) 00338 { 00339 uint8_t status = verify_params->status ; 00340 int8_t datarate = verify_params->datarate ; 00341 int8_t tx_power = verify_params->tx_power ; 00342 int8_t nb_repetitions = verify_params->nb_rep ; 00343 00344 // Handle the case when ADR is off. 00345 if (verify_params->adr_enabled == false) { 00346 // When ADR is off, we are allowed to change the channels mask and the NbRep, 00347 // if the datarate and the TX power of the LinkAdrReq are set to 0x0F. 00348 if ((verify_params->datarate != 0x0F) || (verify_params->tx_power != 0x0F)) { 00349 status = 0; 00350 nb_repetitions = verify_params->current_nb_rep ; 00351 } 00352 00353 // Get the current datarate and tx power 00354 datarate = verify_params->current_datarate ; 00355 tx_power = verify_params->current_tx_power ; 00356 } 00357 00358 if (status != 0) { 00359 // Verify channel datarate 00360 if (verify_channel_DR(verify_params->channel_mask , datarate) == false) { 00361 status &= 0xFD; // Datarate KO 00362 } 00363 00364 // Verify tx power 00365 if (val_in_range(tx_power, phy_params.max_tx_power, 00366 phy_params.min_tx_power) == false) { 00367 // Verify if the maximum TX power is exceeded 00368 if (phy_params.max_tx_power > tx_power) { 00369 // Apply maximum TX power. Accept TX power. 00370 tx_power = phy_params.max_tx_power; 00371 } else { 00372 status &= 0xFB; // TxPower KO 00373 } 00374 } 00375 } 00376 00377 // If the status is ok, verify the NbRep 00378 if (status == 0x07 && nb_repetitions == 0) { 00379 // Restore the default value according to the LoRaWAN specification 00380 nb_repetitions = 1; 00381 } 00382 00383 // Apply changes 00384 *dr = datarate; 00385 *tx_pow = tx_power; 00386 *nb_rep = nb_repetitions; 00387 00388 return status; 00389 } 00390 00391 double LoRaPHY::compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth) 00392 { 00393 return ((double)(1 << phy_dr) / (double) bandwidth) * 1000; 00394 } 00395 00396 double LoRaPHY::compute_symb_timeout_fsk(uint8_t phy_dr) 00397 { 00398 return (8.0 / (double) phy_dr); // 1 symbol equals 1 byte 00399 } 00400 00401 void LoRaPHY::get_rx_window_params(double t_symb, uint8_t min_rx_symb, 00402 uint32_t rx_error, uint32_t wakeup_time, 00403 uint32_t *window_timeout, int32_t *window_offset) 00404 { 00405 // Computed number of symbols 00406 *window_timeout = MAX((uint32_t) ceil(((2 * min_rx_symb - 8) * t_symb + 2 * rx_error) / t_symb), min_rx_symb); 00407 *window_offset = (int32_t) ceil((4.0 * t_symb) - ((*window_timeout * t_symb) / 2.0 ) - wakeup_time); 00408 } 00409 00410 int8_t LoRaPHY::compute_tx_power(int8_t tx_power_idx, float max_eirp, 00411 float antenna_gain) 00412 { 00413 int8_t phy_tx_power = 0; 00414 00415 phy_tx_power = (int8_t) floor((max_eirp - (tx_power_idx * 2U)) - antenna_gain); 00416 00417 return phy_tx_power; 00418 } 00419 00420 00421 int8_t LoRaPHY::get_next_lower_dr(int8_t dr, int8_t min_dr) 00422 { 00423 uint8_t next_lower_dr = dr; 00424 00425 do { 00426 if (next_lower_dr != min_dr) { 00427 next_lower_dr -= 1; 00428 } 00429 } while ((next_lower_dr != min_dr) && !is_datarate_supported(next_lower_dr)); 00430 00431 return next_lower_dr; 00432 } 00433 00434 uint8_t LoRaPHY::get_bandwidth(uint8_t dr) 00435 { 00436 uint32_t *bandwidths = (uint32_t *) phy_params.bandwidths.table; 00437 00438 switch (bandwidths[dr]) { 00439 default: 00440 case 125000: 00441 return 0; 00442 case 250000: 00443 return 1; 00444 case 500000: 00445 return 2; 00446 } 00447 } 00448 00449 uint8_t LoRaPHY::enabled_channel_count(uint8_t datarate, 00450 const uint16_t *channel_mask, 00451 uint8_t *channel_indices, 00452 uint8_t *delayTx) 00453 { 00454 uint8_t count = 0; 00455 uint8_t delay_transmission = 0; 00456 00457 for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { 00458 if (mask_bit_test(channel_mask, i)) { 00459 00460 if (val_in_range(datarate, phy_params.channels.channel_list[i].dr_range.fields.min, 00461 phy_params.channels.channel_list[i].dr_range.fields.max) == 0) { 00462 // data rate range invalid for this channel 00463 continue; 00464 } 00465 00466 band_t *band_table = (band_t *) phy_params.bands.table; 00467 if (band_table[phy_params.channels.channel_list[i].band].off_time > 0) { 00468 // Check if the band is available for transmission 00469 delay_transmission++; 00470 continue; 00471 } 00472 00473 // otherwise count the channel as enabled 00474 channel_indices[count++] = i; 00475 } 00476 } 00477 00478 *delayTx = delay_transmission; 00479 00480 return count; 00481 } 00482 00483 bool LoRaPHY::is_datarate_supported(const int8_t datarate) const 00484 { 00485 if (datarate < phy_params.datarates.size) { 00486 return (((uint8_t *)phy_params.datarates.table)[datarate] != 0) ? true : false; 00487 } else { 00488 return false; 00489 } 00490 } 00491 00492 void LoRaPHY::reset_to_default_values(loramac_protocol_params *params, bool init) 00493 { 00494 if (init) { 00495 params->is_dutycycle_on = phy_params.duty_cycle_enabled; 00496 00497 params->sys_params.max_rx_win_time = phy_params.max_rx_window; 00498 00499 params->sys_params.recv_delay1 = phy_params.recv_delay1; 00500 00501 params->sys_params.recv_delay2 = phy_params.recv_delay2; 00502 00503 params->sys_params.join_accept_delay1 = phy_params.join_accept_delay1; 00504 00505 params->sys_params.join_accept_delay2 = phy_params.join_accept_delay2; 00506 00507 params->sys_params.downlink_dwell_time = phy_params.dl_dwell_time_setting; 00508 } 00509 00510 params->sys_params.channel_tx_power = get_default_tx_power(); 00511 00512 // We shall always start with highest achievable data rate. 00513 // Subsequent decrease in data rate will mean increase in range henceforth. 00514 params->sys_params.channel_data_rate = get_default_max_tx_datarate(); 00515 00516 params->sys_params.rx1_dr_offset = phy_params.default_rx1_dr_offset; 00517 00518 params->sys_params.rx2_channel.frequency = get_default_rx2_frequency(); 00519 00520 params->sys_params.rx2_channel.datarate = get_default_rx2_datarate(); 00521 00522 params->sys_params.uplink_dwell_time = phy_params.ul_dwell_time_setting; 00523 00524 params->sys_params.max_eirp = phy_params.default_max_eirp; 00525 00526 params->sys_params.antenna_gain = phy_params.default_antenna_gain; 00527 } 00528 00529 int8_t LoRaPHY::get_next_lower_tx_datarate(int8_t datarate) 00530 { 00531 if (phy_params.ul_dwell_time_setting == 0) { 00532 return get_next_lower_dr(datarate, phy_params.min_tx_datarate); 00533 } 00534 00535 return get_next_lower_dr(datarate, phy_params.dwell_limit_datarate); 00536 00537 } 00538 00539 uint8_t LoRaPHY::get_minimum_rx_datarate() 00540 { 00541 if (phy_params.dl_dwell_time_setting == 0) { 00542 return phy_params.min_rx_datarate; 00543 } 00544 return phy_params.dwell_limit_datarate; 00545 } 00546 00547 uint8_t LoRaPHY::get_minimum_tx_datarate() 00548 { 00549 if (phy_params.ul_dwell_time_setting == 0) { 00550 return phy_params.min_tx_datarate; 00551 } 00552 return phy_params.dwell_limit_datarate; 00553 } 00554 00555 uint8_t LoRaPHY::get_default_tx_datarate() 00556 { 00557 return phy_params.default_datarate; 00558 } 00559 00560 uint8_t LoRaPHY::get_default_max_tx_datarate() 00561 { 00562 return phy_params.default_max_datarate; 00563 } 00564 00565 uint8_t LoRaPHY::get_default_tx_power() 00566 { 00567 return phy_params.default_tx_power; 00568 } 00569 00570 uint8_t LoRaPHY::get_max_payload(uint8_t datarate, bool use_repeater) 00571 { 00572 uint8_t *payload_table = NULL; 00573 00574 if (use_repeater) { 00575 // if (datarate >= phy_params.payloads_with_repeater.size) { 00576 // //TODO: Can this ever happen? If yes, should we return 0? 00577 // } 00578 payload_table = (uint8_t *) phy_params.payloads_with_repeater.table; 00579 } else { 00580 payload_table = (uint8_t *) phy_params.payloads.table; 00581 } 00582 00583 return payload_table[datarate]; 00584 } 00585 00586 uint16_t LoRaPHY::get_maximum_frame_counter_gap() 00587 { 00588 return phy_params.max_fcnt_gap; 00589 } 00590 00591 uint32_t LoRaPHY::get_ack_timeout() 00592 { 00593 uint16_t ack_timeout_rnd = phy_params.ack_timeout_rnd; 00594 return (phy_params.ack_timeout 00595 + get_random(-ack_timeout_rnd, ack_timeout_rnd)); 00596 } 00597 00598 uint32_t LoRaPHY::get_default_rx2_frequency() 00599 { 00600 return phy_params.rx_window2_frequency; 00601 } 00602 00603 uint8_t LoRaPHY::get_default_rx2_datarate() 00604 { 00605 return phy_params.rx_window2_datarate; 00606 } 00607 00608 uint16_t *LoRaPHY::get_channel_mask(bool get_default) 00609 { 00610 if (get_default) { 00611 return phy_params.channels.default_mask; 00612 } 00613 return phy_params.channels.mask; 00614 } 00615 00616 uint8_t LoRaPHY::get_max_nb_channels() 00617 { 00618 return phy_params.max_channel_cnt; 00619 } 00620 00621 channel_params_t *LoRaPHY::get_phy_channels() 00622 { 00623 return phy_params.channels.channel_list; 00624 } 00625 00626 bool LoRaPHY::is_custom_channel_plan_supported() 00627 { 00628 return phy_params.custom_channelplans_supported; 00629 } 00630 00631 void LoRaPHY::restore_default_channels() 00632 { 00633 // Restore channels default mask 00634 for (uint8_t i = 0; i < phy_params.channels.mask_size; i++) { 00635 phy_params.channels.mask[i] |= phy_params.channels.default_mask[i]; 00636 } 00637 } 00638 00639 bool LoRaPHY::verify_rx_datarate(uint8_t datarate) 00640 { 00641 if (is_datarate_supported(datarate)) { 00642 if (phy_params.dl_dwell_time_setting == 0) { 00643 //TODO: Check this! datarate must be same as minimum! Can be compared directly if OK 00644 return val_in_range(datarate, 00645 phy_params.min_rx_datarate, 00646 phy_params.max_rx_datarate); 00647 } else { 00648 return val_in_range(datarate, 00649 phy_params.dwell_limit_datarate, 00650 phy_params.max_rx_datarate); 00651 } 00652 } 00653 return false; 00654 } 00655 00656 bool LoRaPHY::verify_tx_datarate(uint8_t datarate, bool use_default) 00657 { 00658 if (!is_datarate_supported(datarate)) { 00659 return false; 00660 } 00661 00662 if (use_default) { 00663 return val_in_range(datarate, phy_params.default_datarate, 00664 phy_params.default_max_datarate); 00665 } else if (phy_params.ul_dwell_time_setting == 0) { 00666 return val_in_range(datarate, phy_params.min_tx_datarate, 00667 phy_params.max_tx_datarate); 00668 } else { 00669 return val_in_range(datarate, phy_params.dwell_limit_datarate, 00670 phy_params.max_tx_datarate); 00671 } 00672 } 00673 00674 bool LoRaPHY::verify_tx_power(uint8_t tx_power) 00675 { 00676 return val_in_range(tx_power, phy_params.max_tx_power, 00677 phy_params.min_tx_power); 00678 } 00679 00680 bool LoRaPHY::verify_duty_cycle(bool cycle) 00681 { 00682 if (cycle == phy_params.duty_cycle_enabled) { 00683 return true; 00684 } 00685 return false; 00686 } 00687 00688 bool LoRaPHY::verify_nb_join_trials(uint8_t nb_join_trials) 00689 { 00690 if (nb_join_trials < MBED_CONF_LORA_NB_TRIALS) { 00691 return false; 00692 } 00693 return true; 00694 } 00695 00696 void LoRaPHY::apply_cf_list(const uint8_t *payload, uint8_t size) 00697 { 00698 // if the underlying PHY doesn't support CF-List, ignore the request 00699 if (!phy_params.cflist_supported) { 00700 return; 00701 } 00702 00703 channel_params_t new_channel; 00704 00705 // Setup default datarate range 00706 new_channel.dr_range.value = (phy_params.default_max_datarate << 4) | 00707 phy_params.default_datarate; 00708 00709 // Size of the optional CF list 00710 if (size != 16) { 00711 return; 00712 } 00713 00714 // Last byte is RFU, don't take it into account 00715 // NOTE: Currently the PHY layers supported by LoRaWAN who accept a CF-List 00716 // define first 2 or 3 channels as default channels. this function is 00717 // written keeping that in mind. If there would be a PHY in the future that 00718 // accepts CF-list but have haphazard allocation of default channels, we 00719 // should override this function in the implementation of that particular 00720 // PHY. 00721 for (uint8_t i = 0, channel_id = phy_params.default_channel_cnt; 00722 channel_id < phy_params.max_channel_cnt; i += 3, channel_id++) { 00723 if (channel_id < (phy_params.cflist_channel_cnt + phy_params.default_channel_cnt)) { 00724 // Channel frequency 00725 new_channel.frequency = (uint32_t) payload[i]; 00726 new_channel.frequency |= ((uint32_t) payload[i + 1] << 8); 00727 new_channel.frequency |= ((uint32_t) payload[i + 2] << 16); 00728 new_channel.frequency *= 100; 00729 00730 // Initialize alternative frequency to 0 00731 new_channel.rx1_frequency = 0; 00732 } else { 00733 new_channel.frequency = 0; 00734 new_channel.dr_range.value = 0; 00735 new_channel.rx1_frequency = 0; 00736 } 00737 00738 if (new_channel.frequency != 0) { 00739 //lookup for band 00740 new_channel.band = lookup_band_for_frequency(new_channel.frequency); 00741 00742 // Try to add channel 00743 add_channel(&new_channel, channel_id); 00744 } else { 00745 remove_channel(channel_id); 00746 } 00747 } 00748 } 00749 00750 00751 bool LoRaPHY::get_next_ADR(bool restore_channel_mask, int8_t &dr_out, 00752 int8_t &tx_power_out, uint32_t &adr_ack_cnt) 00753 { 00754 bool set_adr_ack_bit = false; 00755 00756 uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay; 00757 00758 if (dr_out == phy_params.min_tx_datarate) { 00759 adr_ack_cnt = 0; 00760 return set_adr_ack_bit; 00761 } 00762 00763 if (adr_ack_cnt < phy_params.adr_ack_limit) { 00764 return set_adr_ack_bit; 00765 } 00766 00767 // ADR ack counter is larger than ADR-ACK-LIMIT 00768 set_adr_ack_bit = true; 00769 tx_power_out = phy_params.max_tx_power; 00770 00771 if (adr_ack_cnt >= ack_limit_plus_delay) { 00772 if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) { 00773 // Decrease the datarate 00774 dr_out = get_next_lower_tx_datarate(dr_out); 00775 00776 if (dr_out == phy_params.min_tx_datarate) { 00777 // We must set adrAckReq to false as soon as we reach the lowest datarate 00778 set_adr_ack_bit = false; 00779 if (restore_channel_mask) { 00780 // Re-enable default channels 00781 restore_default_channels(); 00782 } 00783 } 00784 } 00785 } 00786 00787 return set_adr_ack_bit; 00788 } 00789 00790 void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, 00791 uint32_t rx_error, 00792 rx_config_params_t *rx_conf_params) 00793 { 00794 double t_symbol = 0.0; 00795 00796 // Get the datarate, perform a boundary check 00797 rx_conf_params->datarate = MIN(datarate, phy_params.max_rx_datarate); 00798 00799 rx_conf_params->bandwidth = get_bandwidth(rx_conf_params->datarate ); 00800 00801 if (phy_params.fsk_supported && rx_conf_params->datarate == phy_params.max_rx_datarate) { 00802 // FSK 00803 t_symbol = compute_symb_timeout_fsk(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate ]); 00804 } else { 00805 // LoRa 00806 t_symbol = compute_symb_timeout_lora(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate ], 00807 ((uint32_t *)phy_params.bandwidths.table)[rx_conf_params->datarate ]); 00808 } 00809 00810 if (rx_conf_params->rx_slot == RX_SLOT_WIN_1 ) { 00811 rx_conf_params->frequency = phy_params.channels.channel_list[rx_conf_params->channel ].frequency; 00812 } 00813 00814 00815 get_rx_window_params(t_symbol, min_rx_symbols, rx_error, RADIO_WAKEUP_TIME, 00816 &rx_conf_params->window_timeout , &rx_conf_params->window_offset ); 00817 } 00818 00819 bool LoRaPHY::rx_config(rx_config_params_t *rx_conf) 00820 { 00821 radio_modems_t modem; 00822 uint8_t dr = rx_conf->datarate ; 00823 uint8_t max_payload = 0; 00824 uint8_t phy_dr = 0; 00825 uint32_t frequency = rx_conf->frequency ; 00826 00827 if (rx_conf->rx_slot == RX_SLOT_WIN_1 ) { 00828 // Apply window 1 frequency 00829 frequency = phy_params.channels.channel_list[rx_conf->channel ].frequency; 00830 // Apply the alternative RX 1 window frequency, if it is available 00831 if (phy_params.channels.channel_list[rx_conf->channel ].rx1_frequency != 0) { 00832 frequency = phy_params.channels.channel_list[rx_conf->channel ].rx1_frequency; 00833 } 00834 } 00835 00836 // Read the physical datarate from the datarates table 00837 uint8_t *datarate_table = (uint8_t *) phy_params.datarates.table; 00838 uint8_t *payload_table = (uint8_t *) phy_params.payloads.table; 00839 uint8_t *payload_with_repeater_table = (uint8_t *) phy_params.payloads_with_repeater.table; 00840 00841 phy_dr = datarate_table[dr]; 00842 00843 _radio->lock(); 00844 00845 _radio->set_channel(frequency); 00846 00847 // Radio configuration 00848 if (dr == DR_7 && phy_params.fsk_supported) { 00849 modem = MODEM_FSK; 00850 _radio->set_rx_config(modem, 50000, phy_dr * 1000, 0, 83333, 5, 00851 rx_conf->window_timeout , false, 0, true, 0, 0, 00852 false, rx_conf->is_rx_continuous ); 00853 } else { 00854 modem = MODEM_LORA; 00855 _radio->set_rx_config(modem, rx_conf->bandwidth , phy_dr, 1, 0, 00856 MBED_CONF_LORA_DOWNLINK_PREAMBLE_LENGTH, 00857 rx_conf->window_timeout , false, 0, false, 0, 0, 00858 true, rx_conf->is_rx_continuous ); 00859 } 00860 00861 if (rx_conf->is_repeater_supported ) { 00862 max_payload = payload_with_repeater_table[dr]; 00863 } else { 00864 max_payload = payload_table[dr]; 00865 } 00866 00867 _radio->set_max_payload_length(modem, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); 00868 00869 _radio->unlock(); 00870 00871 return true; 00872 } 00873 00874 bool LoRaPHY::tx_config(tx_config_params_t *tx_conf, int8_t *tx_power, 00875 lorawan_time_t *tx_toa) 00876 { 00877 radio_modems_t modem; 00878 int8_t phy_dr = ((uint8_t *)phy_params.datarates.table)[tx_conf->datarate]; 00879 channel_params_t *list = phy_params.channels.channel_list; 00880 uint8_t band_idx = list[tx_conf->channel].band; 00881 band_t *bands = (band_t *)phy_params.bands.table; 00882 00883 // limit TX power if set to too much 00884 tx_conf->tx_power = MAX(tx_conf->tx_power, bands[band_idx].max_tx_pwr ); 00885 00886 uint8_t bandwidth = get_bandwidth(tx_conf->datarate); 00887 int8_t phy_tx_power = 0; 00888 00889 // Calculate physical TX power 00890 phy_tx_power = compute_tx_power(tx_conf->tx_power, tx_conf->max_eirp, 00891 tx_conf->antenna_gain); 00892 00893 _radio->lock(); 00894 00895 // Setup the radio frequency 00896 _radio->set_channel(list[tx_conf->channel].frequency); 00897 00898 if (tx_conf->datarate == phy_params.max_tx_datarate) { 00899 // High Speed FSK channel 00900 modem = MODEM_FSK; 00901 _radio->set_tx_config(modem, phy_tx_power, 25000, bandwidth, 00902 phy_dr * 1000, 0, 5, false, true, 0, 0, false, 00903 3000); 00904 } else { 00905 modem = MODEM_LORA; 00906 _radio->set_tx_config(modem, phy_tx_power, 0, bandwidth, phy_dr, 1, 00907 MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH, 00908 false, true, 0, 0, false, 3000); 00909 } 00910 00911 // Setup maximum payload lenght of the radio driver 00912 _radio->set_max_payload_length(modem, tx_conf->pkt_len); 00913 // Get the time-on-air of the next tx frame 00914 *tx_toa = _radio->time_on_air(modem, tx_conf->pkt_len); 00915 00916 _radio->unlock(); 00917 00918 *tx_power = tx_conf->tx_power; 00919 00920 return true; 00921 } 00922 00923 uint8_t LoRaPHY::link_ADR_request(adr_req_params_t *link_adr_req, 00924 int8_t *dr_out, int8_t *tx_power_out, 00925 uint8_t *nb_rep_out, uint8_t *nb_bytes_processed) 00926 { 00927 uint8_t status = 0x07; 00928 link_adr_params_t adr_settings; 00929 uint8_t next_index = 0; 00930 uint8_t bytes_processed = 0; 00931 00932 // rather than dynamically allocating memory, we choose to set 00933 // a channel mask list size of unity here as we know that all 00934 // the PHY layer implementations who have more than 16 channels, i.e., 00935 // have channel mask list size more than unity, override this method. 00936 uint16_t temp_channel_mask[1] = {0}; 00937 00938 verify_adr_params_t verify_params; 00939 00940 while (bytes_processed < link_adr_req->payload_size) { 00941 // Get ADR request parameters 00942 next_index = parse_link_ADR_req(&(link_adr_req->payload [bytes_processed]), 00943 &adr_settings); 00944 00945 if (next_index == 0) { 00946 break; // break loop, since no more request has been found 00947 } 00948 00949 // Update bytes processed 00950 bytes_processed += next_index; 00951 00952 // Revert status, as we only check the last ADR request for the channel mask KO 00953 status = 0x07; 00954 00955 // Setup temporary channels mask 00956 temp_channel_mask[0] = adr_settings.channel_mask; 00957 00958 // Verify channels mask 00959 if (adr_settings.ch_mask_ctrl == 0 && temp_channel_mask[0] == 0) { 00960 status &= 0xFE; // Channel mask KO 00961 } 00962 00963 // channel mask applies to first 16 channels 00964 if (adr_settings.ch_mask_ctrl == 0 || adr_settings.ch_mask_ctrl == 6) { 00965 00966 for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { 00967 00968 // turn on all channels if channel mask control is 6 00969 if (adr_settings.ch_mask_ctrl == 6) { 00970 if (phy_params.channels.channel_list[i].frequency != 0) { 00971 mask_bit_set(temp_channel_mask, i); 00972 } 00973 00974 continue; 00975 } 00976 00977 // if channel mask control is 0, we test the bits and 00978 // frequencies and change the status if we find a discrepancy 00979 if ((mask_bit_test(temp_channel_mask, i)) && 00980 (phy_params.channels.channel_list[i].frequency == 0)) { 00981 // Trying to enable an undefined channel 00982 status &= 0xFE; // Channel mask KO 00983 } 00984 } 00985 } else { 00986 // Channel mask control applies to RFUs 00987 status &= 0xFE; // Channel mask KO 00988 } 00989 } 00990 00991 if (is_datarate_supported(adr_settings.datarate)) { 00992 verify_params.status = status; 00993 00994 verify_params.adr_enabled = link_adr_req->adr_enabled ; 00995 verify_params.current_datarate = link_adr_req->current_datarate ; 00996 verify_params.current_tx_power = link_adr_req->current_tx_power ; 00997 verify_params.current_nb_rep = link_adr_req->current_nb_trans ; 00998 00999 verify_params.datarate = adr_settings.datarate; 01000 verify_params.tx_power = adr_settings.tx_power; 01001 verify_params.nb_rep = adr_settings.nb_rep; 01002 01003 01004 verify_params.channel_mask = temp_channel_mask; 01005 01006 // Verify the parameters and update, if necessary 01007 status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, 01008 &adr_settings.tx_power, &adr_settings.nb_rep); 01009 } else { 01010 status &= 0xFD; // Datarate KO 01011 } 01012 01013 // Update channelsMask if everything is correct 01014 if (status == 0x07) { 01015 // Set the channels mask to a default value 01016 memset(phy_params.channels.mask, 0, 01017 sizeof(uint16_t)*phy_params.channels.mask_size); 01018 01019 // Update the channels mask 01020 copy_channel_mask(phy_params.channels.mask, temp_channel_mask, 01021 phy_params.channels.mask_size); 01022 } 01023 01024 // Update status variables 01025 *dr_out = adr_settings.datarate; 01026 *tx_power_out = adr_settings.tx_power; 01027 *nb_rep_out = adr_settings.nb_rep; 01028 *nb_bytes_processed = bytes_processed; 01029 01030 return status; 01031 } 01032 01033 uint8_t LoRaPHY::accept_rx_param_setup_req(rx_param_setup_req_t *params) 01034 { 01035 uint8_t status = 0x07; 01036 01037 if (lookup_band_for_frequency(params->frequency) < 0) { 01038 status &= 0xFE; 01039 } 01040 01041 // Verify radio frequency 01042 if (_radio->check_rf_frequency(params->frequency) == false) { 01043 status &= 0xFE; // Channel frequency KO 01044 } 01045 01046 // Verify datarate 01047 if (val_in_range(params->datarate, phy_params.min_rx_datarate, 01048 phy_params.max_rx_datarate) == 0) { 01049 status &= 0xFD; // Datarate KO 01050 } 01051 01052 // Verify datarate offset 01053 if (val_in_range(params->dr_offset, phy_params.min_rx1_dr_offset, 01054 phy_params.max_rx1_dr_offset) == 0) { 01055 status &= 0xFB; // Rx1DrOffset range KO 01056 } 01057 01058 return status; 01059 } 01060 01061 bool LoRaPHY::accept_tx_param_setup_req(uint8_t ul_dwell_time, uint8_t dl_dwell_time) 01062 { 01063 if (phy_params.accept_tx_param_setup_req) { 01064 phy_params.ul_dwell_time_setting = ul_dwell_time; 01065 phy_params.dl_dwell_time_setting = dl_dwell_time; 01066 } 01067 01068 return phy_params.accept_tx_param_setup_req; 01069 } 01070 01071 int LoRaPHY::lookup_band_for_frequency(uint32_t freq) const 01072 { 01073 // check all sub bands (if there are sub-bands) to check if the given 01074 // frequency falls into any of the frequency ranges 01075 01076 for (int band = 0; band < phy_params.bands.size; band++) { 01077 if (verify_frequency_for_band(freq, band)) { 01078 return band; 01079 } 01080 } 01081 01082 return -1; 01083 } 01084 01085 bool LoRaPHY::verify_frequency_for_band(uint32_t freq, uint8_t band) const 01086 { 01087 band_t *bands_table = (band_t *)phy_params.bands.table; 01088 01089 if (freq <= bands_table[band].higher_band_freq 01090 && freq >= bands_table[band].lower_band_freq) { 01091 return true; 01092 } else { 01093 return false; 01094 } 01095 } 01096 01097 uint8_t LoRaPHY::dl_channel_request(uint8_t channel_id, uint32_t rx1_frequency) 01098 { 01099 if (!phy_params.dl_channel_req_supported) { 01100 return 0; 01101 } 01102 01103 uint8_t status = 0x03; 01104 01105 // Verify if the frequency is supported 01106 int band = lookup_band_for_frequency(rx1_frequency); 01107 if (band < 0) { 01108 status &= 0xFE; 01109 } 01110 01111 // Verify if an uplink frequency exists 01112 if (phy_params.channels.channel_list[channel_id].frequency == 0) { 01113 status &= 0xFD; 01114 } 01115 01116 // Apply Rx1 frequency, if the status is OK 01117 if (status == 0x03) { 01118 phy_params.channels.channel_list[channel_id].rx1_frequency = rx1_frequency; 01119 } 01120 01121 return status; 01122 } 01123 01124 /** 01125 * Alternate datarate algorithm for join requests. 01126 * - We check from the PHY and take note of total 01127 * number of data rates available upto the default data rate for 01128 * default channels. 01129 * 01130 * - Application sets a total number of re-trials for a Join Request, i.e., 01131 * MBED_CONF_LORA_NB_TRIALS. So MAC layer will send us a counter 01132 * nb_trials < MBED_CONF_LORA_NB_TRIALS which is the current number of trial. 01133 * 01134 * - We roll over total available datarates and pick one according to the 01135 * number of trial sequentially. 01136 * 01137 * - We always start from the Default Data rate and and set the next lower 01138 * data rate for every iteration. 01139 * 01140 * - MAC layer will stop when maximum number of re-trials, i.e., 01141 * MBED_CONF_LORA_NB_TRIALS is achieved. 01142 * 01143 * So essentially MBED_CONF_LORA_NB_TRIALS should be a multiple of range of 01144 * data rates available. For example, in EU868 band, default max. data rate is 01145 * DR_5 and min. data rate is DR_0, so total data rates available are 6. 01146 * 01147 * Hence MBED_CONF_LORA_NB_TRIALS should be a multiple of 6. Setting, 01148 * MBED_CONF_LORA_NB_TRIALS = 6 would mean that every data rate will be tried 01149 * exactly once starting from the largest and finishing at the smallest. 01150 * 01151 * PHY layers which do not have datarates scheme similar to EU band will ofcourse 01152 * override this method. 01153 */ 01154 int8_t LoRaPHY::get_alternate_DR(uint8_t nb_trials) 01155 { 01156 int8_t datarate = 0; 01157 uint8_t total_nb_datrates = (phy_params.default_max_datarate - phy_params.min_tx_datarate) + 1; 01158 01159 uint8_t res = nb_trials % total_nb_datrates; 01160 01161 if (res == 0) { 01162 datarate = phy_params.min_tx_datarate; 01163 } else if (res == 1) { 01164 datarate = phy_params.default_max_datarate; 01165 } else { 01166 datarate = (phy_params.default_max_datarate - res) + 1; 01167 } 01168 01169 return datarate; 01170 } 01171 01172 void LoRaPHY::calculate_backoff(bool joined, bool last_tx_was_join_req, bool dc_enabled, uint8_t channel, 01173 lorawan_time_t elapsed_time, lorawan_time_t tx_toa) 01174 { 01175 band_t *band_table = (band_t *) phy_params.bands.table; 01176 channel_params_t *channel_list = phy_params.channels.channel_list; 01177 01178 uint8_t band_idx = channel_list[channel].band; 01179 uint16_t duty_cycle = band_table[band_idx].duty_cycle ; 01180 uint16_t join_duty_cycle = 0; 01181 01182 // Reset time-off to initial value. 01183 band_table[band_idx].off_time = 0; 01184 01185 if (MBED_CONF_LORA_DUTY_CYCLE_ON_JOIN && joined == false) { 01186 // Get the join duty cycle 01187 if (elapsed_time < 3600000) { 01188 join_duty_cycle = BACKOFF_DC_1_HOUR; 01189 } else if (elapsed_time < (3600000 + 36000000)) { 01190 join_duty_cycle = BACKOFF_DC_10_HOURS; 01191 } else { 01192 join_duty_cycle = BACKOFF_DC_24_HOURS; 01193 } 01194 01195 // Apply the most restricting duty cycle 01196 duty_cycle = MAX(duty_cycle, join_duty_cycle); 01197 } 01198 01199 // No back-off if the last frame was not a join request and when the 01200 // duty cycle is not enabled 01201 if (dc_enabled == false && last_tx_was_join_req == false) { 01202 band_table[band_idx].off_time = 0; 01203 } else { 01204 // Apply band time-off. 01205 band_table[band_idx].off_time = tx_toa * duty_cycle - tx_toa; 01206 } 01207 } 01208 01209 lorawan_status_t LoRaPHY::set_next_channel(channel_selection_params_t *params, 01210 uint8_t *channel, lorawan_time_t *time, 01211 lorawan_time_t *aggregate_timeoff) 01212 { 01213 uint8_t channel_count = 0; 01214 uint8_t delay_tx = 0; 01215 01216 // Note here that the PHY layer implementations which have more than 01217 // 16 channels at their disposal, override this function. That's why 01218 // it is safe to assume that we are dealing with a block of 16 channels 01219 // i.e., EU like implementations. So rather than dynamically allocating 01220 // memory we chose to use a magic number of 16 01221 uint8_t enabled_channels[16]; 01222 01223 memset(enabled_channels, 0xFF, sizeof(uint8_t) * 16); 01224 01225 lorawan_time_t next_tx_delay = 0; 01226 band_t *band_table = (band_t *) phy_params.bands.table; 01227 01228 if (num_active_channels(phy_params.channels.mask, 0, 01229 phy_params.channels.mask_size) == 0) { 01230 01231 // Reactivate default channels 01232 copy_channel_mask(phy_params.channels.mask, 01233 phy_params.channels.default_mask, 01234 phy_params.channels.mask_size); 01235 } 01236 01237 if (params->aggregate_timeoff 01238 <= _lora_time->get_elapsed_time(params->last_aggregate_tx_time)) { 01239 // Reset Aggregated time off 01240 *aggregate_timeoff = 0; 01241 01242 // Update bands Time OFF 01243 next_tx_delay = update_band_timeoff(params->joined, 01244 params->dc_enabled, 01245 band_table, phy_params.bands.size); 01246 01247 // Search how many channels are enabled 01248 channel_count = enabled_channel_count(params->current_datarate, 01249 phy_params.channels.mask, 01250 enabled_channels, &delay_tx); 01251 } else { 01252 delay_tx++; 01253 next_tx_delay = params->aggregate_timeoff - 01254 _lora_time->get_elapsed_time(params->last_aggregate_tx_time); 01255 } 01256 01257 if (channel_count > 0) { 01258 // We found a valid channel 01259 *channel = enabled_channels[get_random(0, channel_count - 1)]; 01260 *time = 0; 01261 return LORAWAN_STATUS_OK; 01262 } 01263 01264 if (delay_tx > 0) { 01265 // Delay transmission due to AggregatedTimeOff or to a band time off 01266 *time = next_tx_delay; 01267 return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED; 01268 } 01269 01270 // Datarate not supported by any channel, restore defaults 01271 copy_channel_mask(phy_params.channels.mask, 01272 phy_params.channels.default_mask, 01273 phy_params.channels.mask_size); 01274 *time = 0; 01275 return LORAWAN_STATUS_NO_CHANNEL_FOUND; 01276 } 01277 01278 lorawan_status_t LoRaPHY::add_channel(const channel_params_t *new_channel, 01279 uint8_t id) 01280 { 01281 bool dr_invalid = false; 01282 bool freq_invalid = false; 01283 01284 if (!phy_params.custom_channelplans_supported 01285 || id >= phy_params.max_channel_cnt) { 01286 01287 return LORAWAN_STATUS_PARAMETER_INVALID; 01288 } 01289 01290 // Validate the datarate range 01291 if (val_in_range(new_channel->dr_range.fields.min, 01292 phy_params.min_tx_datarate, 01293 phy_params.max_tx_datarate) == 0) { 01294 dr_invalid = true; 01295 } 01296 01297 if (val_in_range(new_channel->dr_range.fields.max, phy_params.min_tx_datarate, 01298 phy_params.max_tx_datarate) == 0) { 01299 dr_invalid = true; 01300 } 01301 01302 if (new_channel->dr_range.fields.min > new_channel->dr_range.fields.max) { 01303 dr_invalid = true; 01304 } 01305 01306 // Default channels don't accept all values 01307 if (id < phy_params.default_channel_cnt) { 01308 // Validate the datarate range for min: must be DR_0 01309 if (new_channel->dr_range.fields.min != DR_0) { 01310 dr_invalid = true; 01311 } 01312 01313 // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE 01314 if (val_in_range(new_channel->dr_range.fields.max, 01315 phy_params.default_max_datarate, 01316 phy_params.max_tx_datarate) == 0) { 01317 dr_invalid = true; 01318 } 01319 01320 // We are not allowed to change the frequency 01321 if (new_channel->frequency != phy_params.channels.channel_list[id].frequency) { 01322 freq_invalid = true; 01323 } 01324 } 01325 01326 // Check frequency 01327 if (!freq_invalid) { 01328 if (new_channel->band >= phy_params.bands.size 01329 || verify_frequency_for_band(new_channel->frequency, 01330 new_channel->band) == false) { 01331 freq_invalid = true; 01332 } 01333 } 01334 01335 // Check status 01336 if (dr_invalid && freq_invalid) { 01337 return LORAWAN_STATUS_FREQ_AND_DR_INVALID; 01338 } 01339 01340 if (dr_invalid) { 01341 return LORAWAN_STATUS_DATARATE_INVALID; 01342 } 01343 01344 if (freq_invalid) { 01345 return LORAWAN_STATUS_FREQUENCY_INVALID; 01346 } 01347 01348 memmove(&(phy_params.channels.channel_list[id]), new_channel, sizeof(channel_params_t)); 01349 01350 phy_params.channels.channel_list[id].band = new_channel->band; 01351 01352 mask_bit_set(phy_params.channels.mask, id); 01353 01354 return LORAWAN_STATUS_OK; 01355 } 01356 01357 bool LoRaPHY::remove_channel(uint8_t channel_id) 01358 { 01359 // upper layers are checking if the custom channel planning is supported or 01360 // not. So we don't need to worry about that 01361 if (mask_bit_test(phy_params.channels.default_mask, channel_id)) { 01362 return false; 01363 } 01364 01365 01366 // Remove the channel from the list of channels 01367 const channel_params_t empty_channel = { 0, 0, {0}, 0 }; 01368 phy_params.channels.channel_list[channel_id] = empty_channel; 01369 01370 return disable_channel(phy_params.channels.mask, channel_id, 01371 phy_params.max_channel_cnt); 01372 } 01373 01374 void LoRaPHY::set_tx_cont_mode(cw_mode_params_t *params, uint32_t given_frequency) 01375 { 01376 band_t *bands_table = (band_t *) phy_params.bands.table; 01377 channel_params_t *channels = phy_params.channels.channel_list; 01378 01379 if (params->tx_power > bands_table[channels[params->channel ].band].max_tx_pwr ) { 01380 params->tx_power = bands_table[channels[params->channel ].band].max_tx_pwr ; 01381 } 01382 01383 int8_t phy_tx_power = 0; 01384 uint32_t frequency = 0; 01385 01386 if (given_frequency == 0) { 01387 frequency = channels[params->channel ].frequency; 01388 } else { 01389 frequency = given_frequency; 01390 } 01391 01392 // Calculate physical TX power 01393 if (params->max_eirp > 0 && params->antenna_gain > 0) { 01394 phy_tx_power = compute_tx_power(params->tx_power , params->max_eirp , 01395 params->antenna_gain ); 01396 } else { 01397 phy_tx_power = params->tx_power ; 01398 } 01399 01400 _radio->lock(); 01401 _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout ); 01402 _radio->unlock(); 01403 } 01404 01405 uint8_t LoRaPHY::apply_DR_offset(int8_t dr, int8_t dr_offset) 01406 { 01407 int8_t datarate = dr - dr_offset; 01408 01409 if (datarate < 0) { 01410 datarate = phy_params.min_tx_datarate; 01411 } 01412 01413 return datarate; 01414 } 01415 01416
Generated on Tue Jul 12 2022 15:15:48 by
