Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/sterly_refactor f0e3b9a0f -> 30da46584


Add ADC implementation.  Add device tree implementation.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/30da4658
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/30da4658
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/30da4658

Branch: refs/heads/sterly_refactor
Commit: 30da46584a506e07f06e33277ccd05ee9b65c8aa
Parents: 46ffe2a
Author: Sterling Hughes <[email protected]>
Authored: Wed Aug 3 14:56:32 2016 -0700
Committer: Sterling Hughes <[email protected]>
Committed: Wed Aug 3 14:57:50 2016 -0700

----------------------------------------------------------------------
 .../adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h |   5 +-
 drivers/adc/adc_nrf52/pkg.yml                   |   4 +
 drivers/adc/adc_nrf52/src/adc_nrf52.c           | 333 ++++++++++++++++++-
 drivers/adc/include/adc/adc.h                   | 241 +++++++++++++-
 drivers/adc/pkg.yml                             |   3 +
 drivers/adc/src/adc.c                           |  67 ++++
 hw/bsp/nrf52dk/src/hal_bsp.c                    |   8 +-
 hw/hal/include/hal/hal_bsp.h                    |   2 +
 hw/mcu/nordic/pkg.yml                           |   2 +-
 libs/os/include/os/os_dev.h                     |  12 +-
 libs/os/src/os_dev.c                            |  94 ++++--
 11 files changed, 736 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h
----------------------------------------------------------------------
diff --git a/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h 
b/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h
index 898503b..f356f89 100644
--- a/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h
+++ b/drivers/adc/adc_nrf52/include/adc_nrf52/adc_nrf52.h
@@ -22,6 +22,9 @@
 
 #include <adc/adc.h>
 
-int nrf52_adc_dev_init(struct os_dev *);
+#include <nrf.h>
+#include <nrf_saadc.h>
+
+int nrf52_adc_dev_init(struct os_dev *, void *);
 
 #endif /* __ADC_H__ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/drivers/adc/adc_nrf52/pkg.yml
----------------------------------------------------------------------
diff --git a/drivers/adc/adc_nrf52/pkg.yml b/drivers/adc/adc_nrf52/pkg.yml
index 487b23b..bf978ab 100644
--- a/drivers/adc/adc_nrf52/pkg.yml
+++ b/drivers/adc/adc_nrf52/pkg.yml
@@ -22,6 +22,10 @@ pkg.description: ADC driver for the NRF52
 pkg.author: "Apache Mynewt <[email protected]>"
 pkg.homepage: "http://mynewt.apache.org/";
 pkg.keywords:
+pkg.features: 
+    - ADC_NRF52
+pkg.apis: 
+    - ADC_HW_IMPL
 pkg.deps.TEST:
    - hw/hal
    - hw/mcu/nordic

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/drivers/adc/adc_nrf52/src/adc_nrf52.c
----------------------------------------------------------------------
diff --git a/drivers/adc/adc_nrf52/src/adc_nrf52.c 
b/drivers/adc/adc_nrf52/src/adc_nrf52.c
index c8e5741..36a2e1d 100644
--- a/drivers/adc/adc_nrf52/src/adc_nrf52.c
+++ b/drivers/adc/adc_nrf52/src/adc_nrf52.c
@@ -18,21 +18,290 @@
  */
 
 
+#include <hal/hal_bsp.h>
 #include <adc/adc.h>
+#include <assert.h>
+#include <os/os.h>
+#include <bsp/cmsis_nvic.h>
 
 /* Nordic headers */
 #include <nrf.h>
+#include <nrf_saadc.h>
 #include <nrf_drv_saadc.h>
 #include <app_error.h>
 
+/**
+ * Weak symbol, this is defined in Nordic drivers but not exported.
+ * Needed for NVIC_SetVector().
+ */
+extern void SAADC_IRQHandler(void);
+
+struct nrf52_saadc_stats {
+    uint16_t saadc_events;
+    uint16_t saadc_events_failed;
+};
+static struct nrf52_saadc_stats nrf52_saadc_stats;
+
+struct adc_dev *global_adc_dev;
+nrf_drv_saadc_config_t *global_adc_config;
+
+uint8_t nrf52_adc_chans[NRF_SAADC_CHANNEL_COUNT];
+
+static void
+nrf52_saadc_event_handler(const nrf_drv_saadc_evt_t *event)
+{
+    nrf_drv_saadc_done_evt_t *done_ev;
+    int rc;
+
+    if (global_adc_dev == NULL) {
+        ++nrf52_saadc_stats.saadc_events_failed;
+        return;
+    }
+
+    ++nrf52_saadc_stats.saadc_events;
+
+    /* Right now only data reads supported, assert for unknown event
+     * type.
+     */
+    assert(event->type == NRF_DRV_SAADC_EVT_DONE);
+
+    done_ev = (nrf_drv_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));
+    if (rc != 0) {
+        ++nrf52_saadc_stats.saadc_events_failed;
+    }
+}
+
 
+/**
+ * Open the NRF52 ADC device
+ *
+ * This function locks the device for access from other tasks.
+ *
+ * @param odev The OS device to open
+ * @param wait The time in MS to wait.  If 0 specified, returns immediately
+ *             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 nrf_drv_saadc_config_t, to override the default
+ *             configuration.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 static int
-nrf52_adc_configure(struct adc_dev *dev, void *cfgdata)
+nrf52_adc_open(struct os_dev *odev, uint32_t wait, void *arg)
 {
+    struct adc_dev *dev;
+    int rc;
+
+    dev = (struct adc_dev *) odev;
+
+    if (os_started()) {
+        rc = os_mutex_pend(&dev->ad_lock, wait);
+        if (rc != OS_OK) {
+            goto err;
+        }
+    }
+
+    /* Initialize the device */
+    rc = nrf_drv_saadc_init((nrf_drv_saadc_config_t *) arg,
+            nrf52_saadc_event_handler);
+    if (rc != 0) {
+        goto err;
+    }
+
+    global_adc_dev = dev;
+    global_adc_config = arg;
 
     return (0);
+err:
+    return (rc);
 }
 
+
+/**
+ * Close the NRF52 ADC device.
+ *
+ * This function unlocks the device.
+ *
+ * @param odev The device to close.
+ */
+static int
+nrf52_adc_close(struct os_dev *odev)
+{
+    struct adc_dev *dev;
+
+    dev = (struct adc_dev *) odev;
+
+    nrf_drv_saadc_uninit();
+
+    global_adc_dev = NULL;
+    global_adc_config = NULL;
+
+    if (os_started()) {
+        os_mutex_release(&dev->ad_lock);
+    }
+
+    return (0);
+}
+
+/**
+ * Configure an ADC channel on the Nordic ADC.
+ *
+ * @param dev The ADC device to configure
+ * @param cnum The channel on the ADC device to configure
+ * @param cfgdata An opaque pointer to channel config, expected to be
+ *                a nrf_saadc_channel_config_t
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+static int
+nrf52_adc_configure_channel(struct adc_dev *dev, uint8_t cnum,
+        void *cfgdata)
+{
+    nrf_saadc_channel_config_t *cc;
+    uint16_t refmv;
+    uint8_t res;
+    int rc;
+
+    cc = (nrf_saadc_channel_config_t *) cfgdata;
+
+    rc = nrf_drv_saadc_channel_init(cnum, cc);
+    if (rc != 0) {
+        goto err;
+    }
+
+    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. */
+        res = 10;
+    }
+
+    switch (cc->reference) {
+        case NRF_SAADC_REFERENCE_INTERNAL:
+            refmv = 600; /* 0.6V for NRF52 */
+            break;
+        case NRF_SAADC_REFERENCE_VDD4:
+            refmv = bsp_get_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;
+    }
+
+    /* Store these values in channel definitions, for conversions to
+     * milivolts.
+     */
+    dev->ad_chans[cnum].c_res = res;
+    dev->ad_chans[cnum].c_refmv = refmv;
+    dev->ad_chans[cnum].c_configured = 1;
+
+    return (0);
+err:
+    return (rc);
+}
+
+/**
+ * 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)
+{
+    int rc;
+
+    /* Convert overall buffer length, into a total number of samples which
+     * Nordic APIs expect.
+     */
+    buf_len /= sizeof(nrf_saadc_value_t);
+
+    rc = nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *) buf1, buf_len);
+    if (rc != 0) {
+        goto err;
+    }
+
+    if (buf2) {
+        rc = nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *) buf2,
+                buf_len);
+        if (rc != 0) {
+            goto err;
+        }
+    }
+    return (0);
+err:
+    return (rc);
+}
+
+static int
+nrf52_adc_release_buffer(struct adc_dev *dev, void *buf, int buf_len)
+{
+    int rc;
+
+    buf_len /= sizeof(nrf_saadc_value_t);
+
+    rc = nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *) buf, buf_len);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+/**
+ * Trigger an ADC sample.
+ */
 static int
 nrf52_adc_sample(struct adc_dev *dev)
 {
@@ -42,22 +311,80 @@ nrf52_adc_sample(struct adc_dev *dev)
 }
 
 /**
+ * Blocking read of an ADC channel, returns result as an integer.
+ */
+static int
+nrf52_adc_read_channel(struct adc_dev *dev, uint8_t cnum, int *result)
+{
+    nrf_saadc_value_t adc_value;
+    int rc;
+
+    rc = nrf_drv_saadc_sample_convert(cnum, &adc_value);
+    if (rc != 0) {
+        goto err;
+    }
+
+    *result = (int) adc_value;
+
+    return (0);
+err:
+    return (rc);
+}
+
+static int
+nrf52_adc_read_buffer(struct adc_dev *dev, void *buf, int buf_len, int off,
+        int *result)
+{
+    nrf_saadc_value_t val;
+    int data_off;
+
+    data_off = off * sizeof(nrf_saadc_value_t);
+    assert(data_off < buf_len);
+
+    val = *(nrf_saadc_value_t *) ((uint8_t *) buf + data_off);
+    *result = val;
+
+    return (0);
+}
+
+static int
+nrf52_adc_size_buffer(struct adc_dev *dev, int chans, int samples)
+{
+    return (sizeof(nrf_saadc_value_t) * chans * samples);
+}
+
+
+/**
  * Callback to initialize an adc_dev structure from the os device
  * initialization callback.  This sets up a nrf52_adc_device(), so
  * that subsequent lookups to this device allow us to manipulate it.
  */
 int
-nrf52_adc_dev_init(struct os_dev *odev)
+nrf52_adc_dev_init(struct os_dev *odev, void *arg)
 {
     struct adc_dev *dev;
     struct adc_driver_funcs *af;
 
     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;
+
+    OS_DEV_SETHANDLERS(odev, nrf52_adc_open, nrf52_adc_close);
+
     af = &dev->ad_funcs;
 
-    af->af_config = nrf52_adc_configure;
+    af->af_configure_channel = nrf52_adc_configure_channel;
     af->af_sample = nrf52_adc_sample;
+    af->af_read_channel = nrf52_adc_read_channel;
+    af->af_set_buffer = nrf52_adc_set_buffer;
+    af->af_release_buffer = nrf52_adc_release_buffer;
+    af->af_read_buffer = nrf52_adc_read_buffer;
+    af->af_size_buffer = nrf52_adc_size_buffer;
+
+    NVIC_SetVector(SAADC_IRQn, (uint32_t) SAADC_IRQHandler);
 
     return (0);
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/drivers/adc/include/adc/adc.h
----------------------------------------------------------------------
diff --git a/drivers/adc/include/adc/adc.h b/drivers/adc/include/adc/adc.h
index 01c60ea..01727c0 100644
--- a/drivers/adc/include/adc/adc.h
+++ b/drivers/adc/include/adc/adc.h
@@ -24,20 +24,253 @@
 
 struct adc_dev;
 
-typedef int (*adc_config_func_t)(struct adc_dev *dev, void *);
+/**
+ * Types of ADC events passed to the ADC driver.
+ */
+typedef enum {
+    /* This event represents the result of an ADC run. */
+    ADC_EVENT_RESULT = 0
+} adc_event_type_t;
+
+/**
+ * Event handler for ADC events that are processed in asynchronous mode.
+ *
+ * @param The ADC device being processed
+ * @param The argument data passed to adc_set_result_handler()
+ * @param The event type
+ * @param The buffer containing event data
+ * @param The size in bytes of that buffer.
+ *
+ * @return 0 on success, non-zero error code on failure
+ */
+typedef int (*adc_event_handler_func_t)(struct adc_dev *, void *,
+    adc_event_type_t, void *, int);
+
+/**
+ * Configure an ADC channel for this ADC device.  This is implemented
+ * by the HW specific drivers.
+ *
+ * @param The ADC device to configure
+ * @param The channel number to configure
+ * @param An opaque blob containing HW specific configuration.
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+typedef int (*adc_configure_channel_func_t)(struct adc_dev *dev, uint8_t,
+        void *);
+
+/**
+ * Trigger a sample on the ADC device asynchronously.  This is implemented
+ * by the HW specific drivers.
+ *
+ * @param The ADC device to sample
+ *
+ * @return 0 on success, non-zero error code on failure
+ */
 typedef int (*adc_sample_func_t)(struct adc_dev *);
 
+/**
+ * Blocking read of an ADC channel.  This is implemented by the HW specific
+ * drivers.
+ *
+ * @param The ADC device to perform the blocking read on
+ * @param The channel to read
+ * @param The result to put the ADC reading into
+ *
+ * @return 0 on success, non-zero error code on failure
+ */
+typedef int (*adc_read_channel_func_t)(struct adc_dev *, uint8_t, int *);
+
+/**
+ * Set the buffer(s) to read ADC results into for non-blocking reads.  This
+ * is implemented by the HW specific drivers.
+ *
+ * @param The ADC device to read results into
+ * @param The primary buffer to read results into
+ * @param The secondary buffer to read results into (for cases where
+ *        DMA'ing occurs, and secondary buffer can be used while primary
+ *        is being processed.)
+ * @param The length of both buffers in number of bytes
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+typedef int (*adc_buf_set_func_t)(struct adc_dev *, void *, void *, int);
+
+/**
+ * Release a buffer for an ADC device, allowing the driver to re-use it for
+ * DMA'ing data.
+ *
+ * @param The ADC device to release the buffer to
+ * @param A pointer to the buffer to release
+ * @param The length of the buffer being released.
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+typedef int (*adc_buf_release_func_t)(struct adc_dev *, void *, int);
+
+/**
+ * Read the next entry from an ADC buffer as a integer
+ *
+ * @param The ADC device to read the entry from
+ * @param The buffer to read the entry from
+ * @param The total length of the buffer
+ * @param The entry number to read from the buffer
+ * @param The result to put the entry into
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+typedef int (*adc_buf_read_func_t)(struct adc_dev *, void *, int, int, int *);
+
+/**
+ * Get the size of a buffer
+ *
+ * @param The ADC device to get the buffer size from
+ * @param The number of channels in the buffer
+ * @param The number of samples in the buffer
+ *
+ * @return The size of the buffer
+ */
+typedef int (*adc_buf_size_func_t)(struct adc_dev *, int, int);
+
 struct adc_driver_funcs {
-    adc_config_func_t af_config;
+    adc_configure_channel_func_t af_configure_channel;
     adc_sample_func_t af_sample;
+    adc_read_channel_func_t af_read_channel;
+    adc_buf_set_func_t af_set_buffer;
+    adc_buf_release_func_t af_release_buffer;
+    adc_buf_read_func_t af_read_buffer;
+    adc_buf_size_func_t af_size_buffer;
+};
+
+struct adc_chan_config {
+    uint16_t c_refmv;
+    uint8_t c_res;
+    uint8_t c_configured;
 };
 
 struct adc_dev {
     struct os_dev ad_dev;
+    struct os_mutex ad_lock;
     struct adc_driver_funcs ad_funcs;
+    struct adc_chan_config *ad_chans;
+    int ad_chan_count;
+    adc_event_handler_func_t ad_event_handler_func;
+    void *ad_event_handler_arg;
 };
 
-#define adc_sample(__dev) ((__dev)->ad_funcs.af_sample((__dev)))
-#define adc_configure(__dev, __b) ((__dev)->ad_funcs.af_configure((__dev), 
(__b)))
+int adc_chan_config(struct adc_dev *, uint8_t, void *);
+int adc_chan_read(struct adc_dev *, uint8_t, int *);
+int adc_event_handler_set(struct adc_dev *, adc_event_handler_func_t,
+        void *);
+
+/**
+ * Sample the device specified by dev.  This is used in non-blocking mode
+ * to generate samples into the event buffer.
+ *
+ * @param dev The device to sample
+ *
+ * @return 0 on success, non-zero on failure
+ */
+static inline int
+adc_sample(struct adc_dev *dev)
+{
+    return (dev->ad_funcs.af_sample(dev));
+}
+
+/**
+ * Set a result buffer to store data into.  Optionally, provide a
+ * second buffer to continue writing data into as the first buffer
+ * fills up.  Both buffers must be the same size.
+ *
+ * @param dev The ADC device to set the buffer for
+ * @param buf1 The first buffer to spool data into
+ * @param buf2 The second buffer to spool data into, while the first
+ *             buffer is being processed.  If NULL is provided, it's
+ *             unused.
+ * @param buf_len The length of both buffers, in bytes.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+static inline int
+adc_buf_set(struct adc_dev *dev, void *buf1, void *buf2,
+        int buf_len)
+{
+    return (dev->ad_funcs.af_set_buffer(dev, buf1, buf2, buf_len));
+}
+
+/**
+ * Release a result buffer on the ADC device, and allow for it to be
+ * re-used for DMA'ing results.
+ *
+ * @param dev The device to release the buffer for
+ * @param buf The buffer to release
+ * @param buf_len The length of the buffer being released.
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+static inline int
+adc_buf_release(struct adc_dev *dev, void *buf, int buf_len)
+{
+    return (dev->ad_funcs.af_release_buffer(dev, buf, buf_len));
+}
+
+/**
+ * Read an entry from an ADC buffer
+ *
+ * @param dev The device that the entry is being read from
+ * @param buf The buffer that we're reading the entry from
+ * @param buf_len The length of the buffer we're reading the entry from
+ * @param off The entry number to read from the buffer
+ * @param result A pointer to the result to store the data in
+ *
+ * @return 0 on success, non-zero error code on failure
+ */
+static inline int
+adc_buf_read(struct adc_dev *dev, void *buf, int buf_len, int entry,
+        int *result)
+{
+    return (dev->ad_funcs.af_read_buffer(dev, buf, buf_len, entry, result));
+}
+
+/**
+ * Return the size of an ADC buffer
+ *
+ * @param dev The ADC device to return the buffer size from
+ * @param channels The number of channels for these samples
+ * @param samples The number of SAMPLES on this ADC device
+ *
+ * @return The size of the resulting buffer
+ */
+static inline int
+adc_buf_size(struct adc_dev *dev, int chans, int samples)
+{
+    return (dev->ad_funcs.af_size_buffer(dev, chans, samples));
+}
+
+/**
+ * Take an ADC result and convert it to millivolts.
+ *
+ * @param dev The ADC dev to convert the result on
+ * @param cnum The channel number to convert the result from
+ * @param val The ADC value to convert to millivolts
+ *
+ * @return The convert value in millivolts
+ */
+static inline int
+adc_result_mv(struct adc_dev *dev, uint8_t cnum, int val)
+{
+    int res;
+    int refmv;
+    int ret;
+
+    refmv = (int) dev->ad_chans[cnum].c_refmv;
+    res = (int) dev->ad_chans[cnum].c_res;
+
+    ret = val * refmv;
+    ret += (1 << (res - 2));
+    ret = ret >> res;
+
+    return (ret);
+}
 
 #endif /* __ADC_H__ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/drivers/adc/pkg.yml
----------------------------------------------------------------------
diff --git a/drivers/adc/pkg.yml b/drivers/adc/pkg.yml
index 264adca..8b4a968 100644
--- a/drivers/adc/pkg.yml
+++ b/drivers/adc/pkg.yml
@@ -22,6 +22,9 @@ pkg.description: ADC driver interfaces
 pkg.author: "Apache Mynewt <[email protected]>"
 pkg.homepage: "http://mynewt.apache.org/";
 pkg.keywords:
+pkg.req_apis: 
+    - ADC_HW_IMPL
+
 pkg.deps.TEST:
    - hw/hal
    - libs/testutil

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/drivers/adc/src/adc.c
----------------------------------------------------------------------
diff --git a/drivers/adc/src/adc.c b/drivers/adc/src/adc.c
index 5198538..5eb3440 100644
--- a/drivers/adc/src/adc.c
+++ b/drivers/adc/src/adc.c
@@ -19,4 +19,71 @@
 
 
 #include <adc/adc.h>
+#include <errno.h>
+#include <assert.h>
+
+/**
+ * Configure a channel on the ADC device.
+ *
+ * @param dev The device to configure
+ * @param cnum The channel number to configure
+ * @param data Driver specific configuration data for this channel.
+ *
+ * @return 0 on success, non-zero error code on failure.
+ */
+int
+adc_chan_config(struct adc_dev *dev, uint8_t cnum, void *data)
+{
+    assert(dev->ad_funcs.af_configure_channel != NULL);
+
+    if (cnum > dev->ad_chan_count) {
+        return (EINVAL);
+    }
+
+    return (dev->ad_funcs.af_configure_channel(dev, cnum, data));
+}
+
+/**
+ * Blocking read of an ADC channel.
+ *
+ * @param dev The ADC device to read
+ * @param cnum The channel number to read from that device
+ * @param result Where to put the result of the read
+ *
+ * @return 0 on success, non-zero on error
+ */
+int
+adc_chan_read(struct adc_dev *dev, uint8_t cnum, int *result)
+{
+    assert(dev->ad_funcs.af_read_channel != NULL);
+
+    if (cnum > dev->ad_chan_count) {
+        return (EINVAL);
+    }
+
+    if (!dev->ad_chans[cnum].c_configured) {
+        return (EINVAL);
+    }
+
+    return (dev->ad_funcs.af_read_channel(dev, cnum, result));
+}
+
+/**
+ * Set an event handler.  This handler is called for all ADC events.
+ *
+ * @param dev The ADC device to set the event handler for
+ * @param func The event handler function to call
+ * @param arg The argument to pass the event handler function
+ *
+ * @return 0 on success, non-zero on failure
+ */
+int
+adc_event_handler_set(struct adc_dev *dev, adc_event_handler_func_t func,
+        void *arg)
+{
+    dev->ad_event_handler_func = func;
+    dev->ad_event_handler_arg = arg;
+
+    return (0);
+}
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/hw/bsp/nrf52dk/src/hal_bsp.c
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/src/hal_bsp.c b/hw/bsp/nrf52dk/src/hal_bsp.c
index 2f0b4d9..41b4760 100644
--- a/hw/bsp/nrf52dk/src/hal_bsp.c
+++ b/hw/bsp/nrf52dk/src/hal_bsp.c
@@ -6,7 +6,7 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *  http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
@@ -64,3 +64,9 @@ bsp_core_dump(int *area_cnt)
     *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]);
     return dump_cfg;
 }
+
+uint16_t
+bsp_get_refmv(void)
+{
+    return (2800);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/hw/hal/include/hal/hal_bsp.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_bsp.h b/hw/hal/include/hal/hal_bsp.h
index e2831eb..e41e4bf 100644
--- a/hw/hal/include/hal/hal_bsp.h
+++ b/hw/hal/include/hal/hal_bsp.h
@@ -65,6 +65,8 @@ const struct bsp_mem_dump *bsp_core_dump(int *area_cnt);
 #define BSP_MAX_ID_LEN  32
 int bsp_hw_id(uint8_t *id, int max_len);
 
+uint16_t bsp_get_refmv(void);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/hw/mcu/nordic/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/pkg.yml b/hw/mcu/nordic/pkg.yml
index 5067fc7..4c84dca 100644
--- a/hw/mcu/nordic/pkg.yml
+++ b/hw/mcu/nordic/pkg.yml
@@ -52,7 +52,7 @@ pkg.src_dirs:
     - "src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/"
     - "src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/util/"
 
-pkg.cflags: -std=gnu99 
+pkg.cflags: -std=gnu99 -DNRF52_PAN_28
 
 pkg.deps: 
     - hw/hal 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/libs/os/include/os/os_dev.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os_dev.h b/libs/os/include/os/os_dev.h
index 850eee1..d7e2680 100644
--- a/libs/os/include/os/os_dev.h
+++ b/libs/os/include/os/os_dev.h
@@ -48,8 +48,9 @@ struct os_dev;
 #define OS_DEV_STATUS_INITING (1 << 1)
 #define OS_DEV_STATUS_READY   (1 << 2)
 
-typedef int (*os_dev_init_func_t)(struct os_dev *);
-typedef int (*os_dev_open_func_t)(struct os_dev *);
+typedef int (*os_dev_init_func_t)(struct os_dev *, void *);
+typedef int (*os_dev_open_func_t)(struct os_dev *, uint32_t,
+        void *);
 typedef int (*os_dev_close_func_t)(struct os_dev *);
 
 struct os_dev_handlers {
@@ -59,11 +60,11 @@ struct os_dev_handlers {
 
 /*
  * Device structure.
- *
  */
 struct os_dev {
     struct os_dev_handlers od_handlers;
     os_dev_init_func_t od_init;
+    void *od_init_arg;
     uint8_t od_stage;
     uint8_t od_priority;
     uint8_t od_init_flags;
@@ -77,10 +78,9 @@ struct os_dev {
     (__dev)->od_handlers.od_close = (__close);
 
 int os_dev_create(struct os_dev *dev, char *name, uint8_t stage,
-        uint8_t priority, os_dev_init_func_t od_init);
+        uint8_t priority, os_dev_init_func_t od_init, void *arg);
 int os_dev_initialize_all(uint8_t stage);
-struct os_dev *os_dev_lookup(char *name);
-int os_dev_open(struct os_dev *dev);
+struct os_dev *os_dev_open(char *devname, uint32_t timo, void *arg);
 int os_dev_close(struct os_dev *dev);
 
 #endif /* _OS_DEV_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/30da4658/libs/os/src/os_dev.c
----------------------------------------------------------------------
diff --git a/libs/os/src/os_dev.c b/libs/os/src/os_dev.c
index 979db39..75d61b0 100644
--- a/libs/os/src/os_dev.c
+++ b/libs/os/src/os_dev.c
@@ -28,7 +28,7 @@ static STAILQ_HEAD(, os_dev) g_os_dev_list =
 
 static int
 os_dev_init(struct os_dev *dev, char *name, uint8_t stage,
-        uint8_t priority, os_dev_init_func_t od_init)
+        uint8_t priority, os_dev_init_func_t od_init, void *arg)
 {
     dev->od_name = name;
     dev->od_stage = stage;
@@ -42,8 +42,11 @@ os_dev_init(struct os_dev *dev, char *name, uint8_t stage,
 }
 
 /**
- * Add this device to the kernel.  This function adds the
- * device to the OS
+ * Add the device to the device tree.  This is a private function.
+ *
+ * @param dev The device to add to the device tree.
+ *
+ * @return 0 on success, non-zero on failure.
  */
 static int
 os_dev_add(struct os_dev *dev)
@@ -57,7 +60,8 @@ os_dev_add(struct os_dev *dev)
     }
 
     /* Add devices to the list, sorted first by stage, then by
-     * priority.
+     * priority.  Keep sorted in this order for initialization
+     * stage.
      */
     cur_dev = NULL;
     STAILQ_FOREACH(cur_dev, &g_os_dev_list, od_next) {
@@ -79,13 +83,28 @@ os_dev_add(struct os_dev *dev)
     return (0);
 }
 
+
+/**
+ * Create a new device in the kernel.
+ *
+ * @param dev The device to create.
+ * @param name The name of the device to create.
+ * @param stage The stage to initialize that device to.
+ * @param priority The priority of initializing that device
+ * @param od_init The initialization function to call for this
+ *                device.
+ * @param arg The argument to provide this device initialization
+ *            function.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int
 os_dev_create(struct os_dev *dev, char *name, uint8_t stage,
-        uint8_t priority, os_dev_init_func_t od_init)
+        uint8_t priority, os_dev_init_func_t od_init, void *arg)
 {
     int rc;
 
-    rc = os_dev_init(dev, name, stage, priority, od_init);
+    rc = os_dev_init(dev, name, stage, priority, od_init, arg);
     if (rc != 0) {
         goto err;
     }
@@ -100,7 +119,13 @@ err:
     return (rc);
 }
 
-
+/**
+ * Initialize all devices for a given state.
+ *
+ * @param stage The stage to initialize.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int
 os_dev_initialize_all(uint8_t stage)
 {
@@ -109,10 +134,13 @@ os_dev_initialize_all(uint8_t stage)
 
     STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
         if (dev->od_stage == stage) {
-            rc = dev->od_init(dev);
-            if (dev->od_init_flags & OS_DEV_INIT_F_CRITICAL &&
-                    rc != 0) {
-                goto err;
+            rc = dev->od_init(dev, dev->od_init_arg);
+            if (rc != 0) {
+                if (dev->od_init_flags & OS_DEV_INIT_F_CRITICAL) {
+                    goto err;
+                }
+            } else {
+                dev->od_status |= OS_DEV_STATUS_READY;
             }
         }
     }
@@ -122,7 +150,14 @@ err:
     return (rc);
 }
 
-struct os_dev *
+/**
+ * Lookup a device by name, internal function only.
+ *
+ * @param name The name of the device to look up.
+ *
+ * @return A pointer to the device corresponding to name, or NULL if not found.
+ */
+static struct os_dev *
 os_dev_lookup(char *name)
 {
     struct os_dev *dev;
@@ -136,29 +171,50 @@ os_dev_lookup(char *name)
     return (dev);
 }
 
-
-int
-os_dev_open(struct os_dev *dev)
+/**
+ * Open a device.
+ *
+ * @param dev The device to open
+ * @param timo The timeout to open the device, if not specified.
+ * @param arg The argument to the device open() call.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+struct os_dev *
+os_dev_open(char *devname, uint32_t timo, void *arg)
 {
+    struct os_dev *dev;
     int rc;
 
+    dev = os_dev_lookup(devname);
+    if (dev == NULL) {
+        return (NULL);
+    }
+
     /* Device is not ready to be opened. */
     if ((dev->od_status & OS_DEV_STATUS_READY) == 0) {
-        return (OS_EINVAL);
+        return (NULL);
     }
 
     if (dev->od_handlers.od_open) {
-        rc = dev->od_handlers.od_open(dev);
+        rc = dev->od_handlers.od_open(dev, timo, arg);
         if (rc != 0) {
             goto err;
         }
     }
 
-    return (0);
+    return (dev);
 err:
-    return (rc);
+    return (NULL);
 }
 
+/**
+ * Close a device.
+ *
+ * @param dev The device to close
+ *
+ * @return 0 on success, non-zero on failure.
+ */
 int
 os_dev_close(struct os_dev *dev)
 {

Reply via email to