Fork of SX1276 library, with setLowDataRateOptimize() function added to configure "Low Datarate Optimize" setting of chip.

Dependents:   SX1276_terminal SX1276_Semtech_GUI

Fork of SX127x by wayne roberts

Committer:
dudmuck
Date:
Wed Apr 30 22:49:43 2014 +0000
Revision:
2:fdae76e1215e
Child:
3:3bf2515b1eed
separated LoRa code from FSK code from common code

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 2:fdae76e1215e 18
dudmuck 2:fdae76e1215e 19 //SX127x_fsk::SX127x_fsk(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rst, PinName dio_0, PinName dio_1, PinName fem_ctx, PinName fem_cps) : SX127x(mosi, miso, sclk, cs, rst, dio_0, dio_1, fem_ctx, fem_cps)
dudmuck 2:fdae76e1215e 20 SX127x_fsk::SX127x_fsk(SX127x r) : m_xcvr(r)
dudmuck 2:fdae76e1215e 21 {
dudmuck 2:fdae76e1215e 22 }
dudmuck 2:fdae76e1215e 23
dudmuck 2:fdae76e1215e 24 SX127x_fsk::~SX127x_fsk()
dudmuck 2:fdae76e1215e 25 {
dudmuck 2:fdae76e1215e 26 }
dudmuck 2:fdae76e1215e 27
dudmuck 2:fdae76e1215e 28 void SX127x_fsk::write_fifo(uint8_t len)
dudmuck 2:fdae76e1215e 29 {
dudmuck 2:fdae76e1215e 30 int i;
dudmuck 2:fdae76e1215e 31
dudmuck 2:fdae76e1215e 32 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 33 m_xcvr.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 2:fdae76e1215e 34
dudmuck 2:fdae76e1215e 35 if (!m_xcvr.RegOpMode.bits.LongRangeMode && RegPktConfig1.bits.PacketFormatVariable)
dudmuck 2:fdae76e1215e 36 m_xcvr.m_spi.write(len);
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 2:fdae76e1215e 44 void SX127x_fsk::enable()
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 2:fdae76e1215e 50 wait(0.01);
dudmuck 2:fdae76e1215e 51
dudmuck 2:fdae76e1215e 52 /*RegOpMode.octet = read_reg(REG_OPMODE);
dudmuck 2:fdae76e1215e 53 printf("setloraoff:%02x\r\n", RegOpMode.octet);*/
dudmuck 2:fdae76e1215e 54
dudmuck 2:fdae76e1215e 55 // todo: read FSK regsiters
dudmuck 2:fdae76e1215e 56 //SX1272ReadBuffer( REG_OPMODE, SX1272Regs + 1, 0x70 - 1 );
dudmuck 2:fdae76e1215e 57 RegPktConfig1.octet = m_xcvr.read_reg(REG_FSK_PACKETCONFIG1);
dudmuck 2:fdae76e1215e 58 RegPktConfig2.word = m_xcvr.read_u16(REG_FSK_PACKETCONFIG2);
dudmuck 2:fdae76e1215e 59
dudmuck 2:fdae76e1215e 60 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 61 }
dudmuck 2:fdae76e1215e 62
dudmuck 2:fdae76e1215e 63 uint32_t SX127x_fsk::ComputeRxBw( uint8_t mantisse, uint8_t exponent )
dudmuck 2:fdae76e1215e 64 {
dudmuck 2:fdae76e1215e 65 // rxBw
dudmuck 2:fdae76e1215e 66 if (m_xcvr.RegOpMode.bits.ModulationType == 0)
dudmuck 2:fdae76e1215e 67 return XTAL_FREQ / (mantisse * (1 << (exponent+2)));
dudmuck 2:fdae76e1215e 68 else
dudmuck 2:fdae76e1215e 69 return XTAL_FREQ / (mantisse * (1 << (exponent+3)));
dudmuck 2:fdae76e1215e 70 }
dudmuck 2:fdae76e1215e 71
dudmuck 2:fdae76e1215e 72
dudmuck 2:fdae76e1215e 73 void SX127x_fsk::ComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
dudmuck 2:fdae76e1215e 74 {
dudmuck 2:fdae76e1215e 75 uint8_t tmpExp, tmpMant;
dudmuck 2:fdae76e1215e 76 double tmpRxBw;
dudmuck 2:fdae76e1215e 77 double rxBwMin = 10e6;
dudmuck 2:fdae76e1215e 78
dudmuck 2:fdae76e1215e 79 for( tmpExp = 0; tmpExp < 8; tmpExp++ ) {
dudmuck 2:fdae76e1215e 80 for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) {
dudmuck 2:fdae76e1215e 81 tmpRxBw = ComputeRxBw(tmpMant, tmpExp);
dudmuck 2:fdae76e1215e 82 if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) {
dudmuck 2:fdae76e1215e 83 rxBwMin = fabs( tmpRxBw - rxBwValue );
dudmuck 2:fdae76e1215e 84 *mantisse = tmpMant;
dudmuck 2:fdae76e1215e 85 *exponent = tmpExp;
dudmuck 2:fdae76e1215e 86 }
dudmuck 2:fdae76e1215e 87 }
dudmuck 2:fdae76e1215e 88 }
dudmuck 2:fdae76e1215e 89 }
dudmuck 2:fdae76e1215e 90
dudmuck 2:fdae76e1215e 91
dudmuck 2:fdae76e1215e 92 uint32_t SX127x_fsk::get_rx_bw_hz(uint8_t addr)
dudmuck 2:fdae76e1215e 93 {
dudmuck 2:fdae76e1215e 94 FSKRegRxBw_t reg_bw;
dudmuck 2:fdae76e1215e 95 uint8_t mantissa;
dudmuck 2:fdae76e1215e 96
dudmuck 2:fdae76e1215e 97 if (m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 98 return 0;
dudmuck 2:fdae76e1215e 99
dudmuck 2:fdae76e1215e 100 reg_bw.octet = m_xcvr.read_reg(addr);
dudmuck 2:fdae76e1215e 101 switch (reg_bw.bits.Mantissa) {
dudmuck 2:fdae76e1215e 102 case 0: mantissa = 16; break;
dudmuck 2:fdae76e1215e 103 case 1: mantissa = 20; break;
dudmuck 2:fdae76e1215e 104 case 2: mantissa = 24; break;
dudmuck 2:fdae76e1215e 105 default: mantissa = 0; break;
dudmuck 2:fdae76e1215e 106 }
dudmuck 2:fdae76e1215e 107
dudmuck 2:fdae76e1215e 108 if (addr == REG_FSK_RXBW)
dudmuck 2:fdae76e1215e 109 RegRxBw.octet = reg_bw.octet;
dudmuck 2:fdae76e1215e 110 else if (addr == REG_FSK_AFCBW)
dudmuck 2:fdae76e1215e 111 RegAfcBw.octet = reg_bw.octet;
dudmuck 2:fdae76e1215e 112
dudmuck 2:fdae76e1215e 113 return ComputeRxBw(mantissa, reg_bw.bits.Exponent);
dudmuck 2:fdae76e1215e 114 }
dudmuck 2:fdae76e1215e 115
dudmuck 2:fdae76e1215e 116
dudmuck 2:fdae76e1215e 117 void SX127x_fsk::set_rx_dcc_bw_hz(uint32_t bw_hz, char afc)
dudmuck 2:fdae76e1215e 118 {
dudmuck 2:fdae76e1215e 119 uint8_t mantisse = 0;
dudmuck 2:fdae76e1215e 120 uint8_t exponent = 0;
dudmuck 2:fdae76e1215e 121
dudmuck 2:fdae76e1215e 122 if (m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 123 return;
dudmuck 2:fdae76e1215e 124
dudmuck 2:fdae76e1215e 125 ComputeRxBwMantExp( bw_hz, &mantisse, &exponent );
dudmuck 2:fdae76e1215e 126 //printf("bw_hz:%d, mantisse:%d, exponent:%d\n", bw_hz, mantisse, exponent );
dudmuck 2:fdae76e1215e 127 switch( mantisse ) {
dudmuck 2:fdae76e1215e 128 case 16:
dudmuck 2:fdae76e1215e 129 RegRxBw.bits.Mantissa = 0;
dudmuck 2:fdae76e1215e 130 break;
dudmuck 2:fdae76e1215e 131 case 20:
dudmuck 2:fdae76e1215e 132 RegRxBw.bits.Mantissa = 1;
dudmuck 2:fdae76e1215e 133 break;
dudmuck 2:fdae76e1215e 134 case 24:
dudmuck 2:fdae76e1215e 135 RegRxBw.bits.Mantissa = 2;
dudmuck 2:fdae76e1215e 136 break;
dudmuck 2:fdae76e1215e 137 default:
dudmuck 2:fdae76e1215e 138 // Something went terribely wrong
dudmuck 2:fdae76e1215e 139 printf("maintisse:%d\n", mantisse);
dudmuck 2:fdae76e1215e 140 break;
dudmuck 2:fdae76e1215e 141 }
dudmuck 2:fdae76e1215e 142 RegRxBw.bits.Exponent = exponent;
dudmuck 2:fdae76e1215e 143
dudmuck 2:fdae76e1215e 144 if (afc)
dudmuck 2:fdae76e1215e 145 m_xcvr.write_reg(REG_FSK_AFCBW, RegRxBw.octet);
dudmuck 2:fdae76e1215e 146 else
dudmuck 2:fdae76e1215e 147 m_xcvr.write_reg(REG_FSK_RXBW, RegRxBw.octet);
dudmuck 2:fdae76e1215e 148 }
dudmuck 2:fdae76e1215e 149
dudmuck 2:fdae76e1215e 150
dudmuck 2:fdae76e1215e 151 void SX127x_fsk::start_tx(uint16_t arg_len)
dudmuck 2:fdae76e1215e 152 {
dudmuck 2:fdae76e1215e 153 uint16_t pkt_buf_len;
dudmuck 2:fdae76e1215e 154 FSKRegIrqFlags2_t RegIrqFlags2;
dudmuck 2:fdae76e1215e 155 int maxlen = FSK_FIFO_SIZE-1;
dudmuck 2:fdae76e1215e 156
dudmuck 2:fdae76e1215e 157 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 158 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 159 }
dudmuck 2:fdae76e1215e 160
dudmuck 2:fdae76e1215e 161 if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
dudmuck 2:fdae76e1215e 162 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0;
dudmuck 2:fdae76e1215e 163 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
dudmuck 2:fdae76e1215e 164 }
dudmuck 2:fdae76e1215e 165
dudmuck 2:fdae76e1215e 166 if (RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 2:fdae76e1215e 167 printf("variable-fmt %d\r\n", arg_len);
dudmuck 2:fdae76e1215e 168 pkt_buf_len = arg_len;
dudmuck 2:fdae76e1215e 169 } else {
dudmuck 2:fdae76e1215e 170 pkt_buf_len = RegPktConfig2.bits.PayloadLength;
dudmuck 2:fdae76e1215e 171 printf("fixed-fmt %d\r\n", pkt_buf_len);
dudmuck 2:fdae76e1215e 172 }
dudmuck 2:fdae76e1215e 173
dudmuck 2:fdae76e1215e 174 RegIrqFlags2.octet = m_xcvr.read_reg(REG_FSK_IRQFLAGS2);
dudmuck 2:fdae76e1215e 175 if (RegIrqFlags2.bits.FifoEmpty) {
dudmuck 2:fdae76e1215e 176 if (RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 2:fdae76e1215e 177 --maxlen; // space for length byte
dudmuck 2:fdae76e1215e 178 if (pkt_buf_len > maxlen) {
dudmuck 2:fdae76e1215e 179 /*setup_FifoLevel(FALLING_EDGE);
dudmuck 2:fdae76e1215e 180 radio_write_fifo_(pkt_buf, maxlen, pkt_buf_len);
dudmuck 2:fdae76e1215e 181 remaining_ = pkt_buf_len - maxlen;
dudmuck 2:fdae76e1215e 182 printf("var-oversized %d R=%d\r\n", pkt_buf_len, remaining_);*/
dudmuck 2:fdae76e1215e 183 printf("var-oversized %d\r\n", pkt_buf_len);
dudmuck 2:fdae76e1215e 184 } else {
dudmuck 2:fdae76e1215e 185 //setup_FifoLevel(NO_EDGE); // disable
dudmuck 2:fdae76e1215e 186 printf("var-write-fifo %d\r\n", pkt_buf_len);
dudmuck 2:fdae76e1215e 187 write_fifo(pkt_buf_len);
dudmuck 2:fdae76e1215e 188 //remaining_ = 0; // all was sent
dudmuck 2:fdae76e1215e 189 }
dudmuck 2:fdae76e1215e 190 } else { // fixed-length pkt format...
dudmuck 2:fdae76e1215e 191 pkt_buf_len = RegPktConfig2.bits.PayloadLength;
dudmuck 2:fdae76e1215e 192 if (RegPktConfig2.bits.PayloadLength > maxlen) {
dudmuck 2:fdae76e1215e 193 /*setup_FifoLevel(FALLING_EDGE);
dudmuck 2:fdae76e1215e 194 radio_write_fifo_(pkt_buf, maxlen, -1);
dudmuck 2:fdae76e1215e 195 remaining_ = SX1272FSK->RegPktConfig2.bits.PayloadLength - maxlen;*/
dudmuck 2:fdae76e1215e 196 printf("todo: fsk large packet\r\n");
dudmuck 2:fdae76e1215e 197 } else {
dudmuck 2:fdae76e1215e 198 //setup_FifoLevel(NO_EDGE); // disable
dudmuck 2:fdae76e1215e 199 printf("fixed-write-fifo %d\r\n", RegPktConfig2.bits.PayloadLength);
dudmuck 2:fdae76e1215e 200 write_fifo(RegPktConfig2.bits.PayloadLength);
dudmuck 2:fdae76e1215e 201 }
dudmuck 2:fdae76e1215e 202 }
dudmuck 2:fdae76e1215e 203 } else
dudmuck 2:fdae76e1215e 204 printf("fifo not empty %02x\r\n", RegIrqFlags2.octet);
dudmuck 2:fdae76e1215e 205
dudmuck 2:fdae76e1215e 206 m_xcvr.set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 2:fdae76e1215e 207
dudmuck 2:fdae76e1215e 208 }
dudmuck 2:fdae76e1215e 209
dudmuck 2:fdae76e1215e 210
dudmuck 2:fdae76e1215e 211 void SX127x_fsk::start_rx()
dudmuck 2:fdae76e1215e 212 {
dudmuck 2:fdae76e1215e 213 if (m_xcvr.RegOpMode.bits.LongRangeMode)
dudmuck 2:fdae76e1215e 214 return;
dudmuck 2:fdae76e1215e 215
dudmuck 2:fdae76e1215e 216 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 217 // was already receiving, restart it
dudmuck 2:fdae76e1215e 218 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 219 wait(0.01);
dudmuck 2:fdae76e1215e 220 }
dudmuck 2:fdae76e1215e 221 m_xcvr.set_opmode(RF_OPMODE_RECEIVER);
dudmuck 2:fdae76e1215e 222 }
dudmuck 2:fdae76e1215e 223
dudmuck 2:fdae76e1215e 224 service_action_e SX127x_fsk::service()
dudmuck 2:fdae76e1215e 225 {
dudmuck 2:fdae76e1215e 226 int i;
dudmuck 2:fdae76e1215e 227
dudmuck 2:fdae76e1215e 228 if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
dudmuck 2:fdae76e1215e 229 if (m_xcvr.dio0) {
dudmuck 2:fdae76e1215e 230 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
dudmuck 2:fdae76e1215e 231 return SERVICE_TX_DONE;
dudmuck 2:fdae76e1215e 232 }
dudmuck 2:fdae76e1215e 233 } else if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
dudmuck 2:fdae76e1215e 234 uint8_t len;
dudmuck 2:fdae76e1215e 235 if (RegPktConfig1.bits.PacketFormatVariable) {
dudmuck 2:fdae76e1215e 236 len = m_xcvr.read_reg(REG_FIFO);
dudmuck 2:fdae76e1215e 237 } else {
dudmuck 2:fdae76e1215e 238 len = RegPktConfig2.bits.PayloadLength;
dudmuck 2:fdae76e1215e 239 }
dudmuck 2:fdae76e1215e 240
dudmuck 2:fdae76e1215e 241 m_xcvr.m_cs = 0;
dudmuck 2:fdae76e1215e 242 m_xcvr.m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 2:fdae76e1215e 243 for (i = 0; i < len; i++) {
dudmuck 2:fdae76e1215e 244 m_xcvr.rx_buf[i] = m_xcvr.m_spi.write(0);
dudmuck 2:fdae76e1215e 245 }
dudmuck 2:fdae76e1215e 246 m_xcvr.m_cs = 1;
dudmuck 2:fdae76e1215e 247 return SERVICE_READ_FIFO;
dudmuck 2:fdae76e1215e 248 }
dudmuck 2:fdae76e1215e 249
dudmuck 2:fdae76e1215e 250 return SERVICE_NONE;
dudmuck 2:fdae76e1215e 251 }