Driver library for SX1272/SX1276 transceivers

Fork of SX127x by wayne roberts

Committer:
dudmuck
Date:
Fri May 02 23:35:30 2014 +0000
Revision:
4:d987ac2836bf
Parent:
2:fdae76e1215e
Child:
5:dde68100518b
fixed FSK AFC

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