Driver library for SX1272/SX1276 transceivers
Fork of SX127x by
sx127x.h@0:27aa8733f85d, 2014-03-26 (annotated)
- Committer:
- dudmuck
- Date:
- Wed Mar 26 00:56:09 2014 +0000
- Revision:
- 0:27aa8733f85d
- Child:
- 1:7dc60eb4c7ec
initial commit of library driver for SX1272/SX1276
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dudmuck | 0:27aa8733f85d | 1 | /* SX127x driver |
dudmuck | 0:27aa8733f85d | 2 | * Copyright (c) 2013 Semtech |
dudmuck | 0:27aa8733f85d | 3 | * |
dudmuck | 0:27aa8733f85d | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
dudmuck | 0:27aa8733f85d | 5 | * you may not use this file except in compliance with the License. |
dudmuck | 0:27aa8733f85d | 6 | * You may obtain a copy of the License at |
dudmuck | 0:27aa8733f85d | 7 | * |
dudmuck | 0:27aa8733f85d | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
dudmuck | 0:27aa8733f85d | 9 | * |
dudmuck | 0:27aa8733f85d | 10 | * Unless required by applicable law or agreed to in writing, software |
dudmuck | 0:27aa8733f85d | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
dudmuck | 0:27aa8733f85d | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
dudmuck | 0:27aa8733f85d | 13 | * See the License for the specific language governing permissions and |
dudmuck | 0:27aa8733f85d | 14 | * limitations under the License. |
dudmuck | 0:27aa8733f85d | 15 | */ |
dudmuck | 0:27aa8733f85d | 16 | |
dudmuck | 0:27aa8733f85d | 17 | #ifndef SX127x_H |
dudmuck | 0:27aa8733f85d | 18 | #define SX127x_H |
dudmuck | 0:27aa8733f85d | 19 | |
dudmuck | 0:27aa8733f85d | 20 | #include "mbed.h" |
dudmuck | 0:27aa8733f85d | 21 | |
dudmuck | 0:27aa8733f85d | 22 | #define XTAL_FREQ 32000000 |
dudmuck | 0:27aa8733f85d | 23 | |
dudmuck | 0:27aa8733f85d | 24 | #define FREQ_STEP_MHZ 61.03515625e-6 |
dudmuck | 0:27aa8733f85d | 25 | #define FREQ_STEP_KHZ 61.03515625e-3 |
dudmuck | 0:27aa8733f85d | 26 | #define FREQ_STEP_HZ 61.03515625 |
dudmuck | 0:27aa8733f85d | 27 | |
dudmuck | 0:27aa8733f85d | 28 | #define MHZ_TO_FRF(m) (m / FREQ_STEP_MHZ) |
dudmuck | 0:27aa8733f85d | 29 | |
dudmuck | 0:27aa8733f85d | 30 | /******************************************************************************/ |
dudmuck | 0:27aa8733f85d | 31 | /*! |
dudmuck | 0:27aa8733f85d | 32 | * SX127x Internal registers Address |
dudmuck | 0:27aa8733f85d | 33 | */ |
dudmuck | 0:27aa8733f85d | 34 | #define REG_FIFO 0x00 |
dudmuck | 0:27aa8733f85d | 35 | #define REG_OPMODE 0x01 |
dudmuck | 0:27aa8733f85d | 36 | #define REG_FRFMSB 0x06 |
dudmuck | 0:27aa8733f85d | 37 | #define REG_FRFMID 0x07 |
dudmuck | 0:27aa8733f85d | 38 | #define REG_FRFLSB 0x08 |
dudmuck | 0:27aa8733f85d | 39 | // Tx settings |
dudmuck | 0:27aa8733f85d | 40 | #define REG_PACONFIG 0x09 |
dudmuck | 0:27aa8733f85d | 41 | #define REG_PARAMP 0x0A |
dudmuck | 0:27aa8733f85d | 42 | #define REG_OCP 0x0B |
dudmuck | 0:27aa8733f85d | 43 | // Rx settings |
dudmuck | 0:27aa8733f85d | 44 | #define REG_LNA 0x0C |
dudmuck | 0:27aa8733f85d | 45 | |
dudmuck | 0:27aa8733f85d | 46 | // LoRa registers |
dudmuck | 0:27aa8733f85d | 47 | #define REG_LR_FIFOADDRPTR 0x0d |
dudmuck | 0:27aa8733f85d | 48 | #define REG_LR_FIFOTXBASEADDR 0x0e |
dudmuck | 0:27aa8733f85d | 49 | #define REG_LR_FIFORXBASEADDR 0x0f |
dudmuck | 0:27aa8733f85d | 50 | #define REG_LR_FIFORXCURRENTADDR /*REG_LR_RXDATAADDR*/ 0x10 |
dudmuck | 0:27aa8733f85d | 51 | #define REG_LR_IRQFLAGSMASK 0x11 |
dudmuck | 0:27aa8733f85d | 52 | #define REG_LR_IRQFLAGS 0x12 |
dudmuck | 0:27aa8733f85d | 53 | #define REG_LR_RXNBBYTES 0x13 |
dudmuck | 0:27aa8733f85d | 54 | #define REG_LR_RXHEADERCNTVALUE_MSB 0x14 |
dudmuck | 0:27aa8733f85d | 55 | #define REG_LR_RXHEADERCNTVALUE_LSB 0x15 |
dudmuck | 0:27aa8733f85d | 56 | #define REG_LR_RXPACKETCNTVALUE_MSB 0x16 |
dudmuck | 0:27aa8733f85d | 57 | #define REG_LR_RXPACKETCNTVALUE_LSB 0x17 |
dudmuck | 0:27aa8733f85d | 58 | #define REG_LR_MODEMSTAT 0x18 |
dudmuck | 0:27aa8733f85d | 59 | #define REG_LR_PKTSNRVALUE 0x19 |
dudmuck | 0:27aa8733f85d | 60 | #define REG_LR_PKTRSSIVALUE 0x1a |
dudmuck | 0:27aa8733f85d | 61 | #define REG_LR_RSSIVALUE 0x1b |
dudmuck | 0:27aa8733f85d | 62 | #define REG_LR_HOPCHANNEL 0x1c |
dudmuck | 0:27aa8733f85d | 63 | #define REG_LR_MODEMCONFIG 0x1d |
dudmuck | 0:27aa8733f85d | 64 | #define REG_LR_MODEMCONFIG2 0x1e |
dudmuck | 0:27aa8733f85d | 65 | #define REG_LR_SYMBTIMEOUTLSB 0x1f |
dudmuck | 0:27aa8733f85d | 66 | #define REG_LR_PREAMBLEMSB 0x20 |
dudmuck | 0:27aa8733f85d | 67 | #define REG_LR_PREAMBLELSB 0x21 |
dudmuck | 0:27aa8733f85d | 68 | #define REG_LR_PAYLOADLENGTH 0x22 // and RX length for implicit |
dudmuck | 0:27aa8733f85d | 69 | #define REG_LR_RX_MAX_PAYLOADLENGTH 0x23 // length limit for explicit mode |
dudmuck | 0:27aa8733f85d | 70 | #define REG_LR_HOPPERIOD 0x24 |
dudmuck | 0:27aa8733f85d | 71 | #define REG_LR_RXBYTEADDR /*REG_LR_RXDATAADDR*/ 0x25 |
dudmuck | 0:27aa8733f85d | 72 | #define REG_LR_MODEMCONFIG3 0x26 // sx1272 REG_LR_PPM_CORRECTION_MSB |
dudmuck | 0:27aa8733f85d | 73 | #define REG_LR_PPM_CORRECTION_LSB 0x27 |
dudmuck | 0:27aa8733f85d | 74 | #define REG_LR_TEST28 0x28 // est_freq_error |
dudmuck | 0:27aa8733f85d | 75 | #define REG_LR_TEST29 0x29 // est_freq_error |
dudmuck | 0:27aa8733f85d | 76 | #define REG_LR_TEST2A 0x2a // est_freq_error |
dudmuck | 0:27aa8733f85d | 77 | #define REG_LR_TEST2B 0x2b // |
dudmuck | 0:27aa8733f85d | 78 | #define REG_LR_WIDEBAND_RSSI 0x2c |
dudmuck | 0:27aa8733f85d | 79 | #define REG_LR_AGCH_TH 0x2d // agc_upper_th |
dudmuck | 0:27aa8733f85d | 80 | #define REG_LR_AGCL_TH 0x2e // agc_lower_th |
dudmuck | 0:27aa8733f85d | 81 | #define REG_LR_IFFRQH 0x2f // if_freq(12:8) |
dudmuck | 0:27aa8733f85d | 82 | #define REG_LR_IFFRQL 0x30 // if_freq(7:0) |
dudmuck | 0:27aa8733f85d | 83 | #define REG_LR_TEST31 0x31 // if_freq_auto, ... |
dudmuck | 0:27aa8733f85d | 84 | #define REG_LR_TEST32 0x32 // |
dudmuck | 0:27aa8733f85d | 85 | #define REG_LR_TEST33 0x33 |
dudmuck | 0:27aa8733f85d | 86 | #define REG_LR_DETECTION_THRESHOLD 0x37 |
dudmuck | 0:27aa8733f85d | 87 | /***** registers above 0x40 are same as FSK/OOK page */ |
dudmuck | 0:27aa8733f85d | 88 | |
dudmuck | 0:27aa8733f85d | 89 | #define REG_DIOMAPPING1 0x40 |
dudmuck | 0:27aa8733f85d | 90 | #define REG_DIOMAPPING2 0x41 |
dudmuck | 0:27aa8733f85d | 91 | #define REG_VERSION 0x42 |
dudmuck | 0:27aa8733f85d | 92 | |
dudmuck | 0:27aa8733f85d | 93 | |
dudmuck | 0:27aa8733f85d | 94 | /******************************************************************************/ |
dudmuck | 0:27aa8733f85d | 95 | |
dudmuck | 0:27aa8733f85d | 96 | typedef enum { |
dudmuck | 0:27aa8733f85d | 97 | RF_OPMODE_SLEEP = 0, |
dudmuck | 0:27aa8733f85d | 98 | RF_OPMODE_STANDBY, // 1 |
dudmuck | 0:27aa8733f85d | 99 | RF_OPMODE_SYNTHESIZER_TX, // 2 |
dudmuck | 0:27aa8733f85d | 100 | RF_OPMODE_TRANSMITTER, // 3 |
dudmuck | 0:27aa8733f85d | 101 | RF_OPMODE_SYNTHESIZER_RX, // 4 |
dudmuck | 0:27aa8733f85d | 102 | RF_OPMODE_RECEIVER, // 5 |
dudmuck | 0:27aa8733f85d | 103 | RF_OPMODE_RECEIVER_SINGLE, // 6 |
dudmuck | 0:27aa8733f85d | 104 | RF_OPMODE_CAD // 7 |
dudmuck | 0:27aa8733f85d | 105 | } chip_mode_e; |
dudmuck | 0:27aa8733f85d | 106 | |
dudmuck | 0:27aa8733f85d | 107 | typedef enum { |
dudmuck | 0:27aa8733f85d | 108 | SX_NONE = 0, |
dudmuck | 0:27aa8733f85d | 109 | SX1272, |
dudmuck | 0:27aa8733f85d | 110 | SX1276 |
dudmuck | 0:27aa8733f85d | 111 | } type_e; |
dudmuck | 0:27aa8733f85d | 112 | |
dudmuck | 0:27aa8733f85d | 113 | typedef enum { |
dudmuck | 0:27aa8733f85d | 114 | SERVICE_NONE = 0, |
dudmuck | 0:27aa8733f85d | 115 | SERVICE_ERROR, |
dudmuck | 0:27aa8733f85d | 116 | //! request to call read_fifo() |
dudmuck | 0:27aa8733f85d | 117 | SERVICE_READ_FIFO, |
dudmuck | 0:27aa8733f85d | 118 | //! notification to application of transmit complete |
dudmuck | 0:27aa8733f85d | 119 | SERVICE_TX_DONE |
dudmuck | 0:27aa8733f85d | 120 | } service_action_e; |
dudmuck | 0:27aa8733f85d | 121 | |
dudmuck | 0:27aa8733f85d | 122 | /******************************************************************************/ |
dudmuck | 0:27aa8733f85d | 123 | |
dudmuck | 0:27aa8733f85d | 124 | typedef union { |
dudmuck | 0:27aa8733f85d | 125 | struct { // sx1272 register 0x01 |
dudmuck | 0:27aa8733f85d | 126 | uint8_t Mode : 3; // 0,1,2 |
dudmuck | 0:27aa8733f85d | 127 | uint8_t ModulationShaping : 2; // 3,4 FSK/OOK |
dudmuck | 0:27aa8733f85d | 128 | uint8_t ModulationType : 2; // 5,6 FSK/OOK |
dudmuck | 0:27aa8733f85d | 129 | uint8_t LongRangeMode : 1; // 7 change this bit only in sleep mode |
dudmuck | 0:27aa8733f85d | 130 | } bits; |
dudmuck | 0:27aa8733f85d | 131 | struct { // sx1276 register 0x01 |
dudmuck | 0:27aa8733f85d | 132 | uint8_t Mode : 3; // 0,1,2 |
dudmuck | 0:27aa8733f85d | 133 | uint8_t LowFrequencyModeOn : 1; // 3 1=access to LF test registers (0=HF regs) |
dudmuck | 0:27aa8733f85d | 134 | uint8_t reserved : 1; // 4 |
dudmuck | 0:27aa8733f85d | 135 | uint8_t ModulationType : 2; // 5,6 FSK/OOK |
dudmuck | 0:27aa8733f85d | 136 | uint8_t LongRangeMode : 1; // 7 change this bit only in sleep mode |
dudmuck | 0:27aa8733f85d | 137 | } sx1276FSKbits; |
dudmuck | 0:27aa8733f85d | 138 | struct { // sx1276 register 0x01 |
dudmuck | 0:27aa8733f85d | 139 | uint8_t Mode : 3; // 0,1,2 |
dudmuck | 0:27aa8733f85d | 140 | uint8_t LowFrequencyModeOn : 1; // 3 1=access to LF test registers (0=HF regs) |
dudmuck | 0:27aa8733f85d | 141 | uint8_t reserved : 2; // 4,5 |
dudmuck | 0:27aa8733f85d | 142 | uint8_t AccessSharedReg : 1; // 6 1=FSK registers while in LoRa mode |
dudmuck | 0:27aa8733f85d | 143 | uint8_t LongRangeMode : 1; // 7 change this bit only in sleep mode |
dudmuck | 0:27aa8733f85d | 144 | } sx1276LORAbits; |
dudmuck | 0:27aa8733f85d | 145 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 146 | } RegOpMode_t; |
dudmuck | 0:27aa8733f85d | 147 | |
dudmuck | 0:27aa8733f85d | 148 | typedef union { |
dudmuck | 0:27aa8733f85d | 149 | struct { // sx12xx register 0x09 |
dudmuck | 0:27aa8733f85d | 150 | uint8_t OutputPower : 4; // 0,1,2,3 |
dudmuck | 0:27aa8733f85d | 151 | uint8_t MaxPower : 3; // 4,5,6 |
dudmuck | 0:27aa8733f85d | 152 | uint8_t PaSelect : 1; // 7 1=PA_BOOST |
dudmuck | 0:27aa8733f85d | 153 | } bits; |
dudmuck | 0:27aa8733f85d | 154 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 155 | } RegPaConfig_t; |
dudmuck | 0:27aa8733f85d | 156 | |
dudmuck | 0:27aa8733f85d | 157 | typedef union { |
dudmuck | 0:27aa8733f85d | 158 | struct { // sx12xx register 0x0b |
dudmuck | 0:27aa8733f85d | 159 | uint8_t OcpTrim : 5; // 0,1,2,3,4 |
dudmuck | 0:27aa8733f85d | 160 | uint8_t OcpOn : 1; // 5 |
dudmuck | 0:27aa8733f85d | 161 | uint8_t unused : 2; // 6,7 |
dudmuck | 0:27aa8733f85d | 162 | } bits; |
dudmuck | 0:27aa8733f85d | 163 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 164 | } RegOcp_t; |
dudmuck | 0:27aa8733f85d | 165 | |
dudmuck | 0:27aa8733f85d | 166 | typedef union { |
dudmuck | 0:27aa8733f85d | 167 | struct { // sx12xx register 0x0c |
dudmuck | 0:27aa8733f85d | 168 | uint8_t LnaBoostHF : 2; // 0,1 |
dudmuck | 0:27aa8733f85d | 169 | uint8_t reserved : 1; // 2 |
dudmuck | 0:27aa8733f85d | 170 | uint8_t LnaBoostLF : 2; // 3,4 |
dudmuck | 0:27aa8733f85d | 171 | uint8_t LnaGain : 3; // 5,6,7 |
dudmuck | 0:27aa8733f85d | 172 | } bits; |
dudmuck | 0:27aa8733f85d | 173 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 174 | } RegLna_t; // RXFE |
dudmuck | 0:27aa8733f85d | 175 | |
dudmuck | 0:27aa8733f85d | 176 | typedef union { |
dudmuck | 0:27aa8733f85d | 177 | struct { // sx127x register 0x12 |
dudmuck | 0:27aa8733f85d | 178 | uint8_t CadDetected : 1; // 0 |
dudmuck | 0:27aa8733f85d | 179 | uint8_t FhssChangeChannel : 1; // 1 |
dudmuck | 0:27aa8733f85d | 180 | uint8_t CadDone : 1; // 2 |
dudmuck | 0:27aa8733f85d | 181 | uint8_t TxDone : 1; // 3 |
dudmuck | 0:27aa8733f85d | 182 | uint8_t ValidHeader : 1; // 4 |
dudmuck | 0:27aa8733f85d | 183 | uint8_t PayloadCrcError : 1; // 5 |
dudmuck | 0:27aa8733f85d | 184 | uint8_t RxDone : 1; // 6 |
dudmuck | 0:27aa8733f85d | 185 | uint8_t RxTimeout : 1; // 7 |
dudmuck | 0:27aa8733f85d | 186 | } bits; |
dudmuck | 0:27aa8733f85d | 187 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 188 | } RegIrqFlags_t; |
dudmuck | 0:27aa8733f85d | 189 | |
dudmuck | 0:27aa8733f85d | 190 | typedef union { |
dudmuck | 0:27aa8733f85d | 191 | struct { // sx127x register 0x18 |
dudmuck | 0:27aa8733f85d | 192 | uint8_t detect : 1; // 0 |
dudmuck | 0:27aa8733f85d | 193 | uint8_t sync : 1; // 1 |
dudmuck | 0:27aa8733f85d | 194 | uint8_t rx_ongoing : 1; // 2 |
dudmuck | 0:27aa8733f85d | 195 | uint8_t header_valid : 1; // 3 |
dudmuck | 0:27aa8733f85d | 196 | uint8_t clear : 1; // 4 |
dudmuck | 0:27aa8733f85d | 197 | uint8_t RxCodingRate : 3; // 5,6,7 |
dudmuck | 0:27aa8733f85d | 198 | } bits; |
dudmuck | 0:27aa8733f85d | 199 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 200 | } RegModemStatus_t; |
dudmuck | 0:27aa8733f85d | 201 | |
dudmuck | 0:27aa8733f85d | 202 | typedef union { |
dudmuck | 0:27aa8733f85d | 203 | struct { // sx127x register 0x1c |
dudmuck | 0:27aa8733f85d | 204 | uint8_t FhssPresentChannel : 6; // 0,1,2,3,4,5 |
dudmuck | 0:27aa8733f85d | 205 | uint8_t RxPayloadCrcOn : 1; // 6 |
dudmuck | 0:27aa8733f85d | 206 | uint8_t PllTimeout : 1; // 7 |
dudmuck | 0:27aa8733f85d | 207 | } bits; |
dudmuck | 0:27aa8733f85d | 208 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 209 | } RegHopChannel_t; |
dudmuck | 0:27aa8733f85d | 210 | |
dudmuck | 0:27aa8733f85d | 211 | typedef union { |
dudmuck | 0:27aa8733f85d | 212 | struct { // sx1276 register 0x1d |
dudmuck | 0:27aa8733f85d | 213 | uint8_t ImplicitHeaderModeOn : 1; // 0 |
dudmuck | 0:27aa8733f85d | 214 | uint8_t CodingRate : 3; // 1,2,3 |
dudmuck | 0:27aa8733f85d | 215 | uint8_t Bw : 4; // 4,5,6,7 |
dudmuck | 0:27aa8733f85d | 216 | } sx1276bits; |
dudmuck | 0:27aa8733f85d | 217 | struct { // sx1272 register 0x1d |
dudmuck | 0:27aa8733f85d | 218 | uint8_t LowDataRateOptimize : 1; // 0 ppm_offset: number of cyclic shifts possible to encode to symbol |
dudmuck | 0:27aa8733f85d | 219 | uint8_t RxPayloadCrcOn : 1; // 1 |
dudmuck | 0:27aa8733f85d | 220 | uint8_t ImplicitHeaderModeOn : 1; // 2 |
dudmuck | 0:27aa8733f85d | 221 | uint8_t CodingRate : 3; // 3,4,5 |
dudmuck | 0:27aa8733f85d | 222 | uint8_t Bw : 2; // 6,7 |
dudmuck | 0:27aa8733f85d | 223 | } sx1272bits; |
dudmuck | 0:27aa8733f85d | 224 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 225 | } RegModemConfig_t; |
dudmuck | 0:27aa8733f85d | 226 | |
dudmuck | 0:27aa8733f85d | 227 | typedef union { |
dudmuck | 0:27aa8733f85d | 228 | struct { // sx1276 register 0x1e |
dudmuck | 0:27aa8733f85d | 229 | uint8_t SymbTimeoutMsb : 2; // 0,1 |
dudmuck | 0:27aa8733f85d | 230 | uint8_t RxPayloadCrcOn : 1; // 2 |
dudmuck | 0:27aa8733f85d | 231 | uint8_t TxContinuousMode : 1; // 3 |
dudmuck | 0:27aa8733f85d | 232 | uint8_t SpreadingFactor : 4; // 4,5,6,7 |
dudmuck | 0:27aa8733f85d | 233 | } sx1276bits; |
dudmuck | 0:27aa8733f85d | 234 | struct { // sx1272 register 0x1e |
dudmuck | 0:27aa8733f85d | 235 | uint8_t SymbTimeoutMsb : 2; // 0,1 |
dudmuck | 0:27aa8733f85d | 236 | uint8_t AgcAutoOn : 1; // 2 |
dudmuck | 0:27aa8733f85d | 237 | uint8_t TxContinuousMode : 1; // 3 |
dudmuck | 0:27aa8733f85d | 238 | uint8_t SpreadingFactor : 4; // 4,5,6,7 |
dudmuck | 0:27aa8733f85d | 239 | } sx1272bits; |
dudmuck | 0:27aa8733f85d | 240 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 241 | } RegModemConfig2_t; |
dudmuck | 0:27aa8733f85d | 242 | |
dudmuck | 0:27aa8733f85d | 243 | typedef union { |
dudmuck | 0:27aa8733f85d | 244 | struct { // sx127x register 0x26 |
dudmuck | 0:27aa8733f85d | 245 | uint8_t reserved : 2; // 0,1 |
dudmuck | 0:27aa8733f85d | 246 | uint8_t AgcAutoOn : 1; // 2 |
dudmuck | 0:27aa8733f85d | 247 | uint8_t LowDataRateOptimize : 1; // 3 ppm_offset |
dudmuck | 0:27aa8733f85d | 248 | uint8_t unused : 4; // 4,5,6,7 |
dudmuck | 0:27aa8733f85d | 249 | } sx1276bits; |
dudmuck | 0:27aa8733f85d | 250 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 251 | uint8_t sx1272_ppm_correction_msb; |
dudmuck | 0:27aa8733f85d | 252 | } RegModemConfig3_t; |
dudmuck | 0:27aa8733f85d | 253 | |
dudmuck | 0:27aa8733f85d | 254 | typedef union { |
dudmuck | 0:27aa8733f85d | 255 | struct { // sx127x register 0x31 |
dudmuck | 0:27aa8733f85d | 256 | uint8_t detect_trig_same_peaks_nb : 3; // 0,1,2 |
dudmuck | 0:27aa8733f85d | 257 | uint8_t disable_pll_timeout : 1; // 3 |
dudmuck | 0:27aa8733f85d | 258 | uint8_t tracking_intergral : 2; // 4,5 |
dudmuck | 0:27aa8733f85d | 259 | uint8_t frame_sync_gain : 1; // 6 |
dudmuck | 0:27aa8733f85d | 260 | uint8_t if_freq_auto : 1; // 7 |
dudmuck | 0:27aa8733f85d | 261 | } bits; |
dudmuck | 0:27aa8733f85d | 262 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 263 | } RegTest31_t; |
dudmuck | 0:27aa8733f85d | 264 | |
dudmuck | 0:27aa8733f85d | 265 | |
dudmuck | 0:27aa8733f85d | 266 | /*********************** ...end lora ****************************/ |
dudmuck | 0:27aa8733f85d | 267 | |
dudmuck | 0:27aa8733f85d | 268 | typedef union { |
dudmuck | 0:27aa8733f85d | 269 | struct { // sx12xx register 0x40 |
dudmuck | 0:27aa8733f85d | 270 | uint8_t Dio3Mapping : 2; // 0,1 |
dudmuck | 0:27aa8733f85d | 271 | uint8_t Dio2Mapping : 2; // 2,3 |
dudmuck | 0:27aa8733f85d | 272 | uint8_t Dio1Mapping : 2; // 4,5 |
dudmuck | 0:27aa8733f85d | 273 | uint8_t Dio0Mapping : 2; // 6,7 |
dudmuck | 0:27aa8733f85d | 274 | } bits; |
dudmuck | 0:27aa8733f85d | 275 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 276 | } RegDioMapping1_t; |
dudmuck | 0:27aa8733f85d | 277 | |
dudmuck | 0:27aa8733f85d | 278 | typedef union { |
dudmuck | 0:27aa8733f85d | 279 | struct { // sx12xx register 0x41 |
dudmuck | 0:27aa8733f85d | 280 | uint8_t MapPreambleDetect : 1; // 0 //DIO4 assign: 1b=preambleDet 0b=rssiThresh |
dudmuck | 0:27aa8733f85d | 281 | uint8_t io_mode : 3; // 1,2,3 //0=normal,1=debug,2=fpga,3=pll_tx,4=pll_rx,5=analog |
dudmuck | 0:27aa8733f85d | 282 | uint8_t Dio5Mapping : 2; // 4,5 |
dudmuck | 0:27aa8733f85d | 283 | uint8_t Dio4Mapping : 2; // 6,7 |
dudmuck | 0:27aa8733f85d | 284 | } bits; |
dudmuck | 0:27aa8733f85d | 285 | uint8_t octet; |
dudmuck | 0:27aa8733f85d | 286 | } RegDioMapping2_t; |
dudmuck | 0:27aa8733f85d | 287 | |
dudmuck | 0:27aa8733f85d | 288 | /***************************************************/ |
dudmuck | 0:27aa8733f85d | 289 | |
dudmuck | 0:27aa8733f85d | 290 | |
dudmuck | 0:27aa8733f85d | 291 | /** FSK/LoRa radio transceiver. |
dudmuck | 0:27aa8733f85d | 292 | * see http://en.wikipedia.org/wiki/Chirp_spread_spectrum |
dudmuck | 0:27aa8733f85d | 293 | */ |
dudmuck | 0:27aa8733f85d | 294 | |
dudmuck | 0:27aa8733f85d | 295 | class SX127x { |
dudmuck | 0:27aa8733f85d | 296 | public: |
dudmuck | 0:27aa8733f85d | 297 | /** Create SX127x instance |
dudmuck | 0:27aa8733f85d | 298 | * @param mosi SPI master-out pin |
dudmuck | 0:27aa8733f85d | 299 | * @param miso SPI master-in pin |
dudmuck | 0:27aa8733f85d | 300 | * @param sclk SPI clock pin |
dudmuck | 0:27aa8733f85d | 301 | * @param cs SPI chip-select pin |
dudmuck | 0:27aa8733f85d | 302 | * @param rst radio hardware reset pin |
dudmuck | 0:27aa8733f85d | 303 | * @param dio_0 interrupt pin from radio |
dudmuck | 0:27aa8733f85d | 304 | * @param fem_ctx rx-tx switch for HF bands (800/900) |
dudmuck | 0:27aa8733f85d | 305 | * @param fem_cps rx-tx switch for LF bands (vhf/433) |
dudmuck | 0:27aa8733f85d | 306 | */ |
dudmuck | 0:27aa8733f85d | 307 | |
dudmuck | 0:27aa8733f85d | 308 | SX127x(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0, PinName dio_1, PinName fem_ctx, PinName fem_cps); |
dudmuck | 0:27aa8733f85d | 309 | |
dudmuck | 0:27aa8733f85d | 310 | ~SX127x(); |
dudmuck | 0:27aa8733f85d | 311 | |
dudmuck | 0:27aa8733f85d | 312 | /** set center operating frequency |
dudmuck | 0:27aa8733f85d | 313 | * @param MHz operating frequency in MHz |
dudmuck | 0:27aa8733f85d | 314 | */ |
dudmuck | 0:27aa8733f85d | 315 | void set_frf_MHz( float MHz ); |
dudmuck | 0:27aa8733f85d | 316 | |
dudmuck | 0:27aa8733f85d | 317 | /** get center operating frequency |
dudmuck | 0:27aa8733f85d | 318 | * @returns operating frequency in MHz |
dudmuck | 0:27aa8733f85d | 319 | */ |
dudmuck | 0:27aa8733f85d | 320 | float get_frf_MHz(void); |
dudmuck | 0:27aa8733f85d | 321 | |
dudmuck | 0:27aa8733f85d | 322 | void set_opmode(chip_mode_e mode); |
dudmuck | 0:27aa8733f85d | 323 | |
dudmuck | 0:27aa8733f85d | 324 | /** reset radio using pin |
dudmuck | 0:27aa8733f85d | 325 | */ |
dudmuck | 0:27aa8733f85d | 326 | void hw_reset(void); |
dudmuck | 0:27aa8733f85d | 327 | /** initialise SX1232 class to radio |
dudmuck | 0:27aa8733f85d | 328 | * @note this is called from class instantiation, but must also be manually called after hardware reset |
dudmuck | 0:27aa8733f85d | 329 | */ |
dudmuck | 0:27aa8733f85d | 330 | void init(void); |
dudmuck | 0:27aa8733f85d | 331 | void get_type(void); // identify radio chip |
dudmuck | 0:27aa8733f85d | 332 | |
dudmuck | 0:27aa8733f85d | 333 | /** read register from radio |
dudmuck | 0:27aa8733f85d | 334 | * @param addr register address |
dudmuck | 0:27aa8733f85d | 335 | * @returns the value read from the register |
dudmuck | 0:27aa8733f85d | 336 | */ |
dudmuck | 0:27aa8733f85d | 337 | uint8_t read_reg(uint8_t addr); |
dudmuck | 0:27aa8733f85d | 338 | uint16_t read_u16(uint8_t addr); |
dudmuck | 0:27aa8733f85d | 339 | |
dudmuck | 0:27aa8733f85d | 340 | /** write register to radio |
dudmuck | 0:27aa8733f85d | 341 | * @param addr register address |
dudmuck | 0:27aa8733f85d | 342 | * @param data byte to write |
dudmuck | 0:27aa8733f85d | 343 | */ |
dudmuck | 0:27aa8733f85d | 344 | void write_reg(uint8_t addr, uint8_t data); |
dudmuck | 0:27aa8733f85d | 345 | void write_reg_u24(uint8_t addr, uint32_t data); |
dudmuck | 0:27aa8733f85d | 346 | |
dudmuck | 0:27aa8733f85d | 347 | /** transmit a packet |
dudmuck | 0:27aa8733f85d | 348 | * @param len size of packet |
dudmuck | 0:27aa8733f85d | 349 | * @note Limited to (lora fifo size 256) |
dudmuck | 0:27aa8733f85d | 350 | */ |
dudmuck | 0:27aa8733f85d | 351 | void lora_start_tx(uint8_t len); |
dudmuck | 0:27aa8733f85d | 352 | |
dudmuck | 0:27aa8733f85d | 353 | /** start receive mode |
dudmuck | 0:27aa8733f85d | 354 | * @note the variable service_action needs to be monitored to indicate read_fifo() needs to be called to pull packet from FIFO. |
dudmuck | 0:27aa8733f85d | 355 | */ |
dudmuck | 0:27aa8733f85d | 356 | void lora_start_rx(void); |
dudmuck | 0:27aa8733f85d | 357 | |
dudmuck | 0:27aa8733f85d | 358 | /** Called by main program when indicated by service_action variable, to pull recevied packet from radio FIFO. |
dudmuck | 0:27aa8733f85d | 359 | * @returns count of bytes received |
dudmuck | 0:27aa8733f85d | 360 | * @note received packet in rx_buf[] |
dudmuck | 0:27aa8733f85d | 361 | */ |
dudmuck | 0:27aa8733f85d | 362 | void lora_read_fifo(uint8_t len); |
dudmuck | 0:27aa8733f85d | 363 | |
dudmuck | 0:27aa8733f85d | 364 | void lora_write_fifo(uint8_t len); |
dudmuck | 0:27aa8733f85d | 365 | |
dudmuck | 0:27aa8733f85d | 366 | service_action_e service(void); // (SLIH) ISR bottom half |
dudmuck | 0:27aa8733f85d | 367 | |
dudmuck | 0:27aa8733f85d | 368 | uint8_t getCodingRate(bool from_rx); // false:transmitted, true:last recevied packet |
dudmuck | 0:27aa8733f85d | 369 | void setCodingRate(uint8_t cr); |
dudmuck | 0:27aa8733f85d | 370 | |
dudmuck | 0:27aa8733f85d | 371 | bool getHeaderMode(void); |
dudmuck | 0:27aa8733f85d | 372 | void setHeaderMode(bool hm); |
dudmuck | 0:27aa8733f85d | 373 | |
dudmuck | 0:27aa8733f85d | 374 | uint8_t getBw(void); |
dudmuck | 0:27aa8733f85d | 375 | void setBw(uint8_t bw); |
dudmuck | 0:27aa8733f85d | 376 | |
dudmuck | 0:27aa8733f85d | 377 | uint8_t getSf(void); |
dudmuck | 0:27aa8733f85d | 378 | void setSf(uint8_t sf); |
dudmuck | 0:27aa8733f85d | 379 | |
dudmuck | 0:27aa8733f85d | 380 | bool getRxPayloadCrcOn(void); |
dudmuck | 0:27aa8733f85d | 381 | void setRxPayloadCrcOn(bool); |
dudmuck | 0:27aa8733f85d | 382 | |
dudmuck | 0:27aa8733f85d | 383 | bool getAgcAutoOn(void); |
dudmuck | 0:27aa8733f85d | 384 | void setAgcAutoOn(bool); |
dudmuck | 0:27aa8733f85d | 385 | |
dudmuck | 0:27aa8733f85d | 386 | /*****************************************************/ |
dudmuck | 0:27aa8733f85d | 387 | |
dudmuck | 0:27aa8733f85d | 388 | //! RF transmit packet buffer |
dudmuck | 0:27aa8733f85d | 389 | uint8_t tx_buf[256]; // lora fifo size |
dudmuck | 0:27aa8733f85d | 390 | |
dudmuck | 0:27aa8733f85d | 391 | //! RF receive packet buffer |
dudmuck | 0:27aa8733f85d | 392 | uint8_t rx_buf[256]; // lora fifo size |
dudmuck | 0:27aa8733f85d | 393 | |
dudmuck | 0:27aa8733f85d | 394 | //! radio chip type plugged in |
dudmuck | 0:27aa8733f85d | 395 | type_e type; |
dudmuck | 0:27aa8733f85d | 396 | |
dudmuck | 0:27aa8733f85d | 397 | //! operating mode |
dudmuck | 0:27aa8733f85d | 398 | RegOpMode_t RegOpMode; |
dudmuck | 0:27aa8733f85d | 399 | |
dudmuck | 0:27aa8733f85d | 400 | //! transmitter power configuration |
dudmuck | 0:27aa8733f85d | 401 | RegPaConfig_t RegPaConfig; |
dudmuck | 0:27aa8733f85d | 402 | |
dudmuck | 0:27aa8733f85d | 403 | RegOcp_t RegOcp; // 0x0b |
dudmuck | 0:27aa8733f85d | 404 | |
dudmuck | 0:27aa8733f85d | 405 | // receiver front-end |
dudmuck | 0:27aa8733f85d | 406 | RegLna_t RegLna; // 0x0c |
dudmuck | 0:27aa8733f85d | 407 | |
dudmuck | 0:27aa8733f85d | 408 | RegIrqFlags_t RegIrqFlags; // 0x12 |
dudmuck | 0:27aa8733f85d | 409 | uint8_t RegRxNbBytes; // 0x13 |
dudmuck | 0:27aa8733f85d | 410 | RegModemStatus_t RegModemStatus; // 0x18 |
dudmuck | 0:27aa8733f85d | 411 | int8_t RegPktSnrValue; // 0x19 signed, s/n can be negative |
dudmuck | 0:27aa8733f85d | 412 | uint8_t RegPktRssiValue; // 0x1a |
dudmuck | 0:27aa8733f85d | 413 | RegHopChannel_t RegHopChannel; // 0x1c |
dudmuck | 0:27aa8733f85d | 414 | RegModemConfig_t RegModemConfig; // 0x1d |
dudmuck | 0:27aa8733f85d | 415 | RegModemConfig2_t RegModemConfig2; // 0x1e |
dudmuck | 0:27aa8733f85d | 416 | uint16_t RegPreamble; // 0x20->0x21 |
dudmuck | 0:27aa8733f85d | 417 | uint8_t RegPayloadLength; // 0x22 |
dudmuck | 0:27aa8733f85d | 418 | uint8_t RegRxMaxPayloadLength; // 0x23 |
dudmuck | 0:27aa8733f85d | 419 | uint8_t RegHopPeriod; // 0x24 |
dudmuck | 0:27aa8733f85d | 420 | RegModemConfig3_t RegModemConfig3; // 0x26 |
dudmuck | 0:27aa8733f85d | 421 | RegTest31_t RegTest31; // 0x31 |
dudmuck | 0:27aa8733f85d | 422 | |
dudmuck | 0:27aa8733f85d | 423 | //! pin assignments |
dudmuck | 0:27aa8733f85d | 424 | RegDioMapping1_t RegDioMapping1; |
dudmuck | 0:27aa8733f85d | 425 | |
dudmuck | 0:27aa8733f85d | 426 | //! pin assignments |
dudmuck | 0:27aa8733f85d | 427 | RegDioMapping2_t RegDioMapping2; |
dudmuck | 0:27aa8733f85d | 428 | |
dudmuck | 0:27aa8733f85d | 429 | bool poll_vh; |
dudmuck | 0:27aa8733f85d | 430 | |
dudmuck | 0:27aa8733f85d | 431 | // frequency hopping table |
dudmuck | 0:27aa8733f85d | 432 | const uint32_t *frfs; |
dudmuck | 0:27aa8733f85d | 433 | |
dudmuck | 0:27aa8733f85d | 434 | private: |
dudmuck | 0:27aa8733f85d | 435 | SPI m_spi; |
dudmuck | 0:27aa8733f85d | 436 | DigitalOut m_cs; |
dudmuck | 0:27aa8733f85d | 437 | DigitalInOut reset_pin; |
dudmuck | 0:27aa8733f85d | 438 | DigitalOut femcps; // LF rf switch |
dudmuck | 0:27aa8733f85d | 439 | DigitalOut femctx; // HF rf switch |
dudmuck | 0:27aa8733f85d | 440 | //void dio0_callback(void); |
dudmuck | 0:27aa8733f85d | 441 | bool HF; // sx1272 is always HF |
dudmuck | 0:27aa8733f85d | 442 | void set_nb_trig_peaks(int); |
dudmuck | 0:27aa8733f85d | 443 | |
dudmuck | 0:27aa8733f85d | 444 | protected: |
dudmuck | 0:27aa8733f85d | 445 | InterruptIn dio0; |
dudmuck | 0:27aa8733f85d | 446 | InterruptIn dio1; |
dudmuck | 0:27aa8733f85d | 447 | FunctionPointer _callback_rx; |
dudmuck | 0:27aa8733f85d | 448 | }; |
dudmuck | 0:27aa8733f85d | 449 | |
dudmuck | 0:27aa8733f85d | 450 | #endif /* SX127x_H */ |