> #### New features * Added support for USB interface between the HOST and the concentrator, for sx1250 based concentrator only. * Added support for Listen-Before-Talk for AS923 region, using the additional sx1261 radio from the Semtech Corecell reference design v3. * Added support for Spectral Scan with additional sx1261 radio from the Semtech Corecell reference design v3. * Added support for SX1303 chip, for further Fine Timestamping support. * Merged the master-fdd-cn490 branch to bring support for CN490 Full-Duplex reference design. It is an integration of the releases v1.1.0, v1.1.1, v1.1.2 described below. > #### Changes * HAL: Reworked the complete communication layer. A new loragw_com module has been introduced to handle switching from a USB or a SPI communication interface, aligned function prototypes for sx125x, sx1250 and sx1261 radios. For USB, a mode has been added to group SPI write commands request to the STM32 MCU, in order to optimize latency during time critical configuration phases. * HAL: Added preliminary support for Fine Timestamping for TDOA localization. * HAL: Updated AGC firmware to v6: add configurable delay for PA to start, add Listen-Before-Talk support. * HAL: Added new API function lgw_demod_setconf() to set global demodulator settings. * HAL: Added new API functions for Spectral Scan. * Packet Forwarder: The type of interface is configurable in the global_conf.json file: com_type can be "USB" or "SPI". * Packet Forwarder: Changed the parameters to configure fine timestamping in the global_conf.json. * Packet Forwarder: Added sections to configure the spectral scan and Listen-Before-Talk features. * Packet Forwarder: Added a new thread for background spectral scan example, to show how to use the spectral scan API provided by the HAL, without interfering with the main tasks of the gateway (aka Receive uplinks and transmit downlinks). * Packet Forwarder: Added "nhdr" field parsing from "txpk" JSON downlink request in order to be able to send beacon request from Network Server. * Packet Forwarder: Added chan_multiSF_All in global_conf.json to choose which spreading factors to enable for multi-sf demodulators. * Packet Forwarder: Updated PROTOCOL.md to v1.6. * Tools: added util_spectral_scan, a standalone spectral scanner utility. > #### Notes * This release has been validated on the Semtech Corecell reference design v3 with USB interface. v1.1.2 > Integrated in ***v2.0.0*** from ***master-fdd-cn490*** branch. * packet forwarder: updated global_conf.json.sx1255.CN490.full-duplex with RSSI temperature compensation coefficients, and updated RSSI offset for radio 1. v1.1.1 > Integrated in ***v2.0.0*** from ***master-fdd-cn490*** branch. * HAL: Updated SX1302 LNA/PA LUT configuration for Full Duplex CN490 reference design. * test_loragw_hal_rx/tx: added --fdd option to enable Full Duplex * packet forwarder: updated global_conf.json.sx1255.CN490.full-duplex for CN490 reference design. v1.1.0 > Integrated in ***v2.0.0*** from ***master-fdd-cn490*** branch. * HAL: Added support for CN490 full duplex reference design.
456 lines
13 KiB
C
456 lines
13 KiB
C
/*
|
|
/ _____) _ | |
|
|
( (____ _____ ____ _| |_ _____ ____| |__
|
|
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
|
_____) ) ____| | | || |_| ____( (___| | | |
|
|
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
|
(C)2019 Semtech
|
|
|
|
Description:
|
|
SX1302 Hardware Abstraction Layer entry functions.
|
|
|
|
License: Revised BSD License, see LICENSE.TXT file include in the project
|
|
*/
|
|
|
|
#ifndef _LORAGW_SX1302_H
|
|
#define _LORAGW_SX1302_H
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* --- DEPENDANCIES --------------------------------------------------------- */
|
|
|
|
#include <stdint.h> /* C99 types*/
|
|
|
|
#include "config.h" /* library configuration options (dynamically generated) */
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
|
|
|
/* Default values */
|
|
#define SX1302_AGC_RADIO_GAIN_AUTO 0xFF
|
|
#define TX_START_DELAY_DEFAULT 1500 /* Calibrated value for 500KHz BW */
|
|
|
|
/* type of if_chain + modem */
|
|
#define IF_UNDEFINED 0
|
|
#define IF_LORA_STD 0x10 /* if + standard single-SF LoRa modem */
|
|
#define IF_LORA_MULTI 0x11 /* if + LoRa receiver with multi-SF capability */
|
|
#define IF_FSK_STD 0x20 /* if + standard FSK modem */
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
|
|
|
#define REG_SELECT(rf_chain, a, b) ((rf_chain == 0) ? a : b)
|
|
|
|
#define SET_PPM_ON(bw,dr) (((bw == BW_125KHZ) && ((dr == DR_LORA_SF11) || (dr == DR_LORA_SF12))) || ((bw == BW_250KHZ) && (dr == DR_LORA_SF12)))
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
|
|
|
/**
|
|
@enum sx1302_model_id_t
|
|
@brief
|
|
*/
|
|
typedef enum {
|
|
CHIP_MODEL_ID_SX1302 = 0x02, /* SX1302 can be 0x00 or 0x02 */
|
|
CHIP_MODEL_ID_SX1303 = 0x03,
|
|
CHIP_MODEL_ID_UNKNOWN
|
|
} sx1302_model_id_t;
|
|
|
|
/**
|
|
@enum sx1302_rx_frequency_tracking_t
|
|
@brief Frequency Tracking mode
|
|
*/
|
|
typedef enum {
|
|
RX_FREQ_TRACK_OFF = 0x00,
|
|
RX_FREQ_TRACK_ON = 0x01,
|
|
RX_FREQ_TRACK_AUTO = 0x03
|
|
} sx1302_rx_frequency_tracking_t;
|
|
|
|
/**
|
|
@enum sx1302_rx_fine_timing_mode_t
|
|
@brief Fine Timing mode
|
|
*/
|
|
typedef enum {
|
|
RX_FINE_TIMING_MODE_ABS = 0x01,
|
|
RX_FINE_TIMING_MODE_LINEAR = 0x02,
|
|
RX_FINE_TIMING_MODE_AUTO = 0x03
|
|
} sx1302_rx_fine_timing_mode_t;
|
|
|
|
/**
|
|
@enum sx1302_rx_dft_peak_mode_t
|
|
@brief DFT peak mode
|
|
*/
|
|
typedef enum {
|
|
RX_DFT_PEAK_MODE_DISABLED = 0x00,
|
|
RX_DFT_PEAK_MODE_FULL = 0x01,
|
|
RX_DFT_PEAK_MODE_TRACK = 0x02,
|
|
RX_DFT_PEAK_MODE_AUTO = 0x03
|
|
} sx1302_rx_dft_peak_mode_t;
|
|
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
|
|
|
/**
|
|
@brief Initialize sx1302 for operating, and needed internal structures (rx_buffer,....)
|
|
@param conf a pointer to the fine timestamp configuration context
|
|
@return LGW_REG_SUCCESS if no error, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_init(const struct lgw_conf_ftime_s *conf);
|
|
|
|
/**
|
|
@brief Get the SX1302 unique identifier
|
|
@param eui pointerto the memory holding the concentrator EUI
|
|
@return LGW_REG_SUCCESS if no error, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_get_eui(uint64_t * eui);
|
|
|
|
/**
|
|
@brief Get the SX1302/SX1303 Chip Model ID
|
|
@param model_id pointer to the memory holding the Chip Model ID
|
|
@return LGW_REG_SUCCESS if no error, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_get_model_id(sx1302_model_id_t * model_id);
|
|
|
|
/**
|
|
@brief Check AGC & ARB MCUs parity error, and update timestamp counter wraping status
|
|
@brief This function needs to be called regularly (every few seconds) by the upper layer
|
|
@param N/A
|
|
@return LGW_REG_SUCCESS if no error, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_update(void);
|
|
|
|
/**
|
|
@brief Select the clock source radio
|
|
@param rf_chain The RF chain index from which to get the clock source
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_radio_clock_select(uint8_t rf_chain);
|
|
|
|
/**
|
|
@brief Apply the radio reset sequence to the required RF chain index
|
|
@param rf_chain The RF chain index of the radio to be reset
|
|
@param type The type of radio to be reset
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_radio_reset(uint8_t rf_chain, lgw_radio_type_t type);
|
|
|
|
/**
|
|
@brief Configure the radio type for the given RF chain
|
|
@param rf_chain The RF chain index to be configured
|
|
@param type The type of radio to be set for the given RF chain
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_radio_set_mode(uint8_t rf_chain, lgw_radio_type_t type);
|
|
|
|
/**
|
|
@brief Give/Release control over the radios to/from the Host
|
|
@param host_ctrl Set to true to give control to the host, false otherwise
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_radio_host_ctrl(bool host_ctrl);
|
|
|
|
/**
|
|
@brief Perform the radio calibration sequence and fill the TX gain LUT with calibration offsets
|
|
@param context_rf_chain The RF chains array from which to get RF chains current configuration
|
|
@param clksrc The RF chain index which provides the clock source
|
|
@param txgain_lut A pointer to the TX gain LUT to be filled
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_radio_calibrate(struct lgw_conf_rxrf_s * context_rf_chain, uint8_t clksrc, struct lgw_tx_gain_lut_s * txgain_lut);
|
|
|
|
/**
|
|
@brief Configure the PA and LNA LUTs
|
|
@param context_board A pointer to the current board configuration context
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_pa_lna_lut_configure(struct lgw_conf_board_s * context_board);
|
|
|
|
/**
|
|
@brief Configure the Radio Front-End stage of the SX1302
|
|
@param N/A
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_radio_fe_configure(void);
|
|
|
|
/**
|
|
@brief Returns the type of the given modem index (LoRa MultiSF, LoRa SingleSF, FSK)
|
|
@param if_chain the index if the IF chain
|
|
@return The IF chain type
|
|
*/
|
|
uint8_t sx1302_get_ifmod_config(uint8_t if_chain);
|
|
|
|
/**
|
|
@brief Configure the channelizer stage of the SX1302
|
|
@param if_cfg A pointer to the channels configuration
|
|
@param fix_gain Set to true to force the channelizer to a fixed gain, false to let the AGC controlling it
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_channelizer_configure(struct lgw_conf_rxif_s * if_cfg, bool fix_gain);
|
|
|
|
/**
|
|
@brief Configure the correlator stage of the SX1302 LoRa multi-SF modems
|
|
@param if_cfg A pointer to the channels configuration
|
|
@param demod_cfg A pointer to the demodulators configuration
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_lora_correlator_configure(struct lgw_conf_rxif_s * if_cfg, struct lgw_conf_demod_s * demod_cfg);
|
|
|
|
/**
|
|
@brief Configure the correlator stage of the SX1302 LoRa single-SF modem
|
|
@param cfg A pointer to the channel configuration
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_lora_service_correlator_configure(struct lgw_conf_rxif_s * cfg);
|
|
|
|
/**
|
|
@brief Configure the syncword to be used by LoRa modems (public:0x34, private:0x12)
|
|
@param public Set to true to use the "public" syncword, false to use the private one
|
|
@param lora_service_sf The spreading factor configured for the single-SF LoRa modem
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_lora_syncword(bool public, uint8_t lora_service_sf);
|
|
|
|
/**
|
|
@brief Configure the LoRa multi-SF modems
|
|
@param radio_freq_hz The center frequency of the RF chain (0 or 1)
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_lora_modem_configure(uint32_t radio_freq_hz);
|
|
|
|
/**
|
|
@brief Configure the LoRa single-SF modem
|
|
@param cfg A pointer to the channel configuration
|
|
@param radio_freq_hz The center frequency of the RF chain (0 or 1)
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_lora_service_modem_configure(struct lgw_conf_rxif_s * cfg, uint32_t radio_freq_hz);
|
|
|
|
/**
|
|
@brief Configure the FSK modem
|
|
@param cfg A pointer to the channel configuration
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_fsk_configure(struct lgw_conf_rxif_s * cfg);
|
|
|
|
/**
|
|
@brief Enable the modems
|
|
@param N/A
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_modem_enable(void);
|
|
|
|
/**
|
|
@brief Enable/Disable the GPS to allow PPS trigger and counter sampling
|
|
@param enbale Set to true to enable, false otherwise
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_gps_enable(bool enable);
|
|
|
|
/**
|
|
@brief Get the current SX1302 internal counter value
|
|
@param pps True for getting the counter value at last PPS
|
|
@return the counter value in mciroseconds (32-bits)
|
|
*/
|
|
uint32_t sx1302_timestamp_counter(bool pps);
|
|
|
|
/**
|
|
@brief Load firmware to AGC MCU memory
|
|
@param firmware A pointer to the fw binary to be loaded
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_agc_load_firmware(const uint8_t *firmware);
|
|
|
|
/**
|
|
@brief Read the AGC status register for current status
|
|
@param status A pointer to store the current status returned
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_agc_status(uint8_t* status);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_agc_wait_status(uint8_t status);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_agc_mailbox_read(uint8_t mailbox, uint8_t* value);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_agc_mailbox_write(uint8_t mailbox, uint8_t value);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_agc_start(uint8_t version, lgw_radio_type_t radio_type, uint8_t ana_gain, uint8_t dec_gain, bool full_duplex, bool lbt_enable);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_arb_load_firmware(const uint8_t *firmware);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_arb_status(uint8_t* status);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_arb_wait_status(uint8_t status);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_arb_debug_read(uint8_t reg_id, uint8_t* value);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_arb_debug_write(uint8_t reg_id, uint8_t value);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_arb_start(uint8_t version, const struct lgw_conf_ftime_s * ftime_context);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
uint8_t sx1302_arb_get_debug_stats_detect(uint8_t channel);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
uint8_t sx1302_arb_get_debug_stats_alloc(uint8_t channel);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
void sx1302_arb_print_debug_stats(void);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
uint16_t sx1302_lora_payload_crc(const uint8_t * data, uint8_t size);
|
|
|
|
/**
|
|
@brief Get the number of packets available in rx_buffer and fetch data from ...
|
|
@brief ... the SX1302 if rx_buffer is empty.
|
|
@param nb_pkt A pointer to allocated memory to hold the number of packet fetched
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_fetch(uint8_t * nb_pkt);
|
|
|
|
/**
|
|
@brief Parse and return the next packet available in rx_buffer.
|
|
@param context Gateway configuration context
|
|
@param p The structure to get the packet parsed
|
|
@return LGW_REG_SUCCESS if a packet could be parsed, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p);
|
|
|
|
/**
|
|
@brief Configure the delay to be applied by the SX1302 for TX to start
|
|
@param rf_chain RF chain index to be configured
|
|
@param radio_type Type of radio for this RF chain
|
|
@param modulation Modulation used for the TX
|
|
@param bandwidth Bandwidth used for the TX
|
|
@param chirp_lowpass Chirp Low Pass filtering configuration
|
|
@param delay TX start delay calculated and applied
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uint8_t modulation, uint8_t bandwidth, uint8_t chirp_lowpass, uint16_t * delay);
|
|
|
|
/**
|
|
@brief Compute the offset to be applied on RSSI for temperature compensation
|
|
@param context a pointer to the memory that holds the current temp comp context
|
|
@param temperature the temperature for which to compute the offset to be applied
|
|
@return the offset to be applied to RSSI
|
|
*/
|
|
float sx1302_rssi_get_temperature_offset(struct lgw_rssi_tcomp_s * context, float temperature);
|
|
|
|
/**
|
|
@brief Get current TX status of the SX1302
|
|
@param rf_chain the TX chain we want to get the status from
|
|
@return current status
|
|
*/
|
|
uint8_t sx1302_tx_status(uint8_t rf_chain);
|
|
|
|
/**
|
|
@brief Get current RX status of the SX1302
|
|
@param rf_chain the RX chain we want to get the status from
|
|
@return current status
|
|
@note NOT IMPLEMENTED
|
|
*/
|
|
uint8_t sx1302_rx_status(uint8_t rf_chain);
|
|
|
|
/**
|
|
@brief Abort current transmit
|
|
@param rf_chain the TX chain on which we want to abort transmit
|
|
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
|
*/
|
|
int sx1302_tx_abort(uint8_t rf_chain);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_tx_configure(lgw_radio_type_t radio_type);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut, bool lwan_public, struct lgw_conf_rxif_s * context_fsk, struct lgw_pkt_tx_s * pkt_data);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
int sx1302_set_gpio(uint8_t gpio_reg_val);
|
|
|
|
/**
|
|
@brief TODO
|
|
@param TODO
|
|
@return TODO
|
|
*/
|
|
double sx1302_dc_notch_delay(double if_freq_hz);
|
|
|
|
#endif
|
|
|
|
/* --- EOF ------------------------------------------------------------------ */
|