123

Committer:
dudmuck
Date:
Thu Oct 22 01:25:27 2015 +0000
Revision:
24:cad6e7ce6928
Parent:
10:7382c260c4b1
Child:
25:fa867fb9d2f6
LnaBoostHF defaults to hi-gain, FSK optimzation for preamble detector

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