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

x/exp/io/spi: spi.Devfs.MaxSpeed may be ignored in certain case #16551

Closed
maruel opened this issue Jul 30, 2016 · 9 comments
Closed

x/exp/io/spi: spi.Devfs.MaxSpeed may be ignored in certain case #16551

maruel opened this issue Jul 30, 2016 · 9 comments

Comments

@maruel
Copy link
Contributor

maruel commented Jul 30, 2016

  1. What version of Go are you using (go version)?
    go version go1.7rc3 linux/arm
  2. What operating system and processor architecture are you using (go env)?
    Raspberry Pi 3
    $ go env
    GOARCH="arm"
    GOBIN=""
    GOEXE=""
    GOHOSTARCH="arm"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/pi/src/gopath"
    GORACE=""
    GOROOT="/home/pi/src/golang"
    GOTOOLDIR="/home/pi/src/golang/pkg/tool/linux_arm"
    CC="gcc"
    GOGCCFLAGS="-fPIC -marm -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build544338587=/tmp/go-build -gno-record-gcc-switches"
    CXX="g++"
    CGO_ENABLED="1"
    $ cd $GOPATH/src/golang.org/x/exp && git rev-parse HEAD
    fac9e6d4e3a4bd9d3dd6f47b3c79027a6b64dd0a
  3. What did you do?
    https://play.golang.org/p/BWhX4aQ9G6
    which was extracted from https://github.com/maruel/spiperf/blob/master/gio/gio.go
  4. What did you expect to see?
    Clock frequency to be 10mhz or a somewhat lower value, as supported by the linux SPI driver.
  5. What did you see instead?
    Observed clock frequency is 312khz as seen via oscilloscope. When testing a with one-off code, I get 6.25mhz.
@quentinmit quentinmit added this to the Unreleased milestone Aug 1, 2016
@quentinmit
Copy link
Contributor

MaxSpeed is documented as setting the max speed only; it seems like it's defensible, if a bit silly, for the kernel to choose 312kHz when you request 10MHz. It looks like Go is just passing the requested speed on to the kernel.

@maruel
Copy link
Contributor Author

maruel commented Aug 2, 2016

@quentinmit Please reread my comment. When using my own code, the kernel correctly choose the closest clock speed, which is 6.25mhz.

@quentinmit
Copy link
Contributor

Can you show the output of "strace" on both programs?

@samuel
Copy link

samuel commented Aug 3, 2016

I think the devfs_READ and devfs_WRITE constants are reversed.

With existing values (https://github.com/golang/exp/blob/master/io/spi/devfs.go#L19):

>>> devfs_MAGIC = 107
>>>
>>> devfs_NRBITS   = 8
>>> devfs_TYPEBITS = 8
>>> devfs_SIZEBITS = 13
>>> devfs_DIRBITS  = 3
>>>
>>> devfs_NRSHIFT   = 0
>>> devfs_TYPESHIFT = devfs_NRSHIFT + devfs_NRBITS
>>> devfs_SIZESHIFT = devfs_TYPESHIFT + devfs_TYPEBITS
>>> devfs_DIRSHIFT  = devfs_SIZESHIFT + devfs_SIZEBITS
>>>
>>> devfs_READ  = 2
>>> devfs_WRITE = 4
>>> hex((devfs_WRITE << devfs_DIRSHIFT) | (devfs_MAGIC << devfs_TYPESHIFT) | (4 << devfs_NRSHIFT) | (4 << devfs_SIZESHIFT))
'0x80046b04'
>>> hex((devfs_READ << devfs_DIRSHIFT) | (devfs_MAGIC << devfs_TYPESHIFT) | (4 << devfs_NRSHIFT) | (4 << devfs_SIZESHIFT))
'0x40046b04'

From the C header files:

$ cat values.c
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/spi/spidev.h>
#include <linux/types.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>

int main(int argc, char *argv[]) {
    printf("SPI_IOC_WR_MAX_SPEED_HZ %08x\n", SPI_IOC_WR_MAX_SPEED_HZ);
    printf("SPI_IOC_RD_MAX_SPEED_HZ %08x\n", SPI_IOC_RD_MAX_SPEED_HZ);
    return 0;
}
$ cc values.c && ./a.out
SPI_IOC_WR_MAX_SPEED_HZ 40046b04
SPI_IOC_RD_MAX_SPEED_HZ 80046b04

@rakyll rakyll self-assigned this Aug 24, 2016
@rakyll
Copy link
Contributor

rakyll commented Aug 24, 2016

I think the devfs_READ and devfs_WRITE constants are reversed.

These constants looks suspicious but all other writes (in the scope of my use cases) are succeeding.

strace output would be useful between the two.

@niklasnorin
Copy link

I just want to confirm that we have had to swap devfs_READ and devfs_WRITE to get the code to work. This should really just be fixed.

@the-sibyl
Copy link

I would like to confirm the same findings. The platform that I am developing on is an RPi Zero v1.3. The Linux kernel is 4.9.59+, and the SPI kernel module is spi_bcm2835.

I suspected also that READ and WRITE were reversed and came across this thread after a few days of debugging. I inserted some fmt.Println statements in devfs.go and found that the referenced value was being "rejected."

Both setting the speed and setting the SPI mode bits were broken, and investigation with a high speed logic analyzer was showing a clock around 100 MHz and no change in phase when I set up the peripheral with different parameters.

The following is a snippet of what I used to debug in devfs.go. "m before:" for instance would be 2, and "m after:" would be 0.

        case driver.Mode:
        //      m := uint8(v)
                m := v
                // I discovered later in the evening with a logic analyzer that the mode bit is "ignored" in this implementation
                // just as the speed is.
                fmt.Println("m before:", m)
                if err := c.ioctl(requestCode(devfs_WRITE, devfs_MAGIC, 1, 1), uintptr(unsafe.Pointer(&m))); err != nil {
                        return fmt.Errorf("error setting mode to %v: %v", m, err)
                }
                fmt.Println("m after:", m)
                c.mode = uint8(m)

@maruel
Copy link
Contributor Author

maruel commented Feb 1, 2018

I recommend https://periph.io/x/periph/conn/spi/spireg, which will be supported going forward.

I'll keep this bug open for documentation purposes but I'm unsubscribing for notifications so @ me directly if you want me to see the message.

@maruel
Copy link
Contributor Author

maruel commented Jul 23, 2018

I don't plan to make any change here.

@maruel maruel closed this as completed Jul 23, 2018
@golang golang locked and limited conversation to collaborators Jul 23, 2019
@rsc rsc unassigned rakyll Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants