Driver library for SX1272/SX1276 transceivers

Dependents:   LORA_RX LORA_TX WindConcentrator hid_test ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx127x_fsk.cpp Source File

sx127x_fsk.cpp

00001 #include "sx127x_fsk.h"
00002 
00003 /* SX127x driver
00004  * Copyright (c) 2013 Semtech
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 SX127x_fsk::SX127x_fsk(SX127x& r) : m_xcvr(r)
00020 {
00021 }
00022 
00023 SX127x_fsk::~SX127x_fsk()
00024 {
00025 }
00026 
00027 void SX127x_fsk::write_fifo(uint8_t len)
00028 {
00029     int i;
00030     
00031     m_xcvr.m_cs = 0;
00032     m_xcvr.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
00033     
00034     if (!m_xcvr.RegOpMode.bits.LongRangeMode && RegPktConfig1.bits.PacketFormatVariable) {
00035         m_xcvr.m_spi.write(len);
00036     }
00037     
00038     for (i = 0; i < len; i++) {
00039         m_xcvr.m_spi.write(m_xcvr.tx_buf[i]);
00040     }
00041     m_xcvr.m_cs = 1;
00042 }
00043 
00044 void SX127x_fsk::enable(bool fast)
00045 {
00046     m_xcvr.set_opmode(RF_OPMODE_SLEEP);
00047     
00048     m_xcvr.RegOpMode.bits.LongRangeMode = 0;
00049     m_xcvr.write_reg(REG_OPMODE, m_xcvr.RegOpMode.octet);
00050     if (fast)
00051         return;
00052     
00053     RegPktConfig1.octet = m_xcvr.read_reg(REG_FSK_PACKETCONFIG1);
00054     RegPktConfig2.word = m_xcvr.read_u16(REG_FSK_PACKETCONFIG2);
00055     RegRxConfig.octet = m_xcvr.read_reg(REG_FSK_RXCONFIG);
00056     RegPreambleDetect.octet = m_xcvr.read_reg(REG_FSK_PREAMBLEDETECT);
00057     RegSyncConfig.octet = m_xcvr.read_reg(REG_FSK_SYNCCONFIG);
00058     RegFifoThreshold.octet = m_xcvr.read_reg(REG_FSK_FIFOTHRESH);
00059     RegAfcFei.octet = m_xcvr.read_reg(REG_FSK_AFCFEI);
00060     
00061     if (!RegFifoThreshold.bits.TxStartCondition) {
00062         RegFifoThreshold.bits.TxStartCondition = 1; // start TX on fifoEmpty==0
00063         m_xcvr.write_reg(REG_FSK_FIFOTHRESH, RegFifoThreshold.octet);
00064     }
00065     
00066     if (RegSyncConfig.bits.AutoRestartRxMode != 1) {
00067         RegSyncConfig.bits.AutoRestartRxMode = 1;
00068         m_xcvr.write_reg(REG_FSK_SYNCCONFIG, RegSyncConfig.octet);
00069     }
00070     
00071     RegPreambleDetect.bits.PreambleDetectorOn = 1;
00072     RegPreambleDetect.bits.PreambleDetectorSize = 1;
00073     RegPreambleDetect.bits.PreambleDetectorTol = 10;
00074     m_xcvr.write_reg(REG_FSK_PREAMBLEDETECT, RegPreambleDetect.octet);      
00075     
00076     m_xcvr.set_opmode(RF_OPMODE_STANDBY);     
00077 }
00078 
00079 void SX127x_fsk::init()
00080 {
00081     m_xcvr.set_opmode(RF_OPMODE_STANDBY);
00082     
00083     RegRxConfig.bits.RxTrigger = 6; // have RX restart (trigger) on preamble detection
00084     RegRxConfig.bits.AfcAutoOn = 1; // have AFC performed on RX restart (RX trigger)
00085     m_xcvr.write_reg(REG_FSK_RXCONFIG, RegRxConfig.octet);
00086     
00087     RegPreambleDetect.bits.PreambleDetectorOn = 1;  // enable preamble detector
00088     m_xcvr.write_reg(REG_FSK_PREAMBLEDETECT, RegPreambleDetect.octet);
00089     
00090     m_xcvr.write_reg(REG_FSK_SYNCVALUE1, 0x55);
00091     m_xcvr.write_reg(REG_FSK_SYNCVALUE2, 0x6f); 
00092     m_xcvr.write_reg(REG_FSK_SYNCVALUE3, 0x4e);
00093     RegSyncConfig.bits.SyncSize = 2;
00094     m_xcvr.write_reg(REG_FSK_SYNCCONFIG, RegSyncConfig.octet);
00095     
00096     // in case these were changed from default:
00097     set_bitrate(4800);
00098     set_tx_fdev_hz(5050);
00099     set_rx_dcc_bw_hz(10500, 0);    // rxbw
00100     set_rx_dcc_bw_hz(50000, 1);    // afcbw
00101 }
00102     
00103 uint32_t SX127x_fsk::get_bitrate()
00104 {
00105     uint16_t br = m_xcvr.read_u16(REG_FSK_BITRATEMSB);
00106 
00107     if (br == 0)
00108         return 0;
00109     else {
00110         uint32_t bps = XTAL_FREQ / br;
00111         bit_period_us = bps / 1000;
00112         return bps;
00113     }
00114 }
00115 
00116 void SX127x_fsk::set_bitrate(uint32_t bps)
00117 {
00118     uint16_t tmpBitrate = XTAL_FREQ / bps;
00119     bit_period_us = bps / 1000;
00120     //printf("tmpBitrate:%d = %d / %d\r\n", tmpBitrate, XTAL_FREQ, bps);
00121     m_xcvr.write_u16(REG_FSK_BITRATEMSB, tmpBitrate);
00122 }
00123 
00124 void SX127x_fsk::set_tx_fdev_hz(uint32_t hz)
00125 {
00126     float tmpFdev = hz / FREQ_STEP_HZ;
00127     uint16_t v;
00128     //printf("tmpFdev:%f = %d / %f\r\n", tmpFdev, hz, FREQ_STEP_HZ);
00129     v = (uint16_t)tmpFdev;
00130     m_xcvr.write_u16(REG_FSK_FDEVMSB, v);
00131 }
00132     
00133 uint32_t SX127x_fsk::get_tx_fdev_hz(void)
00134 {
00135     uint16_t fdev = m_xcvr.read_u16(REG_FSK_FDEVMSB);
00136     return fdev * FREQ_STEP_HZ;
00137 }
00138 
00139 uint32_t SX127x_fsk::ComputeRxBw( uint8_t mantisse, uint8_t exponent )
00140 {
00141     // rxBw
00142     if (m_xcvr.RegOpMode.bits.ModulationType == 0)
00143         return XTAL_FREQ / (mantisse * (1 << (exponent+2)));
00144     else
00145         return XTAL_FREQ / (mantisse * (1 << (exponent+3)));    
00146 }
00147 
00148 
00149 void SX127x_fsk::ComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
00150 {
00151     uint8_t tmpExp, tmpMant;
00152     double tmpRxBw;
00153     double rxBwMin = 10e6;
00154 
00155     for( tmpExp = 0; tmpExp < 8; tmpExp++ ) {
00156         for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) {
00157             tmpRxBw = ComputeRxBw(tmpMant, tmpExp);
00158             if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) {
00159                 rxBwMin = fabs( tmpRxBw - rxBwValue );
00160                 *mantisse = tmpMant;
00161                 *exponent = tmpExp;
00162             }
00163         }
00164     }
00165 }
00166 
00167 
00168 uint32_t SX127x_fsk::get_rx_bw_hz(uint8_t addr)
00169 {
00170     RegRxBw_t reg_bw;
00171     uint8_t mantissa;
00172     
00173     if (m_xcvr.RegOpMode.bits.LongRangeMode)
00174         return 0;
00175 
00176     reg_bw.octet = m_xcvr.read_reg(addr);
00177     switch (reg_bw.bits.Mantissa) {
00178         case 0: mantissa = 16; break;
00179         case 1: mantissa = 20; break;
00180         case 2: mantissa = 24; break;
00181         default: mantissa = 0; break;
00182     }
00183 
00184     if (addr == REG_FSK_RXBW)
00185         RegRxBw.octet = reg_bw.octet;
00186     else if (addr == REG_FSK_AFCBW)
00187         RegAfcBw.octet = reg_bw.octet;
00188 
00189     return ComputeRxBw(mantissa, reg_bw.bits.Exponent);    
00190 }
00191 
00192 
00193 void SX127x_fsk::set_rx_dcc_bw_hz(uint32_t bw_hz, char afc)
00194 {
00195     uint8_t mantisse = 0;
00196     uint8_t exponent = 0;
00197     
00198     if (m_xcvr.RegOpMode.bits.LongRangeMode)
00199         return;    
00200 
00201     ComputeRxBwMantExp( bw_hz, &mantisse, &exponent );
00202     //printf("bw_hz:%d, mantisse:%d, exponent:%d\n", bw_hz, mantisse, exponent );
00203     switch( mantisse ) {
00204         case 16:
00205             RegRxBw.bits.Mantissa = 0;
00206             break;
00207         case 20:
00208             RegRxBw.bits.Mantissa = 1;
00209             break;
00210         case 24:
00211             RegRxBw.bits.Mantissa = 2;
00212             break;
00213         default:
00214             // Something went terribely wrong
00215             printf("maintisse:%d\n", mantisse);
00216             break;
00217     }
00218     RegRxBw.bits.Exponent = exponent;
00219 
00220     if (afc)
00221         m_xcvr.write_reg(REG_FSK_AFCBW, RegRxBw.octet);
00222     else
00223         m_xcvr.write_reg(REG_FSK_RXBW, RegRxBw.octet);
00224 }
00225 
00226 
00227 void SX127x_fsk::start_tx(uint16_t arg_len)
00228 {
00229     uint16_t pkt_buf_len;
00230     RegIrqFlags2_t RegIrqFlags2;
00231     int maxlen = FSK_FIFO_SIZE-1;
00232     
00233     if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
00234         m_xcvr.set_opmode(RF_OPMODE_STANDBY);
00235     }
00236 
00237     if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
00238         m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0;
00239         m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
00240     }
00241 
00242     RegPktConfig1.octet = m_xcvr.read_reg(REG_FSK_PACKETCONFIG1);
00243     if (RegPktConfig1.bits.PacketFormatVariable) {
00244         pkt_buf_len = arg_len;
00245     } else {
00246         pkt_buf_len = RegPktConfig2.bits.PayloadLength;
00247     }
00248 
00249     RegIrqFlags2.octet = m_xcvr.read_reg(REG_FSK_IRQFLAGS2);
00250     if (RegIrqFlags2.bits.FifoEmpty) {
00251         if (RegPktConfig1.bits.PacketFormatVariable) {
00252             --maxlen;   // space for length byte
00253             if (pkt_buf_len > maxlen) {
00254                 /*setup_FifoLevel(FALLING_EDGE);
00255                 radio_write_fifo_(pkt_buf, maxlen, pkt_buf_len);
00256                 remaining_ = pkt_buf_len - maxlen;
00257                 printf("var-oversized %d R=%d\r\n", pkt_buf_len, remaining_);*/
00258                 printf("var-oversized %d\r\n", pkt_buf_len);
00259             } else {
00260                 //setup_FifoLevel(NO_EDGE); // disable 
00261                 write_fifo(pkt_buf_len);
00262                 //remaining_ = 0; // all was sent
00263             }
00264         } else { // fixed-length pkt format...
00265             pkt_buf_len = RegPktConfig2.bits.PayloadLength;
00266             if (RegPktConfig2.bits.PayloadLength > maxlen) {
00267                 /*setup_FifoLevel(FALLING_EDGE);
00268                 radio_write_fifo_(pkt_buf, maxlen, -1);
00269                 remaining_ = SX1272FSK->RegPktConfig2.bits.PayloadLength - maxlen;*/
00270                 printf("todo: fsk large packet\r\n");
00271             } else {
00272                 //setup_FifoLevel(NO_EDGE); // disable
00273                 write_fifo(RegPktConfig2.bits.PayloadLength);
00274             }
00275         }
00276     } else
00277         printf("fifo not empty %02x\r\n", RegIrqFlags2.octet);
00278 
00279     m_xcvr.set_opmode(RF_OPMODE_TRANSMITTER);
00280     
00281 }
00282 
00283 void SX127x_fsk::config_dio0_for_pktmode_rx()
00284 {
00285     if (RegPktConfig2.bits.DataModePacket) {
00286         if (RegPktConfig1.bits.CrcOn) {
00287             if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 1) {
00288                 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 1; // to CrcOk
00289                 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
00290             }
00291         } else { // Crc Off, use PayloadReady
00292             if (m_xcvr.RegDioMapping1.bits.Dio0Mapping != 0) {
00293                 m_xcvr.RegDioMapping1.bits.Dio0Mapping = 0; // to PayloadReady
00294                 m_xcvr.write_reg(REG_DIOMAPPING1, m_xcvr.RegDioMapping1.octet);
00295             }
00296         }
00297     }
00298 }
00299 
00300 void SX127x_fsk::start_rx()
00301 {
00302     if (m_xcvr.RegOpMode.bits.LongRangeMode)
00303         return;
00304         
00305     if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
00306         // was already receiving, restart it
00307         m_xcvr.set_opmode(RF_OPMODE_STANDBY);
00308 #if (MBED_MAJOR_VERSION < 6)
00309         ThisThread::sleep_for(10);
00310 #else
00311         ThisThread::sleep_for(10ms);
00312 #endif
00313     }
00314     
00315     config_dio0_for_pktmode_rx();
00316     
00317     m_xcvr.set_opmode(RF_OPMODE_RECEIVER);        
00318 }
00319 
00320 uint8_t SX127x_fsk::get_modulation_shaping()
00321 {
00322     if (m_xcvr.type == SX1276) {
00323         RegPaRamp_t reg_paramp;
00324         reg_paramp.octet = m_xcvr.read_reg(REG_PARAMP);
00325         return reg_paramp.bits.ModulationShaping;
00326     } else if (m_xcvr.type == SX1272) {
00327         m_xcvr.RegOpMode.octet = m_xcvr.read_reg(REG_OPMODE);
00328         return m_xcvr.RegOpMode.bits.ModulationShaping;
00329     } else
00330         return 0xff;
00331 }
00332 
00333 void SX127x_fsk::set_modulation_shaping(uint8_t s)
00334 {
00335     if (m_xcvr.type == SX1276) {
00336         RegPaRamp_t reg_paramp;
00337         reg_paramp.octet = m_xcvr.read_reg(REG_PARAMP);
00338         reg_paramp.bits.ModulationShaping = s;
00339         m_xcvr.write_reg(REG_PARAMP, reg_paramp.octet);
00340     } else if (m_xcvr.type == SX1272) {
00341         m_xcvr.RegOpMode.octet = m_xcvr.read_reg(REG_OPMODE);
00342         m_xcvr.RegOpMode.bits.ModulationShaping = s;
00343         m_xcvr.write_reg(REG_OPMODE, m_xcvr.RegOpMode.octet);
00344     } 
00345 }
00346 
00347 service_action_e SX127x_fsk::service()
00348 {
00349     int i;
00350     
00351     if (m_xcvr.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) {
00352         if (m_xcvr.dio0) {
00353             /* packetSent comes at start of last bit, wait for one bit period */
00354             wait_us(bit_period_us);
00355             if (tx_done_sleep)
00356                 m_xcvr.set_opmode(RF_OPMODE_SLEEP);
00357             else
00358                 m_xcvr.set_opmode(RF_OPMODE_STANDBY);
00359             return SERVICE_TX_DONE;
00360         }
00361     } else if (RegPktConfig2.bits.DataModePacket && m_xcvr.dio0) {
00362         if (RegRxConfig.bits.AfcAutoOn)
00363             RegAfcValue = m_xcvr.read_s16(REG_FSK_AFCMSB);
00364             
00365         if (RegPktConfig1.bits.PacketFormatVariable) {
00366             rx_buf_length = m_xcvr.read_reg(REG_FIFO);
00367         } else {
00368             rx_buf_length = RegPktConfig2.bits.PayloadLength;
00369         }
00370         
00371         m_xcvr.m_cs = 0;
00372         m_xcvr.m_spi.write(REG_FIFO); // bit7 is low for reading from radio
00373         for (i = 0; i < rx_buf_length; i++) {
00374             m_xcvr.rx_buf[i] = m_xcvr.m_spi.write(0);
00375         }
00376         m_xcvr.m_cs = 1;
00377         return SERVICE_READ_FIFO;
00378     }
00379     
00380     return SERVICE_NONE;    
00381 }