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

SPI Slave cannot receive data, sending data to master normally

Hi all,

I am using a custom board with NRF 52840 with SDK15.2 as slave and STM as master. I cannot receive right data, but the data to STM is right.

void spis_incoming_msg_packet_handling(uint8_t *tmp, int size) {
    for(int i = 0 ;i< size;i++)
          m_tx_buf[i+1] = tmp[i];
          tx_size = size;
    if(tmp[0]==0xAA){
     if(tmp[1] == 0x01 ||tmp[1] == 0x02){
       int tmp_size = (int) tmp[2];
       uint16_t tmpLength = (uint16_t)tmp_size;
       if(tmp[tmp_size+3] == 0xBB){
        for(int i = 0 ;i< tmp_size;i++){
          tx_data[i]=tmp[i+2];
          }
          m_length=size;
          if(isConnect)
            ble_nus_data_send(&m_nus, tx_data, &tmpLength, m_conn_handle);
             }
        }
    }
}
void spis_event_handler(nrf_drv_spis_event_t event) {
  if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) {
    spis_xfer_done = true;
    printf("enter handler");
    spis_incoming_msg_packet_handling(m_rx_buf, 100);
  }
}

#if defined(SPI_MODULE)
void switchToSPIS() {

  printf("activating SPIS");
    nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;

    //spis_config.csn_pullup = NRF_GPIO_PIN_PULLUP; // Test 01
    //spis_config.csn_pullup = NRF_GPIO_PIN_NOPULL; // Test 02
    //spis_config.csn_pullup = NRF_GPIO_PIN_PULLDOWN; // Test 03

    spis_config.csn_pin = 4;  //29 //7  APP_SPIS_CS_PIN
    spis_config.miso_pin = 8; //28 // 8  APP_SPIS_MISO_PIN
    spis_config.mosi_pin = NRF_GPIO_PIN_MAP(1,9); //4 //  9  APP_SPIS_MOSI_PIN
    spis_config.sck_pin = 6;  //3 // 10 APP_SPIS_SCK_PIN
    nrf_drv_spis_init(&spis, &spis_config, spis_event_handler);

}

The above are the setup, and the following are the part that prepare buffer.

m_tx_buf[0] = 0xAA;
 m_tx_buf[tx_size-1]=0xCC;
nrf_drv_spis_buffers_set(&spis, m_tx_buf, tx_size, m_rx_buf, 100);

What I got from STM is AAFFFFF...00000CC, may I know what is the problem? As the code works on nrf 52832, just changing the pin. I am not sure if any config is set wrong.

Best regards,

Marco Lai

  • Hi,

    I'm not sure if I understand what you are asking about. What is tx_size set to? If you set the first and last byte of the m_tx_buf array,I would expect you to get something like "AAFFFFF...00000CC", depending on what is in the buffer already.

    • What are you expecting to receive from the STM?
    • Have you checked the SPI lines with a logic analyzer, to see if the output is the same that you see in the application?
    • Are you using the same SPI Mode configuration on both sides?
    • What frequency is the SPI running at?

    You can also possibly try different GPIOs and/or pull, and drive strength configurations for the pins.

    Best regards,
    Jørgen

  • Hi Marco, How are you doing?

    I am facing the similar issue like you. Were you able to resolve yours?

    Below is my code. I am sending 128 bytes of the data and receiving 128 back. I checked from the oscilloscope. Master is sending right data at 1 MHz frequency. But the slave is not receiving. Event_Handler is getting called successfully but the rx buffer is 0 always. Below is my code. It would be really nice if you can help me here.

    #include "sdk_config.h"
    #include "nrf_drv_spis.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>

    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"

    #define SPIIF_HW_SYNC_START (0xAABBu) 
    #define SPIIF_HW_SYNC_END (0x55CCu)

    #define SPI_BLOCK_SIZE (118u)

    typedef struct
    {
    uint8_t dummy; 
    uint8_t sequenceCnt;
    uint16_t dataLen;
    uint16_t syncStart;
    uint8_t dataBuffer[SPI_BLOCK_SIZE]; 
    uint16_t syncEnd
    uint16_t dataCrc16; 
    } SPIIF_SPI_PACKET_T;


    SPIIF_SPI_PACKET_T gSpiIfSpiTx __attribute__((aligned(32)));

    #define SPIS_INSTANCE 1 /**< SPIS instance index. */
    static const nrf_drv_spis_t spis = NRF_DRV_SPIS_INSTANCE(SPIS_INSTANCE);/**< SPIS instance. */

    static uint8_t m_tx_buf[sizeof(SPIIF_SPI_PACKET_T)]; /**< TX buffer. */
    static uint8_t m_rx_buf[sizeof(SPIIF_SPI_PACKET_T)]; /**< RX buffer. */
    static const uint8_t m_length = sizeof(SPIIF_SPI_PACKET_T); /**< Transfer length. */

    static volatile bool spis_xfer_done; /**< Flag used to indicate that SPIS instance completed the transfer. */

    /**
    * @brief SPIS user event handler.
    *
    * @param event
    */
    void spis_event_handler(nrf_drv_spis_event_t event)
    {
    if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
    {
    spis_xfer_done = true;
    }
    }

    int main(void)
    {
    // Enable the constant latency sub power mode to minimize the time it takes
    // for the SPIS peripheral to become active after the CSN line is asserted
    // (when the CPU is in sleep mode).
    //NRF_POWER->TASKS_CONSTLAT = 1;

    nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;

    spis_config.csn_pin = APP_SPIS_CS_PIN;
    spis_config.miso_pin = APP_SPIS_MISO_PIN;
    spis_config.mosi_pin = APP_SPIS_MOSI_PIN;
    spis_config.sck_pin = APP_SPIS_SCK_PIN;

    spis_config.mode = NRF_SPIS_MODE_0;
    spis_config.bit_order = NRF_SPIS_BIT_ORDER_MSB_FIRST;
    spis_config.csn_pullup = NRFX_SPIS_DEFAULT_CSN_PULLUP;
    spis_config.miso_drive = NRFX_SPIS_DEFAULT_MISO_DRIVE;
    spis_config.def = NRFX_SPIS_DEFAULT_DEF;
    spis_config.orc = NRFX_SPIS_DEFAULT_ORC;
    spis_config.irq_priority = NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY;

    gSpiIfSpiTx.dummy = 0u;
    gSpiIfSpiTx.dataLen = 0u;
    gSpiIfSpiTx.sequenceCnt = 1u;
    gSpiIfSpiTx.syncEnd = SPIIF_HW_SYNC_END;
    gSpiIfSpiTx.syncStart = SPIIF_HW_SYNC_START;
    gSpiIfSpiTx.dataCrc16 = 0u;

    for (uint8_t i = 0; i<SPI_BLOCK_SIZE; i++)
    {
    gSpiIfSpiTx.dataBuffer[i] = 0xAA;
    }

    nrf_drv_spis_init(&spis, &spis_config, spis_event_handler);

    while (1)
    {
    memcpy(m_tx_buf, &gSpiIfSpiTx, m_length);

    spis_xfer_done = false;

    nrf_drv_spis_buffers_set(&spis, m_tx_buf, m_length, m_rx_buf, m_length);

    while (!spis_xfer_done)
    {
    __WFE();
    }
    }
    }

Related