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;
        }

    }

   


}

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

     Thank you for clearing that up.

    aalsubhi said:
    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.

    Is it set to exactly 1? You are doing a bit-wise AND operation ( & ), so in the case that they both do not have 1 in the same bit position, then the check will fail.

    From the logic analyzer screenshot you shared earlier, I would again say that it seems to be the master that is initiating the waiting.
    The slave seems to be replying as expected ( and on time ) for every byte sent by the master. So, I think we will have to keep looking into the master side of this, to find the root cause of this behavior.

    Best regards,
    Karl

  • Thanks, Karl for your help.

    The issue is solved by changing the SPI mode for the master. The salve (nrf51882 ) is using spi mode 0 (CPOL = 0, CPHA = 0) . So, I tried to set up my master (msp430fr5994) to use the same spi mode but did not work.

    Changing the master spi mode to (CPOL = 0, CPHA = 1) and keeping the slave mode as it is (CPOL = 0, CPHA = 0) , solved the problem and I was able to send 20 bytes!

  • aalsubhi said:
    Thanks, Karl for your help.

    No problem at all, I am happy to help!

    aalsubhi said:
    Changing the master spi mode to (CPOL = 0, CPHA = 1) and keeping the slave mode as it is (CPOL = 0, CPHA = 0) , solved the problem and I was able to send 20 bytes!

    I am happy to hear that you were able to resolve your issue!
    It seems very strange to me that this is working with a mismatch in SPI modes.. The modes dictate how the devices should read the different signal level shifts, and a mismatch here should lead to incorrect communication.
    Are you certain that the SPI master in fact does not now match the slave - and this is why it is now working as expected? I suspect this might be the case.

    Best regards,
    Karl

Related