123

Committer:
dudmuck
Date:
Wed Apr 30 22:49:43 2014 +0000
Revision:
2:fdae76e1215e
Parent:
1:7dc60eb4c7ec
Child:
4:d987ac2836bf
separated LoRa code from FSK code from common code

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