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 /** Calculates and applies duty cycle back-off time. 00108 * 00109 * Explicitly updates the band time-off. 00110 * 00111 * @param [in] backoff_params A pointer to backoff parameters. 00112 */ 00113 void calculate_backoff(backoff_params_t * backoff_params); 00114 00115 /** 00116 * Tests if a channel is on or off in the channel mask 00117 */ 00118 inline bool mask_bit_test(const uint16_t *mask, unsigned bit) { 00119 return mask[bit/16] & (1U << (bit % 16)); 00120 } 00121 00122 /** 00123 * Tests if a channel is on or off in the channel mask 00124 */ 00125 inline void mask_bit_set(uint16_t *mask, unsigned bit) { 00126 mask[bit/16] |= (1U << (bit % 16)); 00127 } 00128 00129 /** 00130 * Tests if a channel is on or off in the channel mask 00131 */ 00132 inline void mask_bit_clear(uint16_t *mask, unsigned bit) { 00133 mask[bit/16] &= ~(1U << (bit % 16)); 00134 } 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 [in] new_channel_req A pointer to the new_channel_req_params_t. 00143 * 00144 * @return bit mask, according to the LoRaWAN spec 1.0.2. 00145 */ 00146 virtual uint8_t request_new_channel(new_channel_req_params_t* new_channel_req); 00147 00148 /** Grants access to PHY layer parameters. 00149 * 00150 * This is essentially a PHY layer parameter retrieval system. 00151 * A request is made for a certain parameter by setting an appropriate 00152 * attribute. 00153 * 00154 * @param [in] get_phy A pointer to get_phy_params_t 00155 * 00156 * @return A structure containing the requested PHY parameter value. 00157 */ 00158 virtual phy_param_t get_phy_params(get_phy_params_t* get_phy); 00159 00160 /** Process PHY layer state after a successful transmission. 00161 * 00162 * Updates times of the last transmission for the particular channel and 00163 * band upon which last transmission took place. 00164 * 00165 * @param [in] tx_done A pointer to set_band_txdone_params_t 00166 */ 00167 virtual void set_last_tx_done(set_band_txdone_params_t* tx_done); 00168 00169 /** Enables default channels only. 00170 * 00171 * Falls back to a channel mask where only default channels are enabled, all 00172 * other channels are disabled. 00173 */ 00174 virtual void restore_default_channels(); 00175 00176 /** Verify if a parameter is eligible. 00177 * 00178 * @param verify A pointer to the verification_params_t that contains 00179 * parameters which we need to check for validity. 00180 * 00181 * @param phy_attr The attribute for which the verification is needed. 00182 * 00183 * @return True, if the parameter is valid. 00184 */ 00185 virtual bool verify(verification_params_t* verify, phy_attributes_t phy_attr); 00186 00187 /** Processes the incoming CF-list. 00188 * 00189 * Handles the payload containing CF-list and enables channels defined 00190 * therein. 00191 * 00192 * @param cflist_params A pointer to cflist_params_t. 00193 */ 00194 virtual void apply_cf_list(cflist_params_t* cflist_params); 00195 00196 /** Calculates the next datarate to set, when ADR is on or off. 00197 * 00198 * @param restore_channel_mask A boolean set restore channel mask in case 00199 * of failure. 00200 * 00201 * @param dr_out The calculated datarate for the next TX. 00202 * 00203 * @param tx_power_out The TX power for the next TX. 00204 * 00205 * @param adr_ack_counter The calculated ADR acknowledgement counter. 00206 * 00207 * @return True, if an ADR request should be performed. 00208 */ 00209 bool get_next_ADR(bool restore_channel_mask, int8_t& dr_out, 00210 int8_t& tx_power_out, uint32_t& adr_ack_counter); 00211 00212 /** Configure radio reception. 00213 * 00214 * @param [in] config A pointer to the RX configuration. 00215 * 00216 * @param [out] datarate The datarate index set. 00217 * 00218 * @return True, if the configuration was applied successfully. 00219 */ 00220 virtual bool rx_config(rx_config_params_t * config, int8_t* datarate); 00221 00222 /** Computing Receive Windows 00223 * 00224 * For more details please consult the following document, chapter 3.1.2. 00225 * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf 00226 * or 00227 * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf 00228 * 00229 * Downlink start: T = Tx + 1s (+/- 20 us) 00230 * | 00231 * TRxEarly | TRxLate 00232 * | | | 00233 * | | +---+---+---+---+---+---+---+---+ 00234 * | | | Latest Rx window | 00235 * | | +---+---+---+---+---+---+---+---+ 00236 * | | | 00237 * +---+---+---+---+---+---+---+---+ 00238 * | Earliest Rx window | 00239 * +---+---+---+---+---+---+---+---+ 00240 * | 00241 * +---+---+---+---+---+---+---+---+ 00242 *Downlink preamble 8 symbols | | | | | | | | | 00243 * +---+---+---+---+---+---+---+---+ 00244 * 00245 * Worst case Rx window timings 00246 * 00247 * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME 00248 * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME 00249 * 00250 * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR 00251 * 00252 * RxOffset = ( TRxLate + TRxEarly ) / 2 00253 * 00254 * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR 00255 * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME 00256 * 00257 * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol. 00258 */ 00259 /*! 00260 * Computes the RX window timeout and offset. 00261 * 00262 * @param [in] datarate The RX window datarate index to be used. 00263 * 00264 * @param [in] min_rx_symbols The minimum number of symbols required to 00265 * detect an RX frame. 00266 * 00267 * @param [in] rx_error The maximum timing error of the receiver 00268 * in milliseconds. The receiver will turn on 00269 * in a [-rxError : +rxError] ms interval around 00270 * RxOffset. 00271 * 00272 * @param [out] rx_conf_params Pointer to the structure that needs to be 00273 * filled with receive window parameters. 00274 * 00275 */ 00276 virtual void compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, 00277 uint32_t rx_error, 00278 rx_config_params_t *rx_conf_params); 00279 00280 /** Configure radio transmission. 00281 * 00282 * @param [in] tx_config Structure containing tx parameters. 00283 * 00284 * @param [out] tx_power The TX power which will be set. 00285 * 00286 * @param [out] tx_toa The time-on-air of the frame. 00287 * 00288 * @return True, if the configuration was applied successfully. 00289 */ 00290 virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power, 00291 lorawan_time_t* tx_toa); 00292 00293 /** Processes a Link ADR Request. 00294 * 00295 * @param [in] params A pointer ADR request parameters. 00296 * 00297 * @param [out] dr_out The datarate applied. 00298 * 00299 * @param [out] tx_power_out The TX power applied. 00300 * 00301 * @param [out] nb_rep_out The number of repetitions to apply. 00302 * 00303 * @param [out] nb_bytes_parsed The number of bytes parsed. 00304 * 00305 * @return The status of the operation, according to the LoRaMAC specification. 00306 */ 00307 virtual uint8_t link_ADR_request(adr_req_params_t* params, 00308 int8_t* dr_out, int8_t* tx_power_out, 00309 uint8_t* nb_rep_out, 00310 uint8_t* nb_bytes_parsed); 00311 00312 /** Accept or rejects RxParamSetupReq MAC command 00313 * 00314 * The function processes a RX parameter setup request in response to 00315 * server MAC command for RX setup. 00316 * 00317 * @param [in] params A pointer to rx parameter setup request. 00318 * 00319 * @return The status of the operation, according to the LoRaWAN specification. 00320 */ 00321 virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params); 00322 00323 /** Makes decision whether to accept or reject TxParamSetupReq MAC command 00324 * 00325 * @param [in] params A pointer to tx parameter setup request. 00326 * 00327 * @return True to let the MAC know that the request is 00328 * accepted and MAC can apply TX parameters received 00329 * form Network Server. Otherwise false is returned. 00330 */ 00331 virtual bool accept_tx_param_setup_req(tx_param_setup_req_t* params); 00332 00333 /** Processes a DlChannelReq MAC command. 00334 * 00335 * @param [in] params A pointer to downlink channel request. 00336 * 00337 * @return The status of the operation, according to the LoRaWAN specification. 00338 */ 00339 virtual uint8_t dl_channel_request(dl_channel_req_params_t* params); 00340 00341 /** Alternates the datarate of the channel for the join request. 00342 * 00343 * @param nb_trials Number of trials to be made on one given data rate. 00344 * 00345 * @return The datarate to apply . 00346 */ 00347 virtual int8_t get_alternate_DR(uint8_t nb_trials); 00348 00349 /** Searches and sets the next available channel. 00350 * 00351 * If there are multiple channels found available, one of them is selected 00352 * randomly. 00353 * 00354 * @param [in] nextChanParams Parameters for the next channel. 00355 * 00356 * @param [out] channel The next channel to use for TX. 00357 * 00358 * @param [out] time The time to wait for the next transmission according to the duty cycle. 00359 * 00360 * @param [out] aggregatedTimeOff Updates the aggregated time off. 00361 * 00362 * @return Function status [1: OK, 0: Unable to find a channel on the current datarate]. 00363 */ 00364 virtual bool set_next_channel(channel_selection_params_t* nextChanParams, 00365 uint8_t* channel, lorawan_time_t* time, 00366 lorawan_time_t* aggregatedTimeOff); 00367 00368 /** Adds a channel to the channel list. 00369 * 00370 * Verifies the channel parameters and if everything is found legitimate, 00371 * adds that particular channel to the channel list and updates the channel 00372 * mask. 00373 * 00374 * @param [in] new_channel A pointer to the parameters for the new channel. 00375 * @param [in] id Channel ID 00376 * 00377 * @return LORAWAN_STATUS_OK if everything goes fine, negative error code 00378 * otherwise. 00379 */ 00380 virtual lorawan_status_t add_channel(channel_params_t * new_channel, uint8_t id); 00381 00382 /** Removes a channel from the channel list. 00383 * 00384 * @param [in] channel_id Index of the channel to be removed 00385 * 00386 * @return True, if the channel was removed successfully. 00387 */ 00388 virtual bool remove_channel(uint8_t channel_id); 00389 00390 /** Puts the radio into continuous wave mode. 00391 * 00392 * @param [in] continuous_wave A pointer to the function parameters. 00393 * 00394 * @param [in] frequency Frequency to transmit at 00395 */ 00396 virtual void set_tx_cont_mode(cw_mode_params_t * continuous_wave, 00397 uint32_t frequency = 0); 00398 00399 /** Computes new data rate according to the given offset 00400 * 00401 * @param [in] dr The current datarate. 00402 * 00403 * @param [in] dr_offset The offset to be applied. 00404 * 00405 * @return The computed datarate. 00406 */ 00407 virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset); 00408 00409 protected: 00410 LoRaRadio *_radio; 00411 LoRaWANTimeHandler &_lora_time; 00412 loraphy_params_t phy_params; 00413 00414 LoRaPHY(LoRaWANTimeHandler &lora_time); 00415 00416 /** 00417 * Verifies the given frequency. 00418 */ 00419 virtual bool verify_frequency(uint32_t freq); 00420 00421 00422 /** 00423 * Verifies, if a value is in a given range. 00424 */ 00425 uint8_t val_in_range(int8_t value, int8_t min, int8_t max); 00426 00427 /** 00428 * Verifies, if a datarate is available on an active channel. 00429 */ 00430 bool verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, 00431 int8_t minDr, int8_t maxDr, channel_params_t * channels); 00432 00433 /** 00434 * Disables a channel in a given channels mask. 00435 */ 00436 bool disable_channel(uint16_t* channel_mask, uint8_t id, uint8_t max_channels); 00437 00438 /** 00439 * Counts number of bits on in a given mask 00440 */ 00441 uint8_t count_bits(uint16_t mask, uint8_t nb_bits); 00442 00443 /** 00444 * Counts the number of active channels in a given channels mask. 00445 */ 00446 uint8_t num_active_channels(uint16_t* channel_mask, uint8_t start_idx, 00447 uint8_t stop_idx); 00448 00449 /** 00450 * Copy channel masks. 00451 */ 00452 void copy_channel_mask(uint16_t* dest_mask, uint16_t* src_mask, uint8_t len); 00453 00454 /** 00455 * Updates the time-offs of the bands. 00456 */ 00457 lorawan_time_t update_band_timeoff(bool joined, bool dutyCycle, band_t * bands, 00458 uint8_t nb_bands); 00459 00460 /** 00461 * Parses the parameter of an LinkAdrRequest. 00462 */ 00463 uint8_t parse_link_ADR_req(uint8_t* payload, link_adr_params_t* adr_params); 00464 00465 /** 00466 * Verifies and updates the datarate, the TX power and the number of repetitions 00467 * of a LinkAdrRequest. 00468 */ 00469 uint8_t verify_link_ADR_req(verify_adr_params_t* verify_params, int8_t* dr, 00470 int8_t* tx_pow, uint8_t* nb_rep); 00471 00472 /** 00473 * Computes the symbol time for LoRa modulation. 00474 */ 00475 double compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth ); 00476 00477 /** 00478 * Computes the symbol time for FSK modulation. 00479 */ 00480 double compute_symb_timeout_fsk(uint8_t phy_dr); 00481 00482 /** 00483 * Computes the RX window timeout and the RX window offset. 00484 */ 00485 void get_rx_window_params(double t_symbol, uint8_t min_rx_symbols, 00486 uint32_t rx_error, uint32_t wakeup_time, 00487 uint32_t* window_timeout, int32_t* window_offset); 00488 00489 /** 00490 * Computes the txPower, based on the max EIRP and the antenna gain. 00491 */ 00492 int8_t compute_tx_power(int8_t txPowerIndex, float maxEirp, float antennaGain); 00493 00494 /** 00495 * Provides a random number in the range provided. 00496 */ 00497 int32_t get_random(int32_t min, int32_t max); 00498 00499 /** 00500 * Get next lower data rate 00501 */ 00502 int8_t get_next_lower_dr(int8_t dr, int8_t min_dr); 00503 00504 /** 00505 * Get channel bandwidth depending upon data rate table index 00506 */ 00507 uint8_t get_bandwidth(uint8_t dr_index); 00508 00509 uint8_t enabled_channel_count(bool joined, uint8_t datarate, 00510 const uint16_t *mask, uint8_t* enabledChannels, 00511 uint8_t* delayTx); 00512 }; 00513 00514 00515 00516 #endif /* MBED_OS_LORAPHY_BASE_ */
Generated on Tue Jul 12 2022 13:30:22 by
