Ivano Calabrese / ST-DEVKIT-LRWAN

Dependents:   DISCO-L072CZ-LRWAN1-base

Fork of SX1276GenericLib by Helmut Tschemernjak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx1276-mbed-hal.cpp Source File

sx1276-mbed-hal.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C) 2014 Semtech
00008 
00009 Description: -
00010 
00011 License: Revised BSD License, see LICENSE.TXT file include in the project
00012 
00013 Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
00014 */
00015 
00016 /*
00017  * additional development to make it more generic across multiple OS versions
00018  * (c) 2017 Helmut Tschemernjak
00019  * 30826 Garbsen (Hannover) Germany
00020  */
00021 
00022 #ifdef ARDUINO
00023  #include "arduino-mbed.h"
00024 #endif
00025 
00026 #include "sx1276-mbed-hal.h"
00027 
00028 
00029 
00030 SX1276Generic::SX1276Generic( RadioEvents_t *events, BoardType_t board,
00031                             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
00032                             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
00033                             PinName antSwitch, PinName antSwitchTX, PinName antSwitchTXBoost, PinName tcxo)
00034                             : SX1276 ( events)
00035 {
00036     Sleep_ms( 10 );
00037     this->RadioEvents = events;
00038     boardConnected = board;
00039     
00040     _antSwitch = NULL;
00041     _antSwitchTX = NULL;
00042     _antSwitchTXBoost = NULL;
00043     
00044     _tcxo = NULL;
00045     if (tcxo != NC)
00046         _tcxo = new DigitalOut(tcxo);
00047     
00048     switch(boardConnected) {
00049         case SX1276MB1MAS:
00050         case SX1276MB1LAS:
00051             _antSwitch = new DigitalOut(antSwitch);
00052             break;
00053         case RFM95_SX1276:
00054             break;
00055         case MURATA_SX1276:
00056             _antSwitch = new DigitalOut(antSwitch);
00057             _antSwitchTX = new DigitalOut(antSwitchTX);
00058             _antSwitchTXBoost = new DigitalOut(antSwitchTXBoost);
00059             break;
00060         default:
00061             break;
00062     }
00063     _spi = new XSPI(mosi, miso, sclk );
00064     _nss = new DigitalOut(nss);
00065     
00066     _reset = new DigitalInOut(reset);
00067     
00068     _dio0 = NULL;
00069     _dio1 = NULL;
00070     _dio2 = NULL;
00071     _dio3 = NULL;
00072     _dio4 = NULL;
00073     _dio5 = NULL;
00074     if (dio0 != NC)
00075         _dio0 = new InterruptIn(dio0);
00076     if (dio1 != NC)
00077         _dio1 = new InterruptIn(dio1);
00078     if (dio2 != NC)
00079         _dio2 = new InterruptIn(dio2);
00080     if (dio3 != NC)
00081         _dio3 = new InterruptIn(dio3);
00082     if (dio4 != NC)
00083         _dio4 = new InterruptIn(dio4);
00084     if (dio5 != NC)
00085         _dio5 = new DigitalIn(dio5);
00086    
00087     Reset( );
00088 
00089     IoInit( );
00090 
00091     RxChainCalibration( );
00092  
00093     SetOpMode( RF_OPMODE_SLEEP );
00094 
00095     IoIrqInit( dioIrq );
00096 
00097     RadioRegistersInit( );
00098 
00099     SetModem( MODEM_FSK );
00100 }
00101 
00102 SX1276Generic::~SX1276Generic()
00103 {
00104     txTimeoutTimer .detach();
00105     rxTimeoutTimer.detach();
00106     rxTimeoutSyncWord.detach();
00107     
00108     if (_antSwitch )
00109         delete _antSwitch ;
00110     if (_antSwitchTX)
00111         delete _antSwitchTX;
00112     if (_antSwitchTXBoost)
00113         delete _antSwitchTXBoost;
00114     
00115     if (_tcxo ) {
00116         *_tcxo  = 0;
00117         delete (_tcxo );
00118     }
00119     Reset(); // to put chip back into fresh state
00120     delete _reset ;
00121     delete _spi ;
00122     delete _nss;
00123     
00124     if (_dio0 )
00125         delete _dio0 ;
00126     if (_dio1)
00127         delete _dio1;
00128     if (_dio2)
00129         delete _dio2;
00130     if (_dio3)
00131         delete _dio3;
00132     if (_dio4)
00133         delete _dio4;
00134     if (_dio5)
00135         delete _dio5;
00136 }
00137 
00138 
00139 //-------------------------------------------------------------------------
00140 //                      Board relative functions
00141 //-------------------------------------------------------------------------
00142 uint8_t SX1276Generic::DetectBoardType( void )
00143 {
00144     return boardConnected;
00145 }
00146 
00147 void SX1276Generic::IoInit( void )
00148 {
00149     if (_tcxo )
00150         *_tcxo  = 1;
00151     AntSwInit( );
00152     SpiInit( );
00153 }
00154 
00155 
00156 void SX1276Generic::SpiInit( void )
00157 {
00158     *_nss = 1;
00159     _spi ->format( 8,0 );
00160     uint32_t frequencyToSet = 8000000;
00161 #ifdef TARGET_KL25Z //busclock frequency is halved -> double the spi frequency to compensate
00162     _spi ->frequency( frequencyToSet * 2 );
00163 #else
00164     _spi ->frequency( frequencyToSet );
00165 #endif
00166     wait_ms(100);
00167 }
00168 
00169 void SX1276Generic::IoIrqInit( DioIrqHandler *irqHandlers )
00170 {
00171     if (_dio0 )
00172         _dio0 ->rise(callback(this, static_cast< Trigger > ( irqHandlers[0] )));
00173     if (_dio1)
00174         _dio1->rise(callback(this, static_cast< Trigger > ( irqHandlers[1] )));
00175     if (_dio2)
00176         _dio2->rise(callback(this, static_cast< Trigger > ( irqHandlers[2] )));
00177     if (_dio3)
00178         _dio3->rise(callback(this, static_cast< Trigger > ( irqHandlers[3] )));
00179     if (_dio4)
00180         _dio4->rise(callback(this, static_cast< Trigger > ( irqHandlers[4] )));
00181 }
00182 
00183 void SX1276Generic::IoDeInit( void )
00184 {
00185     //nothing
00186 }
00187 
00188 void SX1276Generic::SetRfTxPower( int8_t power )
00189 {
00190     uint8_t paConfig = 0;
00191     uint8_t paDac = 0;
00192     
00193     paConfig = Read( REG_PACONFIG );
00194     paDac = Read( REG_PADAC );
00195     
00196     paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel );
00197     paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
00198     
00199     if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
00200     {
00201         if( power > 17 )
00202         {
00203             paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
00204         }
00205         else
00206         {
00207             paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
00208         }
00209         if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
00210         {
00211             if( power < 5 )
00212             {
00213                 power = 5;
00214             }
00215             if( power > 20 )
00216             {
00217                 power = 20;
00218             }
00219             paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
00220         }
00221         else
00222         {
00223             if( power < 2 )
00224             {
00225                 power = 2;
00226             }
00227             if( power > 17 )
00228             {
00229                 power = 17;
00230             }
00231             paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
00232         }
00233     }
00234     else
00235     {
00236         if( power < -1 )
00237         {
00238             power = -1;
00239         }
00240         if( power > 14 )
00241         {
00242             power = 14;
00243         }
00244         paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
00245     }
00246     Write( REG_PACONFIG, paConfig );
00247     Write( REG_PADAC, paDac );
00248 }
00249 
00250 
00251 uint8_t SX1276Generic::GetPaSelect( uint32_t channel )
00252 {
00253     if( channel > RF_MID_BAND_THRESH )
00254     {
00255         if (boardConnected == SX1276MB1LAS || boardConnected == RFM95_SX1276 || boardConnected == MURATA_SX1276)
00256         {
00257             return RF_PACONFIG_PASELECT_PABOOST;
00258         }
00259         else
00260         {
00261             return RF_PACONFIG_PASELECT_RFO;
00262         }
00263     }
00264     else
00265     {
00266         return RF_PACONFIG_PASELECT_RFO;
00267     }
00268 }
00269 
00270 void SX1276Generic::SetAntSwLowPower( bool status )
00271 {
00272     if( isRadioActive != status )
00273     {
00274         isRadioActive = status;
00275     
00276         if( status == false )
00277         {
00278             AntSwInit( );
00279         }
00280         else
00281         {
00282             AntSwDeInit( );
00283         }
00284     }
00285 }
00286 
00287 void SX1276Generic::AntSwInit( void )
00288 {
00289     if (_antSwitch )
00290         *_antSwitch  = 0;
00291     if (boardConnected == MURATA_SX1276) {
00292         *_antSwitchTX = 0;
00293         *_antSwitchTXBoost = 0;
00294     }
00295 }
00296 
00297 void SX1276Generic::AntSwDeInit( void )
00298 {
00299     if (_antSwitch )
00300         *_antSwitch  = 0;
00301     if (boardConnected == MURATA_SX1276) {
00302         *_antSwitchTX = 0;
00303         *_antSwitchTXBoost = 0;
00304     }
00305 }
00306 
00307 
00308 void SX1276Generic::SetAntSw( uint8_t opMode )
00309 {
00310     switch( opMode )
00311     {
00312         case RFLR_OPMODE_TRANSMITTER:
00313             if (boardConnected == MURATA_SX1276) {
00314                 *_antSwitch  = 0;// Murata-RX
00315                 if (Read( REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST)
00316                     *_antSwitchTXBoost = 1;
00317                 else
00318                     *_antSwitchTX = 1;  // alternate: antSwitchTXBoost = 1
00319             } else {
00320                 if (_antSwitch )
00321                     *_antSwitch  = 1;
00322             }
00323             break;
00324         case RFLR_OPMODE_RECEIVER:
00325         case RFLR_OPMODE_RECEIVER_SINGLE:
00326         case RFLR_OPMODE_CAD:
00327             if (boardConnected == MURATA_SX1276) {
00328                 *_antSwitch  = 1;  // Murata-RX
00329                 *_antSwitchTX = 0;
00330                 *_antSwitchTXBoost = 0;
00331             } else {
00332                 if (_antSwitch )
00333                     _antSwitch  = 0;
00334             }
00335             break;
00336         case RFLR_OPMODE_SLEEP:
00337         case RFLR_OPMODE_STANDBY:
00338         default:
00339             if (boardConnected == MURATA_SX1276) {
00340                 *_antSwitch  = 0;  //Murata-RX
00341                 *_antSwitchTX = 0;
00342                 *_antSwitchTXBoost = 0;
00343             } else {
00344                 if (_antSwitch )
00345                     *_antSwitch  = 0;
00346             }
00347             break;
00348     }
00349 }
00350 
00351 void SX1276Generic::SetTimeout(TimeoutTimer_t timer, timeoutFuncPtr func, int timeout_ms)
00352 {
00353     switch(timer) {
00354         case RXTimeoutTimer:
00355             if (func)
00356                 rxTimeoutTimer.attach_us(callback(this, func), timeout_ms);
00357             else
00358                 rxTimeoutTimer.detach();
00359             break;
00360         case TXTimeoutTimer:
00361             if (func)
00362                 txTimeoutTimer .attach_us(callback(this, func), timeout_ms);
00363             else
00364                 txTimeoutTimer .detach();
00365             break;
00366         case RXTimeoutSyncWordTimer:
00367             if (func)
00368                 rxTimeoutSyncWord.attach_us(callback(this, func), timeout_ms);
00369             else
00370                 rxTimeoutSyncWord.detach();
00371             break;
00372     }
00373 }
00374 
00375 void
00376 SX1276Generic::Sleep_ms(int ms)
00377 {
00378     wait_ms(ms);
00379 }
00380 
00381 bool SX1276Generic::CheckRfFrequency( uint32_t frequency )
00382 {
00383     if (frequency > 1200000)
00384         return false;
00385     // Implement check. Currently all frequencies are supported
00386     return true;
00387 }
00388 
00389 void SX1276Generic::Reset( void )
00390 {
00391     _reset ->output();
00392     *_reset  = 0;
00393     wait_ms( 1 );
00394     *_reset  = 1;
00395     _reset ->input();    // I don't know my input again, maybe to save power (Helmut T)
00396     wait_ms( 6 );
00397 }
00398 
00399 void SX1276Generic::Write( uint8_t addr, uint8_t data )
00400 {
00401     Write( addr, &data, 1 );
00402 }
00403 
00404 uint8_t SX1276Generic::Read( uint8_t addr )
00405 {
00406     uint8_t data;
00407     Read( addr, &data, 1 );
00408     return data;
00409 }
00410 
00411 void SX1276Generic::Write( uint8_t addr, void *buffer, uint8_t size )
00412 {
00413     uint8_t i;
00414     uint8_t *p = (uint8_t *)buffer;
00415 
00416     *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut
00417     _spi ->write( addr | 0x80 );
00418     for( i = 0; i < size; i++ )
00419     {
00420         _spi ->write(*p++);
00421     }
00422     *_nss = 1;
00423 }
00424 
00425 void SX1276Generic::Read( uint8_t addr, void *buffer, uint8_t size )
00426 {
00427     uint8_t i;
00428     uint8_t *p = (uint8_t *)buffer;
00429     
00430     *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut
00431     _spi ->write( addr & 0x7F );
00432     for( i = 0; i < size; i++ )
00433     {
00434         *p++ = _spi ->write( 0 );
00435     }
00436     *_nss = 1;
00437 }
00438 
00439 void SX1276Generic::WriteFifo( void *buffer, uint8_t size )
00440 {
00441     Write( 0, buffer, size );
00442 }
00443 
00444 void SX1276Generic::ReadFifo( void *buffer, uint8_t size )
00445 {
00446     Read( 0, buffer, size );
00447 }