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

NRF51822 spi slave and receiving multiple bytes

 Hello,

I'm trying to interface msp430fr5994  to nrf51822 as spi slave with soft device 110 and SDK v10. The master (msp40) sends 20 bytes to the slave (nrf51). The issue is that the salve (nrf51) is not receiving anything when I check "NRF_DRV_SPIS_XFER_DONE".  I set up the master spi clock to 1MHz, spi mode, and the bit order to be the same on both (master and slave).  Also, I I at the beginning of the transmission, I used 7500 ns delay after driving the CS low and then starting the *** in the master. At the end of the transmission, I stoped the master clock and delay for 2400ns before driving CS high.   I checked spi_init on the nrf and it seems to be set properly. I'm really struggling to get it the spi to work. what did I miss?

Here is nrf code:

#define TX_BUF_SIZE   20u              /**< SPI TX buffer size. */
#define RX_BUF_SIZE   TX_BUF_SIZE       /**< SPI RX buffer size. */



static volatile bool receiving_completed = false; /**< A flag to inform about completed receiving. */



static nrf_drv_spis_t const m_spis = NRF_DRV_SPIS_INSTANCE(SPIS_INSTANCE_NUMBER);

static uint8_t m_tx_buf[TX_BUF_SIZE];   /**< SPI TX buffer. */
static uint8_t m_rx_buf[RX_BUF_SIZE];   /**< SPI RX buffer. */



/**@brief Function for application main entry.
 */
int main(void)
{

      uint32_t err_code;

    err_code = spi_slave_init();
    APP_ERROR_CHECK(err_code);
   


    // Enter main loop.
    while(1)
    {
       
        if (receiving_completed)
        {
            
            receiving_completed =false;
           
            
            

            //Set buffers to recevied new data
            err_code = nrf_drv_spis_buffers_set(&m_spis, m_tx_buf, sizeof(m_tx_buf), m_rx_buf, sizeof(m_rx_buf));
            APP_ERROR_CHECK(err_code);
        }
    }
}

uint32_t spi_slave_init(void)
{
    uint32_t              err_code;
    nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG(SPIS_INSTANCE_NUMBER);

    spis_config.miso_pin        = SPIS_MISO_PIN;
    spis_config.mosi_pin        = SPIS_MOSI_PIN;
    spis_config.sck_pin         = SPIS_SCLK_PIN;
    spis_config.csn_pin         = SPIS_CS_PIN;
    spis_config.mode            = NRF_DRV_SPIS_MODE_0;
    /*
    NRF_DRV_SPIS_MODE_0   -----> (CPOL = 0, CPHA = 0)
    NRF_DRV_SPIS_MODE_1   -----> (CPOL = 0, CPHA = 1)
    NRF_DRV_SPIS_MODE_2   -----> (CPOL = 1, CPHA = 0)
    NRF_DRV_SPIS_MODE_3   -----> (CPOL = 1, CPHA = 1)
    */
    spis_config.bit_order       = NRF_DRV_SPIS_BIT_ORDER_MSB_FIRST;
    

    err_code = nrf_drv_spis_init(&m_spis, &spis_config, spi_slave_event_handle);
    APP_ERROR_CHECK(err_code);
      //Initialize buffers.
    spi_slave_buffers_init(m_tx_buf, m_rx_buf, (uint16_t)TX_BUF_SIZE);

    //Set buffers.
    err_code = nrf_drv_spis_buffers_set(&m_spis, m_tx_buf, sizeof(m_tx_buf), m_rx_buf, sizeof(m_rx_buf));
    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

static void spi_slave_event_handle(nrf_drv_spis_event_t event)
{
 

    if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
    {


        //Check if buffer size is the same as amount of received data.
        APP_ERROR_CHECK_BOOL(event.rx_amount == RX_BUF_SIZE);
       
        if (event.rx_amount == RX_BUF_SIZE)
        {
          // Inform application that receiving is completed.
          receiving_completed = true;
        }

    }

   


}

  • Yes, the master is waiting for a response from the slave after sending each byte. The master is transmitting at 1 MHz. 

    I don't know what could cause the pause in the SCK tickets after transmission the first byte. could it be caused by waiting for a response from the slave?

  • aalsubhi said:
    Yes, the master is waiting for a response from the slave after sending each byte. The master is transmitting at 1 MHz. 

    Thank you for clarifying. How exactly is this implemented?
    SPI is full duplex, so a byte is transferred simultaneously from both the slave and the master. Is the master checking that the byte received during the previous transfer matches some requirements?

    aalsubhi said:
    I don't know what could cause the pause in the SCK tickets after transmission the first byte. could it be caused by waiting for a response from the slave?

    Yes, I would think so - depending on how this waiting is implemented on the master side, and that you have made sure that the master meets the timing requirements specified on page 37 in the Product specification: Table 45 SPIS timing parameters.

    Best regards,
    Karl

  • No, the master is not checking if the received byte meets some requirements.  The master is putting a byte to send  into tx buffer and then wait to recive a byte from the slave.

     //send a byte
     UCA1TXBUF = txBuffer[i];
      /* Wait for a rx character? */
      while (!(UCA1IFG & UCRXIFG)) // UCB1 flage
        ;
    .   

  • I am not sure about what the code snippet above does, since I do not know the contents of those buffers.
    I assume that UCRXIFG is the SPI RX buffer. What is then the UCA1IFG buffer? Your comment states " UCB1 flage", is this correct? There seems to be a mismatch between the UCA1IFG and UCB1 name, at least.
    If my assumptions are correct then it seems to me that the while loop will keep going until UCA1IFG & UCRXIFG evaluates to true, which will be the case if both have a set bit in the same position. Whether this will happen is all dependent on the contents of the UCA1IFG buffer.

    Best regards,
    Karl

  • the comment "UCB1 flag" is a mismatch I'm using the UCA1 model for spi. 

    yes "UCRXIFG" is  SPI received buffer flag which set to 1 when the master received a complete byte from the slave.  "UCA1IFG" is the flag for both RX and TX. It will be set to 1 either when the TX buffer is empty (transmission is completed) or RX received a complete byte.

    the while loop will keep going until UCA1IFG & UCRXIFG evaluates to true

    yes, that's right

Related