Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: SX126xDevKit SX1262PingPong SX126X_TXonly SX126X_PingPong_Demo ... more
Fork of SX126xLib by
sx126x-hal.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2016 Semtech 00008 00009 Description: Handling of the node configuration protocol 00010 00011 License: Revised BSD License, see LICENSE.TXT file include in the project 00012 00013 Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy 00014 */ 00015 #include "sx126x-hal.h" 00016 00017 /*! 00018 * \brief Helper macro to create Interrupt objects only if the pin name is 00019 * different from NC 00020 */ 00021 #define CreateDioPin( pinName, dio ) \ 00022 if( pinName == NC ) \ 00023 { \ 00024 dio = NULL; \ 00025 } \ 00026 else \ 00027 { \ 00028 dio = new InterruptIn( pinName ); \ 00029 } 00030 00031 /*! 00032 * \brief Helper macro to avoid duplicating code for setting dio pins parameters 00033 */ 00034 #define DioAssignCallback( dio, pinMode, callback ) \ 00035 if( dio != NULL ) \ 00036 { \ 00037 dio->mode( pinMode ); \ 00038 dio->rise( this, static_cast <Trigger>( callback ) ); \ 00039 } 00040 00041 /*! 00042 * \brief Used to block execution waiting for low state on radio busy pin. 00043 */ 00044 #define WaitOnBusy( ) while( BUSY == 1 ){ } 00045 00046 /*! 00047 * \brief Used to block execution to give enough time to Busy to go up 00048 * in order to respect Tsw, see datasheet ยง8.3.1 00049 */ 00050 #define WaitOnCounter( ) for( uint8_t counter = 0; counter < 15; counter++ ) \ 00051 { __NOP( ); } 00052 00053 00054 // This code handles cases where assert_param is undefined 00055 #ifndef assert_param 00056 #define assert_param( ... ) 00057 #endif 00058 00059 SX126xHal::SX126xHal( PinName mosi, PinName miso, PinName sclk, PinName nss, 00060 PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst, 00061 PinName freqSel, PinName deviceSelect, PinName antSwPower, RadioCallbacks_t *callbacks ) 00062 : SX126x( callbacks ), 00063 RadioNss( nss ), 00064 RadioReset( rst ), 00065 BUSY( busy ), 00066 FreqSelect( freqSel ), 00067 DeviceSelect( deviceSelect ), 00068 antSwitchPower( antSwPower ) 00069 { 00070 CreateDioPin( dio1, DIO1 ); 00071 CreateDioPin( dio2, DIO2 ); 00072 CreateDioPin( dio3, DIO3 ); 00073 RadioSpi = new SPI( mosi, miso, sclk ); 00074 00075 RadioNss = 1; 00076 RadioReset = 1; 00077 } 00078 00079 SX126xHal::~SX126xHal( void ) 00080 { 00081 if( this->RadioSpi != NULL ) 00082 { 00083 delete RadioSpi; 00084 } 00085 if( DIO1 != NULL ) 00086 { 00087 delete DIO1; 00088 } 00089 if( DIO2 != NULL ) 00090 { 00091 delete DIO2; 00092 } 00093 if( DIO3 != NULL ) 00094 { 00095 delete DIO3; 00096 } 00097 }; 00098 00099 void SX126xHal::SpiInit( void ) 00100 { 00101 RadioNss = 1; 00102 RadioSpi->format( 8, 0 ); 00103 RadioSpi->frequency( SX126x_SPI_FREQ_DEFAULT ); 00104 00105 wait( 0.1 ); 00106 } 00107 00108 00109 void SX126xHal::IoIrqInit( DioIrqHandler irqHandler ) 00110 { 00111 assert_param( RadioSpi != NULL ); 00112 if( RadioSpi != NULL ) 00113 { 00114 SpiInit( ); 00115 } 00116 00117 BUSY.mode( PullNone ); 00118 DioAssignCallback( DIO1, PullNone, irqHandler ); 00119 // DioAssignCallback( DIO2, PullNone, irqHandler ); 00120 // DioAssignCallback( DIO3, PullNone, irqHandler ); 00121 00122 } 00123 00124 void SX126xHal::Reset( void ) 00125 { 00126 __disable_irq( ); 00127 wait_ms( 20 ); 00128 RadioReset.output( ); 00129 RadioReset = 0; 00130 wait_ms( 50 ); 00131 RadioReset = 1; 00132 RadioReset.input( ); // Using the internal pull-up 00133 wait_ms( 20 ); 00134 __enable_irq( ); 00135 } 00136 00137 void SX126xHal::Wakeup( void ) 00138 { 00139 __disable_irq( ); 00140 00141 //Don't wait for BUSY here 00142 00143 if( RadioSpi != NULL ) 00144 { 00145 RadioNss = 0; 00146 RadioSpi->write( RADIO_GET_STATUS ); 00147 RadioSpi->write( 0 ); 00148 RadioNss = 1; 00149 } 00150 00151 // Wait for chip to be ready. 00152 WaitOnBusy( ); 00153 00154 __enable_irq( ); 00155 00156 AntSwOn( ); 00157 } 00158 00159 void SX126xHal::WriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 00160 { 00161 #ifdef ADV_DEBUG 00162 printf("cmd: 0x%02x", command ); 00163 for( uint8_t i = 0; i < size; i++ ) 00164 { 00165 printf("-%02x", buffer[i] ); 00166 } 00167 printf("\n\r"); 00168 #endif 00169 00170 WaitOnBusy( ); 00171 00172 if( RadioSpi != NULL ) 00173 { 00174 RadioNss = 0; 00175 RadioSpi->write( ( uint8_t )command ); 00176 for( uint16_t i = 0; i < size; i++ ) 00177 { 00178 RadioSpi->write( buffer[i] ); 00179 } 00180 RadioNss = 1; 00181 } 00182 WaitOnCounter( ); 00183 } 00184 00185 void SX126xHal::ReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 00186 { 00187 WaitOnBusy( ); 00188 00189 if( RadioSpi != NULL ) 00190 { 00191 RadioNss = 0; 00192 RadioSpi->write( ( uint8_t )command ); 00193 RadioSpi->write( 0 ); 00194 for( uint16_t i = 0; i < size; i++ ) 00195 { 00196 buffer[i] = RadioSpi->write( 0 ); 00197 } 00198 RadioNss = 1; 00199 } 00200 } 00201 00202 void SX126xHal::WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size ) 00203 { 00204 WaitOnBusy( ); 00205 00206 if( RadioSpi != NULL ) 00207 { 00208 RadioNss = 0; 00209 RadioSpi->write( RADIO_WRITE_REGISTER ); 00210 RadioSpi->write( ( address & 0xFF00 ) >> 8 ); 00211 RadioSpi->write( address & 0x00FF ); 00212 for( uint16_t i = 0; i < size; i++ ) 00213 { 00214 RadioSpi->write( buffer[i] ); 00215 } 00216 RadioNss = 1; 00217 } 00218 } 00219 00220 void SX126xHal::WriteReg( uint16_t address, uint8_t value ) 00221 { 00222 WriteRegister( address, &value, 1 ); 00223 } 00224 00225 void SX126xHal::ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size ) 00226 { 00227 WaitOnBusy( ); 00228 00229 if( RadioSpi != NULL ) 00230 { 00231 RadioNss = 0; 00232 RadioSpi->write( RADIO_READ_REGISTER ); 00233 RadioSpi->write( ( address & 0xFF00 ) >> 8 ); 00234 RadioSpi->write( address & 0x00FF ); 00235 RadioSpi->write( 0 ); 00236 for( uint16_t i = 0; i < size; i++ ) 00237 { 00238 buffer[i] = RadioSpi->write( 0 ); 00239 } 00240 RadioNss = 1; 00241 } 00242 } 00243 00244 uint8_t SX126xHal::ReadReg( uint16_t address ) 00245 { 00246 uint8_t data; 00247 00248 ReadRegister( address, &data, 1 ); 00249 return data; 00250 } 00251 00252 void SX126xHal::WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 00253 { 00254 WaitOnBusy( ); 00255 00256 if( RadioSpi != NULL ) 00257 { 00258 RadioNss = 0; 00259 RadioSpi->write( RADIO_WRITE_BUFFER ); 00260 RadioSpi->write( offset ); 00261 for( uint16_t i = 0; i < size; i++ ) 00262 { 00263 RadioSpi->write( buffer[i] ); 00264 } 00265 RadioNss = 1; 00266 } 00267 } 00268 00269 void SX126xHal::ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 00270 { 00271 WaitOnBusy( ); 00272 00273 if( RadioSpi != NULL ) 00274 { 00275 RadioNss = 0; 00276 RadioSpi->write( RADIO_READ_BUFFER ); 00277 RadioSpi->write( offset ); 00278 RadioSpi->write( 0 ); 00279 for( uint16_t i = 0; i < size; i++ ) 00280 { 00281 buffer[i] = RadioSpi->write( 0 ); 00282 } 00283 RadioNss = 1; 00284 } 00285 } 00286 00287 uint8_t SX126xHal::GetDioStatus( void ) 00288 { 00289 return ( *DIO3 << 3 ) | ( *DIO2 << 2 ) | ( *DIO1 << 1 ) | ( BUSY << 0 ); 00290 } 00291 00292 uint8_t SX126xHal::GetDeviceType( void ) 00293 { 00294 uint16_t val = 0; 00295 val = DeviceSelect.read_u16( ); 00296 00297 if( val <= 0x2000 ) 00298 { 00299 return( SX1262 ); 00300 } 00301 else if( val <= 0xA000 ) 00302 { 00303 return( SX1268 ); 00304 } 00305 else 00306 { 00307 return( SX1261 ); 00308 } 00309 } 00310 00311 uint8_t SX126xHal::GetFreqSelect( void ) 00312 { 00313 uint16_t val = 0; 00314 val = FreqSelect.read_u16( ); 00315 00316 if( val < 100 ) 00317 { 00318 return( MATCHING_FREQ_915 ); 00319 } 00320 else if( val <= 0x3000 ) 00321 { 00322 return( MATCHING_FREQ_780 ); 00323 } 00324 else if( val <= 0x4900 ) // 0x4724 00325 { 00326 return( MATCHING_FREQ_490 ); 00327 } 00328 else if( val <= 1 ) 00329 { 00330 return( MATCHING_FREQ_434 ); 00331 } 00332 else if( val <= 1 ) 00333 { 00334 return( MATCHING_FREQ_280 ); 00335 } 00336 else if( val <= 0xF000 ) 00337 { 00338 return( MATCHING_FREQ_169 ); 00339 } 00340 else 00341 { 00342 return( MATCHING_FREQ_868 ); 00343 } 00344 } 00345 00346 void SX126xHal::AntSwOn( void ) 00347 { 00348 antSwitchPower = 1; 00349 } 00350 00351 void SX126xHal::AntSwOff( void ) 00352 { 00353 antSwitchPower = 0; 00354 }
Generated on Tue Jul 12 2022 15:50:44 by
