summaryrefslogtreecommitdiff
path: root/loragw_hal/src
diff options
context:
space:
mode:
authorSylvain Miermont <smiermont@semtech.com>2013-07-03 17:53:18 +0200
committerSylvain Miermont <smiermont@semtech.com>2013-10-23 10:16:59 +0200
commit1361e7215cd0eb3b38faff1c403cb3077e41b2be (patch)
treec52471c65b0a40b081b7de6a8570757f85c71704 /loragw_hal/src
parent3357493e096fc0bd4767d1a3cc0cb7e3e52a4f53 (diff)
downloadlora_gateway-1361e7215cd0eb3b38faff1c403cb3077e41b2be.tar.gz
lora_gateway-1361e7215cd0eb3b38faff1c403cb3077e41b2be.tar.bz2
lora_gateway-1361e7215cd0eb3b38faff1c403cb3077e41b2be.zip
Release Candidate 2v0.rc2
- code cleanup and formating - variable and constants renaming - TX polarity management - fixed bugs thanks to Joe Knapp feedback
Diffstat (limited to 'loragw_hal/src')
-rw-r--r--loragw_hal/src/agc_fw.var6
-rw-r--r--loragw_hal/src/arb_fw.var6
-rw-r--r--loragw_hal/src/loragw_aux.c44
-rw-r--r--loragw_hal/src/loragw_hal.c1667
-rw-r--r--loragw_hal/src/loragw_reg.c1236
-rw-r--r--loragw_hal/src/loragw_spi.c448
6 files changed, 1709 insertions, 1698 deletions
diff --git a/loragw_hal/src/agc_fw.var b/loragw_hal/src/agc_fw.var
index 350e56d..a0dde65 100644
--- a/loragw_hal/src/agc_fw.var
+++ b/loragw_hal/src/agc_fw.var
@@ -1,13 +1,13 @@
/*
- / _____) _ | |
-( (____ _____ ____ _| |_ _____ ____| |__
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
©2013 Semtech-Cycleo
Description:
- AGC firmware
+ AGC firmware
*/
static uint8_t agc_firmware[MCU_AGC_FW_BYTE] = {
diff --git a/loragw_hal/src/arb_fw.var b/loragw_hal/src/arb_fw.var
index 2e41dcc..2cb66f5 100644
--- a/loragw_hal/src/arb_fw.var
+++ b/loragw_hal/src/arb_fw.var
@@ -1,13 +1,13 @@
/*
- / _____) _ | |
-( (____ _____ ____ _| |_ _____ ____| |__
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
©2013 Semtech-Cycleo
Description:
- Arbiter firmware
+ Arbiter firmware
*/
static uint8_t arb_firmware[MCU_ARB_FW_BYTE] = {
diff --git a/loragw_hal/src/loragw_aux.c b/loragw_hal/src/loragw_aux.c
index 52df612..9adafe3 100644
--- a/loragw_hal/src/loragw_aux.c
+++ b/loragw_hal/src/loragw_aux.c
@@ -1,31 +1,31 @@
/*
- / _____) _ | |
-( (____ _____ ____ _| |_ _____ ____| |__
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
©2013 Semtech-Cycleo
Description:
- Lora gateway auxiliary functions
+ Lora gateway auxiliary functions
*/
/* -------------------------------------------------------------------------- */
/* --- DEPENDANCIES --------------------------------------------------------- */
-#include <stdio.h> /* printf fprintf */
-#include <time.h> /* clock_nanosleep */
+#include <stdio.h> /* printf fprintf */
+#include <time.h> /* clock_nanosleep */
/* -------------------------------------------------------------------------- */
/* --- PRIVATE MACROS ------------------------------------------------------- */
#ifdef DEBUG
- #define DEBUG_MSG(str) fprintf(stderr, str)
- #define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
+ #define DEBUG_MSG(str) fprintf(stderr, str)
+ #define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
#else
- #define DEBUG_MSG(str)
- #define DEBUG_PRINTF(fmt, args...)
+ #define DEBUG_MSG(str)
+ #define DEBUG_PRINTF(fmt, args...)
#endif
/* -------------------------------------------------------------------------- */
@@ -33,19 +33,19 @@ Description:
/* This implementation is POSIX-pecific and require a fix to be compatible with C99 */
void wait_ms(unsigned long a) {
- struct timespec dly;
- struct timespec rem;
-
- dly.tv_sec = a / 1000;
- dly.tv_nsec = ((long)a % 1000) * 1000000;
-
- DEBUG_PRINTF("NOTE dly: %ld sec %ld ns\n", dly.tv_sec, dly.tv_nsec);
-
- if((dly.tv_sec > 0) || ((dly.tv_sec == 0) && (dly.tv_nsec > 100000))) {
- clock_nanosleep(CLOCK_MONOTONIC, 0, &dly, &rem);
- DEBUG_PRINTF("NOTE remain: %ld sec %ld ns\n", rem.tv_sec, rem.tv_nsec);
- }
- return;
+ struct timespec dly;
+ struct timespec rem;
+
+ dly.tv_sec = a / 1000;
+ dly.tv_nsec = ((long)a % 1000) * 1000000;
+
+ DEBUG_PRINTF("NOTE dly: %ld sec %ld ns\n", dly.tv_sec, dly.tv_nsec);
+
+ if((dly.tv_sec > 0) || ((dly.tv_sec == 0) && (dly.tv_nsec > 100000))) {
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &dly, &rem);
+ DEBUG_PRINTF("NOTE remain: %ld sec %ld ns\n", rem.tv_sec, rem.tv_nsec);
+ }
+ return;
}
/* --- EOF ------------------------------------------------------------------ */
diff --git a/loragw_hal/src/loragw_hal.c b/loragw_hal/src/loragw_hal.c
index bdf563c..d597f5d 100644
--- a/loragw_hal/src/loragw_hal.c
+++ b/loragw_hal/src/loragw_hal.c
@@ -1,24 +1,25 @@
/*
- / _____) _ | |
-( (____ _____ ____ _| |_ _____ ____| |__
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
©2013 Semtech-Cycleo
Description:
- Lora gateway Hardware Abstraction Layer
+ Lora gateway Hardware Abstraction Layer
*/
/* -------------------------------------------------------------------------- */
/* --- DEPENDANCIES --------------------------------------------------------- */
-#include <stdint.h> /* C99 types */
-#include <stdlib.h> /* malloc & free */
-#include <stdbool.h> /* bool type */
-#include <stdio.h> /* printf fprintf */
-#include <math.h> /* NaN */
+#include <stdint.h> /* C99 types */
+#include <stdlib.h> /* malloc & free */
+#include <stdbool.h> /* bool type */
+#include <stdio.h> /* printf fprintf */
+#include <math.h> /* NaN */
+#include <string.h> /* memcpy */
#include "loragw_reg.h"
#include "loragw_hal.h"
@@ -29,15 +30,15 @@ Description:
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#ifdef DEBUG
- #define DEBUG_MSG(str) fprintf(stderr, str)
- #define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
- #define DEBUG_ARRAY(a,b,c) for(a=0;a<b;++a) fprintf(stderr,"%x.",c[a]);fprintf(stderr,"end\n")
- #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_HAL_ERROR;}
+ #define DEBUG_MSG(str) fprintf(stderr, str)
+ #define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
+ #define DEBUG_ARRAY(a,b,c) for(a=0;a<b;++a) fprintf(stderr,"%x.",c[a]);fprintf(stderr,"end\n")
+ #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_HAL_ERROR;}
#else
- #define DEBUG_MSG(str)
- #define DEBUG_PRINTF(fmt, args...)
- #define DEBUG_ARRAY(a,b,c)
- #define CHECK_NULL(a) if(a==NULL){return LGW_HAL_ERROR;}
+ #define DEBUG_MSG(str)
+ #define DEBUG_PRINTF(fmt, args...)
+ #define DEBUG_ARRAY(a,b,c)
+ #define CHECK_NULL(a) if(a==NULL){return LGW_HAL_ERROR;}
#endif
#define IF_HZ_TO_REG(f) (f << 5)/15625
@@ -45,8 +46,8 @@ Description:
/* -------------------------------------------------------------------------- */
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
-#define MCU_ARB 0
-#define MCU_AGC 1
+#define MCU_ARB 0
+#define MCU_AGC 1
const uint8_t ifmod_config[LGW_IF_CHAIN_NB] = LGW_IFMODEM_CONFIG; /* define hardware capability */
@@ -55,29 +56,30 @@ const uint32_t rf_rx_upfreq[LGW_RF_CHAIN_NB] = LGW_RF_RX_UPFREQ;
const uint32_t rf_tx_lowfreq[LGW_RF_CHAIN_NB] = LGW_RF_TX_LOWFREQ;
const uint32_t rf_tx_upfreq[LGW_RF_CHAIN_NB] = LGW_RF_TX_UPFREQ;
-#define MCU_ARB_FW_BYTE 2048 /* size of the firmware IN BYTES (= twice the number of 14b words) */
-#define MCU_AGC_FW_BYTE 8192 /* size of the firmware IN BYTES (= twice the number of 14b words) */
+#define MCU_ARB_FW_BYTE 2048 /* size of the firmware IN BYTES (= twice the number of 14b words) */
+#define MCU_AGC_FW_BYTE 8192 /* size of the firmware IN BYTES (= twice the number of 14b words) */
-#define SX1257_CLK_OUT 1
-#define SX1257_TX_DAC_CLK_SEL 1 /* 0:int, 1:ext */
-#define SX1257_TX_DAC_GAIN 2 /* 3:0, 2:-3, 1:-6, 0:-9 dBFS (default 2) */
-#define SX1257_TX_MIX_GAIN 14 /* -38 + 2*TxMixGain dB (default 14) */
-#define SX1257_TX_PLL_BW 3 /* 0:75, 1:150, 2:225, 3:300 kHz (default 3) */
-#define SX1257_TX_ANA_BW 0 /* 17.5 / 2*(41-TxAnaBw) MHz (default 0) */
-#define SX1257_TX_DAC_BW 7 /* 24 + 8*TxDacBw Nb FIR taps (default 2) */
-#define SX1257_RX_LNA_GAIN 1 /* 1 to 6, 1 highest gain */
-#define SX1257_RX_BB_GAIN 12 /* 0 to 15 , 15 highest gain */
-#define SX1257_RX_ADC_BW 7 /* 0 to 7, 2:100<BW<200, 5:200<BW<400,7:400<BW (kHz) */
-#define SX1257_RX_ADC_TRIM 7 /* 0 to 7, 6 for 32MHz ref, 5 for 36MHz ref */
-#define SX1257_RXBB_BW 2
+#define SX1257_CLK_OUT 1
+#define SX1257_TX_DAC_CLK_SEL 1 /* 0:int, 1:ext */
+#define SX1257_TX_DAC_GAIN 2 /* 3:0, 2:-3, 1:-6, 0:-9 dBFS (default 2) */
+#define SX1257_TX_MIX_GAIN 14 /* -38 + 2*TxMixGain dB (default 14) */
+#define SX1257_TX_PLL_BW 3 /* 0:75, 1:150, 2:225, 3:300 kHz (default 3) */
+#define SX1257_TX_ANA_BW 0 /* 17.5 / 2*(41-TxAnaBw) MHz (default 0) */
+#define SX1257_TX_DAC_BW 7 /* 24 + 8*TxDacBw Nb FIR taps (default 2) */
+#define SX1257_RX_LNA_GAIN 1 /* 1 to 6, 1 highest gain */
+#define SX1257_RX_BB_GAIN 12 /* 0 to 15 , 15 highest gain */
+#define SX1257_RX_ADC_BW 7 /* 0 to 7, 2:100<BW<200, 5:200<BW<400,7:400<BW (kHz) */
+#define SX1257_RX_ADC_TRIM 7 /* 0 to 7, 6 for 32MHz ref, 5 for 36MHz ref */
+#define SX1257_RXBB_BW 2
-#define RSSI_OFFSET_LORA_MULTI -100.0 // TODO
-#define RSSI_OFFSET_LORA_STD -100.0 // TODO
+#define RSSI_OFFSET_LORA_MULTI -100.0 // TODO: need to find proper value with calibration
+#define RSSI_OFFSET_LORA_STD -100.0 // TODO: need to find proper value with calibration
-#define TX_METADATA_NB 16
-#define RX_METADATA_NB 16
+#define TX_METADATA_NB 16
+#define RX_METADATA_NB 16
-#define MIN_LORA_PREAMBLE 4
+#define MIN_LORA_PREAMBLE 4
+#define PLL_LOCK_MAX_ATTEMPTS 6
/* -------------------------------------------------------------------------- */
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
@@ -120,7 +122,7 @@ void sx125x_write(uint8_t rf_chain, uint8_t addr, uint8_t data);
uint8_t sx125x_read(uint8_t rf_chain, uint8_t addr);
-void setup_sx1257(uint8_t rf_chain, uint32_t freq_hz);
+int setup_sx1257(uint8_t rf_chain, uint32_t freq_hz);
void lgw_constant_adjust(void);
@@ -129,846 +131,855 @@ void lgw_constant_adjust(void);
/* size is the firmware size in bytes (not 14b words) */
int load_firmware(uint8_t target, uint8_t *firmware, uint16_t size) {
- int i;
- int32_t read_value;
- int reg_rst;
- int reg_sel;
-
- /* check parameters */
- CHECK_NULL(firmware);
- if (target == MCU_ARB) {
- if (size != MCU_ARB_FW_BYTE) {
- DEBUG_MSG("ERROR: NOT A VALID SIZE FOR MCU ARG FIRMWARE\n");
- return -1;
- }
- reg_rst = LGW_MCU_RST_0;
- reg_sel = LGW_MCU_SELECT_MUX_0;
- }else if (target == MCU_AGC) {
- if (size != MCU_AGC_FW_BYTE) {
- DEBUG_MSG("ERROR: NOT A VALID SIZE FOR MCU AGC FIRMWARE\n");
- return -1;
- }
- reg_rst = LGW_MCU_RST_1;
- reg_sel = LGW_MCU_SELECT_MUX_1;
- } else {
- DEBUG_MSG("ERROR: NOT A VALID TARGET FOR LOADING FIRMWARE\n");
- return -1;
- }
-
- /* reset the targeted MCU */
- lgw_reg_w(reg_rst, 1);
-
- /* set mux to access MCU program RAM and set address to 0 */
- lgw_reg_w(reg_sel, 0);
- lgw_reg_w(LGW_MCU_PROM_ADDR, 0);
-
- /* write the program in one burst */
- lgw_reg_wb(LGW_MCU_PROM_DATA, firmware, size);
-
- /* give back control of the MCU program ram to the MCU */
- lgw_reg_w(reg_sel, 1);
-
- return 0;
+ int32_t read_value;
+ int reg_rst;
+ int reg_sel;
+
+ /* check parameters */
+ CHECK_NULL(firmware);
+ if (target == MCU_ARB) {
+ if (size != MCU_ARB_FW_BYTE) {
+ DEBUG_MSG("ERROR: NOT A VALID SIZE FOR MCU ARG FIRMWARE\n");
+ return -1;
+ }
+ reg_rst = LGW_MCU_RST_0;
+ reg_sel = LGW_MCU_SELECT_MUX_0;
+ }else if (target == MCU_AGC) {
+ if (size != MCU_AGC_FW_BYTE) {
+ DEBUG_MSG("ERROR: NOT A VALID SIZE FOR MCU AGC FIRMWARE\n");
+ return -1;
+ }
+ reg_rst = LGW_MCU_RST_1;
+ reg_sel = LGW_MCU_SELECT_MUX_1;
+ } else {
+ DEBUG_MSG("ERROR: NOT A VALID TARGET FOR LOADING FIRMWARE\n");
+ return -1;
+ }
+
+ /* reset the targeted MCU */
+ lgw_reg_w(reg_rst, 1);
+
+ /* set mux to access MCU program RAM and set address to 0 */
+ lgw_reg_w(reg_sel, 0);
+ lgw_reg_w(LGW_MCU_PROM_ADDR, 0);
+
+ /* write the program in one burst */
+ lgw_reg_wb(LGW_MCU_PROM_DATA, firmware, size);
+
+ /* give back control of the MCU program ram to the MCU */
+ lgw_reg_w(reg_sel, 1);
+
+ return 0;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void sx125x_write(uint8_t channel, uint8_t addr, uint8_t data) {
- int reg_add, reg_dat, reg_cs;
-
- /* checking input parameters */
- if (channel >= LGW_RF_CHAIN_NB) {
- DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
- return;
- }
- if (addr >= 0x7F) {
- DEBUG_MSG("ERROR: ADDRESS OUT OF RANGE\n");
- return;
- }
-
- /* selecting the target radio */
- switch (channel) {
- case 0:
- reg_add = LGW_SPI_RADIO_A__ADDR;
- reg_dat = LGW_SPI_RADIO_A__DATA;
- reg_cs = LGW_SPI_RADIO_A__CS;
- break;
-
- case 1:
- reg_add = LGW_SPI_RADIO_B__ADDR;
- reg_dat = LGW_SPI_RADIO_B__DATA;
- reg_cs = LGW_SPI_RADIO_B__CS;
- break;
-
- default:
- DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d IN SWITCH STATEMENT\n", channel);
- return;
- }
-
- /* SPI master data write procedure */
- lgw_reg_w(reg_add, 0x80 | addr); /* MSB at 1 for write operation */
- lgw_reg_w(reg_dat, data);
- lgw_reg_w(reg_cs, 1);
- lgw_reg_w(reg_cs, 0);
-
- return;
+ int reg_add, reg_dat, reg_cs;
+
+ /* checking input parameters */
+ if (channel >= LGW_RF_CHAIN_NB) {
+ DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
+ return;
+ }
+ if (addr >= 0x7F) {
+ DEBUG_MSG("ERROR: ADDRESS OUT OF RANGE\n");
+ return;
+ }
+
+ /* selecting the target radio */
+ switch (channel) {
+ case 0:
+ reg_add = LGW_SPI_RADIO_A__ADDR;
+ reg_dat = LGW_SPI_RADIO_A__DATA;
+ reg_cs = LGW_SPI_RADIO_A__CS;
+ break;
+
+ case 1:
+ reg_add = LGW_SPI_RADIO_B__ADDR;
+ reg_dat = LGW_SPI_RADIO_B__DATA;
+ reg_cs = LGW_SPI_RADIO_B__CS;
+ break;
+
+ default:
+ DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d IN SWITCH STATEMENT\n", channel);
+ return;
+ }
+
+ /* SPI master data write procedure */
+ lgw_reg_w(reg_cs, 0);
+ lgw_reg_w(reg_add, 0x80 | addr); /* MSB at 1 for write operation */
+ lgw_reg_w(reg_dat, data);
+ lgw_reg_w(reg_cs, 1);
+ lgw_reg_w(reg_cs, 0);
+
+ return;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
uint8_t sx125x_read(uint8_t channel, uint8_t addr) {
- int reg_add, reg_dat, reg_cs, reg_rb;
- int32_t read_value;
-
- /* checking input parameters */
- if (channel >= LGW_RF_CHAIN_NB) {
- DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
- return 0;
- }
- if (addr >= 0x7F) {
- DEBUG_MSG("ERROR: ADDRESS OUT OF RANGE\n");
- return 0;
- }
-
- /* selecting the target radio */
- switch (channel) {
- case 0:
- reg_add = LGW_SPI_RADIO_A__ADDR;
- reg_dat = LGW_SPI_RADIO_A__DATA;
- reg_cs = LGW_SPI_RADIO_A__CS;
- reg_rb = LGW_SPI_RADIO_A__DATA_READBACK;
- break;
-
- case 1:
- reg_add = LGW_SPI_RADIO_B__ADDR;
- reg_dat = LGW_SPI_RADIO_B__DATA;
- reg_cs = LGW_SPI_RADIO_B__CS;
- reg_rb = LGW_SPI_RADIO_B__DATA_READBACK;
- break;
-
- default:
- DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d IN SWITCH STATEMENT\n", channel);
- return 0;
- }
-
- /* SPI master data read procedure */
- lgw_reg_w(reg_add, addr); /* MSB at 0 for read operation */
- lgw_reg_w(reg_dat, 0);
- lgw_reg_w(reg_cs, 1);
- lgw_reg_w(reg_cs, 0);
- lgw_reg_r(reg_rb, &read_value);
-
- return (uint8_t)read_value;
+ int reg_add, reg_dat, reg_cs, reg_rb;
+ int32_t read_value;
+
+ /* checking input parameters */
+ if (channel >= LGW_RF_CHAIN_NB) {
+ DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
+ return 0;
+ }
+ if (addr >= 0x7F) {
+ DEBUG_MSG("ERROR: ADDRESS OUT OF RANGE\n");
+ return 0;
+ }
+
+ /* selecting the target radio */
+ switch (channel) {
+ case 0:
+ reg_add = LGW_SPI_RADIO_A__ADDR;
+ reg_dat = LGW_SPI_RADIO_A__DATA;
+ reg_cs = LGW_SPI_RADIO_A__CS;
+ reg_rb = LGW_SPI_RADIO_A__DATA_READBACK;
+ break;
+
+ case 1:
+ reg_add = LGW_SPI_RADIO_B__ADDR;
+ reg_dat = LGW_SPI_RADIO_B__DATA;
+ reg_cs = LGW_SPI_RADIO_B__CS;
+ reg_rb = LGW_SPI_RADIO_B__DATA_READBACK;
+ break;
+
+ default:
+ DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d IN SWITCH STATEMENT\n", channel);
+ return 0;
+ }
+
+ /* SPI master data read procedure */
+ lgw_reg_w(reg_cs, 0);
+ lgw_reg_w(reg_add, addr); /* MSB at 0 for read operation */
+ lgw_reg_w(reg_dat, 0);
+ lgw_reg_w(reg_cs, 1);
+ lgw_reg_w(reg_cs, 0);
+ lgw_reg_r(reg_rb, &read_value);
+
+ return (uint8_t)read_value;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-void setup_sx1257(uint8_t rf_chain, uint32_t freq_hz) {
- uint32_t part_int;
- uint32_t part_frac;
- int i = 0;
-
- if (rf_chain >= LGW_RF_CHAIN_NB) {
- DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
- return;
- }
-
- /* misc */
- sx125x_write(rf_chain, 0x10, SX1257_TX_DAC_CLK_SEL + SX1257_CLK_OUT*2);
-
- /* Tx gain and trim */
- sx125x_write(rf_chain, 0x08, SX1257_TX_MIX_GAIN + SX1257_TX_DAC_GAIN*16);
- sx125x_write(rf_chain, 0x0A, SX1257_TX_ANA_BW + SX1257_TX_PLL_BW*32);
- sx125x_write(rf_chain, 0x0B, SX1257_TX_DAC_BW);
-
- /* Rx gain and trim */
- sx125x_write(rf_chain, 0x0C, 0 + SX1257_RX_BB_GAIN*2 + SX1257_RX_LNA_GAIN*32);
- sx125x_write(rf_chain, 0x0D, SX1257_RXBB_BW + SX1257_RX_ADC_TRIM*4 + SX1257_RX_ADC_BW*32);
-
- /* set RX PLL frequency */
- part_int = freq_hz / LGW_SW1257_DENUM; /* integer part, gives the MSB and the middle byte */
- part_frac = ((freq_hz % LGW_SW1257_DENUM) << 8) / LGW_SW1257_DENUM; /* fractional part, gives LSB */
- sx125x_write(rf_chain, 0x01,0xFF & (part_int >> 8)); /* Most Significant Byte */
- sx125x_write(rf_chain, 0x02,0xFF & part_int); /* middle byte */
- sx125x_write(rf_chain, 0x03,0xFF & part_frac); /* Least Significant Byte */
-
- /* start and PLL lock */
- do {
- sx125x_write(rf_chain, 0x00, 1); /* enable Xtal oscillator */
- sx125x_write(rf_chain, 0x00, 3); /* Enable RX (PLL+FE) */
- ++i;
- DEBUG_PRINTF("Note: SX1257 #%d PLL start (attempt %d)\n", rf_chain, i);
- wait_ms(1);
- } while(sx125x_read(rf_chain, 0x11) & 0x02 == 0);
-
- return;
+int setup_sx1257(uint8_t rf_chain, uint32_t freq_hz) {
+ uint32_t part_int;
+ uint32_t part_frac;
+ int i = 0;
+
+ if (rf_chain >= LGW_RF_CHAIN_NB) {
+ DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
+ return -1;
+ }
+
+ /* misc */
+ sx125x_write(rf_chain, 0x10, SX1257_TX_DAC_CLK_SEL + SX1257_CLK_OUT*2);
+
+ /* Tx gain and trim */
+ sx125x_write(rf_chain, 0x08, SX1257_TX_MIX_GAIN + SX1257_TX_DAC_GAIN*16);
+ sx125x_write(rf_chain, 0x0A, SX1257_TX_ANA_BW + SX1257_TX_PLL_BW*32);
+ sx125x_write(rf_chain, 0x0B, SX1257_TX_DAC_BW);
+
+ /* Rx gain and trim */
+ sx125x_write(rf_chain, 0x0C, 0 + SX1257_RX_BB_GAIN*2 + SX1257_RX_LNA_GAIN*32);
+ sx125x_write(rf_chain, 0x0D, SX1257_RXBB_BW + SX1257_RX_ADC_TRIM*4 + SX1257_RX_ADC_BW*32);
+
+ /* set RX PLL frequency */
+ part_int = freq_hz / LGW_SX1257_DENOMINATOR; /* integer part, gives the MSB and the middle byte */
+ part_frac = ((freq_hz % LGW_SX1257_DENOMINATOR) << 8) / LGW_SX1257_DENOMINATOR; /* fractional part, gives LSB */
+ sx125x_write(rf_chain, 0x01,0xFF & (part_int >> 8)); /* Most Significant Byte */
+ sx125x_write(rf_chain, 0x02,0xFF & part_int); /* middle byte */
+ sx125x_write(rf_chain, 0x03,0xFF & part_frac); /* Least Significant Byte */
+
+ /* start and PLL lock */
+ do {
+ if (i >= PLL_LOCK_MAX_ATTEMPTS) {
+ DEBUG_MSG("ERROR: FAIL TO LOCK PLL\n");
+ return -1;
+ }
+ sx125x_write(rf_chain, 0x00, 1); /* enable Xtal oscillator */
+ sx125x_write(rf_chain, 0x00, 3); /* Enable RX (PLL+FE) */
+ ++i;
+ DEBUG_PRINTF("Note: SX1257 #%d PLL start (attempt %d)\n", rf_chain, i);
+ wait_ms(1);
+ } while(sx125x_read(rf_chain, 0x11) & 0x02 == 0);
+
+ return 0;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void lgw_constant_adjust(void) {
-
- /* I/Q path setup */
- // lgw_reg_w(LGW_RX_INVERT_IQ,0); /* default 0 */
- // lgw_reg_w(LGW_MODEM_INVERT_IQ,1); /* default 1 */
- // lgw_reg_w(LGW_CHIRP_INVERT_RX,1); /* default 1 */
- // lgw_reg_w(LGW_RX_EDGE_SELECT,0); /* default 0 */
- // lgw_reg_w(LGW_MBWSSF_MODEM_INVERT_IQ,0); /* default 0 */
- lgw_reg_w(LGW_DC_NOTCH_EN,1); /* default 0 */
- // lgw_reg_w(LGW_RSSI_BB_FILTER_ALPHA,7); /* default 7 */
- lgw_reg_w(LGW_RSSI_DEC_FILTER_ALPHA,7); /* default 5 */
- lgw_reg_w(LGW_RSSI_CHANN_FILTER_ALPHA,7); /* default 8 */
- // lgw_reg_w(LGW_RSSI_BB_DEFAULT_VALUE,32); /* default 32 */
- lgw_reg_w(LGW_RSSI_CHANN_DEFAULT_VALUE,90); /* default 100 */
- lgw_reg_w(LGW_RSSI_DEC_DEFAULT_VALUE,90); /* default 100 */
-
- /* Correlator setup */
- // lgw_reg_w(LGW_CORR_DETECT_EN,126); /* default 126 */
- // lgw_reg_w(LGW_CORR_NUM_SAME_PEAK,4); /* default 4 */
- // lgw_reg_w(LGW_CORR_MAC_GAIN,5); /* default 5 */
- // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF6,0); /* default 0 */
- // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF7,1); /* default 1 */
- // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF8,1); /* default 1 */
- // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF9,1); /* default 1 */
- // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF10,1); /* default 1 */
- // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF11,1); /* default 1 */
- // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF12,1); /* default 1 */
- // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF6,4); /* default 4 */
- // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF7,4); /* default 4 */
- // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF8,4); /* default 4 */
- // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF9,4); /* default 4 */
- // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF10,4); /* default 4 */
- // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF11,4); /* default 4 */
- // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF12,4); /* default 4 */
-
- /* Lora 'multi' modems setup */
- lgw_reg_w(LGW_PREAMBLE_SYMB1_NB,4); /* default 10 */
- // lgw_reg_w(LGW_FREQ_TO_TIME_DRIFT,9); /* default 9 */
- // lgw_reg_w(LGW_FREQ_TO_TIME_INVERT,29); /* default 29 */
- // lgw_reg_w(LGW_FRAME_SYNCH_GAIN,1); /* default 1 */
- // lgw_reg_w(LGW_SYNCH_DETECT_TH,1); /* default 1 */
- // lgw_reg_w(LGW_ZERO_PAD,0); /* default 0 */
- lgw_reg_w(LGW_SNR_AVG_CST,3); /* default 2 */
- // lgw_reg_w(LGW_PPM_OFFSET,0); /* default 0 */
- // lgw_reg_w(LGW_FRAME_SYNCH_PEAK1_POS,1); /* default 1 */
- // lgw_reg_w(LGW_FRAME_SYNCH_PEAK2_POS,2); /* default 2 */
- // lgw_reg_w(LGW_PREAMBLE_FINE_TIMING_GAIN,1); /* default 1 */
- // lgw_reg_w(LGW_ONLY_CRC_EN,1); /* default 1 */
- // lgw_reg_w(LGW_PAYLOAD_FINE_TIMING_GAIN,2); /* default 2 */
- // lgw_reg_w(LGW_TRACKING_INTEGRAL,0); /* default 0 */
- // lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_RDX8,0); /* default 0 */
- // lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_RDX4,0); /* default 0 */
- // lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_SF12_RDX4,4092); /* default 4092 */
- // lgw_reg_w(LGW_MAX_PAYLOAD_LEN,255); /* default 255 */
-
- /* MBWSSF Modem */
- // lgw_reg_w(LGW_MBWSSF_MODEM_ENABLE,1); /* default 0 */
- // lgw_reg_w(LGW_MBWSSF_PREAMBLE_SYMB1_NB,10); /* default 10 */
- // lgw_reg_w(LGW_MBWSSF_FREQ_TO_TIME_DRIFT,36); /* default 36 */
- // lgw_reg_w(LGW_MBWSSF_FREQ_TO_TIME_INVERT,29); /* default 29 */
- // lgw_reg_w(LGW_MBWSSF_FRAME_SYNCH_GAIN,1); /* default 1 */
- // lgw_reg_w(LGW_MBWSSF_SYNCH_DETECT_TH,1); /* default 1 */
- // lgw_reg_w(LGW_MBWSSF_ZERO_PAD,0); /* default 0 */
- // lgw_reg_w(LGW_MBWSSF_PPM_OFFSET,0); /* default 0 */
- // lgw_reg_w(LGW_MBWSSF_FRAME_SYNCH_PEAK1_POS,1); /* default 1 */
- // lgw_reg_w(LGW_MBWSSF_FRAME_SYNCH_PEAK2_POS,2); /* default 2 */
- // lgw_reg_w(LGW_MBWSSF_ONLY_CRC_EN,1); /* default 1 */
- // lgw_reg_w(LGW_MBWSSF_PAYLOAD_FINE_TIMING_GAIN,2); /* default 2 */
- // lgw_reg_w(LGW_MBWSSF_PREAMBLE_FINE_TIMING_GAIN,1); /* default 1 */
- // lgw_reg_w(LGW_MBWSSF_TRACKING_INTEGRAL,0); /* default 0 */
- // lgw_reg_w(LGW_MBWSSF_AGC_FREEZE_ON_DETECT,1); /* default 1 */
-
- /* TX */
- // lgw_reg_w(LGW_TX_MODE,0); /* default 0 */
- lgw_reg_w(LGW_TX_START_DELAY,5000); /* default 0 */
-
- return;
+
+ /* I/Q path setup */
+ // lgw_reg_w(LGW_RX_INVERT_IQ,0); /* default 0 */
+ // lgw_reg_w(LGW_MODEM_INVERT_IQ,1); /* default 1 */
+ // lgw_reg_w(LGW_CHIRP_INVERT_RX,1); /* default 1 */
+ // lgw_reg_w(LGW_RX_EDGE_SELECT,0); /* default 0 */
+ // lgw_reg_w(LGW_MBWSSF_MODEM_INVERT_IQ,0); /* default 0 */
+ lgw_reg_w(LGW_DC_NOTCH_EN,1); /* default 0 */
+ // lgw_reg_w(LGW_RSSI_BB_FILTER_ALPHA,7); /* default 7 */
+ lgw_reg_w(LGW_RSSI_DEC_FILTER_ALPHA,7); /* default 5 */
+ lgw_reg_w(LGW_RSSI_CHANN_FILTER_ALPHA,7); /* default 8 */
+ // lgw_reg_w(LGW_RSSI_BB_DEFAULT_VALUE,32); /* default 32 */
+ lgw_reg_w(LGW_RSSI_CHANN_DEFAULT_VALUE,90); /* default 100 */
+ lgw_reg_w(LGW_RSSI_DEC_DEFAULT_VALUE,90); /* default 100 */
+
+ /* Correlator setup */
+ // lgw_reg_w(LGW_CORR_DETECT_EN,126); /* default 126 */
+ // lgw_reg_w(LGW_CORR_NUM_SAME_PEAK,4); /* default 4 */
+ // lgw_reg_w(LGW_CORR_MAC_GAIN,5); /* default 5 */
+ // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF6,0); /* default 0 */
+ // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF7,1); /* default 1 */
+ // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF8,1); /* default 1 */
+ // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF9,1); /* default 1 */
+ // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF10,1); /* default 1 */
+ // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF11,1); /* default 1 */
+ // lgw_reg_w(LGW_CORR_SAME_PEAKS_OPTION_SF12,1); /* default 1 */
+ // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF6,4); /* default 4 */
+ // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF7,4); /* default 4 */
+ // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF8,4); /* default 4 */
+ // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF9,4); /* default 4 */
+ // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF10,4); /* default 4 */
+ // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF11,4); /* default 4 */
+ // lgw_reg_w(LGW_CORR_SIG_NOISE_RATIO_SF12,4); /* default 4 */
+
+ /* Lora 'multi' modems setup */
+ lgw_reg_w(LGW_PREAMBLE_SYMB1_NB,4); /* default 10 */
+ // lgw_reg_w(LGW_FREQ_TO_TIME_DRIFT,9); /* default 9 */
+ // lgw_reg_w(LGW_FREQ_TO_TIME_INVERT,29); /* default 29 */
+ // lgw_reg_w(LGW_FRAME_SYNCH_GAIN,1); /* default 1 */
+ // lgw_reg_w(LGW_SYNCH_DETECT_TH,1); /* default 1 */
+ // lgw_reg_w(LGW_ZERO_PAD,0); /* default 0 */
+ lgw_reg_w(LGW_SNR_AVG_CST,3); /* default 2 */
+ // lgw_reg_w(LGW_PPM_OFFSET,0); /* default 0 */
+ // lgw_reg_w(LGW_FRAME_SYNCH_PEAK1_POS,1); /* default 1 */
+ // lgw_reg_w(LGW_FRAME_SYNCH_PEAK2_POS,2); /* default 2 */
+ // lgw_reg_w(LGW_PREAMBLE_FINE_TIMING_GAIN,1); /* default 1 */
+ // lgw_reg_w(LGW_ONLY_CRC_EN,1); /* default 1 */
+ // lgw_reg_w(LGW_PAYLOAD_FINE_TIMING_GAIN,2); /* default 2 */
+ // lgw_reg_w(LGW_TRACKING_INTEGRAL,0); /* default 0 */
+ // lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_RDX8,0); /* default 0 */
+ // lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_RDX4,0); /* default 0 */
+ // lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_SF12_RDX4,4092); /* default 4092 */
+ // lgw_reg_w(LGW_MAX_PAYLOAD_LEN,255); /* default 255 */
+
+ /* MBWSSF Modem */
+ // lgw_reg_w(LGW_MBWSSF_MODEM_ENABLE,1); /* default 0 */
+ // lgw_reg_w(LGW_MBWSSF_PREAMBLE_SYMB1_NB,10); /* default 10 */
+ // lgw_reg_w(LGW_MBWSSF_FREQ_TO_TIME_DRIFT,36); /* default 36 */
+ // lgw_reg_w(LGW_MBWSSF_FREQ_TO_TIME_INVERT,29); /* default 29 */
+ // lgw_reg_w(LGW_MBWSSF_FRAME_SYNCH_GAIN,1); /* default 1 */
+ // lgw_reg_w(LGW_MBWSSF_SYNCH_DETECT_TH,1); /* default 1 */
+ // lgw_reg_w(LGW_MBWSSF_ZERO_PAD,0); /* default 0 */
+ // lgw_reg_w(LGW_MBWSSF_PPM_OFFSET,0); /* default 0 */
+ // lgw_reg_w(LGW_MBWSSF_FRAME_SYNCH_PEAK1_POS,1); /* default 1 */
+ // lgw_reg_w(LGW_MBWSSF_FRAME_SYNCH_PEAK2_POS,2); /* default 2 */
+ // lgw_reg_w(LGW_MBWSSF_ONLY_CRC_EN,1); /* default 1 */
+ // lgw_reg_w(LGW_MBWSSF_PAYLOAD_FINE_TIMING_GAIN,2); /* default 2 */
+ // lgw_reg_w(LGW_MBWSSF_PREAMBLE_FINE_TIMING_GAIN,1); /* default 1 */
+ // lgw_reg_w(LGW_MBWSSF_TRACKING_INTEGRAL,0); /* default 0 */
+ // lgw_reg_w(LGW_MBWSSF_AGC_FREEZE_ON_DETECT,1); /* default 1 */
+
+ /* TX */
+ // lgw_reg_w(LGW_TX_MODE,0); /* default 0 */
+ lgw_reg_w(LGW_TX_START_DELAY,5000); /* default 0 */
+ lgw_reg_w(LGW_TX_SWAP_IQ,1); /* "normal" polarity; default 0 */
+
+ return;
}
/* -------------------------------------------------------------------------- */
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
int lgw_rxrf_setconf(uint8_t rf_chain, struct lgw_conf_rxrf_s conf) {
-
- /* check if the gateway is running */
- if (lgw_is_started == true) {
- DEBUG_MSG("ERROR: GATEWAY IS RUNNING, STOP IT BEFORE TOUCHING CONFIGURATION\n");
- return LGW_HAL_ERROR;
- }
-
- /* check input parameters */
- if (rf_chain > LGW_RF_CHAIN_NB) {
- DEBUG_MSG("ERROR: NOT A VALID RF_CHAIN NUMBER\n");
- return LGW_HAL_ERROR;
- }
- if (conf.freq_hz > rf_rx_upfreq[rf_chain]) {
- DEBUG_MSG("ERROR: FREQUENCY TOO HIGH FOR THAT RF_CHAIN\n");
- return LGW_HAL_ERROR;
- } else if (conf.freq_hz < rf_rx_lowfreq[rf_chain]) {
- DEBUG_MSG("ERROR: FREQUENCY TOO LOW FOR THAT RF_CHAIN\n");
- return LGW_HAL_ERROR;
- }
-
- /* set internal config according to parameters */
- rf_enable[rf_chain] = conf.enable;
- rf_rx_freq[rf_chain] = conf.freq_hz;
-
- return LGW_HAL_SUCCESS;
+
+ /* check if the gateway is running */
+ if (lgw_is_started == true) {
+ DEBUG_MSG("ERROR: GATEWAY IS RUNNING, STOP IT BEFORE TOUCHING CONFIGURATION\n");
+ return LGW_HAL_ERROR;
+ }
+
+ /* check input parameters */
+ if (rf_chain > LGW_RF_CHAIN_NB) {
+ DEBUG_MSG("ERROR: NOT A VALID RF_CHAIN NUMBER\n");
+ return LGW_HAL_ERROR;
+ }
+ if (conf.freq_hz > rf_rx_upfreq[rf_chain]) {
+ DEBUG_MSG("ERROR: FREQUENCY TOO HIGH FOR THAT RF_CHAIN\n");
+ return LGW_HAL_ERROR;
+ } else if (conf.freq_hz < rf_rx_lowfreq[rf_chain]) {
+ DEBUG_MSG("ERROR: FREQUENCY TOO LOW FOR THAT RF_CHAIN\n");
+ return LGW_HAL_ERROR;
+ }
+
+ /* set internal config according to parameters */
+ rf_enable[rf_chain] = conf.enable;
+ rf_rx_freq[rf_chain] = conf.freq_hz;
+
+ return LGW_HAL_SUCCESS;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int lgw_rxif_setconf(uint8_t if_chain, struct lgw_conf_rxif_s conf) {
- int i, j; /* tmp variables, to shorten long 'if' lines */
-
- /* check if the gateway is running */
- if (lgw_is_started == true) {
- DEBUG_MSG("ERROR: GATEWAY IS RUNNING, STOP IT BEFORE TOUCHING CONFIGURATION\n");
- return LGW_HAL_ERROR;
- }
-
- /* if chain is disabled, don't care about most parameters */
- if (conf.enable == false) {
- if_enable[if_chain] = false;
- if_freq[if_chain] = 0;
- DEBUG_PRINTF("Note: if_chain %d disabled\n", if_chain);
- return LGW_HAL_SUCCESS;
- }
-
- /* check 'general' parameters */
- /* ? add checks to stay in band (ie. radio_freq+if+BW/2 < fmax) ? */
- if (if_chain > LGW_IF_CHAIN_NB) {
- DEBUG_PRINTF("ERROR: %d NOT A VALID IF_CHAIN NUMBER\n", if_chain);
- return LGW_HAL_ERROR;
- }
- if (ifmod_config[if_chain] == IF_UNDEFINED) {
- DEBUG_PRINTF("ERROR: IF CHAIN %d NOT CONFIGURABLE\n", if_chain);
- }
- if (conf.freq_hz > LGW_RF_BANDWIDTH/2) {
- DEBUG_PRINTF("ERROR: IF FREQUENCY %d TOO HIGH\n", conf.freq_hz);
- return LGW_HAL_ERROR;
- } else if (conf.freq_hz < -LGW_RF_BANDWIDTH/2) {
- DEBUG_PRINTF("ERROR: IF FREQUENCY %d TOO LOW\n", conf.freq_hz);
- return LGW_HAL_ERROR;
- }
-
- /* check parameters according to the type of IF chain + modem,
- fill default if necessary, and commit configuration if everything is OK */
- switch (ifmod_config[if_chain]) {
- case IF_LORA_STD:
- if (conf.rf_chain != 0) {
- DEBUG_MSG("ERROR: LORA_STD IF CHAIN CAN ONLY BE ASSOCIATED TO RF_CHAIN 0\n");
- return LGW_HAL_ERROR;
- }
- /* fill default parameters if needed */
- i = (conf.bandwidth == 0) ? BW_250KHZ : conf.bandwidth;
- j = (conf.datarate == 0) ? DR_LORA_SF9 : conf.datarate;
- /* check BW & DR */
- if ((i != BW_125KHZ) && (i != BW_250KHZ) && (i != BW_500KHZ)) {
- DEBUG_MSG("ERROR: BANDWIDTH NOT SUPPORTED BY LORA_STD IF CHAIN\n");
- return LGW_HAL_ERROR;
- }
- if ((j!=DR_LORA_SF7)&&(j!=DR_LORA_SF8)&&(j!=DR_LORA_SF9)&&(j!=DR_LORA_SF10)&&(j!=DR_LORA_SF11)&&(j!=DR_LORA_SF12)) {
- DEBUG_MSG("ERROR: DATARATE NOT SUPPORTED BY LORA_STD IF CHAIN\n");
- return LGW_HAL_ERROR;
- }
- /* set internal configuration */
- if_enable[if_chain] = conf.enable;
- if_freq[if_chain] = conf.freq_hz;
- lora_rx_bw = i;
- lora_rx_sf = j;
- DEBUG_PRINTF("Note: Lora 'std' if_chain %d configured; en:%d freq:%d bw:%d dr:%d\n", if_chain, if_enable[if_chain], if_freq[if_chain], lora_rx_bw, lora_rx_sf);
- break;
-
- case IF_LORA_MULTI:
- if (conf.rf_chain >= LGW_RF_CHAIN_NB) {
- DEBUG_MSG("ERROR: INVALID RF_CHAIN TO ASSOCIATE WITH A LORA_STD IF CHAIN\n");
- return LGW_HAL_ERROR;
- }
- /* fill default parameters if needed */
- i = (conf.bandwidth == 0) ? BW_125KHZ : conf.bandwidth;
- j = (conf.datarate == 0) ? DR_LORA_MULTI : conf.datarate;
- /* check BW & DR */
- if (i != BW_125KHZ) {
- DEBUG_MSG("ERROR: BANDWIDTH NOT SUPPORTED BY LORA_MULTI IF CHAIN\n");
- return LGW_HAL_ERROR;
- }
- if ((j & DR_LORA_MULTI) == 0) { /* supports any combination of SF between 7 and 12 */
- DEBUG_MSG("ERROR: DATARATE(S) NOT SUPPORTED BY LORA_MULTI IF CHAIN\n");
- return LGW_HAL_ERROR;
- }
- /* set internal configuration */
- if_enable[if_chain] = conf.enable;
- switch (conf.rf_chain) {
- case 0: if_rf_switch &= ~((uint8_t)1 << if_chain); break; /* force a 0 at the if_chain-th position */
- case 1: if_rf_switch |= ((uint8_t)1 << if_chain); break; /* force a 1 at the if_chain-th position */
- default: DEBUG_MSG("ERROR: IMPROPRER IF_CHAIN/RF_CHAIN ASSOCIATION\n");
- }
- if_freq[if_chain] =