SPI Pins for the Omega2

There does not appear to be much clarity surrounding the SPI and the interfacing. The Pinout Diagram lists the GPIO pins as

CS1 - GPIO6
SCLK - GPIO7
MOSI - GPIO8
MISO - GPIO9

The SPI default pins in both the Python and C modules are listed as

CS/SS 7
SCK 6
MOSI 18
MISO 1

The example code makes

spi.cs = 20
spi.sck = 19

and I presume leaves the MOSI and MISO as default (18 ? 1 ?)

So I am left scratching my head as to what is what? Who has managed to connect successfully with the SPI? Next, I think I am going to have to break out the datasheets and the Oscilloscope, but I'd rather not :(

I am also guessing that there is no native kernel SPI interface and it is all bit-banging only? Yay!!!

This worked for me.
Well, at least until some point. It allows me to write 16 bytes to the SPI bus, but if I try to send more, it doesn't work anymore. And if I try spi.writeBytes(position, bytes_list) (in python), it just inserts the byte position at the beginning of bytes_list, and has the same 16 bytes limitation.

@Brice-Parent What did you install to make it work on the omega2?
I followed the documentation but I get an error while registering the spi device : "Failed to find spi-gpio-custom. Maybe it is a built in module ?"

@Brice-Parent What did you install to make it work on the omega2?
I followed the documentation but I get an error while registering the spi device : "Failed to find spi-gpio-custom. Maybe it is a built in module ?"

spi-gpio-custom is software-based bit-banged SPI. The hardware-SPI on GPIOs 6-9 should already be enabled by default. Just do ls -l /dev/spi* and the SPI-bus should show up.

I don't remember having manually installed anything other that pyOnionSpi and maybe python-light (and I'm not even sure for those two...), and I particularly don't remember having installed a specific version of spi-tools like I see here... But anyway, that"s what makes it partially work here !

Edit : But it looks like you just reversed the arguments when creating the OnionSpi object (use 1, 32766 instead of 32766, 1).

I would like to report two issues with using SPI in Python on the Omega2. The first is that the transmit and receive buffers are only 16 bytes. There should be a mechanism in the driver that allows for DMA or interrupts to allow the use of a list longer than 16 bytes. The reason I say this is that the best time between SPI bursts is about 150uS. In other words, the following code;
spi.write([[0xAA, 0x55, 0xAA])
spi.write([[0xAA, 0x55, 0xAA])

will result in about 150uS between SPI transmissions. If the SPI driver would recognize that the list passed in is longer than the built-in queues and then use an interrupt or DMA to keep the queue full until the list was exhausted then a list with several hundred bytes could be sent as one continuous transmission. This would facilitate using the SPI device to drive strings of NeoPixels. As it stands now, only a string of one NeoPixel can be driven by the SPI device. This would also help in using the SPI to communicate with an SPI based tft LCD or any device that requires more than 16 bytes in a continuous burst.

The second issue is that the first byte transmitted always sets the most significant bit to zero (when MSB first). So sending 0xAA results in 0x2A being sent. Not good. This only happens to the first byte of each burst. The only thing I changed from default was the bitrate.

Finally, a complaint that seems to be echoed everywhere in the world of the Omega2. That is the lack of documentation. What is available has mistakes, references the Omega or leaves a lot of information out.

@James-Behrens I've open a ticket 12 days ago about that, without the 150uS delay that I didn't know about (I don't have a scope), but so far no answer from the team. I'll link it to your post for more info.

Also, if you find a workaround to be able to use more than 16 bytes without having to wait for a software update, like a software SPI or another library, please tell me about it.

... and the more I look at this, I think this may not be a bug. The MT7688 hardware can handle only so many bytes per hardware transfer, but it looks like the Linux SPI permits a transfer to be broken into an array of transfers that are processed with a single Chip Select - chaining them together. So it may be some additional work is required in the C and Python libs.

So - about the leading bit of 'address' (which is not a pure SPI construct - there's no requirement for an address to be the first byte of a transfer, or even for transfers to be in bytes). On a hunch, I tried values of address with the top two bits being '10' (example, 0xaa, 0xb2, 0x88, etc.) and values of address with the top two bits being '11' (ex. 0xc0, 0xff, etc.) and found that anything with '10' in the top two bits loses the MSB (transfers it as '0') and anything with '11' in the top two bits transfers it correctly. My test hardware SPI slave is an Atmel ATmega1284P , with the clock phase/polarity set to 0 (which matches the default settings in the Linux driver) (any other settings in the AVR SPI slave corrupt the data). I tried reducing the clock rate and adding a delay but never helped.

So I'm guessing there's a timing/phase issue there; I'll have to get the oscilloscope out and have a look.

@James-Behrens as you probably have seen in my messages; the Omega Python library needs to break up the SPI transfer into 16-byte chunks and chain them together in the SPI_IOC_MESSAGE() call - I think that'll solve the transfer limitation. The loss of the MSB in the first byte (aka address) happens when the top two bits are '10' and not when they're '11' and that's apparently something in the MT7688 SPI driver and/or timing of the SPI slave.

Upper trace is MOSI, lower trace is CLK, aligned to the vertical grid (10uS). You see the CLK leading-edge transitions are in the middle of the data - it all looks right except the first '1' bit is missing (far left, the first clock transition occurs while MOSI is 0).

This is "spi-tool write 0xca 0x11":

So here, MOSI starts with an abbreviated '1' bit, only about 1/2 as long as it should be, though the rest of the data timing is correct.

There are two problems:

list itemWhen the first two bits are '10', the leading '1' is completely not sent by the SPI peripheral.

list itemWhen the first two bits are '11', the leading '1' is about half as long as it should be.

This makes me think something is amiss with the SPI peripheral - perhaps some timing in the MT7621 SPI driver?