Host driver/HAL to build a LoRa Picocell Gateway which communicates through USB with a concentrator board based on Semtech SX1308 multi-channel modem and SX1257/SX1255 RF transceivers.

Committer:
dgabino
Date:
Wed Apr 11 14:38:42 2018 +0000
Revision:
0:102b50f941d0
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dgabino 0:102b50f941d0 1 /*
dgabino 0:102b50f941d0 2 / _____) _ | |
dgabino 0:102b50f941d0 3 ( (____ _____ ____ _| |_ _____ ____| |__
dgabino 0:102b50f941d0 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
dgabino 0:102b50f941d0 5 _____) ) ____| | | || |_| ____( (___| | | |
dgabino 0:102b50f941d0 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
dgabino 0:102b50f941d0 7 (C)2017 Semtech-Cycleo
dgabino 0:102b50f941d0 8
dgabino 0:102b50f941d0 9 Description:
dgabino 0:102b50f941d0 10 Functions used to handle a single LoRa concentrator.
dgabino 0:102b50f941d0 11 Registers are addressed by name.
dgabino 0:102b50f941d0 12 Multi-bytes registers are handled automatically.
dgabino 0:102b50f941d0 13 Read-modify-write is handled automatically.
dgabino 0:102b50f941d0 14
dgabino 0:102b50f941d0 15 License: Revised BSD License, see LICENSE.TXT file include in the project
dgabino 0:102b50f941d0 16
dgabino 0:102b50f941d0 17 */
dgabino 0:102b50f941d0 18
dgabino 0:102b50f941d0 19
dgabino 0:102b50f941d0 20 /* -------------------------------------------------------------------------- */
dgabino 0:102b50f941d0 21 /* --- DEPENDANCIES --------------------------------------------------------- */
dgabino 0:102b50f941d0 22
dgabino 0:102b50f941d0 23 #include <stdint.h> /* C99 types */
dgabino 0:102b50f941d0 24 #include <stdbool.h> /* bool type */
dgabino 0:102b50f941d0 25 #include <stdio.h> /* printf fprintf */
dgabino 0:102b50f941d0 26
dgabino 0:102b50f941d0 27 #include "loragw_com.h"
dgabino 0:102b50f941d0 28 #include "loragw_mcu.h"
dgabino 0:102b50f941d0 29 #include "loragw_reg.h"
dgabino 0:102b50f941d0 30 #include "loragw_aux.h"
dgabino 0:102b50f941d0 31
dgabino 0:102b50f941d0 32 /* -------------------------------------------------------------------------- */
dgabino 0:102b50f941d0 33 /* --- PRIVATE MACROS ------------------------------------------------------- */
dgabino 0:102b50f941d0 34
dgabino 0:102b50f941d0 35 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
dgabino 0:102b50f941d0 36 #if DEBUG_REG == 1
dgabino 0:102b50f941d0 37 #define DEBUG_MSG(str) fprintf(stderr, str)
dgabino 0:102b50f941d0 38 #define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
dgabino 0:102b50f941d0 39 #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;}
dgabino 0:102b50f941d0 40 #else
dgabino 0:102b50f941d0 41 #define DEBUG_MSG(str)
dgabino 0:102b50f941d0 42 #define DEBUG_PRINTF(fmt, args...)
dgabino 0:102b50f941d0 43 #define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;}
dgabino 0:102b50f941d0 44 #endif
dgabino 0:102b50f941d0 45
dgabino 0:102b50f941d0 46 /* -------------------------------------------------------------------------- */
dgabino 0:102b50f941d0 47 /* --- PRIVATE CONSTANTS ---------------------------------------------------- */
dgabino 0:102b50f941d0 48
dgabino 0:102b50f941d0 49 #define PAGE_ADDR 0x00
dgabino 0:102b50f941d0 50 #define PAGE_MASK 0x03
dgabino 0:102b50f941d0 51
dgabino 0:102b50f941d0 52 /*
dgabino 0:102b50f941d0 53 auto generated register mapping for C code : 11-Jul-2013 13:20:40
dgabino 0:102b50f941d0 54 this file contains autogenerated C struct used to access the LoRa register from the Primer firmware
dgabino 0:102b50f941d0 55 this file is autogenerated from registers description
dgabino 0:102b50f941d0 56 293 registers are defined
dgabino 0:102b50f941d0 57 */
dgabino 0:102b50f941d0 58 const struct lgw_reg_s loregs[LGW_TOTALREGS] = {
dgabino 0:102b50f941d0 59 {-1, 0, 0, 0, 2, 0, 0}, /* PAGE_REG */
dgabino 0:102b50f941d0 60 {-1, 0, 7, 0, 1, 0, 0}, /* SOFT_RESET */
dgabino 0:102b50f941d0 61 {-1, 1, 0, 0, 8, 1, 103}, /* VERSION */
dgabino 0:102b50f941d0 62 {-1, 2, 0, 0, 16, 0, 0}, /* RX_DATA_BUF_ADDR */
dgabino 0:102b50f941d0 63 {-1, 4, 0, 0, 8, 0, 0}, /* RX_DATA_BUF_DATA */
dgabino 0:102b50f941d0 64 {-1, 5, 0, 0, 8, 0, 0}, /* TX_DATA_BUF_ADDR */
dgabino 0:102b50f941d0 65 {-1, 6, 0, 0, 8, 0, 0}, /* TX_DATA_BUF_DATA */
dgabino 0:102b50f941d0 66 {-1, 7, 0, 0, 8, 0, 0}, /* CAPTURE_RAM_ADDR */
dgabino 0:102b50f941d0 67 {-1, 8, 0, 0, 8, 1, 0}, /* CAPTURE_RAM_DATA */
dgabino 0:102b50f941d0 68 {-1, 9, 0, 0, 8, 0, 0}, /* MCU_PROM_ADDR */
dgabino 0:102b50f941d0 69 {-1, 10, 0, 0, 8, 0, 0}, /* MCU_PROM_DATA */
dgabino 0:102b50f941d0 70 {-1, 11, 0, 0, 8, 0, 0}, /* RX_PACKET_DATA_FIFO_NUM_STORED */
dgabino 0:102b50f941d0 71 {-1, 12, 0, 0, 16, 1, 0}, /* RX_PACKET_DATA_FIFO_ADDR_POINTER */
dgabino 0:102b50f941d0 72 {-1, 14, 0, 0, 8, 1, 0}, /* RX_PACKET_DATA_FIFO_STATUS */
dgabino 0:102b50f941d0 73 {-1, 15, 0, 0, 8, 1, 0}, /* RX_PACKET_DATA_FIFO_PAYLOAD_SIZE */
dgabino 0:102b50f941d0 74 {-1, 16, 0, 0, 1, 0, 0}, /* MBWSSF_MODEM_ENABLE */
dgabino 0:102b50f941d0 75 {-1, 16, 1, 0, 1, 0, 0}, /* CONCENTRATOR_MODEM_ENABLE */
dgabino 0:102b50f941d0 76 {-1, 16, 2, 0, 1, 0, 0}, /* FSK_MODEM_ENABLE */
dgabino 0:102b50f941d0 77 {-1, 16, 3, 0, 1, 0, 0}, /* GLOBAL_EN */
dgabino 0:102b50f941d0 78 {-1, 17, 0, 0, 1, 0, 1}, /* CLK32M_EN */
dgabino 0:102b50f941d0 79 {-1, 17, 1, 0, 1, 0, 1}, /* CLKHS_EN */
dgabino 0:102b50f941d0 80 {-1, 18, 0, 0, 1, 0, 0}, /* START_BIST0 */
dgabino 0:102b50f941d0 81 {-1, 18, 1, 0, 1, 0, 0}, /* START_BIST1 */
dgabino 0:102b50f941d0 82 {-1, 18, 2, 0, 1, 0, 0}, /* CLEAR_BIST0 */
dgabino 0:102b50f941d0 83 {-1, 18, 3, 0, 1, 0, 0}, /* CLEAR_BIST1 */
dgabino 0:102b50f941d0 84 {-1, 19, 0, 0, 1, 1, 0}, /* BIST0_FINISHED */
dgabino 0:102b50f941d0 85 {-1, 19, 1, 0, 1, 1, 0}, /* BIST1_FINISHED */
dgabino 0:102b50f941d0 86 {-1, 20, 0, 0, 1, 1, 0}, /* MCU_AGC_PROG_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 87 {-1, 20, 1, 0, 1, 1, 0}, /* MCU_ARB_PROG_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 88 {-1, 20, 2, 0, 1, 1, 0}, /* CAPTURE_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 89 {-1, 20, 3, 0, 1, 1, 0}, /* CHAN_FIR_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 90 {-1, 20, 4, 0, 1, 1, 0}, /* CHAN_FIR_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 91 {-1, 21, 0, 0, 1, 1, 0}, /* CORR0_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 92 {-1, 21, 1, 0, 1, 1, 0}, /* CORR1_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 93 {-1, 21, 2, 0, 1, 1, 0}, /* CORR2_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 94 {-1, 21, 3, 0, 1, 1, 0}, /* CORR3_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 95 {-1, 21, 4, 0, 1, 1, 0}, /* CORR4_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 96 {-1, 21, 5, 0, 1, 1, 0}, /* CORR5_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 97 {-1, 21, 6, 0, 1, 1, 0}, /* CORR6_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 98 {-1, 21, 7, 0, 1, 1, 0}, /* CORR7_RAM_BIST_STATUS */
dgabino 0:102b50f941d0 99 {-1, 22, 0, 0, 1, 1, 0}, /* MODEM0_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 100 {-1, 22, 1, 0, 1, 1, 0}, /* MODEM1_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 101 {-1, 22, 2, 0, 1, 1, 0}, /* MODEM2_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 102 {-1, 22, 3, 0, 1, 1, 0}, /* MODEM3_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 103 {-1, 22, 4, 0, 1, 1, 0}, /* MODEM4_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 104 {-1, 22, 5, 0, 1, 1, 0}, /* MODEM5_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 105 {-1, 22, 6, 0, 1, 1, 0}, /* MODEM6_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 106 {-1, 22, 7, 0, 1, 1, 0}, /* MODEM7_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 107 {-1, 23, 0, 0, 1, 1, 0}, /* MODEM0_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 108 {-1, 23, 1, 0, 1, 1, 0}, /* MODEM1_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 109 {-1, 23, 2, 0, 1, 1, 0}, /* MODEM2_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 110 {-1, 23, 3, 0, 1, 1, 0}, /* MODEM3_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 111 {-1, 23, 4, 0, 1, 1, 0}, /* MODEM4_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 112 {-1, 23, 5, 0, 1, 1, 0}, /* MODEM5_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 113 {-1, 23, 6, 0, 1, 1, 0}, /* MODEM6_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 114 {-1, 23, 7, 0, 1, 1, 0}, /* MODEM7_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 115 {-1, 24, 0, 0, 1, 1, 0}, /* MODEM0_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 116 {-1, 24, 1, 0, 1, 1, 0}, /* MODEM1_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 117 {-1, 24, 2, 0, 1, 1, 0}, /* MODEM2_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 118 {-1, 24, 3, 0, 1, 1, 0}, /* MODEM3_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 119 {-1, 24, 4, 0, 1, 1, 0}, /* MODEM4_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 120 {-1, 24, 5, 0, 1, 1, 0}, /* MODEM5_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 121 {-1, 24, 6, 0, 1, 1, 0}, /* MODEM6_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 122 {-1, 24, 7, 0, 1, 1, 0}, /* MODEM7_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 123 {-1, 25, 0, 0, 1, 1, 0}, /* MODEM_MBWSSF_RAM0_BIST_STATUS */
dgabino 0:102b50f941d0 124 {-1, 25, 1, 0, 1, 1, 0}, /* MODEM_MBWSSF_RAM1_BIST_STATUS */
dgabino 0:102b50f941d0 125 {-1, 25, 2, 0, 1, 1, 0}, /* MODEM_MBWSSF_RAM2_BIST_STATUS */
dgabino 0:102b50f941d0 126 {-1, 26, 0, 0, 1, 1, 0}, /* MCU_AGC_DATA_RAM_BIST0_STATUS */
dgabino 0:102b50f941d0 127 {-1, 26, 1, 0, 1, 1, 0}, /* MCU_AGC_DATA_RAM_BIST1_STATUS */
dgabino 0:102b50f941d0 128 {-1, 26, 2, 0, 1, 1, 0}, /* MCU_ARB_DATA_RAM_BIST0_STATUS */
dgabino 0:102b50f941d0 129 {-1, 26, 3, 0, 1, 1, 0}, /* MCU_ARB_DATA_RAM_BIST1_STATUS */
dgabino 0:102b50f941d0 130 {-1, 26, 4, 0, 1, 1, 0}, /* TX_TOP_RAM_BIST0_STATUS */
dgabino 0:102b50f941d0 131 {-1, 26, 5, 0, 1, 1, 0}, /* TX_TOP_RAM_BIST1_STATUS */
dgabino 0:102b50f941d0 132 {-1, 26, 6, 0, 1, 1, 0}, /* DATA_MNGT_RAM_BIST0_STATUS */
dgabino 0:102b50f941d0 133 {-1, 26, 7, 0, 1, 1, 0}, /* DATA_MNGT_RAM_BIST1_STATUS */
dgabino 0:102b50f941d0 134 {-1, 27, 0, 0, 4, 0, 0}, /* GPIO_SELECT_INPUT */
dgabino 0:102b50f941d0 135 {-1, 28, 0, 0, 4, 0, 0}, /* GPIO_SELECT_OUTPUT */
dgabino 0:102b50f941d0 136 {-1, 29, 0, 0, 5, 0, 0}, /* GPIO_MODE */
dgabino 0:102b50f941d0 137 {-1, 30, 0, 0, 5, 1, 0}, /* GPIO_PIN_REG_IN */
dgabino 0:102b50f941d0 138 {-1, 31, 0, 0, 5, 0, 0}, /* GPIO_PIN_REG_OUT */
dgabino 0:102b50f941d0 139 {-1, 32, 0, 0, 8, 1, 0}, /* MCU_AGC_STATUS */
dgabino 0:102b50f941d0 140 {-1, 125, 0, 0, 8, 1, 0}, /* MCU_ARB_STATUS */
dgabino 0:102b50f941d0 141 {-1, 126, 0, 0, 8, 1, 1}, /* CHIP_ID */
dgabino 0:102b50f941d0 142 {-1, 127, 0, 0, 1, 0, 1}, /* EMERGENCY_FORCE_HOST_CTRL */
dgabino 0:102b50f941d0 143 {0, 33, 0, 0, 1, 0, 0}, /* RX_INVERT_IQ */
dgabino 0:102b50f941d0 144 {0, 33, 1, 0, 1, 0, 1}, /* MODEM_INVERT_IQ */
dgabino 0:102b50f941d0 145 {0, 33, 2, 0, 1, 0, 0}, /* MBWSSF_MODEM_INVERT_IQ */
dgabino 0:102b50f941d0 146 {0, 33, 3, 0, 1, 0, 0}, /* RX_EDGE_SELECT */
dgabino 0:102b50f941d0 147 {0, 33, 4, 0, 1, 0, 0}, /* MISC_RADIO_EN */
dgabino 0:102b50f941d0 148 {0, 33, 5, 0, 1, 0, 0}, /* FSK_MODEM_INVERT_IQ */
dgabino 0:102b50f941d0 149 {0, 34, 0, 0, 4, 0, 7}, /* FILTER_GAIN */
dgabino 0:102b50f941d0 150 {0, 35, 0, 0, 8, 0, 240}, /* RADIO_SELECT */
dgabino 0:102b50f941d0 151 {0, 36, 0, 1, 13, 0, -384}, /* IF_FREQ_0 */
dgabino 0:102b50f941d0 152 {0, 38, 0, 1, 13, 0, -128}, /* IF_FREQ_1 */
dgabino 0:102b50f941d0 153 {0, 40, 0, 1, 13, 0, 128}, /* IF_FREQ_2 */
dgabino 0:102b50f941d0 154 {0, 42, 0, 1, 13, 0, 384}, /* IF_FREQ_3 */
dgabino 0:102b50f941d0 155 {0, 44, 0, 1, 13, 0, -384}, /* IF_FREQ_4 */
dgabino 0:102b50f941d0 156 {0, 46, 0, 1, 13, 0, -128}, /* IF_FREQ_5 */
dgabino 0:102b50f941d0 157 {0, 48, 0, 1, 13, 0, 128}, /* IF_FREQ_6 */
dgabino 0:102b50f941d0 158 {0, 50, 0, 1, 13, 0, 384}, /* IF_FREQ_7 */
dgabino 0:102b50f941d0 159 {0, 52, 0, 1, 13, 0, 0}, /* IF_FREQ_8 */
dgabino 0:102b50f941d0 160 {0, 54, 0, 1, 13, 0, 0}, /* IF_FREQ_9 */
dgabino 0:102b50f941d0 161 {0, 64, 0, 0, 1, 0, 0}, /* CHANN_OVERRIDE_AGC_GAIN */
dgabino 0:102b50f941d0 162 {0, 64, 1, 0, 4, 0, 7}, /* CHANN_AGC_GAIN */
dgabino 0:102b50f941d0 163 {0, 65, 0, 0, 7, 0, 0}, /* CORR0_DETECT_EN */
dgabino 0:102b50f941d0 164 {0, 66, 0, 0, 7, 0, 0}, /* CORR1_DETECT_EN */
dgabino 0:102b50f941d0 165 {0, 67, 0, 0, 7, 0, 0}, /* CORR2_DETECT_EN */
dgabino 0:102b50f941d0 166 {0, 68, 0, 0, 7, 0, 0}, /* CORR3_DETECT_EN */
dgabino 0:102b50f941d0 167 {0, 69, 0, 0, 7, 0, 0}, /* CORR4_DETECT_EN */
dgabino 0:102b50f941d0 168 {0, 70, 0, 0, 7, 0, 0}, /* CORR5_DETECT_EN */
dgabino 0:102b50f941d0 169 {0, 71, 0, 0, 7, 0, 0}, /* CORR6_DETECT_EN */
dgabino 0:102b50f941d0 170 {0, 72, 0, 0, 7, 0, 0}, /* CORR7_DETECT_EN */
dgabino 0:102b50f941d0 171 {0, 73, 0, 0, 1, 0, 0}, /* CORR_SAME_PEAKS_OPTION_SF6 */
dgabino 0:102b50f941d0 172 {0, 73, 1, 0, 1, 0, 1}, /* CORR_SAME_PEAKS_OPTION_SF7 */
dgabino 0:102b50f941d0 173 {0, 73, 2, 0, 1, 0, 1}, /* CORR_SAME_PEAKS_OPTION_SF8 */
dgabino 0:102b50f941d0 174 {0, 73, 3, 0, 1, 0, 1}, /* CORR_SAME_PEAKS_OPTION_SF9 */
dgabino 0:102b50f941d0 175 {0, 73, 4, 0, 1, 0, 1}, /* CORR_SAME_PEAKS_OPTION_SF10 */
dgabino 0:102b50f941d0 176 {0, 73, 5, 0, 1, 0, 1}, /* CORR_SAME_PEAKS_OPTION_SF11 */
dgabino 0:102b50f941d0 177 {0, 73, 6, 0, 1, 0, 1}, /* CORR_SAME_PEAKS_OPTION_SF12 */
dgabino 0:102b50f941d0 178 {0, 74, 0, 0, 4, 0, 4}, /* CORR_SIG_NOISE_RATIO_SF6 */
dgabino 0:102b50f941d0 179 {0, 74, 4, 0, 4, 0, 4}, /* CORR_SIG_NOISE_RATIO_SF7 */
dgabino 0:102b50f941d0 180 {0, 75, 0, 0, 4, 0, 4}, /* CORR_SIG_NOISE_RATIO_SF8 */
dgabino 0:102b50f941d0 181 {0, 75, 4, 0, 4, 0, 4}, /* CORR_SIG_NOISE_RATIO_SF9 */
dgabino 0:102b50f941d0 182 {0, 76, 0, 0, 4, 0, 4}, /* CORR_SIG_NOISE_RATIO_SF10 */
dgabino 0:102b50f941d0 183 {0, 76, 4, 0, 4, 0, 4}, /* CORR_SIG_NOISE_RATIO_SF11 */
dgabino 0:102b50f941d0 184 {0, 77, 0, 0, 4, 0, 4}, /* CORR_SIG_NOISE_RATIO_SF12 */
dgabino 0:102b50f941d0 185 {0, 78, 0, 0, 4, 0, 4}, /* CORR_NUM_SAME_PEAK */
dgabino 0:102b50f941d0 186 {0, 78, 4, 0, 3, 0, 5}, /* CORR_MAC_GAIN */
dgabino 0:102b50f941d0 187 {0, 81, 0, 0, 12, 0, 0}, /* ADJUST_MODEM_START_OFFSET_RDX4 */
dgabino 0:102b50f941d0 188 {0, 83, 0, 0, 12, 0, 4092}, /* ADJUST_MODEM_START_OFFSET_SF12_RDX4 */
dgabino 0:102b50f941d0 189 {0, 85, 0, 0, 8, 0, 7}, /* DBG_CORR_SELECT_SF */
dgabino 0:102b50f941d0 190 {0, 86, 0, 0, 8, 0, 0}, /* DBG_CORR_SELECT_CHANNEL */
dgabino 0:102b50f941d0 191 {0, 87, 0, 0, 8, 1, 0}, /* DBG_DETECT_CPT */
dgabino 0:102b50f941d0 192 {0, 88, 0, 0, 8, 1, 0}, /* DBG_SYMB_CPT */
dgabino 0:102b50f941d0 193 {0, 89, 0, 0, 1, 0, 1}, /* CHIRP_INVERT_RX */
dgabino 0:102b50f941d0 194 {0, 89, 1, 0, 1, 0, 1}, /* DC_NOTCH_EN */
dgabino 0:102b50f941d0 195 {0, 90, 0, 0, 1, 0, 0}, /* IMPLICIT_CRC_EN */
dgabino 0:102b50f941d0 196 {0, 90, 1, 0, 3, 0, 0}, /* IMPLICIT_CODING_RATE */
dgabino 0:102b50f941d0 197 {0, 91, 0, 0, 8, 0, 0}, /* IMPLICIT_PAYLOAD_LENGHT */
dgabino 0:102b50f941d0 198 {0, 92, 0, 0, 8, 0, 29}, /* FREQ_TO_TIME_INVERT */
dgabino 0:102b50f941d0 199 {0, 93, 0, 0, 6, 0, 9}, /* FREQ_TO_TIME_DRIFT */
dgabino 0:102b50f941d0 200 {0, 94, 0, 0, 2, 0, 2}, /* PAYLOAD_FINE_TIMING_GAIN */
dgabino 0:102b50f941d0 201 {0, 94, 2, 0, 2, 0, 1}, /* PREAMBLE_FINE_TIMING_GAIN */
dgabino 0:102b50f941d0 202 {0, 94, 4, 0, 2, 0, 0}, /* TRACKING_INTEGRAL */
dgabino 0:102b50f941d0 203 {0, 95, 0, 0, 4, 0, 1}, /* FRAME_SYNCH_PEAK1_POS */
dgabino 0:102b50f941d0 204 {0, 95, 4, 0, 4, 0, 2}, /* FRAME_SYNCH_PEAK2_POS */
dgabino 0:102b50f941d0 205 {0, 96, 0, 0, 16, 0, 10}, /* PREAMBLE_SYMB1_NB */
dgabino 0:102b50f941d0 206 {0, 98, 0, 0, 1, 0, 1}, /* FRAME_SYNCH_GAIN */
dgabino 0:102b50f941d0 207 {0, 98, 1, 0, 1, 0, 1}, /* SYNCH_DETECT_TH */
dgabino 0:102b50f941d0 208 {0, 99, 0, 0, 4, 0, 8}, /* LLR_SCALE */
dgabino 0:102b50f941d0 209 {0, 99, 4, 0, 2, 0, 2}, /* SNR_AVG_CST */
dgabino 0:102b50f941d0 210 {0, 100, 0, 0, 7, 0, 0}, /* PPM_OFFSET */
dgabino 0:102b50f941d0 211 {0, 101, 0, 0, 8, 0, 255}, /* MAX_PAYLOAD_LEN */
dgabino 0:102b50f941d0 212 {0, 102, 0, 0, 1, 0, 1}, /* ONLY_CRC_EN */
dgabino 0:102b50f941d0 213 {0, 103, 0, 0, 8, 0, 0}, /* ZERO_PAD */
dgabino 0:102b50f941d0 214 {0, 104, 0, 0, 4, 0, 8}, /* DEC_GAIN_OFFSET */
dgabino 0:102b50f941d0 215 {0, 104, 4, 0, 4, 0, 7}, /* CHAN_GAIN_OFFSET */
dgabino 0:102b50f941d0 216 {0, 105, 1, 0, 1, 0, 1}, /* FORCE_HOST_RADIO_CTRL */
dgabino 0:102b50f941d0 217 {0, 105, 2, 0, 1, 0, 1}, /* FORCE_HOST_FE_CTRL */
dgabino 0:102b50f941d0 218 {0, 105, 3, 0, 1, 0, 1}, /* FORCE_DEC_FILTER_GAIN */
dgabino 0:102b50f941d0 219 {0, 106, 0, 0, 1, 0, 1}, /* MCU_RST_0 */
dgabino 0:102b50f941d0 220 {0, 106, 1, 0, 1, 0, 1}, /* MCU_RST_1 */
dgabino 0:102b50f941d0 221 {0, 106, 2, 0, 1, 0, 0}, /* MCU_SELECT_MUX_0 */
dgabino 0:102b50f941d0 222 {0, 106, 3, 0, 1, 0, 0}, /* MCU_SELECT_MUX_1 */
dgabino 0:102b50f941d0 223 {0, 106, 4, 0, 1, 1, 0}, /* MCU_CORRUPTION_DETECTED_0 */
dgabino 0:102b50f941d0 224 {0, 106, 5, 0, 1, 1, 0}, /* MCU_CORRUPTION_DETECTED_1 */
dgabino 0:102b50f941d0 225 {0, 106, 6, 0, 1, 0, 0}, /* MCU_SELECT_EDGE_0 */
dgabino 0:102b50f941d0 226 {0, 106, 7, 0, 1, 0, 0}, /* MCU_SELECT_EDGE_1 */
dgabino 0:102b50f941d0 227 {0, 107, 0, 0, 8, 0, 1}, /* CHANN_SELECT_RSSI */
dgabino 0:102b50f941d0 228 {0, 108, 0, 0, 8, 0, 32}, /* RSSI_BB_DEFAULT_VALUE */
dgabino 0:102b50f941d0 229 {0, 109, 0, 0, 8, 0, 100}, /* RSSI_DEC_DEFAULT_VALUE */
dgabino 0:102b50f941d0 230 {0, 110, 0, 0, 8, 0, 100}, /* RSSI_CHANN_DEFAULT_VALUE */
dgabino 0:102b50f941d0 231 {0, 111, 0, 0, 5, 0, 7}, /* RSSI_BB_FILTER_ALPHA */
dgabino 0:102b50f941d0 232 {0, 112, 0, 0, 5, 0, 5}, /* RSSI_DEC_FILTER_ALPHA */
dgabino 0:102b50f941d0 233 {0, 113, 0, 0, 5, 0, 8}, /* RSSI_CHANN_FILTER_ALPHA */
dgabino 0:102b50f941d0 234 {0, 114, 0, 0, 6, 0, 0}, /* IQ_MISMATCH_A_AMP_COEFF */
dgabino 0:102b50f941d0 235 {0, 115, 0, 0, 6, 0, 0}, /* IQ_MISMATCH_A_PHI_COEFF */
dgabino 0:102b50f941d0 236 {0, 116, 0, 0, 6, 0, 0}, /* IQ_MISMATCH_B_AMP_COEFF */
dgabino 0:102b50f941d0 237 {0, 116, 6, 0, 1, 0, 0}, /* IQ_MISMATCH_B_SEL_I */
dgabino 0:102b50f941d0 238 {0, 117, 0, 0, 6, 0, 0}, /* IQ_MISMATCH_B_PHI_COEFF */
dgabino 0:102b50f941d0 239 {1, 33, 0, 0, 1, 0, 0}, /* TX_TRIG_IMMEDIATE */
dgabino 0:102b50f941d0 240 {1, 33, 1, 0, 1, 0, 0}, /* TX_TRIG_DELAYED */
dgabino 0:102b50f941d0 241 {1, 33, 2, 0, 1, 0, 0}, /* TX_TRIG_GPS */
dgabino 0:102b50f941d0 242 {1, 34, 0, 0, 16, 0, 0}, /* TX_START_DELAY */
dgabino 0:102b50f941d0 243 {1, 36, 0, 0, 4, 0, 1}, /* TX_FRAME_SYNCH_PEAK1_POS */
dgabino 0:102b50f941d0 244 {1, 36, 4, 0, 4, 0, 2}, /* TX_FRAME_SYNCH_PEAK2_POS */
dgabino 0:102b50f941d0 245 {1, 37, 0, 0, 3, 0, 0}, /* TX_RAMP_DURATION */
dgabino 0:102b50f941d0 246 {1, 39, 0, 1, 8, 0, 0}, /* TX_OFFSET_I */
dgabino 0:102b50f941d0 247 {1, 40, 0, 1, 8, 0, 0}, /* TX_OFFSET_Q */
dgabino 0:102b50f941d0 248 {1, 41, 0, 0, 1, 0, 0}, /* TX_MODE */
dgabino 0:102b50f941d0 249 {1, 41, 1, 0, 4, 0, 0}, /* TX_ZERO_PAD */
dgabino 0:102b50f941d0 250 {1, 41, 5, 0, 1, 0, 0}, /* TX_EDGE_SELECT */
dgabino 0:102b50f941d0 251 {1, 41, 6, 0, 1, 0, 0}, /* TX_EDGE_SELECT_TOP */
dgabino 0:102b50f941d0 252 {1, 42, 0, 0, 2, 0, 0}, /* TX_GAIN */
dgabino 0:102b50f941d0 253 {1, 42, 2, 0, 3, 0, 5}, /* TX_CHIRP_LOW_PASS */
dgabino 0:102b50f941d0 254 {1, 42, 5, 0, 2, 0, 0}, /* TX_FCC_WIDEBAND */
dgabino 0:102b50f941d0 255 {1, 42, 7, 0, 1, 0, 1}, /* TX_SWAP_IQ */
dgabino 0:102b50f941d0 256 {1, 43, 0, 0, 1, 0, 0}, /* MBWSSF_IMPLICIT_HEADER */
dgabino 0:102b50f941d0 257 {1, 43, 1, 0, 1, 0, 0}, /* MBWSSF_IMPLICIT_CRC_EN */
dgabino 0:102b50f941d0 258 {1, 43, 2, 0, 3, 0, 0}, /* MBWSSF_IMPLICIT_CODING_RATE */
dgabino 0:102b50f941d0 259 {1, 44, 0, 0, 8, 0, 0}, /* MBWSSF_IMPLICIT_PAYLOAD_LENGHT */
dgabino 0:102b50f941d0 260 {1, 45, 0, 0, 1, 0, 1}, /* MBWSSF_AGC_FREEZE_ON_DETECT */
dgabino 0:102b50f941d0 261 {1, 46, 0, 0, 4, 0, 1}, /* MBWSSF_FRAME_SYNCH_PEAK1_POS */
dgabino 0:102b50f941d0 262 {1, 46, 4, 0, 4, 0, 2}, /* MBWSSF_FRAME_SYNCH_PEAK2_POS */
dgabino 0:102b50f941d0 263 {1, 47, 0, 0, 16, 0, 10}, /* MBWSSF_PREAMBLE_SYMB1_NB */
dgabino 0:102b50f941d0 264 {1, 49, 0, 0, 1, 0, 1}, /* MBWSSF_FRAME_SYNCH_GAIN */
dgabino 0:102b50f941d0 265 {1, 49, 1, 0, 1, 0, 1}, /* MBWSSF_SYNCH_DETECT_TH */
dgabino 0:102b50f941d0 266 {1, 50, 0, 0, 8, 0, 10}, /* MBWSSF_DETECT_MIN_SINGLE_PEAK */
dgabino 0:102b50f941d0 267 {1, 51, 0, 0, 3, 0, 3}, /* MBWSSF_DETECT_TRIG_SAME_PEAK_NB */
dgabino 0:102b50f941d0 268 {1, 52, 0, 0, 8, 0, 29}, /* MBWSSF_FREQ_TO_TIME_INVERT */
dgabino 0:102b50f941d0 269 {1, 53, 0, 0, 6, 0, 36}, /* MBWSSF_FREQ_TO_TIME_DRIFT */
dgabino 0:102b50f941d0 270 {1, 54, 0, 0, 12, 0, 0}, /* MBWSSF_PPM_CORRECTION */
dgabino 0:102b50f941d0 271 {1, 56, 0, 0, 2, 0, 2}, /* MBWSSF_PAYLOAD_FINE_TIMING_GAIN */
dgabino 0:102b50f941d0 272 {1, 56, 2, 0, 2, 0, 1}, /* MBWSSF_PREAMBLE_FINE_TIMING_GAIN */
dgabino 0:102b50f941d0 273 {1, 56, 4, 0, 2, 0, 0}, /* MBWSSF_TRACKING_INTEGRAL */
dgabino 0:102b50f941d0 274 {1, 57, 0, 0, 8, 0, 0}, /* MBWSSF_ZERO_PAD */
dgabino 0:102b50f941d0 275 {1, 58, 0, 0, 2, 0, 0}, /* MBWSSF_MODEM_BW */
dgabino 0:102b50f941d0 276 {1, 58, 2, 0, 1, 0, 0}, /* MBWSSF_RADIO_SELECT */
dgabino 0:102b50f941d0 277 {1, 58, 3, 0, 1, 0, 1}, /* MBWSSF_RX_CHIRP_INVERT */
dgabino 0:102b50f941d0 278 {1, 59, 0, 0, 4, 0, 8}, /* MBWSSF_LLR_SCALE */
dgabino 0:102b50f941d0 279 {1, 59, 4, 0, 2, 0, 3}, /* MBWSSF_SNR_AVG_CST */
dgabino 0:102b50f941d0 280 {1, 59, 6, 0, 1, 0, 0}, /* MBWSSF_PPM_OFFSET */
dgabino 0:102b50f941d0 281 {1, 60, 0, 0, 4, 0, 7}, /* MBWSSF_RATE_SF */
dgabino 0:102b50f941d0 282 {1, 60, 4, 0, 1, 0, 1}, /* MBWSSF_ONLY_CRC_EN */
dgabino 0:102b50f941d0 283 {1, 61, 0, 0, 8, 0, 255}, /* MBWSSF_MAX_PAYLOAD_LEN */
dgabino 0:102b50f941d0 284 {1, 62, 0, 0, 8, 1, 128}, /* TX_STATUS */
dgabino 0:102b50f941d0 285 {1, 63, 0, 0, 3, 0, 0}, /* FSK_CH_BW_EXPO */
dgabino 0:102b50f941d0 286 {1, 63, 3, 0, 3, 0, 0}, /* FSK_RSSI_LENGTH */
dgabino 0:102b50f941d0 287 {1, 63, 6, 0, 1, 0, 0}, /* FSK_RX_INVERT */
dgabino 0:102b50f941d0 288 {1, 63, 7, 0, 1, 0, 0}, /* FSK_PKT_MODE */
dgabino 0:102b50f941d0 289 {1, 64, 0, 0, 3, 0, 0}, /* FSK_PSIZE */
dgabino 0:102b50f941d0 290 {1, 64, 3, 0, 1, 0, 0}, /* FSK_CRC_EN */
dgabino 0:102b50f941d0 291 {1, 64, 4, 0, 2, 0, 0}, /* FSK_DCFREE_ENC */
dgabino 0:102b50f941d0 292 {1, 64, 6, 0, 1, 0, 0}, /* FSK_CRC_IBM */
dgabino 0:102b50f941d0 293 {1, 65, 0, 0, 5, 0, 0}, /* FSK_ERROR_OSR_TOL */
dgabino 0:102b50f941d0 294 {1, 65, 7, 0, 1, 0, 0}, /* FSK_RADIO_SELECT */
dgabino 0:102b50f941d0 295 {1, 66, 0, 0, 16, 0, 0}, /* FSK_BR_RATIO */
dgabino 0:102b50f941d0 296 {1, 68, 0, 0, 32, 0, 0}, /* FSK_REF_PATTERN_LSB */
dgabino 0:102b50f941d0 297 {1, 72, 0, 0, 32, 0, 0}, /* FSK_REF_PATTERN_MSB */
dgabino 0:102b50f941d0 298 {1, 76, 0, 0, 8, 0, 0}, /* FSK_PKT_LENGTH */
dgabino 0:102b50f941d0 299 {1, 77, 0, 0, 1, 0, 1}, /* FSK_TX_GAUSSIAN_EN */
dgabino 0:102b50f941d0 300 {1, 77, 1, 0, 2, 0, 0}, /* FSK_TX_GAUSSIAN_SELECT_BT */
dgabino 0:102b50f941d0 301 {1, 77, 3, 0, 1, 0, 1}, /* FSK_TX_PATTERN_EN */
dgabino 0:102b50f941d0 302 {1, 77, 4, 0, 1, 0, 0}, /* FSK_TX_PREAMBLE_SEQ */
dgabino 0:102b50f941d0 303 {1, 77, 5, 0, 3, 0, 0}, /* FSK_TX_PSIZE */
dgabino 0:102b50f941d0 304 {1, 80, 0, 0, 8, 0, 0}, /* FSK_NODE_ADRS */
dgabino 0:102b50f941d0 305 {1, 81, 0, 0, 8, 0, 0}, /* FSK_BROADCAST */
dgabino 0:102b50f941d0 306 {1, 82, 0, 0, 1, 0, 1}, /* FSK_AUTO_AFC_ON */
dgabino 0:102b50f941d0 307 {1, 83, 0, 0, 10, 0, 0}, /* FSK_PATTERN_TIMEOUT_CFG */
dgabino 0:102b50f941d0 308 {2, 33, 0, 0, 8, 0, 0}, /* SPI_RADIO_A__DATA */
dgabino 0:102b50f941d0 309 {2, 34, 0, 0, 8, 1, 0}, /* SPI_RADIO_A__DATA_READBACK */
dgabino 0:102b50f941d0 310 {2, 35, 0, 0, 8, 0, 0}, /* SPI_RADIO_A__ADDR */
dgabino 0:102b50f941d0 311 {2, 37, 0, 0, 1, 0, 0}, /* SPI_RADIO_A__CS */
dgabino 0:102b50f941d0 312 {2, 38, 0, 0, 8, 0, 0}, /* SPI_RADIO_B__DATA */
dgabino 0:102b50f941d0 313 {2, 39, 0, 0, 8, 1, 0}, /* SPI_RADIO_B__DATA_READBACK */
dgabino 0:102b50f941d0 314 {2, 40, 0, 0, 8, 0, 0}, /* SPI_RADIO_B__ADDR */
dgabino 0:102b50f941d0 315 {2, 42, 0, 0, 1, 0, 0}, /* SPI_RADIO_B__CS */
dgabino 0:102b50f941d0 316 {2, 43, 0, 0, 1, 0, 0}, /* RADIO_A_EN */
dgabino 0:102b50f941d0 317 {2, 43, 1, 0, 1, 0, 0}, /* RADIO_B_EN */
dgabino 0:102b50f941d0 318 {2, 43, 2, 0, 1, 0, 1}, /* RADIO_RST */
dgabino 0:102b50f941d0 319 {2, 43, 3, 0, 1, 0, 0}, /* LNA_A_EN */
dgabino 0:102b50f941d0 320 {2, 43, 4, 0, 1, 0, 0}, /* PA_A_EN */
dgabino 0:102b50f941d0 321 {2, 43, 5, 0, 1, 0, 0}, /* LNA_B_EN */
dgabino 0:102b50f941d0 322 {2, 43, 6, 0, 1, 0, 0}, /* PA_B_EN */
dgabino 0:102b50f941d0 323 {2, 44, 0, 0, 2, 0, 0}, /* PA_GAIN */
dgabino 0:102b50f941d0 324 {2, 45, 0, 0, 4, 0, 2}, /* LNA_A_CTRL_LUT */
dgabino 0:102b50f941d0 325 {2, 45, 4, 0, 4, 0, 4}, /* PA_A_CTRL_LUT */
dgabino 0:102b50f941d0 326 {2, 46, 0, 0, 4, 0, 2}, /* LNA_B_CTRL_LUT */
dgabino 0:102b50f941d0 327 {2, 46, 4, 0, 4, 0, 4}, /* PA_B_CTRL_LUT */
dgabino 0:102b50f941d0 328 {2, 47, 0, 0, 5, 0, 0}, /* CAPTURE_SOURCE */
dgabino 0:102b50f941d0 329 {2, 47, 5, 0, 1, 0, 0}, /* CAPTURE_START */
dgabino 0:102b50f941d0 330 {2, 47, 6, 0, 1, 0, 0}, /* CAPTURE_FORCE_TRIGGER */
dgabino 0:102b50f941d0 331 {2, 47, 7, 0, 1, 0, 0}, /* CAPTURE_WRAP */
dgabino 0:102b50f941d0 332 {2, 48, 0, 0, 16, 0, 0}, /* CAPTURE_PERIOD */
dgabino 0:102b50f941d0 333 {2, 51, 0, 0, 8, 1, 0}, /* MODEM_STATUS */
dgabino 0:102b50f941d0 334 {2, 52, 0, 0, 8, 1, 0}, /* VALID_HEADER_COUNTER_0 */
dgabino 0:102b50f941d0 335 {2, 54, 0, 0, 8, 1, 0}, /* VALID_PACKET_COUNTER_0 */
dgabino 0:102b50f941d0 336 {2, 56, 0, 0, 8, 1, 0}, /* VALID_HEADER_COUNTER_MBWSSF */
dgabino 0:102b50f941d0 337 {2, 57, 0, 0, 8, 1, 0}, /* VALID_HEADER_COUNTER_FSK */
dgabino 0:102b50f941d0 338 {2, 58, 0, 0, 8, 1, 0}, /* VALID_PACKET_COUNTER_MBWSSF */
dgabino 0:102b50f941d0 339 {2, 59, 0, 0, 8, 1, 0}, /* VALID_PACKET_COUNTER_FSK */
dgabino 0:102b50f941d0 340 {2, 60, 0, 0, 8, 1, 0}, /* CHANN_RSSI */
dgabino 0:102b50f941d0 341 {2, 61, 0, 0, 8, 1, 0}, /* BB_RSSI */
dgabino 0:102b50f941d0 342 {2, 62, 0, 0, 8, 1, 0}, /* DEC_RSSI */
dgabino 0:102b50f941d0 343 {2, 63, 0, 0, 8, 1, 0}, /* DBG_MCU_DATA */
dgabino 0:102b50f941d0 344 {2, 64, 0, 0, 8, 1, 0}, /* DBG_ARB_MCU_RAM_DATA */
dgabino 0:102b50f941d0 345 {2, 65, 0, 0, 8, 1, 0}, /* DBG_AGC_MCU_RAM_DATA */
dgabino 0:102b50f941d0 346 {2, 66, 0, 0, 16, 1, 0}, /* NEXT_PACKET_CNT */
dgabino 0:102b50f941d0 347 {2, 68, 0, 0, 16, 1, 0}, /* ADDR_CAPTURE_COUNT */
dgabino 0:102b50f941d0 348 {2, 70, 0, 0, 32, 1, 0}, /* TIMESTAMP */
dgabino 0:102b50f941d0 349 {2, 74, 0, 0, 4, 1, 0}, /* DBG_CHANN0_GAIN */
dgabino 0:102b50f941d0 350 {2, 74, 4, 0, 4, 1, 0}, /* DBG_CHANN1_GAIN */
dgabino 0:102b50f941d0 351 {2, 75, 0, 0, 4, 1, 0}, /* DBG_CHANN2_GAIN */
dgabino 0:102b50f941d0 352 {2, 75, 4, 0, 4, 1, 0}, /* DBG_CHANN3_GAIN */
dgabino 0:102b50f941d0 353 {2, 76, 0, 0, 4, 1, 0}, /* DBG_CHANN4_GAIN */
dgabino 0:102b50f941d0 354 {2, 76, 4, 0, 4, 1, 0}, /* DBG_CHANN5_GAIN */
dgabino 0:102b50f941d0 355 {2, 77, 0, 0, 4, 1, 0}, /* DBG_CHANN6_GAIN */
dgabino 0:102b50f941d0 356 {2, 77, 4, 0, 4, 1, 0}, /* DBG_CHANN7_GAIN */
dgabino 0:102b50f941d0 357 {2, 78, 0, 0, 4, 1, 0}, /* DBG_DEC_FILT_GAIN */
dgabino 0:102b50f941d0 358 {2, 79, 0, 0, 3, 1, 0}, /* com_DATA_FIFO_PTR */
dgabino 0:102b50f941d0 359 {2, 79, 3, 0, 3, 1, 0}, /* PACKET_DATA_FIFO_PTR */
dgabino 0:102b50f941d0 360 {2, 80, 0, 0, 8, 0, 0}, /* DBG_ARB_MCU_RAM_ADDR */
dgabino 0:102b50f941d0 361 {2, 81, 0, 0, 8, 0, 0}, /* DBG_AGC_MCU_RAM_ADDR */
dgabino 0:102b50f941d0 362 {2, 82, 0, 0, 1, 0, 0}, /* com_MASTER_CHIP_SELECT_POLARITY */
dgabino 0:102b50f941d0 363 {2, 82, 1, 0, 1, 0, 0}, /* com_MASTER_CPOL */
dgabino 0:102b50f941d0 364 {2, 82, 2, 0, 1, 0, 0}, /* com_MASTER_CPHA */
dgabino 0:102b50f941d0 365 {2, 83, 0, 0, 1, 0, 0}, /* SIG_GEN_ANALYSER_MUX_SEL */
dgabino 0:102b50f941d0 366 {2, 84, 0, 0, 1, 0, 0}, /* SIG_GEN_EN */
dgabino 0:102b50f941d0 367 {2, 84, 1, 0, 1, 0, 0}, /* SIG_ANALYSER_EN */
dgabino 0:102b50f941d0 368 {2, 84, 2, 0, 2, 0, 0}, /* SIG_ANALYSER_AVG_LEN */
dgabino 0:102b50f941d0 369 {2, 84, 4, 0, 3, 0, 0}, /* SIG_ANALYSER_PRECISION */
dgabino 0:102b50f941d0 370 {2, 84, 7, 0, 1, 1, 0}, /* SIG_ANALYSER_VALID_OUT */
dgabino 0:102b50f941d0 371 {2, 85, 0, 0, 8, 0, 0}, /* SIG_GEN_FREQ */
dgabino 0:102b50f941d0 372 {2, 86, 0, 0, 8, 0, 0}, /* SIG_ANALYSER_FREQ */
dgabino 0:102b50f941d0 373 {2, 87, 0, 0, 8, 1, 0}, /* SIG_ANALYSER_I_OUT */
dgabino 0:102b50f941d0 374 {2, 88, 0, 0, 8, 1, 0}, /* SIG_ANALYSER_Q_OUT */
dgabino 0:102b50f941d0 375 {2, 89, 0, 0, 1, 0, 0}, /* GPS_EN */
dgabino 0:102b50f941d0 376 {2, 89, 1, 0, 1, 0, 1}, /* GPS_POL */
dgabino 0:102b50f941d0 377 {2, 90, 0, 1, 8, 0, 0}, /* SW_TEST_REG1 */
dgabino 0:102b50f941d0 378 {2, 91, 2, 1, 6, 0, 0}, /* SW_TEST_REG2 */
dgabino 0:102b50f941d0 379 {2, 92, 0, 1, 16, 0, 0}, /* SW_TEST_REG3 */
dgabino 0:102b50f941d0 380 {2, 94, 0, 0, 4, 1, 0}, /* DATA_MNGT_STATUS */
dgabino 0:102b50f941d0 381 {2, 95, 0, 0, 5, 1, 0}, /* DATA_MNGT_CPT_FRAME_ALLOCATED */
dgabino 0:102b50f941d0 382 {2, 96, 0, 0, 5, 1, 0}, /* DATA_MNGT_CPT_FRAME_FINISHED */
dgabino 0:102b50f941d0 383 {2, 97, 0, 0, 5, 1, 0}, /* DATA_MNGT_CPT_FRAME_READEN */
dgabino 0:102b50f941d0 384 {1, 33, 0, 0, 8, 0, 0} /* TX_TRIG_ALL (alias) */
dgabino 0:102b50f941d0 385 };
dgabino 0:102b50f941d0 386
dgabino 0:102b50f941d0 387 /* -------------------------------------------------------------------------- */
dgabino 0:102b50f941d0 388 /* --- PRIVATE VARIABLES ---------------------------------------------------- */
dgabino 0:102b50f941d0 389
dgabino 0:102b50f941d0 390 void *lgw_com_target = NULL; /*! generic pointer to the COM device */
dgabino 0:102b50f941d0 391 static int lgw_regpage = -1; /*! keep the value of the register page selected */
dgabino 0:102b50f941d0 392 uint8_t lgw_com_mux_mode = 0; /*! current SPI mux mode used */
dgabino 0:102b50f941d0 393
dgabino 0:102b50f941d0 394 /* -------------------------------------------------------------------------- */
dgabino 0:102b50f941d0 395 /* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
dgabino 0:102b50f941d0 396
dgabino 0:102b50f941d0 397 int page_switch(uint8_t target) {
dgabino 0:102b50f941d0 398 lgw_regpage = PAGE_MASK & target;
dgabino 0:102b50f941d0 399 lgw_com_w(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, PAGE_ADDR, (uint8_t)lgw_regpage);
dgabino 0:102b50f941d0 400 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 401 }
dgabino 0:102b50f941d0 402
dgabino 0:102b50f941d0 403 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 404
dgabino 0:102b50f941d0 405 int reg_w_align32(void *com_target, uint8_t com_mux_mode, uint8_t com_mux_target, struct lgw_reg_s r, int32_t reg_value) {
dgabino 0:102b50f941d0 406 int com_stat = LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 407 int i, size_byte;
dgabino 0:102b50f941d0 408 uint8_t buf[4] = "\x00\x00\x00\x00";
dgabino 0:102b50f941d0 409
dgabino 0:102b50f941d0 410 if ((r.leng == 8) && (r.offs == 0)) {
dgabino 0:102b50f941d0 411 /* direct write */
dgabino 0:102b50f941d0 412 com_stat += lgw_com_w(com_target, com_mux_mode, com_mux_target, r.addr, (uint8_t)reg_value);
dgabino 0:102b50f941d0 413 } else if ((r.offs + r.leng) <= 8) {
dgabino 0:102b50f941d0 414 /* single-byte read-modify-write, offs:[0-7], leng:[1-7] */
dgabino 0:102b50f941d0 415 com_stat += lgw_com_r(com_target, com_mux_mode, com_mux_target, r.addr, &buf[0]);
dgabino 0:102b50f941d0 416 buf[1] = ((1 << r.leng) - 1) << r.offs; /* bit mask */
dgabino 0:102b50f941d0 417 buf[2] = ((uint8_t)reg_value) << r.offs; /* new data offsetted */
dgabino 0:102b50f941d0 418 buf[3] = (~buf[1] & buf[0]) | (buf[1] & buf[2]); /* mixing old & new data */
dgabino 0:102b50f941d0 419 com_stat += lgw_com_w(com_target, com_mux_mode, com_mux_target, r.addr, buf[3]);
dgabino 0:102b50f941d0 420 } else if ((r.offs == 0) && (r.leng > 0) && (r.leng <= 32)) {
dgabino 0:102b50f941d0 421 /* multi-byte direct write routine */
dgabino 0:102b50f941d0 422 size_byte = (r.leng + 7) / 8; /* add a byte if it's not an exact multiple of 8 */
dgabino 0:102b50f941d0 423 for (i = 0; i < size_byte; ++i) {
dgabino 0:102b50f941d0 424 /* big endian register file for a file on N bytes
dgabino 0:102b50f941d0 425 Least significant byte is stored in buf[0], most one in buf[N-1] */
dgabino 0:102b50f941d0 426 buf[i] = (uint8_t)(0x000000FF & reg_value);
dgabino 0:102b50f941d0 427 reg_value = (reg_value >> 8);
dgabino 0:102b50f941d0 428 }
dgabino 0:102b50f941d0 429 com_stat += lgw_com_wb(com_target, com_mux_mode, com_mux_target, r.addr, buf, size_byte); /* write the register in one burst */
dgabino 0:102b50f941d0 430 } else {
dgabino 0:102b50f941d0 431 /* register spanning multiple memory bytes but with an offset */
dgabino 0:102b50f941d0 432 DEBUG_MSG("ERROR: REGISTER SIZE AND OFFSET ARE NOT SUPPORTED\n");
dgabino 0:102b50f941d0 433 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 434 }
dgabino 0:102b50f941d0 435
dgabino 0:102b50f941d0 436 return com_stat;
dgabino 0:102b50f941d0 437 }
dgabino 0:102b50f941d0 438
dgabino 0:102b50f941d0 439 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 440
dgabino 0:102b50f941d0 441 int reg_r_align32(void *com_target, uint8_t com_mux_mode, uint8_t com_mux_target, struct lgw_reg_s r, int32_t *reg_value) {
dgabino 0:102b50f941d0 442 int com_stat = LGW_COM_SUCCESS;
dgabino 0:102b50f941d0 443 uint8_t bufu[4] = "\x00\x00\x00\x00";
dgabino 0:102b50f941d0 444 int8_t *bufs = (int8_t *)bufu;
dgabino 0:102b50f941d0 445 int i, size_byte;
dgabino 0:102b50f941d0 446 uint32_t u = 0;
dgabino 0:102b50f941d0 447
dgabino 0:102b50f941d0 448 if ((r.offs + r.leng) <= 8) {
dgabino 0:102b50f941d0 449 /* read one byte, then shift and mask bits to get reg value with sign extension if needed */
dgabino 0:102b50f941d0 450 com_stat += lgw_com_r(com_target, com_mux_mode, com_mux_target, r.addr, &bufu[0]);
dgabino 0:102b50f941d0 451 bufu[1] = bufu[0] << (8 - r.leng - r.offs); /* left-align the data */
dgabino 0:102b50f941d0 452 if (r.sign == true) {
dgabino 0:102b50f941d0 453 bufs[2] = bufs[1] >> (8 - r.leng); /* right align the data with sign extension (ARITHMETIC right shift) */
dgabino 0:102b50f941d0 454 *reg_value = (int32_t)bufs[2]; /* signed pointer -> 32b sign extension */
dgabino 0:102b50f941d0 455 } else {
dgabino 0:102b50f941d0 456 bufu[2] = bufu[1] >> (8 - r.leng); /* right align the data, no sign extension */
dgabino 0:102b50f941d0 457 *reg_value = (int32_t)bufu[2]; /* unsigned pointer -> no sign extension */
dgabino 0:102b50f941d0 458 }
dgabino 0:102b50f941d0 459 } else if ((r.offs == 0) && (r.leng > 0) && (r.leng <= 32)) {
dgabino 0:102b50f941d0 460 size_byte = (r.leng + 7) / 8; /* add a byte if it's not an exact multiple of 8 */
dgabino 0:102b50f941d0 461 com_stat += lgw_com_rb(com_target, com_mux_mode, com_mux_target, r.addr, bufu, size_byte);
dgabino 0:102b50f941d0 462 u = 0;
dgabino 0:102b50f941d0 463 for (i = (size_byte - 1); i >= 0; --i) {
dgabino 0:102b50f941d0 464 u = (uint32_t)bufu[i] + (u << 8); /* transform a 4-byte array into a 32 bit word */
dgabino 0:102b50f941d0 465 }
dgabino 0:102b50f941d0 466 if (r.sign == true) {
dgabino 0:102b50f941d0 467 u = u << (32 - r.leng); /* left-align the data */
dgabino 0:102b50f941d0 468 *reg_value = (int32_t)u >> (32 - r.leng); /* right-align the data with sign extension (ARITHMETIC right shift) */
dgabino 0:102b50f941d0 469 } else {
dgabino 0:102b50f941d0 470 *reg_value = (int32_t)u; /* unsigned value -> return 'as is' */
dgabino 0:102b50f941d0 471 }
dgabino 0:102b50f941d0 472 } else {
dgabino 0:102b50f941d0 473 /* register spanning multiple memory bytes but with an offset */
dgabino 0:102b50f941d0 474 DEBUG_MSG("ERROR: REGISTER SIZE AND OFFSET ARE NOT SUPPORTED\n");
dgabino 0:102b50f941d0 475 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 476 }
dgabino 0:102b50f941d0 477
dgabino 0:102b50f941d0 478 return com_stat;
dgabino 0:102b50f941d0 479 }
dgabino 0:102b50f941d0 480
dgabino 0:102b50f941d0 481 /* -------------------------------------------------------------------------- */
dgabino 0:102b50f941d0 482 /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
dgabino 0:102b50f941d0 483
dgabino 0:102b50f941d0 484 /* Concentrator connect */
dgabino 0:102b50f941d0 485 int lgw_connect(const char *com_path) {
dgabino 0:102b50f941d0 486 uint8_t uid[8];
dgabino 0:102b50f941d0 487 int com_stat = LGW_COM_SUCCESS;
dgabino 0:102b50f941d0 488 uint8_t u = 0;
dgabino 0:102b50f941d0 489
dgabino 0:102b50f941d0 490 DEBUG_MSG("Note: Connecting to concentrator...\n");
dgabino 0:102b50f941d0 491
dgabino 0:102b50f941d0 492 /* check COM link status */
dgabino 0:102b50f941d0 493 if (lgw_com_target != NULL) {
dgabino 0:102b50f941d0 494 DEBUG_MSG("WARNING: concentrator was already connected\n");
dgabino 0:102b50f941d0 495 lgw_com_close(lgw_com_target);
dgabino 0:102b50f941d0 496 }
dgabino 0:102b50f941d0 497
dgabino 0:102b50f941d0 498 /* open the COM link */
dgabino 0:102b50f941d0 499 com_stat = lgw_com_open(&lgw_com_target, com_path);
dgabino 0:102b50f941d0 500 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 501 DEBUG_MSG("ERROR: FAIL TO CONNECT CONCENTRATOR\n");
dgabino 0:102b50f941d0 502 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 503 }
dgabino 0:102b50f941d0 504
dgabino 0:102b50f941d0 505 DEBUG_PRINTF("Note: %s opened successfully\n", com_path);
dgabino 0:102b50f941d0 506
dgabino 0:102b50f941d0 507 /* check MCU FW version */
dgabino 0:102b50f941d0 508 com_stat = lgw_mcu_get_unique_id(&uid[0]);
dgabino 0:102b50f941d0 509 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 510 DEBUG_MSG("ERROR: MCU FW VERSION CHECK FAILED\n");
dgabino 0:102b50f941d0 511 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 512 }
dgabino 0:102b50f941d0 513
dgabino 0:102b50f941d0 514 DEBUG_PRINTF("Note: MCU firmware version checked: 0x%X\n", STM32FWVERSION);
dgabino 0:102b50f941d0 515
dgabino 0:102b50f941d0 516 lgw_com_mux_mode = LGW_COM_MUX_MODE0;
dgabino 0:102b50f941d0 517
dgabino 0:102b50f941d0 518 /* check SX1301 version */
dgabino 0:102b50f941d0 519 com_stat = lgw_com_r(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, loregs[LGW_VERSION].addr, &u);
dgabino 0:102b50f941d0 520 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 521 DEBUG_MSG("ERROR READING CHIP VERSION REGISTER\n");
dgabino 0:102b50f941d0 522 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 523 }
dgabino 0:102b50f941d0 524 if (u != loregs[LGW_VERSION].dflt) {
dgabino 0:102b50f941d0 525 DEBUG_PRINTF("ERROR: NOT EXPECTED CHIP VERSION (v%u)\n", u);
dgabino 0:102b50f941d0 526 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 527 }
dgabino 0:102b50f941d0 528
dgabino 0:102b50f941d0 529 /* write 0 to the page/reset register */
dgabino 0:102b50f941d0 530 com_stat = lgw_com_w(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, loregs[LGW_PAGE_REG].addr, 0);
dgabino 0:102b50f941d0 531 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 532 DEBUG_MSG("ERROR WRITING PAGE REGISTER\n");
dgabino 0:102b50f941d0 533 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 534 } else {
dgabino 0:102b50f941d0 535 lgw_regpage = 0;
dgabino 0:102b50f941d0 536 }
dgabino 0:102b50f941d0 537
dgabino 0:102b50f941d0 538 DEBUG_MSG("Note: success connecting the concentrator\n");
dgabino 0:102b50f941d0 539 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 540 }
dgabino 0:102b50f941d0 541
dgabino 0:102b50f941d0 542 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 543
dgabino 0:102b50f941d0 544 /* Concentrator disconnect */
dgabino 0:102b50f941d0 545 int lgw_disconnect(void) {
dgabino 0:102b50f941d0 546 if (lgw_com_target != NULL) {
dgabino 0:102b50f941d0 547 /* reset MCU */
dgabino 0:102b50f941d0 548 lgw_mcu_reset();
dgabino 0:102b50f941d0 549 /* close COM bridge immediatly after reset to avoid re-enumeration
dgabino 0:102b50f941d0 550 before close */
dgabino 0:102b50f941d0 551 lgw_com_close(lgw_com_target);
dgabino 0:102b50f941d0 552 /* Wait for MCU reset and COM initialization to be complete before
dgabino 0:102b50f941d0 553 returning to avoid trying to restart while MCU is still starting up */
dgabino 0:102b50f941d0 554 wait_ms(MCU_DELAY_COM_INIT + MCU_DELAY_RESET);
dgabino 0:102b50f941d0 555 /* exit */
dgabino 0:102b50f941d0 556 lgw_com_target = NULL;
dgabino 0:102b50f941d0 557 DEBUG_MSG("Note: success disconnecting the concentrator\n");
dgabino 0:102b50f941d0 558 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 559 } else {
dgabino 0:102b50f941d0 560 DEBUG_MSG("WARNING: concentrator was already disconnected\n");
dgabino 0:102b50f941d0 561 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 562 }
dgabino 0:102b50f941d0 563 }
dgabino 0:102b50f941d0 564
dgabino 0:102b50f941d0 565 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 566
dgabino 0:102b50f941d0 567 /* soft-reset function */
dgabino 0:102b50f941d0 568 int lgw_soft_reset(void) {
dgabino 0:102b50f941d0 569 /* check if SPI is initialised */
dgabino 0:102b50f941d0 570 if ((lgw_com_target == NULL) || (lgw_regpage < 0)) {
dgabino 0:102b50f941d0 571 DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n");
dgabino 0:102b50f941d0 572 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 573 }
dgabino 0:102b50f941d0 574 lgw_com_w(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, 0, 0x80); /* 1 -> SOFT_RESET bit */
dgabino 0:102b50f941d0 575 lgw_regpage = 0; /* reset the paging static variable */
dgabino 0:102b50f941d0 576 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 577 }
dgabino 0:102b50f941d0 578
dgabino 0:102b50f941d0 579 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 580
dgabino 0:102b50f941d0 581 /* register verification */
dgabino 0:102b50f941d0 582 int lgw_reg_check(FILE *f) {
dgabino 0:102b50f941d0 583 struct lgw_reg_s r;
dgabino 0:102b50f941d0 584 int32_t read_value;
dgabino 0:102b50f941d0 585 char ok_msg[] = "+++MATCH+++";
dgabino 0:102b50f941d0 586 char notok_msg[] = "###MISMATCH###";
dgabino 0:102b50f941d0 587 char *ptr;
dgabino 0:102b50f941d0 588 int i;
dgabino 0:102b50f941d0 589
dgabino 0:102b50f941d0 590 /* check if SPI is initialised */
dgabino 0:102b50f941d0 591 if ((lgw_com_target == NULL) || (lgw_regpage < 0)) {
dgabino 0:102b50f941d0 592 DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n");
dgabino 0:102b50f941d0 593 fprintf(f, "ERROR: CONCENTRATOR UNCONNECTED\n");
dgabino 0:102b50f941d0 594 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 595 }
dgabino 0:102b50f941d0 596
dgabino 0:102b50f941d0 597 fprintf(f, "Start of register verification\n");
dgabino 0:102b50f941d0 598 for (i = 0; i < LGW_TOTALREGS; ++i) {
dgabino 0:102b50f941d0 599 r = loregs[i];
dgabino 0:102b50f941d0 600 lgw_reg_r(i, &read_value);
dgabino 0:102b50f941d0 601 ptr = (read_value == r.dflt) ? ok_msg : notok_msg;
dgabino 0:102b50f941d0 602 if (r.sign == true) {
dgabino 0:102b50f941d0 603 fprintf(f, "%s reg number %d read: %d (%x) default: %d (%x)\n", ptr, i, read_value, read_value, r.dflt, r.dflt);
dgabino 0:102b50f941d0 604 } else {
dgabino 0:102b50f941d0 605 fprintf(f, "%s reg number %d read: %d (%x) default: %d (%x)\n", ptr, i, read_value, read_value, r.dflt, r.dflt);
dgabino 0:102b50f941d0 606 }
dgabino 0:102b50f941d0 607 }
dgabino 0:102b50f941d0 608 fprintf(f, "End of register verification\n");
dgabino 0:102b50f941d0 609
dgabino 0:102b50f941d0 610 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 611 }
dgabino 0:102b50f941d0 612
dgabino 0:102b50f941d0 613 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 614
dgabino 0:102b50f941d0 615 /* Write to a register addressed by name */
dgabino 0:102b50f941d0 616 int lgw_reg_w(uint16_t register_id, int32_t reg_value) {
dgabino 0:102b50f941d0 617 int com_stat = LGW_COM_SUCCESS;
dgabino 0:102b50f941d0 618 struct lgw_reg_s r;
dgabino 0:102b50f941d0 619
dgabino 0:102b50f941d0 620 /* check input parameters */
dgabino 0:102b50f941d0 621 if (register_id >= LGW_TOTALREGS) {
dgabino 0:102b50f941d0 622 DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n");
dgabino 0:102b50f941d0 623 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 624 }
dgabino 0:102b50f941d0 625
dgabino 0:102b50f941d0 626 /* check if SPI is initialised */
dgabino 0:102b50f941d0 627 if ((lgw_com_target == NULL) || (lgw_regpage < 0)) {
dgabino 0:102b50f941d0 628 DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n");
dgabino 0:102b50f941d0 629 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 630 }
dgabino 0:102b50f941d0 631
dgabino 0:102b50f941d0 632 /* intercept direct access to PAGE_REG & SOFT_RESET */
dgabino 0:102b50f941d0 633 if (register_id == LGW_PAGE_REG) {
dgabino 0:102b50f941d0 634 page_switch(reg_value);
dgabino 0:102b50f941d0 635 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 636 } else if (register_id == LGW_SOFT_RESET) {
dgabino 0:102b50f941d0 637 /* only reset if lsb is 1 */
dgabino 0:102b50f941d0 638 if ((reg_value & 0x01) != 0) {
dgabino 0:102b50f941d0 639 lgw_soft_reset();
dgabino 0:102b50f941d0 640 }
dgabino 0:102b50f941d0 641 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 642 }
dgabino 0:102b50f941d0 643
dgabino 0:102b50f941d0 644 /* get register struct from the struct array */
dgabino 0:102b50f941d0 645 r = loregs[register_id];
dgabino 0:102b50f941d0 646
dgabino 0:102b50f941d0 647 /* reject write to read-only registers */
dgabino 0:102b50f941d0 648 if (r.rdon == 1) {
dgabino 0:102b50f941d0 649 DEBUG_MSG("ERROR: TRYING TO WRITE A READ-ONLY REGISTER\n");
dgabino 0:102b50f941d0 650 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 651 }
dgabino 0:102b50f941d0 652
dgabino 0:102b50f941d0 653 /* select proper register page if needed */
dgabino 0:102b50f941d0 654 if ((r.page != -1) && (r.page != lgw_regpage)) {
dgabino 0:102b50f941d0 655 com_stat += page_switch(r.page);
dgabino 0:102b50f941d0 656 }
dgabino 0:102b50f941d0 657
dgabino 0:102b50f941d0 658 com_stat += reg_w_align32(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, r, reg_value);
dgabino 0:102b50f941d0 659
dgabino 0:102b50f941d0 660 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 661 DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER WRITE\n");
dgabino 0:102b50f941d0 662 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 663 } else {
dgabino 0:102b50f941d0 664 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 665 }
dgabino 0:102b50f941d0 666 }
dgabino 0:102b50f941d0 667
dgabino 0:102b50f941d0 668 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 669
dgabino 0:102b50f941d0 670 /* Read to a register addressed by name */
dgabino 0:102b50f941d0 671 int lgw_reg_r(uint16_t register_id, int32_t *reg_value) {
dgabino 0:102b50f941d0 672 int com_stat = LGW_COM_SUCCESS;
dgabino 0:102b50f941d0 673 struct lgw_reg_s r;
dgabino 0:102b50f941d0 674
dgabino 0:102b50f941d0 675 /* check input parameters */
dgabino 0:102b50f941d0 676 CHECK_NULL(reg_value);
dgabino 0:102b50f941d0 677 if (register_id >= LGW_TOTALREGS) {
dgabino 0:102b50f941d0 678 DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n");
dgabino 0:102b50f941d0 679 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 680 }
dgabino 0:102b50f941d0 681
dgabino 0:102b50f941d0 682 /* check if SPI is initialised */
dgabino 0:102b50f941d0 683 if ((lgw_com_target == NULL) || (lgw_regpage < 0)) {
dgabino 0:102b50f941d0 684 DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n");
dgabino 0:102b50f941d0 685 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 686 }
dgabino 0:102b50f941d0 687
dgabino 0:102b50f941d0 688 /* get register struct from the struct array */
dgabino 0:102b50f941d0 689 r = loregs[register_id];
dgabino 0:102b50f941d0 690
dgabino 0:102b50f941d0 691 /* select proper register page if needed */
dgabino 0:102b50f941d0 692 if ((r.page != -1) && (r.page != lgw_regpage)) {
dgabino 0:102b50f941d0 693 com_stat += page_switch(r.page);
dgabino 0:102b50f941d0 694 }
dgabino 0:102b50f941d0 695
dgabino 0:102b50f941d0 696 com_stat += reg_r_align32(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, r, reg_value);
dgabino 0:102b50f941d0 697
dgabino 0:102b50f941d0 698 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 699 DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER WRITE\n");
dgabino 0:102b50f941d0 700 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 701 } else {
dgabino 0:102b50f941d0 702 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 703 }
dgabino 0:102b50f941d0 704 }
dgabino 0:102b50f941d0 705
dgabino 0:102b50f941d0 706 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 707
dgabino 0:102b50f941d0 708 /* Point to a register by name and do a burst write */
dgabino 0:102b50f941d0 709 int lgw_reg_wb(uint16_t register_id, uint8_t *data, uint16_t size) {
dgabino 0:102b50f941d0 710 int com_stat = LGW_COM_SUCCESS;
dgabino 0:102b50f941d0 711 struct lgw_reg_s r;
dgabino 0:102b50f941d0 712
dgabino 0:102b50f941d0 713 /* check input parameters */
dgabino 0:102b50f941d0 714 CHECK_NULL(data);
dgabino 0:102b50f941d0 715 if (size == 0) {
dgabino 0:102b50f941d0 716 DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n");
dgabino 0:102b50f941d0 717 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 718 }
dgabino 0:102b50f941d0 719 if (register_id >= LGW_TOTALREGS) {
dgabino 0:102b50f941d0 720 DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n");
dgabino 0:102b50f941d0 721 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 722 }
dgabino 0:102b50f941d0 723
dgabino 0:102b50f941d0 724 /* check if SPI is initialised */
dgabino 0:102b50f941d0 725 if ((lgw_com_target == NULL) || (lgw_regpage < 0)) {
dgabino 0:102b50f941d0 726 DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n");
dgabino 0:102b50f941d0 727 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 728 }
dgabino 0:102b50f941d0 729
dgabino 0:102b50f941d0 730 /* get register struct from the struct array */
dgabino 0:102b50f941d0 731 r = loregs[register_id];
dgabino 0:102b50f941d0 732
dgabino 0:102b50f941d0 733 /* reject write to read-only registers */
dgabino 0:102b50f941d0 734 if (r.rdon == 1) {
dgabino 0:102b50f941d0 735 DEBUG_MSG("ERROR: TRYING TO BURST WRITE A READ-ONLY REGISTER\n");
dgabino 0:102b50f941d0 736 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 737 }
dgabino 0:102b50f941d0 738
dgabino 0:102b50f941d0 739 /* select proper register page if needed */
dgabino 0:102b50f941d0 740 if ((r.page != -1) && (r.page != lgw_regpage)) {
dgabino 0:102b50f941d0 741 com_stat += page_switch(r.page);
dgabino 0:102b50f941d0 742 }
dgabino 0:102b50f941d0 743
dgabino 0:102b50f941d0 744 /* do the burst write */
dgabino 0:102b50f941d0 745 com_stat += lgw_com_wb(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, r.addr, data, size);
dgabino 0:102b50f941d0 746
dgabino 0:102b50f941d0 747 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 748 DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER BURST WRITE\n");
dgabino 0:102b50f941d0 749 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 750 } else {
dgabino 0:102b50f941d0 751 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 752 }
dgabino 0:102b50f941d0 753 }
dgabino 0:102b50f941d0 754
dgabino 0:102b50f941d0 755 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
dgabino 0:102b50f941d0 756
dgabino 0:102b50f941d0 757 /* Point to a register by name and do a burst read */
dgabino 0:102b50f941d0 758 int lgw_reg_rb(uint16_t register_id, uint8_t *data, uint16_t size) {
dgabino 0:102b50f941d0 759 int com_stat = LGW_COM_SUCCESS;
dgabino 0:102b50f941d0 760 struct lgw_reg_s r;
dgabino 0:102b50f941d0 761
dgabino 0:102b50f941d0 762 /* check input parameters */
dgabino 0:102b50f941d0 763 CHECK_NULL(data);
dgabino 0:102b50f941d0 764 if (size == 0) {
dgabino 0:102b50f941d0 765 DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n");
dgabino 0:102b50f941d0 766 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 767 }
dgabino 0:102b50f941d0 768 if (register_id >= LGW_TOTALREGS) {
dgabino 0:102b50f941d0 769 DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n");
dgabino 0:102b50f941d0 770 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 771 }
dgabino 0:102b50f941d0 772
dgabino 0:102b50f941d0 773 /* check if SPI is initialised */
dgabino 0:102b50f941d0 774 if ((lgw_com_target == NULL) || (lgw_regpage < 0)) {
dgabino 0:102b50f941d0 775 DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n");
dgabino 0:102b50f941d0 776 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 777 }
dgabino 0:102b50f941d0 778
dgabino 0:102b50f941d0 779 /* get register struct from the struct array */
dgabino 0:102b50f941d0 780 r = loregs[register_id];
dgabino 0:102b50f941d0 781
dgabino 0:102b50f941d0 782 /* select proper register page if needed */
dgabino 0:102b50f941d0 783 if ((r.page != -1) && (r.page != lgw_regpage)) {
dgabino 0:102b50f941d0 784 com_stat += page_switch(r.page);
dgabino 0:102b50f941d0 785 }
dgabino 0:102b50f941d0 786
dgabino 0:102b50f941d0 787 /* do the burst read */
dgabino 0:102b50f941d0 788 com_stat += lgw_com_rb(lgw_com_target, lgw_com_mux_mode, LGW_COM_MUX_TARGET_SX1301, r.addr, data, size);
dgabino 0:102b50f941d0 789
dgabino 0:102b50f941d0 790 if (com_stat != LGW_COM_SUCCESS) {
dgabino 0:102b50f941d0 791 DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER BURST READ\n");
dgabino 0:102b50f941d0 792 return LGW_REG_ERROR;
dgabino 0:102b50f941d0 793 } else {
dgabino 0:102b50f941d0 794 return LGW_REG_SUCCESS;
dgabino 0:102b50f941d0 795 }
dgabino 0:102b50f941d0 796 }
dgabino 0:102b50f941d0 797
dgabino 0:102b50f941d0 798 /* --- EOF ------------------------------------------------------------------ */