/* * "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 // Basic Arduino definitions #include // 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 #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 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 } 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 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 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 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); 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) 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