This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

NRF5284 SPIM3 RX buffer empty

Hi All,

I've run into a weird issue where my SPIM rx buffer remains empty (it's not even filled with garbage - just empty). Am I operating the SPI drivers properly? My process is shown below:

When a command comes in over Bluetooth, I have a "master devkit" initiate a SPI transaction with a "slave devkit". The following function occurs in my main loop (so the CPU starts this ... for now).

static void process_commands()
{
  if (strcmp(token,"read") == 0) {
    NRF_LOG_INFO("read reg cmd recieved");
    
    token = strtok(NULL, delimiter);
    NRF_LOG_INFO("read token: %s", token);
    addr = (uint8_t) atoi(token);
    NRF_LOG_INFO("read addr: %d", addr);

    spi_tx_buf[0]   = addr;
    spi_tx_buf[1]   = 0;
    spi_tx_buf[63]  = 0;
    spi_tx_buf[64]  = 0;
    
    spi_cmd_flag = SPI_READ_REG; //spi_cmd_flag = read
    // NRF_LOG_HEXDUMP_DEBUG(spi_tx_buf, spi_length);
    NRF_LOG_INFO("cmd: %d - %d ... %d - %d",spi_tx_buf[0], spi_tx_buf[1], spi_tx_buf[63], spi_tx_buf[64]);

    // shoot off SPI_TRX
    if (spi_xfer_done == true)
    {
      NRF_LOG_INFO("SENDING SPI CMD...");
      spi_xfer_done = false;
      nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(spi_tx_buf, spi_length, spi_rx_buf, spi_length);
      APP_ERROR_CHECK(nrfx_spim_xfer(&spi, &xfer_desc, 0));
    }
    
  }
  ...
  ...
}

Then I have my spi event handler take whatever was in the rx buffer and send it back to my 'base station' over bluetooth:

void spim_event_handler(nrfx_spim_evt_t const * p_event,
                       void *                  p_context)
{
    spi_xfer_done = true;
    NRF_LOG_INFO("SPI TRX COMPLETE");
    
    if (spi_cmd_flag == SPI_READ_REG) {
      NRF_LOG_INFO("READ REG CCOMPLETE");
      spi_cmd_flag = 0;
      while(ble_nus_data_send(&m_nus, spi_rx_buf, &spi_length, m_conn_handle) != NRF_SUCCESS);
    }
    ...
    ...
}


Unfortunately, when I run this nothing is transmitted over bluetooth... If I try a hexdump it shows nothing (and in fact it crashes the devkit too...). I do not have access to a logic analyzer just yet but I'm looking at getting one to confirm that data is indeed being sent over the MISO. I can confirm that data is being shifted into my "slave" device (LEDs are changing when they're supposed to indicate valid SPI shift ins). Am I handling the SPIM TRX properly though? As in am I setting up the nrfx_spim_xfer object properly?

Thank you for all your help! I'm really stuck!

Ryan

Parents
  • Hi Ryan.

    Could you:

    1.  Post the code where you initialize the peripheral?
    2. Use the debugger and set a breakpoint in the handler, and check if the RX buffer is actually filled.

    regards

    Jared 

  • Hi Jared!

    Nice to see you again.

    The code I initialize the driver with is copied from the nrfx_spim example:

    static void spi_init(void)
    {
        ret_code_t err_code;
    
    
    
        nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
        spi_config.frequency      = NRF_SPIM_FREQ_1M;
        spi_config.ss_pin         = NRFX_SPIM_SS_PIN;
        spi_config.miso_pin       = NRFX_SPIM_MISO_PIN;
        spi_config.mosi_pin       = NRFX_SPIM_MOSI_PIN;
        spi_config.sck_pin        = NRFX_SPIM_SCK_PIN;
        //spi_config.dcx_pin        = NRFX_SPIM_DCX_PIN;
        spi_config.dcx_pin        = NRFX_SPIM_PIN_NOT_USED;
        spi_config.use_hw_ss      = true;
        spi_config.ss_active_high = false;
        APP_ERROR_CHECK(nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL));
    
    
        APP_ERROR_CHECK(err_code);
    }


    With the default config being:
    #define NRFX_SPIM_DEFAULT_CONFIG                             \
    {                                                            \
        .sck_pin        = NRFX_SPIM_PIN_NOT_USED,                \
        .mosi_pin       = NRFX_SPIM_PIN_NOT_USED,                \
        .miso_pin       = NRFX_SPIM_PIN_NOT_USED,                \
        .ss_pin         = NRFX_SPIM_PIN_NOT_USED,                \
        .ss_active_high = false,                                 \
        .irq_priority   = NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY, \
        .orc            = 0xFF,                                  \
        .frequency      = NRF_SPIM_FREQ_4M,                      \
        .mode           = NRF_SPIM_MODE_0,                       \
        .bit_order      = NRF_SPIM_BIT_ORDER_MSB_FIRST,          \
        NRFX_SPIM_DEFAULT_EXTENDED_CONFIG                        \
    }

    (note that the sck, mosi, miso, and ss pins are all overwritten in the spi_init function)

    As far as the breakpoint, I have placed a breakpoint at the line in the event handler and the code is getting there. How do I check if the rx buffer is being filled?

    EDIT:

    This is sad but it may have just been a faulty jumper cable on MISO. I swapped out the jumper and reverted back to a stripped down version of the code (it's bassically just the nrfx_spim and spis examples now) and I've started getting partial data (still not everything ...). It seems that when I send 00, the recieve buffer just treats it as a null... In other words i'm hoping to send an arbitrary array of 65 bytes (values may end up being 00) so I have set up a dummy array:

    // SPI transfer buffer
    static uint8_t       m_tx_buf[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,1};
    static uint8_t       m_rx_buf[sizeof(m_tx_buf) + 1];        // RX buffer.
    static const uint8_t m_length = sizeof(m_tx_buf);        // Transfer length.
    //static uint16_t      m_length = sizeof(uint8_t)*65;


    With this I *just* recieved 0x80 - which is 128 in decimal. Nothing else though! So I sent the following array:

    // SPI transfer buffer
    static uint8_t       m_tx_buf[] = {128,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,1};


    Hexdump stops at the 0's... 

    Is there a better way to interperet raw bytes that come in over spi?

    Thanks so much for your help.

  • Hi Jared!

    Nice to see you again.

    The code I initialize the driver with is copied from the nrfx_spim example:

    static void spi_init(void)
    {
        ret_code_t err_code;
    
    
    
        nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
        spi_config.frequency      = NRF_SPIM_FREQ_1M;
        spi_config.ss_pin         = NRFX_SPIM_SS_PIN;
        spi_config.miso_pin       = NRFX_SPIM_MISO_PIN;
        spi_config.mosi_pin       = NRFX_SPIM_MOSI_PIN;
        spi_config.sck_pin        = NRFX_SPIM_SCK_PIN;
        //spi_config.dcx_pin        = NRFX_SPIM_DCX_PIN;
        spi_config.dcx_pin        = NRFX_SPIM_PIN_NOT_USED;
        spi_config.use_hw_ss      = true;
        spi_config.ss_active_high = false;
        APP_ERROR_CHECK(nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL));
    
    
        APP_ERROR_CHECK(err_code);
    }


    With the default config being:
    #define NRFX_SPIM_DEFAULT_CONFIG                             \
    {                                                            \
        .sck_pin        = NRFX_SPIM_PIN_NOT_USED,                \
        .mosi_pin       = NRFX_SPIM_PIN_NOT_USED,                \
        .miso_pin       = NRFX_SPIM_PIN_NOT_USED,                \
        .ss_pin         = NRFX_SPIM_PIN_NOT_USED,                \
        .ss_active_high = false,                                 \
        .irq_priority   = NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY, \
        .orc            = 0xFF,                                  \
        .frequency      = NRF_SPIM_FREQ_4M,                      \
        .mode           = NRF_SPIM_MODE_0,                       \
        .bit_order      = NRF_SPIM_BIT_ORDER_MSB_FIRST,          \
        NRFX_SPIM_DEFAULT_EXTENDED_CONFIG                        \
    }

    (note that the sck, mosi, miso, and ss pins are all overwritten in the spi_init function)

    As far as the breakpoint, I have placed a breakpoint at the line in the event handler and the code is getting there. How do I check if the rx buffer is being filled?

    EDIT:

    This is sad but it may have just been a faulty jumper cable on MISO. I swapped out the jumper and reverted back to a stripped down version of the code (it's bassically just the nrfx_spim and spis examples now) and I've started getting partial data (still not everything ...). It seems that when I send 00, the recieve buffer just treats it as a null... In other words i'm hoping to send an arbitrary array of 65 bytes (values may end up being 00) so I have set up a dummy array:

    // SPI transfer buffer
    static uint8_t       m_tx_buf[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,1};
    static uint8_t       m_rx_buf[sizeof(m_tx_buf) + 1];        // RX buffer.
    static const uint8_t m_length = sizeof(m_tx_buf);        // Transfer length.
    //static uint16_t      m_length = sizeof(uint8_t)*65;


    With this I *just* recieved 0x80 - which is 128 in decimal. Nothing else though! So I sent the following array:

    // SPI transfer buffer
    static uint8_t       m_tx_buf[] = {128,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,1};


    Hexdump stops at the 0's... 

    Is there a better way to interpret raw bytes that come in over spi? Do I need to worry about "00s" coming in over SPI? Or can I be confident that the ble_nus_data_send will send everything I want it to?

    I have a janky solution that guarantees everything will be sent. I iterate over the rx_buff and convert everything to a char:
          char buf[196];
          uint16_t size_of_buff = sizeof(char)*196;
          for (int i = 0 ; i != 65 ; i++) 
          {
            sprintf(buf + (3*i), "%02x ", spi_rx_buf[i]);
          }
          rx_buff_hex[195] = '\0';
          while(ble_nus_data_send(&m_nus, (uint8_t *) buf, &size_of_buff, m_conn_handle) != NRF_SUCCESS);


    But this takes what would be 65 raw bytes and expands it to 196 chars manually - this seems like it will slow things down...

    Thanks so much for your help.

  • Hi there,

    ryerye120 said:
    How do I check if the rx buffer is being filled?

    You right click the rx_buffer and press add variable to watch. The variable will then be added to the watch window in debug mode. For example: 

    Could add the variable to the watch window and see if the 00's are actually received or not.

    regards

    Jared 

  • You right click the rx_buffer and press add variable to watch. The variable will then be added to the watch window in debug mode. For example:

    This was incredibly helpful! In the end, it was being filled up properly. It seems like the root issue really was a faulty MISO jumper wire. After replacing the MISO wire I could see the rx buff being filled up. Then I was able to take the downstream bits and properly interpret them after converting them to chars (with the previously posted loop).

    Thanks for your help, Jared!


    Kindest regards,

    Ryan

Reply
  • You right click the rx_buffer and press add variable to watch. The variable will then be added to the watch window in debug mode. For example:

    This was incredibly helpful! In the end, it was being filled up properly. It seems like the root issue really was a faulty MISO jumper wire. After replacing the MISO wire I could see the rx buff being filled up. Then I was able to take the downstream bits and properly interpret them after converting them to chars (with the previously posted loop).

    Thanks for your help, Jared!


    Kindest regards,

    Ryan

Children
No Data
Related