diff --git a/.github/workflows/compile-docker.yml b/.github/workflows/compile-docker.yml new file mode 100644 index 00000000..422d852a --- /dev/null +++ b/.github/workflows/compile-docker.yml @@ -0,0 +1,52 @@ +name: Compile Docker Images + +on: [push] + +jobs: + main: + runs-on: ubuntu-20.04 + permissions: + packages: write + contents: read + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Log in to the Container registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v3 + with: + images: | + nebraltd/sx1302_hal + ghcr.io/${{ github.repository }} + flavor: | + latest=true + tags: | + type=sha,prefix= + type=sha,format=long,prefix= + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + push: true + labels: ${{ steps.meta.outputs.labels }} + tags: ${{ steps.meta.outputs.tags }} + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..8c6a2eda --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM balenalib/raspberry-pi-debian:buster-build as sx1302-hal-builder + +ENV ROOT_DIR=/opt + +WORKDIR "$ROOT_DIR" + +# Copy upstream source into expected location +COPY . "$ROOT_DIR" + +RUN . "$ROOT_DIR/compile.sh" diff --git a/compile.sh b/compile.sh new file mode 100644 index 00000000..0fbc887f --- /dev/null +++ b/compile.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +make clean +make -j 4 diff --git a/libloragw/Makefile b/libloragw/Makefile index 881442fa..d3fa1e15 100644 --- a/libloragw/Makefile +++ b/libloragw/Makefile @@ -123,11 +123,9 @@ libloragw.a: $(OBJDIR)/loragw_spi.o \ $(OBJDIR)/loragw_debug.o \ $(OBJDIR)/loragw_hal.o \ $(OBJDIR)/loragw_lbt.o \ - $(OBJDIR)/loragw_stts751.o \ $(OBJDIR)/loragw_gps.o \ $(OBJDIR)/loragw_sx1302_timestamp.o \ - $(OBJDIR)/loragw_sx1302_rx.o \ - $(OBJDIR)/loragw_ad5338r.o + $(OBJDIR)/loragw_sx1302_rx.o $(AR) rcs $@ $^ ### test programs diff --git a/libloragw/inc/loragw_ad5338r.h b/libloragw/inc/loragw_ad5338r.h deleted file mode 100644 index aaecda58..00000000 --- a/libloragw/inc/loragw_ad5338r.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2020 Semtech - -Description: - Basic driver for Analog AD5338R DAC. - -License: Revised BSD License, see LICENSE.TXT file include in the project -*/ - - -#ifndef _LORAGW_AD5338R_H -#define _LORAGW_AD5338R_H - -#include /* C99 types */ -#include /* bool type */ - -#include "config.h" /* library configuration options (dynamically generated) */ - -/* -------------------------------------------------------------------------- */ -/* --- PRIVATE MACROS ------------------------------------------------------- */ - -#define VOLTAGE2HEX_H(a) ( (a)*1024/5/4 ) -#define VOLTAGE2HEX_L(a) ( (((int)((a)*1024/5)) & 0x3) * 64 ) - -/* -------------------------------------------------------------------------- */ -/* --- PRIVATE CONSTANTS ---------------------------------------------------- */ - -#define I2C_PORT_DAC_AD5338R 0x0C - -#define AD5338R_CMD_SIZE 3 - -/* -------------------------------------------------------------------------- */ -/* --- PUBLIC FUNCTIONS ----------------------------------------------------- */ - -int ad5338r_configure(int i2c_fd, uint8_t i2c_addr); -int ad5338r_write(int i2c_fd, uint8_t i2c_addr, uint8_t buf[static AD5338R_CMD_SIZE]); - -#endif diff --git a/libloragw/inc/loragw_stts751.h b/libloragw/inc/loragw_stts751.h deleted file mode 100644 index d7a2dcf2..00000000 --- a/libloragw/inc/loragw_stts751.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2019 Semtech - -Description: - Basic driver for ST ts751 temperature sensor - -License: Revised BSD License, see LICENSE.TXT file include in the project -*/ - - -#ifndef _LORAGW_STTS751_H -#define _LORAGW_STTS751_H - -/* -------------------------------------------------------------------------- */ -/* --- DEPENDANCIES --------------------------------------------------------- */ - -#include /* C99 types */ -#include /* bool type */ - -#include "config.h" /* library configuration options (dynamically generated) */ - -/* -------------------------------------------------------------------------- */ -/* --- INTERNAL SHARED TYPES ------------------------------------------------ */ - -/* -------------------------------------------------------------------------- */ -/* --- INTERNAL SHARED FUNCTIONS -------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -/* --- PUBLIC CONSTANTS ----------------------------------------------------- */ - -/* - 0x39: STTS751-0DP3F - 0x3B: STTS751-1DP3F - 0x38: STTS751-0DP3F on full duplex CN490 ref design - */ -static const uint8_t I2C_PORT_TEMP_SENSOR[] = {0x39, 0x3B, 0x38}; - -/* -------------------------------------------------------------------------- */ -/* --- PUBLIC FUNCTIONS ----------------------------------------------------- */ - -/** -@brief Configure the temperature sensor (ST TS751) -@param i2c_fd file descriptor to access the sensor through I2C -@param i2c_addr the I2C device address of the sensor -@return LGW_I2C_ERROR if fails, LGW_I2C_SUCCESS otherwise -*/ -int stts751_configure(int i2c_fd, uint8_t i2c_addr); - -/** -@brief Get the temperature from the sensor -@param i2c_fd file descriptor to access the sensor through I2C -@param i2c_addr the I2C device address of the sensor -@param temperature pointer to store the temerature read from sensor -@return LGW_I2C_ERROR if fails, LGW_I2C_SUCCESS otherwise -*/ -int stts751_get_temperature(int i2c_fd, uint8_t i2c_addr, float * temperature); - -#endif - -/* --- EOF ------------------------------------------------------------------ */ diff --git a/libloragw/src/loragw_ad5338r.c b/libloragw/src/loragw_ad5338r.c deleted file mode 100644 index ea085130..00000000 --- a/libloragw/src/loragw_ad5338r.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2020 Semtech - -Description: - Basic driver for Analog AD5338R DAC. - -License: Revised BSD License, see LICENSE.TXT file include in the project -*/ - -#include /* C99 types */ -#include /* bool type */ -#include /* printf fprintf */ - -#include "loragw_i2c.h" -#include "loragw_ad5338r.h" - -/* -------------------------------------------------------------------------- */ -/* --- PRIVATE MACROS ------------------------------------------------------- */ - -#if DEBUG_I2C == 1 - #define DEBUG_MSG(str) fprintf(stdout, str) - #define DEBUG_PRINTF(fmt, args...) fprintf(stdout,"%s:%d: "fmt, __FUNCTION__, __LINE__, args) - #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_I2C_ERROR;} -#else - #define DEBUG_MSG(str) - #define DEBUG_PRINTF(fmt, args...) - #define CHECK_NULL(a) if(a==NULL){return LGW_I2C_ERROR;} -#endif - -/* -------------------------------------------------------------------------- */ -/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */ - -int ad5338r_configure(int i2c_fd, uint8_t i2c_addr) { - int err; - uint8_t cmd_soft_reset[AD5338R_CMD_SIZE] = {0x69, 0x00, 0x00}; - uint8_t cmd_power_up_dn[AD5338R_CMD_SIZE] = {0x40, 0x00, 0x00}; - uint8_t cmd_internal_ref[AD5338R_CMD_SIZE] = {0x70, 0x00, 0x00}; - - /* Check Input Params */ - if (i2c_fd <= 0) { - printf("ERROR: invalid I2C file descriptor\n"); - return LGW_I2C_ERROR; - } - - DEBUG_PRINTF("INFO: configuring AD5338R DAC on 0x%02X...\n", i2c_addr); - - /* Sofwtare reset of DAC A & B */ - /* TODO: LSB data bytes seems not acknoledged by AD5338R, leading to an error if sent. - Only send MSB data byte */ - err = i2c_linuxdev_write(i2c_fd, i2c_addr, cmd_soft_reset[0], cmd_soft_reset[1]); - if (err != 0) { - printf("ERROR: AD5338R software reset failed\n"); - return LGW_I2C_ERROR; - } - - /* Normal operation */ - err = ad5338r_write(i2c_fd, i2c_addr, cmd_power_up_dn); - if (err != 0) { - printf("ERROR: AD5338R failed to set to normal operation\n"); - return LGW_I2C_ERROR; - } - - /* Internal reference ON */ - err = ad5338r_write(i2c_fd, i2c_addr, cmd_internal_ref); - if (err != 0) { - printf("ERROR: AD5338R failed to set internal reference ON\n"); - return LGW_I2C_ERROR; - } - - printf("INFO: AD5338R is configured\n"); - - return LGW_I2C_SUCCESS; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int ad5338r_write(int i2c_fd, uint8_t i2c_addr, uint8_t buf[static AD5338R_CMD_SIZE]) { - int err; - - /* Write AD5338R command buffer */ - err = i2c_linuxdev_write_buffer(i2c_fd, i2c_addr, buf, AD5338R_CMD_SIZE); - if (err != 0) { - printf("ERROR: failed to write AD5338R command\n"); - return LGW_I2C_ERROR; - } - - return LGW_I2C_SUCCESS; -} diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c index ffc8ec0f..21bee7b0 100644 --- a/libloragw/src/loragw_hal.c +++ b/libloragw/src/loragw_hal.c @@ -44,8 +44,8 @@ License: Revised BSD License, see LICENSE.TXT file include in the project #include "loragw_sx1261.h" #include "loragw_sx1302.h" #include "loragw_sx1302_timestamp.h" -#include "loragw_stts751.h" -#include "loragw_ad5338r.h" +// #include "loragw_stts751.h" +// #include "loragw_ad5338r.h" #include "loragw_debug.h" /* -------------------------------------------------------------------------- */ @@ -203,11 +203,11 @@ static lgw_context_t lgw_context = { FILE * log_file = NULL; /* I2C temperature sensor handles */ -static int ts_fd = -1; -static uint8_t ts_addr = 0xFF; +// static int ts_fd = -1; +// static uint8_t ts_addr = 0xFF; /* I2C AD5338 handles */ -static int ad_fd = -1; +// static int ad_fd = -1; /* -------------------------------------------------------------------------- */ /* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */ @@ -1092,57 +1092,57 @@ int lgw_start(void) { /* Configure the pseudo-random generator (For Debug) */ dbg_init_random(); - if (CONTEXT_COM_TYPE == LGW_COM_SPI) { - /* Find the temperature sensor on the known supported ports */ - for (i = 0; i < (int)(sizeof I2C_PORT_TEMP_SENSOR); i++) { - ts_addr = I2C_PORT_TEMP_SENSOR[i]; - err = i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd); - if (err != LGW_I2C_SUCCESS) { - printf("ERROR: failed to open I2C for temperature sensor on port 0x%02X\n", ts_addr); - return LGW_HAL_ERROR; - } - - err = stts751_configure(ts_fd, ts_addr); - if (err != LGW_I2C_SUCCESS) { - printf("INFO: no temperature sensor found on port 0x%02X\n", ts_addr); - i2c_linuxdev_close(ts_fd); - ts_fd = -1; - } else { - printf("INFO: found temperature sensor on port 0x%02X\n", ts_addr); - break; - } - } - if (i == sizeof I2C_PORT_TEMP_SENSOR) { - printf("ERROR: no temperature sensor found.\n"); - return LGW_HAL_ERROR; - } - - /* Configure ADC AD338R for full duplex (CN490 reference design) */ - if (CONTEXT_BOARD.full_duplex == true) { - err = i2c_linuxdev_open(I2C_DEVICE, I2C_PORT_DAC_AD5338R, &ad_fd); - if (err != LGW_I2C_SUCCESS) { - printf("ERROR: failed to open I2C for ad5338r\n"); - return LGW_HAL_ERROR; - } - - err = ad5338r_configure(ad_fd, I2C_PORT_DAC_AD5338R); - if (err != LGW_I2C_SUCCESS) { - printf("ERROR: failed to configure ad5338r\n"); - i2c_linuxdev_close(ad_fd); - ad_fd = -1; - return LGW_HAL_ERROR; - } - - /* Turn off the PA: set DAC output to 0V */ - uint8_t volt_val[AD5338R_CMD_SIZE] = { 0x39, (uint8_t)VOLTAGE2HEX_H(0), (uint8_t)VOLTAGE2HEX_L(0) }; - err = ad5338r_write(ad_fd, I2C_PORT_DAC_AD5338R, volt_val); - if (err != LGW_I2C_SUCCESS) { - printf("ERROR: AD5338R: failed to set DAC output to 0V\n"); - return LGW_HAL_ERROR; - } - printf("INFO: AD5338R: Set DAC output to 0x%02X 0x%02X\n", (uint8_t)VOLTAGE2HEX_H(0), (uint8_t)VOLTAGE2HEX_L(0)); - } - } +// if (CONTEXT_COM_TYPE == LGW_COM_SPI) { +// /* Find the temperature sensor on the known supported ports */ +// for (i = 0; i < (int)(sizeof I2C_PORT_TEMP_SENSOR); i++) { +// ts_addr = I2C_PORT_TEMP_SENSOR[i]; +// err = i2c_linuxdev_open(I2C_DEVICE, ts_addr, &ts_fd); +// if (err != LGW_I2C_SUCCESS) { +// printf("ERROR: failed to open I2C for temperature sensor on port 0x%02X\n", ts_addr); +// return LGW_HAL_ERROR; +// } +// +// err = stts751_configure(ts_fd, ts_addr); +// if (err != LGW_I2C_SUCCESS) { +// printf("INFO: no temperature sensor found on port 0x%02X\n", ts_addr); +// i2c_linuxdev_close(ts_fd); +// ts_fd = -1; +// } else { +// printf("INFO: found temperature sensor on port 0x%02X\n", ts_addr); +// break; +// } +// } +// if (i == sizeof I2C_PORT_TEMP_SENSOR) { +// printf("ERROR: no temperature sensor found.\n"); +// return LGW_HAL_ERROR; +// } +// +// /* Configure ADC AD338R for full duplex (CN490 reference design) */ +// if (CONTEXT_BOARD.full_duplex == true) { +// err = i2c_linuxdev_open(I2C_DEVICE, I2C_PORT_DAC_AD5338R, &ad_fd); +// if (err != LGW_I2C_SUCCESS) { +// printf("ERROR: failed to open I2C for ad5338r\n"); +// return LGW_HAL_ERROR; +// } +// +// err = ad5338r_configure(ad_fd, I2C_PORT_DAC_AD5338R); +// if (err != LGW_I2C_SUCCESS) { +// printf("ERROR: failed to configure ad5338r\n"); +// i2c_linuxdev_close(ad_fd); +// ad_fd = -1; +// return LGW_HAL_ERROR; +// } +// +// /* Turn off the PA: set DAC output to 0V */ +// uint8_t volt_val[AD5338R_CMD_SIZE] = { 0x39, (uint8_t)VOLTAGE2HEX_H(0), (uint8_t)VOLTAGE2HEX_L(0) }; +// err = ad5338r_write(ad_fd, I2C_PORT_DAC_AD5338R, volt_val); +// if (err != LGW_I2C_SUCCESS) { +// printf("ERROR: AD5338R: failed to set DAC output to 0V\n"); +// return LGW_HAL_ERROR; +// } +// printf("INFO: AD5338R: Set DAC output to 0x%02X 0x%02X\n", (uint8_t)VOLTAGE2HEX_H(0), (uint8_t)VOLTAGE2HEX_L(0)); +// } +// } /* Connect to the external sx1261 for LBT or Spectral Scan */ if (CONTEXT_SX1261.enable == true) { @@ -1221,23 +1221,23 @@ int lgw_stop(void) { err = LGW_HAL_ERROR; } - if (CONTEXT_COM_TYPE == LGW_COM_SPI) { - DEBUG_MSG("INFO: Closing I2C for temperature sensor\n"); - x = i2c_linuxdev_close(ts_fd); - if (x != 0) { - printf("ERROR: failed to close I2C temperature sensor device (err=%i)\n", x); - err = LGW_HAL_ERROR; - } - - if (CONTEXT_BOARD.full_duplex == true) { - DEBUG_MSG("INFO: Closing I2C for AD5338R\n"); - x = i2c_linuxdev_close(ad_fd); - if (x != 0) { - printf("ERROR: failed to close I2C AD5338R device (err=%i)\n", x); - err = LGW_HAL_ERROR; - } - } - } +// if (CONTEXT_COM_TYPE == LGW_COM_SPI) { +// DEBUG_MSG("INFO: Closing I2C for temperature sensor\n"); +// x = i2c_linuxdev_close(ts_fd); +// if (x != 0) { +// printf("ERROR: failed to close I2C temperature sensor device (err=%i)\n", x); +// err = LGW_HAL_ERROR; +// } +// +// if (CONTEXT_BOARD.full_duplex == true) { +// DEBUG_MSG("INFO: Closing I2C for AD5338R\n"); +// x = i2c_linuxdev_close(ad_fd); +// if (x != 0) { +// printf("ERROR: failed to close I2C AD5338R device (err=%i)\n", x); +// err = LGW_HAL_ERROR; +// } +// } +// } CONTEXT_STARTED = false; @@ -1253,7 +1253,8 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { uint8_t nb_pkt_fetched = 0; uint8_t nb_pkt_found = 0; uint8_t nb_pkt_left = 0; - float current_temperature = 0.0, rssi_temperature_offset = 0.0; + float current_temperature = 30.0; + float rssi_temperature_offset; /* performances variables */ struct timeval tm; @@ -1287,11 +1288,11 @@ int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data) { } /* Apply RSSI temperature compensation */ - res = lgw_get_temperature(¤t_temperature); - if (res != LGW_I2C_SUCCESS) { - printf("ERROR: failed to get current temperature\n"); - return LGW_HAL_ERROR; - } +// res = lgw_get_temperature(¤t_temperature); +// if (res != LGW_I2C_SUCCESS) { +// printf("ERROR: failed to get current temperature\n"); +// return LGW_HAL_ERROR; +// } /* Iterate on the RX buffer to get parsed packets */ for (nb_pkt_found = 0; nb_pkt_found < ((nb_pkt_fetched <= max_pkt) ? nb_pkt_fetched : max_pkt); nb_pkt_found++) { @@ -1412,15 +1413,15 @@ int lgw_send(struct lgw_pkt_tx_s * pkt_data) { } /* Set PA gain with AD5338R when using full duplex CN490 ref design */ - if (CONTEXT_BOARD.full_duplex == true) { - uint8_t volt_val[AD5338R_CMD_SIZE] = {0x39, VOLTAGE2HEX_H(2.51), VOLTAGE2HEX_L(2.51)}; /* set to 2.51V */ - err = ad5338r_write(ad_fd, I2C_PORT_DAC_AD5338R, volt_val); - if (err != LGW_I2C_SUCCESS) { - printf("ERROR: failed to set voltage by ad5338r\n"); - return LGW_HAL_ERROR; - } - printf("INFO: AD5338R: Set DAC output to 0x%02X 0x%02X\n", (uint8_t)VOLTAGE2HEX_H(2.51), (uint8_t)VOLTAGE2HEX_L(2.51)); - } +// if (CONTEXT_BOARD.full_duplex == true) { +// uint8_t volt_val[AD5338R_CMD_SIZE] = {0x39, VOLTAGE2HEX_H(2.51), VOLTAGE2HEX_L(2.51)}; /* set to 2.51V */ +// err = ad5338r_write(ad_fd, I2C_PORT_DAC_AD5338R, volt_val); +// if (err != LGW_I2C_SUCCESS) { +// printf("ERROR: failed to set voltage by ad5338r\n"); +// return LGW_HAL_ERROR; +// } +// printf("INFO: AD5338R: Set DAC output to 0x%02X 0x%02X\n", (uint8_t)VOLTAGE2HEX_H(2.51), (uint8_t)VOLTAGE2HEX_L(2.51)); +// } /* Start Listen-Before-Talk */ if (CONTEXT_SX1261.lbt_conf.enable == true) { @@ -1589,27 +1590,28 @@ int lgw_get_eui(uint64_t* eui) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ int lgw_get_temperature(float* temperature) { - int err = LGW_HAL_ERROR; +// int err = LGW_HAL_ERROR; - DEBUG_PRINTF(" --- %s\n", "IN"); +// DEBUG_PRINTF(" --- %s\n", "IN"); CHECK_NULL(temperature); - - switch (CONTEXT_COM_TYPE) { - case LGW_COM_SPI: - err = stts751_get_temperature(ts_fd, ts_addr, temperature); - break; - case LGW_COM_USB: - err = lgw_com_get_temperature(temperature); - break; - default: - printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__); - break; - } - - DEBUG_PRINTF(" --- %s\n", "OUT"); - - return err; + *temperature = 30.0; + return LGW_HAL_SUCCESS; +// switch (CONTEXT_COM_TYPE) { +// case LGW_COM_SPI: +// err = stts751_get_temperature(ts_fd, ts_addr, temperature); +// break; +// case LGW_COM_USB: +// err = lgw_com_get_temperature(temperature); +// break; +// default: +// printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__); +// break; +// } +// +// DEBUG_PRINTF(" --- %s\n", "OUT"); +// +// return err; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ diff --git a/libloragw/src/loragw_stts751.c b/libloragw/src/loragw_stts751.c deleted file mode 100644 index 7766961c..00000000 --- a/libloragw/src/loragw_stts751.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2019 Semtech - -Description: - Basic driver for ST ts751 temperature sensor - -License: Revised BSD License, see LICENSE.TXT file include in the project -*/ - - -/* -------------------------------------------------------------------------- */ -/* --- DEPENDANCIES --------------------------------------------------------- */ - -#include /* C99 types */ -#include /* bool type */ -#include /* printf fprintf */ - -#include "loragw_i2c.h" -#include "loragw_stts751.h" - -/* -------------------------------------------------------------------------- */ -/* --- PRIVATE MACROS ------------------------------------------------------- */ - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -#if DEBUG_I2C == 1 - #define DEBUG_MSG(str) fprintf(stdout, str) - #define DEBUG_PRINTF(fmt, args...) fprintf(stdout,"%s:%d: "fmt, __FUNCTION__, __LINE__, args) - #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;} -#else - #define DEBUG_MSG(str) - #define DEBUG_PRINTF(fmt, args...) - #define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;} -#endif - -/* -------------------------------------------------------------------------- */ -/* --- PRIVATE CONSTANTS ---------------------------------------------------- */ - -#define STTS751_REG_TEMP_H 0x00 -#define STTS751_REG_STATUS 0x01 -#define STTS751_STATUS_TRIPT BIT(0) -#define STTS751_STATUS_TRIPL BIT(5) -#define STTS751_STATUS_TRIPH BIT(6) -#define STTS751_REG_TEMP_L 0x02 -#define STTS751_REG_CONF 0x03 -#define STTS751_CONF_RES_MASK 0x0C -#define STTS751_CONF_RES_SHIFT 2 -#define STTS751_CONF_EVENT_DIS BIT(7) -#define STTS751_CONF_STOP BIT(6) -#define STTS751_REG_RATE 0x04 -#define STTS751_REG_HLIM_H 0x05 -#define STTS751_REG_HLIM_L 0x06 -#define STTS751_REG_LLIM_H 0x07 -#define STTS751_REG_LLIM_L 0x08 -#define STTS751_REG_TLIM 0x20 -#define STTS751_REG_HYST 0x21 -#define STTS751_REG_SMBUS_TO 0x22 - -#define STTS751_REG_PROD_ID 0xFD -#define STTS751_REG_MAN_ID 0xFE -#define STTS751_REG_REV_ID 0xFF - -#define STTS751_0_PROD_ID 0x00 -#define STTS751_1_PROD_ID 0x01 -#define ST_MAN_ID 0x53 - -/* -------------------------------------------------------------------------- */ -/* --- PRIVATE VARIABLES ---------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */ - -/* -------------------------------------------------------------------------- */ -/* --- 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"); - return LGW_I2C_ERROR; - } - - DEBUG_PRINTF("INFO: configuring STTS751 temperature sensor on 0x%02X...\n", i2c_addr); - - /* Get product ID and test which sensor is mounted */ - 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; - } - switch (val) { - case STTS751_0_PROD_ID: - DEBUG_MSG("INFO: Product ID: STTS751-0\n"); - break; - case STTS751_1_PROD_ID: - DEBUG_MSG("INFO: Product ID: STTS751-1\n"); - break; - default: - printf("ERROR: Product ID: UNKNOWN\n"); - return LGW_I2C_ERROR; - } - - /* Get Manufacturer ID */ - 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"); - return LGW_I2C_ERROR; - } else { - DEBUG_PRINTF("INFO: Manufacturer ID: 0x%02X\n", val); - } - - /* Get revision number */ - 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, 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, 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; - } - - return LGW_I2C_SUCCESS; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -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"); - return LGW_I2C_ERROR; - } - - /* Read Temperature LSB */ - 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, 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; - - DEBUG_PRINTF("Temperature: %f C (h:0x%02X l:0x%02X)\n", *temperature, high_byte, low_byte); - - return LGW_I2C_SUCCESS; -} - -/* --- EOF ------------------------------------------------------------------ */ diff --git a/packet_forwarder/src/lora_pkt_fwd.c b/packet_forwarder/src/lora_pkt_fwd.c index 53661de7..501f0c02 100644 --- a/packet_forwarder/src/lora_pkt_fwd.c +++ b/packet_forwarder/src/lora_pkt_fwd.c @@ -72,6 +72,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project #endif #define JSON_CONF_DEFAULT "global_conf.json" +#define JSON_CONF_LOCAL "local_conf.json" #define DEFAULT_SERVER 127.0.0.1 /* hostname also supported */ #define DEFAULT_PORT_UP 1780 @@ -1431,6 +1432,8 @@ int main(int argc, char ** argv) /* configuration file related */ const char defaut_conf_fname[] = JSON_CONF_DEFAULT; const char * conf_fname = defaut_conf_fname; /* pointer to a string we won't touch */ + const char default_local_conf_fname[] = JSON_CONF_LOCAL; + const char * local_conf_fname = default_local_conf_fname; /* threads */ pthread_t thrid_up; @@ -1545,6 +1548,17 @@ int main(int argc, char ** argv) MSG("ERROR: [main] failed to find any configuration file named %s\n", conf_fname); exit(EXIT_FAILURE); } + /* load local configuration files */ + if (access(local_conf_fname, R_OK) == 0) { /* if there is a local conf, parse it */ + MSG("INFO: found configuration file %s, parsing it\n", local_conf_fname); + x = parse_gateway_configuration(local_conf_fname); + if (x != 0) { + exit(EXIT_FAILURE); + } + } else { + MSG("ERROR: [main] failed to find any configuration file named %s\n", local_conf_fname); + exit(EXIT_FAILURE); + } /* Start GPS a.s.a.p., to allow it to lock */ if (gps_tty_path[0] != '\0') { /* do not try to open GPS device if no path set */ @@ -1875,9 +1889,9 @@ int main(int argc, char ** argv) i = lgw_get_temperature(&temperature); pthread_mutex_unlock(&mx_concent); if (i != LGW_HAL_SUCCESS) { - printf("### Concentrator temperature unknown ###\n"); +// printf("### Concentrator temperature unknown ###\n"); } else { - printf("### Concentrator temperature: %.0f C ###\n", temperature); +// printf("### Concentrator temperature: %.0f C ###\n", temperature); } printf("##### END #####\n"); @@ -3334,6 +3348,51 @@ void thread_jit(void) { MSG("\nINFO: End of JIT thread\n"); } +static void modify_os_time(const uint32_t ppm_tstamp) +{ + struct timespec y; + struct timespec tv; + static bool time_already_set = false; + struct timeval stamp; + gettimeofday(&stamp, NULL); + int time_diff = 0; + lgw_cnt2utc(time_reference_gps, ppm_tstamp, &y); + if ((!gps_enabled) || time_already_set) + { + return; + } + if (y.tv_sec < 1583402711) // time less than '2020-03-05 18:00:00' + { + return; + } + + MSG("INFO: [modify_os_time] local_time=%ld, gps_time=%ld\n", stamp.tv_sec, y.tv_sec); + time_diff = abs(y.tv_sec - stamp.tv_sec); + + if (time_diff < 10) + { + time_already_set = true; + MSG("INFO: [modify_os_time] The difference between the system time(%ld) and the GPS time(%ld) is less than 10 seconds. Use the system time.\n", stamp.tv_sec, y.tv_sec); + return; + } + + tv.tv_sec = y.tv_sec; + tv.tv_nsec = 0; + + int ret = clock_settime(CLOCK_REALTIME, &tv); + if (0 == ret) + { + time_already_set = true; + time_t t; + struct tm* local; + char buf[128] = {0}; + t = time(NULL); + local = localtime(&t); + strftime(buf, 64, "%Y-%m-%d %H:%M:%S", local); + MSG("INFO: [modify_os_time] System time has been synchronized via GPS, %s\n", buf); + } +} + /* -------------------------------------------------------------------------- */ /* --- THREAD 4: PARSE GPS MESSAGE AND KEEP GATEWAY IN SYNC ----------------- */ @@ -3361,6 +3420,7 @@ static void gps_process_sync(void) { /* try to update time reference with the new GPS time & timestamp */ pthread_mutex_lock(&mx_timeref); i = lgw_gps_sync(&time_reference_gps, trig_tstamp, utc, gps_time); + modify_os_time(trig_tstamp); pthread_mutex_unlock(&mx_timeref); if (i != LGW_GPS_SUCCESS) { MSG("WARNING: [gps] GPS out of sync, keeping previous time reference\n"); diff --git a/tools/reset_lgw.sh b/tools/reset_lgw.sh index b58f0e98..efa8ee77 100755 --- a/tools/reset_lgw.sh +++ b/tools/reset_lgw.sh @@ -3,7 +3,6 @@ # This script is intended to be used on SX1302 CoreCell platform, it performs # the following actions: # - export/unpexort GPIO23 and GPIO18 used to reset the SX1302 chip and to enable the LDOs -# - export/unexport GPIO22 used to reset the optional SX1261 radio used for LBT/Spectral Scan # # Usage examples: # ./reset_lgw.sh stop @@ -12,10 +11,11 @@ # GPIO mapping has to be adapted with HW # -SX1302_RESET_PIN=23 # SX1302 reset -SX1302_POWER_EN_PIN=18 # SX1302 power enable -SX1261_RESET_PIN=22 # SX1261 reset (LBT / Spectral Scan) -AD5338R_RESET_PIN=13 # AD5338R reset (full-duplex CN490 reference design) +if [ -z "$2" ]; then + SX1302_RESET_PIN=38 +else + SX1302_RESET_PIN=$2 +fi WAIT_GPIO() { sleep 0.1 @@ -24,34 +24,16 @@ WAIT_GPIO() { init() { # setup GPIOs echo "$SX1302_RESET_PIN" > /sys/class/gpio/export; WAIT_GPIO - echo "$SX1261_RESET_PIN" > /sys/class/gpio/export; WAIT_GPIO - echo "$SX1302_POWER_EN_PIN" > /sys/class/gpio/export; WAIT_GPIO - echo "$AD5338R_RESET_PIN" > /sys/class/gpio/export; WAIT_GPIO # set GPIOs as output echo "out" > /sys/class/gpio/gpio$SX1302_RESET_PIN/direction; WAIT_GPIO - echo "out" > /sys/class/gpio/gpio$SX1261_RESET_PIN/direction; WAIT_GPIO - echo "out" > /sys/class/gpio/gpio$SX1302_POWER_EN_PIN/direction; WAIT_GPIO - echo "out" > /sys/class/gpio/gpio$AD5338R_RESET_PIN/direction; WAIT_GPIO } reset() { echo "CoreCell reset through GPIO$SX1302_RESET_PIN..." - echo "SX1261 reset through GPIO$SX1302_RESET_PIN..." - echo "CoreCell power enable through GPIO$SX1302_POWER_EN_PIN..." - echo "CoreCell ADC reset through GPIO$AD5338R_RESET_PIN..." - - # write output for SX1302 CoreCell power_enable and reset - echo "1" > /sys/class/gpio/gpio$SX1302_POWER_EN_PIN/value; WAIT_GPIO echo "1" > /sys/class/gpio/gpio$SX1302_RESET_PIN/value; WAIT_GPIO echo "0" > /sys/class/gpio/gpio$SX1302_RESET_PIN/value; WAIT_GPIO - - echo "0" > /sys/class/gpio/gpio$SX1261_RESET_PIN/value; WAIT_GPIO - echo "1" > /sys/class/gpio/gpio$SX1261_RESET_PIN/value; WAIT_GPIO - - echo "0" > /sys/class/gpio/gpio$AD5338R_RESET_PIN/value; WAIT_GPIO - echo "1" > /sys/class/gpio/gpio$AD5338R_RESET_PIN/value; WAIT_GPIO } term() { @@ -60,18 +42,6 @@ term() { then echo "$SX1302_RESET_PIN" > /sys/class/gpio/unexport; WAIT_GPIO fi - if [ -d /sys/class/gpio/gpio$SX1261_RESET_PIN ] - then - echo "$SX1261_RESET_PIN" > /sys/class/gpio/unexport; WAIT_GPIO - fi - if [ -d /sys/class/gpio/gpio$SX1302_POWER_EN_PIN ] - then - echo "$SX1302_POWER_EN_PIN" > /sys/class/gpio/unexport; WAIT_GPIO - fi - if [ -d /sys/class/gpio/gpio$AD5338R_RESET_PIN ] - then - echo "$AD5338R_RESET_PIN" > /sys/class/gpio/unexport; WAIT_GPIO - fi } case "$1" in diff --git a/util_chip_id/src/chip_id.c b/util_chip_id/src/chip_id.c index ae670b4c..7f8df145 100644 --- a/util_chip_id/src/chip_id.c +++ b/util_chip_id/src/chip_id.c @@ -37,6 +37,7 @@ License: Revised BSD License, see LICENSE.TXT file include in the project #include "loragw_hal.h" #include "loragw_reg.h" #include "loragw_aux.h" +#include "loragw_sx1302.h" /* -------------------------------------------------------------------------- */ /* --- PRIVATE MACROS ------------------------------------------------------- */ @@ -79,6 +80,7 @@ int main(int argc, char **argv) unsigned int arg_u; uint8_t clocksource = 0; lgw_radio_type_t radio_type = LGW_RADIO_TYPE_SX1250; + sx1302_model_id_t model_id; struct lgw_conf_board_s boardconf; struct lgw_conf_rxrf_s rfconf; @@ -197,6 +199,14 @@ int main(int argc, char **argv) return EXIT_FAILURE; } + /* get the concentrator chip model */ + x = sx1302_get_model_id(&model_id); + if (x != LGW_HAL_SUCCESS) { + printf("ERROR: failed to get concentrator chip model\n"); + } else { + printf("\nINFO: concentrator chip model ID: 0x%02X\n", model_id); + } + /* get the concentrator EUI */ x = lgw_get_eui(&eui); if (x != LGW_HAL_SUCCESS) {