From 1e66084295f37f0d7f5f0a3518e43ae0cc613898 Mon Sep 17 00:00:00 2001 From: Harsh Sharma Date: Thu, 9 Aug 2018 15:10:43 -0500 Subject: Changed attenuation setup to be the difference between the LUT power and the tx packet power and make it automatically set --- libloragw/inc/loragw_fpga.h | 4 ++- libloragw/inc/loragw_hal.h | 8 +++++- libloragw/inc/loragw_reg.h | 2 +- libloragw/src/loragw_fpga.c | 33 ++++++++++++++++--------- libloragw/src/loragw_hal.c | 38 +++++++++++++++-------------- libloragw/src/loragw_reg.c | 4 +-- libloragw/tst/test_loragw_cal.c | 2 +- libloragw/tst/test_loragw_reg.c | 2 +- util_tx_continuous/src/util_tx_continuous.c | 18 ++++++++++++++ 9 files changed, 75 insertions(+), 36 deletions(-) diff --git a/libloragw/inc/loragw_fpga.h b/libloragw/inc/loragw_fpga.h index 07418e4..46246b6 100644 --- a/libloragw/inc/loragw_fpga.h +++ b/libloragw/inc/loragw_fpga.h @@ -99,7 +99,7 @@ float lgw_fpga_get_tx_notch_delay(void); @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, bool fpga_attn_used); +int lgw_fpga_configure(uint32_t tx_notch_freq); /** @brief LoRa concentrator FPGA register write @@ -135,5 +135,7 @@ int lgw_fpga_reg_wb(uint16_t register_id, uint8_t *data, uint16_t size); */ int lgw_fpga_reg_rb(uint16_t register_id, uint8_t *data, uint16_t size); +int lgw_set_attenuation(float attenuation); + #endif /* --- EOF ------------------------------------------------------------------ */ diff --git a/libloragw/inc/loragw_hal.h b/libloragw/inc/loragw_hal.h index 632b72b..15bf918 100644 --- a/libloragw/inc/loragw_hal.h +++ b/libloragw/inc/loragw_hal.h @@ -282,7 +282,6 @@ struct lgw_tx_gain_s { 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 */ - float attenuation; /*!> 7 bits, control of the attenuator , in dBm */ int8_t rf_power; /*!> measured TX power at the board connector, in dBm */ }; @@ -415,6 +414,13 @@ const char* lgw_version_info(void); */ uint32_t lgw_time_on_air(struct lgw_pkt_tx_s *packet); +/** +@brief Set the attenuation for sending packets to get the exact power level +@param attenuation is in dB, it can be between 0-31.75 +@return LGW_HAL_ERROR if the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_set_attenuation(float attenuation); + #endif /* --- EOF ------------------------------------------------------------------ */ diff --git a/libloragw/inc/loragw_reg.h b/libloragw/inc/loragw_reg.h index 085dfb6..1e98efa 100644 --- a/libloragw/inc/loragw_reg.h +++ b/libloragw/inc/loragw_reg.h @@ -413,7 +413,7 @@ concentrator, or if we also want to reset it and configure the FPGA (if present) 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, bool fpga_attn_used); +int lgw_connect(bool spi_only, uint32_t tx_notch_freq); /** @brief Disconnect LoRa concentrator by closing SPI link diff --git a/libloragw/src/loragw_fpga.c b/libloragw/src/loragw_fpga.c index 1379679..ce1c9c6 100644 --- a/libloragw/src/loragw_fpga.c +++ b/libloragw/src/loragw_fpga.c @@ -130,7 +130,7 @@ float lgw_fpga_get_tx_notch_delay(void) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -int lgw_fpga_configure(uint32_t tx_notch_freq, bool fpga_attn_used) { +int lgw_fpga_configure(uint32_t tx_notch_freq) { int x; int32_t val; bool spectral_scan_support, lbt_support; @@ -175,17 +175,9 @@ int lgw_fpga_configure(uint32_t tx_notch_freq, bool fpga_attn_used) { DEBUG_MSG("ERROR: Failed to configure FPGA polarity\n"); return LGW_REG_ERROR; } - /* Set Attenuator mode to be used or not depending on if a full card with valid conf settings are given*/ + /* Set Attenuator mode to be used for the full card*/ if (fpga_version == 32) { - if (fpga_attn_used == true) { - lgw_reg_w(LGW_FPGA_RF_ATTN_MODE, 0); - printf("INFO: Valid attenuation settings detected. Using Attenuator mode\n"); - } else { - printf("INFO: Valid attenuation settings not detected. Using Legacy mode\n"); - lgw_reg_w(LGW_FPGA_RF_ATTN_MODE, 1); - } - } else { - lgw_reg_w(LGW_FPGA_RF_ATTN_MODE, 1); + lgw_fpga_reg_w(LGW_FPGA_RF_ATTN_MODE, 0); } } @@ -367,4 +359,23 @@ int lgw_fpga_reg_rb(uint16_t register_id, uint8_t *data, uint16_t size) { } } +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int lgw_set_attenuation(float attenuation) { + int i; + int32_t val; + if (attenuation > 31.75 || attenuation < 0) { + return LGW_HAL_ERROR; + } + i = lgw_fpga_reg_w(LGW_FPGA_RF_ATTN_VALUE, (uint8_t)(attenuation * LGW_RF_ATTN_CONV_CONST)); + + i = lgw_fpga_reg_r(LGW_FPGA_RF_ATTN_VALUE, &val); + if (i == LGW_REG_SUCCESS) { + DEBUG_PRINTF("INFO: Attenuator set to %u \n", (uint8_t)val); + return LGW_HAL_SUCCESS; + } else { + return LGW_HAL_ERROR; + } +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c index a835aa3..a891fbf 100644 --- a/libloragw/src/loragw_hal.c +++ b/libloragw/src/loragw_hal.c @@ -136,14 +136,13 @@ static uint64_t fsk_sync_word= 0xC194C1; /* default FSK sync word (ALIGNED RIGHT static bool lorawan_public = false; static uint8_t rf_clkout = 0; -struct lgw_tx_gain_lut_s txgain_lut = { +static struct lgw_tx_gain_lut_s txgain_lut = { .size = 2, .lut[0] = { .dig_gain = 0, .pa_gain = 2, .dac_gain = 3, .mix_gain = 10, - .attenuation = -1.0, .rf_power = 14 }, .lut[1] = { @@ -151,7 +150,6 @@ struct lgw_tx_gain_lut_s txgain_lut = { .pa_gain = 3, .dac_gain = 3, .mix_gain = 14, - .attenuation = -1.0, .rf_power = 27 }}; @@ -681,16 +679,12 @@ int lgw_txgain_setconf(struct lgw_tx_gain_lut_s *conf) { DEBUG_MSG("ERROR: TX gain LUT: External PA gain must not exceed 3\n"); return LGW_HAL_ERROR; } - if (conf->lut[i].attenuation > 31.75) { - DEBUG_MSG("ERROR: TX gain LUT: External Attenuation gain must not exceed 31.75\n"); - return LGW_HAL_ERROR; - } + /* Set internal LUT */ txgain_lut.lut[i].dig_gain = conf->lut[i].dig_gain; txgain_lut.lut[i].dac_gain = conf->lut[i].dac_gain; txgain_lut.lut[i].mix_gain = conf->lut[i].mix_gain; txgain_lut.lut[i].pa_gain = conf->lut[i].pa_gain; - txgain_lut.lut[i].attenuation = conf->lut[i].attenuation; txgain_lut.lut[i].rf_power = conf->lut[i].rf_power; } @@ -716,7 +710,7 @@ int lgw_start(void) { if (lgw_is_started == true) { DEBUG_MSG("Note: LoRa concentrator already started, restarting it now\n"); } - reg_stat = lgw_connect(false, rf_tx_notch_freq[rf_tx_enable[1]?1:0], txgain_lut.lut[0].attenuation > -1.0?true:false); + reg_stat = lgw_connect(false, rf_tx_notch_freq[rf_tx_enable[1]?1:0]); if (reg_stat == LGW_REG_ERROR) { DEBUG_MSG("ERROR: FAIL TO CONNECT BOARD\n"); return LGW_HAL_ERROR; @@ -1419,9 +1413,23 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) { tx_start_delay = lgw_get_tx_start_delay(tx_notch_enable, pkt_data.bandwidth); /* interpretation of TX power */ - for (pow_index = txgain_lut.size-1; pow_index > 0; pow_index--) { - if (txgain_lut.lut[pow_index].rf_power <= pkt_data.rf_power) { - break; + + if (read_fpga_version() == 32) { + for (pow_index = 0; pow_index < txgain_lut.size-1; pow_index++) { + if (txgain_lut.lut[pow_index].rf_power >= pkt_data.rf_power) { + x = lgw_set_attenuation((float)(txgain_lut.lut[pow_index].rf_power - pkt_data.rf_power)); + if (x != LGW_HAL_SUCCESS) { + DEBUG_MSG("ERROR: Failed to set attenuation value\n"); + return LGW_HAL_ERROR; + } + break; + } + } + } else { + for (pow_index = txgain_lut.size-1; pow_index > 0; pow_index--) { + if (txgain_lut.lut[pow_index].rf_power <= pkt_data.rf_power) { + break; + } } } @@ -1438,12 +1446,6 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) { /* Set digital gain from LUT */ lgw_reg_w(LGW_TX_GAIN, txgain_lut.lut[pow_index].dig_gain); - int32_t read_value; - lgw_reg_r(LGW_FPGA_RF_ATTN_MODE, &read_value); - if (read_value == 0) { - lgw_reg_w(LGW_FPGA_RF_ATTN_VALUE, txgain_lut.lut[pow_index].attenuation * 4); - } - /* fixed metadata, useful payload and misc metadata compositing */ transfer_size = TX_METADATA_NB + pkt_data.size; /* */ payload_offset = TX_METADATA_NB; /* start the payload just after the metadata */ diff --git a/libloragw/src/loragw_reg.c b/libloragw/src/loragw_reg.c index e040942..4d689da 100644 --- a/libloragw/src/loragw_reg.c +++ b/libloragw/src/loragw_reg.c @@ -511,7 +511,7 @@ bool check_fpga_version(uint8_t version) { } /* Concentrator connect */ -int lgw_connect(bool spi_only, uint32_t tx_notch_freq, bool fpga_attn_used) { +int lgw_connect(bool spi_only, uint32_t tx_notch_freq) { int spi_stat = LGW_SPI_SUCCESS; uint8_t u = 0; int x; @@ -548,7 +548,7 @@ int lgw_connect(bool spi_only, uint32_t tx_notch_freq, bool fpga_attn_used) { lgw_spi_w(lgw_spi_target, lgw_spi_mux_mode, LGW_SPI_MUX_TARGET_FPGA, 0, 1); lgw_spi_w(lgw_spi_target, lgw_spi_mux_mode, LGW_SPI_MUX_TARGET_FPGA, 0, 0); /* FPGA configure */ - x = lgw_fpga_configure(tx_notch_freq, fpga_attn_used); + x = lgw_fpga_configure(tx_notch_freq); if (x != LGW_REG_SUCCESS) { DEBUG_MSG("ERROR CONFIGURING FPGA\n"); return LGW_REG_ERROR; diff --git a/libloragw/tst/test_loragw_cal.c b/libloragw/tst/test_loragw_cal.c index 067c157..533d189 100644 --- a/libloragw/tst/test_loragw_cal.c +++ b/libloragw/tst/test_loragw_cal.c @@ -263,7 +263,7 @@ int main(int argc, char **argv) printf("Number of calibration iterations: %d\n",nb_cal); printf("Calibration command: brd: %d, chip: %d, dac: %d\n\n", cal_cmd >> 6, 1257-2*((cal_cmd & 0x20) >> 5), 2+((cal_cmd & 0x10) >> 4)); - x = lgw_connect(false, DEFAULT_TX_NOTCH_FREQ, false); + x = lgw_connect(false, DEFAULT_TX_NOTCH_FREQ); if (x == -1) { printf("ERROR: FAIL TO CONNECT BOARD\n"); return -1; diff --git a/libloragw/tst/test_loragw_reg.c b/libloragw/tst/test_loragw_reg.c index 2804d5e..37a6f5a 100644 --- a/libloragw/tst/test_loragw_reg.c +++ b/libloragw/tst/test_loragw_reg.c @@ -37,7 +37,7 @@ int main() printf("Beginning of test for loragw_reg.c\n"); - lgw_connect(false, 129E3, false); + lgw_connect(false, 129E3); /* 2 SPI transactions: -> 0x80 0x00 <- 0x00 0x00 forcing page 0 -> 0x01 0x00 <- 0x00 0x64 checking version diff --git a/util_tx_continuous/src/util_tx_continuous.c b/util_tx_continuous/src/util_tx_continuous.c index 79cf4b4..7768c22 100644 --- a/util_tx_continuous/src/util_tx_continuous.c +++ b/util_tx_continuous/src/util_tx_continuous.c @@ -59,6 +59,7 @@ Maintainer: Matthieu Leurent #define DEFAULT_FDEV_KHZ 25 #define DEFAULT_BT 2 #define DEFAULT_NOTCH_FREQ 129000U +#define DEFAULT_ATTENUATION 0.0 /* -------------------------------------------------------------------------- */ /* --- GLOBAL VARIABLES ----------------------------------------------------- */ @@ -95,6 +96,7 @@ int main(int argc, char **argv) {"fdev", 1, 0, 0}, {"bt", 1, 0, 0}, {"notch", 1, 0, 0}, + {"attn", 1, 0, 0}, {0, 0, 0, 0} }; unsigned int arg_u; @@ -107,6 +109,7 @@ int main(int argc, char **argv) uint8_t g_dac = DEFAULT_DAC_GAIN; uint8_t g_mix = DEFAULT_MIXER_GAIN; uint8_t g_pa = DEFAULT_PA_GAIN; + float g_atten = DEFAULT_ATTENUATION; char mod[64] = DEFAULT_MODULATION; uint8_t sf = DEFAULT_SF; unsigned int bw_khz = DEFAULT_BW_KHZ; @@ -146,6 +149,7 @@ int main(int argc, char **argv) printf(" --br FSK bitrate in kbps, [0.5:250]\n"); printf(" --fdev FSK frequency deviation in kHz, [1:250]\n"); printf(" --bt FSK gaussian filter BT trim, [0:3]\n"); + printf(" --attn Attenuator value in dB, Full Card Only [0.0:31.75]\n"); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); return EXIT_SUCCESS; break; @@ -262,6 +266,16 @@ int main(int argc, char **argv) tx_notch_freq = (uint32_t)arg_u * 1000U; } } + else if (strcmp(long_options[option_index].name,"attn") == 0) { + i = sscanf(optarg, "%f", &arg_f); + if ((i != 1) || (arg_f < 0.0) || (arg_f > 31.75)) { + printf("ERROR: argument parsing of --br argument. Use -h to print help\n"); + return EXIT_FAILURE; + } + else { + g_atten = arg_f; + } + } else { printf("ERROR: argument parsing options. Use -h to print help\n"); return EXIT_FAILURE; @@ -349,6 +363,10 @@ int main(int argc, char **argv) txpkt.tx_mode = IMMEDIATE; txpkt.rf_chain = TX_RF_CHAIN; txpkt.rf_power = 0; + if (read_fpga_version() == 32) { + i = lgw_set_attenuation(g_atten); + } + if (strcmp(mod, "FSK") == 0) { txpkt.modulation = MOD_FSK; txpkt.datarate = br_kbps * 1e3; -- cgit v1.2.3