How To Read SPI MISO as a GPIO?

Using nRF5340-DK, nRF Connect for VS Code 2026.1, ncs v3.1.1

I'm interfacing over a SPI bus to a custom ASIC that uses MISO as a sort of RTS/CTS kind of idea. While CS is active the ASIC raises the MISO line asynchronously with SCLK to indicate it has received the command. The ASIC lowers the MISO line asynchronously when it has the result ready to be read. Then the microcontroller finishes the SPI transaction and de-asserts CS.

So, my firmware needs to do this:

1. Assert CS
2. Send several bytes that form the command
3. Wait for asynchronous MISO high to low transition
4. Send dummy bytes to clock in the response
5. De-assert CS

I'm using spi4 as defined in the default device tree. CS is a GPIO controlled by my firmware (as set up in the spi_config struct).

The SPI bus is working to read/write individual registers in the typical way using this Zephyr function: spi_transceive(spec->bus, &spec->config, tx_bufs, rx_bufs);

How can I access MISO as a GPIO to accomplish step 3?

Thanks,
Dan

Parents
  • It seems to be working without suspending the spi4 device. I simply added the GPIO to my board's .overlay file and access it as a GPIO in the middle of using it as a SPI line. I haven't made my algorithm yet. But, my ASIC leaves the MISO line at whatever was last read so I can read a register with an even number in it and see that MISO as a GPIO is 0 then read a register that has an odd number in it and see that MISO as a GPIO is 1.

    Since it seems to work without doing much special I'd like to leave it at that and not do the

    pm_device_action_run(spi0_dev, PM_DEVICE_ACTION_SUSPEND);

    Do you know of a lurking problem with not suspending the SPI device?

    Here's where I make a GPIO. I can read it with gpio_pin_get_dt().

    aliases {
      spi = &spi4;
      spi-cs = &gpio1_11;
      spi-miso = &gpio1_14; // This GPIO pin is also assigned to spi4 as MISO
    ...
    };

    pins {
      compatible = "gpio-keys";
    ...
      gpio1_14: gpio1_14 {
        gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
        label = "SPI MISO as General Purpose Input";
      };
    ...
    };

    I do get a squiggly line under the "14" that says "Pin 14 of &gpio1 already assigned to &spi4 • MISO"

  • I think it is fine. The difference would be that you would have to "manually" read/poll the pin to see which state it is in, while if you set it up as an interrupt pin (after suspending the SPI), you would get an interrupt, so you could put the device in sleep mode while waiting. 

    But it is definitely an option to just read it, wait for a while if it is not ready, and read it again, if that suits your application.

    Best regards,

    Edvin

Reply
  • I think it is fine. The difference would be that you would have to "manually" read/poll the pin to see which state it is in, while if you set it up as an interrupt pin (after suspending the SPI), you would get an interrupt, so you could put the device in sleep mode while waiting. 

    But it is definitely an option to just read it, wait for a while if it is not ready, and read it again, if that suits your application.

    Best regards,

    Edvin

Children
Related