Driver library for SX1272/SX1276 transceivers

Fork of SX127x by wayne roberts

Committer:
efountain
Date:
Thu Sep 04 20:57:28 2014 +0000
Revision:
7:c785b65d3db4
Parent:
6:5d94ee847016
Updated SX127x library...NorAm Mote

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:27aa8733f85d 1 #include "sx127x.h"
dudmuck 0:27aa8733f85d 2
dudmuck 0:27aa8733f85d 3 /* SX127x driver
dudmuck 0:27aa8733f85d 4 * Copyright (c) 2013 Semtech
dudmuck 0:27aa8733f85d 5 *
dudmuck 0:27aa8733f85d 6 * Licensed under the Apache License, Version 2.0 (the "License");
dudmuck 0:27aa8733f85d 7 * you may not use this file except in compliance with the License.
dudmuck 0:27aa8733f85d 8 * You may obtain a copy of the License at
dudmuck 0:27aa8733f85d 9 *
dudmuck 0:27aa8733f85d 10 * http://www.apache.org/licenses/LICENSE-2.0
dudmuck 0:27aa8733f85d 11 *
dudmuck 0:27aa8733f85d 12 * Unless required by applicable law or agreed to in writing, software
dudmuck 0:27aa8733f85d 13 * distributed under the License is distributed on an "AS IS" BASIS,
dudmuck 0:27aa8733f85d 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dudmuck 0:27aa8733f85d 15 * See the License for the specific language governing permissions and
dudmuck 0:27aa8733f85d 16 * limitations under the License.
dudmuck 0:27aa8733f85d 17 */
dudmuck 0:27aa8733f85d 18
dudmuck 0:27aa8733f85d 19 SX127x::SX127x(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0, PinName dio_1, PinName fem_ctx, PinName fem_cps) :
efountain 7:c785b65d3db4 20 m_spi(mosi, miso, sclk,cs), m_cs(cs), reset_pin(rst), dio0(dio_0), dio1(dio_1), femctx(fem_ctx), femcps(fem_cps)
dudmuck 0:27aa8733f85d 21 {
dudmuck 0:27aa8733f85d 22 reset_pin.input();
dudmuck 0:27aa8733f85d 23 m_cs = 1;
dudmuck 0:27aa8733f85d 24 m_spi.format(8, 0);
dudmuck 1:7dc60eb4c7ec 25 m_spi.frequency(3000000);
dudmuck 0:27aa8733f85d 26
dudmuck 0:27aa8733f85d 27 init();
dudmuck 0:27aa8733f85d 28 }
dudmuck 0:27aa8733f85d 29
dudmuck 0:27aa8733f85d 30 SX127x::~SX127x()
dudmuck 0:27aa8733f85d 31 {
dudmuck 0:27aa8733f85d 32 set_opmode(RF_OPMODE_SLEEP);
dudmuck 0:27aa8733f85d 33 }
dudmuck 0:27aa8733f85d 34
dudmuck 0:27aa8733f85d 35 void SX127x::init()
dudmuck 0:27aa8733f85d 36 {
dudmuck 0:27aa8733f85d 37 type = SX_NONE;
dudmuck 0:27aa8733f85d 38
dudmuck 0:27aa8733f85d 39 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:27aa8733f85d 40 RegPaConfig.octet = read_reg(REG_PACONFIG);
dudmuck 0:27aa8733f85d 41 RegLna.octet = read_reg(REG_LNA);
dudmuck 0:27aa8733f85d 42 RegDioMapping1.octet = read_reg(REG_DIOMAPPING1);
dudmuck 0:27aa8733f85d 43 RegDioMapping2.octet = read_reg(REG_DIOMAPPING2);
dudmuck 0:27aa8733f85d 44
dudmuck 4:d987ac2836bf 45 /* if (!RegOpMode.bits.LongRangeMode) {
dudmuck 0:27aa8733f85d 46 if (RegOpMode.bits.Mode != RF_OPMODE_SLEEP)
dudmuck 0:27aa8733f85d 47 set_opmode(RF_OPMODE_SLEEP);
dudmuck 0:27aa8733f85d 48 RegOpMode.bits.LongRangeMode = 1;
dudmuck 0:27aa8733f85d 49 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 4:d987ac2836bf 50 }*/
dudmuck 0:27aa8733f85d 51
dudmuck 0:27aa8733f85d 52 get_type();
dudmuck 0:27aa8733f85d 53
dudmuck 4:d987ac2836bf 54 if (type == SX1272) {
dudmuck 4:d987ac2836bf 55 // turn on PA BOOST, eval boards are wired for this connection
dudmuck 4:d987ac2836bf 56 RegPaConfig.bits.PaSelect = 1;
dudmuck 4:d987ac2836bf 57 write_reg(REG_PACONFIG, RegPaConfig.octet);
dudmuck 4:d987ac2836bf 58 }
dudmuck 0:27aa8733f85d 59 }
dudmuck 0:27aa8733f85d 60
dudmuck 0:27aa8733f85d 61 void SX127x::get_type()
dudmuck 0:27aa8733f85d 62 {
dudmuck 0:27aa8733f85d 63 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:27aa8733f85d 64 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 65 type = SX1276;
dudmuck 0:27aa8733f85d 66 else {
dudmuck 0:27aa8733f85d 67 RegOpMode.sx1276LORAbits.LowFrequencyModeOn = 1;
dudmuck 0:27aa8733f85d 68 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 69 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:27aa8733f85d 70 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 71 type = SX1276;
dudmuck 0:27aa8733f85d 72 else
dudmuck 0:27aa8733f85d 73 type = SX1272;
dudmuck 0:27aa8733f85d 74 }
dudmuck 0:27aa8733f85d 75 }
dudmuck 1:7dc60eb4c7ec 76
dudmuck 1:7dc60eb4c7ec 77 void
dudmuck 1:7dc60eb4c7ec 78 SX127x::ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 79 {
dudmuck 1:7dc60eb4c7ec 80 uint8_t i;
dudmuck 1:7dc60eb4c7ec 81
dudmuck 1:7dc60eb4c7ec 82 m_cs = 0;
dudmuck 1:7dc60eb4c7ec 83
dudmuck 1:7dc60eb4c7ec 84 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 1:7dc60eb4c7ec 85
dudmuck 1:7dc60eb4c7ec 86 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 87 {
dudmuck 1:7dc60eb4c7ec 88 buffer[i] = m_spi.write(0x00);
dudmuck 1:7dc60eb4c7ec 89 }
dudmuck 1:7dc60eb4c7ec 90
dudmuck 1:7dc60eb4c7ec 91 m_cs = 1;
dudmuck 1:7dc60eb4c7ec 92 }
dudmuck 1:7dc60eb4c7ec 93
dudmuck 0:27aa8733f85d 94 uint8_t SX127x::read_reg(uint8_t addr)
dudmuck 0:27aa8733f85d 95 {
dudmuck 0:27aa8733f85d 96 uint8_t ret;
dudmuck 0:27aa8733f85d 97 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 98 m_cs = 0;
dudmuck 0:27aa8733f85d 99
dudmuck 0:27aa8733f85d 100 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 101
dudmuck 0:27aa8733f85d 102 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 103 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 104
dudmuck 0:27aa8733f85d 105 // Deselect the device
dudmuck 0:27aa8733f85d 106 m_cs = 1;
dudmuck 0:27aa8733f85d 107
dudmuck 0:27aa8733f85d 108 return ret;
dudmuck 0:27aa8733f85d 109 }
dudmuck 0:27aa8733f85d 110
dudmuck 2:fdae76e1215e 111 int16_t SX127x::read_s16(uint8_t addr)
dudmuck 2:fdae76e1215e 112 {
dudmuck 2:fdae76e1215e 113 int16_t ret;
dudmuck 2:fdae76e1215e 114 // Select the device by seting chip select low
dudmuck 2:fdae76e1215e 115 m_cs = 0;
dudmuck 2:fdae76e1215e 116
dudmuck 2:fdae76e1215e 117 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 2:fdae76e1215e 118
dudmuck 2:fdae76e1215e 119 // Send a dummy byte to receive the contents of register
dudmuck 2:fdae76e1215e 120 ret = m_spi.write(0x00);
dudmuck 2:fdae76e1215e 121 ret <<= 8;
dudmuck 2:fdae76e1215e 122 ret += m_spi.write(0x00);
dudmuck 2:fdae76e1215e 123
dudmuck 2:fdae76e1215e 124 // Deselect the device
dudmuck 2:fdae76e1215e 125 m_cs = 1;
dudmuck 2:fdae76e1215e 126
dudmuck 2:fdae76e1215e 127 return ret;
dudmuck 2:fdae76e1215e 128 }
dudmuck 2:fdae76e1215e 129
dudmuck 0:27aa8733f85d 130 uint16_t SX127x::read_u16(uint8_t addr)
dudmuck 0:27aa8733f85d 131 {
dudmuck 0:27aa8733f85d 132 uint16_t ret;
dudmuck 0:27aa8733f85d 133 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 134 m_cs = 0;
dudmuck 0:27aa8733f85d 135
dudmuck 0:27aa8733f85d 136 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 137
dudmuck 0:27aa8733f85d 138 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 139 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 140 ret <<= 8;
dudmuck 0:27aa8733f85d 141 ret += m_spi.write(0x00);
dudmuck 0:27aa8733f85d 142
dudmuck 0:27aa8733f85d 143 // Deselect the device
dudmuck 0:27aa8733f85d 144 m_cs = 1;
dudmuck 0:27aa8733f85d 145
dudmuck 0:27aa8733f85d 146 return ret;
dudmuck 0:27aa8733f85d 147 }
dudmuck 0:27aa8733f85d 148
dudmuck 4:d987ac2836bf 149 void SX127x::write_u16(uint8_t addr, uint16_t data)
dudmuck 4:d987ac2836bf 150 {
dudmuck 4:d987ac2836bf 151 m_cs = 0; // Select the device by seting chip select low
dudmuck 4:d987ac2836bf 152
dudmuck 4:d987ac2836bf 153 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 4:d987ac2836bf 154 m_spi.write((data >> 8) & 0xff);
dudmuck 4:d987ac2836bf 155 m_spi.write(data & 0xff);
dudmuck 4:d987ac2836bf 156
dudmuck 4:d987ac2836bf 157 m_cs = 1; // Deselect the device
dudmuck 4:d987ac2836bf 158 }
dudmuck 4:d987ac2836bf 159
dudmuck 4:d987ac2836bf 160 void SX127x::write_u24(uint8_t addr, uint32_t data)
dudmuck 0:27aa8733f85d 161 {
dudmuck 0:27aa8733f85d 162 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 163
dudmuck 0:27aa8733f85d 164 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 165 m_spi.write((data >> 16) & 0xff);
dudmuck 0:27aa8733f85d 166 m_spi.write((data >> 8) & 0xff);
dudmuck 0:27aa8733f85d 167 m_spi.write(data & 0xff);
dudmuck 0:27aa8733f85d 168
dudmuck 0:27aa8733f85d 169 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 170
dudmuck 0:27aa8733f85d 171 if (addr == REG_FRFMSB) {
dudmuck 0:27aa8733f85d 172 if (data < 0x8340000) // < 525MHz
dudmuck 0:27aa8733f85d 173 HF = false;
dudmuck 0:27aa8733f85d 174 else
dudmuck 0:27aa8733f85d 175 HF = true;
dudmuck 0:27aa8733f85d 176 }
dudmuck 0:27aa8733f85d 177 }
dudmuck 0:27aa8733f85d 178
dudmuck 0:27aa8733f85d 179 void SX127x::write_reg(uint8_t addr, uint8_t data)
dudmuck 0:27aa8733f85d 180 {
dudmuck 0:27aa8733f85d 181 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 182
dudmuck 0:27aa8733f85d 183 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 184 m_spi.write(data);
dudmuck 0:27aa8733f85d 185
dudmuck 0:27aa8733f85d 186 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 187 }
dudmuck 0:27aa8733f85d 188
dudmuck 1:7dc60eb4c7ec 189 void SX127x::WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 190 {
dudmuck 1:7dc60eb4c7ec 191 uint8_t i;
dudmuck 1:7dc60eb4c7ec 192
dudmuck 1:7dc60eb4c7ec 193 m_cs = 0; // Select the device by seting chip select low
dudmuck 1:7dc60eb4c7ec 194
dudmuck 1:7dc60eb4c7ec 195 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 1:7dc60eb4c7ec 196 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 197 {
dudmuck 1:7dc60eb4c7ec 198 m_spi.write(buffer[i]);
dudmuck 1:7dc60eb4c7ec 199 }
dudmuck 1:7dc60eb4c7ec 200
dudmuck 1:7dc60eb4c7ec 201 m_cs = 1; // Deselect the device
dudmuck 1:7dc60eb4c7ec 202 }
dudmuck 1:7dc60eb4c7ec 203
dudmuck 0:27aa8733f85d 204 void SX127x::set_opmode(chip_mode_e mode)
dudmuck 0:27aa8733f85d 205 {
dudmuck 0:27aa8733f85d 206 RegOpMode.bits.Mode = mode;
dudmuck 6:5d94ee847016 207
dudmuck 6:5d94ee847016 208 if (mode == RF_OPMODE_TRANSMITTER) { // start of transmission
dudmuck 6:5d94ee847016 209 if (HF)
dudmuck 6:5d94ee847016 210 femctx = 1;
dudmuck 6:5d94ee847016 211 else
dudmuck 6:5d94ee847016 212 femcps = 0;
dudmuck 6:5d94ee847016 213 } else if (mode == RF_OPMODE_RECEIVER) { // start of reception
dudmuck 6:5d94ee847016 214 if (HF)
dudmuck 6:5d94ee847016 215 femctx = 0;
dudmuck 6:5d94ee847016 216 else
dudmuck 6:5d94ee847016 217 femcps = 1;
dudmuck 6:5d94ee847016 218 }
dudmuck 6:5d94ee847016 219
dudmuck 0:27aa8733f85d 220 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 221 }
dudmuck 0:27aa8733f85d 222
dudmuck 0:27aa8733f85d 223 void SX127x::set_frf_MHz( float MHz )
dudmuck 0:27aa8733f85d 224 {
dudmuck 0:27aa8733f85d 225 uint32_t frf;
dudmuck 0:27aa8733f85d 226
dudmuck 0:27aa8733f85d 227 frf = MHz / FREQ_STEP_MHZ;
dudmuck 4:d987ac2836bf 228 write_u24(REG_FRFMSB, frf);
dudmuck 0:27aa8733f85d 229
dudmuck 0:27aa8733f85d 230 if (MHz < 525)
dudmuck 0:27aa8733f85d 231 HF = false;
dudmuck 0:27aa8733f85d 232 else
dudmuck 0:27aa8733f85d 233 HF = true;
dudmuck 0:27aa8733f85d 234 }
dudmuck 0:27aa8733f85d 235
dudmuck 0:27aa8733f85d 236 float SX127x::get_frf_MHz(void)
dudmuck 0:27aa8733f85d 237 {
dudmuck 0:27aa8733f85d 238 uint32_t frf;
dudmuck 0:27aa8733f85d 239 uint8_t lsb, mid, msb;
dudmuck 0:27aa8733f85d 240 float MHz;
dudmuck 0:27aa8733f85d 241
dudmuck 0:27aa8733f85d 242 msb = read_reg(REG_FRFMSB);
dudmuck 0:27aa8733f85d 243 mid = read_reg(REG_FRFMID);
dudmuck 0:27aa8733f85d 244 lsb = read_reg(REG_FRFLSB);
dudmuck 0:27aa8733f85d 245 frf = msb;
dudmuck 0:27aa8733f85d 246 frf <<= 8;
dudmuck 0:27aa8733f85d 247 frf += mid;
dudmuck 0:27aa8733f85d 248 frf <<= 8;
dudmuck 0:27aa8733f85d 249 frf += lsb;
dudmuck 0:27aa8733f85d 250
dudmuck 0:27aa8733f85d 251 MHz = frf * FREQ_STEP_MHZ;
dudmuck 0:27aa8733f85d 252
dudmuck 0:27aa8733f85d 253 if (MHz < 525)
dudmuck 0:27aa8733f85d 254 HF = false;
dudmuck 0:27aa8733f85d 255 else
dudmuck 0:27aa8733f85d 256 HF = true;
dudmuck 0:27aa8733f85d 257
dudmuck 0:27aa8733f85d 258 return MHz;
dudmuck 0:27aa8733f85d 259 }
dudmuck 0:27aa8733f85d 260
dudmuck 0:27aa8733f85d 261 void SX127x::hw_reset()
dudmuck 0:27aa8733f85d 262 {
dudmuck 0:27aa8733f85d 263 /* only a french-swiss design would have hi-Z deassert */
dudmuck 0:27aa8733f85d 264 reset_pin.output();
dudmuck 0:27aa8733f85d 265 reset_pin.write(1);
dudmuck 0:27aa8733f85d 266 wait(0.05);
dudmuck 0:27aa8733f85d 267 reset_pin.input();
dudmuck 0:27aa8733f85d 268 wait(0.05);
dudmuck 0:27aa8733f85d 269 }
dudmuck 0:27aa8733f85d 270