This Library is to establish communication between a transmitter and receivers formed by the combination of SX1272MB2DAS shield and FRDM kl25z board that uses Cortex M0+ architecture.

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