SPI Issues

I have been working with programming the BBB’s SPI interface in python, and have become aware of a large number of issues others may be interested in; if planning on using the SPI interface, I hope this can save others some time. This is ongoing, so some of these issues may not be real in that they may be caused by something else I am doing wrong, so please verify for yourself. If not interested in using the SPI’s please just skip.

Background BBB C: Linux BBB3 3.8.13-bone70 #1 SMP Fri Jan 23 02:15:42 UTC 2015 armv7l GNU/Linux
(note tried upgrading to bone 76, but archive wasn’t found - afraid to upgrade to 3.14 in case everything breaks).

Reason for working with SPI: have developed an interface cape and am verifying everything works:
Cape Summary: 4-out I2C mux, 1 SPI, 1 UART, 1CAN, 8-pin GPIO, PRU-base logic analyzer (similar to BeagleLogic - BeagleBoard), programmable regulator (to allow both 3.3 and 5.0 applications), real-time-clock, temp measurement, output voltage measurement, all outputs buffered plus a CAN driver, 256 kbyte EEPROM. As far as I’ve gotten, the hardware seems to be working (this is the n’th iteration), but am working on software.

Reason for post: many issue re BBB’s SPI. Have exercised both Adafruit_BBIO.SPI and spidev. Summary, both drivers can work; both drivers have bugs. I will try to summarise in a top down manner. Most of the issues below were identified using the built-in logic analyzer; I think for most people to use the SPI’s, it will be necessary to plan on using a logic analyzer.

  1. My board is set up to use SPI1 CS0 (chip select 1 is not available); both HDMI and HDMIN have been disabled. Issue; SPI1 can not be used unless device tree for SPI0 is first loaded (see text placed at end so it doesn’t crowd up summary). If SPI0 is not loaded first, then device files for spi1 are not found. Note: that Adafruit_BBIO.SPI automatically loads ADAFRUIT-SPI0-00A0.dtbo when Adafruit_BBIO.SPI.SPI(0,0) is instantiated; this must be done before instantiating Adafruit_BBIO.SPI.SPI(1,0). This means pins for SPI0 are not available for other functions.

  2. When using ADAFRUIT-SPI1, the chip select line has glitches (i.e. activates) in between writes, usually just a bit after the write, there are no clock pulses at this time, so I doubt this will cause errors. This does not occur when using spidev. I can add a *.png later showing glitches if interest merits.

  3. Both Adafruit_BBIO.SPI and spidev support writing using xfer() and xfer2(). From the documentation; xfer: CS will be released and reactivated between blocks. delay specifies delay in µsec between
    blocks; xfer2: CS will be held active between blocks. Comments: when writing multiple bytes, CS0 goes low, the bytes are transmitted, and then CS0 goes high. I can not find a definition for a “block” and I can not see any discernible difference between the two transactions (i.e. cfer and xfer 2) when looking at the signals using the Logic Analyzer. Summary, you can use either and documentation needs updating.

  4. Loading the device trees for either driver gives similar error messages in the tail of dmesg (see text at end). Despite these error messages, the trees load (verified using sudo cat $SLOTS) and the drivers seem to work.

  5. The parameters specified in the device trees for spidev (that is BB-SPIDEV0-00A0.dtbo and BB-SPIDEV1-00A0.dtbo) are not used; for example, spi-max-frequency is left at 16MHz and mode is left at 1; I looked into the main device tree and these are not specified there; I can only guess they come from the drivers themselves. This error does not occur for ADAFRUIT-SPI0-00A0.dtbo and ADAFRUIT-SPI1-00A0.dtbo trees. If using spidev, then these parameters should be set in code at initialization time.

I will probably use spidev going forward along with specifying the parameters at initialization as the “1 us glitches” of the Adafruit interface worry me. An example of the SPI waveforms when using spidev with d1 looped back to d0 is shown in the attached file. Some error message codes follow below.

I hope this helps save others some time.

Error when loading spi1 if spi0 has not been loaded:

(Pdb) n

→ self.spi = SPI(1,0)
(Pdb) n
IOError: (2, ‘No such file or directory’)
→ self.spi = SPI(1,0)

Instantiating SPI(1,0) after instantiating SPI(0,0) without an error:

→ super(classSPI, self).init()
(Pdb) n

→ self.spi = SPI(0,0)
(Pdb) n
→ if device == 1:
(Pdb) n
→ self.spi = SPI(1,0)
(Pdb) n
→ self.device = device

Errors when loading device trees from dmesg, but drivers still work.

[ 53.458947] bone-capemgr bone_capemgr.9: slot #10: dtbo ‘BB-SPIDEV1-00A0.dtbo’ loaded; converting to live tree
[ 53.459214] bone-capemgr bone_capemgr.9: slot #10: #2 overlays
[ 53.481230] edma-dma-engine edma-dma-engine.0: allocated channel for 0:45
[ 53.481330] edma-dma-engine edma-dma-engine.0: allocated channel for 0:44
[ 53.501256] edma-dma-engine edma-dma-engine.0: allocated channel for 0:43
[ 53.501317] edma-dma-engine edma-dma-engine.0: allocated channel for 0:42
[ 53.501929] ------------[ cut here ]------------
[ 53.501962] WARNING: at fs/sysfs/dir.c:536 sysfs_add_one+0x59/0x78()
[ 53.501970] sysfs: cannot create duplicate filename ‘/bus/platform/devices/0.channel@0’
[ 53.501978] Modules linked in: g_multi libcomposite arc4 ath9k_htc ath9k_common ath9k_hw ath mac80211 cfg80211 rfkill omap_rng uio_pruss(O)
[ 53.502053] [] (unwind_backtrace+0x1/0x9c) from [] (warn_slowpath_common+0x33/0x48)
[ 53.502069] [] (warn_slowpath_common+0x33/0x48) from [] (warn_slowpath_fmt+0x1d/0x28)
[ 53.502085] [] (warn_slowpath_fmt+0x1d/0x28) from [] (sysfs_add_one+0x59/0x78)
[ 53.502104] [] (sysfs_add_one+0x59/0x78) from [] (sysfs_do_create_link+0xc7/0x188)
[ 53.502120] [] (sysfs_do_create_link+0xc7/0x188) from [] (bus_add_device+0x77/0xd0)
[ 53.502147] [] (bus_add_device+0x77/0xd0) from [] (device_add+0x333/0x3d8)
[ 53.502171] [] (device_add+0x333/0x3d8) from [] (of_platform_device_create_pdata+0x37/0x50)
[ 53.502191] [] (of_platform_device_create_pdata+0x37/0x50) from [] (of_overlay_device_entry_change.isra.0+0x89/0xd4)
[ 53.502207] [] (of_overlay_device_entry_change.isra.0+0x89/0xd4) from [] (of_overlay+0x71/0x130)
[ 53.502230] [] (of_overlay+0x71/0x130) from [] (bone_capemgr_load+0x369/0x478)
[ 53.502247] [] (bone_capemgr_load+0x369/0x478) from [] (slots_store+0x19b/0x2e8)
[ 53.502262] [] (slots_store+0x19b/0x2e8) from [] (dev_attr_store+0xb/0x14)
[ 53.502278] [] (dev_attr_store+0xb/0x14) from [] (sysfs_write_file+0xa9/0x10c)
[ 53.502299] [] (sysfs_write_file+0xa9/0x10c) from [] (vfs_write+0x67/0xfc)
[ 53.502314] [] (vfs_write+0x67/0xfc) from [] (sys_write+0x29/0x48)
[ 53.502335] [] (sys_write+0x29/0x48) from [] (ret_fast_syscall+0x1/0x46)
[ 53.502343] —[ end trace f9355f0ec79b9e96 ]—
[ 53.502413] of_overlay_device_entry_change: Failed to create platform device for ‘/ocp/spi@481a0000/channel@0’
[ 53.502497] ------------[ cut here ]------------
[ 53.502512] WARNING: at fs/sysfs/dir.c:536 sysfs_add_one+0x59/0x78()
[ 53.502519] sysfs: cannot create duplicate filename ‘/bus/platform/devices/1.channel@1’
[ 53.502526] Modules linked in: g_multi libcomposite arc4 ath9k_htc ath9k_common ath9k_hw ath mac80211 cfg80211 rfkill omap_rng uio_pruss(O)
[ 53.502700] [] (unwind_backtrace+0x1/0x9c) from [] (warn_slowpath_common+0x33/0x48)
[ 53.502715] [] (warn_slowpath_common+0x33/0x48) from [] (warn_slowpath_fmt+0x1d/0x28)
[ 53.502730] [] (warn_slowpath_fmt+0x1d/0x28) from [] (sysfs_add_one+0x59/0x78)
[ 53.502746] [] (sysfs_add_one+0x59/0x78) from [] (sysfs_do_create_link+0xc7/0x188)
[ 53.502761] [] (sysfs_do_create_link+0xc7/0x188) from [] (bus_add_device+0x77/0xd0)
[ 53.502778] [] (bus_add_device+0x77/0xd0) from [] (device_add+0x333/0x3d8)
[ 53.502796] [] (device_add+0x333/0x3d8) from [] (of_platform_device_create_pdata+0x37/0x50)
[ 53.502813] [] (of_platform_device_create_pdata+0x37/0x50) from [] (of_overlay_device_entry_change.isra.0+0x89/0xd4)
[ 53.502829] [] (of_overlay_device_entry_change.isra.0+0x89/0xd4) from [] (of_overlay+0x71/0x130)
[ 53.502846] [] (of_overlay+0x71/0x130) from [] (bone_capemgr_load+0x369/0x478)
[ 53.502861] [] (bone_capemgr_load+0x369/0x478) from [] (slots_store+0x19b/0x2e8)
[ 53.502875] [] (slots_store+0x19b/0x2e8) from [] (dev_attr_store+0xb/0x14)
[ 53.502890] [] (dev_attr_store+0xb/0x14) from [] (sysfs_write_file+0xa9/0x10c)
[ 53.502904] [] (sysfs_write_file+0xa9/0x10c) from [] (vfs_write+0x67/0xfc)
[ 53.502918] [] (vfs_write+0x67/0xfc) from [] (sys_write+0x29/0x48)
[ 53.502933] [] (sys_write+0x29/0x48) from [] (ret_fast_syscall+0x1/0x46)
[ 53.502941] —[ end trace f9355f0ec79b9e97 ]—
[ 53.504798] of_overlay_device_entry_change: Failed to create platform device for ‘/ocp/spi@481a0000/channel@1’
[ 53.504822] bone-capemgr bone_capemgr.9: slot #10: Applied #2 overlays.

this ^ issue is now resolved in the repo, bone77 is available to be
updated too... (sorry haven't really pushed spi enough to help out
with the rest)


Thanks Robert, I did the recommended upgrade to bone 76, but after the upgrade and running uname -a, it still states bone 70.

The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 17.6 MB of archives.
After this operation, 41.2 MB of additional disk space will be used.
Get:1 Index of /debian wheezy/main linux-image-3.8.13-bone77 armhf 1wheezy [17.6 MB]
Fetched 17.6 MB in 1min 6s (263 kB/s)
Selecting previously unselected package linux-image-3.8.13-bone77.
(Reading database … 121773 files and directories currently installed.)
Unpacking linux-image-3.8.13-bone77 (from …/linux-image-3.8.13-bone77_1wheezy_armhf.deb) …
Setting up linux-image-3.8.13-bone77 (1wheezy) …
update-initramfs: Generating /boot/initrd.img-3.8.13-bone77
Reading package lists… Done
Building dependency tree
Reading state information… Done
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 307 kB of archives.
After this operation, 612 kB of additional disk space will be used.
Get:1 Index of /debian wheezy/main mt7601u-modules-3.8.13-bone77 armhf 1wheezy [307 kB]
Fetched 307 kB in 1s (159 kB/s)
Selecting previously unselected package mt7601u-modules-3.8.13-bone77.
(Reading database … 123366 files and directories currently installed.)
Unpacking mt7601u-modules-3.8.13-bone77 (from …/mt7601u-modules-3.8.13-bone77_1wheezy_armhf.deb) …
Setting up mt7601u-modules-3.8.13-bone77 (1wheezy) …
update-initramfs: Generating /boot/initrd.img-3.8.13-bone77

sudo reboot

Broadcast message from root@BBB3 (pts/0) (Mon Sep 21 16:15:33 2015):

The system is going down for reboot NOW!

Connection to beaglew closed.

ssh martin@beaglew
Debian GNU/Linux 7

BeagleBoard.org BeagleBone Debian Image 2014-04-23

Support/FAQ: Beagleboard:BeagleBoneBlack Debian - eLinux.org
martin@beaglew’s password:
Last login: Mon Sep 21 12:07:13 2015 from granite10

uname -a
Linux BBB3 3.8.13-bone70 #1 SMP Fri Jan 23 02:15:42 UTC 2015 armv7l GNU/Linux

Ah that's why ^^, you are running 2014-04-23 and have the my repo enabled.

update_kernel assumes if the repo is enabled, simply install the
"linux-image-*.deb" is enough to update the boot script..

for "2014-04-23" you want to run these two commands in the else section:


So nuke the rest of that 'if' block, then it'll then work for you..

BTW/Warning, upgrading to v3.14.x is going to cause you bigger issues
with "2014-04-23" as the values we use for u-boot in the location of
the dtb (at the time of 2014-04-23) and v3.14.x 'fat' dtb's cause them
to over write the kernel location in memory. So the board will
hardlock after u-boot jumps to the kernel..

The safe bet for to look at updating to the 2015-07-28 image: (it's
also wheezy and 3.8.x)


as it's just the natural progression of rolling updates from 2014-04-23 image..


Robert, is 4.x not mature enough to do all the above ? Been reading some posts that the PRU don’t work with 4.x, but would like to know if that is user error, or if it’s known and being worked on.

Elias Bakken's gotten v4.1.x's pru to work for his replicape software images..


Elias Bakken’s gotten v4.1.x’s pru to work for his replicape software images…

Don’t know the person, but have heard of the project. I wonder if he’s documented the steps he took in order to get it working . . …

Well, he fed back the patches, so our v4.1.x-ti/bb.org-overlays has
all the stuff he needed to make ti work..


Well, he fed back the patches, so our v4.1.x-ti/bb.org-overlays has
all the stuff he needed to make ti work…

Ah, ok. Still, having never setup the PRU’s personally, I’d still like a good, and preferably modern “how to”. But people seem to be doing that all the time, so I should be able to figure it out.

Thanks Robert, upgrading to a new image is a really big deal as I have so many apts and pips installed; the last time I did it, I think I lost a week although hopefully I’m better at it now. Probably the best way will be to purchase a new BBB and do the upgrade on it so I still have a working board to continue with in case real problems occur. Re updating the kernel, I think if I make the changes:

#if [ ! “x${test_rcnee}” = “x” ] ; then
if [ “x${test_rcnee}” = “x” ] ; then

then the else clause will be triggered. Alternatively, I guess I could comment out your repos from /etc/apt/sources.list and just leave the upgrade shell file as it is? Thanks again.
p.s. would you recommend removing your repos from /etc/apt/sources.list?

I’d just put the new image on an SD card and boot from it before flashing.

I can’t remember the exact commands but there are some dpkg options to produce a list of installed packages to a file and then re-install them from that file after copying it to the new system. Still might get some errors as sometimes package names change, but it gets you close quickly. Just edit the file first to remove the linux-image lines from the original system’s package list. Google should quickly find examples.

Had real problems upgrading to bone77 which took almost half a day but I was eventually successful with the help of bashdb; summary of SPI issues after upgrading.

I’m exclusively using spidev now, but I expect the issues will still hold for Adafruit_BBIO.SPI.

  1. spi1 can still not be used unless device tree for spi0 is first loaded.

  2. loading device tree for spi1 and then loading device tree for spi0 shows both SLOTS, but spi1 does not work.

  3. loading device tree for spi0 and then loading device tree for spi1 shows both SLOTS and spi1 now works, but of course the pins used by spi0 are not available.

  4. errors in /var/log/syslog (i.e. dmesg) occur at the time of loading device tree of spi1, but spi1 still works (assuming spi0 was loaded first)

Additional unrelated info; I have been successful at getting edge driven interrupt-based callback functions working using Adafruit_BBIO.GPIO by trial and error. The documentation on this is sparse to say the least; I can’t figure out which parameters are acceptable for the functions, and what the function actually do; and I can place breakpoints into the callback functions using pdb, but they are not triggered even though the callback functions are called at the rising edge (as programmed); I haven’t tried winpdb to get breakpoints in the callback functions but probably will sometime in the next couple of weeks… Summary, this seems to work and may be a good approach for GPIO’s in python when one does not want to block waiting for the edge.

Overall Summary: I2C fine, GPIO fine but sparse documentation, SPI works but very flaky and can’t use spi1 without wasting pins of spi0

Robert, as usual the upgrade to bone77 unfortunately killed my logic analyzer. I need to recompile uio_pruss.c with a larger size memory for the extram_pool_sz, but to do this I believe I need to download bone77 kernel headers, and then download the kernel from your repository, change and recompile uio_pruss.c, and re-install uio_pruss.ko etc. Unfortunately, I am stuck at the first step:

wget http://rcn-ee.net/deb/precise-armhf/v3.8.13-bone77/linux-headers-3.8.13-bone77_1precise_armhf.deb
returns with a

HTTP request sent, awaiting response… 404 Not Found
Could you possibly tell me what the correct address should be? It seems upgrades just never go right for me.

"precise" I'm sorry, i stopped building for precise a year after
trusty was released (lts+(next lts)+1year) = 2015.04



Was the last build..


Please ignore for now, found headers by changing precise to wheezy (actually I added your repository back into /etc/apt/sources.list and then did an apt-get but I think it’s equivalent). Next step is to get uio_pruss.ko.

And so the upgrade to bone77 continues:

  1. needed to recompile kernel so uio_pruss.c had static int extram_pool_sz = SZ_8M (took a long time to figure out that SZ_8M was the correct define) ; downloaded kernel into BBB and started compiling kernel; failed due to not enough memory.
  2. started over on desktop; had to install cross compilation tool chain. Tried to compile kernel; failed due to dependencies; after Googling, installed dependencies; failed again due to more dependencis; solved with Google; failed due to having directory on Dropbox and it’s issue with case conflicts; copied to a non-Dropbox directory and currently trying again (each try is almost an hour). Moral: even the simplest upgrade will break your programs; plan on stopping everything for at least 1-5 days.

and yet i have everything setup for you to cross compile with :wink:

git clone https://github.com/RobertCNelson/bb-kernel
cd bb-kernel/
git checkout origin/am33x-v3.8 -b tmp