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 SX1280HalIoIrqInit( irqHandlers ); 261 } 262 263 void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin ) 264 { 265 dioIrqHandlers[0](); 266 } 267 268 void SX1280HalIoIrqInit( DioIrqHandler **irqHandlers ) 269 { 270 dioIrqHandlers = irqHandlers; 271 } 272 273 void SX1280HalReset( void ) 274 { 275 HAL_Delay( 20 ); 276 HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 0 ); 277 HAL_Delay( 50 ); 278 HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 1 ); 279 HAL_Delay( 20 ); 280 } 281 282 #if 0 283 // commented out as (3+IRAM_SIZE) > sizeof(halTxBuffer) 284 void SX1280HalClearInstructionRam( void ) 285 { 286 // Clearing the instruction RAM is writing 0x00s on every bytes of the 287 // instruction RAM 288 uint16_t halSize = 3 + IRAM_SIZE; 289 halTxBuffer[0] = RADIO_WRITE_REGISTER; 290 halTxBuffer[1] = ( IRAM_START_ADDRESS >> 8 ) & 0x00FF; 291 halTxBuffer[2] = IRAM_START_ADDRESS & 0x00FF; 292 for( uint16_t index = 0; index < IRAM_SIZE; index++ ) 293 { 294 halTxBuffer[3+index] = 0x00; 295 } 296 297 SX1280HalWaitOnBusy( ); 298 299 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 300 301 SX1280HalSpiTxThenRx( halTxBuffer, halSize, NULL, 0); 302 303 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 304 305 SX1280HalWaitOnBusy( ); 306 } 307 #endif 308 309 void SX1280HalWakeup( void ) 310 { 311 __disable_irq( ); 312 313 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 314 315 uint16_t halSize = 2; 316 halTxBuffer[0] = RADIO_GET_STATUS; 317 halTxBuffer[1] = 0x00; 318 319 SX1280HalSpiTxThenRx( halSize, NULL, 0); 320 321 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 322 323 // Wait for chip to be ready. 324 SX1280HalWaitOnBusy( ); 325 326 __enable_irq( ); 327 } 328 329 void SX1280HalWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 330 { 331 uint16_t halSize = size + 1; 332 SX1280HalWaitOnBusy( ); 333 334 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 335 336 halTxBuffer[0] = command; 337 memcpy( halTxBuffer + 1, ( uint8_t * )buffer, size * sizeof( uint8_t ) ); 338 339 SX1280HalSpiTxThenRx( halSize, NULL, 0); 340 341 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 342 343 if( command != RADIO_SET_SLEEP ) 344 { 345 SX1280HalWaitOnBusy( ); 346 } 347 } 348 349 void SX1280HalReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) 350 { 351 halTxBuffer[0] = command; 352 halTxBuffer[1] = 0x00; 353 354 SX1280HalWaitOnBusy( ); 355 356 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 357 358 SX1280HalSpiTxThenRx( 2, buffer, size); 359 360 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 361 362 SX1280HalWaitOnBusy( ); 363 } 364 365 void SX1280HalWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) 366 { 367 uint16_t halSize = size + 3; 368 halTxBuffer[0] = RADIO_WRITE_REGISTER; 369 halTxBuffer[1] = ( address & 0xFF00 ) >> 8; 370 halTxBuffer[2] = address & 0x00FF; 371 memcpy( halTxBuffer + 3, buffer, size ); 372 373 SX1280HalWaitOnBusy( ); 374 375 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 376 377 SX1280HalSpiTxThenRx( halSize, NULL, 0); 378 379 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 380 381 SX1280HalWaitOnBusy( ); 382 } 383 384 void SX1280HalWriteRegister( uint16_t address, uint8_t value ) 385 { 386 SX1280HalWriteRegisters( address, &value, 1 ); 387 } 388 389 void SX1280HalReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) 390 { 391 halTxBuffer[0] = RADIO_READ_REGISTER; 392 halTxBuffer[1] = ( address & 0xFF00 ) >> 8; 393 halTxBuffer[2] = address & 0x00FF; 394 halTxBuffer[3] = 0x00; 395 396 SX1280HalWaitOnBusy( ); 397 398 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 399 400 SX1280HalSpiTxThenRx( 4, buffer, size); 401 402 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 403 404 SX1280HalWaitOnBusy( ); 405 } 406 407 uint8_t SX1280HalReadRegister( uint16_t address ) 408 { 409 uint8_t data; 410 411 SX1280HalReadRegisters( address, &data, 1 ); 412 413 return data; 414 } 415 416 void SX1280HalWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 417 { 418 uint16_t halSize = size + 2; 419 halTxBuffer[0] = RADIO_WRITE_BUFFER; 420 halTxBuffer[1] = offset; 421 memcpy( halTxBuffer + 2, buffer, size ); 422 423 SX1280HalWaitOnBusy( ); 424 425 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 426 427 SX1280HalSpiTxThenRx( halSize, NULL, 0); 428 429 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 430 431 SX1280HalWaitOnBusy( ); 432 } 433 434 void SX1280HalReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) 435 { 436 halTxBuffer[0] = RADIO_READ_BUFFER; 437 halTxBuffer[1] = offset; 438 halTxBuffer[2] = 0x00; 439 440 SX1280HalWaitOnBusy( ); 441 442 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 ); 443 444 SX1280HalSpiTxThenRx( 3, buffer, size); 445 446 HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); 447 448 SX1280HalWaitOnBusy( ); 449 } 450 451 uint8_t SX1280HalGetDioStatus( void ) 452 { 453 uint8_t Status = HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN ); 454 455 #if( RADIO_DIO1_ENABLE ) 456 Status |= (HAL_GPIO_ReadPin( RADIO_DIO1_GPIO_Port, RADIO_DIO1_Pin ) << 1); 457 #endif 458 #if( RADIO_DIO2_ENABLE ) 459 Status |= (HAL_GPIO_ReadPin( RADIO_DIO2_GPIO_Port, RADIO_DIO2_Pin ) << 2); 460 #endif 461 #if( RADIO_DIO3_ENABLE ) 462 Status |= (HAL_GPIO_ReadPin( RADIO_DIO3_GPIO_Port, RADIO_DIO3_Pin ) << 3); 463 #endif 464 #if( !RADIO_DIO1_ENABLE && !RADIO_DIO2_ENABLE && !RADIO_DIO3_ENABLE ) 465 #error "Please define a DIO" 466 #endif 467 468 return Status; 469 } 470