Page 1 of 1

SPI and SoftSPI on RPi pico: not 8-bit-clean?

Posted: Sat Nov 06, 2021 11:45 am
by hase
Either, I am using the class wrong our I found a bug.

I am running on a RPI Pico, MicroPython version 1.17 (current as of today).

My test code:

Code: Select all

from machine import Pin, SPI, SoftSPI
import rp2
import time

_oe = Pin(15, Pin.OUT)
_oe.high()

latch = Pin(14, Pin.OUT)
latch.low()

#s = SPI(1, baudrate=1_000_000, polarity=0, phase=0, sck=Pin(10), mosi=Pin(11), miso=Pin(12))
s = SoftSPI(baudrate=500000, polarity=0, phase=0, bits=8, firstbit=machine.SoftSPI.MSB, sck=Pin(10), mosi=Pin(11), miso=Pin(12))
s.init()
print(s)
s.write('\x7f')
s.write('\x8f')
The 0x7f comes out as expected: 8 pulses on the clock pin and the data as expected.
The 0x8f comes out as 16 clock pulses and with data I can not make sense of.

I think the SPI should simply transmit the binary data I feed in, right?

Re: SPI and SoftSPI on RPi pico: not 8-bit-clean?

Posted: Sat Nov 06, 2021 6:24 pm
by pythoncoder
hase wrote:
Sat Nov 06, 2021 11:45 am
...
I think the SPI should simply transmit the binary data I feed in, right?
Yes, it's basically a shift register. Have you tried comparing with a hardware SPI?

Re: SPI and SoftSPI on RPi pico: not 8-bit-clean?

Posted: Sat Nov 20, 2021 12:17 pm
by hase
tl;dr:
- same behaviour in SPI and SoftSPI
- problem is SPI.write() with a string argument
- SPI.write() works fine with bytearray argument
- I thinks its a bug :-)

long version:

With a bytearray() the hardware and SoftSPI work fine.
like

Code: Select all

s = SPI(1, baudrate=100000, polarity=0, phase=0, sck=Pin(10), mosi=Pin(11), miso=Pin(12)) 
wert = 129
spidata = bytearray()
spidata.append(wert & 0xff)
s.write(spidata)
I get one byte on the SPI.
I checked with a for wert in range(0,256) of course.

But when using strings as argument to SPI.write() or SoftSPI.write(), i get this weird behaviour:
- characters with byte values below 128 (i.e. highbit not set) are output fine
- characters with the high bit set are converted to some 16-bit value and sent out as two bytes on the SPI
- strings with more than one character show the behaviour for each character, i.e. values <=127 are shifted out as one, >=128 as two bytes
- I did not analyse the 16-bit-values my characters were converted to; looked nonrandom/consistent though.

The behaviour is exactly the same for SPI and SoftSPI, so it happens in the code shared between the two: the conversion from string to bytearray or suchlike.
My gut tells me that using SPI.write() with a string as argument should raise TypeError to enforce use of bytearray.

Iirc. I got the string argument to SPI.write() from some "example" code out there on the Big Evil Internet.
And that will break always, it seems.
I am thinking about people out there without Osci to debug this, the TypeError would help them.

Re: SPI and SoftSPI on RPi pico: not 8-bit-clean?

Posted: Sun Nov 21, 2021 10:29 am
by pythoncoder
I think this is to do with the way Unicode works. Bytearrays or bytes objects are the correct thing to present to interfaces.

Type checking would be useful.