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

SPI communication problem with interfaced sensor getting ASSERTION FAILED?

Hello Everyone,

We are using nRF52840 DK with Segger Embedded Studio (SES) using SDK v15.0 We are sending few command to sensor via SPI for reading sensor value. But while reading sensor value getting asseration failed ERROR at line no: nRF5_SDK_15.0.0_a53641a/modules/nrfx/drivers/src/nrfx_uarte.c:269

When I go to this line saw NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED); difficult to understand what exactly problem. Please help me for fixing this issue.

Looking forward your response....!!!

Thanks...

Parents
  • difficult to understand what exactly problem

    Is it?

    The problem is that it is not in the INITLIALIZED state - it needs to be!

    https://en.wikipedia.org/wiki/Assertion_(software_development)

  • Hi,

    By disabled NRF_LOG_BACKEND_UART_ENABLED 0 in sdk_config.h then this error solved but now getting ERROR 17 [NRF_ERROR_BUSY] at the time of sending command over SPI.

     APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, address, sizeof(address), m_rx_buf, sizeof(m_rx_buf))); 

    Thanks,

    Vishal

  • HI,

    Actually I saw this thread and not understand what exactly errata 87. When I changed the debug mode to release then it working.

    Why this happening for debug mode only.

    Thanks. 

  • Hi,

    In release mode some of the asserts are ignored, such that the application will run instead of asserting.

    In your case it seems you have used the FPU for a calculation, and the calculation output an operational error by invalid data. 

    The fpscr register will tell you which of the three following operational errors it was:

    IOC - Invalid Operation cumulative exception bit.
    DZC - Division by Zero cumulative exception bit.
    OFC - Overflow cumulative exception bit.

    You may choose to remove/modify the assert check depending on your requirements. E.g., remove it entirely if you wish to ignore these exceptions like the errata workaround suggests. You may also read the fpscr to find exactly which bit is set if you want to try to figure out what FPU operation that went wrong preivously.

    Best regards,
    Kenneth

  • Ok, Thanks for the great explanation..!!

    Now we received sensor that we have written this SPI code for that. But it not working I am little bit confused for How send SPI command to sensor and read sensor response. 

    Here is my below simple for read and write SPI command:

    static uint8_t       reset_seq[] = { 0x15, 0x55, 0x40 };     /**< TX buffer. */
    static uint8_t       address_word1[] = { 0x1D, 0x50 };       /**< TX buffer. */
    static uint8_t       address_word2[] = { 0x1D, 0x60 };       /**< TX buffer. */
    static uint8_t       address_word3[] = { 0x1D, 0x90 };       /**< TX buffer. */
    static uint8_t       address_word4[] = { 0x1D, 0xA0 };       /**< TX buffer. */
    static uint8_t       address_pressure[] = { 0x0F, 0x40 };    /**< TX buffer. */
    static uint8_t       address_temp[] = { 0x0F, 0x20 };        /**< TX buffer. */
    static uint8_t       m_rx_buf[sizeof(((uint8_t)0x1D)) + sizeof(((uint8_t)0x1D)) + 1];    /**< RX buffer. */
    static const uint8_t m_length = sizeof(address_word1);
    /**
     * Initialized SPI driver and their pin configurations
     */
    void spi_init() {
      nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
      spi_config.ss_pin = SPI_SS_PIN; /*  PCB Pin: 25*/
      spi_config.miso_pin = SPI_MISO_PIN; /*  PCB Pin: 27*/
      spi_config.mosi_pin = SPI_MOSI_PIN; /*  PCB Pin: 26*/
      spi_config.sck_pin = SPI_SCK_PIN; /*  PCB Pin: 28*/
      spi_config.mode    = NRF_DRV_SPI_MODE_0;
      spi_config.frequency    = NRF_SPI_FREQ_500K;
      APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    }
    
    /**
     * reset sensor module and send sequence.
     */
    void reset_sensor() {
      NRF_LOG_INFO("Reset Sensor");
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, reset_seq, sizeof(reset_seq), NULL, 0));
      spi_xfer_done = false;
        while (!spi_xfer_done) {
         idle_state_handle();
      }
        NRF_LOG_FLUSH();
    }
    
    /**
     * brief function Read calibration data (factory calibrated) from PROM of MS5540C
     * by sending specific address.
     */
    unsigned int read_cal_word(uint8_t *address) {
      unsigned int word = 0;
      memset(m_rx_buf, 0, m_length);
      reset_sensor(); /*Before read calibration word need to reset sensor module*/
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, address, sizeof(address), m_rx_buf, sizeof(m_rx_buf)));
      spi_xfer_done = false;
      while (!spi_xfer_done) {
       idle_state_handle();
      }
      NRF_LOG_FLUSH();
      word = (m_rx_buf[0] << 8) | m_rx_buf[1]; /*Combine received 2 bytes from sensor*/
    //  NRF_LOG_DEBUG("Return Calibration word = %u", word);
      return word;
    }
    

    I am getting wrong calibration word from sensor. Is this above code is correct. What's going wrong in my code.

    Is it necessary to send dummy byte to read data from sensor. 

    Thanks..!!

  • Hi,

    You should set spi_xfer_done = false; before nrf_drv_spi_transfer() to avoid potential race conditions. I can't see your spi_event_handler() but I assume it just set spi_xfer_done = true;

    Your m_rx_buf should be the length of address_word + data, then the actual data you are looking for is after the size of address_word.

    Also a logic analyzer (e.g. https://www.saleae.com/) can be very useful.

    Best regards,
    Kenneth

Reply Children
  • Hi,

    Thanks for your suggestion..

    I have changed spi_xfer_done = false; before nrf_drv_spi_transfer() ; Now as you suggested I have looked and used actual data after size of address: And logs all read calibration factor and looks like working but the first bytes always same here is my below logs:

    <info> app: Level Detector started.
    <info> app: m_length: 2
    <info> app: Reset Sensor
    <info> app: Transfer completed.
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE                     |.       
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE                     |.       
    <info> app: RX Buff_byte1:FE byte2:F0 byte3:D7
    <debug> app: Calibration Word 1: 55280
    <info> app: m_length: 2
    <info> app: Reset Sensor
    <info> app: Transfer completed.
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE 01 9F               |...     
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE 01 9F FF F0         |.....   
    <info> app: RX Buff_byte1:FE byte2:F0 byte3:9F
    <debug> app: Calibration Word 2: 40944
    <info> app: m_length: 2
    <info> app: Reset Sensor
    <info> app: Transfer completed.
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE                     |.       
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE                     |.       
    <info> app: RX Buff_byte1:FE byte2:F0 byte3:C6
    <debug> app: Calibration Word 3: 50928
    <info> app: m_length: 2
    <info> app: Reset Sensor
    <info> app: Transfer completed.
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE 01 DA               |...     
    <info> app: Transfer completed.
    <info> app:  Received:
    <info> app:  FE 01 DA 7F F0         |.....   
    <info> app: RX Buff_byte1:FE byte2:F0 byte3:DA
    <debug> app: Calibration Word 4: 56048
    <info> app: coefficients- C1: 27640 C2:3120 C3:875 C4:795 C5:639 C6:48
    

    Also a logic analyzer (e.g. https://www.saleae.com/) can be very useful.

    Currently we don't have logic analyzer so can not be able to view SPI waveforms.

    I assume it just set spi_xfer_done = true;

    Yes you are correct.

    After that when I tried to read sensor register for measurement received same bytes every measurement like FF FF.

    Will you please make this case as private, So I can share my other code with you..

    Thanks... 

  • I recommend that you get logic analyzer asap, then you can look at the timing, clock and data lines, and also compare the rx_buf/tx_buf to the actual SPI transactions.

    Best regards,
    Kenneth

  • Actually right now we will not able to get logic analyzer, So can you please suggest me solution for How I can fixed this.

    When I send SPI command to sensor it response How I can read correct bytes from this means MSB first and then LSB.

    Is below function is correct for read and write SPI communication.

    unsigned int read_cal_word(uint8_t *address) {
      spi_xfer_done = false;
      unsigned int word = 0;
      uint8_t dummy_byte = 0x00;
      memset(m_rx_buf, 0, m_length);
      memset(m_rx_buf2, 0, sizeof(m_rx_buf2));
    //  NRF_LOG_INFO("m_length: %d", m_length)
      
      reset_sensor(); /*Before read calibration word need to reset sensor module*/
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, address, sizeof(address), m_rx_buf, sizeof(m_rx_buf)));
      nrf_delay_ms(200);
      wait_for_spi_event();
      NRF_LOG_FLUSH();
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &dummy_byte, sizeof(dummy_byte), m_rx_buf2, sizeof(m_rx_buf2)));
      wait_for_spi_event();
      nrf_delay_ms(200);
      NRF_LOG_INFO("RX Buff_byte1:%X byte2:%X", m_rx_buf[2], m_rx_buf2[1]);
      word = (m_rx_buf[2] << 8) | m_rx_buf2[1]; /*Combine received 2 bytes from sensor*/
    //  NRF_LOG_DEBUG("Return Calibration word = %u", word);
      return word;
    }
    

    Please let me know your valuable suggestion..?

    Thanks..

  • I suggest to connect MISO and MOSI together to first verify that m_rx_buf is a loopback of the address and commands you are sending. However a logic analyzer would speed up debugging a lot.

    Best regards,
    Kenneth

  • a logic analyzer would speed up debugging a lot

    Absolutely!!

    This is a hardware interface - trying to debug it with no view into the hardware is just folly!

Related