* Fixed compilation warnings reported by latest versions of GCC
* Reworked handling of temperature sensor
* Clean-up of unused files
* Added instructions and configuration files for packet forwarder auto-start
with systemd
* Added SX1250 radio calibration at startup
This commit is contained in:
Michael Coracin 2019-08-29 15:05:55 +02:00
commit df5cf56b74
25 changed files with 275 additions and 279 deletions

View file

@ -179,8 +179,9 @@ static lgw_context_t lgw_context = {
/* File handle to write debug logs */
FILE * log_file = NULL;
/* File descriptor to I2C linux device */
int lgw_i2c_target = -1;
/* I2C temperature sensor handles */
static int ts_fd = -1;
static uint8_t ts_addr = 0xFF;
/* -------------------------------------------------------------------------- */
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
@ -233,6 +234,7 @@ int lgw_board_setconf(struct lgw_conf_board_s * conf) {
CONTEXT_BOARD.clksrc = conf->clksrc;
CONTEXT_BOARD.full_duplex = conf->full_duplex;
strncpy(CONTEXT_SPI, conf->spidev_path, sizeof CONTEXT_SPI);
CONTEXT_SPI[sizeof CONTEXT_SPI - 1] = '\0'; /* ensure string termination */
DEBUG_PRINTF("Note: board configuration: spidev_path: %s, lorawan_public:%d, clksrc:%d, full_duplex:%d\n", CONTEXT_SPI,
CONTEXT_LWAN_PUBLIC,
@ -555,7 +557,8 @@ int lgw_debug_setconf(struct lgw_conf_debug_s * conf) {
}
if (conf->log_file_name != NULL) {
strncpy(CONTEXT_DEBUG.log_file_name, conf->log_file_name, strlen(conf->log_file_name));
strncpy(CONTEXT_DEBUG.log_file_name, conf->log_file_name, sizeof CONTEXT_DEBUG.log_file_name);
CONTEXT_DEBUG.log_file_name[sizeof CONTEXT_DEBUG.log_file_name - 1] = '\0'; /* ensure string termination */
}
return LGW_HAL_SUCCESS;
@ -564,7 +567,7 @@ int lgw_debug_setconf(struct lgw_conf_debug_s * conf) {
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int lgw_start(void) {
int i, err, err_id_1,err_id_2;
int i, err;
int reg_stat;
if (CONTEXT_STARTED == true) {
@ -713,18 +716,21 @@ int lgw_start(void) {
dbg_init_gpio();
#endif
/* Open I2C */
err_id_1 = i2c_linuxdev_open(I2C_DEVICE, I2C_PORT_TEMP_SENSOR_1, &lgw_i2c_target);
err_id_2 = i2c_linuxdev_open(I2C_DEVICE, I2C_PORT_TEMP_SENSOR_2, &lgw_i2c_target);
if (((err_id_1 != 0) || (lgw_i2c_target <= 0)) && ((err_id_2 != 0) || (lgw_i2c_target <= 0))) {
printf("ERROR: failed to open I2C device %s (err=%i)\n", I2C_DEVICE, err);
return LGW_HAL_ERROR;
}
/* Configure the CoreCell temperature sensor */
if (lgw_stts751_configure() != LGW_I2C_SUCCESS) {
printf("ERROR: failed to configure temperature sensor\n");
return LGW_HAL_ERROR;
/* Try to configure temperature sensor STTS751-0DP3F */
ts_addr = I2C_PORT_TEMP_SENSOR_0;
i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd);
err = stts751_configure(ts_fd, ts_addr);
if (err != LGW_I2C_SUCCESS) {
i2c_linuxdev_close(ts_fd);
ts_fd = -1;
/* Not found, try to configure temperature sensor STTS751-1DP3F */
ts_addr = I2C_PORT_TEMP_SENSOR_1;
i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd);
err = stts751_configure(ts_fd, ts_addr);
if (err != LGW_I2C_SUCCESS) {
printf("ERROR: failed to configure the temperature sensor\n");
return LGW_HAL_ERROR;
}
}
/* set hal state */
@ -753,10 +759,9 @@ int lgw_stop(void) {
lgw_disconnect();
DEBUG_MSG("INFO: Closing I2C\n");
err = i2c_linuxdev_close(lgw_i2c_target);
err = i2c_linuxdev_close(ts_fd);
if (err != 0) {
printf("ERROR: failed to close I2C device (err=%i)\n", err);
/* TODO: return error or not ? */
}
CONTEXT_STARTED = false;
@ -790,7 +795,7 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) {
}
/* Get the current temperature for further RSSI compensation : TODO */
res = lgw_stts751_get_temperature(&current_temperature);
res = stts751_get_temperature(ts_fd, ts_addr, &current_temperature);
if (res != LGW_I2C_SUCCESS) {
printf("ERROR: failed to get current temperature\n");
return LGW_HAL_ERROR;
@ -944,6 +949,8 @@ int lgw_abort_tx(uint8_t rf_chain) {
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int lgw_get_trigcnt(uint32_t* trig_cnt_us) {
CHECK_NULL(trig_cnt_us);
*trig_cnt_us = sx1302_timestamp_counter(true);
return LGW_HAL_SUCCESS;
@ -952,6 +959,8 @@ int lgw_get_trigcnt(uint32_t* trig_cnt_us) {
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int lgw_get_instcnt(uint32_t* inst_cnt_us) {
CHECK_NULL(inst_cnt_us);
*inst_cnt_us = sx1302_timestamp_counter(false);
return LGW_HAL_SUCCESS;
@ -960,6 +969,8 @@ int lgw_get_instcnt(uint32_t* inst_cnt_us) {
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int lgw_get_eui(uint64_t* eui) {
CHECK_NULL(eui);
if (sx1302_get_eui(eui) != LGW_REG_SUCCESS) {
return LGW_HAL_ERROR;
}
@ -968,6 +979,18 @@ int lgw_get_eui(uint64_t* eui) {
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int lgw_get_temperature(float* temperature) {
CHECK_NULL(temperature);
if (stts751_get_temperature(ts_fd, ts_addr, temperature) != LGW_I2C_SUCCESS) {
return LGW_HAL_ERROR;
}
return LGW_HAL_SUCCESS;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
const char* lgw_version_info() {
return lgw_version_string;
}

View file

@ -22,6 +22,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
#include <unistd.h> /* lseek, close */
#include <fcntl.h> /* open */
#include <string.h> /* memset */
#include <errno.h> /* errno */
#include <sys/ioctl.h>
#include <linux/i2c.h>
@ -55,18 +56,18 @@ int i2c_linuxdev_open(const char *path, uint8_t device_addr, int *i2c_fd) {
/* Check input variables */
if (path == NULL) {
DEBUG_MSG("ERROR: null pointer path");
DEBUG_MSG("ERROR: null pointer path\n");
return LGW_I2C_ERROR;
}
if (i2c_fd == NULL) {
DEBUG_MSG("ERROR: null pointer i2c_fd");
DEBUG_MSG("ERROR: null pointer i2c_fd\n");
return LGW_I2C_ERROR;
}
/* Open I2C device */
dev = open(path, O_RDWR);
if (dev < 0) {
DEBUG_PRINTF("ERROR: Failed to open I2C %s - %s", path, strerror(errno));
DEBUG_PRINTF("ERROR: Failed to open I2C %s - %s\n", path, strerror(errno));
return LGW_I2C_ERROR;
}
@ -76,7 +77,7 @@ int i2c_linuxdev_open(const char *path, uint8_t device_addr, int *i2c_fd) {
return LGW_I2C_ERROR;
}
DEBUG_MSG("INFO: I2C port opened successfully");
DEBUG_PRINTF("INFO: I2C port opened successfully (%s, 0x%02X)\n", path, device_addr);
*i2c_fd = dev; /* return file descriptor index */
return LGW_I2C_SUCCESS;
@ -105,7 +106,7 @@ int i2c_linuxdev_read(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_t
packets.nmsgs = 2;
if (ioctl(i2c_fd, I2C_RDWR, &packets) < 0) {
DEBUG_PRINTF("ERROR: Read from I2C Device failed (%d, 0x%02x, 0x%02x) - %s", i2c_fd, device_addr, reg_addr, strerror(errno));
DEBUG_PRINTF("ERROR: Read from I2C Device failed (%d, 0x%02x, 0x%02x) - %s\n", i2c_fd, device_addr, reg_addr, strerror(errno));
return LGW_I2C_ERROR;
}
@ -131,7 +132,7 @@ int i2c_linuxdev_write(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_
packets.nmsgs = 1;
if (ioctl(i2c_fd, I2C_RDWR, &packets) < 0) {
DEBUG_PRINTF("ERROR: Write to I2C Device failed (%d, 0x%02x, 0x%02x) - %s", i2c_fd, device_addr, reg_addr, strerror(errno));
DEBUG_PRINTF("ERROR: Write to I2C Device failed (%d, 0x%02x, 0x%02x) - %s\n", i2c_fd, device_addr, reg_addr, strerror(errno));
return LGW_I2C_ERROR;
}
@ -145,10 +146,10 @@ int i2c_linuxdev_close(int i2c_fd) {
i = close(i2c_fd);
if (i == 0) {
DEBUG_MSG("INFO: I2C port closed successfully");
DEBUG_MSG("INFO: I2C port closed successfully\n");
return LGW_I2C_SUCCESS;
} else {
DEBUG_PRINTF("ERROR: Failed to close I2C - %s", strerror(errno));
DEBUG_PRINTF("ERROR: Failed to close I2C - %s\n", strerror(errno));
return LGW_I2C_ERROR;
}
}

View file

@ -74,49 +74,31 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
/* -------------------------------------------------------------------------- */
/* --- INTERNAL SHARED VARIABLES -------------------------------------------- */
extern int lgw_i2c_target;
uint8_t slave_addr;
/* -------------------------------------------------------------------------- */
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
int stts751_configure( int i2c_fd )
{
int err,err_1,err_2;
/* -------------------------------------------------------------------------- */
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
int stts751_configure(int i2c_fd, uint8_t i2c_addr) {
int err;
uint8_t val;
/* Check Input Params */
if( i2c_fd <= 0 )
{
printf( "ERROR: invalid I2C file descriptor\n" );
if (i2c_fd <= 0) {
printf("ERROR: invalid I2C file descriptor\n");
return LGW_I2C_ERROR;
}
DEBUG_MSG("INFO: configuring STTS751 temperature sensor...\n");
DEBUG_PRINTF("INFO: configuring STTS751 temperature sensor on 0x%02X...\n", i2c_addr);
/* Get product ID and test which sensor is mounted */
err_1 = i2c_linuxdev_read( i2c_fd, I2C_PORT_TEMP_SENSOR_1, STTS751_REG_PROD_ID, &val );
err_2 = i2c_linuxdev_read( i2c_fd, I2C_PORT_TEMP_SENSOR_2, STTS751_REG_PROD_ID, &val );
if ( (err_1 != 0) && (err_2 != 0) )
{
printf( "ERROR: failed to read I2C device 0x%02X (err=%i) or 0x%02X (err=%i) \n", I2C_PORT_TEMP_SENSOR_1, err_1, I2C_PORT_TEMP_SENSOR_2, err_2 );
err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_PROD_ID, &val);
if (err != 0) {
DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
return LGW_I2C_ERROR;
}
else
{
if ( err_1 == 0 )
{
slave_addr = I2C_PORT_TEMP_SENSOR_1;
}
if( err_2 == 0 )
{
slave_addr = I2C_PORT_TEMP_SENSOR_2;
}
}
switch( val )
{
switch (val) {
case STTS751_0_PROD_ID:
DEBUG_MSG("INFO: Product ID: STTS751-0\n");
break;
@ -129,44 +111,37 @@ int stts751_configure( int i2c_fd )
}
/* Get Manufacturer ID */
err = i2c_linuxdev_read( i2c_fd, slave_addr, STTS751_REG_MAN_ID, &val );
if ( err != 0 )
{
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", slave_addr, err );
err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_MAN_ID, &val);
if (err != 0) {
DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
return LGW_I2C_ERROR;
}
if ( val != ST_MAN_ID )
{
printf( "ERROR: Manufacturer ID: UNKNOWN\n" );
if (val != ST_MAN_ID) {
printf("ERROR: Manufacturer ID: UNKNOWN\n");
return LGW_I2C_ERROR;
}
else
{
} else {
DEBUG_PRINTF("INFO: Manufacturer ID: 0x%02X\n", val);
}
/* Get revision number */
err = i2c_linuxdev_read( i2c_fd, slave_addr, STTS751_REG_REV_ID, &val );
if ( err != 0 )
{
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", slave_addr, err );
err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_REV_ID, &val);
if (err != 0) {
DEBUG_PRINTF("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
return LGW_I2C_ERROR;
}
DEBUG_PRINTF("INFO: Revision number: 0x%02X\n", val);
/* Set conversion resolution to 12 bits */
err = i2c_linuxdev_write( i2c_fd, slave_addr, STTS751_REG_CONF, 0x8C ); /* TODO: do not hardcode the whole byte */
if ( err != 0 )
{
printf( "ERROR: failed to write I2C device 0x%02X (err=%i)\n", slave_addr, err );
err = i2c_linuxdev_write(i2c_fd, i2c_addr, STTS751_REG_CONF, 0x8C); /* TODO: do not hardcode the whole byte */
if (err != 0) {
DEBUG_PRINTF("ERROR: failed to write I2C device 0x%02X (err=%i)\n", i2c_addr, err);
return LGW_I2C_ERROR;
}
/* Set conversion rate to 1 / second */
err = i2c_linuxdev_write( i2c_fd, slave_addr, STTS751_REG_RATE, 0x04 );
if ( err != 0 )
{
printf( "ERROR: failed to write I2C device 0x%02X (err=%i)\n", slave_addr, err );
err = i2c_linuxdev_write(i2c_fd, i2c_addr, STTS751_REG_RATE, 0x04);
if (err != 0) {
DEBUG_PRINTF("ERROR: failed to write I2C device 0x%02X (err=%i)\n", i2c_addr, err);
return LGW_I2C_ERROR;
}
@ -175,54 +150,37 @@ int stts751_configure( int i2c_fd )
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int stts751_get_temperature( int i2c_fd, float * temperature)
{
int stts751_get_temperature(int i2c_fd, uint8_t i2c_addr, float * temperature) {
int err;
uint8_t high_byte, low_byte;
int8_t h;
/* Check Input Params */
if( i2c_fd <= 0 )
{
printf( "ERROR: invalid I2C file descriptor\n" );
if (i2c_fd <= 0) {
printf("ERROR: invalid I2C file descriptor\n");
return LGW_I2C_ERROR;
}
/* Read Temperature LSB */
err = i2c_linuxdev_read( i2c_fd, slave_addr, STTS751_REG_TEMP_L, &low_byte );
if ( err != 0 )
{
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", slave_addr, err );
err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_TEMP_L, &low_byte);
if (err != 0) {
printf("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
return LGW_I2C_ERROR;
}
/* Read Temperature MSB */
err = i2c_linuxdev_read( i2c_fd, slave_addr, STTS751_REG_TEMP_H, &high_byte );
if ( err != 0 )
{
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", slave_addr, err );
err = i2c_linuxdev_read(i2c_fd, i2c_addr, STTS751_REG_TEMP_H, &high_byte);
if (err != 0) {
printf("ERROR: failed to read I2C device 0x%02X (err=%i)\n", i2c_addr, err);
return LGW_I2C_ERROR;
}
h = (int8_t)high_byte;
*temperature = ((h << 8) | low_byte) / 256.0;
*temperature = ((h << 8) | low_byte) / 256.0;
DEBUG_PRINTF("Temperature: %f C (h:0x%02X l:0x%02X)\n", *temperature, high_byte, low_byte);
return LGW_I2C_SUCCESS;
}
/* -------------------------------------------------------------------------- */
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
int lgw_stts751_configure(void) {
return stts751_configure(lgw_i2c_target);
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int lgw_stts751_get_temperature(float * temperature) {
return stts751_get_temperature(lgw_i2c_target, temperature);
}
/* --- EOF ------------------------------------------------------------------ */

View file

@ -202,13 +202,36 @@ int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz) {
int32_t freq_reg;
uint8_t buff[16];
/* Set Radio in Standby mode */
/* Set Radio in Standby for calibrations */
buff[0] = (uint8_t)STDBY_RC;
sx1250_write_command(rf_chain, SET_STANDBY, buff, 1);
wait_ms(10);
/* Get status to check Standby mode has been properly set */
buff[0] = 0x00;
sx1250_read_command(rf_chain, GET_STATUS, buff, 1);
if ((uint8_t)(TAKE_N_BITS_FROM(buff[0], 4, 3)) != 0x02) {
printf("ERROR: Failed to set SX1250_%u in STANDBY_RC mode\n", rf_chain);
return -1;
}
/* Run all calibrations (TCXO) */
buff[0] = 0x7F;
sx1250_write_command(rf_chain, CALIBRATE, buff, 1);
wait_ms(10);
/* Set Radio in Standby with XOSC ON */
buff[0] = (uint8_t)STDBY_XOSC;
sx1250_write_command(rf_chain, SET_STANDBY, buff, 1);
wait_ms(10);
/* Get status to check Standby mode has been properly set */
buff[0] = 0x00;
sx1250_read_command(rf_chain, GET_STATUS, buff, 1);
if ((uint8_t)(TAKE_N_BITS_FROM(buff[0], 4, 3)) != 0x03) {
printf("ERROR: Failed to set SX1250_%u in STANDBY_XOSC mode\n", rf_chain);
return -1;
}
/* Set Bitrate to maximum (to lower TX to FS switch time) */
buff[0] = 0x06;

View file

@ -734,13 +734,8 @@ int sx1302_lora_modem_configure(uint32_t radio_freq_hz) {
lgw_reg_w(SX1302_REG_OTP_MODEM_EN_0_MODEM_EN, 0xFF);
/* Enable limited modems */
#if FPGA_BOARD_16_CH
DEBUG_MSG("Configuring 8 limited-SF modems\n");
lgw_reg_w(SX1302_REG_OTP_MODEM_EN_1_MODEM_EN, 0xFF);
#else
DEBUG_MSG("Configuring 4 limited-SF modems\n");
lgw_reg_w(SX1302_REG_OTP_MODEM_EN_1_MODEM_EN, 0x0F);
#endif
/* Configure coarse sync between correlators and modems */
lgw_reg_w(SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_MSB_MODEM_SYNC_DELTA, 0);
@ -981,11 +976,6 @@ int sx1302_agc_load_firmware(const uint8_t *firmware) {
return -1;
}
#if BYPASS_FW_INIT
printf("Disable AGC init protocol\n");
sx1302_agc_mailbox_write(2, 0xF7); /* To be done before fw starts */
#endif
/* Release control over AGC MCU */
lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_HOST_PROG, 0x00);
lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_MCU_CLEAR, 0x00);
@ -1090,11 +1080,6 @@ int sx1302_agc_start(uint8_t version, lgw_radio_type_t radio_type, uint8_t ana_g
}
DEBUG_PRINTF("AGC FW VERSION: %d\n", val);
#if BYPASS_FW_INIT
printf("Bypass AGC init protocol\n");
return 0;
#endif
/* Configure Radio A gains */
sx1302_agc_mailbox_write(0, ana_gain); /* 0:auto agc*/
sx1302_agc_mailbox_write(1, dec_gain);
@ -1396,11 +1381,6 @@ int sx1302_arb_load_firmware(const uint8_t *firmware) {
return -1;
}
#if BYPASS_FW_INIT
printf("Disable ARB init protocol\n");
sx1302_arb_debug_write(2, 0xF7); /* To be done before fw starts */
#endif
/* Release control over ARB MCU */
lgw_reg_w(SX1302_REG_ARB_MCU_CTRL_HOST_PROG, 0x00);
lgw_reg_w(SX1302_REG_ARB_MCU_CTRL_MCU_CLEAR, 0x00);
@ -1568,11 +1548,6 @@ int sx1302_arb_start(uint8_t version) {
}
DEBUG_PRINTF("ARB FW VERSION: %d\n", val);
#if BYPASS_FW_INIT
printf("Bypass ARB init protocol\n");
return 0;
#endif
/* Enable/disable ARB detect/modem alloc stats for the specified SF */
sx1302_arb_set_debug_stats(true, DR_LORA_SF7);
@ -2106,7 +2081,6 @@ int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut,
mod_bw = pkt_data->bandwidth;
break;
case MOD_CW:
/* Intended fall-through */
case MOD_FSK:
mod_bw = (0x01 << 7) | pkt_data->bandwidth;
break;

View file

@ -81,15 +81,9 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
#define SX1302_PKT_TAIL_METADATA 14
/* modem IDs */
#if FPGA_BOARD_16_CH
#define SX1302_LORA_MODEM_ID_MAX 15
#define SX1302_LORA_STD_MODEM_ID 16
#define SX1302_FSK_MODEM_ID 17
#else
#define SX1302_LORA_MODEM_ID_MAX 11
#define SX1302_LORA_STD_MODEM_ID 12
#define SX1302_FSK_MODEM_ID 13
#endif
/* -------------------------------------------------------------------------- */
/* --- PRIVATE VARIABLES ---------------------------------------------------- */