2020-08-16 02:03:43 +08:00
|
|
|
/*
|
|
|
|
* "Si4432.h"
|
|
|
|
*
|
|
|
|
* Added to the program in Version 1.1 by John Price (WA2FZW):
|
|
|
|
*
|
|
|
|
* Modified in Version 1.7 to create a "true" class/object implementation for
|
|
|
|
* handling the Si4432 modules.
|
|
|
|
* Modified by M0WID for 2.6 to remove dependencies on tinySA specific include files
|
|
|
|
* and use SPI class pointer in the constructor
|
|
|
|
*
|
|
|
|
* This file contains symbolic definitions for all the Si4432 registers that are
|
|
|
|
* used in the program and symbols for some of the values that get loaded into or
|
|
|
|
* read from them. For full explanations (whether you can make sense out of them
|
|
|
|
* or not) of the registers please refer to the "Silicon Labs Si4430/31/32 - B1"
|
|
|
|
* data sheet and "Silicon Labs Technical Note A440".
|
|
|
|
*
|
|
|
|
* Some of the functions in here apply only to the receiver and some apply only
|
|
|
|
* to the transmitter. The "Init" functions remember which type of module is
|
|
|
|
* being initiated. Eventually we will use that to avoid doing things which don't
|
|
|
|
* make sense for one type or the other.
|
|
|
|
*
|
|
|
|
* It also contains some structure definitions and some data elements we keep
|
|
|
|
* to ourselves.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SI4432A_H_
|
|
|
|
#define SI4432A_H_ // Prevent double inclusion
|
|
|
|
|
|
|
|
#include <Arduino.h> // Basic Arduino definitions
|
|
|
|
#include <SPI.h> // SPI bus related stuff
|
|
|
|
|
|
|
|
#define ELEMENTS(x) ( sizeof ( x ) / sizeof ( x[0] ))
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In the original program, these were the indicies into the "SI_nSEL" array used
|
|
|
|
* to indicate whether the receiver or transmitter module was selected to perform
|
|
|
|
* an operation on.
|
|
|
|
*
|
|
|
|
* In this implementation, the "_type" variable is set to one or the other in the
|
|
|
|
* initialization functions to remember which type we are.
|
|
|
|
*
|
|
|
|
* The "_type" value will eventually be used to prevent certain operations from
|
|
|
|
* being accidently performed on the wrong type of module; for example, setting the
|
|
|
|
* RBW ("SetRBW") is not valid for the transmitter module or "Get_RSSI" is only
|
|
|
|
* applicable to the receiver module.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define RX_4432 0 // Receiver is Si4432 #0
|
|
|
|
#define TX_4432 1 // Transmitter is Si4432 #1
|
|
|
|
#define TGIF_4432 2
|
|
|
|
#define TGLO_4432 3
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The maximum SPI bus speed for the Si4432 is 10MHz. It operates in SPI MODE0 and
|
|
|
|
* the address and data are transmitted MSBFIRST.
|
|
|
|
*
|
|
|
|
* That being the case, the following definitions will be used in the read and write
|
|
|
|
* functions to set those parameters before each transaction:
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define BUS_SPEED 10000000 // 10 MHz
|
|
|
|
#define BUS_MODE SPI_MODE0 // Data is read on rising edge of the clock
|
|
|
|
#define BUS_ORDER MSBFIRST // Send stuff MSB first
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "WRITE_DELAY" is a time in microseconds that seems to be required after each write
|
|
|
|
* to one of the Si4432 registers on some (but not all) Si4431 modules. You can try
|
|
|
|
* reducing the value to '1', but if you have problems getting one of them to actually
|
|
|
|
* work, try increasing the value. '25' is the value that works for my modules.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define WRITE_DELAY 25
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Si4432 Registers used in the program and bit definitions for some of them:
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define REG_IS2 0x04 // Interrupt Status #1
|
|
|
|
#define ICHIPRDY 0x02 // Chip ready
|
|
|
|
|
|
|
|
#define REG_INT1 0x06 // Interrupt enable register 1
|
|
|
|
|
|
|
|
#define REG_OFC1 0x07 // Operating & Function Control 1
|
|
|
|
#define XTON 0x01 // Ready mode on (see datasheet)
|
|
|
|
#define PLLON 0x02 // PLL on
|
|
|
|
#define RXON 0x04 // Receiver on
|
|
|
|
#define TXON 0x08 // Transmitter on
|
|
|
|
#define X32KSEL 0x10 // Use external 32KHz crystal
|
|
|
|
#define ENLBD 0x40 // Device enabled
|
|
|
|
#define SW_RESET 0x80 // System reset
|
|
|
|
|
|
|
|
#define REG_COLC 0x09 // Crystal Oscillator Load Capacitance
|
|
|
|
|
|
|
|
#define REG_MCOC 0x0A // Microcontroller Output Clock
|
|
|
|
|
|
|
|
#define REG_GPIO0 0x0B // GPIO0 Configuration
|
|
|
|
|
|
|
|
#define REG_GPIO1 0x0C // GPIO1 Configuration
|
|
|
|
|
|
|
|
#define REG_GPIO2 0x0D // GPIO2 Configuration
|
|
|
|
|
|
|
|
#define REG_IFBW 0x1C // IF Filter Bandwidth
|
|
|
|
|
|
|
|
#define REG_AFCGSO 0x1D // AFC Loop Gearshift Override
|
|
|
|
|
|
|
|
#define REG_AFCTC 0x1E // AFC Timing Control
|
|
|
|
|
|
|
|
#define REG_CRGO 0x1F // Clock Recovery Gearshift Override
|
|
|
|
|
|
|
|
#define REG_CROSR 0x20 // Clock Recovery Oversampling Ratio
|
|
|
|
|
|
|
|
#define REG_CRO2 0x21 // Clock Recovery Offset 2
|
|
|
|
|
|
|
|
#define REG_CRO1 0x22 // Clock Recovery Offset 1
|
|
|
|
|
|
|
|
#define REG_CRO0 0x23 // Clock Recovery Offset 0
|
|
|
|
|
|
|
|
#define REG_CRTLG1 0x24 // Clock Recovery Timing Loop Gain 1
|
|
|
|
|
|
|
|
#define REG_CRTLG0 0x25 // Clock Recovery Timing Loop Gain 0
|
|
|
|
|
|
|
|
#define REG_RSSI 0x26 // Received Signal Strength Indicator
|
|
|
|
|
|
|
|
#define REG_AFCLIM 0x2A // AFC Limiter
|
|
|
|
|
|
|
|
#define REG_OOKC1 0x2C // OOK Counter Value 1
|
|
|
|
|
|
|
|
#define REG_OOKC2 0x2D // OOK Counter Value 2
|
|
|
|
|
|
|
|
#define REG_SPH 0x2E // Slicer Peak Hold
|
|
|
|
|
|
|
|
#define REG_DATAC 0x30 // Data access control
|
|
|
|
|
|
|
|
#define REG_AGCOR1 0x69 // AGC Override 1
|
|
|
|
#define LNAGAIN 0x10 // LNA enabled
|
|
|
|
#define AGCEN 0x20 // AGC enabled
|
|
|
|
#define PGAGAIN 0x0F // PGA Gain value in dB/3
|
|
|
|
#define AGC_ON 0x60 // Turn the AGC on
|
|
|
|
|
|
|
|
#define REG_TXPWR 0x6D // Transmitter Power
|
|
|
|
|
2020-08-19 04:30:39 +08:00
|
|
|
#define REG_FOFF1 0x73 // Frequency Offset registers
|
|
|
|
#define REG_FOFF2 0x74
|
|
|
|
|
2020-08-16 02:03:43 +08:00
|
|
|
#define REG_FBS 0x75 // Frequency Band Select
|
|
|
|
#define SBSEL 0x40
|
|
|
|
#define HBSEL 0x20
|
|
|
|
#define F_BAND 0x1F
|
|
|
|
|
|
|
|
#define REG_NCF1 0x76 // Nominal Carrier Frequency 1
|
|
|
|
|
|
|
|
#define REG_NCF0 0x77 // Nominal Carrier Frequency 0
|
|
|
|
|
|
|
|
|
2020-10-13 06:35:14 +08:00
|
|
|
enum {DO_NOT_USE, USE_IN_AUTO, AVAILABLE}; // bandpass filter status values
|
|
|
|
|
2020-08-16 02:03:43 +08:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
float bandwidth10; // Just one decimal point to save space (kHz * 10)
|
|
|
|
unsigned long settleTime; // Narrower bandwidth filter needs longer settling time before RSSI is stable
|
|
|
|
uint16_t dwn3_bypass; // Bypass decimate by 3 stage if set
|
|
|
|
uint16_t ndec_exp; // IF Filter decimation rate = 2^ndec_exp. larger number -> lower bandwidth (range 0-5)
|
|
|
|
uint16_t filset; // IF Filter coefficient set. Predefined FIR filter sets (1-15)
|
2020-10-13 06:35:14 +08:00
|
|
|
uint16_t Status; // 0 = DO_NOT_USE, 1 = USE_IN_AUTO, 2 = AVAILABLE
|
2020-08-16 02:03:43 +08:00
|
|
|
} bandpassFilter_t;
|
|
|
|
|
|
|
|
class Si4432
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
explicit Si4432 ( SPIClass* spi, uint8_t cs, uint8_t id ); // Constructor
|
|
|
|
|
|
|
|
bool Init ( uint8_t cap ); // Initialize the SI4432 module, return false if failed
|
|
|
|
//bool TX_Init ( uint8_t cap, uint8_t power ); // Initialize the transmitter module, return false if failed
|
|
|
|
|
|
|
|
void SetFrequency ( uint32_t Freq ); // Set module's frequency
|
|
|
|
uint32_t GetFrequency (); // Get the module's frequency
|
|
|
|
uint32_t ReadFrequency (); // Read frequency from SI4432
|
|
|
|
|
2020-08-19 05:21:11 +08:00
|
|
|
void SetOffsetFreq ( int32_t freq ); // Set a frequency offset from the nominal frequency
|
|
|
|
void SetOffset ( int32_t offset ); // Offset based on number of offset increments
|
2020-08-19 04:30:39 +08:00
|
|
|
|
2020-08-16 02:03:43 +08:00
|
|
|
void SetPowerReference ( int freq ); // Set the GPIO output for the LO
|
|
|
|
void SetDrive ( uint8_t level ); // Sets the drive level
|
|
|
|
|
|
|
|
float SetRBW ( float reqBandwidth10, unsigned long* delaytime_p ); // "reqBandwidth" in kHz * 10
|
|
|
|
|
|
|
|
void SetPreampGain ( int gain ); // Sets preamp gain
|
|
|
|
int GetPreampGain (); // Get current gain register
|
|
|
|
int ReadPreampGain (); // Read gain register from SI4432
|
|
|
|
bool PreAmpAGC(); // Reads the register and return true if agc set to auto
|
|
|
|
bool GetPreAmpAGC (); // Return true if agc set to auto
|
|
|
|
|
|
|
|
uint8_t GetRSSI (); // Get Receiver Signal Strength
|
2020-08-21 05:27:55 +08:00
|
|
|
|
2020-08-16 02:03:43 +08:00
|
|
|
void RxMode (); // Put module in RX mode
|
2020-08-21 05:27:55 +08:00
|
|
|
void TxMode ( uint8_t level ); // Put module in TX mode
|
|
|
|
void ReadyMode (); // Put module in READY mode, crystal on, PLL off
|
|
|
|
uint8_t GetMode ();
|
|
|
|
void SetMode (uint8_t newMode);
|
|
|
|
|
2020-08-16 02:03:43 +08:00
|
|
|
void Tune ( uint8_t cap ); // Set the crystal tuning capacitance
|
|
|
|
|
|
|
|
void WriteByte ( byte reg, byte setting ); // Write a byte of data to the specified register
|
|
|
|
uint8_t ReadByte ( uint8_t reg ); // Read a byte of data from the specified register
|
|
|
|
|
|
|
|
uint16_t GetBandpassFilter10 ( uint8_t index ); // Return the filter bandwidth for selected element of bandpassFilters array
|
|
|
|
uint8_t GetBandpassFilterCount ();
|
|
|
|
|
|
|
|
void PrintRegs (); // Dump all the Si4432 registers
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These are common functions that are only accessible from within the object.
|
|
|
|
*/
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
void SubInit (); // Initialization common to both modules
|
|
|
|
bool Reset (); // Initialize the module
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Private data elements:
|
|
|
|
*/
|
|
|
|
|
|
|
|
uint8_t _cs; // Chip select pin number for the module
|
|
|
|
float _bw; // Current bandwidth setting
|
|
|
|
uint32_t _dt; // Current delay time setting
|
|
|
|
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
|
2020-08-19 04:30:39 +08:00
|
|
|
int _hbsel; // High band (1) or low band (0)
|
2020-08-16 02:03:43 +08:00
|
|
|
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
|
|
|
|
// can be different to that requested due
|
|
|
|
// to resolution)
|
|
|
|
int _gainReg; // value of the gain reg written to the device
|
|
|
|
bool _autoGain; // true if auto
|
|
|
|
|
|
|
|
static bandpassFilter_t _bandpassFilters[];
|
|
|
|
static uint8_t _bpfCount; // Number of elements in bandpassFilters array
|
|
|
|
|
|
|
|
}; // End of class "Si4432"
|
|
|
|
|
|
|
|
#endif
|