SPI on new BBBW with current image

I’m posting this here hoping to save others some frustration/pain that I’ve gone through trying to get SPI working on the beagle bone black wireless.

The documentation for this is a shambles currently, with conflicting and out of date information all over the internet.

So, for those who find this post via google, let me explain what’s going on and how we got to here. SPI on the BBB is actually really easy, it just may not seem like it.

Ok, for starters when you google this, you’ve probably found a bunch of information on dts, overlays, capemgr, slots, etc…

I’ll take a sec to explain the history of this first.

So, linux traditionally used kernel modules (drivers) for every piece of hardware that you might want to use. This strategy didn’t work very well when all these ARM devices like the beagle bone started showing up because there were so many devices with different configurations, and it really didn’t make sense to add all that to the kernel. As a solution to this, Linus came up with this idea for a level of abstraction called a device tree.

The device tree is basically a way to describe the mapping and purpose of physical hardware to the kernel. This is done via a ‘dts’ file, which is a source code file that lists the specific properties of the hardware. This source code file is compiled into a binary that the kernel can understand, a ‘dtb’ or ‘dtbo’ file. So, early on in beagle bone history, this was how things were done. There were lots of dts and dtbo files that were made for all sorts of different purposes, and you, as the user could swap these out depending on how you want pins configured. You can also create your own. This is where some of the older articles you see that have instructions about creating a dts file and compiling it to enable SPI come from.

Well, that whole thing was pretty spiffy, but there were some drawbacks. One, it wasn’t very approachable for new folks. You basically had to learn a new language and toolchain just to configure pins. While better than writing a kernel module, that still wasn’t great. Also, all of this configuration happened at boot time, so every time you wanted to make a change you had to reboot. This really doesn’t work well for a device where you want to be able to hot swap extension boards and reconfigure things at runtime. Third, this all happened in kernel space, which as an industry we try not to do. It’s better to keep as much as possible in user space.

To address those issues: enter the Cape Manager. The cape manager is a pretty fancy piece of kernel module software that has the ability to dynamically load and swap out device tree overlays, and the tools live in userspace. When you see instructions on the web about adding lines to uEnv.txt like:

optargs=quiet drm.debug=7 capemgr.enable_partno=BB-SPIDEV0

this is telling the cape manager to load the SPI device tree overlay at boot time. Everywhere you look on the internet, this is the recommended solution for enabling SPI on 'current' devices. But, it doesn't work.

Why? Well, to explain that requires one more step.

Even though the cape manager is neat software from an engineering perspective, and really accomplished its goals well, it still leaves something to be desired from a new user perspective. Folks who are just getting into the whole maker scene are reasonably confused by all this.

To address that, some new software was created which is enormously fancy, called universal io.

Basically what this is, is a device tree overlay that's loaded by the cape manager at boot time that has the ability to dynamically configure all of the pins at runtime using a tool called config-pin.

You can see it and read more about it here: https://github.com/cdsteinkuehler/beaglebone-universal-io

So, with this utility all of the pins that aren't reserved for HDMI can be hot configured by using the simple config-pin command, and this includes SPI!

So, finally after that long bit of history, here's how you actually set up and use SPI on a new beagle bone black wireless with a current image:

#data out
config-pin P.18 spi

#clock out
config-pin P.22 spi

Rinse, repeat if you need other pins like CS, or MISO.

After days of learning all of the above, and figuring all this out, I'm finally able to see a beautiful output wave form on my oscope.

I hope this helps someone else new to all this!

Did you actually test this on the BBBW (not the BBB)? I did and I couldn’t get the SPI to work.