Driver library for SX1272/SX1276 transceivers

Fork of SX127x by wayne roberts

Committer:
dudmuck
Date:
Mon Jun 30 17:05:12 2014 +0000
Revision:
6:5d94ee847016
Parent:
5:dde68100518b
moved RF switch (femcps/femctx) control to set_opmode()

Who changed what in which revision?

UserRevisionLine numberNew 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 2:fdae76e1215e 46
dudmuck 0:27aa8733f85d 47 /***** registers above 0x40 are same as FSK/OOK page */
dudmuck 0:27aa8733f85d 48
dudmuck 0:27aa8733f85d 49 #define REG_DIOMAPPING1 0x40
dudmuck 0:27aa8733f85d 50 #define REG_DIOMAPPING2 0x41
dudmuck 0:27aa8733f85d 51 #define REG_VERSION 0x42
dudmuck 0:27aa8733f85d 52
dudmuck 6:5d94ee847016 53 #define REG_PLL 0x5C // RX PLL bandwidth
dudmuck 6:5d94ee847016 54 #define REG_BSYNCTST2 0x67
dudmuck 2:fdae76e1215e 55 /******************************************************************************/
dudmuck 0:27aa8733f85d 56
dudmuck 0:27aa8733f85d 57
dudmuck 0:27aa8733f85d 58 typedef enum {
dudmuck 0:27aa8733f85d 59 RF_OPMODE_SLEEP = 0,
dudmuck 0:27aa8733f85d 60 RF_OPMODE_STANDBY, // 1
dudmuck 0:27aa8733f85d 61 RF_OPMODE_SYNTHESIZER_TX, // 2
dudmuck 0:27aa8733f85d 62 RF_OPMODE_TRANSMITTER, // 3
dudmuck 0:27aa8733f85d 63 RF_OPMODE_SYNTHESIZER_RX, // 4
dudmuck 0:27aa8733f85d 64 RF_OPMODE_RECEIVER, // 5
dudmuck 0:27aa8733f85d 65 RF_OPMODE_RECEIVER_SINGLE, // 6
dudmuck 0:27aa8733f85d 66 RF_OPMODE_CAD // 7
dudmuck 0:27aa8733f85d 67 } chip_mode_e;
dudmuck 0:27aa8733f85d 68
dudmuck 0:27aa8733f85d 69 typedef enum {
dudmuck 0:27aa8733f85d 70 SX_NONE = 0,
dudmuck 0:27aa8733f85d 71 SX1272,
dudmuck 0:27aa8733f85d 72 SX1276
dudmuck 0:27aa8733f85d 73 } type_e;
dudmuck 0:27aa8733f85d 74
dudmuck 0:27aa8733f85d 75 typedef enum {
dudmuck 0:27aa8733f85d 76 SERVICE_NONE = 0,
dudmuck 0:27aa8733f85d 77 SERVICE_ERROR,
dudmuck 0:27aa8733f85d 78 //! request to call read_fifo()
dudmuck 0:27aa8733f85d 79 SERVICE_READ_FIFO,
dudmuck 0:27aa8733f85d 80 //! notification to application of transmit complete
dudmuck 0:27aa8733f85d 81 SERVICE_TX_DONE
dudmuck 0:27aa8733f85d 82 } service_action_e;
dudmuck 0:27aa8733f85d 83
dudmuck 0:27aa8733f85d 84 /******************************************************************************/
dudmuck 0:27aa8733f85d 85
dudmuck 0:27aa8733f85d 86 typedef union {
dudmuck 0:27aa8733f85d 87 struct { // sx1272 register 0x01
dudmuck 0:27aa8733f85d 88 uint8_t Mode : 3; // 0,1,2
dudmuck 0:27aa8733f85d 89 uint8_t ModulationShaping : 2; // 3,4 FSK/OOK
dudmuck 0:27aa8733f85d 90 uint8_t ModulationType : 2; // 5,6 FSK/OOK
dudmuck 0:27aa8733f85d 91 uint8_t LongRangeMode : 1; // 7 change this bit only in sleep mode
dudmuck 0:27aa8733f85d 92 } bits;
dudmuck 0:27aa8733f85d 93 struct { // sx1276 register 0x01
dudmuck 0:27aa8733f85d 94 uint8_t Mode : 3; // 0,1,2
dudmuck 0:27aa8733f85d 95 uint8_t LowFrequencyModeOn : 1; // 3 1=access to LF test registers (0=HF regs)
dudmuck 0:27aa8733f85d 96 uint8_t reserved : 1; // 4
dudmuck 0:27aa8733f85d 97 uint8_t ModulationType : 2; // 5,6 FSK/OOK
dudmuck 0:27aa8733f85d 98 uint8_t LongRangeMode : 1; // 7 change this bit only in sleep mode
dudmuck 0:27aa8733f85d 99 } sx1276FSKbits;
dudmuck 0:27aa8733f85d 100 struct { // sx1276 register 0x01
dudmuck 0:27aa8733f85d 101 uint8_t Mode : 3; // 0,1,2
dudmuck 0:27aa8733f85d 102 uint8_t LowFrequencyModeOn : 1; // 3 1=access to LF test registers (0=HF regs)
dudmuck 0:27aa8733f85d 103 uint8_t reserved : 2; // 4,5
dudmuck 0:27aa8733f85d 104 uint8_t AccessSharedReg : 1; // 6 1=FSK registers while in LoRa mode
dudmuck 0:27aa8733f85d 105 uint8_t LongRangeMode : 1; // 7 change this bit only in sleep mode
dudmuck 0:27aa8733f85d 106 } sx1276LORAbits;
dudmuck 0:27aa8733f85d 107 uint8_t octet;
dudmuck 0:27aa8733f85d 108 } RegOpMode_t;
dudmuck 0:27aa8733f85d 109
dudmuck 0:27aa8733f85d 110 typedef union {
dudmuck 0:27aa8733f85d 111 struct { // sx12xx register 0x09
dudmuck 0:27aa8733f85d 112 uint8_t OutputPower : 4; // 0,1,2,3
dudmuck 0:27aa8733f85d 113 uint8_t MaxPower : 3; // 4,5,6
dudmuck 0:27aa8733f85d 114 uint8_t PaSelect : 1; // 7 1=PA_BOOST
dudmuck 0:27aa8733f85d 115 } bits;
dudmuck 0:27aa8733f85d 116 uint8_t octet;
dudmuck 0:27aa8733f85d 117 } RegPaConfig_t;
dudmuck 0:27aa8733f85d 118
dudmuck 0:27aa8733f85d 119 typedef union {
dudmuck 0:27aa8733f85d 120 struct { // sx12xx register 0x0b
dudmuck 0:27aa8733f85d 121 uint8_t OcpTrim : 5; // 0,1,2,3,4
dudmuck 0:27aa8733f85d 122 uint8_t OcpOn : 1; // 5
dudmuck 0:27aa8733f85d 123 uint8_t unused : 2; // 6,7
dudmuck 0:27aa8733f85d 124 } bits;
dudmuck 0:27aa8733f85d 125 uint8_t octet;
dudmuck 0:27aa8733f85d 126 } RegOcp_t;
dudmuck 0:27aa8733f85d 127
dudmuck 0:27aa8733f85d 128 typedef union {
dudmuck 0:27aa8733f85d 129 struct { // sx12xx register 0x0c
dudmuck 0:27aa8733f85d 130 uint8_t LnaBoostHF : 2; // 0,1
dudmuck 0:27aa8733f85d 131 uint8_t reserved : 1; // 2
dudmuck 0:27aa8733f85d 132 uint8_t LnaBoostLF : 2; // 3,4
dudmuck 0:27aa8733f85d 133 uint8_t LnaGain : 3; // 5,6,7
dudmuck 0:27aa8733f85d 134 } bits;
dudmuck 0:27aa8733f85d 135 uint8_t octet;
dudmuck 0:27aa8733f85d 136 } RegLna_t; // RXFE
dudmuck 0:27aa8733f85d 137
dudmuck 0:27aa8733f85d 138
dudmuck 2:fdae76e1215e 139 /*********************** ****************************/
dudmuck 0:27aa8733f85d 140
dudmuck 0:27aa8733f85d 141 typedef union {
dudmuck 0:27aa8733f85d 142 struct { // sx12xx register 0x40
dudmuck 0:27aa8733f85d 143 uint8_t Dio3Mapping : 2; // 0,1
dudmuck 0:27aa8733f85d 144 uint8_t Dio2Mapping : 2; // 2,3
dudmuck 0:27aa8733f85d 145 uint8_t Dio1Mapping : 2; // 4,5
dudmuck 0:27aa8733f85d 146 uint8_t Dio0Mapping : 2; // 6,7
dudmuck 0:27aa8733f85d 147 } bits;
dudmuck 0:27aa8733f85d 148 uint8_t octet;
dudmuck 0:27aa8733f85d 149 } RegDioMapping1_t;
dudmuck 0:27aa8733f85d 150
dudmuck 0:27aa8733f85d 151 typedef union {
dudmuck 0:27aa8733f85d 152 struct { // sx12xx register 0x41
dudmuck 0:27aa8733f85d 153 uint8_t MapPreambleDetect : 1; // 0 //DIO4 assign: 1b=preambleDet 0b=rssiThresh
dudmuck 0:27aa8733f85d 154 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 155 uint8_t Dio5Mapping : 2; // 4,5
dudmuck 0:27aa8733f85d 156 uint8_t Dio4Mapping : 2; // 6,7
dudmuck 0:27aa8733f85d 157 } bits;
dudmuck 0:27aa8733f85d 158 uint8_t octet;
dudmuck 0:27aa8733f85d 159 } RegDioMapping2_t;
dudmuck 0:27aa8733f85d 160
dudmuck 6:5d94ee847016 161 typedef union {
dudmuck 6:5d94ee847016 162 struct { // sx1272 register 0x5c
dudmuck 6:5d94ee847016 163 uint8_t reserved : 6; // 0->5
dudmuck 6:5d94ee847016 164 uint8_t PllBandwidth : 2; // 6,7
dudmuck 6:5d94ee847016 165 } bits;
dudmuck 6:5d94ee847016 166 uint8_t octet;
dudmuck 6:5d94ee847016 167 } RegPll_t;
dudmuck 6:5d94ee847016 168
dudmuck 6:5d94ee847016 169 typedef union {
dudmuck 6:5d94ee847016 170 struct { // sx1272 register 0x67
dudmuck 6:5d94ee847016 171 uint8_t bsync_mode : 3; // 0,1,2
dudmuck 6:5d94ee847016 172 uint8_t reserved : 1; // 3
dudmuck 6:5d94ee847016 173 uint8_t bsync_thresh_validity : 1; // 4
dudmuck 6:5d94ee847016 174 uint8_t unused : 3; // 5,6,7
dudmuck 6:5d94ee847016 175 } bits;
dudmuck 6:5d94ee847016 176 uint8_t octet;
dudmuck 6:5d94ee847016 177 } RegBsyncTest2_t;
dudmuck 6:5d94ee847016 178
dudmuck 0:27aa8733f85d 179 /***************************************************/
dudmuck 0:27aa8733f85d 180
dudmuck 0:27aa8733f85d 181 /** FSK/LoRa radio transceiver.
dudmuck 0:27aa8733f85d 182 * see http://en.wikipedia.org/wiki/Chirp_spread_spectrum
dudmuck 0:27aa8733f85d 183 */
dudmuck 0:27aa8733f85d 184
dudmuck 0:27aa8733f85d 185 class SX127x {
dudmuck 0:27aa8733f85d 186 public:
dudmuck 0:27aa8733f85d 187 /** Create SX127x instance
dudmuck 0:27aa8733f85d 188 * @param mosi SPI master-out pin
dudmuck 0:27aa8733f85d 189 * @param miso SPI master-in pin
dudmuck 0:27aa8733f85d 190 * @param sclk SPI clock pin
dudmuck 0:27aa8733f85d 191 * @param cs SPI chip-select pin
dudmuck 0:27aa8733f85d 192 * @param rst radio hardware reset pin
dudmuck 0:27aa8733f85d 193 * @param dio_0 interrupt pin from radio
dudmuck 0:27aa8733f85d 194 * @param fem_ctx rx-tx switch for HF bands (800/900)
dudmuck 0:27aa8733f85d 195 * @param fem_cps rx-tx switch for LF bands (vhf/433)
dudmuck 0:27aa8733f85d 196 */
dudmuck 2:fdae76e1215e 197
dudmuck 0:27aa8733f85d 198 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 199
dudmuck 0:27aa8733f85d 200 ~SX127x();
dudmuck 0:27aa8733f85d 201
dudmuck 0:27aa8733f85d 202 /** set center operating frequency
dudmuck 0:27aa8733f85d 203 * @param MHz operating frequency in MHz
dudmuck 0:27aa8733f85d 204 */
dudmuck 0:27aa8733f85d 205 void set_frf_MHz( float MHz );
dudmuck 0:27aa8733f85d 206
dudmuck 0:27aa8733f85d 207 /** get center operating frequency
dudmuck 0:27aa8733f85d 208 * @returns operating frequency in MHz
dudmuck 0:27aa8733f85d 209 */
dudmuck 0:27aa8733f85d 210 float get_frf_MHz(void);
dudmuck 0:27aa8733f85d 211
dudmuck 0:27aa8733f85d 212 void set_opmode(chip_mode_e mode);
dudmuck 0:27aa8733f85d 213
dudmuck 0:27aa8733f85d 214 /** reset radio using pin
dudmuck 0:27aa8733f85d 215 */
dudmuck 0:27aa8733f85d 216 void hw_reset(void);
dudmuck 0:27aa8733f85d 217 /** initialise SX1232 class to radio
dudmuck 0:27aa8733f85d 218 * @note this is called from class instantiation, but must also be manually called after hardware reset
dudmuck 0:27aa8733f85d 219 */
dudmuck 0:27aa8733f85d 220 void init(void);
dudmuck 0:27aa8733f85d 221 void get_type(void); // identify radio chip
dudmuck 0:27aa8733f85d 222
dudmuck 0:27aa8733f85d 223 /** read register from radio
dudmuck 0:27aa8733f85d 224 * @param addr register address
dudmuck 0:27aa8733f85d 225 * @returns the value read from the register
dudmuck 0:27aa8733f85d 226 */
dudmuck 0:27aa8733f85d 227 uint8_t read_reg(uint8_t addr);
dudmuck 0:27aa8733f85d 228 uint16_t read_u16(uint8_t addr);
dudmuck 2:fdae76e1215e 229 int16_t read_s16(uint8_t addr);
dudmuck 0:27aa8733f85d 230
dudmuck 1:7dc60eb4c7ec 231 /** read register from radio. from an arbitrary amount of registers following the first
dudmuck 1:7dc60eb4c7ec 232 * @param addr register address
dudmuck 1:7dc60eb4c7ec 233 * @param buffer the read values will be placed here
dudmuck 1:7dc60eb4c7ec 234 * @param size how many registers to read
dudmuck 1:7dc60eb4c7ec 235 */
dudmuck 1:7dc60eb4c7ec 236 void ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size );
dudmuck 1:7dc60eb4c7ec 237
dudmuck 0:27aa8733f85d 238 /** write register to radio
dudmuck 0:27aa8733f85d 239 * @param addr register address
dudmuck 0:27aa8733f85d 240 * @param data byte to write
dudmuck 0:27aa8733f85d 241 */
dudmuck 0:27aa8733f85d 242 void write_reg(uint8_t addr, uint8_t data);
dudmuck 4:d987ac2836bf 243 void write_u16(uint8_t addr, uint16_t data);
dudmuck 4:d987ac2836bf 244 void write_u24(uint8_t addr, uint32_t data);
dudmuck 0:27aa8733f85d 245
dudmuck 1:7dc60eb4c7ec 246 /** write register(s) to radio, to an arbitrary amount of registers following first
dudmuck 1:7dc60eb4c7ec 247 * @param addr register address
dudmuck 1:7dc60eb4c7ec 248 * @param buffer byte(s) to write
dudmuck 1:7dc60eb4c7ec 249 * @param size count of registers to write to
dudmuck 1:7dc60eb4c7ec 250 */
dudmuck 1:7dc60eb4c7ec 251 void WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size );
dudmuck 1:7dc60eb4c7ec 252
dudmuck 1:7dc60eb4c7ec 253 /* *switch between FSK or LoRa modes */
dudmuck 2:fdae76e1215e 254 //void SetLoRaOn(bool);
dudmuck 1:7dc60eb4c7ec 255
dudmuck 0:27aa8733f85d 256 /*****************************************************/
dudmuck 0:27aa8733f85d 257
dudmuck 0:27aa8733f85d 258 //! RF transmit packet buffer
dudmuck 0:27aa8733f85d 259 uint8_t tx_buf[256]; // lora fifo size
dudmuck 0:27aa8733f85d 260
dudmuck 0:27aa8733f85d 261 //! RF receive packet buffer
dudmuck 0:27aa8733f85d 262 uint8_t rx_buf[256]; // lora fifo size
dudmuck 0:27aa8733f85d 263
dudmuck 0:27aa8733f85d 264 //! radio chip type plugged in
dudmuck 0:27aa8733f85d 265 type_e type;
dudmuck 0:27aa8733f85d 266
dudmuck 0:27aa8733f85d 267 //! operating mode
dudmuck 0:27aa8733f85d 268 RegOpMode_t RegOpMode;
dudmuck 0:27aa8733f85d 269
dudmuck 0:27aa8733f85d 270 //! transmitter power configuration
dudmuck 0:27aa8733f85d 271 RegPaConfig_t RegPaConfig;
dudmuck 0:27aa8733f85d 272
dudmuck 0:27aa8733f85d 273 RegOcp_t RegOcp; // 0x0b
dudmuck 0:27aa8733f85d 274
dudmuck 0:27aa8733f85d 275 // receiver front-end
dudmuck 0:27aa8733f85d 276 RegLna_t RegLna; // 0x0c
dudmuck 0:27aa8733f85d 277
dudmuck 0:27aa8733f85d 278 //! pin assignments
dudmuck 0:27aa8733f85d 279 RegDioMapping1_t RegDioMapping1;
dudmuck 0:27aa8733f85d 280
dudmuck 0:27aa8733f85d 281 //! pin assignments
dudmuck 2:fdae76e1215e 282 RegDioMapping2_t RegDioMapping2;
dudmuck 0:27aa8733f85d 283
dudmuck 6:5d94ee847016 284 RegPll_t RegPll; // 0x5C
dudmuck 6:5d94ee847016 285 RegBsyncTest2_t RegBsyncTest2; // 0x67
dudmuck 6:5d94ee847016 286
dudmuck 0:27aa8733f85d 287 // frequency hopping table
dudmuck 0:27aa8733f85d 288 const uint32_t *frfs;
dudmuck 0:27aa8733f85d 289
dudmuck 5:dde68100518b 290 DigitalIn dio0;
dudmuck 5:dde68100518b 291 DigitalIn dio1;
dudmuck 6:5d94ee847016 292
dudmuck 2:fdae76e1215e 293 DigitalOut m_cs;
dudmuck 2:fdae76e1215e 294 SPI m_spi;
dudmuck 2:fdae76e1215e 295 bool HF; // sx1272 is always HF
dudmuck 1:7dc60eb4c7ec 296
dudmuck 2:fdae76e1215e 297 private:
dudmuck 0:27aa8733f85d 298 DigitalInOut reset_pin;
dudmuck 0:27aa8733f85d 299 //void dio0_callback(void);
dudmuck 6:5d94ee847016 300 DigitalOut femcps; // LF rf switch
dudmuck 6:5d94ee847016 301 DigitalOut femctx; // HF rf switch
dudmuck 2:fdae76e1215e 302
dudmuck 0:27aa8733f85d 303
dudmuck 0:27aa8733f85d 304 protected:
dudmuck 2:fdae76e1215e 305 FunctionPointer _callback_rx;
dudmuck 2:fdae76e1215e 306
dudmuck 0:27aa8733f85d 307 };
dudmuck 0:27aa8733f85d 308
dudmuck 0:27aa8733f85d 309 #endif /* SX127x_H */