124 lines
3.2 KiB
C++
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;
|
|
};
|