Gregory Cristian / SX1276Lib

Dependents:   LoRaWAN_actility LoRaWAN_MBED LoRaWANSharedTest

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[] = 
00018 {                                                 
00019     { MODEM_FSK , REG_LNA                , 0x23 },
00020     { MODEM_FSK , REG_RXCONFIG           , 0x1E },
00021     { MODEM_FSK , REG_RSSICONFIG         , 0xD2 },
00022     { MODEM_FSK , REG_PREAMBLEDETECT     , 0xAA },
00023     { MODEM_FSK , REG_OSC                , 0x07 },
00024     { MODEM_FSK , REG_SYNCCONFIG         , 0x12 },
00025     { MODEM_FSK , REG_SYNCVALUE1         , 0xC1 },
00026     { MODEM_FSK , REG_SYNCVALUE2         , 0x94 },
00027     { MODEM_FSK , REG_SYNCVALUE3         , 0xC1 },
00028     { MODEM_FSK , REG_PACKETCONFIG1      , 0xD8 },
00029     { MODEM_FSK , REG_FIFOTHRESH         , 0x8F },
00030     { MODEM_FSK , REG_IMAGECAL           , 0x02 },
00031     { MODEM_FSK , REG_DIOMAPPING1        , 0x00 },
00032     { MODEM_FSK , REG_DIOMAPPING2        , 0x30 },
00033     { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },  
00034 };
00035 
00036 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
00037                             void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
00038                             PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
00039                             PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
00040                             PinName antSwitch )
00041                             : SX1276 ( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5),
00042                             antSwitch( antSwitch ),
00043                         #if( defined ( TARGET_NUCLEO_L152RE ) )
00044                             fake( D8 ) 
00045                         #else
00046                             fake( A3 )
00047                         #endif
00048 {
00049     Reset( );
00050     
00051     RxChainCalibration( );
00052     
00053     IoInit( );
00054     
00055     SetOpMode( RF_OPMODE_SLEEP );
00056     
00057     IoIrqInit( dioIrq );
00058     
00059     RadioRegistersInit( );
00060 
00061     SetModem( MODEM_FSK );
00062 
00063     this->settings.State = IDLE ;
00064 }
00065 
00066 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ), 
00067                             void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) ) 
00068                         #if defined ( TARGET_NUCLEO_L152RE )
00069                         :   SX1276 ( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, A3, D9 ), // For NUCLEO L152RE dio4 is on port A3
00070                             antSwitch( A4 ),
00071                             fake( D8 )
00072                         #else
00073                         :   SX1276 ( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ),
00074                             antSwitch( A4 ), 
00075                             fake( A3 )
00076                         #endif
00077 {
00078     Reset( );
00079     
00080     boardConnected = UNKNOWN;
00081     
00082     DetectBoardType( );
00083     
00084     RxChainCalibration( );
00085     
00086     IoInit( );
00087     
00088     SetOpMode( RF_OPMODE_SLEEP );
00089     IoIrqInit( dioIrq );
00090     
00091     RadioRegistersInit( );
00092 
00093     SetModem( MODEM_FSK );
00094 
00095     this->settings.State = IDLE ;
00096 }
00097 
00098 //-------------------------------------------------------------------------
00099 //                      Board relative functions
00100 //-------------------------------------------------------------------------
00101 uint8_t SX1276MB1xAS::DetectBoardType( void )
00102 {
00103     if( boardConnected == UNKNOWN )
00104     {
00105         antSwitch .input( );
00106         wait_ms( 1 );
00107         if( antSwitch  == 1 )
00108         {
00109             boardConnected = SX1276MB1LAS;
00110         }
00111         else
00112         {
00113             boardConnected = SX1276MB1MAS;
00114         }
00115         antSwitch .output( );
00116         wait_ms( 1 );
00117     }
00118     return ( boardConnected );
00119 }
00120 
00121 void SX1276MB1xAS::IoInit( void )
00122 {
00123     AntSwInit( );
00124     SpiInit( );
00125 }
00126 
00127 void SX1276MB1xAS::RadioRegistersInit( ){
00128     uint8_t i = 0;
00129     for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t  ); i++ )
00130     {
00131         SetModem( RadioRegsInit[i].Modem );
00132         Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
00133     }    
00134 }
00135 
00136 void SX1276MB1xAS::SpiInit( void )
00137 {
00138     nss = 1;    
00139     spi .format( 8,0 );   
00140     uint32_t frequencyToSet = 8000000;
00141     #if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
00142         spi .frequency( frequencyToSet );
00143     #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate
00144         spi .frequency( frequencyToSet * 2 );
00145     #else
00146         #warning "Check the board's SPI frequency"
00147     #endif
00148     wait(0.1); 
00149 }
00150 
00151 void SX1276MB1xAS::IoIrqInit( DioIrqHandler *irqHandlers )
00152 {
00153     #if( defined ( TARGET_NUCLEO_L152RE ) ||  defined ( TARGET_LPC11U6X ) )
00154         dio0 .mode(PullDown);
00155         dio1.mode(PullDown);   
00156         dio2.mode(PullDown);
00157         dio3.mode(PullDown); 
00158         dio4.mode(PullDown); 
00159     #endif
00160     dio0 .rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[0] ) );
00161     dio1.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[1] ) );
00162     dio2.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[2] ) );
00163     dio3.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[3] ) );
00164     dio4.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[4] ) );
00165 }
00166 
00167 void SX1276MB1xAS::IoDeInit( void )
00168 {
00169     //nothing
00170 }
00171 
00172 uint8_t SX1276MB1xAS::GetPaSelect( uint32_t channel )
00173 {
00174     if( channel > RF_MID_BAND_THRESH )
00175     {
00176         if( boardConnected == SX1276MB1LAS )
00177         {
00178             return RF_PACONFIG_PASELECT_PABOOST;
00179         }
00180         else
00181         {
00182             return RF_PACONFIG_PASELECT_RFO;
00183         }
00184     }
00185     else
00186     {
00187         return RF_PACONFIG_PASELECT_RFO;
00188     }
00189 }
00190 
00191 void SX1276MB1xAS::SetAntSwLowPower( bool status )
00192 {
00193     if( isRadioActive != status )
00194     {
00195         isRadioActive = status;
00196     
00197         if( status == false )
00198         {
00199             AntSwInit( );
00200         }
00201         else
00202         {
00203             AntSwDeInit( );
00204         }
00205     }
00206 }
00207 
00208 void SX1276MB1xAS::AntSwInit( void )
00209 {
00210     antSwitch  = 0;
00211 }
00212 
00213 void SX1276MB1xAS::AntSwDeInit( void )
00214 {
00215     antSwitch  = 0;
00216 }
00217 
00218 void SX1276MB1xAS::SetAntSw( uint8_t rxTx )
00219 {
00220     if( this->rxTx == rxTx )
00221     {
00222         //no need to go further
00223         return;
00224     }
00225 
00226     this->rxTx = rxTx ;
00227 
00228     if( rxTx != 0 )
00229     {
00230         antSwitch  = 1;
00231     }
00232     else
00233     {
00234         antSwitch  = 0;
00235     }
00236 }
00237 
00238 bool SX1276MB1xAS::CheckRfFrequency( uint32_t frequency )
00239 {
00240     //TODO: Implement check, currently all frequencies are supported
00241     return true;
00242 }
00243 
00244 
00245 void SX1276MB1xAS::Reset( void )
00246 {
00247     reset .output();
00248     reset  = 0;
00249     wait_ms( 1 );
00250     reset .input();
00251     wait_ms( 6 );
00252 }
00253     
00254 void SX1276MB1xAS::Write( uint8_t addr, uint8_t data )
00255 {
00256     Write( addr, &data, 1 );
00257 }
00258 
00259 uint8_t SX1276MB1xAS::Read( uint8_t addr )
00260 {
00261     uint8_t data;
00262     Read( addr, &data, 1 );
00263     return data;
00264 }
00265 
00266 void SX1276MB1xAS::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
00267 {
00268     uint8_t i;
00269 
00270     nss = 0;
00271     spi .write( addr | 0x80 );
00272     for( i = 0; i < size; i++ )
00273     {
00274         spi .write( buffer[i] );
00275     }
00276     nss = 1;
00277 }
00278 
00279 void SX1276MB1xAS::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
00280 {
00281     uint8_t i;
00282 
00283     nss = 0;
00284     spi .write( addr & 0x7F );
00285     for( i = 0; i < size; i++ )
00286     {
00287         buffer[i] = spi .write( 0 );
00288     }
00289     nss = 1;
00290 }
00291 
00292 void SX1276MB1xAS::WriteFifo( uint8_t *buffer, uint8_t size )
00293 {
00294     Write( 0, buffer, size );
00295 }
00296 
00297 void SX1276MB1xAS::ReadFifo( uint8_t *buffer, uint8_t size )
00298 {
00299     Read( 0, buffer, size );
00300 }