20171208

Fork of SX1276Lib by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sx1276-hal.cpp Source File

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