/* * File: si5351a.c * Author: www.henteko.org * * Created on 2016/12/26, 14:19 */ #include #include #include #include "si5351a.h" void i2c_init() { OpenI2C(MASTER, SLEW_ON); // i2c master mode, clock 400khz SSPADD = 9; // _XTAL_FREQ / (SSPADD + 1) * 4 = 400khz } void si5351_write(unsigned char reg, unsigned char data) { StartI2C(); WriteI2C(SI5351_I2C_ADDR); WriteI2C(reg); WriteI2C(data); StopI2C(); } void si5351_init(void) { si5351_write(SI5351_XTAL_LOAD, 0x80); // 8pF } void si5351_setpll(unsigned char pll, unsigned char mult, unsigned long num, unsigned long denom) { unsigned long P1; unsigned long P2; unsigned long P3; P1 = 128 * mult + (128 * (double)num / denom) - 512; P2 = 128 * num - denom * (unsigned long)(128 * (double)num / denom); P3 = denom; si5351_write(pll, (P3 & 0x0000FF00) >> 8); si5351_write(pll + 1, (P3 & 0x000000FF)); si5351_write(pll + 2, (P1 & 0x00030000) >> 16); si5351_write(pll + 3, (P1 & 0x0000FF00) >> 8); si5351_write(pll + 4, (P1 & 0x000000FF)); si5351_write(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16)); si5351_write(pll + 6, (P2 & 0x0000FF00) >> 8); si5351_write(pll + 7, (P2 & 0x000000FF)); } void si5351_setms(unsigned char synth, unsigned long div) { unsigned long P1; unsigned long P2; unsigned long P3; P1 = 128 * div - 512; P2 = 0; P3 = 1; si5351_write(synth, (P3 & 0x0000FF00) >> 8); si5351_write(synth + 1, (P3 & 0x000000FF)); si5351_write(synth + 2, ((P1 & 0x00030000) >> 16)); si5351_write(synth + 3, (P1 & 0x0000FF00) >> 8); si5351_write(synth + 4, (P1 & 0x000000FF)); si5351_write(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16)); si5351_write(synth + 6, (P2 & 0x0000FF00) >> 8); si5351_write(synth + 7, (P2 & 0x000000FF)); } void si5351_setfreq(unsigned char channel, unsigned long freq) { unsigned long div; // synth divider value unsigned long pllfreq; // target PLL frequency unsigned char mult; // multisynth a unsigned long num; // multisynth b unsigned long denom; // multisynth c unsigned long lltmp; // temporary value div = SI5351_PLL_FREQ / freq; div = div>>1<<1; // synth divider value is even integer pllfreq = div * freq; denom = 0xfffff; // 20bit denominator max value mult = pllfreq / SI5351_XTAL_FREQ; lltmp = pllfreq % SI5351_XTAL_FREQ; num = lltmp * ((double)denom / SI5351_XTAL_FREQ); si5351_write(SI5351_OUTPUT_CTRL, 0xff); if(channel == 0) { si5351_write(SI5351_CLK0_CTRL, 0x80); si5351_setpll(SI5351_PLL_A, mult, num, denom); si5351_setms(SI5351_MS_0, div); si5351_write(SI5351_PLL_RESET, 0xa0); si5351_write(SI5351_CLK0_CTRL, 0x4f); } else { si5351_write(SI5351_CLK1_CTRL, 0x80); si5351_setpll(SI5351_PLL_B, mult, num, denom); si5351_setms(SI5351_MS_1, div); si5351_write(SI5351_PLL_RESET, 0xa0); si5351_write(SI5351_CLK1_CTRL, 0x6f); } si5351_write(SI5351_OUTPUT_CTRL, 0x00); }