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

writebytes/readbytes broken? #19

Open
JAEGER2K opened this issue Mar 19, 2015 · 10 comments
Open

writebytes/readbytes broken? #19

JAEGER2K opened this issue Mar 19, 2015 · 10 comments

Comments

@JAEGER2K
Copy link

I connected MISO and MOSI on my RaspberryPI and ran this program:

#!/usr/bin/env python
import spidev
def dmp(A):
    s = ""
    cnt = 0
    for a in A:
        s+="%0.2X " % a
        cnt=(cnt+1)%6
        if cnt == 0:
            s+="\n"
    print s

spi = spidev.SpiDev()
spi.open(0,0)
b = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D]
print "testing read/write bytes"
spi.writebytes(b)
dmp(spi.readbytes(len(b)))
print "testing xfer"
dmp(spi.xfer(b))
print "testing xfer2"
dmp(spi.xfer2(b))
spi.close()

The array b should be echoed, but instead there are only zeroes. I checked writebytes() with an oscilloscope and it seems like it doesn't send anything at all.
But xfer and xfer2 work.

Or have I misunderstood writebytes? I thought it doesn't return anything, but keeps the data in a buffer which is accessable via readbytes.

some other interesting stuff:

$ uname -a
Linux raspberrypi 3.18.9+ #768 PREEMPT Sun Mar 15 18:59:03 GMT 2015 armv6l GNU/Linux
$ modinfo spi-bcm2708 
filename:       /lib/modules/3.18.9+/kernel/drivers/spi/spi-bcm2708.ko
alias:          platform:bcm2708_spi
license:        GPL v2
author:         Chris Boot <bootc@bootc.net>
description:    SPI controller driver for Broadcom BCM2708
srcversion:     4C511494EF4EBE6610ACDB6
alias:          of:N*T*Cbrcm,bcm2708-spi*
depends:        
intree:         Y
vermagic:       3.18.9+ preempt mod_unload modversions ARMv6 
@jainakshay91
Copy link

I second this. Readbytes and writebytes do not seem to be working. Instead I am using xfer and xfer2.

@Gadgetoid
Copy link
Contributor

Tested this on a Raspberry Pi 3, running Raspbian, Kernel 4.4.15 and Python 2.7.9.

Ran, simply:

from spidev import SpiDev
dev = SpiDev(0,0)
dev.writebytes([0,1,2,4,8,16,32,64,128])

Results were exactly as expected. 9 groups of clock pulses on my scope, with each bit asserted at the right time.

I used the repl to run the writebytes command and caught it in single-shot mode on my scope.

Same result sending: list(range(0,128)) - got the sequential list of numbers I expected.

Can you identify your Pi, by running:

cat /proc/cpuinfo | grep Revision

And I'll see if I can replicate on the same hardware.

I haven't tested readbytes yet.

@JAEGER2K
Copy link
Author

JAEGER2K commented Oct 17, 2016

Can you identify your Pi, by running:

Unfortunately I can't. At the time I posted this issue I've worked on a project for my university. Now it's finished and I don't have access to the hardware anymore. But maybe @jainakshay91 can help you.

@dwhall
Copy link

dwhall commented Jul 2, 2017

I believe I am seeing this issue.
Hardware is a Raspberry Pi 3 Model B.
Software is Raspbian Jessie w/Desktop 2017-06-21 straight from raspiberrypi.org.
I'm using the spidev module built into the raspbian image; I don't know how old the module is.
Spi enabled via sudo raspi-config, but only /dev/spi0.0 and /dev/spi0.1 are present. No /dev/spi1* devices.
Loopback wire connecting Rpi's pins 19 to 21 (SPI0 MOSI to MISO).

$ uname -a
Linux KC4KSU-41 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l GNU/Linux

$ cat /proc/cpuinfo | grep Revision
Revision	: a22082

$ modinfo /lib/modules/4.4.50-v7+/kernel/drivers/spi/spi-bcm2835.ko 
filename:       /lib/modules/4.4.50-v7+/kernel/drivers/spi/spi-bcm2835.ko
license:        GPL v2
author:         Chris Boot <bootc@bootc.net>
description:    SPI controller driver for Broadcom BCM2835
srcversion:     64E8A93AAE8A9E8C014112F
alias:          of:N*T*Cbrcm,bcm2835-spi*
depends:        
intree:         Y
vermagic:       4.4.50-v7+ SMP mod_unload modversions ARMv7 

$ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import spidev
>>> s = spidev.SpiDev(0,0)
>>> d = [0xaa,0x55,0xcc,0x33]
>>> s.xfer2(d)
[170, 85, 204, 51]
>>> s.xfer(d)
[170, 85, 204, 51]
>>> s.writebytes(d)
>>> s.readbytes(len(d))
[0, 0, 0, 0]

With a scope, I can see that the calls to xfer2(), xfer() and writebytes() all generate proper signals on the MOSI line. I get the same result using
Python 2.7.9 (default, Sep 17 2016, 20:26:04)
[GCC 4.9.2] on linux2

I see that the call to writebytes() generates a signal on MOSI that loops back to MISO. I expect that the data on MISO is then read into a hardware or software buffer and that readbytes() would convey the data from that buffer. Is this expectation wrong?

If there are instructions on how to build and install this module, please share and I'll retry using the latest source.

Other tidbit. I can call readbytes() with any reasonable non-zero value (1..512) and I get in return a list of that many zeros. I can call readbytes(100) repeatedly and get many 100-length lists of zeros, but there was no traffic on the SPI bus. I would expect some error reading from an empty queue.

@aromanro
Copy link

I just did the same check, with a loopback line between MOSI and MISO and got the same result for readbytes. xfer replicates the input as expected, but not writebytes/readbytes.

@aromanro
Copy link

I have more info on this, I played with the SPI driver more on Raspberry, the issue is originating from the driver itself. I wrote some C code that does something similar as the python lib and it seems that it's not the library's fault, it's the way the driver works.

@semininja
Copy link

I believe that writebytes() and readbytes() cannot be used with a loopback, because when you use the former, you'll write 8 bits of data without reading, which means MISO ignores the written bits; then, when you readbytes() after that, you have already stopped sending data on MOSI, so there's nothing to read but 0.

In other words, you'd need to have an external device, at least to act as a buffer, in order to test this properly. I believe this is not a bug, but an implementation/testing error.

@semininja
Copy link

To provide some more explanation, I believe that write/readbytes() are meant for one-way transfer; i.e. "write bytes and ignore response" and "read bytes without writing anything", while xfer/2() are meant for reading while writing.

@LazloKovacs
Copy link

It seems to be an issue on the second SPI bus on the pi4 using spidev. This code fails

from spidev import *
#BUS = 0
BUS = 1
spi = SpiDev(BUS,0)
spi.max_speed_hz = 1000000
spi.no_cs = True
spi.mode = 1
contents = [6]
#spi.xfer(contents)
spi.writebytes(contents)

while the other three combinations of BUS= 0/1 and xfer/writebytes work. My /boot/config.txt includes

dtparam=spi=on
dtoverlay=spi1-3cs

@LazloKovacs
Copy link

Please ignore my last (too hasty) comment. I was correct with the observation that it's spi1 related, but not in my diagnosis. It seems to be an interaction between spi mode and the bus. On my system, both writebytes and xfer fail with xfer reporting
"SystemError: <method 'xfer' of 'SpiDev' objects> returned a result with an error set",
both work for (1,0), (0,0), and (0,1).
Also fails in the same way for MODE =3 but not for MODE = 2, so its definitely phase-related.
Here's my code:

#Fails for both xfer and writebytes for BUS = 1 and MODE = 1, works for other
#combinations.

from spidev import *

BUS = 1
MODE = 1
ComMethod = 'xfer'
ComMethod = 'writebytes'

spi = SpiDev(BUS,0)
spi.max_speed_hz = 1000000
spi.mode = MODE
contents = [6]
if ComMethod == 'xfer':
spi.xfer(contents)
else:
spi.writebytes(contents)

Since this is not the problem reported, (differing behavior of xfer and either readbytes or writebytes), it may have nothing to do with the reported problem. Sorry for any confusion caused.

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

7 participants