123

Committer:
Wayne Roberts
Date:
Fri Jul 10 09:23:52 2020 -0700
Revision:
36:af9b41b1e285
Parent:
33:4b9fd8969428
Child:
37:d298b7089c56
run on mbed-6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 33:4b9fd8969428 1 #include "sx12xx.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 29:b72ac28d59e9 19 SX127x::SX127x(PinName dio_0, PinName dio_1, PinName cs, SPI& spi_r, PinName rst) :
dudmuck 29:b72ac28d59e9 20 dio0(dio_0), dio1(dio_1), m_cs(cs), m_spi(spi_r), reset_pin(rst)
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 25:fa867fb9d2f6 53 RegLna.bits.LnaBoostHF = 3;
dudmuck 25:fa867fb9d2f6 54 write_reg(REG_LNA, 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);
Wayne Roberts 36:af9b41b1e285 64 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 36:af9b41b1e285 65 ThisThread::sleep_for(10);
Wayne Roberts 36:af9b41b1e285 66 #else
Wayne Roberts 36:af9b41b1e285 67 ThisThread::sleep_for(10ms);
Wayne Roberts 36:af9b41b1e285 68 #endif
dudmuck 10:7382c260c4b1 69 RegOpMode.bits.LongRangeMode = 1;
dudmuck 10:7382c260c4b1 70 write_reg(REG_OPMODE, RegOpMode.octet);
Wayne Roberts 36:af9b41b1e285 71 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 36:af9b41b1e285 72 ThisThread::sleep_for(10);
Wayne Roberts 36:af9b41b1e285 73 #else
Wayne Roberts 36:af9b41b1e285 74 ThisThread::sleep_for(10ms);
Wayne Roberts 36:af9b41b1e285 75 #endif
dudmuck 10:7382c260c4b1 76 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 10:7382c260c4b1 77 }
dudmuck 10:7382c260c4b1 78
dudmuck 0:27aa8733f85d 79 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 80 type = SX1276;
dudmuck 0:27aa8733f85d 81 else {
dudmuck 0:27aa8733f85d 82 RegOpMode.sx1276LORAbits.LowFrequencyModeOn = 1;
dudmuck 0:27aa8733f85d 83 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 84 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:27aa8733f85d 85 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 86 type = SX1276;
dudmuck 0:27aa8733f85d 87 else
dudmuck 0:27aa8733f85d 88 type = SX1272;
dudmuck 0:27aa8733f85d 89 }
dudmuck 0:27aa8733f85d 90 }
dudmuck 1:7dc60eb4c7ec 91
dudmuck 1:7dc60eb4c7ec 92 void
dudmuck 1:7dc60eb4c7ec 93 SX127x::ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 94 {
dudmuck 1:7dc60eb4c7ec 95 uint8_t i;
dudmuck 1:7dc60eb4c7ec 96
dudmuck 1:7dc60eb4c7ec 97 m_cs = 0;
dudmuck 1:7dc60eb4c7ec 98
dudmuck 1:7dc60eb4c7ec 99 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 1:7dc60eb4c7ec 100
dudmuck 1:7dc60eb4c7ec 101 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 102 {
dudmuck 1:7dc60eb4c7ec 103 buffer[i] = m_spi.write(0x00);
dudmuck 1:7dc60eb4c7ec 104 }
dudmuck 1:7dc60eb4c7ec 105
dudmuck 1:7dc60eb4c7ec 106 m_cs = 1;
dudmuck 1:7dc60eb4c7ec 107 }
dudmuck 1:7dc60eb4c7ec 108
dudmuck 0:27aa8733f85d 109 uint8_t SX127x::read_reg(uint8_t addr)
dudmuck 0:27aa8733f85d 110 {
dudmuck 0:27aa8733f85d 111 uint8_t ret;
dudmuck 0:27aa8733f85d 112 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 113 m_cs = 0;
dudmuck 0:27aa8733f85d 114
dudmuck 0:27aa8733f85d 115 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 116
dudmuck 0:27aa8733f85d 117 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 118 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 119
dudmuck 0:27aa8733f85d 120 // Deselect the device
dudmuck 0:27aa8733f85d 121 m_cs = 1;
dudmuck 0:27aa8733f85d 122
dudmuck 0:27aa8733f85d 123 return ret;
dudmuck 0:27aa8733f85d 124 }
dudmuck 0:27aa8733f85d 125
dudmuck 2:fdae76e1215e 126 int16_t SX127x::read_s16(uint8_t addr)
dudmuck 2:fdae76e1215e 127 {
dudmuck 2:fdae76e1215e 128 int16_t ret;
dudmuck 2:fdae76e1215e 129 // Select the device by seting chip select low
dudmuck 2:fdae76e1215e 130 m_cs = 0;
dudmuck 2:fdae76e1215e 131
dudmuck 2:fdae76e1215e 132 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 2:fdae76e1215e 133
dudmuck 2:fdae76e1215e 134 // Send a dummy byte to receive the contents of register
dudmuck 2:fdae76e1215e 135 ret = m_spi.write(0x00);
dudmuck 2:fdae76e1215e 136 ret <<= 8;
dudmuck 2:fdae76e1215e 137 ret += m_spi.write(0x00);
dudmuck 2:fdae76e1215e 138
dudmuck 2:fdae76e1215e 139 // Deselect the device
dudmuck 2:fdae76e1215e 140 m_cs = 1;
dudmuck 2:fdae76e1215e 141
dudmuck 2:fdae76e1215e 142 return ret;
dudmuck 2:fdae76e1215e 143 }
dudmuck 2:fdae76e1215e 144
dudmuck 0:27aa8733f85d 145 uint16_t SX127x::read_u16(uint8_t addr)
dudmuck 0:27aa8733f85d 146 {
dudmuck 0:27aa8733f85d 147 uint16_t ret;
dudmuck 0:27aa8733f85d 148 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 149 m_cs = 0;
dudmuck 0:27aa8733f85d 150
dudmuck 0:27aa8733f85d 151 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 152
dudmuck 0:27aa8733f85d 153 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 154 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 155 ret <<= 8;
dudmuck 0:27aa8733f85d 156 ret += m_spi.write(0x00);
dudmuck 0:27aa8733f85d 157
dudmuck 0:27aa8733f85d 158 // Deselect the device
dudmuck 0:27aa8733f85d 159 m_cs = 1;
dudmuck 0:27aa8733f85d 160
dudmuck 0:27aa8733f85d 161 return ret;
dudmuck 0:27aa8733f85d 162 }
dudmuck 0:27aa8733f85d 163
dudmuck 4:d987ac2836bf 164 void SX127x::write_u16(uint8_t addr, uint16_t data)
dudmuck 4:d987ac2836bf 165 {
dudmuck 4:d987ac2836bf 166 m_cs = 0; // Select the device by seting chip select low
dudmuck 4:d987ac2836bf 167
dudmuck 4:d987ac2836bf 168 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 4:d987ac2836bf 169 m_spi.write((data >> 8) & 0xff);
dudmuck 4:d987ac2836bf 170 m_spi.write(data & 0xff);
dudmuck 4:d987ac2836bf 171
dudmuck 4:d987ac2836bf 172 m_cs = 1; // Deselect the device
dudmuck 4:d987ac2836bf 173 }
dudmuck 4:d987ac2836bf 174
dudmuck 4:d987ac2836bf 175 void SX127x::write_u24(uint8_t addr, uint32_t data)
dudmuck 0:27aa8733f85d 176 {
dudmuck 0:27aa8733f85d 177 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 178
dudmuck 0:27aa8733f85d 179 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 180 m_spi.write((data >> 16) & 0xff);
dudmuck 0:27aa8733f85d 181 m_spi.write((data >> 8) & 0xff);
dudmuck 0:27aa8733f85d 182 m_spi.write(data & 0xff);
dudmuck 0:27aa8733f85d 183
dudmuck 0:27aa8733f85d 184 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 185
dudmuck 0:27aa8733f85d 186 if (addr == REG_FRFMSB) {
dudmuck 0:27aa8733f85d 187 if (data < 0x8340000) // < 525MHz
dudmuck 0:27aa8733f85d 188 HF = false;
dudmuck 0:27aa8733f85d 189 else
dudmuck 0:27aa8733f85d 190 HF = true;
dudmuck 0:27aa8733f85d 191 }
dudmuck 0:27aa8733f85d 192 }
dudmuck 0:27aa8733f85d 193
dudmuck 0:27aa8733f85d 194 void SX127x::write_reg(uint8_t addr, uint8_t data)
dudmuck 0:27aa8733f85d 195 {
dudmuck 0:27aa8733f85d 196 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 197
dudmuck 0:27aa8733f85d 198 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 199 m_spi.write(data);
dudmuck 0:27aa8733f85d 200
dudmuck 0:27aa8733f85d 201 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 202 }
dudmuck 0:27aa8733f85d 203
dudmuck 1:7dc60eb4c7ec 204 void SX127x::WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 205 {
dudmuck 1:7dc60eb4c7ec 206 uint8_t i;
dudmuck 1:7dc60eb4c7ec 207
dudmuck 1:7dc60eb4c7ec 208 m_cs = 0; // Select the device by seting chip select low
dudmuck 1:7dc60eb4c7ec 209
dudmuck 1:7dc60eb4c7ec 210 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 1:7dc60eb4c7ec 211 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 212 {
dudmuck 1:7dc60eb4c7ec 213 m_spi.write(buffer[i]);
dudmuck 1:7dc60eb4c7ec 214 }
dudmuck 1:7dc60eb4c7ec 215
dudmuck 1:7dc60eb4c7ec 216 m_cs = 1; // Deselect the device
dudmuck 1:7dc60eb4c7ec 217 }
dudmuck 1:7dc60eb4c7ec 218
dudmuck 0:27aa8733f85d 219 void SX127x::set_opmode(chip_mode_e mode)
dudmuck 0:27aa8733f85d 220 {
dudmuck 0:27aa8733f85d 221 RegOpMode.bits.Mode = mode;
dudmuck 7:927a05f84ede 222
dudmuck 7:927a05f84ede 223 // callback to control antenna switch and PaSelect (PABOOST/RFO) for TX
dudmuck 30:da4ea47f552a 224 if (rf_switch)
dudmuck 30:da4ea47f552a 225 rf_switch.call();
dudmuck 7:927a05f84ede 226
dudmuck 0:27aa8733f85d 227 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 228 }
dudmuck 0:27aa8733f85d 229
dudmuck 0:27aa8733f85d 230 void SX127x::set_frf_MHz( float MHz )
dudmuck 0:27aa8733f85d 231 {
dudmuck 0:27aa8733f85d 232 uint32_t frf;
dudmuck 0:27aa8733f85d 233
dudmuck 27:da6341d9d5b1 234 frf = MHz / (float)FREQ_STEP_MHZ;
dudmuck 4:d987ac2836bf 235 write_u24(REG_FRFMSB, frf);
dudmuck 0:27aa8733f85d 236
dudmuck 0:27aa8733f85d 237 if (MHz < 525)
dudmuck 0:27aa8733f85d 238 HF = false;
dudmuck 0:27aa8733f85d 239 else
dudmuck 0:27aa8733f85d 240 HF = true;
dudmuck 0:27aa8733f85d 241 }
dudmuck 0:27aa8733f85d 242
dudmuck 0:27aa8733f85d 243 float SX127x::get_frf_MHz(void)
dudmuck 0:27aa8733f85d 244 {
dudmuck 0:27aa8733f85d 245 uint32_t frf;
dudmuck 0:27aa8733f85d 246 uint8_t lsb, mid, msb;
dudmuck 0:27aa8733f85d 247 float MHz;
dudmuck 0:27aa8733f85d 248
dudmuck 0:27aa8733f85d 249 msb = read_reg(REG_FRFMSB);
dudmuck 0:27aa8733f85d 250 mid = read_reg(REG_FRFMID);
dudmuck 0:27aa8733f85d 251 lsb = read_reg(REG_FRFLSB);
dudmuck 0:27aa8733f85d 252 frf = msb;
dudmuck 0:27aa8733f85d 253 frf <<= 8;
dudmuck 0:27aa8733f85d 254 frf += mid;
dudmuck 0:27aa8733f85d 255 frf <<= 8;
dudmuck 0:27aa8733f85d 256 frf += lsb;
dudmuck 0:27aa8733f85d 257
dudmuck 0:27aa8733f85d 258 MHz = frf * FREQ_STEP_MHZ;
dudmuck 0:27aa8733f85d 259
dudmuck 0:27aa8733f85d 260 if (MHz < 525)
dudmuck 0:27aa8733f85d 261 HF = false;
dudmuck 0:27aa8733f85d 262 else
dudmuck 0:27aa8733f85d 263 HF = true;
dudmuck 0:27aa8733f85d 264
dudmuck 0:27aa8733f85d 265 return MHz;
dudmuck 0:27aa8733f85d 266 }
dudmuck 0:27aa8733f85d 267
dudmuck 0:27aa8733f85d 268 void SX127x::hw_reset()
dudmuck 0:27aa8733f85d 269 {
dudmuck 27:da6341d9d5b1 270 int in = reset_pin.read();
dudmuck 0:27aa8733f85d 271 reset_pin.output();
dudmuck 0:27aa8733f85d 272 reset_pin.write(1);
Wayne Roberts 36:af9b41b1e285 273 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 36:af9b41b1e285 274 ThisThread::sleep_for(50);
dudmuck 27:da6341d9d5b1 275 if (in == 1) { /* pin is pulled up somewhere? */
dudmuck 27:da6341d9d5b1 276 reset_pin.write(0);
Wayne Roberts 36:af9b41b1e285 277 ThisThread::sleep_for(5);
dudmuck 27:da6341d9d5b1 278 }
dudmuck 0:27aa8733f85d 279 reset_pin.input();
Wayne Roberts 36:af9b41b1e285 280 ThisThread::sleep_for(5);
Wayne Roberts 36:af9b41b1e285 281 #else
Wayne Roberts 36:af9b41b1e285 282 ThisThread::sleep_for(50ms);
Wayne Roberts 36:af9b41b1e285 283 if (in == 1) { /* pin is pulled up somewhere? */
Wayne Roberts 36:af9b41b1e285 284 reset_pin.write(0);
Wayne Roberts 36:af9b41b1e285 285 ThisThread::sleep_for(5ms);
Wayne Roberts 36:af9b41b1e285 286 }
Wayne Roberts 36:af9b41b1e285 287 reset_pin.input();
Wayne Roberts 36:af9b41b1e285 288 ThisThread::sleep_for(5ms);
Wayne Roberts 36:af9b41b1e285 289 #endif
dudmuck 0:27aa8733f85d 290 }
dudmuck 0:27aa8733f85d 291