SetOffset Function done
Rationalised SI4432 Init Added SI4432:SetOffset function - not tested
This commit is contained in:
parent
94d02de911
commit
be199ef50c
205
si4432.cpp
205
si4432.cpp
@ -97,82 +97,6 @@ bool Si4432::Init ( uint8_t cap )
|
|||||||
|
|
||||||
if ( !Reset () ) // Reset the module
|
if ( !Reset () ) // Reset the module
|
||||||
return false; // If that failed
|
return false; // If that failed
|
||||||
SubInit (); // Things common to both modules
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* We turn on receive mode ("RXON"), the PLL ("PLLON") and ready mode
|
|
||||||
* ("XTON"). The Si4432 module does not have the 32.768 kHz crystal for
|
|
||||||
* the microcontroller, so we do not turn on the "X32KSEL" bit.
|
|
||||||
*
|
|
||||||
* The initial frequency is set to 433.92 MHz which is a typical IF
|
|
||||||
* Finally the GPIO-2 pin is set to ground.
|
|
||||||
*
|
|
||||||
* 03/24 - Logic verified against A440 register edscription document
|
|
||||||
*/
|
|
||||||
|
|
||||||
WriteByte ( REG_OFC1, ( RXON | PLLON | XTON )); // Receiver, PLL and "Ready Mode" all on
|
|
||||||
Tune ( cap ); // Set the crystal capacitance to fine tune frequency
|
|
||||||
|
|
||||||
SetFrequency ( 443920000 ); // 443.92MHz
|
|
||||||
delayMicroseconds ( 300 ); // Time to allow the SI4432 state machine to do its stuff
|
|
||||||
Serial.printf ( "End of Init - _cs = %i\n", _cs );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//bool Si4432::TX_Init ( uint8_t cap, uint8_t power )
|
|
||||||
//{
|
|
||||||
// _type = TX_4432; // We're a transmitter
|
|
||||||
//
|
|
||||||
// if ( !Reset () ) // Reset the module
|
|
||||||
// return false; // If that failed
|
|
||||||
// _pwr = power; // Set the transmitter power level
|
|
||||||
// SubInit (); // Things common to both modules
|
|
||||||
//
|
|
||||||
//
|
|
||||||
///*
|
|
||||||
// * Settings specific to the transmitter module.
|
|
||||||
// *
|
|
||||||
// * This is almost identical to how we set up the receiver except we turn
|
|
||||||
// * on the "TXON" bit (0x08) instead of the "RXON" bit. We also set the
|
|
||||||
// * transmitter power based on the mixer module being used. ("CalcPower"
|
|
||||||
// * function sets the value).
|
|
||||||
// *
|
|
||||||
// * GPIO-2 is handled differently; here, we set GPIO-2 to output the
|
|
||||||
// * microcontroller clock at maximum drive level (0xC0). We also set the
|
|
||||||
// * microcontroller clock speed to 10MHz.
|
|
||||||
// *
|
|
||||||
// * 03/24 - Logic verified against A440
|
|
||||||
// */
|
|
||||||
//
|
|
||||||
// Tune ( cap ); // Set the crystal capacitance
|
|
||||||
// WriteByte ( REG_TXPWR, _pwr ); // Power based on mixer in use
|
|
||||||
//
|
|
||||||
// WriteByte ( REG_GPIO2, 0xC0 ); // Maximum drive and microcontroller clock output
|
|
||||||
// WriteByte ( REG_MCOC, 0x02 ); // Set 10MHz clock output
|
|
||||||
//
|
|
||||||
// SetFrequency ( 443920000 ); // 433.92MHz (setting.IF_Freq???)
|
|
||||||
//
|
|
||||||
// delayMicroseconds ( 300 ); // Doesn't work without this!
|
|
||||||
//
|
|
||||||
// WriteByte ( REG_OFC1, ( TXON | PLLON | XTON )); // Transmitter, PLL and "Ready Mode" all on
|
|
||||||
//
|
|
||||||
//// Serial.println ( "End of TX_Init" );
|
|
||||||
//
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "SubInit" is used by the "Init" function to set up
|
|
||||||
* all the registers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Si4432::SubInit ()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -257,10 +181,31 @@ void Si4432::SubInit ()
|
|||||||
WriteByte ( REG_GPIO1, 0x15 ); // GPIO-1 RX State (output)
|
WriteByte ( REG_GPIO1, 0x15 ); // GPIO-1 RX State (output)
|
||||||
|
|
||||||
WriteByte ( REG_GPIO2, 0x1F ); // Set GPIO-2 output to ground until needed
|
WriteByte ( REG_GPIO2, 0x1F ); // Set GPIO-2 output to ground until needed
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* We turn on receive mode ("RXON"), the PLL ("PLLON") and ready mode
|
||||||
|
* ("XTON"). The Si4432 module does not have the 32.768 kHz crystal for
|
||||||
|
* the microcontroller, so we do not turn on the "X32KSEL" bit.
|
||||||
|
*
|
||||||
|
* The initial frequency is set to 433.92 MHz which is a typical IF
|
||||||
|
* Finally the GPIO-2 pin is set to ground.
|
||||||
|
*
|
||||||
|
* 03/24 - Logic verified against A440 register edscription document
|
||||||
|
*/
|
||||||
|
|
||||||
|
WriteByte ( REG_OFC1, ( RXON | PLLON | XTON )); // Receiver, PLL and "Ready Mode" all on
|
||||||
|
Tune ( cap ); // Set the crystal capacitance to fine tune frequency
|
||||||
|
|
||||||
|
SetFrequency ( 443920000 ); // 443.92MHz
|
||||||
|
delayMicroseconds ( 300 ); // Time to allow the SI4432 state machine to do its stuff
|
||||||
|
Serial.printf ( "End of Init - _cs = %i\n", _cs );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Reset" - Initializes the Si4432.
|
* "Reset" - Initializes the Si4432.
|
||||||
*
|
*
|
||||||
@ -369,7 +314,7 @@ uint8_t Si4432::ReadByte ( uint8_t reg )
|
|||||||
|
|
||||||
void Si4432::SetFrequency ( uint32_t freq )
|
void Si4432::SetFrequency ( uint32_t freq )
|
||||||
{
|
{
|
||||||
int hbsel; // High/low band select bit
|
int hbsel; // high band select, but shifted to the correct location in the byte
|
||||||
int sbsel; // Sideband select bit
|
int sbsel; // Sideband select bit
|
||||||
uint16_t carrier; // Carrier frequency
|
uint16_t carrier; // Carrier frequency
|
||||||
uint32_t reqFreq = freq; // Copy of requested frequency
|
uint32_t reqFreq = freq; // Copy of requested frequency
|
||||||
@ -440,56 +385,31 @@ uint8_t registerBuf[4]; // Used to send frequency data in burst mode
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* M0WID mod - Update the frequency in "burst" mode as opposed to separate
|
* M0WID mod - Update the frequency in "burst" mode as opposed to separate
|
||||||
* writes for each register, but only update what is needed
|
* writes for each register
|
||||||
*/
|
*/
|
||||||
uint8_t ncf1 = ( carrier >> 8 ) & 0xFF;
|
uint8_t ncf1 = ( carrier >> 8 ) & 0xFF;
|
||||||
|
|
||||||
// if (fbs != _fbs) // write all three registers
|
registerBuf[0] = REG_FBS|0x80; // First register in write mode (bit 7 set)
|
||||||
// {
|
registerBuf[1] = fbs; // FBS register value
|
||||||
registerBuf[0] = REG_FBS|0x80; // First register in write mode (bit 7 set)
|
registerBuf[2] = ncf1 ; // NCF1 value
|
||||||
registerBuf[1] = fbs; // FBS register value
|
registerBuf[3] = carrier & 0xFF; // NCF0 value
|
||||||
registerBuf[2] = ncf1 ; // NCF1 value
|
|
||||||
registerBuf[3] = carrier & 0xFF; // NCF0 value
|
//_spi->beginTransaction ( SPISettings ( BUS_SPEED, BUS_ORDER, BUS_MODE ));
|
||||||
|
// spiSimpleTransaction(_spi->bus());
|
||||||
//_spi->beginTransaction ( SPISettings ( BUS_SPEED, BUS_ORDER, BUS_MODE ));
|
digitalWrite ( _cs, LOW ); // Select the correct device
|
||||||
// spiSimpleTransaction(_spi->bus());
|
_spi->transfer ( registerBuf, 4 ); // Send the data
|
||||||
digitalWrite ( _cs, LOW ); // Select the correct device
|
digitalWrite ( _cs, HIGH ); // Deselect the device
|
||||||
_spi->transfer ( registerBuf, 4 ); // Send the data
|
//_spi->endTransaction();
|
||||||
digitalWrite ( _cs, HIGH ); // Deselect the device
|
_ncf1 = ncf1;
|
||||||
//_spi->endTransaction();
|
_fbs = fbs;
|
||||||
_ncf1 = ncf1;
|
|
||||||
_fbs = fbs;
|
|
||||||
// }
|
|
||||||
// else if (ncf1 != _ncf1) // Only write both bytes of the carrier data
|
|
||||||
// {
|
|
||||||
// registerBuf[0] = REG_NCF1|0x80; // First register in write mode (bit 7 set)
|
|
||||||
// registerBuf[1] = ncf1 ; // NCF1 value
|
|
||||||
// registerBuf[2] = carrier & 0xFF; // NCF0 value
|
|
||||||
// digitalWrite ( _cs, LOW ); // Select the correct device
|
|
||||||
// _spi->transfer ( registerBuf, 3 ); // Send the data
|
|
||||||
// digitalWrite ( _cs, HIGH ); // Deselect the device
|
|
||||||
// _ncf1 = ncf1;
|
|
||||||
// }
|
|
||||||
// else // Only write the least significant byte of the carrier register
|
|
||||||
// {
|
|
||||||
// registerBuf[0] = REG_NCF0|0x80; // First register in write mode (bit 7 set)
|
|
||||||
// registerBuf[1] = carrier & 0xFF; // NCF0 value
|
|
||||||
// digitalWrite ( _cs, LOW ); // Select the correct device
|
|
||||||
// _spi->transfer ( registerBuf, 2 ); // Send the data
|
|
||||||
// digitalWrite ( _cs, HIGH ); // Deselect the device
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
uint32_t fb = ( fbs & F_BAND ) ;
|
uint32_t fb = ( fbs & F_BAND ) ;
|
||||||
hbsel = hbsel>>5; // should be 1 or 0
|
_hbsel = hbsel>>5; // should be 1 or 0
|
||||||
|
|
||||||
// _freq will contain the actual frequency, not necessarily what was requested
|
// _freq will contain the actual frequency, not necessarily what was requested
|
||||||
_freq = (double)(10000000 * (hbsel + 1 )) * ( (double)fb + (double)24 + (double)carrier / (double)64000) ;
|
_freq = (double)(10000000 * (_hbsel + 1 )) * ( (double)fb + (double)24 + (double)carrier / (double)64000) ;
|
||||||
// Serial.printf("set Freq :%i, actual:%i, fb:%i, fc:%i, hbsel:%i\n", reqFreq, _freq, fb, carrier, hbsel);
|
// Serial.printf("set Freq :%i, actual:%i, fb:%i, fc:%i, hbsel:%i\n", reqFreq, _freq, fb, carrier, hbsel);
|
||||||
|
|
||||||
// _spi->endTransaction(); // Release the bus
|
|
||||||
// delayMicroseconds ( WRITE_DELAY ); // Delay needed when writing frequency
|
|
||||||
|
|
||||||
// Serial.print ( ", N = " );
|
// Serial.print ( ", N = " );
|
||||||
// Serial.print ( N );
|
// Serial.print ( N );
|
||||||
|
|
||||||
@ -518,10 +438,55 @@ uint8_t registerBuf[4]; // Used to send frequency data in burst mode
|
|||||||
* handled by the calling program.
|
* handled by the calling program.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// delayMicroseconds ( _dt ); // M0WID - Delay depends on RBW
|
// delayMicroseconds ( _dt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "SetOffset" adjusts the frequency from the nominal value set in SetFrequency.
|
||||||
|
* It is intended for use by the SI4432 AFC algorithm to enable more accurate
|
||||||
|
* frequency matching of different radios, but we can turn off the AFC and use it
|
||||||
|
* to adjust the frequency without having the Si4432 go through its TX-RX-TX state machine
|
||||||
|
* and enable reduced edlay times from setting a frequency to getting valid readings
|
||||||
|
* The offset can vary +- 80kHz in low bands (f<480MHz) and +-160kHz in high bands (480-960MHz)
|
||||||
|
* negative numbers are twos complement of the positive offset
|
||||||
|
*/
|
||||||
|
void Si4432::SetOffset ( int32_t offset )
|
||||||
|
{
|
||||||
|
uint8_t registerBuf[3]; // Used to send data in burst mode
|
||||||
|
|
||||||
|
uint32_t posOffset;
|
||||||
|
if (offset < 0)
|
||||||
|
posOffset = -offset;
|
||||||
|
else
|
||||||
|
posOffset = offset;
|
||||||
|
|
||||||
|
uint16_t fo = (double)offset/(156.25 * (double)(_hbsel + 1));
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
// do twos complement - invert the bits (0-8) (use XOR) and add one
|
||||||
|
fo = (fo ^ 0x3F) + 1;
|
||||||
|
|
||||||
|
Serial.printf(" offset %i fo=%3x \n", offset, fo);
|
||||||
|
|
||||||
|
// write to the Si4432
|
||||||
|
registerBuf[0] = REG_FOFF1|0x80; // First register in write mode (bit 7 set)
|
||||||
|
registerBuf[1] = fo & 0xFF; // first 8 bits
|
||||||
|
registerBuf[2] = (fo >> 8 ) & 0x03; // last 2 bits
|
||||||
|
|
||||||
|
//_spi->beginTransaction ( SPISettings ( BUS_SPEED, BUS_ORDER, BUS_MODE ));
|
||||||
|
// spiSimpleTransaction(_spi->bus());
|
||||||
|
digitalWrite ( _cs, LOW ); // Select the correct device
|
||||||
|
_spi->transfer ( registerBuf, 3 ); // Send the data
|
||||||
|
digitalWrite ( _cs, HIGH ); // Deselect the device
|
||||||
|
//_spi->endTransaction();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "SetRBW" Sets the "Resolution Bandwidth" based on a required value passed in
|
* "SetRBW" Sets the "Resolution Bandwidth" based on a required value passed in
|
||||||
* and returns the actual value chosen as well as the required delay to allow the
|
* and returns the actual value chosen as well as the required delay to allow the
|
||||||
|
6
si4432.h
6
si4432.h
@ -142,6 +142,9 @@
|
|||||||
|
|
||||||
#define REG_TXPWR 0x6D // Transmitter Power
|
#define REG_TXPWR 0x6D // Transmitter Power
|
||||||
|
|
||||||
|
#define REG_FOFF1 0x73 // Frequency Offset registers
|
||||||
|
#define REG_FOFF2 0x74
|
||||||
|
|
||||||
#define REG_FBS 0x75 // Frequency Band Select
|
#define REG_FBS 0x75 // Frequency Band Select
|
||||||
#define SBSEL 0x40
|
#define SBSEL 0x40
|
||||||
#define HBSEL 0x20
|
#define HBSEL 0x20
|
||||||
@ -175,6 +178,8 @@ void SetFrequency ( uint32_t Freq ); // Set module's frequency
|
|||||||
uint32_t GetFrequency (); // Get the module's frequency
|
uint32_t GetFrequency (); // Get the module's frequency
|
||||||
uint32_t ReadFrequency (); // Read frequency from SI4432
|
uint32_t ReadFrequency (); // Read frequency from SI4432
|
||||||
|
|
||||||
|
void SetOffset ( int32_t offset ); // Set a frequency offset from the nominal frequency
|
||||||
|
|
||||||
void SetPowerReference ( int freq ); // Set the GPIO output for the LO
|
void SetPowerReference ( int freq ); // Set the GPIO output for the LO
|
||||||
void SetDrive ( uint8_t level ); // Sets the drive level
|
void SetDrive ( uint8_t level ); // Sets the drive level
|
||||||
void TxMode ( uint8_t level ); // Put module in TX mode
|
void TxMode ( uint8_t level ); // Put module in TX mode
|
||||||
@ -221,6 +226,7 @@ uint8_t _pwr; // Current power output (TX only?)
|
|||||||
uint8_t _type; // Transmitter or receiver
|
uint8_t _type; // Transmitter or receiver
|
||||||
uint8_t _capacitance; // Crystal load capacitance
|
uint8_t _capacitance; // Crystal load capacitance
|
||||||
SPIClass* _spi; // Pointer to the SPI object
|
SPIClass* _spi; // Pointer to the SPI object
|
||||||
|
int _hbsel; // High band (1) or low band (0)
|
||||||
uint8_t _fbs; // Current value of frequency band select register
|
uint8_t _fbs; // Current value of frequency band select register
|
||||||
uint8_t _ncf1; // Current value for most significant byte of carrier
|
uint8_t _ncf1; // Current value for most significant byte of carrier
|
||||||
uint32_t _freq; // Current actual frequency
|
uint32_t _freq; // Current actual frequency
|
||||||
|
Loading…
Reference in New Issue
Block a user