<?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>Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/39454/calibrating-saadc-on-nrf52832</link><description>Hi, 
 I am using an nRF52832 with S132 and SDK v15.0.0 and already read in the forum about issues related to the SAADC calibration (inlcuing the erratum [86]). The problem I have is that the ADC constantly (not only once!) delivers wrong data after I</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 01 Mar 2021 14:20:11 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/39454/calibrating-saadc-on-nrf52832" /><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/296893?ContentTypeID=1</link><pubDate>Mon, 01 Mar 2021 14:20:11 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:97431ec2-0c3b-41f2-b1d9-f9635b4a1683</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;Have you taken a look at this repository:&lt;br /&gt;&lt;a href="https://github.com/NordicPlayground/nRF52-ADC-examples/tree/master/nrfx_saadc_simple_low_power_app_timer_multichannel_oversample"&gt;https://github.com/NordicPlayground/nRF52-ADC-examples/tree/master/nrfx_saadc_simple_low_power_app_timer_multichannel_oversample&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kenneth&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/296726?ContentTypeID=1</link><pubDate>Mon, 01 Mar 2021 02:54:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:25e0e03b-2b4c-4f3d-980b-63a00b6a8632</guid><dc:creator>N Ashelman</dc:creator><description>&lt;p&gt;Thanks for sharing your experiences. Indeed, as you found, I can get calibration to run successfully once at startup (but not again), but I too am not observing much improvement. Without calibration, I am measuring GROUND at -1 to -2 raw value (10-bit). Calibration will sometimes bring this to zero, but sometimes not. Have not tried yet under temperature variations.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;If you are able to dig up the old code, it might be of use to me &amp;amp; others using this ticket in the future. It seems to come up pretty high in search results :-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/296687?ContentTypeID=1</link><pubDate>Sat, 27 Feb 2021 17:19:25 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:138fd757-4c47-462a-9c69-940cb92ea988</guid><dc:creator>Franz</dc:creator><description>&lt;p&gt;Hi! &lt;/p&gt;
&lt;p&gt;I would have to check next week since I do not remember the exact code that I used to get rid of the described error. I only remeber that I changes my ADC code to only have one channel enabled at a time. I can send you the piece in a few days if you whish. One BIG word of caution, though.&lt;/p&gt;
&lt;p&gt;Although I managed to get rid of the error and calibration in regular interval does not throw errors, I have the feeling that calibration does not work at all on the 52832. Of course I cannot prove that or be sure, but&amp;nbsp; we invested a lot of time to measure the code the adc delivers on a number of boards under controlled thermal conditions and we had one devkit with nrf52832 where the calibration even made things worse than without any calibration.&lt;/p&gt;
&lt;p&gt;I had another private ticket open on a similar topic because of confidential code, but we never managed to get rid of problems with bad performance of calibration (we have &amp;quot;jumps&amp;quot; in the signal of about 6 LSB12b, which might be ok from a datasheet perspective, but does defeat the purpose of the calibration unless you use a very wide temperature range).&lt;/p&gt;
&lt;p&gt;BR&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/296468?ContentTypeID=1</link><pubDate>Fri, 26 Feb 2021 09:56:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3f1c9591-b8e8-40e0-95f2-08de8f0c71aa</guid><dc:creator>N Ashelman</dc:creator><description>&lt;p&gt;Hi Franz:&lt;br /&gt;I have used the example code for calibrate_saadc() and having the same &lt;span&gt;NRFX_ERROR_INVALID_STATE&amp;nbsp;&lt;/span&gt;problem you reported earlier. Could you give some more details about how you solved this?&lt;br /&gt;How can calibration be so hard? Looks like it&amp;#39;s time for Nordic to add a library on top of the driver to support this kind of stuff...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/208560?ContentTypeID=1</link><pubDate>Sun, 08 Sep 2019 13:11:54 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d9fa7d76-62cb-4097-a20d-3a89e66ce3a2</guid><dc:creator>Franz</dc:creator><description>&lt;p&gt;Problem was the missing workaround of PAN86, among one additional code bug.. closed&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/161056?ContentTypeID=1</link><pubDate>Mon, 10 Dec 2018 16:01:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e6e88cc6-85ac-48e9-b039-cce51d71d809</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;I am not sure what more debugging that can be done from here, but looking at the code it seems that&amp;nbsp;nrfx_saadc_sample() will report&amp;nbsp;NRFX_ERROR_INVALID_STATE if m_cb.adc_state != NRF_SAADC_STATE_BUSY.&lt;/p&gt;
&lt;p&gt;So maybe your first task is to set a breakpoint when&amp;nbsp;err_code = NRFX_ERROR_INVALID_STATE; in&amp;nbsp;nrfx_saadc_sample() to find the actual value of&amp;nbsp;m_cb.adc_state. And then you can add a log output every time&amp;nbsp;m_cb.adc_state is set to the specific value to find which function is called that set it to !&lt;span&gt;NRF_SAADC_STATE_BUSY in this case.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards,&lt;br /&gt;Kenneth&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/160933?ContentTypeID=1</link><pubDate>Mon, 10 Dec 2018 10:26:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:67c044f2-b2f4-4c4a-b9fa-449cc97a2e52</guid><dc:creator>Franz</dc:creator><description>&lt;p&gt;&lt;span&gt;Hi Kenneth,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It&amp;acute;s been some time. any update to this?&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/153128?ContentTypeID=1</link><pubDate>Wed, 17 Oct 2018 06:29:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cb3cf03a-6e89-4a2a-8687-d066335d145b</guid><dc:creator>Franz</dc:creator><description>&lt;p&gt;Hi Kenneth,&lt;/p&gt;
&lt;p&gt;Well sorry, I could have found out that for myself. My program crashed around the line, where the ADC is initilaised with &amp;quot;NULL&amp;quot;, so I was a bit blinded but actually, the crash happened somwhere else.&lt;/p&gt;
&lt;p&gt;However, back to the main topic of my question: I still have troubles using the offset calibration. My program does essentially the same as your provided example code and more specifically, it uses the exact code of the &amp;quot;calibrate_saadc&amp;quot; function.&lt;/p&gt;
&lt;p&gt;Unfortunately, when i have the call to the calibrate function in my code (right after nrfx_saadc_init), the program hangs in &amp;quot;nrfx_saadc_sample()&amp;quot; with &amp;quot;NRFX_ERROR_INVALID_STATE&amp;quot; after the first adc conversion (1 sample per CH) is complete.&lt;/p&gt;
&lt;p&gt;This does not happen when I comment the line with the call to the calibrate function during adc initialisation.&lt;/p&gt;
&lt;p&gt;Any hints?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/153105?ContentTypeID=1</link><pubDate>Tue, 16 Oct 2018 16:24:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bf5a26d4-ea66-465e-83af-6e6a374aa5a6</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;It is example code so please change this as you see fit, but basically using NULL will set default settings from sdk_config.h&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;__STATIC_INLINE ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config,
                                              nrf_drv_saadc_event_handler_t  event_handler)
{
    if (p_config == NULL)
    {
        static const nrfx_saadc_config_t default_config = NRFX_SAADC_DEFAULT_CONFIG;
        p_config = &amp;amp;default_config;
    }
    return nrfx_saadc_init(p_config, event_handler);
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/153045?ContentTypeID=1</link><pubDate>Tue, 16 Oct 2018 11:46:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8f472cd5-dcb9-4cc0-bd2b-461832e54e7b</guid><dc:creator>Franz</dc:creator><description>&lt;p&gt;E.g. line number 99 in the code example you shared above.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/152963?ContentTypeID=1</link><pubDate>Tue, 16 Oct 2018 06:59:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:392ac68d-7320-480f-b6a5-d720521bd967</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;About 5) What file and line number are you referring to?&lt;/p&gt;
&lt;p&gt;Kenneth&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/152952?ContentTypeID=1</link><pubDate>Tue, 16 Oct 2018 05:51:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fbcb242d-2421-4a2b-90d8-c6e916972500</guid><dc:creator>Franz</dc:creator><description>&lt;p&gt;Hi Kenneth,&lt;/p&gt;
&lt;p&gt;Thanks for the reply.&lt;/p&gt;
&lt;p&gt;According to the numbering of my initial questions:&lt;/p&gt;
&lt;p&gt;3.) Good to know, so it is no problem with IR processing because the delay until the IR is handled, is big enough in any case?&lt;/p&gt;
&lt;p&gt;4.) Will have to check where in the forum I saw it, I will come back to that.&lt;/p&gt;
&lt;p&gt;5.) Well there is one thing I want to ask about this example which is also somthing I did not understand in another example: How is the call to&amp;nbsp;err_code = nrf_drv_saadc_init(NULL, saadc_callback); supposed to work?&lt;/p&gt;
&lt;p&gt;I use nrfx_saadc_init(NULL,saadc_callback); according to the new API in SDK V15, but there is a line in the function &amp;quot;nrfx_saadc_init(NULL,saadc_callback);&amp;quot; that obviously returns immediately if the function is called with a NULL pointer. What is the reason for nto initialising with a proper &amp;quot;ADC config structure&amp;quot; ?&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Calibrating SAADC on nrf52832</title><link>https://devzone.nordicsemi.com/thread/152901?ContentTypeID=1</link><pubDate>Mon, 15 Oct 2018 13:28:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b961c959-2654-43ba-8735-645e3aaa7cd5</guid><dc:creator>Kenneth</dc:creator><description>&lt;p&gt;Hi,&amp;nbsp;&lt;/p&gt;
[quote user=""]Do I have to do a dummy TASK_SAMPLE before calling the abort function so that a conversion is in progress?[/quote]
&lt;p&gt;See this case:&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/29806/nrf52832-sdk14---saadc-calibration-issues"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/29806/nrf52832-sdk14---saadc-calibration-issues&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1.&amp;nbsp;You should implement according to Errata 86 if you are using calibrate offset yes.&lt;/p&gt;
&lt;p&gt;2. This is already handled in&amp;nbsp;nrfx_saadc_abort().&lt;/p&gt;
&lt;p&gt;3. The transfer to RAM may be a problem if you are directly using this as a pointer value for other peripheral, e.g. have a saadc done event to uart start tx task. But for interrupt processing it&amp;#39;s not a problem.&lt;/p&gt;
&lt;p&gt;4. Not sure if I see that, what examples project and source file are you referring to?&lt;/p&gt;
&lt;p&gt;5. A colleague made this example, maybe it can help you also:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/**
 * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 * 
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 * 
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 * 
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 * 
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA &amp;quot;AS IS&amp;quot; AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */
/** @file
 * @defgroup nrf_adc_example main.c
 * @{
 * @ingroup nrf_adc_example
 * @brief ADC Example Application main file.
 *
 * This file contains the source code for a sample application using ADC.
 *
 * @image html example_board_setup_a.jpg &amp;quot;Use board setup A for this example.&amp;quot;
 */

#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;nrf_drv_saadc.h&amp;quot;

#include &amp;quot;boards.h&amp;quot;
#include &amp;quot;app_error.h&amp;quot;
#include &amp;quot;nrf_delay.h&amp;quot;
#include &amp;quot;app_util_platform.h&amp;quot;
#include &amp;quot;nrf_pwr_mgmt.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;

#define SAMPLES_IN_BUFFER 5
#define HW_TIMEOUT 10000


nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER];

void calibrate_saadc(void);

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;

        err_code = nrf_drv_saadc_buffer_convert(p_event-&amp;gt;data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        for (uint8_t i = 0; i &amp;lt; SAMPLES_IN_BUFFER; i++)
        {
            NRF_LOG_INFO(&amp;quot;%d&amp;quot;, p_event-&amp;gt;data.done.p_buffer[i]);
        }
    }
}


void saadc_init(void)
{
    ret_code_t err_code;
    nrf_saadc_channel_config_t channel_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);

    err_code = nrf_drv_saadc_init(NULL, saadc_callback);
    APP_ERROR_CHECK(err_code);

    calibrate_saadc();

    err_code = nrf_drv_saadc_channel_init(0, &amp;amp;channel_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}

void calibrate_saadc(void)
{
    nrfx_err_t nrfx_err_code = NRFX_SUCCESS;

    // Stop ADC
    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    NRFX_IRQ_DISABLE(SAADC_IRQn);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);

    // Wait for ADC being stopped.
    bool result;
    NRFX_WAIT_FOR(nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED), HW_TIMEOUT, 0, result);
    NRFX_ASSERT(result);

    // Start calibration
    NRFX_IRQ_ENABLE(SAADC_IRQn);
    nrfx_err_code = nrfx_saadc_calibrate_offset();
    APP_ERROR_CHECK(nrfx_err_code);
    while(nrfx_saadc_is_busy()){};
    
    // Stop ADC
    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    NRFX_IRQ_DISABLE(SAADC_IRQn);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);

    // Wait for ADC being stopped. 
    NRFX_WAIT_FOR(nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED), HW_TIMEOUT, 0, result);
    NRFX_ASSERT(result);
    
    // Enable IRQ
    NRFX_IRQ_ENABLE(SAADC_IRQn);

}


/**
 * @brief Function for main application entry.
 */
int main(void)
{
    uint32_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();

    ret_code_t ret_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(ret_code);

    saadc_init();

    NRF_LOG_INFO(&amp;quot;SAADC calibration example started.&amp;quot;);

    while (1)
    {
        nrf_pwr_mgmt_run();
        NRF_LOG_FLUSH();
    }
}


/** @} */
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>