SX1261 and sx1262 common library

Dependents:   SX126xDevKit SX1262PingPong SX126X_TXonly SX126X_PingPong_Demo ... more

Fork of SX126xLib by Gregory Cristian

Committer:
GregCr
Date:
Mon Sep 04 15:16:44 2017 +0000
Revision:
4:c6ef863d0b07
Parent:
3:7e3595a9ebe0
Child:
5:e488e6f185f3
Candidate release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GregCr 0:deaafdfde3bb 1 /*
GregCr 0:deaafdfde3bb 2 / _____) _ | |
GregCr 0:deaafdfde3bb 3 ( (____ _____ ____ _| |_ _____ ____| |__
GregCr 0:deaafdfde3bb 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
GregCr 0:deaafdfde3bb 5 _____) ) ____| | | || |_| ____( (___| | | |
GregCr 0:deaafdfde3bb 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
GregCr 0:deaafdfde3bb 7 (C)2016 Semtech
GregCr 0:deaafdfde3bb 8
GregCr 0:deaafdfde3bb 9 Description: Handling of the node configuration protocol
GregCr 0:deaafdfde3bb 10
GregCr 0:deaafdfde3bb 11 License: Revised BSD License, see LICENSE.TXT file include in the project
GregCr 0:deaafdfde3bb 12
GregCr 0:deaafdfde3bb 13 Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy
GregCr 0:deaafdfde3bb 14 */
GregCr 1:35d34672a089 15 #include "sx126x-hal.h"
GregCr 0:deaafdfde3bb 16
GregCr 4:c6ef863d0b07 17 /*!
GregCr 4:c6ef863d0b07 18 * \brief Helper macro to create Interrupt objects only if the pin name is
GregCr 4:c6ef863d0b07 19 * different from NC
GregCr 4:c6ef863d0b07 20 */
GregCr 4:c6ef863d0b07 21 #define CreateDioPin( pinName, dio ) \
GregCr 4:c6ef863d0b07 22 if( pinName == NC ) \
GregCr 4:c6ef863d0b07 23 { \
GregCr 4:c6ef863d0b07 24 dio = NULL; \
GregCr 4:c6ef863d0b07 25 } \
GregCr 4:c6ef863d0b07 26 else \
GregCr 4:c6ef863d0b07 27 { \
GregCr 4:c6ef863d0b07 28 dio = new InterruptIn( pinName ); \
GregCr 4:c6ef863d0b07 29 }
GregCr 4:c6ef863d0b07 30
GregCr 4:c6ef863d0b07 31 /*!
GregCr 4:c6ef863d0b07 32 * \brief Helper macro to avoid duplicating code for setting dio pins parameters
GregCr 4:c6ef863d0b07 33 */
GregCr 4:c6ef863d0b07 34 #define DioAssignCallback( dio, pinMode, callback ) \
GregCr 4:c6ef863d0b07 35 if( dio != NULL ) \
GregCr 4:c6ef863d0b07 36 { \
GregCr 4:c6ef863d0b07 37 dio->mode( pinMode ); \
GregCr 4:c6ef863d0b07 38 dio->rise( this, static_cast <Trigger>( callback ) ); \
GregCr 4:c6ef863d0b07 39 }
GregCr 0:deaafdfde3bb 40
GregCr 0:deaafdfde3bb 41 /*!
GregCr 0:deaafdfde3bb 42 * \brief Used to block execution waiting for low state on radio busy pin.
GregCr 0:deaafdfde3bb 43 */
GregCr 4:c6ef863d0b07 44 #define WaitOnBusy( ) while( BUSY == 1 ){ }
GregCr 0:deaafdfde3bb 45
GregCr 0:deaafdfde3bb 46 /*!
GregCr 4:c6ef863d0b07 47 * \brief Used to block execution to give enough time to Busy to go up
GregCr 0:deaafdfde3bb 48 */
GregCr 4:c6ef863d0b07 49 #define WaitOnCounter( ) for( uint8_t counter = 0; counter < 15; counter++ ) \
GregCr 4:c6ef863d0b07 50 { __nop( ); }
GregCr 0:deaafdfde3bb 51
GregCr 4:c6ef863d0b07 52
GregCr 4:c6ef863d0b07 53 // This code handles cases where assert_param is undefined
GregCr 4:c6ef863d0b07 54 #ifndef assert_param
GregCr 4:c6ef863d0b07 55 #define assert_param( ... )
GregCr 4:c6ef863d0b07 56 #endif
GregCr 0:deaafdfde3bb 57
GregCr 4:c6ef863d0b07 58 SX126xHal::SX126xHal( PinName mosi, PinName miso, PinName sclk, PinName nss,
GregCr 4:c6ef863d0b07 59 PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst,
GregCr 4:c6ef863d0b07 60 PinName deviceSelect, PinName antSwPower, RadioCallbacks_t *callbacks )
GregCr 4:c6ef863d0b07 61 : SX126x( callbacks ),
GregCr 0:deaafdfde3bb 62 RadioNss( nss ),
GregCr 0:deaafdfde3bb 63 RadioReset( rst ),
GregCr 0:deaafdfde3bb 64 BUSY( busy ),
GregCr 4:c6ef863d0b07 65 DeviceSelect( deviceSelect ),
GregCr 4:c6ef863d0b07 66 antSwitchPower( antSwPower )
GregCr 0:deaafdfde3bb 67 {
GregCr 4:c6ef863d0b07 68 CreateDioPin( dio1, DIO1 );
GregCr 4:c6ef863d0b07 69 CreateDioPin( dio2, DIO2 );
GregCr 4:c6ef863d0b07 70 CreateDioPin( dio3, DIO3 );
GregCr 0:deaafdfde3bb 71 RadioSpi = new SPI( mosi, miso, sclk );
GregCr 0:deaafdfde3bb 72
GregCr 0:deaafdfde3bb 73 RadioNss = 1;
GregCr 0:deaafdfde3bb 74 RadioReset = 1;
GregCr 0:deaafdfde3bb 75 }
GregCr 0:deaafdfde3bb 76
GregCr 4:c6ef863d0b07 77 SX126xHal::~SX126xHal( void )
GregCr 0:deaafdfde3bb 78 {
GregCr 4:c6ef863d0b07 79 if( this->RadioSpi != NULL )
GregCr 4:c6ef863d0b07 80 {
GregCr 4:c6ef863d0b07 81 delete RadioSpi;
GregCr 4:c6ef863d0b07 82 }
GregCr 4:c6ef863d0b07 83 if( DIO1 != NULL )
GregCr 4:c6ef863d0b07 84 {
GregCr 4:c6ef863d0b07 85 delete DIO1;
GregCr 4:c6ef863d0b07 86 }
GregCr 4:c6ef863d0b07 87 if( DIO2 != NULL )
GregCr 4:c6ef863d0b07 88 {
GregCr 4:c6ef863d0b07 89 delete DIO2;
GregCr 4:c6ef863d0b07 90 }
GregCr 4:c6ef863d0b07 91 if( DIO3 != NULL )
GregCr 4:c6ef863d0b07 92 {
GregCr 4:c6ef863d0b07 93 delete DIO3;
GregCr 4:c6ef863d0b07 94 }
GregCr 4:c6ef863d0b07 95 };
GregCr 0:deaafdfde3bb 96
GregCr 2:4ff11ea92fbe 97 void SX126xHal::SpiInit( void )
GregCr 0:deaafdfde3bb 98 {
GregCr 0:deaafdfde3bb 99 RadioNss = 1;
GregCr 0:deaafdfde3bb 100 RadioSpi->format( 8, 0 );
GregCr 2:4ff11ea92fbe 101 RadioSpi->frequency( SX126x_SPI_FREQ_DEFAULT );
GregCr 0:deaafdfde3bb 102
GregCr 0:deaafdfde3bb 103 wait( 0.1 );
GregCr 0:deaafdfde3bb 104 }
GregCr 0:deaafdfde3bb 105
GregCr 0:deaafdfde3bb 106
GregCr 2:4ff11ea92fbe 107 void SX126xHal::IoIrqInit( DioIrqHandler irqHandler )
GregCr 0:deaafdfde3bb 108 {
GregCr 4:c6ef863d0b07 109 assert_param( RadioSpi != NULL );
GregCr 0:deaafdfde3bb 110 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 111 {
GregCr 0:deaafdfde3bb 112 SpiInit( );
GregCr 0:deaafdfde3bb 113 }
GregCr 0:deaafdfde3bb 114
GregCr 4:c6ef863d0b07 115 BUSY.mode( PullNone );
GregCr 4:c6ef863d0b07 116 DioAssignCallback( DIO1, PullNone, irqHandler );
GregCr 4:c6ef863d0b07 117 // DioAssignCallback( DIO2, PullNone, irqHandler );
GregCr 4:c6ef863d0b07 118 // DioAssignCallback( DIO3, PullNone, irqHandler );
GregCr 0:deaafdfde3bb 119
GregCr 0:deaafdfde3bb 120 }
GregCr 0:deaafdfde3bb 121
GregCr 2:4ff11ea92fbe 122 void SX126xHal::Reset( void )
GregCr 0:deaafdfde3bb 123 {
GregCr 0:deaafdfde3bb 124 __disable_irq( );
GregCr 4:c6ef863d0b07 125 wait_ms( 20 );
GregCr 4:c6ef863d0b07 126 RadioReset.output( );
GregCr 0:deaafdfde3bb 127 RadioReset = 0;
GregCr 4:c6ef863d0b07 128 wait_ms( 50 );
GregCr 0:deaafdfde3bb 129 RadioReset = 1;
GregCr 4:c6ef863d0b07 130 RadioReset.input( ); // Using the internal pull-up
GregCr 4:c6ef863d0b07 131 wait_ms( 20 );
GregCr 0:deaafdfde3bb 132 __enable_irq( );
GregCr 0:deaafdfde3bb 133 }
GregCr 0:deaafdfde3bb 134
GregCr 2:4ff11ea92fbe 135 void SX126xHal::Wakeup( void )
GregCr 0:deaafdfde3bb 136 {
GregCr 0:deaafdfde3bb 137 __disable_irq( );
GregCr 0:deaafdfde3bb 138
GregCr 4:c6ef863d0b07 139 //Don't wait for BUSY here
GregCr 0:deaafdfde3bb 140
GregCr 0:deaafdfde3bb 141 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 142 {
GregCr 0:deaafdfde3bb 143 RadioNss = 0;
GregCr 0:deaafdfde3bb 144 RadioSpi->write( RADIO_GET_STATUS );
GregCr 0:deaafdfde3bb 145 RadioSpi->write( 0 );
GregCr 0:deaafdfde3bb 146 RadioNss = 1;
GregCr 0:deaafdfde3bb 147 }
GregCr 0:deaafdfde3bb 148
GregCr 0:deaafdfde3bb 149 // Wait for chip to be ready.
GregCr 4:c6ef863d0b07 150 WaitOnBusy( );
GregCr 0:deaafdfde3bb 151
GregCr 0:deaafdfde3bb 152 __enable_irq( );
GregCr 4:c6ef863d0b07 153
GregCr 4:c6ef863d0b07 154 AntSwOn( );
GregCr 0:deaafdfde3bb 155 }
GregCr 0:deaafdfde3bb 156
GregCr 2:4ff11ea92fbe 157 void SX126xHal::WriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
GregCr 0:deaafdfde3bb 158 {
GregCr 4:c6ef863d0b07 159 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 160 printf("cmd: 0x%02x", command );
GregCr 4:c6ef863d0b07 161 for( uint8_t i = 0; i < size; i++ )
GregCr 4:c6ef863d0b07 162 {
GregCr 4:c6ef863d0b07 163 printf("-%02x", buffer[i] );
GregCr 4:c6ef863d0b07 164 }
GregCr 4:c6ef863d0b07 165 printf("\n\r");
GregCr 4:c6ef863d0b07 166 #endif
GregCr 4:c6ef863d0b07 167
GregCr 4:c6ef863d0b07 168 WaitOnBusy( );
GregCr 0:deaafdfde3bb 169
GregCr 0:deaafdfde3bb 170 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 171 {
GregCr 0:deaafdfde3bb 172 RadioNss = 0;
GregCr 0:deaafdfde3bb 173 RadioSpi->write( ( uint8_t )command );
GregCr 0:deaafdfde3bb 174 for( uint16_t i = 0; i < size; i++ )
GregCr 0:deaafdfde3bb 175 {
GregCr 0:deaafdfde3bb 176 RadioSpi->write( buffer[i] );
GregCr 0:deaafdfde3bb 177 }
GregCr 0:deaafdfde3bb 178 RadioNss = 1;
GregCr 0:deaafdfde3bb 179 }
GregCr 4:c6ef863d0b07 180 WaitOnCounter( );
GregCr 0:deaafdfde3bb 181 }
GregCr 0:deaafdfde3bb 182
GregCr 2:4ff11ea92fbe 183 void SX126xHal::ReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
GregCr 0:deaafdfde3bb 184 {
GregCr 4:c6ef863d0b07 185 WaitOnBusy( );
GregCr 0:deaafdfde3bb 186
GregCr 0:deaafdfde3bb 187 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 188 {
GregCr 0:deaafdfde3bb 189 RadioNss = 0;
GregCr 0:deaafdfde3bb 190 RadioSpi->write( ( uint8_t )command );
GregCr 0:deaafdfde3bb 191 RadioSpi->write( 0 );
GregCr 0:deaafdfde3bb 192 for( uint16_t i = 0; i < size; i++ )
GregCr 0:deaafdfde3bb 193 {
GregCr 0:deaafdfde3bb 194 buffer[i] = RadioSpi->write( 0 );
GregCr 0:deaafdfde3bb 195 }
GregCr 0:deaafdfde3bb 196 RadioNss = 1;
GregCr 0:deaafdfde3bb 197 }
GregCr 0:deaafdfde3bb 198 }
GregCr 0:deaafdfde3bb 199
GregCr 2:4ff11ea92fbe 200 void SX126xHal::WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size )
GregCr 0:deaafdfde3bb 201 {
GregCr 4:c6ef863d0b07 202 WaitOnBusy( );
GregCr 0:deaafdfde3bb 203
GregCr 0:deaafdfde3bb 204 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 205 {
GregCr 0:deaafdfde3bb 206 RadioNss = 0;
GregCr 0:deaafdfde3bb 207 RadioSpi->write( RADIO_WRITE_REGISTER );
GregCr 0:deaafdfde3bb 208 RadioSpi->write( ( address & 0xFF00 ) >> 8 );
GregCr 0:deaafdfde3bb 209 RadioSpi->write( address & 0x00FF );
GregCr 0:deaafdfde3bb 210 for( uint16_t i = 0; i < size; i++ )
GregCr 0:deaafdfde3bb 211 {
GregCr 0:deaafdfde3bb 212 RadioSpi->write( buffer[i] );
GregCr 0:deaafdfde3bb 213 }
GregCr 0:deaafdfde3bb 214 RadioNss = 1;
GregCr 0:deaafdfde3bb 215 }
GregCr 0:deaafdfde3bb 216 }
GregCr 0:deaafdfde3bb 217
GregCr 4:c6ef863d0b07 218 void SX126xHal::WriteReg( uint16_t address, uint8_t value )
GregCr 0:deaafdfde3bb 219 {
GregCr 0:deaafdfde3bb 220 WriteRegister( address, &value, 1 );
GregCr 0:deaafdfde3bb 221 }
GregCr 0:deaafdfde3bb 222
GregCr 2:4ff11ea92fbe 223 void SX126xHal::ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size )
GregCr 0:deaafdfde3bb 224 {
GregCr 4:c6ef863d0b07 225 WaitOnBusy( );
GregCr 0:deaafdfde3bb 226
GregCr 0:deaafdfde3bb 227 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 228 {
GregCr 0:deaafdfde3bb 229 RadioNss = 0;
GregCr 0:deaafdfde3bb 230 RadioSpi->write( RADIO_READ_REGISTER );
GregCr 0:deaafdfde3bb 231 RadioSpi->write( ( address & 0xFF00 ) >> 8 );
GregCr 0:deaafdfde3bb 232 RadioSpi->write( address & 0x00FF );
GregCr 0:deaafdfde3bb 233 RadioSpi->write( 0 );
GregCr 0:deaafdfde3bb 234 for( uint16_t i = 0; i < size; i++ )
GregCr 0:deaafdfde3bb 235 {
GregCr 0:deaafdfde3bb 236 buffer[i] = RadioSpi->write( 0 );
GregCr 0:deaafdfde3bb 237 }
GregCr 0:deaafdfde3bb 238 RadioNss = 1;
GregCr 0:deaafdfde3bb 239 }
GregCr 0:deaafdfde3bb 240 }
GregCr 0:deaafdfde3bb 241
GregCr 4:c6ef863d0b07 242 uint8_t SX126xHal::ReadReg( uint16_t address )
GregCr 0:deaafdfde3bb 243 {
GregCr 0:deaafdfde3bb 244 uint8_t data;
GregCr 0:deaafdfde3bb 245
GregCr 0:deaafdfde3bb 246 ReadRegister( address, &data, 1 );
GregCr 0:deaafdfde3bb 247 return data;
GregCr 0:deaafdfde3bb 248 }
GregCr 0:deaafdfde3bb 249
GregCr 2:4ff11ea92fbe 250 void SX126xHal::WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
GregCr 0:deaafdfde3bb 251 {
GregCr 4:c6ef863d0b07 252 WaitOnBusy( );
GregCr 0:deaafdfde3bb 253
GregCr 0:deaafdfde3bb 254 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 255 {
GregCr 0:deaafdfde3bb 256 RadioNss = 0;
GregCr 0:deaafdfde3bb 257 RadioSpi->write( RADIO_WRITE_BUFFER );
GregCr 0:deaafdfde3bb 258 RadioSpi->write( offset );
GregCr 0:deaafdfde3bb 259 for( uint16_t i = 0; i < size; i++ )
GregCr 0:deaafdfde3bb 260 {
GregCr 0:deaafdfde3bb 261 RadioSpi->write( buffer[i] );
GregCr 0:deaafdfde3bb 262 }
GregCr 0:deaafdfde3bb 263 RadioNss = 1;
GregCr 0:deaafdfde3bb 264 }
GregCr 0:deaafdfde3bb 265 }
GregCr 0:deaafdfde3bb 266
GregCr 2:4ff11ea92fbe 267 void SX126xHal::ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
GregCr 0:deaafdfde3bb 268 {
GregCr 4:c6ef863d0b07 269 WaitOnBusy( );
GregCr 0:deaafdfde3bb 270
GregCr 0:deaafdfde3bb 271 if( RadioSpi != NULL )
GregCr 0:deaafdfde3bb 272 {
GregCr 0:deaafdfde3bb 273 RadioNss = 0;
GregCr 0:deaafdfde3bb 274 RadioSpi->write( RADIO_READ_BUFFER );
GregCr 0:deaafdfde3bb 275 RadioSpi->write( offset );
GregCr 0:deaafdfde3bb 276 RadioSpi->write( 0 );
GregCr 0:deaafdfde3bb 277 for( uint16_t i = 0; i < size; i++ )
GregCr 0:deaafdfde3bb 278 {
GregCr 0:deaafdfde3bb 279 buffer[i] = RadioSpi->write( 0 );
GregCr 0:deaafdfde3bb 280 }
GregCr 0:deaafdfde3bb 281 RadioNss = 1;
GregCr 0:deaafdfde3bb 282 }
GregCr 0:deaafdfde3bb 283 }
GregCr 0:deaafdfde3bb 284
GregCr 2:4ff11ea92fbe 285 uint8_t SX126xHal::GetDioStatus( void )
GregCr 0:deaafdfde3bb 286 {
GregCr 4:c6ef863d0b07 287 return ( *DIO3 << 3 ) | ( *DIO2 << 2 ) | ( *DIO1 << 1 ) | ( BUSY << 0 );
GregCr 4:c6ef863d0b07 288 }
GregCr 4:c6ef863d0b07 289
GregCr 4:c6ef863d0b07 290 uint8_t SX126xHal::GetDeviceType( void )
GregCr 4:c6ef863d0b07 291 {
GregCr 4:c6ef863d0b07 292 return( DeviceSelect.read( ) );
GregCr 0:deaafdfde3bb 293 }
GregCr 0:deaafdfde3bb 294
GregCr 4:c6ef863d0b07 295 void SX126xHal::AntSwOn( void )
GregCr 4:c6ef863d0b07 296 {
GregCr 4:c6ef863d0b07 297 antSwitchPower = 1;
GregCr 4:c6ef863d0b07 298 }
GregCr 0:deaafdfde3bb 299
GregCr 4:c6ef863d0b07 300 void SX126xHal::AntSwOff( void )
GregCr 4:c6ef863d0b07 301 {
GregCr 4:c6ef863d0b07 302 antSwitchPower = 0;
GregCr 4:c6ef863d0b07 303 }