mbed

Fork of mbed-dev by mbed official

Revision:
149:156823d33999
Parent:
147:30b64687e01f
Child:
153:fa9ff456f731
diff -r 21d94c44109e -r 156823d33999 targets/TARGET_ONSEMI/TARGET_NCS36510/analogin_api.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/analogin_api.c	Fri Oct 28 11:17:30 2016 +0100
@@ -0,0 +1,192 @@
+/**
+ ******************************************************************************
+ * @file adc_sar.c
+ * @brief Implementation of a SAR ADC driver
+ * @internal
+ * @author ON Semiconductor
+ * $Rev:
+ * $Date:
+ ******************************************************************************
+ * Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”).
+ * All rights reserved.  This software and/or documentation is licensed by ON Semiconductor
+ * under limited terms and conditions.  The terms and conditions pertaining to the software
+ * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf
+ * (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and
+ * if applicable the software license agreement.  Do not use this software and/or
+ * documentation unless you have carefully read and you agree to the limited terms and
+ * conditions.  By using this software and/or documentation, you agree to the limited
+ * terms and conditions.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ * @endinternal
+ *
+ * @ingroup adc_sar
+ *
+ * @details
+ * <p>
+ * </p>
+ *
+ */
+
+#include "device.h"
+#include "analogin_api.h"
+#include "PeripheralPins.h"
+#include "mbed_assert.h"
+#include "clock.h"
+#include "adc_sar.h"
+
+#if DEVICE_ANALOGIN
+
+/**
+ * \defgroup hal_analogin Analogin hal functions
+ * @{
+ */
+
+/** Initialize the analogin peripheral
+ *
+ * Configures the pin used by analogin.
+ * @param obj The analogin object to initialize
+ * @param pin The analogin pin name
+ */
+void analogin_init(analogin_t *obj, PinName pin)
+{
+    CLOCK_ENABLE(CLOCK_ADC);
+    ADCName adc;
+    uint8_t adc_pin = 0;
+
+    adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
+    MBED_ASSERT(adc != (ADCName)NC);
+
+    obj->adcReg = (AdcReg_pt)adc;
+    obj->pin = pin;
+    obj->pinFlag = 1;
+
+    switch (pin) {
+        case A0:
+            adc_pin=0;
+            break;
+        case A1:
+            adc_pin = 1;
+            break;
+        case A2:
+            adc_pin = 2;
+            break;
+        case A3:
+            adc_pin = 3;
+            break;
+        default:
+            break;
+    }
+
+    /* If no config parameters are passed on; assume default value */
+    if (obj->adcConf == Null) {
+        /* Single sample, absolute conversion, scale = 1 */
+        obj->adcReg->CONTROL.WORD = ((0 << ADC_CONTROL_MODE_BIT_POS) |
+                                     (1 << ADC_CONTROL_MEASTYPE_BIT_POS) |
+                                     (1 << ADC_CONTROL_INPUTSCALE_BIT_POS) |
+                                     (((uint8_t)adc_pin) << ADC_CONTROL_MEAS_CH_BIT_POS));
+
+        /* Prescaler enabled; set to 7 */
+        obj->adcReg->PRESCALE.WORD = ((True << ADC_PRESCALE_EN_BIT_POS) |
+                                      (7 << ADC_PRESCALE_VAL_BIT_POS)); /* ADC clock = 32MHz/(Prescale + 1) */
+
+        obj->adcReg->DELAY.WORD = ((0x34 << ADC_DELAY_SAMPLE_RATE_BIT_POS) | /** 25 uS Sets the sample rate in units of PCLKperiod *  (Prescale + 1). */
+                                   (0x05 << ADC_DELAY_WARMUP_BIT_POS) | /** 12.5 uS Sets the measure time in units of PCLKperiod * (Prescale + 1). */
+                                   (0x1A << ADC_DELAY_SAMPLE_TIME_BIT_POS)); /** 2.5 uS Sets the warm-up time in units of PCLKperiod * (Prescale + 1). */
+
+        obj->adcReg->IR = 0; /** No interrupt generated */
+    } else {
+        obj->adcConf->convCh = adc_pin;
+
+        /* ADC register settings */
+        if((obj->adcConf->measurementType) == ADC_RELATIVE_MEAS) {
+            obj->adcReg->CONTROL.WORD = ((obj->adcConf->mode << ADC_CONTROL_MODE_BIT_POS) |
+                                         (obj->adcConf->measurementType << ADC_CONTROL_MEASTYPE_BIT_POS) |
+                                         (obj->adcConf->inputScale << ADC_CONTROL_INPUTSCALE_BIT_POS) |
+                                         (obj->adcConf->convCh << ADC_CONTROL_MEAS_CH_BIT_POS) |
+                                         (obj->adcConf->referenceCh << ADC_CONTROL_REF_CH_BIT_POS));
+        } else {
+            obj->adcReg->CONTROL.WORD = ((obj->adcConf->mode << ADC_CONTROL_MODE_BIT_POS) |
+                                         (obj->adcConf->measurementType << ADC_CONTROL_MEASTYPE_BIT_POS) |
+                                         (obj->adcConf->inputScale << ADC_CONTROL_INPUTSCALE_BIT_POS) |
+                                         (obj->adcConf->convCh << ADC_CONTROL_MEAS_CH_BIT_POS));
+        }
+
+        obj->adcReg->PRESCALE.WORD = ((True << ADC_PRESCALE_EN_BIT_POS) |
+                                      (obj->adcConf->PrescaleVal << ADC_PRESCALE_VAL_BIT_POS)); /* ADC clock = 32MHz/(Prescale + 1) */
+
+        obj->adcReg->DELAY.WORD = ((obj->adcConf->samplingRate << ADC_DELAY_SAMPLE_RATE_BIT_POS) | /** 25 uS Sets the sample rate in units of PCLKperiod *  (Prescale + 1). */
+                                   (obj->adcConf->WarmUpTime << ADC_DELAY_WARMUP_BIT_POS) | /** 12.5 uS Sets the measure time in units of PCLKperiod * (Prescale + 1). */
+                                   (obj->adcConf->samplingTime << ADC_DELAY_SAMPLE_TIME_BIT_POS)); /** 2.5 uS Sets the warm-up time in units of PCLKperiod * (Prescale + 1). */
+
+        obj->adcReg->IR = obj->adcConf->interruptConfig; /**  Interrupt setting */
+    }
+
+    /* Enable interrupt */
+    NVIC_ClearPendingIRQ(Adc_IRQn);
+    NVIC_EnableIRQ(Adc_IRQn);
+}
+
+/** Read the input voltage, represented as a float in the range [0.0, 1.0]
+ *
+ * @param obj The analogin object
+ * @return A floating value representing the current input voltage
+ */
+float analogin_read(analogin_t *obj)
+{
+    float retVal = 0.0;
+    uint16_t value = analogin_read_u16(obj);
+    retVal = (float)value * (1.0f / (float)0x03FF);
+    return(retVal);
+}
+
+/** Read the value from analogin pin, represented as an unsigned 16bit value
+ *
+ * @param obj The analogin object
+ * @return An unsigned 16bit value representing the current input voltage
+ */
+uint16_t analogin_read_u16(analogin_t *obj)
+{
+    uint16_t adcData = 0;
+    uint8_t adc_pin = 0;
+
+    CLOCK_ENABLE(CLOCK_ADC);
+
+    if (obj->pinFlag) {
+        switch (obj->pin) {
+            case A0:
+                adc_pin=0;
+                break;
+            case A1:
+                adc_pin = 1;
+                break;
+            case A2:
+                adc_pin = 2;
+                break;
+            case A3:
+                adc_pin = 3;
+                break;
+            default:
+                break;
+        }
+
+        /* Re initialize the pin configured for ADC read */
+        obj->adcReg->CONTROL.BITS.CONV_CH = adc_pin;
+    }
+
+    obj->adcReg->CONTROL.BITS.START_CONV=1;    /* Start The Conversion */
+
+    while((uint32_t)(obj->adcReg->STATUS)!=(uint32_t)1) {
+    }
+    adcData =(uint16_t)(obj->adcReg->DATA);
+    CLOCK_DISABLE(CLOCK_ADC);
+
+    return(adcData);
+}
+
+#endif // DEVICE_ANALOGIN
+