doceme / py-spidev

MIT License
459 stars 205 forks source link

Reading MISO pin after SPI transaction possible? #103

Closed tomekki closed 4 years ago

tomekki commented 4 years ago

Hello, I was wondering whether py-spidev would allow to read the MISO pin outside of a SPI transaction (clock signal must not be generated when reading this pin).

I came across some SPI devices which are using the MISO pin for other things when not communicating with a microcontroller. In my current example (CS5532, page 33) the MISO pin indicates that the next ADC value is available.

I also look forward for work-around suggestions which are better as the sleeps I had to place into my code.

/Tomekki

Gadgetoid commented 4 years ago

This is far outside of the remit of py-spidev, which only interfaces with the Linux spidev driver.

Depending on your host board and available libraries you should- in theory- be able to change the pin mux to switch from spi MSIO to a standard GPIO, perform the read, and switch back. It might even be possible to simply read the input state without this change (providing whatever library you use to read it doesn't change the function of the pin)- but it's not something I've tried.

doceme commented 4 years ago

I agree with @Gadgetoid. I know there is no "official" specification for SPI, so I'm not arguing that this is in or out of "spec" for SPI, but the py-spidev project is really supposed to wrap the underlying user-space spidev driver, which doesn't support the behavior you describe.

tomekki commented 4 years ago

Thank you both for your feedback. As suggested by @Gadgetoid, I will try to see whether there is some way to change the pin mux in a timely manner on my Rasberry Pi4. What I can say is that gpiozero and py-spidev do not play along nicely. But I just started experimenting.

semininja commented 4 years ago

Consider also connecting MISO to another pin set as input, if you're able to read from non-SPI pins at the same time using another library.

tomekki commented 4 years ago

@semininja That is exactly what I did. Thanks again!

For those who got stranded here using google or so:

CS_PIN = DigitalOutputDevice(2, initial_value=True, active_high=False)
MISO_SPY_PIN = DigitalInputDevice(4)

driver.start_continious_conv(
    CS_PIN,
    ChannelSetupRegisterPointerBits.CSRP1)

# Read 100 values from ADC
values = []
CS_PIN.on()
while len(values) < 100:
    if MISO_SPY_PIN.value == 0:
        conv = driver.read_adc(None)
        values.append(conv)
CS_PIN.off()