LoRa gateway to link to Raspberry - Working ok
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 _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 if( channel > RF_MID_BAND_THRESH ) 00279 { 00280 if (boardConnected == SX1276MB1LAS || boardConnected == RFM95_SX1276 || boardConnected == MURATA_SX1276 || boardConnected == HELTEC_L4_1276) 00281 { 00282 return RF_PACONFIG_PASELECT_PABOOST; 00283 } 00284 else 00285 { 00286 return RF_PACONFIG_PASELECT_RFO; 00287 } 00288 } 00289 else 00290 { 00291 return RF_PACONFIG_PASELECT_RFO; 00292 } 00293 } 00294 00295 void SX1276Generic::SetAntSwLowPower( bool status ) 00296 { 00297 if( isRadioActive != status ) 00298 { 00299 isRadioActive = status; 00300 00301 if( status == false ) 00302 { 00303 AntSwInit( ); 00304 } 00305 else 00306 { 00307 AntSwDeInit( ); 00308 } 00309 } 00310 } 00311 00312 void SX1276Generic::AntSwInit( void ) 00313 { 00314 if (_antSwitch) 00315 *_antSwitch = 0; 00316 if (boardConnected == MURATA_SX1276) { 00317 *_antSwitchTX = 0; 00318 *_antSwitchTXBoost = 0; 00319 } 00320 if (boardConnected == HELTEC_L4_1276) 00321 *_antSwitchPwr = PWR_OFF; 00322 } 00323 00324 void SX1276Generic::AntSwDeInit( void ) 00325 { 00326 if (_antSwitch) 00327 *_antSwitch = 0; 00328 if (boardConnected == MURATA_SX1276) { 00329 *_antSwitchTX = 0; 00330 *_antSwitchTXBoost = 0; 00331 } 00332 if (boardConnected == HELTEC_L4_1276) 00333 *_antSwitchPwr = PWR_OFF; 00334 } 00335 00336 00337 void SX1276Generic::SetAntSw( uint8_t opMode ) 00338 { 00339 switch( opMode ) 00340 { 00341 case RFLR_OPMODE_TRANSMITTER: 00342 if (boardConnected == MURATA_SX1276) { 00343 *_antSwitch = 0;// Murata-RX 00344 if (Read( REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) 00345 *_antSwitchTXBoost = 1; 00346 else 00347 *_antSwitchTX = 1; // alternate: antSwitchTXBoost = 1 00348 } else { 00349 if (_antSwitch) 00350 *_antSwitch = 1; 00351 } 00352 if (boardConnected == HELTEC_L4_1276) 00353 *_antSwitchPwr = PWR_ON; 00354 break; 00355 case RFLR_OPMODE_RECEIVER: 00356 case RFLR_OPMODE_RECEIVER_SINGLE: 00357 case RFLR_OPMODE_CAD: 00358 if (boardConnected == MURATA_SX1276) { 00359 *_antSwitch = 1; // Murata-RX 00360 *_antSwitchTX = 0; 00361 *_antSwitchTXBoost = 0; 00362 } else if (boardConnected == HELTEC_L4_1276) { 00363 *_antSwitchPwr = PWR_ON; 00364 } else { 00365 if (_antSwitch) 00366 _antSwitch = 0; 00367 } 00368 break; 00369 case RFLR_OPMODE_SLEEP: 00370 case RFLR_OPMODE_STANDBY: 00371 default: 00372 if (boardConnected == MURATA_SX1276) { 00373 *_antSwitch = 0; //Murata-RX 00374 *_antSwitchTX = 0; 00375 *_antSwitchTXBoost = 0; 00376 } else if (boardConnected == HELTEC_L4_1276) { 00377 *_antSwitchPwr = PWR_OFF; 00378 } else { 00379 if (_antSwitch) 00380 *_antSwitch = 0; 00381 } 00382 break; 00383 } 00384 } 00385 00386 void SX1276Generic::SetTimeout(TimeoutTimer_t timer, timeoutFuncPtr func, int timeout_ms) 00387 { 00388 switch(timer) { 00389 case RXTimeoutTimer: 00390 if (func) 00391 rxTimeoutTimer.attach_us(callback(this, func), timeout_ms); 00392 else 00393 rxTimeoutTimer.detach(); 00394 break; 00395 case TXTimeoutTimer: 00396 if (func) 00397 txTimeoutTimer .attach_us(callback(this, func), timeout_ms); 00398 else 00399 txTimeoutTimer .detach(); 00400 break; 00401 case RXTimeoutSyncWordTimer: 00402 if (func) 00403 rxTimeoutSyncWord.attach_us(callback(this, func), timeout_ms); 00404 else 00405 rxTimeoutSyncWord.detach(); 00406 break; 00407 } 00408 } 00409 00410 void 00411 SX1276Generic::Sleep_ms(int ms) 00412 { 00413 wait_ms(ms); 00414 } 00415 00416 bool SX1276Generic::CheckRfFrequency( uint32_t frequency ) 00417 { 00418 if (frequency > 1200000) 00419 return false; 00420 // Implement check. Currently all frequencies are supported 00421 return true; 00422 } 00423 00424 void SX1276Generic::Reset( void ) 00425 { 00426 _reset ->output(); 00427 *_reset = 0; 00428 wait_ms( 1 ); 00429 *_reset = 1; 00430 _reset ->input(); // I don't know why input again, maybe to save power (Helmut T) 00431 wait_ms( 6 ); 00432 } 00433 00434 void SX1276Generic::Write( uint8_t addr, uint8_t data ) 00435 { 00436 Write( addr, &data, 1 ); 00437 } 00438 00439 uint8_t SX1276Generic::Read( uint8_t addr ) 00440 { 00441 uint8_t data; 00442 Read( addr, &data, 1 ); 00443 return data; 00444 } 00445 00446 void SX1276Generic::Write( uint8_t addr, void *buffer, uint8_t size ) 00447 { 00448 uint8_t i; 00449 uint8_t *p = (uint8_t *)buffer; 00450 00451 *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut 00452 _spi ->write( addr | 0x80 ); 00453 for( i = 0; i < size; i++ ) 00454 { 00455 _spi ->write(*p++); 00456 } 00457 *_nss = 1; 00458 } 00459 00460 void SX1276Generic::Read( uint8_t addr, void *buffer, uint8_t size ) 00461 { 00462 uint8_t i; 00463 uint8_t *p = (uint8_t *)buffer; 00464 00465 *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut 00466 _spi ->write( addr & 0x7F ); 00467 for( i = 0; i < size; i++ ) 00468 { 00469 *p++ = _spi ->write( 0 ); 00470 } 00471 *_nss = 1; 00472 } 00473 00474 void SX1276Generic::WriteFifo( void *buffer, uint8_t size ) 00475 { 00476 Write( 0, buffer, size ); 00477 } 00478 00479 void SX1276Generic::ReadFifo( void *buffer, uint8_t size ) 00480 { 00481 Read( 0, buffer, size ); 00482 }
Generated on Sat Jul 16 2022 06:25:27 by 1.7.2