Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DISCO-L072CZ-LRWAN1-base
Fork of SX1276GenericLib by
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 }
Generated on Tue Jul 12 2022 21:48:25 by
 1.7.2
 1.7.2 
    