diff --git a/hal/targets.json b/hal/targets.json
index 5d6e036bdf..3c48cbfd93 100644
--- a/hal/targets.json
+++ b/hal/targets.json
@@ -1375,7 +1375,7 @@
         "supported_form_factors": ["ARDUINO"],
         "inherits": ["MCU_NRF51_32K"],
         "progen": {"target": "nrf51-dk"},
-        "device_has": ["ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH"]
+        "device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH"]
     },
     "NRF51_DK_BOOT": {
         "supported_form_factors": ["ARDUINO"],
diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/analogin_api.c b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/analogin_api.c
index 44d5342831..ac349e0d36 100644
--- a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/analogin_api.c
+++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/analogin_api.c
@@ -12,17 +12,18 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */
+ */ 
 #include "mbed_assert.h"
 #include "analogin_api.h"
 #include "cmsis.h"
 #include "pinmap.h"
+#include "nrf_drv_adc.h"
 
 #ifdef DEVICE_ANALOGIN
 
-#define ANALOGIN_MEDIAN_FILTER      1
-#define ADC_10BIT_RANGE             0x3FF
-#define ADC_RANGE    ADC_10BIT_RANGE
+
+#define ADC_10BIT_RANGE  0x3FF
+#define ADC_RANGE        ADC_10BIT_RANGE
 
 static const PinMap PinMap_ADC[] = {
     {p1, ADC0_0, 4},
@@ -38,47 +39,42 @@ static const PinMap PinMap_ADC[] = {
     {NC, NC, 0}
 };
 
+
 void analogin_init(analogin_t *obj, PinName pin)
 {
-    int analogInputPin = 0;
-    const PinMap *map  = PinMap_ADC;
-
-    obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); //(NRF_ADC_Type *)
+    obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
     MBED_ASSERT(obj->adc != (ADCName)NC);
 
-    while (map->pin != NC) {
-        if (map->pin == pin) {
-            analogInputPin = map->function;
-            break;
-        }
-        map++;
-    }
-    obj->adc_pin = (uint8_t)analogInputPin;
-
-    NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
-    NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
-                      (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
-                      (ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) |
-                      (analogInputPin << ADC_CONFIG_PSEL_Pos) |
-                      (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+    uint32_t pinFunc = pinmap_function(pin, PinMap_ADC);
+    MBED_ASSERT(pinFunc != (uint32_t)NC);
+    
+    obj->adc_pin =  pinFunc;
+    
+    ret_code_t ret_code;
+                                              // p_config, event_handler
+    ret_code = nrf_drv_adc_init(NULL , NULL); // select blocking mode
+    MBED_ASSERT(ret_code == NRF_SUCCESS);
 }
 
 uint16_t analogin_read_u16(analogin_t *obj)
 {
-    NRF_ADC->CONFIG     &= ~ADC_CONFIG_PSEL_Msk;
-    NRF_ADC->CONFIG     |= obj->adc_pin << ADC_CONFIG_PSEL_Pos;
-    NRF_ADC->EVENTS_END  = 0;
-    NRF_ADC->TASKS_START = 1;
+    nrf_adc_value_t adc_value;
+       
+    nrf_drv_adc_channel_t adc_channel = NRF_DRV_ADC_DEFAULT_CHANNEL(obj->adc_pin);
+    
 
-    while (!NRF_ADC->EVENTS_END) {
-    }
-
-    return (uint16_t)NRF_ADC->RESULT; // 10 bit
+    ret_code_t ret_code;
+    
+    ret_code = nrf_drv_adc_sample_convert( &adc_channel, &adc_value);
+    MBED_ASSERT(ret_code == NRF_SUCCESS);
+    
+    return adc_value;
 }
 
 float analogin_read(analogin_t *obj)
 {
     uint16_t value = analogin_read_u16(obj);
+
     return (float)value * (1.0f / (float)ADC_RANGE);
 }
 
diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/pwmout_api.c b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/pwmout_api.c
index 063b94d37b..2b4d27f3c6 100644
--- a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/pwmout_api.c
+++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/pwmout_api.c
@@ -138,7 +138,7 @@ void pwmout_init(pwmout_t *obj, PinName pin)
 
 void pwmout_free(pwmout_t *obj)
 {
-    MBED_ASSERT(obj->pwm != (PWMName)NC);
+    MBED_ASSERT(obj->pwm_name != (PWMName)NC);
     MBED_ASSERT(obj->pwm_channel < PWM_CHANNELS_PER_INSTANCE);
 
     pwm_t * pwm = (pwm_t *) obj->pwm_struct;
@@ -160,7 +160,8 @@ void pwmout_write(pwmout_t *obj, float value)
     if (value > 1.0f) {
         value = 1.0f;
     }
-    uint16_t ticks = (uint16_t)((float)app_pwm_cycle_ticks_get(pwm->instance) * value);
+
+    app_pwm_channel_duty_set(pwm->instance, obj->pwm_channel, (app_pwm_duty_t)(value * 100.0f) );
 }
 
 float pwmout_read(pwmout_t *obj)
diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/sdk/drivers_nrf/adc/nrf_drv_adc.c b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/sdk/drivers_nrf/adc/nrf_drv_adc.c
new file mode 100644
index 0000000000..1c4a0f163b
--- /dev/null
+++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/sdk/drivers_nrf/adc/nrf_drv_adc.c
@@ -0,0 +1,253 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include "nrf_drv_adc.h"
+#include "nrf_drv_common.h"
+#include "nrf_assert.h"
+#include "app_util_platform.h"
+#include "app_util.h"
+
+typedef struct
+{
+    nrf_drv_adc_event_handler_t event_handler;
+    nrf_drv_adc_channel_t     * p_head;
+    nrf_drv_adc_channel_t     * p_current_conv;
+    nrf_adc_value_t           * p_buffer;
+    uint8_t                     size;
+    uint8_t                     idx;
+    nrf_drv_state_t             state;
+} adc_cb_t;
+
+static adc_cb_t m_cb;
+static const nrf_drv_adc_config_t m_default_config = NRF_DRV_ADC_DEFAULT_CONFIG;
+
+ret_code_t nrf_drv_adc_init(nrf_drv_adc_config_t const * p_config,
+                            nrf_drv_adc_event_handler_t  event_handler)
+{
+    if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
+    {
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    nrf_adc_event_clear(NRF_ADC_EVENT_END);
+    if (event_handler)
+    {
+        if (!p_config)
+        {
+            p_config = (nrf_drv_adc_config_t *)&m_default_config;
+        }
+        nrf_drv_common_irq_enable(ADC_IRQn, p_config->interrupt_priority);
+    }
+    m_cb.event_handler = event_handler;
+    m_cb.state = NRF_DRV_STATE_INITIALIZED;
+
+    return NRF_SUCCESS;
+}
+
+void nrf_drv_adc_uninit(void)
+{
+    m_cb.p_head = NULL;
+    nrf_drv_common_irq_disable(ADC_IRQn);
+    nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
+    nrf_adc_task_trigger(NRF_ADC_TASK_STOP);
+
+    m_cb.state = NRF_DRV_STATE_UNINITIALIZED;
+}
+
+void nrf_drv_adc_channel_enable(nrf_drv_adc_channel_t * const p_channel)
+{
+    ASSERT(mp_state == NRF_DRV_STATE_INITIALIZED);
+    ASSERT(!is_address_from_stack(p_channel));
+
+    p_channel->p_next = NULL;
+    if (m_cb.p_head == NULL)
+    {
+        m_cb.p_head = p_channel;
+    }
+    else
+    {
+        nrf_drv_adc_channel_t * p_curr_channel = m_cb.p_head;
+        while (p_curr_channel->p_next != NULL)
+        {
+            ASSERT(p_channel != p_curr_channel);
+            p_curr_channel = p_curr_channel->p_next;
+        }
+        p_curr_channel->p_next = p_channel;
+    }
+}
+
+void nrf_drv_adc_channel_disable(nrf_drv_adc_channel_t * const p_channel)
+{
+    ASSERT(mp_state == NRF_DRV_STATE_INITIALIZED);
+    ASSERT(m_cb.p_head);
+
+    nrf_drv_adc_channel_t * p_curr_channel = m_cb.p_head;
+    nrf_drv_adc_channel_t * p_prev_channel = NULL;
+    while(p_curr_channel != p_channel)
+    {
+        p_prev_channel = p_curr_channel;
+        p_curr_channel = p_curr_channel->p_next;
+        ASSERT(p_curr_channel == NULL);
+    }
+    if (p_prev_channel)
+    {
+        p_prev_channel->p_next = p_curr_channel->p_next;
+    }
+    else
+    {
+        m_cb.p_head = p_curr_channel->p_next;
+    }
+}
+
+void nrf_drv_adc_sample(void)
+{
+    ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
+    ASSERT(!nrf_adc_is_busy());
+    nrf_adc_start();
+}
+
+ret_code_t nrf_drv_adc_sample_convert(nrf_drv_adc_channel_t const * const p_channel, 
+                                      nrf_adc_value_t * p_value)
+{
+    ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
+    if(m_cb.state == NRF_DRV_STATE_POWERED_ON)
+    {
+        return NRF_ERROR_BUSY;
+    }
+    else
+    {
+        m_cb.state = NRF_DRV_STATE_POWERED_ON;
+
+        nrf_adc_config_set(p_channel->config.data);
+        nrf_adc_enable();
+        nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
+        nrf_adc_start();
+        if (p_value)
+        {
+            while(!nrf_adc_event_check(NRF_ADC_EVENT_END)) {}
+            nrf_adc_event_clear(NRF_ADC_EVENT_END);
+            *p_value = (nrf_adc_value_t)nrf_adc_result_get();
+            nrf_adc_disable();
+
+            m_cb.state = NRF_DRV_STATE_INITIALIZED;
+        }
+        else
+        {
+            ASSERT(m_cb.event_handler);
+            m_cb.p_buffer = NULL;
+            nrf_adc_int_enable(NRF_ADC_INT_END_MASK);
+        }
+        return NRF_SUCCESS;
+    }
+}
+
+static bool adc_sample_process()
+{
+    nrf_adc_event_clear(NRF_ADC_EVENT_END);
+    nrf_adc_disable();
+    m_cb.p_buffer[m_cb.idx] = (nrf_adc_value_t)nrf_adc_result_get();
+    m_cb.idx++;
+    if (m_cb.idx < m_cb.size)
+    {
+        bool task_trigger = false;
+        if (m_cb.p_current_conv->p_next == NULL)
+        {
+            m_cb.p_current_conv = m_cb.p_head;
+        }
+        else
+        {
+            m_cb.p_current_conv = m_cb.p_current_conv->p_next;
+            task_trigger = true;
+        }
+        nrf_adc_config_set(m_cb.p_current_conv->config.data);
+        nrf_adc_enable();
+        if (task_trigger)
+        {
+            //nrf_adc_start();
+            nrf_adc_task_trigger(NRF_ADC_TASK_START);
+        }
+        return false;
+    }
+    else
+    {
+        return true;
+    }
+}
+
+ret_code_t nrf_drv_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size)
+{
+    ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
+    if(m_cb.state == NRF_DRV_STATE_POWERED_ON)
+    {
+        return NRF_ERROR_BUSY;
+    }
+    else
+    {
+        m_cb.state          = NRF_DRV_STATE_POWERED_ON;
+        m_cb.p_current_conv = m_cb.p_head;
+        m_cb.size           = size;
+        m_cb.idx            = 0;
+        m_cb.p_buffer       = buffer;
+        nrf_adc_config_set(m_cb.p_current_conv->config.data);
+        nrf_adc_event_clear(NRF_ADC_EVENT_END);
+        nrf_adc_enable();
+        if (m_cb.event_handler)
+        {
+            nrf_adc_int_enable(NRF_ADC_INT_END_MASK);
+        }
+        else
+        {
+            while(1)
+            {
+                while(!nrf_adc_event_check(NRF_ADC_EVENT_END)){}
+
+                if (adc_sample_process())
+                {
+                    m_cb.state = NRF_DRV_STATE_INITIALIZED;
+                    break;
+                }
+            }
+        }
+        return NRF_SUCCESS;
+    }
+}
+
+bool nrf_drv_adc_is_busy(void)
+{
+    ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
+    return (m_cb.state == NRF_DRV_STATE_POWERED_ON) ? true : false;
+}
+
+void ADC_IRQHandler(void)
+{
+    if (m_cb.p_buffer == NULL)
+    {
+        nrf_adc_event_clear(NRF_ADC_EVENT_END);
+        nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
+        nrf_adc_disable();
+        nrf_drv_adc_evt_t evt;
+        evt.type = NRF_DRV_ADC_EVT_SAMPLE;
+        evt.data.sample.sample = (nrf_adc_value_t)nrf_adc_result_get();
+        m_cb.state = NRF_DRV_STATE_INITIALIZED;
+        m_cb.event_handler(&evt);
+    }
+    else if (adc_sample_process())
+    {
+        nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
+        nrf_drv_adc_evt_t evt;
+        evt.type = NRF_DRV_ADC_EVT_DONE;
+        evt.data.done.p_buffer = m_cb.p_buffer;
+        evt.data.done.size     = m_cb.size;
+        m_cb.state = NRF_DRV_STATE_INITIALIZED;
+        m_cb.event_handler(&evt);
+    }
+}
diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/sdk/drivers_nrf/adc/nrf_drv_adc.h b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/sdk/drivers_nrf/adc/nrf_drv_adc.h
new file mode 100644
index 0000000000..fddd43d2f6
--- /dev/null
+++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF51822/sdk/drivers_nrf/adc/nrf_drv_adc.h
@@ -0,0 +1,297 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include "nrf_adc.h"
+#include "nrf_drv_config.h"
+#include "sdk_errors.h"
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup nrf_adc ADC HAL and driver
+ * @ingroup nrf_drivers
+ * @brief Analog-to-digital converter (ADC) APIs.
+ * @details The ADC HAL provides basic APIs for accessing the registers of the analog-to-digital converter.
+ * The ADC driver provides APIs on a higher level.
+ *
+ * @defgroup nrf_adc_drv ADC driver
+ * @{
+ * @ingroup nrf_adc
+ * @brief Analog-to-digital converter (ADC) driver. 
+ */
+
+
+/**
+ * @brief Driver event types.
+ */
+typedef enum
+{
+    NRF_DRV_ADC_EVT_DONE,    ///< Event generated when the buffer is filled with samples.
+    NRF_DRV_ADC_EVT_SAMPLE,  ///< Event generated when the requested channel is sampled.
+} nrf_drv_adc_evt_type_t;
+
+typedef int16_t nrf_adc_value_t;
+
+/**
+ * @brief Analog-to-digital converter driver DONE event.
+ */
+typedef struct
+{
+    nrf_adc_value_t *        p_buffer; ///< Pointer to buffer with converted samples.
+    uint16_t                 size;     ///< Number of samples in the buffer.
+} nrf_drv_adc_done_evt_t;
+
+/**
+ * @brief Analog-to-digital converter driver SAMPLE event.
+ */
+typedef struct
+{
+    nrf_adc_value_t   sample; ///< Converted sample.
+} nrf_drv_adc_sample_evt_t;
+
+/**
+ * @brief Analog-to-digital converter driver event.
+ */
+typedef struct
+{
+    nrf_drv_adc_evt_type_t type;  ///< Event type.
+    union
+    {
+        nrf_drv_adc_done_evt_t   done;   ///< Data for DONE event.
+        nrf_drv_adc_sample_evt_t sample; ///< Data for SAMPLE event.
+    } data;
+} nrf_drv_adc_evt_t;
+
+/**@brief Macro for initializing the ADC channel with the default configuration. */
+#define NRF_DRV_ADC_DEFAULT_CHANNEL(analog_input)          \
+ {{{                                                       \
+    .resolution = NRF_ADC_CONFIG_RES_10BIT,                \
+    .input      = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE, \
+    .reference  = NRF_ADC_CONFIG_REF_VBG,                  \
+    .ain        = (analog_input)                           \
+ }}, NULL}
+
+/**
+ * @brief ADC channel configuration.
+ *
+ * @note The bit fields reflect bit fields in the ADC CONFIG register.
+ */
+typedef struct 
+{
+    uint32_t resolution        :2; ///< 8-10 bit resolution.
+    uint32_t input             :3; ///< Input selection and scaling.
+    uint32_t reference         :2; ///< Reference source.
+    uint32_t reserved          :1; ///< Unused bit fields.
+    uint32_t ain               :8; ///< Analog input.
+    uint32_t external_reference:2; ///< Eternal reference source.
+}nrf_drv_adc_channel_config_t;
+
+// Forward declaration of the nrf_drv_adc_channel_t type.
+typedef struct nrf_drv_adc_channel_s nrf_drv_adc_channel_t;
+
+/**
+ * @brief ADC channel.
+ *
+ * This structure is defined by the user and used by the driver. Therefore, it should
+ * not be defined on the stack as a local variable.
+ */
+struct nrf_drv_adc_channel_s
+{
+    union
+    {
+        nrf_drv_adc_channel_config_t config; ///< Channel configuration.
+        uint32_t data;                       ///< Raw value.
+    } config;
+    nrf_drv_adc_channel_t      * p_next;     ///< Pointer to the next enabled channel (for internal use).
+};
+
+/**
+ * @brief ADC configuration.
+ */
+typedef struct 
+{
+    uint8_t interrupt_priority;              ///< Priority of ADC interrupt.
+} nrf_drv_adc_config_t;
+
+/** @brief ADC default configuration. */
+#define NRF_DRV_ADC_DEFAULT_CONFIG                \
+{                                                 \
+    .interrupt_priority = ADC_CONFIG_IRQ_PRIORITY \
+}
+
+/**
+ * @brief User event handler prototype.
+ *
+ * This function is called when the requested number of samples has been processed.
+ *
+ * @param p_event Event.
+ */
+typedef void (*nrf_drv_adc_event_handler_t)(nrf_drv_adc_evt_t const * p_event);
+
+/**
+ * @brief Function for initializing the ADC.
+ *
+ * If a valid event handler is provided, the driver is initialized in non-blocking mode.
+ * If event_handler is NULL, the driver works in blocking mode.
+ *
+ * @param[in] p_config Driver configuration.
+ * @param[in] event_handler Event handler provided by the user.
+ *
+ * @retval    NRF_SUCCESS If initialization was successful.
+ * @retval    NRF_ERROR_INVALID_STATE If the driver is already initialized.
+ */
+ret_code_t nrf_drv_adc_init(nrf_drv_adc_config_t const * p_config,
+                            nrf_drv_adc_event_handler_t  event_handler);
+
+/**
+ * @brief Function for uninitializing the ADC.
+ *
+ * This function stops all ongoing conversions and disables all channels.
+ */
+void nrf_drv_adc_uninit(void);
+
+/**
+ * @brief Function for enabling an ADC channel.
+ *
+ * This function configures and enables the channel. When @ref nrf_drv_adc_buffer_convert is
+ * called, all channels that have been enabled with this function are sampled.
+ *
+ * @note The channel instance variable @p p_channel is used by the driver as an item
+ *       in a list. Therefore, it cannot be an automatic variable, and an assertion fails if it is
+ *       an automatic variable (if asserts are enabled).
+ */
+void nrf_drv_adc_channel_enable(nrf_drv_adc_channel_t * const p_channel);
+
+/**
+ * @brief Function for disabling an ADC channel.
+ */
+void nrf_drv_adc_channel_disable(nrf_drv_adc_channel_t * const p_channel);
+
+/**
+ * @brief Function for starting ADC sampling.
+ *
+ * This function triggers single ADC sampling. If more than one channel is enabled, the driver
+ * emulates scanning and all channels are sampled in the order they were enabled.
+ */
+void nrf_drv_adc_sample(void);
+
+/**
+ * @brief Function for executing a single ADC conversion.
+ *
+ * This function selects the desired input and starts a single conversion. If a valid pointer 
+ * is provided for the result, the function blocks until the conversion is completed. Otherwise, the
+ * function returns when the conversion is started, and the result is provided in an event (driver
+ * must be initialized in non-blocking mode otherwise an assertion will fail). The function will fail if
+ * ADC is busy. The channel does not need to be enabled to perform a single conversion.
+ *
+ * @param[in]  p_channel Channel.
+ * @param[out] p_value   Pointer to the location where the result should be placed. Unless NULL is
+ *                       provided, the function is blocking.
+ *
+ * @retval NRF_SUCCESS    If conversion was successful.
+ * @retval NRF_ERROR_BUSY If the ADC driver is busy.
+ */
+ret_code_t nrf_drv_adc_sample_convert(nrf_drv_adc_channel_t const * const p_channel, 
+                                      nrf_adc_value_t * p_value);
+
+/**
+ * @brief Function for converting data to the buffer.
+ *
+ * If the driver is initialized in non-blocking mode, this function returns when the first conversion
+ * is set up. When the buffer is filled, the application is notified by the event handler. If the
+ * driver is initialized in blocking mode, the function returns when the buffer is filled.
+ *
+ * Conversion is done on all enabled channels, but it is not triggered by this
+ * function. This function will prepare the ADC for sampling and then 
+ * wait for the SAMPLE task. Sampling can be triggered manually by the @ref 
+ * nrf_drv_adc_sample function or by PPI using the @ref NRF_ADC_TASK_START task.
+ *
+ * @note If more than one channel is enabled, the function emulates scanning, and 
+ * a single START task will trigger conversion on all enabled channels. For example:
+ * If 3 channels are enabled and the user requests 6 samples, the completion event 
+ * handler will be called after 2 START tasks. 
+ * @note The application must adjust the sampling frequency. The maximum frequency 
+ * depends on the sampling timer and the maximum latency of the ADC interrupt. If 
+ * an interrupt is not handled before the next sampling is triggered, the sample 
+ * will be lost.
+ *
+ * @param[in] buffer Result buffer.
+ * @param[in] size   Buffer size in samples.
+ *
+ * @retval NRF_SUCCESS    If conversion was successful.
+ * @retval NRF_ERROR_BUSY If the driver is busy.
+ */
+ret_code_t nrf_drv_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size);
+
+/**
+ * @brief Function for retrieving the ADC state.
+ *
+ * @retval true  If the ADC is busy.
+ * @retval false If the ADC is ready.
+ */
+bool nrf_drv_adc_is_busy(void);
+
+/**
+ * @brief Function for getting the address of the ADC START task.
+ *
+ * This function is used to get the address of the START task, which can be used to trigger ADC
+ * conversion.
+ *
+ * @return Start task address.
+ */
+__STATIC_INLINE uint32_t nrf_drv_adc_start_task_get(void);
+
+/**
+ * @brief Function for converting a GPIO pin number to an analog input pin mask to be used in
+ *        the ADC channel configuration.
+ *
+ * @param[in]  pin GPIO pin.
+ *
+ * @return     Analog input pin mask. The function returns @ref NRF_ADC_CONFIG_INPUT_DISABLED
+ *             if the specified pin is not an analog input.
+ */
+__STATIC_INLINE nrf_adc_config_input_t nrf_drv_adc_gpio_to_ain(uint32_t pin);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE uint32_t nrf_drv_adc_start_task_get(void)
+{
+    return nrf_adc_task_address_get(NRF_ADC_TASK_START);
+}
+
+__STATIC_INLINE nrf_adc_config_input_t nrf_drv_adc_gpio_to_ain(uint32_t pin)
+{
+    // AIN2 - AIN7
+    if (pin >= 1 && pin <= 6)
+    {
+        return (nrf_adc_config_input_t)(1 << (pin+1));
+    }
+    // AIN0 - AIN1
+    else if (pin >= 26 && pin <= 27)
+    {
+        return (nrf_adc_config_input_t)(1 <<(pin - 26));
+    }
+    else
+    {
+        return NRF_ADC_CONFIG_INPUT_DISABLED;
+    }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/** @} */
diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/hal/nrf_adc.c b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/hal/nrf_adc.c
new file mode 100644
index 0000000000..e408ca7007
--- /dev/null
+++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/hal/nrf_adc.c
@@ -0,0 +1,78 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/**
+ * @file
+ * @brief ADC HAL implementation
+ */
+
+#include "nrf_adc.h"
+
+#ifndef NRF52
+
+/**
+ * @brief Function for configuring ADC.
+ *
+ * This function powers on ADC and configures it. ADC is in DISABLE state after configuration,
+ * so it should be enabled before using it.
+ *
+ * @param[in] config  Requested configuration.
+ */
+void nrf_adc_configure(nrf_adc_config_t * config)
+{
+    uint32_t config_reg = 0;
+
+    config_reg |= ((uint32_t)config->resolution << ADC_CONFIG_RES_Pos) & ADC_CONFIG_RES_Msk;
+    config_reg |= ((uint32_t)config->scaling << ADC_CONFIG_INPSEL_Pos) & ADC_CONFIG_INPSEL_Msk;
+    config_reg |= ((uint32_t)config->reference << ADC_CONFIG_REFSEL_Pos) & ADC_CONFIG_REFSEL_Msk;
+
+    if (config->reference & ADC_CONFIG_EXTREFSEL_Msk)
+    {
+        config_reg |= config->reference & ADC_CONFIG_EXTREFSEL_Msk;
+    }
+
+    /* select input */
+    nrf_adc_input_select(NRF_ADC_CONFIG_INPUT_DISABLED);
+
+    /* set new configuration keeping selected input */
+    NRF_ADC->CONFIG = config_reg | (NRF_ADC->CONFIG & ADC_CONFIG_PSEL_Msk);
+}
+
+
+/**
+ * @brief Blocking function for executing single ADC conversion.
+ *
+ * This function selects the desired input, starts a single conversion,
+ * waits for it to finish, and returns the result.
+ * ADC is left in STOP state, the given input is selected.
+ * This function does not check if ADC is initialized and powered.
+ *
+ * @param[in] input Requested input to be selected.
+ *
+ * @return Conversion result
+ */
+int32_t nrf_adc_convert_single(nrf_adc_config_input_t input)
+{
+    int32_t val;
+
+    nrf_adc_input_select(input);
+    nrf_adc_start();
+
+    while (!nrf_adc_conversion_finished())
+    {
+    }
+    nrf_adc_conversion_event_clean();
+    val = nrf_adc_result_get();
+    nrf_adc_stop();
+    return val;
+}
+#endif
diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/hal/nrf_adc.h b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/hal/nrf_adc.h
new file mode 100644
index 0000000000..c697a22415
--- /dev/null
+++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/sdk/drivers_nrf/hal/nrf_adc.h
@@ -0,0 +1,416 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#ifndef NRF_ADC_H_
+#define NRF_ADC_H_
+
+/**
+ * @defgroup nrf_adc_hal ADC HAL
+ * @{
+ * @ingroup nrf_adc
+ * @brief @tagAPI51 Hardware access layer for managing the analog-to-digital converter (ADC).
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "nrf.h"
+
+#ifndef NRF52
+/**
+ * @enum  nrf_adc_config_resolution_t
+ * @brief Resolution of the analog-to-digital converter.
+ */
+
+/**
+ * @brief ADC interrupts.
+ */
+typedef enum
+{
+    NRF_ADC_INT_END_MASK  = ADC_INTENSET_END_Msk,   /**< ADC interrupt on END event. */
+} nrf_adc_int_mask_t;
+
+typedef enum
+{
+    NRF_ADC_CONFIG_RES_8BIT  = ADC_CONFIG_RES_8bit,  /**< 8 bit resolution. */
+    NRF_ADC_CONFIG_RES_9BIT  = ADC_CONFIG_RES_9bit,  /**< 9 bit resolution. */
+    NRF_ADC_CONFIG_RES_10BIT = ADC_CONFIG_RES_10bit, /**< 10 bit resolution. */
+} nrf_adc_config_resolution_t;
+
+
+/**
+ * @enum nrf_adc_config_scaling_t
+ * @brief Scaling factor of the analog-to-digital conversion.
+ */
+typedef enum
+{
+    NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE  = ADC_CONFIG_INPSEL_AnalogInputNoPrescaling,        /**< Full scale input. */
+    NRF_ADC_CONFIG_SCALING_INPUT_TWO_THIRDS  = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling, /**< 2/3 scale input. */
+    NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD   = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling,  /**< 1/3 scale input. */
+    NRF_ADC_CONFIG_SCALING_SUPPLY_TWO_THIRDS = ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling,      /**< 2/3 of supply. */
+    NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD  = ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling        /**< 1/3 of supply. */
+} nrf_adc_config_scaling_t;
+
+/**
+ * @enum nrf_adc_config_reference_t
+ * @brief Reference selection of the analog-to-digital converter.
+ */
+typedef enum
+{
+    NRF_ADC_CONFIG_REF_VBG              = ADC_CONFIG_REFSEL_VBG,                      /**< 1.2 V reference. */
+    NRF_ADC_CONFIG_REF_SUPPLY_ONE_HALF  = ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling,  /**< 1/2 of power supply. */
+    NRF_ADC_CONFIG_REF_SUPPLY_ONE_THIRD = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling, /**< 1/3 of power supply. */
+    NRF_ADC_CONFIG_REF_EXT_REF0         = ADC_CONFIG_REFSEL_External |
+                                          ADC_CONFIG_EXTREFSEL_AnalogReference0 <<
+    ADC_CONFIG_EXTREFSEL_Pos, /**< External reference 0. */
+        NRF_ADC_CONFIG_REF_EXT_REF1 = ADC_CONFIG_REFSEL_External |
+                                  ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos, /**< External reference 0. */
+} nrf_adc_config_reference_t;
+
+/**
+ * @enum nrf_adc_config_input_t
+ * @brief Input selection of the analog-to-digital converter.
+ */
+typedef enum
+{
+    NRF_ADC_CONFIG_INPUT_DISABLED = ADC_CONFIG_PSEL_Disabled,     /**< No input selected. */
+    NRF_ADC_CONFIG_INPUT_0        = ADC_CONFIG_PSEL_AnalogInput0, /**< Input 0. */
+    NRF_ADC_CONFIG_INPUT_1        = ADC_CONFIG_PSEL_AnalogInput1, /**< Input 1. */
+    NRF_ADC_CONFIG_INPUT_2        = ADC_CONFIG_PSEL_AnalogInput2, /**< Input 2. */
+    NRF_ADC_CONFIG_INPUT_3        = ADC_CONFIG_PSEL_AnalogInput3, /**< Input 3. */
+    NRF_ADC_CONFIG_INPUT_4        = ADC_CONFIG_PSEL_AnalogInput4, /**< Input 4. */
+    NRF_ADC_CONFIG_INPUT_5        = ADC_CONFIG_PSEL_AnalogInput5, /**< Input 5. */
+    NRF_ADC_CONFIG_INPUT_6        = ADC_CONFIG_PSEL_AnalogInput6, /**< Input 6. */
+    NRF_ADC_CONFIG_INPUT_7        = ADC_CONFIG_PSEL_AnalogInput7, /**< Input 7. */
+} nrf_adc_config_input_t;
+
+/**
+ * @enum nrf_adc_task_t
+ * @brief Analog-to-digital converter tasks.
+ */
+typedef enum
+{
+    /*lint -save -e30*/
+    NRF_ADC_TASK_START = offsetof(NRF_ADC_Type, TASKS_START), /**< ADC start sampling task. */
+    NRF_ADC_TASK_STOP  = offsetof(NRF_ADC_Type, TASKS_STOP)   /**< ADC stop sampling task. */
+    /*lint -restore*/
+} nrf_adc_task_t;
+
+/**
+ * @enum nrf_adc_event_t
+ * @brief Analog-to-digital converter events.
+ */
+typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
+{
+    /*lint -save -e30*/
+    NRF_ADC_EVENT_END = offsetof(NRF_ADC_Type, EVENTS_END) /**< End of conversion event. */
+    /*lint -restore*/
+} nrf_adc_event_t;
+
+/**@brief Analog-to-digital converter configuration. */
+typedef struct
+{
+    nrf_adc_config_resolution_t resolution; /**< ADC resolution. */
+    nrf_adc_config_scaling_t    scaling;    /**< ADC scaling factor. */
+    nrf_adc_config_reference_t  reference;  /**< ADC reference. */
+} nrf_adc_config_t;
+
+/** Default ADC configuration. */
+#define NRF_ADC_CONFIG_DEFAULT { NRF_ADC_CONFIG_RES_10BIT,               \
+                                 NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD, \
+                                 NRF_ADC_CONFIG_REF_VBG }
+
+/**
+ * @brief Function for configuring ADC.
+ *
+ * This function powers on the analog-to-digital converter and configures it. 
+ * After the configuration, the ADC is in DISABLE state and must be
+ * enabled before using it.
+ *
+ * @param[in] config Configuration parameters.
+ */
+void nrf_adc_configure(nrf_adc_config_t * config);
+
+/**
+ * @brief Blocking function for executing a single ADC conversion.
+ *
+ * This function selects the desired input, starts a single conversion,
+ * waits for it to finish, and returns the result.
+ * After the input is selected, the analog-to-digital converter
+ * is left in STOP state.
+ * The function does not check if the ADC is initialized and powered.
+ *
+ * @param[in] input Input to be selected.
+ *
+ * @return Conversion result.
+ */
+int32_t nrf_adc_convert_single(nrf_adc_config_input_t input);
+
+/**
+ * @brief Function for selecting ADC input.
+ *
+ * This function selects the active input of ADC. Ensure that
+ * the ADC is powered on and in IDLE state before calling this function.
+ *
+ * @param[in] input Input to be selected.
+ */
+__STATIC_INLINE void nrf_adc_input_select(nrf_adc_config_input_t input)
+{
+    NRF_ADC->CONFIG =
+        ((uint32_t)input << ADC_CONFIG_PSEL_Pos) | (NRF_ADC->CONFIG & ~ADC_CONFIG_PSEL_Msk);
+
+    if (input != NRF_ADC_CONFIG_INPUT_DISABLED)
+    {
+        NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos;
+    }
+    else
+    {
+        NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled << ADC_ENABLE_ENABLE_Pos;
+    }
+}
+
+
+/**
+ * @brief Function for retrieving the ADC conversion result.
+ *
+ * This function retrieves and returns the last analog-to-digital conversion result.
+ *
+ * @return Last conversion result.
+ */
+__STATIC_INLINE int32_t nrf_adc_result_get(void)
+{
+    return (int32_t)NRF_ADC->RESULT;
+}
+
+
+/**
+ * @brief Function for checking whether the ADC is busy.
+ *
+ * This function checks whether the analog-to-digital converter is busy with a conversion.
+ *
+ * @retval true If the ADC is busy.
+ * @retval false If the ADC is not busy.
+ */
+__STATIC_INLINE bool nrf_adc_is_busy(void)
+{
+    return ( (NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) == ADC_BUSY_BUSY_Msk);
+}
+
+/**
+ * @brief Function for getting the ADC's enabled interrupts.
+ *
+ * @param[in] mask Mask of interrupts to check.
+ *
+ * @return State of the interrupts selected by the mask.
+ *
+ * @sa nrf_adc_int_enable()
+ * @sa nrf_adc_int_disable()
+ */
+__STATIC_INLINE uint32_t nrf_adc_int_get(uint32_t mask)
+{
+    return (NRF_ADC->INTENSET & mask); // when read this register will return the value of INTEN.
+}
+
+
+/**
+ * @brief Function for starting conversion.
+ *
+ * @sa nrf_adc_stop()
+ *
+ */
+__STATIC_INLINE void nrf_adc_start(void)
+{
+    NRF_ADC->TASKS_START = 1;
+}
+
+
+/**
+ * @brief Function for stopping conversion. 
+ *
+ * If the analog-to-digital converter is in inactive state, power consumption is reduced.
+ *
+ * @sa nrf_adc_start()
+ *
+ */
+__STATIC_INLINE void nrf_adc_stop(void)
+{
+    NRF_ADC->TASKS_STOP = 1;
+}
+
+
+/**
+ * @brief Function for checking if the requested ADC conversion has ended.
+ *
+ * @retval true If the task has finished.
+ * @retval false If the task is still running.
+ */
+__STATIC_INLINE bool nrf_adc_conversion_finished(void)
+{
+    return ((bool)NRF_ADC->EVENTS_END);
+}
+
+/**
+ * @brief Function for clearing the conversion END event.
+ */
+__STATIC_INLINE void nrf_adc_conversion_event_clean(void)
+{
+    NRF_ADC->EVENTS_END = 0;
+}
+
+/**
+ * @brief Function for getting the address of an ADC task register.
+ *
+ * @param[in] adc_task ADC task.
+ *
+ * @return Address of the specified ADC task.
+ */
+__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task);
+
+/**
+ * @brief Function for getting the address of a specific ADC event register.
+ *
+ * @param[in] adc_event ADC event.
+ *
+ * @return Address of the specified ADC event.
+ */
+__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event);
+
+/**
+ * @brief Function for setting the CONFIG register in ADC.
+ *
+ * @param[in] configuration Value to be written to the CONFIG register.
+ */
+__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration);
+
+/**
+ * @brief Function for clearing an ADC event.
+ *
+ * @param[in] event Event to clear.
+ */
+__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event);
+
+/**
+ * @brief Function for checking state of an ADC event.
+ *
+ * @param[in] event Event to check.
+ *
+ * @retval true  If the event is set.
+ * @retval false If the event is not set.
+ */
+__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event);
+
+/**
+ * @brief Function for enabling specified interrupts.
+ *
+ * @param[in] int_mask  Interrupts to enable.
+ */
+__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask);
+
+/**
+ * @brief Function for disabling specified interrupts.
+ *
+ * @param[in] int_mask  Interrupts to disable.
+ */
+__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask);
+
+/**
+ * @brief Function for retrieving the state of a given interrupt.
+ *
+ * @param[in] int_mask Interrupt to check.
+ *
+ * @retval true  If the interrupt is enabled.
+ * @retval false If the interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask);
+
+/**
+ * @brief Function for activating a specific ADC task.
+ *
+ * @param[in] task Task to activate.
+ */
+__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task);
+
+/**
+ * @brief Function for enabling ADC.
+ *
+ */
+__STATIC_INLINE void nrf_adc_enable(void);
+
+/**
+ * @brief Function for disabling ADC.
+ *
+ */
+__STATIC_INLINE void nrf_adc_disable(void);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task)
+{
+    return (uint32_t)((uint8_t *)NRF_ADC + adc_task);
+}
+
+__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event)
+{
+    return (uint32_t)((uint8_t *)NRF_ADC + adc_event);
+}
+
+__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration)
+{
+    NRF_ADC->CONFIG = configuration;
+}
+
+__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event)) = 0x0UL;
+}
+
+__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event)
+{
+    return (bool)*(volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event);
+}
+
+__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask)
+{
+    NRF_ADC->INTENSET = int_mask;
+}
+
+__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask)
+{
+    NRF_ADC->INTENCLR = int_mask;
+}
+
+__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask)
+{
+    return (bool)(NRF_ADC->INTENSET & int_mask);
+}
+
+__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)task)) = 0x1UL;
+}
+
+__STATIC_INLINE void nrf_adc_enable(void)
+{
+    NRF_ADC->ENABLE = 1;
+}
+
+__STATIC_INLINE void nrf_adc_disable(void)
+{
+    NRF_ADC->ENABLE = 0;
+}
+#endif
+#endif /* NRF52 */
+/**
+ *@}
+ **/
+
+#endif /* NRF_ADC_H_ */