<?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 does an EGU register get a value?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/104266/how-does-an-egu-register-get-a-value</link><description>I have been trying to decipher the NRF specification documents to simply understand how PPI, interrupts, Tasks, Events, and EGUs are supposed to work together. I am still confused. Searching the DevZone, I came up with this post which refers to this nordic</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 29 Sep 2023 21:20:39 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/104266/how-does-an-egu-register-get-a-value" /><item><title>RE: How does an EGU register get a value?</title><link>https://devzone.nordicsemi.com/thread/448404?ContentTypeID=1</link><pubDate>Fri, 29 Sep 2023 21:20:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e6b96277-e119-424c-9673-6ec4f2db565d</guid><dc:creator>Omid</dc:creator><description>&lt;p&gt;Thanks, that is great!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How does an EGU register get a value?</title><link>https://devzone.nordicsemi.com/thread/448403?ContentTypeID=1</link><pubDate>Fri, 29 Sep 2023 21:13:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7bfcdb9e-8f8e-4cc7-ae1b-c493e5e1a946</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;The &lt;span&gt;&amp;quot;SWI4_EGU4_IRQHandler&amp;quot;&lt;/span&gt; is an interrupt function accessed only by an implicit assembly language call instruction&amp;nbsp;from the vector interrupt table, which resides at physical address 0000&amp;#39;0000 unless a bootloader or softdevice is used in which case&amp;nbsp;the&amp;nbsp;&lt;span&gt;vector interrupt table&amp;nbsp;&lt;/span&gt;can reside elsewhere and a vector register is used by the bootloader or softdevice to point at that vector table. That &lt;span&gt;SWI4_EGU4_IRQHandler&amp;nbsp;&lt;/span&gt;vector is instigated in hardware by EVENTS_TRIGGERED going active (&amp;#39;0&amp;#39; to &amp;#39;1&amp;#39;), which in turn goes to active &amp;#39;1&amp;#39; either by an enabled Hardware Event going active or by executing a software instruction TASKS_TRIGGER; the result is identical whether invoked via hardware event or software trigger.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;__vector_table
        DCD     sfe(CSTACK)
        DCD     Reset_Handler
        DCD     NMI_Handler
        DCD     HardFault_Handler
        DCD     MemoryManagement_Handler
        DCD     BusFault_Handler
        DCD     UsageFault_Handler
        DCD     0                         ; Reserved
        DCD     0                         ; Reserved
        DCD     0                         ; Reserved
        DCD     0                         ; Reserved
        DCD     SVC_Handler
        DCD     DebugMon_Handler
        DCD     0                         ; Reserved
        DCD     PendSV_Handler
        DCD     SysTick_Handler

        ; External Interrupts
        DCD     POWER_CLOCK_IRQHandler
        DCD     RADIO_IRQHandler
        DCD     UARTE0_UART0_IRQHandler
        DCD     SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
        DCD     SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
        DCD     NFCT_IRQHandler
        DCD     GPIOTE_IRQHandler
        DCD     SAADC_IRQHandler
        DCD     TIMER0_IRQHandler
        DCD     TIMER1_IRQHandler
        DCD     TIMER2_IRQHandler
        DCD     RTC0_IRQHandler
        DCD     TEMP_IRQHandler
        DCD     RNG_IRQHandler
        DCD     ECB_IRQHandler
        DCD     CCM_AAR_IRQHandler
        DCD     WDT_IRQHandler
        DCD     RTC1_IRQHandler
        DCD     QDEC_IRQHandler
        DCD     COMP_LPCOMP_IRQHandler
        DCD     SWI0_EGU0_IRQHandler
        DCD     SWI1_EGU1_IRQHandler
        DCD     SWI2_EGU2_IRQHandler
        DCD     SWI3_EGU3_IRQHandler
        DCD     SWI4_EGU4_IRQHandler
        DCD     SWI5_EGU5_IRQHandler
        DCD     TIMER3_IRQHandler
        DCD     TIMER4_IRQHandler
        DCD     PWM0_IRQHandler
        DCD     PDM_IRQHandler
        DCD     0                         ; Reserved
        DCD     0                         ; Reserved
        DCD     MWU_IRQHandler
        DCD     PWM1_IRQHandler
        DCD     PWM2_IRQHandler
        DCD     SPIM2_SPIS2_SPI2_IRQHandler
        DCD     RTC2_IRQHandler
        DCD     I2S_IRQHandler
        DCD     FPU_IRQHandler
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Yes, init() only executes once usually from main().&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How does an EGU register get a value?</title><link>https://devzone.nordicsemi.com/thread/448398?ContentTypeID=1</link><pubDate>Fri, 29 Sep 2023 19:26:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b4209dae-cc11-42a0-aa1f-204a8cc81c61</guid><dc:creator>Omid</dc:creator><description>&lt;p&gt;Thanks for your answer&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/members/hmolesworth"&gt;hmolesworth&lt;/a&gt;&amp;nbsp;, could you also tell me what calls the &amp;quot;SWI4_EGU4_IRQHandler&amp;quot;? what tiggers that?&amp;nbsp;&lt;br /&gt;&lt;br /&gt;My educated guess is that whenever the timer call back executes the timer handler it would write on the &amp;quot;EVENTS_TRIGGERED&amp;quot; register of the NRF_EGU4, upon which the &amp;quot;SWI4_EGU4_IRQHandler&amp;quot; will be automatically executed. (In other words,&amp;nbsp;there is a mechanism continually monitoring the&amp;nbsp;&lt;span&gt;EVENTS_TRIGGERED register and, the moment there is a registered event, it will trigger the handler.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Also, shouldn&amp;#39;t the &amp;quot;init()&amp;quot; function be called inside the&amp;nbsp;main {} function? (I guess you assumed that an obvious thing, just asking for more clarity)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How does an EGU register get a value?</title><link>https://devzone.nordicsemi.com/thread/448227?ContentTypeID=1</link><pubDate>Thu, 28 Sep 2023 22:51:01 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:41ed871b-647e-4898-96d5-ee2cd05d2a28</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;I can give a guide following my own understanding, probably not following the documentation .. anyway Hardware Events can trigger other Hardware Events. Any Hardware Event can &lt;em&gt;optionally&lt;/em&gt; be linked to an interrupt vector. A Hardware Event is not an interrupt; Hardware Events and interrupts are enabled differently, one does not infer the other.&lt;/p&gt;
&lt;p&gt;Here is my example of using an EGU to move some data processing out of a critical timing interrupt into a less-critical timing EGU interrupt to avoid missing the other time-critical timer events. I put this first (not what you are seeking) as it shows the exact way the EGU Hardware Event with corresponding EQU interrupt is triggered, in this case by a software instruction (instigating the Hardware Task):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Event Generator Unit (EGUn)
static NRF_EGU_Type* pNRF_EGU = NRF_EGU4;
#define SWI_EGU_IRQn SWI4_EGU4_IRQn

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;
        // Slow stuff goes here moved from timer interupt
    }
}

void init(void)
{
    // EGU setup 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);
}
// This IRQ handler will trigger 3 times every Rx character bit
void TIMER3_IRQHandler(void)
{
    .. snip other events
    if (pTimer-&amp;gt;EVENTS_COMPARE[4] == 1)
    {
        pTimer-&amp;gt;EVENTS_COMPARE[4] = 0;
        if (blahblah
        {
            // Trigger the character ready to process event by activating the lower-priority EGU interrupt
            pNRF_EGU-&amp;gt;TASKS_TRIGGER[0] = 1;
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Example of using an EGU to process a Hardware Event directly (not via software instruction) by instigating an EGU&amp;nbsp;Hardware Event (Task) from the timer (or other) Hardware Event. This EGU Hardware Event can optionally trigger the associated EGU software interrupt:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Event Generator Unit (EGUn)
static NRF_EGU_Type* pNRF_EGU = NRF_EGU4;
#define SWI_EGU_IRQn SWI4_EGU4_IRQn

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;
        // etc
    }
}

void init(void)
{
    // Configure PPI channel with connection between pTIMER-&amp;gt;EVENTS_COMPARE[4] and pNRF_EGU-&amp;gt;TASKS_TRIGGER[0]
    NRF_PPI-&amp;gt;CH[PPI_CHANNEL].EEP = (uint32_t)&amp;amp;pTimer-&amp;gt;EVENTS_COMPARE[4];
    NRF_PPI-&amp;gt;CH[PPI_CHANNEL].TEP = (uint32_t)&amp;amp;pNRF_EGU-&amp;gt;TASKS_TRIGGER[0];
    // EGU setup 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);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Any Hardware Event can similarly be linked to an EGU Hardware Event (and thus an EGU software interrupt) by this PPI mechanism.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>