This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SPI SLave MISO High until buffers set

I am working with the nRF51822 S110 and having trouble implementing SPI. In other devices' SPI protocols, MISO can be held high until the device is ready to transmit data. I want to bring MISO high and then set it low once the SPI_SLAVE_BUFFERS_SET_DONE event occurs. Is this possible?

The reason I want this behavior is simple. I will send a one byte "command" from the Master indicating I want to read my buffer. The nRF51822 SPI Slave will respond with the number of bytes that can be read, and then the Master will force clock those bytes into its buffer. I believe I am having problems with synchronicity in the system.

I have no way of knowing when the nRF is ready to transmit its data and thus have to resort to arbitrary delays in my SPI Master firmware. I have no GPIOs tied between the two MCUs that could be used for indicating ready data.

I noticed the below SPI Slave code and was hopeful that one of the configurations would solve my issue, but none are what I need. Is my only solution to try and disable the SPI Slave module to manually set the MISO line high and then reenable SPI once the buffers are set? Am I overcomplicating this and is there a simpler approach. I am definitely open to other, better ways of doing this and any feedback is appreciated.

Thanks.

/* Bits 10..8 : Drive configuration. */
#define GPIO_PIN_CNF_DRIVE_Pos (8UL) /*!< Position of DRIVE field. */
#define GPIO_PIN_CNF_DRIVE_Msk (0x7UL << GPIO_PIN_CNF_DRIVE_Pos) /*!< Bit mask of DRIVE field. */
#define GPIO_PIN_CNF_DRIVE_S0S1 (0x00UL) /*!< Standard '0', Standard '1'. */
#define GPIO_PIN_CNF_DRIVE_H0S1 (0x01UL) /*!< High '0', Standard '1'. */
#define GPIO_PIN_CNF_DRIVE_S0H1 (0x02UL) /*!< Standard '0', High '1'. */
#define GPIO_PIN_CNF_DRIVE_H0H1 (0x03UL) /*!< High '0', High '1'. */
#define GPIO_PIN_CNF_DRIVE_D0S1 (0x04UL) /*!< Disconnected '0', Standard '1'. */
#define GPIO_PIN_CNF_DRIVE_D0H1 (0x05UL) /*!< Disconnected '0', High '1'. */
#define GPIO_PIN_CNF_DRIVE_S0D1 (0x06UL) /*!< Standard '0', Disconnected '1'. */
#define GPIO_PIN_CNF_DRIVE_H0D1 (0x07UL) /*!< High '0', Disconnected '1'. */

void spi_slave_set_drive_config(uint32_t alternate_config)
{
    m_drive_config = alternate_config;
    return;
}


uint32_t spi_slave_init(const spi_slave_config_t * p_spi_slave_config){
    uint32_t err_code;
    uint32_t spi_mode_mask;
    
    if (p_spi_slave_config == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Configure the SPI pins for input.
    NRF_GPIO->PIN_CNF[p_spi_slave_config->pin_miso] = 
        (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) |
        (m_drive_config << GPIO_PIN_CNF_DRIVE_Pos)              |
        (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)   |
        (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)  |
        (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
  • Hi

    Usually we would recommend to add the fifth line, which the SPI slave uses to signal the master that it is ready to send data, but I hear that no extra line is available in your case.

    • I guess you could manually write 0xFFFFFFFF to the PSELMISO register to momentarily unconfigure the MISO pin
    • Manually set the MISO pin high when SPIS has data to send
    • When the master sets the CSN line low to start a SPI transaction, reconfigure the MISO pin by writing the the PSELMISO
    • Make sure the master will wait for an adequate time so the nRF51822 has time to reconfigure the PSELMISO before SPI master will start to clock out data.

    The use of MISO line would only work if there are no other SPI slaves on the SPI bus.

Related