kidoman / embd

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

Is SPI working correctly on RPi? #42

Closed crabmusket closed 7 years ago

crabmusket commented 8 years ago

I'm trying to get SPI working to interface with an MCP3008 ADC. I can do it fine in Python:

#!/usr/bin/python3

import spidev
import time
import os

spi = spidev.SpiDev()
spi.open(0, 0)

# channel must be an integer from 0-7 inclusive
def readFromAdc(channel):
    speed = 100 * 1000
    delay = 0
    bpw = 8
    adc = spi.xfer2([1, (8 + channel) << 4, 0], speed, delay, bpw)
    data = ((adc[1] & 3) << 8) + adc[2]
    return data

def main():
    val = readFromAdc(channel = 0)
    print('Value: {}'.format(val))

if __name__ == '__main__':
    main()

But I tried using embd by copying the code in this post. I also tried it with raw SPI as follows:

package main

import (
    "flag"
    "fmt"
    "github.com/kidoman/embd"
    _ "github.com/kidoman/embd/host/rpi"
)

func main() {
    flag.Parse()

    err := embd.InitSPI()
    if err != nil {
        panic(err)
    }
    defer embd.CloseSPI()

    const (
        device  = 0
        speed   = 1e5
        bpw     = 8
        delay   = 0
        channel = 0
    )

    spi := embd.NewSPIBus(embd.SPIMode0, device, int(speed), bpw, delay)
    defer spi.Close()

    data := make([]uint8, 3)
    data[0] = 1
    data[1] = (8 + channel) << 4
    data[2] = 0

    err = spi.TransferAndRecieveData(data)
    if err != nil {
        panic(err)
    }
    reading := data[2] + (data[1]&3)<<8
    fmt.Printf("Value: %v\n", reading)
}

The blog code and my code both result in:

pi@raspberrypi ~ $ sudo ./datalogger
panic: invalid argument

goroutine 1 [running]:
main.main()
    /go/src/datalogger/main.go:37 +0x21c

goroutine 19 [chan receive]:
github.com/golang/glog.(*loggingT).flushDaemon(0x1f5c58)
    /go/src/github.com/golang/glog/glog.go:882 +0x60
created by github.com/golang/glog.init.1
    /go/src/github.com/golang/glog/glog.go:410 +0x2cc

I tried more logging but it looks okay:

pi@raspberrypi ~ $ sudo ./datalogger -v 3 -logtostderr
I1224 00:39:51.226839    2193 spibus.go:91] spi: sucessfully opened file /dev/spidev0.0
I1224 00:39:51.227806    2193 spibus.go:118] spi: setting spi mode to 0
I1224 00:39:51.228224    2193 spibus.go:126] spi: mode set to 0
I1224 00:39:51.228572    2193 spibus.go:136] spi: setting spi speedMax to 100000
I1224 00:39:51.228915    2193 spibus.go:143] spi: speedMax set to 100000
I1224 00:39:51.229239    2193 spibus.go:155] spi: setting spi bpw to 8
I1224 00:39:51.229610    2193 spibus.go:162] spi: bpw set to 8
I1224 00:39:51.230125    2193 spibus.go:173] spi: delayms set to 0
I1224 00:39:51.230455    2193 spibus.go:109] spi: bus 0 initialized
I1224 00:39:51.230775    2193 spibus.go:110] spi: bus 0 initialized with spiIOCTransfer as {0 0 0 100000 0 8}
I1224 00:39:51.231325    2193 spibus.go:189] spi: sending dataBuffer [1 128 0] with carrier {273049248 273049248 3 100000 0 8}
I1224 00:39:51.231743    2193 spibus.go:193] spi: failed to read due to invalid argument
panic: invalid argument

I also had a look at the kernel but couldn't figure out what would cause an error.

Oh, I'm on a Raspberry Pi B+ if that helps. Cross-compiling from Debian, Go 1.5 using

GOOS=linux GOARCH=arm go build -o datalogger main.go

EDIT: I wonder if the dynamically linked C libs could be different on the Pi? Maybe I should try compiling there.

wujiang commented 8 years ago

It can be related to this issue: https://github.com/kidoman/embd/issues/24. This PR https://github.com/kidoman/embd/pull/39/files can be helpful.

crabmusket commented 8 years ago

Oh, I could have sworn I searched for SPI in issues first. That does look relevant; thanks!