Giorgos Tsapparellas / SX1272Lib

Dependents:   LoRaWAN_mbed_lmic_agriculture_app

Fork of SX1272Lib by Semtech

Embed: (wiki syntax)

« Back to documentation index

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

sx1272-hal.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C) 2015 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 
00016  Used by Giorgos Tsapparellas for Internet of Things (IoT) smart monitoring
00017  device for agriculture using LoRaWAN technology.
00018  
00019  Date of issued copy: 20 January 2018
00020  
00021  Modifications: 
00022  - No external modifications of the existing "AS IT IS" software.
00023  
00024  Notice that, connectivity for SX1272MB2xAS LoRa shield is allocated as:
00025  SX1272MB2xAS   MBED Pin
00026  SCK             D13
00027  MOSI            D11
00028  MISO            D12
00029  NSS             D10
00030  DIO0            D2
00031  DIO1            D3
00032  DIO2            D4
00033  DIO3            D5
00034  DIO4            D8
00035  DIO5            D9
00036  NRESET          A0
00037 */
00038 #include "sx1272-hal.h"
00039 
00040 #if defined ( TARGET_MOTE_L152RC )
00041 /*
00042        PD_2=0  PD_2=1
00043 op PaB  rfo     rfo
00044 0  4.6  18.5    27.0
00045 1  5.6  21.1    28.1
00046 2  6.7  23.3    29.1
00047 3  7.7  25.3    30.1
00048 4  8.8  26.2    30.7
00049 5  9.8  27.3    31.2
00050 6  10.7 28.1    31.6
00051 7  11.7 28.6    32.2
00052 8  12.8 29.2    32.4
00053 9  13.7 29.9    32.9
00054 10 14.7 30.5    33.1
00055 11 15.6 30.8    33.4
00056 12 16.4 30.9    33.6
00057 13 17.1 31.0    33.7
00058 14 17.8 31.1    33.7
00059 15 18.4 31.1    33.7
00060 */
00061 //                           txpow:   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14  15  16  17  18  19
00062 static const uint8_t PaBTable[20] = { 0, 0, 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15 };
00063 
00064 //                           txpow:  20 21 22 23 24 25 26 27 28 29 30
00065 static const uint8_t RfoTable[11] = { 1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 9 };
00066 
00067 #endif
00068 
00069 const RadioRegisters_t  SX1272MB2xAS::RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;
00070 
00071 SX1272MB2xAS::SX1272MB2xAS( RadioEvents_t *events,
00072                             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
00073                             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
00074 #if defined ( TARGET_MOTE_L152RC )
00075                             PinName rfSwitchCntr1, PinName rfSwitchCntr2 )
00076 #elif defined ( TARGET_MTS_MDOT_F411RE )
00077                             PinName txctl, PinName rxctl )
00078 #else
00079                             PinName antSwitch )
00080 #endif
00081                             : SX1272 ( events, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5 ),
00082 #if defined ( TARGET_MOTE_L152RC )
00083                             RfSwitchCntr1( rfSwitchCntr1 ),
00084                             RfSwitchCntr2( rfSwitchCntr2 ),
00085                             PwrAmpCntr( PD_2 )
00086 #elif defined ( TARGET_MTS_MDOT_F411RE )
00087                             TxCtl ( txctl ),
00088                             RxCtl ( rxctl )
00089 #else
00090                             AntSwitch( antSwitch ),
00091                         #if( defined ( TARGET_NUCLEO_L152RE ) ) || defined ( TARGET_NUCLEO_L476RG )
00092                             Fake( D8 )
00093                         #else
00094                             Fake( A3 )
00095                         #endif
00096 #endif
00097 {
00098     this->RadioEvents = events;
00099 
00100     Reset( );
00101 
00102     IoInit( );
00103 
00104     SetOpMode( RF_OPMODE_SLEEP );
00105 
00106     IoIrqInit( dioIrq );
00107 
00108     RadioRegistersInit( );
00109 
00110     SetModem( MODEM_FSK );
00111 
00112     this->settings.State = RF_IDLE ;
00113 }
00114 
00115 SX1272MB2xAS::SX1272MB2xAS( RadioEvents_t *events )
00116                         #if defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_NUCLEO_L476RG )
00117                         :   SX1272 ( events, D11, D12, D13, D10, A0, D2, D3, D4, D5, A3, D9 ), // For NUCLEO L152RE dio4 is on port A3
00118                             AntSwitch( A4 ),
00119                             Fake( D8 )
00120                         #elif defined ( TARGET_MOTE_L152RC )
00121                         :   SX1272 ( events, PB_15, PB_14, PB_13, PB_12, PC_2, PC_6, PC_10, PC_11, PC_8, PC_9, PC_12 ),
00122                             RfSwitchCntr1( PC_4 ),
00123                             RfSwitchCntr2( PC_13 ),
00124                             PwrAmpCntr( PD_2 )
00125                         #elif defined ( TARGET_MTS_MDOT_F411RE )
00126                         :   SX1272 ( events, LORA_MOSI, LORA_MISO, LORA_SCK, LORA_NSS, LORA_RESET, LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5 ),
00127                             TxCtl( LORA_TXCTL ),
00128                             RxCtl( LORA_RXCTL )
00129                         #else
00130                         :   SX1272 ( events, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ),
00131                             AntSwitch( A4 ), 
00132                             Fake( A3 )
00133                         #endif
00134 {
00135     this->RadioEvents = events;
00136 
00137     Reset( );
00138 
00139     boardConnected = UNKNOWN;
00140 
00141     DetectBoardType( );
00142 
00143     IoInit( );
00144 
00145     SetOpMode( RF_OPMODE_SLEEP );
00146     IoIrqInit( dioIrq );
00147 
00148     RadioRegistersInit( );
00149 
00150     SetModem( MODEM_FSK );
00151 
00152     this->settings.State = RF_IDLE ;
00153 }
00154 
00155 //-------------------------------------------------------------------------
00156 //                      Board relative functions
00157 //-------------------------------------------------------------------------
00158 uint8_t SX1272MB2xAS::DetectBoardType( void )
00159 {
00160     if( boardConnected == UNKNOWN )
00161     {
00162 #if defined ( TARGET_MOTE_L152RC )
00163         boardConnected = NA_MOTE_72;
00164 #elif defined ( TARGET_MTS_MDOT_F411RE )
00165         boardConnected = MDOT_F411RE;
00166 #else
00167         this->AntSwitch.input( );
00168         wait_ms( 1 );
00169         if( this->AntSwitch == 1 )
00170         {
00171             boardConnected = SX1272MB1DCS;
00172         }
00173         else
00174         {
00175             boardConnected = SX1272MB2XAS;
00176         }
00177         this->AntSwitch.output( );
00178         wait_ms( 1 );
00179 #endif
00180     }
00181     return ( boardConnected );
00182 }
00183 
00184 void SX1272MB2xAS::IoInit( void )
00185 {
00186     AntSwInit( );
00187     SpiInit( );
00188 }
00189 
00190 void SX1272MB2xAS::RadioRegistersInit( )
00191 {
00192     uint8_t i = 0;
00193     for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t  ); i++ )
00194     {
00195         SetModem( RadioRegsInit[i].Modem );
00196         Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
00197     }    
00198 }
00199 
00200 void SX1272MB2xAS::SpiInit( void )
00201 {
00202     nss = 1;    
00203     spi .format( 8,0 );   
00204     uint32_t frequencyToSet = 8000000;
00205     #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_MOTE_L152RC ) || defined ( TARGET_NUCLEO_L476RG ) ||  defined ( TARGET_LPC11U6X ) || defined ( TARGET_MTS_MDOT_F411RE ) )
00206         spi .frequency( frequencyToSet );
00207     #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate
00208         spi .frequency( frequencyToSet * 2 );
00209     #else
00210         #warning "Check the board's SPI frequency"
00211     #endif
00212     wait(0.1); 
00213 }
00214 
00215 void SX1272MB2xAS::IoIrqInit( DioIrqHandler *irqHandlers )
00216 {
00217 #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_MOTE_L152RC ) || defined ( TARGET_NUCLEO_L476RG ) || defined ( TARGET_NUCLEO_L476RG ) ||  defined ( TARGET_LPC11U6X ) )
00218     dio0.mode( PullDown );
00219     dio1.mode( PullDown );
00220     dio2.mode( PullDown );
00221     dio3.mode( PullDown );
00222     dio4.mode( PullDown );
00223 #endif
00224     dio0.rise( this, static_cast< TriggerMB2xAS > ( irqHandlers[0] ) );
00225     dio1.rise( this, static_cast< TriggerMB2xAS > ( irqHandlers[1] ) );
00226     dio2.rise( this, static_cast< TriggerMB2xAS > ( irqHandlers[2] ) );
00227     dio3.rise( this, static_cast< TriggerMB2xAS > ( irqHandlers[3] ) );
00228     dio4.rise( this, static_cast< TriggerMB2xAS > ( irqHandlers[4] ) );
00229 }
00230 
00231 void SX1272MB2xAS::IoDeInit( void )
00232 {
00233     //nothing
00234 }
00235 
00236 void SX1272MB2xAS::SetRfTxPower( int8_t power )
00237 {
00238     uint8_t paConfig = 0;
00239     uint8_t paDac = 0;
00240 
00241     paConfig = Read( REG_PACONFIG );
00242     paDac = Read( REG_PADAC );
00243 
00244 #if defined ( TARGET_MOTE_L152RC )
00245     if( power > 19 )
00246     {
00247         paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | RF_PACONFIG_PASELECT_RFO;
00248         paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | RfoTable[power - 20];
00249     }
00250     else
00251     {
00252         paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | RF_PACONFIG_PASELECT_PABOOST;
00253         paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | PaBTable[power];
00254     }
00255 #else
00256     paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel );
00257 
00258     if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
00259     {
00260         if( power > 17 )
00261         {
00262             paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
00263         }
00264         else
00265         {
00266             paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
00267         }
00268         if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
00269         {
00270             if( power < 5 )
00271             {
00272                 power = 5;
00273             }
00274             if( power > 20 )
00275             {
00276                 power = 20;
00277             }
00278             paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
00279         }
00280         else
00281         {
00282             if( power < 2 )
00283             {
00284                 power = 2;
00285             }
00286             if( power > 17 )
00287             {
00288                 power = 17;
00289             }
00290             paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
00291         }
00292     }
00293     else
00294     {
00295         if( power < -1 )
00296         {
00297             power = -1;
00298         }
00299         if( power > 14 )
00300         {
00301             power = 14;
00302         }
00303         paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
00304     }
00305 #endif
00306     Write( REG_PACONFIG, paConfig );
00307     Write( REG_PADAC, paDac );
00308 }
00309 
00310 uint8_t SX1272MB2xAS::GetPaSelect( uint32_t channel )
00311 {
00312     if( boardConnected == SX1272MB1DCS || boardConnected == MDOT_F411RE )
00313     {
00314         return RF_PACONFIG_PASELECT_PABOOST;
00315     }
00316     else
00317     {
00318         return RF_PACONFIG_PASELECT_RFO;
00319     }
00320 }
00321 
00322 void SX1272MB2xAS::SetAntSwLowPower( bool status )
00323 {
00324     if( isRadioActive != status )
00325     {
00326         isRadioActive = status;
00327     
00328         if( status == false )
00329         {
00330             AntSwInit( );
00331         }
00332         else
00333         {
00334             AntSwDeInit( );
00335         }
00336     }
00337 }
00338 
00339 void SX1272MB2xAS::AntSwInit( void )
00340 {
00341 #if defined ( TARGET_MOTE_L152RC )
00342     this->RfSwitchCntr1  = 0;
00343     this->RfSwitchCntr2 = 0;
00344     this->PwrAmpCntr = 0;
00345 #elif defined ( TARGET_MTS_MDOT_F411RE )
00346     this->TxCtl = 0;
00347     this->RxCtl = 0;
00348 #else
00349     this->AntSwitch = 0;
00350 #endif
00351 }
00352 
00353 void SX1272MB2xAS::AntSwDeInit( void )
00354 {
00355 #if defined ( TARGET_MOTE_L152RC )
00356     this->RfSwitchCntr1  = 0;
00357     this->RfSwitchCntr2 = 0;
00358     this->PwrAmpCntr = 0;
00359 #elif defined ( TARGET_MTS_MDOT_F411RE )
00360     this->TxCtl = 0;
00361     this->RxCtl = 0;
00362 #else
00363     this->AntSwitch = 0;
00364 #endif
00365 }
00366 
00367 void SX1272MB2xAS::SetAntSw( uint8_t opMode )
00368 {
00369     switch( opMode )
00370     {
00371     case RFLR_OPMODE_TRANSMITTER:
00372 #if defined ( TARGET_MOTE_L152RC )
00373         if( ( Read( REG_PACONFIG ) & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
00374         {
00375             this->RfSwitchCntr1  = 1;
00376             this->RfSwitchCntr2 = 0;
00377         }
00378         else
00379         {
00380             this->RfSwitchCntr1  = 0;
00381             this->RfSwitchCntr2 = 1;
00382         }
00383 #elif defined ( TARGET_MTS_MDOT_F411RE )
00384         /* SKY13350 */
00385         this->TxCtl = 1;
00386         this->RxCtl = 0;
00387 #else
00388         this->AntSwitch = 1;
00389 #endif
00390         break;
00391     case RFLR_OPMODE_RECEIVER:
00392     case RFLR_OPMODE_RECEIVER_SINGLE:
00393     case RFLR_OPMODE_CAD:
00394 #if defined ( TARGET_MOTE_L152RC )
00395         this->RfSwitchCntr1  = 1;
00396         this->RfSwitchCntr2 = 1;
00397 #elif defined ( TARGET_MTS_MDOT_F411RE )
00398         /* SKY13350 */
00399         this->TxCtl = 0;
00400         this->RxCtl = 1;
00401 #else
00402         this->AntSwitch = 0;
00403 #endif
00404         break;
00405     default:
00406 #if defined ( TARGET_MOTE_L152RC )
00407         this->RfSwitchCntr1  = 0;
00408         this->RfSwitchCntr2 = 0;
00409         this->PwrAmpCntr = 0;
00410 #elif defined ( TARGET_MTS_MDOT_F411RE )
00411         /* SKY13350 */
00412         this->TxCtl = 0;
00413         this->RxCtl = 0;
00414 #else
00415         this->AntSwitch = 0;
00416 #endif
00417         break;
00418     }
00419 }
00420 
00421 bool SX1272MB2xAS::CheckRfFrequency( uint32_t frequency )
00422 {
00423     // Implement check. Currently all frequencies are supported
00424     return true;
00425 }
00426 
00427 void SX1272MB2xAS::Reset( void )
00428 {
00429     reset.output( );
00430     reset = 0;
00431     wait_ms( 1 );
00432     reset.input( );
00433     wait_ms( 6 );
00434 }
00435 
00436 void SX1272MB2xAS::Write( uint8_t addr, uint8_t data )
00437 {
00438     Write( addr, &data, 1 );
00439 }
00440 
00441 uint8_t SX1272MB2xAS::Read( uint8_t addr )
00442 {
00443     uint8_t data;
00444     Read( addr, &data, 1 );
00445     return data;
00446 }
00447 
00448 void SX1272MB2xAS::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
00449 {
00450     uint8_t i;
00451 
00452     nss = 0;
00453     spi .write( addr | 0x80 );
00454     for( i = 0; i < size; i++ )
00455     {
00456         spi .write( buffer[i] );
00457     }
00458     nss = 1;
00459 }
00460 
00461 void SX1272MB2xAS::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
00462 {
00463     uint8_t i;
00464 
00465     nss = 0;
00466     spi .write( addr & 0x7F );
00467     for( i = 0; i < size; i++ )
00468     {
00469         buffer[i] = spi .write( 0 );
00470     }
00471     nss = 1;
00472 }
00473 
00474 void SX1272MB2xAS::WriteFifo( uint8_t *buffer, uint8_t size )
00475 {
00476     Write( 0, buffer, size );
00477 }
00478 
00479 void SX1272MB2xAS::ReadFifo( uint8_t *buffer, uint8_t size )
00480 {
00481     Read( 0, buffer, size );
00482 }