xref: /btstack/chipset/sx128x/SMTC_Drivers/sx1280-driver-c/sx1280-hal.c (revision 90825e06ef7db74092a42a40bc9e7171996f0f42)
1cb5466b0SMatthias Ringwald /*
2cb5466b0SMatthias Ringwald   ______                              _
3cb5466b0SMatthias Ringwald  / _____)             _              | |
4cb5466b0SMatthias Ringwald ( (____  _____ ____ _| |_ _____  ____| |__
5cb5466b0SMatthias Ringwald  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
6cb5466b0SMatthias Ringwald  _____) ) ____| | | || |_| ____( (___| | | |
7cb5466b0SMatthias Ringwald (______/|_____)_|_|_| \__)_____)\____)_| |_|
8cb5466b0SMatthias Ringwald     (C)2016 Semtech
9cb5466b0SMatthias Ringwald 
10cb5466b0SMatthias Ringwald Description: Handling of the node configuration protocol
11cb5466b0SMatthias Ringwald 
12cb5466b0SMatthias Ringwald License: Revised BSD License, see LICENSE.TXT file include in the project
13cb5466b0SMatthias Ringwald 
14cb5466b0SMatthias Ringwald Maintainer: Miguel Luis, Matthieu Verdy and Benjamin Boulet
15cb5466b0SMatthias Ringwald */
16cb5466b0SMatthias Ringwald #include "hw.h"
17cb5466b0SMatthias Ringwald #include "sx1280-hal.h"
18cb5466b0SMatthias Ringwald #include "radio.h"
19cb5466b0SMatthias Ringwald #include <string.h>
20cb5466b0SMatthias Ringwald 
21cb5466b0SMatthias Ringwald // logging on
22cb5466b0SMatthias Ringwald #include "SEGGER_RTT.h"
23cb5466b0SMatthias Ringwald #define printf(format, ...) SEGGER_RTT_printf(0, format,  ## __VA_ARGS__)
24cb5466b0SMatthias Ringwald 
25351edbb3SMatthias Ringwald // make CubeMX defines usable
26351edbb3SMatthias Ringwald #ifndef RADIO_BUSY_PORT
27351edbb3SMatthias Ringwald #define RADIO_BUSY_PORT RADIO_BUSY_GPIO_Port
28351edbb3SMatthias Ringwald #endif
29351edbb3SMatthias Ringwald #ifndef RADIO_BUSY_PIN
30351edbb3SMatthias Ringwald #define RADIO_BUSY_PIN RADIO_BUSY_Pin
31351edbb3SMatthias Ringwald #endif
32351edbb3SMatthias Ringwald #ifndef RADIO_nRESET_PORT
33351edbb3SMatthias Ringwald #define RADIO_nRESET_PORT RADIO_nRESET_GPIO_Port
34351edbb3SMatthias Ringwald #endif
35351edbb3SMatthias Ringwald #ifndef RADIO_nRESET_PIN
36351edbb3SMatthias Ringwald #define RADIO_nRESET_PIN RADIO_nRESET_Pin
37351edbb3SMatthias Ringwald #endif
38351edbb3SMatthias Ringwald #ifndef RADIO_NSS_PORT
39351edbb3SMatthias Ringwald #define RADIO_NSS_PORT RADIO_NSS_GPIO_Port
40351edbb3SMatthias Ringwald #endif
41351edbb3SMatthias Ringwald #ifndef RADIO_NSS_PIN
42351edbb3SMatthias Ringwald #define RADIO_NSS_PIN RADIO_NSS_Pin
43351edbb3SMatthias Ringwald #endif
44cb5466b0SMatthias Ringwald /*!
45cb5466b0SMatthias Ringwald  * \brief Define the size of tx and rx hal buffers
46cb5466b0SMatthias Ringwald  *
47cb5466b0SMatthias Ringwald  * The Tx and Rx hal buffers are used for SPI communication to
48cb5466b0SMatthias Ringwald  * store data to be sent/receive to/from the chip.
49cb5466b0SMatthias Ringwald  *
50cb5466b0SMatthias Ringwald  * \warning The application must ensure the maximal useful size to be much lower
51cb5466b0SMatthias Ringwald  *          than the MAX_HAL_BUFFER_SIZE
52cb5466b0SMatthias Ringwald  */
53cb5466b0SMatthias Ringwald #define MAX_HAL_BUFFER_SIZE   0xFFF
54cb5466b0SMatthias Ringwald 
55cb5466b0SMatthias Ringwald #define IRQ_HIGH_PRIORITY  0
56cb5466b0SMatthias Ringwald 
57cb5466b0SMatthias Ringwald /*!
58cb5466b0SMatthias Ringwald  * Radio driver structure initialization
59cb5466b0SMatthias Ringwald  */
60cb5466b0SMatthias Ringwald const struct Radio_s Radio =
61cb5466b0SMatthias Ringwald {
62cb5466b0SMatthias Ringwald     SX1280Init,
63cb5466b0SMatthias Ringwald     SX1280HalReset,
64cb5466b0SMatthias Ringwald     SX1280GetStatus,
65cb5466b0SMatthias Ringwald     SX1280HalWriteCommand,
66cb5466b0SMatthias Ringwald     SX1280HalReadCommand,
67cb5466b0SMatthias Ringwald     SX1280HalWriteRegisters,
68cb5466b0SMatthias Ringwald     SX1280HalWriteRegister,
69cb5466b0SMatthias Ringwald     SX1280HalReadRegisters,
70cb5466b0SMatthias Ringwald     SX1280HalReadRegister,
71cb5466b0SMatthias Ringwald     SX1280HalWriteBuffer,
72cb5466b0SMatthias Ringwald     SX1280HalReadBuffer,
73cb5466b0SMatthias Ringwald     SX1280HalGetDioStatus,
74cb5466b0SMatthias Ringwald     SX1280GetFirmwareVersion,
75cb5466b0SMatthias Ringwald     SX1280SetRegulatorMode,
76cb5466b0SMatthias Ringwald     SX1280SetStandby,
77cb5466b0SMatthias Ringwald     SX1280SetPacketType,
78cb5466b0SMatthias Ringwald     SX1280SetModulationParams,
79cb5466b0SMatthias Ringwald     SX1280SetPacketParams,
80cb5466b0SMatthias Ringwald     SX1280SetRfFrequency,
81cb5466b0SMatthias Ringwald     SX1280SetBufferBaseAddresses,
82cb5466b0SMatthias Ringwald     SX1280SetTxParams,
83cb5466b0SMatthias Ringwald     SX1280SetDioIrqParams,
84cb5466b0SMatthias Ringwald     SX1280SetSyncWord,
85cb5466b0SMatthias Ringwald     SX1280SetRx,
86cb5466b0SMatthias Ringwald     SX1280GetPayload,
87cb5466b0SMatthias Ringwald     SX1280SendPayload,
88cb5466b0SMatthias Ringwald     SX1280SetRangingRole,
89cb5466b0SMatthias Ringwald     SX1280SetPollingMode,
90cb5466b0SMatthias Ringwald     SX1280SetInterruptMode,
91cb5466b0SMatthias Ringwald     SX1280SetRegistersDefault,
92cb5466b0SMatthias Ringwald     SX1280GetOpMode,
93cb5466b0SMatthias Ringwald     SX1280SetSleep,
94cb5466b0SMatthias Ringwald     SX1280SetFs,
95cb5466b0SMatthias Ringwald     SX1280SetTx,
96cb5466b0SMatthias Ringwald     SX1280SetRxDutyCycle,
97cb5466b0SMatthias Ringwald     SX1280SetCad,
98cb5466b0SMatthias Ringwald     SX1280SetTxContinuousWave,
99cb5466b0SMatthias Ringwald     SX1280SetTxContinuousPreamble,
100cb5466b0SMatthias Ringwald     SX1280GetPacketType,
101cb5466b0SMatthias Ringwald     SX1280SetCadParams,
102cb5466b0SMatthias Ringwald     SX1280GetRxBufferStatus,
103cb5466b0SMatthias Ringwald     SX1280GetPacketStatus,
104cb5466b0SMatthias Ringwald     SX1280GetRssiInst,
105cb5466b0SMatthias Ringwald     SX1280GetIrqStatus,
106cb5466b0SMatthias Ringwald     SX1280ClearIrqStatus,
107cb5466b0SMatthias Ringwald     SX1280Calibrate,
108cb5466b0SMatthias Ringwald     SX1280SetSaveContext,
109cb5466b0SMatthias Ringwald     SX1280SetAutoTx,
110cb5466b0SMatthias Ringwald     SX1280StopAutoTx,
111cb5466b0SMatthias Ringwald     SX1280SetAutoFS,
112cb5466b0SMatthias Ringwald     SX1280SetLongPreamble,
113cb5466b0SMatthias Ringwald     SX1280SetPayload,
114cb5466b0SMatthias Ringwald     SX1280SetSyncWordErrorTolerance,
115cb5466b0SMatthias Ringwald     SX1280SetCrcSeed,
116cb5466b0SMatthias Ringwald     SX1280SetBleAccessAddress,
117cb5466b0SMatthias Ringwald     SX1280SetBleAdvertizerAccessAddress,
118cb5466b0SMatthias Ringwald     SX1280SetCrcPolynomial,
119cb5466b0SMatthias Ringwald     SX1280SetWhiteningSeed,
120cb5466b0SMatthias Ringwald     SX1280EnableManualGain,
121cb5466b0SMatthias Ringwald     SX1280DisableManualGain,
122cb5466b0SMatthias Ringwald     SX1280SetManualGainValue,
123cb5466b0SMatthias Ringwald     SX1280SetLNAGainSetting,
124cb5466b0SMatthias Ringwald     SX1280SetRangingIdLength,
125cb5466b0SMatthias Ringwald     SX1280SetDeviceRangingAddress,
126cb5466b0SMatthias Ringwald     SX1280SetRangingRequestAddress,
127cb5466b0SMatthias Ringwald     SX1280GetRangingResult,
128cb5466b0SMatthias Ringwald     SX1280SetRangingCalibration,
129cb5466b0SMatthias Ringwald     SX1280GetRangingPowerDeltaThresholdIndicator,
130cb5466b0SMatthias Ringwald     SX1280RangingClearFilterResult,
131cb5466b0SMatthias Ringwald     SX1280RangingSetFilterNumSamples,
132cb5466b0SMatthias Ringwald     SX1280GetFrequencyError,
133cb5466b0SMatthias Ringwald };
134cb5466b0SMatthias Ringwald 
135c0c089bbSMatthias Ringwald // static uint8_t halRxBuffer[MAX_HAL_BUFFER_SIZE];
136c0c089bbSMatthias Ringwald static uint8_t halTxBuffer[MAX_HAL_BUFFER_SIZE];
137c0c089bbSMatthias Ringwald const static uint8_t halZeroBuffer[MAX_HAL_BUFFER_SIZE];
138cb5466b0SMatthias Ringwald static DioIrqHandler **dioIrqHandlers;
139cb5466b0SMatthias Ringwald 
140cb5466b0SMatthias Ringwald extern SPI_HandleTypeDef RADIO_SPI_HANDLE;
14178bb22e9SMatthias Ringwald extern DMA_HandleTypeDef RADIO_SPI_DMA_RX;
14278bb22e9SMatthias Ringwald extern DMA_HandleTypeDef RADIO_SPI_DMA_TX;
14378bb22e9SMatthias Ringwald 
144cb5466b0SMatthias Ringwald 
145351edbb3SMatthias Ringwald #ifdef USE_BK_SPI
146351edbb3SMatthias Ringwald 
spi_enable(SPI_HandleTypeDef * hspi)1472fac2f8aSMatthias Ringwald static void spi_enable(SPI_HandleTypeDef *hspi){
14878bb22e9SMatthias Ringwald 	/* Set fiforxthreshold according the reception data length: 8bit */
1492fac2f8aSMatthias Ringwald 	SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
15078bb22e9SMatthias Ringwald 
15178bb22e9SMatthias Ringwald 	/* Check if the SPI is already enabled */
1522fac2f8aSMatthias Ringwald 	if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1532fac2f8aSMatthias Ringwald 	{
15478bb22e9SMatthias Ringwald 		/* Enable SPI peripheral */
1552fac2f8aSMatthias Ringwald 		__HAL_SPI_ENABLE(hspi);
15678bb22e9SMatthias Ringwald 	}
1572fac2f8aSMatthias Ringwald }
1582fac2f8aSMatthias Ringwald 
spi_tx(SPI_HandleTypeDef * hspi,const uint8_t * tx_data,uint16_t tx_len)1592fac2f8aSMatthias Ringwald static void spi_tx(SPI_HandleTypeDef *hspi, const uint8_t * tx_data, uint16_t tx_len){
1602fac2f8aSMatthias Ringwald     // send tx / ignore rx
1612fac2f8aSMatthias Ringwald     uint8_t tx_byte = *tx_data++;
1622fac2f8aSMatthias Ringwald     while (tx_len > 0){
1632fac2f8aSMatthias Ringwald         tx_len--;
1642fac2f8aSMatthias Ringwald         // while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) == 0);
1652fac2f8aSMatthias Ringwald         *(__IO uint8_t *)&hspi->Instance->DR = tx_byte;
1662fac2f8aSMatthias Ringwald         tx_byte = *tx_data++;
1672fac2f8aSMatthias Ringwald         while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) == 0);
1682fac2f8aSMatthias Ringwald         uint8_t rx_byte = *(__IO uint8_t *)&hspi->Instance->DR;
1692fac2f8aSMatthias Ringwald         (void) rx_byte;
1702fac2f8aSMatthias Ringwald     }
1712fac2f8aSMatthias Ringwald }
1722fac2f8aSMatthias Ringwald 
spi_rx(SPI_HandleTypeDef * hspi,uint8_t * rx_buffer,uint16_t rx_len)1732fac2f8aSMatthias Ringwald static void spi_rx(SPI_HandleTypeDef *hspi,  uint8_t * rx_buffer, uint16_t rx_len){
1742fac2f8aSMatthias Ringwald     // send NOP / store rx
1752fac2f8aSMatthias Ringwald     while (rx_len > 0){
1762fac2f8aSMatthias Ringwald         rx_len--;
1772fac2f8aSMatthias Ringwald         // while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) == 0);
1782fac2f8aSMatthias Ringwald         *(__IO uint8_t *)&hspi->Instance->DR = 0;
1792fac2f8aSMatthias Ringwald         while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) == 0);
1802fac2f8aSMatthias Ringwald         *rx_buffer++ = *(__IO uint8_t *)&hspi->Instance->DR;
1812fac2f8aSMatthias Ringwald     }
1822fac2f8aSMatthias Ringwald }
1832fac2f8aSMatthias Ringwald 
spi_tx_only_dma(const uint8_t * tx_data,uint16_t tx_len)1842fac2f8aSMatthias Ringwald static void spi_tx_only_dma(const uint8_t * tx_data, uint16_t tx_len) {
18578bb22e9SMatthias Ringwald 
18678bb22e9SMatthias Ringwald 	HAL_DMA_Start(&RADIO_SPI_DMA_TX, (uintptr_t) tx_data, (uintptr_t) &RADIO_SPI_HANDLE.Instance->DR, tx_len);
18778bb22e9SMatthias Ringwald 
18878bb22e9SMatthias Ringwald 	/* Enable Tx DMA Request */
18978bb22e9SMatthias Ringwald 	SET_BIT(RADIO_SPI_HANDLE.Instance->CR2, SPI_CR2_TXDMAEN);
19078bb22e9SMatthias Ringwald 
19178bb22e9SMatthias Ringwald 	HAL_DMA_PollForTransfer(&RADIO_SPI_DMA_TX, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
19278bb22e9SMatthias Ringwald 
19378bb22e9SMatthias Ringwald 	/* Discard received byte */
19478bb22e9SMatthias Ringwald 	(void) RADIO_SPI_HANDLE.Instance->DR;
19578bb22e9SMatthias Ringwald }
19678bb22e9SMatthias Ringwald 
spi_tx_rx_dma(const uint8_t * tx_data,uint8_t * rx_buffer,uint16_t size)19778bb22e9SMatthias Ringwald static void spi_tx_rx_dma(const uint8_t * tx_data, uint8_t * rx_buffer, uint16_t size) {
19878bb22e9SMatthias Ringwald 
19978bb22e9SMatthias Ringwald 	/* Enable Rx DMA Request */
20078bb22e9SMatthias Ringwald 	SET_BIT(RADIO_SPI_HANDLE.Instance->CR2, SPI_CR2_RXDMAEN);
20178bb22e9SMatthias Ringwald 
20278bb22e9SMatthias Ringwald 	HAL_DMA_Start(&RADIO_SPI_DMA_RX, (uintptr_t) &RADIO_SPI_HANDLE.Instance->DR, (uintptr_t) rx_buffer, size);
20378bb22e9SMatthias Ringwald 	HAL_DMA_Start(&RADIO_SPI_DMA_TX, (uintptr_t) tx_data, (uintptr_t) &RADIO_SPI_HANDLE.Instance->DR, size);
20478bb22e9SMatthias Ringwald 
20578bb22e9SMatthias Ringwald 	/* Enable Tx DMA Request */
20678bb22e9SMatthias Ringwald 	SET_BIT(RADIO_SPI_HANDLE.Instance->CR2, SPI_CR2_TXDMAEN);
20778bb22e9SMatthias Ringwald 
20878bb22e9SMatthias Ringwald 	HAL_DMA_PollForTransfer(&RADIO_SPI_DMA_TX, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
20978bb22e9SMatthias Ringwald 	HAL_DMA_PollForTransfer(&RADIO_SPI_DMA_RX, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
21078bb22e9SMatthias Ringwald }
21178bb22e9SMatthias Ringwald 
212b22bcb2cSMatthias Ringwald #endif
213b22bcb2cSMatthias Ringwald 
2142fac2f8aSMatthias Ringwald // assert: tx_data == tx_buffer (local call), tx_len > 0
2152fac2f8aSMatthias Ringwald // DMA is disabled as one extra byte is read
SX1280HalSpiTxThenRx(uint16_t tx_len,uint8_t * rx_buffer,uint16_t rx_len)216b22bcb2cSMatthias Ringwald void SX1280HalSpiTxThenRx(uint16_t tx_len, uint8_t * rx_buffer, uint16_t rx_len){
217b22bcb2cSMatthias Ringwald 
2182fac2f8aSMatthias Ringwald 	spi_enable(&RADIO_SPI_HANDLE);
21978bb22e9SMatthias Ringwald 
2202fac2f8aSMatthias Ringwald 	// min size for dma to be faster
2212fac2f8aSMatthias Ringwald 	const uint16_t dma_min_size_tx = 100;
2222fac2f8aSMatthias Ringwald 
2232fac2f8aSMatthias Ringwald 	if (tx_len < dma_min_size_tx) {
22478bb22e9SMatthias Ringwald 		// Custom Polling
2252fac2f8aSMatthias Ringwald 		spi_tx(&RADIO_SPI_HANDLE, halTxBuffer, tx_len);
226b22bcb2cSMatthias Ringwald 	} else {
22778bb22e9SMatthias Ringwald 		// Custom DMA
22878bb22e9SMatthias Ringwald 		spi_tx_only_dma( halTxBuffer, tx_len );
22978bb22e9SMatthias Ringwald 	}
23078bb22e9SMatthias Ringwald 
2312fac2f8aSMatthias Ringwald 	// 'Flush' Fifo by reading until marked empty
2322fac2f8aSMatthias Ringwald 	HAL_SPIEx_FlushRxFifo(&RADIO_SPI_HANDLE);
2332fac2f8aSMatthias Ringwald 
2342fac2f8aSMatthias Ringwald 	if (rx_len == 0) return;
2352fac2f8aSMatthias Ringwald 
2362fac2f8aSMatthias Ringwald 	// min size for dma to be faster
2372fac2f8aSMatthias Ringwald 	const uint16_t dma_min_size_rx = 100;
2382fac2f8aSMatthias Ringwald 
2392fac2f8aSMatthias Ringwald 	if (rx_len < dma_min_size_rx){
24078bb22e9SMatthias Ringwald 		// Custom Polling
2412fac2f8aSMatthias Ringwald 		spi_rx(&RADIO_SPI_HANDLE, rx_buffer, rx_len);
24278bb22e9SMatthias Ringwald 	} else {
243c0c089bbSMatthias Ringwald 		// Custom DMA
244c0c089bbSMatthias Ringwald 		spi_tx_rx_dma( halZeroBuffer, rx_buffer, rx_len);
245c0c089bbSMatthias Ringwald 	}
24678bb22e9SMatthias Ringwald }
247cb5466b0SMatthias Ringwald 
248cb5466b0SMatthias Ringwald /*!
249cb5466b0SMatthias Ringwald  * \brief Used to block execution waiting for low state on radio busy pin.
250cb5466b0SMatthias Ringwald  *        Essentially used in SPI communications
251cb5466b0SMatthias Ringwald  */
SX1280HalWaitOnBusy(void)252cb5466b0SMatthias Ringwald void SX1280HalWaitOnBusy( void )
253cb5466b0SMatthias Ringwald {
254cb5466b0SMatthias Ringwald     while( HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN ) == 1 );
255cb5466b0SMatthias Ringwald }
256cb5466b0SMatthias Ringwald 
SX1280HalInit(DioIrqHandler ** irqHandlers)257cb5466b0SMatthias Ringwald void SX1280HalInit( DioIrqHandler **irqHandlers )
258cb5466b0SMatthias Ringwald {
259cb5466b0SMatthias Ringwald     SX1280HalReset( );
260*90825e06SMatthias Ringwald     SX1280HalWakeup();
261cb5466b0SMatthias Ringwald     SX1280HalIoIrqInit( irqHandlers );
262cb5466b0SMatthias Ringwald }
263cb5466b0SMatthias Ringwald 
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)264cb5466b0SMatthias Ringwald void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )
265cb5466b0SMatthias Ringwald {
266cb5466b0SMatthias Ringwald     dioIrqHandlers[0]();
267cb5466b0SMatthias Ringwald }
268cb5466b0SMatthias Ringwald 
SX1280HalIoIrqInit(DioIrqHandler ** irqHandlers)269cb5466b0SMatthias Ringwald void SX1280HalIoIrqInit( DioIrqHandler **irqHandlers )
270cb5466b0SMatthias Ringwald {
271cb5466b0SMatthias Ringwald     dioIrqHandlers = irqHandlers;
272cb5466b0SMatthias Ringwald }
273cb5466b0SMatthias Ringwald 
SX1280HalReset(void)274cb5466b0SMatthias Ringwald void SX1280HalReset( void )
275cb5466b0SMatthias Ringwald {
276cb5466b0SMatthias Ringwald     HAL_Delay( 20 );
277cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 0 );
278cb5466b0SMatthias Ringwald     HAL_Delay( 50 );
279cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_nRESET_PORT, RADIO_nRESET_PIN, 1 );
280cb5466b0SMatthias Ringwald     HAL_Delay( 20 );
281cb5466b0SMatthias Ringwald }
282cb5466b0SMatthias Ringwald 
283b22bcb2cSMatthias Ringwald #if 0
284b22bcb2cSMatthias Ringwald // commented out as (3+IRAM_SIZE) > sizeof(halTxBuffer)
285cb5466b0SMatthias Ringwald void SX1280HalClearInstructionRam( void )
286cb5466b0SMatthias Ringwald {
287cb5466b0SMatthias Ringwald     // Clearing the instruction RAM is writing 0x00s on every bytes of the
288cb5466b0SMatthias Ringwald     // instruction RAM
289cb5466b0SMatthias Ringwald     uint16_t halSize = 3 + IRAM_SIZE;
290cb5466b0SMatthias Ringwald     halTxBuffer[0] = RADIO_WRITE_REGISTER;
291cb5466b0SMatthias Ringwald     halTxBuffer[1] = ( IRAM_START_ADDRESS >> 8 ) & 0x00FF;
292cb5466b0SMatthias Ringwald     halTxBuffer[2] = IRAM_START_ADDRESS & 0x00FF;
293cb5466b0SMatthias Ringwald     for( uint16_t index = 0; index < IRAM_SIZE; index++ )
294cb5466b0SMatthias Ringwald     {
295cb5466b0SMatthias Ringwald         halTxBuffer[3+index] = 0x00;
296cb5466b0SMatthias Ringwald     }
297cb5466b0SMatthias Ringwald 
298cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
299cb5466b0SMatthias Ringwald 
300cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
301cb5466b0SMatthias Ringwald 
302b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( halTxBuffer, halSize, NULL, 0);
303cb5466b0SMatthias Ringwald 
304cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
305cb5466b0SMatthias Ringwald 
306cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
307cb5466b0SMatthias Ringwald }
308b22bcb2cSMatthias Ringwald #endif
309cb5466b0SMatthias Ringwald 
SX1280HalWakeup(void)310cb5466b0SMatthias Ringwald void SX1280HalWakeup( void )
311cb5466b0SMatthias Ringwald {
312cb5466b0SMatthias Ringwald     __disable_irq( );
313cb5466b0SMatthias Ringwald 
314cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
315cb5466b0SMatthias Ringwald 
316cb5466b0SMatthias Ringwald     uint16_t halSize = 2;
317cb5466b0SMatthias Ringwald     halTxBuffer[0] = RADIO_GET_STATUS;
318cb5466b0SMatthias Ringwald     halTxBuffer[1] = 0x00;
319cb5466b0SMatthias Ringwald 
320b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
321cb5466b0SMatthias Ringwald 
322cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
323cb5466b0SMatthias Ringwald 
324cb5466b0SMatthias Ringwald     // Wait for chip to be ready.
325cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
326cb5466b0SMatthias Ringwald 
327cb5466b0SMatthias Ringwald     __enable_irq( );
328cb5466b0SMatthias Ringwald }
329cb5466b0SMatthias Ringwald 
SX1280HalWriteCommand(RadioCommands_t command,uint8_t * buffer,uint16_t size)330cb5466b0SMatthias Ringwald void SX1280HalWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
331cb5466b0SMatthias Ringwald {
332cb5466b0SMatthias Ringwald     uint16_t halSize  = size + 1;
333cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
334cb5466b0SMatthias Ringwald 
335cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
336cb5466b0SMatthias Ringwald 
337cb5466b0SMatthias Ringwald     halTxBuffer[0] = command;
338cb5466b0SMatthias Ringwald     memcpy( halTxBuffer + 1, ( uint8_t * )buffer, size * sizeof( uint8_t ) );
339cb5466b0SMatthias Ringwald 
340b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
341cb5466b0SMatthias Ringwald 
342cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
343cb5466b0SMatthias Ringwald 
344cb5466b0SMatthias Ringwald     if( command != RADIO_SET_SLEEP )
345cb5466b0SMatthias Ringwald     {
346cb5466b0SMatthias Ringwald         SX1280HalWaitOnBusy( );
347cb5466b0SMatthias Ringwald     }
348cb5466b0SMatthias Ringwald }
349cb5466b0SMatthias Ringwald 
SX1280HalReadCommand(RadioCommands_t command,uint8_t * buffer,uint16_t size)350cb5466b0SMatthias Ringwald void SX1280HalReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
351cb5466b0SMatthias Ringwald {
352cb5466b0SMatthias Ringwald     halTxBuffer[0] = command;
353cb5466b0SMatthias Ringwald     halTxBuffer[1] = 0x00;
354cb5466b0SMatthias Ringwald 
355cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
356cb5466b0SMatthias Ringwald 
357cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
358cb5466b0SMatthias Ringwald 
359b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( 2, buffer, size);
360cb5466b0SMatthias Ringwald 
361cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
362cb5466b0SMatthias Ringwald 
363cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
364cb5466b0SMatthias Ringwald }
365cb5466b0SMatthias Ringwald 
SX1280HalWriteRegisters(uint16_t address,uint8_t * buffer,uint16_t size)366cb5466b0SMatthias Ringwald void SX1280HalWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
367cb5466b0SMatthias Ringwald {
368cb5466b0SMatthias Ringwald     uint16_t halSize = size + 3;
369cb5466b0SMatthias Ringwald     halTxBuffer[0] = RADIO_WRITE_REGISTER;
370cb5466b0SMatthias Ringwald     halTxBuffer[1] = ( address & 0xFF00 ) >> 8;
371cb5466b0SMatthias Ringwald     halTxBuffer[2] = address & 0x00FF;
372cb5466b0SMatthias Ringwald     memcpy( halTxBuffer + 3, buffer, size );
373cb5466b0SMatthias Ringwald 
374cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
375cb5466b0SMatthias Ringwald 
376cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
377cb5466b0SMatthias Ringwald 
378b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
379cb5466b0SMatthias Ringwald 
380cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
381cb5466b0SMatthias Ringwald 
382cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
383cb5466b0SMatthias Ringwald }
384cb5466b0SMatthias Ringwald 
SX1280HalWriteRegister(uint16_t address,uint8_t value)385cb5466b0SMatthias Ringwald void SX1280HalWriteRegister( uint16_t address, uint8_t value )
386cb5466b0SMatthias Ringwald {
387cb5466b0SMatthias Ringwald     SX1280HalWriteRegisters( address, &value, 1 );
388cb5466b0SMatthias Ringwald }
389cb5466b0SMatthias Ringwald 
SX1280HalReadRegisters(uint16_t address,uint8_t * buffer,uint16_t size)390cb5466b0SMatthias Ringwald void SX1280HalReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
391cb5466b0SMatthias Ringwald {
392cb5466b0SMatthias Ringwald     halTxBuffer[0] = RADIO_READ_REGISTER;
393cb5466b0SMatthias Ringwald     halTxBuffer[1] = ( address & 0xFF00 ) >> 8;
394cb5466b0SMatthias Ringwald     halTxBuffer[2] = address & 0x00FF;
395cb5466b0SMatthias Ringwald     halTxBuffer[3] = 0x00;
396cb5466b0SMatthias Ringwald 
397cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
398cb5466b0SMatthias Ringwald 
399cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
400cb5466b0SMatthias Ringwald 
401b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( 4, buffer, size);
402cb5466b0SMatthias Ringwald 
403cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
404cb5466b0SMatthias Ringwald 
405cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
406cb5466b0SMatthias Ringwald }
407cb5466b0SMatthias Ringwald 
SX1280HalReadRegister(uint16_t address)408cb5466b0SMatthias Ringwald uint8_t SX1280HalReadRegister( uint16_t address )
409cb5466b0SMatthias Ringwald {
410cb5466b0SMatthias Ringwald     uint8_t data;
411cb5466b0SMatthias Ringwald 
412cb5466b0SMatthias Ringwald     SX1280HalReadRegisters( address, &data, 1 );
413cb5466b0SMatthias Ringwald 
414cb5466b0SMatthias Ringwald     return data;
415cb5466b0SMatthias Ringwald }
416cb5466b0SMatthias Ringwald 
SX1280HalWriteBuffer(uint8_t offset,uint8_t * buffer,uint8_t size)417cb5466b0SMatthias Ringwald void SX1280HalWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
418cb5466b0SMatthias Ringwald {
419cb5466b0SMatthias Ringwald     uint16_t halSize = size + 2;
420cb5466b0SMatthias Ringwald     halTxBuffer[0] = RADIO_WRITE_BUFFER;
421cb5466b0SMatthias Ringwald     halTxBuffer[1] = offset;
422cb5466b0SMatthias Ringwald     memcpy( halTxBuffer + 2, buffer, size );
423cb5466b0SMatthias Ringwald 
424cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
425cb5466b0SMatthias Ringwald 
426cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
427cb5466b0SMatthias Ringwald 
428b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( halSize, NULL, 0);
429cb5466b0SMatthias Ringwald 
430cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
431cb5466b0SMatthias Ringwald 
432cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
433cb5466b0SMatthias Ringwald }
434cb5466b0SMatthias Ringwald 
SX1280HalReadBuffer(uint8_t offset,uint8_t * buffer,uint8_t size)435cb5466b0SMatthias Ringwald void SX1280HalReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
436cb5466b0SMatthias Ringwald {
437cb5466b0SMatthias Ringwald     halTxBuffer[0] = RADIO_READ_BUFFER;
438cb5466b0SMatthias Ringwald     halTxBuffer[1] = offset;
439cb5466b0SMatthias Ringwald     halTxBuffer[2] = 0x00;
440cb5466b0SMatthias Ringwald 
441cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
442cb5466b0SMatthias Ringwald 
443cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 0 );
444cb5466b0SMatthias Ringwald 
445b22bcb2cSMatthias Ringwald 	SX1280HalSpiTxThenRx( 3, buffer, size);
446cb5466b0SMatthias Ringwald 
447cb5466b0SMatthias Ringwald     HAL_GPIO_WritePin( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 );
448cb5466b0SMatthias Ringwald 
449cb5466b0SMatthias Ringwald     SX1280HalWaitOnBusy( );
450cb5466b0SMatthias Ringwald }
451cb5466b0SMatthias Ringwald 
SX1280HalGetDioStatus(void)452cb5466b0SMatthias Ringwald uint8_t SX1280HalGetDioStatus( void )
453cb5466b0SMatthias Ringwald {
454cb5466b0SMatthias Ringwald 	uint8_t Status = HAL_GPIO_ReadPin( RADIO_BUSY_PORT, RADIO_BUSY_PIN );
455cb5466b0SMatthias Ringwald 
456cb5466b0SMatthias Ringwald #if( RADIO_DIO1_ENABLE )
457cb5466b0SMatthias Ringwald 	Status |= (HAL_GPIO_ReadPin( RADIO_DIO1_GPIO_Port, RADIO_DIO1_Pin ) << 1);
458cb5466b0SMatthias Ringwald #endif
459cb5466b0SMatthias Ringwald #if( RADIO_DIO2_ENABLE )
460cb5466b0SMatthias Ringwald 	Status |= (HAL_GPIO_ReadPin( RADIO_DIO2_GPIO_Port, RADIO_DIO2_Pin ) << 2);
461cb5466b0SMatthias Ringwald #endif
462cb5466b0SMatthias Ringwald #if( RADIO_DIO3_ENABLE )
463cb5466b0SMatthias Ringwald 	Status |= (HAL_GPIO_ReadPin( RADIO_DIO3_GPIO_Port, RADIO_DIO3_Pin ) << 3);
464cb5466b0SMatthias Ringwald #endif
465cb5466b0SMatthias Ringwald #if( !RADIO_DIO1_ENABLE && !RADIO_DIO2_ENABLE && !RADIO_DIO3_ENABLE )
466cb5466b0SMatthias Ringwald #error "Please define a DIO"
467cb5466b0SMatthias Ringwald #endif
468cb5466b0SMatthias Ringwald 
469cb5466b0SMatthias Ringwald 	return Status;
470cb5466b0SMatthias Ringwald }
471