Skip to content

Commit bb606c8

Browse files
committed
Changed radio drivers floating point to integer computations
1 parent 02eac20 commit bb606c8

File tree

8 files changed

+252
-90
lines changed

8 files changed

+252
-90
lines changed

src/radio/lr1110/radio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, uint32_t datarat
654654
lr1110_radio_set_gfsk_crc_params( &LR1110, 0x1D0F, 0x1021 );
655655
lr1110_radio_set_gfsk_whitening_params( &LR1110, 0x01FF );
656656

657-
RxTimeout = ( uint32_t )( symbTimeout * ( ( 1.0 / ( double ) datarate ) * 8.0 ) * 1000 );
657+
RxTimeout = ( uint32_t )symbTimeout * 8000UL / datarate;;
658658
break;
659659

660660
case MODEM_LORA:

src/radio/sx126x/radio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth,
681681
SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } );
682682
SX126xSetWhiteningSeed( 0x01FF );
683683

684-
RxTimeout = ( uint32_t )( symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1000 );
684+
RxTimeout = ( uint32_t )symbTimeout * 8000UL / datarate;
685685
break;
686686

687687
case MODEM_LORA:

src/radio/sx126x/sx126x.c

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,25 @@
2828
#include "sx126x.h"
2929
#include "sx126x-board.h"
3030

31+
/*!
32+
* \brief Internal frequency of the radio
33+
*/
34+
#define SX126X_XTAL_FREQ 32000000UL
35+
36+
/*!
37+
* \brief Scaling factor used to perform fixed-point operations
38+
*/
39+
#define SX126X_PLL_STEP_SHIFT_AMOUNT ( 14 )
40+
41+
/*!
42+
* \brief PLL step - scaled with SX126X_PLL_STEP_SHIFT_AMOUNT
43+
*/
44+
#define SX126X_PLL_STEP_SCALED ( SX126X_XTAL_FREQ >> ( 25 - SX126X_PLL_STEP_SHIFT_AMOUNT ) )
45+
3146
/*!
3247
* \brief Maximum value for parameter symbNum in \ref SX126xSetLoRaSymbNumTimeout
3348
*/
34-
#define SX126X_MAX_LORA_SYMB_NUM_TIMEOUT 248
49+
#define SX126X_MAX_LORA_SYMB_NUM_TIMEOUT 248
3550

3651
/*!
3752
* \brief Radio registers definition
@@ -62,6 +77,15 @@ volatile uint32_t FrequencyError = 0;
6277
*/
6378
static bool ImageCalibrated = false;
6479

80+
/*!
81+
* \brief Get the number of PLL steps for a given frequency in Hertz
82+
*
83+
* \param [in] freqInHz Frequency in Hertz
84+
*
85+
* \returns Number of PLL steps
86+
*/
87+
static uint32_t SX126xConvertFreqInHzToPllStep( uint32_t freqInHz );
88+
6589
/*
6690
* SX126x DIO IRQ callback functions prototype
6791
*/
@@ -459,19 +483,19 @@ void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeo
459483
void SX126xSetRfFrequency( uint32_t frequency )
460484
{
461485
uint8_t buf[4];
462-
uint32_t freq = 0;
463486

464487
if( ImageCalibrated == false )
465488
{
466489
SX126xCalibrateImage( frequency );
467490
ImageCalibrated = true;
468491
}
469492

470-
freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP );
471-
buf[0] = ( uint8_t )( ( freq >> 24 ) & 0xFF );
472-
buf[1] = ( uint8_t )( ( freq >> 16 ) & 0xFF );
473-
buf[2] = ( uint8_t )( ( freq >> 8 ) & 0xFF );
474-
buf[3] = ( uint8_t )( freq & 0xFF );
493+
uint32_t freqInPllSteps = SX126xConvertFreqInHzToPllStep( frequency );
494+
495+
buf[0] = ( uint8_t )( ( freqInPllSteps >> 24 ) & 0xFF );
496+
buf[1] = ( uint8_t )( ( freqInPllSteps >> 16 ) & 0xFF );
497+
buf[2] = ( uint8_t )( ( freqInPllSteps >> 8 ) & 0xFF );
498+
buf[3] = ( uint8_t )( freqInPllSteps & 0xFF );
475499
SX126xWriteCommand( RADIO_SET_RFFREQUENCY, buf, 4 );
476500
}
477501

@@ -549,13 +573,13 @@ void SX126xSetModulationParams( ModulationParams_t *modulationParams )
549573
{
550574
case PACKET_TYPE_GFSK:
551575
n = 8;
552-
tempVal = ( uint32_t )( 32 * ( ( double )XTAL_FREQ / ( double )modulationParams->Params.Gfsk.BitRate ) );
576+
tempVal = ( uint32_t )( 32 * SX126X_XTAL_FREQ / modulationParams->Params.Gfsk.BitRate );
553577
buf[0] = ( tempVal >> 16 ) & 0xFF;
554578
buf[1] = ( tempVal >> 8 ) & 0xFF;
555579
buf[2] = tempVal & 0xFF;
556580
buf[3] = modulationParams->Params.Gfsk.ModulationShaping;
557581
buf[4] = modulationParams->Params.Gfsk.Bandwidth;
558-
tempVal = ( uint32_t )( ( double )modulationParams->Params.Gfsk.Fdev / ( double )FREQ_STEP );
582+
tempVal = SX126xConvertFreqInHzToPllStep( modulationParams->Params.Gfsk.Fdev );
559583
buf[5] = ( tempVal >> 16 ) & 0xFF;
560584
buf[6] = ( tempVal >> 8 ) & 0xFF;
561585
buf[7] = ( tempVal& 0xFF );
@@ -765,3 +789,19 @@ void SX126xClearIrqStatus( uint16_t irq )
765789
buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF );
766790
SX126xWriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 );
767791
}
792+
793+
static uint32_t SX126xConvertFreqInHzToPllStep( uint32_t freqInHz )
794+
{
795+
uint32_t stepsInt;
796+
uint32_t stepsFrac;
797+
798+
// pllSteps = freqInHz / (SX126X_XTAL_FREQ / 2^19 )
799+
// Get integer and fractional parts of the frequency computed with a PLL step scaled value
800+
stepsInt = freqInHz / SX126X_PLL_STEP_SCALED;
801+
stepsFrac = freqInHz - ( stepsInt * SX126X_PLL_STEP_SCALED );
802+
803+
// Apply the scaling factor to retrieve a frequency in Hz (+ ceiling)
804+
return ( stepsInt << SX126X_PLL_STEP_SHIFT_AMOUNT ) +
805+
( ( ( stepsFrac << SX126X_PLL_STEP_SHIFT_AMOUNT ) + ( SX126X_PLL_STEP_SCALED >> 1 ) ) /
806+
SX126X_PLL_STEP_SCALED );
807+
}

src/radio/sx126x/sx126x.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -692,21 +692,10 @@ typedef struct SX126x_s
692692
*/
693693
typedef void ( DioIrqHandler )( void* context );
694694

695-
/*!
695+
/*
696696
* SX126x definitions
697697
*/
698698

699-
/*!
700-
* \brief Provides the frequency of the chip running on the radio and the frequency step
701-
*
702-
* \remark These defines are used for computing the frequency divider to set the RF frequency
703-
*/
704-
#define XTAL_FREQ ( double )32000000
705-
#define FREQ_DIV ( double )pow( 2.0, 25.0 )
706-
#define FREQ_STEP ( double )( XTAL_FREQ / FREQ_DIV )
707-
708-
#define RX_BUFFER_SIZE 256
709-
710699
/*!
711700
* \brief The radio callbacks structure
712701
* Holds function pointers to be called on radio interrupts

src/radio/sx1272/sx1272.c

Lines changed: 97 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,26 @@
2929
#include "sx1272.h"
3030
#include "sx1272-board.h"
3131

32+
/*!
33+
* \brief Internal frequency of the radio
34+
*/
35+
#define SX1272_XTAL_FREQ 32000000UL
36+
37+
/*!
38+
* \brief Scaling factor used to perform fixed-point operations
39+
*/
40+
#define SX1272_PLL_STEP_SHIFT_AMOUNT ( 8 )
41+
42+
/*!
43+
* \brief PLL step - scaled with SX1276_PLL_STEP_SHIFT_AMOUNT
44+
*/
45+
#define SX1272_PLL_STEP_SCALED ( SX1272_XTAL_FREQ >> ( 19 - SX1272_PLL_STEP_SHIFT_AMOUNT ) )
46+
47+
/*!
48+
* \brief Radio buffer size
49+
*/
50+
#define RX_TX_BUFFER_SIZE 256
51+
3252
/*
3353
* Local types definition
3454
*/
@@ -87,25 +107,43 @@ static void SX1272ReadFifo( uint8_t *buffer, uint8_t size );
87107
*/
88108
static void SX1272SetOpMode( uint8_t opMode );
89109

90-
/**
91-
* @brief Get the parameter corresponding to a FSK Rx bandwith immediately above the minimum requested one.
110+
/*!
111+
* \brief Get frequency in Hertz for a given number of PLL steps
112+
*
113+
* \param [in] pllSteps Number of PLL steps
114+
*
115+
* \returns Frequency in Hertz
116+
*/
117+
static uint32_t SX1272ConvertPllStepToFreqInHz( uint32_t pllSteps );
118+
119+
/*!
120+
* \brief Get the number of PLL steps for a given frequency in Hertz
92121
*
93-
* @param [in] bw Minimum required bandwith in Hz
122+
* \param [in] freqInHz Frequency in Hertz
94123
*
95-
* @returns parameter
124+
* \returns Number of PLL steps
125+
*/
126+
static uint32_t SX1272ConvertFreqInHzToPllStep( uint32_t freqInHz );
127+
128+
/*!
129+
* \brief Get the parameter corresponding to a FSK Rx bandwith immediately above the minimum requested one.
130+
*
131+
* \param [in] bw Minimum required bandwith in Hz
132+
*
133+
* \returns parameter
96134
*/
97135
static uint8_t GetFskBandwidthRegValue( uint32_t bw );
98136

99-
/**
100-
* Get the actual value in Hertz of a given LoRa bandwidth
137+
/*!
138+
* \brief Get the actual value in Hertz of a given LoRa bandwidth
101139
*
102140
* \param [in] bw LoRa bandwidth parameter
103141
*
104142
* \returns Actual LoRa bandwidth in Hertz
105143
*/
106144
static uint32_t SX1272GetLoRaBandwidthInHz( uint32_t bw );
107145

108-
/**
146+
/*!
109147
* Compute the numerator for GFSK time-on-air computation.
110148
*
111149
* \remark To get the actual time-on-air in second, this value has to be divided by the GFSK bitrate in bits per
@@ -121,7 +159,7 @@ static uint32_t SX1272GetLoRaBandwidthInHz( uint32_t bw );
121159
static uint32_t SX1272GetGfskTimeOnAirNumerator( uint16_t preambleLen, bool fixLen,
122160
uint8_t payloadLen, bool crcOn );
123161

124-
/**
162+
/*!
125163
* Compute the numerator for LoRa time-on-air computation.
126164
*
127165
* \remark To get the actual time-on-air in second, this value has to be divided by the LoRa bandwidth in Hertz.
@@ -232,7 +270,7 @@ static RadioEvents_t *RadioEvents;
232270
/*!
233271
* Reception buffer
234272
*/
235-
static uint8_t RxTxBuffer[RX_BUFFER_SIZE];
273+
static uint8_t RxTxBuffer[RX_TX_BUFFER_SIZE];
236274

237275
/*
238276
* Public global variables
@@ -296,11 +334,13 @@ RadioState_t SX1272GetStatus( void )
296334

297335
void SX1272SetChannel( uint32_t freq )
298336
{
337+
uint32_t freqInPllSteps = SX1272ConvertFreqInHzToPllStep( freq );
338+
299339
SX1272.Settings.Channel = freq;
300-
freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
301-
SX1272Write( REG_FRFMSB, ( uint8_t )( ( freq >> 16 ) & 0xFF ) );
302-
SX1272Write( REG_FRFMID, ( uint8_t )( ( freq >> 8 ) & 0xFF ) );
303-
SX1272Write( REG_FRFLSB, ( uint8_t )( freq & 0xFF ) );
340+
341+
SX1272Write( REG_FRFMSB, ( uint8_t )( ( freqInPllSteps >> 16 ) & 0xFF ) );
342+
SX1272Write( REG_FRFMID, ( uint8_t )( ( freqInPllSteps >> 8 ) & 0xFF ) );
343+
SX1272Write( REG_FRFLSB, ( uint8_t )( freqInPllSteps & 0xFF ) );
304344
}
305345

306346
bool SX1272IsChannelFree( uint32_t freq, uint32_t rxBandwidth, int16_t rssiThresh, uint32_t maxCarrierSenseTime )
@@ -398,11 +438,11 @@ void SX1272SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
398438
SX1272.Settings.Fsk.IqInverted = iqInverted;
399439
SX1272.Settings.Fsk.RxContinuous = rxContinuous;
400440
SX1272.Settings.Fsk.PreambleLen = preambleLen;
401-
SX1272.Settings.Fsk.RxSingleTimeout = ( uint32_t )( symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1000 );
441+
SX1272.Settings.Fsk.RxSingleTimeout = ( uint32_t )symbTimeout * 8000UL / datarate;
402442

403-
datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
404-
SX1272Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
405-
SX1272Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
443+
uint32_t bitRate = ( uint32_t )( SX1272_XTAL_FREQ / datarate );
444+
SX1272Write( REG_BITRATEMSB, ( uint8_t )( bitRate >> 8 ) );
445+
SX1272Write( REG_BITRATELSB, ( uint8_t )( bitRate & 0xFF ) );
406446

407447
SX1272Write( REG_RXBW, GetFskBandwidthRegValue( bandwidth ) );
408448
SX1272Write( REG_AFCBW, GetFskBandwidthRegValue( bandwidthAfc ) );
@@ -542,13 +582,13 @@ void SX1272SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
542582
SX1272.Settings.Fsk.IqInverted = iqInverted;
543583
SX1272.Settings.Fsk.TxTimeout = timeout;
544584

545-
fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
546-
SX1272Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
547-
SX1272Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
585+
uint32_t fdevInPllSteps = SX1272ConvertFreqInHzToPllStep( fdev );
586+
SX1272Write( REG_FDEVMSB, ( uint8_t )( fdevInPllSteps >> 8 ) );
587+
SX1272Write( REG_FDEVLSB, ( uint8_t )( fdevInPllSteps & 0xFF ) );
548588

549-
datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
550-
SX1272Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
551-
SX1272Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
589+
uint32_t bitRate = ( uint32_t )( SX1272_XTAL_FREQ / datarate );
590+
SX1272Write( REG_BITRATEMSB, ( uint8_t )( bitRate >> 8 ) );
591+
SX1272Write( REG_BITRATELSB, ( uint8_t )( bitRate & 0xFF ) );
552592

553593
SX1272Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
554594
SX1272Write( REG_PREAMBLELSB, preambleLen & 0xFF );
@@ -857,7 +897,7 @@ void SX1272SetRx( uint32_t timeout )
857897
break;
858898
}
859899

860-
memset( RxTxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
900+
memset( RxTxBuffer, 0, ( size_t )RX_TX_BUFFER_SIZE );
861901

862902
SX1272.Settings.State = RF_RX_RUNNING;
863903
if( timeout != 0 )
@@ -1192,6 +1232,37 @@ uint32_t SX1272GetWakeupTime( void )
11921232
return SX1272GetBoardTcxoWakeupTime( ) + RADIO_WAKEUP_TIME;
11931233
}
11941234

1235+
static uint32_t SX1272ConvertPllStepToFreqInHz( uint32_t pllSteps )
1236+
{
1237+
uint32_t freqInHzInt;
1238+
uint32_t freqInHzFrac;
1239+
1240+
// freqInHz = pllSteps * ( SX1272_XTAL_FREQ / 2^19 )
1241+
// Get integer and fractional parts of the frequency computed with a PLL step scaled value
1242+
freqInHzInt = pllSteps >> SX1272_PLL_STEP_SHIFT_AMOUNT;
1243+
freqInHzFrac = pllSteps - ( freqInHzInt << SX1272_PLL_STEP_SHIFT_AMOUNT );
1244+
1245+
// Apply the scaling factor to retrieve a frequency in Hz (+ ceiling)
1246+
return freqInHzInt * SX1272_PLL_STEP_SCALED +
1247+
( ( freqInHzFrac * SX1272_PLL_STEP_SCALED + ( 128 ) ) >> SX1272_PLL_STEP_SHIFT_AMOUNT );
1248+
}
1249+
1250+
static uint32_t SX1272ConvertFreqInHzToPllStep( uint32_t freqInHz )
1251+
{
1252+
uint32_t stepsInt;
1253+
uint32_t stepsFrac;
1254+
1255+
// pllSteps = freqInHz / (SX1272_XTAL_FREQ / 2^19 )
1256+
// Get integer and fractional parts of the frequency computed with a PLL step scaled value
1257+
stepsInt = freqInHz / SX1272_PLL_STEP_SCALED;
1258+
stepsFrac = freqInHz - ( stepsInt * SX1272_PLL_STEP_SCALED );
1259+
1260+
// Apply the scaling factor to retrieve a frequency in Hz (+ ceiling)
1261+
return ( stepsInt << SX1272_PLL_STEP_SHIFT_AMOUNT ) +
1262+
( ( ( stepsFrac << SX1272_PLL_STEP_SHIFT_AMOUNT ) + ( SX1272_PLL_STEP_SCALED >> 1 ) ) /
1263+
SX1272_PLL_STEP_SCALED );
1264+
}
1265+
11951266
static uint8_t GetFskBandwidthRegValue( uint32_t bw )
11961267
{
11971268
uint8_t i;
@@ -1692,9 +1763,8 @@ static void SX1272OnDio2Irq( void* context )
16921763

16931764
SX1272.Settings.FskPacketHandler.RssiValue = -( SX1272Read( REG_RSSIVALUE ) >> 1 );
16941765

1695-
SX1272.Settings.FskPacketHandler.AfcValue = ( int32_t )( ( double )( ( ( uint16_t )SX1272Read( REG_AFCMSB ) << 8 ) |
1696-
( uint16_t )SX1272Read( REG_AFCLSB ) ) *
1697-
( double )FREQ_STEP );
1766+
SX1272.Settings.FskPacketHandler.AfcValue = ( int32_t )SX1272ConvertPllStepToFreqInHz( ( ( uint16_t )SX1272Read( REG_AFCMSB ) << 8 ) |
1767+
( uint16_t )SX1272Read( REG_AFCLSB ) );
16981768
SX1272.Settings.FskPacketHandler.RxGain = ( SX1272Read( REG_LNA ) >> 5 ) & 0x07;
16991769
}
17001770
break;

src/radio/sx1272/sx1272.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,9 @@ typedef struct SX1272_s
154154
*/
155155
typedef void ( DioIrqHandler )( void* context );
156156

157-
/*!
157+
/*
158158
* SX1272 definitions
159159
*/
160-
#define XTAL_FREQ 32000000
161-
#define FREQ_STEP 61.03515625
162-
163-
#define RX_BUFFER_SIZE 256
164160

165161
/*!
166162
* ============================================================================

0 commit comments

Comments
 (0)