BBB SPI throwing ioctl errors

Hi,

about two years ago I was running the old 3.* kernel and SPI worked fine for what I was doing.
I updated to Debian 8.6 / 4.4.40-ti-r80 but now the same unchanged code throws odd errors that I can’t figure out on my own.

Here is how I’m writing out via SPI (16 bpw, mode 2)

struct spi_ioc_transfer info =
{
.tx_buf = (unsigned long)wbuf,
.len = length,
};

int ret = ioctl(fd, SPI_IOC_MESSAGE(1), &info);
if (ret < 1)
{
printf(“error: %s\n”, strerror(ret));
return 0;
}

The size of wbuf usually ranges from 10 bytes to 10000 bytes.
It will print “error: Unknown error -1” which does not leave me with much.

I also noticed that now (with the new kernel) I had to remove cs_change = 1 from the spi_ioc_transfer struct or else CS would stay low the whole time (between messages).

Anyway, should I revert to 3.* or does anyone know what’s going on?

It’s not your code, that should be obvious when it work in 3.8.x kernels, and not so well on 4.x.

But the first thing that pops into my mind is that this is related to DMA. However about pasting a full output of the error messages you’re getting.

I also noticed that now (with the new kernel) I had to remove cs_change = 1 from the spi_ioc_transfer struct or else CS would stay low the whole time (between messages).

Anyway, should I revert to 3.* or does anyone know what’s going on?

I’m not familiar with SPI code on embedded Linux, but I have written a bit for bare metal devices. What you’re describing here almost sounds like cs_change = 1 is behaving like a mechanism for toggling the CS bit.

Here is something to keep in mind. kernel 3.8.x in the context of the beaglebone is a fairly old kernel. It’s noticeably slower to me( less responsive ), it’s going to have less features than 4.x.

Anyway:
https://github.com/RobertCNelson/dtb-rebuilder/blob/4.4-ti/src/arm/am33xx-overlay-edma-fix.dtsi

What this overlay does is enable SPI at boot through the main board file overlay. I’m not sure why this is supposed to fix the problem, but supposedly it does. This overlay is meant to be #include(ed) in the main board file overlay that gets loaded at boot. Like so: https://github.com/RobertCNelson/dtb-rebuilder/blob/4.4-ti/src/arm/am335x-boneblack.dts#L12-Lundefined

But you’ll notice that it’s disabled in this board file, and probably all( by default ). You can try uncommenting this in the given board file you’re using, and then giving it a shot.

Will it work ? I’m not sure, but it’s a good place to start.

How would you do this ? Well you would git pull this repo, Find the source for the board file you’re using. Edit the source appropriately(uncomment the line I mentioned ). then from the root directory of this repo run make, then make install. Also, if you’re familiar with make files, and you read the makefile for this project. You’ll notice there is the possibility to make, and install a single overlay.

Something you should be aware of. Occasionally I’ve had this whole procedure lock my own beaglebone at boot. I’m not 100% sure why, but I suspect this problem was because of a kernel to overlay version mismatch. How I personally resolved this problem for myself. Was to make a copy of the board overlay file I needed. Decompile it with dtc, make my changes to the output file. Then recompile the source with these changes in place. Finally, move the “old” overlay out of the way, and replace with the newly recompiled overlay binary.