<?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>nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/107330/nrf52833-adc-not-giving-accurate-value</link><description>Hi all, 
 We have been working to scan 4 analog inputs from the 4 analog channels (AIN0,AIN1,AIN5,AIN7). To implement this we are using &amp;quot;saadc driver&amp;quot; provided by nrf on our chipset nrf52833. Currently I am using 10 bit resolution and single ended mode</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 16 Jan 2024 10:23:52 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/107330/nrf52833-adc-not-giving-accurate-value" /><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464349?ContentTypeID=1</link><pubDate>Tue, 16 Jan 2024 10:23:52 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:55dfdb4b-4a21-4a08-b335-d9b82ed9b297</guid><dc:creator>Jared</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;As already mentioned by the other user. Anything over VDD + 0V3 is over the maximum voltage that the nRF can handle. If you expose it to any higher voltage then the protection diode will start to lead and eventually break resulting in the nRF being damaged.&lt;/p&gt;
&lt;p&gt;You need to make sure that the resistor divider scales down the voltage so that it&amp;#39;s always inside the working voltage range of the nRF52833.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;regards&lt;br /&gt;Jared&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464285?ContentTypeID=1</link><pubDate>Tue, 16 Jan 2024 05:18:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:64d0bf65-35ff-47cc-b113-23527ec734f9</guid><dc:creator>Ramfrost</dc:creator><description>&lt;p&gt;Thank You so much for&amp;nbsp;your suggestions, I will have a conversation with my hardware designer and will update about it later.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464269?ContentTypeID=1</link><pubDate>Mon, 15 Jan 2024 18:20:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2a8ba4ad-a51e-48ee-9384-edfc935c2848</guid><dc:creator>hmolesworth</dc:creator><description>&lt;p&gt;Not clear which connector pin is actually used for the input voltage, but it looks like it feeds the voltage divider (2 resistors of equal value) which therefore delivers &lt;em&gt;(Input voltage)/2&lt;/em&gt; to the analogue input pin. I quote:&lt;/p&gt;
&lt;p&gt;&amp;quot;&lt;em&gt;With internal reference, single ended input (grounded negative input), and a gain of 1/6 the input range will be:&amp;nbsp;&lt;/em&gt;&lt;em&gt;Input range = (0.6 V)/(1/6) = 3.6 V&lt;/em&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;So the maximum input voltage using the resistor divider is &lt;em&gt;2 * 3.6V = 7.2V. &lt;/em&gt;Any input voltage applied to that resistor divider above 7.2 volts will saturate the SAADC and may not be correctly converted .. and worse still:&lt;/p&gt;
&lt;p&gt;&amp;quot;&lt;em&gt;The AIN0-AIN7 inputs cannot exceed VDD, or be lower than VSS.&lt;/em&gt;&amp;quot; which means that the nRF52833 input pin is limited to VCC (3.6 volts max) so any voltage above that 7.2 volt input at the external connector will cause a fault condition and the internal schottky clamp diode will connect the input voltage to the internal VDD which is very bad when low-value resistors are used and may cause irreparable damage.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Solution&lt;/em&gt;: Try increasing the value of the upper resistor in the resistor divider such that an input voltage of 10 volts at the connector gives less than 3.6 volts (actually the nRF52 VDD) at the analogue input&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464264?ContentTypeID=1</link><pubDate>Mon, 15 Jan 2024 17:40:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dfc051b0-18ec-4574-931a-d71ab6d9c64d</guid><dc:creator>Ramfrost</dc:creator><description>&lt;p&gt;Currently I do not have bench top supply and that is why I am using a Switch Mode Power Supply and yes I have measured the voltage it is constant. The Accuracy is better with a different kind of Analog Input source but I am getting proper values only in the range of 0v to 7v but when the source voltage at analog input pin gets in the range of 9v - 10v, I start getting the half adc resoultion which is close to 500 adc register value&amp;nbsp;whose corresponding voltage is close to 5v.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464235?ContentTypeID=1</link><pubDate>Mon, 15 Jan 2024 15:17:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6f166871-4046-4cc3-8e50-c5c4d4e967dd</guid><dc:creator>Jared</dc:creator><description>[quote user="Jared"]How is your board supplied, have you tried supplying the board from a bench top supply and measure a fixed voltage from a bench top supply? Is the accuracy improved?[/quote]
&lt;p&gt;Can you try this?&lt;/p&gt;
&lt;p&gt;regards&lt;/p&gt;
&lt;p&gt;Jared&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464020?ContentTypeID=1</link><pubDate>Fri, 12 Jan 2024 17:53:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b26bb004-b6a8-47eb-9329-12624b42d705</guid><dc:creator>Ramfrost</dc:creator><description>&lt;p&gt;This is the schematics.&lt;a href="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/Schematic_5F00_IO-_2D00_-4DI3D4AI2AM_5F00_2023_2D00_12_2D00_26.pdf"&gt;devzone.nordicsemi.com/.../Schematic_5F00_IO-_2D00_-4DI3D4AI2AM_5F00_2023_2D00_12_2D00_26.pdf&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464019?ContentTypeID=1</link><pubDate>Fri, 12 Jan 2024 17:19:13 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4c52122c-9d21-455e-b040-70efdb98b446</guid><dc:creator>Ramfrost</dc:creator><description>&lt;p&gt;The last one.&lt;pre class="ui-code" data-mode="text"&gt;//this is nrf_saadc.h
/**
 * Copyright (c) 2015 - 2017, 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.
 * 
 */


#ifndef NRF_SAADC_H_
#define NRF_SAADC_H_

/**
 * @defgroup nrf_saadc_hal SAADC HAL
 * @{
 * @ingroup nrf_saadc
 *
 * @brief @tagAPI52 Hardware access layer for accessing the SAADC peripheral.
 */

#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;quot;nrf.h&amp;quot;
#include &amp;quot;nrf_assert.h&amp;quot;

/* Missing declaration */
/* Bit 24 : Enable burst mode */
#define SAADC_CH_CONFIG_BURST_Pos (24UL) /*!&amp;lt; Position of BURST field. */
#define SAADC_CH_CONFIG_BURST_Msk (0x1UL &amp;lt;&amp;lt; SAADC_CH_CONFIG_BURST_Pos) /*!&amp;lt; Bit mask of BURST field. */
#define SAADC_CH_CONFIG_BURST_Disabled (0UL) /*!&amp;lt; Burst mode is disabled (normal operation) */
#define SAADC_CH_CONFIG_BURST_Enabled (1UL) /*!&amp;lt; Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM. */


#ifdef __cplusplus
extern &amp;quot;C&amp;quot; {
#endif

#define NRF_SAADC_CHANNEL_COUNT 8

/**
 * @brief Resolution of the analog-to-digital converter.
 */
typedef enum
{
    NRF_SAADC_RESOLUTION_8BIT  = SAADC_RESOLUTION_VAL_8bit,  ///&amp;lt; 8 bit resolution.
    NRF_SAADC_RESOLUTION_10BIT = SAADC_RESOLUTION_VAL_10bit, ///&amp;lt; 10 bit resolution.
    NRF_SAADC_RESOLUTION_12BIT = SAADC_RESOLUTION_VAL_12bit, ///&amp;lt; 12 bit resolution.
    NRF_SAADC_RESOLUTION_14BIT = SAADC_RESOLUTION_VAL_14bit  ///&amp;lt; 14 bit resolution.
} nrf_saadc_resolution_t;


/**
 * @brief Input selection for the analog-to-digital converter.
 */
typedef enum
{
    NRF_SAADC_INPUT_DISABLED = SAADC_CH_PSELP_PSELP_NC,           ///&amp;lt; Not connected.
    NRF_SAADC_INPUT_AIN0     = SAADC_CH_PSELP_PSELP_AnalogInput0, ///&amp;lt; Analog input 0 (AIN0).
    NRF_SAADC_INPUT_AIN1     = SAADC_CH_PSELP_PSELP_AnalogInput1, ///&amp;lt; Analog input 1 (AIN1).
    NRF_SAADC_INPUT_AIN2     = SAADC_CH_PSELP_PSELP_AnalogInput2, ///&amp;lt; Analog input 2 (AIN2).
    NRF_SAADC_INPUT_AIN3     = SAADC_CH_PSELP_PSELP_AnalogInput3, ///&amp;lt; Analog input 3 (AIN3).
    NRF_SAADC_INPUT_AIN4     = SAADC_CH_PSELP_PSELP_AnalogInput4, ///&amp;lt; Analog input 4 (AIN4).
    NRF_SAADC_INPUT_AIN5     = SAADC_CH_PSELP_PSELP_AnalogInput5, ///&amp;lt; Analog input 5 (AIN5).
    NRF_SAADC_INPUT_AIN6     = SAADC_CH_PSELP_PSELP_AnalogInput6, ///&amp;lt; Analog input 6 (AIN6).
    NRF_SAADC_INPUT_AIN7     = SAADC_CH_PSELP_PSELP_AnalogInput7, ///&amp;lt; Analog input 7 (AIN7).
    NRF_SAADC_INPUT_VDD      = SAADC_CH_PSELP_PSELP_VDD           ///&amp;lt; VDD as input.
} nrf_saadc_input_t;


/**
 * @brief Analog-to-digital converter oversampling mode.
 */
typedef enum
{
    NRF_SAADC_OVERSAMPLE_DISABLED = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass,   ///&amp;lt; No oversampling.
    NRF_SAADC_OVERSAMPLE_2X       = SAADC_OVERSAMPLE_OVERSAMPLE_Over2x,   ///&amp;lt; Oversample 2x.
    NRF_SAADC_OVERSAMPLE_4X       = SAADC_OVERSAMPLE_OVERSAMPLE_Over4x,   ///&amp;lt; Oversample 4x.
    NRF_SAADC_OVERSAMPLE_8X       = SAADC_OVERSAMPLE_OVERSAMPLE_Over8x,   ///&amp;lt; Oversample 8x.
    NRF_SAADC_OVERSAMPLE_16X      = SAADC_OVERSAMPLE_OVERSAMPLE_Over16x,  ///&amp;lt; Oversample 16x.
    NRF_SAADC_OVERSAMPLE_32X      = SAADC_OVERSAMPLE_OVERSAMPLE_Over32x,  ///&amp;lt; Oversample 32x.
    NRF_SAADC_OVERSAMPLE_64X      = SAADC_OVERSAMPLE_OVERSAMPLE_Over64x,  ///&amp;lt; Oversample 64x.
    NRF_SAADC_OVERSAMPLE_128X     = SAADC_OVERSAMPLE_OVERSAMPLE_Over128x, ///&amp;lt; Oversample 128x.
    NRF_SAADC_OVERSAMPLE_256X     = SAADC_OVERSAMPLE_OVERSAMPLE_Over256x  ///&amp;lt; Oversample 256x.
} nrf_saadc_oversample_t;


/**
 * @brief Analog-to-digital converter channel resistor control.
 */
typedef enum
{
    NRF_SAADC_RESISTOR_DISABLED = SAADC_CH_CONFIG_RESP_Bypass,   ///&amp;lt; Bypass resistor ladder.
    NRF_SAADC_RESISTOR_PULLDOWN = SAADC_CH_CONFIG_RESP_Pulldown, ///&amp;lt; Pull-down to GND.
    NRF_SAADC_RESISTOR_PULLUP   = SAADC_CH_CONFIG_RESP_Pullup,   ///&amp;lt; Pull-up to VDD.
    NRF_SAADC_RESISTOR_VDD1_2   = SAADC_CH_CONFIG_RESP_VDD1_2    ///&amp;lt; Set input at VDD/2.
} nrf_saadc_resistor_t;


/**
 * @brief Gain factor of the analog-to-digital converter input.
 */
typedef enum
{
    NRF_SAADC_GAIN1_6 = SAADC_CH_CONFIG_GAIN_Gain1_6, ///&amp;lt; Gain factor 1/6.
    NRF_SAADC_GAIN1_5 = SAADC_CH_CONFIG_GAIN_Gain1_5, ///&amp;lt; Gain factor 1/5.
    NRF_SAADC_GAIN1_4 = SAADC_CH_CONFIG_GAIN_Gain1_4, ///&amp;lt; Gain factor 1/4.
    NRF_SAADC_GAIN1_3 = SAADC_CH_CONFIG_GAIN_Gain1_3, ///&amp;lt; Gain factor 1/3.
    NRF_SAADC_GAIN1_2 = SAADC_CH_CONFIG_GAIN_Gain1_2, ///&amp;lt; Gain factor 1/2.
    NRF_SAADC_GAIN1   = SAADC_CH_CONFIG_GAIN_Gain1,   ///&amp;lt; Gain factor 1.
    NRF_SAADC_GAIN2   = SAADC_CH_CONFIG_GAIN_Gain2,   ///&amp;lt; Gain factor 2.
    NRF_SAADC_GAIN4   = SAADC_CH_CONFIG_GAIN_Gain4,   ///&amp;lt; Gain factor 4.
} nrf_saadc_gain_t;


/**
 * @brief Reference selection for the analog-to-digital converter.
 */
typedef enum
{
    NRF_SAADC_REFERENCE_INTERNAL = SAADC_CH_CONFIG_REFSEL_Internal, ///&amp;lt; Internal reference (0.6 V).
    NRF_SAADC_REFERENCE_VDD4     = SAADC_CH_CONFIG_REFSEL_VDD1_4    ///&amp;lt; VDD/4 as reference.
} nrf_saadc_reference_t;


/**
 * @brief Analog-to-digital converter acquisition time.
 */
typedef enum
{
    NRF_SAADC_ACQTIME_3US  = SAADC_CH_CONFIG_TACQ_3us,  ///&amp;lt; 3 us.
    NRF_SAADC_ACQTIME_5US  = SAADC_CH_CONFIG_TACQ_5us,  ///&amp;lt; 5 us.
    NRF_SAADC_ACQTIME_10US = SAADC_CH_CONFIG_TACQ_10us, ///&amp;lt; 10 us.
    NRF_SAADC_ACQTIME_15US = SAADC_CH_CONFIG_TACQ_15us, ///&amp;lt; 15 us.
    NRF_SAADC_ACQTIME_20US = SAADC_CH_CONFIG_TACQ_20us, ///&amp;lt; 20 us.
    NRF_SAADC_ACQTIME_40US = SAADC_CH_CONFIG_TACQ_40us  ///&amp;lt; 40 us.
} nrf_saadc_acqtime_t;


/**
 * @brief Analog-to-digital converter channel mode.
 */
typedef enum
{
    NRF_SAADC_MODE_SINGLE_ENDED = SAADC_CH_CONFIG_MODE_SE,  ///&amp;lt; Single ended, PSELN will be ignored, negative input to ADC shorted to GND.
    NRF_SAADC_MODE_DIFFERENTIAL = SAADC_CH_CONFIG_MODE_Diff ///&amp;lt; Differential mode.
} nrf_saadc_mode_t;


/**
 * @brief Analog-to-digital converter channel burst mode.
 */
typedef enum
{
    NRF_SAADC_BURST_DISABLED = SAADC_CH_CONFIG_BURST_Disabled, ///&amp;lt; Burst mode is disabled (normal operation).
    NRF_SAADC_BURST_ENABLED  = SAADC_CH_CONFIG_BURST_Enabled   ///&amp;lt; Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM.
} nrf_saadc_burst_t;


/**
 * @brief Analog-to-digital converter tasks.
 */
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
    NRF_SAADC_TASK_START           = offsetof(NRF_SAADC_Type, TASKS_START),           ///&amp;lt; Start the ADC and prepare the result buffer in RAM.
    NRF_SAADC_TASK_SAMPLE          = offsetof(NRF_SAADC_Type, TASKS_SAMPLE),          ///&amp;lt; Take one ADC sample. If scan is enabled, all channels are sampled.
    NRF_SAADC_TASK_STOP            = offsetof(NRF_SAADC_Type, TASKS_STOP),            ///&amp;lt; Stop the ADC and terminate any on-going conversion.
    NRF_SAADC_TASK_CALIBRATEOFFSET = offsetof(NRF_SAADC_Type, TASKS_CALIBRATEOFFSET), ///&amp;lt; Starts offset auto-calibration.
} nrf_saadc_task_t;


/**
 * @brief Analog-to-digital converter events.
 */
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
    NRF_SAADC_EVENT_STARTED       = offsetof(NRF_SAADC_Type, EVENTS_STARTED),       ///&amp;lt; The ADC has started.
    NRF_SAADC_EVENT_END           = offsetof(NRF_SAADC_Type, EVENTS_END),           ///&amp;lt; The ADC has filled up the result buffer.
    NRF_SAADC_EVENT_DONE          = offsetof(NRF_SAADC_Type, EVENTS_DONE),          ///&amp;lt; A conversion task has been completed.
    NRF_SAADC_EVENT_RESULTDONE    = offsetof(NRF_SAADC_Type, EVENTS_RESULTDONE),    ///&amp;lt; A result is ready to get transferred to RAM.
    NRF_SAADC_EVENT_CALIBRATEDONE = offsetof(NRF_SAADC_Type, EVENTS_CALIBRATEDONE), ///&amp;lt; Calibration is complete.
    NRF_SAADC_EVENT_STOPPED       = offsetof(NRF_SAADC_Type, EVENTS_STOPPED),       ///&amp;lt; The ADC has stopped.
    NRF_SAADC_EVENT_CH0_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITH),  ///&amp;lt; Last result is equal or above CH[0].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH0_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITL),  ///&amp;lt; Last result is equal or below CH[0].LIMIT.LOW.
    NRF_SAADC_EVENT_CH1_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITH),  ///&amp;lt; Last result is equal or above CH[1].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH1_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITL),  ///&amp;lt; Last result is equal or below CH[1].LIMIT.LOW.
    NRF_SAADC_EVENT_CH2_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITH),  ///&amp;lt; Last result is equal or above CH[2].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH2_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITL),  ///&amp;lt; Last result is equal or below CH[2].LIMIT.LOW.
    NRF_SAADC_EVENT_CH3_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITH),  ///&amp;lt; Last result is equal or above CH[3].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH3_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITL),  ///&amp;lt; Last result is equal or below CH[3].LIMIT.LOW.
    NRF_SAADC_EVENT_CH4_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITH),  ///&amp;lt; Last result is equal or above CH[4].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH4_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITL),  ///&amp;lt; Last result is equal or below CH[4].LIMIT.LOW.
    NRF_SAADC_EVENT_CH5_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITH),  ///&amp;lt; Last result is equal or above CH[5].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH5_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITL),  ///&amp;lt; Last result is equal or below CH[5].LIMIT.LOW.
    NRF_SAADC_EVENT_CH6_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITH),  ///&amp;lt; Last result is equal or above CH[6].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH6_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITL),  ///&amp;lt; Last result is equal or below CH[6].LIMIT.LOW.
    NRF_SAADC_EVENT_CH7_LIMITH    = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITH),  ///&amp;lt; Last result is equal or above CH[7].LIMIT.HIGH.
    NRF_SAADC_EVENT_CH7_LIMITL    = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITL)   ///&amp;lt; Last result is equal or below CH[7].LIMIT.LOW.
} nrf_saadc_event_t;


/**
 * @brief Analog-to-digital converter interrupt masks.
 */
typedef enum
{
    NRF_SAADC_INT_STARTED       = SAADC_INTENSET_STARTED_Msk,       ///&amp;lt; Interrupt on EVENTS_STARTED event.
    NRF_SAADC_INT_END           = SAADC_INTENSET_END_Msk,           ///&amp;lt; Interrupt on EVENTS_END event.
    NRF_SAADC_INT_DONE          = SAADC_INTENSET_DONE_Msk,          ///&amp;lt; Interrupt on EVENTS_DONE event.
    NRF_SAADC_INT_RESULTDONE    = SAADC_INTENSET_RESULTDONE_Msk,    ///&amp;lt; Interrupt on EVENTS_RESULTDONE event.
    NRF_SAADC_INT_CALIBRATEDONE = SAADC_INTENSET_CALIBRATEDONE_Msk, ///&amp;lt; Interrupt on EVENTS_CALIBRATEDONE event.
    NRF_SAADC_INT_STOPPED       = SAADC_INTENSET_STOPPED_Msk,       ///&amp;lt; Interrupt on EVENTS_STOPPED event.
    NRF_SAADC_INT_CH0LIMITH     = SAADC_INTENSET_CH0LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[0].LIMITH event.
    NRF_SAADC_INT_CH0LIMITL     = SAADC_INTENSET_CH0LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[0].LIMITL event.
    NRF_SAADC_INT_CH1LIMITH     = SAADC_INTENSET_CH1LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[1].LIMITH event.
    NRF_SAADC_INT_CH1LIMITL     = SAADC_INTENSET_CH1LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[1].LIMITL event.
    NRF_SAADC_INT_CH2LIMITH     = SAADC_INTENSET_CH2LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[2].LIMITH event.
    NRF_SAADC_INT_CH2LIMITL     = SAADC_INTENSET_CH2LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[2].LIMITL event.
    NRF_SAADC_INT_CH3LIMITH     = SAADC_INTENSET_CH3LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[3].LIMITH event.
    NRF_SAADC_INT_CH3LIMITL     = SAADC_INTENSET_CH3LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[3].LIMITL event.
    NRF_SAADC_INT_CH4LIMITH     = SAADC_INTENSET_CH4LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[4].LIMITH event.
    NRF_SAADC_INT_CH4LIMITL     = SAADC_INTENSET_CH4LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[4].LIMITL event.
    NRF_SAADC_INT_CH5LIMITH     = SAADC_INTENSET_CH5LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[5].LIMITH event.
    NRF_SAADC_INT_CH5LIMITL     = SAADC_INTENSET_CH5LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[5].LIMITL event.
    NRF_SAADC_INT_CH6LIMITH     = SAADC_INTENSET_CH6LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[6].LIMITH event.
    NRF_SAADC_INT_CH6LIMITL     = SAADC_INTENSET_CH6LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[6].LIMITL event.
    NRF_SAADC_INT_CH7LIMITH     = SAADC_INTENSET_CH7LIMITH_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[7].LIMITH event.
    NRF_SAADC_INT_CH7LIMITL     = SAADC_INTENSET_CH7LIMITL_Msk,     ///&amp;lt; Interrupt on EVENTS_CH[7].LIMITL event.
    NRF_SAADC_INT_ALL           = 0x7FFFFFFFUL                      ///&amp;lt; Mask of all interrupts.
} nrf_saadc_int_mask_t;


/**
 * @brief Analog-to-digital converter value limit type.
 */
typedef enum
{
    NRF_SAADC_LIMIT_LOW  = 0,
    NRF_SAADC_LIMIT_HIGH = 1
} nrf_saadc_limit_t;


typedef int16_t nrf_saadc_value_t;  ///&amp;lt; Type of a single ADC conversion result.


/**
 * @brief Analog-to-digital converter configuration structure.
 */
typedef struct
{
    nrf_saadc_resolution_t resolution;
    nrf_saadc_oversample_t oversample;
    nrf_saadc_value_t *    buffer;
    uint32_t               buffer_size;
} nrf_saadc_config_t;


/**
 * @brief Analog-to-digital converter channel configuration structure.
 */
typedef struct
{
    nrf_saadc_resistor_t  resistor_p;
    nrf_saadc_resistor_t  resistor_n;
    nrf_saadc_gain_t      gain;
    nrf_saadc_reference_t reference;
    nrf_saadc_acqtime_t   acq_time;
    nrf_saadc_mode_t      mode;
    nrf_saadc_burst_t     burst;
    nrf_saadc_input_t     pin_p;
    nrf_saadc_input_t     pin_n;
} nrf_saadc_channel_config_t;


/**
 * @brief Function for triggering a specific SAADC task.
 *
 * @param[in] saadc_task SAADC task.
 */
__STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task)
{
    *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task)) = 0x1UL;
}


/**
 * @brief Function for getting the address of a specific SAADC task register.
 *
 * @param[in] saadc_task SAADC task.
 *
 * @return Address of the specified SAADC task.
 */
__STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task)
{
    return (uint32_t)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task);
}


/**
 * @brief Function for getting the state of a specific SAADC event.
 *
 * @param[in] saadc_event SAADC event.
 *
 * @return State of the specified SAADC event.
 */
__STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event)
{
    return (bool)*(volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
}


/**
 * @brief Function for clearing the specific SAADC event.
 *
 * @param[in] saadc_event SAADC event.
 */
__STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event)
{
    *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)) = 0x0UL;
#if __CORTEX_M == 0x04
    volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event));
    (void)dummy;
#endif
}


/**
 * @brief Function for getting the address of a specific SAADC event register.
 *
 * @param[in] saadc_event SAADC event.
 *
 * @return Address of the specified SAADC event.
 */
__STATIC_INLINE uint32_t  nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event)
{
    return (uint32_t )((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
}


/**
 * @brief Function for getting the address of a specific SAADC limit event register.
 *
 * @param[in] channel Channel number.
 * @param[in] limit_type Low limit or high limit.
 *
 * @return Address of the specified SAADC limit event.
 */
__STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel, nrf_saadc_limit_t limit_type)
{
    ASSERT(channel &amp;lt; NRF_SAADC_CHANNEL_COUNT);
    if (limit_type == NRF_SAADC_LIMIT_HIGH)
    {
        return &amp;amp;NRF_SAADC-&amp;gt;EVENTS_CH[channel].LIMITH;
    }
    else
    {
        return &amp;amp;NRF_SAADC-&amp;gt;EVENTS_CH[channel].LIMITL;
    }
}


/**
 * @brief Function for getting the SAADC channel monitoring limit events.
 *
 * @param[in] channel    Channel number.
 * @param[in] limit_type Low limit or high limit.
 */
__STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf_saadc_limit_t limit_type)
{
    if (limit_type == NRF_SAADC_LIMIT_HIGH)
    {
        return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH +
                        (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITH - NRF_SAADC_EVENT_CH0_LIMITH)
                        * (uint32_t) channel );
    }
    else
    {
        return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL +
                        (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITL - NRF_SAADC_EVENT_CH0_LIMITL)
                        * (uint32_t) channel );
    }
}


/**
 * @brief Function for configuring the input pins for a specific SAADC channel.
 *
 * @param[in] channel Channel number.
 * @param[in] pselp   Positive input.
 * @param[in] pseln   Negative input. Set to NRF_SAADC_INPUT_DISABLED in single ended mode.
 */
__STATIC_INLINE void nrf_saadc_channel_input_set(uint8_t channel,
                                                 nrf_saadc_input_t pselp,
                                                 nrf_saadc_input_t pseln)
{
    NRF_SAADC-&amp;gt;CH[channel].PSELN = pseln;
    NRF_SAADC-&amp;gt;CH[channel].PSELP = pselp;
}


/**
 * @brief Function for setting the SAADC channel monitoring limits.
 *
 * @param[in] channel Channel number.
 * @param[in] low     Low limit.
 * @param[in] high    High limit.
 */
__STATIC_INLINE void nrf_saadc_channel_limits_set(uint8_t channel, int16_t low, int16_t high)
{
    NRF_SAADC-&amp;gt;CH[channel].LIMIT = (
            (((uint32_t) low &amp;lt;&amp;lt; SAADC_CH_LIMIT_LOW_Pos) &amp;amp; SAADC_CH_LIMIT_LOW_Msk)
          | (((uint32_t) high &amp;lt;&amp;lt; SAADC_CH_LIMIT_HIGH_Pos) &amp;amp; SAADC_CH_LIMIT_HIGH_Msk));
}


/**
 * @brief Function for enabling specified SAADC interrupts.
 *
 * @param[in] saadc_int_mask Interrupt(s) to enable.
 */
__STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask)
{
    NRF_SAADC-&amp;gt;INTENSET = saadc_int_mask;
}


/**
 * @brief Function for retrieving the state of specified SAADC interrupts.
 *
 * @param[in] saadc_int_mask Interrupt(s) to check.
 *
 * @retval true  If all specified interrupts are enabled.
 * @retval false If at least one of the given interrupts is not enabled.
 */
__STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask)
{
    return (bool)(NRF_SAADC-&amp;gt;INTENSET &amp;amp; saadc_int_mask);
}


/**
 * @brief Function for disabling specified interrupts.
 *
 * @param saadc_int_mask Interrupt(s) to disable.
 */
__STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask)
{
    NRF_SAADC-&amp;gt;INTENCLR = saadc_int_mask;
}


/**
 * @brief Function for generating masks for SAADC channel limit interrupts.
 *
 * @param[in] channel    SAADC channel number.
 * @param[in] limit_type Limit type.
 *
 * @returns Interrupt mask.
 */
__STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type)
{
    ASSERT(channel &amp;lt; NRF_SAADC_CHANNEL_COUNT);
    uint32_t mask = (limit_type == NRF_SAADC_LIMIT_LOW) ? NRF_SAADC_INT_CH0LIMITL : NRF_SAADC_INT_CH0LIMITH;
    return mask &amp;lt;&amp;lt; (channel * 2);
}


/**
 * @brief Function for checking whether the SAADC is busy.
 *
 * This function checks whether the analog-to-digital converter is busy with a conversion.
 *
 * @retval true  If the SAADC is busy.
 * @retval false If the SAADC is not busy.
 */
__STATIC_INLINE bool nrf_saadc_busy_check(void)
{
    //return ((NRF_SAADC-&amp;gt;STATUS &amp;amp; SAADC_STATUS_STATUS_Msk) == SAADC_STATUS_STATUS_Msk);
    //simplified for performance
    return NRF_SAADC-&amp;gt;STATUS;
}


/**
 * @brief Function for enabling the SAADC.
 *
 * The analog-to-digital converter must be enabled before use.
 */
__STATIC_INLINE void nrf_saadc_enable(void)
{
    NRF_SAADC-&amp;gt;ENABLE = (SAADC_ENABLE_ENABLE_Enabled &amp;lt;&amp;lt; SAADC_ENABLE_ENABLE_Pos);
}


/**
 * @brief Function for disabling the SAADC.
 */
__STATIC_INLINE void nrf_saadc_disable(void)
{
    NRF_SAADC-&amp;gt;ENABLE = (SAADC_ENABLE_ENABLE_Disabled &amp;lt;&amp;lt; SAADC_ENABLE_ENABLE_Pos);
}


/**
 * @brief Function for checking if the SAADC is enabled.
 *
 * @retval true  If the SAADC is enabled.
 * @retval false If the SAADC is not enabled.
 */
__STATIC_INLINE bool nrf_saadc_enable_check(void)
{
    //simplified for performance
    return NRF_SAADC-&amp;gt;ENABLE;
}


/**
 * @brief Function for initializing the SAADC result buffer.
 *
 * @param[in] buffer Pointer to the result buffer.
 * @param[in] num    Size of buffer in words.
 */
__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * buffer, uint32_t num)
{
    NRF_SAADC-&amp;gt;RESULT.PTR = (uint32_t)buffer;
    NRF_SAADC-&amp;gt;RESULT.MAXCNT = num;
}

/**
 * @brief Function for getting the number of buffer words transferred since last START operation.
 *
 * @returns Number of words transferred.
 */
__STATIC_INLINE uint16_t nrf_saadc_amount_get(void)
{
    return NRF_SAADC-&amp;gt;RESULT.AMOUNT;
}


/**
 * @brief Function for setting the SAADC sample resolution.
 *
 * @param[in] resolution Bit resolution.
 */
__STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution)
{
    NRF_SAADC-&amp;gt;RESOLUTION = resolution;
}


/**
 * @brief Function for configuring the oversampling feature.
 *
 * @param[in] oversample Oversampling mode.
 */
__STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample)
{
    NRF_SAADC-&amp;gt;OVERSAMPLE = oversample;
}

/**
 * @brief Function for getting the oversampling feature configuration.
 *
 * @return Oversampling configuration.
 */
__STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void)
{
    return (nrf_saadc_oversample_t)NRF_SAADC-&amp;gt;OVERSAMPLE;
}

/**
 * @brief Function for initializing the SAADC channel.
 *
 * @param[in] channel Channel number.
 * @param[in] config  Pointer to the channel configuration structure.
 */
void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config);

/**
 *@}
 **/


#ifdef __cplusplus
}
#endif

#endif /* NRF_SAADC_H_ */&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464018?ContentTypeID=1</link><pubDate>Fri, 12 Jan 2024 17:16:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:52af2c88-a449-49ee-aad1-2b4b21113335</guid><dc:creator>Ramfrost</dc:creator><description>&lt;p&gt;Adding other files.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;// this is nrf_drv_saadc.c
/**
 * Copyright (c) 2015 - 2017, 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.
 * 
 */
#include &amp;quot;sdk_common.h&amp;quot;
#if NRF_MODULE_ENABLED(SAADC)
#include &amp;quot;nrf_drv_saadc.h&amp;quot;
#include &amp;quot;nrf_assert.h&amp;quot;
#include &amp;quot;../../_nrf_api/nrf_drv_common.h&amp;quot;
#include &amp;quot;../../../utils/iws_defines.h&amp;quot;
//#include &amp;quot;nrf_drv_common.h&amp;quot;
//#include &amp;quot;app_util_platform.h&amp;quot;
//#include &amp;quot;pws.h&amp;quot; //commented later

#define NRF_LOG_MODULE_NAME &amp;quot;SAADC&amp;quot;


void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config)
{
//    DEBUG_SEND(true, &amp;quot;saadc ch_init&amp;quot;);// added later
    NRF_SAADC-&amp;gt;CH[channel].CONFIG =
            ((config-&amp;gt;resistor_p   &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESP_Pos)   &amp;amp; SAADC_CH_CONFIG_RESP_Msk)
            | ((config-&amp;gt;resistor_n &amp;lt;&amp;lt; SAADC_CH_CONFIG_RESN_Pos)   &amp;amp; SAADC_CH_CONFIG_RESN_Msk)
            | ((config-&amp;gt;gain       &amp;lt;&amp;lt; SAADC_CH_CONFIG_GAIN_Pos)   &amp;amp; SAADC_CH_CONFIG_GAIN_Msk)
            | ((config-&amp;gt;reference  &amp;lt;&amp;lt; SAADC_CH_CONFIG_REFSEL_Pos) &amp;amp; SAADC_CH_CONFIG_REFSEL_Msk)
            | ((config-&amp;gt;acq_time   &amp;lt;&amp;lt; SAADC_CH_CONFIG_TACQ_Pos)   &amp;amp; SAADC_CH_CONFIG_TACQ_Msk)
            | ((config-&amp;gt;mode       &amp;lt;&amp;lt; SAADC_CH_CONFIG_MODE_Pos)   &amp;amp; SAADC_CH_CONFIG_MODE_Msk)
            | ((config-&amp;gt;burst      &amp;lt;&amp;lt; SAADC_CH_CONFIG_BURST_Pos)  &amp;amp; SAADC_CH_CONFIG_BURST_Msk);
    nrf_saadc_channel_input_set(channel, config-&amp;gt;pin_p, config-&amp;gt;pin_n);
    return;
}

#if SAADC_CONFIG_LOG_ENABLED
#define NRF_LOG_LEVEL       SAADC_CONFIG_LOG_LEVEL
#define NRF_LOG_INFO_COLOR  SAADC_CONFIG_INFO_COLOR
#define NRF_LOG_DEBUG_COLOR SAADC_CONFIG_DEBUG_COLOR
#define EVT_TO_STR(event)   (event == NRF_SAADC_EVENT_STARTED ? &amp;quot;NRF_SAADC_EVENT_STARTED&amp;quot; :                         \
                            (event == NRF_SAADC_EVENT_END ? &amp;quot;NRF_SAADC_EVENT_END&amp;quot; :                                 \
                            (event == NRF_SAADC_EVENT_DONE ? &amp;quot;NRF_SAADC_EVENT_DONE&amp;quot; :                               \
                            (event == NRF_SAADC_EVENT_RESULTDONE ? &amp;quot;NRF_SAADC_EVENT_RESULTDONE&amp;quot; :                   \
                            (event == NRF_SAADC_EVENT_CALIBRATEDONE ? &amp;quot;NRF_SAADC_EVENT_CALIBRATEDONE&amp;quot; :             \
                            (event == NRF_SAADC_EVENT_STOPPED ? &amp;quot;NRF_SAADC_EVENT_STOPPED&amp;quot; : &amp;quot;UNKNOWN EVENT&amp;quot;))))))
#define EVT_TO_STR_LIMIT(event) (event == NRF_SAADC_LIMIT_LOW ? &amp;quot;NRF_SAADC_LIMIT_LOW&amp;quot; :                                \
                                (event == NRF_SAADC_LIMIT_HIGH ? &amp;quot;NRF_SAADC_LIMIT_HIGH&amp;quot; : &amp;quot;UNKNOWN EVENT&amp;quot;))
#else //SAADC_CONFIG_LOG_ENABLED
#define EVT_TO_STR(event)   &amp;quot;&amp;quot;
#define NRF_LOG_LEVEL       0
#endif //SAADC_CONFIG_LOG_ENABLED
//#include &amp;quot;nrf_log.h&amp;quot;
//#include &amp;quot;nrf_log_ctrl.h&amp;quot;


typedef enum
{
    NRF_SAADC_STATE_IDLE        = 0,
    NRF_SAADC_STATE_BUSY        = 1,
    NRF_SAADC_STATE_CALIBRATION = 2
} nrf_saadc_state_t;


typedef struct
{
    nrf_saadc_input_t pselp;
    nrf_saadc_input_t pseln;
} nrf_saadc_psel_buffer;

//static const nrf_drv_saadc_config_t m_default_config = NRF_DRV_SAADC_DEFAULT_CONFIG;

/** @brief SAADC control block.*/
typedef struct
{
    nrf_drv_saadc_event_handler_t event_handler;                 ///&amp;lt; Event handler function pointer.
    volatile nrf_saadc_value_t  * p_buffer;                      ///&amp;lt; Sample buffer.
    volatile uint16_t             buffer_size;                   ///&amp;lt; Size of the sample buffer.
    volatile nrf_saadc_value_t  * p_secondary_buffer;            ///&amp;lt; Secondary sample buffer.
    volatile nrf_saadc_state_t    adc_state;                     ///&amp;lt; State of the SAADC.
    uint32_t                      limits_enabled_flags;          ///&amp;lt; Enabled limits flags.
    uint16_t                      secondary_buffer_size;         ///&amp;lt; Size of the secondary buffer.
    uint16_t                      buffer_size_left;              ///&amp;lt; When low power mode is active indicates how many samples left to convert on current buffer.
    nrf_saadc_psel_buffer         psel[NRF_SAADC_CHANNEL_COUNT]; ///&amp;lt; Pin configurations of SAADC channels.
    nrf_drv_state_t               state;                         ///&amp;lt; Driver initialization state.
    uint8_t                       active_channels;               ///&amp;lt; Number of enabled SAADC channels.
    bool                          low_power_mode;                ///&amp;lt; Indicates if low power mode is active.
    bool                          conversions_end;               ///&amp;lt; When low power mode is active indicates end of conversions on current buffer.
} nrf_drv_saadc_cb_t;

static nrf_drv_saadc_cb_t m_cb;

#define LOW_LIMIT_TO_FLAG(channel)      ((2 * channel + 1))
#define HIGH_LIMIT_TO_FLAG(channel)     ((2 * channel))
#define FLAG_IDX_TO_EVENT(idx)          ((nrf_saadc_event_t)((uint32_t)NRF_SAADC_EVENT_CH0_LIMITH + \
                                            4 * idx))
#define LIMIT_EVENT_TO_CHANNEL(event)   (uint8_t)(((uint32_t)event - \
                                            (uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) / 8)
#define LIMIT_EVENT_TO_LIMIT_TYPE(event)((((uint32_t)event - (uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) &amp;amp; 4) \
                                            ? NRF_SAADC_LIMIT_LOW : NRF_SAADC_LIMIT_HIGH)
#define HW_TIMEOUT 10000

void SAADC_IRQHandler(void)
{
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_END))
    {
//        DEBUG_SEND(true, &amp;quot;IRQ End Event&amp;quot;);// added later
        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
//        NRF_LOG_DEBUG(&amp;quot;Event: %s.\r\n&amp;quot;, (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_END));

        if (!m_cb.low_power_mode || m_cb.conversions_end)
        {
            nrf_drv_saadc_evt_t evt;
            evt.type               = NRF_DRV_SAADC_EVT_DONE;
            evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.p_buffer;
            evt.data.done.size     = m_cb.buffer_size;

            if (m_cb.p_secondary_buffer == NULL)
            {
                m_cb.adc_state = NRF_SAADC_STATE_IDLE;
            }
            else
            {
                m_cb.buffer_size_left   = m_cb.secondary_buffer_size;
                m_cb.p_buffer           = m_cb.p_secondary_buffer;
                m_cb.buffer_size        = m_cb.secondary_buffer_size;
                m_cb.p_secondary_buffer = NULL;
                if (!m_cb.low_power_mode)
                {
                    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
                }
            }
            m_cb.event_handler(&amp;amp;evt);
            m_cb.conversions_end = false;
        }
    }
    if (m_cb.low_power_mode &amp;amp;&amp;amp; nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
//        NRF_LOG_DEBUG(&amp;quot;Event: %s.\r\n&amp;quot;, (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_STARTED));

        if (m_cb.buffer_size_left &amp;gt; m_cb.active_channels)
        {
            // More samples to convert than for single event.
            m_cb.buffer_size_left -= m_cb.active_channels;
            nrf_saadc_buffer_init((nrf_saadc_value_t *)&amp;amp;m_cb.p_buffer[m_cb.buffer_size -
                                                                      m_cb.buffer_size_left],
                                  m_cb.active_channels);
        }
        else if ((m_cb.buffer_size_left == m_cb.active_channels) &amp;amp;&amp;amp;

                 (m_cb.p_secondary_buffer != NULL))
        {
            // Samples to convert for one event, prepare next buffer.
            m_cb.conversions_end  = true;
            m_cb.buffer_size_left = 0;
            nrf_saadc_buffer_init((nrf_saadc_value_t *)m_cb.p_secondary_buffer,
                                  m_cb.active_channels);
        }
        else if (m_cb.buffer_size_left == m_cb.active_channels)
        {
            // Samples to convert for one event, but no second buffer.
            m_cb.conversions_end  = true;
            m_cb.buffer_size_left = 0;
        }
        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
        nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
    }
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_CALIBRATEDONE))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_CALIBRATEDONE);
//        NRF_LOG_DEBUG(&amp;quot;Event: %s.\r\n&amp;quot;, (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_CALIBRATEDONE));
        m_cb.adc_state = NRF_SAADC_STATE_IDLE;

        nrf_drv_saadc_evt_t evt;
        evt.type = NRF_DRV_SAADC_EVT_CALIBRATEDONE;
        m_cb.event_handler(&amp;amp;evt);
    }
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
//        NRF_LOG_DEBUG(&amp;quot;Event: %s.\r\n&amp;quot;, (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_STOPPED));
        m_cb.adc_state = NRF_SAADC_STATE_IDLE;
    }
    else
    {
        uint32_t          limit_flags = m_cb.limits_enabled_flags;
        uint32_t          flag_idx;
        nrf_saadc_event_t event;

        while (limit_flags)
        {
            flag_idx     = __CLZ(limit_flags);
            limit_flags &amp;amp;= ~((1UL &amp;lt;&amp;lt; 31) &amp;gt;&amp;gt; flag_idx);
            event        = FLAG_IDX_TO_EVENT(flag_idx);
            if (nrf_saadc_event_check(event))
            {
                nrf_saadc_event_clear(event);
                nrf_drv_saadc_evt_t evt;
                evt.type                  = NRF_DRV_SAADC_EVT_LIMIT;
                evt.data.limit.channel    = LIMIT_EVENT_TO_CHANNEL(event);
                evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event);
//                NRF_LOG_DEBUG(&amp;quot;Event limit, channel: %d, limit type: %s.\r\n&amp;quot;, evt.data.limit.channel, (uint32_t)EVT_TO_STR(evt.data.limit.limit_type));
                m_cb.event_handler(&amp;amp;evt);
            }
        }
    }
}


ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config,
                              nrf_drv_saadc_event_handler_t  event_handler)
{
//    DEBUG_SEND(true, &amp;quot;saadc init&amp;quot;);// added later
    ret_code_t err_code;

    if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
    {
        err_code = NRF_ERROR_INVALID_STATE;
//        NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;,
//                        (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }
    if (event_handler == NULL)
    {
        err_code = NRF_ERROR_INVALID_PARAM;
//        NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;,
//                        (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }

    if (p_config == NULL)
    {
    	err_code = NRF_ERROR_INVALID_PARAM;
//    	NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;,
//    	                        (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    	return err_code;
    }

    m_cb.event_handler = event_handler;
    nrf_saadc_resolution_set(p_config-&amp;gt;resolution);
    nrf_saadc_oversample_set(p_config-&amp;gt;oversample);
    m_cb.low_power_mode       = p_config-&amp;gt;low_power_mode;
    m_cb.state                = NRF_DRV_STATE_INITIALIZED;
    m_cb.adc_state            = NRF_SAADC_STATE_IDLE;
    m_cb.active_channels      = 0;
    m_cb.limits_enabled_flags = 0;
    m_cb.conversions_end      = false;

    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
    //nrf_drv_common_irq_enable(SAADC_IRQn, p_config-&amp;gt;interrupt_priority);
    Sys_enableAppIrq(SAADC_IRQn, SAADC_IRQHandler);
    nrf_drv_common_irq_enable(SAADC_IRQn, p_config-&amp;gt;interrupt_priority);
    nrf_saadc_int_enable(NRF_SAADC_INT_END);
    if (m_cb.low_power_mode)
    {
        nrf_saadc_int_enable(NRF_SAADC_INT_STARTED);
    }

    nrf_saadc_enable();

    err_code = NRF_SUCCESS;
//    NRF_LOG_INFO(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}


void nrf_drv_saadc_uninit(void)
{
//    DEBUG_SEND(true, &amp;quot;saadc uninit&amp;quot;);// added later
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);

    nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
    nrf_drv_common_irq_disable(SAADC_IRQn);
//    lib_system-&amp;gt;disableAppIrq(SAADC_IRQn);

    nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);

    // Wait for ADC being stopped.
    uint32_t timeout = HW_TIMEOUT;

    while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0 &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        --timeout;
    }
    ASSERT(timeout &amp;gt; 0);

    nrf_saadc_disable();
    m_cb.adc_state = NRF_SAADC_STATE_IDLE;

    for (uint8_t channel = 0; channel &amp;lt; NRF_SAADC_CHANNEL_COUNT; ++channel)
    {
        if (m_cb.psel[channel].pselp != NRF_SAADC_INPUT_DISABLED)
        {
            (void)nrf_drv_saadc_channel_uninit(channel);
        }
    }

    m_cb.state = NRF_DRV_STATE_UNINITIALIZED;
}


ret_code_t nrf_drv_saadc_channel_init(uint8_t                                  channel,
                                      nrf_saadc_channel_config_t const * const p_config)
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc ch_init&amp;quot;);// added later
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
    ASSERT(channel &amp;lt; NRF_SAADC_CHANNEL_COUNT);
    // Oversampling can be used only with one channel.
    ASSERT((nrf_saadc_oversample_get() == NRF_SAADC_OVERSAMPLE_DISABLED) ||
           (m_cb.active_channels == 0));
    ASSERT((p_config-&amp;gt;pin_p &amp;lt;= NRF_SAADC_INPUT_VDD) &amp;amp;&amp;amp;
           (p_config-&amp;gt;pin_p &amp;gt; NRF_SAADC_INPUT_DISABLED));
    ASSERT(p_config-&amp;gt;pin_n &amp;lt;= NRF_SAADC_INPUT_VDD);

    ret_code_t err_code;

    // A channel can only be initialized if the driver is in the idle state.
    if (m_cb.adc_state != NRF_SAADC_STATE_IDLE)
    {
        err_code = NRF_ERROR_BUSY;
//        NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;,
//                        (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }

    if (!m_cb.psel[channel].pselp)
    {
        ++m_cb.active_channels;
    }
    m_cb.psel[channel].pselp = p_config-&amp;gt;pin_p;
    m_cb.psel[channel].pseln = p_config-&amp;gt;pin_n;
    nrf_saadc_channel_init(channel, p_config);
    nrf_saadc_channel_input_set(channel, p_config-&amp;gt;pin_p, p_config-&amp;gt;pin_n);
//    NRF_LOG_INFO(&amp;quot;Channel initialized: %d.\r\n&amp;quot;, channel);
    err_code = NRF_SUCCESS;
//    NRF_LOG_INFO(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}


ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel)
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc ch_init&amp;quot;);// added later
    ASSERT(channel &amp;lt; NRF_SAADC_CHANNEL_COUNT)
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);

    ret_code_t err_code;

    // A channel can only be uninitialized if the driver is in the idle state.
    if (m_cb.adc_state != NRF_SAADC_STATE_IDLE)
    {
        err_code = NRF_ERROR_BUSY;
//        NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;,
//                        (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }

    if (m_cb.psel[channel].pselp)
    {
        --m_cb.active_channels;
    }
    m_cb.psel[channel].pselp = NRF_SAADC_INPUT_DISABLED;
    m_cb.psel[channel].pseln = NRF_SAADC_INPUT_DISABLED;
    nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
    nrf_drv_saadc_limits_set(channel, NRF_DRV_SAADC_LIMITL_DISABLED, NRF_DRV_SAADC_LIMITH_DISABLED);
//    NRF_LOG_INFO(&amp;quot;Channel denitialized: %d.\r\n&amp;quot;, channel);

    err_code = NRF_SUCCESS;
//    NRF_LOG_INFO(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;,
//                    (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}


uint32_t nrf_drv_saadc_sample_task_get(void)
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc sample_task get&amp;quot;);// added later
    return nrf_saadc_task_address_get(
        m_cb.low_power_mode ? NRF_SAADC_TASK_START : NRF_SAADC_TASK_SAMPLE);
}


ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value)
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc sample convert&amp;quot;);// added later
    ret_code_t err_code;

    if (m_cb.adc_state != NRF_SAADC_STATE_IDLE)
    {
        err_code = NRF_ERROR_BUSY;
//        NRF_LOG_WARNING(&amp;quot;Function: %s error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }
    m_cb.adc_state = NRF_SAADC_STATE_BUSY;
    nrf_saadc_int_disable(NRF_SAADC_INT_STARTED | NRF_SAADC_INT_END);
    nrf_saadc_buffer_init(p_value, 1);
    if (m_cb.active_channels &amp;gt; 1)
    {
        for (uint8_t i = 0; i &amp;lt; NRF_SAADC_CHANNEL_COUNT; ++i)
        {
            nrf_saadc_channel_input_set(i, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
        }
    }
    nrf_saadc_channel_input_set(channel,
                                m_cb.psel[channel].pselp, m_cb.psel[channel].pseln);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);

    uint32_t timeout = HW_TIMEOUT;

    while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) &amp;amp;&amp;amp; timeout &amp;gt; 0)
    {
        timeout--;
    }
    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);

//    NRF_LOG_INFO(&amp;quot;Conversion value: %d, channel.\r\n&amp;quot;, *p_value, channel);

    if (m_cb.active_channels &amp;gt; 1)
    {
        for (uint8_t i = 0; i &amp;lt; NRF_SAADC_CHANNEL_COUNT; ++i)
        {
            nrf_saadc_channel_input_set(i, m_cb.psel[i].pselp, m_cb.psel[i].pseln);
        }
    }

    if (m_cb.low_power_mode)
    {
        nrf_saadc_int_enable(NRF_SAADC_INT_STARTED | NRF_SAADC_INT_END);
    }
    else
    {
        nrf_saadc_int_enable(NRF_SAADC_INT_END);
    }

    m_cb.adc_state = NRF_SAADC_STATE_IDLE;

    err_code = NRF_SUCCESS;
//    NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}


ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * p_buffer, uint16_t size)
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc buff_covert&amp;quot;);// added later
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
    ASSERT((size % m_cb.active_channels) == 0);
    ret_code_t err_code;


    nrf_saadc_int_disable(NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE);
    if (m_cb.adc_state == NRF_SAADC_STATE_CALIBRATION)
    {
        nrf_saadc_int_enable(NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE);
        err_code = NRF_ERROR_BUSY;
//        NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }
    if (m_cb.adc_state == NRF_SAADC_STATE_BUSY)
    {
        if ( m_cb.p_secondary_buffer)
        {
            nrf_saadc_int_enable(NRF_SAADC_INT_END);
            err_code = NRF_ERROR_BUSY;
//            NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
            return err_code;
        }
        else
        {
            m_cb.p_secondary_buffer    = p_buffer;
            m_cb.secondary_buffer_size = size;
            if (!m_cb.low_power_mode)
            {
                while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0);
                nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
                nrf_saadc_buffer_init(p_buffer, size);
            }
            nrf_saadc_int_enable(NRF_SAADC_INT_END);
            err_code = NRF_SUCCESS;
//            NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
            return err_code;
        }
    }
    nrf_saadc_int_enable(NRF_SAADC_INT_END);
    m_cb.adc_state = NRF_SAADC_STATE_BUSY;

    m_cb.p_buffer           = p_buffer;
    m_cb.buffer_size        = size;
    m_cb.p_secondary_buffer = NULL;

//    NRF_LOG_INFO(&amp;quot;Function: %d, buffer length: %d, active channels: %d.\r\n&amp;quot;,
//                    (uint32_t)__func__, size, m_cb.active_channels);

    if (m_cb.low_power_mode)
    {
        m_cb.buffer_size_left = size;
        nrf_saadc_buffer_init(p_buffer, m_cb.active_channels);
    }
    else
    {
        nrf_saadc_buffer_init(p_buffer, size);
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
        nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
    }

    err_code = NRF_SUCCESS;
//    NRF_LOG_INFO(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}


ret_code_t nrf_drv_saadc_sample()
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc sample&amp;quot;);// added later
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);

    ret_code_t err_code = NRF_SUCCESS;
    if (m_cb.adc_state != NRF_SAADC_STATE_BUSY)
    {
        err_code = NRF_ERROR_INVALID_STATE;
    }
    else if (m_cb.low_power_mode)
    {
        nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
    }
    else
    {
        nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
    }

//    NRF_LOG_INFO(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}


ret_code_t nrf_drv_saadc_calibrate_offset()
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc calibrate&amp;quot;);// added later
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);

    ret_code_t err_code;

    if (m_cb.adc_state != NRF_SAADC_STATE_IDLE)
    {
        err_code = NRF_ERROR_BUSY;
//        NRF_LOG_WARNING(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }

    m_cb.adc_state = NRF_SAADC_STATE_CALIBRATION;

    nrf_saadc_event_clear(NRF_SAADC_EVENT_CALIBRATEDONE);
    nrf_saadc_int_enable(NRF_SAADC_INT_CALIBRATEDONE);
    nrf_saadc_task_trigger(NRF_SAADC_TASK_CALIBRATEOFFSET);
    err_code = NRF_SUCCESS;
//    NRF_LOG_INFO(&amp;quot;Function: %s, error code: %s.\r\n&amp;quot;, (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}


bool nrf_drv_saadc_is_busy(void)
{
    return (m_cb.adc_state != NRF_SAADC_STATE_IDLE);
}


void nrf_drv_saadc_abort(void)
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc abort&amp;quot;);// added later
    if (nrf_drv_saadc_is_busy())
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
        nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);

        if (m_cb.adc_state == NRF_SAADC_STATE_CALIBRATION)
        {
            m_cb.adc_state = NRF_SAADC_STATE_IDLE;
        }
        else
        {
            // Wait for ADC being stopped.
            uint32_t timeout = HW_TIMEOUT;

            while ((m_cb.adc_state != NRF_SAADC_STATE_IDLE) &amp;amp;&amp;amp; (timeout &amp;gt; 0))
            {
                --timeout;
            }
            ASSERT(timeout &amp;gt; 0);
        }

        m_cb.p_buffer           = 0;
        m_cb.p_secondary_buffer = 0;
//        NRF_LOG_INFO(&amp;quot;Conversion aborted.\r\n&amp;quot;);
    }
}


void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high)
{
//    DEBUG_SEND(true, &amp;quot;drv_saadc limit_set&amp;quot;);// added later
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
    ASSERT(m_cb.event_handler); // only non blocking mode supported
    ASSERT(limit_low &amp;gt;= NRF_DRV_SAADC_LIMITL_DISABLED);
    ASSERT(limit_high &amp;lt;= NRF_DRV_SAADC_LIMITH_DISABLED);
    ASSERT(limit_low &amp;lt; limit_high);
    nrf_saadc_channel_limits_set(channel, limit_low, limit_high);

    uint32_t int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_LOW);
    if (limit_low == NRF_DRV_SAADC_LIMITL_DISABLED)
    {
        m_cb.limits_enabled_flags &amp;amp;= ~(0x80000000 &amp;gt;&amp;gt; LOW_LIMIT_TO_FLAG(channel));
        nrf_saadc_int_disable(int_mask);
    }
    else
    {
        m_cb.limits_enabled_flags |= (0x80000000 &amp;gt;&amp;gt; LOW_LIMIT_TO_FLAG(channel));
        nrf_saadc_int_enable(int_mask);
    }

    int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_HIGH);
    if (limit_high == NRF_DRV_SAADC_LIMITH_DISABLED)
    {
        m_cb.limits_enabled_flags &amp;amp;= ~(0x80000000 &amp;gt;&amp;gt; HIGH_LIMIT_TO_FLAG(channel));
        nrf_saadc_int_disable(int_mask);
    }
    else
    {
        m_cb.limits_enabled_flags |= (0x80000000 &amp;gt;&amp;gt; HIGH_LIMIT_TO_FLAG(channel));
        nrf_saadc_int_enable(int_mask);
    }
}
#endif //NRF_MODULE_ENABLED(SAADC)
&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/464017?ContentTypeID=1</link><pubDate>Fri, 12 Jan 2024 17:14:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7e8e621b-9536-4f62-9e33-262ff9357d63</guid><dc:creator>Ramfrost</dc:creator><description>&lt;p&gt;Hi Jared, thanks for you response.&lt;/p&gt;
&lt;p&gt;yes we are scaling down the voltage and then passing it to the AIN pins. The power is being supplied with a 24v SMPS and there is another option to power it from 230v AC to 12 DC converter which is mentioned in the schematics. I am not sure wirepas uses the complete nrf sdk but definitely the use the nrf&amp;#39;s api. For the time being I am able to read ADC votage from 0 to 7v from a different source(may be the battery I was using was not suitable for this test) but when the voltage of the source gets in the range of 9v - 10v I am getting half(around 5v) which is quite surprising. I am attaching the saadc driver files and the schematics of the board which I am using. The adc code is already shared with the question.&lt;/p&gt;
&lt;p&gt;Please let me know if you want anything else.&lt;pre class="ui-code" data-mode="text"&gt;// this is nrf_drv_saadc.h
/**
 * Copyright (c) 2015 - 2017, 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.
 * 
 */

/**
 * @addtogroup nrf_saadc SAADC HAL and driver
 * @ingroup    nrf_drivers
 * @brief      @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) APIs.
 * @details The SAADC HAL provides basic APIs for accessing the registers of the SAADC peripheral.
 * The SAADC driver provides APIs on a higher level.
 *
 * @defgroup nrf_drv_saadc SAADC driver
 * @{
 * @ingroup  nrf_saadc
 *
 * @brief    @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) driver.
 */

#ifndef NRF_DRV_SAADC_H__
#define NRF_DRV_SAADC_H__

#include &amp;quot;sdk_config.h&amp;quot;
#include &amp;quot;nrf_saadc.h&amp;quot;
#include &amp;quot;sdk_errors.h&amp;quot;
#include &amp;quot;nrf_drv_common.h&amp;quot;

#ifdef __cplusplus
extern &amp;quot;C&amp;quot; {
#endif

/**
 * @brief Value that should be set as high limit to disable limit detection.
 */
#define NRF_DRV_SAADC_LIMITH_DISABLED (2047)
/**
 * @brief Value that should be set as low limit to disable limit detection.
 */
#define NRF_DRV_SAADC_LIMITL_DISABLED (-2048)


/**
 * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
 *        in single ended mode.
 *
 * @param PIN_P Analog input.
 */
#define NRF_DRV_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_10US,          \
        .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         \
    }

/**
 * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
 *        in differential mode.
 *
 * @param PIN_P Positive analog input.
 * @param PIN_N Negative analog input.
 */
#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \
    {                                                                   \
        .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_10US,                           \
        .mode       = NRF_SAADC_MODE_DIFFERENTIAL,                      \
        .pin_p      = (nrf_saadc_input_t)(PIN_P),                       \
        .pin_n      = (nrf_saadc_input_t)(PIN_N)                        \
    }

/**
 * @brief Analog-to-digital converter driver configuration structure.
 */
typedef struct
{
    nrf_saadc_resolution_t resolution;         ///&amp;lt; Resolution configuration.
    nrf_saadc_oversample_t oversample;         ///&amp;lt; Oversampling configuration.
    uint8_t                interrupt_priority; ///&amp;lt; Interrupt priority.
    bool                   low_power_mode;     ///&amp;lt; Indicates if low power mode is active.
} nrf_drv_saadc_config_t;

/**
 * @brief Driver event types.
 */
typedef enum
{
    NRF_DRV_SAADC_EVT_DONE,         ///&amp;lt; Event generated when the buffer is filled with samples.
    NRF_DRV_SAADC_EVT_LIMIT,        ///&amp;lt; Event generated after one of the limits is reached.
    NRF_DRV_SAADC_EVT_CALIBRATEDONE ///&amp;lt; Event generated when the calibration is complete.
} nrf_drv_saadc_evt_type_t;

/**
 * @brief Analog-to-digital converter driver done event data.
 */
typedef struct
{
    nrf_saadc_value_t * p_buffer; ///&amp;lt; Pointer to buffer with converted samples.
    uint16_t            size;     ///&amp;lt; Number of samples in the buffer.
} nrf_drv_saadc_done_evt_t;

/**
 * @brief Analog-to-digital converter driver limit event data.
 */
typedef struct
{
    uint8_t           channel;    ///&amp;lt; Channel on which the limit was detected.
    nrf_saadc_limit_t limit_type; ///&amp;lt; Type of limit detected.
} nrf_drv_saadc_limit_evt_t;

/**
 * @brief Analog-to-digital converter driver event structure.
 */
typedef struct
{
    nrf_drv_saadc_evt_type_t type; ///&amp;lt; Event type.
    union
    {
        nrf_drv_saadc_done_evt_t  done;  ///&amp;lt; Data for @ref NRF_DRV_SAADC_EVT_DONE event.
        nrf_drv_saadc_limit_evt_t limit; ///&amp;lt; Data for @ref NRF_DRV_SAADC_EVT_LIMIT event.
    } data;
} nrf_drv_saadc_evt_t;

/**
 * @brief ADC event handler.
 *
 * @param[in] p_event     Pointer to an ADC event. The event structure is allocated on
 *                        the stack, so it is valid only within the context of
 *                        the event handler.
 */
typedef void (* nrf_drv_saadc_event_handler_t)(nrf_drv_saadc_evt_t const * p_event);

/**
 * @brief Function for initializing the SAADC.
 *
 * @param[in] p_config      Pointer to a configuration structure. If NULL, the default one is used.
 * @param[in] event_handler Event handler provided by the user.
 *
 * @retval    NRF_SUCCESS If initialization was successful.
 * @retval    NRF_ERROR_INVALID_STATE If the driver is already initialized.
 * @retval    NRF_ERROR_INVALID_PARAM If event_handler is NULL.
 */
ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config,
                              nrf_drv_saadc_event_handler_t  event_handler);

/**
 * @brief Function for uninitializing the SAADC.
 *
 * This function stops all ongoing conversions and disables all channels.
 */
void nrf_drv_saadc_uninit(void);


/**
 * @brief Function for getting the address of a SAMPLE SAADC task.
 *
 * @return     Task address.
 */
uint32_t nrf_drv_saadc_sample_task_get(void);

/**
 * @brief Function for initializing an SAADC channel.
 *
 * This function configures and enables the channel.
 *
 * @retval NRF_SUCCESS             If initialization was successful.
 * @retval NRF_ERROR_INVALID_STATE If the ADC was not initialized.
 * @retval NRF_ERROR_NO_MEM        If the specified channel was already allocated.
 */
ret_code_t nrf_drv_saadc_channel_init(uint8_t                                  channel,
                                      nrf_saadc_channel_config_t const * const p_config);


/**
 * @brief Function for uninitializing an SAADC channel.
 *
 * @retval NRF_SUCCESS    If uninitialization was successful.
 * @retval NRF_ERROR_BUSY If the ADC is busy.
 */
ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel);

/**
 * @brief Function for starting SAADC sampling.
 *
 * @retval NRF_SUCCESS             If ADC sampling was triggered.
 * @retval NRF_ERROR_INVALID_STATE If ADC is in idle state.
 */
ret_code_t nrf_drv_saadc_sample(void);

/**
 * @brief Blocking function for executing a single ADC conversion.
 *
 * This function selects the desired input, starts a single conversion,
 * waits for it to finish, and returns the result.
 *
 * The function will fail if ADC is busy.
 *
 * @param[in]  channel Channel.
 * @param[out] p_value Pointer to the location where the result should be placed.
 *
 * @retval NRF_SUCCESS    If conversion was successful.
 * @retval NRF_ERROR_BUSY If the ADC driver is busy.
 */
ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value);

/**
 * @brief Function for issuing conversion of data to the buffer.
 *
 * This function is non-blocking. The application is notified about filling the buffer by the event handler.
 * Conversion will be done on all enabled channels. If the ADC is in idle state, the function will set up Easy
 * DMA for the conversion. The ADC will be ready for sampling and wait for the SAMPLE task. It can be
 * triggered manually by the @ref nrf_drv_saadc_sample function or by PPI using the @ref NRF_SAADC_TASK_SAMPLE
 * task. If one buffer is already set and the conversion is ongoing, calling this function will
 * result in queuing the given buffer. The driver will start filling the issued buffer when the first one is
 * completed. If the function is called again before the first buffer is filled or calibration is in progress,
 * it will return with error.
 *
 * @param[in] buffer Result buffer.
 * @param[in] size   Buffer size in words.
 *
 * @retval NRF_SUCCESS    If conversion was successful.
 * @retval NRF_ERROR_BUSY If the driver already has two buffers set or calibration is in progress.
 */
ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * buffer, uint16_t size);

/**
 * @brief Function for triggering the ADC offset calibration.
 *
 * This function is non-blocking. The application is notified about completion by the event handler.
 * Calibration will also trigger DONE and RESULTDONE events.
 *
 * The function will fail if ADC is busy or calibration is already in progress.
 *
 * @retval NRF_SUCCESS    If calibration was started successfully.
 * @retval NRF_ERROR_BUSY If the ADC driver is busy.
 */
ret_code_t nrf_drv_saadc_calibrate_offset(void);

/**
 * @brief Function for retrieving the SAADC state.
 *
 * @retval true  If the ADC is busy.
 * @retval false If the ADC is ready.
 */
bool nrf_drv_saadc_is_busy(void);

/**
 * @brief Function for aborting ongoing and buffered conversions.
 * @note @ref NRF_DRV_SAADC_EVT_DONE event will be generated if there is a conversion in progress.
 *       Event will contain number of words in the sample buffer.
 */
void nrf_drv_saadc_abort(void);

/**
 * @brief Function for setting the SAADC channel limits.
 *        When limits are enabled and the result exceeds the defined bounds, the limit handler function is called.
 *
 * @param[in] channel SAADC channel number.
 * @param[in] limit_low Lower limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to
 *            @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results below this value will trigger
 *            the handler function. Set to @ref NRF_DRV_SAADC_LIMITL_DISABLED to disable this limit.
 * @param[in] limit_high Upper limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to
 *            @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results above this value will trigger
 *            the handler function. Set to @ref NRF_DRV_SAADC_LIMITH_DISABLED to disable this limit.
 */
void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high);

#ifdef __cplusplus
}
#endif

#endif // NRF_DRV_SAADC_H__

/** @} */&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nrf52833 ADC not giving accurate value.</title><link>https://devzone.nordicsemi.com/thread/463943?ContentTypeID=1</link><pubDate>Fri, 12 Jan 2024 10:03:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0c654cbd-1a51-4f9c-ba8d-33a81703a0f0</guid><dc:creator>Jared</dc:creator><description>&lt;p&gt;Hi there,&lt;/p&gt;
&lt;p&gt;I have some questions that I would like you to answer:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How are you connecting the 9V into the analog pin? I&amp;#39;m assuming that you&amp;#39;re scaling down the voltage somehow first?&lt;/li&gt;
&lt;li&gt;Are you using a custom board, can you share the schematics?&lt;/li&gt;
&lt;li&gt;How is your board supplied, have you tried supplying the board from a bench top supply and measure a fixed voltage from a bench top supply? Is the accuracy improved?&lt;/li&gt;
&lt;li&gt;You mentioned that you&amp;#39;re using the wirepas SDK. Is it used in conjunction with one of our SDKs, which one?&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;regards&lt;br /&gt;Jared&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>