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.
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 _antSwitchPwr = NULL; 00041 _antSwitch = NULL; 00042 _antSwitchTX = NULL; 00043 _antSwitchTXBoost = NULL; 00044 00045 _tcxo = NULL; 00046 if (tcxo != NC) 00047 _tcxo = new DigitalOut(tcxo); 00048 00049 switch(boardConnected) { 00050 case SX1276MB1MAS: 00051 case SX1276MB1LAS: 00052 _antSwitch = new DigitalOut(antSwitch); 00053 break; 00054 case RFM95_SX1276: 00055 break; 00056 case HELTEC_L4_1276: 00057 _antSwitchPwr = new DigitalOut(antSwitch); 00058 break; 00059 case MURATA_SX1276: 00060 _antSwitch = new DigitalOut(antSwitch); 00061 _antSwitchTX = new DigitalOut(antSwitchTX); 00062 _antSwitchTXBoost = new DigitalOut(antSwitchTXBoost); 00063 break; 00064 default: 00065 break; 00066 } 00067 _spi = new XSPI(mosi, miso, sclk ); 00068 _nss = new DigitalOut(nss); 00069 00070 _reset = new DigitalInOut(reset); 00071 00072 _dio0 = NULL; 00073 _dio1 = NULL; 00074 _dio2 = NULL; 00075 _dio3 = NULL; 00076 _dio4 = NULL; 00077 _dio5 = NULL; 00078 if (dio0 != NC) 00079 _dio0 = new InterruptIn(dio0); 00080 if (dio1 != NC) 00081 _dio1 = new InterruptIn(dio1); 00082 if (dio2 != NC) 00083 _dio2 = new InterruptIn(dio2); 00084 if (dio3 != NC) 00085 _dio3 = new InterruptIn(dio3); 00086 if (dio4 != NC) 00087 _dio4 = new InterruptIn(dio4); 00088 if (dio5 != NC) 00089 _dio5 = new DigitalIn(dio5); 00090 00091 Reset( ); 00092 00093 IoInit( ); 00094 00095 RxChainCalibration( ); 00096 00097 SetOpMode( RF_OPMODE_SLEEP ); 00098 00099 IoIrqInit( dioIrq ); 00100 00101 RadioRegistersInit( ); 00102 00103 SetModem( MODEM_FSK ); 00104 } 00105 00106 SX1276Generic::~SX1276Generic() 00107 { 00108 txTimeoutTimer .detach(); 00109 rxTimeoutTimer.detach(); 00110 rxTimeoutSyncWord.detach(); 00111 00112 if (_antSwitchPwr ) 00113 delete(_antSwitchPwr ); 00114 if (_antSwitch) 00115 delete _antSwitch; 00116 if (_antSwitchTX) 00117 delete _antSwitchTX; 00118 if (_antSwitchTXBoost) 00119 delete _antSwitchTXBoost; 00120 00121 if (_tcxo ) { 00122 *_tcxo = 0; 00123 delete (_tcxo ); 00124 } 00125 /* 00126 * Reset(); // to put chip back into fresh state 00127 * We disabled the Reset() to allow the destructor to keep the 00128 * chip in Sleep() mode to stay turned off with little energy 00129 * consumption. 00130 */ 00131 delete _reset ; 00132 delete _spi ; 00133 delete _nss; 00134 00135 if (_dio0 ) 00136 delete _dio0 ; 00137 if (_dio1) 00138 delete _dio1; 00139 if (_dio2) 00140 delete _dio2; 00141 if (_dio3) 00142 delete _dio3; 00143 if (_dio4) 00144 delete _dio4; 00145 if (_dio5) 00146 delete _dio5; 00147 } 00148 00149 00150 //------------------------------------------------------------------------- 00151 // Board relative functions 00152 //------------------------------------------------------------------------- 00153 uint8_t SX1276Generic::DetectBoardType( void ) 00154 { 00155 return boardConnected; 00156 } 00157 00158 void SX1276Generic::IoInit( void ) 00159 { 00160 if (_tcxo ) 00161 *_tcxo = 1; 00162 AntSwInit( ); 00163 SpiInit( ); 00164 } 00165 00166 00167 void SX1276Generic::SpiInit( void ) 00168 { 00169 *_nss = 1; 00170 _spi ->format( 8,0 ); 00171 uint32_t frequencyToSet = 8000000; 00172 #ifdef TARGET_KL25Z //busclock frequency is halved -> double the spi frequency to compensate 00173 _spi ->frequency( frequencyToSet * 2 ); 00174 #else 00175 _spi ->frequency( frequencyToSet ); 00176 #endif 00177 wait_ms(100); 00178 } 00179 00180 void SX1276Generic::IoIrqInit( DioIrqHandler *irqHandlers ) 00181 { 00182 if (_dio0 ) 00183 _dio0 ->rise(callback(this, static_cast< Trigger > ( irqHandlers[0] ))); 00184 else 00185 irqHandlers[0] = NULL; 00186 00187 if (_dio1) 00188 _dio1->rise(callback(this, static_cast< Trigger > ( irqHandlers[1] ))); 00189 else 00190 irqHandlers[1] = NULL; 00191 00192 if (_dio2) 00193 _dio2->rise(callback(this, static_cast< Trigger > ( irqHandlers[2] ))); 00194 else 00195 irqHandlers[2] = NULL; 00196 00197 if (_dio3) 00198 _dio3->rise(callback(this, static_cast< Trigger > ( irqHandlers[3] ))); 00199 else 00200 irqHandlers[3] = NULL; 00201 00202 if (_dio4) 00203 _dio4->rise(callback(this, static_cast< Trigger > ( irqHandlers[4] ))); 00204 else 00205 irqHandlers[4] = NULL; 00206 } 00207 00208 void SX1276Generic::IoDeInit( void ) 00209 { 00210 //nothing 00211 } 00212 00213 void SX1276Generic::SetRfTxPower( int8_t power ) 00214 { 00215 uint8_t paConfig = 0; 00216 uint8_t paDac = 0; 00217 00218 paConfig = Read( REG_PACONFIG ); 00219 paDac = Read( REG_PADAC ); 00220 00221 paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel ); 00222 paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; 00223 00224 if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) 00225 { 00226 if( power > 17 ) 00227 { 00228 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON; 00229 } 00230 else 00231 { 00232 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF; 00233 } 00234 if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON ) 00235 { 00236 if( power < 5 ) 00237 { 00238 power = 5; 00239 } 00240 if( power > 20 ) 00241 { 00242 power = 20; 00243 } 00244 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); 00245 } 00246 else 00247 { 00248 if( power < 2 ) 00249 { 00250 power = 2; 00251 } 00252 if( power > 17 ) 00253 { 00254 power = 17; 00255 } 00256 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); 00257 } 00258 } 00259 else 00260 { 00261 if( power < -1 ) 00262 { 00263 power = -1; 00264 } 00265 if( power > 14 ) 00266 { 00267 power = 14; 00268 } 00269 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); 00270 } 00271 Write( REG_PACONFIG, paConfig ); 00272 Write( REG_PADAC, paDac ); 00273 } 00274 00275 00276 uint8_t SX1276Generic::GetPaSelect( uint32_t channel ) 00277 { 00278 return RF_PACONFIG_PASELECT_PABOOST; 00279 if( channel > RF_MID_BAND_THRESH ) 00280 { 00281 if (boardConnected == SX1276MB1LAS || boardConnected == RFM95_SX1276 || boardConnected == MURATA_SX1276 || boardConnected == HELTEC_L4_1276) 00282 { 00283 return RF_PACONFIG_PASELECT_PABOOST; 00284 } 00285 else 00286 { 00287 return RF_PACONFIG_PASELECT_RFO; 00288 } 00289 } 00290 else 00291 { 00292 return RF_PACONFIG_PASELECT_RFO; 00293 } 00294 } 00295 00296 void SX1276Generic::SetAntSwLowPower( bool status ) 00297 { 00298 if( isRadioActive != status ) 00299 { 00300 isRadioActive = status; 00301 00302 if( status == false ) 00303 { 00304 AntSwInit( ); 00305 } 00306 else 00307 { 00308 AntSwDeInit( ); 00309 } 00310 } 00311 } 00312 00313 void SX1276Generic::AntSwInit( void ) 00314 { 00315 if (_antSwitch) 00316 *_antSwitch = 0; 00317 if (boardConnected == MURATA_SX1276) { 00318 *_antSwitchTX = 0; 00319 *_antSwitchTXBoost = 0; 00320 } 00321 if (boardConnected == HELTEC_L4_1276) 00322 *_antSwitchPwr = PWR_OFF; 00323 } 00324 00325 void SX1276Generic::AntSwDeInit( void ) 00326 { 00327 if (_antSwitch) 00328 *_antSwitch = 0; 00329 if (boardConnected == MURATA_SX1276) { 00330 *_antSwitchTX = 0; 00331 *_antSwitchTXBoost = 0; 00332 } 00333 if (boardConnected == HELTEC_L4_1276) 00334 *_antSwitchPwr = PWR_OFF; 00335 } 00336 00337 00338 void SX1276Generic::SetAntSw( uint8_t opMode ) 00339 { 00340 switch( opMode ) 00341 { 00342 case RFLR_OPMODE_TRANSMITTER: 00343 if (boardConnected == MURATA_SX1276) { 00344 *_antSwitch = 0;// Murata-RX 00345 if (Read( REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) 00346 *_antSwitchTXBoost = 1; 00347 else 00348 *_antSwitchTX = 1; // alternate: antSwitchTXBoost = 1 00349 } else { 00350 if (_antSwitch) 00351 *_antSwitch = 1; 00352 } 00353 if (boardConnected == HELTEC_L4_1276) 00354 *_antSwitchPwr = PWR_ON; 00355 break; 00356 case RFLR_OPMODE_RECEIVER: 00357 case RFLR_OPMODE_RECEIVER_SINGLE: 00358 case RFLR_OPMODE_CAD: 00359 if (boardConnected == MURATA_SX1276) { 00360 *_antSwitch = 1; // Murata-RX 00361 *_antSwitchTX = 0; 00362 *_antSwitchTXBoost = 0; 00363 } else if (boardConnected == HELTEC_L4_1276) { 00364 *_antSwitchPwr = PWR_ON; 00365 } else { 00366 if (_antSwitch) 00367 _antSwitch = 0; 00368 } 00369 break; 00370 case RFLR_OPMODE_SLEEP: 00371 case RFLR_OPMODE_STANDBY: 00372 default: 00373 if (boardConnected == MURATA_SX1276) { 00374 *_antSwitch = 0; //Murata-RX 00375 *_antSwitchTX = 0; 00376 *_antSwitchTXBoost = 0; 00377 } else if (boardConnected == HELTEC_L4_1276) { 00378 *_antSwitchPwr = PWR_OFF; 00379 } else { 00380 if (_antSwitch) 00381 *_antSwitch = 0; 00382 } 00383 break; 00384 } 00385 } 00386 00387 void SX1276Generic::SetTimeout(TimeoutTimer_t timer, timeoutFuncPtr func, int timeout_ms) 00388 { 00389 switch(timer) { 00390 case RXTimeoutTimer: 00391 if (func) 00392 rxTimeoutTimer.attach_us(callback(this, func), timeout_ms); 00393 else 00394 rxTimeoutTimer.detach(); 00395 break; 00396 case TXTimeoutTimer: 00397 if (func) 00398 txTimeoutTimer .attach_us(callback(this, func), timeout_ms); 00399 else 00400 txTimeoutTimer .detach(); 00401 break; 00402 case RXTimeoutSyncWordTimer: 00403 if (func) 00404 rxTimeoutSyncWord.attach_us(callback(this, func), timeout_ms); 00405 else 00406 rxTimeoutSyncWord.detach(); 00407 break; 00408 } 00409 } 00410 00411 void 00412 SX1276Generic::Sleep_ms(int ms) 00413 { 00414 wait_ms(ms); 00415 } 00416 00417 bool SX1276Generic::CheckRfFrequency( uint32_t frequency ) 00418 { 00419 if (frequency > 1200000) 00420 return false; 00421 // Implement check. Currently all frequencies are supported 00422 return true; 00423 } 00424 00425 void SX1276Generic::Reset( void ) 00426 { 00427 _reset ->output(); 00428 *_reset = 0; 00429 wait_ms( 1 ); 00430 *_reset = 1; 00431 _reset ->input(); // I don't know why input again, maybe to save power (Helmut T) 00432 wait_ms( 6 ); 00433 } 00434 00435 void SX1276Generic::Write( uint8_t addr, uint8_t data ) 00436 { 00437 Write( addr, &data, 1 ); 00438 } 00439 00440 uint8_t SX1276Generic::Read( uint8_t addr ) 00441 { 00442 uint8_t data; 00443 Read( addr, &data, 1 ); 00444 return data; 00445 } 00446 00447 void SX1276Generic::Write( uint8_t addr, void *buffer, uint8_t size ) 00448 { 00449 uint8_t i; 00450 uint8_t *p = (uint8_t *)buffer; 00451 00452 *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut 00453 _spi ->write( addr | 0x80 ); 00454 for( i = 0; i < size; i++ ) 00455 { 00456 _spi ->write(*p++); 00457 } 00458 *_nss = 1; 00459 } 00460 00461 void SX1276Generic::Read( uint8_t addr, void *buffer, uint8_t size ) 00462 { 00463 uint8_t i; 00464 uint8_t *p = (uint8_t *)buffer; 00465 00466 *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut 00467 _spi ->write( addr & 0x7F ); 00468 for( i = 0; i < size; i++ ) 00469 { 00470 *p++ = _spi ->write( 0 ); 00471 } 00472 *_nss = 1; 00473 } 00474 00475 void SX1276Generic::WriteFifo( void *buffer, uint8_t size ) 00476 { 00477 Write( 0, buffer, size ); 00478 } 00479 00480 void SX1276Generic::ReadFifo( void *buffer, uint8_t size ) 00481 { 00482 Read( 0, buffer, size ); 00483 }
Generated on Mon Jul 18 2022 22:00:11 by
1.7.2