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
|
||||
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_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.
|
||||
*
|
||||
@ -369,7 +314,7 @@ uint8_t Si4432::ReadByte ( uint8_t reg )
|
||||
|
||||
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
|
||||
uint16_t carrier; // Carrier 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
|
||||
* writes for each register, but only update what is needed
|
||||
* writes for each register
|
||||
*/
|
||||
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[2] = ncf1 ; // NCF1 value
|
||||
registerBuf[3] = carrier & 0xFF; // NCF0 value
|
||||
|
||||
//_spi->beginTransaction ( SPISettings ( BUS_SPEED, BUS_ORDER, BUS_MODE ));
|
||||
// spiSimpleTransaction(_spi->bus());
|
||||
digitalWrite ( _cs, LOW ); // Select the correct device
|
||||
_spi->transfer ( registerBuf, 4 ); // Send the data
|
||||
digitalWrite ( _cs, HIGH ); // Deselect the device
|
||||
//_spi->endTransaction();
|
||||
_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
|
||||
//
|
||||
// }
|
||||
registerBuf[0] = REG_FBS|0x80; // First register in write mode (bit 7 set)
|
||||
registerBuf[1] = fbs; // FBS register value
|
||||
registerBuf[2] = ncf1 ; // NCF1 value
|
||||
registerBuf[3] = carrier & 0xFF; // NCF0 value
|
||||
|
||||
//_spi->beginTransaction ( SPISettings ( BUS_SPEED, BUS_ORDER, BUS_MODE ));
|
||||
// spiSimpleTransaction(_spi->bus());
|
||||
digitalWrite ( _cs, LOW ); // Select the correct device
|
||||
_spi->transfer ( registerBuf, 4 ); // Send the data
|
||||
digitalWrite ( _cs, HIGH ); // Deselect the device
|
||||
//_spi->endTransaction();
|
||||
_ncf1 = ncf1;
|
||||
_fbs = fbs;
|
||||
|
||||
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 = (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);
|
||||
|
||||
// _spi->endTransaction(); // Release the bus
|
||||
// delayMicroseconds ( WRITE_DELAY ); // Delay needed when writing frequency
|
||||
|
||||
// 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.
|
||||
*/
|
||||
|
||||
// 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
|
||||
* 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_FOFF1 0x73 // Frequency Offset registers
|
||||
#define REG_FOFF2 0x74
|
||||
|
||||
#define REG_FBS 0x75 // Frequency Band Select
|
||||
#define SBSEL 0x40
|
||||
#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 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 SetDrive ( uint8_t level ); // Sets the drive level
|
||||
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 _capacitance; // Crystal load capacitance
|
||||
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 _ncf1; // Current value for most significant byte of carrier
|
||||
uint32_t _freq; // Current actual frequency
|
||||
|
Loading…
Reference in New Issue
Block a user