<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SPI behaviour differs between debug and release modes</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/67794/spi-behaviour-differs-between-debug-and-release-modes</link><description>I have a custom board using NRF52832 which communicates with a BMI160 accelerometer/gyroscope chip by SPI. 
 I have been developing in Segger Embedded Studio (v5.10d) in debug mode, and I can configure the BMI160 and read data from the sensor without</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 17 Nov 2020 12:52:28 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/67794/spi-behaviour-differs-between-debug-and-release-modes" /><item><title>RE: SPI behaviour differs between debug and release modes</title><link>https://devzone.nordicsemi.com/thread/280358?ContentTypeID=1</link><pubDate>Tue, 17 Nov 2020 12:52:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:04631e34-681a-4501-af1a-477b02ac9a30</guid><dc:creator>Simonr</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;Sorry about the delayed response, but Edvin is out of office for the time being, and we&amp;#39;ve only now gotten to his backlog. Does this spi_xfer_done event return true even though you are receiving the wrong values in release mode? Is it reached/trigged at all when your application is running?&lt;/p&gt;
&lt;p&gt;I also think that what Edvin said about the speed of the application in Release mode is what&amp;#39;s causing this. You can try confirming this by setting the Optimization Level in SEGGER&amp;#39;s project options to&amp;nbsp;&lt;strong&gt;NONE&amp;nbsp;&lt;/strong&gt;for instance?&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Simon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SPI behaviour differs between debug and release modes</title><link>https://devzone.nordicsemi.com/thread/279807?ContentTypeID=1</link><pubDate>Thu, 12 Nov 2020 18:23:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6177c949-a6d2-43be-88d2-9dbd68a674f2</guid><dc:creator>Ronnie Tango</dc:creator><description>&lt;p&gt;Hi, thanks for the response.&lt;/p&gt;
&lt;p&gt;The spi read function does indeed have a callback:&lt;/p&gt;
&lt;pre&gt;void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
   spi_xfer_done = true;
}&lt;/pre&gt;
&lt;p&gt;&lt;span&gt;but&amp;nbsp;unfortunately waiting for this to be completed before checking the register result did not change anything...&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Is there any other info I can provide that might give a clue? I believe I&amp;#39;m using the SPI&amp;nbsp;driver (&lt;/span&gt;nrfx_spi_xfer) rather than SPIM.&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SPI behaviour differs between debug and release modes</title><link>https://devzone.nordicsemi.com/thread/278005?ContentTypeID=1</link><pubDate>Mon, 02 Nov 2020 10:01:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ddb955c4-98b3-4833-b3ee-5c32fb826557</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;without knowing too much about this driver, it may look like there is an event handler that you should wait for somewhere. The reason why it is working in debug is that the release version may have some more optimization (particularly for time), so that the function that &amp;quot;reads the registers&amp;quot; (basically triggers the SPI transaction) returns, but the callback hasn&amp;#39;t triggered yet.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So does the SPI have a callback? If yes, try to wait for the callback before you check the&amp;nbsp;tmpData. The callback (if present) is set in the init function of your SPI. Something like this snippet from the SDK\examples\peripheral\spi example:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;APP_ERROR_CHECK(nrf_drv_spi_init(&amp;amp;spi, &amp;amp;spi_config, spi_event_handler, NULL));&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If the SPI is set up with an event handler, the SPI calls are none-blocking, meaning they will return before the SPI transactions are done. If you do not have an SPI handler the calls are blocking, meaning they will not return until the transaction is complete.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Depending on whether you are using the spim or spi driver this is implemented a bit differently, but looking at the SPIM implementation:&lt;/p&gt;
&lt;p&gt;From&amp;nbsp;spim_xfer() in nrfx_spim.c:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;    if (!p_cb-&amp;gt;handler)
    {
        while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)){}

#if NRFX_CHECK(NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED)
        if (p_spim == NRF_SPIM3)
        {
            anomaly_198_disable();
        }
#endif
        if (p_cb-&amp;gt;ss_pin != NRFX_SPIM_PIN_NOT_USED)
        {
#if NRFX_CHECK(NRFX_SPIM_EXTENDED_ENABLED)
            if (!p_cb-&amp;gt;use_hw_ss)
#endif
            {
                if (p_cb-&amp;gt;ss_active_high)
                {
                    nrf_gpio_pin_clear(p_cb-&amp;gt;ss_pin);
                }
                else
                {
                    nrf_gpio_pin_set(p_cb-&amp;gt;ss_pin);
                }
            }
        }
    }
    else
    {
        spim_int_enable(p_spim, !(flags &amp;amp; NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER));
    }&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;So if there is a callback, p_cb-&amp;gt;handler, the task will be triggered, and then return.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What you are seeing is probably that&amp;nbsp;bmi160_get_regs() returns, but the callback is not yet triggered, so the data is not actually received. Then you trigger a new SPI read, but in the meantime, the callback is received, and the data is updated. Try to wait for the callback, and set spi_xfer_done = true in the callback (like in the example):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;volatile bool spi_xfer_done;

void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
    spi_xfer_done = true;
    ...
    
}

static void my_function()
{
    uint8_t tmpData = 0;
    
    spi_xfer_done = false;
    uint8_t rslt = bmi160_get_regs(BMI160_CHIP_ID_ADDR, &amp;amp;tmpData, 1, &amp;amp;bmi160);
    while (spi_xfer_done == false)
    {
        // Wait
    }
    if (tmpData == BMI160_CHIP_ID)
    {
        ledOn(GREEN_LED_MASK);
    }
    ...
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Try something like that.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SPI behaviour differs between debug and release modes</title><link>https://devzone.nordicsemi.com/thread/277866?ContentTypeID=1</link><pubDate>Fri, 30 Oct 2020 15:22:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:61b4ff42-18ff-4d01-8037-017e0c998d11</guid><dc:creator>Ronnie Tango</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Thanks for your reply - sorry, I should probably have included both points you mention in the original post.&lt;/p&gt;
&lt;p&gt;The bmi160_get_regs() function&amp;nbsp;comes from the bmi160 driver provided by Bosch, and is as follows:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;int8_t bmi160_get_regs(uint8_t reg_addr, uint8_t *data, uint16_t len, const struct bmi160_dev *dev)
{
    int8_t rslt = BMI160_OK;

    /* Variable to define temporary length */
    uint16_t temp_len = len + dev-&amp;gt;dummy_byte;

    /* Variable to define temporary buffer */
    uint8_t temp_buf[temp_len];

    /* Variable to define loop */
    uint16_t indx = 0;

    /* Null-pointer check */
    if ((dev == NULL) || (dev-&amp;gt;read == NULL))
    {
        rslt = BMI160_E_NULL_PTR;
    }
    else if (len == 0)
    {
        rslt = BMI160_READ_WRITE_LENGHT_INVALID;
    }
    else
    {
        /* Configuring reg_addr for SPI Interface */
        if (dev-&amp;gt;interface == BMI160_SPI_INTF)
        {
            reg_addr = (reg_addr | BMI160_SPI_RD_MASK);
        }
        rslt = dev-&amp;gt;read(dev-&amp;gt;id, reg_addr, temp_buf, temp_len);

        if (rslt == BMI160_OK)
        {
            /* Read the data from the position next to dummy byte */
            while (indx &amp;lt; len)
            {
                data[indx] = temp_buf[indx];
                indx++;
            }
        }
        else
        {
            rslt = BMI160_E_COM_FAIL;
        }
    }

    return rslt;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The dev-&amp;gt;read function pointer (line 30) in turn calls the user spi read function&amp;nbsp;bmi160_spi_read() from the original post.&lt;/p&gt;
&lt;p&gt;In both debug and release mode, bmi160_get_regs() is always returning no error (BMI160_OK).&lt;/p&gt;
&lt;p&gt;As far as I can tell, tmpData should definitely be getting set correctly in bmi160_get_regs(). Using the debugger, the result of the two get_regs calls from the first code snippet in the original post are:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Debug mode:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;bmi160_get_regs(BMI160_CHIP_ID_ADDR&amp;hellip;) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span class="Apple-tab-span"&gt;&lt;/span&gt;-&amp;gt; data[0] = 0xD1&lt;span class="Apple-converted-space"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;//&lt;span class="Apple-converted-space"&gt;&amp;nbsp; &lt;/span&gt;0xD1 is the correct chip id&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;bmi160_get_regs(BMI160_ACCEL_RANGE_ADDR&amp;hellip;) &lt;span class="Apple-tab-span"&gt; &lt;/span&gt;-&amp;gt; data[0] = 0x0C&lt;span class="Apple-converted-space"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;//&lt;span class="Apple-converted-space"&gt;&amp;nbsp; &lt;/span&gt;0x0C is the correct accelerometer range&lt;span class="Apple-tab-span"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span class="Apple-tab-span"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Release mode:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;bmi160_get_regs(BMI160_CHIP_ID_ADDR&amp;hellip;)&lt;span class="Apple-converted-space"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;-&amp;gt; data[0] &lt;/span&gt;&lt;span&gt;= 0x00&lt;span class="Apple-converted-space"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;bmi160_get_regs(BMI160_ACCEL_RANGE_ADDR&amp;hellip;)&lt;span class="Apple-tab-span"&gt; &lt;/span&gt;-&amp;gt; data[0] = 0xD1&lt;span class="Apple-converted-space"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;//&lt;span class="Apple-converted-space"&gt;&amp;nbsp; &lt;/span&gt;0xD1 is the chip id that should have been returned last time&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SPI behaviour differs between debug and release modes</title><link>https://devzone.nordicsemi.com/thread/277837?ContentTypeID=1</link><pubDate>Fri, 30 Oct 2020 14:17:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:be67bcee-1707-430c-a2e7-d612d40852e1</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;Can you try to check what&amp;nbsp;bmi160_get_regs() returns when you are running in release mode?&lt;/p&gt;
&lt;p&gt;Does it return NRF_SUCCESS?&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t know what your drivers looks like. What does bmi160_get_regs() look like? Is there any chance that it doesn&amp;#39;t set the&amp;nbsp;tmpData? I think you need to debug (actually debug and monitor logging or something, not setting it back to &amp;quot;Debug mode&amp;quot;).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;BR,&lt;br /&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>