<?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 send a sequence of indications?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications</link><description>I need to indicate a characteristic value that is longer than the MTU. Using the pc-ble-driver, no problem. Windows supports semaphores and I can call sd_ble_gatts_hvx(), wait on a semaphore, and release the semaphore in the BLE_GATTS_EVT_HVC event and</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Sun, 24 Jan 2021 22:22:05 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications" /><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/290878?ContentTypeID=1</link><pubDate>Sun, 24 Jan 2021 22:22:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9f6eef11-b7f4-4998-bcb4-cc47554a3494</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;Turns out all the issues I was having had nothing to do with indication sequences and handling of the sd_ble_evt_get().&lt;/p&gt;
&lt;p&gt;It was NRF_LOG_DEBUG. I guess I was trying to write an array of bytes converted to a HEX string that was too long. I do not know what the limit is, but commenting out that line of code solved the problem. Cost me a week and a half of hair pulling frustration.&lt;/p&gt;
&lt;p&gt;Was looking for answers in all the wrong places....&lt;/p&gt;
&lt;p&gt;So the approach I took where in the for(;;) loop I handle the sd_app_evt_wait()&lt;/p&gt;
&lt;p&gt;followed by the sd_ble_evt_get() with all its own loops but eventual dispatch on&lt;/p&gt;
&lt;p&gt;ble_evt_dispatch()&lt;/p&gt;
&lt;p&gt;I put the command handler in a one-short timer and set a flag if data needed to be indicated&lt;/p&gt;
&lt;p&gt;The indicate_data() method was in that main for(;;) loop. It would only get invoked if the flag was set.&lt;/p&gt;
&lt;p&gt;Though the final solution is VERY different than any of the health device examples it works. It might be good if you had an example which illustrated this kind of process. THough it is no semaphore; it accomplishes what a semaphore would have done. But it is much more like a basic embedded loop where you loop through, perform/handle one task, loop again and handle the next and so on.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/290322?ContentTypeID=1</link><pubDate>Wed, 20 Jan 2021 15:23:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:98dbff2c-6e48-4c4c-9eec-a4a7d4b6f888</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;Okay, I looked at the thread mode which I am doing or trying to do. However, it contradicts what I have read in the documentation. The docs say that I need to call the sd_ble_evt_get() until I drain all the queued events. That&amp;#39;s not what I see in the message flow. The message flow says to call the sd_app_evt_wait() after the call with response NRF_SUCCESS.&lt;/p&gt;
&lt;p&gt;I am not doing that now (though things are still not working). Which is correct? cycle through the sd_ble_evt_get() and dispatch event until I get no more events OR call once, dispatch event, call sd_app_evt_wait and repeat?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/290277?ContentTypeID=1</link><pubDate>Wed, 20 Jan 2021 13:46:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:50ac62d5-02a3-4ed0-a828-0776928cd035</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Events are removed from the Softdevice&amp;#39;s internal event buffer when you run the event get functions. So,&amp;nbsp; these functions should not be called from multiple places in your code.&lt;/p&gt;
&lt;p&gt;You may use the &amp;quot;Thread mode event&amp;quot; retrival approach shown by the sequence chart linked to below if you preffer to poll the SD events from the main loop. Just make sure the Softdevice interrupt is not enabled in that case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Relevant Message Sequence Charts&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;&lt;a href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.api.v3.0.0/group___b_l_e___c_o_m_m_o_n___i_r_q___e_v_t___m_s_c.html"&gt;Interrupt-driven Event Retrieval&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;
&lt;p&gt;&lt;a href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.api.v3.0.0/group___b_l_e___c_o_m_m_o_n___t_h_r_e_a_d___e_v_t___m_s_c.html"&gt;Thread Mode Event Retrieval&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Also, a bit back to the original topic, you can take a look at the ancs_tx_buffer.c implementation in the ble_app_ancs_c example to see how we use a ring buffer to queue up multiple indication packets in the application.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/290171?ContentTypeID=1</link><pubDate>Wed, 20 Jan 2021 09:39:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d3774f8b-282b-4079-bb7b-dfb159117f8a</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;Yes, I found the sd_ble_evt_get() method. The documentation itself is pretty good, but the search engine stinks. It doesn&amp;#39;t even find text on the same page that you put into the search bar. I stumbled on this method after methodically looking for every &amp;#39;function&amp;#39; list I could find in the SoftDevice.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I also did a simple experiment by putting a handler in the that final for-loop and trying each of the sd_*_get() methods that had to do with getting events and printing the results. I didn&amp;#39;t try the sd_ble_evt-get() method yet as it was the last one I found.&lt;/p&gt;
&lt;p&gt;In my case&amp;nbsp;&lt;span&gt;sd_nvic_GetPendingIRQ(SWI2_IRQn)&amp;nbsp; always returned true and quickly overflowed the print buffer.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I am not using the SDK for a couple of reasons - I want to minimize SDK calls making portability from one chip to another as well as portability to newer versions much simpler. There were HUGE changes in the SDK from s110 v 8 to s130 v 12.3 demanding major code re-writes. However, after converting the old s110 v 8 code to using JUST SoftDevice, moving to s130 was very simple and took but a few minutes. Changes to move from nRF51822 to nRF52840 using just SoftDevice are also minimal. I personally find it easier sticking with BLE fundamentals which SoftDevice gives; you know that every BLE API must be able to perform certain basic tasks. Those I know. Learning how an SDK wrapper works is always a big commitment.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;BUT the biggest reason for sticking with SoftDevice only is that I also have code for the pc-ble-driver which ONLY has SoftDevice. It&amp;#39;s a great test platform as you can use the PC.&amp;nbsp;Having all code bases as similar and as portable as possible is clearly advantageous.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Now I try sd_ble_evt_get() in my test loop and see what it gives me. First and foremost, &lt;strong&gt;who gets the event first.&lt;/strong&gt; My test loop or my ble event dispatch function that appears in all the Nordic health device examples?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Result of try&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Well it looks like the event handler I registered with SoftDevice gets it first and when I get it in the main &amp;#39;for&amp;#39; loop the event is already drained. So that means (I guess) that I need to call my event handler from my &amp;#39;test&amp;#39; method where I call sd_ble_evt_get().&amp;nbsp; AND do NOT register my event handler with SoftDevice. (Does this slow things down?)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The whole purpose is, again, to allow me to call the indication method repeatedly in a &amp;#39;BUSY&amp;#39; loop without hanging. Since I would be calling my event handler from the main for-loop, the event handler and the timer should all be in the main process.&amp;nbsp; &amp;nbsp;I hope.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/290125?ContentTypeID=1</link><pubDate>Wed, 20 Jan 2021 07:38:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:033955f9-c757-43f3-b4b4-9326c160eb1b</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;So I guess you are not using the &lt;span class="item"&gt;&lt;a class="" title="SoftDevice handler library" href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v12.3.0/lib_softdevice_handler.html?cp=7_5_9_3_32"&gt;SoftDevice handler library&lt;/a&gt;&lt;/span&gt; to retreive and forward Softdevice events as you are trying to implement this mechanism yourself? To get BLE events, you will need to call sd_ble_evt_get(). sd_evt_get() is for SoC events like you said.&lt;/p&gt;
[quote userid="83646" url="~/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications/290015#290015"]Do I have to deal with this function: sd_nvic_GetPendingIRQ()? If so, what is the correct&amp;nbsp;IRQn_Type to use? Is it SWI2_IRQn? How would I use this function to get the BLE events?[/quote]
&lt;p&gt;I recommend you review the existing softdevice_handler.c implementation to see how it&amp;#39;s done there. You may also want to read up on the ARM Cortex M exception model to get a better understandig of interrupts work on this chip.&lt;/p&gt;
&lt;p&gt;sd_nvic_GetPendingIRQ(SWI2_IRQn) is always going return false because the interrupt pending bit is cleared as soon as the interrupt is serviced by the&amp;nbsp; SWI2_IRQHandler (Note: SWI2_IRQHandler&amp;nbsp; is redefined to SOFTDEVICE_EVT_IRQHandler in sdk code). It only makes sense to use sd_nvic_GetPendingIRQ() if the interrupt is masked (ie temporarly disabled)&lt;/p&gt;
[quote userid="83646" url="~/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications/290015#290015"]When you say app will wake up you mean my app, correct?[/quote]
&lt;p&gt;Yes, correct. The program will return from the sd_app_evt_wait() call when an application interrupt has been triggered. &lt;/p&gt;
[quote userid="83646" url="~/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications/290015#290015"]How do I poll the softdevice event queue? I have not found a method to do that.[/quote]
&lt;p&gt;With sd_evt_get() and sd_ble_evt_get()&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/290015?ContentTypeID=1</link><pubDate>Tue, 19 Jan 2021 13:36:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c800767d-5600-4dcd-9013-4f217d618298</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;It appears something you have told me is wrong. When sd_app_evt_wait() returns the only function I have at my disposal is sd_evt_get(). This method reports these events according to the documentation:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;enum NRF_SOC_EVTS
{
  NRF_EVT_HFCLKSTARTED,                         /**&amp;lt; Event indicating that the HFCLK has started. */
  NRF_EVT_POWER_FAILURE_WARNING,                /**&amp;lt; Event indicating that a power failure warning has occurred. */
  NRF_EVT_FLASH_OPERATION_SUCCESS,              /**&amp;lt; Event indicating that the ongoing flash operation has completed successfully. */
  NRF_EVT_FLASH_OPERATION_ERROR,                /**&amp;lt; Event indicating that the ongoing flash operation has timed out with an error. */
  NRF_EVT_RADIO_BLOCKED,                        /**&amp;lt; Event indicating that a radio timeslot was blocked. */
  NRF_EVT_RADIO_CANCELED,                       /**&amp;lt; Event indicating that a radio timeslot was canceled by SoftDevice. */
  NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**&amp;lt; Event indicating that a radio timeslot signal callback handler return was invalid. */
  NRF_EVT_RADIO_SESSION_IDLE,                   /**&amp;lt; Event indicating that a radio timeslot session is idle. */
  NRF_EVT_RADIO_SESSION_CLOSED,                 /**&amp;lt; Event indicating that a radio timeslot session is closed. */
  NRF_EVT_NUMBER_OF_EVTS
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;These are useless to me and have nothing to do with Bluetooth. How do I get the BLE events?&lt;/p&gt;
&lt;p&gt;Do I have to deal with this function: sd_nvic_GetPendingIRQ()? If so, what is the correct&amp;nbsp;IRQn_Type to use? Is it SWI2_IRQn? How would I use this function to get the BLE events?&lt;/p&gt;
&lt;p&gt;When you say app will wake up you mean my app, correct?&lt;/p&gt;
&lt;p&gt;How do I poll the softdevice event queue? I have not found a method to do that.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289996?ContentTypeID=1</link><pubDate>Tue, 19 Jan 2021 12:28:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b7e9840e-1ae1-41b8-8507-09b33435c217</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Application event comes from the interrupts sources listed in&amp;nbsp; the nrf51.h header. I&amp;#39;ve highlighted those that are reserved to the Softdevice in the image below. Interrupts reserved by the Softdevice are proccessed in the background without invoking the application.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1611058812838v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
[quote user="brianreinhold"]what events would cause &amp;#39;my_command_handler&amp;#39; to be called? Would a&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE cause the&amp;nbsp;sd_app_evt_wait() to return? Is BLE_GATTS_EVT_WRITE an Application event? &lt;/span&gt;[/quote]
&lt;p&gt;&amp;nbsp;The app will wake up on the SD_EVT_IRQn, and then start to poll the Softdevice event queue (BLE_GATTS_EVT_WRITE, etc). It&amp;#39;s the SD_EVT_IRQn interrupt that makes the app tor return from sd_app_evt_wait().&lt;/p&gt;
[quote user="brianreinhold"]what events would cause &amp;#39;my_command_handler&amp;#39; to be called? [/quote]
&lt;p&gt;&amp;nbsp;After any of the interrupt shown above, so you will still need to use a bolean flag if you want &amp;quot;my_command_handler()&amp;quot; to only be executed after a certain event. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289866?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 18:46:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e8ced18c-4c3c-4413-8336-edabe64568d9</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;It&amp;#39;s still not clear to me what an application event is. As I stated I hoped that I could use this wait() to replace a semaphore.&lt;/p&gt;
&lt;p&gt;If I have something like this (the power_manager() has the&amp;nbsp;&lt;span&gt;sd_app_evt_wait()&amp;nbsp;)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;    for (;;)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            my_command_handler();
            power_manage();
        }
    }&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;what events would cause &amp;#39;my_command_handler&amp;#39; to be called? Would a&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE cause the&amp;nbsp;sd_app_evt_wait() to return? Is BLE_GATTS_EVT_WRITE an Application event? If so that would be great (as long as the event handler that I have initialized with the soft device gets called first).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I have read the docs on these methods over and over again but there were so many things (like application events) that I just could not figure out what was meant.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It would be SOOO helpful if someone would say exactly what an &amp;#39;application&amp;#39; event is.&amp;nbsp;I write the application, but I clearly do not define these events. Are application events ALL events received by the application? In the docs they talk about SoftDevice events and don&amp;#39;t call them application events. So what is the story?&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289849?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 16:37:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1b54c5ce-a665-4f38-9dcd-d0267488164b</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;As stated in the API documentation for sd_app_evt_wait(), an application event is either an application interrupt or a pended interrupt when the interrupt is disabled. An example of this is when the RTC1 interrupt gets triggered inside the app_timer module. This interrupt would then make your program return from the sd_app_evt_wait() function.&lt;/p&gt;
[quote user="brianreinhold"]Also, enumerations like&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE are &lt;strong&gt;&lt;em&gt;events&lt;/em&gt;&lt;/strong&gt;, not interrupts as I understand it.&lt;/span&gt;[/quote]
&lt;p&gt;&amp;nbsp;Yes, you&amp;#39;ve understood it correctly. These are internal Softdevice events.&lt;/p&gt;
&lt;p&gt;The Softdevice triggers the SOFTDEVICE_EVT_IRQ interrupt to let the application know when new Softdevice events are available, and the application will then retrieve the the events by calling&amp;nbsp; sd_evt_get() and sd_ble_evt_get() while still inside the Softdevice interrupt handler.&lt;/p&gt;
[quote user="brianreinhold"]If I were sending notifications instead of indications would it still be so complicated? Many vendors send sequences of data but I don&amp;#39;t know if they use Nordic chips. But they also use notifications instead of indications.[/quote]
&lt;p&gt;Notifications are a bit easier to deal with as you can queue up multiple notifications at a time. Though, instead of handling busy errors, you will have to handle the NRF_ERROR_NO_TX_PACKETS error if the notification output queue becomes full.&lt;/p&gt;
&lt;p&gt;Also, I took a screenshot from Keil to try illustrate how Softdevice events are being propagated to the on_ble_evt() handler from the Softdevice interrupt. Let me know if you have questions to this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;on_ble_evt() invoked in interrupt context:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/interrupt.JPG" alt=" " /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289762?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 13:39:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0d52810b-f07f-4f67-86ab-c7d6441abd3b</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;Now that just adds to the confusion. I have long looked at this function as a hopeful solution to many problems but I have never been able to understand what an &amp;#39;application event&amp;#39;&amp;nbsp; was. In most contexts that I have worked in, &amp;#39;application&amp;#39; is what I write on top of an SDK. But if that is true, I would expect I could define an event but I cannot. So how do I wake this thing up? Once called does it wake on every event such as a&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Also, enumerations like&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE are &lt;strong&gt;&lt;em&gt;events&lt;/em&gt;&lt;/strong&gt;, not interrupts as I understand it. Well they are are called events. Maybe not? When I receive a GATTS or GAP event, am I back on the main context? Or am I only in the main context if I am in the main function? So am I forced to be that for loop which is now occupied&amp;nbsp;by the &amp;#39;power_manage()&amp;#39; method?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If I were sending notifications instead of indications would it still be so complicated? Many vendors send sequences of data but I don&amp;#39;t know if they use Nordic chips. But they also use notifications instead of indications.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289747?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 13:21:53 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8d28211d-0bc3-4501-8455-fe25405999a1</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;By calling &lt;span class="item"&gt;&lt;a title="sd_app_evt_wait" href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s130.api.v2.0.0/group___n_r_f___s_o_c___f_u_n_c_t_i_o_n_s.html?cp=5_7_2_3_2_7_2_0#ga11d88d38ac99fb72cde74c9385d36433"&gt;sd_app_evt_wait&lt;/a&gt;&lt;/span&gt;(), or __WFE() if the Softdevice is disabled.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289742?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 13:14:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b5bf3b41-cbe5-43fb-9277-45b1d7270180</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;Simple question that&amp;#39;s not so simple - How does one invoke a sleep as you reference in this system?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289732?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 13:02:42 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ff206ade-2d01-4f15-a0ad-c490b1dcd311</guid><dc:creator>Vidar Berg</dc:creator><description>[quote userid="83646" url="~/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications/289725#289725"]Since I cannot send data until the client asks for it via a&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE event, I invoke a timer and when the timer completes, I invoke the call. I do not know if that is in the main context or not. &lt;/span&gt;[/quote]
&lt;p&gt;Is it the SDK app timer? In that case, you will have to use it with the app scheduler as Einar explains in the &lt;a href="https://devzone.nordicsemi.com/nordic/short-range-guides/b/software-development-kit/posts/scheduler-tutorial"&gt;nRF5 SDK Scheduler Tutorial&lt;/a&gt;. The timer handler will be invoked in an interrupt context if not.&lt;/p&gt;
[quote userid="83646" url="~/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications/289725#289725"]This sounds messy and inefficient. But you still have not answered my question about NRF_ERROR_BUSY. &lt;em&gt;If I get that response is it the case I&lt;/em&gt; &lt;strong&gt;MUST&lt;/strong&gt; recall the method? If I do not, the data will not be indicated. OR can I just wait?[/quote]
&lt;p&gt;The data will only be sent if the call returned NRF_SUCCESS&lt;/p&gt;
[quote userid="83646" url="~/f/nordic-q-a/70569/how-to-send-a-sequence-of-indications/289725#289725"]By the way, does an&amp;nbsp;nrf_delay_ms(50); count as a sleep?[/quote]
&lt;p&gt;No, it&amp;#39;s a busy wait. The CPU will execute a bunch of NOPs as you said.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289725?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 12:54:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b5a13937-31ee-4b53-96c0-422797902a3e</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;Since I cannot send data until the client asks for it via a&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE event, I invoke a timer and when the timer completes, I invoke the call. I do not know if that is in the main context or not. If the only way to call it from the main context is in that infinite for-loop that means basically I have to put my whole command handler in there and wait on it to be triggered. In the pc-ble-driver case I do, but I use a semaphore so it works like a charm. Now I guess the only way to do this with some efficiency is to wait on a volatile boolean triggered in the&amp;nbsp;BLE_GATTS_EVT_WRITE event and after the first trigger reset the sleep to a much shorter time.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This sounds messy and inefficient. But you still have not answered my question about NRF_ERROR_BUSY. &lt;em&gt;If I get that response is it the case I&lt;/em&gt; &lt;strong&gt;MUST&lt;/strong&gt; recall the method? If I do not, the data will not be indicated. OR can I just wait?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;By the way, does an&amp;nbsp;nrf_delay_ms(50); count as a sleep? My understanding is that this is also a full throttle tag of the CPU with a bunch of NOPs. It does not solve the problem but I only have 50 ms so far.&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289718?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 12:43:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:61e02ce7-454e-4262-92f2-11685a2caf78</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Ok, maybe it doesn&amp;#39;t make sense to use an actual semaphore as this is an interrupt driven system without a task scheduler. But you can still use a boolean flag like I suggested.&lt;/p&gt;
[quote user="brianreinhold"]That for-loop looks deadly - will completely floor the processor; running an infinite loop as fast as the processor can go.[/quote]
&lt;p&gt;&amp;nbsp;That&amp;#39;s true only if you don&amp;#39;t call the sleep function after processing the if statements.&lt;/p&gt;
[quote user="brianreinhold"]Now if I do that, what happens if a get an NRF_ERROR_BUSY? Do I have to call again or is it so that the first call will eventually complete if I wait long enough? [/quote]
&lt;p&gt;&amp;nbsp;Yes, you can implement retries. It should not get stuck if you are doing it from the main context.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289709?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 12:19:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:61c112df-364b-49bb-9462-6ee7ae661f4d</guid><dc:creator>brianreinhold</dc:creator><description>&lt;p&gt;How do you use a semaphore in s130 SDK 12.3.0 - as I stated in the initial post I can&amp;#39;t do that. There is no such thing in SDK 12.3.0! My ideal solution would be to create a semaphore, indicate the data, wait on that semaphore, and release the semaphore in the BLE_GATTS_EVT_HVC. But that is not possible.&lt;/p&gt;
&lt;p&gt;That for-loop looks deadly - will completely floor the processor; running an infinite loop as fast as the processor can go.&lt;/p&gt;
&lt;p&gt;I do not think I am calling it from an interrupt context. In the&amp;nbsp;&lt;span&gt;BLE_GATTS_EVT_WRITE event where I &amp;#39;call&amp;#39; the send data method, all I do is invoke a timer. When the timer expires, it calls the send data. It is there where I get three indications&amp;nbsp;out and then it stops.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So given you are using a full-throttle for-loop that tags the CPU I suppose I could do the same thing in my sender. Just do a while loop on the wait_for_hvc. That&amp;#39;s what a semaphore does after all without flooring the processor because the semaphore stops the thread from eating up CPU.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Now if I do that, what happens if a get an NRF_ERROR_BUSY? Do I have to call again or is it so that the first call will eventually complete if I wait long enough? Otherwise it seems like a catch-22. I can&amp;#39;t retry a BUSY because it might become stuck, but if I get a busy and then do a full throttle while loop wait, the call will never complete because of the BUSY.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;None of this makes too much sense. If I tag the processor in that for or while loop, how is it going to get anything done?&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to send a sequence of indications?</title><link>https://devzone.nordicsemi.com/thread/289706?ContentTypeID=1</link><pubDate>Mon, 18 Jan 2021 12:05:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3bd330e5-37de-429c-b906-346be9479a36</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;&lt;span&gt;Hi,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;sd_ble_gatts_hvx() may get stuck with the NRF_ERROR_BUSY error if you&amp;#39;re calling it from an interrupt context as it may block the BLE_GATTS_EVT_HVC Softdevice event from ever coming through. A solution to this can be to send the data from your main loop instead, and either use a flag or a semaphore to know when you have received the BLE_GATTS_EVT_HVC event. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/* Flag to wait for pending 
 * Handle Value Confirmation 
 */
static volatile bool wait_for_hvc; 

/* This function is invoked in the Softdevice interrupt context
   unless you are using a scheduler */
static void on_ble_evt(ble_evt_t * p_ble_evt)
{
    uint32_t err_code;

    switch (p_ble_evt-&amp;gt;header.evt_id)
    {
        case BLE_GATTS_EVT_HVC:
            wait_for_hvc = false;
    ..
..

int main(void)
{
    ...
    for (;;)
    {
        if (&amp;lt;send data&amp;gt;)
        {
            send_data();
            wait_for_hvc = true;&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;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></channel></rss>