Driver library for SX1272/SX1276 transceivers

Dependents:   LORA_RX LORA_TX WindConcentrator hid_test ... more

/media/uploads/dudmuck/lora.png

Driver library for SX1272 and SX1276 radio transceivers.

This device uses CSS modulation to provide much improved link budget. The RF hardware is same as in FSK devices, just with added LoRa spread-spectrum modem.

This library provides functions to configure radio chip and transmit & receive packets.

Using This Library

Library function service_radio() must be called continuously from main loop, to service interrupts from radio.

/media/uploads/dudmuck/sx1272rf1_connector_300.jpg

Board Specific implementation

FunctionPointer for rf_switch callback allows the program to implement control of RF switch unique to their board. Example options are:

  • SKY13373 for external power amplifier implementation. Requires two DigitalOut pins.
  • SKY13350 using PA_BOOST. requires two DigitalOut pins.
  • PE4259-63: controlled directly by radio chip, no software function needed. However, in the case of SX1276MB1xAS, the RXTX pin on IO2 should be driven by this callback function when R16 is installed (without R15) on this shield board.

Some configurations may need to force the use of RFO or PA_BOOST, or a board could offer both options. The rf_switch function pointer callback should support the implementation choice on the board.

further reading

Committer:
Wayne Roberts
Date:
Fri Jul 10 09:23:52 2020 -0700
Revision:
36:af9b41b1e285
Parent:
28:207594d5cf0e
run on mbed-6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 2:fdae76e1215e 1 #include "sx127x_fsk.h"
dudmuck 2:fdae76e1215e 2
dudmuck 2:fdae76e1215e 3 /* SX127x driver
dudmuck 2:fdae76e1215e 4 * Copyright (c) 2013 Semtech
dudmuck 2:fdae76e1215e 5 *
dudmuck 2:fdae76e1215e 6 * Licensed under the Apache License, Version 2.0 (the "License");
dudmuck 2:fdae76e1215e 7 * you may not use this file except in compliance with the License.
dudmuck 2:fdae76e1215e 8 * You may obtain a copy of the License at
dudmuck 2:fdae76e1215e 9 *
dudmuck 2:fdae76e1215e 10 * http://www.apache.org/licenses/LICENSE-2.0
dudmuck 2:fdae76e1215e 11 *
dudmuck 2:fdae76e1215e 12 * Unless required by applicable law or agreed to in writing, software
dudmuck 2:fdae76e1215e 13 * distributed under the License is distributed on an "AS IS" BASIS,
dudmuck 2:fdae76e1215e 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dudmuck 2:fdae76e1215e 15 * See the License for the specific language governing permissions and
dudmuck 2:fdae76e1215e 16 * limitations under the License.
dudmuck 2:fdae76e1215e 17 */
dudmuck 3:3bf2515b1eed 18
dudmuck 3:3bf2515b1eed 19 SX127x_fsk::SX127x_fsk(SX127x& r) : m_xcvr(r)
dudmuck 2:fdae76e1215e 20 {
dudmuck 2:fdae76e1215e 21 }
dudmuck 2:fdae76e1215e 22
dudmuck 2:fdae76e1215e 23 SX127x_fsk::~SX127x_fsk()
dudmuck 2:fdae76e1215e 24 {
dudmuck 2:fdae76e1215e 25 }
dudmuck 2:fdae76e1215e 26
dudmuck 2:fdae76e1215e 27 void SX127x_fsk::write_fifo(uint8_t len)
dudmuck 2:fdae76e1215e 28 {
dudmuck 2:fdae76e1215e 29 int i;
dudmuck 2:fdae76e1215e 30
dudmuck 2:fdae76e1215e 31 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 32 m_xcvr.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 2:fdae76e1215e 33
dudmuck 3:3bf2515b1eed 34 if (!m_xcvr.RegOpMode.bits.LongRangeMode && RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 2:fdae76e1215e 35 m_xcvr.m_spi.write(len);
dudmuck 3:3bf2515b1eed 36 }
dudmuck 2:fdae76e1215e 37
dudmuck 2:fdae76e1215e 38 for (i = 0; i < len; i++) {
dudmuck 2:fdae76e1215e 39 m_xcvr.m_spi.write(m_xcvr.tx_buf[i]);
dudmuck 2:fdae76e1215e 40 }
dudmuck 2:fdae76e1215e 41 m_xcvr.m_cs = 1;
dudmuck 2:fdae76e1215e 42 }
dudmuck 2:fdae76e1215e 43
dudmuck 12:bda42457c34a 44 void SX127x_fsk::enable(bool fast)
dudmuck 2:fdae76e1215e 45 {
dudmuck 2:fdae76e1215e 46 m_xcvr.set_opmode(RF_OPMODE_SLEEP);
dudmuck 2:fdae76e1215e 47
dudmuck 2:fdae76e1215e 48 m_xcvr.RegOpMode.bits.LongRangeMode = 0;
dudmuck 2:fdae76e1215e 49 m_xcvr.write_reg(REG_OPMODE, m_xcvr.RegOpMode.octet);
dudmuck 12:bda42457c34a 50 if (fast)
dudmuck 12:bda42457c34a 51 return;
dudmuck 2:fdae76e1215e 52
dudmuck 2:fdae76e1215e 53 RegPktConfig1.octet = m_xcvr.read_reg(REG_FSK_PACKETCONFIG1);
dudmuck 2:fdae76e1215e 54 RegPktConfig2.word = m_xcvr.read_u16(REG_FSK_PACKETCONFIG2);
dudmuck 12:bda42457c34a 55 RegRxConfig.octet = m_xcvr.read_reg(REG_FSK_RXCONFIG);
dudmuck 3:3bf2515b1eed 56 RegPreambleDetect.octet = m_xcvr.read_reg(REG_FSK_PREAMBLEDETECT);
dudmuck 3:3bf2515b1eed 57 RegSyncConfig.octet = m_xcvr.read_reg(REG_FSK_SYNCCONFIG);
dudmuck 3:3bf2515b1eed 58 RegFifoThreshold.octet = m_xcvr.read_reg(REG_FSK_FIFOTHRESH);
dudmuck 3:3bf2515b1eed 59 RegAfcFei.octet = m_xcvr.read_reg(REG_FSK_AFCFEI);
dudmuck 3:3bf2515b1eed 60
dudmuck 3:3bf2515b1eed 61 if (!RegFifoThreshold.bits.TxStartCondition) {
dudmuck 3:3bf2515b1eed 62 RegFifoThreshold.bits.TxStartCondition = 1; // start TX on fifoEmpty==0
dudmuck 3:3bf2515b1eed 63 m_xcvr.write_reg(REG_FSK_FIFOTHRESH, RegFifoThreshold.octet);
dudmuck 3:3bf2515b1eed 64 }
dudmuck 3:3bf2515b1eed 65
dudmuck 3:3bf2515b1eed 66 if (RegSyncConfig.bits.AutoRestartRxMode != 1) {
dudmuck 3:3bf2515b1eed 67 RegSyncConfig.bits.AutoRestartRxMode = 1;
dudmuck 3:3bf2515b1eed 68 m_xcvr.write_reg(REG_FSK_SYNCCONFIG, RegSyncConfig.octet);
dudmuck 3:3bf2515b1eed 69 }
dudmuck 3:3bf2515b1eed 70
dudmuck 25:fa867fb9d2f6 71 RegPreambleDetect.bits.PreambleDetectorOn = 1;
dudmuck 25:fa867fb9d2f6 72 RegPreambleDetect.bits.PreambleDetectorSize = 1;
dudmuck 25:fa867fb9d2f6 73 RegPreambleDetect.bits.PreambleDetectorTol = 10;
dudmuck 25:fa867fb9d2f6 74 m_xcvr.write_reg(REG_FSK_PREAMBLEDETECT, RegPreambleDetect.octet);
dudmuck 2:fdae76e1215e 75
dudmuck 2:fdae76e1215e 76 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 77 }
dudmuck 2:fdae76e1215e 78
dudmuck 4:d987ac2836bf 79 void SX127x_fsk::init()
dudmuck 4:d987ac2836bf 80 {
dudmuck 4:d987ac2836bf 81 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 4:d987ac2836bf 82
dudmuck 4:d987ac2836bf 83 RegRxConfig.bits.RxTrigger = 6; // have RX restart (trigger) on preamble detection
dudmuck 4:d987ac2836bf 84 RegRxConfig.bits.AfcAutoOn = 1; // have AFC performed on RX restart (RX trigger)
dudmuck 4:d987ac2836bf 85 m_xcvr.write_reg(REG_FSK_RXCONFIG, RegRxConfig.octet);
dudmuck 4:d987ac2836bf 86
dudmuck 4:d987ac2836bf 87 RegPreambleDetect.bits.PreambleDetectorOn = 1; // enable preamble detector
dudmuck 4:d987ac2836bf 88 m_xcvr.write_reg(REG_FSK_PREAMBLEDETECT, RegPreambleDetect.octet);
dudmuck 4:d987ac2836bf 89
dudmuck 4:d987ac2836bf 90 m_xcvr.write_reg(REG_FSK_SYNCVALUE1, 0x55);
dudmuck 4:d987ac2836bf 91 m_xcvr.write_reg(REG_FSK_SYNCVALUE2, 0x6f);
dudmuck 4:d987ac2836bf 92 m_xcvr.write_reg(REG_FSK_SYNCVALUE3, 0x4e);
dudmuck 4:d987ac2836bf 93 RegSyncConfig.bits.SyncSize = 2;
dudmuck 4:d987ac2836bf 94 m_xcvr.write_reg(REG_FSK_SYNCCONFIG, RegSyncConfig.octet);
dudmuck 4:d987ac2836bf 95
dudmuck 4:d987ac2836bf 96 // in case these were changed from default:
dudmuck 4:d987ac2836bf 97 set_bitrate(4800);
dudmuck 4:d987ac2836bf 98 set_tx_fdev_hz(5050);
dudmuck 4:d987ac2836bf 99 set_rx_dcc_bw_hz(10500, 0); // rxbw
dudmuck 4:d987ac2836bf 100 set_rx_dcc_bw_hz(50000, 1); // afcbw
dudmuck 4:d987ac2836bf 101 }
dudmuck 4:d987ac2836bf 102
dudmuck 4:d987ac2836bf 103 uint32_t SX127x_fsk::get_bitrate()
dudmuck 4:d987ac2836bf 104 {
dudmuck 4:d987ac2836bf 105 uint16_t br = m_xcvr.read_u16(REG_FSK_BITRATEMSB);
dudmuck 4:d987ac2836bf 106
dudmuck 4:d987ac2836bf 107 if (br == 0)
dudmuck 4:d987ac2836bf 108 return 0;
dudmuck 26:4876e515ff4c 109 else {
dudmuck 26:4876e515ff4c 110 uint32_t bps = XTAL_FREQ / br;
dudmuck 26:4876e515ff4c 111 bit_period_us = bps / 1000;
dudmuck 26:4876e515ff4c 112 return bps;
dudmuck 26:4876e515ff4c 113 }
dudmuck 4:d987ac2836bf 114 }
dudmuck 4:d987ac2836bf 115
dudmuck 4:d987ac2836bf 116 void SX127x_fsk::set_bitrate(uint32_t bps)
dudmuck 4:d987ac2836bf 117 {
dudmuck 4:d987ac2836bf 118 uint16_t tmpBitrate = XTAL_FREQ / bps;
dudmuck 26:4876e515ff4c 119 bit_period_us = bps / 1000;
dudmuck 4:d987ac2836bf 120 //printf("tmpBitrate:%d = %d / %d\r\n", tmpBitrate, XTAL_FREQ, bps);
dudmuck 4:d987ac2836bf 121 m_xcvr.write_u16(REG_FSK_BITRATEMSB, tmpBitrate);
dudmuck 4:d987ac2836bf 122 }
dudmuck 4:d987ac2836bf 123
dudmuck 4:d987ac2836bf 124 void SX127x_fsk::set_tx_fdev_hz(uint32_t hz)
dudmuck 4:d987ac2836bf 125 {
dudmuck 4:d987ac2836bf 126 float tmpFdev = hz / FREQ_STEP_HZ;
dudmuck 4:d987ac2836bf 127 uint16_t v;
dudmuck 4:d987ac2836bf 128 //printf("tmpFdev:%f = %d / %f\r\n", tmpFdev, hz, FREQ_STEP_HZ);
dudmuck 4:d987ac2836bf 129 v = (uint16_t)tmpFdev;
dudmuck 4:d987ac2836bf 130 m_xcvr.write_u16(REG_FSK_FDEVMSB, v);
dudmuck 4:d987ac2836bf 131 }
dudmuck 4:d987ac2836bf 132
dudmuck 4:d987ac2836bf 133 uint32_t SX127x_fsk::get_tx_fdev_hz(void)
dudmuck 4:d987ac2836bf 134 {
dudmuck 4:d987ac2836bf 135 uint16_t fdev = m_xcvr.read_u16(REG_FSK_FDEVMSB);
dudmuck 4:d987ac2836bf 136 return fdev * FREQ_STEP_HZ;
dudmuck 4:d987ac2836bf 137 }
dudmuck 4:d987ac2836bf 138
dudmuck 2:fdae76e1215e 139 uint32_t SX127x_fsk::ComputeRxBw( uint8_t mantisse, uint8_t exponent )
dudmuck 2:fdae76e1215e 140 {
dudmuck 2:fdae76e1215e 141 // rxBw
dudmuck 2:fdae76e1215e 142 if (m_xcvr.RegOpMode.bits.ModulationType == 0)
dudmuck 2:fdae76e1215e 143 return XTAL_FREQ / (mantisse * (1 << (exponent+2)));
dudmuck 2:fdae76e1215e 144 else
dudmuck 2:fdae76e1215e 145 return XTAL_FREQ / (mantisse * (1 << (exponent+3)));
dudmuck 2:fdae76e1215e 146 }
dudmuck 2:fdae76e1215e 147
dudmuck 2:fdae76e1215e 148
dudmuck 2:fdae76e1215e 149 void SX127x_fsk::ComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
dudmuck 2:fdae76e1215e 150 {
dudmuck 2:fdae76e1215e 151 uint8_t tmpExp, tmpMant;
dudmuck 2:fdae76e1215e 152 double tmpRxBw;
dudmuck 2:fdae76e1215e 153 double rxBwMin = 10e6;
dudmuck 2:fdae76e1215e 154
dudmuck 2:fdae76e1215e 155 for( tmpExp = 0; tmpExp < 8; tmpExp++ ) {
dudmuck 2:fdae76e1215e 156 for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) {
dudmuck 2:fdae76e1215e 157 tmpRxBw = ComputeRxBw(tmpMant, tmpExp);
dudmuck 2:fdae76e1215e 158 if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) {
dudmuck 2:fdae76e1215e 159 rxBwMin = fabs( tmpRxBw - rxBwValue );
dudmuck 2:fdae76e1215e 160 *mantisse = tmpMant;
dudmuck 2:fdae76e1215e 161 *exponent = tmpExp;
dudmuck 2:fdae76e1215e 162 }
dudmuck 2:fdae76e1215e 163 }
dudmuck 2:fdae76e1215e 164 }
dudmuck 2:fdae76e1215e 165 }
dudmuck 2:fdae76e1215e 166
dudmuck 2:fdae76e1215e 167
dudmuck 2:fdae76e1215e 168 uint32_t SX127x_fsk::get_rx_bw_hz(uint8_t addr)
dudmuck 2:fdae76e1215e 169 {
dudmuck 3:3bf2515b1eed 170 RegRxBw_t reg_bw;
dudmuck 2:fdae76e1215e 171 uint8_t mantissa;
dudmuck 2:fdae76e1215e 172
dudmuck 2:fdae76e1215e 173 if (m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 174 return 0;
dudmuck 2:fdae76e1215e 175
dudmuck 2:fdae76e1215e 176 reg_bw.octet = m_xcvr.read_reg(addr);
dudmuck 2:fdae76e1215e 177 switch (reg_bw.bits.Mantissa) {
dudmuck 2:fdae76e1215e 178 case 0: mantissa = 16; break;
dudmuck 2:fdae76e1215e 179 case 1: mantissa = 20; break;
dudmuck 2:fdae76e1215e 180 case 2: mantissa = 24; break;
dudmuck 2:fdae76e1215e 181 default: mantissa = 0; break;
dudmuck 2:fdae76e1215e 182 }
dudmuck 2:fdae76e1215e 183
dudmuck 2:fdae76e1215e 184 if (addr == REG_FSK_RXBW)
dudmuck 2:fdae76e1215e 185 RegRxBw.octet = reg_bw.octet;
dudmuck 2:fdae76e1215e 186 else if (addr == REG_FSK_AFCBW)
dudmuck 2:fdae76e1215e 187 RegAfcBw.octet = reg_bw.octet;
dudmuck 2:fdae76e1215e 188
dudmuck 2:fdae76e1215e 189 return ComputeRxBw(mantissa, reg_bw.bits.Exponent);
dudmuck 2:fdae76e1215e 190 }
dudmuck 2:fdae76e1215e 191
dudmuck 2:fdae76e1215e 192
dudmuck 2:fdae76e1215e 193 void SX127x_fsk::set_rx_dcc_bw_hz(uint32_t bw_hz, char afc)
dudmuck 2:fdae76e1215e 194 {
dudmuck 2:fdae76e1215e 195 uint8_t mantisse = 0;
dudmuck 2:fdae76e1215e 196 uint8_t exponent = 0;
dudmuck 2:fdae76e1215e 197
dudmuck 2:fdae76e1215e 198 if (m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 199 return;
dudmuck 2:fdae76e1215e 200
dudmuck 2:fdae76e1215e 201 ComputeRxBwMantExp( bw_hz, &mantisse, &exponent );
dudmuck 2:fdae76e1215e 202 //printf("bw_hz:%d, mantisse:%d, exponent:%d\n", bw_hz, mantisse, exponent );
dudmuck 2:fdae76e1215e 203 switch( mantisse ) {
dudmuck 2:fdae76e1215e 204 case 16:
dudmuck 2:fdae76e1215e 205 RegRxBw.bits.Mantissa = 0;
dudmuck 2:fdae76e1215e 206 break;
dudmuck 2:fdae76e1215e 207 case 20:
dudmuck 2:fdae76e1215e 208 RegRxBw.bits.Mantissa = 1;
dudmuck 2:fdae76e1215e 209 break;
dudmuck 2:fdae76e1215e 210 case 24:
dudmuck 2:fdae76e1215e 211 RegRxBw.bits.Mantissa = 2;
dudmuck 2:fdae76e1215e 212 break;
dudmuck 2:fdae76e1215e 213 default:
dudmuck 2:fdae76e1215e 214 // Something went terribely wrong
dudmuck 2:fdae76e1215e 215 printf("maintisse:%d\n", mantisse);
dudmuck 2:fdae76e1215e 216 break;
dudmuck 2:fdae76e1215e 217 }
dudmuck 2:fdae76e1215e 218 RegRxBw.bits.Exponent = exponent;
dudmuck 2:fdae76e1215e 219
dudmuck 2:fdae76e1215e 220 if (afc)
dudmuck 2:fdae76e1215e 221 m_xcvr.write_reg(REG_FSK_AFCBW, RegRxBw.octet);
dudmuck 2:fdae76e1215e 222 else
dudmuck 2:fdae76e1215e 223 m_xcvr.write_reg(REG_FSK_RXBW, RegRxBw.octet);
dudmuck 2:fdae76e1215e 224 }
dudmuck 2:fdae76e1215e 225
dudmuck 2:fdae76e1215e 226
dudmuck 2:fdae76e1215e 227 void SX127x_fsk::start_tx(uint16_t arg_len)
dudmuck 2:fdae76e1215e 228 {
dudmuck 2:fdae76e1215e 229 uint16_t pkt_buf_len;
dudmuck 3:3bf2515b1eed 230 RegIrqFlags2_t RegIrqFlags2;
dudmuck 2:fdae76e1215e 231 int maxlen = FSK_FIFO_SIZE-1;
dudmuck 2:fdae76e1215e 232
dudmuck 2:fdae76e1215e 233 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 234 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 235 }
dudmuck 2:fdae76e1215e 236
dudmuck 2:fdae76e1215e 237 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 2:fdae76e1215e 238 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0;
dudmuck 2:fdae76e1215e 239 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 240 }
dudmuck 2:fdae76e1215e 241
dudmuck 21:b4ba73b59bb4 242 RegPktConfig1.octet = m_xcvr.read_reg(REG_FSK_PACKETCONFIG1);
dudmuck 2:fdae76e1215e 243 if (RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 2:fdae76e1215e 244 pkt_buf_len = arg_len;
dudmuck 2:fdae76e1215e 245 } else {
dudmuck 2:fdae76e1215e 246 pkt_buf_len = RegPktConfig2.bits.PayloadLength;
dudmuck 2:fdae76e1215e 247 }
dudmuck 2:fdae76e1215e 248
dudmuck 2:fdae76e1215e 249 RegIrqFlags2.octet = m_xcvr.read_reg(REG_FSK_IRQFLAGS2);
dudmuck 2:fdae76e1215e 250 if (RegIrqFlags2.bits.FifoEmpty) {
dudmuck 2:fdae76e1215e 251 if (RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 2:fdae76e1215e 252 --maxlen; // space for length byte
dudmuck 2:fdae76e1215e 253 if (pkt_buf_len > maxlen) {
dudmuck 2:fdae76e1215e 254 /*setup_FifoLevel(FALLING_EDGE);
dudmuck 2:fdae76e1215e 255 radio_write_fifo_(pkt_buf, maxlen, pkt_buf_len);
dudmuck 2:fdae76e1215e 256 remaining_ = pkt_buf_len - maxlen;
dudmuck 2:fdae76e1215e 257 printf("var-oversized %d R=%d\r\n", pkt_buf_len, remaining_);*/
dudmuck 2:fdae76e1215e 258 printf("var-oversized %d\r\n", pkt_buf_len);
dudmuck 2:fdae76e1215e 259 } else {
dudmuck 8:c9592cbc9f86 260 //setup_FifoLevel(NO_EDGE); // disable
dudmuck 2:fdae76e1215e 261 write_fifo(pkt_buf_len);
dudmuck 2:fdae76e1215e 262 //remaining_ = 0; // all was sent
dudmuck 2:fdae76e1215e 263 }
dudmuck 2:fdae76e1215e 264 } else { // fixed-length pkt format...
dudmuck 2:fdae76e1215e 265 pkt_buf_len = RegPktConfig2.bits.PayloadLength;
dudmuck 2:fdae76e1215e 266 if (RegPktConfig2.bits.PayloadLength > maxlen) {
dudmuck 2:fdae76e1215e 267 /*setup_FifoLevel(FALLING_EDGE);
dudmuck 2:fdae76e1215e 268 radio_write_fifo_(pkt_buf, maxlen, -1);
dudmuck 2:fdae76e1215e 269 remaining_ = SX1272FSK->RegPktConfig2.bits.PayloadLength - maxlen;*/
dudmuck 2:fdae76e1215e 270 printf("todo: fsk large packet\r\n");
dudmuck 2:fdae76e1215e 271 } else {
dudmuck 2:fdae76e1215e 272 //setup_FifoLevel(NO_EDGE); // disable
dudmuck 2:fdae76e1215e 273 write_fifo(RegPktConfig2.bits.PayloadLength);
dudmuck 2:fdae76e1215e 274 }
dudmuck 2:fdae76e1215e 275 }
dudmuck 2:fdae76e1215e 276 } else
dudmuck 2:fdae76e1215e 277 printf("fifo not empty %02x\r\n", RegIrqFlags2.octet);
dudmuck 2:fdae76e1215e 278
dudmuck 2:fdae76e1215e 279 m_xcvr.set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 2:fdae76e1215e 280
dudmuck 2:fdae76e1215e 281 }
dudmuck 2:fdae76e1215e 282
dudmuck 3:3bf2515b1eed 283 void SX127x_fsk::config_dio0_for_pktmode_rx()
dudmuck 3:3bf2515b1eed 284 {
dudmuck 27:da6341d9d5b1 285 if (RegPktConfig2.bits.DataModePacket) {
dudmuck 27:da6341d9d5b1 286 if (RegPktConfig1.bits.CrcOn) {
dudmuck 27:da6341d9d5b1 287 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 1) {
dudmuck 27:da6341d9d5b1 288 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 1; // to CrcOk
dudmuck 27:da6341d9d5b1 289 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 27:da6341d9d5b1 290 }
dudmuck 27:da6341d9d5b1 291 } else { // Crc Off, use PayloadReady
dudmuck 27:da6341d9d5b1 292 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 27:da6341d9d5b1 293 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; // to PayloadReady
dudmuck 27:da6341d9d5b1 294 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 27:da6341d9d5b1 295 }
dudmuck 3:3bf2515b1eed 296 }
dudmuck 3:3bf2515b1eed 297 }
dudmuck 3:3bf2515b1eed 298 }
dudmuck 2:fdae76e1215e 299
dudmuck 2:fdae76e1215e 300 void SX127x_fsk::start_rx()
dudmuck 2:fdae76e1215e 301 {
dudmuck 2:fdae76e1215e 302 if (m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 303 return;
dudmuck 2:fdae76e1215e 304
dudmuck 2:fdae76e1215e 305 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 306 // was already receiving, restart it
dudmuck 2:fdae76e1215e 307 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
Wayne Roberts 36:af9b41b1e285 308 #if (MBED_MAJOR_VERSION < 6)
Wayne Roberts 36:af9b41b1e285 309 ThisThread::sleep_for(10);
Wayne Roberts 36:af9b41b1e285 310 #else
Wayne Roberts 36:af9b41b1e285 311 ThisThread::sleep_for(10ms);
Wayne Roberts 36:af9b41b1e285 312 #endif
dudmuck 2:fdae76e1215e 313 }
dudmuck 3:3bf2515b1eed 314
dudmuck 3:3bf2515b1eed 315 config_dio0_for_pktmode_rx();
dudmuck 3:3bf2515b1eed 316
dudmuck 2:fdae76e1215e 317 m_xcvr.set_opmode(RF_OPMODE_RECEIVER);
dudmuck 2:fdae76e1215e 318 }
dudmuck 2:fdae76e1215e 319
dudmuck 27:da6341d9d5b1 320 uint8_t SX127x_fsk::get_modulation_shaping()
dudmuck 27:da6341d9d5b1 321 {
dudmuck 27:da6341d9d5b1 322 if (m_xcvr.type == SX1276) {
dudmuck 27:da6341d9d5b1 323 RegPaRamp_t reg_paramp;
dudmuck 27:da6341d9d5b1 324 reg_paramp.octet = m_xcvr.read_reg(REG_PARAMP);
dudmuck 27:da6341d9d5b1 325 return reg_paramp.bits.ModulationShaping;
dudmuck 27:da6341d9d5b1 326 } else if (m_xcvr.type == SX1272) {
dudmuck 27:da6341d9d5b1 327 m_xcvr.RegOpMode.octet = m_xcvr.read_reg(REG_OPMODE);
dudmuck 27:da6341d9d5b1 328 return m_xcvr.RegOpMode.bits.ModulationShaping;
dudmuck 27:da6341d9d5b1 329 } else
dudmuck 27:da6341d9d5b1 330 return 0xff;
dudmuck 27:da6341d9d5b1 331 }
dudmuck 27:da6341d9d5b1 332
dudmuck 27:da6341d9d5b1 333 void SX127x_fsk::set_modulation_shaping(uint8_t s)
dudmuck 27:da6341d9d5b1 334 {
dudmuck 27:da6341d9d5b1 335 if (m_xcvr.type == SX1276) {
dudmuck 27:da6341d9d5b1 336 RegPaRamp_t reg_paramp;
dudmuck 27:da6341d9d5b1 337 reg_paramp.octet = m_xcvr.read_reg(REG_PARAMP);
dudmuck 27:da6341d9d5b1 338 reg_paramp.bits.ModulationShaping = s;
dudmuck 27:da6341d9d5b1 339 m_xcvr.write_reg(REG_PARAMP, reg_paramp.octet);
dudmuck 27:da6341d9d5b1 340 } else if (m_xcvr.type == SX1272) {
dudmuck 27:da6341d9d5b1 341 m_xcvr.RegOpMode.octet = m_xcvr.read_reg(REG_OPMODE);
dudmuck 27:da6341d9d5b1 342 m_xcvr.RegOpMode.bits.ModulationShaping = s;
dudmuck 27:da6341d9d5b1 343 m_xcvr.write_reg(REG_OPMODE, m_xcvr.RegOpMode.octet);
dudmuck 27:da6341d9d5b1 344 }
dudmuck 27:da6341d9d5b1 345 }
dudmuck 27:da6341d9d5b1 346
dudmuck 2:fdae76e1215e 347 service_action_e SX127x_fsk::service()
dudmuck 2:fdae76e1215e 348 {
dudmuck 2:fdae76e1215e 349 int i;
dudmuck 2:fdae76e1215e 350
dudmuck 2:fdae76e1215e 351 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
dudmuck 2:fdae76e1215e 352 if (m_xcvr.dio0) {
dudmuck 26:4876e515ff4c 353 /* packetSent comes at start of last bit, wait for one bit period */
dudmuck 26:4876e515ff4c 354 wait_us(bit_period_us);
dudmuck 26:4876e515ff4c 355 if (tx_done_sleep)
dudmuck 26:4876e515ff4c 356 m_xcvr.set_opmode(RF_OPMODE_SLEEP);
dudmuck 26:4876e515ff4c 357 else
dudmuck 26:4876e515ff4c 358 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 359 return SERVICE_TX_DONE;
dudmuck 2:fdae76e1215e 360 }
dudmuck 28:207594d5cf0e 361 } else if (RegPktConfig2.bits.DataModePacket && m_xcvr.dio0) {
dudmuck 3:3bf2515b1eed 362 if (RegRxConfig.bits.AfcAutoOn)
dudmuck 3:3bf2515b1eed 363 RegAfcValue = m_xcvr.read_s16(REG_FSK_AFCMSB);
dudmuck 3:3bf2515b1eed 364
dudmuck 2:fdae76e1215e 365 if (RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 3:3bf2515b1eed 366 rx_buf_length = m_xcvr.read_reg(REG_FIFO);
dudmuck 2:fdae76e1215e 367 } else {
dudmuck 3:3bf2515b1eed 368 rx_buf_length = RegPktConfig2.bits.PayloadLength;
dudmuck 2:fdae76e1215e 369 }
dudmuck 2:fdae76e1215e 370
dudmuck 2:fdae76e1215e 371 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 372 m_xcvr.m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 3:3bf2515b1eed 373 for (i = 0; i < rx_buf_length; i++) {
dudmuck 2:fdae76e1215e 374 m_xcvr.rx_buf[i] = m_xcvr.m_spi.write(0);
dudmuck 2:fdae76e1215e 375 }
dudmuck 2:fdae76e1215e 376 m_xcvr.m_cs = 1;
dudmuck 2:fdae76e1215e 377 return SERVICE_READ_FIFO;
dudmuck 2:fdae76e1215e 378 }
dudmuck 2:fdae76e1215e 379
dudmuck 2:fdae76e1215e 380 return SERVICE_NONE;
dudmuck 2:fdae76e1215e 381 }