summaryrefslogtreecommitdiff
path: root/libloragw/inc
diff options
context:
space:
mode:
authorHarsh Sharma <92harshsharma@gmail.com>2018-06-13 13:24:54 -0500
committerHarsh Sharma <92harshsharma@gmail.com>2018-06-13 13:24:54 -0500
commit7c383be1542368f2601015d9fc2a417197677677 (patch)
treebc06453f879cbadf65fd88123c506956403c5684 /libloragw/inc
downloadlora_gateway_mtac_full-7c383be1542368f2601015d9fc2a417197677677.tar.gz
lora_gateway_mtac_full-7c383be1542368f2601015d9fc2a417197677677.tar.bz2
lora_gateway_mtac_full-7c383be1542368f2601015d9fc2a417197677677.zip
Initial Commit
Diffstat (limited to 'libloragw/inc')
-rw-r--r--libloragw/inc/loragw_aux.h48
-rw-r--r--libloragw/inc/loragw_fpga.h135
-rw-r--r--libloragw/inc/loragw_gps.h235
-rw-r--r--libloragw/inc/loragw_hal.h419
-rw-r--r--libloragw/inc/loragw_lbt.h70
-rw-r--r--libloragw/inc/loragw_radio.h73
-rw-r--r--libloragw/inc/loragw_reg.h461
-rw-r--r--libloragw/inc/loragw_spi.h105
-rw-r--r--libloragw/inc/loragw_sx125x.h49
-rw-r--r--libloragw/inc/loragw_sx1272_fsk.h113
-rw-r--r--libloragw/inc/loragw_sx1272_lora.h89
-rw-r--r--libloragw/inc/loragw_sx1276_fsk.h112
-rw-r--r--libloragw/inc/loragw_sx1276_lora.h94
13 files changed, 2003 insertions, 0 deletions
diff --git a/libloragw/inc/loragw_aux.h b/libloragw/inc/loragw_aux.h
new file mode 100644
index 0000000..35b39ab
--- /dev/null
+++ b/libloragw/inc/loragw_aux.h
@@ -0,0 +1,48 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ LoRa concentrator HAL common auxiliary functions
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Sylvain Miermont
+*/
+
+
+#ifndef _LORAGW_AUX_H
+#define _LORAGW_AUX_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#include "config.h" /* library configuration options (dynamically generated) */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC MACROS -------------------------------------------------------- */
+
+/**
+@brief Get a particular bit value from a byte
+@param b [in] Any byte from which we want a bit value
+@param p [in] Position of the bit in the byte [0..7]
+@param n [in] Number of bits we want to get
+@return The value corresponding the requested bits
+*/
+#define TAKE_N_BITS_FROM(b, p, n) (((b) >> (p)) & ((1 << (n)) - 1))
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+/**
+@brief Wait for a certain time (millisecond accuracy)
+@param t number of milliseconds to wait.
+*/
+void wait_ms(unsigned long t);
+
+#endif
+
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_fpga.h b/libloragw/inc/loragw_fpga.h
new file mode 100644
index 0000000..f599f73
--- /dev/null
+++ b/libloragw/inc/loragw_fpga.h
@@ -0,0 +1,135 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ Functions used to handle FPGA register access for LoRa concentrator.
+ Registers are addressed by name.
+ Multi-bytes registers are handled automatically.
+ Read-modify-write is handled automatically.
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Michael Coracin
+*/
+
+#ifndef _LORAGW_FPGA_REG_H
+#define _LORAGW_FPGA_REG_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#include <stdint.h> /* C99 types */
+#include <stdbool.h> /* bool type */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+#define LGW_REG_SUCCESS 0
+#define LGW_REG_ERROR -1
+
+#define LGW_MIN_NOTCH_FREQ 126000U /* 126 KHz */
+#define LGW_MAX_NOTCH_FREQ 250000U /* 250 KHz */
+#define LGW_DEFAULT_NOTCH_FREQ 129000U /* 129 KHz */
+
+/*
+auto generated register mapping for C code
+this file contains autogenerated C struct used to access the FPGA registers
+this file is autogenerated from registers description
+*/
+
+#define LGW_FPGA_SOFT_RESET 0
+#define LGW_FPGA_FEATURE 1
+#define LGW_FPGA_LBT_INITIAL_FREQ 2
+#define LGW_FPGA_VERSION 3
+#define LGW_FPGA_STATUS 4
+#define LGW_FPGA_CTRL_FEATURE_START 5
+#define LGW_FPGA_CTRL_RADIO_RESET 6
+#define LGW_FPGA_CTRL_INPUT_SYNC_I 7
+#define LGW_FPGA_CTRL_INPUT_SYNC_Q 8
+#define LGW_FPGA_CTRL_OUTPUT_SYNC 9
+#define LGW_FPGA_CTRL_INVERT_IQ 10
+#define LGW_FPGA_CTRL_ACCESS_HISTO_MEM 11
+#define LGW_FPGA_CTRL_CLEAR_HISTO_MEM 12
+#define LGW_FPGA_HISTO_RAM_ADDR 13
+#define LGW_FPGA_HISTO_RAM_DATA 14
+#define LGW_FPGA_HISTO_NB_READ 15
+#define LGW_FPGA_LBT_TIMESTAMP_CH 16
+#define LGW_FPGA_LBT_TIMESTAMP_SELECT_CH 17
+#define LGW_FPGA_LBT_CH0_FREQ_OFFSET 18
+#define LGW_FPGA_LBT_CH1_FREQ_OFFSET 19
+#define LGW_FPGA_LBT_CH2_FREQ_OFFSET 20
+#define LGW_FPGA_LBT_CH3_FREQ_OFFSET 21
+#define LGW_FPGA_LBT_CH4_FREQ_OFFSET 22
+#define LGW_FPGA_LBT_CH5_FREQ_OFFSET 23
+#define LGW_FPGA_LBT_CH6_FREQ_OFFSET 24
+#define LGW_FPGA_LBT_CH7_FREQ_OFFSET 25
+#define LGW_FPGA_SCAN_FREQ_OFFSET 26
+#define LGW_FPGA_LBT_SCAN_TIME_CH0 27
+#define LGW_FPGA_LBT_SCAN_TIME_CH1 28
+#define LGW_FPGA_LBT_SCAN_TIME_CH2 29
+#define LGW_FPGA_LBT_SCAN_TIME_CH3 30
+#define LGW_FPGA_LBT_SCAN_TIME_CH4 31
+#define LGW_FPGA_LBT_SCAN_TIME_CH5 32
+#define LGW_FPGA_LBT_SCAN_TIME_CH6 33
+#define LGW_FPGA_LBT_SCAN_TIME_CH7 34
+#define LGW_FPGA_RSSI_TARGET 35
+#define LGW_FPGA_HISTO_SCAN_FREQ 36
+#define LGW_FPGA_NOTCH_FREQ_OFFSET 37
+#define LGW_FPGA_TOTALREGS 38
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+/**
+@brief LoRa concentrator TX notch filter delay
+@return delay in microseconds introduced by TX notch filter
+*/
+float lgw_fpga_get_tx_notch_delay(void);
+
+/**
+@brief LoRa concentrator FPGA configuration
+@param tx_notch_freq TX notch filter frequency, in Hertz
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_fpga_configure(uint32_t tx_notch_freq);
+
+/**
+@brief LoRa concentrator FPGA register write
+@param register_id register number in the data structure describing registers
+@param reg_value signed value to write to the register (for u32, use cast)
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_fpga_reg_w(uint16_t register_id, int32_t reg_value);
+
+/**
+@brief LoRa concentrator FPGA register read
+@param register_id register number in the data structure describing registers
+@param reg_value pointer to a variable where to write register read value
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_fpga_reg_r(uint16_t register_id, int32_t *reg_value);
+
+/**
+@brief LoRa concentrator FPGA register burst write
+@param register_id register number in the data structure describing registers
+@param data pointer to byte array that will be sent to the LoRa concentrator
+@param size size of the transfer, in byte(s)
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_fpga_reg_wb(uint16_t register_id, uint8_t *data, uint16_t size);
+
+/**
+@brief LoRa concentrator FPGA register burst read
+@param register_id register number in the data structure describing registers
+@param data pointer to byte array that will be written from the LoRa concentrator
+@param size size of the transfer, in byte(s)
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_fpga_reg_rb(uint16_t register_id, uint8_t *data, uint16_t size);
+
+#endif
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_gps.h b/libloragw/inc/loragw_gps.h
new file mode 100644
index 0000000..6dbd30b
--- /dev/null
+++ b/libloragw/inc/loragw_gps.h
@@ -0,0 +1,235 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ Library of functions to manage a GNSS module (typically GPS) for accurate
+ timestamping of packets and synchronisation of gateways.
+ A limited set of module brands/models are supported.
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Michael Coracin
+*/
+
+
+#ifndef _LORAGW_GPS_H
+#define _LORAGW_GPS_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#define _GNU_SOURCE
+#include <stdint.h> /* C99 types */
+#include <time.h> /* time library */
+#include <termios.h> /* speed_t */
+#include <unistd.h> /* ssize_t */
+
+#include "config.h" /* library configuration options (dynamically generated) */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC TYPES --------------------------------------------------------- */
+
+/**
+@struct coord_s
+@brief Time solution required for timestamp to absolute time conversion
+*/
+struct tref {
+ time_t systime; /*!> system time when solution was calculated */
+ uint32_t count_us; /*!> reference concentrator internal timestamp */
+ struct timespec utc; /*!> reference UTC time (from GPS/NMEA) */
+ struct timespec gps; /*!> reference GPS time (since 01.Jan.1980) */
+ double xtal_err; /*!> raw clock error (eg. <1 'slow' XTAL) */
+};
+
+/**
+@struct coord_s
+@brief Geodesic coordinates
+*/
+struct coord_s {
+ double lat; /*!> latitude [-90,90] (North +, South -) */
+ double lon; /*!> longitude [-180,180] (East +, West -)*/
+ short alt; /*!> altitude in meters (WGS 84 geoid ref.) */
+};
+
+/**
+@enum gps_msg
+@brief Type of GPS (and other GNSS) sentences
+*/
+enum gps_msg {
+ UNKNOWN, /*!> neutral value */
+ IGNORED, /*!> frame was not parsed by the system */
+ INVALID, /*!> system try to parse frame but failed */
+ INCOMPLETE, /*!> frame parsed was missing bytes */
+ /* NMEA messages of interest */
+ NMEA_RMC, /*!> Recommended Minimum data (time + date) */
+ NMEA_GGA, /*!> Global positioning system fix data (pos + alt) */
+ NMEA_GNS, /*!> GNSS fix data (pos + alt, sat number) */
+ NMEA_ZDA, /*!> Time and Date */
+ /* NMEA message useful for time reference quality assessment */
+ NMEA_GBS, /*!> GNSS Satellite Fault Detection */
+ NMEA_GST, /*!> GNSS Pseudo Range Error Statistics */
+ NMEA_GSA, /*!> GNSS DOP and Active Satellites (sat number) */
+ NMEA_GSV, /*!> GNSS Satellites in View (sat SNR) */
+ /* Misc. NMEA messages */
+ NMEA_GLL, /*!> Latitude and longitude, with time fix and status */
+ NMEA_TXT, /*!> Text Transmission */
+ NMEA_VTG, /*!> Course over ground and Ground speed */
+ /* uBlox proprietary NMEA messages of interest */
+ UBX_NAV_TIMEGPS, /*!> GPS Time Solution */
+ UBX_NAV_TIMEUTC /*!> UTC Time Solution */
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+#define LGW_GPS_SUCCESS 0
+#define LGW_GPS_ERROR -1
+
+#define LGW_GPS_MIN_MSG_SIZE (8)
+#define LGW_GPS_UBX_SYNC_CHAR (0xB5)
+#define LGW_GPS_NMEA_SYNC_CHAR (0x24)
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+/**
+@brief Configure a GPS module
+
+@param tty_path path to the TTY connected to the GPS
+@param gps_familly parameter (eg. ubx6 for uBlox gen.6)
+@param target_brate target baudrate for communication (0 keeps default target baudrate)
+@param fd_ptr pointer to a variable to receive file descriptor on GPS tty
+@return success if the function was able to connect and configure a GPS module
+*/
+int lgw_gps_enable(char* tty_path, char* gps_familly, speed_t target_brate, int* fd_ptr);
+
+/**
+@brief Restore GPS serial configuration and close serial device
+
+@param fd file descriptor on GPS tty
+@return success if the function was able to complete
+*/
+int lgw_gps_disable(int fd);
+
+/**
+@brief Parse messages coming from the GPS system (or other GNSS)
+
+@param serial_buff pointer to the string to be parsed
+@param buff_size maximum string lengths for NMEA parsing (incl. null char)
+@return type of frame parsed
+
+The RAW NMEA sentences are parsed to a global set of variables shared with the
+lgw_gps_get function.
+If the lgw_parse_nmea and lgw_gps_get are used in different threads, a mutex
+lock must be acquired before calling either function.
+*/
+enum gps_msg lgw_parse_nmea(const char* serial_buff, int buff_size);
+
+/**
+@brief Parse Ublox proprietary messages coming from the GPS system
+
+@param serial_buff pointer to the string to be parsed
+@param buff_size maximum string lengths for UBX parsing (incl. null char)
+@param msg_size number of bytes parsed as UBX message if found
+@return type of frame parsed
+
+The RAW UBX sentences are parsed to a global set of variables shared with the
+lgw_gps_get function.
+If the lgw_parse_ubx and lgw_gps_get are used in different threads, a mutex
+lock must be acquired before calling either function.
+*/
+enum gps_msg lgw_parse_ubx(const char* serial_buff, size_t buff_size, size_t *msg_size);
+
+/**
+@brief Get the GPS solution (space & time) for the concentrator
+
+@param utc pointer to store UTC time, with ns precision (NULL to ignore)
+@param gps_time pointer to store GPS time, with ns precision (NULL to ignore)
+@param loc pointer to store coordinates (NULL to ignore)
+@param err pointer to store coordinates standard deviation (NULL to ignore)
+@return success if the chosen elements could be returned
+
+This function read the global variables generated by the NMEA/UBX parsing
+functions lgw_parse_nmea/lgw_parse_ubx. It returns time and location data in a
+format that is exploitable by other functions in that library sub-module.
+If the lgw_parse_nmea/lgw_parse_ubx and lgw_gps_get are used in different
+threads, a mutex lock must be acquired before calling either function.
+*/
+int lgw_gps_get(struct timespec *utc, struct timespec *gps_time, struct coord_s *loc, struct coord_s *err);
+
+/**
+@brief Get time and position information from the serial GPS last message received
+@param utc UTC time, with ns precision (leap seconds are ignored)
+@param gps_time timestamp of last time pulse from the GPS module converted to the UNIX epoch
+ (leap seconds are ignored)
+@param loc location information
+@param err location error estimate if supported
+@return success if timestamp was read and time reference could be refreshed
+
+Set systime to 0 in ref to trigger initial synchronization.
+*/
+int lgw_gps_sync(struct tref *ref, uint32_t count_us, struct timespec utc, struct timespec gps_time);
+
+/**
+@brief Convert concentrator timestamp counter value to UTC time
+
+@param ref time reference structure required for time conversion
+@param count_us internal timestamp counter of the LoRa concentrator
+@param utc pointer to store UTC time, with ns precision (leap seconds ignored)
+@return success if the function was able to convert timestamp to UTC
+
+This function is typically used when a packet is received to transform the
+internal counter-based timestamp in an absolute timestamp with an accuracy in
+the order of a couple microseconds (ns resolution).
+*/
+int lgw_cnt2utc(struct tref ref, uint32_t count_us, struct timespec* utc);
+
+/**
+@brief Convert UTC time to concentrator timestamp counter value
+
+@param ref time reference structure required for time conversion
+@param utc UTC time, with ns precision (leap seconds are ignored)
+@param count_us pointer to store internal timestamp counter of LoRa concentrator
+@return success if the function was able to convert UTC to timestamp
+
+This function is typically used when a packet must be sent at an accurate time
+(eg. to send a piggy-back response after receiving a packet from a node) to
+transform an absolute UTC time into a matching internal concentrator timestamp.
+*/
+int lgw_utc2cnt(struct tref ref,struct timespec utc, uint32_t* count_us);
+
+/**
+@brief Convert concentrator timestamp counter value to GPS time
+
+@param ref time reference structure required for time conversion
+@param count_us internal timestamp counter of the LoRa concentrator
+@param gps_time pointer to store GPS time, with ns precision (leap seconds ignored)
+@return success if the function was able to convert timestamp to GPS time
+
+This function is typically used when a packet is received to transform the
+internal counter-based timestamp in an absolute timestamp with an accuracy in
+the order of a millisecond.
+*/
+int lgw_cnt2gps(struct tref ref, uint32_t count_us, struct timespec* gps_time);
+
+/**
+@brief Convert GPS time to concentrator timestamp counter value
+
+@param ref time reference structure required for time conversion
+@param gps_time GPS time, with ns precision (leap seconds are ignored)
+@param count_us pointer to store internal timestamp counter of LoRa concentrator
+@return success if the function was able to convert GPS time to timestamp
+
+This function is typically used when a packet must be sent at an accurate time
+(eg. to send a piggy-back response after receiving a packet from a node) to
+transform an absolute GPS time into a matching internal concentrator timestamp.
+*/
+int lgw_gps2cnt(struct tref ref, struct timespec gps_time, uint32_t* count_us);
+
+#endif
+
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_hal.h b/libloragw/inc/loragw_hal.h
new file mode 100644
index 0000000..d5f9ade
--- /dev/null
+++ b/libloragw/inc/loragw_hal.h
@@ -0,0 +1,419 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ LoRa concentrator Hardware Abstraction Layer
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Sylvain Miermont
+*/
+
+
+#ifndef _LORAGW_HAL_H
+#define _LORAGW_HAL_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#include <stdint.h> /* C99 types */
+#include <stdbool.h> /* bool type */
+
+#include "config.h" /* library configuration options (dynamically generated) */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC MACROS -------------------------------------------------------- */
+
+#define IS_LORA_BW(bw) ((bw == BW_125KHZ) || (bw == BW_250KHZ) || (bw == BW_500KHZ))
+#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))
+#define IS_LORA_MULTI_DR(dr) ((dr & ~DR_LORA_MULTI) == 0) /* ones outside of DR_LORA_MULTI bitmask -> not a combination of LoRa datarates */
+#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))
+
+#define IS_FSK_BW(bw) ((bw >= 1) && (bw <= 7))
+#define IS_FSK_DR(dr) ((dr >= DR_FSK_MIN) && (dr <= DR_FSK_MAX))
+
+#define IS_TX_MODE(mode) ((mode == IMMEDIATE) || (mode == TIMESTAMPED) || (mode == ON_GPS))
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+/* return status code */
+#define LGW_HAL_SUCCESS 0
+#define LGW_HAL_ERROR -1
+#define LGW_LBT_ISSUE 1
+
+/* radio-specific parameters */
+#define LGW_XTAL_FREQU 32000000 /* frequency of the RF reference oscillator */
+#define LGW_RF_CHAIN_NB 2 /* number of RF chains */
+#define LGW_RF_RX_BANDWIDTH {1000000, 1000000} /* bandwidth of the radios */
+
+/* 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 */
+
+/* concentrator chipset-specific parameters */
+/* to use array parameters, declare a local const and use 'if_chain' as index */
+#define LGW_IF_CHAIN_NB 10 /* number of IF+modem RX chains */
+#define LGW_PKT_FIFO_SIZE 16 /* depth of the RX packet FIFO */
+#define LGW_DATABUFF_SIZE 1024 /* size in bytes of the RX data buffer (contains payload & metadata) */
+#define LGW_REF_BW 125000 /* typical bandwidth of data channel */
+#define LGW_MULTI_NB 8 /* number of LoRa 'multi SF' chains */
+#define LGW_IFMODEM_CONFIG {\
+ IF_LORA_MULTI, \
+ IF_LORA_MULTI, \
+ IF_LORA_MULTI, \
+ IF_LORA_MULTI, \
+ IF_LORA_MULTI, \
+ IF_LORA_MULTI, \
+ IF_LORA_MULTI, \
+ IF_LORA_MULTI, \
+ IF_LORA_STD, \
+ IF_FSK_STD } /* configuration of available IF chains and modems on the hardware */
+
+/* values available for the 'modulation' parameters */
+/* NOTE: arbitrary values */
+#define MOD_UNDEFINED 0
+#define MOD_LORA 0x10
+#define MOD_FSK 0x20
+
+/* values available for the 'bandwidth' parameters (LoRa & FSK) */
+/* NOTE: directly encode FSK RX bandwidth, do not change */
+#define BW_UNDEFINED 0
+#define BW_500KHZ 0x01
+#define BW_250KHZ 0x02
+#define BW_125KHZ 0x03
+#define BW_62K5HZ 0x04
+#define BW_31K2HZ 0x05
+#define BW_15K6HZ 0x06
+#define BW_7K8HZ 0x07
+
+/* values available for the 'datarate' parameters */
+/* NOTE: LoRa values used directly to code SF bitmask in 'multi' modem, do not change */
+#define DR_UNDEFINED 0
+#define DR_LORA_SF7 0x02
+#define DR_LORA_SF8 0x04
+#define DR_LORA_SF9 0x08
+#define DR_LORA_SF10 0x10
+#define DR_LORA_SF11 0x20
+#define DR_LORA_SF12 0x40
+#define DR_LORA_MULTI 0x7E
+/* NOTE: for FSK directly use baudrate between 500 bauds and 250 kbauds */
+#define DR_FSK_MIN 500
+#define DR_FSK_MAX 250000
+
+/* values available for the 'coderate' parameters (LoRa only) */
+/* NOTE: arbitrary values */
+#define CR_UNDEFINED 0
+#define CR_LORA_4_5 0x01
+#define CR_LORA_4_6 0x02
+#define CR_LORA_4_7 0x03
+#define CR_LORA_4_8 0x04
+
+/* values available for the 'status' parameter */
+/* NOTE: values according to hardware specification */
+#define STAT_UNDEFINED 0x00
+#define STAT_NO_CRC 0x01
+#define STAT_CRC_BAD 0x11
+#define STAT_CRC_OK 0x10
+
+/* values available for the 'tx_mode' parameter */
+#define IMMEDIATE 0
+#define TIMESTAMPED 1
+#define ON_GPS 2
+//#define ON_EVENT 3
+//#define GPS_DELAYED 4
+//#define EVENT_DELAYED 5
+
+/* values available for 'select' in the status function */
+#define TX_STATUS 1
+#define RX_STATUS 2
+
+/* status code for TX_STATUS */
+/* NOTE: arbitrary values */
+#define TX_STATUS_UNKNOWN 0
+#define TX_OFF 1 /* TX modem disabled, it will ignore commands */
+#define TX_FREE 2 /* TX modem is free, ready to receive a command */
+#define TX_SCHEDULED 3 /* TX modem is loaded, ready to send the packet after an event and/or delay */
+#define TX_EMITTING 4 /* TX modem is emitting */
+
+/* status code for RX_STATUS */
+/* NOTE: arbitrary values */
+#define RX_STATUS_UNKNOWN 0
+#define RX_OFF 1 /* RX modem is disabled, it will ignore commands */
+#define RX_ON 2 /* RX modem is receiving */
+#define RX_SUSPENDED 3 /* RX is suspended while a TX is ongoing */
+
+/* Maximum size of Tx gain LUT */
+#define TX_GAIN_LUT_SIZE_MAX 16
+
+/* LBT constants */
+#define LBT_CHANNEL_FREQ_NB 8 /* Number of LBT channels */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC TYPES --------------------------------------------------------- */
+
+/**
+@enum lgw_radio_type_e
+@brief Radio types that can be found on the LoRa Gateway
+*/
+enum lgw_radio_type_e {
+ LGW_RADIO_TYPE_NONE,
+ LGW_RADIO_TYPE_SX1255,
+ LGW_RADIO_TYPE_SX1257,
+ LGW_RADIO_TYPE_SX1272,
+ LGW_RADIO_TYPE_SX1276
+};
+
+/**
+@struct lgw_conf_board_s
+@brief Configuration structure for board specificities
+*/
+struct lgw_conf_board_s {
+ bool lorawan_public; /*!> Enable ONLY for *public* networks using the LoRa MAC protocol */
+ uint8_t clksrc; /*!> Index of RF chain which provides clock to concentrator */
+};
+
+/**
+@struct lgw_conf_lbt_chan_s
+@brief Configuration structure for LBT channels
+*/
+struct lgw_conf_lbt_chan_s {
+ uint32_t freq_hz;
+ uint16_t scan_time_us;
+};
+
+/**
+@struct lgw_conf_lbt_s
+@brief Configuration structure for LBT specificities
+*/
+struct lgw_conf_lbt_s {
+ bool enable; /*!> enable or disable LBT */
+ int8_t rssi_target; /*!> RSSI threshold to detect if channel is busy or not (dBm) */
+ uint8_t nb_channel; /*!> number of LBT channels */
+ struct lgw_conf_lbt_chan_s channels[LBT_CHANNEL_FREQ_NB];
+ int8_t rssi_offset; /*!> RSSI offset to be applied to SX127x RSSI values */
+};
+
+/**
+@struct lgw_conf_rxrf_s
+@brief Configuration structure for a RF chain
+*/
+struct lgw_conf_rxrf_s {
+ bool enable; /*!> enable or disable that RF chain */
+ uint32_t freq_hz; /*!> center frequency of the radio in Hz */
+ float rssi_offset; /*!> Board-specific RSSI correction factor */
+ enum lgw_radio_type_e type; /*!> Radio type for that RF chain (SX1255, SX1257....) */
+ bool tx_enable; /*!> enable or disable TX on that RF chain */
+ uint32_t tx_notch_freq; /*!> TX notch filter frequency [126KHz..250KHz] */
+};
+
+/**
+@struct lgw_conf_rxif_s
+@brief Configuration structure for an IF chain
+*/
+struct lgw_conf_rxif_s {
+ bool enable; /*!> enable or disable that IF chain */
+ uint8_t rf_chain; /*!> to which RF chain is that IF chain associated */
+ int32_t freq_hz; /*!> center frequ of the IF chain, relative to RF chain frequency */
+ uint8_t bandwidth; /*!> RX bandwidth, 0 for default */
+ uint32_t datarate; /*!> RX datarate, 0 for default */
+ uint8_t sync_word_size; /*!> size of FSK sync word (number of bytes, 0 for default) */
+ uint64_t sync_word; /*!> FSK sync word (ALIGN RIGHT, eg. 0xC194C1) */
+};
+
+/**
+@struct lgw_pkt_rx_s
+@brief Structure containing the metadata of a packet that was received and a pointer to the payload
+*/
+struct lgw_pkt_rx_s {
+ uint32_t freq_hz; /*!> central frequency of the IF chain */
+ uint8_t if_chain; /*!> by which IF chain was packet received */
+ uint8_t status; /*!> status of the received packet */
+ uint32_t count_us; /*!> internal concentrator counter for timestamping, 1 microsecond resolution */
+ uint8_t rf_chain; /*!> through which RF chain the packet was received */
+ uint8_t modulation; /*!> modulation used by the packet */
+ uint8_t bandwidth; /*!> modulation bandwidth (LoRa only) */
+ uint32_t datarate; /*!> RX datarate of the packet (SF for LoRa) */
+ uint8_t coderate; /*!> error-correcting code of the packet (LoRa only) */
+ float rssi; /*!> average packet RSSI in dB */
+ float snr; /*!> average packet SNR, in dB (LoRa only) */
+ float snr_min; /*!> minimum packet SNR, in dB (LoRa only) */
+ float snr_max; /*!> maximum packet SNR, in dB (LoRa only) */
+ uint16_t crc; /*!> CRC that was received in the payload */
+ uint16_t size; /*!> payload size in bytes */
+ uint8_t payload[256]; /*!> buffer containing the payload */
+};
+
+/**
+@struct lgw_pkt_tx_s
+@brief Structure containing the configuration of a packet to send and a pointer to the payload
+*/
+struct lgw_pkt_tx_s {
+ uint32_t freq_hz; /*!> center frequency of TX */
+ uint8_t tx_mode; /*!> select on what event/time the TX is triggered */
+ uint32_t count_us; /*!> timestamp or delay in microseconds for TX trigger */
+ uint8_t rf_chain; /*!> through which RF chain will the packet be sent */
+ int8_t rf_power; /*!> TX power, in dBm */
+ uint8_t modulation; /*!> modulation to use for the packet */
+ uint8_t bandwidth; /*!> modulation bandwidth (LoRa only) */
+ uint32_t datarate; /*!> TX datarate (baudrate for FSK, SF for LoRa) */
+ uint8_t coderate; /*!> error-correcting code of the packet (LoRa only) */
+ bool invert_pol; /*!> invert signal polarity, for orthogonal downlinks (LoRa only) */
+ uint8_t f_dev; /*!> frequency deviation, in kHz (FSK only) */
+ uint16_t preamble; /*!> set the preamble length, 0 for default */
+ bool no_crc; /*!> if true, do not send a CRC in the packet */
+ bool no_header; /*!> if true, enable implicit header mode (LoRa), fixed length (FSK) */
+ uint16_t size; /*!> payload size in bytes */
+ uint8_t payload[256]; /*!> buffer containing the payload */
+};
+
+/**
+@struct lgw_tx_gain_s
+@brief Structure containing all gains of Tx chain
+*/
+struct lgw_tx_gain_s {
+ uint8_t dig_gain; /*!> 2 bits, control of the digital gain of SX1301 */
+ uint8_t pa_gain; /*!> 2 bits, control of the external PA (SX1301 I/O) */
+ uint8_t dac_gain; /*!> 2 bits, control of the radio DAC */
+ uint8_t mix_gain; /*!> 4 bits, control of the radio mixer */
+ int8_t rf_power; /*!> measured TX power at the board connector, in dBm */
+};
+
+/**
+@struct lgw_tx_gain_lut_s
+@brief Structure defining the Tx gain LUT
+*/
+struct lgw_tx_gain_lut_s {
+ struct lgw_tx_gain_s lut[TX_GAIN_LUT_SIZE_MAX]; /*!> Array of Tx gain struct */
+ uint8_t size; /*!> Number of LUT indexes */
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+/**
+@brief Configure the gateway board
+@param conf structure containing the configuration parameters
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_board_setconf(struct lgw_conf_board_s conf);
+
+/**
+@brief Configure the gateway lbt function
+@param conf structure containing the configuration parameters
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_lbt_setconf(struct lgw_conf_lbt_s conf);
+
+/**
+@brief Configure an RF chain (must configure before start)
+@param rf_chain number of the RF chain to configure [0, LGW_RF_CHAIN_NB - 1]
+@param conf structure containing the configuration parameters
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_rxrf_setconf(uint8_t rf_chain, struct lgw_conf_rxrf_s conf);
+
+/**
+@brief Configure an IF chain + modem (must configure before start)
+@param if_chain number of the IF chain + modem to configure [0, LGW_IF_CHAIN_NB - 1]
+@param conf structure containing the configuration parameters
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_rxif_setconf(uint8_t if_chain, struct lgw_conf_rxif_s conf);
+
+/**
+@brief Configure the Tx gain LUT
+@param pointer to structure defining the LUT
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_txgain_setconf(struct lgw_tx_gain_lut_s *conf);
+
+/**
+@brief Connect to the LoRa concentrator, reset it and configure it according to previously set parameters
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_start(void);
+
+/**
+@brief Stop the LoRa concentrator and disconnect it
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_stop(void);
+
+/**
+@brief A non-blocking function that will fetch up to 'max_pkt' packets from the LoRa concentrator FIFO and data buffer
+@param max_pkt maximum number of packet that must be retrieved (equal to the size of the array of struct)
+@param pkt_data pointer to an array of struct that will receive the packet metadata and payload pointers
+@return LGW_HAL_ERROR id the operation failed, else the number of packets retrieved
+*/
+int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data);
+
+/**
+@brief Schedule a packet to be send immediately or after a delay depending on tx_mode
+@param pkt_data structure containing the data and metadata for the packet to send
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+
+/!\ When sending a packet, there is a delay (approx 1.5ms) for the analog
+circuitry to start and be stable. This delay is adjusted by the HAL depending
+on the board version (lgw_i_tx_start_delay_us).
+
+In 'timestamp' mode, this is transparent: the modem is started
+lgw_i_tx_start_delay_us microseconds before the user-set timestamp value is
+reached, the preamble of the packet start right when the internal timestamp
+counter reach target value.
+
+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 lgw_i_tx_start_delay_us, then the packet is emitted.
+
+In 'triggered' mode (aka PPS/GPS mode), the packet, typically a beacon, is
+emitted lgw_i_tx_start_delay_us microsenconds 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.
+*/
+int lgw_send(struct lgw_pkt_tx_s pkt_data);
+
+/**
+@brief Give the the status of different part of the LoRa concentrator
+@param select is used to select what status we want to know
+@param code is used to return the status code
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_status(uint8_t select, uint8_t *code);
+
+/**
+@brief Abort a currently scheduled or ongoing TX
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_abort_tx(void);
+
+/**
+@brief Return value of internal counter when latest event (eg GPS pulse) was captured
+@param trig_cnt_us pointer to receive timestamp value
+@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
+*/
+int lgw_get_trigcnt(uint32_t* trig_cnt_us);
+
+/**
+@brief Allow user to check the version/options of the library once compiled
+@return pointer on a human-readable null terminated string
+*/
+const char* lgw_version_info(void);
+
+/**
+@brief Return time on air of given packet, in milliseconds
+@param packet is a pointer to the packet structure
+@return the packet time on air in milliseconds
+*/
+uint32_t lgw_time_on_air(struct lgw_pkt_tx_s *packet);
+
+#endif
+
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_lbt.h b/libloragw/inc/loragw_lbt.h
new file mode 100644
index 0000000..cb8aada
--- /dev/null
+++ b/libloragw/inc/loragw_lbt.h
@@ -0,0 +1,70 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ Functions used to handle the Listen Before Talk feature
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Michael Coracin
+*/
+
+#ifndef _LORAGW_LBT_H
+#define _LORAGW_LBT_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#include <stdint.h> /* C99 types */
+#include <stdbool.h> /* bool type */
+
+#include "loragw_hal.h"
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+#define LGW_LBT_SUCCESS 0
+#define LGW_LBT_ERROR -1
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+/**
+@brief Set the configuration parameters for LBT feature
+@param conf structure containing the configuration parameters
+@return LGW_LBT_ERROR id the operation failed, LGW_LBT_SUCCESS else
+*/
+int lbt_setconf(struct lgw_conf_lbt_s * conf);
+
+/**
+@brief Configure the concentrator for LBT feature
+@return LGW_LBT_ERROR id the operation failed, LGW_LBT_SUCCESS else
+*/
+int lbt_setup(void);
+
+/**
+@brief Start the LBT FSM
+@return LGW_LBT_ERROR id the operation failed, LGW_LBT_SUCCESS else
+*/
+int lbt_start(void);
+
+/**
+@brief Configure the concentrator for LBT feature
+@param pkt_data pointer to downlink packet to be trabsmitted
+@param tx_allowed pointer to receive permission for transmission
+@return LGW_LBT_ERROR id the operation failed, LGW_LBT_SUCCESS else
+*/
+int lbt_is_channel_free(struct lgw_pkt_tx_s * pkt_data, uint16_t tx_start_delay, bool * tx_allowed);
+
+/**
+@brief Check if LBT is enabled
+@return true if enabled, false otherwise
+*/
+bool lbt_is_enabled(void);
+
+#endif
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_radio.h b/libloragw/inc/loragw_radio.h
new file mode 100644
index 0000000..32d494b
--- /dev/null
+++ b/libloragw/inc/loragw_radio.h
@@ -0,0 +1,73 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ Functions used to handle LoRa concentrator radios.
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Michael Coracin
+*/
+
+#ifndef _LORAGW_RADIO_H
+#define _LORAGW_RADIO_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#include <stdint.h> /* C99 types */
+#include <stdbool.h> /* bool type */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+#define LGW_REG_SUCCESS 0
+#define LGW_REG_ERROR -1
+
+#define SX125x_32MHz_FRAC 15625 /* irreductible fraction for PLL register caculation */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+enum lgw_sx127x_rxbw_e {
+ LGW_SX127X_RXBW_2K6_HZ,
+ LGW_SX127X_RXBW_3K1_HZ,
+ LGW_SX127X_RXBW_3K9_HZ,
+ LGW_SX127X_RXBW_5K2_HZ,
+ LGW_SX127X_RXBW_6K3_HZ,
+ LGW_SX127X_RXBW_7K8_HZ,
+ LGW_SX127X_RXBW_10K4_HZ,
+ LGW_SX127X_RXBW_12K5_HZ,
+ LGW_SX127X_RXBW_15K6_HZ,
+ LGW_SX127X_RXBW_20K8_HZ,
+ LGW_SX127X_RXBW_25K_HZ,
+ LGW_SX127X_RXBW_31K3_HZ,
+ LGW_SX127X_RXBW_41K7_HZ,
+ LGW_SX127X_RXBW_50K_HZ,
+ LGW_SX127X_RXBW_62K5_HZ,
+ LGW_SX127X_RXBW_83K3_HZ,
+ LGW_SX127X_RXBW_100K_HZ,
+ LGW_SX127X_RXBW_125K_HZ,
+ LGW_SX127X_RXBW_166K7_HZ,
+ LGW_SX127X_RXBW_200K_HZ,
+ LGW_SX127X_RXBW_250K_HZ
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+int lgw_setup_sx125x(uint8_t rf_chain, uint8_t rf_clkout, bool rf_enable, uint8_t rf_radio_type, uint32_t freq_hz);
+
+int lgw_setup_sx127x(uint32_t frequency, uint8_t modulation, enum lgw_sx127x_rxbw_e rxbw_khz, int8_t rssi_offset);
+
+int lgw_sx127x_reg_w(uint8_t address, uint8_t reg_value);
+
+int lgw_sx127x_reg_r(uint8_t address, uint8_t *reg_value);
+
+
+#endif
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_reg.h b/libloragw/inc/loragw_reg.h
new file mode 100644
index 0000000..2a944a7
--- /dev/null
+++ b/libloragw/inc/loragw_reg.h
@@ -0,0 +1,461 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ Functions used to handle a single LoRa concentrator.
+ Registers are addressed by name.
+ Multi-bytes registers are handled automatically.
+ Read-modify-write is handled automatically.
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Sylvain Miermont
+*/
+
+
+#ifndef _LORAGW_REG_H
+#define _LORAGW_REG_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#include <stdint.h> /* C99 types */
+#include <stdbool.h> /* bool type */
+
+#include "config.h" /* library configuration options (dynamically generated) */
+
+/* -------------------------------------------------------------------------- */
+/* --- INTERNAL SHARED TYPES ------------------------------------------------ */
+
+struct lgw_reg_s {
+ int8_t page; /*!< page containing the register (-1 for all pages) */
+ uint8_t addr; /*!< base address of the register (7 bit) */
+ uint8_t offs; /*!< position of the register LSB (between 0 to 7) */
+ bool sign; /*!< 1 indicates the register is signed (2 complem.) */
+ uint8_t leng; /*!< number of bits in the register */
+ bool rdon; /*!< 1 indicates a read-only register */
+ int32_t dflt; /*!< register default value */
+};
+
+/* -------------------------------------------------------------------------- */
+/* --- INTERNAL SHARED FUNCTIONS -------------------------------------------- */
+
+int reg_w_align32(void *spi_target, uint8_t spi_mux_mode, uint8_t spi_mux_target, struct lgw_reg_s r, int32_t reg_value);
+int reg_r_align32(void *spi_target, uint8_t spi_mux_mode, uint8_t spi_mux_target, struct lgw_reg_s r, int32_t *reg_value);
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+#define LGW_REG_SUCCESS 0
+#define LGW_REG_ERROR -1
+
+/*
+auto generated register mapping for C code : 11-Jul-2013 13:20:40
+this file contains autogenerated C struct used to access the LORA registers
+this file is autogenerated from registers description
+293 registers are defined
+*/
+
+#define LGW_PAGE_REG 0
+#define LGW_SOFT_RESET 1
+#define LGW_VERSION 2
+#define LGW_RX_DATA_BUF_ADDR 3
+#define LGW_RX_DATA_BUF_DATA 4
+#define LGW_TX_DATA_BUF_ADDR 5
+#define LGW_TX_DATA_BUF_DATA 6
+#define LGW_CAPTURE_RAM_ADDR 7
+#define LGW_CAPTURE_RAM_DATA 8
+#define LGW_MCU_PROM_ADDR 9
+#define LGW_MCU_PROM_DATA 10
+#define LGW_RX_PACKET_DATA_FIFO_NUM_STORED 11
+#define LGW_RX_PACKET_DATA_FIFO_ADDR_POINTER 12
+#define LGW_RX_PACKET_DATA_FIFO_STATUS 13
+#define LGW_RX_PACKET_DATA_FIFO_PAYLOAD_SIZE 14
+#define LGW_MBWSSF_MODEM_ENABLE 15
+#define LGW_CONCENTRATOR_MODEM_ENABLE 16
+#define LGW_FSK_MODEM_ENABLE 17
+#define LGW_GLOBAL_EN 18
+#define LGW_CLK32M_EN 19
+#define LGW_CLKHS_EN 20
+#define LGW_START_BIST0 21
+#define LGW_START_BIST1 22
+#define LGW_CLEAR_BIST0 23
+#define LGW_CLEAR_BIST1 24
+#define LGW_BIST0_FINISHED 25
+#define LGW_BIST1_FINISHED 26
+#define LGW_MCU_AGC_PROG_RAM_BIST_STATUS 27
+#define LGW_MCU_ARB_PROG_RAM_BIST_STATUS 28
+#define LGW_CAPTURE_RAM_BIST_STATUS 29
+#define LGW_CHAN_FIR_RAM0_BIST_STATUS 30
+#define LGW_CHAN_FIR_RAM1_BIST_STATUS 31
+#define LGW_CORR0_RAM_BIST_STATUS 32
+#define LGW_CORR1_RAM_BIST_STATUS 33
+#define LGW_CORR2_RAM_BIST_STATUS 34
+#define LGW_CORR3_RAM_BIST_STATUS 35
+#define LGW_CORR4_RAM_BIST_STATUS 36
+#define LGW_CORR5_RAM_BIST_STATUS 37
+#define LGW_CORR6_RAM_BIST_STATUS 38
+#define LGW_CORR7_RAM_BIST_STATUS 39
+#define LGW_MODEM0_RAM0_BIST_STATUS 40
+#define LGW_MODEM1_RAM0_BIST_STATUS 41
+#define LGW_MODEM2_RAM0_BIST_STATUS 42
+#define LGW_MODEM3_RAM0_BIST_STATUS 43
+#define LGW_MODEM4_RAM0_BIST_STATUS 44
+#define LGW_MODEM5_RAM0_BIST_STATUS 45
+#define LGW_MODEM6_RAM0_BIST_STATUS 46
+#define LGW_MODEM7_RAM0_BIST_STATUS 47
+#define LGW_MODEM0_RAM1_BIST_STATUS 48
+#define LGW_MODEM1_RAM1_BIST_STATUS 49
+#define LGW_MODEM2_RAM1_BIST_STATUS 50
+#define LGW_MODEM3_RAM1_BIST_STATUS 51
+#define LGW_MODEM4_RAM1_BIST_STATUS 52
+#define LGW_MODEM5_RAM1_BIST_STATUS 53
+#define LGW_MODEM6_RAM1_BIST_STATUS 54
+#define LGW_MODEM7_RAM1_BIST_STATUS 55
+#define LGW_MODEM0_RAM2_BIST_STATUS 56
+#define LGW_MODEM1_RAM2_BIST_STATUS 57
+#define LGW_MODEM2_RAM2_BIST_STATUS 58
+#define LGW_MODEM3_RAM2_BIST_STATUS 59
+#define LGW_MODEM4_RAM2_BIST_STATUS 60
+#define LGW_MODEM5_RAM2_BIST_STATUS 61
+#define LGW_MODEM6_RAM2_BIST_STATUS 62
+#define LGW_MODEM7_RAM2_BIST_STATUS 63
+#define LGW_MODEM_MBWSSF_RAM0_BIST_STATUS 64
+#define LGW_MODEM_MBWSSF_RAM1_BIST_STATUS 65
+#define LGW_MODEM_MBWSSF_RAM2_BIST_STATUS 66
+#define LGW_MCU_AGC_DATA_RAM_BIST0_STATUS 67
+#define LGW_MCU_AGC_DATA_RAM_BIST1_STATUS 68
+#define LGW_MCU_ARB_DATA_RAM_BIST0_STATUS 69
+#define LGW_MCU_ARB_DATA_RAM_BIST1_STATUS 70
+#define LGW_TX_TOP_RAM_BIST0_STATUS 71
+#define LGW_TX_TOP_RAM_BIST1_STATUS 72
+#define LGW_DATA_MNGT_RAM_BIST0_STATUS 73
+#define LGW_DATA_MNGT_RAM_BIST1_STATUS 74
+#define LGW_GPIO_SELECT_INPUT 75
+#define LGW_GPIO_SELECT_OUTPUT 76
+#define LGW_GPIO_MODE 77
+#define LGW_GPIO_PIN_REG_IN 78
+#define LGW_GPIO_PIN_REG_OUT 79
+#define LGW_MCU_AGC_STATUS 80
+#define LGW_MCU_ARB_STATUS 81
+#define LGW_CHIP_ID 82
+#define LGW_EMERGENCY_FORCE_HOST_CTRL 83
+#define LGW_RX_INVERT_IQ 84
+#define LGW_MODEM_INVERT_IQ 85
+#define LGW_MBWSSF_MODEM_INVERT_IQ 86
+#define LGW_RX_EDGE_SELECT 87
+#define LGW_MISC_RADIO_EN 88
+#define LGW_FSK_MODEM_INVERT_IQ 89
+#define LGW_FILTER_GAIN 90
+#define LGW_RADIO_SELECT 91
+#define LGW_IF_FREQ_0 92
+#define LGW_IF_FREQ_1 93
+#define LGW_IF_FREQ_2 94
+#define LGW_IF_FREQ_3 95
+#define LGW_IF_FREQ_4 96
+#define LGW_IF_FREQ_5 97
+#define LGW_IF_FREQ_6 98
+#define LGW_IF_FREQ_7 99
+#define LGW_IF_FREQ_8 100
+#define LGW_IF_FREQ_9 101
+#define LGW_CHANN_OVERRIDE_AGC_GAIN 102
+#define LGW_CHANN_AGC_GAIN 103
+#define LGW_CORR0_DETECT_EN 104
+#define LGW_CORR1_DETECT_EN 105
+#define LGW_CORR2_DETECT_EN 106
+#define LGW_CORR3_DETECT_EN 107
+#define LGW_CORR4_DETECT_EN 108
+#define LGW_CORR5_DETECT_EN 109
+#define LGW_CORR6_DETECT_EN 110
+#define LGW_CORR7_DETECT_EN 111
+#define LGW_CORR_SAME_PEAKS_OPTION_SF6 112
+#define LGW_CORR_SAME_PEAKS_OPTION_SF7 113
+#define LGW_CORR_SAME_PEAKS_OPTION_SF8 114
+#define LGW_CORR_SAME_PEAKS_OPTION_SF9 115
+#define LGW_CORR_SAME_PEAKS_OPTION_SF10 116
+#define LGW_CORR_SAME_PEAKS_OPTION_SF11 117
+#define LGW_CORR_SAME_PEAKS_OPTION_SF12 118
+#define LGW_CORR_SIG_NOISE_RATIO_SF6 119
+#define LGW_CORR_SIG_NOISE_RATIO_SF7 120
+#define LGW_CORR_SIG_NOISE_RATIO_SF8 121
+#define LGW_CORR_SIG_NOISE_RATIO_SF9 122
+#define LGW_CORR_SIG_NOISE_RATIO_SF10 123
+#define LGW_CORR_SIG_NOISE_RATIO_SF11 124
+#define LGW_CORR_SIG_NOISE_RATIO_SF12 125
+#define LGW_CORR_NUM_SAME_PEAK 126
+#define LGW_CORR_MAC_GAIN 127
+#define LGW_ADJUST_MODEM_START_OFFSET_RDX4 128
+#define LGW_ADJUST_MODEM_START_OFFSET_SF12_RDX4 129
+#define LGW_DBG_CORR_SELECT_SF 130
+#define LGW_DBG_CORR_SELECT_CHANNEL 131
+#define LGW_DBG_DETECT_CPT 132
+#define LGW_DBG_SYMB_CPT 133
+#define LGW_CHIRP_INVERT_RX 134
+#define LGW_DC_NOTCH_EN 135
+#define LGW_IMPLICIT_CRC_EN 136
+#define LGW_IMPLICIT_CODING_RATE 137
+#define LGW_IMPLICIT_PAYLOAD_LENGHT 138
+#define LGW_FREQ_TO_TIME_INVERT 139
+#define LGW_FREQ_TO_TIME_DRIFT 140
+#define LGW_PAYLOAD_FINE_TIMING_GAIN 141
+#define LGW_PREAMBLE_FINE_TIMING_GAIN 142
+#define LGW_TRACKING_INTEGRAL 143
+#define LGW_FRAME_SYNCH_PEAK1_POS 144
+#define LGW_FRAME_SYNCH_PEAK2_POS 145
+#define LGW_PREAMBLE_SYMB1_NB 146
+#define LGW_FRAME_SYNCH_GAIN 147
+#define LGW_SYNCH_DETECT_TH 148
+#define LGW_LLR_SCALE 149
+#define LGW_SNR_AVG_CST 150
+#define LGW_PPM_OFFSET 151
+#define LGW_MAX_PAYLOAD_LEN 152
+#define LGW_ONLY_CRC_EN 153
+#define LGW_ZERO_PAD 154
+#define LGW_DEC_GAIN_OFFSET 155
+#define LGW_CHAN_GAIN_OFFSET 156
+#define LGW_FORCE_HOST_RADIO_CTRL 157
+#define LGW_FORCE_HOST_FE_CTRL 158
+#define LGW_FORCE_DEC_FILTER_GAIN 159
+#define LGW_MCU_RST_0 160
+#define LGW_MCU_RST_1 161
+#define LGW_MCU_SELECT_MUX_0 162
+#define LGW_MCU_SELECT_MUX_1 163
+#define LGW_MCU_CORRUPTION_DETECTED_0 164
+#define LGW_MCU_CORRUPTION_DETECTED_1 165
+#define LGW_MCU_SELECT_EDGE_0 166
+#define LGW_MCU_SELECT_EDGE_1 167
+#define LGW_CHANN_SELECT_RSSI 168
+#define LGW_RSSI_BB_DEFAULT_VALUE 169
+#define LGW_RSSI_DEC_DEFAULT_VALUE 170
+#define LGW_RSSI_CHANN_DEFAULT_VALUE 171
+#define LGW_RSSI_BB_FILTER_ALPHA 172
+#define LGW_RSSI_DEC_FILTER_ALPHA 173
+#define LGW_RSSI_CHANN_FILTER_ALPHA 174
+#define LGW_IQ_MISMATCH_A_AMP_COEFF 175
+#define LGW_IQ_MISMATCH_A_PHI_COEFF 176
+#define LGW_IQ_MISMATCH_B_AMP_COEFF 177
+#define LGW_IQ_MISMATCH_B_SEL_I 178
+#define LGW_IQ_MISMATCH_B_PHI_COEFF 179
+#define LGW_TX_TRIG_IMMEDIATE 180
+#define LGW_TX_TRIG_DELAYED 181
+#define LGW_TX_TRIG_GPS 182
+#define LGW_TX_START_DELAY 183
+#define LGW_TX_FRAME_SYNCH_PEAK1_POS 184
+#define LGW_TX_FRAME_SYNCH_PEAK2_POS 185
+#define LGW_TX_RAMP_DURATION 186
+#define LGW_TX_OFFSET_I 187
+#define LGW_TX_OFFSET_Q 188
+#define LGW_TX_MODE 189
+#define LGW_TX_ZERO_PAD 190
+#define LGW_TX_EDGE_SELECT 191
+#define LGW_TX_EDGE_SELECT_TOP 192
+#define LGW_TX_GAIN 193
+#define LGW_TX_CHIRP_LOW_PASS 194
+#define LGW_TX_FCC_WIDEBAND 195
+#define LGW_TX_SWAP_IQ 196
+#define LGW_MBWSSF_IMPLICIT_HEADER 197
+#define LGW_MBWSSF_IMPLICIT_CRC_EN 198
+#define LGW_MBWSSF_IMPLICIT_CODING_RATE 199
+#define LGW_MBWSSF_IMPLICIT_PAYLOAD_LENGHT 200
+#define LGW_MBWSSF_AGC_FREEZE_ON_DETECT 201
+#define LGW_MBWSSF_FRAME_SYNCH_PEAK1_POS 202
+#define LGW_MBWSSF_FRAME_SYNCH_PEAK2_POS 203
+#define LGW_MBWSSF_PREAMBLE_SYMB1_NB 204
+#define LGW_MBWSSF_FRAME_SYNCH_GAIN 205
+#define LGW_MBWSSF_SYNCH_DETECT_TH 206
+#define LGW_MBWSSF_DETECT_MIN_SINGLE_PEAK 207
+#define LGW_MBWSSF_DETECT_TRIG_SAME_PEAK_NB 208
+#define LGW_MBWSSF_FREQ_TO_TIME_INVERT 209
+#define LGW_MBWSSF_FREQ_TO_TIME_DRIFT 210
+#define LGW_MBWSSF_PPM_CORRECTION 211
+#define LGW_MBWSSF_PAYLOAD_FINE_TIMING_GAIN 212
+#define LGW_MBWSSF_PREAMBLE_FINE_TIMING_GAIN 213
+#define LGW_MBWSSF_TRACKING_INTEGRAL 214
+#define LGW_MBWSSF_ZERO_PAD 215
+#define LGW_MBWSSF_MODEM_BW 216
+#define LGW_MBWSSF_RADIO_SELECT 217
+#define LGW_MBWSSF_RX_CHIRP_INVERT 218
+#define LGW_MBWSSF_LLR_SCALE 219
+#define LGW_MBWSSF_SNR_AVG_CST 220
+#define LGW_MBWSSF_PPM_OFFSET 221
+#define LGW_MBWSSF_RATE_SF 222
+#define LGW_MBWSSF_ONLY_CRC_EN 223
+#define LGW_MBWSSF_MAX_PAYLOAD_LEN 224
+#define LGW_TX_STATUS 225
+#define LGW_FSK_CH_BW_EXPO 226
+#define LGW_FSK_RSSI_LENGTH 227
+#define LGW_FSK_RX_INVERT 228
+#define LGW_FSK_PKT_MODE 229
+#define LGW_FSK_PSIZE 230
+#define LGW_FSK_CRC_EN 231
+#define LGW_FSK_DCFREE_ENC 232
+#define LGW_FSK_CRC_IBM 233
+#define LGW_FSK_ERROR_OSR_TOL 234
+#define LGW_FSK_RADIO_SELECT 235
+#define LGW_FSK_BR_RATIO 236
+#define LGW_FSK_REF_PATTERN_LSB 237
+#define LGW_FSK_REF_PATTERN_MSB 238
+#define LGW_FSK_PKT_LENGTH 239
+#define LGW_FSK_TX_GAUSSIAN_EN 240
+#define LGW_FSK_TX_GAUSSIAN_SELECT_BT 241
+#define LGW_FSK_TX_PATTERN_EN 242
+#define LGW_FSK_TX_PREAMBLE_SEQ 243
+#define LGW_FSK_TX_PSIZE 244
+#define LGW_FSK_NODE_ADRS 245
+#define LGW_FSK_BROADCAST 246
+#define LGW_FSK_AUTO_AFC_ON 247
+#define LGW_FSK_PATTERN_TIMEOUT_CFG 248
+#define LGW_SPI_RADIO_A__DATA 249
+#define LGW_SPI_RADIO_A__DATA_READBACK 250
+#define LGW_SPI_RADIO_A__ADDR 251
+#define LGW_SPI_RADIO_A__CS 252
+#define LGW_SPI_RADIO_B__DATA 253
+#define LGW_SPI_RADIO_B__DATA_READBACK 254
+#define LGW_SPI_RADIO_B__ADDR 255
+#define LGW_SPI_RADIO_B__CS 256
+#define LGW_RADIO_A_EN 257
+#define LGW_RADIO_B_EN 258
+#define LGW_RADIO_RST 259
+#define LGW_LNA_A_EN 260
+#define LGW_PA_A_EN 261
+#define LGW_LNA_B_EN 262
+#define LGW_PA_B_EN 263
+#define LGW_PA_GAIN 264
+#define LGW_LNA_A_CTRL_LUT 265
+#define LGW_PA_A_CTRL_LUT 266
+#define LGW_LNA_B_CTRL_LUT 267
+#define LGW_PA_B_CTRL_LUT 268
+#define LGW_CAPTURE_SOURCE 269
+#define LGW_CAPTURE_START 270
+#define LGW_CAPTURE_FORCE_TRIGGER 271
+#define LGW_CAPTURE_WRAP 272
+#define LGW_CAPTURE_PERIOD 273
+#define LGW_MODEM_STATUS 274
+#define LGW_VALID_HEADER_COUNTER_0 275
+#define LGW_VALID_PACKET_COUNTER_0 276
+#define LGW_VALID_HEADER_COUNTER_MBWSSF 277
+#define LGW_VALID_HEADER_COUNTER_FSK 278
+#define LGW_VALID_PACKET_COUNTER_MBWSSF 279
+#define LGW_VALID_PACKET_COUNTER_FSK 280
+#define LGW_CHANN_RSSI 281
+#define LGW_BB_RSSI 282
+#define LGW_DEC_RSSI 283
+#define LGW_DBG_MCU_DATA 284
+#define LGW_DBG_ARB_MCU_RAM_DATA 285
+#define LGW_DBG_AGC_MCU_RAM_DATA 286
+#define LGW_NEXT_PACKET_CNT 287
+#define LGW_ADDR_CAPTURE_COUNT 288
+#define LGW_TIMESTAMP 289
+#define LGW_DBG_CHANN0_GAIN 290
+#define LGW_DBG_CHANN1_GAIN 291
+#define LGW_DBG_CHANN2_GAIN 292
+#define LGW_DBG_CHANN3_GAIN 293
+#define LGW_DBG_CHANN4_GAIN 294
+#define LGW_DBG_CHANN5_GAIN 295
+#define LGW_DBG_CHANN6_GAIN 296
+#define LGW_DBG_CHANN7_GAIN 297
+#define LGW_DBG_DEC_FILT_GAIN 298
+#define LGW_SPI_DATA_FIFO_PTR 299
+#define LGW_PACKET_DATA_FIFO_PTR 300
+#define LGW_DBG_ARB_MCU_RAM_ADDR 301
+#define LGW_DBG_AGC_MCU_RAM_ADDR 302
+#define LGW_SPI_MASTER_CHIP_SELECT_POLARITY 303
+#define LGW_SPI_MASTER_CPOL 304
+#define LGW_SPI_MASTER_CPHA 305
+#define LGW_SIG_GEN_ANALYSER_MUX_SEL 306
+#define LGW_SIG_GEN_EN 307
+#define LGW_SIG_ANALYSER_EN 308
+#define LGW_SIG_ANALYSER_AVG_LEN 309
+#define LGW_SIG_ANALYSER_PRECISION 310
+#define LGW_SIG_ANALYSER_VALID_OUT 311
+#define LGW_SIG_GEN_FREQ 312
+#define LGW_SIG_ANALYSER_FREQ 313
+#define LGW_SIG_ANALYSER_I_OUT 314
+#define LGW_SIG_ANALYSER_Q_OUT 315
+#define LGW_GPS_EN 316
+#define LGW_GPS_POL 317
+#define LGW_SW_TEST_REG1 318
+#define LGW_SW_TEST_REG2 319
+#define LGW_SW_TEST_REG3 320
+#define LGW_DATA_MNGT_STATUS 321
+#define LGW_DATA_MNGT_CPT_FRAME_ALLOCATED 322
+#define LGW_DATA_MNGT_CPT_FRAME_FINISHED 323
+#define LGW_DATA_MNGT_CPT_FRAME_READEN 324
+#define LGW_TX_TRIG_ALL 325
+
+#define LGW_TOTALREGS 326
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+/**
+@brief Connect LoRa concentrator by opening SPI link
+@param spi_only indicates if we only want to create the SPI connexion to the
+concentrator, or if we also want to reset it and configure the FPGA (if present)
+@param tx_notch_filter TX notch filter frequency to be set in the FPGA (only
+used with SX1301AP2 reference design).
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_connect(bool spi_only, uint32_t tx_notch_freq);
+
+/**
+@brief Disconnect LoRa concentrator by closing SPI link
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_disconnect(void);
+
+/**
+@brief Use the soft-reset register to put the concentrator in initial state
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_soft_reset(void);
+
+/**
+@brief Check if the registers are ok, send diagnostics to stdio/stderr/file
+@param f file descriptor to to which the check result will be written
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_reg_check(FILE *f);
+
+/**
+@brief LoRa concentrator register write
+@param register_id register number in the data structure describing registers
+@param reg_value signed value to write to the register (for u32, use cast)
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_reg_w(uint16_t register_id, int32_t reg_value);
+
+/**
+@brief LoRa concentrator register read
+@param register_id register number in the data structure describing registers
+@param reg_value pointer to a variable where to write register read value
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_reg_r(uint16_t register_id, int32_t *reg_value);
+
+/**
+@brief LoRa concentrator register burst write
+@param register_id register number in the data structure describing registers
+@param data pointer to byte array that will be sent to the LoRa concentrator
+@param size size of the transfer, in byte(s)
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_reg_wb(uint16_t register_id, uint8_t *data, uint16_t size);
+
+/**
+@brief LoRa concentrator register burst read
+@param register_id register number in the data structure describing registers
+@param data pointer to byte array that will be written from the LoRa concentrator
+@param size size of the transfer, in byte(s)
+@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR)
+*/
+int lgw_reg_rb(uint16_t register_id, uint8_t *data, uint16_t size);
+
+
+#endif
+
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_spi.h b/libloragw/inc/loragw_spi.h
new file mode 100644
index 0000000..fef1f48
--- /dev/null
+++ b/libloragw/inc/loragw_spi.h
@@ -0,0 +1,105 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech-Cycleo
+
+Description:
+ Host specific functions to address the LoRa concentrator registers through a
+ SPI interface.
+ Single-byte read/write and burst read/write.
+ Does not handle pagination.
+ Could be used with multiple SPI ports in parallel (explicit file descriptor)
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+Maintainer: Sylvain Miermont
+*/
+
+
+#ifndef _LORAGW_SPI_H
+#define _LORAGW_SPI_H
+
+/* -------------------------------------------------------------------------- */
+/* --- DEPENDANCIES --------------------------------------------------------- */
+
+#include <stdint.h> /* C99 types*/
+
+#include "config.h" /* library configuration options (dynamically generated) */
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
+
+#define LGW_SPI_SUCCESS 0
+#define LGW_SPI_ERROR -1
+#define LGW_BURST_CHUNK 1024
+
+#define LGW_SPI_MUX_MODE0 0x0 /* No FPGA */
+#define LGW_SPI_MUX_MODE1 0x1 /* FPGA, with spi mux header */
+
+#define LGW_SPI_MUX_TARGET_SX1301 0x0
+#define LGW_SPI_MUX_TARGET_FPGA 0x1
+#define LGW_SPI_MUX_TARGET_EEPROM 0x2
+#define LGW_SPI_MUX_TARGET_SX127X 0x3
+
+/* -------------------------------------------------------------------------- */
+/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
+
+/**
+@brief LoRa concentrator SPI setup (configure I/O and peripherals)
+@param spi_target_ptr pointer on a generic pointer to SPI target (implementation dependant)
+@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
+*/
+
+int lgw_spi_open(void **spi_target_ptr);
+
+/**
+@brief LoRa concentrator SPI close
+@param spi_target generic pointer to SPI target (implementation dependant)
+@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
+*/
+
+int lgw_spi_close(void *spi_target);
+
+/**
+@brief LoRa concentrator SPI single-byte write
+@param spi_target generic pointer to SPI target (implementation dependant)
+@param address 7-bit register address
+@param data data byte to write
+@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
+*/
+int lgw_spi_w(void *spi_target, uint8_t spi_mux_mode, uint8_t spi_mux_target, uint8_t address, uint8_t data);
+
+/**
+@brief LoRa concentrator SPI single-byte read
+@param spi_target generic pointer to SPI target (implementation dependant)
+@param address 7-bit register address
+@param data data byte to write
+@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
+*/
+int lgw_spi_r(void *spi_target, uint8_t spi_mux_mode, uint8_t spi_mux_target, uint8_t address, uint8_t *data);
+
+/**
+@brief LoRa concentrator SPI burst (multiple-byte) write
+@param spi_target generic pointer to SPI target (implementation dependant)
+@param address 7-bit register address
+@param data pointer to byte array that will be sent to the LoRa concentrator
+@param size size of the transfer, in byte(s)
+@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
+*/
+int lgw_spi_wb(void *spi_target, uint8_t spi_mux_mode, uint8_t spi_mux_target, uint8_t address, uint8_t *data, uint16_t size);
+
+/**
+@brief LoRa concentrator SPI burst (multiple-byte) read
+@param spi_target generic pointer to SPI target (implementation dependant)
+@param address 7-bit register address
+@param data pointer to byte array that will be written from the LoRa concentrator
+@param size size of the transfer, in byte(s)
+@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
+*/
+int lgw_spi_rb(void *spi_target, uint8_t spi_mux_mode, uint8_t spi_mux_target, uint8_t address, uint8_t *data, uint16_t size);
+
+#endif
+
+/* --- EOF ------------------------------------------------------------------ */
diff --git a/libloragw/inc/loragw_sx125x.h b/libloragw/inc/loragw_sx125x.h
new file mode 100644
index 0000000..120ee68
--- /dev/null
+++ b/libloragw/inc/loragw_sx125x.h
@@ -0,0 +1,49 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: SX125x radio registers and constant definitions
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Michael Coracin
+*/
+#ifndef __SX125X_REGS_H__
+#define __SX125X_REGS_H__
+
+/*
+SX1257 frequency setting :
+F_register(24bit) = F_rf (Hz) / F_step(Hz)
+ = F_rf (Hz) * 2^19 / F_xtal(Hz)
+ = F_rf (Hz) * 2^19 / 32e6
+ = F_rf (Hz) * 256/15625
+
+SX1255 frequency setting :
+F_register(24bit) = F_rf (Hz) / F_step(Hz)
+ = F_rf (Hz) * 2^20 / F_xtal(Hz)
+ = F_rf (Hz) * 2^20 / 32e6
+ = F_rf (Hz) * 512/15625
+*/
+
+#define SX125x_TX_DAC_CLK_SEL 1 /* 0:int, 1:ext */
+#define SX125x_TX_DAC_GAIN 2 /* 3:0, 2:-3, 1:-6, 0:-9 dBFS (default 2) */
+#define SX125x_TX_MIX_GAIN 14 /* -38 + 2*TxMixGain dB (default 14) */
+#define SX125x_TX_PLL_BW 1 /* 0:75, 1:150, 2:225, 3:300 kHz (default 3) */
+#define SX125x_TX_ANA_BW 0 /* 17.5 / 2*(41-TxAnaBw) MHz (default 0) */
+#define SX125x_TX_DAC_BW 5 /* 24 + 8*TxDacBw Nb FIR taps (default 2) */
+#define SX125x_RX_LNA_GAIN 1 /* 1 to 6, 1 highest gain */
+#define SX125x_RX_BB_GAIN 12 /* 0 to 15 , 15 highest gain */
+#define SX125x_LNA_ZIN 1 /* 0:50, 1:200 Ohms (default 1) */
+#define SX125x_RX_ADC_BW 7 /* 0 to 7, 2:100<BW<200, 5:200<BW<400,7:400<BW kHz SSB (default 7) */
+#define SX125x_RX_ADC_TRIM 6 /* 0 to 7, 6 for 32MHz ref, 5 for 36MHz ref */
+#define SX125x_RX_BB_BW 0 /* 0:750, 1:500, 2:375; 3:250 kHz SSB (default 1, max 3) */
+#define SX125x_RX_PLL_BW 0 /* 0:75, 1:150, 2:225, 3:300 kHz (default 3, max 3) */
+#define SX125x_ADC_TEMP 0 /* ADC temperature measurement mode (default 0) */
+#define SX125x_XOSC_GM_STARTUP 13 /* (default 13) */
+#define SX125x_XOSC_DISABLE 2 /* Disable of Xtal Oscillator blocks bit0:regulator, bit1:core(gm), bit2:amplifier */
+
+#endif // __SX125X_REGS_H__
diff --git a/libloragw/inc/loragw_sx1272_fsk.h b/libloragw/inc/loragw_sx1272_fsk.h
new file mode 100644
index 0000000..c202bc4
--- /dev/null
+++ b/libloragw/inc/loragw_sx1272_fsk.h
@@ -0,0 +1,113 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: SX1272 FSK modem registers
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Michael Coracin
+*/
+#ifndef _LORAGW_SX1272_REGS_FSK_H
+#define _LORAGW_SX1272_REGS_FSK_H
+
+/*!
+ * ============================================================================
+ * SX1272 Internal registers Address
+ * ============================================================================
+ */
+#define SX1272_REG_FIFO 0x00
+// Common settings
+#define SX1272_REG_OPMODE 0x01
+#define SX1272_REG_BITRATEMSB 0x02
+#define SX1272_REG_BITRATELSB 0x03
+#define SX1272_REG_FDEVMSB 0x04
+#define SX1272_REG_FDEVLSB 0x05
+#define SX1272_REG_FRFMSB 0x06
+#define SX1272_REG_FRFMID 0x07
+#define SX1272_REG_FRFLSB 0x08
+// Tx settings
+#define SX1272_REG_PACONFIG 0x09
+#define SX1272_REG_PARAMP 0x0A
+#define SX1272_REG_OCP 0x0B
+// Rx settings
+#define SX1272_REG_LNA 0x0C
+#define SX1272_REG_RXCONFIG 0x0D
+#define SX1272_REG_RSSICONFIG 0x0E
+#define SX1272_REG_RSSICOLLISION 0x0F
+#define SX1272_REG_RSSITHRESH 0x10
+#define SX1272_REG_RSSIVALUE 0x11
+#define SX1272_REG_RXBW 0x12
+#define SX1272_REG_AFCBW 0x13
+#define SX1272_REG_OOKPEAK 0x14
+#define SX1272_REG_OOKFIX 0x15
+#define SX1272_REG_OOKAVG 0x16
+#define SX1272_REG_RES17 0x17
+#define SX1272_REG_RES18 0x18
+#define SX1272_REG_RES19 0x19
+#define SX1272_REG_AFCFEI 0x1A
+#define SX1272_REG_AFCMSB 0x1B
+#define SX1272_REG_AFCLSB 0x1C
+#define SX1272_REG_FEIMSB 0x1D
+#define SX1272_REG_FEILSB 0x1E
+#define SX1272_REG_PREAMBLEDETECT 0x1F
+#define SX1272_REG_RXTIMEOUT1 0x20
+#define SX1272_REG_RXTIMEOUT2 0x21
+#define SX1272_REG_RXTIMEOUT3 0x22
+#define SX1272_REG_RXDELAY 0x23
+// Oscillator settings
+#define SX1272_REG_OSC 0x24
+// Packet handler settings
+#define SX1272_REG_PREAMBLEMSB 0x25
+#define SX1272_REG_PREAMBLELSB 0x26
+#define SX1272_REG_SYNCCONFIG 0x27
+#define SX1272_REG_SYNCVALUE1 0x28
+#define SX1272_REG_SYNCVALUE2 0x29
+#define SX1272_REG_SYNCVALUE3 0x2A
+#define SX1272_REG_SYNCVALUE4 0x2B
+#define SX1272_REG_SYNCVALUE5 0x2C
+#define SX1272_REG_SYNCVALUE6 0x2D
+#define SX1272_REG_SYNCVALUE7 0x2E
+#define SX1272_REG_SYNCVALUE8 0x2F
+#define SX1272_REG_PACKETCONFIG1 0x30
+#define SX1272_REG_PACKETCONFIG2 0x31
+#define SX1272_REG_PAYLOADLENGTH 0x32
+#define SX1272_REG_NODEADRS 0x33
+#define SX1272_REG_BROADCASTADRS 0x34
+#define SX1272_REG_FIFOTHRESH 0x35
+// SM settings
+#define SX1272_REG_SEQCONFIG1 0x36
+#define SX1272_REG_SEQCONFIG2 0x37
+#define SX1272_REG_TIMERRESOL 0x38
+#define SX1272_REG_TIMER1COEF 0x39
+#define SX1272_REG_TIMER2COEF 0x3A
+// Service settings
+#define SX1272_REG_IMAGECAL 0x3B
+#define SX1272_REG_TEMP 0x3C
+#define SX1272_REG_LOWBAT 0x3D
+// Status
+#define SX1272_REG_IRQFLAGS1 0x3E
+#define SX1272_REG_IRQFLAGS2 0x3F
+// I/O settings
+#define SX1272_REG_DIOMAPPING1 0x40
+#define SX1272_REG_DIOMAPPING2 0x41
+// Version
+#define SX1272_REG_VERSION 0x42
+// Additional settings
+#define SX1272_REG_AGCREF 0x43
+#define SX1272_REG_AGCTHRESH1 0x44
+#define SX1272_REG_AGCTHRESH2 0x45
+#define SX1272_REG_AGCTHRESH3 0x46
+#define SX1272_REG_PLLHOP 0x4B
+#define SX1272_REG_TCXO 0x58
+#define SX1272_REG_PADAC 0x5A
+#define SX1272_REG_PLL 0x5C
+#define SX1272_REG_PLLLOWPN 0x5E
+#define SX1272_REG_FORMERTEMP 0x6C
+#define SX1272_REG_BITRATEFRAC 0x70
+
+#endif // _LORAGW_SX1272_REGS_FSK_H
diff --git a/libloragw/inc/loragw_sx1272_lora.h b/libloragw/inc/loragw_sx1272_lora.h
new file mode 100644
index 0000000..7f7a7a5
--- /dev/null
+++ b/libloragw/inc/loragw_sx1272_lora.h
@@ -0,0 +1,89 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: SX1272 LoRa modem registers and bits definitions
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Michael Coracin
+*/
+#ifndef _LORAGW_SX1272_REGS_LORA_H
+#define _LORAGW_SX1272_REGS_LORA_H
+
+/*!
+ * ============================================================================
+ * SX1272 Internal registers Address
+ * ============================================================================
+ */
+#define SX1272_REG_LR_FIFO 0x00
+// Common settings
+#define SX1272_REG_LR_OPMODE 0x01
+#define SX1272_REG_LR_FRFMSB 0x06
+#define SX1272_REG_LR_FRFMID 0x07
+#define SX1272_REG_LR_FRFLSB 0x08
+// Tx settings
+#define SX1272_REG_LR_PACONFIG 0x09
+#define SX1272_REG_LR_PARAMP 0x0A
+#define SX1272_REG_LR_OCP 0x0B
+// Rx settings
+#define SX1272_REG_LR_LNA 0x0C
+// LoRa registers
+#define SX1272_REG_LR_FIFOADDRPTR 0x0D
+#define SX1272_REG_LR_FIFOTXBASEADDR 0x0E
+#define SX1272_REG_LR_FIFORXBASEADDR 0x0F
+#define SX1272_REG_LR_FIFORXCURRENTADDR 0x10
+#define SX1272_REG_LR_IRQFLAGSMASK 0x11
+#define SX1272_REG_LR_IRQFLAGS 0x12
+#define SX1272_REG_LR_RXNBBYTES 0x13
+#define SX1272_REG_LR_RXHEADERCNTVALUEMSB 0x14
+#define SX1272_REG_LR_RXHEADERCNTVALUELSB 0x15
+#define SX1272_REG_LR_RXPACKETCNTVALUEMSB 0x16
+#define SX1272_REG_LR_RXPACKETCNTVALUELSB 0x17
+#define SX1272_REG_LR_MODEMSTAT 0x18
+#define SX1272_REG_LR_PKTSNRVALUE 0x19
+#define SX1272_REG_LR_PKTRSSIVALUE 0x1A
+#define SX1272_REG_LR_RSSIVALUE 0x1B
+#define SX1272_REG_LR_HOPCHANNEL 0x1C
+#define SX1272_REG_LR_MODEMCONFIG1 0x1D
+#define SX1272_REG_LR_MODEMCONFIG2 0x1E
+#define SX1272_REG_LR_SYMBTIMEOUTLSB 0x1F
+#define SX1272_REG_LR_PREAMBLEMSB 0x20
+#define SX1272_REG_LR_PREAMBLELSB 0x21
+#define SX1272_REG_LR_PAYLOADLENGTH 0x22
+#define SX1272_REG_LR_PAYLOADMAXLENGTH 0x23
+#define SX1272_REG_LR_HOPPERIOD 0x24
+#define SX1272_REG_LR_FIFORXBYTEADDR 0x25
+#define SX1272_REG_LR_FEIMSB 0x28
+#define SX1272_REG_LR_FEIMID 0x29
+#define SX1272_REG_LR_FEILSB 0x2A
+#define SX1272_REG_LR_RSSIWIDEBAND 0x2C
+#define SX1272_REG_LR_DETECTOPTIMIZE 0x31
+#define SX1272_REG_LR_INVERTIQ 0x33
+#define SX1272_REG_LR_DETECTIONTHRESHOLD 0x37
+#define SX1272_REG_LR_SYNCWORD 0x39
+#define SX1272_REG_LR_INVERTIQ2 0x3B
+
+// end of documented register in datasheet
+// I/O settings
+#define SX1272_REG_LR_DIOMAPPING1 0x40
+#define SX1272_REG_LR_DIOMAPPING2 0x41
+// Version
+#define SX1272_REG_LR_VERSION 0x42
+// Additional settings
+#define SX1272_REG_LR_AGCREF 0x43
+#define SX1272_REG_LR_AGCTHRESH1 0x44
+#define SX1272_REG_LR_AGCTHRESH2 0x45
+#define SX1272_REG_LR_AGCTHRESH3 0x46
+#define SX1272_REG_LR_PLLHOP 0x4B
+#define SX1272_REG_LR_TCXO 0x58
+#define SX1272_REG_LR_PADAC 0x5A
+#define SX1272_REG_LR_PLL 0x5C
+#define SX1272_REG_LR_PLLLOWPN 0x5E
+#define SX1272_REG_LR_FORMERTEMP 0x6C
+
+#endif // _LORAGW_SX1272_REGS_LORA_H
diff --git a/libloragw/inc/loragw_sx1276_fsk.h b/libloragw/inc/loragw_sx1276_fsk.h
new file mode 100644
index 0000000..944958a
--- /dev/null
+++ b/libloragw/inc/loragw_sx1276_fsk.h
@@ -0,0 +1,112 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: SX1276 FSK modem registers
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Michael Coracin
+*/
+#ifndef _LORAGW_SX1276_REGS_FSK_H
+#define _LORAGW_SX1276_REGS_FSK_H
+
+/*!
+ * ============================================================================
+ * SX1276 Internal registers Address
+ * ============================================================================
+ */
+#define SX1276_REG_FIFO 0x00
+// Common settings
+#define SX1276_REG_OPMODE 0x01
+#define SX1276_REG_BITRATEMSB 0x02
+#define SX1276_REG_BITRATELSB 0x03
+#define SX1276_REG_FDEVMSB 0x04
+#define SX1276_REG_FDEVLSB 0x05
+#define SX1276_REG_FRFMSB 0x06
+#define SX1276_REG_FRFMID 0x07
+#define SX1276_REG_FRFLSB 0x08
+// Tx settings
+#define SX1276_REG_PACONFIG 0x09
+#define SX1276_REG_PARAMP 0x0A
+#define SX1276_REG_OCP 0x0B
+// Rx settings
+#define SX1276_REG_LNA 0x0C
+#define SX1276_REG_RXCONFIG 0x0D
+#define SX1276_REG_RSSICONFIG 0x0E
+#define SX1276_REG_RSSICOLLISION 0x0F
+#define SX1276_REG_RSSITHRESH 0x10
+#define SX1276_REG_RSSIVALUE 0x11
+#define SX1276_REG_RXBW 0x12
+#define SX1276_REG_AFCBW 0x13
+#define SX1276_REG_OOKPEAK 0x14
+#define SX1276_REG_OOKFIX 0x15
+#define SX1276_REG_OOKAVG 0x16
+#define SX1276_REG_RES17 0x17
+#define SX1276_REG_RES18 0x18
+#define SX1276_REG_RES19 0x19
+#define SX1276_REG_AFCFEI 0x1A
+#define SX1276_REG_AFCMSB 0x1B
+#define SX1276_REG_AFCLSB 0x1C
+#define SX1276_REG_FEIMSB 0x1D
+#define SX1276_REG_FEILSB 0x1E
+#define SX1276_REG_PREAMBLEDETECT 0x1F
+#define SX1276_REG_RXTIMEOUT1 0x20
+#define SX1276_REG_RXTIMEOUT2 0x21
+#define SX1276_REG_RXTIMEOUT3 0x22
+#define SX1276_REG_RXDELAY 0x23
+// Oscillator settings
+#define SX1276_REG_OSC 0x24
+// Packet handler settings
+#define SX1276_REG_PREAMBLEMSB 0x25
+#define SX1276_REG_PREAMBLELSB 0x26
+#define SX1276_REG_SYNCCONFIG 0x27
+#define SX1276_REG_SYNCVALUE1 0x28
+#define SX1276_REG_SYNCVALUE2 0x29
+#define SX1276_REG_SYNCVALUE3 0x2A
+#define SX1276_REG_SYNCVALUE4 0x2B
+#define SX1276_REG_SYNCVALUE5 0x2C
+#define SX1276_REG_SYNCVALUE6 0x2D
+#define SX1276_REG_SYNCVALUE7 0x2E
+#define SX1276_REG_SYNCVALUE8 0x2F
+#define SX1276_REG_PACKETCONFIG1 0x30
+#define SX1276_REG_PACKETCONFIG2 0x31
+#define SX1276_REG_PAYLOADLENGTH 0x32
+#define SX1276_REG_NODEADRS 0x33
+#define SX1276_REG_BROADCASTADRS 0x34
+#define SX1276_REG_FIFOTHRESH 0x35
+// SM settings
+#define SX1276_REG_SEQCONFIG1 0x36
+#define SX1276_REG_SEQCONFIG2 0x37
+#define SX1276_REG_TIMERRESOL 0x38
+#define SX1276_REG_TIMER1COEF 0x39
+#define SX1276_REG_TIMER2COEF 0x3A
+// Service settings
+#define SX1276_REG_IMAGECAL 0x3B
+#define SX1276_REG_TEMP 0x3C
+#define SX1276_REG_LOWBAT 0x3D
+// Status
+#define SX1276_REG_IRQFLAGS1 0x3E
+#define SX1276_REG_IRQFLAGS2 0x3F
+// I/O settings
+#define SX1276_REG_DIOMAPPING1 0x40
+#define SX1276_REG_DIOMAPPING2 0x41
+// Version
+#define SX1276_REG_VERSION 0x42
+// Additional settings
+#define SX1276_REG_PLLHOP 0x44
+#define SX1276_REG_TCXO 0x4B
+#define SX1276_REG_PADAC 0x4D
+#define SX1276_REG_FORMERTEMP 0x5B
+#define SX1276_REG_BITRATEFRAC 0x5D
+#define SX1276_REG_AGCREF 0x61
+#define SX1276_REG_AGCTHRESH1 0x62
+#define SX1276_REG_AGCTHRESH2 0x63
+#define SX1276_REG_AGCTHRESH3 0x64
+#define SX1276_REG_PLL 0x70
+
+#endif // __SX1276_REGS_FSK_H__
diff --git a/libloragw/inc/loragw_sx1276_lora.h b/libloragw/inc/loragw_sx1276_lora.h
new file mode 100644
index 0000000..d03e1ff
--- /dev/null
+++ b/libloragw/inc/loragw_sx1276_lora.h
@@ -0,0 +1,94 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: SX1276 LoRa modem registers
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Michael Coracin
+*/
+#ifndef _LORAGW_SX1276_REGS_LORA_H
+#define _LORAGW_SX1276_REGS_LORA_H
+
+/*!
+ * ============================================================================
+ * SX1276 Internal registers Address
+ * ============================================================================
+ */
+#define SX1276_REG_LR_FIFO 0x00
+// Common settings
+#define SX1276_REG_LR_OPMODE 0x01
+#define SX1276_REG_LR_FRFMSB 0x06
+#define SX1276_REG_LR_FRFMID 0x07
+#define SX1276_REG_LR_FRFLSB 0x08
+// Tx settings
+#define SX1276_REG_LR_PACONFIG 0x09
+#define SX1276_REG_LR_PARAMP 0x0A
+#define SX1276_REG_LR_OCP 0x0B
+// Rx settings
+#define SX1276_REG_LR_LNA 0x0C
+// LoRa registers
+#define SX1276_REG_LR_FIFOADDRPTR 0x0D
+#define SX1276_REG_LR_FIFOTXBASEADDR 0x0E
+#define SX1276_REG_LR_FIFORXBASEADDR 0x0F
+#define SX1276_REG_LR_FIFORXCURRENTADDR 0x10
+#define SX1276_REG_LR_IRQFLAGSMASK 0x11
+#define SX1276_REG_LR_IRQFLAGS 0x12
+#define SX1276_REG_LR_RXNBBYTES 0x13
+#define SX1276_REG_LR_RXHEADERCNTVALUEMSB 0x14
+#define SX1276_REG_LR_RXHEADERCNTVALUELSB 0x15
+#define SX1276_REG_LR_RXPACKETCNTVALUEMSB 0x16
+#define SX1276_REG_LR_RXPACKETCNTVALUELSB 0x17
+#define SX1276_REG_LR_MODEMSTAT 0x18
+#define SX1276_REG_LR_PKTSNRVALUE 0x19
+#define SX1276_REG_LR_PKTRSSIVALUE 0x1A
+#define SX1276_REG_LR_RSSIVALUE 0x1B
+#define SX1276_REG_LR_HOPCHANNEL 0x1C
+#define SX1276_REG_LR_MODEMCONFIG1 0x1D
+#define SX1276_REG_LR_MODEMCONFIG2 0x1E
+#define SX1276_REG_LR_SYMBTIMEOUTLSB 0x1F
+#define SX1276_REG_LR_PREAMBLEMSB 0x20
+#define SX1276_REG_LR_PREAMBLELSB 0x21
+#define SX1276_REG_LR_PAYLOADLENGTH 0x22
+#define SX1276_REG_LR_PAYLOADMAXLENGTH 0x23
+#define SX1276_REG_LR_HOPPERIOD 0x24
+#define SX1276_REG_LR_FIFORXBYTEADDR 0x25
+#define SX1276_REG_LR_MODEMCONFIG3 0x26
+#define SX1276_REG_LR_FEIMSB 0x28
+#define SX1276_REG_LR_FEIMID 0x29
+#define SX1276_REG_LR_FEILSB 0x2A
+#define SX1276_REG_LR_RSSIWIDEBAND 0x2C
+#define SX1276_REG_LR_TEST2F 0x2F
+#define SX1276_REG_LR_TEST30 0x30
+#define SX1276_REG_LR_DETECTOPTIMIZE 0x31
+#define SX1276_REG_LR_INVERTIQ 0x33
+#define SX1276_REG_LR_TEST36 0x36
+#define SX1276_REG_LR_DETECTIONTHRESHOLD 0x37
+#define SX1276_REG_LR_SYNCWORD 0x39
+#define SX1276_REG_LR_TEST3A 0x3A
+#define SX1276_REG_LR_INVERTIQ2 0x3B
+
+// end of documented register in datasheet
+// I/O settings
+#define SX1276_REG_LR_DIOMAPPING1 0x40
+#define SX1276_REG_LR_DIOMAPPING2 0x41
+// Version
+#define SX1276_REG_LR_VERSION 0x42
+// Additional settings
+#define SX1276_REG_LR_PLLHOP 0x44
+#define SX1276_REG_LR_TCXO 0x4B
+#define SX1276_REG_LR_PADAC 0x4D
+#define SX1276_REG_LR_FORMERTEMP 0x5B
+#define SX1276_REG_LR_BITRATEFRAC 0x5D
+#define SX1276_REG_LR_AGCREF 0x61
+#define SX1276_REG_LR_AGCTHRESH1 0x62
+#define SX1276_REG_LR_AGCTHRESH2 0x63
+#define SX1276_REG_LR_AGCTHRESH3 0x64
+#define SX1276_REG_LR_PLL 0x70
+
+#endif // _LORAGW_SX1276_REGS_LORA_H