← index #5068Issue #4660
Related · high · value 1.251
QUERY · ISSUE

A SERVERE BUG OF SPI-SLAVE IN PYB

openby rychongopened 2019-09-04updated 2019-09-10
port-stm32

Hi Everybody:

    There is a servere problem in pyb.SPI module, this problem occur when using the SPI.SLAVE mode:
    Problem one:
    1. SPI Master send 8 bytes buf = b'12345678' to pyboard which is working in SPI.SLAVE.
    2. If we use SPI Slave receive 4 bytes, then we receive b'1234', the SPI Slave is in working order. However, if you send the 8 bytes and receive 4 bytes again, you will receive b'5123'. Try again, you will receive b'4123', then it will always be b'4123'.
    3. This problem can be solved by two ways: A. keep the number of receive bytes equal to the send bytes. B. Use spi.init(****) before receive, and spi.deinit() after receive.

   The Reason of This Bug:
    I guess SPI Slave receive an extra bytes and and storage all received bytes in hardward register, for instance, if you use SPI Slave receive 4 bytes at the first time, it will receive 4 bytes (b'1234') and the extra bytes is b'5', it return first 4 bytes(b'1234') to you. Repeat this process again, it will still receive b'1234' but it return the extra bytes b'5'+b'123', thus it return you b'5123'(the last bytes b'4' will be leave in the extra bytes). Repeat this process again, it will receive b'1234' and return the extra bytes b'4' + b'123', the last bytes b'4' will be storage in the extra bytes. Repeat this process again, you still receive b'1234', and if you change the send bytes to b'abcdefgh', you will receive b'4abc', then to b'dabc'. 

    Another problem is that, you can't use spi.recv with slave mode in the callback function of interrupt, it can't receive any information and collapse.
CANDIDATE · ISSUE

SPI slave is effected by MOSI traffic even though S/S is low

openby rhubarbdogopened 2019-03-31updated 2019-04-04
port-stm32

I have this pybord program

import pyb

spi = pyb.SPI(2, pyb.SPI.SLAVE, polarity = 0, phase = 0, bits = 8)

def slave_select(line):
    pyb.LED(4).on()
    try:
        spi.send('Cabbage', timeout = 100)
    except OSError:
        pass
    pyb.delay(500)
    pyb.LED(4).off()
    
pyb.ExtInt(pyb.Pin('Y5'), pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_DOWN,\
           slave_select)

while True:
    pyb.delay(1000)

and this microbit program as SPI Master

from microbit import *

baud = 9600

pin16.write_digital(0)
spi.init(baudrate = baud, bits = 8, mode = 0)

def recv_message(nbytes = 128):
    pin16.write_digital(1)
    sleep(1)
    text = spi.read(nbytes)
    pin16.write_digital(0)

    return text

text = recv_message(7)
print(text)

spi.write('Hello')
print('sent hello')

text = recv_message(7)
print(text)

I get this output

b'Cabbage'
sent hello
b'eeeeeee'

pyboard - soft reset & microbit soft reset

b'CCabbag'
sent hello
b'eeeeeee'

pyboard hard reset & microbit soft reset

b'Cabbage'
sent hello
b'eeeeeee'

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied