<?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>How to wake UART from System-OFF without the use of RDY and REQ pins (or any sort of Hardware Flow Control), for an nRF54L15?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/128022/how-to-wake-uart-from-system-off-without-the-use-of-rdy-and-req-pins-or-any-sort-of-hardware-flow-control-for-an-nrf54l15</link><description>Issue 
 How to properly wake an nRF54L15 from System-Off mode when the device receives a UART transmission, without the use of the LPUART Ready and Request lines or any sort of HWFC . I understand that System-Off fully powers down the UART so we can&amp;#39;t</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 06 May 2026 13:14:55 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/128022/how-to-wake-uart-from-system-off-without-the-use-of-rdy-and-req-pins-or-any-sort-of-hardware-flow-control-for-an-nrf54l15" /><item><title>RE: How to wake UART from System-OFF without the use of RDY and REQ pins (or any sort of Hardware Flow Control), for an nRF54L15?</title><link>https://devzone.nordicsemi.com/thread/565971?ContentTypeID=1</link><pubDate>Wed, 06 May 2026 13:14:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:67377f74-5574-4836-96fb-7d014d5ec5e5</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;&lt;span&gt;With good help from Cursor I made some experiments using the Zephyr Async UART API with a nRF54L15 DK and found when&amp;nbsp;testing&amp;nbsp;with 7 and 8 byte preambles that the chip was able to enable UART reception in time to receive the actual payload.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Log from Python test script (the nRF54L15 DK will echo back the test string if it&amp;nbsp;was able to receive the whole string):&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1778072703697v6.png" alt=" " /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Sending 32 bytes of data every second resulted in an average current of a little over 100 uA:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1778072718985v7.jpeg" alt=" " /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1778072736104v8.png" alt=" " /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Test project:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;a href="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/uart_5F00_async_5F00_low_5F00_power_5F00_wake.zip"&gt;devzone.nordicsemi.com/.../uart_5F00_async_5F00_low_5F00_power_5F00_wake.zip&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Vidar&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to wake UART from System-OFF without the use of RDY and REQ pins (or any sort of Hardware Flow Control), for an nRF54L15?</title><link>https://devzone.nordicsemi.com/thread/565924?ContentTypeID=1</link><pubDate>Tue, 05 May 2026 23:54:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:075d441d-7e90-49fb-8e28-f54bf5d14665</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Here&amp;#39;s my code for the nRF52840 which might save some time. I used Timer 3 to capture the 3 samples per bit and EGU4 with a lower interrupt priority to process the received character. I was using differential RS485 so simply ignore the unwanted signal for a normal UART.&lt;/p&gt;
&lt;p&gt;Any feedback for improvements welcomed.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define NUMBER_OF_RX_INPUT_PIN_SAMPLES_PER_VOTE  3
#define NUMBER_OF_RX_INPUT_BITS                 10    // Start - 8 x Data - Stop
#define NUMBER_OF_INPUT_PIN_SAMPLES (NUMBER_OF_RX_INPUT_BITS * NUMBER_OF_RX_INPUT_PIN_SAMPLES_PER_VOTE)
#define COUNT_IS_STOP_BIT (NUMBER_OF_INPUT_PIN_SAMPLES-2)
#define TIMER_PRESCALER 0
#define LL_SAMPLE_RATE (LL_BAUDRATE * NUMBER_OF_RX_INPUT_PIN_SAMPLES_PER_VOTE)
#define RX_BUFFER_SIZE 4
#define LL_SAMPLE_TIME ((F_CLK + (LL_SAMPLE_RATE/2))/ LL_SAMPLE_RATE)
#define RX_NEG_INPUT_PIN_MASK (1 &amp;lt;&amp;lt; PWM_NEG)
#define RX_POS_INPUT_PIN_MASK (1 &amp;lt;&amp;lt; PWM_POS)

// Rx pins sample history
volatile uint32_t mRxInputPinSamples[NUMBER_OF_INPUT_PIN_SAMPLES] = {0};
volatile uint32_t mRxInputPinSampleCount = 0;
volatile uint8_t mRxByteP[RX_BUFFER_SIZE] = {0};
volatile uint8_t mRxByteN[RX_BUFFER_SIZE] = {0};
volatile uint8_t mRxIndex = 0;
// Event Generator Unit (EGUn)
static NRF_EGU_Type* pNRF_EGU = NRF_EGU4;
#define SWI_EGU_IRQn SWI4_EGU4_IRQn

// Standard Uart character 0x21 - 3-vote samples, single timer (T4), SBT=BT/3, requires reload
//
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//      |     |     |     |     |     |     |     |     |     |     |
// Idle &amp;#39;Start&amp;#39;Bit 0&amp;#39;Bit 1&amp;#39;Bit 2&amp;#39;Bit 3&amp;#39;Bit 4&amp;#39;Bit 5&amp;#39;Bit 6&amp;#39;Bit 7&amp;#39;Stop &amp;#39;  Idle
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |                       |     |           |
//      |     |     |                       |     |           |       Normal
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//      |     |     |                       |     |           |       Invert
//      |     |     |                       |     |           |
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |     |     |     |     |     |     |     |     |
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//      |     |     |     |     |     |     |     |     |     |     |
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |                                                  Clear Reload
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +- Stop Bit  after 1/2 Stop bit wait for next Start  -     -
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | | +--- Stop Bit  Check  pTimer4-&amp;gt;CC[4] = SBT/2+(28*SBT)  *     3,4,0
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | +----- Stop Bit  Check  pTimer4-&amp;gt;CC[3] = SBT/2+(27*SBT)  -     2
//       | | | | | | | | | | | | | | | | | | | | | | | | | | +------- Bit 7     Vote 3 pTimer4-&amp;gt;CC[2] = SBT/2+(26*SBT)  -     1
//       | | | | | | | | | | | | | | | | | | | | | | | | | +--------- Bit 7     Vote 2 pTimer4-&amp;gt;CC[1] = SBT/2+(25*SBT)  -     0
//       | | | | | | | | | | | | | | | | | | | | | | | | +----------- Bit 7     Vote 1 pTimer4-&amp;gt;CC[0] = SBT/2+(24*SBT)  -     5
//       | | | | | | | | |                                              etc for pairs of bits
//       | | | | | | | | +------------------------------------------- Bit 1     Vote 3 pTimer4-&amp;gt;CC[2] = SBT/2+(8*SBT)   -     1
//       | | | | | | | +--------------------------------------------- Bit 1     Vote 2 pTimer4-&amp;gt;CC[1] = SBT/2+(7*SBT)   -     0
//       | | | | | | +----------------------------------------------- Bit 1     Vote 1 pTimer4-&amp;gt;CC[0] = SBT/2+(6*SBT)   -     5
//       | | | | | +------------------------------------------------- Bit 0     Vote 3 pTimer4-&amp;gt;CC[5] = SBT/2+(5*SBT)   *     4
//       | | | | +--------------------------------------------------- Bit 0     Vote 2 pTimer4-&amp;gt;CC[4] = SBT/2+(4*SBT)   -     3
//       | | | +----------------------------------------------------- Bit 0     Vote 1 pTimer4-&amp;gt;CC[3] = SBT/2+(3*SBT)   -     2
//       | | +------------------------------------------------------- Start Bit Vote 3 pTimer4-&amp;gt;CC[2] = SBT/2+(2*SBT)   -     1
//       | +--------------------------------------------------------- Start Bit Vote 2 pTimer4-&amp;gt;CC[1] = SBT/2+(1*SBT)   -     0
//       +----------------------------------------------------------- Start Bit Vote 1 pTimer4-&amp;gt;CC[0] = SBT/2           -     -

void RxTimerInit(void)
{
    // Errata: [78] TIMER: High current consumption when using timer STOP task only
    //  - Workaround: Use the SHUTDOWN task after the STOP task or instead of the STOP task
    //  - this also stops the Timer from hanging after a time change
    //  - affects nRF52832, nRF52840
    pTimer-&amp;gt;TASKS_SHUTDOWN = 1;
    // There is no STOPPED Event, and this register is read-only, so add a delay to ensure it is stopped before changes
    // pTimer-&amp;gt;TASKS_STOP = 1;
    nrf_gpio_cfg(DEBUG_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
    nrf_delay_us(200);
    // 32-bit timer
    pTimer-&amp;gt;MODE    = TIMER_MODE_MODE_Timer;
    pTimer-&amp;gt;BITMODE = TIMER_BITMODE_BITMODE_32Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;
    // 1us timer period
    pTimer-&amp;gt;PRESCALER = TIMER_PRESCALER &amp;lt;&amp;lt; TIMER_PRESCALER_PRESCALER_Pos; // 16/2^4 -&amp;gt; 1MHz, 16/2^8-&amp;gt;62.5KHz or 16uSec tick
    // Now clear timer register
    pTimer-&amp;gt;TASKS_CLEAR = 1;

    // Sample compare value, generates EVENTS_COMPARE[n]
    pTimer-&amp;gt;CC[0] = LL_SAMPLE_TIME / 2;
    pTimer-&amp;gt;CC[1] = LL_SAMPLE_TIME * 1 + LL_SAMPLE_TIME / 2;
    pTimer-&amp;gt;CC[2] = LL_SAMPLE_TIME * 2 + LL_SAMPLE_TIME / 2;
    pTimer-&amp;gt;CC[3] = LL_SAMPLE_TIME * 3 + LL_SAMPLE_TIME / 2;
    pTimer-&amp;gt;CC[4] = LL_SAMPLE_TIME * 4 + LL_SAMPLE_TIME / 2;
    pTimer-&amp;gt;CC[5] = LL_SAMPLE_TIME * 5 + LL_SAMPLE_TIME / 2;

    // Enable IRQ on EVENTS_COMPARE[n]
    pTimer-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE0_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE0_Pos;
    pTimer-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE1_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE1_Pos;
    pTimer-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE2_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE2_Pos;
    pTimer-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE3_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE3_Pos;
    pTimer-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE4_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE4_Pos;
    pTimer-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE5_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE5_Pos;

    // Clear the timer when COMPARE5 event is triggered
    pTimer-&amp;gt;SHORTS = (TIMER_SHORTS_COMPARE5_CLEAR_Enabled &amp;lt;&amp;lt; TIMER_SHORTS_COMPARE5_CLEAR_Pos);

    // Clear all events
    pTimer-&amp;gt;EVENTS_COMPARE[0] = 0;
    pTimer-&amp;gt;EVENTS_COMPARE[1] = 0;
    pTimer-&amp;gt;EVENTS_COMPARE[2] = 0;
    pTimer-&amp;gt;EVENTS_COMPARE[3] = 0;
    pTimer-&amp;gt;EVENTS_COMPARE[4] = 0;
    pTimer-&amp;gt;EVENTS_COMPARE[5] = 0;

    mRxIndex = 0;

    // Set interrupt priority and enable interrupt
    NVIC_SetPriority(PWM_TIMER_IRQn, 6);
    NVIC_ClearPendingIRQ(PWM_TIMER_IRQn);

    // Clear the character ready to process event
    pNRF_EGU-&amp;gt;EVENTS_TRIGGERED[0] = 0;
    pNRF_EGU-&amp;gt;INTENSET = 1;
   // Set interrupt priority lower priority than timer and enable interrupt
    NVIC_SetPriority(SWI_EGU_IRQn, 6+1);
    NVIC_ClearPendingIRQ(SWI_EGU_IRQn);
    NVIC_EnableIRQ(SWI_EGU_IRQn);

    nrf_delay_us(100);
    NVIC_EnableIRQ(PWM_TIMER_IRQn);
    pTimer-&amp;gt;TASKS_START = 1;
}

// Event Generator Unit (EGUn)
void SWI4_EGU4_IRQHandler(void)
{
    // Handle the character ready to process event
    if (pNRF_EGU-&amp;gt;EVENTS_TRIGGERED[0])
    {
        // Clear the character ready to process event
        pNRF_EGU-&amp;gt;EVENTS_TRIGGERED[0] = 0;

        // copy data to release buffer or use dual buffare!!

        // stop character frame here, ready for next, process voting
        // Rx pins sample history, later copy this buffer and process outside ISR
        volatile uint32_t * PinSample = &amp;amp;mRxInputPinSamples[NUMBER_OF_RX_INPUT_PIN_SAMPLES_PER_VOTE];
        uint8_t RxByteP = 0, RxByteN = 0, RxBitMask = 0x01;

        for (uint32_t BitIndex = 1; BitIndex &amp;lt; NUMBER_OF_RX_INPUT_BITS - 1; BitIndex++, RxBitMask &amp;lt;&amp;lt;= 1)
        {
            uint32_t VoteP = 0, VoteN = 0;
            for (uint32_t VoteIndex = 0; VoteIndex &amp;lt; NUMBER_OF_RX_INPUT_PIN_SAMPLES_PER_VOTE; VoteIndex++, PinSample++)
            {
                VoteP += ((*PinSample &amp;amp; RX_NEG_INPUT_PIN_MASK) == 0 ? 1 : 0);
                VoteN += ((*PinSample &amp;amp; RX_POS_INPUT_PIN_MASK) == 0 ? 1 : 0);
            }
            if (VoteP &amp;gt;= (NUMBER_OF_RX_INPUT_PIN_SAMPLES_PER_VOTE + 1) / 2)
            {
                RxByteP |= RxBitMask;
            }
            if (VoteN &amp;gt;= (NUMBER_OF_RX_INPUT_PIN_SAMPLES_PER_VOTE + 1) / 2)
            {
                RxByteN |= RxBitMask;
            }
        }
        mRxInputPinSampleCount = 0;
        mRxByteN[mRxIndex] = RxByteN;
        mRxByteP[mRxIndex] = RxByteP;
        mRxIndex++;
    }
}

// This IRQ handler will trigger 3 times every Rx character bit
void TIMER3_IRQHandler(void)
{
    bool TerminateReception = false;

    NRF_GPIO-&amp;gt;OUTSET = (1 &amp;lt;&amp;lt; DEBUG_PIN);


    if (pTimer-&amp;gt;EVENTS_COMPARE[0] == 1)
    {
        // SCOPE_PROBE_2_HIGH;
        mRxInputPinSamples[mRxInputPinSampleCount++] = NRF_GPIO-&amp;gt;IN;
        pTimer-&amp;gt;EVENTS_COMPARE[0] = 0;
    }
    if (pTimer-&amp;gt;EVENTS_COMPARE[1] == 1)
    {
        mRxInputPinSamples[mRxInputPinSampleCount++] = NRF_GPIO-&amp;gt;IN;
        pTimer-&amp;gt;EVENTS_COMPARE[1] = 0;
        // Adjust initial Start Bit sample time back to same as other bits
        pTimer-&amp;gt;CC[0] = LL_SAMPLE_TIME;
    }
    if (pTimer-&amp;gt;EVENTS_COMPARE[2] == 1)
    {
        mRxInputPinSamples[mRxInputPinSampleCount++] = NRF_GPIO-&amp;gt;IN;
        pTimer-&amp;gt;EVENTS_COMPARE[2] = 0;
    }
    if (pTimer-&amp;gt;EVENTS_COMPARE[3] == 1)
    {
        mRxInputPinSamples[mRxInputPinSampleCount++] = NRF_GPIO-&amp;gt;IN;
        pTimer-&amp;gt;EVENTS_COMPARE[3] = 0;
    }
    if (pTimer-&amp;gt;EVENTS_COMPARE[4] == 1)
    {
        mRxInputPinSamples[mRxInputPinSampleCount++] = NRF_GPIO-&amp;gt;IN;
        pTimer-&amp;gt;EVENTS_COMPARE[4] = 0;
        if (mRxInputPinSampleCount &amp;gt;= COUNT_IS_STOP_BIT)
        {
            // Trigger the character ready to process event
            pNRF_EGU-&amp;gt;TASKS_TRIGGER[0] = 1;
            if (mRxIndex &amp;gt;= RX_BUFFER_SIZE)
            {
                TerminateReception = true;
            }
            // SCOPE_PROBE_2_LOW;
        }
    }
    if (pTimer-&amp;gt;EVENTS_COMPARE[5] == 1)
    {
        mRxInputPinSamples[mRxInputPinSampleCount++] = NRF_GPIO-&amp;gt;IN;
        pTimer-&amp;gt;EVENTS_COMPARE[5] = 0;
        //if (mRxInputPinSampleCount &amp;lt;= COUNT_IS_STOP_BIT)
        {
            // repeat here  for next 2 bits, use SHORTS
        }
        // Update sample compare value, generates EVENTS_COMPARE[n]
        pTimer-&amp;gt;CC[0] = LL_SAMPLE_TIME * 1;
        pTimer-&amp;gt;CC[1] = LL_SAMPLE_TIME * 2;
        pTimer-&amp;gt;CC[2] = LL_SAMPLE_TIME * 3;
        pTimer-&amp;gt;CC[3] = LL_SAMPLE_TIME * 4;
        pTimer-&amp;gt;CC[4] = LL_SAMPLE_TIME * 5;
        pTimer-&amp;gt;CC[5] = LL_SAMPLE_TIME * 6;
    }
    if (mRxInputPinSampleCount &amp;gt;= NUMBER_OF_INPUT_PIN_SAMPLES)
    {
        TerminateReception = true;
    }
    if (TerminateReception)
    {
        //pTimer-&amp;gt;TASKS_SHUTDOWN = 1;
        pTimer-&amp;gt;TASKS_STOP = 1;
        //pTimer-&amp;gt;SHORTS = (TIMER_SHORTS_COMPARE5_STOP_Enabled &amp;lt;&amp;lt; TIMER_SHORTS_COMPARE5_STOP_Pos);
    }
    // Clear pending hardware register bus operations
    __DSB();
    //nrf_delay_us(30);
    NRF_GPIO-&amp;gt;OUTCLR = (1 &amp;lt;&amp;lt; DEBUG_PIN);
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to wake UART from System-OFF without the use of RDY and REQ pins (or any sort of Hardware Flow Control), for an nRF54L15?</title><link>https://devzone.nordicsemi.com/thread/565919?ContentTypeID=1</link><pubDate>Tue, 05 May 2026 19:37:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d7497b71-302f-4737-bee8-c6a8a0f25ff5</guid><dc:creator>QuintonS</dc:creator><description>&lt;p&gt;Exactly! This is where my mind was going when we thought up just sampling the GPIO at the baudrate. We can by-pass the UART hardware issues and just decode the data ourselves to get the transmission back. Then we can orient the data by finding which bytes correspond to the preamble. Since I know we can get a UART up early enough in System-Off to capture part of the preamble, a GPIO pins is even more trivial.&lt;br /&gt;&lt;br /&gt;Interesting idea to sample even more frequently than needed to help reduce noise. I think this is the most ideal solution as it offers the most control over the physical data and prevents a poorly timed UART init from corrupting the data.&lt;br /&gt;&lt;br /&gt;Thanks for the reply and the diagrams explaining it in more detail. I&amp;#39;ll make sure to read into this a bit more too.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to wake UART from System-OFF without the use of RDY and REQ pins (or any sort of Hardware Flow Control), for an nRF54L15?</title><link>https://devzone.nordicsemi.com/thread/565916?ContentTypeID=1</link><pubDate>Tue, 05 May 2026 19:20:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c85efa24-cc77-47b8-b3e3-f44693992602</guid><dc:creator>QuintonS</dc:creator><description>&lt;p&gt;The problem with this is that UART hardware can&amp;#39;t tell the difference between a first true start bit edge (hi-&amp;gt;lo) and just some random data bit flipping the RX line. If the UART peripheral capture triggers on a data bit pulling RX down and not the start bit, the capture frame is fundamentally corrupted and the hardware has no way to recover from that. Any data the UART pushed to the DMA (if it even manages to get a valid frame by chance) will be corrupted.&lt;br /&gt;&lt;br /&gt;I could be miss-understanding the inner workings of UART but from my testing this is exactly what is happening. I can wake the UART up fast enough to begin capturing part of the preamble but the received data is sometimes correct, other times completely garbage.&lt;br /&gt;&lt;br /&gt;Just to address the timings you mentioned, from my testing I found that POST_KERNEL takes roughly 11 [ms] to reach. This is what led to moving the initialization to PRE_KERNEL_1 which is sufficiently early to start the capture during the preamble window.&lt;br /&gt;&lt;br /&gt;You mentioned an interesting point about System-On where disabling the UART reduces its power draw. I think you are completely correct with that. We just did some more testing of the power draw in System-On mode and it is a lot lower than our previous results managing to maintain a idle draw in the 6 [uA] region. I will try some more tests with exactly this just to verify.&lt;br /&gt;&lt;br /&gt;Building on the System-On solution some more, setting the GPIO pin to trigger the DPPI to bring up the UART and DMA could potentially work and allow us to capture immediately. This may allow us to get past the hardware limitation (I could be wrong about there even being one).&lt;br /&gt;&lt;br /&gt;Thanks for the reply and hopefully we&amp;#39;ll having some more information soon here.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to wake UART from System-OFF without the use of RDY and REQ pins (or any sort of Hardware Flow Control), for an nRF54L15?</title><link>https://devzone.nordicsemi.com/thread/565913?ContentTypeID=1</link><pubDate>Tue, 05 May 2026 18:01:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:395d8421-c96b-4f73-ac2b-2aa271175d02</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Preambles are usually known and could therefore be used to correlate (slide against) an otherwise unknown bit stream. However a timer-based Rx might be worth investigating as that would require less power than a UART methinks. I tested this approach a while back; it works well.&lt;/p&gt;
&lt;p&gt;Single bit sample, dual timers (T3 and T4), no reload:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Standard Uart character 0x21 - Single sample, dual timers (T3 and T4), no reload
//
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//      |     |     |     |     |     |     |     |     |     |     |
// Idle &amp;#39;Start&amp;#39;Bit 0&amp;#39;Bit 1&amp;#39;Bit 2&amp;#39;Bit 3&amp;#39;Bit 4&amp;#39;Bit 5&amp;#39;Bit 6&amp;#39;Bit 7&amp;#39;Stop &amp;#39;  Idle
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |                       |     |           |
//      |     |     |                       |     |           |       Normal
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//      |     |     |                       |     |           |       Invert
//      |     |     |                       |     |           |
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//         |     |     |     |     |     |     |     |     |     |                                          Clear
//         |     |     |     |     |     |     |     |     |     +--- Stop bit  pTimer4-&amp;gt;CC[5] = BT/2+(9*BT)  *
//         |     |     |     |     |     |     |     |     +--------- Bit 7     pTimer4-&amp;gt;CC[4] = BT/2+(8*BT)  -
//         |     |     |     |     |     |     |     +--------------- Bit 6     pTimer4-&amp;gt;CC[3] = BT/2+(7*BT)  -
//         |     |     |     |     |     |     +--------------------- Bit 5     pTimer4-&amp;gt;CC[2] = BT/2+(6*BT)  -
//         |     |     |     |     |     +--------------------------- Bit 4     pTimer4-&amp;gt;CC[1] = BT/2+(5*BT)  -
//         |     |     |     |     +--------------------------------- Bit 3     pTimer4-&amp;gt;CC[0] = BT/2+(4*BT)  -
//         |     |     |     +--------------------------------------- Bit 2     pTimer3-&amp;gt;CC[3] = BT/2+(3*BT)  -
//         |     |     +--------------------------------------------- Bit 1     pTimer3-&amp;gt;CC[2] = BT/2+(2*BT)  -
//         |     +--------------------------------------------------- Bit 0     pTimer3-&amp;gt;CC[1] = BT/2+(1*BT)  -
//         +--------------------------------------------------------- Start Bit pTimer3-&amp;gt;CC[0] = BT/2         -
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Single bit sample, single timer (T4), requires reload:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Standard Uart character 0x21 - Single sample, single timer (T4), requires reload
//
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//      |     |     |     |     |     |     |     |     |     |     |
// Idle &amp;#39;Start&amp;#39;Bit 0&amp;#39;Bit 1&amp;#39;Bit 2&amp;#39;Bit 3&amp;#39;Bit 4&amp;#39;Bit 5&amp;#39;Bit 6&amp;#39;Bit 7&amp;#39;Stop &amp;#39;  Idle
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |                       |     |           |
//      |     |     |                       |     |           |       Normal
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//      |     |     |                       |     |           |       Invert
//      |     |     |                       |     |           |
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |     |     |     |     |     |     |     |     |
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//      |     |     |     |     |     |     |     |     |     |     |
//         |     |     |     |     |     |     |     |     |     |                                          Clear Reload
//         |     |     |     |     |     |     |     |     |     +--- Stop bit  pTimer4-&amp;gt;CC[3] = BT/2+(9*BT) *      2,3,0
//         |     |     |     |     |     |     |     |     +--------- Bit 7     pTimer4-&amp;gt;CC[2] = BT/2+(8*BT) -      1
//         |     |     |     |     |     |     |     +--------------- Bit 6     pTimer4-&amp;gt;CC[1] = BT/2+(7*BT) -      0
//         |     |     |     |     |     |     +--------------------- Bit 5     pTimer4-&amp;gt;CC[0] = BT/2+(6*BT) -      -
//         |     |     |     |     |     +--------------------------- Bit 4     pTimer4-&amp;gt;CC[5] = BT/2+(5*BT) *      -
//         |     |     |     |     +--------------------------------- Bit 3     pTimer4-&amp;gt;CC[4] = BT/2+(4*BT) -      -
//         |     |     |     +--------------------------------------- Bit 2     pTimer4-&amp;gt;CC[3] = BT/2+(3*BT) -      2
//         |     |     +--------------------------------------------- Bit 1     pTimer4-&amp;gt;CC[2] = BT/2+(2*BT) -      1
//         |     +--------------------------------------------------- Bit 0     pTimer4-&amp;gt;CC[1] = BT/2+(1*BT) -      0
//         +--------------------------------------------------------- Start Bit pTimer4-&amp;gt;CC[0] = BT/2        -      -
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;More robust (better noise immunity) 3-vote bit samples, single timer (T4), SBT=BT/3, requires reload:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Standard Uart character 0x21 - 3-vote samples, single timer (T4), SBT=BT/3, requires reload
//
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//      |     |     |     |     |     |     |     |     |     |     |
// Idle &amp;#39;Start&amp;#39;Bit 0&amp;#39;Bit 1&amp;#39;Bit 2&amp;#39;Bit 3&amp;#39;Bit 4&amp;#39;Bit 5&amp;#39;Bit 6&amp;#39;Bit 7&amp;#39;Stop &amp;#39;  Idle
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |                       |     |           |
//      |     |     |                       |     |           |       Normal
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//
//      +-----+     +-----+-----+-----+-----+     +-----+-----+
//      |     |     |                       |     |           |       Invert
//      |     |     |                       |     |           |
// -----+     +-----+                       +-----+           +-----+-------
//      |     |     |     |     |     |     |     |     |     |     |
//      |     |     |     |     |     |     |     |     |     |     | Bit Framing
//      |     |     |     |     |     |     |     |     |     |     |
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |                                                  Clear Reload
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +- Stop Bit  after 1/2 Stop bit wait for next Start  -     -
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | | +--- Stop Bit  Check  pTimer4-&amp;gt;CC[4] = SBT/2+(28*SBT)  *     3,4,0
//       | | | | | | | | | | | | | | | | | | | | | | | | | | | +----- Stop Bit  Check  pTimer4-&amp;gt;CC[3] = SBT/2+(27*SBT)  -     2
//       | | | | | | | | | | | | | | | | | | | | | | | | | | +------- Bit 7     Vote 3 pTimer4-&amp;gt;CC[2] = SBT/2+(26*SBT)  -     1
//       | | | | | | | | | | | | | | | | | | | | | | | | | +--------- Bit 7     Vote 2 pTimer4-&amp;gt;CC[1] = SBT/2+(25*SBT)  -     0
//       | | | | | | | | | | | | | | | | | | | | | | | | +----------- Bit 7     Vote 1 pTimer4-&amp;gt;CC[0] = SBT/2+(24*SBT)  -     5
//       | | | | | | | | |                                              etc for pairs of bits
//       | | | | | | | | +------------------------------------------- Bit 1     Vote 3 pTimer4-&amp;gt;CC[2] = SBT/2+(8*SBT)   -     1
//       | | | | | | | +--------------------------------------------- Bit 1     Vote 2 pTimer4-&amp;gt;CC[1] = SBT/2+(7*SBT)   -     0
//       | | | | | | +----------------------------------------------- Bit 1     Vote 1 pTimer4-&amp;gt;CC[0] = SBT/2+(6*SBT)   -     5
//       | | | | | +------------------------------------------------- Bit 0     Vote 3 pTimer4-&amp;gt;CC[5] = SBT/2+(5*SBT)   *     4
//       | | | | +--------------------------------------------------- Bit 0     Vote 2 pTimer4-&amp;gt;CC[4] = SBT/2+(4*SBT)   -     3
//       | | | +----------------------------------------------------- Bit 0     Vote 1 pTimer4-&amp;gt;CC[3] = SBT/2+(3*SBT)   -     2
//       | | +------------------------------------------------------- Start Bit Vote 3 pTimer4-&amp;gt;CC[2] = SBT/2+(2*SBT)   -     1
//       | +--------------------------------------------------------- Start Bit Vote 2 pTimer4-&amp;gt;CC[1] = SBT/2+(1*SBT)   -     0
//       +----------------------------------------------------------- Start Bit Vote 1 pTimer4-&amp;gt;CC[0] = SBT/2           -     -
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to wake UART from System-OFF without the use of RDY and REQ pins (or any sort of Hardware Flow Control), for an nRF54L15?</title><link>https://devzone.nordicsemi.com/thread/565863?ContentTypeID=1</link><pubDate>Tue, 05 May 2026 07:26:34 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f905598f-8d76-4fde-b045-be647bb6d073</guid><dc:creator>Bjarki Andreasen</dc:creator><description>&lt;p&gt;In short, there is no way to capture the first byte(s) sent from the target device if the SoC is in System off. This is because the UART is not active in this mode.&lt;/p&gt;
&lt;p&gt;The expected current for sleeping while waiting for UART is around 130uA, as the system must be in System on all idle with the UART RX enabled. This is the &amp;quot;normal&amp;quot;, though pretty power hungry way to wait for UART data.&lt;/p&gt;
&lt;p&gt;System on all idle can achieve around 5uA if the UART is not enabled, the wakeup time is around 7us. System off acheives way lower, with a startup time of aroung 60us. If you are okay with loosing the first UART byte, you could either:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;If system on all idle, Deinit the UART, configure the RX pin as gpio interrupt, wait for interrupt, immediately reinit the UART.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;If System off, disable the UART, configure RX pin as GPIO wakeup, on wakeup, configure UART (should be automatic since system is rebooting)&lt;/p&gt;
&lt;p&gt;At 9600 baudrate, the first byte will take around&amp;nbsp;(1 / 9600) * 11 = 1.1ms so the SoC has plenty of time to wake up before the second byte.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If its imperitive that the first byte is not lost, best case is still those 130uA.&lt;/p&gt;
&lt;p&gt;Regarding the external UART with FIFO, that could surely work if you find a particularly low power one. But that is of course quite costly, and will use more current while active compared to using the internal UART given you now have the SoC + some bus + external UART enabled while talking to your target device.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>