Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SX127x by
sx127x.h@1:7dc60eb4c7ec, 2014-04-14 (annotated)
- Committer:
- dudmuck
- Date:
- Mon Apr 14 21:57:41 2014 +0000
- Revision:
- 1:7dc60eb4c7ec
- Parent:
- 0:27aa8733f85d
- Child:
- 2:fdae76e1215e
added read/write functions for USB HID application
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 | 1:7dc60eb4c7ec | 24 | #define FREQ_STEP_MHZ 61.03515625e-6 // 32 / (2^19) |
dudmuck | 1:7dc60eb4c7ec | 25 | #define FREQ_STEP_KHZ 61.03515625e-3 // 32e3 / (2^19) |
dudmuck | 1:7dc60eb4c7ec | 26 | #define FREQ_STEP_HZ 61.03515625 // 32e6 / (2^19) |
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 | 1:7dc60eb4c7ec | 340 | /** read register from radio. from an arbitrary amount of registers following the first |
dudmuck | 1:7dc60eb4c7ec | 341 | * @param addr register address |
dudmuck | 1:7dc60eb4c7ec | 342 | * @param buffer the read values will be placed here |
dudmuck | 1:7dc60eb4c7ec | 343 | * @param size how many registers to read |
dudmuck | 1:7dc60eb4c7ec | 344 | */ |
dudmuck | 1:7dc60eb4c7ec | 345 | void ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); |
dudmuck | 1:7dc60eb4c7ec | 346 | |
dudmuck | 0:27aa8733f85d | 347 | /** write register to radio |
dudmuck | 0:27aa8733f85d | 348 | * @param addr register address |
dudmuck | 0:27aa8733f85d | 349 | * @param data byte to write |
dudmuck | 0:27aa8733f85d | 350 | */ |
dudmuck | 0:27aa8733f85d | 351 | void write_reg(uint8_t addr, uint8_t data); |
dudmuck | 0:27aa8733f85d | 352 | void write_reg_u24(uint8_t addr, uint32_t data); |
dudmuck | 0:27aa8733f85d | 353 | |
dudmuck | 1:7dc60eb4c7ec | 354 | /** write register(s) to radio, to an arbitrary amount of registers following first |
dudmuck | 1:7dc60eb4c7ec | 355 | * @param addr register address |
dudmuck | 1:7dc60eb4c7ec | 356 | * @param buffer byte(s) to write |
dudmuck | 1:7dc60eb4c7ec | 357 | * @param size count of registers to write to |
dudmuck | 1:7dc60eb4c7ec | 358 | */ |
dudmuck | 1:7dc60eb4c7ec | 359 | void WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); |
dudmuck | 1:7dc60eb4c7ec | 360 | |
dudmuck | 0:27aa8733f85d | 361 | /** transmit a packet |
dudmuck | 0:27aa8733f85d | 362 | * @param len size of packet |
dudmuck | 0:27aa8733f85d | 363 | * @note Limited to (lora fifo size 256) |
dudmuck | 0:27aa8733f85d | 364 | */ |
dudmuck | 0:27aa8733f85d | 365 | void lora_start_tx(uint8_t len); |
dudmuck | 0:27aa8733f85d | 366 | |
dudmuck | 0:27aa8733f85d | 367 | /** start receive mode |
dudmuck | 0:27aa8733f85d | 368 | * @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 | 369 | */ |
dudmuck | 0:27aa8733f85d | 370 | void lora_start_rx(void); |
dudmuck | 0:27aa8733f85d | 371 | |
dudmuck | 0:27aa8733f85d | 372 | /** Called by main program when indicated by service_action variable, to pull recevied packet from radio FIFO. |
dudmuck | 0:27aa8733f85d | 373 | * @returns count of bytes received |
dudmuck | 0:27aa8733f85d | 374 | * @note received packet in rx_buf[] |
dudmuck | 0:27aa8733f85d | 375 | */ |
dudmuck | 0:27aa8733f85d | 376 | void lora_read_fifo(uint8_t len); |
dudmuck | 0:27aa8733f85d | 377 | |
dudmuck | 1:7dc60eb4c7ec | 378 | /** fills radio FIFO with payload contents, prior to transmission |
dudmuck | 1:7dc60eb4c7ec | 379 | * @param len count of bytes to put into FIFO |
dudmuck | 1:7dc60eb4c7ec | 380 | * @note tx_buf[] should contain desired payload (to send) prior to calling |
dudmuck | 1:7dc60eb4c7ec | 381 | */ |
dudmuck | 0:27aa8733f85d | 382 | void lora_write_fifo(uint8_t len); |
dudmuck | 0:27aa8733f85d | 383 | |
dudmuck | 0:27aa8733f85d | 384 | service_action_e service(void); // (SLIH) ISR bottom half |
dudmuck | 0:27aa8733f85d | 385 | |
dudmuck | 1:7dc60eb4c7ec | 386 | /** CodingRate: how much FEC to encoding onto packet */ |
dudmuck | 0:27aa8733f85d | 387 | uint8_t getCodingRate(bool from_rx); // false:transmitted, true:last recevied packet |
dudmuck | 0:27aa8733f85d | 388 | void setCodingRate(uint8_t cr); |
dudmuck | 0:27aa8733f85d | 389 | |
dudmuck | 1:7dc60eb4c7ec | 390 | /** HeaderMode: explicit mode sents CodingRate and payload length, implicit mode requires assumption by receiver */ |
dudmuck | 0:27aa8733f85d | 391 | bool getHeaderMode(void); |
dudmuck | 0:27aa8733f85d | 392 | void setHeaderMode(bool hm); |
dudmuck | 0:27aa8733f85d | 393 | |
dudmuck | 1:7dc60eb4c7ec | 394 | /** bandwidth: SX1272 has three bandwidths. SX1276 adds more narrower bandwidths. */ |
dudmuck | 0:27aa8733f85d | 395 | uint8_t getBw(void); |
dudmuck | 0:27aa8733f85d | 396 | void setBw(uint8_t bw); |
dudmuck | 0:27aa8733f85d | 397 | |
dudmuck | 1:7dc60eb4c7ec | 398 | /** spreading factor: trade-off between data rate and processing gain (link budget) */ |
dudmuck | 0:27aa8733f85d | 399 | uint8_t getSf(void); |
dudmuck | 0:27aa8733f85d | 400 | void setSf(uint8_t sf); |
dudmuck | 0:27aa8733f85d | 401 | |
dudmuck | 1:7dc60eb4c7ec | 402 | /** enable CRC in transmitted packet */ |
dudmuck | 0:27aa8733f85d | 403 | bool getRxPayloadCrcOn(void); |
dudmuck | 0:27aa8733f85d | 404 | void setRxPayloadCrcOn(bool); |
dudmuck | 0:27aa8733f85d | 405 | |
dudmuck | 0:27aa8733f85d | 406 | bool getAgcAutoOn(void); |
dudmuck | 0:27aa8733f85d | 407 | void setAgcAutoOn(bool); |
dudmuck | 0:27aa8733f85d | 408 | |
dudmuck | 1:7dc60eb4c7ec | 409 | /* *switch between FSK or LoRa modes */ |
dudmuck | 1:7dc60eb4c7ec | 410 | void SetLoRaOn(bool); |
dudmuck | 1:7dc60eb4c7ec | 411 | |
dudmuck | 0:27aa8733f85d | 412 | /*****************************************************/ |
dudmuck | 0:27aa8733f85d | 413 | |
dudmuck | 0:27aa8733f85d | 414 | //! RF transmit packet buffer |
dudmuck | 0:27aa8733f85d | 415 | uint8_t tx_buf[256]; // lora fifo size |
dudmuck | 0:27aa8733f85d | 416 | |
dudmuck | 0:27aa8733f85d | 417 | //! RF receive packet buffer |
dudmuck | 0:27aa8733f85d | 418 | uint8_t rx_buf[256]; // lora fifo size |
dudmuck | 0:27aa8733f85d | 419 | |
dudmuck | 0:27aa8733f85d | 420 | //! radio chip type plugged in |
dudmuck | 0:27aa8733f85d | 421 | type_e type; |
dudmuck | 0:27aa8733f85d | 422 | |
dudmuck | 0:27aa8733f85d | 423 | //! operating mode |
dudmuck | 0:27aa8733f85d | 424 | RegOpMode_t RegOpMode; |
dudmuck | 0:27aa8733f85d | 425 | |
dudmuck | 0:27aa8733f85d | 426 | //! transmitter power configuration |
dudmuck | 0:27aa8733f85d | 427 | RegPaConfig_t RegPaConfig; |
dudmuck | 0:27aa8733f85d | 428 | |
dudmuck | 0:27aa8733f85d | 429 | RegOcp_t RegOcp; // 0x0b |
dudmuck | 0:27aa8733f85d | 430 | |
dudmuck | 0:27aa8733f85d | 431 | // receiver front-end |
dudmuck | 0:27aa8733f85d | 432 | RegLna_t RegLna; // 0x0c |
dudmuck | 0:27aa8733f85d | 433 | |
dudmuck | 0:27aa8733f85d | 434 | RegIrqFlags_t RegIrqFlags; // 0x12 |
dudmuck | 0:27aa8733f85d | 435 | uint8_t RegRxNbBytes; // 0x13 |
dudmuck | 0:27aa8733f85d | 436 | RegModemStatus_t RegModemStatus; // 0x18 |
dudmuck | 0:27aa8733f85d | 437 | int8_t RegPktSnrValue; // 0x19 signed, s/n can be negative |
dudmuck | 0:27aa8733f85d | 438 | uint8_t RegPktRssiValue; // 0x1a |
dudmuck | 0:27aa8733f85d | 439 | RegHopChannel_t RegHopChannel; // 0x1c |
dudmuck | 0:27aa8733f85d | 440 | RegModemConfig_t RegModemConfig; // 0x1d |
dudmuck | 0:27aa8733f85d | 441 | RegModemConfig2_t RegModemConfig2; // 0x1e |
dudmuck | 0:27aa8733f85d | 442 | uint16_t RegPreamble; // 0x20->0x21 |
dudmuck | 0:27aa8733f85d | 443 | uint8_t RegPayloadLength; // 0x22 |
dudmuck | 0:27aa8733f85d | 444 | uint8_t RegRxMaxPayloadLength; // 0x23 |
dudmuck | 0:27aa8733f85d | 445 | uint8_t RegHopPeriod; // 0x24 |
dudmuck | 0:27aa8733f85d | 446 | RegModemConfig3_t RegModemConfig3; // 0x26 |
dudmuck | 0:27aa8733f85d | 447 | RegTest31_t RegTest31; // 0x31 |
dudmuck | 0:27aa8733f85d | 448 | |
dudmuck | 0:27aa8733f85d | 449 | //! pin assignments |
dudmuck | 0:27aa8733f85d | 450 | RegDioMapping1_t RegDioMapping1; |
dudmuck | 0:27aa8733f85d | 451 | |
dudmuck | 0:27aa8733f85d | 452 | //! pin assignments |
dudmuck | 0:27aa8733f85d | 453 | RegDioMapping2_t RegDioMapping2; |
dudmuck | 0:27aa8733f85d | 454 | |
dudmuck | 0:27aa8733f85d | 455 | bool poll_vh; |
dudmuck | 0:27aa8733f85d | 456 | |
dudmuck | 0:27aa8733f85d | 457 | // frequency hopping table |
dudmuck | 0:27aa8733f85d | 458 | const uint32_t *frfs; |
dudmuck | 0:27aa8733f85d | 459 | |
dudmuck | 1:7dc60eb4c7ec | 460 | InterruptIn dio0; |
dudmuck | 1:7dc60eb4c7ec | 461 | InterruptIn dio1; |
dudmuck | 1:7dc60eb4c7ec | 462 | DigitalOut femcps; // LF rf switch |
dudmuck | 1:7dc60eb4c7ec | 463 | DigitalOut femctx; // HF rf switch |
dudmuck | 1:7dc60eb4c7ec | 464 | |
dudmuck | 0:27aa8733f85d | 465 | private: |
dudmuck | 0:27aa8733f85d | 466 | SPI m_spi; |
dudmuck | 0:27aa8733f85d | 467 | DigitalOut m_cs; |
dudmuck | 0:27aa8733f85d | 468 | DigitalInOut reset_pin; |
dudmuck | 1:7dc60eb4c7ec | 469 | |
dudmuck | 0:27aa8733f85d | 470 | //void dio0_callback(void); |
dudmuck | 0:27aa8733f85d | 471 | bool HF; // sx1272 is always HF |
dudmuck | 0:27aa8733f85d | 472 | void set_nb_trig_peaks(int); |
dudmuck | 0:27aa8733f85d | 473 | |
dudmuck | 0:27aa8733f85d | 474 | protected: |
dudmuck | 1:7dc60eb4c7ec | 475 | |
dudmuck | 0:27aa8733f85d | 476 | FunctionPointer _callback_rx; |
dudmuck | 0:27aa8733f85d | 477 | }; |
dudmuck | 0:27aa8733f85d | 478 | |
dudmuck | 0:27aa8733f85d | 479 | #endif /* SX127x_H */ |