Design, Homebrewing, Microcontrollers

Si5351A Investigations Part 2

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.

SI5351 Test Board
SI5351 Test Board

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).

Homebrewing, Test and Measurement

Si5351A Investigations Part 1

Sometime not too long ago, I was tipped off (sorry, I don’t remember by whom) to a potential rival to the popular Si570 called the Si5351. This PLL-based clock generator IC has a few points in its favor over the Si570: it is significantly less expensive (even with the required external crystal or clock) and it can output multiple independent clock frequencies from 8 kHz to 160 MHz at the same time (3 or 8 output ports, depending on which version you get). You could potentially generate a stable VFO and BFO signal from the same tiny IC, or perhaps build a multi-channel grabber receiver or MEPT/WSPR transmitter.

These capabilities looked too good to pass up, so I ordered a few of the Si5351A variety, which is the MSSOP-10 package with 3 output channels and a 10 ppm 25 MHz crystal to pair with it. A bit of searching on the Internet shows a bit of discussion about the IC in the ham radio communities, but I haven’t found any examples of the IC being used in a ham radio project yet. So, my plan of attack is to take an incremental approach in investigating this interesting IC.

The first part of this diabolical plan is to simply breadboard the bare minimum components and use a Bus Pirate to talk to the Si5351 so that I can get a handle on how it is programmed and its capabilities. That is what the rest of this blog post will be covering. Step two will involve using Si5351 as the VFO in a multiband grabber receiver (with plug-in BPF modules) that will be paired with a Raspberry Pi running LOPORA or WSPR. Assuming that works well, the final step will be to investigate whether the Si5351 can be tuned quickly and glitch-free on the fly and will be suitable for use in a proper transceiver.

As you can somewhat see in the photo above, I mounted the 5351 on a SSOP carrier board and glued that to a large piece of copper clad. The crystal needs to be mounted as close to the 5351 as possible, so I took the small 5×3 mm 25 MHz crystal and mounted it directly to the pads on the carrier board. For now, power can be conveniently provided by the Bus Pirate. It was a breeze to connect the Bus Pirate for I2C operation, start a serial console on my Linux Mint PC, and start issuing commands to the 5351. (As an aside, I can’t recommend the Bus Pirate highly enough for this type of experimentation. It’s well worth the modest price for the ability to quickly and simply start experimenting with new ICs).

5351 Start Up Spectrum

On start up, I measured the spectrum above. As you can see from the marker measurement, the fundamental is at an amazing +18.5 dBm. The output impedance of 85 ohms, so properly matched, the output power could be even higher. The good news is that there are four output level options in a 5351 register, so it can be turned down. Also, I intend to use a pi attenuator pad in order to provide a better match to 50 ohms anyway, so the high power may be a good thing. Also, you will notice the large harmonic content of the output. I don’t currently have a working oscilloscope, but I’m sure that the waveform looks quite squarish.

Having confirmed that the IC at least works on power-up, I then proceeded to issue I2C commands to the 5351 that should disable and enable the output that I was measuring. Sure enough, that worked exactly as expected. Then, by using a Windows program called ClockBuilder supplied by Silicon Labs, I generated the full register set that needed to be written in order to change frequencies and manually changed the registers via the Bus Pirate, and sure enough the output changed frequencies. But not quite to exactly the desired frequency.

After puzzling on this problem a bit, I realized that I neglected to set on of the 5351 registers which controls the load capacitance on the external crystal. I use a crystal with an 8 pF specified load capacitance, but the Si5351 defaults to 10 pF on start up. After changing this register to the proper value, the output frequency was quite a bit closer to the nominal value, but still was about 1 kHz off (at a setting of 20 MHz). At this point, I assume this is a close as I can get it, and that I will need to write a calibration routine to determine the PPM error of the output and apply that error to the calculations which determine the PLL settings for a desired output frequency. I should have more on that in my next Si5351 post.

Being able to change frequencies is wonderful, but not when you have to use a PC program to do it. So the next step of the journey was to figure out an algorithm so that the 5351 can be tuned via microcontroller.

In order to explain this, I’ll need to provide a very brief overview of the Si5351 architecture. There are two main fractional PLLs in the 5351, each of which are independently locked to the external crystal (either 25 MHz or 27 MHz). These PLLs have a VCO which runs from 600 to 900 MHz. Each output channel then has a 2nd synthesizer which is locked to the output of either of the PLLs. This is also a fractional synthesizer which divides down the 600 to 900 MHz PLL frequency to the output frequency ranging from 1 to 160 MHz. There is also a final divider which can get that output frequency down to as low as 8 kHz if desired.

The trick then is to come up with an algorithm to determine the correct (and hopefully optimum) division ratios for each synthesizer in the 5351. PLLs are not my strong suit (the last one I built from hand was a LM 566 circuit in college), so I didn’t make much progress on my own. The Si5351 algorithm does not have the required data, but fortunately there is an application note that does have the basic algorithm. Still, that didn’t really explain a strategy for optimization of the synthesizer settings.

Fortunately, Tomas OK4BX gave me a huge bit of help in the Etherkit IRC channel. It turns out that there is an Si5351 driver in the Linux kernel, oddly enough. Not being a kernel hacker, the code conventions were a bit odd to me, but I was able to suss out enough to strip some basic tuning code out and now have a working C program (currently running on the Linux desktop) which can generate the a set of synthesizer frequencies and the register settings needed to tune to that frequency. I’m not ready to post it publicly yet, but rest assured that I will put it up on GitHub when it’s more complete and cleaned up.

That’s where things stand as of today. The next task will be to complete the C tuning program, then transfer that to an AVR microcontroller so that it can do the hard work of setting all of the registers on the Si5351. After that, I need to devise a calibration routine so that hopefully I can bring the frequency accuracy of the Si5351 to much closer than it is now (currently at 60 ppm, hopefully to within 1 Hz at 50 MHz or so). If that can be accomplished, then I should be good to go with integrating the Si5351 into a grabber receiver. Stay tuned for further updates.