kidoman / embd

Embedded Programming Framework in Go
http://embd.kidoman.io
MIT License
1.28k stars 156 forks source link

SPIIOCTransfer struct is missing fields #38

Open hbhasker opened 9 years ago

hbhasker commented 9 years ago

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 commented 9 years ago

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

bgentry commented 8 years ago

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.