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.
Fork of SX1276Lib by
sx1276-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 #include "sx1276-hal.h" 00016 00017 const RadioRegisters_t SX1276MB1xAS::RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE; 00018 00019 SX1276MB1xAS::SX1276MB1xAS( RadioEvents_t *events, BoardType_t board, 00020 PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset, 00021 PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5, 00022 PinName antSwitch ) 00023 : SX1276 ( events, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5 ), 00024 AntSwitch( antSwitch ), 00025 #if( defined ( TARGET_NUCLEO_L152RE ) ) 00026 Fake( D8 ) 00027 #else 00028 Fake( A3 ) 00029 #endif 00030 { 00031 this->RadioEvents = events; 00032 00033 boardConnected = board; 00034 00035 Reset( ); 00036 00037 RxChainCalibration( ); 00038 00039 IoInit( ); 00040 00041 SetOpMode( RF_OPMODE_SLEEP ); 00042 00043 IoIrqInit( dioIrq ); 00044 00045 RadioRegistersInit( ); 00046 00047 SetModem( MODEM_FSK ); 00048 00049 this->settings.State = RF_IDLE ; 00050 } 00051 00052 SX1276MB1xAS::SX1276MB1xAS( RadioEvents_t *events ) 00053 #if defined ( TARGET_NUCLEO_L152RE ) || defined (TARGET_NUCLEO_L476RG) || defined (TARGET_NUCLEO_F401RE) 00054 : SX1276 ( events, D11, D12, D13, D10, A0, D2, D3, D4, D5, A3, D9 ), // For NUCLEO L152RE dio4 is on port A3 00055 AntSwitch( A4 ), 00056 Fake( D8 ) 00057 #elif defined( TARGET_NUCLEO_L073RZ ) 00058 : SX1276 ( events, PB_15, PB_14, PB_13, PB_12, PC_6, PC_8, D3, D4, D5, D8, D9 ), 00059 AntSwitch( A4 ), 00060 Fake( A3 ) 00061 #elif defined( TARGET_LPC11U6X ) 00062 : SX1276 ( events, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ), 00063 AntSwitch( P0_23 ), 00064 Fake( A3 ) 00065 #else 00066 : SX1276 ( events, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ), 00067 AntSwitch( A4 ), 00068 Fake( A3 ) 00069 #endif 00070 { 00071 this->RadioEvents = events; 00072 00073 Reset( ); 00074 00075 boardConnected = RFM95_SX1276; 00076 00077 DetectBoardType( ); 00078 00079 RxChainCalibration( ); 00080 00081 IoInit( ); 00082 00083 SetOpMode( RF_OPMODE_SLEEP ); 00084 IoIrqInit( dioIrq ); 00085 00086 RadioRegistersInit( ); 00087 00088 SetModem( MODEM_FSK ); 00089 00090 this->settings.State = RF_IDLE ; 00091 } 00092 00093 //------------------------------------------------------------------------- 00094 // Board relative functions 00095 //------------------------------------------------------------------------- 00096 uint8_t SX1276MB1xAS::DetectBoardType( void ) 00097 { 00098 return boardConnected; 00099 } 00100 00101 void SX1276MB1xAS::IoInit( void ) 00102 { 00103 AntSwInit( ); 00104 SpiInit( ); 00105 } 00106 00107 void SX1276MB1xAS::RadioRegistersInit( ) 00108 { 00109 uint8_t i = 0; 00110 for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ ) 00111 { 00112 SetModem( RadioRegsInit[i].Modem ); 00113 Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value ); 00114 } 00115 } 00116 00117 void SX1276MB1xAS::SpiInit( void ) 00118 { 00119 nss = 1; 00120 spi .format( 8,0 ); 00121 uint32_t frequencyToSet = 8000000; 00122 #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_MOTE_L152RC ) || defined ( TARGET_NUCLEO_L476RG ) || defined ( TARGET_LPC11U6X ) || defined ( TARGET_MTS_MDOT_F411RE ) || defined ( TARGET_NUCLEO_L073RZ )) 00123 spi .frequency( frequencyToSet ); 00124 #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate 00125 spi .frequency( frequencyToSet * 2 ); 00126 #else 00127 #warning "Check the board's SPI frequency" 00128 #endif 00129 wait(0.1); 00130 } 00131 00132 void SX1276MB1xAS::IoIrqInit( DioIrqHandler *irqHandlers ) 00133 { 00134 #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_LPC11U6X ) ) 00135 dio0 .mode( PullDown ); 00136 dio1.mode( PullDown ); 00137 dio2.mode( PullDown ); 00138 dio3.mode( PullDown ); 00139 dio4.mode( PullDown ); 00140 #endif 00141 dio0 .rise( mbed::callback( this, static_cast< TriggerMB1xAS > ( irqHandlers[0] ) ) ); 00142 dio1.rise( mbed::callback( this, static_cast< TriggerMB1xAS > ( irqHandlers[1] ) ) ); 00143 dio2.rise( mbed::callback( this, static_cast< TriggerMB1xAS > ( irqHandlers[2] ) ) ); 00144 dio3.rise( mbed::callback( this, static_cast< TriggerMB1xAS > ( irqHandlers[3] ) ) ); 00145 dio4.rise( mbed::callback( this, static_cast< TriggerMB1xAS > ( irqHandlers[4] ) ) ); 00146 } 00147 00148 void SX1276MB1xAS::IoDeInit( void ) 00149 { 00150 //nothing 00151 } 00152 00153 void SX1276MB1xAS::SetRfTxPower( int8_t power ) 00154 { 00155 uint8_t paConfig = 0; 00156 uint8_t paDac = 0; 00157 00158 paConfig = Read( REG_PACONFIG ); 00159 paDac = Read( REG_PADAC ); 00160 00161 paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel ); 00162 paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; 00163 00164 if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) 00165 { 00166 if( power > 17 ) 00167 { 00168 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON; 00169 } 00170 else 00171 { 00172 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF; 00173 } 00174 if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON ) 00175 { 00176 if( power < 5 ) 00177 { 00178 power = 5; 00179 } 00180 if( power > 20 ) 00181 { 00182 power = 20; 00183 } 00184 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); 00185 } 00186 else 00187 { 00188 if( power < 2 ) 00189 { 00190 power = 2; 00191 } 00192 if( power > 17 ) 00193 { 00194 power = 17; 00195 } 00196 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); 00197 } 00198 } 00199 else 00200 { 00201 if( power < -1 ) 00202 { 00203 power = -1; 00204 } 00205 if( power > 14 ) 00206 { 00207 power = 14; 00208 } 00209 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); 00210 } 00211 Write( REG_PACONFIG, paConfig ); 00212 Write( REG_PADAC, paDac ); 00213 } 00214 00215 uint8_t SX1276MB1xAS::GetPaSelect( uint32_t channel ) 00216 { 00217 if( channel > RF_MID_BAND_THRESH ) 00218 { 00219 if( boardConnected == SX1276MB1LAS || boardConnected == RFM95_SX1276 || boardConnected == MURATA_SX1276) 00220 { 00221 return RF_PACONFIG_PASELECT_PABOOST; 00222 } 00223 else 00224 { 00225 return RF_PACONFIG_PASELECT_RFO; 00226 } 00227 } 00228 else 00229 { 00230 return RF_PACONFIG_PASELECT_RFO; 00231 } 00232 } 00233 00234 void SX1276MB1xAS::SetAntSwLowPower( bool status ) 00235 { 00236 if( isRadioActive != status ) 00237 { 00238 isRadioActive = status; 00239 00240 if( status == false ) 00241 { 00242 AntSwInit( ); 00243 } 00244 else 00245 { 00246 AntSwDeInit( ); 00247 } 00248 } 00249 } 00250 00251 void SX1276MB1xAS::AntSwInit( void ) 00252 { 00253 this->AntSwitch = 0; 00254 } 00255 00256 void SX1276MB1xAS::AntSwDeInit( void ) 00257 { 00258 this->AntSwitch = 0; 00259 } 00260 00261 void SX1276MB1xAS::SetAntSw( uint8_t opMode ) 00262 { 00263 switch( opMode ) 00264 { 00265 case RFLR_OPMODE_TRANSMITTER: 00266 this->AntSwitch = 1; 00267 break; 00268 case RFLR_OPMODE_RECEIVER: 00269 case RFLR_OPMODE_RECEIVER_SINGLE: 00270 case RFLR_OPMODE_CAD: 00271 this->AntSwitch = 0; 00272 break; 00273 default: 00274 this->AntSwitch = 0; 00275 break; 00276 } 00277 } 00278 00279 bool SX1276MB1xAS::CheckRfFrequency( uint32_t frequency ) 00280 { 00281 // Implement check. Currently all frequencies are supported 00282 return true; 00283 } 00284 00285 void SX1276MB1xAS::Reset( void ) 00286 { 00287 reset .output( ); 00288 reset = 0; 00289 wait_ms( 1 ); 00290 reset .input( ); 00291 wait_ms( 6 ); 00292 } 00293 00294 void SX1276MB1xAS::Write( uint8_t addr, uint8_t data ) 00295 { 00296 Write( addr, &data, 1 ); 00297 } 00298 00299 uint8_t SX1276MB1xAS::Read( uint8_t addr ) 00300 { 00301 uint8_t data; 00302 Read( addr, &data, 1 ); 00303 return data; 00304 } 00305 00306 void SX1276MB1xAS::Write( uint8_t addr, uint8_t *buffer, uint8_t size ) 00307 { 00308 uint8_t i; 00309 00310 nss = 0; 00311 spi .write( addr | 0x80 ); 00312 for( i = 0; i < size; i++ ) 00313 { 00314 spi .write( buffer[i] ); 00315 } 00316 nss = 1; 00317 } 00318 00319 void SX1276MB1xAS::Read( uint8_t addr, uint8_t *buffer, uint8_t size ) 00320 { 00321 uint8_t i; 00322 00323 nss = 0; 00324 spi .write( addr & 0x7F ); 00325 for( i = 0; i < size; i++ ) 00326 { 00327 buffer[i] = spi .write( 0 ); 00328 } 00329 nss = 1; 00330 } 00331 00332 void SX1276MB1xAS::WriteFifo( uint8_t *buffer, uint8_t size ) 00333 { 00334 Write( 0, buffer, size ); 00335 } 00336 00337 void SX1276MB1xAS::ReadFifo( uint8_t *buffer, uint8_t size ) 00338 { 00339 Read( 0, buffer, size ); 00340 }
Generated on Tue Jul 12 2022 20:43:13 by
1.7.2
