<?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>Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/91027/speeding-up-application-to-send-24bit-i2s-data-at-16-khz-via-ble</link><description>Hi, 
 I&amp;#39;m trying to send I2S data (~ 16 kHz, 24 bits) via BLE using the nRF52 DK and the nRF5 SDK 17.1.0. After I get the data from the I2S driver (by specification, they are in 32bit format), I add them to very simple ring buffer. The problem is, that</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 01 Sep 2022 12:47:12 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/91027/speeding-up-application-to-send-24bit-i2s-data-at-16-khz-via-ble" /><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/384344?ContentTypeID=1</link><pubDate>Thu, 01 Sep 2022 12:47:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:aad29ca8-feb7-406e-a01c-0493ed34db39</guid><dc:creator>Edvin</dc:creator><description>[quote user="Moritz_S"]I also tried increasing NRF_SDH_BLE_GAP_EVENT_LENGTH further (e.g. to 400 as it is in the ATT Max. Throughput example), but this did not increase throughput further.[/quote]
&lt;p&gt;Increasing this will only give a higher throughput if it was the parameter that was blocking. Increasing it to more than the radio would have time to use every connection interval will not have any effect.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Glad to hear that you found something that seems to be working.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/384294?ContentTypeID=1</link><pubDate>Thu, 01 Sep 2022 10:03:53 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b3b1e877-5a6f-4a66-9b37-a7d57692dbeb</guid><dc:creator>Moritz_S</dc:creator><description>&lt;p&gt;Hi Edvin, &lt;/p&gt;
&lt;p&gt;thanks for your answer and suggestions. I implemented the suggested changes into both, the application sending dummy data and the original I2S application. They compile without warnings now.&lt;/p&gt;
&lt;p&gt;For both I&amp;#39;m using 2MBPS PHY and 50 ms connection interval.&lt;/p&gt;
&lt;p&gt;When sending dummy data, I can achieve ~ 1060 kbps, which is a little less than the optimum, but that&amp;#39;s okay for now. I will continue testing, if less 2.4 GHz devices in the environment will increase the throughput.&lt;/p&gt;
&lt;p&gt;When enabling I2S however, throughput goes down to ~ 60 kbps, which is not sufficient at all. then I realized that when using I2S, my NRF_SDH_BLE_GAP_EVENT_LENGTH was set to 6 (I was using two different projects ^^). Increasing that value to 40 (as it is in the project sending dummy data) also increased my throughput to a number that seems to be close to what I need for sending my I2S data. I still loose some data, but that is due to my buffer and not the BLE - so I just need to improve my implementation of the buffer. &lt;/p&gt;
&lt;p&gt;For anybody interested: I also tried increasing NRF_SDH_BLE_GAP_EVENT_LENGTH further (e.g. to 400 as it is in the ATT Max. Throughput example), but this did not increase throughput further.&lt;/p&gt;
&lt;p&gt;Overall, it seems that my problem is solved. But what impact has the NRF_SDH_BLE_GAP_EVENT_LENGTH parameter on what is happening in the code? I mean the connection interval is still 50 ms, no matter how high the NRF_SDH_BLE_GAP_EVENT_LENGTH.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/384094?ContentTypeID=1</link><pubDate>Wed, 31 Aug 2022 10:23:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1935a455-9ff9-44cb-a5b0-565d7d204581</guid><dc:creator>Edvin</dc:creator><description>[quote user="Moritz_S"]The result was: The byte count reported on the sender side (534.114 bytes) was significantly higher than on the receiving side (277.020 bytes). [/quote]
&lt;p&gt;That should not be possible. If so, there is something wrong with the way you are counting either received or sent bytes.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Notes from looking at your surag_sense.zip file:&lt;/p&gt;
&lt;p&gt;Line 1133 in main.c:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;err_code = ble_aas_value_update(&amp;amp;m_aas, &amp;amp;data);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;should be:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;err_code = ble_aas_value_update(&amp;amp;m_aas, data);
// or
err_code = ble_aas_value_update(&amp;amp;m_aas, &amp;amp;data[0]);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The same goes for m_array in 1034:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;err_code = ble_aas_value_update(&amp;amp;m_aas, m_array);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Then go to ble_aas.c line 74, and change it to:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;const ble_gatts_evt_write_t * p_evt_write = &amp;amp;p_ble_evt-&amp;gt;evt.gatts_evt.params.write;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;First after doing these changes I can compile your application without warnings. In most cases you should treat warnings as errors, because it may lead to undefined behavior. The only exception I can think of is when variables are &amp;quot;set but not used&amp;quot;, while you are adding and removing things for debugging.&amp;nbsp;&lt;/p&gt;
[quote user="Moritz_S"]The result was: The byte count reported on the sender side (534.114 bytes) was significantly higher than on the receiving side (277.020 bytes). When calculating throughput from the log file, it was mostly between 30 and 39 KBps.[/quote]
&lt;p&gt;If this is based on the log file from nRF Connect for Desktop, I would not trust that. I suggest you write a central application that can count the received bytes properly. The reason for this is that at least the GUI in nRF Connect for Desktop is not able to keep up with the throughput, and I believe that the log reflects the GUI, meaning it will not receive all the bytes.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Counting the sent_bytes from your peripheral (I used an app timer to trigger every 1 second, and saw that it had sent 3 058 884 bytes over 29 seconds which is roughly 105kB per second = 800kbps. This is roughly how much you can get on 1MBPS PHY in BLE.&lt;/p&gt;
&lt;p&gt;Checking by setting the connection interval to 500ms, I get slightly above 800kpbs (noisy environment in the office), and that is above what is possible with 1MBPS.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Looking at the log from nRF Connect for desktop, I sometimes see:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;1:17:52.043	Attribute value changed, handle: 0x10, value (0x): 03-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
11:17:52.043	Attribute value changed, handle: 0x10, value (0x): 17-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
&lt;/pre&gt;Meaning that all the packets between 0x03 and 0x17 are not printed in the log. They are received if the peripheral can queue it successfully, because the only way that the packet are not acked is if they disconnect.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/383829?ContentTypeID=1</link><pubDate>Tue, 30 Aug 2022 09:05:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dcb0441c-844a-4b8a-8453-fa030882cb35</guid><dc:creator>Moritz_S</dc:creator><description>&lt;p&gt;Hi Edvin,&lt;/p&gt;
&lt;p&gt;thanks for your response, I have tested two things now:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Measuring throughput while sending dummy data&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;I have removed the I2S code from the application (I2S still enabled in sdk_config.h) and implemented sending dummy data as shown in the ble_app_uart example into my application and tested it on an NRF52 DK as sender and an NRF52 Dongle as the receiver together with NRF Connect for Desktop Bluetooth 4.0 (on Ubuntu 20.04 LTS). The hard fault is now gone.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;The result was: The byte count reported on the sender side (534.114 bytes) was significantly higher than on the receiving side (277.020 bytes). When calculating throughput from the log file, it was mostly between 30 and 39 KBps.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;I counted the bytes on the receivers side from the log file of NRF Connect for Desktop. I noticed that in most cases the bytes counted on the receivers side are roughly 50 % of the bytes counted on the sender&amp;#39;s side.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Here is my project with the code for sending dummy data (using SDK 17.0.1) and the log file related to the case described above.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;a href="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/example_5F00_logfile.txt"&gt;devzone.nordicsemi.com/.../example_5F00_logfile.txt&lt;/a&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;a href="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/surag_5F00_sense.zip"&gt;devzone.nordicsemi.com/.../surag_5F00_sense.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Measuring throughput with original I2S code&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;I have used the same approach to count the bytes that are sent using my original application including I2S.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Now the byte count on the sender&amp;#39;s and the receiving side are equal to each other (42.768 bytes) but throughput reduced significantly to ~ 8 KBps.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My Conclusions:&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;- it seems that I2S in fact has an impact on the achievable throughput?&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;- NRF Connect for Desktop seems to have problem with logging higher data rates?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;What do you think about these conclusions? Can you suggest any next steps?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/382052?ContentTypeID=1</link><pubDate>Wed, 17 Aug 2022 13:16:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7cd7241a-638a-4ae9-9ebb-73515ce98915</guid><dc:creator>Edvin</dc:creator><description>[quote user="Moritz_S"]I haven&amp;#39;t been able to find out what that means and how to address this issue. Can you help me out?[/quote]
&lt;p&gt;That is a hardfault. These are a bit tricky to debug.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The log (from nRF Connect) only states that the peripheral disappeared, and hence you got a timeout disconnection.&lt;/p&gt;
&lt;p&gt;If you sent the appliication you are using, will I be able to replicate the issue (hardfault) without an external microphone attached?&lt;/p&gt;
&lt;p&gt;In fact, I think you should try to reduce the application to only send dummy data, so that we can exclude the I2S operations for now. Just to see whether the I2S + the data processing is slowing down things at all.&lt;/p&gt;
&lt;p&gt;If you strip it down, and send it so that I can try to run it on a DK, I can see what your connection parameters looks like.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In case you are interrested, I&amp;#39;ll attach a couple of modified examples (ble_app_uart and ble_app_uart_c) which will just send dummy data from one device to the other based on some button presses.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/0825.nus_5F00_throughput.zip"&gt;devzone.nordicsemi.com/.../0825.nus_5F00_throughput.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It runs in SDK16.0.0, so please download and test it in SDK16.0.0. Just unzip it next to the ble_app_uart example in the folder structure. Flash one DK with the peripheral example and another with the central, and press button 1 (I think) on one of them, and monitor the RTT log output.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/381883?ContentTypeID=1</link><pubDate>Wed, 17 Aug 2022 06:19:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:05d8f304-b4bc-4ec5-9580-c6fd2cb68ae0</guid><dc:creator>Moritz_S</dc:creator><description>&lt;p&gt;Good morning,&lt;/p&gt;
&lt;p&gt;after my answer from yesterday I checked again my connection parameters and, in fact, I was using 7.5 ms as event length. I changed that now to 50 ms by changing&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define CONN_INTERVAL_DEFAULT           (uint16_t)(MSEC_TO_UNITS(7.5, UNIT_1_25_MS)) 
#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(50, UNIT_1_25_MS) &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define CONN_INTERVAL_DEFAULT           (uint16_t)(MSEC_TO_UNITS(50, UNIT_1_25_MS)) 
#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(50, UNIT_1_25_MS)        /**&amp;lt; Minimum acceptable connection interval (0.1 seconds). */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(50, UNIT_1_25_MS) &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;and according to nRF Connect for Desktop, my connection parameters should now allow maximum throughput (2 M PHY and optimal connection parameters). I&amp;#39;m attaching my log file from nRF Connect.&lt;a href="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/2022_2D00_08_2D00_17T06_5F00_13_5F00_35.488Z_2D00_log.txt"&gt;devzone.nordicsemi.com/.../2022_2D00_08_2D00_17T06_5F00_13_5F00_35.488Z_2D00_log.txt&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, this did not improve the overall process so much - I&amp;#39;m still receiving less samples than I would expect when recording, e.g., 3 seconds (~ 48.000 samples expected). So I looked again at the maximum throughput example. One significant difference in the example&amp;#39;s sdk_config.h is&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// &amp;lt;o&amp;gt; NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. 
// &amp;lt;i&amp;gt; The time set aside for this connection on every connection interval in 1.25 ms units.

#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
#define NRF_SDH_BLE_GAP_EVENT_LENGTH 400
#endif&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;this value is 6 in my application. I tried setting the value first to 400 and then to 40 (to achieve 50 ms), but I got the following warnings:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;&amp;lt;warning&amp;gt; nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
&amp;lt;warning&amp;gt; nrf_sdh_ble: Change the RAM start location from 0x20002AD8 to 0x20002BE0.
&amp;lt;warning&amp;gt; nrf_sdh_ble: Maximum RAM size for application is 0xD420.
&amp;lt;error&amp;gt; nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I changed the RAM start location as I was told, but since then my application stops working after roughly 1 second without a clear error message. I can only see an arrow in the &amp;#39;Disassembly&amp;#39; window of Segger emStudio pointing to&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;00000A60    4B01    ldr r3,
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I haven&amp;#39;t been able to find out what that means and how to address this issue. Can you help me out?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/381814?ContentTypeID=1</link><pubDate>Tue, 16 Aug 2022 14:04:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1aa1eeca-cf2a-47f7-9e6d-3f64cb664081</guid><dc:creator>Moritz_S</dc:creator><description>&lt;p&gt;Hi Edvin,&lt;/p&gt;
&lt;p&gt;thanks for youor answer.&lt;/p&gt;
&lt;p&gt;Yes, the i2s buffer always provides 32 bit samples: &amp;quot;&lt;span&gt;The size of the buffers is specified in a number of 32-bit words. Such a 32-bit memory word can either contain four 8-bit samples, two 16-bit samples or one right-aligned 24-bit sample sign extended to 32 bit.&amp;quot; (from &lt;a href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/i2s.html?cp=4_2_0_43_6#concept_gq4_jly_vr"&gt;here&lt;/a&gt;). I&amp;#39;m quite sure that the casting works, since I&amp;#39;m expecting a sine wave to be sent and I&amp;#39;m receiving this (verified with nRF Connect for Desktop).&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I tried to reduce the amount of code in my initial post, that&amp;#39;s why I didn&amp;#39;t post it. Here is the full BLE implementation including ble_aas_value_update(), which is based on the ble_app_template from the SDK and the &lt;a href="https://github.com/NordicPlayground/nRF52-Bluetooth-Course"&gt;nRF52-Bluetooth-Course&lt;/a&gt;&amp;nbsp;(as is the overall project).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;//  ble_aas.c

#include &amp;quot;sdk_common.h&amp;quot;
#include &amp;quot;ble_srv_common.h&amp;quot;
#include &amp;quot;ble_aas.h&amp;quot;
#include &amp;lt;string.h&amp;gt;
#include &amp;quot;nrf_gpio.h&amp;quot;
#include &amp;quot;boards.h&amp;quot;
#include &amp;quot;nrf_log.h&amp;quot;

uint32_t ble_aas_value_update(ble_aas_t * p_aas, uint8_t *value){
    
    if (p_aas == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Update value in the GATT table with the value that is passed to this function
    uint32_t err_code = NRF_SUCCESS;
    ble_gatts_value_t gatts_value;

    // Initialize value struct.
    memset(&amp;amp;gatts_value, 0, sizeof(gatts_value));

    //gatts_value.len     = sizeof(value);
    gatts_value.len = 243;
    gatts_value.offset  = 0;
    gatts_value.p_value = value;
    //gatts_value.p_value = m_array;

    // Update database.
    err_code = sd_ble_gatts_value_set(p_aas-&amp;gt;conn_handle,
                                        p_aas-&amp;gt;aas_value_handle.value_handle,
                                        &amp;amp;gatts_value);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    // Notify peer that value of the charactersitc has changed

    // Send value if connected and notifying.
    // 1. check if connection handle is valid
    if ((p_aas-&amp;gt;conn_handle != BLE_CONN_HANDLE_INVALID)) 
    {
        ble_gatts_hvx_params_t hvx_params;

        memset(&amp;amp;hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = p_aas-&amp;gt;aas_value_handle.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = gatts_value.offset;
        //hvx_params.offset = 0;
        hvx_params.p_len  = &amp;amp;gatts_value.len;
        //hvx_params.p_len  = 244;
        hvx_params.p_data = gatts_value.p_value;
        //hvx_params.p_data = &amp;amp;value;

        err_code = sd_ble_gatts_hvx(p_aas-&amp;gt;conn_handle, &amp;amp;hvx_params);
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
    }

    return err_code;
}

/**@brief Function for handling the Write event.
 *
 * @param[in]   p_aas       AAS Service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack.
 */
static void on_write(ble_aas_t * p_aas, ble_evt_t const * p_ble_evt)
{
    ble_gatts_evt_write_t * p_evt_write = &amp;amp;p_ble_evt-&amp;gt;evt.gatts_evt.params.write;
    
    // Check if the handle passed with the event matches the Custom Value Characteristic handle.
    if (p_evt_write-&amp;gt;handle == p_aas-&amp;gt;aas_value_handle.value_handle)
    {
        // Put specific task here.
        #ifdef BOARD_PCA10040
            nrf_gpio_pin_toggle(LED_4);
        #endif
    }

    // Check if the Custom value CCCD is written to and that the value is the appropriate length, i.e 2 bytes.
    if ((p_evt_write-&amp;gt;handle == p_aas-&amp;gt;aas_value_handle.cccd_handle)
        &amp;amp;&amp;amp; (p_evt_write-&amp;gt;len == 2)
       )
    {

        // CCCD written, call application event handler
        if (p_aas-&amp;gt;evt_handler != NULL)
        {
            ble_aas_evt_t evt;

            if (ble_srv_is_notification_enabled(p_evt_write-&amp;gt;data))
            {
                evt.evt_type = BLE_AAS_EVT_NOTIFICATION_ENABLED;
            }
            else
            {
                evt.evt_type = BLE_AAS_EVT_NOTIFICATION_DISABLED;
            }
            // Call the application event handler.
            p_aas-&amp;gt;evt_handler(p_aas, &amp;amp;evt);
        }

    }
}

/**@brief Function for handling the Connect event.
 *
 * @param[in]   p_aas       AAS Service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack.
 */
static void on_connect(ble_aas_t * p_aas, ble_evt_t const * p_ble_evt)
{
    p_aas-&amp;gt;conn_handle = p_ble_evt-&amp;gt;evt.gap_evt.conn_handle;

    ble_aas_evt_t evt;

    evt.evt_type = BLE_AAS_EVT_CONNECTED;

    p_aas-&amp;gt;evt_handler(p_aas, &amp;amp;evt);
   
    // Request PHY update
    NRF_LOG_INFO(&amp;quot;PHY update requested.&amp;quot;);
    ble_gap_phys_t const phys =
    {
        .rx_phys = BLE_GAP_PHY_2MBPS,
        .tx_phys = BLE_GAP_PHY_2MBPS
    };

    ret_code_t err_code;
    err_code = sd_ble_gap_phy_update(p_aas-&amp;gt;conn_handle, &amp;amp;phys);
    APP_ERROR_CHECK(err_code);

    // switch on LED 1
    nrf_gpio_pin_toggle(LED_1);

}

/**@brief Function for handling the Disconnect event.
 *
 * @param[in]   p_aas       AAS Service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack.
 */
static void on_disconnect(ble_aas_t * p_aas, ble_evt_t const * p_ble_evt)
{
    UNUSED_PARAMETER(p_ble_evt);
    p_aas-&amp;gt;conn_handle = BLE_CONN_HANDLE_INVALID;

    // switch off LED 1
    nrf_gpio_pin_toggle(LED_1);
}

void on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
    ble_aas_t * p_aas = (ble_aas_t *) p_context;
    
    if (p_aas == NULL || p_ble_evt == NULL)
    {
        return;
    }

    switch (p_ble_evt-&amp;gt;header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            on_connect(p_aas, p_ble_evt);
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            on_disconnect(p_aas, p_ble_evt);
            break;

        case BLE_GATTS_EVT_WRITE:
            on_write(p_aas, p_ble_evt);
        default:
            // No implementation needed.
            break;
    }
}

/**@brief Function for adding the characteristics.
 *
 * @param[in]   p_aas        AAS Service structure.
 * @param[in]   p_aas_init   Information needed to initialize the service.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t add_characteristic(ble_aas_t * p_aas, const ble_aas_init_t * p_aas_init)
{
    uint32_t            err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;

    memset(&amp;amp;cccd_md, 0, sizeof(cccd_md));

    //  Read  operation on CCCD should be possible without authentication.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&amp;amp;cccd_md.write_perm);
    
    cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

    memset(&amp;amp;char_md, 0, sizeof(char_md));

    char_md.char_props.read   = 1;
    char_md.char_props.write  = 1;
    char_md.char_props.notify = 1; 
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
    char_md.p_cccd_md         = &amp;amp;cccd_md; 
    char_md.p_sccd_md         = NULL;

    memset(&amp;amp;attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = p_aas_init-&amp;gt;initial_value_char_attr_md.read_perm;
    attr_md.write_perm = p_aas_init-&amp;gt;initial_value_char_attr_md.write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;

    ble_uuid.type = p_aas-&amp;gt;uuid_type;
    ble_uuid.uuid = AUDIO_CHAR_UUID;

    memset(&amp;amp;attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &amp;amp;ble_uuid;
    attr_char_value.p_attr_md = &amp;amp;attr_md;
    // set initial size of the attribute
    // attr_char_value.init_len  = sizeof(uint8_t);
    attr_char_value.init_len = 243;
    attr_char_value.init_offs = 0;
    // set max size of attribute 
    // attr_char_value.max_len   = sizeof(uint8_t);
    attr_char_value.max_len = 243;

    err_code = sd_ble_gatts_characteristic_add(p_aas-&amp;gt;service_handle, &amp;amp;char_md,
                                               &amp;amp;attr_char_value,
                                               &amp;amp;p_aas-&amp;gt;aas_value_handle);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    return NRF_SUCCESS;
}

uint32_t ble_aas_init(ble_aas_t * p_aas, const ble_aas_init_t * p_aas_init)
{
    if (p_aas == NULL || p_aas_init == NULL)
    {
        return NRF_ERROR_NULL;
    }

    uint32_t   err_code;
    ble_uuid_t ble_uuid;

    // Initialize service structure
    p_aas-&amp;gt;evt_handler = p_aas_init-&amp;gt;evt_handler;
    p_aas-&amp;gt;conn_handle = BLE_CONN_HANDLE_INVALID;

    // Add AAS Service UUID
    ble_uuid128_t base_uuid = {AAS_SERVICE_UUID_BASE};
    err_code = sd_ble_uuid_vs_add(&amp;amp;base_uuid, &amp;amp;p_aas-&amp;gt;uuid_type);
    VERIFY_SUCCESS(err_code);

    ble_uuid.type = p_aas-&amp;gt;uuid_type;
    ble_uuid.uuid = AAS_SERVICE_UUID;

    // Add the AAS Service
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &amp;amp;ble_uuid, &amp;amp;p_aas-&amp;gt;service_handle);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    return add_characteristic(p_aas, p_aas_init);&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;And the BLE related definitions from my main.c file:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define APP_ADV_INTERVAL                300                                     /**&amp;lt; The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
#define APP_ADV_DURATION                18000                                   /**&amp;lt; The advertising duration (180 seconds) in units of 10 milliseconds. */
#define APP_BLE_OBSERVER_PRIO           3                                       /**&amp;lt; Application&amp;#39;s BLE observer priority. You shouldn&amp;#39;t need to modify this value. */
#define APP_BLE_CONN_CFG_TAG            1                                       /**&amp;lt; A tag identifying the SoftDevice BLE configuration. */

#define DATA_LENGTH_DEFAULT             27
#define DATA_LENGTH_MAX                 251

#define CONN_INTERVAL_DEFAULT           (uint16_t)(MSEC_TO_UNITS(7.5, UNIT_1_25_MS)) 
#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)        /**&amp;lt; Minimum acceptable connection interval (0.1 seconds). */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(50, UNIT_1_25_MS)        /**&amp;lt; Maximum acceptable connection interval (0.2 second). */
#define SLAVE_LATENCY                   0                                       /**&amp;lt; Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)         /**&amp;lt; Connection supervisory timeout (4 seconds). */

#define BLE_PHY_DEFAULT                 BLE_GAP_PHY_2MBPS

#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                   /**&amp;lt; Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                  /**&amp;lt; Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                       /**&amp;lt; Number of attempts before giving up the connection parameter negotiation. */

#define SEC_PARAM_BOND                  1                                       /**&amp;lt; Perform bonding. */
#define SEC_PARAM_MITM                  0                                       /**&amp;lt; Man In The Middle protection not required. */
#define SEC_PARAM_LESC                  0                                       /**&amp;lt; LE Secure Connections not enabled. */
#define SEC_PARAM_KEYPRESS              0                                       /**&amp;lt; Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_NONE                    /**&amp;lt; No I/O capabilities. */
#define SEC_PARAM_OOB                   0                                       /**&amp;lt; Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE          7                                       /**&amp;lt; Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE          16                                      /**&amp;lt; Maximum encryption key size. */&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;From my understanding, and looking at the log above, the connection parameters should be fine. The theoretisch BLE throughput should also be fine to send the amount of data I require (16.000 Hz x 24 bits). This is why I came the conclusion that the BLE should not be the bottleneck. The receiving peer is btw a nrf52840 Dongle, so I&amp;#39;m also not expecting any problems there. However, I will have a look at nRF for Desktop logfiles and share that with you in a minute.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you need more details on the implementation, I can share my project/ all files here as well.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/381805?ContentTypeID=1</link><pubDate>Tue, 16 Aug 2022 13:32:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7514fdb1-1a07-4853-b409-73de0ff3e5e8</guid><dc:creator>Edvin</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t think the bottleneck is the 24-&amp;gt;32 bit casting.&lt;/p&gt;
&lt;p&gt;I didn&amp;#39;t look too much at the logic in your casting, and my I2S is a bit rusty, since there is no sound HW on the DKs. But is it correct that the&amp;nbsp;p_released-&amp;gt;p_rx_buffer in the data_handler() callback has samples of 32 bits, where the last 8 bits are blank (0x00 or 0xFF)? I.e. 0xAAAAAA00, and the next sample has 0xBBBBBB00, and 0xCCCCCC00 and so on?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If so, after you cast it to 32 bytes, are you left with this in the buffer?&lt;/p&gt;
&lt;p&gt;0xAAAAAABB 0xBBBBCCCC 0xCCDDDDDD 0x... and so on? Or what does it look like after you cast it?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I assume that your bottleneck is currently the BLE, and not the CPU or I2S.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I see that some parts of the application are missing, such as the implementation of&amp;nbsp;ble_aas_value_update(). What does it look like? Is this always sending a large buffer? The trick in BLE is to always send large buffers (to reduce the overhead/payload ratio). Then, you need to keep the buffers full at all times for maximum throughput.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If this is satisfied, the throughput is up to the rest of your connection parameters. This isn&amp;#39;t straight forward, but you need an MTU that is large enough (looks good from your log). What is your connection interval, connection event length, and PHY?&lt;/p&gt;
&lt;p&gt;To play around with the connection parameters, I suggest you take a look at the SDK\examples\ble_central_and_peripheral\experimental\&lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/ble_sdk_app_att_mtu.html?cp=8_1_4_2_1_0_1#ble_sdk_app_att_mtu_test"&gt;ble_app_att_mtu_throughput&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I believe maxing the event length, using around 50ms connection interval, and using 2MBPS PHY will give the highest throughput.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Edvin&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Speeding up application to send 24bit I2S data at 16 kHz via BLE</title><link>https://devzone.nordicsemi.com/thread/381740?ContentTypeID=1</link><pubDate>Tue, 16 Aug 2022 11:12:53 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6171c090-b2a4-4111-b9cb-37b3fcb84800</guid><dc:creator>Moritz_S</dc:creator><description>&lt;p&gt;I was checking the CPU usage by enabling NRF_PWR_MGMT_CONFIG_LOG_ENABLED and NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED. The output in the debug window can be seen below. It seems the cpu usage never exceeds 4 %, so&amp;nbsp; I guess there has to be a way to speed this process up?&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;info&amp;gt; app_timer: RTC: initialized.
&amp;lt;info&amp;gt; pwr_mgmt: Init
TWI device detected at address 0x18.
 Accessing Page no : 00 
 Error in register 1. Write = 01 but Read = 00
 Accessing Page no : 01 
 Accessing Page no : 00 &amp;lt;info&amp;gt; I2S: Initialized.
&amp;lt;info&amp;gt; app: I2S successfully initialized.
&amp;lt;info&amp;gt; app: Fast advertising.
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 47%
&amp;lt;debug&amp;gt; nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
&amp;lt;debug&amp;gt; nrf_ble_gatt: Updating data length to 251 on connection 0x0.
&amp;lt;info&amp;gt; app: PHY update requested.
&amp;lt;info&amp;gt; app: Connected.
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;debug&amp;gt; nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
&amp;lt;debug&amp;gt; nrf_ble_gatt: Data length updated to 251 on connection 0x0.
&amp;lt;debug&amp;gt; nrf_ble_gatt: max_rx_octets: 251
&amp;lt;debug&amp;gt; nrf_ble_gatt: max_tx_octets: 251
&amp;lt;debug&amp;gt; nrf_ble_gatt: max_rx_time: 2120
&amp;lt;debug&amp;gt; nrf_ble_gatt: max_tx_time: 2120
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; I2S: Started.
&amp;lt;info&amp;gt; app: I2S started.

&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 4%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 4%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 5%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 4%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 3%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 5%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 3%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 2%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 2%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 2%
&amp;lt;info&amp;gt; I2S: Stopped.
&amp;lt;info&amp;gt; app: package added to ble stack: 281
&amp;lt;info&amp;gt; app: samples sent: 60408
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%
&amp;lt;info&amp;gt; pwr_mgmt: CPU Usage: 0%&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>