XRange SX1272Lib

Dependents:   XRangePingPong XRange-LoRaWAN-lmic-app lora-transceiver

Fork of SX1276Lib by Semtech

SX1272 LoRa RF module https://www.netblocks.eu/xrange-sx1272-lora-datasheet/

Driver for the SX1272 RF Transceiver.

Committer:
GregCr
Date:
Mon Aug 18 14:24:46 2014 +0000
Revision:
0:e6ceb13d2d05
Child:
1:f979673946c0
SX1276 Library first attempt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GregCr 0:e6ceb13d2d05 1 /*
GregCr 0:e6ceb13d2d05 2 / _____) _ | |
GregCr 0:e6ceb13d2d05 3 ( (____ _____ ____ _| |_ _____ ____| |__
GregCr 0:e6ceb13d2d05 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
GregCr 0:e6ceb13d2d05 5 _____) ) ____| | | || |_| ____( (___| | | |
GregCr 0:e6ceb13d2d05 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
GregCr 0:e6ceb13d2d05 7 ( C )2014 Semtech
GregCr 0:e6ceb13d2d05 8
GregCr 0:e6ceb13d2d05 9 Description: -
GregCr 0:e6ceb13d2d05 10
GregCr 0:e6ceb13d2d05 11 License: Revised BSD License, see LICENSE.TXT file include in the project
GregCr 0:e6ceb13d2d05 12
GregCr 0:e6ceb13d2d05 13 Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
GregCr 0:e6ceb13d2d05 14 */
GregCr 0:e6ceb13d2d05 15 #include "sx1276-hal.h"
GregCr 0:e6ceb13d2d05 16
GregCr 0:e6ceb13d2d05 17 const RadioRegisters_t SX1276MB1xAS::RadioRegsInit[] =
GregCr 0:e6ceb13d2d05 18 {
GregCr 0:e6ceb13d2d05 19 { MODEM_FSK , REG_LNA , 0x23 },
GregCr 0:e6ceb13d2d05 20 { MODEM_FSK , REG_RXCONFIG , 0x1E },
GregCr 0:e6ceb13d2d05 21 { MODEM_FSK , REG_RSSICONFIG , 0xD2 },
GregCr 0:e6ceb13d2d05 22 { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },
GregCr 0:e6ceb13d2d05 23 { MODEM_FSK , REG_OSC , 0x07 },
GregCr 0:e6ceb13d2d05 24 { MODEM_FSK , REG_SYNCCONFIG , 0x12 },
GregCr 0:e6ceb13d2d05 25 { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },
GregCr 0:e6ceb13d2d05 26 { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },
GregCr 0:e6ceb13d2d05 27 { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },
GregCr 0:e6ceb13d2d05 28 { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },
GregCr 0:e6ceb13d2d05 29 { MODEM_FSK , REG_FIFOTHRESH , 0x8F },
GregCr 0:e6ceb13d2d05 30 { MODEM_FSK , REG_IMAGECAL , 0x02 },
GregCr 0:e6ceb13d2d05 31 { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },
GregCr 0:e6ceb13d2d05 32 { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },
GregCr 0:e6ceb13d2d05 33 { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },
GregCr 0:e6ceb13d2d05 34 };
GregCr 0:e6ceb13d2d05 35
GregCr 0:e6ceb13d2d05 36 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int8_t rssi, int8_t snr ), void ( *rxTimeout ) ( ), void ( *rxError ) ( ),
GregCr 0:e6ceb13d2d05 37 PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
GregCr 0:e6ceb13d2d05 38 PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
GregCr 0:e6ceb13d2d05 39 PinName antSwitch )
GregCr 0:e6ceb13d2d05 40 : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5),
GregCr 0:e6ceb13d2d05 41 antSwitch( antSwitch ),
GregCr 0:e6ceb13d2d05 42 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
GregCr 0:e6ceb13d2d05 43 fake( A3 )
GregCr 0:e6ceb13d2d05 44 #elif defined ( TARGET_NUCLEO_L152RE )
GregCr 0:e6ceb13d2d05 45 fake( D8 )
GregCr 0:e6ceb13d2d05 46 #else
GregCr 0:e6ceb13d2d05 47 #warning "Check availability of IRQs on your selected board"
GregCr 0:e6ceb13d2d05 48 #endif
GregCr 0:e6ceb13d2d05 49 {
GregCr 0:e6ceb13d2d05 50 Reset( );
GregCr 0:e6ceb13d2d05 51
GregCr 0:e6ceb13d2d05 52 RxChainCalibration( );
GregCr 0:e6ceb13d2d05 53
GregCr 0:e6ceb13d2d05 54 IoInit( );
GregCr 0:e6ceb13d2d05 55
GregCr 0:e6ceb13d2d05 56 SetOpMode( RF_OPMODE_SLEEP );
GregCr 0:e6ceb13d2d05 57
GregCr 0:e6ceb13d2d05 58 IoIrqInit( dioIrq );
GregCr 0:e6ceb13d2d05 59
GregCr 0:e6ceb13d2d05 60 RadioRegistersInit( );
GregCr 0:e6ceb13d2d05 61
GregCr 0:e6ceb13d2d05 62 SetModem( MODEM_FSK );
GregCr 0:e6ceb13d2d05 63
GregCr 0:e6ceb13d2d05 64 this->settings.State = IDLE ;
GregCr 0:e6ceb13d2d05 65 }
GregCr 0:e6ceb13d2d05 66
GregCr 0:e6ceb13d2d05 67 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int8_t rssi, int8_t snr ), void ( *rxTimeout ) ( ), void ( *rxError ) ( ) )
GregCr 0:e6ceb13d2d05 68 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
GregCr 0:e6ceb13d2d05 69 : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ),
GregCr 0:e6ceb13d2d05 70 antSwitch( A4 ),
GregCr 0:e6ceb13d2d05 71 fake( A3 )
GregCr 0:e6ceb13d2d05 72 #elif defined ( TARGET_NUCLEO_L152RE )
GregCr 0:e6ceb13d2d05 73 : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, D11, D12, D13, D10, A0, D2, D3, D4, D5, A3, D9 ), // For NUCLEO L152RE dio4 is on port A3
GregCr 0:e6ceb13d2d05 74 antSwitch( A4 ),
GregCr 0:e6ceb13d2d05 75 fake( D8 )
GregCr 0:e6ceb13d2d05 76 #else
GregCr 0:e6ceb13d2d05 77 #warning "Check availability of IRQs on your selected board"
GregCr 0:e6ceb13d2d05 78 #endif
GregCr 0:e6ceb13d2d05 79 {
GregCr 0:e6ceb13d2d05 80 Reset( );
GregCr 0:e6ceb13d2d05 81
GregCr 0:e6ceb13d2d05 82 RxChainCalibration( );
GregCr 0:e6ceb13d2d05 83
GregCr 0:e6ceb13d2d05 84 IoInit( );
GregCr 0:e6ceb13d2d05 85
GregCr 0:e6ceb13d2d05 86 SetOpMode( RF_OPMODE_SLEEP );
GregCr 0:e6ceb13d2d05 87 IoIrqInit( dioIrq );
GregCr 0:e6ceb13d2d05 88
GregCr 0:e6ceb13d2d05 89 RadioRegistersInit( );
GregCr 0:e6ceb13d2d05 90
GregCr 0:e6ceb13d2d05 91 SetModem( MODEM_FSK );
GregCr 0:e6ceb13d2d05 92
GregCr 0:e6ceb13d2d05 93 this->settings.State = IDLE ;
GregCr 0:e6ceb13d2d05 94 }
GregCr 0:e6ceb13d2d05 95
GregCr 0:e6ceb13d2d05 96 //-------------------------------------------------------------------------
GregCr 0:e6ceb13d2d05 97 // Board relative functions
GregCr 0:e6ceb13d2d05 98 //-------------------------------------------------------------------------
GregCr 0:e6ceb13d2d05 99
GregCr 0:e6ceb13d2d05 100 void SX1276MB1xAS::IoInit( void )
GregCr 0:e6ceb13d2d05 101 {
GregCr 0:e6ceb13d2d05 102 AntSwInit( );
GregCr 0:e6ceb13d2d05 103 SpiInit( );
GregCr 0:e6ceb13d2d05 104 }
GregCr 0:e6ceb13d2d05 105
GregCr 0:e6ceb13d2d05 106 void SX1276MB1xAS::RadioRegistersInit( ){
GregCr 0:e6ceb13d2d05 107 uint8_t i = 0;
GregCr 0:e6ceb13d2d05 108 for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
GregCr 0:e6ceb13d2d05 109 {
GregCr 0:e6ceb13d2d05 110 SetModem( RadioRegsInit[i].Modem );
GregCr 0:e6ceb13d2d05 111 Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
GregCr 0:e6ceb13d2d05 112 }
GregCr 0:e6ceb13d2d05 113 }
GregCr 0:e6ceb13d2d05 114
GregCr 0:e6ceb13d2d05 115 void SX1276MB1xAS::SpiInit( void )
GregCr 0:e6ceb13d2d05 116 {
GregCr 0:e6ceb13d2d05 117
GregCr 0:e6ceb13d2d05 118 nss = 1;
GregCr 0:e6ceb13d2d05 119 spi.format( 8,0 );
GregCr 0:e6ceb13d2d05 120 uint32_t frequencyToSet = 8000000;
GregCr 0:e6ceb13d2d05 121 #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_LPC11U6X ) )
GregCr 0:e6ceb13d2d05 122 spi.frequency( frequencyToSet );
GregCr 0:e6ceb13d2d05 123 #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate
GregCr 0:e6ceb13d2d05 124 spi.frequency( frequencyToSet * 2 );
GregCr 0:e6ceb13d2d05 125 #else
GregCr 0:e6ceb13d2d05 126 #warning "Check the board's SPI frequency"
GregCr 0:e6ceb13d2d05 127 #endif
GregCr 0:e6ceb13d2d05 128 wait(0.1);
GregCr 0:e6ceb13d2d05 129 }
GregCr 0:e6ceb13d2d05 130
GregCr 0:e6ceb13d2d05 131 void SX1276MB1xAS::IoIrqInit( DioIrqHandler *irqHandlers )
GregCr 0:e6ceb13d2d05 132 {
GregCr 0:e6ceb13d2d05 133 #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_LPC11U6X ) )
GregCr 0:e6ceb13d2d05 134 dio0.mode(PullDown);
GregCr 0:e6ceb13d2d05 135 dio1.mode(PullDown);
GregCr 0:e6ceb13d2d05 136 dio2.mode(PullDown);
GregCr 0:e6ceb13d2d05 137 dio3.mode(PullDown);
GregCr 0:e6ceb13d2d05 138 dio4.mode(PullDown);
GregCr 0:e6ceb13d2d05 139 #endif
GregCr 0:e6ceb13d2d05 140 dio0.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[0] ) );
GregCr 0:e6ceb13d2d05 141 dio1.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[1] ) );
GregCr 0:e6ceb13d2d05 142 dio2.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[2] ) );
GregCr 0:e6ceb13d2d05 143 dio3.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[3] ) );
GregCr 0:e6ceb13d2d05 144 dio4.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[4] ) );
GregCr 0:e6ceb13d2d05 145 }
GregCr 0:e6ceb13d2d05 146
GregCr 0:e6ceb13d2d05 147 void SX1276MB1xAS::IoDeInit( void )
GregCr 0:e6ceb13d2d05 148 {
GregCr 0:e6ceb13d2d05 149 //nothing
GregCr 0:e6ceb13d2d05 150 }
GregCr 0:e6ceb13d2d05 151
GregCr 0:e6ceb13d2d05 152 uint8_t SX1276MB1xAS::GetPaSelect( uint32_t channel )
GregCr 0:e6ceb13d2d05 153 {
GregCr 0:e6ceb13d2d05 154 if( channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 155 {
GregCr 0:e6ceb13d2d05 156 return RF_PACONFIG_PASELECT_PABOOST;
GregCr 0:e6ceb13d2d05 157 }
GregCr 0:e6ceb13d2d05 158 else
GregCr 0:e6ceb13d2d05 159 {
GregCr 0:e6ceb13d2d05 160 return RF_PACONFIG_PASELECT_RFO;
GregCr 0:e6ceb13d2d05 161 }
GregCr 0:e6ceb13d2d05 162 }
GregCr 0:e6ceb13d2d05 163
GregCr 0:e6ceb13d2d05 164 void SX1276MB1xAS::SetAntSwLowPower( bool status )
GregCr 0:e6ceb13d2d05 165 {
GregCr 0:e6ceb13d2d05 166 if( isRadioActive != status )
GregCr 0:e6ceb13d2d05 167 {
GregCr 0:e6ceb13d2d05 168 isRadioActive = status;
GregCr 0:e6ceb13d2d05 169
GregCr 0:e6ceb13d2d05 170 if( status == false )
GregCr 0:e6ceb13d2d05 171 {
GregCr 0:e6ceb13d2d05 172 AntSwInit( );
GregCr 0:e6ceb13d2d05 173 }
GregCr 0:e6ceb13d2d05 174 else
GregCr 0:e6ceb13d2d05 175 {
GregCr 0:e6ceb13d2d05 176 AntSwDeInit( );
GregCr 0:e6ceb13d2d05 177 }
GregCr 0:e6ceb13d2d05 178 }
GregCr 0:e6ceb13d2d05 179 }
GregCr 0:e6ceb13d2d05 180
GregCr 0:e6ceb13d2d05 181 void SX1276MB1xAS::AntSwInit( void )
GregCr 0:e6ceb13d2d05 182 {
GregCr 0:e6ceb13d2d05 183 antSwitch = 0;
GregCr 0:e6ceb13d2d05 184 }
GregCr 0:e6ceb13d2d05 185
GregCr 0:e6ceb13d2d05 186 void SX1276MB1xAS::AntSwDeInit( void )
GregCr 0:e6ceb13d2d05 187 {
GregCr 0:e6ceb13d2d05 188 antSwitch = 0;
GregCr 0:e6ceb13d2d05 189 }
GregCr 0:e6ceb13d2d05 190
GregCr 0:e6ceb13d2d05 191 void SX1276MB1xAS::SetAntSw( uint8_t rxTx )
GregCr 0:e6ceb13d2d05 192 {
GregCr 0:e6ceb13d2d05 193 if( this->rxTx == rxTx )
GregCr 0:e6ceb13d2d05 194 {
GregCr 0:e6ceb13d2d05 195 //no need to go further
GregCr 0:e6ceb13d2d05 196 return;
GregCr 0:e6ceb13d2d05 197 }
GregCr 0:e6ceb13d2d05 198
GregCr 0:e6ceb13d2d05 199 this->rxTx = rxTx;
GregCr 0:e6ceb13d2d05 200
GregCr 0:e6ceb13d2d05 201 if( rxTx != 0 )
GregCr 0:e6ceb13d2d05 202 {
GregCr 0:e6ceb13d2d05 203 antSwitch = 1;
GregCr 0:e6ceb13d2d05 204 }
GregCr 0:e6ceb13d2d05 205 else
GregCr 0:e6ceb13d2d05 206 {
GregCr 0:e6ceb13d2d05 207 antSwitch = 0;
GregCr 0:e6ceb13d2d05 208 }
GregCr 0:e6ceb13d2d05 209 }
GregCr 0:e6ceb13d2d05 210
GregCr 0:e6ceb13d2d05 211 bool SX1276MB1xAS::CheckRfFrequency( uint32_t frequency )
GregCr 0:e6ceb13d2d05 212 {
GregCr 0:e6ceb13d2d05 213 //TODO: Implement check, currently all frequencies are supported
GregCr 0:e6ceb13d2d05 214 return true;
GregCr 0:e6ceb13d2d05 215 }
GregCr 0:e6ceb13d2d05 216
GregCr 0:e6ceb13d2d05 217
GregCr 0:e6ceb13d2d05 218 void SX1276MB1xAS::Reset( void )
GregCr 0:e6ceb13d2d05 219 {
GregCr 0:e6ceb13d2d05 220 reset = 0;
GregCr 0:e6ceb13d2d05 221 wait_ms( 1 );
GregCr 0:e6ceb13d2d05 222 reset = 1;
GregCr 0:e6ceb13d2d05 223 wait_ms( 6 );
GregCr 0:e6ceb13d2d05 224 }
GregCr 0:e6ceb13d2d05 225
GregCr 0:e6ceb13d2d05 226 void SX1276MB1xAS::Write( uint8_t addr, uint8_t data )
GregCr 0:e6ceb13d2d05 227 {
GregCr 0:e6ceb13d2d05 228 Write( addr, &data, 1 );
GregCr 0:e6ceb13d2d05 229 }
GregCr 0:e6ceb13d2d05 230
GregCr 0:e6ceb13d2d05 231 uint8_t SX1276MB1xAS::Read( uint8_t addr )
GregCr 0:e6ceb13d2d05 232 {
GregCr 0:e6ceb13d2d05 233 uint8_t data;
GregCr 0:e6ceb13d2d05 234 Read( addr, &data, 1 );
GregCr 0:e6ceb13d2d05 235 return data;
GregCr 0:e6ceb13d2d05 236 }
GregCr 0:e6ceb13d2d05 237
GregCr 0:e6ceb13d2d05 238 void SX1276MB1xAS::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 239 {
GregCr 0:e6ceb13d2d05 240 uint8_t i;
GregCr 0:e6ceb13d2d05 241
GregCr 0:e6ceb13d2d05 242 nss = 0;
GregCr 0:e6ceb13d2d05 243 spi.write( addr | 0x80 );
GregCr 0:e6ceb13d2d05 244 for( i = 0; i < size; i++ )
GregCr 0:e6ceb13d2d05 245 {
GregCr 0:e6ceb13d2d05 246 spi.write( buffer[i] );
GregCr 0:e6ceb13d2d05 247 }
GregCr 0:e6ceb13d2d05 248 nss = 1;
GregCr 0:e6ceb13d2d05 249 }
GregCr 0:e6ceb13d2d05 250
GregCr 0:e6ceb13d2d05 251 void SX1276MB1xAS::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 252 {
GregCr 0:e6ceb13d2d05 253 uint8_t i;
GregCr 0:e6ceb13d2d05 254
GregCr 0:e6ceb13d2d05 255 nss = 0;
GregCr 0:e6ceb13d2d05 256 spi.write( addr & 0x7F );
GregCr 0:e6ceb13d2d05 257 for( i = 0; i < size; i++ )
GregCr 0:e6ceb13d2d05 258 {
GregCr 0:e6ceb13d2d05 259 buffer[i] = spi.write( 0 );
GregCr 0:e6ceb13d2d05 260 }
GregCr 0:e6ceb13d2d05 261 nss = 1;
GregCr 0:e6ceb13d2d05 262 }
GregCr 0:e6ceb13d2d05 263
GregCr 0:e6ceb13d2d05 264 void SX1276MB1xAS::WriteFifo( uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 265 {
GregCr 0:e6ceb13d2d05 266 Write( 0, buffer, size );
GregCr 0:e6ceb13d2d05 267 }
GregCr 0:e6ceb13d2d05 268
GregCr 0:e6ceb13d2d05 269 void SX1276MB1xAS::ReadFifo( uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 270 {
GregCr 0:e6ceb13d2d05 271 Read( 0, buffer, size );
GregCr 0:e6ceb13d2d05 272 }