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: SX1280PingPong RangignMaster RangingSlave MSNV2-Terminal_V1-6 ... more
sx1280-hal.cpp
00001 /* 00002 ______ _ 00003 / _____) _ | | 00004 ( (____ _____ ____ _| |_ _____ ____| |__ 00005 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00006 _____) ) ____| | | || |_| ____( (___| | | | 00007 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00008 (C)2016 Semtech 00009 00010 Description: Handling of the node configuration protocol 00011 00012 License: Revised BSD License, see LICENSE.TXT file include in the project 00013 00014 Maintainer: Miguel Luis, Gregory Cristian and Matthieu Verdy 00015 */ 00016 #include "sx1280-hal.h" 00017 00018 /*! 00019 * \brief Helper macro to create Interrupt objects only if the pin name is 00020 * different from NC 00021 */ 00022 #define CreateDioPin( pinName, dio ) \ 00023 if( pinName == NC ) \ 00024 { \ 00025 dio = NULL; \ 00026 } \ 00027 else \ 00028 { \ 00029 dio = new InterruptIn( pinName ); \ 00030 } 00031 00032 /*! 00033 * \brief Helper macro to avoid duplicating code for setting dio pins parameters 00034 */ 00035 #if defined( TARGET_NUCLEO_L476RG ) 00036 #define DioAssignCallback( dio, pinMode, callback ) \ 00037 if( dio != NULL ) \ 00038 { \ 00039 dio->mode( pinMode ); \ 00040 dio->rise( this, static_cast <Trigger>( callback ) ); \ 00041 } 00042 #else 00043 #define DioAssignCallback( dio, pinMode, callback ) \ 00044 if( dio != NULL ) \ 00045 { \ 00046 dio->rise( this, static_cast <Trigger>( callback ) ); \ 00047 } 00048 #endif 00049 /*! 00050 * \brief Used to block execution waiting for low state on radio busy pin. 00051 * Essentially used in SPI communications 00052 */ 00053 #define WaitOnBusy( ) while( BUSY == 1 ){ } 00054 00055 /*! 00056 * \brief Blocking routine for waiting the UART to be writeable 00057 * 00058 */ 00059 #define WaitUartWritable( ) while( RadioUart->writeable( ) == false ){ } 00060 00061 /*! 00062 * \brief Blocking routine for waiting the UART to be readable 00063 * 00064 */ 00065 #define WaitUartReadable( ) while( RadioUart->readable( ) == false ){ } 00066 00067 // This code handles cases where assert_param is undefined 00068 #ifndef assert_param 00069 #define assert_param( ... ) 00070 #endif 00071 00072 SX1280Hal::SX1280Hal( PinName mosi, PinName miso, PinName sclk, PinName nss, 00073 PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst, 00074 RadioCallbacks_t *callbacks ) 00075 : SX1280( callbacks ), 00076 RadioNss( nss ), 00077 RadioReset( rst ), 00078 RadioCtsn( NC ), 00079 BUSY( busy ) 00080 { 00081 CreateDioPin( dio1, DIO1 ); 00082 CreateDioPin( dio2, DIO2 ); 00083 CreateDioPin( dio3, DIO3 ); 00084 RadioSpi = new SPI( mosi, miso, sclk ); 00085 RadioUart = NULL; 00086 00087 RadioNss = 1; 00088 RadioReset = 1; 00089 } 00090 00091 SX1280Hal::SX1280Hal( PinName tx, PinName rx, PinName ctsn, 00092 PinName busy, PinName dio1, PinName dio2, PinName dio3, PinName rst, 00093 RadioCallbacks_t *callbacks ) 00094 : SX1280( callbacks ), 00095 RadioNss( NC ), 00096 RadioReset( rst ), 00097 RadioCtsn( ctsn ), 00098 BUSY( busy ) 00099 { 00100 CreateDioPin( dio1, DIO1 ); 00101 CreateDioPin( dio2, DIO2 ); 00102 CreateDioPin( dio3, DIO3 ); 00103 RadioSpi = NULL; 00104 RadioUart = new Serial( tx, rx ); 00105 RadioCtsn = 0; 00106 RadioReset = 1; 00107 } 00108 00109 SX1280Hal::~SX1280Hal( void ) 00110 { 00111 if( this->RadioSpi != NULL ) 00112 { 00113 delete RadioSpi; 00114 } 00115 if( this->RadioUart != NULL ) 00116 { 00117 delete RadioUart; 00118 } 00119 if( DIO1 != NULL ) 00120 { 00121 delete DIO1; 00122 } 00123 if( DIO2 != NULL ) 00124 { 00125 delete DIO2; 00126 } 00127 if( DIO3 != NULL ) 00128 { 00129 delete DIO3; 00130 } 00131 }; 00132 00133 void SX1280Hal::SpiInit( void ) 00134 { 00135 RadioNss = 1; 00136 RadioSpi->format( 8, 0 ); 00137 #if defined( TARGET_KL25Z ) 00138 this->SetSpiSpeed( 4000000 ); 00139 #elif defined( TARGET_NUCLEO_L476RG ) 00140 this->SetSpiSpeed( 8000000 ); 00141 #else 00142 this->SetSpiSpeed( 8000000 ); 00143 #endif 00144 wait( 0.1 ); 00145 } 00146 00147 void SX1280Hal::SetSpiSpeed( uint32_t spiSpeed ) 00148 { 00149 RadioSpi->frequency( spiSpeed ); 00150 } 00151 00152 void SX1280Hal::UartInit( void ) 00153 { 00154 RadioUart->format( 9, SerialBase::Even, 1 ); // 8 data bits + 1 even parity bit + 1 stop bit 00155 RadioUart->baud( 115200 ); 00156 // After this point, the UART is running standard mode: 8 data bit, 1 even 00157 // parity bit, 1 stop bit, 115200 baud, LSB first 00158 wait_us( 10 ); 00159 } 00160 00161 void SX1280Hal::IoIrqInit( DioIrqHandler irqHandler ) 00162 { 00163 assert_param( RadioSpi != NULL || RadioUart != NULL ); 00164 if( RadioSpi != NULL ) 00165 { 00166 SpiInit( ); 00167 } 00168 if( RadioUart != NULL ) 00169 { 00170 UartInit( ); 00171 } 00172 00173 BUSY.mode( PullNone ); 00174 00175 DioAssignCallback( DIO1, PullNone, irqHandler ); 00176 DioAssignCallback( DIO2, PullNone, irqHandler ); 00177 DioAssignCallback( DIO3, PullNone, irqHandler ); 00178 } 00179 00180 void SX1280Hal::Reset( void ) 00181 { 00182 __disable_irq( ); 00183 wait_ms( 20 ); 00184 RadioReset.output( ); 00185 RadioReset = 0; 00186 wait_ms( 50 ); 00187 RadioReset = 1; 00188 RadioReset.input( ); // Using the internal pull-up 00189 wait_ms( 20 ); 00190 __enable_irq( ); 00191 } 00192 00193 void SX1280Hal::Wakeup( void ) 00194 { 00195 __disable_irq( ); 00196 00197 //Don't wait for BUSY here 00198 00199 if( RadioSpi != NULL ) 00200 { 00201 RadioNss = 0; 00202 RadioSpi->write( RADIO_GET_STATUS ); 00203 RadioSpi->write( 0 ); 00204 RadioNss = 1; 00205 } 00206 if( RadioUart != NULL ) 00207 { 00208 RadioUart->putc( RADIO_GET_STATUS ); 00209 WaitUartReadable( ); 00210 RadioUart->getc( ); 00211 } 00212 00213 // Wait for chip to be ready. 00214 WaitOnBusy( ); 00215 00216 __enable_irq( ); 00217 } 00218 00219 void SX1280Hal::WriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 00220 { 00221 WaitOnBusy( ); 00222 00223 if( RadioSpi != NULL ) 00224 { 00225 RadioNss = 0; 00226 RadioSpi->write( ( uint8_t )command ); 00227 for( uint16_t i = 0; i < size; i++ ) 00228 { 00229 RadioSpi->write( buffer[i] ); 00230 } 00231 RadioNss = 1; 00232 } 00233 if( RadioUart != NULL ) 00234 { 00235 RadioUart->putc( command ); 00236 if( size > 0 ) 00237 { 00238 RadioUart->putc( size ); 00239 for( uint16_t i = 0; i < size; i++ ) 00240 { 00241 RadioUart->putc( buffer[i] ); 00242 } 00243 } 00244 } 00245 00246 if( command != RADIO_SET_SLEEP ) 00247 { 00248 WaitOnBusy( ); 00249 } 00250 } 00251 00252 void SX1280Hal::ReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 00253 { 00254 WaitOnBusy( ); 00255 00256 if( RadioSpi != NULL ) 00257 { 00258 RadioNss = 0; 00259 if( command == RADIO_GET_STATUS ) 00260 { 00261 buffer[0] = RadioSpi->write( ( uint8_t )command ); 00262 RadioSpi->write( 0 ); 00263 RadioSpi->write( 0 ); 00264 } 00265 else 00266 { 00267 RadioSpi->write( ( uint8_t )command ); 00268 RadioSpi->write( 0 ); 00269 for( uint16_t i = 0; i < size; i++ ) 00270 { 00271 buffer[i] = RadioSpi->write( 0 ); 00272 } 00273 } 00274 RadioNss = 1; 00275 } 00276 if( RadioUart != NULL ) 00277 { 00278 RadioUart->putc( command ); 00279 00280 // Behavior on the UART is different depending of the opcode command 00281 if( ( command == RADIO_GET_PACKETTYPE ) || 00282 ( command == RADIO_GET_RXBUFFERSTATUS ) || 00283 ( command == RADIO_GET_RSSIINST ) || 00284 ( command == RADIO_GET_PACKETSTATUS ) || 00285 ( command == RADIO_GET_IRQSTATUS ) ) 00286 { 00287 /* 00288 * TODO : Check size size in UART (uint8_t in putc) 00289 */ 00290 RadioUart->putc( size ); 00291 } 00292 00293 WaitUartReadable( ); 00294 for( uint16_t i = 0; i < size; i++ ) 00295 { 00296 buffer[i] = RadioUart->getc( ); 00297 } 00298 } 00299 00300 WaitOnBusy( ); 00301 } 00302 00303 void SX1280Hal::WriteRegister( uint16_t address, uint8_t *buffer, uint16_t size ) 00304 { 00305 WaitOnBusy( ); 00306 00307 if( RadioSpi != NULL ) 00308 { 00309 RadioNss = 0; 00310 RadioSpi->write( RADIO_WRITE_REGISTER ); 00311 RadioSpi->write( ( address & 0xFF00 ) >> 8 ); 00312 RadioSpi->write( address & 0x00FF ); 00313 for( uint16_t i = 0; i < size; i++ ) 00314 { 00315 RadioSpi->write( buffer[i] ); 00316 } 00317 RadioNss = 1; 00318 } 00319 if( RadioUart != NULL ) 00320 { 00321 uint16_t addr = address; 00322 uint16_t i = 0; 00323 for( addr = address; ( addr + 255 ) < ( address + size ); ) 00324 { 00325 RadioUart->putc( RADIO_WRITE_REGISTER ); 00326 RadioUart->putc( ( addr & 0xFF00 ) >> 8 ); 00327 RadioUart->putc( addr & 0x00FF ); 00328 RadioUart->putc( 255 ); 00329 for( uint16_t lastAddr = addr + 255 ; addr < lastAddr; i++, addr++ ) 00330 { 00331 RadioUart->putc( buffer[i] ); 00332 } 00333 } 00334 RadioUart->putc( RADIO_WRITE_REGISTER ); 00335 RadioUart->putc( ( addr & 0xFF00 ) >> 8 ); 00336 RadioUart->putc( addr & 0x00FF ); 00337 RadioUart->putc( address + size - addr ); 00338 00339 for( ; addr < ( address + size ); addr++, i++ ) 00340 { 00341 RadioUart->putc( buffer[i] ); 00342 } 00343 } 00344 00345 WaitOnBusy( ); 00346 } 00347 00348 void SX1280Hal::WriteRegister( uint16_t address, uint8_t value ) 00349 { 00350 WriteRegister( address, &value, 1 ); 00351 } 00352 00353 void SX1280Hal::ReadRegister( uint16_t address, uint8_t *buffer, uint16_t size ) 00354 { 00355 WaitOnBusy( ); 00356 00357 if( RadioSpi != NULL ) 00358 { 00359 RadioNss = 0; 00360 RadioSpi->write( RADIO_READ_REGISTER ); 00361 RadioSpi->write( ( address & 0xFF00 ) >> 8 ); 00362 RadioSpi->write( address & 0x00FF ); 00363 RadioSpi->write( 0 ); 00364 for( uint16_t i = 0; i < size; i++ ) 00365 { 00366 buffer[i] = RadioSpi->write( 0 ); 00367 } 00368 RadioNss = 1; 00369 } 00370 if( RadioUart != NULL ) 00371 { 00372 uint16_t addr = address; 00373 uint16_t i = 0; 00374 for( addr = address; ( addr + 255 ) < ( address + size ); ) 00375 { 00376 RadioUart->putc( RADIO_READ_REGISTER ); 00377 RadioUart->putc( ( addr & 0xFF00 ) >> 8 ); 00378 RadioUart->putc( addr & 0x00FF ); 00379 RadioUart->putc( 255 ); 00380 WaitUartReadable( ); 00381 for( uint16_t lastAddr = addr + 255 ; addr < lastAddr; i++, addr++ ) 00382 { 00383 buffer[i] = RadioUart->getc( ); 00384 } 00385 } 00386 RadioUart->putc( RADIO_READ_REGISTER ); 00387 RadioUart->putc( ( addr & 0xFF00 ) >> 8 ); 00388 RadioUart->putc( addr & 0x00FF ); 00389 RadioUart->putc( address + size - addr ); 00390 WaitUartReadable( ); 00391 for( ; addr < ( address + size ); addr++, i++ ) 00392 { 00393 buffer[i] = RadioUart->getc( ); 00394 } 00395 } 00396 00397 WaitOnBusy( ); 00398 } 00399 00400 uint8_t SX1280Hal::ReadRegister( uint16_t address ) 00401 { 00402 uint8_t data; 00403 00404 ReadRegister( address, &data, 1 ); 00405 return data; 00406 } 00407 00408 void SX1280Hal::WriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 00409 { 00410 WaitOnBusy( ); 00411 00412 if( RadioSpi != NULL ) 00413 { 00414 RadioNss = 0; 00415 RadioSpi->write( RADIO_WRITE_BUFFER ); 00416 RadioSpi->write( offset ); 00417 for( uint16_t i = 0; i < size; i++ ) 00418 { 00419 RadioSpi->write( buffer[i] ); 00420 } 00421 RadioNss = 1; 00422 } 00423 if( RadioUart != NULL ) 00424 { 00425 RadioUart->putc( RADIO_WRITE_BUFFER ); 00426 RadioUart->putc( offset ); 00427 RadioUart->putc( size ); 00428 for( uint16_t i = 0; i < size; i++ ) 00429 { 00430 RadioUart->putc( buffer[i] ); 00431 } 00432 } 00433 00434 WaitOnBusy( ); 00435 } 00436 00437 void SX1280Hal::ReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 00438 { 00439 WaitOnBusy( ); 00440 00441 if( RadioSpi != NULL ) 00442 { 00443 RadioNss = 0; 00444 RadioSpi->write( RADIO_READ_BUFFER ); 00445 RadioSpi->write( offset ); 00446 RadioSpi->write( 0 ); 00447 for( uint16_t i = 0; i < size; i++ ) 00448 { 00449 buffer[i] = RadioSpi->write( 0 ); 00450 } 00451 RadioNss = 1; 00452 } 00453 if( RadioUart != NULL ) 00454 { 00455 RadioUart->putc( RADIO_READ_BUFFER ); 00456 RadioUart->putc( offset ); 00457 RadioUart->putc( size ); 00458 WaitUartReadable( ); 00459 for( uint16_t i = 0; i < size; i++ ) 00460 { 00461 buffer[i] = RadioUart->getc( ); 00462 } 00463 } 00464 00465 WaitOnBusy( ); 00466 } 00467 00468 uint8_t SX1280Hal::GetDioStatus( void ) 00469 { 00470 return ( *DIO3 << 3 ) | ( *DIO2 << 2 ) | ( *DIO1 << 1 ) | ( BUSY << 0 ); 00471 }
Generated on Tue Jul 12 2022 19:08:29 by
1.7.2
SX1280RF1ZHP