BA / Mbed OS BaBoRo1
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      bool mask_bit_test(const uint16_t *mask, unsigned bit);
00119 
00120      /**
00121       * Tests if a channel is on or off in the channel mask
00122       */
00123      void mask_bit_set(uint16_t *mask, unsigned bit);
00124 
00125      /**
00126       * Tests if a channel is on or off in the channel mask
00127       */
00128      void mask_bit_clear(uint16_t *mask, unsigned bit);
00129 
00130     /** Entertain a new channel request MAC command.
00131      *
00132      * MAC command subsystem processes the new channel request coming form
00133      * the network server and then MAC layer asks the PHY layer to entertain
00134      * the request.
00135      *
00136      * @param [in] new_channel_req    A pointer to the new_channel_req_params_t.
00137      *
00138      * @return bit mask, according to the LoRaWAN spec 1.0.2.
00139      */
00140     virtual uint8_t request_new_channel(new_channel_req_params_t* new_channel_req);
00141 
00142     /** Process PHY layer state after a successful transmission.
00143      *
00144      * Updates times of the last transmission for the particular channel and
00145      * band upon which last transmission took place.
00146      *
00147      * @param [in] tx_done    A pointer to set_band_txdone_params_t
00148      */
00149     virtual void set_last_tx_done(set_band_txdone_params_t* tx_done);
00150 
00151     /** Enables default channels only.
00152      *
00153      * Falls back to a channel mask where only default channels are enabled, all
00154      * other channels are disabled.
00155      */
00156     virtual void restore_default_channels();
00157 
00158     /** Processes the incoming CF-list.
00159      *
00160      * Handles the payload containing CF-list and enables channels defined
00161      * therein.
00162      *
00163      * @param cflist_params    A pointer to cflist_params_t.
00164      */
00165    virtual void apply_cf_list(cflist_params_t* cflist_params);
00166 
00167     /** Calculates the next datarate to set, when ADR is on or off.
00168      *
00169      * @param restore_channel_mask    A boolean set restore channel mask in case
00170      *                                of failure.
00171      *
00172      * @param dr_out                  The calculated datarate for the next TX.
00173      *
00174      * @param tx_power_out            The TX power for the next TX.
00175      *
00176      * @param adr_ack_counter         The calculated ADR acknowledgement counter.
00177      *
00178      * @return True, if an ADR request should be performed.
00179      */
00180     bool get_next_ADR(bool restore_channel_mask, int8_t& dr_out,
00181                       int8_t& tx_power_out, uint32_t& adr_ack_counter);
00182 
00183     /** Configure radio reception.
00184      *
00185      * @param [in] config    A pointer to the RX configuration.
00186      *
00187      * @param [out] datarate The datarate index set.
00188      *
00189      * @return True, if the configuration was applied successfully.
00190      */
00191     virtual bool rx_config(rx_config_params_t * config, int8_t* datarate);
00192 
00193     /** Computing Receive Windows
00194      *
00195      * For more details please consult the following document, chapter 3.1.2.
00196      * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
00197      * or
00198      * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
00199      *
00200      *                 Downlink start: T = Tx + 1s (+/- 20 us)
00201      *                            |
00202      *             TRxEarly       |        TRxLate
00203      *                |           |           |
00204      *                |           |           +---+---+---+---+---+---+---+---+
00205      *                |           |           |       Latest Rx window        |
00206      *                |           |           +---+---+---+---+---+---+---+---+
00207      *                |           |           |
00208      *                +---+---+---+---+---+---+---+---+
00209      *                |       Earliest Rx window      |
00210      *                +---+---+---+---+---+---+---+---+
00211      *                            |
00212      *                            +---+---+---+---+---+---+---+---+
00213      *Downlink preamble 8 symbols |   |   |   |   |   |   |   |   |
00214      *                            +---+---+---+---+---+---+---+---+
00215      *
00216      *                     Worst case Rx window timings
00217      *
00218      * TRxLate  = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
00219      * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
00220      *
00221      * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
00222      *
00223      * RxOffset = ( TRxLate + TRxEarly ) / 2
00224      *
00225      * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
00226      * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
00227      *
00228      * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol.
00229      */
00230     /*!
00231      * Computes the RX window timeout and offset.
00232      *
00233      * @param [in] datarate         The RX window datarate index to be used.
00234      *
00235      * @param [in] min_rx_symbols   The minimum number of symbols required to
00236      *                              detect an RX frame.
00237      *
00238      * @param [in] rx_error         The maximum timing error of the receiver
00239      *                              in milliseconds. The receiver will turn on
00240      *                              in a [-rxError : +rxError] ms interval around
00241      *                              RxOffset.
00242      *
00243      * @param [out] rx_conf_params  Pointer to the structure that needs to be
00244      *                              filled with receive window parameters.
00245      *
00246      */
00247     virtual void compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols,
00248                                        uint32_t rx_error,
00249                                        rx_config_params_t  *rx_conf_params);
00250 
00251     /** Configure radio transmission.
00252      *
00253      * @param [in]  tx_config    Structure containing tx parameters.
00254      *
00255      * @param [out] tx_power     The TX power which will be set.
00256      *
00257      * @param [out] tx_toa       The time-on-air of the frame.
00258      *
00259      * @return True, if the configuration was applied successfully.
00260      */
00261     virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power,
00262                                 lorawan_time_t* tx_toa);
00263 
00264     /** Processes a Link ADR Request.
00265      *
00266      * @param [in]  params          A pointer ADR request parameters.
00267      *
00268      * @param [out] dr_out          The datarate applied.
00269      *
00270      * @param [out] tx_power_out    The TX power applied.
00271      *
00272      * @param [out] nb_rep_out      The number of repetitions to apply.
00273      *
00274      * @param [out] nb_bytes_parsed The number of bytes parsed.
00275      *
00276      * @return The status of the operation, according to the LoRaMAC specification.
00277      */
00278     virtual uint8_t link_ADR_request(adr_req_params_t* params,
00279                                      int8_t* dr_out, int8_t* tx_power_out,
00280                                      uint8_t* nb_rep_out,
00281                                      uint8_t* nb_bytes_parsed);
00282 
00283     /** Accept or rejects RxParamSetupReq MAC command
00284      *
00285      * The function processes a RX parameter setup request in response to
00286      * server MAC command for RX setup.
00287      *
00288      * @param [in] params    A pointer to rx parameter setup request.
00289      *
00290      * @return The status of the operation, according to the LoRaWAN specification.
00291      */
00292     virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params);
00293 
00294     /** Makes decision whether to accept or reject TxParamSetupReq MAC command
00295      *
00296      * @param [in] params    A pointer to tx parameter setup request.
00297      *
00298      * @return               True to let the MAC know that the request is
00299      *                       accepted and MAC can apply TX parameters received
00300      *                       form Network Server. Otherwise false is returned.
00301      */
00302     virtual bool accept_tx_param_setup_req(tx_param_setup_req_t* params);
00303 
00304     /** Processes a DlChannelReq MAC command.
00305      *
00306      * @param [in] params    A pointer to downlink channel request.
00307      *
00308      * @return The status of the operation, according to the LoRaWAN specification.
00309      */
00310     virtual uint8_t dl_channel_request(dl_channel_req_params_t* params);
00311 
00312     /** Alternates the datarate of the channel for the join request.
00313      *
00314      * @param nb_trials    Number of trials to be made on one given data rate.
00315      *
00316      * @return             The datarate to apply .
00317      */
00318     virtual int8_t get_alternate_DR(uint8_t nb_trials);
00319 
00320     /** Searches and sets the next available channel.
00321      *
00322      * If there are multiple channels found available, one of them is selected
00323      * randomly.
00324      *
00325      * @param [in]  nextChanParams Parameters for the next channel.
00326      *
00327      * @param [out] channel The next channel to use for TX.
00328      *
00329      * @param [out] time The time to wait for the next transmission according to the duty cycle.
00330      *
00331      * @param [out] aggregatedTimeOff Updates the aggregated time off.
00332      *
00333      * @return Function status [1: OK, 0: Unable to find a channel on the current datarate].
00334      */
00335     virtual bool set_next_channel(channel_selection_params_t* nextChanParams,
00336                                    uint8_t* channel, lorawan_time_t* time,
00337                                    lorawan_time_t* aggregatedTimeOff);
00338 
00339     /** Adds a channel to the channel list.
00340      *
00341      * Verifies the channel parameters and if everything is found legitimate,
00342      * adds that particular channel to the channel list and updates the channel
00343      * mask.
00344      *
00345      * @param [in] new_channel A pointer to the parameters for the new channel.
00346      * @param [in] id          Channel ID
00347      *
00348      * @return LORAWAN_STATUS_OK if everything goes fine, negative error code
00349      *         otherwise.
00350      */
00351     virtual lorawan_status_t add_channel(channel_params_t * new_channel, uint8_t id);
00352 
00353     /** Removes a channel from the channel list.
00354      *
00355      * @param [in] channel_id Index of the channel to be removed
00356      *
00357      * @return True, if the channel was removed successfully.
00358      */
00359     virtual bool remove_channel(uint8_t channel_id);
00360 
00361     /** Puts the radio into continuous wave mode.
00362      *
00363      * @param [in] continuous_wave   A pointer to the function parameters.
00364      *
00365      * @param [in] frequency         Frequency to transmit at
00366      */
00367     virtual void set_tx_cont_mode(cw_mode_params_t * continuous_wave,
00368                                   uint32_t frequency = 0);
00369 
00370     /** Computes new data rate according to the given offset
00371      *
00372      * @param [in] dr The current datarate.
00373      *
00374      * @param [in] dr_offset The offset to be applied.
00375      *
00376      * @return     The computed datarate.
00377      */
00378     virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset);
00379 
00380     /**
00381      * @brief reset_to_default_values resets some parameters to default values
00382      * @param params Pointer to MAC protocol parameters which will be reset
00383      * @param init If true, most of the values will be modified
00384      */
00385     void reset_to_default_values(loramac_protocol_params *params, bool init = false);
00386 
00387 public:
00388     /**
00389      * @brief get_next_lower_tx_datarate Gets the next lower datarate
00390      * @param datarate Current TX datarate
00391      * @return Lower datarate than given one or minimum if lower cannot be found anymore
00392      */
00393     int8_t get_next_lower_tx_datarate(int8_t datarate);
00394 
00395     /**
00396      * @brief get_minimum_rx_datarate Gets the minimum RX datarate supported by a device
00397      * @return Minimum RX datarate
00398      */
00399     uint8_t get_minimum_rx_datarate();
00400 
00401     /**
00402      * @brief get_minimum_tx_datarate Gets the minimum TX datarate supported by a device
00403      * @return Minimum TX datarate
00404      */
00405     uint8_t get_minimum_tx_datarate();
00406 
00407     /**
00408      * @brief get_default_tx_datarate Gets the default TX datarate
00409      * @return default TX datarate
00410      */
00411     uint8_t get_default_tx_datarate();
00412 
00413     /**
00414      * @brief get_default_tx_power Gets the default TX power
00415      * @return Default TX power
00416      */
00417     uint8_t get_default_tx_power();
00418 
00419     /**
00420      * @brief get_max_payload Gets maximum amount in bytes which device can send
00421      * @param datarate A datarate to use
00422      * @param use_repeater If true repeater table is used, otherwise payloads table is used
00423      * @return Maximum number of bytes for payload
00424      */
00425     uint8_t get_max_payload(uint8_t datarate, bool use_repeater = false);
00426 
00427     /**
00428      * @brief get_maximum_frame_counter_gap Gets maximum frame counter gap
00429      * @return Maximum frame counter gap
00430      */
00431     uint16_t get_maximum_frame_counter_gap();
00432 
00433     /**
00434      * @brief get_ack_timeout Gets timeout value for ACK to be received
00435      * @return ACK timeout
00436      */
00437     uint32_t get_ack_timeout();
00438 
00439     /**
00440      * @brief get_default_rx2_frequency Gets default RX2 frequency
00441      * @return RX2 frequency
00442      */
00443     uint32_t get_default_rx2_frequency();
00444 
00445     /**
00446      * @brief get_default_rx2_datarate Gets default RX2 datarate
00447      * @return RX2 datarate
00448      */
00449     uint8_t get_default_rx2_datarate();
00450 
00451     /**
00452      * @brief get_channel_mask Gets the channel mask
00453      * @param get_default If true the default mask is returned, otherwise the current mask is returned
00454      * @return A channel mask
00455      */
00456     uint16_t* get_channel_mask(bool get_default = false);
00457 
00458     /**
00459      * @brief get_max_nb_channels Gets maximum number of channels supported
00460      * @return Number of channels
00461      */
00462     uint8_t get_max_nb_channels();
00463 
00464     /**
00465      * @brief get_phy_channels Gets PHY channels
00466      * @return PHY channels
00467      */
00468     channel_params_t * get_phy_channels();
00469 
00470     /**
00471      * @brief is_custom_channel_plan_supported Checks if custom channel plan is supported
00472      * @return True if custom channel plan is supported, false otherwise
00473      */
00474     bool is_custom_channel_plan_supported();
00475 
00476 public: //Verifiers
00477 
00478     /**
00479      * @brief verify_rx_datarate Verifies that given RX datarate is valid
00480      * @param datarate Datarate to check
00481      * @return true if given datarate is valid, false otherwise
00482      */
00483     bool verify_rx_datarate(uint8_t datarate);
00484 
00485     /**
00486      * @brief verify_tx_datarate Verifies that given TX datarate is valid
00487      * @param datarate Datarate to check
00488      * @param use_default If true validation is done against default value
00489      * @return true if given datarate is valid, false otherwise
00490      */
00491     bool verify_tx_datarate(uint8_t datarate, bool use_default = false);
00492 
00493     /**
00494      * @brief verify_tx_power Verifies that given TX power is valid
00495      * @param tx_power Power to check
00496      * @return True if valid, false otherwise
00497      */
00498     bool verify_tx_power(uint8_t tx_power);
00499 
00500     /**
00501      * @brief verify_duty_cycle Verifies that given cycle is valid
00502      * @param cycle Cycle to check
00503      * @return True if valid, false otherwise
00504      */
00505     bool verify_duty_cycle(bool cycle);
00506 
00507     /**
00508      * @brief verify_nb_join_trials Verifies that given number of trials is valid
00509      * @param nb_join_trials Number to check
00510      * @return True if valid, false otherwise
00511      */
00512     bool verify_nb_join_trials(uint8_t nb_join_trials);
00513 
00514 protected:
00515     LoRaRadio *_radio;
00516     LoRaWANTimeHandler &_lora_time;
00517     loraphy_params_t phy_params;
00518 
00519     LoRaPHY(LoRaWANTimeHandler &lora_time);
00520 
00521     /**
00522      * Verifies the given frequency.
00523      */
00524     virtual bool verify_frequency(uint32_t freq);
00525 
00526 
00527     /**
00528      * Verifies, if a value is in a given range.
00529      */
00530     uint8_t val_in_range(int8_t value, int8_t min, int8_t max);
00531 
00532     /**
00533      * Verifies, if a datarate is available on an active channel.
00534      */
00535     bool verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, int8_t dr,
00536                            int8_t minDr, int8_t maxDr, channel_params_t * channels);
00537 
00538     /**
00539      * Disables a channel in a given channels mask.
00540      */
00541     bool disable_channel(uint16_t* channel_mask, uint8_t id, uint8_t max_channels);
00542 
00543     /**
00544      * Counts number of bits on in a given mask
00545      */
00546     uint8_t count_bits(uint16_t mask, uint8_t nb_bits);
00547 
00548     /**
00549      * Counts the number of active channels in a given channels mask.
00550      */
00551     uint8_t num_active_channels(uint16_t* channel_mask, uint8_t start_idx,
00552                                 uint8_t stop_idx);
00553 
00554     /**
00555      * Copy channel masks.
00556      */
00557     void copy_channel_mask(uint16_t* dest_mask, uint16_t* src_mask, uint8_t len);
00558 
00559     /**
00560      * Updates the time-offs of the bands.
00561      */
00562     lorawan_time_t update_band_timeoff(bool joined, bool dutyCycle, band_t * bands,
00563                                        uint8_t nb_bands);
00564 
00565     /**
00566      * Parses the parameter of an LinkAdrRequest.
00567      */
00568     uint8_t parse_link_ADR_req(uint8_t* payload, link_adr_params_t* adr_params);
00569 
00570     /**
00571      * Verifies and updates the datarate, the TX power and the number of repetitions
00572      * of a LinkAdrRequest.
00573      */
00574     uint8_t verify_link_ADR_req(verify_adr_params_t* verify_params, int8_t* dr,
00575                                 int8_t* tx_pow, uint8_t* nb_rep);
00576 
00577     /**
00578      * Computes the symbol time for LoRa modulation.
00579      */
00580     double compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth );
00581 
00582     /**
00583      * Computes the symbol time for FSK modulation.
00584      */
00585     double compute_symb_timeout_fsk(uint8_t phy_dr);
00586 
00587     /**
00588      * Computes the RX window timeout and the RX window offset.
00589      */
00590     void get_rx_window_params(double t_symbol, uint8_t min_rx_symbols,
00591                               uint32_t rx_error, uint32_t wakeup_time,
00592                               uint32_t* window_timeout, int32_t* window_offset);
00593 
00594     /**
00595      * Computes the txPower, based on the max EIRP and the antenna gain.
00596      */
00597     int8_t compute_tx_power(int8_t txPowerIndex, float maxEirp, float antennaGain);
00598 
00599     /**
00600      * Provides a random number in the range provided.
00601      */
00602     int32_t get_random(int32_t min, int32_t max);
00603 
00604     /**
00605      * Get next lower data rate
00606      */
00607     int8_t get_next_lower_dr(int8_t dr, int8_t min_dr);
00608 
00609     /**
00610      * Get channel bandwidth depending upon data rate table index
00611      */
00612     uint8_t get_bandwidth(uint8_t dr_index);
00613 
00614     uint8_t enabled_channel_count(bool joined, uint8_t datarate,
00615                                   const uint16_t *mask, uint8_t* enabledChannels,
00616                                   uint8_t* delayTx);
00617 };
00618 
00619 
00620 
00621 #endif /* MBED_OS_LORAPHY_BASE_ */