4545
Fork of mbed-dev by
targets/TARGET_ONSEMI/TARGET_NCS36510/analogin_api.c
- Committer:
- iftaziz
- Date:
- 2017-08-23
- Revision:
- 166:33361e55dd8c
- Parent:
- 161:2cc1468da177
File content as of revision 166:33361e55dd8c:
/** ****************************************************************************** * @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; obj->ADC_Offset_Value = TRIMREG->ADC_OFFSET_TRIM; 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) | (6 << 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); /* Offset the ADC data with trim value */ if (obj->ADC_Offset_Value != 0xFFFFFFFF) { if(adcData >= obj->ADC_Offset_Value) { adcData -= obj->ADC_Offset_Value; } } return(adcData); } #endif // DEVICE_ANALOGIN