<?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 do I interrupt an event handler?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/93592/how-do-i-interrupt-an-event-handler</link><description>Hi, 
 I&amp;#39;m extremely new to Nordic (and embedded development in general), but I&amp;#39;m writing some code that turns on various LED colors based on input from an Android app (BLE). This app may send multiple channels right after the other (e.g. R=100,G=90,B</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 11 Nov 2022 23:27:28 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/93592/how-do-i-interrupt-an-event-handler" /><item><title>RE: How do I interrupt an event handler?</title><link>https://devzone.nordicsemi.com/thread/395407?ContentTypeID=1</link><pubDate>Fri, 11 Nov 2022 23:27:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:64499fdf-8398-4b36-977f-c5d70c747e96</guid><dc:creator>ellamoss</dc:creator><description>&lt;p&gt;Yes, this is perfect! I&amp;#39;m using setup 3 now but I&amp;#39;ll look into app timers with the ble_app_hrs example. Thank you!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do I interrupt an event handler?</title><link>https://devzone.nordicsemi.com/thread/395401?ContentTypeID=1</link><pubDate>Fri, 11 Nov 2022 22:45:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ed4aac22-9454-4a4e-8d9c-87ebd429b0e4</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Sorry for the long delay. I got some backlog piling up.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here are some pseudo code of what I understand your setups:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;// Setup 1
void new_red_goal_handler(new_red_goal)     { red_goal      = new_red_goal; }
void new_green_goal_handler(new_green_goal) { green_goal    = new_green_goal; }
void new_blue_goal_handler(new_blue_goal)   { blue_goal     = new_blue_goal; }

void main(void) {
    ...
    while (1) {
        if (red_now &amp;lt; red_goal) red_now++;
        if (red_now &amp;gt; red_goal) red_now--;
        if (green_now &amp;lt; green_goal) green_now++;
        if (green_now &amp;gt; green_goal) green_now--;
        if (blue_now &amp;lt; blue_goal) blue_now++;
        if (blue_now &amp;gt; blue_goal) blue_now--;
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;// Setup 2

void update_levels(void) {
    while (1) {
        if (red_now &amp;lt; red_goal) red_now++;
        if (red_now &amp;gt; red_goal) red_now--;
        if (green_now &amp;lt; green_goal) green_now++;
        if (green_now &amp;gt; green_goal) green_now--;
        if (blue_now &amp;lt; blue_goal) blue_now++;
        if (blue_now &amp;gt; blue_goal) blue_now--;
        nrf_delay_us(200);
    }
}

void new_red_goal_handler(new_red_goal) { 
    red_goal      = new_red_goal;
    update_levels();
}
void new_green_goal_handler(new_green_goal) {
    green_goal    = new_green_goal;
    update_levels();
}
void new_blue_goal_handler(new_blue_goal) {
    blue_goal     = new_blue_goal;
    update_levels();
}

void main(void) {
    ...
    while (1) {
        // Nothing
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;// Setup 3

void update_levels(void) {
    while (1) {
        if (red_now &amp;lt; red_goal) red_now++;
        if (red_now &amp;gt; red_goal) red_now--;
        if (green_now &amp;lt; green_goal) green_now++;
        if (green_now &amp;gt; green_goal) green_now--;
        if (blue_now &amp;lt; blue_goal) blue_now++;
        if (blue_now &amp;gt; blue_goal) blue_now--;
        nrf_delay_us(200);
    }
}

void new_red_goal_handler(new_red_goal)     { red_goal      = new_red_goal; }
void new_green_goal_handler(new_green_goal) { green_goal    = new_green_goal; }
void new_blue_goal_handler(new_blue_goal)   { blue_goal     = new_blue_goal; }

void main(void) {
    ...
    while (1) {
        __WFI();
        update_levels();
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Is that about correct?&lt;/p&gt;
&lt;p&gt;If that is correct, then:&lt;/p&gt;
&lt;p&gt;Setup 1 will work.&lt;/p&gt;
&lt;p&gt;Setup 2 will also work. But as you said, only one color channel can be updated at a time.&lt;br /&gt;The reason is that all the work is done in the handler.&amp;nbsp;As you probably have guessed given your question, the other handlers cannot interrupt this, because they are all of the same priority.&lt;br /&gt;Performing significant amount of work in a handler is not a good idea. When it is a&amp;nbsp;loop that takes a significant amount of time, it is even worse. &lt;br /&gt;Setup 2&amp;nbsp;is not recommended at all.&lt;/p&gt;
&lt;p&gt;Setup 3 will work only if you have a consistent source of events or interrupts.&amp;nbsp;If your device is advertising or keeping a connection, that will do.&amp;nbsp;It can be better regarding power consumption. However, behavior wise, it should be no difference.&lt;br /&gt;There is technically the risk that if a connection is dropped, and the device does not advertise anymore, and thus run out of event to wake up with, then it will go to sleep forever. That is unless you have a different source of periodic events/interrupts.&lt;/p&gt;
&lt;p&gt;The strategy in Setup 1 is alright if your application is simple. Is there a reason you don&amp;#39;t like having the code run in a busy loop?&lt;/p&gt;
&lt;p&gt;If you wish for all three color channels to&amp;nbsp;change at the same time, maybe you can setup so they are all updated in the same handler?&lt;/p&gt;
&lt;p&gt;Finally, it can be improved in response time and power consumption with an App Timer.&amp;nbsp;The risk in Setup 3 will also be eliminated. If you are interested, the ble_app_hrs&amp;nbsp;uses it.&lt;/p&gt;
&lt;p&gt;If you need further help to set it up, or have any questions, just let me know. This comment got kind of long.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do I interrupt an event handler?</title><link>https://devzone.nordicsemi.com/thread/394996?ContentTypeID=1</link><pubDate>Wed, 09 Nov 2022 19:16:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d3e641e3-6ca5-423d-ad00-20913d9a9f36</guid><dc:creator>ellamoss</dc:creator><description>&lt;p&gt;The basic event handler just sets global variables, e.g. red_goal = [what comes in from the BLE app]. It&amp;#39;s triggered on the BLE_GATTS_EVT_WRITE event.&lt;/p&gt;
&lt;p&gt;Then, once those variables are all updated, I want to run the update_levels() code, which I&amp;#39;ve provided above.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve just read about the __WFI() functionality. I think this is the solution to my problem. I&amp;#39;ve moved the update_levels() out of the event handler, and then moved this code into main:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;while(1){
    __WFI();
    update_levels();
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Is this doing what I think it is? That is, does it just wait for an interrupt in a low-power state, then update_levels() when an interrupt comes in?&lt;/p&gt;
&lt;p&gt;Thanks for your help.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How do I interrupt an event handler?</title><link>https://devzone.nordicsemi.com/thread/394528?ContentTypeID=1</link><pubDate>Mon, 07 Nov 2022 17:15:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:16115803-b687-477f-809d-81bd410e9d65</guid><dc:creator>Hieu</dc:creator><description>&lt;p&gt;Hi ellamoss,&lt;/p&gt;
&lt;p&gt;It is nice to have someone joining the same field. All the more when they are trying to start with our solution. Welcome abroad! :D&lt;/p&gt;
&lt;p&gt;To better understand this, could you please explain what kind of event handler are we talking about here? What triggers the handler? What kind of data transmission do you have?&lt;/p&gt;
&lt;p&gt;It is generally not a good idea to do a lot of things in the event handlers, since it happens in the interrupt context and blocks execution of other lower-priority handlers and the main loop. Let&amp;#39;s take a look at your setup and see if it is okay in this case, or if there is any better approach.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Hieu&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>