xref: /btstack/chipset/sx128x/SMTC_Drivers/sx1280-driver-c/sx1280-hal.c (revision a8d51f092f1b660d0f6921369ad2bc3f9368296c)
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 #ifndef USE_BK_SPI
136 static uint8_t halRxBuffer[MAX_HAL_BUFFER_SIZE] = {0x00};
137 #endif
138 static uint8_t halTxBuffer[MAX_HAL_BUFFER_SIZE] = {0x00};
139 
140 static DioIrqHandler **dioIrqHandlers;
141 
142 extern SPI_HandleTypeDef RADIO_SPI_HANDLE;
143 
144 #ifdef USE_BK_SPI
145 
146 static void spi_tx_then_rx(SPI_HandleTypeDef *hspi, const uint8_t * tx_data, uint16_t tx_len, uint8_t * rx_buffer, uint16_t rx_len){
147 
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     // send tx / ignore rx
159 
160     uint8_t tx_byte = *tx_data++;
161     while (tx_len > 0){
162         tx_len--;
163         // while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) == 0);
164         *(__IO uint8_t *)&hspi->Instance->DR = tx_byte;
165         tx_byte = *tx_data++;
166         while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) == 0);
167         // *rx_buffer++ = *(__IO uint8_t *)&hspi->Instance->DR;
168         uint8_t rx_byte = *(__IO uint8_t *)&hspi->Instance->DR;
169         (void) rx_byte;
170     }
171 
172     // send NOP / store rx
173 
174     while (rx_len > 0){
175         rx_len--;
176         // while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) == 0);
177         *(__IO uint8_t *)&hspi->Instance->DR = 0;
178         while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) == 0);
179         *rx_buffer++ = *(__IO uint8_t *)&hspi->Instance->DR;
180     }
181 }
182 #endif
183 
184 // assert: tx_data == tx_buffer (local call)
185 void SX1280HalSpiTxThenRx(uint16_t tx_len, uint8_t * rx_buffer, uint16_t rx_len){
186 
187 #ifdef USE_BK_SPI
188 	spi_tx_then_rx(&RADIO_SPI_HANDLE, halTxBuffer, tx_len, rx_buffer, rx_len);
189 #else
190 	if (rx_len == 0){
191 
192 		// SPI Transfer
193 		HAL_SPI_Transmit( &RADIO_SPI_HANDLE, halTxBuffer, size, HAL_MAX_DELAY );
194 
195 	} else {
196 		// fill TX buffer with zeros
197 		memset(&halTxBuffer[tx_len], 0, rx_len);
198 
199 		// SPI Transfer
200 #ifdef STM32L4XX_FAMILY
201 		// Comment For STM32L0XX and STM32L1XX Intégration, uncomment for STM32L4XX Intégration
202 		HAL_SPIEx_FlushRxFifo( &RADIO_SPI_HANDLE );
203 #endif
204 	    HAL_SPI_TransmitReceive( &RADIO_SPI_HANDLE, halTxBuffer, halRxBuffer, size, HAL_MAX_DELAY );
205 
206 		// return rx data
207 	    memcpy( rx_buffer, &halRxBuffer[tx_len], size );
208 	}
209 #endif
210 }
211 
212 /*!
213  * \brief Used to block execution waiting for low state on radio busy pin.
214  *        Essentially used in SPI communications
215  */
216 void SX1280HalWaitOnBusy( void )
217 {
218     while( HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN ) == 1 );
219 }
220 
221 void SX1280HalInit( DioIrqHandler **irqHandlers )
222 {
223     SX1280HalReset( );
224     SX1280HalIoIrqInit( irqHandlers );
225 }
226 
227 void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )
228 {
229     dioIrqHandlers[0]();
230 }
231 
232 void SX1280HalIoIrqInit( DioIrqHandler **irqHandlers )
233 {
234     dioIrqHandlers = irqHandlers;
235 }
236 
237 void SX1280HalReset( void )
238 {
239     HAL_Delay( 20 );
240     HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 0 );
241     HAL_Delay( 50 );
242     HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 1 );
243     HAL_Delay( 20 );
244 }
245 
246 #if 0
247 // commented out as (3+IRAM_SIZE) > sizeof(halTxBuffer)
248 void SX1280HalClearInstructionRam( void )
249 {
250     // Clearing the instruction RAM is writing 0x00s on every bytes of the
251     // instruction RAM
252     uint16_t halSize = 3 + IRAM_SIZE;
253     halTxBuffer[0] = RADIO_WRITE_REGISTER;
254     halTxBuffer[1] = ( IRAM_START_ADDRESS >> 8 ) & 0x00FF;
255     halTxBuffer[2] = IRAM_START_ADDRESS & 0x00FF;
256     for( uint16_t index = 0; index < IRAM_SIZE; index++ )
257     {
258         halTxBuffer[3+index] = 0x00;
259     }
260 
261     SX1280HalWaitOnBusy( );
262 
263     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
264 
265 	SX1280HalSpiTxThenRx( halTxBuffer, halSize, NULL, 0);
266 
267     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
268 
269     SX1280HalWaitOnBusy( );
270 }
271 #endif
272 
273 void SX1280HalWakeup( void )
274 {
275     __disable_irq( );
276 
277     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
278 
279     uint16_t halSize = 2;
280     halTxBuffer[0] = RADIO_GET_STATUS;
281     halTxBuffer[1] = 0x00;
282 
283 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
284 
285     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
286 
287     // Wait for chip to be ready.
288     SX1280HalWaitOnBusy( );
289 
290     __enable_irq( );
291 }
292 
293 void SX1280HalWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
294 {
295     uint16_t halSize  = size + 1;
296     SX1280HalWaitOnBusy( );
297 
298     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
299 
300     halTxBuffer[0] = command;
301     memcpy( halTxBuffer + 1, ( uint8_t * )buffer, size * sizeof( uint8_t ) );
302 
303 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
304 
305     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
306 
307     if( command != RADIO_SET_SLEEP )
308     {
309         SX1280HalWaitOnBusy( );
310     }
311 }
312 
313 void SX1280HalReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
314 {
315     halTxBuffer[0] = command;
316     halTxBuffer[1] = 0x00;
317 
318     SX1280HalWaitOnBusy( );
319 
320     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
321 
322 	SX1280HalSpiTxThenRx( 2, buffer, size);
323 
324     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
325 
326     SX1280HalWaitOnBusy( );
327 }
328 
329 void SX1280HalWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
330 {
331     uint16_t halSize = size + 3;
332     halTxBuffer[0] = RADIO_WRITE_REGISTER;
333     halTxBuffer[1] = ( address & 0xFF00 ) >> 8;
334     halTxBuffer[2] = address & 0x00FF;
335     memcpy( halTxBuffer + 3, buffer, size );
336 
337     SX1280HalWaitOnBusy( );
338 
339     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
340 
341 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
342 
343     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
344 
345     SX1280HalWaitOnBusy( );
346 }
347 
348 void SX1280HalWriteRegister( uint16_t address, uint8_t value )
349 {
350     SX1280HalWriteRegisters( address, &value, 1 );
351 }
352 
353 void SX1280HalReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
354 {
355     halTxBuffer[0] = RADIO_READ_REGISTER;
356     halTxBuffer[1] = ( address & 0xFF00 ) >> 8;
357     halTxBuffer[2] = address & 0x00FF;
358     halTxBuffer[3] = 0x00;
359 
360     SX1280HalWaitOnBusy( );
361 
362     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
363 
364 	SX1280HalSpiTxThenRx( 4, buffer, size);
365 
366     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
367 
368     SX1280HalWaitOnBusy( );
369 }
370 
371 uint8_t SX1280HalReadRegister( uint16_t address )
372 {
373     uint8_t data;
374 
375     SX1280HalReadRegisters( address, &data, 1 );
376 
377     return data;
378 }
379 
380 void SX1280HalWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
381 {
382     uint16_t halSize = size + 2;
383     halTxBuffer[0] = RADIO_WRITE_BUFFER;
384     halTxBuffer[1] = offset;
385     memcpy( halTxBuffer + 2, buffer, size );
386 
387     SX1280HalWaitOnBusy( );
388 
389     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
390 
391 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
392 
393     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
394 
395     SX1280HalWaitOnBusy( );
396 }
397 
398 void SX1280HalReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
399 {
400     halTxBuffer[0] = RADIO_READ_BUFFER;
401     halTxBuffer[1] = offset;
402     halTxBuffer[2] = 0x00;
403 
404     SX1280HalWaitOnBusy( );
405 
406     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
407 
408 	SX1280HalSpiTxThenRx( 3, buffer, size);
409 
410     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
411 
412     SX1280HalWaitOnBusy( );
413 }
414 
415 uint8_t SX1280HalGetDioStatus( void )
416 {
417 	uint8_t Status = HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN );
418 
419 #if( RADIO_DIO1_ENABLE )
420 	Status |= (HAL_GPIO_ReadPin( RADIO_DIO1_GPIO_Port, RADIO_DIO1_Pin ) << 1);
421 #endif
422 #if( RADIO_DIO2_ENABLE )
423 	Status |= (HAL_GPIO_ReadPin( RADIO_DIO2_GPIO_Port, RADIO_DIO2_Pin ) << 2);
424 #endif
425 #if( RADIO_DIO3_ENABLE )
426 	Status |= (HAL_GPIO_ReadPin( RADIO_DIO3_GPIO_Port, RADIO_DIO3_Pin ) << 3);
427 #endif
428 #if( !RADIO_DIO1_ENABLE && !RADIO_DIO2_ENABLE && !RADIO_DIO3_ENABLE )
429 #error "Please define a DIO"
430 #endif
431 
432 	return Status;
433 }
434