LibreVNA/Software/VNA_embedded/Application/Drivers/Si5351C.hpp
2020-09-12 12:17:35 +02:00

124 lines
3.2 KiB
C++

#pragma once
#include "stm.hpp"
class Si5351C {
public:
enum class PLL : uint8_t {
A = 0,
B = 1,
};
enum class DriveStrength : uint8_t {
mA2 = 0x00,
mA4 = 0x01,
mA6 = 0x02,
mA8 = 0x03,
};
enum class PLLSource : uint8_t {
XTAL,
CLKIN,
};
constexpr Si5351C(I2C_HandleTypeDef *i2c, uint32_t XTAL_freq, GPIO_InitTypeDef *intr_gpio = nullptr,
uint16_t intr_pin = 0, GPIO_InitTypeDef *oeb_gpio = nullptr, uint16_t oeb_pin = 0):
i2c(i2c),
intr_gpio(intr_gpio),
intr_pin(intr_pin),
oeb_gpio(oeb_gpio),
oeb_pin(oeb_pin),
FreqPLL{},
FreqXTAL(XTAL_freq),
FreqCLKINDiv(0) {
};
bool Init(uint32_t clkin_freq = 0);
bool ConfigureCLKIn(uint32_t clkin_freq);
bool SetPLL(PLL pll, uint32_t frequency, PLLSource src);
bool SetCLK(uint8_t clknum, uint32_t frequency, PLL source, DriveStrength strength = DriveStrength::mA2, uint32_t PLLFreqOverride = 0);
bool SetCLKtoXTAL(uint8_t clknum);
bool SetCLKToCLKIN(uint8_t clknum);
bool Enable(uint8_t clknum);
bool Disable(uint8_t clknum);
bool Locked(PLL pll);
bool ResetPLL(PLL pll);
bool ExtCLKAvailable();
// Direct register access of clk configuration registers
// config has to point to a buffer containing at least 8 bytes
bool WriteRawCLKConfig(uint8_t clknum, const uint8_t *config);
bool ReadRawCLKConfig(uint8_t clknum, uint8_t *config);
private:
void FindOptimalDivider(uint32_t f_pll, uint32_t f, uint32_t &P1, uint32_t &P2, uint32_t &P3);
enum class Reg : uint8_t {
DeviceStatus = 0,
InterruptStatusSticky = 1,
InterruptStatusMask = 2,
OutputEnableControl = 3,
OEBPinMask = 9,
PLLInputSource = 15,
CLK0Control = 16,
CLK1Control = 17,
CLK2Control = 18,
CLK3Control = 19,
CLK4Control = 20,
CLK5Control = 21,
CLK6Control = 22,
CLK7Control = 23,
CLK3_0DisableState = 24,
CLK7_4DisableState = 25,
MSNA_CONFIG = 26,
MSNB_CONFIG = 34,
MS0_CONFIG = 42,
MS1_CONFIG = 50,
MS2_CONFIG = 58,
MS3_CONFIG = 66,
MS4_CONFIG = 74,
MS5_CONFIG = 82,
MS6_CONFIG = 90,
MS7_CONFIG = 91,
R6_7_Divider = 92,
// Left out: Spread Spectrum and VCXO parameters
CLK0_Offset = 165,
CLK1_Offset = 166,
CLK2_Offset = 167,
CLK3_Offset = 168,
CLK4_Offset = 169,
CLK5_Offset = 170,
PLLReset = 177,
CrystalLoadCapacitance = 183,
FanoutEnable = 187,
};
using PLLConfig = struct {
uint32_t P1, P2, P3;
bool IntegerMode;
PLLSource source;
};
bool WritePLLConfig(PLLConfig config, PLL pll);
using ClkConfig = struct {
uint32_t P1, P2, P3;
uint8_t RDiv; // 1 to 128, only 2^n
bool DivideBy4;
bool PoweredDown;
bool IntegerMode;
PLL source;
bool Inverted;
DriveStrength strength;
};
bool WriteClkConfig(ClkConfig config, uint8_t clknum);
static constexpr uint8_t address = 0xC0;
bool WriteRegister(Reg reg, uint8_t data);
bool ReadRegister(Reg reg, uint8_t *data);
bool SetBits(Reg reg, uint8_t bits);
bool ClearBits(Reg reg, uint8_t bits);
bool WriteRegisterRange(Reg start, const uint8_t *data, uint8_t len);
bool ReadRegisterRange(Reg start, uint8_t *data, uint8_t len);
I2C_HandleTypeDef *i2c;
GPIO_InitTypeDef *intr_gpio;
uint16_t intr_pin;
GPIO_InitTypeDef *oeb_gpio;
uint16_t oeb_pin;
uint32_t FreqPLL[2];
uint32_t FreqXTAL, FreqCLKINDiv;
};