simpleSA/si4432.h

253 lines
9.2 KiB
C
Raw Normal View History

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
#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
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)
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-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
2020-10-16 05:37:01 +08:00
float SetRBW ( float reqBandwidth10, unsigned long* delaytime_p, uint16_t* filter_p ); // "reqBandwidth" in kHz * 10
2020-08-16 02:03:43 +08:00
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-16 02:03:43 +08:00
void RxMode (); // Put module in RX mode
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
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