1

Committer:
floatlei
Date:
Sat Oct 08 02:35:14 2016 +0000
Revision:
0:7e14d7c443f1
11

Who changed what in which revision?

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