Damian Gabino / picoGW_mcu
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers loragw_hal.h Source File

loragw_hal.h

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007   (C)2017 Semtech-Cycleo
00008 
00009 Description:
00010     LoRa concentrator Hardware Abstraction Layer
00011 
00012 License: Revised BSD License, see LICENSE.TXT file include in the project
00013 
00014 */
00015 
00016 
00017 #ifndef _LORAGW_HAL_H
00018 #define _LORAGW_HAL_H
00019 
00020 /* -------------------------------------------------------------------------- */
00021 /* --- DEPENDANCIES --------------------------------------------------------- */
00022 
00023 #include <stdint.h>     /* C99 types */
00024 #include <stdbool.h>    /* bool type */
00025 
00026 /* -------------------------------------------------------------------------- */
00027 /* --- PUBLIC MACROS -------------------------------------------------------- */
00028 
00029 #define IS_LORA_BW(bw)          ((bw == BW_125KHZ) || (bw == BW_250KHZ) || (bw == BW_500KHZ))
00030 #define IS_LORA_STD_DR(dr)      ((dr == DR_LORA_SF7) || (dr == DR_LORA_SF8) || (dr == DR_LORA_SF9) || (dr == DR_LORA_SF10) || (dr == DR_LORA_SF11) || (dr == DR_LORA_SF12))
00031 #define IS_LORA_MULTI_DR(dr)    ((dr & ~DR_LORA_MULTI) == 0) /* ones outside of DR_LORA_MULTI bitmask -> not a combination of LoRa datarates */
00032 #define IS_LORA_CR(cr)          ((cr == CR_LORA_4_5) || (cr == CR_LORA_4_6) || (cr == CR_LORA_4_7) || (cr == CR_LORA_4_8))
00033 
00034 #define IS_FSK_BW(bw)           ((bw >= 1) && (bw <= 7))
00035 #define IS_FSK_DR(dr)           ((dr >= DR_FSK_MIN) && (dr <= DR_FSK_MAX))
00036 
00037 #define IS_TX_MODE(mode)        ((mode == IMMEDIATE) || (mode == TIMESTAMPED) || (mode == ON_GPS))
00038 
00039 /* -------------------------------------------------------------------------- */
00040 /* --- PUBLIC CONSTANTS ----------------------------------------------------- */
00041 
00042 /* return status code */
00043 #define LGW_HAL_SUCCESS     0
00044 #define LGW_HAL_ERROR       -1
00045 
00046 /* radio-specific parameters */
00047 #define LGW_XTAL_FREQU      32000000            /* frequency of the RF reference oscillator */
00048 #define LGW_RF_CHAIN_NB     2                   /* number of RF chains */
00049 #define LGW_RF_RX_BANDWIDTH {1000000, 1000000}  /* bandwidth of the radios */
00050 
00051 /* type of if_chain + modem */
00052 #define IF_UNDEFINED        0
00053 #define IF_LORA_STD         0x10    /* if + standard single-SF LoRa modem */
00054 #define IF_LORA_MULTI       0x11    /* if + LoRa receiver with multi-SF capability */
00055 #define IF_FSK_STD          0x20    /* if + standard FSK modem */
00056 
00057 /* concentrator chipset-specific parameters */
00058 /* to use array parameters, declare a local const and use 'if_chain' as index */
00059 #define LGW_IF_CHAIN_NB     10    /* number of IF+modem RX chains */
00060 #define LGW_PKT_FIFO_SIZE   16    /* depth of the RX packet FIFO */
00061 #define LGW_DATABUFF_SIZE   1024    /* size in bytes of the RX data buffer (contains payload & metadata) */
00062 #define LGW_REF_BW          125000    /* typical bandwidth of data channel */
00063 #define LGW_MULTI_NB        8    /* number of LoRa 'multi SF' chains */
00064 #define LGW_IFMODEM_CONFIG {\
00065         IF_LORA_MULTI, \
00066         IF_LORA_MULTI, \
00067         IF_LORA_MULTI, \
00068         IF_LORA_MULTI, \
00069         IF_LORA_MULTI, \
00070         IF_LORA_MULTI, \
00071         IF_LORA_MULTI, \
00072         IF_LORA_MULTI, \
00073         IF_LORA_STD, \
00074         IF_FSK_STD } /* configuration of available IF chains and modems on the hardware */
00075 
00076 /* values available for the 'modulation' parameters */
00077 /* NOTE: arbitrary values */
00078 #define MOD_UNDEFINED   0
00079 #define MOD_LORA        0x10
00080 #define MOD_FSK         0x20
00081 
00082 /* values available for the 'bandwidth' parameters (LoRa & FSK) */
00083 /* NOTE: directly encode FSK RX bandwidth, do not change */
00084 #define BW_UNDEFINED    0
00085 #define BW_500KHZ       0x01
00086 #define BW_250KHZ       0x02
00087 #define BW_125KHZ       0x03
00088 #define BW_62K5HZ       0x04
00089 #define BW_31K2HZ       0x05
00090 #define BW_15K6HZ       0x06
00091 #define BW_7K8HZ        0x07
00092 
00093 /* values available for the 'datarate' parameters */
00094 /* NOTE: LoRa values used directly to code SF bitmask in 'multi' modem, do not change */
00095 #define DR_UNDEFINED    0
00096 #define DR_LORA_SF7     0x02
00097 #define DR_LORA_SF8     0x04
00098 #define DR_LORA_SF9     0x08
00099 #define DR_LORA_SF10    0x10
00100 #define DR_LORA_SF11    0x20
00101 #define DR_LORA_SF12    0x40
00102 #define DR_LORA_MULTI   0x7E
00103 /* NOTE: for FSK directly use baudrate between 500 bauds and 250 kbauds */
00104 #define DR_FSK_MIN      500
00105 #define DR_FSK_MAX      250000
00106 
00107 /* values available for the 'coderate' parameters (LoRa only) */
00108 /* NOTE: arbitrary values */
00109 #define CR_UNDEFINED    0
00110 #define CR_LORA_4_5     0x01
00111 #define CR_LORA_4_6     0x02
00112 #define CR_LORA_4_7     0x03
00113 #define CR_LORA_4_8     0x04
00114 
00115 /* values available for the 'status' parameter */
00116 /* NOTE: values according to hardware specification */
00117 #define STAT_UNDEFINED  0x00
00118 #define STAT_NO_CRC     0x01
00119 #define STAT_CRC_BAD    0x11
00120 #define STAT_CRC_OK     0x10
00121 
00122 /* values available for the 'tx_mode' parameter */
00123 #define IMMEDIATE       0
00124 #define TIMESTAMPED     1
00125 #define ON_GPS          2
00126 //#define ON_EVENT      3
00127 //#define GPS_DELAYED   4
00128 //#define EVENT_DELAYED 5
00129 
00130 /* values available for 'select' in the status function */
00131 #define TX_STATUS       1
00132 #define RX_STATUS       2
00133 
00134 /* status code for TX_STATUS */
00135 /* NOTE: arbitrary values */
00136 #define TX_STATUS_UNKNOWN   0
00137 #define TX_OFF              1    /* TX modem disabled, it will ignore commands */
00138 #define TX_FREE             2    /* TX modem is free, ready to receive a command */
00139 #define TX_SCHEDULED        3    /* TX modem is loaded, ready to send the packet after an event and/or delay */
00140 #define TX_EMITTING         4    /* TX modem is emitting */
00141 
00142 /* status code for RX_STATUS */
00143 /* NOTE: arbitrary values */
00144 #define RX_STATUS_UNKNOWN   0
00145 #define RX_OFF              1    /* RX modem is disabled, it will ignore commands  */
00146 #define RX_ON               2    /* RX modem is receiving */
00147 #define RX_SUSPENDED        3    /* RX is suspended while a TX is ongoing */
00148 
00149 /* Maximum size of Tx gain LUT */
00150 #define TX_GAIN_LUT_SIZE_MAX 16
00151 
00152 /* -------------------------------------------------------------------------- */
00153 /* --- PUBLIC TYPES --------------------------------------------------------- */
00154 
00155 /**
00156 @enum lgw_radio_type_e
00157 @brief Radio types that can be found on the LoRa Gateway
00158 */
00159 enum lgw_radio_type_e {
00160     LGW_RADIO_TYPE_NONE,
00161     LGW_RADIO_TYPE_SX1255,
00162     LGW_RADIO_TYPE_SX1257,
00163     LGW_RADIO_TYPE_SX1272,
00164     LGW_RADIO_TYPE_SX1276
00165 };
00166 
00167 /**
00168 @struct lgw_conf_board_s
00169 @brief Configuration structure for board specificities
00170 */
00171 struct lgw_conf_board_s {
00172     bool    lorawan_public; /*!> Enable ONLY for *public* networks using the LoRa MAC protocol */
00173     uint8_t clksrc ;         /*!> Index of RF chain which provides clock to concentrator */
00174 };
00175 
00176 /**
00177 @struct lgw_conf_rxrf_s
00178 @brief Configuration structure for a RF chain
00179 */
00180 struct lgw_conf_rxrf_s {
00181     bool                    enable;         /*!> enable or disable that RF chain */
00182     uint32_t                freq_hz ;        /*!> center frequency of the radio in Hz */
00183     float                   rssi_offset ;    /*!> Board-specific RSSI correction factor */
00184     enum lgw_radio_type_e   type ;           /*!> Radio type for that RF chain (SX1255, SX1257....) */
00185     uint32_t                tx_enable ;      /*!> enable or disable TX on that RF chain */
00186 };
00187 
00188 /**
00189 @struct lgw_conf_rxif_s
00190 @brief Configuration structure for an IF chain
00191 */
00192 struct lgw_conf_rxif_s {
00193     bool        enable;         /*!> enable or disable that IF chain */
00194     uint8_t     rf_chain ;       /*!> to which RF chain is that IF chain associated */
00195     int32_t     freq_hz ;        /*!> center frequ of the IF chain, relative to RF chain frequency */
00196     uint8_t     bandwidth ;      /*!> RX bandwidth, 0 for default */
00197     uint32_t    datarate ;       /*!> RX datarate, 0 for default */
00198     uint8_t     sync_word_size ; /*!> size of FSK sync word (number of bytes, 0 for default) */
00199     uint64_t    sync_word ;      /*!> FSK sync word (ALIGN RIGHT, eg. 0xC194C1) */
00200 };
00201 
00202 /**
00203 @struct lgw_pkt_rx_s
00204 @brief Structure containing the metadata of a packet that was received and a pointer to the payload
00205 */
00206 struct lgw_pkt_rx_s {
00207     uint32_t    freq_hz;        /*!> central frequency of the IF chain */
00208     uint8_t     if_chain ;       /*!> by which IF chain was packet received */
00209     uint8_t     status ;         /*!> status of the received packet */
00210     uint32_t    count_us ;       /*!> internal concentrator counter for timestamping, 1 microsecond resolution */
00211     uint8_t     rf_chain ;       /*!> through which RF chain the packet was received */
00212     uint8_t     modulation ;     /*!> modulation used by the packet */
00213     uint8_t     bandwidth ;      /*!> modulation bandwidth (LoRa only) */
00214     uint32_t    datarate ;       /*!> RX datarate of the packet (SF for LoRa) */
00215     uint8_t     coderate ;       /*!> error-correcting code of the packet (LoRa only) */
00216     float       rssi ;           /*!> average packet RSSI in dB */
00217     float       snr ;            /*!> average packet SNR, in dB (LoRa only) */
00218     float       snr_min ;        /*!> minimum packet SNR, in dB (LoRa only) */
00219     float       snr_max ;        /*!> maximum packet SNR, in dB (LoRa only) */
00220     uint16_t    crc ;            /*!> CRC that was received in the payload */
00221     uint16_t    size ;           /*!> payload size in bytes */
00222     uint8_t     payload [256];   /*!> buffer containing the payload */
00223 };
00224 
00225 
00226 
00227 /**
00228 @struct lgw_pkt_tx_s
00229 @brief Structure containing the configuration of a packet to send and a pointer to the payload
00230 */
00231 struct lgw_pkt_tx_s {
00232     uint32_t    freq_hz;        /*!> center frequency of TX */
00233     uint8_t     tx_mode ;        /*!> select on what event/time the TX is triggered */
00234     uint32_t    count_us ;       /*!> timestamp or delay in microseconds for TX trigger */
00235     uint8_t     rf_chain ;       /*!> through which RF chain will the packet be sent */
00236     int8_t      rf_power ;       /*!> TX power, in dBm */
00237     uint8_t     modulation ;     /*!> modulation to use for the packet */
00238     uint8_t     bandwidth ;      /*!> modulation bandwidth (LoRa only) */
00239     uint32_t    datarate ;       /*!> TX datarate (baudrate for FSK, SF for LoRa) */
00240     uint8_t     coderate ;       /*!> error-correcting code of the packet (LoRa only) */
00241     bool        invert_pol ;     /*!> invert signal polarity, for orthogonal downlinks (LoRa only) */
00242     uint8_t     f_dev ;          /*!> frequency deviation, in kHz (FSK only) */
00243     uint16_t    preamble ;       /*!> set the preamble length, 0 for default */
00244     bool        no_crc ;         /*!> if true, do not send a CRC in the packet */
00245     bool        no_header ;      /*!> if true, enable implicit header mode (LoRa), fixed length (FSK) */
00246     uint16_t    size ;           /*!> payload size in bytes */
00247     uint8_t     payload [256];   /*!> buffer containing the payload */
00248 };
00249 
00250 /**
00251 @struct lgw_tx_gain_s
00252 @brief Structure containing all gains of Tx chain
00253 */
00254 struct lgw_tx_gain_s {
00255     uint8_t dig_gain;   /*!> 2 bits, control of the digital gain of SX1308 */
00256     uint8_t pa_gain ;    /*!> 2 bits, control of the external PA (SX1308 I/O) */
00257     uint8_t dac_gain ;   /*!> 2 bits, control of the radio DAC */
00258     uint8_t mix_gain ;   /*!> 4 bits, control of the radio mixer */
00259     int8_t  rf_power ;   /*!> measured TX power at the board connector, in dBm */
00260 };
00261 
00262 /**
00263 @struct lgw_tx_gain_lut_s
00264 @brief Structure defining the Tx gain LUT
00265 */
00266 struct lgw_tx_gain_lut_s {
00267     struct lgw_tx_gain_s    lut[TX_GAIN_LUT_SIZE_MAX];  /*!> Array of Tx gain struct */
00268     uint8_t                 size ;                       /*!> Number of LUT indexes */
00269 };
00270 
00271 /* -------------------------------------------------------------------------- */
00272 /* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
00273 
00274 /**
00275 @brief Configure the gateway board
00276 @param conf structure containing the configuration parameters
00277 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00278 */
00279 int lgw_board_setconf(struct lgw_conf_board_s conf);
00280 
00281 /**
00282 @brief Configure an RF chain (must configure before start)
00283 @param rf_chain number of the RF chain to configure [0, LGW_RF_CHAIN_NB - 1]
00284 @param conf structure containing the configuration parameters
00285 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00286 */
00287 int lgw_rxrf_setconf(uint8_t rf_chain, struct lgw_conf_rxrf_s conf);
00288 
00289 /**
00290 @brief Configure an IF chain + modem (must configure before start)
00291 @param if_chain number of the IF chain + modem to configure [0, LGW_IF_CHAIN_NB - 1]
00292 @param conf structure containing the configuration parameters
00293 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00294 */
00295 int lgw_rxif_setconf(uint8_t if_chain, struct lgw_conf_rxif_s conf);
00296 
00297 /**
00298 @brief Configure the Tx gain LUT
00299 @param pointer to structure defining the LUT
00300 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00301 */
00302 int lgw_txgain_setconf(struct lgw_tx_gain_lut_s *conf);
00303 
00304 /**
00305 @brief Connect to the LoRa concentrator, reset it and configure it according to previously set parameters
00306 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00307 */
00308 int lgw_start(void);
00309 
00310 /**
00311 @brief Stop the LoRa concentrator and disconnect it
00312 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00313 */
00314 int lgw_stop(void);
00315 
00316 /**
00317 @brief A non-blocking function that will fetch up to 'max_pkt' packets from the LoRa concentrator FIFO and data buffer
00318 @param max_pkt maximum number of packet that must be retrieved (equal to the size of the array of struct)
00319 @param pkt_data pointer to an array of struct that will receive the packet metadata and payload pointers
00320 @return LGW_HAL_ERROR id the operation failed, else the number of packets retrieved
00321 */
00322 int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data);
00323 
00324 /**
00325 @brief Schedule a packet to be send immediately or after a delay depending on tx_mode
00326 @param pkt_data structure containing the data and metadata for the packet to send
00327 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00328 
00329 /!\ When sending a packet, there is a 1.5 ms delay for the analog circuitry to start and be stable (TX_START_DELAY).
00330 In 'timestamp' mode, this is transparent: the modem is started 1.5ms before the user-set timestamp value is reached, the preamble of the packet start right when the internal timestamp counter reach target value.
00331 In 'immediate' mode, the packet is emitted as soon as possible: transferring the packet (and its parameters) from the host to the concentrator takes some time, then there is the TX_START_DELAY, then the packet is emitted.
00332 In 'triggered' mode (aka PPS/GPS mode), the packet, typically a beacon, is emitted 1.5ms after a rising edge of the trigger signal. Because there is no way to anticipate the triggering event and start the analog circuitry beforehand, that delay must be taken into account in the protocol.
00333 */
00334 int lgw_send(struct lgw_pkt_tx_s pkt_data);
00335 
00336 /**
00337 @brief Give the the status of different part of the LoRa concentrator
00338 @param select is used to select what status we want to know
00339 @param code is used to return the status code
00340 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00341 */
00342 int lgw_status(uint8_t select, uint8_t *code);
00343 
00344 /**
00345 @brief Abort a currently scheduled or ongoing TX
00346 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00347 */
00348 int lgw_abort_tx(void);
00349 
00350 /**
00351 @brief Return value of internal counter when latest event (eg GPS pulse) was captured
00352 @param trig_cnt_us pointer to receive timestamp value
00353 @return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
00354 */
00355 int lgw_get_trigcnt(uint32_t* trig_cnt_us);
00356 
00357 /**
00358 @brief Allow user to check the version/options of the library once compiled
00359 @return pointer on a human-readable null terminated string
00360 */
00361 const char* lgw_version_info(void);
00362 
00363 /**
00364 @brief Return time on air of given packet, in milliseconds
00365 @param packet is a pointer to the packet structure
00366 @return the packet time on air in milliseconds
00367 */
00368 uint32_t lgw_time_on_air(struct lgw_pkt_tx_s *packet);
00369 
00370 /**
00371 @brief Transfer the calibration offsets from the AGC firwmare to the local array
00372 @param idx_start is the start index in the local array where the calibration offset are being copied
00373 @param idx_nb is the number of calibration offsets to be copied in the local array
00374 @return the packet time on air in milliseconds
00375 */
00376 void lgw_calibration_offset_transfer(uint8_t idx_start, uint8_t idx_nb);
00377 
00378 #endif
00379 
00380 /* --- EOF ------------------------------------------------------------------ */