Writing

Feed Software, technology, sysadmin war stories, and more.

Wednesday, October 12, 2011

Assembling the USRP and making GNU Radio work with it

(This is the third post in a series. You might want to start from the beginning for context.)

Part three: Assembling the USRP and making GNU Radio work with it.

My doorbell rang around 11 AM. It was FedEx with a huge box of technology just for me. It had been a week since I ordered, and I was ready to get working on this thing.

You might think that software defined radio is like building a car by hand. No, it's harder than that. It's like building a car factory by hand in order to then build a car. Assembling this thing and dealing with the software was no different.

USRP chassis and parts

The USRP hardware arrives in the usual anti-static bags with warnings about how you could fry things by mishandling them. I carefully unpacked all of it and noticed the distinct lack of assembled bits. There were two major parts to the chassis: one of them was the bottom, sides, and front panel, and the other was just the top and back. There was also a huge bag of hardware: screws, standoffs, rubber feet, and the like.

Motherboard + daughterboard

There were no directions for which parts went where. I managed to figure out that my original placement of those standoff nuts (seen in the first photo) was incorrect when the motherboard failed to line up correctly. I backed all of them out and flopped it down on the chassis and put the nuts through the motherboard. Success! With this in place, the DBSRX2 daughterboard mounted without any trouble, and I connected its antenna jumper to a front panel connector.

Now it was time to start fighting with software. I knew my GR build didn't have USRP support because I had purposely skipped those deps earlier in the week. So now I had to go back and install things like SDCC. Naturally, the latest version had the wrong interface and would not make GR happy, as if the SDCC API had changed. So, I went back to the SDCC version in the GR docs (from 2004) and found that it would not build on my system. So I found the last 2.x version, figuring it would be new enough to build and old enough to have the right API. It did, and I moved on.

Of course, SDCC had its own dependencies, so I had to get gputils. With that installed, SDCC decided to trip over something else. It had its own function called getline() which now conflicts with something in glibc. Lovely. I decided to fix this one by going into their source and squashing all of those calls into some other name. Finally, it built cleanly and was installed.

So now at long last, I had a build of GNU Radio with USRP support, and it was time to run the USRP tests. This uncovered even more badness. It could see the USRP itself -- the motherboard -- but not the DBSRX2 daughterboard. I thought maybe I had fried something at first, since it was yielding some really bizarre nonsense numbers, but then I saw it.

It turns out that newer USRP daughterboards now require the use of an interface called UHD. I needed to get those drivers and firmware and install everything first. So, okay, I did that. UHD itself needed cmake, so I did that too. With all of this in place, I went back to build GR again, expecting to see it say "gr-uhd" now.

Nope. Nothing.

I guessed I needed something past the last actual tarball release of GNU Radio, and I was right. So now, I needed git on my machine so I could pull in their raw source tree and build from HEAD. It took a good bit to fetch all of that, re-configure, re-build, and re-install GR, but finally, I had something which would actually find all of my hardware.

That's when I ran into another fundamental problem.

There are a bunch of examples in the GNU Radio suite, including those for the "gnuradio-companion" graphical environment, but it seems that all of them were for the old style USRP. That is, they are for the USRP interface which was in the stock version. Nothing actually supported the UHD interface, so when I tried to run them, they'd just complain about not having any hardware and would quit.

This includes gr-smartnet, by the way. If you have an old DBSRX or TVRX board from the pre-UHD days, it probably Just Works for you. For me, it just laughed and pretended I had no radio at all. Great.

My diary gets a little fuzzy here, but somehow I managed to put together a simple narrow band FM receiver in gnuradio-companion based on the UHD USRP source. Working out from that, I slowly turned it from being a GUI FFT analysis thing into something which only digested raw data.

Then I started hooking the innards of gr-smartnet into it piece by piece. Everything had to be ported to the UHD way of thinking about things. Considering I had never seen any of this code before today, the fact I was making it work was pretty encouraging. I kept going and going.

By the time I stopped, I had something which would listen to a SmartNet control channel and tell you which talkgroups were active and which channel (frequency) they were on.

Command: Traffic on 853.42500 : PD 4 - Records
Command: Traffic on 851.60000 : PD 1
Command: Traffic on 853.42500 : PD 4 - Records

I looked up. It was about noon the next day. All of this had happened in just 24 hours: assembling a box with no instructions, figuring out a bunch of new APIs, and then making sense of an incoming stream of messages. It was time to take a break and sleep.

Next: part four: call logging, attempting audio, and burning a CPU.