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