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

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
User avatar
hase
Posts: 5
Joined: Thu Jan 11, 2018 1:24 pm
Location: Berlin, Germany, Europe, Earth
Contact:

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

Post by hase » Sat Nov 06, 2021 11:45 am

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?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

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

Post by pythoncoder » Sat Nov 06, 2021 6:24 pm

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?
Peter Hinch
Index to my micropython libraries.

User avatar
hase
Posts: 5
Joined: Thu Jan 11, 2018 1:24 pm
Location: Berlin, Germany, Europe, Earth
Contact:

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

Post by hase » Sat Nov 20, 2021 12:17 pm

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.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

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

Post by pythoncoder » Sun Nov 21, 2021 10:29 am

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.
Peter Hinch
Index to my micropython libraries.

Post Reply