Fork for adding SAM L21 Xplained Pro support

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