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
spi_enable(SPI_HandleTypeDef * hspi)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
spi_tx(SPI_HandleTypeDef * hspi,const uint8_t * tx_data,uint16_t tx_len)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
spi_rx(SPI_HandleTypeDef * hspi,uint8_t * rx_buffer,uint16_t rx_len)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
spi_tx_only_dma(const uint8_t * tx_data,uint16_t tx_len)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
spi_tx_rx_dma(const uint8_t * tx_data,uint8_t * rx_buffer,uint16_t size)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
SX1280HalSpiTxThenRx(uint16_t tx_len,uint8_t * rx_buffer,uint16_t rx_len)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 */
SX1280HalWaitOnBusy(void)252 void SX1280HalWaitOnBusy( void )
253 {
254 while( HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN ) == 1 );
255 }
256
SX1280HalInit(DioIrqHandler ** irqHandlers)257 void SX1280HalInit( DioIrqHandler **irqHandlers )
258 {
259 SX1280HalReset( );
260 SX1280HalWakeup();
261 SX1280HalIoIrqInit( irqHandlers );
262 }
263
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)264 void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )
265 {
266 dioIrqHandlers[0]();
267 }
268
SX1280HalIoIrqInit(DioIrqHandler ** irqHandlers)269 void SX1280HalIoIrqInit( DioIrqHandler **irqHandlers )
270 {
271 dioIrqHandlers = irqHandlers;
272 }
273
SX1280HalReset(void)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
SX1280HalWakeup(void)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
SX1280HalWriteCommand(RadioCommands_t command,uint8_t * buffer,uint16_t size)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
SX1280HalReadCommand(RadioCommands_t command,uint8_t * buffer,uint16_t size)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
SX1280HalWriteRegisters(uint16_t address,uint8_t * buffer,uint16_t size)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
SX1280HalWriteRegister(uint16_t address,uint8_t value)385 void SX1280HalWriteRegister( uint16_t address, uint8_t value )
386 {
387 SX1280HalWriteRegisters( address, &value, 1 );
388 }
389
SX1280HalReadRegisters(uint16_t address,uint8_t * buffer,uint16_t size)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
SX1280HalReadRegister(uint16_t address)408 uint8_t SX1280HalReadRegister( uint16_t address )
409 {
410 uint8_t data;
411
412 SX1280HalReadRegisters( address, &data, 1 );
413
414 return data;
415 }
416
SX1280HalWriteBuffer(uint8_t offset,uint8_t * buffer,uint8_t size)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
SX1280HalReadBuffer(uint8_t offset,uint8_t * buffer,uint8_t size)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
SX1280HalGetDioStatus(void)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