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.
LoRaPHY.h
00001 /** 00002 * @file LoRaPHY.h 00003 * 00004 * @brief An abstract class providing radio object to children and 00005 * provide base for implementing LoRa PHY layer 00006 * 00007 * \code 00008 * ______ _ 00009 * / _____) _ | | 00010 * ( (____ _____ ____ _| |_ _____ ____| |__ 00011 * \____ \| ___ | (_ _) ___ |/ ___) _ \ 00012 * _____) ) ____| | | || |_| ____( (___| | | | 00013 * (______/|_____)_|_|_| \__)_____)\____)_| |_| 00014 * (C)2013 Semtech 00015 * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00016 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00017 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00018 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00019 * embedded.connectivity.solutions=============== 00020 * 00021 * \endcode 00022 * 00023 * Description: LoRa PHY layer 00024 * 00025 * License: Revised BSD License, see LICENSE.TXT file include in the project 00026 * 00027 * Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 00028 * 00029 * Copyright (c) 2017, Arm Limited and affiliates. 00030 * SPDX-License-Identifier: BSD-3-Clause 00031 * 00032 */ 00033 00034 #ifndef MBED_OS_LORAPHY_BASE_ 00035 #define MBED_OS_LORAPHY_BASE_ 00036 00037 #include "lorawan/LoRaRadio.h" 00038 #include "lorawan/system/LoRaWANTimer.h" 00039 #include "lorawan/lorastack/phy/lora_phy_ds.h" 00040 #include "platform/NonCopyable.h" 00041 00042 class LoRaPHY : private mbed::NonCopyable<LoRaPHY> { 00043 00044 public: 00045 virtual ~LoRaPHY(); 00046 00047 /** Stores a reference to Radio object. 00048 * 00049 * Application is responsible for constructing a 'LoRaRadio' object 00050 * which is passed down to the PHY layer. 00051 * 00052 * @param radio a reference to radio driver object 00053 */ 00054 void set_radio_instance(LoRaRadio& radio); 00055 00056 /** Puts radio in sleep mode. 00057 * 00058 * Requests the radio driver to enter sleep mode. 00059 */ 00060 void put_radio_to_sleep(void); 00061 00062 /** Puts radio in standby mode. 00063 * 00064 * Requests the radio driver to enter standby mode. 00065 */ 00066 void put_radio_to_standby(void); 00067 00068 /** Puts radio in receive mode. 00069 * 00070 * Requests the radio driver to enter receive mode for a given time or to 00071 * enter continuous reception mode. 00072 * 00073 * @param is_rx_continuous if true, sets the radio to enter continuous 00074 * reception mode. 00075 * 00076 * @param max_rx_window duration of receive window 00077 */ 00078 void setup_rx_window(bool is_rx_continuous, uint32_t max_rx_window); 00079 00080 /** Delegates MAC layer request to transmit packet. 00081 * 00082 * @param buf a pointer to the data which needs to be transmitted 00083 * 00084 * @param size size of the data in bytes 00085 */ 00086 void handle_send(uint8_t *buf, uint8_t size); 00087 00088 /** Enables/Disables public network mode. 00089 * 00090 * Public and private LoRaWAN network constitute different preambles and 00091 * Net IDs. This API isused to tell the radio which network mode is in use. 00092 * 00093 * @param set true or false 00094 */ 00095 void setup_public_network_mode(bool set); 00096 00097 /** Provides a random number from radio. 00098 * 00099 * Returns a 32-bit random unsigned integer value based upon RSSI 00100 * measurements. 00101 * 00102 * @return a 32-bit long random number 00103 * 00104 */ 00105 uint32_t get_radio_rng(); 00106 00107 /** 00108 * @brief calculate_backoff Calculates and applies duty cycle back-off time. 00109 * Explicitly updates the band time-off. 00110 * 00111 * @param joined Set to true, if the node has already joined a network, otherwise false. 00112 * @param last_tx_was_join_req Set to true, if the last uplink was a join request. 00113 * @param dc_enabled Set to true, if the duty cycle is enabled, otherwise false. 00114 * @param channel The current channel index. 00115 * @param elapsed_time Elapsed time since the start of the node. 00116 * @param tx_toa Time-on-air of the last transmission. 00117 */ 00118 void calculate_backoff(bool joined, bool last_tx_was_join_req, bool dc_enabled, uint8_t channel, 00119 lorawan_time_t elapsed_time, lorawan_time_t tx_toa); 00120 00121 /** 00122 * Tests if a channel is on or off in the channel mask 00123 */ 00124 bool mask_bit_test(const uint16_t *mask, unsigned bit); 00125 00126 /** 00127 * Tests if a channel is on or off in the channel mask 00128 */ 00129 void mask_bit_set(uint16_t *mask, unsigned bit); 00130 00131 /** 00132 * Tests if a channel is on or off in the channel mask 00133 */ 00134 void mask_bit_clear(uint16_t *mask, unsigned bit); 00135 00136 /** Entertain a new channel request MAC command. 00137 * 00138 * MAC command subsystem processes the new channel request coming form 00139 * the network server and then MAC layer asks the PHY layer to entertain 00140 * the request. 00141 * 00142 * @param channel_id The channel ID. 00143 * @param new_channel A pointer to the new channel's parameters. 00144 * 00145 * @return bit mask, according to the LoRaWAN spec 1.0.2. 00146 */ 00147 virtual uint8_t request_new_channel(int8_t channel_id, channel_params_t * new_channel); 00148 00149 /** Process PHY layer state after a successful transmission. 00150 * @brief set_last_tx_done Updates times of the last transmission for the particular channel and 00151 * band upon which last transmission took place. 00152 * @param channel The channel in use. 00153 * @param joined Boolean telling if node has joined the network. 00154 * @param last_tx_done_time The last TX done time. 00155 */ 00156 virtual void set_last_tx_done(uint8_t channel, bool joined, lorawan_time_t last_tx_done_time); 00157 00158 /** Enables default channels only. 00159 * 00160 * Falls back to a channel mask where only default channels are enabled, all 00161 * other channels are disabled. 00162 */ 00163 virtual void restore_default_channels(); 00164 00165 /** Processes the incoming CF-list. 00166 * 00167 * Handles the payload containing CF-list and enables channels defined 00168 * therein. 00169 * 00170 * @param payload Payload to process. 00171 * @param size Size of the payload. 00172 * 00173 */ 00174 virtual void apply_cf_list(const uint8_t* payload, uint8_t size); 00175 00176 /** Calculates the next datarate to set, when ADR is on or off. 00177 * 00178 * @param restore_channel_mask A boolean set restore channel mask in case 00179 * of failure. 00180 * 00181 * @param dr_out The calculated datarate for the next TX. 00182 * 00183 * @param tx_power_out The TX power for the next TX. 00184 * 00185 * @param adr_ack_counter The calculated ADR acknowledgement counter. 00186 * 00187 * @return True, if an ADR request should be performed. 00188 */ 00189 bool get_next_ADR(bool restore_channel_mask, int8_t& dr_out, 00190 int8_t& tx_power_out, uint32_t& adr_ack_counter); 00191 00192 /** Configure radio reception. 00193 * 00194 * @param [in] config A pointer to the RX configuration. 00195 * 00196 * @param [out] datarate The datarate index set. 00197 * 00198 * @return True, if the configuration was applied successfully. 00199 */ 00200 virtual bool rx_config(rx_config_params_t * config, int8_t* datarate); 00201 00202 /** Computing Receive Windows 00203 * 00204 * For more details please consult the following document, chapter 3.1.2. 00205 * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf 00206 * or 00207 * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf 00208 * 00209 * Downlink start: T = Tx + 1s (+/- 20 us) 00210 * | 00211 * TRxEarly | TRxLate 00212 * | | | 00213 * | | +---+---+---+---+---+---+---+---+ 00214 * | | | Latest Rx window | 00215 * | | +---+---+---+---+---+---+---+---+ 00216 * | | | 00217 * +---+---+---+---+---+---+---+---+ 00218 * | Earliest Rx window | 00219 * +---+---+---+---+---+---+---+---+ 00220 * | 00221 * +---+---+---+---+---+---+---+---+ 00222 *Downlink preamble 8 symbols | | | | | | | | | 00223 * +---+---+---+---+---+---+---+---+ 00224 * 00225 * Worst case Rx window timings 00226 * 00227 * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME 00228 * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME 00229 * 00230 * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR 00231 * 00232 * RxOffset = ( TRxLate + TRxEarly ) / 2 00233 * 00234 * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR 00235 * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME 00236 * 00237 * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol. 00238 */ 00239 /*! 00240 * Computes the RX window timeout and offset. 00241 * 00242 * @param [in] datarate The RX window datarate index to be used. 00243 * 00244 * @param [in] min_rx_symbols The minimum number of symbols required to 00245 * detect an RX frame. 00246 * 00247 * @param [in] rx_error The maximum timing error of the receiver 00248 * in milliseconds. The receiver will turn on 00249 * in a [-rxError : +rxError] ms interval around 00250 * RxOffset. 00251 * 00252 * @param [out] rx_conf_params Pointer to the structure that needs to be 00253 * filled with receive window parameters. 00254 * 00255 */ 00256 virtual void compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, 00257 uint32_t rx_error, 00258 rx_config_params_t *rx_conf_params); 00259 00260 /** Configure radio transmission. 00261 * 00262 * @param [in] tx_config Structure containing tx parameters. 00263 * 00264 * @param [out] tx_power The TX power which will be set. 00265 * 00266 * @param [out] tx_toa The time-on-air of the frame. 00267 * 00268 * @return True, if the configuration was applied successfully. 00269 */ 00270 virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power, 00271 lorawan_time_t* tx_toa); 00272 00273 /** Processes a Link ADR Request. 00274 * 00275 * @param [in] params A pointer ADR request parameters. 00276 * 00277 * @param [out] dr_out The datarate applied. 00278 * 00279 * @param [out] tx_power_out The TX power applied. 00280 * 00281 * @param [out] nb_rep_out The number of repetitions to apply. 00282 * 00283 * @param [out] nb_bytes_parsed The number of bytes parsed. 00284 * 00285 * @return The status of the operation, according to the LoRaMAC specification. 00286 */ 00287 virtual uint8_t link_ADR_request(adr_req_params_t* params, 00288 int8_t* dr_out, int8_t* tx_power_out, 00289 uint8_t* nb_rep_out, 00290 uint8_t* nb_bytes_parsed); 00291 00292 /** Accept or rejects RxParamSetupReq MAC command 00293 * 00294 * The function processes a RX parameter setup request in response to 00295 * server MAC command for RX setup. 00296 * 00297 * @param [in] params A pointer to rx parameter setup request. 00298 * 00299 * @return The status of the operation, according to the LoRaWAN specification. 00300 */ 00301 virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params); 00302 00303 /** 00304 * @brief accept_tx_param_setup_req Makes decision whether to accept or reject TxParamSetupReq MAC command. 00305 * 00306 * @param ul_dwell_time The uplink dwell time. 00307 * @param dl_dwell_time The downlink dwell time. 00308 * 00309 * @return True to let the MAC know that the request is 00310 * accepted and MAC can apply TX parameters received 00311 * form Network Server. Otherwise false is returned. 00312 */ 00313 virtual bool accept_tx_param_setup_req(uint8_t ul_dwell_time, uint8_t dl_dwell_time); 00314 00315 /** Processes a DlChannelReq MAC command. 00316 * 00317 * @param channel_id The channel ID to add the frequency. 00318 * @param rx1_frequency The alternative frequency for the Rx1 window. 00319 * 00320 * @return The status of the operation, according to the LoRaWAN specification. 00321 */ 00322 virtual uint8_t dl_channel_request(uint8_t channel_id, uint32_t rx1_frequency); 00323 00324 /** Alternates the datarate of the channel for the join request. 00325 * 00326 * @param nb_trials Number of trials to be made on one given data rate. 00327 * 00328 * @return The datarate to apply . 00329 */ 00330 virtual int8_t get_alternate_DR(uint8_t nb_trials); 00331 00332 /** Searches and sets the next available channel. 00333 * 00334 * If there are multiple channels found available, one of them is selected 00335 * randomly. 00336 * 00337 * @param [in] nextChanParams Parameters for the next channel. 00338 * 00339 * @param [out] channel The next channel to use for TX. 00340 * 00341 * @param [out] time The time to wait for the next transmission according to the duty cycle. 00342 * 00343 * @param [out] aggregatedTimeOff Updates the aggregated time off. 00344 * 00345 * @return Function status [1: OK, 0: Unable to find a channel on the current datarate]. 00346 */ 00347 virtual lorawan_status_t set_next_channel(channel_selection_params_t* nextChanParams, 00348 uint8_t* channel, lorawan_time_t* time, 00349 lorawan_time_t* aggregatedTimeOff); 00350 00351 /** Adds a channel to the channel list. 00352 * 00353 * Verifies the channel parameters and if everything is found legitimate, 00354 * adds that particular channel to the channel list and updates the channel 00355 * mask. 00356 * 00357 * @param [in] new_channel A pointer to the parameters for the new channel. 00358 * @param [in] id Channel ID 00359 * 00360 * @return LORAWAN_STATUS_OK if everything goes fine, negative error code 00361 * otherwise. 00362 */ 00363 virtual lorawan_status_t add_channel(channel_params_t * new_channel, uint8_t id); 00364 00365 /** Removes a channel from the channel list. 00366 * 00367 * @param [in] channel_id Index of the channel to be removed 00368 * 00369 * @return True, if the channel was removed successfully. 00370 */ 00371 virtual bool remove_channel(uint8_t channel_id); 00372 00373 /** Puts the radio into continuous wave mode. 00374 * 00375 * @param [in] continuous_wave A pointer to the function parameters. 00376 * 00377 * @param [in] frequency Frequency to transmit at 00378 */ 00379 virtual void set_tx_cont_mode(cw_mode_params_t * continuous_wave, 00380 uint32_t frequency = 0); 00381 00382 /** Computes new data rate according to the given offset 00383 * 00384 * @param [in] dr The current datarate. 00385 * 00386 * @param [in] dr_offset The offset to be applied. 00387 * 00388 * @return The computed datarate. 00389 */ 00390 virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset); 00391 00392 /** 00393 * @brief reset_to_default_values resets some parameters to default values 00394 * @param params Pointer to MAC protocol parameters which will be reset 00395 * @param init If true, most of the values will be modified 00396 */ 00397 void reset_to_default_values(loramac_protocol_params *params, bool init = false); 00398 00399 public: 00400 /** 00401 * @brief get_next_lower_tx_datarate Gets the next lower datarate 00402 * @param datarate Current TX datarate 00403 * @return Lower datarate than given one or minimum if lower cannot be found anymore 00404 */ 00405 int8_t get_next_lower_tx_datarate(int8_t datarate); 00406 00407 /** 00408 * @brief get_minimum_rx_datarate Gets the minimum RX datarate supported by a device 00409 * @return Minimum RX datarate 00410 */ 00411 uint8_t get_minimum_rx_datarate(); 00412 00413 /** 00414 * @brief get_minimum_tx_datarate Gets the minimum TX datarate supported by a device 00415 * @return Minimum TX datarate 00416 */ 00417 uint8_t get_minimum_tx_datarate(); 00418 00419 /** 00420 * @brief get_default_tx_datarate Gets the default TX datarate 00421 * @return default TX datarate 00422 */ 00423 uint8_t get_default_tx_datarate(); 00424 00425 /** 00426 * @brief get_default_tx_power Gets the default TX power 00427 * @return Default TX power 00428 */ 00429 uint8_t get_default_tx_power(); 00430 00431 /** 00432 * @brief get_max_payload Gets maximum amount in bytes which device can send 00433 * @param datarate A datarate to use 00434 * @param use_repeater If true repeater table is used, otherwise payloads table is used 00435 * @return Maximum number of bytes for payload 00436 */ 00437 uint8_t get_max_payload(uint8_t datarate, bool use_repeater = false); 00438 00439 /** 00440 * @brief get_maximum_frame_counter_gap Gets maximum frame counter gap 00441 * @return Maximum frame counter gap 00442 */ 00443 uint16_t get_maximum_frame_counter_gap(); 00444 00445 /** 00446 * @brief get_ack_timeout Gets timeout value for ACK to be received 00447 * @return ACK timeout 00448 */ 00449 uint32_t get_ack_timeout(); 00450 00451 /** 00452 * @brief get_default_rx2_frequency Gets default RX2 frequency 00453 * @return RX2 frequency 00454 */ 00455 uint32_t get_default_rx2_frequency(); 00456 00457 /** 00458 * @brief get_default_rx2_datarate Gets default RX2 datarate 00459 * @return RX2 datarate 00460 */ 00461 uint8_t get_default_rx2_datarate(); 00462 00463 /** 00464 * @brief get_channel_mask Gets the channel mask 00465 * @param get_default If true the default mask is returned, otherwise the current mask is returned 00466 * @return A channel mask 00467 */ 00468 uint16_t* get_channel_mask(bool get_default = false); 00469 00470 /** 00471 * @brief get_max_nb_channels Gets maximum number of channels supported 00472 * @return Number of channels 00473 */ 00474 uint8_t get_max_nb_channels(); 00475 00476 /** 00477 * @brief get_phy_channels Gets PHY channels 00478 * @return PHY channels 00479 */ 00480 channel_params_t * get_phy_channels(); 00481 00482 /** 00483 * @brief is_custom_channel_plan_supported Checks if custom channel plan is supported 00484 * @return True if custom channel plan is supported, false otherwise 00485 */ 00486 bool is_custom_channel_plan_supported(); 00487 00488 public: //Verifiers 00489 00490 /** 00491 * @brief verify_rx_datarate Verifies that given RX datarate is valid 00492 * @param datarate Datarate to check 00493 * @return true if given datarate is valid, false otherwise 00494 */ 00495 bool verify_rx_datarate(uint8_t datarate); 00496 00497 /** 00498 * @brief verify_tx_datarate Verifies that given TX datarate is valid 00499 * @param datarate Datarate to check 00500 * @param use_default If true validation is done against default value 00501 * @return true if given datarate is valid, false otherwise 00502 */ 00503 bool verify_tx_datarate(uint8_t datarate, bool use_default = false); 00504 00505 /** 00506 * @brief verify_tx_power Verifies that given TX power is valid 00507 * @param tx_power Power to check 00508 * @return True if valid, false otherwise 00509 */ 00510 bool verify_tx_power(uint8_t tx_power); 00511 00512 /** 00513 * @brief verify_duty_cycle Verifies that given cycle is valid 00514 * @param cycle Cycle to check 00515 * @return True if valid, false otherwise 00516 */ 00517 bool verify_duty_cycle(bool cycle); 00518 00519 /** 00520 * @brief verify_nb_join_trials Verifies that given number of trials is valid 00521 * @param nb_join_trials Number to check 00522 * @return True if valid, false otherwise 00523 */ 00524 bool verify_nb_join_trials(uint8_t nb_join_trials); 00525 00526 protected: 00527 LoRaPHY(LoRaWANTimeHandler &lora_time); 00528 00529 /** 00530 * Verifies the given frequency. 00531 */ 00532 virtual bool verify_frequency(uint32_t freq); 00533 00534 00535 /** 00536 * Verifies, if a value is in a given range. 00537 */ 00538 uint8_t val_in_range(int8_t value, int8_t min, int8_t max); 00539 00540 /** 00541 * Verifies, if a datarate is available on an active channel. 00542 */ 00543 bool verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, 00544 int8_t minDr, int8_t maxDr, channel_params_t * channels); 00545 00546 /** 00547 * Disables a channel in a given channels mask. 00548 */ 00549 bool disable_channel(uint16_t* channel_mask, uint8_t id, uint8_t max_channels); 00550 00551 /** 00552 * Counts number of bits on in a given mask 00553 */ 00554 uint8_t count_bits(uint16_t mask, uint8_t nb_bits); 00555 00556 /** 00557 * Counts the number of active channels in a given channels mask. 00558 */ 00559 uint8_t num_active_channels(uint16_t* channel_mask, uint8_t start_idx, 00560 uint8_t stop_idx); 00561 00562 /** 00563 * Copy channel masks. 00564 */ 00565 void copy_channel_mask(uint16_t* dest_mask, uint16_t* src_mask, uint8_t len); 00566 00567 /** 00568 * Updates the time-offs of the bands. 00569 */ 00570 lorawan_time_t update_band_timeoff(bool joined, bool dutyCycle, band_t * bands, 00571 uint8_t nb_bands); 00572 00573 /** 00574 * Parses the parameter of an LinkAdrRequest. 00575 */ 00576 uint8_t parse_link_ADR_req(uint8_t* payload, link_adr_params_t* adr_params); 00577 00578 /** 00579 * Verifies and updates the datarate, the TX power and the number of repetitions 00580 * of a LinkAdrRequest. 00581 */ 00582 uint8_t verify_link_ADR_req(verify_adr_params_t* verify_params, int8_t* dr, 00583 int8_t* tx_pow, uint8_t* nb_rep); 00584 00585 /** 00586 * Computes the symbol time for LoRa modulation. 00587 */ 00588 double compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth ); 00589 00590 /** 00591 * Computes the symbol time for FSK modulation. 00592 */ 00593 double compute_symb_timeout_fsk(uint8_t phy_dr); 00594 00595 /** 00596 * Computes the RX window timeout and the RX window offset. 00597 */ 00598 void get_rx_window_params(double t_symbol, uint8_t min_rx_symbols, 00599 uint32_t rx_error, uint32_t wakeup_time, 00600 uint32_t* window_timeout, int32_t* window_offset); 00601 00602 /** 00603 * Computes the txPower, based on the max EIRP and the antenna gain. 00604 */ 00605 int8_t compute_tx_power(int8_t txPowerIndex, float maxEirp, float antennaGain); 00606 00607 /** 00608 * Provides a random number in the range provided. 00609 */ 00610 int32_t get_random(int32_t min, int32_t max); 00611 00612 /** 00613 * Get next lower data rate 00614 */ 00615 int8_t get_next_lower_dr(int8_t dr, int8_t min_dr); 00616 00617 /** 00618 * Get channel bandwidth depending upon data rate table index 00619 */ 00620 uint8_t get_bandwidth(uint8_t dr_index); 00621 00622 uint8_t enabled_channel_count(bool joined, uint8_t datarate, 00623 const uint16_t *mask, uint8_t* enabledChannels, 00624 uint8_t* delayTx); 00625 00626 bool is_datarate_supported(const int8_t datarate) const; 00627 00628 protected: 00629 LoRaRadio *_radio; 00630 LoRaWANTimeHandler &_lora_time; 00631 loraphy_params_t phy_params; 00632 }; 00633 00634 #endif /* MBED_OS_LORAPHY_BASE_ */
Generated on Tue Jul 12 2022 14:23:51 by
