This is an automated email from the ASF dual-hosted git repository.

janc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 55dc8b7cc85658da7950d987fa80a6c2ea09d71b
Author: Miguel Azevedo <miguella...@gmail.com>
AuthorDate: Thu Feb 13 03:35:56 2020 +0000

    hw/drivers/adc: Update nrf52_adc driver for nrfx 2.0.0
---
 .../adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h    |  63 +-
 hw/drivers/adc/adc_nrf52/src/adc_nrf52.c           | 590 +++++++++++++------
 hw/mcu/nordic/nrf52xxx/src/nrfx_saadc_mod.c        | 651 ---------------------
 3 files changed, 482 insertions(+), 822 deletions(-)

diff --git a/hw/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h 
b/hw/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h
index edd0938..52f8efe 100644
--- a/hw/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h
+++ b/hw/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h
@@ -26,8 +26,67 @@
 extern "C" {
 #endif
 
+typedef enum {
+    ADC_RESOLUTION_8BIT = 0,
+    ADC_RESOLUTION_10BIT,
+    ADC_RESOLUTION_12BIT,
+    ADC_RESOLUTION_14BIT
+} adc_resolution_t;
+
+typedef enum {
+    ADC_OVERSAMPLE_DISABLED = 0,
+    ADC_OVERSAMPLE_2X,
+    ADC_OVERSAMPLE_4X,
+    ADC_OVERSAMPLE_8X,
+    ADC_OVERSAMPLE_16X,
+    ADC_OVERSAMPLE_32X,
+    ADC_OVERSAMPLE_64X,
+    ADC_OVERSAMPLE_128X,
+    ADC_OVERSAMPLE_256X
+} adc_oversample_t;
+
 struct nrf52_adc_dev_cfg {
-    uint16_t nadc_refmv;               /* reference VDD in mV */
+    uint16_t nadc_refmv;         /* Reference VDD in mV */
+};
+
+struct adc_dev_cfg {
+    adc_resolution_t resolution;
+    adc_oversample_t oversample; /* Only works on single channel mode */
+    bool calibrate;              /* Calibrate before sampling */
+};
+
+typedef enum {
+    ADC_REFERENCE_INTERNAL = 0,
+    ADC_REFERENCE_VDD_DIV_4
+} adc_ref_t;
+
+typedef enum {
+    ADC_GAIN1_6 = 0,
+    ADC_GAIN1_5,
+    ADC_GAIN1_4,
+    ADC_GAIN1_3,
+    ADC_GAIN1_2,
+    ADC_GAIN1,
+    ADC_GAIN2,
+    ADC_GAIN4
+} adc_gain_t;
+
+typedef enum {
+    ADC_ACQTIME_3US = 0,
+    ADC_ACQTIME_5US,
+    ADC_ACQTIME_10US,
+    ADC_ACQTIME_15US,
+    ADC_ACQTIME_20US,
+    ADC_ACQTIME_40US
+} adc_acq_time_t;
+
+struct adc_chan_cfg {
+    adc_gain_t gain;
+    adc_ref_t reference;
+    adc_acq_time_t acq_time;
+    uint8_t pin;
+    bool differential;
+    uint8_t pin_negative;
 };
 
 int nrf52_adc_dev_init(struct os_dev *, void *);
@@ -36,4 +95,4 @@ int nrf52_adc_dev_init(struct os_dev *, void *);
 }
 #endif
 
-#endif /* __ADC_H__ */
+#endif /* __ADC_NRF52_H__ */
diff --git a/hw/drivers/adc/adc_nrf52/src/adc_nrf52.c 
b/hw/drivers/adc/adc_nrf52/src/adc_nrf52.c
index 85ddffc..44cb266 100644
--- a/hw/drivers/adc/adc_nrf52/src/adc_nrf52.c
+++ b/hw/drivers/adc/adc_nrf52/src/adc_nrf52.c
@@ -24,9 +24,7 @@
 #include <mcu/cmsis_nvic.h>
 
 /* Nordic headers */
-#include <nrfx.h>
 #include <nrf_saadc.h>
-#include <nrfx_saadc.h>
 
 #include "adc_nrf52/adc_nrf52.h"
 
@@ -36,50 +34,102 @@ struct nrf52_saadc_stats {
 };
 static struct nrf52_saadc_stats nrf52_saadc_stats;
 
+static struct nrf52_adc_dev_cfg *init_cfg;
 static struct adc_dev *global_adc_dev;
-static nrfx_saadc_config_t *global_adc_config;
-static struct nrf52_adc_dev_cfg *init_adc_config;
+static struct adc_chan_config nrf52_adc_chans[SAADC_CH_NUM];
 
-static uint8_t nrf52_adc_chans[NRF_SAADC_CHANNEL_COUNT * sizeof(struct 
adc_chan_config)];
+struct nrf52_adc_chan {
+    nrf_saadc_input_t pin_p;
+    nrf_saadc_input_t pin_n;
+    nrf_saadc_channel_config_t nrf_chan;
+};
 
-static void
-nrf52_saadc_event_handler(const nrfx_saadc_evt_t *event)
-{
-    nrfx_saadc_done_evt_t *done_ev;
-    int rc;
+struct nrf52_saadc_dev_global {
+    nrf_saadc_value_t *primary_buf;
+    nrf_saadc_value_t *secondary_buf;
+    uint16_t primary_size;
+    uint16_t secondary_size;
+    nrf_saadc_resolution_t resolution;
+    nrf_saadc_oversample_t oversample;
+    struct nrf52_adc_chan channels[SAADC_CH_NUM];
+    bool calibrate;
+};
 
-    if (global_adc_dev == NULL || !global_adc_dev->ad_event_handler_func) {
-        ++nrf52_saadc_stats.saadc_events_failed;
-        return;
-    }
+static struct nrf52_saadc_dev_global g_drv_instance;
 
-    ++nrf52_saadc_stats.saadc_events;
+/**
+ * Initialize a channel with default/unconfigured values.
+ */
+static void
+channel_unconf(int cnum)
+{
+    nrf_saadc_channel_config_t default_ch = {
+        .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,
+        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
+        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
+    };
+
+    memcpy(&g_drv_instance.channels[cnum].nrf_chan,
+           &default_ch,
+           sizeof(nrf_saadc_channel_config_t));
+    g_drv_instance.channels[cnum].pin_p = NRF_SAADC_INPUT_DISABLED;
+    g_drv_instance.channels[cnum].pin_n = NRF_SAADC_INPUT_DISABLED;
+    global_adc_dev->ad_chans[cnum].c_configured = 0;
+}
 
-    switch (event->type) {
-        case NRFX_SAADC_EVT_DONE:
-            done_ev = (nrfx_saadc_done_evt_t * const) &event->data.done;
-
-            rc = global_adc_dev->ad_event_handler_func(global_adc_dev,
-                                       global_adc_dev->ad_event_handler_arg,
-                                       ADC_EVENT_RESULT, done_ev->p_buffer,
-                                       done_ev->size * 
sizeof(nrf_saadc_value_t));
-            break;
-        case NRFX_SAADC_EVT_CALIBRATEDONE:
-            rc = global_adc_dev->ad_event_handler_func(global_adc_dev,
-                                       global_adc_dev->ad_event_handler_arg,
-                                       ADC_EVENT_CALIBRATED, NULL, 0);
-            break;
-        default:
-            assert(0);
-            break;
+/**
+ * Initialize a driver instance with default/unconfigured values.
+ */
+static void
+init_instance_unconf(void)
+{
+    int cnum;
+
+    g_drv_instance.primary_buf = NULL;
+    g_drv_instance.secondary_buf = NULL;
+    g_drv_instance.primary_size = 0;
+    g_drv_instance.secondary_size = 0;
+    g_drv_instance.resolution = NRF_SAADC_RESOLUTION_14BIT;
+    g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_DISABLED;
+    g_drv_instance.calibrate = false;
+
+    for (cnum = 0; cnum < SAADC_CH_NUM; cnum++) {
+        channel_unconf(cnum);
     }
+}
 
-    if (rc != 0) {
-        ++nrf52_saadc_stats.saadc_events_failed;
+/**
+ * Unconfigures the device registers
+ */
+static void
+clear_device_regs(void)
+{
+    int cnum;
+    nrf_saadc_channel_config_t default_ch = {
+        .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,
+        .resistor_p = NRF_SAADC_RESISTOR_DISABLED,
+        .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
+    };
+
+    nrf_saadc_int_disable(NRF_SAADC, NRF_SAADC_INT_ALL);
+    nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
+    nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED);
+
+    for (cnum = 0; cnum < SAADC_CH_NUM; cnum++) {
+        nrf_saadc_channel_init(NRF_SAADC, cnum, &default_ch);
+        nrf_saadc_channel_input_set(NRF_SAADC, cnum, NRF_SAADC_INPUT_DISABLED,
+                                    NRF_SAADC_INPUT_DISABLED);
     }
 }
 
-
 /**
  * Open the NRF52 ADC device
  *
@@ -90,7 +140,7 @@ nrf52_saadc_event_handler(const nrfx_saadc_evt_t *event)
  *             if resource unavailable.  If OS_WAIT_FOREVER specified, blocks
  *             until resource is available.
  * @param arg  Argument provided by higher layer to open, in this case
- *             it can be a nrfx_saadc_config_t, to override the default
+ *             it can be a adc_dev_cfg, to override the default
  *             configuration.
  *
  * @return 0 on success, non-zero on failure.
@@ -98,11 +148,10 @@ nrf52_saadc_event_handler(const nrfx_saadc_evt_t *event)
 static int
 nrf52_adc_open(struct os_dev *odev, uint32_t wait, void *arg)
 {
-    struct adc_dev *dev;
     int rc = 0;
     int unlock = 0;
-
-    dev = (struct adc_dev *) odev;
+    struct adc_dev *dev = (struct adc_dev *) odev;
+    struct adc_dev_cfg *adc_config = (struct adc_dev_cfg *) arg;
 
     if (os_started()) {
         rc = os_mutex_pend(&dev->ad_lock, wait);
@@ -113,24 +162,71 @@ nrf52_adc_open(struct os_dev *odev, uint32_t wait, void 
*arg)
     }
 
     if (++(dev->ad_ref_cnt) == 1) {
-        /* Initialize the device */
-        rc = nrfx_saadc_init((nrfx_saadc_config_t *) arg,
-                nrf52_saadc_event_handler);
-        if (rc != NRFX_SUCCESS) {
-            goto err;
-        }
-        rc = 0;
-
+        init_instance_unconf();
+        NVIC_SetPriority(SAADC_IRQn, 0);
+        NVIC_EnableIRQ(SAADC_IRQn);
         global_adc_dev = dev;
-        global_adc_config = arg;
+
+        if (adc_config) {
+            switch (adc_config->resolution) {
+            case ADC_RESOLUTION_8BIT:
+                g_drv_instance.resolution = NRF_SAADC_RESOLUTION_8BIT;
+                break;
+            case ADC_RESOLUTION_10BIT:
+                g_drv_instance.resolution = NRF_SAADC_RESOLUTION_10BIT;
+                break;
+            case ADC_RESOLUTION_12BIT:
+                g_drv_instance.resolution = NRF_SAADC_RESOLUTION_12BIT;
+                break;
+            case ADC_RESOLUTION_14BIT:
+                g_drv_instance.resolution = NRF_SAADC_RESOLUTION_14BIT;
+                break;
+            default:
+                assert(0);
+            }
+
+            switch (adc_config->oversample) {
+            case ADC_OVERSAMPLE_DISABLED:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_DISABLED;
+                break;
+            case ADC_OVERSAMPLE_2X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_2X;
+                break;
+            case ADC_OVERSAMPLE_4X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_4X;
+                break;
+            case ADC_OVERSAMPLE_8X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_8X;
+                break;
+            case ADC_OVERSAMPLE_16X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_16X;
+                break;
+            case ADC_OVERSAMPLE_32X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_32X;
+                break;
+            case ADC_OVERSAMPLE_64X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_64X;
+                break;
+            case ADC_OVERSAMPLE_128X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_128X;
+                break;
+            case ADC_OVERSAMPLE_256X:
+                g_drv_instance.oversample = NRF_SAADC_OVERSAMPLE_256X;
+                break;
+            default:
+                assert(0);
+            }
+
+            g_drv_instance.calibrate = adc_config->calibrate;
+        }
     }
 err:
     if (unlock) {
         os_mutex_release(&dev->ad_lock);
     }
-    return (rc);
-}
 
+    return rc;
+}
 
 /**
  * Close the NRF52 ADC device.
@@ -156,10 +252,22 @@ nrf52_adc_close(struct os_dev *odev)
         unlock = 1;
     }
     if (--(dev->ad_ref_cnt) == 0) {
-        nrfx_saadc_uninit();
+        NVIC_DisableIRQ(SAADC_IRQn);
+        if (nrf_saadc_busy_check(NRF_SAADC)) {
+            nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
+            nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
+
+            while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_STOPPED));
+
+            nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STOPPED);
+            nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
+        }
+
+        nrf_saadc_disable(NRF_SAADC);
+        init_instance_unconf();
+        clear_device_regs();
 
         global_adc_dev = NULL;
-        global_adc_config = NULL;
     }
 
 err:
@@ -181,84 +289,98 @@ err:
  * @return 0 on success, non-zero on failure.
  */
 static int
-nrf52_adc_configure_channel(struct adc_dev *dev, uint8_t cnum,
-        void *cfgdata)
+nrf52_adc_configure_channel(struct adc_dev *dev, uint8_t cnum, void *cfgdata)
 {
-    nrf_saadc_channel_config_t *cc;
+    struct adc_chan_cfg *cfg = (struct adc_chan_cfg *) cfgdata;
     uint16_t refmv;
-    uint8_t res;
-    int rc;
+    nrf_saadc_resolution_t res;
 
-    cc = (nrf_saadc_channel_config_t *) cfgdata;
+    if (cnum > SAADC_CH_NUM) {
+        return OS_EINVAL;
+    }
 
-    rc = nrfx_saadc_channel_init(cnum, cc);
-    if (rc != NRFX_SUCCESS) {
-        goto err;
+    if (nrf_saadc_busy_check(NRF_SAADC)) {
+        return OS_EBUSY;
     }
 
-    if (global_adc_config) {
-        /* Set the resolution and reference voltage for this channel to
-        * enable conversion functions.
-        */
-        switch (global_adc_config->resolution) {
-            case NRF_SAADC_RESOLUTION_8BIT:
-                res = 8;
-                break;
-            case NRF_SAADC_RESOLUTION_10BIT:
-                res = 10;
-                break;
-            case NRF_SAADC_RESOLUTION_12BIT:
-                res = 12;
-                break;
-            case NRF_SAADC_RESOLUTION_14BIT:
-                res = 14;
-                break;
-            default:
-                assert(0);
-        }
-    } else {
-        /* Default to 10-bit resolution. */
+    channel_unconf(cnum);
+    dev->ad_chans[cnum].c_configured = 0;
+    if (!cfgdata) {
+        nrf_saadc_channel_init(NRF_SAADC, cnum,
+                               &g_drv_instance.channels[cnum].nrf_chan);
+        return 0;
+    }
+
+    switch (g_drv_instance.resolution) {
+    case NRF_SAADC_RESOLUTION_8BIT:
+        res = 8;
+        break;
+    case NRF_SAADC_RESOLUTION_10BIT:
         res = 10;
+        break;
+    case NRF_SAADC_RESOLUTION_12BIT:
+        res = 12;
+        break;
+    case NRF_SAADC_RESOLUTION_14BIT:
+        res = 14;
+        break;
+    default:
+        assert(0);
     }
 
-    switch (cc->reference) {
-        case NRF_SAADC_REFERENCE_INTERNAL:
-            refmv = 600; /* 0.6V for NRF52 */
-            break;
-        case NRF_SAADC_REFERENCE_VDD4:
-            refmv = init_adc_config->nadc_refmv / 4;
-            break;
-        default:
-            assert(0);
+    switch (cfg->reference) {
+    case ADC_REFERENCE_INTERNAL:
+        g_drv_instance.channels[cnum].nrf_chan.reference =
+            NRF_SAADC_REFERENCE_INTERNAL;
+        refmv = 600; /* 0.6V for NRF52 */
+        break;
+    case ADC_REFERENCE_VDD_DIV_4:
+        g_drv_instance.channels[cnum].nrf_chan.reference =
+            NRF_SAADC_REFERENCE_VDD4;
+        refmv = init_cfg->nadc_refmv / 4;
+        break;
+    default:
+        assert(0);
     }
 
     /* Adjust reference voltage for gain. */
-    switch (cc->gain) {
-        case NRF_SAADC_GAIN1_6:
-            refmv *= 6;
-            break;
-        case NRF_SAADC_GAIN1_5:
-            refmv *= 5;
-            break;
-        case NRF_SAADC_GAIN1_4:
-            refmv *= 4;
-            break;
-        case NRF_SAADC_GAIN1_3:
-            refmv *= 3;
-            break;
-        case NRF_SAADC_GAIN1_2:
-            refmv *= 2;
-            break;
-        case NRF_SAADC_GAIN2:
-            refmv /= 2;
-            break;
-        case NRF_SAADC_GAIN4:
-            refmv /= 4;
-            break;
-        default:
-            break;
+    switch (cfg->gain) {
+    case ADC_GAIN1_6:
+        refmv *= 6;
+        break;
+    case ADC_GAIN1_5:
+        refmv *= 5;
+        break;
+    case ADC_GAIN1_4:
+        refmv *= 4;
+        break;
+    case ADC_GAIN1_3:
+        refmv *= 3;
+        break;
+    case ADC_GAIN1_2:
+        refmv *= 2;
+        break;
+    case ADC_GAIN2:
+        refmv /= 2;
+        break;
+    case ADC_GAIN4:
+        refmv /= 4;
+        break;
+    default:
+        break;
+    }
+
+    g_drv_instance.channels[cnum].pin_p = cfg->pin;
+    if (cfg->differential) {
+        g_drv_instance.channels[cnum].nrf_chan.mode =
+            NRF_SAADC_MODE_DIFFERENTIAL;
+        g_drv_instance.channels[cnum].pin_n = cfg->pin_negative;
     }
 
+    /* Init Channel's registers */
+    nrf_saadc_channel_init(NRF_SAADC, cnum,
+                           &g_drv_instance.channels[cnum].nrf_chan);
+
     /* Store these values in channel definitions, for conversions to
      * milivolts.
      */
@@ -266,58 +388,56 @@ nrf52_adc_configure_channel(struct adc_dev *dev, uint8_t 
cnum,
     dev->ad_chans[cnum].c_refmv = refmv;
     dev->ad_chans[cnum].c_configured = 1;
 
-    return (0);
-err:
-    return (rc);
+    return 0;
 }
 
 /**
- * Set buffer to read data into.  Implementation of setbuffer handler.
+ * Set buffer to read data into. Implementation of setbuffer handler.
  * Sets both the primary and secondary buffers for DMA.
  */
 static int
-nrf52_adc_set_buffer(struct adc_dev *dev, void *buf1, void *buf2,
-        int buf_len)
+nrf52_adc_set_buffer(struct adc_dev *dev, void *buf1, void *buf2, int buf_len)
 {
-    int rc;
-
-    /* Convert overall buffer length, into a total number of samples which
-     * Nordic APIs expect.
-     */
-    buf_len /= sizeof(nrf_saadc_value_t);
+    assert(dev);
+    assert(buf1);
 
-    rc = nrfx_saadc_buffer_convert((nrf_saadc_value_t *) buf1, buf_len);
-    if (rc != NRFX_SUCCESS) {
-        goto err;
+    if (buf_len <= 0) {
+        return OS_EINVAL;
     }
 
+    buf_len /= sizeof(nrf_saadc_value_t);
+    g_drv_instance.primary_buf = buf1;
+    g_drv_instance.primary_size = buf_len;
     if (buf2) {
-        rc = nrfx_saadc_buffer_convert((nrf_saadc_value_t *) buf2,
-                buf_len);
-        if (rc != NRFX_SUCCESS) {
-            goto err;
-        }
+        g_drv_instance.secondary_buf = buf2;
+        g_drv_instance.secondary_size = buf_len;
     }
-    return (0);
-err:
-    return (rc);
+
+    return 0;
 }
 
 static int
 nrf52_adc_release_buffer(struct adc_dev *dev, void *buf, int buf_len)
 {
-    int rc;
+    assert(dev);
+    assert(buf);
 
-    buf_len /= sizeof(nrf_saadc_value_t);
+    if (buf_len <= 0) {
+        return OS_EINVAL;
+    }
 
-    rc = nrfx_saadc_buffer_convert((nrf_saadc_value_t *) buf, buf_len);
-    if (rc != NRFX_SUCCESS) {
-        goto err;
+    buf_len /= sizeof(nrf_saadc_value_t);
+    if (!g_drv_instance.primary_buf) {
+        g_drv_instance.primary_buf = buf;
+        g_drv_instance.primary_size = buf_len;
+    } else if (!g_drv_instance.secondary_buf) {
+        g_drv_instance.secondary_buf = buf;
+        g_drv_instance.secondary_size = buf_len;
+    } else {
+        return OS_ENOENT;
     }
 
-    return (0);
-err:
-    return (rc);
+    return 0;
 }
 
 /**
@@ -326,9 +446,58 @@ err:
 static int
 nrf52_adc_sample(struct adc_dev *dev)
 {
-    nrfx_saadc_sample();
+    int cnum;
+    int cnum_last = 0;
+    int used_chans = 0;
+
+    if (nrf_saadc_busy_check(NRF_SAADC)) {
+        return OS_EBUSY;
+    }
+
+    for (cnum = 0; cnum < SAADC_CH_NUM; cnum++) {
+        if (dev->ad_chans[cnum].c_configured) {
+            cnum_last = cnum;
+            used_chans++;
+            nrf_saadc_channel_input_set(NRF_SAADC, cnum,
+                                        g_drv_instance.channels[cnum].pin_p,
+                                        g_drv_instance.channels[cnum].pin_n);
+        }
+    }
+    assert(used_chans > 0);
+
+    if (g_drv_instance.primary_size < (used_chans * 
sizeof(nrf_saadc_value_t))) {
+        return OS_ENOMEM;
+    }
+
+    if ((used_chans == 1) &&
+        (g_drv_instance.oversample != NRF_SAADC_OVERSAMPLE_DISABLED)) {
+        nrf_saadc_burst_set(NRF_SAADC, cnum_last, NRF_SAADC_BURST_ENABLED);
+        nrf_saadc_oversample_set(NRF_SAADC, g_drv_instance.oversample);
+    } else {
+        nrf_saadc_oversample_set(NRF_SAADC, NRF_SAADC_OVERSAMPLE_DISABLED);
+    }
+
+    nrf_saadc_resolution_set(NRF_SAADC, g_drv_instance.resolution);
+    nrf_saadc_buffer_init(NRF_SAADC, g_drv_instance.primary_buf,
+                          g_drv_instance.primary_size);
+
+    nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
+    nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
+    nrf_saadc_int_enable(NRF_SAADC,
+                         NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE);
+
+    /* Start Sampling */
+    nrf_saadc_enable(NRF_SAADC);
 
-    return (0);
+    if (g_drv_instance.calibrate) {
+        nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_CALIBRATEOFFSET);
+    } else {
+        nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
+        nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
+        nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
+    }
+
+    return 0;
 }
 
 /**
@@ -337,9 +506,13 @@ nrf52_adc_sample(struct adc_dev *dev)
 static int
 nrf52_adc_read_channel(struct adc_dev *dev, uint8_t cnum, int *result)
 {
-    nrf_saadc_value_t adc_value;
     int rc;
     int unlock = 0;
+    nrf_saadc_value_t adc_value;
+
+    if (nrf_saadc_busy_check(NRF_SAADC)) {
+        return OS_EBUSY;
+    }
 
     if (os_started()) {
         rc = os_mutex_pend(&dev->ad_lock, OS_TIMEOUT_NEVER);
@@ -348,11 +521,42 @@ nrf52_adc_read_channel(struct adc_dev *dev, uint8_t cnum, 
int *result)
         }
         unlock = 1;
     }
-    rc = nrfx_saadc_sample_convert(cnum, &adc_value);
-    if (rc != NRFX_SUCCESS) {
+
+    /* Channel must be configured */
+    if (!dev->ad_chans[cnum].c_configured) {
+        rc = OS_EINVAL;
         goto err;
     }
 
+    /* Enable the channel, set pins */
+    nrf_saadc_channel_input_set(NRF_SAADC, cnum,
+                                g_drv_instance.channels[cnum].pin_p,
+                                g_drv_instance.channels[cnum].pin_n);
+
+    if (g_drv_instance.oversample != NRF_SAADC_OVERSAMPLE_DISABLED) {
+        nrf_saadc_burst_set(NRF_SAADC, cnum, NRF_SAADC_BURST_ENABLED);
+        nrf_saadc_oversample_set(NRF_SAADC, g_drv_instance.oversample);
+    } else {
+        nrf_saadc_oversample_set(NRF_SAADC, NRF_SAADC_OVERSAMPLE_DISABLED);
+    }
+
+    nrf_saadc_resolution_set(NRF_SAADC, g_drv_instance.resolution);
+    nrf_saadc_buffer_init(NRF_SAADC, &adc_value, 1);
+    nrf_saadc_enable(NRF_SAADC);
+
+    nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
+    nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
+    while (!nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END));
+
+    nrf_saadc_disable(NRF_SAADC);
+    nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_STARTED);
+    nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
+
+    /* Disable the channel, unset pins */
+    nrf_saadc_channel_input_set(NRF_SAADC, cnum,
+                                NRF_SAADC_INPUT_DISABLED,
+                                NRF_SAADC_INPUT_DISABLED);
+
     *result = (int) adc_value;
     rc = 0;
 
@@ -360,12 +564,12 @@ err:
     if (unlock) {
         os_mutex_release(&dev->ad_lock);
     }
-    return (rc);
+    return rc;
 }
 
 static int
 nrf52_adc_read_buffer(struct adc_dev *dev, void *buf, int buf_len, int off,
-        int *result)
+                      int *result)
 {
     nrf_saadc_value_t val;
     int data_off;
@@ -376,21 +580,74 @@ nrf52_adc_read_buffer(struct adc_dev *dev, void *buf, int 
buf_len, int off,
     val = *(nrf_saadc_value_t *) ((uint8_t *) buf + data_off);
     *result = val;
 
-    return (0);
+    return 0;
 }
 
 static int
 nrf52_adc_size_buffer(struct adc_dev *dev, int chans, int samples)
 {
-    return (sizeof(nrf_saadc_value_t) * chans * samples);
+    return sizeof(nrf_saadc_value_t) * chans * samples;
+}
+
+void
+nrf52_saadc_irq_handler(void)
+{
+    adc_event_type_t ev = ADC_EVENT_CALIBRATED;
+    void *buf = NULL;
+    int bufsize = 0;
+
+    if (global_adc_dev == NULL || !global_adc_dev->ad_event_handler_func) {
+        ++nrf52_saadc_stats.saadc_events_failed;
+        return;
+    }
+    ++nrf52_saadc_stats.saadc_events;
+
+    if (nrf_saadc_event_check(NRF_SAADC, NRF_SAADC_EVENT_END)) {
+        nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_END);
+
+        buf = g_drv_instance.primary_buf;
+        bufsize = g_drv_instance.primary_size * sizeof(nrf_saadc_value_t);
+        if (g_drv_instance.secondary_buf) {
+            g_drv_instance.primary_buf = g_drv_instance.secondary_buf;
+            g_drv_instance.primary_size = g_drv_instance.secondary_size;
+            g_drv_instance.secondary_buf = NULL;
+            g_drv_instance.secondary_size = 0;
+
+            nrf_saadc_buffer_init(NRF_SAADC,
+                                  g_drv_instance.primary_buf,
+                                  g_drv_instance.primary_size);
+        } else {
+            nrf_saadc_int_disable(NRF_SAADC, NRF_SAADC_INT_ALL);
+            nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
+            nrf_saadc_disable(NRF_SAADC);
+        }
+
+
+        ev = ADC_EVENT_RESULT;
+        global_adc_dev->ad_event_handler_func(global_adc_dev,
+                                              
global_adc_dev->ad_event_handler_arg,
+                                              ev, buf, bufsize);
+    } else if (nrf_saadc_event_check(NRF_SAADC, 
NRF_SAADC_EVENT_CALIBRATEDONE)) {
+        nrf_saadc_event_clear(NRF_SAADC, NRF_SAADC_EVENT_CALIBRATEDONE);
+
+        global_adc_dev->ad_event_handler_func(global_adc_dev,
+                                              
global_adc_dev->ad_event_handler_arg,
+                                              ev, buf, bufsize);
+
+        nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_STOP);
+        nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_START);
+        nrf_saadc_task_trigger(NRF_SAADC, NRF_SAADC_TASK_SAMPLE);
+    } else {
+        ++nrf52_saadc_stats.saadc_events_failed;
+    }
 }
 
 #if MYNEWT_VAL(OS_SYSVIEW)
 static void
-saadc_irq_handler(void)
+sysview_irq_handler(void)
 {
     os_trace_isr_enter();
-    nrfx_saadc_irq_handler();
+    nrf52_saadc_irq_handler();
     os_trace_isr_exit();
 }
 #endif
@@ -417,28 +674,23 @@ int
 nrf52_adc_dev_init(struct os_dev *odev, void *arg)
 {
     struct adc_dev *dev;
-
     dev = (struct adc_dev *) odev;
 
     os_mutex_init(&dev->ad_lock);
 
     dev->ad_chans = (void *) nrf52_adc_chans;
-    dev->ad_chan_count = NRF_SAADC_CHANNEL_COUNT;
+    dev->ad_chan_count = SAADC_CH_NUM;
 
-    OS_DEV_SETHANDLERS(odev, nrf52_adc_open, nrf52_adc_close);
-
-    assert(init_adc_config == NULL || init_adc_config == arg);
-    init_adc_config = arg;
+    init_cfg = (struct nrf52_adc_dev_cfg *) arg;
 
+    OS_DEV_SETHANDLERS(odev, nrf52_adc_open, nrf52_adc_close);
     dev->ad_funcs = &nrf52_adc_funcs;
 
 #if MYNEWT_VAL(OS_SYSVIEW)
-    NVIC_SetVector(SAADC_IRQn, (uint32_t) saadc_irq_handler);
+    NVIC_SetVector(SAADC_IRQn, (uint32_t) sysview_irq_handler);
 #else
-    NVIC_SetVector(SAADC_IRQn, (uint32_t) nrfx_saadc_irq_handler);
+    NVIC_SetVector(SAADC_IRQn, (uint32_t) nrf52_saadc_irq_handler);
 #endif
 
-    return (0);
+    return 0;
 }
-
-
diff --git a/hw/mcu/nordic/nrf52xxx/src/nrfx_saadc_mod.c 
b/hw/mcu/nordic/nrf52xxx/src/nrfx_saadc_mod.c
deleted file mode 100644
index 8d63e94..0000000
--- a/hw/mcu/nordic/nrf52xxx/src/nrfx_saadc_mod.c
+++ /dev/null
@@ -1,651 +0,0 @@
-/**
- * Copyright (c) 2015 - 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 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 the copyright holder nor the names of its
- *    contributors may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "syscfg/syscfg.h"
-
-#if MYNEWT_VAL(BSP_NRF52)
-
-#include <nrfx.h>
-
-#if NRFX_CHECK(NRFX_SAADC_ENABLED)
-#include <nrfx_saadc.h>
-
-#define NRFX_LOG_MODULE SAADC
-#include <nrfx_log.h>
-
-#define EVT_TO_STR(event)                                                      
 \
-    (event == NRF_SAADC_EVENT_STARTED       ? "NRF_SAADC_EVENT_STARTED"       
: \
-    (event == NRF_SAADC_EVENT_END           ? "NRF_SAADC_EVENT_END"           
: \
-    (event == NRF_SAADC_EVENT_DONE          ? "NRF_SAADC_EVENT_DONE"          
: \
-    (event == NRF_SAADC_EVENT_RESULTDONE    ? "NRF_SAADC_EVENT_RESULTDONE"    
: \
-    (event == NRF_SAADC_EVENT_CALIBRATEDONE ? "NRF_SAADC_EVENT_CALIBRATEDONE" 
: \
-    (event == NRF_SAADC_EVENT_STOPPED       ? "NRF_SAADC_EVENT_STOPPED"       
: \
-                                              "UNKNOWN EVENT"))))))
-
-
-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;
-
-/** @brief SAADC control block.*/
-typedef struct
-{
-    nrfx_saadc_event_handler_t    event_handler;                 ///< Event 
handler function pointer.
-    volatile nrf_saadc_value_t  * p_buffer;                      ///< Sample 
buffer.
-    volatile uint16_t             buffer_size;                   ///< Size of 
the sample buffer.
-    volatile nrf_saadc_value_t  * p_secondary_buffer;            ///< 
Secondary sample buffer.
-    volatile nrf_saadc_state_t    adc_state;                     ///< State of 
the SAADC.
-    uint32_t                      limits_enabled_flags;          ///< Enabled 
limits flags.
-    uint16_t                      secondary_buffer_size;         ///< Size of 
the secondary buffer.
-    uint16_t                      buffer_size_left;              ///< 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]; ///< Pin 
configurations of SAADC channels.
-    nrfx_drv_state_t              state;                         ///< Driver 
initialization state.
-    uint8_t                       active_channels;               ///< Number 
of enabled SAADC channels.
-    bool                          low_power_mode;                ///< 
Indicates if low power mode is active.
-    bool                          conversions_end;               ///< When low 
power mode is active indicates end of conversions on current buffer.
-} nrfx_saadc_cb_t;
-
-static nrfx_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) & 4) \
-                                            ? NRF_SAADC_LIMIT_LOW : 
NRF_SAADC_LIMIT_HIGH)
-#define HW_TIMEOUT 10000
-
-void nrfx_saadc_irq_handler(void)
-{
-    if (nrf_saadc_event_check(NRF_SAADC_EVENT_END))
-    {
-        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
-        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_SAADC_EVENT_END));
-
-        if (!m_cb.low_power_mode || m_cb.conversions_end)
-        {
-            nrfx_saadc_evt_t evt;
-            evt.type               = NRFX_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(&evt);
-            m_cb.conversions_end = false;
-        }
-    }
-    if (m_cb.low_power_mode && nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED))
-    {
-        nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
-        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_SAADC_EVENT_STARTED));
-
-        if (m_cb.buffer_size_left > 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 
*)&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) &&
-
-                 (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);
-        NRFX_LOG_DEBUG("Event: %s.", 
EVT_TO_STR(NRF_SAADC_EVENT_CALIBRATEDONE));
-        m_cb.adc_state = NRF_SAADC_STATE_IDLE;
-
-        nrfx_saadc_evt_t evt;
-        evt.type = NRFX_SAADC_EVT_CALIBRATEDONE;
-        m_cb.event_handler(&evt);
-    }
-    if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED))
-    {
-        nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
-        NRFX_LOG_DEBUG("Event: %s.", 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 &= ~((1UL << 31) >> flag_idx);
-            event        = FLAG_IDX_TO_EVENT(flag_idx);
-            if (nrf_saadc_event_check(event))
-            {
-                nrf_saadc_event_clear(event);
-                nrfx_saadc_evt_t evt;
-                evt.type                  = NRFX_SAADC_EVT_LIMIT;
-                evt.data.limit.channel    = LIMIT_EVENT_TO_CHANNEL(event);
-                evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event);
-                NRFX_LOG_DEBUG("Event limit, channel: %d, limit type: %d.",
-                               evt.data.limit.channel,
-                               evt.data.limit.limit_type);
-                m_cb.event_handler(&evt);
-            }
-        }
-    }
-}
-
-
-nrfx_err_t nrfx_saadc_init(nrfx_saadc_config_t const * p_config,
-                           nrfx_saadc_event_handler_t  event_handler)
-{
-    NRFX_ASSERT(p_config);
-    NRFX_ASSERT(event_handler);
-    nrfx_err_t err_code;
-
-    if (m_cb.state != NRFX_DRV_STATE_UNINITIALIZED)
-    {
-        err_code = NRFX_ERROR_INVALID_STATE;
-        NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                         __func__,
-                         NRFX_LOG_ERROR_STRING_GET(err_code));
-        return err_code;
-    }
-
-    m_cb.event_handler = event_handler;
-    nrf_saadc_resolution_set(p_config->resolution);
-    nrf_saadc_oversample_set(p_config->oversample);
-    m_cb.low_power_mode       = p_config->low_power_mode;
-    m_cb.state                = NRFX_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_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
-    NRFX_IRQ_PRIORITY_SET(SAADC_IRQn, p_config->interrupt_priority);
-    NRFX_IRQ_ENABLE(SAADC_IRQn);
-    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 = NRFX_SUCCESS;
-    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, 
NRFX_LOG_ERROR_STRING_GET(err_code));
-
-    return err_code;
-}
-
-
-void nrfx_saadc_uninit(void)
-{
-    NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
-
-    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);
-
-    nrf_saadc_disable();
-    m_cb.adc_state = NRF_SAADC_STATE_IDLE;
-
-    for (uint32_t channel = 0; channel < NRF_SAADC_CHANNEL_COUNT; ++channel)
-    {
-        if (m_cb.psel[channel].pselp != NRF_SAADC_INPUT_DISABLED)
-        {
-            nrfx_err_t err_code = nrfx_saadc_channel_uninit(channel);
-            NRFX_ASSERT(err_code == NRFX_SUCCESS);
-        }
-    }
-
-    m_cb.state = NRFX_DRV_STATE_UNINITIALIZED;
-}
-
-
-nrfx_err_t nrfx_saadc_channel_init(uint8_t                                  
channel,
-                                   nrf_saadc_channel_config_t const * const 
p_config)
-{
-    NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
-    NRFX_ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
-    // Oversampling can be used only with one channel.
-    NRFX_ASSERT((nrf_saadc_oversample_get() == NRF_SAADC_OVERSAMPLE_DISABLED) 
||
-                (m_cb.active_channels == 0));
-    NRFX_ASSERT((p_config->pin_p <= NRF_SAADC_INPUT_VDD) &&
-                (p_config->pin_p > NRF_SAADC_INPUT_DISABLED));
-    NRFX_ASSERT(p_config->pin_n <= NRF_SAADC_INPUT_VDD);
-
-    nrfx_err_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 = NRFX_ERROR_BUSY;
-        NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                         __func__,
-                         NRFX_LOG_ERROR_STRING_GET(err_code));
-        return err_code;
-    }
-
-#ifdef NRF52_PAN_74
-    if ((p_config->acq_time == NRF_SAADC_ACQTIME_3US) ||
-        (p_config->acq_time == NRF_SAADC_ACQTIME_5US))
-    {
-        nrf_saadc_disable();
-    }
-#endif //NRF52_PAN_74
-
-    if (m_cb.psel[channel].pselp == NRF_SAADC_INPUT_DISABLED)
-    {
-        ++m_cb.active_channels;
-    }
-    m_cb.psel[channel].pselp = p_config->pin_p;
-    m_cb.psel[channel].pseln = p_config->pin_n;
-    nrf_saadc_channel_init(channel, p_config);
-    nrf_saadc_channel_input_set(channel, p_config->pin_p, p_config->pin_n);
-
-#ifdef NRF52_PAN_74
-    if ((p_config->acq_time == NRF_SAADC_ACQTIME_3US) ||
-        (p_config->acq_time == NRF_SAADC_ACQTIME_5US))
-    {
-        nrf_saadc_enable();
-    }
-#endif //NRF52_PAN_74
-
-    NRFX_LOG_INFO("Channel initialized: %d.", channel);
-    err_code = NRFX_SUCCESS;
-    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, 
NRFX_LOG_ERROR_STRING_GET(err_code));
-    return err_code;
-}
-
-
-nrfx_err_t nrfx_saadc_channel_uninit(uint8_t channel)
-{
-    NRFX_ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
-    NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
-
-    nrfx_err_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 = NRFX_ERROR_BUSY;
-        NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                         __func__,
-                         NRFX_LOG_ERROR_STRING_GET(err_code));
-        return err_code;
-    }
-
-    if (m_cb.psel[channel].pselp != NRF_SAADC_INPUT_DISABLED)
-    {
-        --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);
-    nrfx_saadc_limits_set(channel, NRFX_SAADC_LIMITL_DISABLED, 
NRFX_SAADC_LIMITH_DISABLED);
-    NRFX_LOG_INFO("Channel denitialized: %d.", channel);
-
-    err_code = NRFX_SUCCESS;
-    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, 
NRFX_LOG_ERROR_STRING_GET(err_code));
-    return err_code;
-}
-
-
-uint32_t nrfx_saadc_sample_task_get(void)
-{
-    return nrf_saadc_task_address_get(
-                m_cb.low_power_mode ? NRF_SAADC_TASK_START : 
NRF_SAADC_TASK_SAMPLE);
-}
-
-
-nrfx_err_t nrfx_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * 
p_value)
-{
-    nrfx_err_t err_code;
-
-    if (m_cb.adc_state != NRF_SAADC_STATE_IDLE)
-    {
-        err_code = NRFX_ERROR_BUSY;
-        NRFX_LOG_WARNING("Function: %s error code: %s.",
-                         __func__,
-                         NRFX_LOG_ERROR_STRING_GET(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 > 1)
-    {
-        for (uint32_t i = 0; i < 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);
-
-    bool result;
-    NRFX_WAIT_FOR(nrf_saadc_event_check(NRF_SAADC_EVENT_END), HW_TIMEOUT, 0, 
result);
-    NRFX_ASSERT(result);
-
-    nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
-    nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
-
-    NRFX_LOG_INFO("Conversion value: %d, channel %d.", *p_value, channel);
-
-    if (m_cb.active_channels > 1)
-    {
-        for (uint32_t i = 0; i < 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 = NRFX_SUCCESS;
-    NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                     __func__,
-                     NRFX_LOG_ERROR_STRING_GET(err_code));
-    return err_code;
-}
-
-
-nrfx_err_t nrfx_saadc_buffer_convert(nrf_saadc_value_t * p_buffer, uint16_t 
size)
-{
-    NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
-    NRFX_ASSERT((size % m_cb.active_channels) == 0);
-    nrfx_err_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 = NRFX_ERROR_BUSY;
-        NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                         __func__,
-                         NRFX_LOG_ERROR_STRING_GET(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 = NRFX_ERROR_BUSY;
-            NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                             __func__,
-                             NRFX_LOG_ERROR_STRING_GET(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 = NRFX_SUCCESS;
-            NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                             __func__,
-                             NRFX_LOG_ERROR_STRING_GET(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;
-
-    NRFX_LOG_INFO("Function: %s, buffer length: %d, active channels: %d.",
-                  __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 = NRFX_SUCCESS;
-    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, 
NRFX_LOG_ERROR_STRING_GET(err_code));
-    return err_code;
-}
-
-
-nrfx_err_t nrfx_saadc_sample()
-{
-    NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
-
-    nrfx_err_t err_code = NRFX_SUCCESS;
-    if (m_cb.adc_state != NRF_SAADC_STATE_BUSY)
-    {
-        err_code = NRFX_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);
-    }
-
-    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, 
NRFX_LOG_ERROR_STRING_GET(err_code));
-    return err_code;
-}
-
-
-nrfx_err_t nrfx_saadc_calibrate_offset()
-{
-    NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
-
-    nrfx_err_t err_code;
-
-    if (m_cb.adc_state != NRF_SAADC_STATE_IDLE)
-    {
-        err_code = NRFX_ERROR_BUSY;
-        NRFX_LOG_WARNING("Function: %s, error code: %s.",
-                         __func__,
-                         NRFX_LOG_ERROR_STRING_GET(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 = NRFX_SUCCESS;
-    NRFX_LOG_INFO("Function: %s, error code: %s.",
-                  __func__,
-                  NRFX_LOG_ERROR_STRING_GET(err_code));
-    return err_code;
-}
-
-
-bool nrfx_saadc_is_busy(void)
-{
-    return (m_cb.adc_state != NRF_SAADC_STATE_IDLE);
-}
-
-
-void nrfx_saadc_abort(void)
-{
-    if (nrfx_saadc_is_busy())
-    {
-        nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
-        nrf_saadc_int_enable(NRF_SAADC_INT_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.
-            bool result;
-            NRFX_WAIT_FOR((m_cb.adc_state != NRF_SAADC_STATE_IDLE), 
HW_TIMEOUT, 0, result);
-            NRFX_ASSERT(result);
-        }
-
-        nrf_saadc_int_disable(NRF_SAADC_INT_STOPPED);
-
-        m_cb.p_buffer           = 0;
-        m_cb.p_secondary_buffer = 0;
-        NRFX_LOG_INFO("Conversion aborted.");
-    }
-}
-
-
-void nrfx_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t 
limit_high)
-{
-    NRFX_ASSERT(m_cb.state != NRFX_DRV_STATE_UNINITIALIZED);
-    NRFX_ASSERT(m_cb.event_handler); // only non blocking mode supported
-    NRFX_ASSERT(limit_low >= NRFX_SAADC_LIMITL_DISABLED);
-    NRFX_ASSERT(limit_high <= NRFX_SAADC_LIMITH_DISABLED);
-    NRFX_ASSERT(limit_low < 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 == NRFX_SAADC_LIMITL_DISABLED)
-    {
-        m_cb.limits_enabled_flags &= ~(0x80000000 >> 
LOW_LIMIT_TO_FLAG(channel));
-        nrf_saadc_int_disable(int_mask);
-    }
-    else
-    {
-        m_cb.limits_enabled_flags |= (0x80000000 >> 
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 == NRFX_SAADC_LIMITH_DISABLED)
-    {
-        m_cb.limits_enabled_flags &= ~(0x80000000 >> 
HIGH_LIMIT_TO_FLAG(channel));
-        nrf_saadc_int_disable(int_mask);
-    }
-    else
-    {
-        m_cb.limits_enabled_flags |= (0x80000000 >> 
HIGH_LIMIT_TO_FLAG(channel));
-        nrf_saadc_int_enable(int_mask);
-    }
-}
-
-void nrfx_enable_adc_chan(int chan, nrf_saadc_input_t pselp,
-                          nrf_saadc_input_t pseln)
-{
-    NRFX_ASSERT(m_cb.active_channels < NRF_SAADC_CHANNEL_COUNT);
-    ++m_cb.active_channels;
-    nrf_saadc_channel_input_set(chan, pselp, pseln);
-}
-
-void nrfx_disable_adc_chan(int chan)
-{
-    NRFX_ASSERT(m_cb.active_channels != 0);
-    --m_cb.active_channels;
-    nrf_saadc_channel_input_set(chan, NRF_SAADC_INPUT_DISABLED,
-                                NRF_SAADC_INPUT_DISABLED);
-}
-#endif // NRFX_CHECK(NRFX_SAADC_ENABLED)
-#endif /* MYNEWT_VAL(BSP_NRF52) */

Reply via email to