I was having some trouble with using the camera as an SPI peripheral (slave), specifically with the rpc library, but I think the issue is more with the SPI bus, in general. The problem manifested in odd behaviour with the SS pin (P3): after the first time it went LOW, the pin would no longer have any effect on the SPI transactions. For example, after the first transaction, I could connect the SS pin to 3V3 and SPI would more or less work(!) (but I suspect the ‘less’ part is due to the SS pin not working right, which leads to frame errors).
I traced the issue to SPI.deinit(). When that function is called, the pin mode for P3 is changed to an alternate function and it always reads LOW – even if connected to 3V3. So when testing the SS pin for the start of a transaction, it always returns LOW, so framing errors can occur.
I ran a short code to demonstrate:
import pyb
pin = pyb.Pin("P3", mode = pyb.Pin.IN, pull = pyb.Pin.PULL_UP)
spi = pyb.SPI(2)
print(pin.mode())
print(pin.af())
print(pin.af_list())
print(pin.value())
spi.init(pyb.SPI.SLAVE, polarity=0, phase=0)
print('init')
print(pin.mode())
print(pin.af())
print(pin.af_list())
print(pin.value())
spi.deinit()
print('deinit')
print(pin.mode())
print(pin.af())
print(pin.af_list())
print(pin.value())
When you run this code, the pin mode changes to 3 after deinit() is called, which corresponds to an alternate function, in this case AF = 0 --> Pin.AF1_TIM1.
I get a lost in the library files, and I’m struggling to figure out where exactly deinit() lives – I’d be curious to see what that function does and try to fix it.
The full output of the above code is:
0
0
[Pin.AF1_TIM1, Pin.AF5_SPI2, Pin.AF7_USART3, Pin.AF9_CAN2]
1
init
1
0
[Pin.AF1_TIM1, Pin.AF5_SPI2, Pin.AF7_USART3, Pin.AF9_CAN2]
1
deinit
3 ## <------ pin mode has changed!
0
[Pin.AF1_TIM1, Pin.AF5_SPI2, Pin.AF7_USART3, Pin.AF9_CAN2]
0 ## <------ always reads LOW!