<?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>NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/51085/nrf9160-dk-adc-long-sample-times</link><description>I&amp;#39;m working with the NRF9160 DK and have found the sample times for the ADC to be abnormally long. I am sampling three channels and seeing a total time for the ADC read of 80+us when I&amp;#39;m expecting something on the order of 15us. I have experimented with</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 27 Aug 2019 16:42:54 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/51085/nrf9160-dk-adc-long-sample-times" /><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/206451?ContentTypeID=1</link><pubDate>Tue, 27 Aug 2019 16:42:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f9a20775-8670-4c7d-af1a-0ce149675456</guid><dc:creator>nordic_matt</dc:creator><description>&lt;p&gt;That worked. Thanks!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/205810?ContentTypeID=1</link><pubDate>Fri, 23 Aug 2019 08:58:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e76a0b7d-ca49-4ba3-a9ad-321efd5fca54</guid><dc:creator>H&amp;#229;kon Alseth</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The driver does not use the nrfx_saadc.c file, but rather the API in the header file.&lt;/p&gt;
&lt;p&gt;To force the usage of nrfx_saadc.c, you need to do these two things.&lt;/p&gt;
&lt;p&gt;1. Create a Kconfig file in your application directory (ie: nrf/samples/nrf9160/adc/) that contains this:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;mainmenu &amp;quot;NRFX SAADC&amp;quot;

config FORCE_NRFX_SAADC
	bool &amp;quot;Test to force SAADC&amp;quot;
	select NRFX_SAADC    
    default y

source &amp;quot;$ZEPHYR_BASE/Kconfig.zephyr&amp;quot;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;2. Since the file is guarded by a &amp;quot;ENABLE&amp;quot; macro, we need to add this to the prj.conf file:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;CONFIG_COMPILER_OPT=&amp;quot;-DNRFX_SAADC_ENABLED=1&amp;quot;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I apologize for the inconvenience regarding using the nrfx drivers directly. I have been in contact with developers to make it easier to enable these modules directly, and I can assure you that we are working on improving this.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Kind regards,&lt;/p&gt;
&lt;p&gt;Håkon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/205141?ContentTypeID=1</link><pubDate>Tue, 20 Aug 2019 19:54:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:31c606b8-613a-4826-b80b-6e55e09d17fb</guid><dc:creator>nordic_matt</dc:creator><description>&lt;p&gt;Here&amp;#39;s something interesting.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If I use functions from hal/nrf_saadc.h, I can get it to build. But if I use functions from nrfx_saadc.h, i&amp;#39;ll get undefined references.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/205041?ContentTypeID=1</link><pubDate>Tue, 20 Aug 2019 12:55:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:56083417-b793-4f14-8722-d111d6b45522</guid><dc:creator>nordic_matt</dc:creator><description>&lt;p&gt;I&amp;#39;m not sure why I&amp;#39;m getting undefined references. Here is my main.c file. Maybe there&amp;#39;s something obvious?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
 */

#include &amp;lt;gpio.h&amp;gt;
#include &amp;lt;net/socket.h&amp;gt;
#include &amp;lt;nrf9160.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;uart.h&amp;gt;
#include &amp;lt;adc.h&amp;gt;
#include &amp;lt;zephyr.h&amp;gt;
#include &amp;lt;nrfx.h&amp;gt;
#include &amp;lt;nrfx_saadc.h&amp;gt;
//#include &amp;lt;hal/nrf_saadc.h&amp;gt;
//#include &amp;lt;nrfx_dppi.h&amp;gt; 


struct device *gpio_dev;

#define SAADC_DEFAULT_CONFIG                                               \
{                                                                               \
    .resolution         = (nrf_saadc_resolution_t)NRFX_SAADC_CONFIG_RESOLUTION, \
    .oversample         = (nrf_saadc_oversample_t)NRFX_SAADC_CONFIG_OVERSAMPLE, \
    .interrupt_priority = NRFX_SAADC_CONFIG_IRQ_PRIORITY,                       \
    .low_power_mode     = NRFX_SAADC_CONFIG_LP_MODE                             \
}

#define SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \
{                                                   \
    .resistor_p = NRF_SAADC_RESISTOR_DISABLED,      \
    .resistor_n = NRF_SAADC_RESISTOR_DISABLED,      \
    .gain       = NRF_SAADC_GAIN1_6,                \
    .reference  = NRF_SAADC_REFERENCE_INTERNAL,     \
    .acq_time   = NRF_SAADC_ACQTIME_3US,           \
    .mode       = NRF_SAADC_MODE_SINGLE_ENDED,      \
    .burst      = NRF_SAADC_BURST_DISABLED,         \
    .pin_p      = (nrf_saadc_input_t)(PIN_P),       \
    .pin_n      = NRF_SAADC_INPUT_DISABLED          \
}

nrf_saadc_channel_config_t saadc_channel_config = SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
static bool adcCalibrateDone;


#define BUFFER_SIZE 3
static nrf_saadc_value_t m_sample_buffer[BUFFER_SIZE];

static void saadc_callback(nrfx_saadc_evt_t const * p_event){

    if ( p_event-&amp;gt;type == NRFX_SAADC_EVT_DONE )
    {
       printk(&amp;quot;ADC raw value: %d\n&amp;quot;, m_sample_buffer[0]);
    }
    else if( p_event-&amp;gt;type == NRFX_SAADC_EVT_CALIBRATEDONE )
    {
      adcCalibrateDone = true;
    }
}

void InitAdcModule(void)
{
    nrfx_err_t err_code;
    nrfx_saadc_config_t drv_saadc_cfg = SAADC_DEFAULT_CONFIG;
		
    err_code = nrfx_saadc_init( &amp;amp;drv_saadc_cfg, saadc_callback );
    if(err_code != NRFX_SUCCESS){
        //Blah error
    }
	
    adcCalibrateDone = false;
    err_code = nrfx_saadc_calibrate_offset( );
    if(err_code != NRFX_SUCCESS){
        //Blah error
    }
	
    if( err_code == NRFX_SUCCESS )
    {
	err_code = 0;
	while( !adcCalibrateDone );  
    }
	
}

//void timer_handler(nrf_timer_event_t event_type, void * p_context)
//{
//
//}


//void saadc_sampling_event_init(void)
//{
//    ret_code_t err_code;
//
//    err_code = nrf_drv_ppi_init();
//    APP_ERROR_CHECK(err_code);
//
//    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
//    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
//    err_code = nrf_drv_timer_init(&amp;amp;m_timer, &amp;amp;timer_cfg, timer_handler);
//    APP_ERROR_CHECK(err_code);
//
//    /* setup m_timer for compare event every 400ms */
//    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&amp;amp;m_timer, 400);
//    nrf_drv_timer_extended_compare(&amp;amp;m_timer,
//                                   NRF_TIMER_CC_CHANNEL0,
//                                   ticks,
//                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
//                                   false);
//    nrf_drv_timer_enable(&amp;amp;m_timer);
//
//    uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&amp;amp;m_timer,
//                                                                                NRF_TIMER_CC_CHANNEL0);
//    uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();
//
//    /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
//    err_code = nrf_drv_ppi_channel_alloc(&amp;amp;m_ppi_channel);
//    APP_ERROR_CHECK(err_code);
//
//    err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
//                                          timer_compare_event_addr,
//                                          saadc_sample_task_addr);
//    APP_ERROR_CHECK(err_code);
//}

static int adc_sample(void)
{
	int ret;


	/*printk(&amp;quot;ADC read err: %d\n&amp;quot;, ret);

	/* Print the AIN0 values */
	/*for (int i = 0; i &amp;lt; BUFFER_SIZE; i++) {
		float adc_voltage = 0;
		adc_voltage = (float)(((float)m_sample_buffer[i] / 1023.0f) *
				      3600.0f);
		printk(&amp;quot;ADC raw value: %d\n&amp;quot;, m_sample_buffer[i]);
		printf(&amp;quot;Measured voltage: %f mV\n&amp;quot;, adc_voltage);
	}
*/
	return ret;
}


static inline void nrf_delay_us(u32_t microsec)
{
	NRF_TIMER1_NS-&amp;gt;TASKS_CLEAR = 1;
	if (microsec &amp;lt; 2 )
		return;
	NRF_TIMER1_NS-&amp;gt;CC[0] = (microsec &amp;lt;&amp;lt; 4) - 26;
	NRF_TIMER1_NS-&amp;gt;PRESCALER = 0;
	NRF_TIMER1_NS-&amp;gt;TASKS_START = 1;
	while (NRF_TIMER1_NS-&amp;gt;EVENTS_COMPARE[0] == 0)
		;
	NRF_TIMER1_NS-&amp;gt;EVENTS_COMPARE[0] = 0;
	NRF_TIMER1_NS-&amp;gt;TASKS_STOP = 1;	
}

int main(void)
{
	nrfx_err_t err;
        nrf_saadc_value_t  adc_value;

	printk(&amp;quot;nrf91 saadc sampling AIN0 (P0.13)\n&amp;quot;);
	printk(&amp;quot;Example requires secure_boot to have &amp;quot;);
	printk(&amp;quot;SAADC set to non-secure!\n&amp;quot;);
	printk(&amp;quot;If not; BusFault/UsageFault will be triggered\n&amp;quot;);

//        gpio_dev = device_get_binding(DT_GPIO_P0_DEV_NAME);
//
//        if (!gpio_dev) {
//		printk(&amp;quot;Cannot bind gpio device&amp;quot;);
//		return -ENODEV;
//	}
//
//        err = gpio_pin_configure(gpio_dev, 10, GPIO_DIR_OUT);//Set pin 0 to output


        //Startup the high frequency clock
        NRF_CLOCK_NS-&amp;gt;TASKS_HFCLKSTART = 1;
	while (NRF_CLOCK_NS-&amp;gt;EVENTS_HFCLKSTARTED == 0);

        //Configure the timer
//        NRF_TIMER1_NS-&amp;gt;TASKS_CLEAR = 1;
//	NRF_TIMER1_NS-&amp;gt;PRESCALER = 0;//Run at 16MHz

        InitAdcModule();

	while (1) {

		err = nrfx_saadc_sample();

		if (err) {
			printk(&amp;quot;Error in adc sampling: %d\n&amp;quot;, err);
		}
		k_sleep(500);

	}
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Maybe it&amp;#39;s my prj.conf? I started with the asset tracker application and haven&amp;#39;t changed the prj.conf much? Maybe I should just start over?&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;CONFIG_BSD_LIBRARY=y
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NETWORKING=y
CONFIG_NET_BUF_USER_DATA_SIZE=1
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_RAW_MODE=y
CONFIG_TRUSTED_EXECUTION_NONSECURE=y
CONFIG_LOG=n
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_HEAP_MEM_POOL_SIZE=1024
CONFIG_LTE_LINK_CONTROL=n
CONFIG_ADC=y
CONFIG_ADC_0=y
CONFIG_ADC_NRFX_SAADC=y


CONFIG_MAIN_STACK_SIZE=4096&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/204988?ContentTypeID=1</link><pubDate>Tue, 20 Aug 2019 10:43:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e2c1698f-bae9-4b46-89db-8ba8ed3c93b7</guid><dc:creator>H&amp;#229;kon Alseth</dc:creator><description>&lt;p&gt;If you keep the project &amp;quot;as-is&amp;quot;, meaning that all the zephyr related ADC drivers are enabled, then all the nrfx-saadc components are also enabled (sources + headers). Remove the zephyr adc driver functions in your application, then include nrfx_saadc.h in your main.c file. This should then not give you any undefined references.&lt;/p&gt;
&lt;p&gt;If you want to use the event handler, you have to add the interrupt wrapper for the OS, as done here for the PDM:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/51164/pdm-hardware-exception/204916#204916"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/51164/pdm-hardware-exception/204916#204916&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Its not very easy to use nrfx directly, and this is something that I&amp;#39;m reporting internally so that we can improve this in the future.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Kind regards,&lt;/p&gt;
&lt;p&gt;Håkon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/204873?ContentTypeID=1</link><pubDate>Mon, 19 Aug 2019 22:53:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6559c24a-16f2-4628-9129-7457fe253620</guid><dc:creator>nordic_matt</dc:creator><description>&lt;p&gt;I tried working with nrfx_saadc.h and including it and had lots of trouble. I&amp;#39;m not sure how to get it to build with SES and for the build to find the file. I get errors like:&lt;/p&gt;
&lt;p&gt;1&amp;gt; C:\Nordic\ncs\nrf\samples\nrf9160\adc\build_nrf9160_pca10090ns/../src/main.c:68: undefined reference to `nrfx_saadc_init&amp;#39;&lt;/p&gt;
&lt;p&gt;I tried going through the Zephyr menuconfig to get it to find the nrfx_saadc.h file but to no avail. Searching around I found plenty of examples of how to work with the old SDK but since this is 9160, they need modification. I also found this example:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devzone.nordicsemi.com/nordic/cellular-iot-guides/b/getting-started-cellular/posts/nrf-connect-sdk-tutorial"&gt;https://devzone.nordicsemi.com/nordic/cellular-iot-guides/b/getting-started-cellular/posts/nrf-connect-sdk-tutorial&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is using&amp;nbsp;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;hal/nrf_saadc.h&amp;gt;&lt;/p&gt;
&lt;p&gt;So, the question is, What is the right way to go about this? I see that nrfx_saadc.h includes hal/nrf_saadc.h. But then I see in the Zephyr structure that it is including adc_nrfx_saadc.h. I&amp;#39;m new to this whole Zephyr structure and want to work with best practices. Could you provide a little guidance?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/204647?ContentTypeID=1</link><pubDate>Mon, 19 Aug 2019 07:19:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:63620275-ef84-4e27-96ac-5670fa3cefe6</guid><dc:creator>H&amp;#229;kon Alseth</dc:creator><description>[quote userid="82454" url="~/f/nordic-q-a/51085/nrf9160-dk-adc-long-sample-times/204562"]So, the best approach is to avoid using Zephyr for time critical measurements?[/quote]
&lt;p&gt;Everything has its use-case. If you require a higher sampling rate, I would recommend using a timer + PPI to trigger the SAADC. By including the nrfx_saadc.h (and ppi) into your project, you should be able to tie these together. If you search for &amp;quot;saadc ppi&amp;quot; (or other variations) on this forum, you should find snippets on how to set it up.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Kind regards,&lt;/p&gt;
&lt;p&gt;H&amp;aring;kon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/204562?ContentTypeID=1</link><pubDate>Fri, 16 Aug 2019 15:56:38 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:301eb309-6a76-4c10-bc7c-80c9a28d9992</guid><dc:creator>nordic_matt</dc:creator><description>&lt;p&gt;So, the best approach is to avoid using Zephyr for time critical measurements? Direct register&amp;nbsp;addressing?&amp;nbsp; Do you have some example code you could post?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: NRF9160 DK ADC long sample times</title><link>https://devzone.nordicsemi.com/thread/204550?ContentTypeID=1</link><pubDate>Fri, 16 Aug 2019 14:57:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:78748f04-52e0-4f64-9320-c6cf69642d86</guid><dc:creator>H&amp;#229;kon Alseth</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I can confirm that there is overhead in the zephyr API that causes the SAADC to run a bit slower. There&amp;#39;s semaphores for locking and unlocking in the adc driver (adc_nrfx_saadc.c), which goes to sleep (or yields), and it takes a bit of time to wake up on events and run the code&amp;nbsp;as well. I see approx. 35 us overhead on a single measurement.&lt;/p&gt;
&lt;p&gt;20 us acq = 56 us&lt;/p&gt;
&lt;p&gt;10 us acq = 46 us&lt;/p&gt;
&lt;p&gt;3 us acq = 41 us&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note that it also takes some microseconds for the conversion to be available as well.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Kind regards,&lt;/p&gt;
&lt;p&gt;Håkon&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>