123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687 |
- /*
- / _____) _ | |
- ( (____ _____ ____ _| |_ _____ ____| |__
- \____ \| ___ | (_ _) ___ |/ ___) _ \
- _____) ) ____| | | || |_| ____( (___| | | |
- (______/|_____)_|_|_| \__)_____)\____)_| |_|
- (C)2019 Semtech
- Description:
- Functions used to handle LoRa concentrator SX1261 radio used to handle LBT
- and Spectral Scan.
- License: Revised BSD License, see LICENSE.TXT file include in the project
- */
- /* -------------------------------------------------------------------------- */
- /* --- DEPENDANCIES --------------------------------------------------------- */
- #include <stdint.h> /* C99 types */
- #include <stdio.h> /* printf fprintf */
- #include <string.h> /* strncmp */
- #include "loragw_sx1261.h"
- #include "loragw_spi.h"
- #include "loragw_com.h"
- #include "loragw_aux.h"
- #include "loragw_reg.h"
- #include "loragw_hal.h"
- #include "sx1261_com.h"
- #include "sx1261_pram.var"
- /* -------------------------------------------------------------------------- */
- /* --- PRIVATE MACROS ------------------------------------------------------- */
- #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
- #if DEBUG_LBT == 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
- #define CHECK_ERR(a) if(a==-1){return LGW_REG_ERROR;}
- #define DEBUG_SX1261_GET_STATUS 0
- /* -------------------------------------------------------------------------- */
- /* --- PRIVATE CONSTANTS ---------------------------------------------------- */
- #define SX1261_PRAM_VERSION_FULL_SIZE 16 /* 15 bytes + terminating char */
- /* -------------------------------------------------------------------------- */
- /* --- PRIVATE VARIABLES ---------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
- /* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
- int sx1261_pram_get_version(char * version_str) {
- uint8_t buff[3 + SX1261_PRAM_VERSION_FULL_SIZE] = { 0 };
- int x;
- /* Check input parameter */
- CHECK_NULL(version_str);
- /* Get version string (15 bytes) at address 0x320 */
- buff[0] = 0x03;
- buff[1] = 0x20;
- buff[2] = 0x00; /* status */
- x = sx1261_reg_r(SX1261_READ_REGISTER, buff, 18);
- if (x != LGW_REG_SUCCESS) {
- printf("ERROR: failed to read SX1261 PRAM version\n");
- return x;
- }
- /* Return full PRAM version string */
- buff[18] = '\0';
- strncpy(version_str, (char*)(buff + 3), 16); /* 15 bytes + terminating char */
- version_str[16] = '\0';
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_get_status(uint8_t * status) {
- uint8_t buff[1];
- buff[0] = 0x00;
- sx1261_reg_r(SX1261_GET_STATUS, buff, 1);
- *status = buff[0] & 0x7E; /* ignore bit 0 & 7 */
- DEBUG_PRINTF("SX1261: %s: get_status: 0x%02X (0x%02X)\n", __FUNCTION__, *status, buff[0]);
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_check_status(uint8_t expected_status) {
- int err;
- uint8_t status;
- err = sx1261_get_status(&status);
- if (err != LGW_REG_SUCCESS) {
- printf("ERROR: %s: failed to get status\n", __FUNCTION__);
- return LGW_REG_ERROR;
- }
- if (status != expected_status) {
- printf("ERROR: %s: SX1261 status is not as expected: got:0x%02X expected:0x%02X\n", __FUNCTION__, status, expected_status);
- return LGW_REG_ERROR;
- }
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- const char * get_scan_status_str(const lgw_spectral_scan_status_t status) {
- switch (status) {
- case LGW_SPECTRAL_SCAN_STATUS_NONE:
- return "LGW_SPECTRAL_SCAN_STATUS_NONE";
- case LGW_SPECTRAL_SCAN_STATUS_ON_GOING:
- return "LGW_SPECTRAL_SCAN_STATUS_ON_GOING";
- case LGW_SPECTRAL_SCAN_STATUS_ABORTED:
- return "LGW_SPECTRAL_SCAN_STATUS_ABORTED";
- case LGW_SPECTRAL_SCAN_STATUS_COMPLETED:
- return "LGW_SPECTRAL_SCAN_STATUS_COMPLETED";
- default:
- return "LGW_SPECTRAL_SCAN_STATUS_UNKNOWN";
- }
- }
- /* -------------------------------------------------------------------------- */
- /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
- int sx1261_connect(lgw_com_type_t com_type, const char *com_path) {
- if (com_type == LGW_COM_SPI && com_path == NULL) {
- printf("ERROR: %s: unspecified COM path to connect to sx1261 radio\n", __FUNCTION__);
- return LGW_REG_ERROR;
- }
- return sx1261_com_open(com_type, com_path);
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_disconnect(void) {
- return sx1261_com_close();
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_reg_w(sx1261_op_code_t op_code, uint8_t *data, uint16_t size) {
- int com_stat;
- /* checking input parameters */
- CHECK_NULL(data);
- com_stat = sx1261_com_w(op_code, data, size);
- if (com_stat != LGW_COM_SUCCESS) {
- printf("ERROR: COM ERROR DURING SX1261 RADIO REGISTER WRITE\n");
- return LGW_REG_ERROR;
- } else {
- return LGW_REG_SUCCESS;
- }
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_reg_r(sx1261_op_code_t op_code, uint8_t *data, uint16_t size) {
- int com_stat;
- /* checking input parameters */
- CHECK_NULL(data);
- com_stat = sx1261_com_r(op_code, data, size);
- if (com_stat != LGW_COM_SUCCESS) {
- printf("ERROR: COM ERROR DURING SX1261 RADIO REGISTER READ\n");
- return LGW_REG_ERROR;
- } else {
- return LGW_REG_SUCCESS;
- }
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_load_pram(void) {
- int i, err;
- uint8_t buff[32];
- char pram_version[SX1261_PRAM_VERSION_FULL_SIZE];
- uint32_t val, addr;
- /* Set Radio in Standby mode */
- buff[0] = (uint8_t)SX1261_STDBY_RC;
- sx1261_reg_w(SX1261_SET_STANDBY, buff, 1);
- /* Check status */
- err = sx1261_check_status(SX1261_STATUS_MODE_STBY_RC | SX1261_STATUS_READY);
- if (err != LGW_REG_SUCCESS) {
- printf("ERROR: %s: SX1261 status error\n", __FUNCTION__);
- return -1;
- }
- err = sx1261_pram_get_version(pram_version);
- if (err != LGW_REG_SUCCESS) {
- printf("ERROR: %s: SX1261 failed to get pram version\n", __FUNCTION__);
- return -1;
- }
- printf("SX1261: PRAM version: %s\n", pram_version);
- /* Enable patch update */
- buff[0] = 0x06;
- buff[1] = 0x10;
- buff[2] = 0x10;
- err = sx1261_reg_w( SX1261_WRITE_REGISTER, buff, 3);
- CHECK_ERR(err);
- /* Load patch */
- for (i = 0; i < (int)PRAM_COUNT; i++) {
- val = pram[i];
- addr = 0x8000 + 4*i;
- buff[0] = (addr >> 8) & 0xFF;
- buff[1] = (addr >> 0) & 0xFF;
- buff[2] = (val >> 24) & 0xFF;
- buff[3] = (val >> 16) & 0xFF;
- buff[4] = (val >> 8) & 0xFF;
- buff[5] = (val >> 0) & 0xFF;
- err = sx1261_reg_w(SX1261_WRITE_REGISTER, buff, 6);
- CHECK_ERR(err);
- }
- /* Disable patch update */
- buff[0] = 0x06;
- buff[1] = 0x10;
- buff[2] = 0x00;
- err = sx1261_reg_w( SX1261_WRITE_REGISTER, buff, 3);
- CHECK_ERR(err);
- /* Update pram */
- buff[0] = 0;
- err = sx1261_reg_w(0xd9, buff, 0);
- CHECK_ERR(err);
- err = sx1261_pram_get_version(pram_version);
- if (err != LGW_REG_SUCCESS) {
- printf("ERROR: %s: SX1261 failed to get pram version\n", __FUNCTION__);
- return -1;
- }
- printf("SX1261: PRAM version: %s\n", pram_version);
- /* Check PRAM version (only last 4 bytes) */
- if (strncmp(pram_version + 11, sx1261_pram_version_string, 4) != 0) {
- printf("ERROR: SX1261 PRAM version mismatch (got:%s expected:%s)\n", pram_version + 11, sx1261_pram_version_string);
- return -1;
- }
- return 0;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_calibrate(uint32_t freq_hz) {
- int err = LGW_REG_SUCCESS;
- uint8_t buff[16];
- buff[0] = 0x00;
- err = sx1261_reg_r(SX1261_GET_STATUS, buff, 1);
- CHECK_ERR(err);
- /* Run calibration */
- if ((freq_hz > 430E6) && (freq_hz < 440E6)) {
- buff[0] = 0x6B;
- buff[1] = 0x6F;
- } else if ((freq_hz > 470E6) && (freq_hz < 510E6)) {
- buff[0] = 0x75;
- buff[1] = 0x81;
- } else if ((freq_hz > 779E6) && (freq_hz < 787E6)) {
- buff[0] = 0xC1;
- buff[1] = 0xC5;
- } else if ((freq_hz > 863E6) && (freq_hz < 870E6)) {
- buff[0] = 0xD7;
- buff[1] = 0xDB;
- } else if ((freq_hz > 902E6) && (freq_hz < 928E6)) {
- buff[0] = 0xE1;
- buff[1] = 0xE9;
- } else {
- printf("ERROR: failed to calibrate sx1261 radio, frequency range not supported (%u)\n", freq_hz);
- return LGW_REG_ERROR;
- }
- err = sx1261_reg_w(SX1261_CALIBRATE_IMAGE, buff, 2);
- CHECK_ERR(err);
- /* Wait for calibration to complete */
- wait_ms(10);
- buff[0] = 0x00;
- buff[1] = 0x00;
- buff[2] = 0x00;
- err = sx1261_reg_r(SX1261_GET_DEVICE_ERRORS, buff, 3);
- CHECK_ERR(err);
- if (TAKE_N_BITS_FROM(buff[2], 4, 1) != 0) {
- printf("ERROR: sx1261 Image Calibration Error\n");
- return LGW_REG_ERROR;
- }
- return err;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_setup(void) {
- int err;
- uint8_t buff[32];
- /* Set Radio in Standby mode */
- buff[0] = (uint8_t)SX1261_STDBY_RC;
- err = sx1261_reg_w(SX1261_SET_STANDBY, buff, 1);
- CHECK_ERR(err);
- /* Check radio status */
- err = sx1261_check_status(SX1261_STATUS_MODE_STBY_RC | SX1261_STATUS_READY);
- CHECK_ERR(err);
- /* Set Buffer Base address */
- buff[0] = 0x80;
- buff[1] = 0x80;
- err = sx1261_reg_w(SX1261_SET_BUFFER_BASE_ADDRESS, buff, 2);
- CHECK_ERR(err);
- /* sensi adjust */
- buff[0] = 0x08;
- buff[1] = 0xAC;
- buff[2] = 0xCB;
- err = sx1261_reg_w(SX1261_WRITE_REGISTER, buff, 3);
- CHECK_ERR(err);
- DEBUG_MSG("SX1261: setup for LBT / Spectral Scan done\n");
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_set_rx_params(uint32_t freq_hz, uint8_t bandwidth) {
- int err;
- uint8_t buff[16];
- int32_t freq_reg;
- uint8_t fsk_bw_reg;
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Set SPI write bulk mode to optimize speed on USB */
- err = sx1261_com_set_write_mode(LGW_COM_WRITE_MODE_BULK);
- CHECK_ERR(err);
- /* Disable any on-going spectral scan to free the sx1261 radio for LBT */
- err = sx1261_spectral_scan_abort();
- CHECK_ERR(err);
- /* Set FS */
- err = sx1261_reg_w(SX1261_SET_FS, buff, 0);
- CHECK_ERR(err);
- #if DEBUG_SX1261_GET_STATUS /* need to disable spi bulk mode if enable this check */
- /* Check radio status */
- err = sx1261_check_status(SX1261_STATUS_MODE_FS | SX1261_STATUS_READY);
- CHECK_ERR(err);
- #endif
- /* Set frequency */
- freq_reg = SX1261_FREQ_TO_REG(freq_hz);
- buff[0] = (uint8_t)(freq_reg >> 24);
- buff[1] = (uint8_t)(freq_reg >> 16);
- buff[2] = (uint8_t)(freq_reg >> 8);
- buff[3] = (uint8_t)(freq_reg >> 0);
- err = sx1261_reg_w(SX1261_SET_RF_FREQUENCY, buff, 4);
- CHECK_ERR(err);
- /* Configure RSSI averaging window */
- buff[0] = 0x08;
- buff[1] = 0x9B;
- buff[2] = 0x05 << 2;
- err = sx1261_reg_w(SX1261_WRITE_REGISTER, buff, 3);
- CHECK_ERR(err);
- /* Set PacketType */
- buff[0] = 0x00; /* FSK */
- err = sx1261_reg_w(SX1261_SET_PACKET_TYPE, buff, 1);
- CHECK_ERR(err);
- /* Set GFSK bandwidth */
- switch (bandwidth) {
- case BW_125KHZ:
- fsk_bw_reg = 0x0A; /* RX_BW_234300 Hz */
- break;
- case BW_250KHZ:
- fsk_bw_reg = 0x09; /* RX_BW_467000 Hz */
- break;
- default:
- printf("ERROR: %s: Cannot configure sx1261 for bandwidth %u\n", __FUNCTION__, bandwidth);
- return LGW_REG_ERROR;
- }
- /* Set modulation params for FSK */
- buff[0] = 0; // BR
- buff[1] = 0x14; // BR
- buff[2] = 0x00; // BR
- buff[3] = 0x00; // Gaussian BT disabled
- buff[4] = fsk_bw_reg;
- buff[5] = 0x02; // FDEV
- buff[6] = 0xE9; // FDEV
- buff[7] = 0x0F; // FDEV
- err = sx1261_reg_w(SX1261_SET_MODULATION_PARAMS, buff, 8);
- CHECK_ERR(err);
- /* Set packet params for FSK */
- buff[0] = 0x00; /* Preamble length MSB */
- buff[1] = 0x20; /* Preamble length LSB 32 bits*/
- buff[2] = 0x05; /* Preamble detector lenght 16 bits */
- buff[3] = 0x20; /* SyncWordLength 32 bits*/
- buff[4] = 0x00; /* AddrComp disabled */
- buff[5] = 0x01; /* PacketType variable size */
- buff[6] = 0xff; /* PayloadLength 255 bytes */
- buff[7] = 0x00; /* CRCType 1 Byte */
- buff[8] = 0x00; /* Whitening disabled*/
- err = sx1261_reg_w(SX1261_SET_PACKET_PARAMS, buff, 9);
- CHECK_ERR(err);
- /* Set Radio in Rx continuous mode */
- buff[0] = 0xFF;
- buff[1] = 0xFF;
- buff[2] = 0xFF;
- err = sx1261_reg_w(SX1261_SET_RX, buff, 3);
- CHECK_ERR(err);
- /* Flush write (USB BULK mode) */
- err = sx1261_com_flush();
- if (err != 0) {
- printf("ERROR: %s: Failed to flush sx1261 SPI\n", __FUNCTION__);
- return -1;
- }
- /* Setting back to SINGLE BULK write mode */
- err = sx1261_com_set_write_mode(LGW_COM_WRITE_MODE_SINGLE);
- CHECK_ERR(err);
- #if DEBUG_SX1261_GET_STATUS
- /* Check radio status */
- err = sx1261_check_status(SX1261_STATUS_MODE_RX | SX1261_STATUS_READY);
- CHECK_ERR(err);
- #endif
- DEBUG_PRINTF("SX1261: RX params set to %u Hz (bw:0x%02X)\n", freq_hz, bandwidth);
- _meas_time_stop(4, tm, __FUNCTION__);
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_lbt_start(lgw_lbt_scan_time_t scan_time_us, int8_t threshold_dbm) {
- int err;
- uint8_t buff[16];
- uint16_t nb_scan;
- uint8_t threshold_reg = -2 * threshold_dbm;
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- switch (scan_time_us) {
- case LGW_LBT_SCAN_TIME_128_US:
- nb_scan = 24;
- break;
- case LGW_LBT_SCAN_TIME_5000_US:
- nb_scan = 715;
- break;
- default:
- printf("ERROR: wrong scan_time_us value\n");
- return -1;
- }
- #if DEBUG_SX1261_GET_STATUS
- /* Check radio status */
- err = sx1261_check_status(SX1261_STATUS_MODE_RX | SX1261_STATUS_READY);
- CHECK_ERR(err);
- #endif
- /* Configure LBT scan */
- buff[0] = 11; // intervall_rssi_read (10 => 7.68 usec,11 => 8.2 usec, 12 => 8.68 usec)
- buff[1] = (nb_scan >> 8) & 0xFF;
- buff[2] = (nb_scan >> 0) & 0xFF;
- buff[3] = threshold_reg;
- buff[4] = 1; // gpioId
- err = sx1261_reg_w(0x9a, buff, 5);
- CHECK_ERR(err);
- /* Wait for Scan Time before TX trigger request */
- wait_us((uint16_t)scan_time_us);
- DEBUG_PRINTF("SX1261: LBT started: scan time = %uus, threshold = %ddBm\n", (uint16_t)scan_time_us, threshold_dbm);
- _meas_time_stop(4, tm, __FUNCTION__);
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_lbt_stop(void) {
- int err;
- uint8_t buff[16];
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Disable LBT */
- buff[0] = 0x08;
- buff[1] = 0x9B;
- buff[2] = 0x00;
- err = sx1261_reg_w(SX1261_WRITE_REGISTER, buff, 3);
- CHECK_ERR(err);
- /* Set FS */
- err = sx1261_reg_w(SX1261_SET_FS, buff, 0);
- CHECK_ERR(err);
- DEBUG_MSG("SX1261: LBT stopped\n");
- _meas_time_stop(4, tm, __FUNCTION__);
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_spectral_scan_start(uint16_t nb_scan) {
- int err;
- uint8_t buff[4]; /* 66 bytes for spectral scan results + 2 bytes register address + 1 dummy byte for reading */
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Start spectral scan */
- buff[0] = (nb_scan >> 8) & 0xFF; /* nb_scan MSB */
- buff[1] = (nb_scan >> 0) & 0xFF; /* nb_scan LSB */
- buff[2] = 11; /* interval between scans - 8.2 us */
- err = sx1261_reg_w(0x9b, buff, 9);
- CHECK_ERR(err);
- DEBUG_MSG("INFO: Spectral Scan started...\n");
- _meas_time_stop(4, tm, __FUNCTION__);
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_spectral_scan_get_results(int8_t rssi_offset, int16_t * levels_dbm, uint16_t * results) {
- int err, i;
- uint8_t buff[69]; /* 66 bytes for spectral scan results + 2 bytes register address + 1 dummy byte for reading */
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Check input parameters */
- CHECK_NULL(levels_dbm);
- CHECK_NULL(results);
- /* Get the results (66 bytes) */
- buff[0] = 0x04;
- buff[1] = 0x01;
- buff[2] = 0x00; /* dummy */
- for (i = 3; i < (66 + 3) ; i++) {
- buff[i] = 0x00;
- }
- err = sx1261_reg_r(SX1261_READ_REGISTER, buff, 66 + 3);
- CHECK_ERR(err);
- /* Copy the results in the given buffers */
- /* The number of points measured ABOVE each threshold */
- for (i = 0; i < 32; i++) {
- levels_dbm[i] = -i*4 + rssi_offset;
- results[i] = (uint16_t)((buff[3 + i*2] << 8) | buff[3 + i*2 + 1]);
- }
- /* The number of points measured BELOW the lower threshold */
- levels_dbm[32] = -31*4 + rssi_offset;
- results[32] = (uint16_t)((buff[3 + 32*2] << 8) + buff[3 + 32*2 + 1]);
- _meas_time_stop(4, tm, __FUNCTION__);
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_spectral_scan_status(lgw_spectral_scan_status_t * status) {
- int err;
- uint8_t buff[16];
- /* performances variables */
- struct timeval tm;
- CHECK_NULL(status);
- /* Record function start time */
- _meas_time_start(&tm);
- /* Get status */
- buff[0] = 0x07;
- buff[1] = 0xCD;
- buff[2] = 0x00; /* dummy */
- buff[3] = 0x00; /* read value holder */
- err = sx1261_reg_r(SX1261_READ_REGISTER, buff, 4);
- CHECK_ERR(err);
- switch (buff[3]) {
- case 0x00:
- *status = LGW_SPECTRAL_SCAN_STATUS_NONE;
- break;
- case 0x0F:
- *status = LGW_SPECTRAL_SCAN_STATUS_ON_GOING;
- break;
- case 0xF0:
- *status = LGW_SPECTRAL_SCAN_STATUS_ABORTED;
- break;
- case 0xFF:
- *status = LGW_SPECTRAL_SCAN_STATUS_COMPLETED;
- break;
- default:
- *status = LGW_SPECTRAL_SCAN_STATUS_UNKNOWN;
- break;
- }
- DEBUG_PRINTF("INFO: %s: %s\n", __FUNCTION__, get_scan_status_str(*status));
- _meas_time_stop(4, tm, __FUNCTION__);
- return LGW_REG_SUCCESS;
- }
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- int sx1261_spectral_scan_abort(void) {
- int err;
- uint8_t buff[16];
- /* performances variables */
- struct timeval tm;
- /* Record function start time */
- _meas_time_start(&tm);
- /* Disable LBT */
- buff[0] = 0x08;
- buff[1] = 0x9B;
- buff[2] = 0x00;
- err = sx1261_reg_w(SX1261_WRITE_REGISTER, buff, 3);
- CHECK_ERR(err);
- DEBUG_MSG("SX1261: spectral scan aborted\n");
- _meas_time_stop(4, tm, __FUNCTION__);
- return LGW_REG_SUCCESS;
- }
- /* --- EOF ------------------------------------------------------------------ */
|