SX1276Lib updated in order to be RTOS aware

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, 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 }