It has been another productive weekend with the Si5351 here in the shack. Since the last report, I've made significant progress in confirming that the Si5351 may be a good candidate for use as a LO in a radio.
After getting the most basic communications with the Si5351 going via the Bus Pirate, my next task was to find out if I could determine a calibration routine that eventually would be easy enough for anyone to do with even simple equipment like a digimode PC program and WWV. Recall from my previous post that there was quite a bit of error in the output frequency when uncorrected (over 1 kHz error at 20 MHz output frequency). According to its datasheet, the Si5351 has 0 PPM of inherent frequency error, which means that all frequency errors should result only from the attached 25/27 MHz reference crystal. Theoretically, if that can be measured, one calibration value should be good across the entire tuning range.
I added in a line of code to change the nominal 25 MHz reference frequency (called "parent_rate" in the above code snippet) based on an amount of error entered as a command line argument in parts-per-ten million. This reference frequency is the basis of the calculations of the two synthesizer values calculated in the program, so tweaking it to its actual oscillation frequency should give the proper output frequency wherever that output frequency is set.
After adding this simple calibration code, I first used my tuning program to output a set of registers for 10.000000 MHz oscillation with 0 correction. These tuning registers were loaded into the Si5351 and the output was measured on my Tektronix DC 503A frequency counter at 1 Hz resolution. A difference of -887 Hz was measured between the nominal 10.000000 MHz frequency requested and the actual output frequency. Next, as you can see in the screenshot above, I entered a correction factor of -887 parts-per-ten million into the tuning program and generated a new set of tuning registers. (For those who are curious, the program prints out a variety of variables for troubleshooting, then at the end spits out the hexadecimal code for the Bus Pirate to send the registers to the Si5351. I just copy and paste that string into my serial terminal).
Happily, the Si5351 output a frequency within 1 Hz of the nominal 10.00000 MHz requested frequency. Experiments with other tuning frequencies showed similar amounts of error. Up at 50 MHz, the frequency counter only showed ~3 Hz of error. This bodes very well for the use of the 5351 in amateur radio projects.
So, with calibration seemingly under control, it was time to move everything over to a microcontroller. The above photo shows the current hardware setup. I've added my old favorite, an Atmel ATmega328P microcontroller, with a 16 MHz crystal. I have also added a USB B jack, as I intend to make this Si5351 controlled and powered exclusively via USB. Since the Si5351 operates off of 3.3 V power, I provide power to it and the '328P via a LE33CZ LDO regulator fed from the USB 5 V supply. I have also added some simple resistive voltage dividers to the AVR ISP lines to convert 5 V programming signals down to 3.3 V.
Fortunately, I now seem to have enough AVR code sitting around that a lot of these new endeavors can be launched very quickly via the application of a bit of copy-and-paste. I borrowed a bit of I2C code from some CC1 development work and pasted in the rough tuning code that I originally wrote for the Linux command line. A bit of jiggery-pokery and I was able to get the '328P sending I2C commands to the Si5351 to set various parameters and tune to a non-default frequency in order to ensure that the I2C comms were working.
Which is where I currently sit with the project. Next up on the agenda is to write a basic Si5351 library for the ATmega88/168/328 series and then paste in the V-USB code in order to get USB control up and running. After that, it will be onward with the grabber receiver portion of this experiment. Stay tuned for updates (and yes, code will be forthcoming on GitHub once it's in a decent state).