<?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>nRF52840 fails to go to low-power mode when using UART RX double buffering</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/54271/nrf52840-fails-to-go-to-low-power-mode-when-using-uart-rx-double-buffering</link><description>Hello, 
 We are experiencing an issue when putting the nRF52840 back to a low-power state after having had UART configured for double buffering. For context we are using nRF5 SDK v15.3.0. 
 We have reverted to a very simple example application which does</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 14 Nov 2019 08:07:56 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/54271/nrf52840-fails-to-go-to-low-power-mode-when-using-uart-rx-double-buffering" /><item><title>RE: nRF52840 fails to go to low-power mode when using UART RX double buffering</title><link>https://devzone.nordicsemi.com/thread/219993?ContentTypeID=1</link><pubDate>Thu, 14 Nov 2019 08:07:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:06b971f8-8683-4e7e-870d-305368fed609</guid><dc:creator>Sigurd</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote userid="84991" url="~/f/nordic-q-a/54271/nrf52840-fails-to-go-to-low-power-mode-when-using-uart-rx-double-buffering/219802"]Simple RX abort sequence (fails to return to low power mode, current is ~907uA)[/quote]
&lt;p&gt;I see the same behavior, and was able to reproduce it with this code:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/**
 * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA &amp;quot;AS IS&amp;quot; AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 * @defgroup Based on uart_example_main main.c
 * @{
 * @ingroup uart_example
 * @brief UART Example Application main file.
 *
 * This file contains the source code for a sample application using UART.
 *
 */

#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;

#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;nrf_delay.h&amp;quot;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;bsp.h&amp;quot;
#if defined (UART_PRESENT)
#include &amp;quot;nrf_uart.h&amp;quot;
#endif
#if defined (UARTE_PRESENT)
#include &amp;quot;nrf_uarte.h&amp;quot;
#endif

#include &amp;quot;nrf_drv_uart.h&amp;quot;

#define UARTE_INSTANCE  0 
static const nrfx_uarte_t uarte = NRFX_UARTE_INSTANCE(UARTE_INSTANCE);  /**&amp;lt; UARTE instance. **/

void uarte_event_handler(nrfx_uarte_event_t const * p_event, void* p_context)
{
    uint32_t err_code;

    switch (p_event-&amp;gt;type)
    {
        case NRFX_UARTE_EVT_TX_DONE:

            break;

        case NRFX_UARTE_EVT_RX_DONE:

            break;

        case NRFX_UARTE_EVT_ERROR:

            break;



        default:
            break;
    }
}

static uint8_t rx_buffer[1];

#define UARTE_WORKAROUND_ENABLED 1

int main(void)
{
    uint32_t err_code;

    bsp_board_init(BSP_INIT_LEDS);


    nrfx_uarte_config_t uarte_config = NRFX_UARTE_DEFAULT_CONFIG;
    uarte_config.pseltxd = TX_PIN_NUMBER;
    uarte_config.pselrxd = RX_PIN_NUMBER; 
    uarte_config.pselcts = NRF_UARTE_PSEL_DISCONNECTED;
    uarte_config.pselrts = NRF_UARTE_PSEL_DISCONNECTED;
    uarte_config.p_context = NULL;
    uarte_config.hwfc = NRF_UARTE_HWFC_DISABLED;
    uarte_config.parity = NRF_UARTE_PARITY_EXCLUDED;
    uarte_config.baudrate = NRF_UARTE_BAUDRATE_115200;
    uarte_config.interrupt_priority = NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY;

    APP_ERROR_CHECK(nrfx_uarte_init(&amp;amp;uarte, &amp;amp;uarte_config, uarte_event_handler));

    nrfx_uarte_rx(&amp;amp;uarte, rx_buffer, 1);
    nrfx_uarte_rx_abort(&amp;amp;uarte);
    nrfx_uarte_uninit(&amp;amp;uarte);


    #if UARTE_WORKAROUND_ENABLED
    *(volatile uint32_t *)0x40002FFC = 0;
    *(volatile uint32_t *)0x40002FFC;
    *(volatile uint32_t *)0x40002FFC = 1;
    #endif // UARTE_WORKAROUND_ENABLED


    while (true)
    {
         // Wait for an event.
        __WFE();
        // Clear the internal event register.
        __SEV();
        __WFE();

    }
}


/** @} */&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;It might seem like the mention fix in nrfx only covers TX operation, and not RX. So the workaround mentioned by&amp;nbsp;hmolesworth in the other post is still needed.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If&amp;nbsp;you are using UARTE0:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;    *(volatile uint32_t *)0x40002FFC = 0;
    *(volatile uint32_t *)0x40002FFC;
    *(volatile uint32_t *)0x40002FFC = 1;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;For UARTE1:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="text"&gt;*(volatile uint32_t *)0x40028FFC = 0;
*(volatile uint32_t *)0x40028FFC;
*(volatile uint32_t *)0x40028FFC = 1;&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I did some testing, and it seems like waiting for the RXTO event after RX_STOPPED is triggered is required. I will report this to the nrfx team, and the fix will hopefully make it into the upcoming&amp;nbsp;nrfx v2.1 relase.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
{
    uarte_control_block_t * p_cb = &amp;amp;m_cb[p_instance-&amp;gt;drv_inst_idx];

    if (p_cb-&amp;gt;handler)
    {
        interrupts_disable(p_instance);
    }
    // Make sure all transfers are finished before UARTE is disabled
    // to achieve the lowest power consumption.
    nrf_uarte_shorts_disable(p_instance-&amp;gt;p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
    nrf_uarte_event_clear(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_RXTO);
    nrf_uarte_task_trigger(p_instance-&amp;gt;p_reg, NRF_UARTE_TASK_STOPRX);
    while (!nrf_uarte_event_check(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_RXTO))
    {}
    nrf_uarte_event_clear(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_TXSTOPPED);
    nrf_uarte_task_trigger(p_instance-&amp;gt;p_reg, NRF_UARTE_TASK_STOPTX);
    while (!nrf_uarte_event_check(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_TXSTOPPED))
    {}

    nrf_uarte_disable(p_instance-&amp;gt;p_reg);
    pins_to_default(p_instance);

#if NRFX_CHECK(NRFX_PRS_ENABLED)
    nrfx_prs_release(p_instance-&amp;gt;p_reg);
#endif

    p_cb-&amp;gt;state   = NRFX_DRV_STATE_UNINITIALIZED;
    p_cb-&amp;gt;handler = NULL;
    NRFX_LOG_INFO(&amp;quot;Instance uninitialized: %d.&amp;quot;, p_instance-&amp;gt;drv_inst_idx);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit2:&amp;nbsp;&lt;/strong&gt;Added a test for rx_buffer_length (Check if there is any ongoing reception)&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void nrfx_uarte_uninit(nrfx_uarte_t const * p_instance)
{
    uarte_control_block_t * p_cb = &amp;amp;m_cb[p_instance-&amp;gt;drv_inst_idx];

    if (p_cb-&amp;gt;handler)
    {
        interrupts_disable(p_instance);
    }
    // Make sure all transfers are finished before UARTE is disabled
    // to achieve the lowest power consumption.
    nrf_uarte_shorts_disable(p_instance-&amp;gt;p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX);
    
    // Check if there is any ongoing reception.
    if (p_cb-&amp;gt;rx_buffer_length)
    {
    nrf_uarte_event_clear(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_RXTO);
    nrf_uarte_task_trigger(p_instance-&amp;gt;p_reg, NRF_UARTE_TASK_STOPRX);
    while (!nrf_uarte_event_check(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_RXTO))
    {}
    }
    
    nrf_uarte_event_clear(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_TXSTOPPED);
    nrf_uarte_task_trigger(p_instance-&amp;gt;p_reg, NRF_UARTE_TASK_STOPTX);
    while (!nrf_uarte_event_check(p_instance-&amp;gt;p_reg, NRF_UARTE_EVENT_TXSTOPPED))
    {}

    nrf_uarte_disable(p_instance-&amp;gt;p_reg);
    pins_to_default(p_instance);

#if NRFX_CHECK(NRFX_PRS_ENABLED)
    nrfx_prs_release(p_instance-&amp;gt;p_reg);
#endif

    p_cb-&amp;gt;state   = NRFX_DRV_STATE_UNINITIALIZED;
    p_cb-&amp;gt;handler = NULL;
    NRFX_LOG_INFO(&amp;quot;Instance uninitialized: %d.&amp;quot;, p_instance-&amp;gt;drv_inst_idx);
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52840 fails to go to low-power mode when using UART RX double buffering</title><link>https://devzone.nordicsemi.com/thread/219802?ContentTypeID=1</link><pubDate>Wed, 13 Nov 2019 06:47:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:951929ea-26f6-4bf4-8dc6-5cda2a2175cc</guid><dc:creator>Robert Hutchinson</dc:creator><description>&lt;p&gt;Hi Sigurd,&lt;/p&gt;
&lt;p&gt;Further to the findings above, it seems that we are unable to abort from a RX transfer and successfully return to a low-power state (refer to the sequence below). It effectively means that only after the number of bytes configured by nrfx_uarte_rx() have been received can we successfully uninitialize the peripheral, which is simple but significant problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Simple RX abort sequence (fails to return to low power mode, current is ~907uA)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;nrfx_uarte_init(&amp;amp;diag_uarte_instance, &amp;amp;uarte_config, uarte_event_handler);
nrfx_uarte_rx(&amp;amp;diag_uarte_instance, &amp;amp;rx0, 1);
nrfx_uarte_rx_abort(&amp;amp;diag_uarte_instance);
nrfx_uarte_uninit(&amp;amp;diag_uarte_instance);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Note that we have tested this with SDK v16.0.0. Could you please let us know if there is something we&amp;#39;re doing wrong here?&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Rob&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52840 fails to go to low-power mode when using UART RX double buffering</title><link>https://devzone.nordicsemi.com/thread/219777?ContentTypeID=1</link><pubDate>Wed, 13 Nov 2019 00:33:38 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f863484f-1731-4956-8a2f-12d2ae007fb8</guid><dc:creator>Robert Hutchinson</dc:creator><description>&lt;p&gt;Hi Sigurd,&lt;/p&gt;
&lt;p&gt;Thanks for your help and suggestion.&lt;/p&gt;
&lt;p&gt;We have updated to the latest SDK v16.0.0, which has nrfx v1.8.0, however the problem is still present.&lt;/p&gt;
&lt;p&gt;I believe the UART changes in v1.7.2 were actually something we had experienced previously and had been working around by&amp;nbsp;nrfx_uarte_tx_abort&amp;nbsp; after sending over UART. However, the changes do not seem to help us on the receive side, as described above.&lt;/p&gt;
&lt;p&gt;If you have any further pointers or could clarify the usage of double buffering on RX transfers that would be great.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Rob&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52840 fails to go to low-power mode when using UART RX double buffering</title><link>https://devzone.nordicsemi.com/thread/219729?ContentTypeID=1</link><pubDate>Tue, 12 Nov 2019 15:33:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e54823dc-d629-41f7-881c-a62fdbfef0c7</guid><dc:creator>Sigurd</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Please try to update to latest nrfx driver, and see it that solves the issue. There was a bug-fixe when it comes to&amp;nbsp;&lt;span&gt;gracefully uinit of the UARTE peripheral in nrfx v1.7.2. See e.g. &lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/53121/uart-low-power-shutdown-issue"&gt;this post&lt;/a&gt; on this topic.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>