<?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>SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/68383/saadc-v2-sampling-using-the-rtc</link><description>Hi there, 
 I&amp;#39;m having some trouble piecing together an app to use V2 of the NRFX SAADC API, compounded with this being my first time using the SAADC functionality on an nRF board. 
 In summary, my program receives an &amp;quot;ERROR 8 [NRF_ERROR_INVALID_STATE</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 20 Nov 2020 03:28:51 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/68383/saadc-v2-sampling-using-the-rtc" /><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/281017?ContentTypeID=1</link><pubDate>Fri, 20 Nov 2020 03:28:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:69937170-bf0e-4f9e-8316-6c1c0c998ce7</guid><dc:creator>Christopher Hunt</dc:creator><description>[quote userid="91183" url="~/f/nordic-q-a/68383/saadc-v2-sampling-using-the-rtc/280986#280986"]&lt;p&gt;Thanks for everything Karl. I&amp;#39;m still having difficulty understanding why my SAADC sampling fires just once. Any pointers there would be great. I feel like I&amp;#39;m very close, but struggling with this last aspect. Here&amp;#39;s my current code again:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div class="evolution-code-editor theme-clouds"&gt;&lt;a href="#" class="fullscreen"&gt;&lt;/a&gt;&lt;/div&gt;[/quote]
&lt;p&gt;I think I&amp;#39;ve now got to the bottom of the problem I had in understanding SAADC. My assumption was that I could drive the nrfx_saadc V2 state machine by&amp;nbsp;firing&amp;nbsp;SAADC tasks. I&amp;nbsp;paired back everything to the Nordic Playground SAADC simple low power app timer example and replaced the app timer with RTC and PPI behaviour. My conclusion is that the&amp;nbsp;NRF_SAADC_TASK_SAMPLE task has no effect when fired from PPI as the nrfx_saadc state machine is not in a &amp;quot;sampling&amp;quot; state. To attain a sampling state,&amp;nbsp;nrfx_saadc_mode_trigger() must be called i.e. it isn&amp;#39;t enough to issue a&amp;nbsp;NRF_SAADC_TASK_SAMPLE task, even when&amp;nbsp;nrfx_saadc_mode_trigger() has been called once to kick everything off.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve put my fork of the ADC playground low power app with RTC here for reference:&amp;nbsp;&lt;a href="https://github.com/huntc/nRF52-ADC-examples/tree/rtc-ppi/nrfx_saadc_simple_low_power_app_timer"&gt;https://github.com/huntc/nRF52-ADC-examples/tree/rtc-ppi/nrfx_saadc_simple_low_power_app_timer&lt;/a&gt;. To see my specific changes, please see this commit:&amp;nbsp;&lt;a href="https://github.com/huntc/nRF52-ADC-examples/commit/d4075a7ce59f840819b642f93c80af308a1e4f12"&gt;https://github.com/huntc/nRF52-ADC-examples/commit/d4075a7ce59f840819b642f93c80af308a1e4f12&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think I shall now abandon the RTC/PPI driven approach here as it doesn&amp;#39;t seem possible. The earlier suggestion of using LPCOMP seems more useful for my particular use-case anyhow. Thanks, and I hope this dialogue has been useful.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280986?ContentTypeID=1</link><pubDate>Thu, 19 Nov 2020 20:26:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d330875e-1e24-42ce-8e50-88c540efd6a8</guid><dc:creator>Christopher Hunt</dc:creator><description>[quote userid="87869" url="~/f/nordic-q-a/68383/saadc-v2-sampling-using-the-rtc/280768#280768"]Please do not hesitate to ask, if you should encounter any issues or questions in the future.&lt;br /&gt;[/quote]
&lt;p&gt;Thanks for everything Karl. I&amp;#39;m still having difficulty understanding why my SAADC sampling fires just once. Any pointers there would be great. I feel like I&amp;#39;m very close, but struggling with this last aspect. Here&amp;#39;s my current code again:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/**@brief Handle analog events
 */
static void on_saadc_in_evt(nrfx_saadc_evt_t const *p_event)
{
    ret_code_t err_code;

    switch (p_event-&amp;gt;type)
    {
    case NRFX_SAADC_EVT_DONE:
        // Process the data
        
        // Set the next compare check that&amp;#39;ll cause another sample
        next_sample_ticks += ACCEL_SAMPLER_RESOLUTION_TICKS;
        err_code = nrfx_rtc_cc_set(&amp;amp;m_rtc, 0, next_sample_ticks, false);
        APP_ERROR_CHECK(err_code);
        break;
    default:
        break;
    }
}

static void on_rtc_evt(nrfx_rtc_int_type_t int_type)
{
}

/**@brief Set up our analogue sensors
 */
static void saadc_init()
{
    ret_code_t err_code;

    err_code = nrfx_saadc_init(NRFX_SAADC_CONFIG_IRQ_PRIORITY);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_channels_config(m_accel, 3);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_simple_mode_set((1 &amp;lt;&amp;lt; 0) | (1 &amp;lt;&amp;lt; 1) | (1 &amp;lt;&amp;lt; 2),
                                          NRF_SAADC_RESOLUTION_8BIT,
                                          NRF_SAADC_OVERSAMPLE_DISABLED,
                                          on_saadc_in_evt);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_buffer_set(m_accel_sample_buf, ACCEL_SAMPLE_CHANNELS);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_mode_trigger();
    APP_ERROR_CHECK(err_code);

    nrfx_rtc_config_t rtc_config = NRFX_RTC_DEFAULT_CONFIG;
    err_code = nrfx_rtc_init(&amp;amp;m_rtc, &amp;amp;rtc_config, on_rtc_evt);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_rtc_cc_set(&amp;amp;m_rtc, 0, next_sample_ticks, false);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_ppi_channel_alloc(&amp;amp;m_accel_ppi_channel);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_ppi_channel_assign(m_accel_ppi_channel,
                                       nrfx_rtc_event_address_get(&amp;amp;m_rtc, NRF_RTC_EVENT_COMPARE_0),
                                       nrf_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE));
    APP_ERROR_CHECK(err_code);
    err_code = nrfx_ppi_channel_enable(m_accel_ppi_channel);
    APP_ERROR_CHECK(err_code);

    nrfx_rtc_enable(&amp;amp;m_rtc);
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280768?ContentTypeID=1</link><pubDate>Thu, 19 Nov 2020 08:07:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dbf7af82-f9b9-4655-a3ac-ddbc4a90d802</guid><dc:creator>Karl Ylvisaker</dc:creator><description>[quote user="Christopher Hunt"]Thanks for the pointer toward LPCOMP - I may well come back to this one.[/quote]
&lt;p&gt;No problem at all, I am happy to help!&lt;br /&gt;I too think that the LPCOMP or &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fcomp.html"&gt;COMP&lt;/a&gt;&amp;nbsp;peripheral might sound right for your application here ( depending on what real-time and accuracy requirements you are working with ).&amp;nbsp;&lt;br /&gt;Please bear in mind that the LPCOMP, COMP and SAADC shares resources, which you will need to keep in mind when working with a combination of these ( LPCOMP and COMP is mutually exclusive, for example ).&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Please do not hesitate to ask, if you should encounter any issues or questions in the future.&lt;br /&gt;&lt;br /&gt;Good luck with your development!&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280767?ContentTypeID=1</link><pubDate>Thu, 19 Nov 2020 08:01:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:db36aab6-bec6-4925-9228-04a7dec04e2a</guid><dc:creator>Christopher Hunt</dc:creator><description>[quote userid="87869" url="~/f/nordic-q-a/68383/saadc-v2-sampling-using-the-rtc/280593#280593"]You can see the PPI channel allocation - how to configure, setup and enable PPI channels - demonstrated in &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/nrf_dev_saadc_example.html"&gt;the SAADC peripheral example from the SDK&lt;/a&gt;. In the example the sampling task is connected to the CAPUTRE/COMPARE event of a counter, to have it trigger at a certain interval - without use of the CPU. You can follow the general approach of this example, and just change which event you are connecting the sampling task to.&lt;br /&gt;[/quote]
&lt;p&gt;I think I&amp;#39;m getting the hang of this now - PPI was new to me, but I&amp;#39;m excited at the possibilities. :-)&lt;/p&gt;
&lt;p&gt;What I&amp;#39;m now wanting to do is to use the low-powered RTC2 to cause sampling via PPI (RTC1 is used for an app timer). I feel like I&amp;#39;m almost there... I&amp;#39;ve managed to wire up a compare event to the sampling event... but it only samples once. I&amp;#39;m *reasonably* confident in the RTC being setup ok, as I did do some debugging to confirm this. So, I think my problem is still in the realm of SAADC. Further guidance is really appreciated!&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the updated code (I&amp;#39;ve also switched to the simpler SAADC interface to, well, make it simpler!):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/**@brief Handle analog events
 */
static void on_saadc_in_evt(nrfx_saadc_evt_t const *p_event)
{
    ret_code_t err_code;

    switch (p_event-&amp;gt;type)
    {
    case NRFX_SAADC_EVT_DONE:
        // Process the data
        
        // Set the next compare check that&amp;#39;ll cause another sample
        next_sample_ticks += ACCEL_SAMPLER_RESOLUTION_TICKS;
        err_code = nrfx_rtc_cc_set(&amp;amp;m_rtc, 0, next_sample_ticks, false);
        APP_ERROR_CHECK(err_code);
        break;
    default:
        break;
    }
}

static void on_rtc_evt(nrfx_rtc_int_type_t int_type)
{
}

/**@brief Set up our analogue sensors
 */
static void saadc_init()
{
    ret_code_t err_code;

    err_code = nrfx_saadc_init(NRFX_SAADC_CONFIG_IRQ_PRIORITY);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_channels_config(m_accel, 3);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_simple_mode_set((1 &amp;lt;&amp;lt; 0) | (1 &amp;lt;&amp;lt; 1) | (1 &amp;lt;&amp;lt; 2),
                                          NRF_SAADC_RESOLUTION_8BIT,
                                          NRF_SAADC_OVERSAMPLE_DISABLED,
                                          on_saadc_in_evt);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_buffer_set(m_accel_sample_buf, ACCEL_SAMPLE_CHANNELS);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_mode_trigger();
    APP_ERROR_CHECK(err_code);

    nrfx_rtc_config_t rtc_config = NRFX_RTC_DEFAULT_CONFIG;
    err_code = nrfx_rtc_init(&amp;amp;m_rtc, &amp;amp;rtc_config, on_rtc_evt);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_rtc_cc_set(&amp;amp;m_rtc, 0, next_sample_ticks, false);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_ppi_channel_alloc(&amp;amp;m_accel_ppi_channel);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_ppi_channel_assign(m_accel_ppi_channel,
                                       nrfx_rtc_event_address_get(&amp;amp;m_rtc, NRF_RTC_EVENT_COMPARE_0),
                                       nrf_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE));
    APP_ERROR_CHECK(err_code);
    err_code = nrfx_ppi_channel_enable(m_accel_ppi_channel);
    APP_ERROR_CHECK(err_code);

    nrfx_rtc_enable(&amp;amp;m_rtc);
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280765?ContentTypeID=1</link><pubDate>Thu, 19 Nov 2020 07:54:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:de31d876-421d-416e-a616-b530e8e21ca4</guid><dc:creator>Christopher Hunt</dc:creator><description>[quote userid="87869" url="~/f/nordic-q-a/68383/saadc-v2-sampling-using-the-rtc/280593#280593"]However, what you perhaps could do instead - depending on the constraints and requirements of your application - is to use &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Flpcomp.html"&gt;the LPCOMP peripheral&lt;/a&gt; for this.&lt;br /&gt;Are you familiar with the LPCOMP peripheral?&lt;br /&gt;[/quote]
&lt;p&gt;Thanks for the pointer toward LPCOMP - I may well come back to this one.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280593?ContentTypeID=1</link><pubDate>Wed, 18 Nov 2020 12:04:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c5a2ae86-01d7-4024-b26f-05c5d659ffdb</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello Christopher,&lt;/p&gt;
[quote user="Christopher Hunt"]Just digesting the other bits, but here&amp;#39;s my timer code. I can confirm that the timer is firing.[/quote]
&lt;p&gt;No problem - thank you for providing the timer code.&lt;br /&gt;The general approach seems alright, but bear in mind that I do not know the values of the arguments passed to the different functions.&lt;/p&gt;
[quote user="Christopher Hunt"]I&amp;#39;ve been thinking more about this since you suggested it. Here&amp;#39;s my use case: I&amp;#39;ve got a 3 axis analog accelerometer and want to detect if a &amp;quot;significant&amp;quot; force occurs on any one of its three axis points. Each axis value is supplied to an analog pin. The accelerometer reports up to 3G of force, so given 8-bit sampling, a sample value for an axis of 128 or more indicates 1.5G or greater.[/quote]
&lt;p&gt;Thank you for clarifying - this helps a lot in understanding your issue.&lt;/p&gt;
[quote user="Christopher Hunt"]It&amp;#39;d be great to have PPI generate a sampling task for the SAADC if a value on any one of the three axis points exceeds 128. Reading (and re-reading!) the doc seems to indicate that there&amp;#39;s an &amp;quot;EVENTS_CH[0].LIMITH&amp;quot; event that can be monitored. I&amp;#39;ve been looking for examples of how to use PPI specifically for the limit test, but I&amp;#39;ve not yet found any. It&amp;#39;d be great if you could point me in the right direction. My understanding so far is that I must use&amp;nbsp;nrfx_ppi_channel_alloc,&amp;nbsp;nrfx_ppi_channel_assign, and then&amp;nbsp;nrf_drv_ppi_channel_enable. I&amp;#39;m&amp;nbsp;thinking that I&amp;#39;ll also have to set &amp;quot;start_on_end&amp;quot; for the SAADC advanced config and have a buffer sample size of 3; one for each channel. Again, thanks for any pointers here.[/quote]
&lt;p&gt;You are correct that there exists a LIMIT event in the SAADC, which can be generated once a channel exceeds a certain value, please see the&amp;nbsp;&lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Fsaadc.html&amp;amp;anchor=saadc_limits"&gt;&lt;em&gt;Event monitoring using limits&lt;/em&gt; section of the SAADC peripheral documentation&lt;/a&gt;. However, the limits are not monitored continuously - this would require the SAADC to sample &amp;#39;continuously&amp;#39; - instead, they are checked against each finished conversion. So, to generate LIMIT events, you will need to be sampling -&amp;gt; You may not use the limit events to begin sampling, because the limits are checked against already acquired samples.&lt;br /&gt;Does what I have written here make sense? Please do not hesitate to let me know if it is unclear.&lt;br /&gt;&lt;br /&gt;However, what you perhaps could do instead - depending on the constraints and requirements of your application - is to use &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52840%2Flpcomp.html"&gt;the LPCOMP peripheral&lt;/a&gt; for this.&lt;br /&gt;Are you familiar with the LPCOMP peripheral?&lt;br /&gt;&lt;br /&gt;You can see the PPI channel allocation - how to configure, setup and enable PPI channels - demonstrated in &lt;a href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/nrf_dev_saadc_example.html"&gt;the SAADC peripheral example from the SDK&lt;/a&gt;. In the example the sampling task is connected to the CAPUTRE/COMPARE event of a counter, to have it trigger at a certain interval - without use of the CPU. You can follow the general approach of this example, and just change which event you are connecting the sampling task to.&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280514?ContentTypeID=1</link><pubDate>Wed, 18 Nov 2020 07:50:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:27f67b17-2040-45e6-b1ac-e1a90049b243</guid><dc:creator>Christopher Hunt</dc:creator><description>&lt;p&gt;Here&amp;#39;s my PPI/SAADC code so far in case it helps (it isn&amp;#39;t&amp;nbsp;fully working though...):&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;/**@brief Handle analog events
 */
static void on_saadc_in_evt(nrfx_saadc_evt_t const *p_event)
{
    ret_code_t err_code;

    switch (p_event-&amp;gt;type)
    {
    case NRFX_SAADC_EVT_DONE:
        // Do something with the data
        break;
    case NRFX_SAADC_EVT_BUF_REQ:
        m_accel_current_buffer = 1 - m_accel_current_buffer;
        err_code = nrfx_saadc_buffer_set(m_accel_sample_bufs[m_accel_current_buffer], ACCEL_SAMPLES_PER_BUFFER);
        APP_ERROR_CHECK(err_code);
        break;
    default:
        break;
    }
}

/**@brief Set up our analogue sensors
 */
static void saadc_init()
{
    ret_code_t err_code;
    nrf_saadc_event_t ppi_event;

    nrfx_saadc_adv_config_t config = {
        .oversampling = NRF_SAADC_OVERSAMPLE_DISABLED,
        .burst = NRF_SAADC_BURST_DISABLED,
        .internal_timer_cc = 0,
        .start_on_end = true,
    };

    err_code = nrfx_saadc_init(NRFX_SAADC_CONFIG_IRQ_PRIORITY);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_channels_config(m_accel, 3);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_advanced_mode_set((1 &amp;lt;&amp;lt; 0) | (1 &amp;lt;&amp;lt; 1) | (1 &amp;lt;&amp;lt; 2),
                                            NRF_SAADC_RESOLUTION_8BIT,
                                            &amp;amp;config,
                                            on_saadc_in_evt);
    APP_ERROR_CHECK(err_code);

    err_code = nrfx_saadc_buffer_set(m_accel_sample_bufs[m_accel_current_buffer], ACCEL_SAMPLES_PER_BUFFER);
    APP_ERROR_CHECK(err_code);

    for (int i = 0; i &amp;lt; 3; ++i)
    {
        err_code = nrfx_ppi_channel_alloc(&amp;amp;m_accel_ppi_channel[i]);
        APP_ERROR_CHECK(err_code);
        nrf_saadc_channel_limits_set(i, 0, 128);
        switch (i)
        {
        case 0:
            ppi_event = NRF_SAADC_EVENT_CH0_LIMITH;
        case 1:
            ppi_event = NRF_SAADC_EVENT_CH1_LIMITH;
        case 2:
            ppi_event = NRF_SAADC_EVENT_CH2_LIMITH;
        }
        err_code = nrfx_ppi_channel_assign(m_accel_ppi_channel[i],
                                           nrf_saadc_event_address_get(ppi_event),
                                           nrf_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE));
        APP_ERROR_CHECK(err_code);
        err_code = nrfx_ppi_channel_enable(m_accel_ppi_channel[i]);
        APP_ERROR_CHECK(err_code);
    }

    err_code = nrfx_saadc_mode_trigger();
    APP_ERROR_CHECK(err_code);
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280507?ContentTypeID=1</link><pubDate>Wed, 18 Nov 2020 07:05:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7cc8c740-f446-4f81-af0f-5fec84b701cd</guid><dc:creator>Christopher Hunt</dc:creator><description>[quote userid="87869" url="~/f/nordic-q-a/68383/saadc-v2-sampling-using-the-rtc/280299#280299"]You might also want to consider having your sampling trigger by PPI, instead of by CPU intervention - especially if it is important that sampling is not interrupted or delayed due to the SoftDevice controlling the CPU.[/quote]
&lt;p&gt;I&amp;#39;ve been thinking more about this since you suggested it. Here&amp;#39;s my use case: I&amp;#39;ve got a 3 axis analog accelerometer and want to detect if a &amp;quot;significant&amp;quot; force occurs on any one of its three axis points. Each axis value is supplied to an analog pin. The accelerometer reports up to 3G of force, so given 8-bit sampling, a sample value for an axis of 128 or more indicates 1.5G or greater.&lt;/p&gt;
&lt;p&gt;It&amp;#39;d be great to have PPI generate a sampling task for the SAADC if a value on any one of the three axis points exceeds 128. Reading (and re-reading!) the doc seems to indicate that there&amp;#39;s an &amp;quot;EVENTS_CH[0].LIMITH&amp;quot; event that can be monitored. I&amp;#39;ve been looking for examples of how to use PPI specifically for the limit test, but I&amp;#39;ve not yet found any. It&amp;#39;d be great if you could point me in the right direction. My understanding so far is that I must use&amp;nbsp;nrfx_ppi_channel_alloc,&amp;nbsp;nrfx_ppi_channel_assign, and then&amp;nbsp;nrf_drv_ppi_channel_enable. I&amp;#39;m&amp;nbsp;thinking that I&amp;#39;ll also have to set &amp;quot;start_on_end&amp;quot; for the SAADC advanced config and have a buffer sample size of 3; one for each channel. Again, thanks for any pointers here.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280477?ContentTypeID=1</link><pubDate>Tue, 17 Nov 2020 22:01:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:986004c8-1fa4-4488-8fda-378a26a06272</guid><dc:creator>Christopher Hunt</dc:creator><description>&lt;p&gt;Just digesting the other bits, but here&amp;#39;s my timer code. I can confirm that the timer is firing.&lt;/p&gt;
&lt;p&gt;Meanwhile, to declare the timer:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;APP_TIMER_DEF(m_hand_sanitizer_accel_sampler_timer_id);
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;To create the timer:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;    err_code = app_timer_create(&amp;amp;m_hand_sanitizer_accel_sampler_timer_id, APP_TIMER_MODE_REPEATED, hand_sanitizer_accel_sampler_timer);
    APP_ERROR_CHECK(err_code);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;To enable the timer:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;    err_code = app_timer_start(m_hand_sanitizer_accel_sampler_timer_id, APP_TIMER_TICKS(ACCEL_SAMPLER_RESOLUTION_MS), NULL);
    APP_ERROR_CHECK(err_code);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;To handler the timer:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;static void hand_sanitizer_accel_sampler_timer(void *p_context)
{
    nrfx_saadc_mode_trigger();
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280299?ContentTypeID=1</link><pubDate>Tue, 17 Nov 2020 10:09:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5a7367db-2f34-456a-a5db-88dbd0422ad7</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello Christopher,&lt;/p&gt;
[quote user="Christopher Hunt"]Thanks for the reply, Karl.[/quote]
&lt;p&gt;No problem at all, I am happy to help!&lt;/p&gt;
[quote user="Christopher Hunt"]Gosh, I missed that description of the return code having even inspected the source! So, I should ignore the invalid state code perhaps during my timer event, as it is quite legitimate to be in this invalid state?[/quote]
&lt;p&gt;I am not sure that I understand exactly what you mean by this, but if this error code is returned then that means the peripheral indeed is in an invalid state for beginning sampling. If you just ignore this error, then you will &amp;quot;lose&amp;quot; this sample ( i.e no sample will be taken at this time, causing a gap in your sampling ).&lt;/p&gt;
[quote user="Christopher Hunt"]So if I ignore the invalid state then during the timer handler, I&amp;#39;m not yet able to see any sampling come through i.e. I don&amp;#39;t see an&amp;nbsp;NRFX_SAADC_EVT_DONE raised.[/quote]
&lt;p&gt;I would say this is as expected - if your buffer size is 3, and you attempt to do 3 calls to&amp;nbsp;&lt;em&gt;_sample,&amp;nbsp;&lt;/em&gt;with 1 or more returning an error code != NRF_SUCCESS, then the buffer will not fill, and the DONE event thus will not be generated.&lt;/p&gt;
[quote user="Christopher Hunt"]The timer is firing once per 100ms i.e. 10 times per second.[/quote]
&lt;p&gt;Thank you for clarifying.&lt;br /&gt;Could you show me the code in which you setup and start this timer? I just want to rule out that this in fact is happening at a different interval.&lt;/p&gt;
[quote user="Christopher Hunt"]Related: Should I avoid the V2 API given the lack of a good example to guide me? As I&amp;#39;m developing a new device, I&amp;#39;d like to adopt the most contemporary APIs, but perhaps I&amp;#39;m jumping the gun on this one...[/quote]
&lt;p&gt;While not in the SDK, there exists some short examples to demonstrate the usage of the V2 driver, please see &lt;a href="https://github.com/NordicSemiconductor/nrfx/wiki/nrfx-1.8.1-to-2.0.0#saadc-1"&gt;the SAADC section of the nrfx changelog for this&lt;/a&gt;. In this case, the &lt;a href="https://github.com/NordicSemiconductor/nrfx/wiki/SAADC-Simple-mode-with-IRQs"&gt;Simple mode with IRQ example&lt;/a&gt;&amp;nbsp;might be especially useful to take a look at. &lt;br /&gt;It is hard for me to advise on whether you could stick to the old SAADC driver, or should make the change to V2 since I do not know about the specifics of your project, but I definitely recommend getting familiar with the V2, as it is a improvement of the old driver. You might also want to consider having your sampling trigger by PPI, instead of by CPU intervention - especially if it is important that sampling is not interrupted or delayed due to the SoftDevice controlling the CPU.&lt;br /&gt;&lt;br /&gt;Please do not hesitate to ask if anything should be unclear, or if you should encounter any issues or questions! :)&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280203?ContentTypeID=1</link><pubDate>Mon, 16 Nov 2020 20:26:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:337b67ca-fc04-439f-b22a-114f658c2581</guid><dc:creator>Christopher Hunt</dc:creator><description>&lt;p&gt;So if I ignore the invalid state then during the timer handler, I&amp;#39;m not yet able to see any sampling come through i.e. I don&amp;#39;t see an&amp;nbsp;NRFX_SAADC_EVT_DONE raised. Anything else obviously missing from my setup?&lt;/p&gt;
&lt;p&gt;Related: Should I avoid the V2 API given the lack of a good example to guide me? As I&amp;#39;m developing a new device, I&amp;#39;d like to adopt the most contemporary APIs, but perhaps I&amp;#39;m jumping the gun on this one...&lt;/p&gt;
&lt;p&gt;Thanks.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280202?ContentTypeID=1</link><pubDate>Mon, 16 Nov 2020 20:13:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c44f3b96-371f-41c7-bbf0-69284432d75d</guid><dc:creator>Christopher Hunt</dc:creator><description>&lt;p&gt;Thanks for the reply, Karl.&lt;/p&gt;
&lt;p&gt;Gosh, I missed that description of the return code having even inspected the source! So, I should ignore the invalid state code perhaps during my timer event, as it is quite legitimate to be in this invalid state?&lt;/p&gt;
&lt;p&gt;The timer is firing once per 100ms i.e. 10 times per second.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: SAADC V2 sampling using the RTC</title><link>https://devzone.nordicsemi.com/thread/280114?ContentTypeID=1</link><pubDate>Mon, 16 Nov 2020 13:38:36 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8c915c83-99f0-462c-ab08-e6feb639c10f</guid><dc:creator>Karl Ylvisaker</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
[quote user=""]In summary, my program receives an &amp;quot;ERROR 8 [NRF_ERROR_INVALID_STATE]&amp;quot; when calling the nrfx_saadc_mode_trigger function.[/quote]
&lt;p&gt;Great, then we have something very specific to look into here.&lt;br /&gt;An exempt from &lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fdrivers_nrfx_v2.4.0%2Fgroup__nrfx__saadc.html&amp;amp;anchor=ga172d9c365082d686532d965ec45c03d5"&gt;the nrfx_saadc_mode_trigger function API Reference documentation&lt;/a&gt; reads:&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan="1" rowspan="1"&gt;NRFX_ERROR_INVALID_STATE&lt;/td&gt;
&lt;td colspan="1" rowspan="1"&gt;There is an ongoing conversion being performed in the non-blocking manner or the driver is in the idle mode.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
[quote user=""]Am I under the false impression that the timer should trigger the sampling?[/quote][quote user=""]A timer is created and, when it fires, it then triggers the sampling:[/quote]
&lt;p&gt;How often do you intend to sample? How often does this RTC trigger?&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Karl&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>