Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPIIOCTransfer struct is missing fields #38

Open
hbhasker opened this issue Sep 3, 2015 · 2 comments
Open

SPIIOCTransfer struct is missing fields #38

hbhasker opened this issue Sep 3, 2015 · 2 comments

Comments

@hbhasker
Copy link

hbhasker commented Sep 3, 2015

I had been banging my head against SPI transfer randomly deciding to bork with an invalid fd error and finally i figured there was something weird in the bus driver. Spent sometime reading about the ioctl interface to control SPI described here https://www.kernel.org/doc/Documentation/spi/spidev and realized that the SPIIOCTransfer struct in embd/host/generic/spibus.go does not align with the ioc structure defined in the kernel header.

The kernel header defines the structure as follows

struct spi_ioc_transfer {
__u64 tx_buf;
__u64 rx_buf;

    __u32           len;
    __u32           speed_hz;

    __u16           delay_usecs;
    __u8            bits_per_word;
    __u8            cs_change;
    __u32           pad;

    /* If the contents of 'struct spi_ioc_transfer' ever change
     * incompatibly, then the ioctl number (currently 0) must change;
     * ioctls with constant size fields get a bit more in the way of
     * error checking than ones (like this) where that field varies.
     *
     * NOTE: struct layout is the same in 64bit and 32bit userspace.
     */

};

The embd structure is missing the cs_change and pad fields. Once I added them in SPI transfer works like a charm and I am able to exchange messages without errors with an arduino connected over SPI.

You may want to expose the csChange field as well so that a user could decide to explicitly drop chipselect after one transfer. BTW I noticed that the actual kernel API allows more than one spiIOCTransfers to be chained by passing an array of them but looks like embd only exposes one transfer. Which is fine in most cases I guess.

type spiIOCTransfer struct {
txBuf uint64
rxBuf uint64

    length      uint32
    speedHz     uint32
    delayus     uint16
    bitsPerWord uint8

` csChange uint8
pad uint32
}

@hbhasker
Copy link
Author

hbhasker commented Sep 3, 2015

BTW this is was on my raspberry pi model B rev2. So it maybe different for other hosts not sure.

@bgentry
Copy link

bgentry commented Sep 16, 2015

I can confirm that the following diff at least lets me get back some values from my MCP3008 via SPI on a Raspberry Pi 2 Model B using the latest NOOBS:

diff --git a/host/generic/spibus.go b/host/generic/spibus.go
index f682daa..2f8c26d 100644
--- a/host/generic/spibus.go
+++ b/host/generic/spibus.go
@@ -36,6 +36,9 @@ type spiIOCTransfer struct {
        speedHz     uint32
        delayus     uint16
        bitsPerWord uint8
+
+       csChange uint8
+       pad      uint32
 }

 type spiBus struct {

As such this resolves #24.

bgentry added a commit to bgentry/embd that referenced this issue Oct 6, 2015
Per the discussion in kidoman#38, these two fields are part of the equivalent
struct in the kernel SPI driver. Adding the fields allows the SPI driver
to work on a Raspberry Pi Model 2 B.

h/t @hbhasker

Fixes kidoman#38. Fixes kidoman#24.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants