123

Committer:
dudmuck
Date:
Mon Apr 14 21:57:41 2014 +0000
Revision:
1:7dc60eb4c7ec
Parent:
0:27aa8733f85d
Child:
2:fdae76e1215e
added read/write functions for USB HID application

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 0:27aa8733f85d 52 RegModemConfig.octet = read_reg(REG_LR_MODEMCONFIG);
dudmuck 0:27aa8733f85d 53 RegModemConfig2.octet = read_reg(REG_LR_MODEMCONFIG2);
dudmuck 0:27aa8733f85d 54 RegTest31.octet = read_reg(REG_LR_TEST31);
dudmuck 0:27aa8733f85d 55
dudmuck 0:27aa8733f85d 56 get_type();
dudmuck 0:27aa8733f85d 57
dudmuck 0:27aa8733f85d 58 // turn on PA BOOST, eval boards are wired for this connection
dudmuck 0:27aa8733f85d 59 RegPaConfig.bits.PaSelect = 1;
dudmuck 0:27aa8733f85d 60 write_reg(REG_PACONFIG, RegPaConfig.octet);
dudmuck 0:27aa8733f85d 61
dudmuck 0:27aa8733f85d 62 // CRC for TX is disabled by default
dudmuck 0:27aa8733f85d 63 setRxPayloadCrcOn(true);
dudmuck 0:27aa8733f85d 64 }
dudmuck 0:27aa8733f85d 65
dudmuck 0:27aa8733f85d 66 void SX127x::get_type()
dudmuck 0:27aa8733f85d 67 {
dudmuck 0:27aa8733f85d 68 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:27aa8733f85d 69 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 70 type = SX1276;
dudmuck 0:27aa8733f85d 71 else {
dudmuck 0:27aa8733f85d 72 RegOpMode.sx1276LORAbits.LowFrequencyModeOn = 1;
dudmuck 0:27aa8733f85d 73 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 74 RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 0:27aa8733f85d 75 if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
dudmuck 0:27aa8733f85d 76 type = SX1276;
dudmuck 0:27aa8733f85d 77 else
dudmuck 0:27aa8733f85d 78 type = SX1272;
dudmuck 0:27aa8733f85d 79 }
dudmuck 0:27aa8733f85d 80 }
dudmuck 1:7dc60eb4c7ec 81
dudmuck 1:7dc60eb4c7ec 82 void
dudmuck 1:7dc60eb4c7ec 83 SX127x::ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 84 {
dudmuck 1:7dc60eb4c7ec 85 uint8_t i;
dudmuck 1:7dc60eb4c7ec 86
dudmuck 1:7dc60eb4c7ec 87 m_cs = 0;
dudmuck 1:7dc60eb4c7ec 88
dudmuck 1:7dc60eb4c7ec 89 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 1:7dc60eb4c7ec 90
dudmuck 1:7dc60eb4c7ec 91 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 92 {
dudmuck 1:7dc60eb4c7ec 93 buffer[i] = m_spi.write(0x00);
dudmuck 1:7dc60eb4c7ec 94 }
dudmuck 1:7dc60eb4c7ec 95
dudmuck 1:7dc60eb4c7ec 96 m_cs = 1;
dudmuck 1:7dc60eb4c7ec 97 }
dudmuck 1:7dc60eb4c7ec 98
dudmuck 0:27aa8733f85d 99 uint8_t SX127x::read_reg(uint8_t addr)
dudmuck 0:27aa8733f85d 100 {
dudmuck 0:27aa8733f85d 101 uint8_t ret;
dudmuck 0:27aa8733f85d 102 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 103 m_cs = 0;
dudmuck 0:27aa8733f85d 104
dudmuck 0:27aa8733f85d 105 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 106
dudmuck 0:27aa8733f85d 107 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 108 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 109
dudmuck 0:27aa8733f85d 110 // Deselect the device
dudmuck 0:27aa8733f85d 111 m_cs = 1;
dudmuck 0:27aa8733f85d 112
dudmuck 0:27aa8733f85d 113 return ret;
dudmuck 0:27aa8733f85d 114 }
dudmuck 0:27aa8733f85d 115
dudmuck 0:27aa8733f85d 116 uint16_t SX127x::read_u16(uint8_t addr)
dudmuck 0:27aa8733f85d 117 {
dudmuck 0:27aa8733f85d 118 uint16_t ret;
dudmuck 0:27aa8733f85d 119 // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 120 m_cs = 0;
dudmuck 0:27aa8733f85d 121
dudmuck 0:27aa8733f85d 122 m_spi.write(addr); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 123
dudmuck 0:27aa8733f85d 124 // Send a dummy byte to receive the contents of register
dudmuck 0:27aa8733f85d 125 ret = m_spi.write(0x00);
dudmuck 0:27aa8733f85d 126 ret <<= 8;
dudmuck 0:27aa8733f85d 127 ret += m_spi.write(0x00);
dudmuck 0:27aa8733f85d 128
dudmuck 0:27aa8733f85d 129 // Deselect the device
dudmuck 0:27aa8733f85d 130 m_cs = 1;
dudmuck 0:27aa8733f85d 131
dudmuck 0:27aa8733f85d 132 return ret;
dudmuck 0:27aa8733f85d 133 }
dudmuck 0:27aa8733f85d 134
dudmuck 0:27aa8733f85d 135 void SX127x::write_reg_u24(uint8_t addr, uint32_t data)
dudmuck 0:27aa8733f85d 136 {
dudmuck 0:27aa8733f85d 137 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 138
dudmuck 0:27aa8733f85d 139 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 140 m_spi.write((data >> 16) & 0xff);
dudmuck 0:27aa8733f85d 141 m_spi.write((data >> 8) & 0xff);
dudmuck 0:27aa8733f85d 142 m_spi.write(data & 0xff);
dudmuck 0:27aa8733f85d 143
dudmuck 0:27aa8733f85d 144 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 145
dudmuck 0:27aa8733f85d 146 if (addr == REG_FRFMSB) {
dudmuck 0:27aa8733f85d 147 if (data < 0x8340000) // < 525MHz
dudmuck 0:27aa8733f85d 148 HF = false;
dudmuck 0:27aa8733f85d 149 else
dudmuck 0:27aa8733f85d 150 HF = true;
dudmuck 0:27aa8733f85d 151 }
dudmuck 0:27aa8733f85d 152 }
dudmuck 0:27aa8733f85d 153
dudmuck 0:27aa8733f85d 154 void SX127x::write_reg(uint8_t addr, uint8_t data)
dudmuck 0:27aa8733f85d 155 {
dudmuck 0:27aa8733f85d 156 m_cs = 0; // Select the device by seting chip select low
dudmuck 0:27aa8733f85d 157
dudmuck 0:27aa8733f85d 158 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 159 m_spi.write(data);
dudmuck 0:27aa8733f85d 160
dudmuck 0:27aa8733f85d 161 m_cs = 1; // Deselect the device
dudmuck 0:27aa8733f85d 162 }
dudmuck 0:27aa8733f85d 163
dudmuck 1:7dc60eb4c7ec 164 void SX127x::WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
dudmuck 1:7dc60eb4c7ec 165 {
dudmuck 1:7dc60eb4c7ec 166 uint8_t i;
dudmuck 1:7dc60eb4c7ec 167
dudmuck 1:7dc60eb4c7ec 168 m_cs = 0; // Select the device by seting chip select low
dudmuck 1:7dc60eb4c7ec 169
dudmuck 1:7dc60eb4c7ec 170 m_spi.write(addr | 0x80); // bit7 is high for writing to radio
dudmuck 1:7dc60eb4c7ec 171 for( i = 0; i < size; i++ )
dudmuck 1:7dc60eb4c7ec 172 {
dudmuck 1:7dc60eb4c7ec 173 m_spi.write(buffer[i]);
dudmuck 1:7dc60eb4c7ec 174 }
dudmuck 1:7dc60eb4c7ec 175
dudmuck 1:7dc60eb4c7ec 176 m_cs = 1; // Deselect the device
dudmuck 1:7dc60eb4c7ec 177 }
dudmuck 1:7dc60eb4c7ec 178
dudmuck 0:27aa8733f85d 179 void SX127x::lora_write_fifo(uint8_t len)
dudmuck 0:27aa8733f85d 180 {
dudmuck 0:27aa8733f85d 181 int i;
dudmuck 0:27aa8733f85d 182
dudmuck 0:27aa8733f85d 183 m_cs = 0;
dudmuck 0:27aa8733f85d 184 m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 0:27aa8733f85d 185 for (i = 0; i < len; i++) {
dudmuck 0:27aa8733f85d 186 m_spi.write(tx_buf[i]);
dudmuck 0:27aa8733f85d 187 }
dudmuck 0:27aa8733f85d 188 m_cs = 1;
dudmuck 0:27aa8733f85d 189 }
dudmuck 0:27aa8733f85d 190
dudmuck 0:27aa8733f85d 191 void SX127x::lora_read_fifo(uint8_t len)
dudmuck 0:27aa8733f85d 192 {
dudmuck 0:27aa8733f85d 193 int i;
dudmuck 0:27aa8733f85d 194
dudmuck 0:27aa8733f85d 195 m_cs = 0;
dudmuck 0:27aa8733f85d 196 m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 0:27aa8733f85d 197 for (i = 0; i < len; i++) {
dudmuck 0:27aa8733f85d 198 rx_buf[i] = m_spi.write(0);
dudmuck 0:27aa8733f85d 199 }
dudmuck 0:27aa8733f85d 200 m_cs = 1;
dudmuck 0:27aa8733f85d 201 }
dudmuck 0:27aa8733f85d 202
dudmuck 1:7dc60eb4c7ec 203 void
dudmuck 1:7dc60eb4c7ec 204 SX127x::SetLoRaOn( bool enable )
dudmuck 1:7dc60eb4c7ec 205 {
dudmuck 1:7dc60eb4c7ec 206 set_opmode(RF_OPMODE_SLEEP);
dudmuck 1:7dc60eb4c7ec 207
dudmuck 1:7dc60eb4c7ec 208 if (enable)
dudmuck 1:7dc60eb4c7ec 209 {
dudmuck 1:7dc60eb4c7ec 210 RegOpMode.bits.LongRangeMode = 1;
dudmuck 1:7dc60eb4c7ec 211 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 1:7dc60eb4c7ec 212
dudmuck 1:7dc60eb4c7ec 213 /*RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 1:7dc60eb4c7ec 214 printf("setloraon:%02x\r\n", RegOpMode.octet);*/
dudmuck 1:7dc60eb4c7ec 215
dudmuck 1:7dc60eb4c7ec 216
dudmuck 1:7dc60eb4c7ec 217 /* // RxDone RxTimeout FhssChangeChannel CadDone
dudmuck 1:7dc60eb4c7ec 218 SX1272LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;
dudmuck 1:7dc60eb4c7ec 219 // CadDetected ModeReady
dudmuck 1:7dc60eb4c7ec 220 SX1272LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;
dudmuck 1:7dc60eb4c7ec 221 SX1272WriteBuffer( REG_LR_DIOMAPPING1, &SX1272LR->RegDioMapping1, 2 );*/
dudmuck 1:7dc60eb4c7ec 222 RegDioMapping1.bits.Dio0Mapping = 0; // DIO0 to RxDone
dudmuck 1:7dc60eb4c7ec 223 RegDioMapping1.bits.Dio1Mapping = 0;
dudmuck 1:7dc60eb4c7ec 224 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 1:7dc60eb4c7ec 225
dudmuck 1:7dc60eb4c7ec 226 // todo: read LoRa regsiters
dudmuck 1:7dc60eb4c7ec 227 //SX1272ReadBuffer( REG_LR_OPMODE, SX1272Regs + 1, 0x70 - 1 );
dudmuck 1:7dc60eb4c7ec 228 }
dudmuck 1:7dc60eb4c7ec 229 else
dudmuck 1:7dc60eb4c7ec 230 {
dudmuck 1:7dc60eb4c7ec 231 RegOpMode.bits.LongRangeMode = 0;
dudmuck 1:7dc60eb4c7ec 232 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 1:7dc60eb4c7ec 233
dudmuck 1:7dc60eb4c7ec 234 /*RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 1:7dc60eb4c7ec 235 printf("setloraoff:%02x\r\n", RegOpMode.octet);*/
dudmuck 1:7dc60eb4c7ec 236
dudmuck 1:7dc60eb4c7ec 237 // todo: read FSK regsiters
dudmuck 1:7dc60eb4c7ec 238 //SX1272ReadBuffer( REG_OPMODE, SX1272Regs + 1, 0x70 - 1 );
dudmuck 1:7dc60eb4c7ec 239 }
dudmuck 1:7dc60eb4c7ec 240
dudmuck 1:7dc60eb4c7ec 241 set_opmode(RF_OPMODE_STANDBY);
dudmuck 1:7dc60eb4c7ec 242 }
dudmuck 1:7dc60eb4c7ec 243
dudmuck 1:7dc60eb4c7ec 244
dudmuck 0:27aa8733f85d 245 void SX127x::set_opmode(chip_mode_e mode)
dudmuck 0:27aa8733f85d 246 {
dudmuck 0:27aa8733f85d 247 RegOpMode.bits.Mode = mode;
dudmuck 0:27aa8733f85d 248 write_reg(REG_OPMODE, RegOpMode.octet);
dudmuck 0:27aa8733f85d 249 }
dudmuck 0:27aa8733f85d 250
dudmuck 0:27aa8733f85d 251 void SX127x::set_frf_MHz( float MHz )
dudmuck 0:27aa8733f85d 252 {
dudmuck 0:27aa8733f85d 253 uint32_t frf;
dudmuck 0:27aa8733f85d 254
dudmuck 0:27aa8733f85d 255 frf = MHz / FREQ_STEP_MHZ;
dudmuck 0:27aa8733f85d 256 write_reg_u24(REG_FRFMSB, frf);
dudmuck 0:27aa8733f85d 257
dudmuck 0:27aa8733f85d 258 if (MHz < 525)
dudmuck 0:27aa8733f85d 259 HF = false;
dudmuck 0:27aa8733f85d 260 else
dudmuck 0:27aa8733f85d 261 HF = true;
dudmuck 0:27aa8733f85d 262 }
dudmuck 0:27aa8733f85d 263
dudmuck 0:27aa8733f85d 264 float SX127x::get_frf_MHz(void)
dudmuck 0:27aa8733f85d 265 {
dudmuck 0:27aa8733f85d 266 uint32_t frf;
dudmuck 0:27aa8733f85d 267 uint8_t lsb, mid, msb;
dudmuck 0:27aa8733f85d 268 float MHz;
dudmuck 0:27aa8733f85d 269
dudmuck 0:27aa8733f85d 270 msb = read_reg(REG_FRFMSB);
dudmuck 0:27aa8733f85d 271 mid = read_reg(REG_FRFMID);
dudmuck 0:27aa8733f85d 272 lsb = read_reg(REG_FRFLSB);
dudmuck 0:27aa8733f85d 273 frf = msb;
dudmuck 0:27aa8733f85d 274 frf <<= 8;
dudmuck 0:27aa8733f85d 275 frf += mid;
dudmuck 0:27aa8733f85d 276 frf <<= 8;
dudmuck 0:27aa8733f85d 277 frf += lsb;
dudmuck 0:27aa8733f85d 278
dudmuck 0:27aa8733f85d 279 MHz = frf * FREQ_STEP_MHZ;
dudmuck 0:27aa8733f85d 280
dudmuck 0:27aa8733f85d 281 if (MHz < 525)
dudmuck 0:27aa8733f85d 282 HF = false;
dudmuck 0:27aa8733f85d 283 else
dudmuck 0:27aa8733f85d 284 HF = true;
dudmuck 0:27aa8733f85d 285
dudmuck 0:27aa8733f85d 286 return MHz;
dudmuck 0:27aa8733f85d 287 }
dudmuck 0:27aa8733f85d 288
dudmuck 0:27aa8733f85d 289 uint8_t SX127x::getCodingRate(bool from_rx)
dudmuck 0:27aa8733f85d 290 {
dudmuck 0:27aa8733f85d 291 if (from_rx) {
dudmuck 0:27aa8733f85d 292 // expected RegModemStatus was read on RxDone interrupt
dudmuck 0:27aa8733f85d 293 return RegModemStatus.bits.RxCodingRate;
dudmuck 0:27aa8733f85d 294 } else { // transmitted coding rate...
dudmuck 0:27aa8733f85d 295 if (type == SX1276)
dudmuck 0:27aa8733f85d 296 return RegModemConfig.sx1276bits.CodingRate;
dudmuck 0:27aa8733f85d 297 else if (type == SX1272)
dudmuck 0:27aa8733f85d 298 return RegModemConfig.sx1272bits.CodingRate;
dudmuck 0:27aa8733f85d 299 else
dudmuck 0:27aa8733f85d 300 return 0;
dudmuck 0:27aa8733f85d 301 }
dudmuck 0:27aa8733f85d 302 }
dudmuck 0:27aa8733f85d 303
dudmuck 0:27aa8733f85d 304 void SX127x::setCodingRate(uint8_t cr)
dudmuck 0:27aa8733f85d 305 {
dudmuck 0:27aa8733f85d 306 if (type == SX1276)
dudmuck 0:27aa8733f85d 307 RegModemConfig.sx1276bits.CodingRate = cr;
dudmuck 0:27aa8733f85d 308 else if (type == SX1272)
dudmuck 0:27aa8733f85d 309 RegModemConfig.sx1272bits.CodingRate = cr;
dudmuck 0:27aa8733f85d 310 else
dudmuck 0:27aa8733f85d 311 return;
dudmuck 0:27aa8733f85d 312
dudmuck 0:27aa8733f85d 313 write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 0:27aa8733f85d 314 }
dudmuck 0:27aa8733f85d 315
dudmuck 0:27aa8733f85d 316 bool SX127x::getHeaderMode(void)
dudmuck 0:27aa8733f85d 317 {
dudmuck 0:27aa8733f85d 318 if (type == SX1276)
dudmuck 0:27aa8733f85d 319 return RegModemConfig.sx1276bits.ImplicitHeaderModeOn;
dudmuck 0:27aa8733f85d 320 else if (type == SX1272)
dudmuck 0:27aa8733f85d 321 return RegModemConfig.sx1272bits.ImplicitHeaderModeOn;
dudmuck 0:27aa8733f85d 322 else
dudmuck 0:27aa8733f85d 323 return false;
dudmuck 0:27aa8733f85d 324 }
dudmuck 0:27aa8733f85d 325
dudmuck 0:27aa8733f85d 326 void SX127x::setHeaderMode(bool hm)
dudmuck 0:27aa8733f85d 327 {
dudmuck 0:27aa8733f85d 328 if (type == SX1276)
dudmuck 0:27aa8733f85d 329 RegModemConfig.sx1276bits.ImplicitHeaderModeOn = hm;
dudmuck 0:27aa8733f85d 330 else if (type == SX1272)
dudmuck 0:27aa8733f85d 331 RegModemConfig.sx1272bits.ImplicitHeaderModeOn = hm;
dudmuck 0:27aa8733f85d 332 else
dudmuck 0:27aa8733f85d 333 return;
dudmuck 0:27aa8733f85d 334
dudmuck 0:27aa8733f85d 335 write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 0:27aa8733f85d 336 }
dudmuck 0:27aa8733f85d 337
dudmuck 0:27aa8733f85d 338 uint8_t SX127x::getBw(void)
dudmuck 0:27aa8733f85d 339 {
dudmuck 0:27aa8733f85d 340 if (type == SX1276)
dudmuck 0:27aa8733f85d 341 return RegModemConfig.sx1276bits.Bw;
dudmuck 0:27aa8733f85d 342 else if (type == SX1272)
dudmuck 0:27aa8733f85d 343 return RegModemConfig.sx1272bits.Bw;
dudmuck 0:27aa8733f85d 344 else
dudmuck 0:27aa8733f85d 345 return 0;
dudmuck 0:27aa8733f85d 346 }
dudmuck 0:27aa8733f85d 347
dudmuck 0:27aa8733f85d 348 void SX127x::setBw(uint8_t bw)
dudmuck 0:27aa8733f85d 349 {
dudmuck 0:27aa8733f85d 350 if (type == SX1276)
dudmuck 0:27aa8733f85d 351 RegModemConfig.sx1276bits.Bw = bw;
dudmuck 0:27aa8733f85d 352 else if (type == SX1272) {
dudmuck 0:27aa8733f85d 353 RegModemConfig.sx1272bits.Bw = bw;
dudmuck 0:27aa8733f85d 354 if (RegModemConfig2.sx1272bits.SpreadingFactor > 10)
dudmuck 0:27aa8733f85d 355 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 0:27aa8733f85d 356 else
dudmuck 0:27aa8733f85d 357 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 0:27aa8733f85d 358 } else
dudmuck 0:27aa8733f85d 359 return;
dudmuck 0:27aa8733f85d 360
dudmuck 0:27aa8733f85d 361 write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 0:27aa8733f85d 362 }
dudmuck 0:27aa8733f85d 363
dudmuck 0:27aa8733f85d 364 uint8_t SX127x::getSf(void)
dudmuck 0:27aa8733f85d 365 {
dudmuck 0:27aa8733f85d 366 // spreading factor same between sx127[26]
dudmuck 0:27aa8733f85d 367 return RegModemConfig2.sx1276bits.SpreadingFactor;
dudmuck 0:27aa8733f85d 368 }
dudmuck 0:27aa8733f85d 369
dudmuck 0:27aa8733f85d 370 void SX127x::set_nb_trig_peaks(int n)
dudmuck 0:27aa8733f85d 371 {
dudmuck 0:27aa8733f85d 372 RegTest31.bits.detect_trig_same_peaks_nb = n;
dudmuck 0:27aa8733f85d 373 write_reg(REG_LR_TEST31, RegTest31.octet);
dudmuck 0:27aa8733f85d 374 }
dudmuck 0:27aa8733f85d 375
dudmuck 0:27aa8733f85d 376 void SX127x::setSf(uint8_t sf)
dudmuck 0:27aa8733f85d 377 {
dudmuck 0:27aa8733f85d 378 // false detections vs missed detections tradeoff
dudmuck 0:27aa8733f85d 379 switch (sf) {
dudmuck 0:27aa8733f85d 380 case 6:
dudmuck 0:27aa8733f85d 381 set_nb_trig_peaks(3);
dudmuck 0:27aa8733f85d 382 break;
dudmuck 0:27aa8733f85d 383 case 7:
dudmuck 0:27aa8733f85d 384 set_nb_trig_peaks(4);
dudmuck 0:27aa8733f85d 385 break;
dudmuck 0:27aa8733f85d 386 default:
dudmuck 0:27aa8733f85d 387 set_nb_trig_peaks(5);
dudmuck 0:27aa8733f85d 388 break;
dudmuck 0:27aa8733f85d 389 }
dudmuck 0:27aa8733f85d 390
dudmuck 0:27aa8733f85d 391 // write register at 0x37 with value 0xc if at SF6
dudmuck 0:27aa8733f85d 392 if (sf < 7)
dudmuck 0:27aa8733f85d 393 write_reg(REG_LR_DETECTION_THRESHOLD, 0x0c);
dudmuck 0:27aa8733f85d 394 else
dudmuck 0:27aa8733f85d 395 write_reg(REG_LR_DETECTION_THRESHOLD, 0x0a);
dudmuck 0:27aa8733f85d 396
dudmuck 0:27aa8733f85d 397 RegModemConfig2.sx1276bits.SpreadingFactor = sf; // spreading factor same between sx127[26]
dudmuck 0:27aa8733f85d 398 write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 0:27aa8733f85d 399
dudmuck 0:27aa8733f85d 400 if (type == SX1272) {
dudmuck 0:27aa8733f85d 401 if (sf > 10 && RegModemConfig.sx1272bits.Bw == 0) // if bw=125KHz and sf11 or sf12
dudmuck 0:27aa8733f85d 402 RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
dudmuck 0:27aa8733f85d 403 else
dudmuck 0:27aa8733f85d 404 RegModemConfig.sx1272bits.LowDataRateOptimize = 0;
dudmuck 0:27aa8733f85d 405 write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 0:27aa8733f85d 406 } else if (type == SX1276) {
dudmuck 0:27aa8733f85d 407 if (sf > 10 && RegModemConfig.sx1272bits.Bw == 0) // if bw=125KHz and sf11 or sf12
dudmuck 0:27aa8733f85d 408 RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
dudmuck 0:27aa8733f85d 409 else
dudmuck 0:27aa8733f85d 410 RegModemConfig3.sx1276bits.LowDataRateOptimize = 0;
dudmuck 0:27aa8733f85d 411 write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 0:27aa8733f85d 412 }
dudmuck 0:27aa8733f85d 413 }
dudmuck 0:27aa8733f85d 414
dudmuck 0:27aa8733f85d 415 bool SX127x::getRxPayloadCrcOn(void)
dudmuck 0:27aa8733f85d 416 {
dudmuck 0:27aa8733f85d 417 if (type == SX1276)
dudmuck 0:27aa8733f85d 418 return RegModemConfig2.sx1276bits.RxPayloadCrcOn;
dudmuck 0:27aa8733f85d 419 else if (type == SX1272)
dudmuck 0:27aa8733f85d 420 return RegModemConfig.sx1272bits.RxPayloadCrcOn;
dudmuck 0:27aa8733f85d 421 else
dudmuck 0:27aa8733f85d 422 return 0;
dudmuck 0:27aa8733f85d 423 }
dudmuck 0:27aa8733f85d 424
dudmuck 0:27aa8733f85d 425 void SX127x::setRxPayloadCrcOn(bool on)
dudmuck 0:27aa8733f85d 426 {
dudmuck 0:27aa8733f85d 427 if (type == SX1276) {
dudmuck 0:27aa8733f85d 428 RegModemConfig2.sx1276bits.RxPayloadCrcOn = on;
dudmuck 0:27aa8733f85d 429 write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 0:27aa8733f85d 430 } else if (type == SX1272) {
dudmuck 0:27aa8733f85d 431 RegModemConfig.sx1272bits.RxPayloadCrcOn = on;
dudmuck 0:27aa8733f85d 432 write_reg(REG_LR_MODEMCONFIG, RegModemConfig.octet);
dudmuck 0:27aa8733f85d 433 }
dudmuck 0:27aa8733f85d 434 }
dudmuck 0:27aa8733f85d 435
dudmuck 0:27aa8733f85d 436 bool SX127x::getAgcAutoOn(void)
dudmuck 0:27aa8733f85d 437 {
dudmuck 0:27aa8733f85d 438 if (type == SX1276) {
dudmuck 0:27aa8733f85d 439 RegModemConfig3.octet = read_reg(REG_LR_MODEMCONFIG3);
dudmuck 0:27aa8733f85d 440 return RegModemConfig3.sx1276bits.AgcAutoOn;
dudmuck 0:27aa8733f85d 441 } else if (type == SX1272) {
dudmuck 0:27aa8733f85d 442 RegModemConfig2.octet = read_reg(REG_LR_MODEMCONFIG2);
dudmuck 0:27aa8733f85d 443 return RegModemConfig2.sx1272bits.AgcAutoOn;
dudmuck 0:27aa8733f85d 444 } else
dudmuck 0:27aa8733f85d 445 return 0;
dudmuck 0:27aa8733f85d 446 }
dudmuck 0:27aa8733f85d 447
dudmuck 0:27aa8733f85d 448 void SX127x::setAgcAutoOn(bool on)
dudmuck 0:27aa8733f85d 449 {
dudmuck 0:27aa8733f85d 450 if (type == SX1276) {
dudmuck 0:27aa8733f85d 451 RegModemConfig3.sx1276bits.AgcAutoOn = on;
dudmuck 0:27aa8733f85d 452 write_reg(REG_LR_MODEMCONFIG3, RegModemConfig3.octet);
dudmuck 0:27aa8733f85d 453 } else if (type == SX1272) {
dudmuck 0:27aa8733f85d 454 RegModemConfig2.sx1272bits.AgcAutoOn = on;
dudmuck 0:27aa8733f85d 455 write_reg(REG_LR_MODEMCONFIG2, RegModemConfig2.octet);
dudmuck 0:27aa8733f85d 456 }
dudmuck 0:27aa8733f85d 457
dudmuck 0:27aa8733f85d 458 }
dudmuck 0:27aa8733f85d 459
dudmuck 0:27aa8733f85d 460 void SX127x::lora_start_tx(uint8_t len)
dudmuck 0:27aa8733f85d 461 {
dudmuck 0:27aa8733f85d 462 if (type == SX1276) {
dudmuck 0:27aa8733f85d 463 // PA_BOOST on LF, RFO on HF
dudmuck 0:27aa8733f85d 464 if (HF) {
dudmuck 0:27aa8733f85d 465 if (RegPaConfig.bits.PaSelect) {
dudmuck 0:27aa8733f85d 466 RegPaConfig.bits.PaSelect = 0;
dudmuck 0:27aa8733f85d 467 write_reg(REG_PACONFIG, RegPaConfig.octet);
dudmuck 0:27aa8733f85d 468 }
dudmuck 0:27aa8733f85d 469 } else { // LF...
dudmuck 0:27aa8733f85d 470 if (!RegPaConfig.bits.PaSelect) {
dudmuck 0:27aa8733f85d 471 RegPaConfig.bits.PaSelect = 1;
dudmuck 0:27aa8733f85d 472 write_reg(REG_PACONFIG, RegPaConfig.octet);
dudmuck 0:27aa8733f85d 473 }
dudmuck 0:27aa8733f85d 474 }
dudmuck 0:27aa8733f85d 475 } else if (type == SX1272) {
dudmuck 0:27aa8733f85d 476 // always PA_BOOST
dudmuck 0:27aa8733f85d 477 if (!RegPaConfig.bits.PaSelect) {
dudmuck 0:27aa8733f85d 478 RegPaConfig.bits.PaSelect = 1;
dudmuck 0:27aa8733f85d 479 write_reg(REG_PACONFIG, RegPaConfig.octet);
dudmuck 0:27aa8733f85d 480 }
dudmuck 0:27aa8733f85d 481 }
dudmuck 0:27aa8733f85d 482
dudmuck 0:27aa8733f85d 483
dudmuck 0:27aa8733f85d 484 // DIO0 to TxDone
dudmuck 0:27aa8733f85d 485 if (RegDioMapping1.bits.Dio0Mapping != 1) {
dudmuck 0:27aa8733f85d 486 RegDioMapping1.bits.Dio0Mapping = 1;
dudmuck 0:27aa8733f85d 487 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:27aa8733f85d 488 }
dudmuck 0:27aa8733f85d 489
dudmuck 0:27aa8733f85d 490 // set FifoPtrAddr to FifoTxPtrBase
dudmuck 0:27aa8733f85d 491 write_reg(REG_LR_FIFOADDRPTR, read_reg(REG_LR_FIFOTXBASEADDR));
dudmuck 0:27aa8733f85d 492
dudmuck 0:27aa8733f85d 493 // write PayloadLength bytes to fifo
dudmuck 0:27aa8733f85d 494 lora_write_fifo(len);
dudmuck 0:27aa8733f85d 495
dudmuck 0:27aa8733f85d 496 if (HF)
dudmuck 0:27aa8733f85d 497 femctx = 1;
dudmuck 0:27aa8733f85d 498 else
dudmuck 0:27aa8733f85d 499 femcps = 0;
dudmuck 0:27aa8733f85d 500
dudmuck 0:27aa8733f85d 501 // radio doesnt provide FhssChangeChannel with channel=0 for TX
dudmuck 0:27aa8733f85d 502 if (RegHopPeriod > 0)
dudmuck 0:27aa8733f85d 503 write_reg_u24(REG_FRFMSB, frfs[0]);
dudmuck 0:27aa8733f85d 504
dudmuck 0:27aa8733f85d 505 set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 0:27aa8733f85d 506 }
dudmuck 0:27aa8733f85d 507
dudmuck 0:27aa8733f85d 508
dudmuck 0:27aa8733f85d 509
dudmuck 0:27aa8733f85d 510 void SX127x::lora_start_rx()
dudmuck 0:27aa8733f85d 511 {
dudmuck 0:27aa8733f85d 512 if (HF)
dudmuck 0:27aa8733f85d 513 femctx = 0;
dudmuck 0:27aa8733f85d 514 else
dudmuck 0:27aa8733f85d 515 femcps = 1;
dudmuck 0:27aa8733f85d 516
dudmuck 0:27aa8733f85d 517 if (RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 0:27aa8733f85d 518 RegDioMapping1.bits.Dio0Mapping = 0; // DIO0 to RxDone
dudmuck 0:27aa8733f85d 519 write_reg(REG_DIOMAPPING1, RegDioMapping1.octet);
dudmuck 0:27aa8733f85d 520 }
dudmuck 0:27aa8733f85d 521
dudmuck 0:27aa8733f85d 522 write_reg(REG_LR_FIFOADDRPTR, read_reg(REG_LR_FIFORXBASEADDR));
dudmuck 0:27aa8733f85d 523
dudmuck 0:27aa8733f85d 524 // shouldn't be necessary, radio should provide FhssChangeChannel with channel=0 for RX
dudmuck 0:27aa8733f85d 525 if (RegHopPeriod > 0)
dudmuck 0:27aa8733f85d 526 write_reg_u24(REG_FRFMSB, frfs[0]);
dudmuck 0:27aa8733f85d 527
dudmuck 0:27aa8733f85d 528 set_opmode(RF_OPMODE_RECEIVER);
dudmuck 0:27aa8733f85d 529 }
dudmuck 0:27aa8733f85d 530
dudmuck 0:27aa8733f85d 531
dudmuck 0:27aa8733f85d 532 void SX127x::hw_reset()
dudmuck 0:27aa8733f85d 533 {
dudmuck 0:27aa8733f85d 534 /* only a french-swiss design would have hi-Z deassert */
dudmuck 0:27aa8733f85d 535 reset_pin.output();
dudmuck 0:27aa8733f85d 536 reset_pin.write(1);
dudmuck 0:27aa8733f85d 537 wait(0.05);
dudmuck 0:27aa8733f85d 538 reset_pin.input();
dudmuck 0:27aa8733f85d 539 wait(0.05);
dudmuck 0:27aa8733f85d 540 }
dudmuck 0:27aa8733f85d 541
dudmuck 0:27aa8733f85d 542 service_action_e SX127x::service()
dudmuck 0:27aa8733f85d 543 {
dudmuck 0:27aa8733f85d 544
dudmuck 0:27aa8733f85d 545 if (RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 0:27aa8733f85d 546 if (poll_vh) {
dudmuck 0:27aa8733f85d 547 RegIrqFlags.octet = read_reg(REG_LR_IRQFLAGS);
dudmuck 0:27aa8733f85d 548 if (RegIrqFlags.bits.ValidHeader) {
dudmuck 0:27aa8733f85d 549 RegIrqFlags.octet = 0;
dudmuck 0:27aa8733f85d 550 RegIrqFlags.bits.ValidHeader = 1;
dudmuck 0:27aa8733f85d 551 write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 0:27aa8733f85d 552 printf("VH\r\n");
dudmuck 0:27aa8733f85d 553 }
dudmuck 0:27aa8733f85d 554 }
dudmuck 0:27aa8733f85d 555 }
dudmuck 0:27aa8733f85d 556
dudmuck 0:27aa8733f85d 557 // FhssChangeChannel
dudmuck 0:27aa8733f85d 558 if (RegDioMapping1.bits.Dio1Mapping == 1) {
dudmuck 0:27aa8733f85d 559 if (dio1) {
dudmuck 0:27aa8733f85d 560 RegHopChannel.octet = read_reg(REG_LR_HOPCHANNEL);
dudmuck 0:27aa8733f85d 561 write_reg_u24(REG_FRFMSB, frfs[RegHopChannel.bits.FhssPresentChannel]);
dudmuck 0:27aa8733f85d 562 printf("hopch:%d\r\n", RegHopChannel.bits.FhssPresentChannel);
dudmuck 0:27aa8733f85d 563 RegIrqFlags.octet = 0;
dudmuck 0:27aa8733f85d 564 RegIrqFlags.bits.FhssChangeChannel = 1;
dudmuck 0:27aa8733f85d 565 write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 0:27aa8733f85d 566
dudmuck 0:27aa8733f85d 567 }
dudmuck 0:27aa8733f85d 568 }
dudmuck 0:27aa8733f85d 569
dudmuck 0:27aa8733f85d 570 if (dio0 == 0)
dudmuck 0:27aa8733f85d 571 return SERVICE_NONE;
dudmuck 0:27aa8733f85d 572
dudmuck 0:27aa8733f85d 573 switch (RegDioMapping1.bits.Dio0Mapping) {
dudmuck 0:27aa8733f85d 574 case 0: // RxDone
dudmuck 0:27aa8733f85d 575 /* user checks for CRC error in IrqFlags */
dudmuck 0:27aa8733f85d 576 RegIrqFlags.octet = read_reg(REG_LR_IRQFLAGS); // save flags
dudmuck 0:27aa8733f85d 577 RegHopChannel.octet = read_reg(REG_LR_HOPCHANNEL);
dudmuck 0:27aa8733f85d 578 if (RegIrqFlags.bits.FhssChangeChannel) {
dudmuck 0:27aa8733f85d 579 write_reg_u24(REG_FRFMSB, frfs[RegHopChannel.bits.FhssPresentChannel]);
dudmuck 0:27aa8733f85d 580 }
dudmuck 0:27aa8733f85d 581 //printf("[%02x]", RegIrqFlags.octet);
dudmuck 0:27aa8733f85d 582 write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet); // clear flags in radio
dudmuck 0:27aa8733f85d 583
dudmuck 0:27aa8733f85d 584 /* any register of interest on received packet is read(saved) here */
dudmuck 0:27aa8733f85d 585 RegModemStatus.octet = read_reg(REG_LR_MODEMSTAT);
dudmuck 0:27aa8733f85d 586 RegPktSnrValue = read_reg(REG_LR_PKTSNRVALUE);
dudmuck 0:27aa8733f85d 587 RegPktRssiValue = read_reg(REG_LR_PKTRSSIVALUE);
dudmuck 0:27aa8733f85d 588 RegRxNbBytes = read_reg(REG_LR_RXNBBYTES);
dudmuck 0:27aa8733f85d 589
dudmuck 0:27aa8733f85d 590 write_reg(REG_LR_FIFOADDRPTR, read_reg(REG_LR_FIFORXCURRENTADDR));
dudmuck 0:27aa8733f85d 591 lora_read_fifo(RegRxNbBytes);
dudmuck 0:27aa8733f85d 592 return SERVICE_READ_FIFO;
dudmuck 0:27aa8733f85d 593 case 1: // TxDone
dudmuck 0:27aa8733f85d 594 if (HF)
dudmuck 0:27aa8733f85d 595 femctx = 0;
dudmuck 0:27aa8733f85d 596 else
dudmuck 0:27aa8733f85d 597 femcps = 1;
dudmuck 0:27aa8733f85d 598
dudmuck 0:27aa8733f85d 599 RegIrqFlags.octet = 0;
dudmuck 0:27aa8733f85d 600 RegIrqFlags.bits.TxDone = 1;
dudmuck 0:27aa8733f85d 601 write_reg(REG_LR_IRQFLAGS, RegIrqFlags.octet);
dudmuck 0:27aa8733f85d 602 return SERVICE_TX_DONE;
dudmuck 0:27aa8733f85d 603 } // ...switch (RegDioMapping1.bits.Dio0Mapping)
dudmuck 0:27aa8733f85d 604
dudmuck 0:27aa8733f85d 605 return SERVICE_ERROR;
dudmuck 0:27aa8733f85d 606 }