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) {
