<?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>Manually triggering SAADC - which to use?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/70290/manually-triggering-saadc---which-to-use</link><description>I want to trigger SAADC samples manually, when a certain BLE message arrives. I&amp;#39;d ideally like to have a trigger scan 4 individual channels. 
 I see two function calls, though. Here are their descriptions: 
 
 nrfx_saadc_mode_trigger() - Function for</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 11 Jan 2021 12:47:23 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/70290/manually-triggering-saadc---which-to-use" /><item><title>RE: Manually triggering SAADC - which to use?</title><link>https://devzone.nordicsemi.com/thread/288376?ContentTypeID=1</link><pubDate>Mon, 11 Jan 2021 12:47:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5b2372a8-223a-4eb9-9efd-6b0134f5e60b</guid><dc:creator>haakonsh</dc:creator><description>&lt;p&gt;When you call the&amp;nbsp;&lt;span&gt;buffer_convert function in the saadc callback you&amp;#39;re telling the driver to switch to the next buffer. The pointer given to&amp;nbsp;buffer_convert is then added to the queue.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Manually triggering SAADC - which to use?</title><link>https://devzone.nordicsemi.com/thread/288375?ContentTypeID=1</link><pubDate>Mon, 11 Jan 2021 12:44:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:94750261-3acd-44d7-8281-ddc959ce7821</guid><dc:creator>haakonsh</dc:creator><description>[quote user=""]&lt;p&gt;I see two function calls, though.&amp;nbsp; Here are their descriptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nrfx_saadc_mode_trigger() -&amp;nbsp;&lt;span&gt;Function for triggering the conversion in the configured mode.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;nrfx_saadc_sample() -&amp;nbsp;&lt;span&gt;Function for starting the SAADC sampling.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;[/quote]
&lt;p&gt;&amp;nbsp;use&amp;nbsp;&lt;a title="nrfx_saadc_sample" href="https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__nrfx__saadc.html?cp=7_1_6_8_0_30_1_20#gaf117e087540c455a6dfe05f258d118f0"&gt;nrfx_saadc_sample&lt;/a&gt;.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
[quote user=""]&lt;p&gt;Then, to make things even more confusing, there&amp;#39;s this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nrf_drv_saadc_buffer_convert() - The function nrf_drv_saadc_buffer_convert() can be used to start the conversion in non-blocking mode&lt;/li&gt;&lt;/ul&gt;[/quote]
&lt;p&gt;&amp;nbsp;It prepares the next buffer by writing to the&amp;nbsp;&lt;a title="  RESULT.PTR  " href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/saadc.html?cp=4_2_0_36_10_40#register.RESULT.PTR"&gt;RESULT.PTR&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a title="  RESULT.MAXCNT  " href="https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/saadc.html?cp=4_2_0_36_10_41#register.RESULT.MAXCNT"&gt;RESULT.MAXCNT&lt;/a&gt;&amp;nbsp;registers and then triggering a START task. It does not start sampling however.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
[quote user=""]where SAMPLES_IN_BUFFER is 4 beacuse I&amp;#39;m scanning 4 channels, and [2] is because it&amp;#39;s somehow double buffering.&amp;nbsp; With manual triggering, I&amp;#39;m not really sure that&amp;#39;s necessary, though, is it?[/quote]
&lt;p&gt;&amp;nbsp;If you trigger another SAMPLE task before you have process your buffer you will override it, double-buffering prevents that. Whether you need it or not is up to you to decide.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Manually triggering SAADC - which to use?</title><link>https://devzone.nordicsemi.com/thread/288263?ContentTypeID=1</link><pubDate>Sat, 09 Jan 2021 16:12:02 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:586f3577-5833-432b-8f57-fbdb14e839cf</guid><dc:creator>wz2b</dc:creator><description>&lt;p&gt;I am kind of thinking that the callback calls&amp;nbsp;nrf_drv_saadc_buffer_convert() to hand a userspace chunk of memory back to the SAADC driver so that it can use it.&amp;nbsp; I&amp;#39;m thinking it&amp;#39;s more of a queueing kind of operation.&amp;nbsp; So in the example, it calls it twice in init() I think to hand both buffers to the SAADC driver.&amp;nbsp; Then in the callback, it uses it to tell the SAADC driver that userspace has taken the data it wants out, and so it is handing the buffer BACK to the SAADC driver for the next time.&amp;nbsp; What&amp;#39;s confusing is that in the example code it calls buffer_convert before it actually uses the data.&amp;nbsp; I think, logically, it would be the other way around: you get a callback, and it&amp;#39;s p_event -&amp;gt;data.done.p_buffer is a pointer to the buffer.&amp;nbsp; I would think you would 1) consume that data 2) when you are DONE call buffer_convert() to hand the buffer back to the SAADC driver.&amp;nbsp; But it does it the opposite way.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;static void saadc_callback(nrf_drv_saadc_evt_t const *p_event) {
  if (p_event-&amp;gt;type == NRF_DRV_SAADC_EVT_DONE) {
    ret_code_t err_code;
    uint16_t adc_value;
    uint8_t value[SAADC_SAMPLES_IN_BUFFER * 2];
    uint16_t bytes_to_send;

    // set buffers
    // The function nrf_drv_saadc_buffer_convert can be used to start
    // conversion in non-blocking mode. The function returns immediately
    // after the buffer is configured. If the driver is busy, it returns
    // with an error. nrf_drv_saadc_buffer_convert sets the SAADC up for
    // conversion, but does not trigger sampling. To trigger sampling,
    // call the function nrf_drv_saadc_sample or, through PPI, use the
    // task SAMPLE from SAADC. nrf_drv_saadc_sample_task_get can be used
    // to get the task address. Single sampling triggers conversion on
    // all initialized channels. When the requested buffer is filled
    // with samples, an event of type NRF_DRV_SAADC_EVT_DONE is generated.
    err_code = nrf_drv_saadc_buffer_convert(p_event-&amp;gt;data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

    // print samples on hardware UART and parse data for BLE transmission
    printf(&amp;quot;ADC event number: %d\r\n&amp;quot;, (int)m_adc_evt_counter);
    for (int i = 0; i &amp;lt; SAADC_SAMPLES_IN_BUFFER; i++) {
      printf(&amp;quot;%d\r\n&amp;quot;, p_event-&amp;gt;data.done.p_buffer[i]);

      adc_value = p_event-&amp;gt;data.done.p_buffer[i];
      value[i * 2] = adc_value;
      value[(i * 2) + 1] = adc_value &amp;gt;&amp;gt; 8;
    }

    // Send data over BLE via NUS service. Create string from samples and send string with correct length.
    uint8_t nus_string[50];
    bytes_to_send = sprintf(nus_string,
        &amp;quot;CH0: %d\r\nCH1: %d\r\nCH2: %d\r\nCH3: %d&amp;quot;,
        p_event-&amp;gt;data.done.p_buffer[0],
        p_event-&amp;gt;data.done.p_buffer[1],
        p_event-&amp;gt;data.done.p_buffer[2],
        p_event-&amp;gt;data.done.p_buffer[3]);

    //        err_code = ble_nus_data_send(&amp;amp;m_nus, nus_string, &amp;amp;bytes_to_send, m_conn_handle);
    if ((err_code != NRF_ERROR_INVALID_STATE) &amp;amp;&amp;amp; (err_code != NRF_ERROR_NOT_FOUND)) {
      APP_ERROR_CHECK(err_code);
    }

    m_adc_evt_counter++;
  }
}
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>