123

Committer:
dudmuck
Date:
Fri Feb 27 22:50:18 2015 +0000
Revision:
10:7382c260c4b1
Parent:
7:927a05f84ede
Child:
24:cad6e7ce6928
added get_symbol_duration() to determine if LowDataRateOptimize should be used

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 7:927a05f84ede 19 SX127x::SX127x(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0, PinName dio_1) :
dudmuck 7:927a05f84ede 20 m_spi(mosi, miso, sclk), m_cs(cs), reset_pin(rst), dio0(dio_0), dio1(dio_1)
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 0:27aa8733f85d 45 get_type();
dudmuck 0:27aa8733f85d 46
dudmuck 4:d987ac2836bf 47 if (type == SX1272) {
dudmuck 4:d987ac2836bf 48 // turn on PA BOOST, eval boards are wired for this connection
dudmuck 4:d987ac2836bf 49 RegPaConfig.bits.PaSelect = 1;
dudmuck 4:d987ac2836bf 50 write_reg(REG_PACONFIG, RegPaConfig.octet);
dudmuck 4:d987ac2836bf 51 }
dudmuck 0:27aa8733f85d 52 }
dudmuck 0:27aa8733f85d 53
dudmuck 0:27aa8733f85d 54 void SX127x::get_type()
dudmuck 0:27aa8733f85d 55 {
dudmuck 0:27aa8733f85d 56 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 10:7382c260c4b1 57
dudmuck 10:7382c260c4b1 58 /* SX1272 starts in FSK mode on powerup, RegOpMode bit3 will be set for BT1.0 in FSK */
dudmuck 10:7382c260c4b1 59 if (!RegOpMode.bits.LongRangeMode) {
dudmuck 10:7382c260c4b1 60 set_opmode(RF_OPMODE_SLEEP);
dudmuck 10:7382c260c4b1 61 wait(0.01);
dudmuck 10:7382c260c4b1 62 RegOpMode.bits.LongRangeMode = 1;
dudmuck 10:7382c260c4b1 63 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 10:7382c260c4b1 64 wait(0.01);
dudmuck 10:7382c260c4b1 65 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 10:7382c260c4b1 66 }
dudmuck 10:7382c260c4b1 67
dudmuck 0:27aa8733f85d 68 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 69 type = SX1276;
dudmuck 0:27aa8733f85d 70 else {
dudmuck 0:27aa8733f85d 71 RegOpMode.sx1276LORAbits.LowFrequencyModeOn = 1;
dudmuck 0:27aa8733f85d 72 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 73 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:27aa8733f85d 74 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 75 type = SX1276;
dudmuck 0:27aa8733f85d 76 else
dudmuck 0:27aa8733f85d 77 type = SX1272;
dudmuck 0:27aa8733f85d 78 }
dudmuck 0:27aa8733f85d 79 }
dudmuck 1:7dc60eb4c7ec 80
dudmuck 1:7dc60eb4c7ec 81 void
dudmuck 1:7dc60eb4c7ec 82 SX127x::ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 83 {
dudmuck 1:7dc60eb4c7ec 84 uint8_t i;
dudmuck 1:7dc60eb4c7ec 85
dudmuck 1:7dc60eb4c7ec 86 m_cs = 0;
dudmuck 1:7dc60eb4c7ec 87
dudmuck 1:7dc60eb4c7ec 88 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 1:7dc60eb4c7ec 89
dudmuck 1:7dc60eb4c7ec 90 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 91 {
dudmuck 1:7dc60eb4c7ec 92 buffer[i] = m_spi.write(0x00);
dudmuck 1:7dc60eb4c7ec 93 }
dudmuck 1:7dc60eb4c7ec 94
dudmuck 1:7dc60eb4c7ec 95 m_cs = 1;
dudmuck 1:7dc60eb4c7ec 96 }
dudmuck 1:7dc60eb4c7ec 97
dudmuck 0:27aa8733f85d 98 uint8_t SX127x::read_reg(uint8_t addr)
dudmuck 0:27aa8733f85d 99 {
dudmuck 0:27aa8733f85d 100 uint8_t ret;
dudmuck 0:27aa8733f85d 101 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 102 m_cs = 0;
dudmuck 0:27aa8733f85d 103
dudmuck 0:27aa8733f85d 104 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 105
dudmuck 0:27aa8733f85d 106 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 107 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 108
dudmuck 0:27aa8733f85d 109 // Deselect the device
dudmuck 0:27aa8733f85d 110 m_cs = 1;
dudmuck 0:27aa8733f85d 111
dudmuck 0:27aa8733f85d 112 return ret;
dudmuck 0:27aa8733f85d 113 }
dudmuck 0:27aa8733f85d 114
dudmuck 2:fdae76e1215e 115 int16_t SX127x::read_s16(uint8_t addr)
dudmuck 2:fdae76e1215e 116 {
dudmuck 2:fdae76e1215e 117 int16_t ret;
dudmuck 2:fdae76e1215e 118 // Select the device by seting chip select low
dudmuck 2:fdae76e1215e 119 m_cs = 0;
dudmuck 2:fdae76e1215e 120
dudmuck 2:fdae76e1215e 121 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 2:fdae76e1215e 122
dudmuck 2:fdae76e1215e 123 // Send a dummy byte to receive the contents of register
dudmuck 2:fdae76e1215e 124 ret = m_spi.write(0x00);
dudmuck 2:fdae76e1215e 125 ret <<= 8;
dudmuck 2:fdae76e1215e 126 ret += m_spi.write(0x00);
dudmuck 2:fdae76e1215e 127
dudmuck 2:fdae76e1215e 128 // Deselect the device
dudmuck 2:fdae76e1215e 129 m_cs = 1;
dudmuck 2:fdae76e1215e 130
dudmuck 2:fdae76e1215e 131 return ret;
dudmuck 2:fdae76e1215e 132 }
dudmuck 2:fdae76e1215e 133
dudmuck 0:27aa8733f85d 134 uint16_t SX127x::read_u16(uint8_t addr)
dudmuck 0:27aa8733f85d 135 {
dudmuck 0:27aa8733f85d 136 uint16_t ret;
dudmuck 0:27aa8733f85d 137 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 138 m_cs = 0;
dudmuck 0:27aa8733f85d 139
dudmuck 0:27aa8733f85d 140 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 141
dudmuck 0:27aa8733f85d 142 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 143 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 144 ret <<= 8;
dudmuck 0:27aa8733f85d 145 ret += m_spi.write(0x00);
dudmuck 0:27aa8733f85d 146
dudmuck 0:27aa8733f85d 147 // Deselect the device
dudmuck 0:27aa8733f85d 148 m_cs = 1;
dudmuck 0:27aa8733f85d 149
dudmuck 0:27aa8733f85d 150 return ret;
dudmuck 0:27aa8733f85d 151 }
dudmuck 0:27aa8733f85d 152
dudmuck 4:d987ac2836bf 153 void SX127x::write_u16(uint8_t addr, uint16_t data)
dudmuck 4:d987ac2836bf 154 {
dudmuck 4:d987ac2836bf 155 m_cs = 0; // Select the device by seting chip select low
dudmuck 4:d987ac2836bf 156
dudmuck 4:d987ac2836bf 157 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 4:d987ac2836bf 158 m_spi.write((data >> 8) & 0xff);
dudmuck 4:d987ac2836bf 159 m_spi.write(data & 0xff);
dudmuck 4:d987ac2836bf 160
dudmuck 4:d987ac2836bf 161 m_cs = 1; // Deselect the device
dudmuck 4:d987ac2836bf 162 }
dudmuck 4:d987ac2836bf 163
dudmuck 4:d987ac2836bf 164 void SX127x::write_u24(uint8_t addr, uint32_t data)
dudmuck 0:27aa8733f85d 165 {
dudmuck 0:27aa8733f85d 166 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 167
dudmuck 0:27aa8733f85d 168 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 169 m_spi.write((data >> 16) & 0xff);
dudmuck 0:27aa8733f85d 170 m_spi.write((data >> 8) & 0xff);
dudmuck 0:27aa8733f85d 171 m_spi.write(data & 0xff);
dudmuck 0:27aa8733f85d 172
dudmuck 0:27aa8733f85d 173 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 174
dudmuck 0:27aa8733f85d 175 if (addr == REG_FRFMSB) {
dudmuck 0:27aa8733f85d 176 if (data < 0x8340000) // < 525MHz
dudmuck 0:27aa8733f85d 177 HF = false;
dudmuck 0:27aa8733f85d 178 else
dudmuck 0:27aa8733f85d 179 HF = true;
dudmuck 0:27aa8733f85d 180 }
dudmuck 0:27aa8733f85d 181 }
dudmuck 0:27aa8733f85d 182
dudmuck 0:27aa8733f85d 183 void SX127x::write_reg(uint8_t addr, uint8_t data)
dudmuck 0:27aa8733f85d 184 {
dudmuck 0:27aa8733f85d 185 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 186
dudmuck 0:27aa8733f85d 187 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 188 m_spi.write(data);
dudmuck 0:27aa8733f85d 189
dudmuck 0:27aa8733f85d 190 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 191 }
dudmuck 0:27aa8733f85d 192
dudmuck 1:7dc60eb4c7ec 193 void SX127x::WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 194 {
dudmuck 1:7dc60eb4c7ec 195 uint8_t i;
dudmuck 1:7dc60eb4c7ec 196
dudmuck 1:7dc60eb4c7ec 197 m_cs = 0; // Select the device by seting chip select low
dudmuck 1:7dc60eb4c7ec 198
dudmuck 1:7dc60eb4c7ec 199 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 1:7dc60eb4c7ec 200 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 201 {
dudmuck 1:7dc60eb4c7ec 202 m_spi.write(buffer[i]);
dudmuck 1:7dc60eb4c7ec 203 }
dudmuck 1:7dc60eb4c7ec 204
dudmuck 1:7dc60eb4c7ec 205 m_cs = 1; // Deselect the device
dudmuck 1:7dc60eb4c7ec 206 }
dudmuck 1:7dc60eb4c7ec 207
dudmuck 0:27aa8733f85d 208 void SX127x::set_opmode(chip_mode_e mode)
dudmuck 0:27aa8733f85d 209 {
dudmuck 0:27aa8733f85d 210 RegOpMode.bits.Mode = mode;
dudmuck 7:927a05f84ede 211
dudmuck 7:927a05f84ede 212 // callback to control antenna switch and PaSelect (PABOOST/RFO) for TX
dudmuck 7:927a05f84ede 213 rf_switch.call();
dudmuck 7:927a05f84ede 214
dudmuck 0:27aa8733f85d 215 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 216 }
dudmuck 0:27aa8733f85d 217
dudmuck 0:27aa8733f85d 218 void SX127x::set_frf_MHz( float MHz )
dudmuck 0:27aa8733f85d 219 {
dudmuck 0:27aa8733f85d 220 uint32_t frf;
dudmuck 0:27aa8733f85d 221
dudmuck 0:27aa8733f85d 222 frf = MHz / FREQ_STEP_MHZ;
dudmuck 4:d987ac2836bf 223 write_u24(REG_FRFMSB, frf);
dudmuck 0:27aa8733f85d 224
dudmuck 0:27aa8733f85d 225 if (MHz < 525)
dudmuck 0:27aa8733f85d 226 HF = false;
dudmuck 0:27aa8733f85d 227 else
dudmuck 0:27aa8733f85d 228 HF = true;
dudmuck 0:27aa8733f85d 229 }
dudmuck 0:27aa8733f85d 230
dudmuck 0:27aa8733f85d 231 float SX127x::get_frf_MHz(void)
dudmuck 0:27aa8733f85d 232 {
dudmuck 0:27aa8733f85d 233 uint32_t frf;
dudmuck 0:27aa8733f85d 234 uint8_t lsb, mid, msb;
dudmuck 0:27aa8733f85d 235 float MHz;
dudmuck 0:27aa8733f85d 236
dudmuck 0:27aa8733f85d 237 msb = read_reg(REG_FRFMSB);
dudmuck 0:27aa8733f85d 238 mid = read_reg(REG_FRFMID);
dudmuck 0:27aa8733f85d 239 lsb = read_reg(REG_FRFLSB);
dudmuck 0:27aa8733f85d 240 frf = msb;
dudmuck 0:27aa8733f85d 241 frf <<= 8;
dudmuck 0:27aa8733f85d 242 frf += mid;
dudmuck 0:27aa8733f85d 243 frf <<= 8;
dudmuck 0:27aa8733f85d 244 frf += lsb;
dudmuck 0:27aa8733f85d 245
dudmuck 0:27aa8733f85d 246 MHz = frf * FREQ_STEP_MHZ;
dudmuck 0:27aa8733f85d 247
dudmuck 0:27aa8733f85d 248 if (MHz < 525)
dudmuck 0:27aa8733f85d 249 HF = false;
dudmuck 0:27aa8733f85d 250 else
dudmuck 0:27aa8733f85d 251 HF = true;
dudmuck 0:27aa8733f85d 252
dudmuck 0:27aa8733f85d 253 return MHz;
dudmuck 0:27aa8733f85d 254 }
dudmuck 0:27aa8733f85d 255
dudmuck 0:27aa8733f85d 256 void SX127x::hw_reset()
dudmuck 0:27aa8733f85d 257 {
dudmuck 0:27aa8733f85d 258 /* only a french-swiss design would have hi-Z deassert */
dudmuck 0:27aa8733f85d 259 reset_pin.output();
dudmuck 0:27aa8733f85d 260 reset_pin.write(1);
dudmuck 0:27aa8733f85d 261 wait(0.05);
dudmuck 0:27aa8733f85d 262 reset_pin.input();
dudmuck 0:27aa8733f85d 263 wait(0.05);
dudmuck 0:27aa8733f85d 264 }
dudmuck 0:27aa8733f85d 265