Denislam Valeev / Mbed OS Nucleo_rtos_basic
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaPHY.h Source File

LoRaPHY.h

Go to the documentation of this file.
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_ */