xref: /btstack/chipset/sx128x/SMTC_Drivers/sx1280-driver-c/sx1280.c (revision 2ced7aa0927ba0b4fada9921b4e8db0b15a9135a)
1cb5466b0SMatthias Ringwald /*
2cb5466b0SMatthias Ringwald   ______                              _
3cb5466b0SMatthias Ringwald  / _____)             _              | |
4cb5466b0SMatthias Ringwald ( (____  _____ ____ _| |_ _____  ____| |__
5cb5466b0SMatthias Ringwald  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
6cb5466b0SMatthias Ringwald  _____) ) ____| | | || |_| ____( (___| | | |
7cb5466b0SMatthias Ringwald (______/|_____)_|_|_| \__)_____)\____)_| |_|
8cb5466b0SMatthias Ringwald     (C)2016 Semtech
9cb5466b0SMatthias Ringwald 
10cb5466b0SMatthias Ringwald Description: Driver for SX1280 devices
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 <string.h>
17cb5466b0SMatthias Ringwald #include "sx1280.h"
18cb5466b0SMatthias Ringwald #include "sx1280-hal.h"
19*2ced7aa0SMatthias Ringwald #include "RangingCorrection.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 
25cb5466b0SMatthias Ringwald 
26cb5466b0SMatthias Ringwald /*!
27cb5466b0SMatthias Ringwald  * \brief Radio registers definition
28cb5466b0SMatthias Ringwald  *
29cb5466b0SMatthias Ringwald  */
30cb5466b0SMatthias Ringwald typedef struct
31cb5466b0SMatthias Ringwald {
32cb5466b0SMatthias Ringwald     uint16_t      Addr;                             //!< The address of the register
33cb5466b0SMatthias Ringwald     uint8_t       Value;                            //!< The value of the register
34cb5466b0SMatthias Ringwald }RadioRegisters_t;
35cb5466b0SMatthias Ringwald 
36cb5466b0SMatthias Ringwald /*!
37cb5466b0SMatthias Ringwald  * \brief Radio hardware registers initialization definition
38cb5466b0SMatthias Ringwald  */
39cb5466b0SMatthias Ringwald // { Address, RegValue }
40*2ced7aa0SMatthias Ringwald #define RADIO_INIT_REGISTERS_VALUE  { 0 }
41cb5466b0SMatthias Ringwald 
42cb5466b0SMatthias Ringwald /*!
43cb5466b0SMatthias Ringwald  * \brief Radio hardware registers initialization
44cb5466b0SMatthias Ringwald  */
45cb5466b0SMatthias Ringwald const RadioRegisters_t RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;
46cb5466b0SMatthias Ringwald 
47cb5466b0SMatthias Ringwald /*!
48cb5466b0SMatthias Ringwald  * \brief Holds the internal operating mode of the radio
49cb5466b0SMatthias Ringwald  */
50cb5466b0SMatthias Ringwald static RadioOperatingModes_t OperatingMode;
51cb5466b0SMatthias Ringwald 
52cb5466b0SMatthias Ringwald /*!
53cb5466b0SMatthias Ringwald  * \brief Stores the current packet type set in the radio
54cb5466b0SMatthias Ringwald  */
55cb5466b0SMatthias Ringwald static RadioPacketTypes_t PacketType;
56cb5466b0SMatthias Ringwald 
57cb5466b0SMatthias Ringwald /*!
58cb5466b0SMatthias Ringwald  * \brief Stores the current LoRa bandwidth set in the radio
59cb5466b0SMatthias Ringwald  */
60cb5466b0SMatthias Ringwald static RadioLoRaBandwidths_t LoRaBandwidth;
61cb5466b0SMatthias Ringwald 
62cb5466b0SMatthias Ringwald /*!
63cb5466b0SMatthias Ringwald  * \brief Holds the polling state of the driver
64cb5466b0SMatthias Ringwald  */
65cb5466b0SMatthias Ringwald static bool PollingMode;
66cb5466b0SMatthias Ringwald 
67cb5466b0SMatthias Ringwald /*!
68cb5466b0SMatthias Ringwald  * Hardware DIO IRQ callback initialization
69cb5466b0SMatthias Ringwald  */
70cb5466b0SMatthias Ringwald DioIrqHandler *DioIrq[] = { SX1280OnDioIrq };
71cb5466b0SMatthias Ringwald 
72cb5466b0SMatthias Ringwald void SX1280OnDioIrq( void );
73cb5466b0SMatthias Ringwald 
74cb5466b0SMatthias Ringwald /*!
75cb5466b0SMatthias Ringwald  * \brief Holds a flag raised on radio interrupt
76cb5466b0SMatthias Ringwald  */
77cb5466b0SMatthias Ringwald static bool IrqState;
78cb5466b0SMatthias Ringwald 
79cb5466b0SMatthias Ringwald static RadioCallbacks_t* RadioCallbacks;
80cb5466b0SMatthias Ringwald 
SX1280complement2(const uint32_t num,const uint8_t bitCnt)81cb5466b0SMatthias Ringwald int32_t SX1280complement2( const uint32_t num, const uint8_t bitCnt )
82cb5466b0SMatthias Ringwald {
83cb5466b0SMatthias Ringwald     int32_t retVal = ( int32_t )num;
84cb5466b0SMatthias Ringwald     if( num >= 2<<( bitCnt - 2 ) )
85cb5466b0SMatthias Ringwald     {
86cb5466b0SMatthias Ringwald         retVal -= 2<<( bitCnt - 1 );
87cb5466b0SMatthias Ringwald     }
88cb5466b0SMatthias Ringwald     return retVal;
89cb5466b0SMatthias Ringwald }
90cb5466b0SMatthias Ringwald 
SX1280Init(RadioCallbacks_t * callbacks)91cb5466b0SMatthias Ringwald void SX1280Init( RadioCallbacks_t *callbacks )
92cb5466b0SMatthias Ringwald {
93cb5466b0SMatthias Ringwald     RadioCallbacks = callbacks;
94cb5466b0SMatthias Ringwald 
95cb5466b0SMatthias Ringwald     SX1280HalInit( DioIrq );
96cb5466b0SMatthias Ringwald }
97cb5466b0SMatthias Ringwald 
SX1280SetRegistersDefault(void)98cb5466b0SMatthias Ringwald void SX1280SetRegistersDefault( void )
99cb5466b0SMatthias Ringwald {
100cb5466b0SMatthias Ringwald     for( int16_t i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
101cb5466b0SMatthias Ringwald     {
102cb5466b0SMatthias Ringwald         SX1280HalWriteRegister( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
103cb5466b0SMatthias Ringwald     }
104cb5466b0SMatthias Ringwald }
105cb5466b0SMatthias Ringwald 
SX1280GetFirmwareVersion(void)106cb5466b0SMatthias Ringwald uint16_t SX1280GetFirmwareVersion( void )
107cb5466b0SMatthias Ringwald {
108cb5466b0SMatthias Ringwald     return( ( ( SX1280HalReadRegister( REG_LR_FIRMWARE_VERSION_MSB ) ) << 8 ) | ( SX1280HalReadRegister( REG_LR_FIRMWARE_VERSION_MSB + 1 ) ) );
109cb5466b0SMatthias Ringwald }
110cb5466b0SMatthias Ringwald 
SX1280GetStatus(void)111cb5466b0SMatthias Ringwald RadioStatus_t SX1280GetStatus( void )
112cb5466b0SMatthias Ringwald {
113cb5466b0SMatthias Ringwald     uint8_t stat = 0;
114cb5466b0SMatthias Ringwald     RadioStatus_t status;
115cb5466b0SMatthias Ringwald 
116cb5466b0SMatthias Ringwald     SX1280HalReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 );
117cb5466b0SMatthias Ringwald     status.Value = stat;
118cb5466b0SMatthias Ringwald     return status;
119cb5466b0SMatthias Ringwald }
120cb5466b0SMatthias Ringwald 
SX1280GetOpMode(void)121cb5466b0SMatthias Ringwald RadioOperatingModes_t SX1280GetOpMode( void )
122cb5466b0SMatthias Ringwald {
123cb5466b0SMatthias Ringwald     return OperatingMode;
124cb5466b0SMatthias Ringwald }
125cb5466b0SMatthias Ringwald 
SX1280SetSleep(SleepParams_t sleepConfig)126cb5466b0SMatthias Ringwald void SX1280SetSleep( SleepParams_t sleepConfig )
127cb5466b0SMatthias Ringwald {
128cb5466b0SMatthias Ringwald     uint8_t sleep = ( sleepConfig.WakeUpRTC << 3 ) |
129cb5466b0SMatthias Ringwald                     ( sleepConfig.InstructionRamRetention << 2 ) |
130cb5466b0SMatthias Ringwald                     ( sleepConfig.DataBufferRetention << 1 ) |
131cb5466b0SMatthias Ringwald                     ( sleepConfig.DataRamRetention );
132cb5466b0SMatthias Ringwald 
133cb5466b0SMatthias Ringwald     OperatingMode = MODE_SLEEP;
134cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_SLEEP, &sleep, 1 );
135cb5466b0SMatthias Ringwald }
136cb5466b0SMatthias Ringwald 
SX1280SetStandby(RadioStandbyModes_t standbyConfig)137cb5466b0SMatthias Ringwald void SX1280SetStandby( RadioStandbyModes_t standbyConfig )
138cb5466b0SMatthias Ringwald {
139cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 );
140cb5466b0SMatthias Ringwald     if( standbyConfig == STDBY_RC )
141cb5466b0SMatthias Ringwald     {
142cb5466b0SMatthias Ringwald         OperatingMode = MODE_STDBY_RC;
143cb5466b0SMatthias Ringwald     }
144cb5466b0SMatthias Ringwald     else
145cb5466b0SMatthias Ringwald     {
146cb5466b0SMatthias Ringwald         OperatingMode = MODE_STDBY_XOSC;
147cb5466b0SMatthias Ringwald     }
148cb5466b0SMatthias Ringwald }
149cb5466b0SMatthias Ringwald 
SX1280SetFs(void)150cb5466b0SMatthias Ringwald void SX1280SetFs( void )
151cb5466b0SMatthias Ringwald {
152cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_FS, 0, 0 );
153cb5466b0SMatthias Ringwald     OperatingMode = MODE_FS;
154cb5466b0SMatthias Ringwald }
155cb5466b0SMatthias Ringwald 
SX1280SetTx(TickTime_t timeout)156cb5466b0SMatthias Ringwald void SX1280SetTx( TickTime_t timeout )
157cb5466b0SMatthias Ringwald {
158cb5466b0SMatthias Ringwald     uint8_t buf[3];
159cb5466b0SMatthias Ringwald     buf[0] = timeout.Step;
160cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )( ( timeout.NbSteps >> 8 ) & 0x00FF );
161cb5466b0SMatthias Ringwald     buf[2] = ( uint8_t )( timeout.NbSteps & 0x00FF );
162cb5466b0SMatthias Ringwald 
163cb5466b0SMatthias Ringwald // BK BEGIN - skip clear IRQ, it is cleared in process irq
164cb5466b0SMatthias Ringwald //   SX1280ClearIrqStatus( IRQ_RADIO_ALL );
165cb5466b0SMatthias Ringwald // BK END
166cb5466b0SMatthias Ringwald 
167cb5466b0SMatthias Ringwald     // If the radio is doing ranging operations, then apply the specific calls
168cb5466b0SMatthias Ringwald     // prior to SetTx
169cb5466b0SMatthias Ringwald     if( SX1280GetPacketType( ) == PACKET_TYPE_RANGING )
170cb5466b0SMatthias Ringwald     {
171cb5466b0SMatthias Ringwald         SX1280SetRangingRole( RADIO_RANGING_ROLE_MASTER );
172cb5466b0SMatthias Ringwald     }
173cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_TX, buf, 3 );
174cb5466b0SMatthias Ringwald     OperatingMode = MODE_TX;
175cb5466b0SMatthias Ringwald }
176cb5466b0SMatthias Ringwald 
SX1280SetRx(TickTime_t timeout)177cb5466b0SMatthias Ringwald void SX1280SetRx( TickTime_t timeout )
178cb5466b0SMatthias Ringwald {
179cb5466b0SMatthias Ringwald     uint8_t buf[3];
180cb5466b0SMatthias Ringwald     buf[0] = timeout.Step;
181cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )( ( timeout.NbSteps >> 8 ) & 0x00FF );
182cb5466b0SMatthias Ringwald     buf[2] = ( uint8_t )( timeout.NbSteps & 0x00FF );
183cb5466b0SMatthias Ringwald 
184cb5466b0SMatthias Ringwald 
185cb5466b0SMatthias Ringwald // BK BEGIN - skip clear IRQ, it is cleared in process irq
186cb5466b0SMatthias Ringwald //    SX1280ClearIrqStatus( IRQ_RADIO_ALL );
187cb5466b0SMatthias Ringwald // BK END
188cb5466b0SMatthias Ringwald 
189cb5466b0SMatthias Ringwald     // If the radio is doing ranging operations, then apply the specific calls
190cb5466b0SMatthias Ringwald     // prior to SetRx
191cb5466b0SMatthias Ringwald     if( SX1280GetPacketType( ) == PACKET_TYPE_RANGING )
192cb5466b0SMatthias Ringwald     {
193cb5466b0SMatthias Ringwald         SX1280SetRangingRole( RADIO_RANGING_ROLE_SLAVE );
194cb5466b0SMatthias Ringwald     }
195cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_RX, buf, 3 );
196cb5466b0SMatthias Ringwald     OperatingMode = MODE_RX;
197cb5466b0SMatthias Ringwald }
198cb5466b0SMatthias Ringwald 
SX1280SetRxDutyCycle(RadioTickSizes_t Step,uint16_t NbStepRx,uint16_t RxNbStepSleep)199cb5466b0SMatthias Ringwald void SX1280SetRxDutyCycle( RadioTickSizes_t Step, uint16_t NbStepRx, uint16_t RxNbStepSleep )
200cb5466b0SMatthias Ringwald {
201cb5466b0SMatthias Ringwald     uint8_t buf[5];
202cb5466b0SMatthias Ringwald 
203cb5466b0SMatthias Ringwald     buf[0] = Step;
204cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )( ( NbStepRx >> 8 ) & 0x00FF );
205cb5466b0SMatthias Ringwald     buf[2] = ( uint8_t )( NbStepRx & 0x00FF );
206cb5466b0SMatthias Ringwald     buf[3] = ( uint8_t )( ( RxNbStepSleep >> 8 ) & 0x00FF );
207cb5466b0SMatthias Ringwald     buf[4] = ( uint8_t )( RxNbStepSleep & 0x00FF );
208cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 5 );
209cb5466b0SMatthias Ringwald     OperatingMode = MODE_RX;
210cb5466b0SMatthias Ringwald }
211cb5466b0SMatthias Ringwald 
SX1280SetCad(void)212cb5466b0SMatthias Ringwald void SX1280SetCad( void )
213cb5466b0SMatthias Ringwald {
214cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_CAD, 0, 0 );
215cb5466b0SMatthias Ringwald     OperatingMode = MODE_CAD;
216cb5466b0SMatthias Ringwald }
217cb5466b0SMatthias Ringwald 
SX1280SetTxContinuousWave(void)218cb5466b0SMatthias Ringwald void SX1280SetTxContinuousWave( void )
219cb5466b0SMatthias Ringwald {
220cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 );
221cb5466b0SMatthias Ringwald }
222cb5466b0SMatthias Ringwald 
SX1280SetTxContinuousPreamble(void)223cb5466b0SMatthias Ringwald void SX1280SetTxContinuousPreamble( void )
224cb5466b0SMatthias Ringwald {
225cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 );
226cb5466b0SMatthias Ringwald }
227cb5466b0SMatthias Ringwald 
SX1280SetPacketType(RadioPacketTypes_t packetType)228cb5466b0SMatthias Ringwald void SX1280SetPacketType( RadioPacketTypes_t packetType )
229cb5466b0SMatthias Ringwald {
230cb5466b0SMatthias Ringwald     // Save packet type internally to avoid questioning the radio
231cb5466b0SMatthias Ringwald     PacketType = packetType;
232cb5466b0SMatthias Ringwald 
233cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 );
234cb5466b0SMatthias Ringwald }
235cb5466b0SMatthias Ringwald 
SX1280GetPacketType(void)236cb5466b0SMatthias Ringwald RadioPacketTypes_t SX1280GetPacketType( void )
237cb5466b0SMatthias Ringwald {
238cb5466b0SMatthias Ringwald     return PacketType;
239cb5466b0SMatthias Ringwald }
240cb5466b0SMatthias Ringwald 
SX1280SetRfFrequency(uint32_t frequency)241cb5466b0SMatthias Ringwald void SX1280SetRfFrequency( uint32_t frequency )
242cb5466b0SMatthias Ringwald {
243cb5466b0SMatthias Ringwald     uint8_t buf[3];
244cb5466b0SMatthias Ringwald     uint32_t freq = 0;
245cb5466b0SMatthias Ringwald 
246cb5466b0SMatthias Ringwald     freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP );
247cb5466b0SMatthias Ringwald     buf[0] = ( uint8_t )( ( freq >> 16 ) & 0xFF );
248cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )( ( freq >> 8 ) & 0xFF );
249cb5466b0SMatthias Ringwald     buf[2] = ( uint8_t )( freq & 0xFF );
250cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_RFFREQUENCY, buf, 3 );
251cb5466b0SMatthias Ringwald }
252cb5466b0SMatthias Ringwald 
SX1280SetTxParams(int8_t power,RadioRampTimes_t rampTime)253cb5466b0SMatthias Ringwald void SX1280SetTxParams( int8_t power, RadioRampTimes_t rampTime )
254cb5466b0SMatthias Ringwald {
255cb5466b0SMatthias Ringwald     uint8_t buf[2];
256cb5466b0SMatthias Ringwald 
257cb5466b0SMatthias Ringwald     // The power value to send on SPI/UART is in the range [0..31] and the
258cb5466b0SMatthias Ringwald     // physical output power is in the range [-18..13]dBm
259cb5466b0SMatthias Ringwald     buf[0] = power + 18;
260cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )rampTime;
261cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_TXPARAMS, buf, 2 );
262cb5466b0SMatthias Ringwald }
263cb5466b0SMatthias Ringwald 
SX1280SetCadParams(RadioLoRaCadSymbols_t cadSymbolNum)264cb5466b0SMatthias Ringwald void SX1280SetCadParams( RadioLoRaCadSymbols_t cadSymbolNum )
265cb5466b0SMatthias Ringwald {
266cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_CADPARAMS, ( uint8_t* )&cadSymbolNum, 1 );
267cb5466b0SMatthias Ringwald     OperatingMode = MODE_CAD;
268cb5466b0SMatthias Ringwald }
269cb5466b0SMatthias Ringwald 
SX1280SetBufferBaseAddresses(uint8_t txBaseAddress,uint8_t rxBaseAddress)270cb5466b0SMatthias Ringwald void SX1280SetBufferBaseAddresses( uint8_t txBaseAddress, uint8_t rxBaseAddress )
271cb5466b0SMatthias Ringwald {
272cb5466b0SMatthias Ringwald     uint8_t buf[2];
273cb5466b0SMatthias Ringwald 
274cb5466b0SMatthias Ringwald     buf[0] = txBaseAddress;
275cb5466b0SMatthias Ringwald     buf[1] = rxBaseAddress;
276cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 );
277cb5466b0SMatthias Ringwald }
278cb5466b0SMatthias Ringwald 
SX1280SetModulationParams(ModulationParams_t * modulationParams)279cb5466b0SMatthias Ringwald void SX1280SetModulationParams( ModulationParams_t *modulationParams )
280cb5466b0SMatthias Ringwald {
281cb5466b0SMatthias Ringwald     uint8_t buf[3];
282cb5466b0SMatthias Ringwald 
283cb5466b0SMatthias Ringwald     // Check if required configuration corresponds to the stored packet type
284cb5466b0SMatthias Ringwald     // If not, silently update radio packet type
285cb5466b0SMatthias Ringwald     if( PacketType != modulationParams->PacketType )
286cb5466b0SMatthias Ringwald     {
287cb5466b0SMatthias Ringwald         SX1280SetPacketType( modulationParams->PacketType );
288cb5466b0SMatthias Ringwald     }
289cb5466b0SMatthias Ringwald 
290cb5466b0SMatthias Ringwald     switch( modulationParams->PacketType )
291cb5466b0SMatthias Ringwald     {
292cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
293cb5466b0SMatthias Ringwald             buf[0] = modulationParams->Params.Gfsk.BitrateBandwidth;
294cb5466b0SMatthias Ringwald             buf[1] = modulationParams->Params.Gfsk.ModulationIndex;
295cb5466b0SMatthias Ringwald             buf[2] = modulationParams->Params.Gfsk.ModulationShaping;
296cb5466b0SMatthias Ringwald             break;
297cb5466b0SMatthias Ringwald 
298cb5466b0SMatthias Ringwald         case PACKET_TYPE_LORA:
299cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
300cb5466b0SMatthias Ringwald             buf[0] = modulationParams->Params.LoRa.SpreadingFactor;
301cb5466b0SMatthias Ringwald             buf[1] = modulationParams->Params.LoRa.Bandwidth;
302cb5466b0SMatthias Ringwald             buf[2] = modulationParams->Params.LoRa.CodingRate;
303cb5466b0SMatthias Ringwald             LoRaBandwidth = modulationParams->Params.LoRa.Bandwidth;
304cb5466b0SMatthias Ringwald             break;
305cb5466b0SMatthias Ringwald 
306cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
307cb5466b0SMatthias Ringwald             buf[0] = modulationParams->Params.Flrc.BitrateBandwidth;
308cb5466b0SMatthias Ringwald             buf[1] = modulationParams->Params.Flrc.CodingRate;
309cb5466b0SMatthias Ringwald             buf[2] = modulationParams->Params.Flrc.ModulationShaping;
310cb5466b0SMatthias Ringwald             break;
311cb5466b0SMatthias Ringwald 
312cb5466b0SMatthias Ringwald         case PACKET_TYPE_BLE:
313cb5466b0SMatthias Ringwald             buf[0] = modulationParams->Params.Ble.BitrateBandwidth;
314cb5466b0SMatthias Ringwald             buf[1] = modulationParams->Params.Ble.ModulationIndex;
315cb5466b0SMatthias Ringwald             buf[2] = modulationParams->Params.Ble.ModulationShaping;
316cb5466b0SMatthias Ringwald             break;
317cb5466b0SMatthias Ringwald 
318cb5466b0SMatthias Ringwald         case PACKET_TYPE_NONE:
319cb5466b0SMatthias Ringwald             buf[0] = 0;
320cb5466b0SMatthias Ringwald             buf[1] = 0;
321cb5466b0SMatthias Ringwald             buf[2] = 0;
322cb5466b0SMatthias Ringwald             break;
323cb5466b0SMatthias Ringwald     }
324cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, 3 );
325cb5466b0SMatthias Ringwald }
326cb5466b0SMatthias Ringwald 
SX1280SetPacketParams(PacketParams_t * packetParams)327cb5466b0SMatthias Ringwald void SX1280SetPacketParams( PacketParams_t *packetParams )
328cb5466b0SMatthias Ringwald {
329cb5466b0SMatthias Ringwald     uint8_t buf[7];
330cb5466b0SMatthias Ringwald 
331cb5466b0SMatthias Ringwald     // Check if required configuration corresponds to the stored packet type
332cb5466b0SMatthias Ringwald     // If not, silently update radio packet type
333cb5466b0SMatthias Ringwald     if( PacketType != packetParams->PacketType )
334cb5466b0SMatthias Ringwald     {
335cb5466b0SMatthias Ringwald         SX1280SetPacketType( packetParams->PacketType );
336cb5466b0SMatthias Ringwald     }
337cb5466b0SMatthias Ringwald 
338cb5466b0SMatthias Ringwald     switch( packetParams->PacketType )
339cb5466b0SMatthias Ringwald     {
340cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
341cb5466b0SMatthias Ringwald             buf[0] = packetParams->Params.Gfsk.PreambleLength;
342cb5466b0SMatthias Ringwald             buf[1] = packetParams->Params.Gfsk.SyncWordLength;
343cb5466b0SMatthias Ringwald             buf[2] = packetParams->Params.Gfsk.SyncWordMatch;
344cb5466b0SMatthias Ringwald             buf[3] = packetParams->Params.Gfsk.HeaderType;
345cb5466b0SMatthias Ringwald             buf[4] = packetParams->Params.Gfsk.PayloadLength;
346cb5466b0SMatthias Ringwald             buf[5] = packetParams->Params.Gfsk.CrcLength;
347cb5466b0SMatthias Ringwald             buf[6] = packetParams->Params.Gfsk.Whitening;
348cb5466b0SMatthias Ringwald             break;
349cb5466b0SMatthias Ringwald 
350cb5466b0SMatthias Ringwald         case PACKET_TYPE_LORA:
351cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
352cb5466b0SMatthias Ringwald             buf[0] = packetParams->Params.LoRa.PreambleLength;
353cb5466b0SMatthias Ringwald             buf[1] = packetParams->Params.LoRa.HeaderType;
354cb5466b0SMatthias Ringwald             buf[2] = packetParams->Params.LoRa.PayloadLength;
355cb5466b0SMatthias Ringwald             buf[3] = packetParams->Params.LoRa.CrcMode;
356cb5466b0SMatthias Ringwald             buf[4] = packetParams->Params.LoRa.InvertIQ;
357cb5466b0SMatthias Ringwald             buf[5] = 0;
358cb5466b0SMatthias Ringwald             buf[6] = 0;
359cb5466b0SMatthias Ringwald             break;
360cb5466b0SMatthias Ringwald 
361cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
362cb5466b0SMatthias Ringwald             buf[0] = packetParams->Params.Flrc.PreambleLength;
363cb5466b0SMatthias Ringwald             buf[1] = packetParams->Params.Flrc.SyncWordLength;
364cb5466b0SMatthias Ringwald             buf[2] = packetParams->Params.Flrc.SyncWordMatch;
365cb5466b0SMatthias Ringwald             buf[3] = packetParams->Params.Flrc.HeaderType;
366cb5466b0SMatthias Ringwald             buf[4] = packetParams->Params.Flrc.PayloadLength;
367cb5466b0SMatthias Ringwald             buf[5] = packetParams->Params.Flrc.CrcLength;
368cb5466b0SMatthias Ringwald             buf[6] = packetParams->Params.Flrc.Whitening;
369cb5466b0SMatthias Ringwald             break;
370cb5466b0SMatthias Ringwald 
371cb5466b0SMatthias Ringwald         case PACKET_TYPE_BLE:
372cb5466b0SMatthias Ringwald             buf[0] = packetParams->Params.Ble.ConnectionState;
373cb5466b0SMatthias Ringwald             buf[1] = packetParams->Params.Ble.CrcField;
374cb5466b0SMatthias Ringwald             buf[2] = packetParams->Params.Ble.BlePacketType;
375cb5466b0SMatthias Ringwald             buf[3] = packetParams->Params.Ble.Whitening;
376cb5466b0SMatthias Ringwald             buf[4] = 0;
377cb5466b0SMatthias Ringwald             buf[5] = 0;
378cb5466b0SMatthias Ringwald             buf[6] = 0;
379cb5466b0SMatthias Ringwald             break;
380cb5466b0SMatthias Ringwald 
381cb5466b0SMatthias Ringwald         case PACKET_TYPE_NONE:
382cb5466b0SMatthias Ringwald             buf[0] = 0;
383cb5466b0SMatthias Ringwald             buf[1] = 0;
384cb5466b0SMatthias Ringwald             buf[2] = 0;
385cb5466b0SMatthias Ringwald             buf[3] = 0;
386cb5466b0SMatthias Ringwald             buf[4] = 0;
387cb5466b0SMatthias Ringwald             buf[5] = 0;
388cb5466b0SMatthias Ringwald             buf[6] = 0;
389cb5466b0SMatthias Ringwald             break;
390cb5466b0SMatthias Ringwald     }
391cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_PACKETPARAMS, buf, 7 );
392cb5466b0SMatthias Ringwald }
393cb5466b0SMatthias Ringwald 
SX1280GetRxBufferStatus(uint8_t * payloadLength,uint8_t * rxStartBufferPointer)394cb5466b0SMatthias Ringwald void SX1280GetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer )
395cb5466b0SMatthias Ringwald {
396cb5466b0SMatthias Ringwald     uint8_t status[2];
397cb5466b0SMatthias Ringwald 
398cb5466b0SMatthias Ringwald     SX1280HalReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 );
399cb5466b0SMatthias Ringwald 
400cb5466b0SMatthias Ringwald     // In case of LORA fixed header, the payloadLength is obtained by reading
401cb5466b0SMatthias Ringwald     // the register REG_LR_PAYLOADLENGTH
402cb5466b0SMatthias Ringwald     if( ( SX1280GetPacketType( ) == PACKET_TYPE_LORA ) && ( SX1280HalReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) )
403cb5466b0SMatthias Ringwald     {
404cb5466b0SMatthias Ringwald         *payloadLength = SX1280HalReadRegister( REG_LR_PAYLOADLENGTH );
405cb5466b0SMatthias Ringwald     }
406cb5466b0SMatthias Ringwald     else if( SX1280GetPacketType( ) == PACKET_TYPE_BLE )
407cb5466b0SMatthias Ringwald     {
408cb5466b0SMatthias Ringwald         // In the case of BLE, the size returned in status[0] do not include the 2-byte length PDU header
409cb5466b0SMatthias Ringwald         // so it is added there
410cb5466b0SMatthias Ringwald         *payloadLength = status[0] + 2;
411cb5466b0SMatthias Ringwald     }
412cb5466b0SMatthias Ringwald     else
413cb5466b0SMatthias Ringwald     {
414cb5466b0SMatthias Ringwald         *payloadLength = status[0];
415cb5466b0SMatthias Ringwald     }
416cb5466b0SMatthias Ringwald 
417cb5466b0SMatthias Ringwald     *rxStartBufferPointer = status[1];
418cb5466b0SMatthias Ringwald }
419cb5466b0SMatthias Ringwald 
SX1280GetPacketStatus(PacketStatus_t * pktStatus)420cb5466b0SMatthias Ringwald void SX1280GetPacketStatus( PacketStatus_t *pktStatus )
421cb5466b0SMatthias Ringwald {
422cb5466b0SMatthias Ringwald     uint8_t status[5];
423cb5466b0SMatthias Ringwald 
424cb5466b0SMatthias Ringwald     SX1280HalReadCommand( RADIO_GET_PACKETSTATUS, status, 5 );
425cb5466b0SMatthias Ringwald 
426cb5466b0SMatthias Ringwald     pktStatus->packetType = SX1280GetPacketType( );
427cb5466b0SMatthias Ringwald     switch( pktStatus->packetType )
428cb5466b0SMatthias Ringwald     {
429cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
430cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.RssiAvg = -status[0] / 2;
431cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.RssiSync = -status[1] / 2;
432cb5466b0SMatthias Ringwald 
433cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
434cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
435cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
436cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
437cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
438cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
439cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
440cb5466b0SMatthias Ringwald 
441cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
442cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.TxRxStatus.PacketSent = status[3] & 0x01;
443cb5466b0SMatthias Ringwald 
444cb5466b0SMatthias Ringwald             pktStatus->Params.Gfsk.SyncAddrStatus = status[4] & 0x07;
445cb5466b0SMatthias Ringwald             break;
446cb5466b0SMatthias Ringwald 
447cb5466b0SMatthias Ringwald         case PACKET_TYPE_LORA:
448cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
449cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.RssiPkt = -status[0] / 2;
450cb5466b0SMatthias Ringwald             ( status[1] < 128 ) ? ( pktStatus->Params.LoRa.SnrPkt = status[1] / 4 ) : ( pktStatus->Params.LoRa.SnrPkt = ( ( status[1] - 256 ) /4 ) );
451cb5466b0SMatthias Ringwald 
452cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
453cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
454cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
455cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
456cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
457cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
458cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
459cb5466b0SMatthias Ringwald 
460cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
461cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.TxRxStatus.PacketSent = status[3] & 0x01;
462cb5466b0SMatthias Ringwald 
463cb5466b0SMatthias Ringwald             pktStatus->Params.LoRa.SyncAddrStatus = status[4] & 0x07;
464cb5466b0SMatthias Ringwald             break;
465cb5466b0SMatthias Ringwald 
466cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
467cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.RssiAvg = -status[0] / 2;
468cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.RssiSync = -status[1] / 2;
469cb5466b0SMatthias Ringwald 
470cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
471cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
472cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
473cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
474cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
475cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
476cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
477cb5466b0SMatthias Ringwald 
478cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.TxRxStatus.RxPid = ( status[3] >> 6 ) & 0x03;
479cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.TxRxStatus.RxNoAck = ( status[3] >> 5 ) & 0x01;
480cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.TxRxStatus.RxPidErr = ( status[3] >> 4 ) & 0x01;
481cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.TxRxStatus.PacketSent = status[3] & 0x01;
482cb5466b0SMatthias Ringwald 
483cb5466b0SMatthias Ringwald             pktStatus->Params.Flrc.SyncAddrStatus = status[4] & 0x07;
484cb5466b0SMatthias Ringwald             break;
485cb5466b0SMatthias Ringwald 
486cb5466b0SMatthias Ringwald         case PACKET_TYPE_BLE:
487cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.RssiAvg = -status[0] / 2;
488cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.RssiSync = -status[1] / 2;
489cb5466b0SMatthias Ringwald 
490cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.ErrorStatus.SyncError = ( status[2] >> 6 ) & 0x01;
491cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.ErrorStatus.LengthError = ( status[2] >> 5 ) & 0x01;
492cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.ErrorStatus.CrcError = ( status[2] >> 4 ) & 0x01;
493cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.ErrorStatus.AbortError = ( status[2] >> 3 ) & 0x01;
494cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.ErrorStatus.HeaderReceived = ( status[2] >> 2 ) & 0x01;
495cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.ErrorStatus.PacketReceived = ( status[2] >> 1 ) & 0x01;
496cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.ErrorStatus.PacketControlerBusy = status[2] & 0x01;
497cb5466b0SMatthias Ringwald 
498cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.TxRxStatus.PacketSent = status[3] & 0x01;
499cb5466b0SMatthias Ringwald 
500cb5466b0SMatthias Ringwald             pktStatus->Params.Ble.SyncAddrStatus = status[4] & 0x07;
501cb5466b0SMatthias Ringwald             break;
502cb5466b0SMatthias Ringwald 
503cb5466b0SMatthias Ringwald         case PACKET_TYPE_NONE:
504cb5466b0SMatthias Ringwald             // In that specific case, we set everything in the pktStatus to zeros
505cb5466b0SMatthias Ringwald             // and reset the packet type accordingly
506cb5466b0SMatthias Ringwald             memset( pktStatus, 0, sizeof( PacketStatus_t ) );
507cb5466b0SMatthias Ringwald             pktStatus->packetType = PACKET_TYPE_NONE;
508cb5466b0SMatthias Ringwald             break;
509cb5466b0SMatthias Ringwald     }
510cb5466b0SMatthias Ringwald }
511cb5466b0SMatthias Ringwald 
SX1280GetRssiInst(void)512cb5466b0SMatthias Ringwald int8_t SX1280GetRssiInst( void )
513cb5466b0SMatthias Ringwald {
514cb5466b0SMatthias Ringwald     uint8_t raw = 0;
515cb5466b0SMatthias Ringwald 
516cb5466b0SMatthias Ringwald     SX1280HalReadCommand( RADIO_GET_RSSIINST, &raw, 1 );
517cb5466b0SMatthias Ringwald 
518cb5466b0SMatthias Ringwald     return ( int8_t )( -raw / 2 );
519cb5466b0SMatthias Ringwald }
520cb5466b0SMatthias Ringwald 
SX1280SetDioIrqParams(uint16_t irqMask,uint16_t dio1Mask,uint16_t dio2Mask,uint16_t dio3Mask)521cb5466b0SMatthias Ringwald void SX1280SetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask )
522cb5466b0SMatthias Ringwald {
523cb5466b0SMatthias Ringwald     uint8_t buf[8];
524cb5466b0SMatthias Ringwald 
525cb5466b0SMatthias Ringwald     buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF );
526cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )( irqMask & 0x00FF );
527cb5466b0SMatthias Ringwald     buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF );
528cb5466b0SMatthias Ringwald     buf[3] = ( uint8_t )( dio1Mask & 0x00FF );
529cb5466b0SMatthias Ringwald     buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF );
530cb5466b0SMatthias Ringwald     buf[5] = ( uint8_t )( dio2Mask & 0x00FF );
531cb5466b0SMatthias Ringwald     buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF );
532cb5466b0SMatthias Ringwald     buf[7] = ( uint8_t )( dio3Mask & 0x00FF );
533cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_DIOIRQPARAMS, buf, 8 );
534cb5466b0SMatthias Ringwald }
535cb5466b0SMatthias Ringwald 
SX1280GetIrqStatus(void)536cb5466b0SMatthias Ringwald uint16_t SX1280GetIrqStatus( void )
537cb5466b0SMatthias Ringwald {
538cb5466b0SMatthias Ringwald     uint8_t irqStatus[2];
539cb5466b0SMatthias Ringwald 
540cb5466b0SMatthias Ringwald     SX1280HalReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 );
541cb5466b0SMatthias Ringwald 
542cb5466b0SMatthias Ringwald     return ( irqStatus[0] << 8 ) | irqStatus[1];
543cb5466b0SMatthias Ringwald }
544cb5466b0SMatthias Ringwald 
SX1280ClearIrqStatus(uint16_t irq)545cb5466b0SMatthias Ringwald void SX1280ClearIrqStatus( uint16_t irq )
546cb5466b0SMatthias Ringwald {
547cb5466b0SMatthias Ringwald     uint8_t buf[2];
548cb5466b0SMatthias Ringwald 
549cb5466b0SMatthias Ringwald     buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF );
550cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF );
551cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 );
552cb5466b0SMatthias Ringwald }
553cb5466b0SMatthias Ringwald 
SX1280Calibrate(CalibrationParams_t calibParam)554cb5466b0SMatthias Ringwald void SX1280Calibrate( CalibrationParams_t calibParam )
555cb5466b0SMatthias Ringwald {
556cb5466b0SMatthias Ringwald     uint8_t cal = ( calibParam.ADCBulkPEnable << 5 ) |
557cb5466b0SMatthias Ringwald                   ( calibParam.ADCBulkNEnable << 4 ) |
558cb5466b0SMatthias Ringwald                   ( calibParam.ADCPulseEnable << 3 ) |
559cb5466b0SMatthias Ringwald                   ( calibParam.PLLEnable << 2 ) |
560cb5466b0SMatthias Ringwald                   ( calibParam.RC13MEnable << 1 ) |
561cb5466b0SMatthias Ringwald                   ( calibParam.RC64KEnable );
562cb5466b0SMatthias Ringwald 
563cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_CALIBRATE, &cal, 1 );
564cb5466b0SMatthias Ringwald }
565cb5466b0SMatthias Ringwald 
SX1280SetRegulatorMode(RadioRegulatorModes_t mode)566cb5466b0SMatthias Ringwald void SX1280SetRegulatorMode( RadioRegulatorModes_t mode )
567cb5466b0SMatthias Ringwald {
568cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 );
569cb5466b0SMatthias Ringwald }
570cb5466b0SMatthias Ringwald 
SX1280SetSaveContext(void)571cb5466b0SMatthias Ringwald void SX1280SetSaveContext( void )
572cb5466b0SMatthias Ringwald {
573cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_SAVECONTEXT, 0, 0 );
574cb5466b0SMatthias Ringwald }
575cb5466b0SMatthias Ringwald 
SX1280SetAutoTx(uint16_t time)576cb5466b0SMatthias Ringwald void SX1280SetAutoTx( uint16_t time )
577cb5466b0SMatthias Ringwald {
578cb5466b0SMatthias Ringwald     uint16_t compensatedTime = time - ( uint16_t )AUTO_RX_TX_OFFSET;
579cb5466b0SMatthias Ringwald     uint8_t buf[2];
580cb5466b0SMatthias Ringwald 
581cb5466b0SMatthias Ringwald     buf[0] = ( uint8_t )( ( compensatedTime >> 8 ) & 0x00FF );
582cb5466b0SMatthias Ringwald     buf[1] = ( uint8_t )( compensatedTime & 0x00FF );
583cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_AUTOTX, buf, 2 );
584cb5466b0SMatthias Ringwald }
585cb5466b0SMatthias Ringwald 
SX1280StopAutoTx(void)586cb5466b0SMatthias Ringwald void SX1280StopAutoTx( void )
587cb5466b0SMatthias Ringwald {
588cb5466b0SMatthias Ringwald     uint8_t buf[2] = {0x00, 0x00};
589cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_AUTOTX, buf, 2 );
590cb5466b0SMatthias Ringwald }
591cb5466b0SMatthias Ringwald 
SX1280SetAutoFS(uint8_t enable)592cb5466b0SMatthias Ringwald void SX1280SetAutoFS( uint8_t enable )
593cb5466b0SMatthias Ringwald {
594cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_AUTOFS, &enable, 1 );
595cb5466b0SMatthias Ringwald }
596cb5466b0SMatthias Ringwald 
SX1280SetLongPreamble(uint8_t enable)597cb5466b0SMatthias Ringwald void SX1280SetLongPreamble( uint8_t enable )
598cb5466b0SMatthias Ringwald {
599cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_LONGPREAMBLE, &enable, 1 );
600cb5466b0SMatthias Ringwald }
601cb5466b0SMatthias Ringwald 
SX1280SetPayload(uint8_t * buffer,uint8_t size)602cb5466b0SMatthias Ringwald void SX1280SetPayload( uint8_t *buffer, uint8_t size )
603cb5466b0SMatthias Ringwald {
604cb5466b0SMatthias Ringwald     SX1280HalWriteBuffer( 0x00, buffer, size );
605cb5466b0SMatthias Ringwald }
606cb5466b0SMatthias Ringwald 
SX1280GetPayload(uint8_t * buffer,uint8_t * size,uint8_t maxSize)607cb5466b0SMatthias Ringwald uint8_t SX1280GetPayload( uint8_t *buffer, uint8_t *size , uint8_t maxSize )
608cb5466b0SMatthias Ringwald {
609cb5466b0SMatthias Ringwald     uint8_t offset;
610cb5466b0SMatthias Ringwald 
611cb5466b0SMatthias Ringwald     SX1280GetRxBufferStatus( size, &offset );
612cb5466b0SMatthias Ringwald     if( *size > maxSize )
613cb5466b0SMatthias Ringwald     {
614cb5466b0SMatthias Ringwald         return 1;
615cb5466b0SMatthias Ringwald     }
616cb5466b0SMatthias Ringwald     SX1280HalReadBuffer( offset, buffer, *size );
617cb5466b0SMatthias Ringwald     return 0;
618cb5466b0SMatthias Ringwald }
619cb5466b0SMatthias Ringwald 
SX1280SendPayload(uint8_t * payload,uint8_t size,TickTime_t timeout)620cb5466b0SMatthias Ringwald void SX1280SendPayload( uint8_t *payload, uint8_t size, TickTime_t timeout )
621cb5466b0SMatthias Ringwald {
622cb5466b0SMatthias Ringwald     SX1280SetPayload( payload, size );
623cb5466b0SMatthias Ringwald     SX1280SetTx( timeout );
624cb5466b0SMatthias Ringwald }
625cb5466b0SMatthias Ringwald 
SX1280SetSyncWord(uint8_t syncWordIdx,uint8_t * syncWord)626cb5466b0SMatthias Ringwald uint8_t SX1280SetSyncWord( uint8_t syncWordIdx, uint8_t *syncWord )
627cb5466b0SMatthias Ringwald {
628cb5466b0SMatthias Ringwald     uint16_t addr;
629cb5466b0SMatthias Ringwald     uint8_t syncwordSize = 0;
630cb5466b0SMatthias Ringwald 
631cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
632cb5466b0SMatthias Ringwald     {
633cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
634cb5466b0SMatthias Ringwald             syncwordSize = 5;
635cb5466b0SMatthias Ringwald             switch( syncWordIdx )
636cb5466b0SMatthias Ringwald             {
637cb5466b0SMatthias Ringwald                 case 1:
638cb5466b0SMatthias Ringwald                     addr = REG_LR_SYNCWORDBASEADDRESS1;
639cb5466b0SMatthias Ringwald                     break;
640cb5466b0SMatthias Ringwald 
641cb5466b0SMatthias Ringwald                 case 2:
642cb5466b0SMatthias Ringwald                     addr = REG_LR_SYNCWORDBASEADDRESS2;
643cb5466b0SMatthias Ringwald                     break;
644cb5466b0SMatthias Ringwald 
645cb5466b0SMatthias Ringwald                 case 3:
646cb5466b0SMatthias Ringwald                     addr = REG_LR_SYNCWORDBASEADDRESS3;
647cb5466b0SMatthias Ringwald                     break;
648cb5466b0SMatthias Ringwald 
649cb5466b0SMatthias Ringwald                 default:
650cb5466b0SMatthias Ringwald                     return 1;
651cb5466b0SMatthias Ringwald             }
652cb5466b0SMatthias Ringwald             break;
653cb5466b0SMatthias Ringwald 
654cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
655cb5466b0SMatthias Ringwald             // For FLRC packet type, the SyncWord is one byte shorter and
656cb5466b0SMatthias Ringwald             // the base address is shifted by one byte
657cb5466b0SMatthias Ringwald             syncwordSize = 4;
658cb5466b0SMatthias Ringwald             switch( syncWordIdx )
659cb5466b0SMatthias Ringwald             {
660cb5466b0SMatthias Ringwald                 case 1:
661cb5466b0SMatthias Ringwald                     addr = REG_LR_SYNCWORDBASEADDRESS1 + 1;
662cb5466b0SMatthias Ringwald                     break;
663cb5466b0SMatthias Ringwald 
664cb5466b0SMatthias Ringwald                 case 2:
665cb5466b0SMatthias Ringwald                     addr = REG_LR_SYNCWORDBASEADDRESS2 + 1;
666cb5466b0SMatthias Ringwald                     break;
667cb5466b0SMatthias Ringwald 
668cb5466b0SMatthias Ringwald                 case 3:
669cb5466b0SMatthias Ringwald                     addr = REG_LR_SYNCWORDBASEADDRESS3 + 1;
670cb5466b0SMatthias Ringwald                     break;
671cb5466b0SMatthias Ringwald 
672cb5466b0SMatthias Ringwald                 default:
673cb5466b0SMatthias Ringwald                     return 1;
674cb5466b0SMatthias Ringwald             }
675cb5466b0SMatthias Ringwald             break;
676cb5466b0SMatthias Ringwald 
677cb5466b0SMatthias Ringwald         case PACKET_TYPE_BLE:
678cb5466b0SMatthias Ringwald             // For Ble packet type, only the first SyncWord is used and its
679cb5466b0SMatthias Ringwald             // address is shifted by one byte
680cb5466b0SMatthias Ringwald             syncwordSize = 4;
681cb5466b0SMatthias Ringwald             switch( syncWordIdx )
682cb5466b0SMatthias Ringwald             {
683cb5466b0SMatthias Ringwald                 case 1:
684cb5466b0SMatthias Ringwald                     addr = REG_LR_SYNCWORDBASEADDRESS1 + 1;
685cb5466b0SMatthias Ringwald                     break;
686cb5466b0SMatthias Ringwald 
687cb5466b0SMatthias Ringwald                 default:
688cb5466b0SMatthias Ringwald                     return 1;
689cb5466b0SMatthias Ringwald             }
690cb5466b0SMatthias Ringwald             break;
691cb5466b0SMatthias Ringwald 
692cb5466b0SMatthias Ringwald         default:
693cb5466b0SMatthias Ringwald             return 1;
694cb5466b0SMatthias Ringwald     }
695cb5466b0SMatthias Ringwald     SX1280HalWriteRegisters( addr, syncWord, syncwordSize );
696cb5466b0SMatthias Ringwald     return 0;
697cb5466b0SMatthias Ringwald }
698cb5466b0SMatthias Ringwald 
SX1280SetSyncWordErrorTolerance(uint8_t ErrorBits)699cb5466b0SMatthias Ringwald void SX1280SetSyncWordErrorTolerance( uint8_t ErrorBits )
700cb5466b0SMatthias Ringwald {
701cb5466b0SMatthias Ringwald     ErrorBits = ( SX1280HalReadRegister( REG_LR_SYNCWORDTOLERANCE ) & 0xF0 ) | ( ErrorBits & 0x0F );
702cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_SYNCWORDTOLERANCE, ErrorBits );
703cb5466b0SMatthias Ringwald }
704cb5466b0SMatthias Ringwald 
SX1280SetCrcSeed(uint16_t seed)705cb5466b0SMatthias Ringwald void SX1280SetCrcSeed( uint16_t seed )
706cb5466b0SMatthias Ringwald {
707cb5466b0SMatthias Ringwald     uint8_t val[2];
708cb5466b0SMatthias Ringwald 
709cb5466b0SMatthias Ringwald     val[0] = ( uint8_t )( seed >> 8 ) & 0xFF;
710cb5466b0SMatthias Ringwald     val[1] = ( uint8_t )( seed  & 0xFF );
711cb5466b0SMatthias Ringwald 
712cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
713cb5466b0SMatthias Ringwald     {
714cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
715cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
716cb5466b0SMatthias Ringwald             SX1280HalWriteRegisters( REG_LR_CRCSEEDBASEADDR, val, 2 );
717cb5466b0SMatthias Ringwald             break;
718cb5466b0SMatthias Ringwald 
719cb5466b0SMatthias Ringwald         default:
720cb5466b0SMatthias Ringwald             break;
721cb5466b0SMatthias Ringwald     }
722cb5466b0SMatthias Ringwald }
723cb5466b0SMatthias Ringwald 
SX1280SetBleAccessAddress(uint32_t accessAddress)724cb5466b0SMatthias Ringwald void SX1280SetBleAccessAddress( uint32_t accessAddress )
725cb5466b0SMatthias Ringwald {
726cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS, ( accessAddress >> 24 ) & 0x000000FF );
727cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 1, ( accessAddress >> 16 ) & 0x000000FF );
728cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 2, ( accessAddress >> 8 ) & 0x000000FF );
729cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_BLE_ACCESS_ADDRESS + 3, accessAddress & 0x000000FF );
730cb5466b0SMatthias Ringwald }
731cb5466b0SMatthias Ringwald 
SX1280SetBleAdvertizerAccessAddress(void)732cb5466b0SMatthias Ringwald void SX1280SetBleAdvertizerAccessAddress( void )
733cb5466b0SMatthias Ringwald {
734cb5466b0SMatthias Ringwald     SX1280SetBleAccessAddress( BLE_ADVERTIZER_ACCESS_ADDRESS );
735cb5466b0SMatthias Ringwald }
736cb5466b0SMatthias Ringwald 
SX1280SetCrcPolynomial(uint16_t polynomial)737cb5466b0SMatthias Ringwald void SX1280SetCrcPolynomial( uint16_t polynomial )
738cb5466b0SMatthias Ringwald {
739cb5466b0SMatthias Ringwald     uint8_t val[2];
740cb5466b0SMatthias Ringwald 
741cb5466b0SMatthias Ringwald     val[0] = ( uint8_t )( polynomial >> 8 ) & 0xFF;
742cb5466b0SMatthias Ringwald     val[1] = ( uint8_t )( polynomial  & 0xFF );
743cb5466b0SMatthias Ringwald 
744cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
745cb5466b0SMatthias Ringwald     {
746cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
747cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
748cb5466b0SMatthias Ringwald             SX1280HalWriteRegisters( REG_LR_CRCPOLYBASEADDR, val, 2 );
749cb5466b0SMatthias Ringwald             break;
750cb5466b0SMatthias Ringwald 
751cb5466b0SMatthias Ringwald         default:
752cb5466b0SMatthias Ringwald             break;
753cb5466b0SMatthias Ringwald     }
754cb5466b0SMatthias Ringwald }
755cb5466b0SMatthias Ringwald 
SX1280SetWhiteningSeed(uint8_t seed)756cb5466b0SMatthias Ringwald void SX1280SetWhiteningSeed( uint8_t seed )
757cb5466b0SMatthias Ringwald {
758cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
759cb5466b0SMatthias Ringwald     {
760cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
761cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
762cb5466b0SMatthias Ringwald         case PACKET_TYPE_BLE:
763cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( REG_LR_WHITSEEDBASEADDR, seed );
764cb5466b0SMatthias Ringwald             break;
765cb5466b0SMatthias Ringwald 
766cb5466b0SMatthias Ringwald         default:
767cb5466b0SMatthias Ringwald             break;
768cb5466b0SMatthias Ringwald     }
769cb5466b0SMatthias Ringwald }
770cb5466b0SMatthias Ringwald 
SX1280EnableManualGain(void)771cb5466b0SMatthias Ringwald void SX1280EnableManualGain( void )
772cb5466b0SMatthias Ringwald {
773cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_ENABLE_MANUAL_GAIN_CONTROL, SX1280HalReadRegister( REG_ENABLE_MANUAL_GAIN_CONTROL ) | MASK_MANUAL_GAIN_CONTROL );
774cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_DEMOD_DETECTION, SX1280HalReadRegister( REG_DEMOD_DETECTION ) & MASK_DEMOD_DETECTION );
775cb5466b0SMatthias Ringwald }
776cb5466b0SMatthias Ringwald 
SX1280DisableManualGain(void)777cb5466b0SMatthias Ringwald void SX1280DisableManualGain( void )
778cb5466b0SMatthias Ringwald {
779cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_ENABLE_MANUAL_GAIN_CONTROL, SX1280HalReadRegister( REG_ENABLE_MANUAL_GAIN_CONTROL ) & ~MASK_MANUAL_GAIN_CONTROL );
780cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_DEMOD_DETECTION, SX1280HalReadRegister( REG_DEMOD_DETECTION ) | ~MASK_DEMOD_DETECTION );
781cb5466b0SMatthias Ringwald }
782cb5466b0SMatthias Ringwald 
SX1280SetManualGainValue(uint8_t gain)783cb5466b0SMatthias Ringwald void SX1280SetManualGainValue( uint8_t gain )
784cb5466b0SMatthias Ringwald {
785cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_MANUAL_GAIN_VALUE, ( SX1280HalReadRegister( REG_MANUAL_GAIN_VALUE ) & MASK_MANUAL_GAIN_VALUE ) | gain );
786cb5466b0SMatthias Ringwald }
787cb5466b0SMatthias Ringwald 
SX1280SetLNAGainSetting(const RadioLnaSettings_t lnaSetting)788cb5466b0SMatthias Ringwald void SX1280SetLNAGainSetting( const RadioLnaSettings_t lnaSetting )
789cb5466b0SMatthias Ringwald {
790cb5466b0SMatthias Ringwald     switch( lnaSetting )
791cb5466b0SMatthias Ringwald     {
792cb5466b0SMatthias Ringwald         case LNA_HIGH_SENSITIVITY_MODE:
793cb5466b0SMatthias Ringwald         {
794cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( REG_LNA_REGIME, SX1280HalReadRegister( REG_LNA_REGIME ) | MASK_LNA_REGIME );
795cb5466b0SMatthias Ringwald             break;
796cb5466b0SMatthias Ringwald         }
797cb5466b0SMatthias Ringwald         case LNA_LOW_POWER_MODE:
798cb5466b0SMatthias Ringwald         {
799cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( REG_LNA_REGIME, SX1280HalReadRegister( REG_LNA_REGIME ) & ~MASK_LNA_REGIME );
800cb5466b0SMatthias Ringwald             break;
801cb5466b0SMatthias Ringwald         }
802cb5466b0SMatthias Ringwald     }
803cb5466b0SMatthias Ringwald }
804cb5466b0SMatthias Ringwald 
SX1280SetRangingIdLength(RadioRangingIdCheckLengths_t length)805cb5466b0SMatthias Ringwald void SX1280SetRangingIdLength( RadioRangingIdCheckLengths_t length )
806cb5466b0SMatthias Ringwald {
807cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
808cb5466b0SMatthias Ringwald     {
809cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
810cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( REG_LR_RANGINGIDCHECKLENGTH, ( ( ( ( uint8_t )length ) & 0x03 ) << 6 ) | ( SX1280HalReadRegister( REG_LR_RANGINGIDCHECKLENGTH ) & 0x3F ) );
811cb5466b0SMatthias Ringwald             break;
812cb5466b0SMatthias Ringwald 
813cb5466b0SMatthias Ringwald         default:
814cb5466b0SMatthias Ringwald             break;
815cb5466b0SMatthias Ringwald     }
816cb5466b0SMatthias Ringwald }
817cb5466b0SMatthias Ringwald 
SX1280SetDeviceRangingAddress(uint32_t address)818cb5466b0SMatthias Ringwald void SX1280SetDeviceRangingAddress( uint32_t address )
819cb5466b0SMatthias Ringwald {
820cb5466b0SMatthias Ringwald     uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address };
821cb5466b0SMatthias Ringwald 
822cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
823cb5466b0SMatthias Ringwald     {
824cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
825cb5466b0SMatthias Ringwald             SX1280HalWriteRegisters( REG_LR_DEVICERANGINGADDR, addrArray, 4 );
826cb5466b0SMatthias Ringwald             break;
827cb5466b0SMatthias Ringwald 
828cb5466b0SMatthias Ringwald         default:
829cb5466b0SMatthias Ringwald             break;
830cb5466b0SMatthias Ringwald     }
831cb5466b0SMatthias Ringwald }
832cb5466b0SMatthias Ringwald 
SX1280SetRangingRequestAddress(uint32_t address)833cb5466b0SMatthias Ringwald void SX1280SetRangingRequestAddress( uint32_t address )
834cb5466b0SMatthias Ringwald {
835cb5466b0SMatthias Ringwald     uint8_t addrArray[] = { address >> 24, address >> 16, address >> 8, address };
836cb5466b0SMatthias Ringwald 
837cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
838cb5466b0SMatthias Ringwald     {
839cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
840cb5466b0SMatthias Ringwald             SX1280HalWriteRegisters( REG_LR_REQUESTRANGINGADDR, addrArray, 4 );
841cb5466b0SMatthias Ringwald             break;
842cb5466b0SMatthias Ringwald 
843cb5466b0SMatthias Ringwald         default:
844cb5466b0SMatthias Ringwald             break;
845cb5466b0SMatthias Ringwald     }
846cb5466b0SMatthias Ringwald }
847cb5466b0SMatthias Ringwald 
SX1280GetRangingResult(RadioRangingResultTypes_t resultType)848cb5466b0SMatthias Ringwald double SX1280GetRangingResult( RadioRangingResultTypes_t resultType )
849cb5466b0SMatthias Ringwald {
850cb5466b0SMatthias Ringwald     uint32_t valLsb = 0;
851cb5466b0SMatthias Ringwald     double val = 0.0;
852cb5466b0SMatthias Ringwald 
853cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
854cb5466b0SMatthias Ringwald     {
855cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
856cb5466b0SMatthias Ringwald             SX1280SetStandby( STDBY_XOSC );
857cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( 0x97F, SX1280HalReadRegister( 0x97F ) | ( 1 << 1 ) ); // enable LORA modem clock
858cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( REG_LR_RANGINGRESULTCONFIG, ( SX1280HalReadRegister( REG_LR_RANGINGRESULTCONFIG ) & MASK_RANGINGMUXSEL ) | ( ( ( ( uint8_t )resultType ) & 0x03 ) << 4 ) );
859cb5466b0SMatthias Ringwald             valLsb = ( ( SX1280HalReadRegister( REG_LR_RANGINGRESULTBASEADDR ) << 16 ) | ( SX1280HalReadRegister( REG_LR_RANGINGRESULTBASEADDR + 1 ) << 8 ) | ( SX1280HalReadRegister( REG_LR_RANGINGRESULTBASEADDR + 2 ) ) );
860cb5466b0SMatthias Ringwald             SX1280SetStandby( STDBY_RC );
861cb5466b0SMatthias Ringwald 
862cb5466b0SMatthias Ringwald             // Convertion from LSB to distance. For explanation on the formula, refer to Datasheet of SX1280
863cb5466b0SMatthias Ringwald             switch( resultType )
864cb5466b0SMatthias Ringwald             {
865cb5466b0SMatthias Ringwald                 case RANGING_RESULT_RAW:
866cb5466b0SMatthias Ringwald                     // Convert the ranging LSB to distance in meter
867cb5466b0SMatthias Ringwald                     val = ( double )SX1280complement2( valLsb, 24 ) / ( double )SX1280GetLoRaBandwidth( ) * 36621.09375;
868cb5466b0SMatthias Ringwald                     break;
869cb5466b0SMatthias Ringwald 
870cb5466b0SMatthias Ringwald                 case RANGING_RESULT_AVERAGED:
871cb5466b0SMatthias Ringwald                 case RANGING_RESULT_DEBIASED:
872cb5466b0SMatthias Ringwald                 case RANGING_RESULT_FILTERED:
873cb5466b0SMatthias Ringwald                     val = ( double )valLsb * 20.0 / 100.0;
874cb5466b0SMatthias Ringwald                     break;
875cb5466b0SMatthias Ringwald 
876cb5466b0SMatthias Ringwald                 default:
877cb5466b0SMatthias Ringwald                     val = 0.0;
878cb5466b0SMatthias Ringwald             }
879cb5466b0SMatthias Ringwald             break;
880cb5466b0SMatthias Ringwald 
881cb5466b0SMatthias Ringwald         default:
882cb5466b0SMatthias Ringwald             break;
883cb5466b0SMatthias Ringwald     }
884cb5466b0SMatthias Ringwald     return val;
885cb5466b0SMatthias Ringwald }
886cb5466b0SMatthias Ringwald 
SX1280GetRangingPowerDeltaThresholdIndicator(void)887cb5466b0SMatthias Ringwald uint8_t SX1280GetRangingPowerDeltaThresholdIndicator( void )
888cb5466b0SMatthias Ringwald {
889cb5466b0SMatthias Ringwald     SX1280SetStandby( STDBY_XOSC );
890cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( 0x97F, SX1280HalReadRegister( 0x97F ) | ( 1 << 1 ) ); // enable LoRa modem clock
891cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_RANGINGRESULTCONFIG, ( SX1280HalReadRegister( REG_LR_RANGINGRESULTCONFIG ) & MASK_RANGINGMUXSEL ) | ( ( ( ( uint8_t )RANGING_RESULT_RAW ) & 0x03 ) << 4 ) ); // Select raw results
892cb5466b0SMatthias Ringwald     return SX1280HalReadRegister( REG_RANGING_RSSI );
893cb5466b0SMatthias Ringwald }
894cb5466b0SMatthias Ringwald 
SX1280SetRangingCalibration(uint16_t cal)895cb5466b0SMatthias Ringwald void SX1280SetRangingCalibration( uint16_t cal )
896cb5466b0SMatthias Ringwald {
897cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
898cb5466b0SMatthias Ringwald     {
899cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
900cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( REG_LR_RANGINGRERXTXDELAYCAL, ( uint8_t )( ( cal >> 8 ) & 0xFF ) );
901cb5466b0SMatthias Ringwald             SX1280HalWriteRegister( REG_LR_RANGINGRERXTXDELAYCAL + 1, ( uint8_t )( ( cal ) & 0xFF ) );
902cb5466b0SMatthias Ringwald             break;
903cb5466b0SMatthias Ringwald 
904cb5466b0SMatthias Ringwald         default:
905cb5466b0SMatthias Ringwald             break;
906cb5466b0SMatthias Ringwald     }
907cb5466b0SMatthias Ringwald }
908cb5466b0SMatthias Ringwald 
SX1280RangingClearFilterResult(void)909cb5466b0SMatthias Ringwald void SX1280RangingClearFilterResult( void )
910cb5466b0SMatthias Ringwald {
911cb5466b0SMatthias Ringwald     uint8_t regVal = SX1280HalReadRegister( REG_LR_RANGINGRESULTCLEARREG );
912cb5466b0SMatthias Ringwald 
913cb5466b0SMatthias Ringwald     // To clear result, set bit 5 to 1 then to 0
914cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal | ( 1 << 5 ) );
915cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_RANGINGRESULTCLEARREG, regVal & ( ~( 1 << 5 ) ) );
916cb5466b0SMatthias Ringwald }
917cb5466b0SMatthias Ringwald 
SX1280RangingSetFilterNumSamples(uint8_t num)918cb5466b0SMatthias Ringwald void SX1280RangingSetFilterNumSamples( uint8_t num )
919cb5466b0SMatthias Ringwald {
920cb5466b0SMatthias Ringwald     // Silently set 8 as minimum value
921cb5466b0SMatthias Ringwald     SX1280HalWriteRegister( REG_LR_RANGINGFILTERWINDOWSIZE, ( num < DEFAULT_RANGING_FILTER_SIZE ) ? DEFAULT_RANGING_FILTER_SIZE : num );
922cb5466b0SMatthias Ringwald }
923cb5466b0SMatthias Ringwald 
SX1280ParseHexFileLine(char * line)924cb5466b0SMatthias Ringwald int8_t SX1280ParseHexFileLine( char* line )
925cb5466b0SMatthias Ringwald {
926cb5466b0SMatthias Ringwald     uint16_t addr;
927cb5466b0SMatthias Ringwald     uint16_t n;
928cb5466b0SMatthias Ringwald     uint8_t code;
929cb5466b0SMatthias Ringwald     uint8_t bytes[256];
930cb5466b0SMatthias Ringwald 
931cb5466b0SMatthias Ringwald     if( SX1280GetHexFileLineFields( line, bytes, &addr, &n, &code ) != 0 )
932cb5466b0SMatthias Ringwald     {
933cb5466b0SMatthias Ringwald         if( code == 0 )
934cb5466b0SMatthias Ringwald         {
935cb5466b0SMatthias Ringwald             SX1280HalWriteRegisters( addr, bytes, n );
936cb5466b0SMatthias Ringwald         }
937cb5466b0SMatthias Ringwald         if( code == 1 )
938cb5466b0SMatthias Ringwald         { // end of file
939cb5466b0SMatthias Ringwald             //return 2;
940cb5466b0SMatthias Ringwald         }
941cb5466b0SMatthias Ringwald         if( code == 2 )
942cb5466b0SMatthias Ringwald         { // begin of file
943cb5466b0SMatthias Ringwald             //return 3;
944cb5466b0SMatthias Ringwald         }
945cb5466b0SMatthias Ringwald     }
946cb5466b0SMatthias Ringwald     else
947cb5466b0SMatthias Ringwald     {
948cb5466b0SMatthias Ringwald         return 0;
949cb5466b0SMatthias Ringwald     }
950cb5466b0SMatthias Ringwald     return 1;
951cb5466b0SMatthias Ringwald }
952cb5466b0SMatthias Ringwald 
SX1280SetRangingRole(RadioRangingRoles_t role)953cb5466b0SMatthias Ringwald void SX1280SetRangingRole( RadioRangingRoles_t role )
954cb5466b0SMatthias Ringwald {
955cb5466b0SMatthias Ringwald     uint8_t buf[1];
956cb5466b0SMatthias Ringwald 
957cb5466b0SMatthias Ringwald     buf[0] = role;
958cb5466b0SMatthias Ringwald     SX1280HalWriteCommand( RADIO_SET_RANGING_ROLE, &buf[0], 1 );
959cb5466b0SMatthias Ringwald }
960cb5466b0SMatthias Ringwald 
SX1280GetHexFileLineFields(char * line,uint8_t * bytes,uint16_t * addr,uint16_t * num,uint8_t * code)961cb5466b0SMatthias Ringwald int8_t SX1280GetHexFileLineFields( char* line, uint8_t *bytes, uint16_t *addr, uint16_t *num, uint8_t *code )
962cb5466b0SMatthias Ringwald {
963cb5466b0SMatthias Ringwald     uint16_t sum, len, cksum;
964cb5466b0SMatthias Ringwald     char *ptr;
965cb5466b0SMatthias Ringwald 
966cb5466b0SMatthias Ringwald     *num = 0;
967cb5466b0SMatthias Ringwald     if( line[0] != ':' )
968cb5466b0SMatthias Ringwald     {
969cb5466b0SMatthias Ringwald         return 0;
970cb5466b0SMatthias Ringwald     }
971cb5466b0SMatthias Ringwald     if( strlen( line ) < 11 )
972cb5466b0SMatthias Ringwald     {
973cb5466b0SMatthias Ringwald         return 0;
974cb5466b0SMatthias Ringwald     }
975cb5466b0SMatthias Ringwald     ptr = line + 1;
976cb5466b0SMatthias Ringwald     if( !sscanf( ptr, "%02hx", &len ) )
977cb5466b0SMatthias Ringwald     {
978cb5466b0SMatthias Ringwald         return 0;
979cb5466b0SMatthias Ringwald     }
980cb5466b0SMatthias Ringwald     ptr += 2;
981cb5466b0SMatthias Ringwald     if( strlen( line ) < ( 11 + ( len * 2 ) ) )
982cb5466b0SMatthias Ringwald     {
983cb5466b0SMatthias Ringwald         return 0;
984cb5466b0SMatthias Ringwald     }
985cb5466b0SMatthias Ringwald     if( !sscanf( ptr, "%04hx", addr ) )
986cb5466b0SMatthias Ringwald     {
987cb5466b0SMatthias Ringwald         return 0;
988cb5466b0SMatthias Ringwald     }
989cb5466b0SMatthias Ringwald     ptr += 4;
990cb5466b0SMatthias Ringwald     if( !sscanf( ptr, "%02hhx", code ) )
991cb5466b0SMatthias Ringwald     {
992cb5466b0SMatthias Ringwald         return 0;
993cb5466b0SMatthias Ringwald     }
994cb5466b0SMatthias Ringwald     ptr += 2;
995cb5466b0SMatthias Ringwald     sum = ( len & 255 ) + ( ( *addr >> 8 ) & 255 ) + ( *addr & 255 ) + ( ( *code >> 8 ) & 255 ) + ( *code & 255 );
996cb5466b0SMatthias Ringwald     while( *num != len )
997cb5466b0SMatthias Ringwald     {
998cb5466b0SMatthias Ringwald         if( !sscanf( ptr, "%02hhx", &bytes[*num] ) )
999cb5466b0SMatthias Ringwald         {
1000cb5466b0SMatthias Ringwald             return 0;
1001cb5466b0SMatthias Ringwald         }
1002cb5466b0SMatthias Ringwald         ptr += 2;
1003cb5466b0SMatthias Ringwald         sum += bytes[*num] & 255;
1004cb5466b0SMatthias Ringwald         ( *num )++;
1005cb5466b0SMatthias Ringwald         if( *num >= 256 )
1006cb5466b0SMatthias Ringwald         {
1007cb5466b0SMatthias Ringwald             return 0;
1008cb5466b0SMatthias Ringwald         }
1009cb5466b0SMatthias Ringwald     }
1010cb5466b0SMatthias Ringwald     if( !sscanf( ptr, "%02hx", &cksum ) )
1011cb5466b0SMatthias Ringwald     {
1012cb5466b0SMatthias Ringwald         return 0;
1013cb5466b0SMatthias Ringwald     }
1014cb5466b0SMatthias Ringwald     if( ( ( sum & 255 ) + ( cksum & 255 ) ) & 255 )
1015cb5466b0SMatthias Ringwald     {
1016cb5466b0SMatthias Ringwald         return 0; // checksum error
1017cb5466b0SMatthias Ringwald     }
1018cb5466b0SMatthias Ringwald 
1019cb5466b0SMatthias Ringwald     return 1;
1020cb5466b0SMatthias Ringwald }
1021cb5466b0SMatthias Ringwald 
SX1280GetFrequencyError()1022cb5466b0SMatthias Ringwald double SX1280GetFrequencyError( )
1023cb5466b0SMatthias Ringwald {
1024cb5466b0SMatthias Ringwald     uint8_t efeRaw[3] = {0};
1025cb5466b0SMatthias Ringwald     uint32_t efe = 0;
1026cb5466b0SMatthias Ringwald     double efeHz = 0.0;
1027cb5466b0SMatthias Ringwald 
1028cb5466b0SMatthias Ringwald     switch( SX1280GetPacketType( ) )
1029cb5466b0SMatthias Ringwald     {
1030cb5466b0SMatthias Ringwald         case PACKET_TYPE_LORA:
1031cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
1032cb5466b0SMatthias Ringwald             efeRaw[0] = SX1280HalReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB );
1033cb5466b0SMatthias Ringwald             efeRaw[1] = SX1280HalReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 1 );
1034cb5466b0SMatthias Ringwald             efeRaw[2] = SX1280HalReadRegister( REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB + 2 );
1035cb5466b0SMatthias Ringwald             efe = ( efeRaw[0]<<16 ) | ( efeRaw[1]<<8 ) | efeRaw[2];
1036cb5466b0SMatthias Ringwald             efe &= REG_LR_ESTIMATED_FREQUENCY_ERROR_MASK;
1037cb5466b0SMatthias Ringwald 
1038cb5466b0SMatthias Ringwald             efeHz = 1.55 * ( double )SX1280complement2( efe, 20 ) / ( 1600.0 / ( double )SX1280GetLoRaBandwidth( ) * 1000.0 );
1039cb5466b0SMatthias Ringwald             break;
1040cb5466b0SMatthias Ringwald 
1041cb5466b0SMatthias Ringwald         case PACKET_TYPE_NONE:
1042cb5466b0SMatthias Ringwald         case PACKET_TYPE_BLE:
1043cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
1044cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
1045cb5466b0SMatthias Ringwald             break;
1046cb5466b0SMatthias Ringwald     }
1047cb5466b0SMatthias Ringwald 
1048cb5466b0SMatthias Ringwald     return efeHz;
1049cb5466b0SMatthias Ringwald }
1050cb5466b0SMatthias Ringwald 
SX1280SetPollingMode(void)1051cb5466b0SMatthias Ringwald void SX1280SetPollingMode( void )
1052cb5466b0SMatthias Ringwald {
1053cb5466b0SMatthias Ringwald     PollingMode = true;
1054cb5466b0SMatthias Ringwald }
1055cb5466b0SMatthias Ringwald 
SX1280GetLoRaBandwidth()1056cb5466b0SMatthias Ringwald int32_t SX1280GetLoRaBandwidth( )
1057cb5466b0SMatthias Ringwald {
1058cb5466b0SMatthias Ringwald     int32_t bwValue = 0;
1059cb5466b0SMatthias Ringwald 
1060cb5466b0SMatthias Ringwald     switch( LoRaBandwidth )
1061cb5466b0SMatthias Ringwald     {
1062cb5466b0SMatthias Ringwald         case LORA_BW_0200:
1063cb5466b0SMatthias Ringwald             bwValue = 203125;
1064cb5466b0SMatthias Ringwald             break;
1065cb5466b0SMatthias Ringwald 
1066cb5466b0SMatthias Ringwald         case LORA_BW_0400:
1067cb5466b0SMatthias Ringwald             bwValue = 406250;
1068cb5466b0SMatthias Ringwald             break;
1069cb5466b0SMatthias Ringwald 
1070cb5466b0SMatthias Ringwald         case LORA_BW_0800:
1071cb5466b0SMatthias Ringwald             bwValue = 812500;
1072cb5466b0SMatthias Ringwald             break;
1073cb5466b0SMatthias Ringwald 
1074cb5466b0SMatthias Ringwald         case LORA_BW_1600:
1075cb5466b0SMatthias Ringwald             bwValue = 1625000;
1076cb5466b0SMatthias Ringwald             break;
1077cb5466b0SMatthias Ringwald 
1078cb5466b0SMatthias Ringwald         default:
1079cb5466b0SMatthias Ringwald             bwValue = 0;
1080cb5466b0SMatthias Ringwald     }
1081cb5466b0SMatthias Ringwald     return bwValue;
1082cb5466b0SMatthias Ringwald }
1083cb5466b0SMatthias Ringwald 
SX1280GetRangingCorrectionPerSfBwGain(const RadioLoRaSpreadingFactors_t sf,const RadioLoRaBandwidths_t bw,const int8_t gain)1084cb5466b0SMatthias Ringwald double SX1280GetRangingCorrectionPerSfBwGain( const RadioLoRaSpreadingFactors_t sf, const RadioLoRaBandwidths_t bw, const int8_t gain){
1085cb5466b0SMatthias Ringwald     uint8_t sf_index, bw_index;
1086cb5466b0SMatthias Ringwald 
1087cb5466b0SMatthias Ringwald     switch(sf){
1088cb5466b0SMatthias Ringwald         case LORA_SF5:
1089cb5466b0SMatthias Ringwald             sf_index = 0;
1090cb5466b0SMatthias Ringwald             break;
1091cb5466b0SMatthias Ringwald         case LORA_SF6:
1092cb5466b0SMatthias Ringwald             sf_index = 1;
1093cb5466b0SMatthias Ringwald             break;
1094cb5466b0SMatthias Ringwald         case LORA_SF7:
1095cb5466b0SMatthias Ringwald             sf_index = 2;
1096cb5466b0SMatthias Ringwald             break;
1097cb5466b0SMatthias Ringwald         case LORA_SF8:
1098cb5466b0SMatthias Ringwald             sf_index = 3;
1099cb5466b0SMatthias Ringwald             break;
1100cb5466b0SMatthias Ringwald         case LORA_SF9:
1101cb5466b0SMatthias Ringwald             sf_index = 4;
1102cb5466b0SMatthias Ringwald             break;
1103cb5466b0SMatthias Ringwald         case LORA_SF10:
1104cb5466b0SMatthias Ringwald             sf_index = 5;
1105cb5466b0SMatthias Ringwald             break;
1106cb5466b0SMatthias Ringwald 		case LORA_SF11:
1107cb5466b0SMatthias Ringwald 			sf_index = 6;
1108cb5466b0SMatthias Ringwald 			break;
1109cb5466b0SMatthias Ringwald 		case LORA_SF12:
1110cb5466b0SMatthias Ringwald             sf_index = 7;
1111cb5466b0SMatthias Ringwald             break;
1112cb5466b0SMatthias Ringwald     }
1113cb5466b0SMatthias Ringwald     switch(bw){
1114cb5466b0SMatthias Ringwald         case LORA_BW_0400:
1115cb5466b0SMatthias Ringwald             bw_index = 0;
1116cb5466b0SMatthias Ringwald             break;
1117cb5466b0SMatthias Ringwald         case LORA_BW_0800:
1118cb5466b0SMatthias Ringwald             bw_index = 1;
1119cb5466b0SMatthias Ringwald             break;
1120cb5466b0SMatthias Ringwald         case LORA_BW_1600:
1121cb5466b0SMatthias Ringwald             bw_index = 2;
1122cb5466b0SMatthias Ringwald             break;
1123cb5466b0SMatthias Ringwald     }
1124cb5466b0SMatthias Ringwald 
1125cb5466b0SMatthias Ringwald     double correction = RangingCorrectionPerSfBwGain[sf_index][bw_index][gain];
1126cb5466b0SMatthias Ringwald     return correction;
1127cb5466b0SMatthias Ringwald }
1128cb5466b0SMatthias Ringwald 
SX1280ComputeRangingCorrectionPolynome(const RadioLoRaSpreadingFactors_t sf,const RadioLoRaBandwidths_t bw,const double median)1129cb5466b0SMatthias Ringwald double SX1280ComputeRangingCorrectionPolynome(const RadioLoRaSpreadingFactors_t sf, const RadioLoRaBandwidths_t bw, const double median){
1130cb5466b0SMatthias Ringwald     uint8_t sf_index, bw_index;
1131cb5466b0SMatthias Ringwald 
1132cb5466b0SMatthias Ringwald     switch(sf){
1133cb5466b0SMatthias Ringwald         case LORA_SF5:
1134cb5466b0SMatthias Ringwald             sf_index = 0;
1135cb5466b0SMatthias Ringwald             break;
1136cb5466b0SMatthias Ringwald         case LORA_SF6:
1137cb5466b0SMatthias Ringwald             sf_index = 1;
1138cb5466b0SMatthias Ringwald             break;
1139cb5466b0SMatthias Ringwald         case LORA_SF7:
1140cb5466b0SMatthias Ringwald             sf_index = 2;
1141cb5466b0SMatthias Ringwald             break;
1142cb5466b0SMatthias Ringwald         case LORA_SF8:
1143cb5466b0SMatthias Ringwald             sf_index = 3;
1144cb5466b0SMatthias Ringwald             break;
1145cb5466b0SMatthias Ringwald         case LORA_SF9:
1146cb5466b0SMatthias Ringwald             sf_index = 4;
1147cb5466b0SMatthias Ringwald             break;
1148cb5466b0SMatthias Ringwald         case LORA_SF10:
1149cb5466b0SMatthias Ringwald             sf_index = 5;
1150cb5466b0SMatthias Ringwald             break;
1151cb5466b0SMatthias Ringwald 		case LORA_SF11:
1152cb5466b0SMatthias Ringwald 			sf_index = 6;
1153cb5466b0SMatthias Ringwald 			break;
1154cb5466b0SMatthias Ringwald 		case LORA_SF12:
1155cb5466b0SMatthias Ringwald             sf_index = 7;
1156cb5466b0SMatthias Ringwald             break;
1157cb5466b0SMatthias Ringwald     }
1158cb5466b0SMatthias Ringwald     switch(bw){
1159cb5466b0SMatthias Ringwald         case LORA_BW_0400:
1160cb5466b0SMatthias Ringwald             bw_index = 0;
1161cb5466b0SMatthias Ringwald             break;
1162cb5466b0SMatthias Ringwald         case LORA_BW_0800:
1163cb5466b0SMatthias Ringwald             bw_index = 1;
1164cb5466b0SMatthias Ringwald             break;
1165cb5466b0SMatthias Ringwald         case LORA_BW_1600:
1166cb5466b0SMatthias Ringwald             bw_index = 2;
1167cb5466b0SMatthias Ringwald             break;
1168cb5466b0SMatthias Ringwald     }
1169cb5466b0SMatthias Ringwald     const RangingCorrectionPolynomes_t *polynome = RangingCorrectionPolynomesPerSfBw[sf_index][bw_index];
1170cb5466b0SMatthias Ringwald     double correctedValue = 0.0;
1171cb5466b0SMatthias Ringwald     double correctionCoeff = 0;
1172cb5466b0SMatthias Ringwald     for(uint8_t order = 0; order < polynome->order; order++){
1173cb5466b0SMatthias Ringwald         correctionCoeff = polynome->coefficients[order] * pow(median, polynome->order - order - 1);
1174cb5466b0SMatthias Ringwald         correctedValue += correctionCoeff;
1175cb5466b0SMatthias Ringwald     }
1176cb5466b0SMatthias Ringwald     return correctedValue;
1177cb5466b0SMatthias Ringwald }
1178cb5466b0SMatthias Ringwald 
SX1280SetInterruptMode(void)1179cb5466b0SMatthias Ringwald void SX1280SetInterruptMode( void )
1180cb5466b0SMatthias Ringwald {
1181cb5466b0SMatthias Ringwald     PollingMode = false;
1182cb5466b0SMatthias Ringwald }
1183cb5466b0SMatthias Ringwald 
SX1280OnDioIrq(void)1184cb5466b0SMatthias Ringwald void SX1280OnDioIrq( void )
1185cb5466b0SMatthias Ringwald {
1186cb5466b0SMatthias Ringwald     /*
1187cb5466b0SMatthias Ringwald      * When polling mode is activated, it is up to the application to call
1188cb5466b0SMatthias Ringwald      * ProcessIrqs( ). Otherwise, the driver automatically calls ProcessIrqs( )
1189cb5466b0SMatthias Ringwald      * on radio interrupt.
1190cb5466b0SMatthias Ringwald      */
1191cb5466b0SMatthias Ringwald     if( PollingMode == true )
1192cb5466b0SMatthias Ringwald     {
1193cb5466b0SMatthias Ringwald         IrqState = true;
1194cb5466b0SMatthias Ringwald     }
1195cb5466b0SMatthias Ringwald     else
1196cb5466b0SMatthias Ringwald     {
1197cb5466b0SMatthias Ringwald         SX1280ProcessIrqs( );
1198cb5466b0SMatthias Ringwald     }
1199cb5466b0SMatthias Ringwald }
1200cb5466b0SMatthias Ringwald 
SX1280AutoTxWillStart(void)1201cb5466b0SMatthias Ringwald void SX1280AutoTxWillStart( void ){
1202cb5466b0SMatthias Ringwald     OperatingMode = MODE_TX;
1203cb5466b0SMatthias Ringwald }
1204cb5466b0SMatthias Ringwald 
SX1280ProcessIrqs(void)1205cb5466b0SMatthias Ringwald void SX1280ProcessIrqs( void )
1206cb5466b0SMatthias Ringwald {
1207cb5466b0SMatthias Ringwald     RadioPacketTypes_t packetType = PACKET_TYPE_NONE;
1208cb5466b0SMatthias Ringwald 
1209cb5466b0SMatthias Ringwald     if( SX1280GetOpMode( ) == MODE_SLEEP )
1210cb5466b0SMatthias Ringwald     {
1211cb5466b0SMatthias Ringwald         return; // DIO glitch on V2b :-)
1212cb5466b0SMatthias Ringwald     }
1213cb5466b0SMatthias Ringwald 
1214cb5466b0SMatthias Ringwald     if( PollingMode == true )
1215cb5466b0SMatthias Ringwald     {
1216cb5466b0SMatthias Ringwald         if( IrqState == true )
1217cb5466b0SMatthias Ringwald         {
1218cb5466b0SMatthias Ringwald             __disable_irq( );
1219cb5466b0SMatthias Ringwald             IrqState = false;
1220cb5466b0SMatthias Ringwald             __enable_irq( );
1221cb5466b0SMatthias Ringwald         }
1222cb5466b0SMatthias Ringwald         else
1223cb5466b0SMatthias Ringwald         {
1224cb5466b0SMatthias Ringwald             return;
1225cb5466b0SMatthias Ringwald         }
1226cb5466b0SMatthias Ringwald     }
1227cb5466b0SMatthias Ringwald 
1228cb5466b0SMatthias Ringwald     packetType = SX1280GetPacketType( );
1229cb5466b0SMatthias Ringwald     uint16_t irqRegs = SX1280GetIrqStatus( );
1230cb5466b0SMatthias Ringwald     SX1280ClearIrqStatus( IRQ_RADIO_ALL );
1231cb5466b0SMatthias Ringwald 
1232cb5466b0SMatthias Ringwald     switch( packetType )
1233cb5466b0SMatthias Ringwald     {
1234cb5466b0SMatthias Ringwald         case PACKET_TYPE_GFSK:
1235cb5466b0SMatthias Ringwald         case PACKET_TYPE_FLRC:
1236cb5466b0SMatthias Ringwald         case PACKET_TYPE_BLE:
1237cb5466b0SMatthias Ringwald             switch( OperatingMode )
1238cb5466b0SMatthias Ringwald             {
1239cb5466b0SMatthias Ringwald                 case MODE_RX:
1240cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
1241cb5466b0SMatthias Ringwald                     {
1242cb5466b0SMatthias Ringwald                         if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
1243cb5466b0SMatthias Ringwald                         {
1244cb5466b0SMatthias Ringwald                             if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1245cb5466b0SMatthias Ringwald                             {
1246cb5466b0SMatthias Ringwald                                 RadioCallbacks->rxError( IRQ_CRC_ERROR_CODE );
1247cb5466b0SMatthias Ringwald                             }
1248cb5466b0SMatthias Ringwald                         }
1249cb5466b0SMatthias Ringwald                         else if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR )
1250cb5466b0SMatthias Ringwald                         {
1251cb5466b0SMatthias Ringwald                             if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1252cb5466b0SMatthias Ringwald                             {
1253cb5466b0SMatthias Ringwald                                 RadioCallbacks->rxError( IRQ_SYNCWORD_ERROR_CODE );
1254cb5466b0SMatthias Ringwald                             }
1255cb5466b0SMatthias Ringwald                         }
1256cb5466b0SMatthias Ringwald                         else
1257cb5466b0SMatthias Ringwald                         {
1258cb5466b0SMatthias Ringwald                             if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxDone != NULL ) )
1259cb5466b0SMatthias Ringwald                             {
1260cb5466b0SMatthias Ringwald                                 RadioCallbacks->rxDone( );
1261cb5466b0SMatthias Ringwald                             }
1262cb5466b0SMatthias Ringwald                         }
1263cb5466b0SMatthias Ringwald                     }
1264cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID )
1265cb5466b0SMatthias Ringwald                     {
1266cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxSyncWordDone != NULL ) )
1267cb5466b0SMatthias Ringwald                         {
1268cb5466b0SMatthias Ringwald                             RadioCallbacks->rxSyncWordDone( );
1269cb5466b0SMatthias Ringwald                         }
1270cb5466b0SMatthias Ringwald                     }
1271cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_SYNCWORD_ERROR ) == IRQ_SYNCWORD_ERROR )
1272cb5466b0SMatthias Ringwald                     {
1273cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1274cb5466b0SMatthias Ringwald                         {
1275cb5466b0SMatthias Ringwald                             RadioCallbacks->rxError( IRQ_SYNCWORD_ERROR_CODE );
1276cb5466b0SMatthias Ringwald                         }
1277cb5466b0SMatthias Ringwald                     }
1278cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1279cb5466b0SMatthias Ringwald                     {
1280cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxTimeout != NULL ) )
1281cb5466b0SMatthias Ringwald                         {
1282cb5466b0SMatthias Ringwald                             RadioCallbacks->rxTimeout( );
1283cb5466b0SMatthias Ringwald                         }
1284cb5466b0SMatthias Ringwald                     }
1285cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1286cb5466b0SMatthias Ringwald                     {
1287cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1288cb5466b0SMatthias Ringwald                         {
1289cb5466b0SMatthias Ringwald                             RadioCallbacks->txDone( );
1290cb5466b0SMatthias Ringwald                         }
1291cb5466b0SMatthias Ringwald                     }
1292cb5466b0SMatthias Ringwald                     break;
1293cb5466b0SMatthias Ringwald                 case MODE_TX:
1294cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1295cb5466b0SMatthias Ringwald                     {
1296cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1297cb5466b0SMatthias Ringwald                         {
1298cb5466b0SMatthias Ringwald                             RadioCallbacks->txDone( );
1299cb5466b0SMatthias Ringwald                         }
1300cb5466b0SMatthias Ringwald                     }
1301cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1302cb5466b0SMatthias Ringwald                     {
1303cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txTimeout != NULL ) )
1304cb5466b0SMatthias Ringwald                         {
1305cb5466b0SMatthias Ringwald                             RadioCallbacks->txTimeout( );
1306cb5466b0SMatthias Ringwald                         }
1307cb5466b0SMatthias Ringwald                     }
1308cb5466b0SMatthias Ringwald                     break;
1309cb5466b0SMatthias Ringwald                 default:
1310cb5466b0SMatthias Ringwald                     // Unexpected IRQ: silently returns
1311cb5466b0SMatthias Ringwald                     break;
1312cb5466b0SMatthias Ringwald             }
1313cb5466b0SMatthias Ringwald             break;
1314cb5466b0SMatthias Ringwald         case PACKET_TYPE_LORA:
1315cb5466b0SMatthias Ringwald             switch( OperatingMode )
1316cb5466b0SMatthias Ringwald             {
1317cb5466b0SMatthias Ringwald                 case MODE_RX:
1318cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
1319cb5466b0SMatthias Ringwald                     {
1320cb5466b0SMatthias Ringwald                         if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
1321cb5466b0SMatthias Ringwald                         {
1322cb5466b0SMatthias Ringwald                             if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1323cb5466b0SMatthias Ringwald                             {
1324cb5466b0SMatthias Ringwald                                 RadioCallbacks->rxError( IRQ_CRC_ERROR_CODE );
1325cb5466b0SMatthias Ringwald                             }
1326cb5466b0SMatthias Ringwald                         }
1327cb5466b0SMatthias Ringwald                         else
1328cb5466b0SMatthias Ringwald                         {
1329cb5466b0SMatthias Ringwald                             if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxDone != NULL ) )
1330cb5466b0SMatthias Ringwald                             {
1331cb5466b0SMatthias Ringwald                                 RadioCallbacks->rxDone( );
1332cb5466b0SMatthias Ringwald                             }
1333cb5466b0SMatthias Ringwald                         }
1334cb5466b0SMatthias Ringwald                     }
1335cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
1336cb5466b0SMatthias Ringwald                     {
1337cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxHeaderDone != NULL ) )
1338cb5466b0SMatthias Ringwald                         {
1339cb5466b0SMatthias Ringwald                             RadioCallbacks->rxHeaderDone( );
1340cb5466b0SMatthias Ringwald                         }
1341cb5466b0SMatthias Ringwald                     }
1342cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )
1343cb5466b0SMatthias Ringwald                     {
1344cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1345cb5466b0SMatthias Ringwald                         {
1346cb5466b0SMatthias Ringwald                             RadioCallbacks->rxError( IRQ_HEADER_ERROR_CODE );
1347cb5466b0SMatthias Ringwald                         }
1348cb5466b0SMatthias Ringwald                     }
1349cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1350cb5466b0SMatthias Ringwald                     {
1351cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxTimeout != NULL ) )
1352cb5466b0SMatthias Ringwald                         {
1353cb5466b0SMatthias Ringwald                             RadioCallbacks->rxTimeout( );
1354cb5466b0SMatthias Ringwald                         }
1355cb5466b0SMatthias Ringwald                     }
1356cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED )
1357cb5466b0SMatthias Ringwald                     {
1358cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1359cb5466b0SMatthias Ringwald                         {
1360cb5466b0SMatthias Ringwald                             RadioCallbacks->rxError( IRQ_RANGING_ON_LORA_ERROR_CODE );
1361cb5466b0SMatthias Ringwald                         }
1362cb5466b0SMatthias Ringwald                     }
1363cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1364cb5466b0SMatthias Ringwald                     {
1365cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1366cb5466b0SMatthias Ringwald                         {
1367cb5466b0SMatthias Ringwald                             RadioCallbacks->txDone( );
1368cb5466b0SMatthias Ringwald                         }
1369cb5466b0SMatthias Ringwald                     }
1370cb5466b0SMatthias Ringwald                     break;
1371cb5466b0SMatthias Ringwald                 case MODE_TX:
1372cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1373cb5466b0SMatthias Ringwald                     {
1374cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txDone != NULL ) )
1375cb5466b0SMatthias Ringwald                         {
1376cb5466b0SMatthias Ringwald                             RadioCallbacks->txDone( );
1377cb5466b0SMatthias Ringwald                         }
1378cb5466b0SMatthias Ringwald                     }
1379cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1380cb5466b0SMatthias Ringwald                     {
1381cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->txTimeout != NULL ) )
1382cb5466b0SMatthias Ringwald                         {
1383cb5466b0SMatthias Ringwald                             RadioCallbacks->txTimeout( );
1384cb5466b0SMatthias Ringwald                         }
1385cb5466b0SMatthias Ringwald                     }
1386cb5466b0SMatthias Ringwald                     break;
1387cb5466b0SMatthias Ringwald                 case MODE_CAD:
1388cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE )
1389cb5466b0SMatthias Ringwald                     {
1390cb5466b0SMatthias Ringwald                         if( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED )
1391cb5466b0SMatthias Ringwald                         {
1392cb5466b0SMatthias Ringwald                             if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->cadDone != NULL ) )
1393cb5466b0SMatthias Ringwald                             {
1394cb5466b0SMatthias Ringwald                                 RadioCallbacks->cadDone( true );
1395cb5466b0SMatthias Ringwald                             }
1396cb5466b0SMatthias Ringwald                         }
1397cb5466b0SMatthias Ringwald                         else
1398cb5466b0SMatthias Ringwald                         {
1399cb5466b0SMatthias Ringwald                             if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->cadDone != NULL ) )
1400cb5466b0SMatthias Ringwald                             {
1401cb5466b0SMatthias Ringwald                                 RadioCallbacks->cadDone( false );
1402cb5466b0SMatthias Ringwald                             }
1403cb5466b0SMatthias Ringwald                         }
1404cb5466b0SMatthias Ringwald                     }
1405cb5466b0SMatthias Ringwald                     else if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1406cb5466b0SMatthias Ringwald                     {
1407cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxTimeout != NULL ) )
1408cb5466b0SMatthias Ringwald                         {
1409cb5466b0SMatthias Ringwald                             RadioCallbacks->rxTimeout( );
1410cb5466b0SMatthias Ringwald                         }
1411cb5466b0SMatthias Ringwald                     }
1412cb5466b0SMatthias Ringwald                     break;
1413cb5466b0SMatthias Ringwald                 default:
1414cb5466b0SMatthias Ringwald                     // Unexpected IRQ: silently returns
1415cb5466b0SMatthias Ringwald                     break;
1416cb5466b0SMatthias Ringwald             }
1417cb5466b0SMatthias Ringwald             break;
1418cb5466b0SMatthias Ringwald         case PACKET_TYPE_RANGING:
1419cb5466b0SMatthias Ringwald             switch( OperatingMode )
1420cb5466b0SMatthias Ringwald             {
1421cb5466b0SMatthias Ringwald                 // MODE_RX indicates an IRQ on the Slave side
1422cb5466b0SMatthias Ringwald                 case MODE_RX:
1423cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_DISCARDED ) == IRQ_RANGING_SLAVE_REQUEST_DISCARDED )
1424cb5466b0SMatthias Ringwald                     {
1425cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1426cb5466b0SMatthias Ringwald                         {
1427cb5466b0SMatthias Ringwald                             RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE );
1428cb5466b0SMatthias Ringwald                         }
1429cb5466b0SMatthias Ringwald                     }
1430cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RANGING_SLAVE_REQUEST_VALID ) == IRQ_RANGING_SLAVE_REQUEST_VALID )
1431cb5466b0SMatthias Ringwald                     {
1432cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1433cb5466b0SMatthias Ringwald                         {
1434cb5466b0SMatthias Ringwald                             RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_VALID_CODE );
1435cb5466b0SMatthias Ringwald                         }
1436cb5466b0SMatthias Ringwald                     }
1437cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RANGING_SLAVE_RESPONSE_DONE ) == IRQ_RANGING_SLAVE_RESPONSE_DONE )
1438cb5466b0SMatthias Ringwald                     {
1439cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1440cb5466b0SMatthias Ringwald                         {
1441cb5466b0SMatthias Ringwald                             RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_VALID_CODE );
1442cb5466b0SMatthias Ringwald                         }
1443cb5466b0SMatthias Ringwald                     }
1444cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1445cb5466b0SMatthias Ringwald                     {
1446cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1447cb5466b0SMatthias Ringwald                         {
1448cb5466b0SMatthias Ringwald                             RadioCallbacks->rangingDone( IRQ_RANGING_SLAVE_ERROR_CODE );
1449cb5466b0SMatthias Ringwald                         }
1450cb5466b0SMatthias Ringwald                     }
1451cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
1452cb5466b0SMatthias Ringwald                     {
1453cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxHeaderDone != NULL ) )
1454cb5466b0SMatthias Ringwald                         {
1455cb5466b0SMatthias Ringwald                             RadioCallbacks->rxHeaderDone( );
1456cb5466b0SMatthias Ringwald                         }
1457cb5466b0SMatthias Ringwald                     }
1458cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )
1459cb5466b0SMatthias Ringwald                     {
1460cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rxError != NULL ) )
1461cb5466b0SMatthias Ringwald                         {
1462cb5466b0SMatthias Ringwald                             RadioCallbacks->rxError( IRQ_HEADER_ERROR_CODE );
1463cb5466b0SMatthias Ringwald                         }
1464cb5466b0SMatthias Ringwald                     }
1465cb5466b0SMatthias Ringwald                     break;
1466cb5466b0SMatthias Ringwald                 // MODE_TX indicates an IRQ on the Master side
1467cb5466b0SMatthias Ringwald                 case MODE_TX:
1468cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RANGING_MASTER_RESULT_TIMEOUT ) == IRQ_RANGING_MASTER_RESULT_TIMEOUT )
1469cb5466b0SMatthias Ringwald                     {
1470cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1471cb5466b0SMatthias Ringwald                         {
1472cb5466b0SMatthias Ringwald                             RadioCallbacks->rangingDone( IRQ_RANGING_MASTER_ERROR_CODE );
1473cb5466b0SMatthias Ringwald                         }
1474cb5466b0SMatthias Ringwald                     }
1475cb5466b0SMatthias Ringwald                     if( ( irqRegs & IRQ_RANGING_MASTER_RESULT_VALID ) == IRQ_RANGING_MASTER_RESULT_VALID )
1476cb5466b0SMatthias Ringwald                     {
1477cb5466b0SMatthias Ringwald                         if( ( RadioCallbacks != NULL ) && ( RadioCallbacks->rangingDone != NULL ) )
1478cb5466b0SMatthias Ringwald                         {
1479cb5466b0SMatthias Ringwald                             RadioCallbacks->rangingDone( IRQ_RANGING_MASTER_VALID_CODE );
1480cb5466b0SMatthias Ringwald                         }
1481cb5466b0SMatthias Ringwald                     }
1482cb5466b0SMatthias Ringwald                     break;
1483cb5466b0SMatthias Ringwald                 default:
1484cb5466b0SMatthias Ringwald                     // Unexpected IRQ: silently returns
1485cb5466b0SMatthias Ringwald                     break;
1486cb5466b0SMatthias Ringwald             }
1487cb5466b0SMatthias Ringwald             break;
1488cb5466b0SMatthias Ringwald         default:
1489cb5466b0SMatthias Ringwald             // Unexpected IRQ: silently returns
1490cb5466b0SMatthias Ringwald             break;
1491cb5466b0SMatthias Ringwald     }
1492cb5466b0SMatthias Ringwald }
1493