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:
mluis
Date:
Thu Jan 22 12:47:47 2015 +0000
Revision:
15:04374b1c33fa
Parent:
12:aa5b3bf7fdf4
Enabled by default the whitening when using FSK modem.; Added an invalid bandwidth to the Bandwidths table in order to avoid an error when selecting 250 kHz bandwidth when using FSK modem.

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 8:0fe3e0e8007b 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 },
mluis 15:04374b1c33fa 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 7:2b555111463f 36 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
GregCr 12:aa5b3bf7fdf4 37 void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ),
GregCr 0:e6ceb13d2d05 38 PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
GregCr 0:e6ceb13d2d05 39 PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
GregCr 0:e6ceb13d2d05 40 PinName antSwitch )
GregCr 7:2b555111463f 41 : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, mosi, miso, sclk, nss, reset, dio0, dio1, dio2, dio3, dio4, dio5),
GregCr 0:e6ceb13d2d05 42 antSwitch( antSwitch ),
GregCr 12:aa5b3bf7fdf4 43 #if( defined ( TARGET_NUCLEO_L152RE ) )
GregCr 12:aa5b3bf7fdf4 44 fake( D8 )
GregCr 12:aa5b3bf7fdf4 45 #else
GregCr 0:e6ceb13d2d05 46 fake( A3 )
GregCr 0:e6ceb13d2d05 47 #endif
GregCr 0:e6ceb13d2d05 48 {
GregCr 0:e6ceb13d2d05 49 Reset( );
GregCr 0:e6ceb13d2d05 50
GregCr 0:e6ceb13d2d05 51 RxChainCalibration( );
GregCr 0:e6ceb13d2d05 52
GregCr 0:e6ceb13d2d05 53 IoInit( );
GregCr 0:e6ceb13d2d05 54
GregCr 0:e6ceb13d2d05 55 SetOpMode( RF_OPMODE_SLEEP );
GregCr 0:e6ceb13d2d05 56
GregCr 0:e6ceb13d2d05 57 IoIrqInit( dioIrq );
GregCr 0:e6ceb13d2d05 58
GregCr 0:e6ceb13d2d05 59 RadioRegistersInit( );
GregCr 0:e6ceb13d2d05 60
GregCr 0:e6ceb13d2d05 61 SetModem( MODEM_FSK );
GregCr 0:e6ceb13d2d05 62
GregCr 0:e6ceb13d2d05 63 this->settings.State = IDLE ;
GregCr 0:e6ceb13d2d05 64 }
GregCr 0:e6ceb13d2d05 65
GregCr 7:2b555111463f 66 SX1276MB1xAS::SX1276MB1xAS( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
GregCr 12:aa5b3bf7fdf4 67 void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool ChannelActivityDetected ) )
GregCr 12:aa5b3bf7fdf4 68 #if defined ( TARGET_NUCLEO_L152RE )
GregCr 7:2b555111463f 69 : 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
GregCr 0:e6ceb13d2d05 70 antSwitch( A4 ),
GregCr 0:e6ceb13d2d05 71 fake( D8 )
GregCr 0:e6ceb13d2d05 72 #else
GregCr 12:aa5b3bf7fdf4 73 : SX1276( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone, D11, D12, D13, D10, A0, D2, D3, D4, D5, D8, D9 ),
GregCr 12:aa5b3bf7fdf4 74 antSwitch( A4 ),
GregCr 12:aa5b3bf7fdf4 75 fake( A3 )
GregCr 0:e6ceb13d2d05 76 #endif
GregCr 0:e6ceb13d2d05 77 {
GregCr 0:e6ceb13d2d05 78 Reset( );
GregCr 0:e6ceb13d2d05 79
GregCr 5:11ec8a6ba4f0 80 boardConnected = UNKNOWN;
GregCr 5:11ec8a6ba4f0 81
GregCr 1:f979673946c0 82 DetectBoardType( );
GregCr 1:f979673946c0 83
GregCr 0:e6ceb13d2d05 84 RxChainCalibration( );
GregCr 0:e6ceb13d2d05 85
GregCr 0:e6ceb13d2d05 86 IoInit( );
GregCr 0:e6ceb13d2d05 87
GregCr 0:e6ceb13d2d05 88 SetOpMode( RF_OPMODE_SLEEP );
GregCr 0:e6ceb13d2d05 89 IoIrqInit( dioIrq );
GregCr 0:e6ceb13d2d05 90
GregCr 0:e6ceb13d2d05 91 RadioRegistersInit( );
GregCr 0:e6ceb13d2d05 92
GregCr 0:e6ceb13d2d05 93 SetModem( MODEM_FSK );
GregCr 0:e6ceb13d2d05 94
GregCr 0:e6ceb13d2d05 95 this->settings.State = IDLE ;
GregCr 0:e6ceb13d2d05 96 }
GregCr 0:e6ceb13d2d05 97
GregCr 0:e6ceb13d2d05 98 //-------------------------------------------------------------------------
GregCr 0:e6ceb13d2d05 99 // Board relative functions
GregCr 0:e6ceb13d2d05 100 //-------------------------------------------------------------------------
GregCr 2:5eb3066446dd 101 uint8_t SX1276MB1xAS::DetectBoardType( void )
GregCr 1:f979673946c0 102 {
GregCr 5:11ec8a6ba4f0 103 if( boardConnected == UNKNOWN )
GregCr 1:f979673946c0 104 {
GregCr 5:11ec8a6ba4f0 105 antSwitch.input( );
GregCr 5:11ec8a6ba4f0 106 wait_ms( 1 );
GregCr 5:11ec8a6ba4f0 107 if( antSwitch == 1 )
GregCr 5:11ec8a6ba4f0 108 {
GregCr 5:11ec8a6ba4f0 109 boardConnected = SX1276MB1LAS;
GregCr 5:11ec8a6ba4f0 110 }
GregCr 5:11ec8a6ba4f0 111 else
GregCr 5:11ec8a6ba4f0 112 {
GregCr 5:11ec8a6ba4f0 113 boardConnected = SX1276MB1MAS;
GregCr 5:11ec8a6ba4f0 114 }
GregCr 5:11ec8a6ba4f0 115 antSwitch.output( );
GregCr 5:11ec8a6ba4f0 116 wait_ms( 1 );
GregCr 1:f979673946c0 117 }
GregCr 2:5eb3066446dd 118 return ( boardConnected );
GregCr 1:f979673946c0 119 }
GregCr 0:e6ceb13d2d05 120
GregCr 0:e6ceb13d2d05 121 void SX1276MB1xAS::IoInit( void )
GregCr 0:e6ceb13d2d05 122 {
GregCr 0:e6ceb13d2d05 123 AntSwInit( );
GregCr 0:e6ceb13d2d05 124 SpiInit( );
GregCr 0:e6ceb13d2d05 125 }
GregCr 0:e6ceb13d2d05 126
GregCr 0:e6ceb13d2d05 127 void SX1276MB1xAS::RadioRegistersInit( ){
GregCr 0:e6ceb13d2d05 128 uint8_t i = 0;
GregCr 0:e6ceb13d2d05 129 for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
GregCr 0:e6ceb13d2d05 130 {
GregCr 0:e6ceb13d2d05 131 SetModem( RadioRegsInit[i].Modem );
GregCr 0:e6ceb13d2d05 132 Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
GregCr 0:e6ceb13d2d05 133 }
GregCr 0:e6ceb13d2d05 134 }
GregCr 0:e6ceb13d2d05 135
GregCr 0:e6ceb13d2d05 136 void SX1276MB1xAS::SpiInit( void )
GregCr 0:e6ceb13d2d05 137 {
GregCr 0:e6ceb13d2d05 138 nss = 1;
GregCr 0:e6ceb13d2d05 139 spi.format( 8,0 );
GregCr 0:e6ceb13d2d05 140 uint32_t frequencyToSet = 8000000;
GregCr 0:e6ceb13d2d05 141 #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_LPC11U6X ) )
GregCr 0:e6ceb13d2d05 142 spi.frequency( frequencyToSet );
GregCr 0:e6ceb13d2d05 143 #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate
GregCr 0:e6ceb13d2d05 144 spi.frequency( frequencyToSet * 2 );
GregCr 0:e6ceb13d2d05 145 #else
GregCr 0:e6ceb13d2d05 146 #warning "Check the board's SPI frequency"
GregCr 0:e6ceb13d2d05 147 #endif
GregCr 0:e6ceb13d2d05 148 wait(0.1);
GregCr 0:e6ceb13d2d05 149 }
GregCr 0:e6ceb13d2d05 150
GregCr 0:e6ceb13d2d05 151 void SX1276MB1xAS::IoIrqInit( DioIrqHandler *irqHandlers )
GregCr 0:e6ceb13d2d05 152 {
GregCr 0:e6ceb13d2d05 153 #if( defined ( TARGET_NUCLEO_L152RE ) || defined ( TARGET_LPC11U6X ) )
GregCr 0:e6ceb13d2d05 154 dio0.mode(PullDown);
GregCr 0:e6ceb13d2d05 155 dio1.mode(PullDown);
GregCr 0:e6ceb13d2d05 156 dio2.mode(PullDown);
GregCr 0:e6ceb13d2d05 157 dio3.mode(PullDown);
GregCr 0:e6ceb13d2d05 158 dio4.mode(PullDown);
GregCr 0:e6ceb13d2d05 159 #endif
GregCr 0:e6ceb13d2d05 160 dio0.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[0] ) );
GregCr 0:e6ceb13d2d05 161 dio1.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[1] ) );
GregCr 0:e6ceb13d2d05 162 dio2.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[2] ) );
GregCr 0:e6ceb13d2d05 163 dio3.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[3] ) );
GregCr 0:e6ceb13d2d05 164 dio4.rise( this, static_cast< TriggerMB1xAS > ( irqHandlers[4] ) );
GregCr 0:e6ceb13d2d05 165 }
GregCr 0:e6ceb13d2d05 166
GregCr 0:e6ceb13d2d05 167 void SX1276MB1xAS::IoDeInit( void )
GregCr 0:e6ceb13d2d05 168 {
GregCr 0:e6ceb13d2d05 169 //nothing
GregCr 0:e6ceb13d2d05 170 }
GregCr 0:e6ceb13d2d05 171
GregCr 0:e6ceb13d2d05 172 uint8_t SX1276MB1xAS::GetPaSelect( uint32_t channel )
GregCr 0:e6ceb13d2d05 173 {
GregCr 0:e6ceb13d2d05 174 if( channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 175 {
GregCr 3:ca84be1f3fac 176 if( boardConnected == SX1276MB1LAS )
GregCr 1:f979673946c0 177 {
GregCr 1:f979673946c0 178 return RF_PACONFIG_PASELECT_PABOOST;
GregCr 1:f979673946c0 179 }
GregCr 1:f979673946c0 180 else
GregCr 1:f979673946c0 181 {
GregCr 1:f979673946c0 182 return RF_PACONFIG_PASELECT_RFO;
GregCr 1:f979673946c0 183 }
GregCr 0:e6ceb13d2d05 184 }
GregCr 0:e6ceb13d2d05 185 else
GregCr 0:e6ceb13d2d05 186 {
GregCr 0:e6ceb13d2d05 187 return RF_PACONFIG_PASELECT_RFO;
GregCr 0:e6ceb13d2d05 188 }
GregCr 0:e6ceb13d2d05 189 }
GregCr 0:e6ceb13d2d05 190
GregCr 0:e6ceb13d2d05 191 void SX1276MB1xAS::SetAntSwLowPower( bool status )
GregCr 0:e6ceb13d2d05 192 {
GregCr 0:e6ceb13d2d05 193 if( isRadioActive != status )
GregCr 0:e6ceb13d2d05 194 {
GregCr 0:e6ceb13d2d05 195 isRadioActive = status;
GregCr 0:e6ceb13d2d05 196
GregCr 0:e6ceb13d2d05 197 if( status == false )
GregCr 0:e6ceb13d2d05 198 {
GregCr 0:e6ceb13d2d05 199 AntSwInit( );
GregCr 0:e6ceb13d2d05 200 }
GregCr 0:e6ceb13d2d05 201 else
GregCr 0:e6ceb13d2d05 202 {
GregCr 0:e6ceb13d2d05 203 AntSwDeInit( );
GregCr 0:e6ceb13d2d05 204 }
GregCr 0:e6ceb13d2d05 205 }
GregCr 0:e6ceb13d2d05 206 }
GregCr 0:e6ceb13d2d05 207
GregCr 0:e6ceb13d2d05 208 void SX1276MB1xAS::AntSwInit( void )
GregCr 0:e6ceb13d2d05 209 {
GregCr 0:e6ceb13d2d05 210 antSwitch = 0;
GregCr 0:e6ceb13d2d05 211 }
GregCr 0:e6ceb13d2d05 212
GregCr 0:e6ceb13d2d05 213 void SX1276MB1xAS::AntSwDeInit( void )
GregCr 0:e6ceb13d2d05 214 {
GregCr 0:e6ceb13d2d05 215 antSwitch = 0;
GregCr 0:e6ceb13d2d05 216 }
GregCr 0:e6ceb13d2d05 217
GregCr 0:e6ceb13d2d05 218 void SX1276MB1xAS::SetAntSw( uint8_t rxTx )
GregCr 0:e6ceb13d2d05 219 {
GregCr 0:e6ceb13d2d05 220 if( this->rxTx == rxTx )
GregCr 0:e6ceb13d2d05 221 {
GregCr 0:e6ceb13d2d05 222 //no need to go further
GregCr 0:e6ceb13d2d05 223 return;
GregCr 0:e6ceb13d2d05 224 }
GregCr 0:e6ceb13d2d05 225
GregCr 0:e6ceb13d2d05 226 this->rxTx = rxTx;
GregCr 0:e6ceb13d2d05 227
GregCr 0:e6ceb13d2d05 228 if( rxTx != 0 )
GregCr 0:e6ceb13d2d05 229 {
GregCr 0:e6ceb13d2d05 230 antSwitch = 1;
GregCr 0:e6ceb13d2d05 231 }
GregCr 0:e6ceb13d2d05 232 else
GregCr 0:e6ceb13d2d05 233 {
GregCr 0:e6ceb13d2d05 234 antSwitch = 0;
GregCr 0:e6ceb13d2d05 235 }
GregCr 0:e6ceb13d2d05 236 }
GregCr 0:e6ceb13d2d05 237
GregCr 0:e6ceb13d2d05 238 bool SX1276MB1xAS::CheckRfFrequency( uint32_t frequency )
GregCr 0:e6ceb13d2d05 239 {
GregCr 0:e6ceb13d2d05 240 //TODO: Implement check, currently all frequencies are supported
GregCr 0:e6ceb13d2d05 241 return true;
GregCr 0:e6ceb13d2d05 242 }
GregCr 0:e6ceb13d2d05 243
GregCr 0:e6ceb13d2d05 244
GregCr 0:e6ceb13d2d05 245 void SX1276MB1xAS::Reset( void )
GregCr 0:e6ceb13d2d05 246 {
GregCr 4:f0ce52e94d3f 247 reset.output();
GregCr 0:e6ceb13d2d05 248 reset = 0;
GregCr 0:e6ceb13d2d05 249 wait_ms( 1 );
GregCr 4:f0ce52e94d3f 250 reset.input();
GregCr 0:e6ceb13d2d05 251 wait_ms( 6 );
GregCr 0:e6ceb13d2d05 252 }
GregCr 0:e6ceb13d2d05 253
GregCr 0:e6ceb13d2d05 254 void SX1276MB1xAS::Write( uint8_t addr, uint8_t data )
GregCr 0:e6ceb13d2d05 255 {
GregCr 0:e6ceb13d2d05 256 Write( addr, &data, 1 );
GregCr 0:e6ceb13d2d05 257 }
GregCr 0:e6ceb13d2d05 258
GregCr 0:e6ceb13d2d05 259 uint8_t SX1276MB1xAS::Read( uint8_t addr )
GregCr 0:e6ceb13d2d05 260 {
GregCr 0:e6ceb13d2d05 261 uint8_t data;
GregCr 0:e6ceb13d2d05 262 Read( addr, &data, 1 );
GregCr 0:e6ceb13d2d05 263 return data;
GregCr 0:e6ceb13d2d05 264 }
GregCr 0:e6ceb13d2d05 265
GregCr 0:e6ceb13d2d05 266 void SX1276MB1xAS::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 267 {
GregCr 0:e6ceb13d2d05 268 uint8_t i;
GregCr 0:e6ceb13d2d05 269
GregCr 0:e6ceb13d2d05 270 nss = 0;
GregCr 0:e6ceb13d2d05 271 spi.write( addr | 0x80 );
GregCr 0:e6ceb13d2d05 272 for( i = 0; i < size; i++ )
GregCr 0:e6ceb13d2d05 273 {
GregCr 0:e6ceb13d2d05 274 spi.write( buffer[i] );
GregCr 0:e6ceb13d2d05 275 }
GregCr 0:e6ceb13d2d05 276 nss = 1;
GregCr 0:e6ceb13d2d05 277 }
GregCr 0:e6ceb13d2d05 278
GregCr 0:e6ceb13d2d05 279 void SX1276MB1xAS::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 280 {
GregCr 0:e6ceb13d2d05 281 uint8_t i;
GregCr 0:e6ceb13d2d05 282
GregCr 0:e6ceb13d2d05 283 nss = 0;
GregCr 0:e6ceb13d2d05 284 spi.write( addr & 0x7F );
GregCr 0:e6ceb13d2d05 285 for( i = 0; i < size; i++ )
GregCr 0:e6ceb13d2d05 286 {
GregCr 0:e6ceb13d2d05 287 buffer[i] = spi.write( 0 );
GregCr 0:e6ceb13d2d05 288 }
GregCr 0:e6ceb13d2d05 289 nss = 1;
GregCr 0:e6ceb13d2d05 290 }
GregCr 0:e6ceb13d2d05 291
GregCr 0:e6ceb13d2d05 292 void SX1276MB1xAS::WriteFifo( uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 293 {
GregCr 0:e6ceb13d2d05 294 Write( 0, buffer, size );
GregCr 0:e6ceb13d2d05 295 }
GregCr 0:e6ceb13d2d05 296
GregCr 0:e6ceb13d2d05 297 void SX1276MB1xAS::ReadFifo( uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 298 {
GregCr 0:e6ceb13d2d05 299 Read( 0, buffer, size );
GregCr 0:e6ceb13d2d05 300 }