<?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>Turn off BLE for optimal ADC readings</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/32874/turn-off-ble-for-optimal-adc-readings</link><description>I&amp;#39;m working on an application in which we are using a custom board with the NRF52382, which is powered by a battery. We sample our ADC every 6ms, record these values for about twenty seconds, and then transmit them to a phone using the NUS_uart service</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Thu, 26 Apr 2018 19:23:31 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/32874/turn-off-ble-for-optimal-adc-readings" /><item><title>RE: Turn off BLE for optimal ADC readings</title><link>https://devzone.nordicsemi.com/thread/130036?ContentTypeID=1</link><pubDate>Thu, 26 Apr 2018 19:23:31 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:714dfcbd-5e2b-480b-94d9-224c038ce505</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;The accuracy depend on an accurate internal clock for sampling, the best accuracy is ensured by starting the external high frequency crystal.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Turn off BLE for optimal ADC readings</title><link>https://devzone.nordicsemi.com/thread/129820?ContentTypeID=1</link><pubDate>Wed, 25 Apr 2018 14:57:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3483fd5f-a9d1-4156-aad8-a1dc7f7400e0</guid><dc:creator>Mason</dc:creator><description>&lt;p&gt;Can you provide some clarification as to what this will accomplish? &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Turn off BLE for optimal ADC readings</title><link>https://devzone.nordicsemi.com/thread/129795?ContentTypeID=1</link><pubDate>Wed, 25 Apr 2018 13:59:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f090bf6a-f973-462f-a87c-d37ae6a7876d</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;If you are not using timeslot, then you should make sure to request HFCLK by calling sd_clock_hfclk_request() and wait sd_clock_hfclk_is_running() for before starting ADC measurements. When all ADC measurements are done you can call&amp;nbsp;sd_clock_hfclk_release().&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Turn off BLE for optimal ADC readings</title><link>https://devzone.nordicsemi.com/thread/127923?ContentTypeID=1</link><pubDate>Wed, 11 Apr 2018 22:37:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:124a3adf-8fda-415c-a954-b563c52f9100</guid><dc:creator>Mason</dc:creator><description>&lt;p&gt;I&amp;#39;ve attempted using both the timeslot API to request a timeslot in which the radio is inactive. I&amp;#39;ve tried to request a period of 10.5 seconds, but it seems that the connection interval takes priority and the radio starts chatting again.&lt;/p&gt;
&lt;p&gt;To aid in this, I&amp;#39;ve configured a radio notification event to set a volatile flag before and after radio events, such that I&amp;#39;ll omit capturing a reading when a radio is about to occur, and request another timeslot instead.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I based my timeslot code on Ole Bauck&amp;#39;s timeslot.c from &lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/19200/timeslot-extension/74376#74376"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/19200/timeslot-extension/74376#74376&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdbool.h&amp;gt;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;nrf_sdh.h&amp;quot;
#include &amp;quot;nrf_soc.h&amp;quot;
#include &amp;quot;boards.h&amp;quot;

#include &amp;quot;nrf_log.h&amp;quot;
#include &amp;quot;nrf_log_ctrl.h&amp;quot;
#include &amp;quot;nrf_log_default_backends.h&amp;quot;

/**Constants for timeslot API
*/
static nrf_radio_request_t  m_timeslot_request;
static uint32_t             m_slot_length;

volatile uint32_t total_timeslot_length;
volatile uint32_t extend_success_count;
volatile uint32_t fail_count;

static nrf_radio_signal_callback_return_param_t signal_callback_return_param;

#define TIMESLOT_EXTEND_LENGTH 200//was 200
#define TIMESLOT_TIMER_INTERRUPT_END_MARGIN		50		//margin in us on timer 0 interrupt before the timeslot ends
#define QUIET_TIME 10500000 //10.5 seconds

/**@brief Request next timeslot event in earliest configuration
 */
uint32_t request_next_event_earliest(void)
{
    m_slot_length                                  = 15000;
    m_timeslot_request.request_type                = NRF_RADIO_REQ_TYPE_EARLIEST;
    m_timeslot_request.params.earliest.hfclk       = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
    m_timeslot_request.params.earliest.priority    = NRF_RADIO_PRIORITY_NORMAL;
    m_timeslot_request.params.earliest.length_us   = m_slot_length;
    m_timeslot_request.params.earliest.timeout_us  = 1000000;
    return sd_radio_request(&amp;amp;m_timeslot_request);
}


/**@brief Configure next timeslot event in earliest configuration
 */
void configure_next_event_earliest(void)
{
    m_slot_length                                  = 15000;
    m_timeslot_request.request_type                = NRF_RADIO_REQ_TYPE_EARLIEST;
    m_timeslot_request.params.earliest.hfclk       = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
    m_timeslot_request.params.earliest.priority    = NRF_RADIO_PRIORITY_NORMAL;
    m_timeslot_request.params.earliest.length_us   = m_slot_length;
    m_timeslot_request.params.earliest.timeout_us  = 1000000;
}


/**@brief Configure next timeslot event in normal configuration
 */
void configure_next_event_normal(void)
{
    m_slot_length                                 = 15000;
    m_timeslot_request.request_type               = NRF_RADIO_REQ_TYPE_NORMAL;
    m_timeslot_request.params.normal.hfclk        = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
    m_timeslot_request.params.normal.priority     = NRF_RADIO_PRIORITY_HIGH;
    m_timeslot_request.params.normal.distance_us  = 100000;
    m_timeslot_request.params.normal.length_us    = m_slot_length;
}


/**@brief Timeslot signal handler
 */
void nrf_evt_signal_handler(uint32_t evt_id, void * p_context)
{
	UNUSED_PARAMETER(p_context);
    uint32_t err_code;

    switch (evt_id)
    {
        case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
            //No implementation needed
            break;
        case NRF_EVT_RADIO_SESSION_IDLE:
            //No implementation needed
            break;
        case NRF_EVT_RADIO_SESSION_CLOSED:
            //No implementation needed, session ended
            break;
        case NRF_EVT_RADIO_BLOCKED:
            //Fall through
        case NRF_EVT_RADIO_CANCELED:
            err_code = request_next_event_earliest();
            APP_ERROR_CHECK(err_code);
            break;
        default:
            break;
    }
}


/**@brief Timeslot event handler
 */
nrf_radio_signal_callback_return_param_t * radio_callback(uint8_t signal_type)
{
    switch(signal_type)
    {
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
			NRF_TIMER0-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE0_Msk;
			NRF_TIMER0-&amp;gt;BITMODE = (TIMER_BITMODE_BITMODE_32Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos);
			NRF_TIMER0-&amp;gt;PRESCALER = (4 &amp;lt;&amp;lt; TIMER_PRESCALER_PRESCALER_Pos);
            NRF_TIMER0-&amp;gt;CC[0] = m_slot_length - TIMESLOT_TIMER_INTERRUPT_END_MARGIN;
            NVIC_EnableIRQ(TIMER0_IRQn);

			total_timeslot_length = m_slot_length;

			signal_callback_return_param.params.request.p_next = NULL;
            signal_callback_return_param.params.extend.length_us = TIMESLOT_EXTEND_LENGTH;
            signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND;

            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
            signal_callback_return_param.params.request.p_next = NULL;
            signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
            break;

        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
			//timeslot is ending, signal the end action
            NRF_LOG_INFO(&amp;quot;Timeslot ending after %d microseconds\n&amp;quot;, NRF_TIMER0-&amp;gt;CC[0]);
			signal_callback_return_param.params.request.p_next = NULL;
			signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_END;
            break;
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:

			extend_success_count++;

            if(total_timeslot_length &amp;gt;= QUIET_TIME)
			{
				signal_callback_return_param.params.request.p_next = NULL;
				signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
			}
			else
			{
				total_timeslot_length += TIMESLOT_EXTEND_LENGTH;

				NRF_TIMER0-&amp;gt;CC[0] = total_timeslot_length - TIMESLOT_TIMER_INTERRUPT_END_MARGIN;
				signal_callback_return_param.params.request.p_next = NULL;
				signal_callback_return_param.params.extend.length_us = TIMESLOT_EXTEND_LENGTH;
				signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND;
			}
            break;
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:

            fail_count++;

			signal_callback_return_param.params.request.p_next = NULL;
            signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_END;
            break;
        default:
            //No implementation needed
            break;
    }
    return (&amp;amp;signal_callback_return_param);
}


/**@brief Function for initializing the timeslot API.
 */
uint32_t timeslot_sd_init(void)
{
    uint32_t err_code;

    err_code = sd_radio_session_open(radio_callback);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = request_next_event_earliest();
    if (err_code != NRF_SUCCESS)
    {
        (void)sd_radio_session_close();
        return err_code;
    }
    return NRF_SUCCESS;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This is what I&amp;#39;ve done to set up a Radio notification to set a flag to True when the radio is inactive, and false when the radio is active:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void SWI1_IRQHandler(bool radio_evt)
{
    radio_flag = !radio_flag;
}

/**@brief Function for initializing Radio Notification Software Interrupts.
 */
uint32_t radio_notification_init(uint32_t irq_priority, uint8_t notification_type, uint8_t notification_distance)
{
    uint32_t err_code;

    err_code = sd_nvic_ClearPendingIRQ(SWI1_IRQn);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = sd_nvic_SetPriority(SWI1_IRQn, irq_priority);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = sd_nvic_EnableIRQ(SWI1_IRQn);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    // Configure the event
    return sd_radio_notification_cfg_set(notification_type, notification_distance);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Which I enable with&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;err_code = radio_notification_init(3, NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, NRF_RADIO_NOTIFICATION_DISTANCE_5500US);
APP_ERROR_CHECK(err_code);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;after I call ble_stack_init();&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Within my adc callback, I have the following:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;					if ( get_radio_flag() )
					{
						set_value_in_array( adc_counter, adc_value[1]);

						adc_counter++;

						if (adc_counter &amp;gt;= get_max_readings())
						{
							end_reading_routine();
						}
					}

					else
					{
					//error code should be checked here
						request_next_event_earliest();
					}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;EDIT: by accessing radio_flag directly as a global volatile instead of using a getter, and toggling the value of radio_flag as the sole task of SWI1_IRQHandler, I was able to see some reduction in noise in my readings. &lt;/p&gt;
&lt;p&gt;I&amp;#39;d like to make use of the timeslot API to further reduce the noise in my signal, as the approach I&amp;#39;m taking doesn&amp;#39;t always prevent noise from affecting my readings (this is on a custom board, in which a battery is the voltage source)&lt;/p&gt;
&lt;p&gt;Please let me know if you need any additional information or if I&amp;#39;m doing anything that&amp;#39;s obviously incorrect.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Turn off BLE for optimal ADC readings</title><link>https://devzone.nordicsemi.com/thread/126668?ContentTypeID=1</link><pubDate>Tue, 03 Apr 2018 13:36:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2e2cb350-8945-472b-9a3f-f662e2f502e0</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;You can either request a timeslot, then you will get an un-interrupted timeslot that you can do what you like. Or you can use radio notifications, and plan your ADC operations after or between radio events.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Turn off BLE for optimal ADC readings</title><link>https://devzone.nordicsemi.com/thread/126543?ContentTypeID=1</link><pubDate>Mon, 02 Apr 2018 21:39:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4286c3ef-170e-4f32-bef2-4dad2c943463</guid><dc:creator>Mason</dc:creator><description>&lt;p&gt;For clarification:&lt;/p&gt;
&lt;p&gt;Can I disable the link layer temporarily?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>