123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- /*
- / _____) _ | |
- ( (____ _____ ____ _| |_ _____ ____| |__
- \____ \| ___ | (_ _) ___ |/ ___) _ \
- _____) ) ____| | | || |_| ____( (___| | | |
- (______/|_____)_|_|_| \__)_____)\____)_| |_|
- (C)2020 Semtech
- Description:
- Functions to abstract the communication interface used to communicate with
- the concentrator.
- Single-byte read/write and burst read/write.
- License: Revised BSD License, see LICENSE.TXT file include in the project
- */
- /* -------------------------------------------------------------------------- */
- /* --- DEPENDANCIES --------------------------------------------------------- */
- #include <stdint.h> /* C99 types */
- #include <stdio.h> /* printf fprintf */
- #include "loragw_com.h"
- #include "loragw_usb.h"
- #include "loragw_spi.h"
- #include "loragw_aux.h"
- /* -------------------------------------------------------------------------- */
- /* --- PRIVATE MACROS ------------------------------------------------------- */
- #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
- #if DEBUG_COM == 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_COM_ERROR;}
- #else
- #define DEBUG_MSG(str)
- #define DEBUG_PRINTF(fmt, args...)
- #define CHECK_NULL(a) if(a==NULL){return LGW_COM_ERROR;}
- #endif
- /* -------------------------------------------------------------------------- */
- /* --- PRIVATE CONSTANTS ---------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
- /* --- PRIVATE VARIABLES ---------------------------------------------------- */
- /**
- @brief The current communication type in use (SPI, USB)
- */
- static lgw_com_type_t _lgw_com_type = LGW_COM_UNKNOWN;
- /**
- @brief A generic pointer to the COM device (file descriptor)
- */
- static void* _lgw_com_target = NULL;
- /* -------------------------------------------------------------------------- */
- /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
- int lgw_com_open(lgw_com_type_t com_type, const char * com_path) {
- int com_stat;
- /* Check input parameters */
- CHECK_NULL(com_path);
- if ((com_type != LGW_COM_SPI) && (com_type != LGW_COM_USB)) {
- DEBUG_MSG("ERROR: COMMUNICATION INTERFACE TYPE IS NOT SUPPORTED\n");
- return LGW_COM_ERROR;
- }
- if (_lgw_com_target != NULL) {
- DEBUG_MSG("WARNING: CONCENTRATOR WAS ALREADY CONNECTED\n");
- lgw_com_close();
- }
- /* set current com type */
- _lgw_com_type = com_type;
- switch (com_type) {
- case LGW_COM_SPI:
- printf("Opening SPI communication interface\n");
- com_stat = lgw_spi_open(com_path, &_lgw_com_target);
- break;
- case LGW_COM_USB:
- printf("Opening USB communication interface\n");
- com_stat = lgw_usb_open(com_path, &_lgw_com_target);
- break;
- default:
- com_stat = LGW_COM_ERROR;
- break;
- }
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SPI release */
- int lgw_com_close(void) {
- int com_stat;
- if (_lgw_com_target == NULL) {
- printf("ERROR: concentrator is not connected\n");
- return -1;
- }
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- printf("Closing SPI communication interface\n");
- com_stat = lgw_spi_close(_lgw_com_target);
- break;
- case LGW_COM_USB:
- printf("Closing USB communication interface\n");
- com_stat = lgw_usb_close(_lgw_com_target);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- _lgw_com_target = NULL;
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* Simple write */
- int lgw_com_w(uint8_t spi_mux_target, uint16_t address, uint8_t data) {
- int com_stat;
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Check input parameters */
- CHECK_NULL(_lgw_com_target);
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- com_stat = lgw_spi_w(_lgw_com_target, spi_mux_target, address, data);
- break;
- case LGW_COM_USB:
- com_stat = lgw_usb_w(_lgw_com_target, spi_mux_target, address, data);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- /* Compute time spent in this function */
- _meas_time_stop(5, tm, __FUNCTION__);
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* Simple read */
- int lgw_com_r(uint8_t spi_mux_target, uint16_t address, uint8_t *data) {
- int com_stat;
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Check input parameters */
- CHECK_NULL(_lgw_com_target);
- CHECK_NULL(data);
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- com_stat = lgw_spi_r(_lgw_com_target, spi_mux_target, address, data);
- break;
- case LGW_COM_USB:
- com_stat = lgw_usb_r(_lgw_com_target, spi_mux_target, address, data);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- /* Compute time spent in this function */
- _meas_time_stop(5, tm, __FUNCTION__);
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int lgw_com_rmw(uint8_t spi_mux_target, uint16_t address, uint8_t offs, uint8_t leng, uint8_t data) {
- int com_stat;
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Check input parameters */
- CHECK_NULL(_lgw_com_target);
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- com_stat = lgw_spi_rmw(_lgw_com_target, spi_mux_target, address, offs, leng, data);
- break;
- case LGW_COM_USB:
- com_stat = lgw_usb_rmw(_lgw_com_target, address, offs, leng, data);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- /* Compute time spent in this function */
- _meas_time_stop(5, tm, __FUNCTION__);
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* Burst (multiple-byte) write */
- int lgw_com_wb(uint8_t spi_mux_target, uint16_t address, const uint8_t *data, uint16_t size) {
- int com_stat;
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Check input parameters */
- CHECK_NULL(_lgw_com_target);
- CHECK_NULL(data);
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- com_stat = lgw_spi_wb(_lgw_com_target, spi_mux_target, address, data, size);
- break;
- case LGW_COM_USB:
- com_stat = lgw_usb_wb(_lgw_com_target, spi_mux_target, address, data, size);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- /* Compute time spent in this function */
- _meas_time_stop(5, tm, __FUNCTION__);
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* Burst (multiple-byte) read */
- int lgw_com_rb(uint8_t spi_mux_target, uint16_t address, uint8_t *data, uint16_t size) {
- int com_stat;
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Check input parameters */
- CHECK_NULL(_lgw_com_target);
- CHECK_NULL(data);
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- com_stat = lgw_spi_rb(_lgw_com_target, spi_mux_target, address, data, size);
- break;
- case LGW_COM_USB:
- com_stat = lgw_usb_rb(_lgw_com_target, spi_mux_target, address, data, size);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- /* Compute time spent in this function */
- _meas_time_stop(5, tm, __FUNCTION__);
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int lgw_com_set_write_mode(lgw_com_write_mode_t write_mode) {
- int com_stat = LGW_COM_SUCCESS;
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- /* Do nothing: only single mode is supported on SPI */
- break;
- case LGW_COM_USB:
- com_stat = lgw_usb_set_write_mode(write_mode);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int lgw_com_flush(void) {
- int com_stat = LGW_COM_SUCCESS;
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- /* Do nothing: only single mode is supported on SPI */
- break;
- case LGW_COM_USB:
- com_stat = lgw_usb_flush(_lgw_com_target);
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- com_stat = LGW_COM_ERROR;
- break;
- }
- return com_stat;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- uint16_t lgw_com_chunk_size(void) {
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- return lgw_spi_chunk_size();
- case LGW_COM_USB:
- return lgw_usb_chunk_size();
- break;
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- return 0;
- }
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int lgw_com_get_temperature(float * temperature) {
- /* Check input parameters */
- CHECK_NULL(_lgw_com_target);
- CHECK_NULL(temperature);
- switch (_lgw_com_type) {
- case LGW_COM_SPI:
- printf("ERROR(%s:%d): not supported for SPI com\n", __FUNCTION__, __LINE__);
- return -1;
- case LGW_COM_USB:
- return lgw_usb_get_temperature(_lgw_com_target, temperature);
- default:
- printf("ERROR(%s:%d): wrong communication type (SHOULD NOT HAPPEN)\n", __FUNCTION__, __LINE__);
- return LGW_COM_ERROR;
- }
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- void* lgw_com_target(void) {
- return _lgw_com_target;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- lgw_com_type_t lgw_com_type(void) {
- return _lgw_com_type;
- }
- /* --- EOF ------------------------------------------------------------------ */
|