SPI py2py Master and Slave comm problem

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Adixylian
Posts: 13
Joined: Thu Jan 21, 2016 7:21 pm

SPI py2py Master and Slave comm problem

Post by Adixylian » Wed Sep 27, 2017 3:33 pm

So I got two pyboards MicroPython v1.9.1-196-g45645043 on 2017-07-29; PYBv1.1 with STM32F405RG communicating with each other via SPI
One pyboard acts as a Slave, the other one as a master

The problem is, the communication works for some short period of time and then something breaks and the comms go nuts.

Master code:
`py2=pyb.SPI(2, pyb.SPI.MASTER, 500000, polarity=0, phase=1, bits=8, firstbit=pyb.SPI.MSB, ti=False, crc=0x7)

ss=pyb.Pin('Y5', pyb.Pin.OUT_PP)
ss.high()

def py2py():
ss.low()
pyb.delay(5)
data=py2.send_recv(b'\x00\xaa\x00\xbb\x00\xaa\x00\xbb\x00\xaa\x00\xbb\x00\xaa\x00\xbb\x00\xaa\x00\xbb\x00\xaa\x00\xbb')
ss.high()
`

Slave code:
`py1 = pyb.SPI(2, pyb.SPI.SLAVE, 500000, polarity=0, phase=1, bits=8, firstbit=pyb.SPI.MSB, ti=False, crc=0x7)
data=bytearray(24)
ss=pyb.Pin('Y5', pyb.Pin.IN)

def f(a):
py1.send_recv(data)

inter=pyb.ExtInt(ss, pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_DOWN, f)
`
As you can see, the Slave pyboard uses an interrupt. So, when Master calls the function py2py(), he triggers the interrupt on the Slave who then does what it does, it sends the data.

And it works for some short period of time, then it just breaks and the Master starts receiving weird buffers. Or, if I also have comms via i2c(1) on Master, the SPI comm completely breaks and Master never receives anything --> data is data=b'\x00'*24

I'm not profesionallist for communications and it's still a new thing for me, so if somebody can help me, please do :D

What I did try is using only py2.recv and py1.send, got the same thing. And, it doesn't work without the pyb.delay() in py2py() func.

Note, the pyboards both have other comms via i2c and the other SPI pins (all the comms work perfect), but they do not use interrupts. The only interrupt that is used in the whole programs is the one that is written here.

And I know that the SPI comms, when pyboard acts as Master, works completely fine. It has been tested on one of my sensors and it works all the time as it should :D

Help me please

ajie_dirgantara
Posts: 73
Joined: Fri Sep 02, 2016 9:26 am

Re: SPI py2py Master and Slave comm problem

Post by ajie_dirgantara » Mon Oct 09, 2017 6:38 am

Some problem with pyboard SPI could be solved by using spi.deinit() here and there. In my case, I do deinit() everytime I need to read SPI data, and re-initialize everytime I do SPI write.

User avatar
pythoncoder
Posts: 1963
Joined: Fri Jul 18, 2014 8:01 am

Re: SPI py2py Master and Slave comm problem

Post by pythoncoder » Tue Oct 10, 2017 8:27 am

I wonder if the problem is interrupt latency. I'd try a much lower baudrate to see if that has any effect.
Peter Hinch

Adixylian
Posts: 13
Joined: Thu Jan 21, 2016 7:21 pm

Re: SPI py2py Master and Slave comm problem

Post by Adixylian » Thu Oct 12, 2017 5:21 pm

I tried many different baudrates, didn't have any effect.

Without interrupt it works every cca 10th time.
All I did is just to add if statement in the end of the Slave main loop
Something like -->
...
if ss==0:
spi.write(package,timeout=XY)
else:
print('no comms')
...

Also, I added the delay in the master and timeout on the slave , so that the slave always waits for the master

I tested the comms for few hours (I think it was on for some 4 hours), and the comms had the same "scheme" as on the beginning.
Well that is some progress because the comms didn't die after some time. But still, only every approx 10th time SPI comm is succesfull

I'm going to try adding deinit() and init() and see what will happen

Also, initializing UART comms while SPI is also init adds some problems, but I don't know why...

EDIT: I tried deinit() and because of unknown reasons, it works... SPI communication is stable and has 100% succesfull comms.

But, that is without the interrupt.
With interrupt comms are awful. But like this, I have to put delay(x), where x is the time that is needed for slave to finish it's main loop. That makes SPI comms not so helpful because the time that the delay adds is just too big...

User avatar
pythoncoder
Posts: 1963
Joined: Fri Jul 18, 2014 8:01 am

Re: SPI py2py Master and Slave comm problem

Post by pythoncoder » Fri Oct 13, 2017 8:08 am

You mention UARTs. In my opinion UART communications are better supported and more reliable than SPI slave mode. Communication is asynchronous and hardware flow control is supported, so it can be pretty bomb proof. If I wanted to communicate between MicroPython targets I would use UARTs if at all possible.

As you've discovered MicroPython lacks an asynchronous buffered SPI slave mode. That said, I'm not sure why your interrupt driven code is failing when run at low baudrates.
Peter Hinch

Post Reply