Ilya Krylov / SX127x1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx127x.cpp Source File

sx127x.cpp

00001 #include "sx12xx.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::SX127x(PinName dio_0, PinName dio_1, PinName cs, SPI& spi_r, PinName rst) :
00020                 dio0(dio_0), dio1(dio_1), m_cs(cs), m_spi(spi_r), reset_pin(rst)
00021 {
00022     reset_pin.input();
00023     m_cs = 1;
00024     m_spi.format(8, 0);
00025     m_spi.frequency(3000000);
00026     
00027     init();
00028 }
00029 
00030 SX127x::~SX127x()
00031 {
00032     set_opmode(RF_OPMODE_SLEEP);
00033 }
00034 
00035 void SX127x::init()
00036 {
00037     type = SX_NONE;
00038 
00039     RegOpMode.octet = read_reg(REG_OPMODE);
00040     RegPaConfig.octet = read_reg(REG_PACONFIG);
00041     RegDioMapping1.octet = read_reg(REG_DIOMAPPING1);
00042     RegDioMapping2.octet = read_reg(REG_DIOMAPPING2);
00043     
00044     get_type();
00045     
00046     if (type == SX1272) {
00047         // turn on PA BOOST, eval boards are wired for this connection
00048         RegPaConfig.bits.PaSelect = 1;
00049         write_reg(REG_PACONFIG, RegPaConfig.octet);
00050     }
00051     
00052     RegLna.octet = read_reg(REG_LNA);
00053     RegLna.bits.LnaBoostHF = 3;
00054     write_reg(REG_LNA, RegLna.octet);    
00055 }
00056 
00057 void SX127x::get_type()
00058 {
00059     RegOpMode.octet = read_reg(REG_OPMODE);
00060     
00061     /* SX1272 starts in FSK mode on powerup, RegOpMode bit3 will be set for BT1.0 in FSK */
00062     if (!RegOpMode.bits.LongRangeMode) {
00063         set_opmode(RF_OPMODE_SLEEP);
00064 #if (MBED_MAJOR_VERSION < 6)
00065         wait_us(10000);
00066 #else
00067         wait_us(10000);
00068 #endif
00069         RegOpMode.bits.LongRangeMode = 1;
00070         write_reg(REG_OPMODE, RegOpMode.octet);
00071 #if (MBED_MAJOR_VERSION < 6)
00072         wait_us(10000);
00073 #else
00074         wait_us(10000);
00075 #endif
00076         RegOpMode.octet = read_reg(REG_OPMODE);     
00077     }
00078 
00079     if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
00080         type = SX1276;
00081     else {
00082         RegOpMode.sx1276LORAbits.LowFrequencyModeOn = 1;
00083         write_reg(REG_OPMODE, RegOpMode.octet);
00084         RegOpMode.octet = read_reg(REG_OPMODE);
00085         if (RegOpMode.sx1276LORAbits.LowFrequencyModeOn)
00086             type = SX1276;
00087         else
00088             type = SX1272;
00089     }
00090 }
00091 
00092 void
00093 SX127x::ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
00094 {
00095     uint8_t i;
00096     
00097     m_cs = 0;
00098     
00099     m_spi.write(addr); // bit7 is low for reading from radio
00100 
00101     for( i = 0; i < size; i++ )
00102     {
00103         buffer[i] = m_spi.write(0x00);
00104     }
00105     
00106     m_cs = 1;
00107 }
00108 
00109 uint8_t SX127x::read_reg(uint8_t addr)
00110 {
00111     uint8_t ret;
00112     // Select the device by seting chip select low
00113     m_cs = 0;
00114 
00115     m_spi.write(addr); // bit7 is low for reading from radio
00116  
00117     // Send a dummy byte to receive the contents of register
00118     ret = m_spi.write(0x00);
00119  
00120     // Deselect the device
00121     m_cs = 1;
00122     
00123     return ret;
00124 }
00125 
00126 int16_t SX127x::read_s16(uint8_t addr)
00127 {
00128     int16_t ret;
00129     // Select the device by seting chip select low
00130     m_cs = 0;
00131 
00132     m_spi.write(addr); // bit7 is low for reading from radio
00133  
00134     // Send a dummy byte to receive the contents of register
00135     ret = m_spi.write(0x00);
00136     ret <<= 8;
00137     ret += m_spi.write(0x00);
00138  
00139     // Deselect the device
00140     m_cs = 1;
00141     
00142     return ret;
00143 }
00144 
00145 uint16_t SX127x::read_u16(uint8_t addr)
00146 {
00147     uint16_t ret;
00148     // Select the device by seting chip select low
00149     m_cs = 0;
00150 
00151     m_spi.write(addr); // bit7 is low for reading from radio
00152  
00153     // Send a dummy byte to receive the contents of register
00154     ret = m_spi.write(0x00);
00155     ret <<= 8;
00156     ret += m_spi.write(0x00);
00157  
00158     // Deselect the device
00159     m_cs = 1;
00160     
00161     return ret;
00162 }
00163 
00164 void SX127x::write_u16(uint8_t addr, uint16_t data)
00165 {
00166     m_cs = 0;   // Select the device by seting chip select low
00167 
00168     m_spi.write(addr | 0x80); // bit7 is high for writing to radio
00169     m_spi.write((data >> 8) & 0xff);
00170     m_spi.write(data & 0xff);
00171  
00172     m_cs = 1;   // Deselect the device
00173 }
00174 
00175 void SX127x::write_u24(uint8_t addr, uint32_t data)
00176 {
00177     m_cs = 0;   // Select the device by seting chip select low
00178 
00179     m_spi.write(addr | 0x80); // bit7 is high for writing to radio
00180     m_spi.write((data >> 16) & 0xff);
00181     m_spi.write((data >> 8) & 0xff);
00182     m_spi.write(data & 0xff);
00183  
00184     m_cs = 1;   // Deselect the device
00185     
00186     if (addr == REG_FRFMSB) {
00187         if (data < 0x8340000)   // < 525MHz
00188             HF = false;
00189         else
00190             HF = true;
00191     }
00192 }
00193 
00194 void SX127x::write_reg(uint8_t addr, uint8_t data)
00195 {
00196     m_cs = 0;   // Select the device by seting chip select low
00197 
00198     m_spi.write(addr | 0x80); // bit7 is high for writing to radio
00199     m_spi.write(data);
00200  
00201     m_cs = 1;   // Deselect the device
00202 }
00203 
00204 void SX127x::WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
00205 {
00206     uint8_t i;
00207 
00208     m_cs = 0;   // Select the device by seting chip select low
00209 
00210     m_spi.write(addr | 0x80); // bit7 is high for writing to radio
00211     for( i = 0; i < size; i++ )
00212     {
00213         m_spi.write(buffer[i]);
00214     }
00215 
00216     m_cs = 1;   // Deselect the device
00217 }
00218 
00219 void SX127x::set_opmode(chip_mode_e mode)
00220 {
00221     RegOpMode.bits.Mode = mode;
00222     
00223     // callback to control antenna switch and PaSelect (PABOOST/RFO) for TX
00224     if (rf_switch )
00225         rf_switch .call();
00226     
00227     write_reg(REG_OPMODE, RegOpMode.octet);
00228 }
00229 
00230 void SX127x::set_frf_MHz( float MHz )
00231 {
00232     uint32_t frf;
00233     
00234     frf = MHz / (float)FREQ_STEP_MHZ;
00235     write_u24(REG_FRFMSB, frf);
00236     
00237     if (MHz < 525)
00238         HF = false;
00239     else
00240         HF = true;
00241 }
00242 
00243 float SX127x::get_frf_MHz(void)
00244 {
00245     uint32_t frf;
00246     uint8_t lsb, mid, msb;
00247     float MHz;
00248     
00249     msb = read_reg(REG_FRFMSB);
00250     mid = read_reg(REG_FRFMID);
00251     lsb = read_reg(REG_FRFLSB);
00252     frf = msb;
00253     frf <<= 8;
00254     frf += mid;
00255     frf <<= 8;
00256     frf += lsb;
00257     
00258     MHz = frf * FREQ_STEP_MHZ;
00259     
00260     if (MHz < 525)
00261         HF = false;
00262     else
00263         HF = true;
00264         
00265     return MHz;
00266 }
00267 
00268 void SX127x::hw_reset()
00269 {
00270     int in = reset_pin.read();
00271     reset_pin.output();
00272     reset_pin.write(1);
00273 #if (MBED_MAJOR_VERSION < 6)
00274     wait_us(10000);
00275     if (in == 1) { /* pin is pulled up somewhere? */
00276         reset_pin.write(0);
00277         wait_us(10000);
00278     }
00279     reset_pin.input();
00280     wait_us(5000);
00281 #else
00282     wait_us(50000);
00283     if (in == 1) { /* pin is pulled up somewhere? */
00284         reset_pin.write(0);
00285         wait_us(5000);
00286     }
00287     reset_pin.input();
00288     wait_us(5000);
00289 #endif
00290 }
00291