The product I’m working on right now has a load of very arcane requirements, forcing me to delve into areas totally new to me. One of those is precision clocking, since the product requires synchronized capture of data across multiple units. As such I went hunting for PLLs that would do the job I need. The key is the ability to adjust the speed very slightly in order to synchronize multiple clocks on multiple units to the exact same speed over the long term.
TI’s CDCE9xx series of chips turned out to have all the right features. Each chip in the series has an onboard VCXO, which allows me to tweak the exact speed of the crystal with a voltage input, up to +-150ppm. The various chips in the line have differing numbers of PLLs, each with 2 outputs on separate dividers. The 12+9 bit N/M divider and 7-bit predivider allow for almost any sane clock speed you can dream up. Coupled with the right crystal, it does exactly what I need.
But, there’s the problem. TI specifies a whole mess of arcane crystal parameters needed in order to make the pullable VCXO actually work. The catch is that nobody selling crystals actually publishes most of those numbers. That means that you can neither determine the pullability range of a given crystal, nor find a crystal that actually works. They list a number of specific crystals that “should work”, but not only are those datasheets no more help, but nobody (Digikey, Newark, Mouser, or anybody else I can buy from) sells them. Hard stop.
Well, as I was looking through the listed vendors hoping to get my hands on some at least some samples, I tried to focus on US-based companies so I could actually communicate with them (all the others are in China etc). Turns out Pletronics is based in Lynnwood, Washington, just a couple hundred miles north of here. I sent them an email asking if they could point me to a crystal that’s supposed to work with and be pullable by the CDCE9xx series, and got back an answer that surprised me, and made my week. They happen to sell a part that’s a CDCE9xx and matching crystal in one package!
The FD77T is the biggest of that line, based on the CDCE949. The package is all of 5x7mm, which is ever so slightly larger than the CDCE913 alone (5×6.4mm), and noticeable smaller than the CDCE949 (7.8×6.4mm). Compared to the CDCE949, crystal, and related parts, it’s radically smaller and easier to deal with. It takes VCCIO, VCCINT, I2C, and VCXO control and spits out 7 PLL outputs, end of story. The smaller versions (FD7[345]T) have fewer PLLs and outputs, but in the exact same package. Pletronics seems to stock the FD77T for at least sample quantities with 24MHz, 24.576MHz, and 25MHz crystals.
The kicker is that the 1,000 unit pricing I was quoted was in the $2.50 range. That’s cheaper than either the CDCE913 or the high-spec crystal separately!
In order to do testing, I made up a tiny adapter board for the FD77T that brings out all the pins, supplies the 1.8V VCCINT, and adds an extra set of top-side headers for the I2C programming interface:
In order to program the actual chip, you have to set up a rather complex sequence of registers. TI provides a program called ClockPro that does it for you, but it seems to be written in MatLab and is ludicrously slow. To top it off, it’s Windoze only and doesn’t provide any easy way of getting the register values out in a form that can be programmed in. I’ve had to resort to literally typing in hex from the binary show in the bit viewer, which is very error-prone and not much fun at all. So last night I constructed a Python script that does the core PLL calculation, and this morning added code to use the BusPirate to set the clock. So far it works like a charm!
The code uses an iterative method, but one I’ve already thought through as far as implementation in a microcontroller. It works back from the target clock, first finding a Pdiv that results in a Fvco closest to the nominal 135MHz. It then tries all valid Pdiv’s above and below that still fit within the 80-230MHz range. For each Pdiv/Fvco combination, it tries all the N multipliers from 1 through the max 4095, checking if the multiplied frequency modulo the Fvco results in no remainder, producing a viable M. From there it calculates the intermediate values required to shove into the PLL registers, and outputs an I2C string to the BusPirate to set the clock.
As useful as the above is, setting the clock speed can sometimes be something you want to do at run-time. Or more likely, you just don’t want to have to go through all that trouble when prototyping requires you to change the clock. To solve that problem, I also designed a board that includes a microcontroller:
Populating this board is lower priority, but it’ll happen sometime soon. The Xmega32A4 on the right is intended to run a microcontroller version of the above algorithm, with some tweaks in place for performance. Mostly that means trying to fit the calculation into common bit widths, and dealing with the cases where it can’t gracefully and efficiently. The goal is to have a register set on the MCU accessible via the various available protocols (the upper row of the board is a straight copy of a “serial” port on the Xmega, providing hardware async serial, I2C, and SPI) that lets you simply say “I want xx.yyyMHz on pin X, go!” and get a clock out. Things get a little bit more complicated when you ask it to deliver two different clocks on pins that share a PLL, but that’s only a matter of finding a common Fvco with which two Pdiv’s generate the requested clocks.
A more interesting feature of the code destined for the MCU is the ability to lock the crystal to an external pulse. To do so you would designate one of the interface pins as a trigger, and configure it for a particular mode. To start off, the MCU will switch its clock from the internal oscillator to one of the PLL’s outputs, thus creating a cycle counter based on the crystal. When these pulses are detected on the pin, the MCU will compute the difference between the actual counter and the desired counter, and run a PID to generate the VCXO control voltage, thereby dragging the crystal back into alignment with the external source.
The trigger modes would be pulse-before-count, pulse-after-count, and pulse-per-X. In the first, the controlling circuit is expected to provide a trigger pulse, and then set a register with the cycle count that it was supposed to be located at. In the second, you would set the register before the trigger pulse. In the last, you set the number of cycles that are supposed to occur between pulses that come at regular intervals. This mode is ideal for interfacing with the 1PPS signal coming off a GPS receiver. Run the MCU off Y1 at the base 24.576MHz frequency, set the register to 24,576,000, connect 1PPS to the right pin, and suddenly you have a locked atomic frequency.
I intend to sell both of these modules on my (still upcoming) webshop. The bare module should probably run about $10, while the Xmega-based module will likely run around $20-$25. As usual, if you need one of these and can’t wait for the webshop, let me know and I’ll see what I can do. Just remember the code for the MCU doesn’t exist just yet.