If you missed my last installment, the summary is that I left for Hamvention with a partially working Whitebox Bravo. The device turned on and all the chips responded to my SPI commands and other control signals, but my PLL’s were not locking.
There is a very long story of things I tried a long the way. I’ll cover the high points. At first, I thought perhaps the short’ed clock net had b0rked the clock buffer for the PLL. I tried booting up a new board that had never been powered on with the manufacturing defect. No dice.
Luckily, the RF PLL, the ADF4351 has a way to see inside the Phase Frequency Detector (PFD) to see why it would not be locking. When I looked at the output for the VCO divider, things looked alright. But the PFD output for the clock indicated the signal wasn’t making it into the chip.
This proved that the IC wasn’t totally fried, and now I knew it had to be something really silly. I decided to follow my gut, and change from a resistor (DC coupling) to a capacitor (AC coupled) on the net from the TCXO to the PLL. And walah. As soon as I made this change, both PLL’s worked perfectly (I know, another Technician class mistake!) Here’s the output of the phase frequency detector:
So it wasn’t anything major, and sadly I didn’t have my first real world need to solve the Laplace Transform. But I learned a valuable lesson:
Don’t do little changes at the end, right before going to print. Even if they’re little.
I added a bunch of passives around the TCXO to allow for the option of plugging in a 10 MHz reference clock via an SMA connector. This is a popular ask and critical for radio astronomy as well as cell phone base stations. I made this addition very late in the design cycle and didn’t receive anything more than a short “looks good to me” design review on it.
I would have saved a lot of headache for myself if I had stuck to the original set of features. There can always be another revision for more new stuff.
So now, it seemed like the radio was operational. I had two locking PLL’s. I had a transmit chain coming from the FPGA, and then being encoded by my DAC. I set up the real test - hooking up the transmit SMA jack on the Whitebox to a receiver on my USRP.
Thanks to my extensive debugging of the project, I got a signal to come out first try at exactly where I expected it to be!
What you’re seeing here is:
- A 1.2khz AM modulated signal coming out of the DAC
- Which was mixed with a carrier at 144.39 MHz.
- Then sent to the USRP over a coaxial cable.
- Then down mixed with a 144MHz center frequency.
You can see both the CW tone as well as harmonics. Remember, the CMX991 radio chip is unbuffered and unfiltered as I have yet to choose a particular applications of this building block circuit. I would like to start the discussion about what topologies and components should be at this stage in the circuit (Please join the discussion below if you have any ideas on this!)
Now things are going to get fun. The hardware is there and functioning as a radio. The base drivers are there to control the hardware, turning on and off different parts for power savings.
It’s time to do some Digital Signal Processing. This is the Black Magic I wanted to learn in the first place.
The start for trying out new ideas in this arena is to have a well-tested signal processing engine hook into the hardware. And there’s no better signal processing system for radio than GNURadio.
Step one is to get data from GNURadio to the Whitebox over Ethernet. My last change got this to work at a sustained 50,000 samples / second, or 50kS/s. Each sample is two 16-bit 2’s complement numbers (say that 64 times fast!), representing the quadrature data.
I dumped a snapshot of samples flowing from GNURadio, over UDP and to my user space program. I used pylab to generate this graph. Thank you to the developers here, integrating matplotlib into a 1 line command line. With all the Python libraries (including SciPy) you end up with a feature set that approaches MATLAB.
After samples hit the user space program on the radio, I need to get the samples across the ARM, and to the FPGA for interpolation. This is done over the on-board System-on-a-Chip Bus. The bus I’m hooking into on the SmartFusion is called the APB3 bus.
Here’s a sneak preview of what I want to talk about next: designing, simulating and synthesizing the digital exciter so that way it works seamlessly from Linux to the antenna.
This simulation was done 100% in Python, and uses a Bus Functional Model to simulate the ARM processor corresponding with the core I’m writing. The purple sawtooth wave in the lower right demonstrates the capabilities of the exciter to pick up samples via the AP3 bus, then in buffer in a FIFO to enter the DSP clock domain. In the signal chain we interpolate and interleave the signal to be encoded by the quadrature DAC.