1 /* 2 ______ _ 3 / _____) _ | | 4 ( (____ _____ ____ _| |_ _____ ____| |__ 5 \____ \| ___ | (_ _) ___ |/ ___) _ \ 6 _____) ) ____| | | || |_| ____( (___| | | | 7 (______/|_____)_|_|_| \__)_____)\____)_| |_| 8 (C)2016 Semtech 9 10 Description: Handling of the node configuration protocol 11 12 License: Revised BSD License, see LICENSE.TXT file include in the project 13 14 Maintainer: Miguel Luis, Matthieu Verdy and Benjamin Boulet 15 */ 16 #include "hw.h" 17 #include "sx1280-hal.h" 18 #include "radio.h" 19 #include <string.h> 20 21 // logging on 22 #include "SEGGER_RTT.h" 23 #define printf(format, ...) SEGGER_RTT_printf(0, format, ## __VA_ARGS__) 24 25 // make CubeMX defines usable 26 #ifndef RADIO_BUSY_PORT 27 #define RADIO_BUSY_PORT RADIO_BUSY_GPIO_Port 28 #endif 29 #ifndef RADIO_BUSY_PIN 30 #define RADIO_BUSY_PIN RADIO_BUSY_Pin 31 #endif 32 #ifndef RADIO_nRESET_PORT 33 #define RADIO_nRESET_PORT RADIO_nRESET_GPIO_Port 34 #endif 35 #ifndef RADIO_nRESET_PIN 36 #define RADIO_nRESET_PIN RADIO_nRESET_Pin 37 #endif 38 #ifndef RADIO_NSS_PORT 39 #define RADIO_NSS_PORT RADIO_NSS_GPIO_Port 40 #endif 41 #ifndef RADIO_NSS_PIN 42 #define RADIO_NSS_PIN RADIO_NSS_Pin 43 #endif 44 /*! 45 * \brief Define the size of tx and rx hal buffers 46 * 47 * The Tx and Rx hal buffers are used for SPI communication to 48 * store data to be sent/receive to/from the chip. 49 * 50 * \warning The application must ensure the maximal useful size to be much lower 51 * than the MAX_HAL_BUFFER_SIZE 52 */ 53 #define MAX_HAL_BUFFER_SIZE 0xFFF 54 55 #define IRQ_HIGH_PRIORITY 0 56 57 /*! 58 * Radio driver structure initialization 59 */ 60 const struct Radio_s Radio = 61 { 62 SX1280Init, 63 SX1280HalReset, 64 SX1280GetStatus, 65 SX1280HalWriteCommand, 66 SX1280HalReadCommand, 67 SX1280HalWriteRegisters, 68 SX1280HalWriteRegister, 69 SX1280HalReadRegisters, 70 SX1280HalReadRegister, 71 SX1280HalWriteBuffer, 72 SX1280HalReadBuffer, 73 SX1280HalGetDioStatus, 74 SX1280GetFirmwareVersion, 75 SX1280SetRegulatorMode, 76 SX1280SetStandby, 77 SX1280SetPacketType, 78 SX1280SetModulationParams, 79 SX1280SetPacketParams, 80 SX1280SetRfFrequency, 81 SX1280SetBufferBaseAddresses, 82 SX1280SetTxParams, 83 SX1280SetDioIrqParams, 84 SX1280SetSyncWord, 85 SX1280SetRx, 86 SX1280GetPayload, 87 SX1280SendPayload, 88 SX1280SetRangingRole, 89 SX1280SetPollingMode, 90 SX1280SetInterruptMode, 91 SX1280SetRegistersDefault, 92 SX1280GetOpMode, 93 SX1280SetSleep, 94 SX1280SetFs, 95 SX1280SetTx, 96 SX1280SetRxDutyCycle, 97 SX1280SetCad, 98 SX1280SetTxContinuousWave, 99 SX1280SetTxContinuousPreamble, 100 SX1280GetPacketType, 101 SX1280SetCadParams, 102 SX1280GetRxBufferStatus, 103 SX1280GetPacketStatus, 104 SX1280GetRssiInst, 105 SX1280GetIrqStatus, 106 SX1280ClearIrqStatus, 107 SX1280Calibrate, 108 SX1280SetSaveContext, 109 SX1280SetAutoTx, 110 SX1280StopAutoTx, 111 SX1280SetAutoFS, 112 SX1280SetLongPreamble, 113 SX1280SetPayload, 114 SX1280SetSyncWordErrorTolerance, 115 SX1280SetCrcSeed, 116 SX1280SetBleAccessAddress, 117 SX1280SetBleAdvertizerAccessAddress, 118 SX1280SetCrcPolynomial, 119 SX1280SetWhiteningSeed, 120 SX1280EnableManualGain, 121 SX1280DisableManualGain, 122 SX1280SetManualGainValue, 123 SX1280SetLNAGainSetting, 124 SX1280SetRangingIdLength, 125 SX1280SetDeviceRangingAddress, 126 SX1280SetRangingRequestAddress, 127 SX1280GetRangingResult, 128 SX1280SetRangingCalibration, 129 SX1280GetRangingPowerDeltaThresholdIndicator, 130 SX1280RangingClearFilterResult, 131 SX1280RangingSetFilterNumSamples, 132 SX1280GetFrequencyError, 133 }; 134 135 // static uint8_t halRxBuffer[MAX_HAL_BUFFER_SIZE]; 136 static uint8_t halTxBuffer[MAX_HAL_BUFFER_SIZE]; 137 const static uint8_t halZeroBuffer[MAX_HAL_BUFFER_SIZE]; 138 static DioIrqHandler **dioIrqHandlers; 139 140 extern SPI_HandleTypeDef RADIO_SPI_HANDLE; 141 extern DMA_HandleTypeDef RADIO_SPI_DMA_RX; 142 extern DMA_HandleTypeDef RADIO_SPI_DMA_TX; 143 144 145 #ifdef USE_BK_SPI 146 147 static void spi_enable(SPI_HandleTypeDef *hspi){ 148 /* Set fiforxthreshold according the reception data length: 8bit */ 149 SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); 150 151 /* Check if the SPI is already enabled */ 152 if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) 153 { 154 /* Enable SPI peripheral */ 155 __HAL_SPI_ENABLE(hspi); 156 } 157 } 158 159 static void spi_tx(SPI_HandleTypeDef *hspi, const uint8_t * tx_data, uint16_t tx_len){ 160 // send tx / ignore rx 161 uint8_t tx_byte = *tx_data++; 162 while (tx_len > 0){ 163 tx_len--; 164 // while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) == 0); 165 *(__IO uint8_t *)&hspi->Instance->DR = tx_byte; 166 tx_byte = *tx_data++; 167 while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) == 0); 168 uint8_t rx_byte = *(__IO uint8_t *)&hspi->Instance->DR; 169 (void) rx_byte; 170 } 171 } 172 173 static void spi_rx(SPI_HandleTypeDef *hspi, uint8_t * rx_buffer, uint16_t rx_len){ 174 // send NOP / store rx 175 while (rx_len > 0){ 176 rx_len--; 177 // while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) == 0); 178 *(__IO uint8_t *)&hspi->Instance->DR = 0; 179 while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) == 0); 180 *rx_buffer++ = *(__IO uint8_t *)&hspi->Instance->DR; 181 } 182 } 183 184 static void spi_tx_only_dma(const uint8_t * tx_data, uint16_t tx_len) { 185 186 HAL_DMA_Start(&RADIO_SPI_DMA_TX, (uintptr_t) tx_data, (uintptr_t) &RADIO_SPI_HANDLE.Instance->DR, tx_len); 187 188 /* Enable Tx DMA Request */ 189 SET_BIT(RADIO_SPI_HANDLE.Instance->CR2, SPI_CR2_TXDMAEN); 190 191 HAL_DMA_PollForTransfer(&RADIO_SPI_DMA_TX, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); 192 193 /* Discard received byte */ 194 (void) RADIO_SPI_HANDLE.Instance->DR; 195 } 196 197 static void spi_tx_rx_dma(const uint8_t * tx_data, uint8_t * rx_buffer, uint16_t size) { 198 199 /* Enable Rx DMA Request */ 200 SET_BIT(RADIO_SPI_HANDLE.Instance->CR2, SPI_CR2_RXDMAEN); 201 202 HAL_DMA_Start(&RADIO_SPI_DMA_RX, (uintptr_t) &RADIO_SPI_HANDLE.Instance->DR, (uintptr_t) rx_buffer, size); 203 HAL_DMA_Start(&RADIO_SPI_DMA_TX, (uintptr_t) tx_data, (uintptr_t) &RADIO_SPI_HANDLE.Instance->DR, size); 204 205 /* Enable Tx DMA Request */ 206 SET_BIT(RADIO_SPI_HANDLE.Instance->CR2, SPI_CR2_TXDMAEN); 207 208 HAL_DMA_PollForTransfer(&RADIO_SPI_DMA_TX, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); 209 HAL_DMA_PollForTransfer(&RADIO_SPI_DMA_RX, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); 210 } 211 212 #endif 213 214 // assert: tx_data == tx_buffer (local call), tx_len > 0 215 // DMA is disabled as one extra byte is read 216 void SX1280HalSpiTxThenRx(uint16_t tx_len, uint8_t * rx_buffer, uint16_t rx_len){ 217 218 spi_enable(&RADIO_SPI_HANDLE); 219 220 // min size for dma to be faster 221 const uint16_t dma_min_size_tx = 100; 222 223 if (tx_len < dma_min_size_tx) { 224 // Custom Polling 225 spi_tx(&RADIO_SPI_HANDLE, halTxBuffer, tx_len); 226 } else { 227 // Custom DMA 228 spi_tx_only_dma( halTxBuffer, tx_len ); 229 } 230 231 // 'Flush' Fifo by reading until marked empty 232 HAL_SPIEx_FlushRxFifo(&RADIO_SPI_HANDLE); 233 234 if (rx_len == 0) return; 235 236 // min size for dma to be faster 237 const uint16_t dma_min_size_rx = 100; 238 239 if (rx_len < dma_min_size_rx){ 240 // Custom Polling 241 spi_rx(&RADIO_SPI_HANDLE, rx_buffer, rx_len); 242 } else { 243 // Custom DMA 244 spi_tx_rx_dma( halZeroBuffer, rx_buffer, rx_len); 245 } 246 } 247 248 /*! 249 * \brief Used to block execution waiting for low state on radio busy pin. 250 * Essentially used in SPI communications 251 */ 252 void SX1280HalWaitOnBusy( void ) 253 { 254 while( HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN ) == 1 ); 255 } 256 257 void SX1280HalInit( DioIrqHandler **irqHandlers ) 258 { 259 SX1280HalReset( ); 260 SX1280HalWakeup(); 261 SX1280HalIoIrqInit( irqHandlers ); 262 } 263 264 void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin ) 265 { 266 dioIrqHandlers[0](); 267 } 268 269 void SX1280HalIoIrqInit( DioIrqHandler **irqHandlers ) 270 { 271 dioIrqHandlers = irqHandlers; 272 } 273 274 void SX1280HalReset( void ) 275 { 276 HAL_Delay( 20 ); 277 HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 0 ); 278 HAL_Delay( 50 ); 279 HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 1 ); 280 HAL_Delay( 20 ); 281 } 282 283 #if 0 284 // commented out as (3+IRAM_SIZE) > sizeof(halTxBuffer) 285 void SX1280HalClearInstructionRam( void ) 286 { 287 // Clearing the instruction RAM is writing 0x00s on every bytes of the 288 // instruction RAM 289 uint16_t halSize = 3 + IRAM_SIZE; 290 halTxBuffer[0] = RADIO_WRITE_REGISTER; 291 halTxBuffer[1] = ( IRAM_START_ADDRESS >> 8 ) & 0x00FF; 292 halTxBuffer[2] = IRAM_START_ADDRESS & 0x00FF; 293 for( uint16_t index = 0; index < IRAM_SIZE; index++ ) 294 { 295 halTxBuffer[3+index] = 0x00; 296 } 297 298 SX1280HalWaitOnBusy( ); 299 300 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 301 302 SX1280HalSpiTxThenRx( halTxBuffer, halSize, NULL, 0); 303 304 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 305 306 SX1280HalWaitOnBusy( ); 307 } 308 #endif 309 310 void SX1280HalWakeup( void ) 311 { 312 __disable_irq( ); 313 314 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 315 316 uint16_t halSize = 2; 317 halTxBuffer[0] = RADIO_GET_STATUS; 318 halTxBuffer[1] = 0x00; 319 320 SX1280HalSpiTxThenRx( halSize, NULL, 0); 321 322 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 323 324 // Wait for chip to be ready. 325 SX1280HalWaitOnBusy( ); 326 327 __enable_irq( ); 328 } 329 330 void SX1280HalWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 331 { 332 uint16_t halSize = size + 1; 333 SX1280HalWaitOnBusy( ); 334 335 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 336 337 halTxBuffer[0] = command; 338 memcpy( halTxBuffer + 1, ( uint8_t * )buffer, size * sizeof( uint8_t ) ); 339 340 SX1280HalSpiTxThenRx( halSize, NULL, 0); 341 342 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 343 344 if( command != RADIO_SET_SLEEP ) 345 { 346 SX1280HalWaitOnBusy( ); 347 } 348 } 349 350 void SX1280HalReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 351 { 352 halTxBuffer[0] = command; 353 halTxBuffer[1] = 0x00; 354 355 SX1280HalWaitOnBusy( ); 356 357 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 358 359 SX1280HalSpiTxThenRx( 2, buffer, size); 360 361 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 362 363 SX1280HalWaitOnBusy( ); 364 } 365 366 void SX1280HalWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) 367 { 368 uint16_t halSize = size + 3; 369 halTxBuffer[0] = RADIO_WRITE_REGISTER; 370 halTxBuffer[1] = ( address & 0xFF00 ) >> 8; 371 halTxBuffer[2] = address & 0x00FF; 372 memcpy( halTxBuffer + 3, buffer, size ); 373 374 SX1280HalWaitOnBusy( ); 375 376 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 377 378 SX1280HalSpiTxThenRx( halSize, NULL, 0); 379 380 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 381 382 SX1280HalWaitOnBusy( ); 383 } 384 385 void SX1280HalWriteRegister( uint16_t address, uint8_t value ) 386 { 387 SX1280HalWriteRegisters( address, &value, 1 ); 388 } 389 390 void SX1280HalReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) 391 { 392 halTxBuffer[0] = RADIO_READ_REGISTER; 393 halTxBuffer[1] = ( address & 0xFF00 ) >> 8; 394 halTxBuffer[2] = address & 0x00FF; 395 halTxBuffer[3] = 0x00; 396 397 SX1280HalWaitOnBusy( ); 398 399 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 400 401 SX1280HalSpiTxThenRx( 4, buffer, size); 402 403 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 404 405 SX1280HalWaitOnBusy( ); 406 } 407 408 uint8_t SX1280HalReadRegister( uint16_t address ) 409 { 410 uint8_t data; 411 412 SX1280HalReadRegisters( address, &data, 1 ); 413 414 return data; 415 } 416 417 void SX1280HalWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 418 { 419 uint16_t halSize = size + 2; 420 halTxBuffer[0] = RADIO_WRITE_BUFFER; 421 halTxBuffer[1] = offset; 422 memcpy( halTxBuffer + 2, buffer, size ); 423 424 SX1280HalWaitOnBusy( ); 425 426 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 427 428 SX1280HalSpiTxThenRx( halSize, NULL, 0); 429 430 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 431 432 SX1280HalWaitOnBusy( ); 433 } 434 435 void SX1280HalReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 436 { 437 halTxBuffer[0] = RADIO_READ_BUFFER; 438 halTxBuffer[1] = offset; 439 halTxBuffer[2] = 0x00; 440 441 SX1280HalWaitOnBusy( ); 442 443 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 444 445 SX1280HalSpiTxThenRx( 3, buffer, size); 446 447 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 448 449 SX1280HalWaitOnBusy( ); 450 } 451 452 uint8_t SX1280HalGetDioStatus( void ) 453 { 454 uint8_t Status = HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN ); 455 456 #if( RADIO_DIO1_ENABLE ) 457 Status |= (HAL_GPIO_ReadPin( RADIO_DIO1_GPIO_Port, RADIO_DIO1_Pin ) << 1); 458 #endif 459 #if( RADIO_DIO2_ENABLE ) 460 Status |= (HAL_GPIO_ReadPin( RADIO_DIO2_GPIO_Port, RADIO_DIO2_Pin ) << 2); 461 #endif 462 #if( RADIO_DIO3_ENABLE ) 463 Status |= (HAL_GPIO_ReadPin( RADIO_DIO3_GPIO_Port, RADIO_DIO3_Pin ) << 3); 464 #endif 465 #if( !RADIO_DIO1_ENABLE && !RADIO_DIO2_ENABLE && !RADIO_DIO3_ENABLE ) 466 #error "Please define a DIO" 467 #endif 468 469 return Status; 470 } 471