SPI communication problem. OpenMV H7

Hello!
I’m trying to send data from OpenMV H7 to stm32 controller. OpenMV acts like slave and it is absolutely crusial. I’m using hardware SPI. First package after SPI initialization sends correctly, but than SPI won’t send anything, so I need to reinitialize it every main cycle iteration.
Is it possible to send several packages without reinitializing SPI? How can I do it?
I don’t want to use any additional libraries.

Code that I tried at first (sends only one package):

import sensor, image, time, pyb
from pyb import SPI

spi = SPI(2, SPI.SLAVE, polarity=0, phase=0)
buf = bytearray(10)

def crc8(data, len):
    crc = 0xFF
    j = 0
    for i in range(0, len):
        crc = crc ^ data[i];
        for j in range(0, 8):
            if (crc & 0x80):
                crc = (crc << 1) ^ 0x31
            else:
             crc = crc << 1
    return crc


while(True):
    clock.tick()
    img = sensor.snapshot()

    buf[0] = 0xBB
    buf[1] = 7
    buf[2] = 1
    buf[3] = 2
    buf[4] = 3
    buf[5] = 4
    buf[6] = 5
    buf[7] = 6
    buf[8] = 7
    buf[9] = crc8(buf, 9)
    spi.write(buf)

Code with reinitializing SPI every cycle (works somehow):

import sensor, image, time, pyb
from pyb import SPI

buf = bytearray(10)

def crc8(data, len):
    crc = 0xFF
    j = 0
    for i in range(0, len):
        crc = crc ^ data[i];
        for j in range(0, 8):
            if (crc & 0x80):
                crc = (crc << 1) ^ 0x31
            else:
             crc = crc << 1
    return crc


while(True):
    clock.tick()
    img = sensor.snapshot()

    spi = SPI(2, SPI.SLAVE, polarity=0, phase=0)
    buf[0] = 0xBB
    buf[1] = 7
    buf[2] = 1
    buf[3] = 2
    buf[4] = 3
    buf[5] = 4
    buf[6] = 5
    buf[7] = 6
    buf[8] = 7
    buf[9] = crc8(buf, 9)
    spi.write(buf)
    spi.deinit()

Use our RPC library: rpc — rpc library — MicroPython 1.15 documentation

We literally sat down and wrote a SUPER robust comms library for the camera that works over SPI, UART, I2C, USB, WIFI, CAN, etc.

Please use it.

Doing comms in general is very hard. If you don’t know what you are doing so many things will trip you up.

Hello!
I don’t want to use any additional libraries because I need pretty simple form of communication. I believe I can achieve this using only basic functional. Also with RPC I’ll need to write whole library for stm32 by myself wich will take only more time.
Can you explain what might be the problem and how could I solve it?

See how the RPC library handles SPI communication. You need to sync the two board which requires the use of waiting on the CS pin to go low.

In your current code there’s no byte alignment. So, what you read could be anything shifted in time.

Given you don’t want to use the RPC library then you are on your own. We wrote the library after endless people trying to get drivers for comms working and having endless issues setting up the transaction because it is not easy. It’s not even a MicroPython or OpenMV thing. In general getting two processors to sync over SPI is hard.

The RPC library in our firmware repo under examples/libraries/RPC.py shows how to read/write bytes between SPI master and slaves with frame alignment.

Hello Kwagyeman,

I am confused on how to use rpc between a Raspberry Pi and OpenMV camera. Am suppose to install rpc.py on the Pi? It causes problems when I do (umachine, omv not found)

There’s a separate version of the library that runs in the desktop. See the tools directory in the main GitHub repo.

However, I recommend only using the RPC library for UART/SPI/CAN/I2C comms. It’s depends on a tight synchronization between both devices which application processors can’t necessarily meet.

I recommend using the MicroPython pyboard.py script to control the camera or our specialized debug controller scripts in our tools directory. You can send scripts to the camera to run via these scripts and then get print results back.

Are you talking about here:

I need to use the SPI interface and I don’t see any functionality for it.

Hi, you’ll need to create a SPI interface. Per the documentation this isn’t particularly hard to do. You just have to implement a Python RPS master or slave class.

You can find an example for the UART via pyserial already in that file.

i have something working using pigpio python library.

code snippet to use updated rpc.py lib with SPI (only rpc_spi_master works)
rpc_image_xfer_V3.py (5.2 KB)
rpc (1).py (38.6 KB)

1 Like

Thanks for sharing!