Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by Turbinenreiter » Mon Feb 20, 2017 7:50 pm

I'm using the pyboard as SPI slave and a Raspberry Pi as Master, both running MicroPython and I'm seeing a lot of weirdness going on.

For example, I'm sending this (as byterray):

Code: Select all

[254, 202, 1, 0, 170, 15, 62, 32, 1]
and get his on the pyboard:

Code: Select all

[126, 74, 1, 0, 42, 15, 62, 32, 0]
That's a flip of the first bit. Always the first, never a different one. The first two bytes always have the bitflip, the other bites sometimes do, sometimes don't. This only happens from Pi to pyboard.
Needless to say, it didn't do that yesterday, only change I made was that the pyboard is now running from the SD card and not the internal flash.

At the same time, the data I send from the pyboard to the Raspberry Pi is fine, except when it isn't. Sometimes this happens:
send from the pyboard:

Code: Select all

[254, 202, 1, 0]
receive on the Pi:

Code: Select all

[0, 254, 202, 1]
It's only ever off by one, but not always. This happens in both directions.

This off-by-one-byte error also happens in a completely different project on completely different hardware with an atmel board running linux and an atxmega programmed in C++.

I'm using pyb.SPI on the pyboard, because machine doesn't seem to have a Slave mode.

Code: Select all

import micropython
micropython.alloc_emergency_exception_buf(100)
from pyb import SPI, Pin, ExtInt
spi = SPI(1, SPI.SLAVE, baudrate=10000)

def callback(trigger):
    spi.send_recv(data.bytes, control.bytes)
    data.struct.new = False

interrupt = ExtInt(cs, ExtInt.IRQ_FALLING, Pin.PULL_UP, callback)

while True:
	...

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by dhylands » Mon Feb 20, 2017 10:00 pm

I would look at the various modes and make sure that both sides are being consistent about when the data is being clocked.

Normally, you want the data to driven on one edge (rising or falling) and latched on the opposite edge.

This is probably easiest to see on a logic analyzer if you sent a bitstream of alternating 0's and 1's then it's easy to see when the data changes versus the clock. There should be a clock edge that's in the middle of when the bit is 0 or 1. That's the edge the slave should be using.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by deshipu » Mon Feb 20, 2017 10:07 pm

Did you make sure the polarity and phase are the same on both devices, and the clock is slow enough for both devices to work reliably?

Do you happen to know a logic analyzer that you could use to see what is actually there on the cables (and thus know which device is wrong)?

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by Turbinenreiter » Tue Feb 21, 2017 10:03 am

I checked the SPI mode again, changed my UNIX SPI library a bit, and am now sure that both devices sue the same mode.

Then I played around a bit, changing the modes to be the same, then to be different. Nothing changed, still bad communication.

Until I did a spi.deinit() before reseting the board. And now it's perfect. Also, now the SPI works when the mode matches and has errors when the mode mismatches.

Conclusion:
* make sure you are using the same mode on both devices
* deinit the spi object before you reload the script with a changed SPI mode

I gotta say you guys give good workflow. I post a cry for help usually around midnight before giving up and going to sleep. Next morning with a fresh brain and your input my problems are solved quickly.

Now I'll order an logic analyzer.

gercha2
Posts: 6
Joined: Sun Jan 15, 2017 5:19 am

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by gercha2 » Sat Mar 25, 2017 2:47 am

hello everyone, I guess I have the same issue,
I checked and have both Rpi and pyboard v1.1 with the same mode and frequency.
I have Rpi as master and it is sending 4 bytes through SPI: /0x01/0x02/0x03/0x04 in a loop. By otherhand, the pyboard is slave. It is receiving 4 bytes as is shown:

Code: Select all

b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
b'\x04\x01\x02\x03'
I don't know why the order is changing. I will really appreciate some help about this issue.

Trying to solve this I have put SPI.deinit() at the beginning, but I got an error.
This is the script:

Code: Select all

from pyb import SPI, ExtInt, Pin
SPI.deinit()
#
spi = SPI(2,SPI.SLAVE, baudrate=16000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, crc=None)
while True:
    data = spi.recv(4)
    print(data)
and this is the TypeError:

Code: Select all

^Cgercha3@ubuntu:~/coddingcommpyrpi$ vim SPI_pyb.py
gercha3@ubuntu:~/coddingcommpyrpi$ sudo python3 pyboard.py SPI_pyb.py
Traceback (most recent call last):
  File "<stdin>", line 11, in <module>
TypeError: function takes 1 positional arguments but 0 were given
gercha3@ubuntu:~/coddingcommpyrpi$ 

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by pythoncoder » Sat Mar 25, 2017 7:51 am

I think you should have

Code: Select all

spi.deinit()
i.e. call the instance method.

As for the byte order I think your master and slave are not synchronised. The master is sending 1,2,3,4,1,2,3,4... The slave has missed three bytes at some stage so is receiving the 4 from transmission N, followed by the 1,2,3 from transmission N + 1.

SPI doesn't have any built-in synchronisation so you must provide it. The master will happily send data to a slave which hasn't yet initialised itself, so they can easily start out of sync. One approach might be to use a GPIO line so that the slave can tell the master when it's ready to receive.

Even when started software SPI slave mode is difficult to use. SPI slaves are usually implemented in hardware to guarantee that they respond to incoming data in a timely fashion - otherwise they can lose synchronisation. This is because the interface has no handshaking: the master will throw data at an unresponsive slave oblivious to its state. So if your application spends time doing something other than servicing the slave interface it can easily lose data.
Peter Hinch
Index to my micropython libraries.

gercha2
Posts: 6
Joined: Sun Jan 15, 2017 5:19 am

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by gercha2 » Sun Mar 26, 2017 7:48 pm

Thank you!!!, I solved it. At last I got: "/x01/x02/x03/x04"
I didn´t know where to put (spi.deinit), because I got a Type Error. So fortunately your ad was very useful. I missed where SPI stops reading for synchronization. Then I follow some procedures described in: https://docs.micropython.org/en/latest/ ... b.SPI.html
Pyboard as Slave receiving data from Raspberry pi 2(SPI - Master):
1. import SPI from pyb
2. SPI initialization (e.g. spi = SPI(2,SPI.SLAVE, baudrate=16000000, polarity=0, phase=0,...); I pesonally used SPI(2)
(Important to both MASTER and SLAVE be matched in Polarity and phase) as mention Turbinenreiter:
Conclusion:
* make sure you are using the same mode on both devices
* deinit the spi object before you reload the script with a changed SPI mode
3. receive data from Master (Depend on the number of bytes to receive)
4. spi.deinit()
5. print(data)

paraflou
Posts: 3
Joined: Mon Apr 24, 2017 8:36 am

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by paraflou » Mon Apr 24, 2017 11:43 am

Hello there,

I am trying to fix an spi slave esp8266 with micropython.
Your discussion was very helpful.

I have a question.

Does anyone had it worked with an interrupt handler when spi is in slave mode?
I want to fix sth that raises an interrupt whenever incoming data to spi slave occur.

Any clue or idea?

thanks

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by deshipu » Mon Apr 24, 2017 7:27 pm

As far as I know, the ESP8266 port doesn't support SPI slave.

paraflou
Posts: 3
Joined: Mon Apr 24, 2017 8:36 am

Re: Consistent bitflips when using pyboard as SPI slave and other SPI weirdnesses

Post by paraflou » Tue Apr 25, 2017 11:54 am

deshipu wrote:As far as I know, the ESP8266 port doesn't support SPI slave.
If someone can guide me about the procedure i might be able to help and port spi slave to micropython!

Post Reply