Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
targets/hal/TARGET_ONSEMI/TARGET_NCS36510/analogin_api.c@144:ef7eb2e8f9f7, 2016-09-02 (annotated)
- Committer:
- <>
- Date:
- Fri Sep 02 15:07:44 2016 +0100
- Revision:
- 144:ef7eb2e8f9f7
- Child:
- 147:30b64687e01f
This updates the lib to the mbed lib v125
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
<> | 144:ef7eb2e8f9f7 | 1 | /** |
<> | 144:ef7eb2e8f9f7 | 2 | ****************************************************************************** |
<> | 144:ef7eb2e8f9f7 | 3 | * @file adc_sar.c |
<> | 144:ef7eb2e8f9f7 | 4 | * @brief Implementation of a SAR ADC driver |
<> | 144:ef7eb2e8f9f7 | 5 | * @internal |
<> | 144:ef7eb2e8f9f7 | 6 | * @author ON Semiconductor |
<> | 144:ef7eb2e8f9f7 | 7 | * $Rev: |
<> | 144:ef7eb2e8f9f7 | 8 | * $Date: |
<> | 144:ef7eb2e8f9f7 | 9 | ****************************************************************************** |
<> | 144:ef7eb2e8f9f7 | 10 | * @copyright (c) 2012 ON Semiconductor. All rights reserved. |
<> | 144:ef7eb2e8f9f7 | 11 | * ON Semiconductor is supplying this software for use with ON Semiconductor |
<> | 144:ef7eb2e8f9f7 | 12 | * processor based microcontrollers only. |
<> | 144:ef7eb2e8f9f7 | 13 | * |
<> | 144:ef7eb2e8f9f7 | 14 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED |
<> | 144:ef7eb2e8f9f7 | 15 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF |
<> | 144:ef7eb2e8f9f7 | 16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. |
<> | 144:ef7eb2e8f9f7 | 17 | * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, |
<> | 144:ef7eb2e8f9f7 | 18 | * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
<> | 144:ef7eb2e8f9f7 | 19 | * @endinternal |
<> | 144:ef7eb2e8f9f7 | 20 | * |
<> | 144:ef7eb2e8f9f7 | 21 | * @ingroup adc_sar |
<> | 144:ef7eb2e8f9f7 | 22 | * |
<> | 144:ef7eb2e8f9f7 | 23 | * @details |
<> | 144:ef7eb2e8f9f7 | 24 | * <p> |
<> | 144:ef7eb2e8f9f7 | 25 | * </p> |
<> | 144:ef7eb2e8f9f7 | 26 | * |
<> | 144:ef7eb2e8f9f7 | 27 | */ |
<> | 144:ef7eb2e8f9f7 | 28 | |
<> | 144:ef7eb2e8f9f7 | 29 | #include "device.h" |
<> | 144:ef7eb2e8f9f7 | 30 | #include "analogin_api.h" |
<> | 144:ef7eb2e8f9f7 | 31 | #include "PeripheralPins.h" |
<> | 144:ef7eb2e8f9f7 | 32 | #include "mbed_assert.h" |
<> | 144:ef7eb2e8f9f7 | 33 | #include "clock.h" |
<> | 144:ef7eb2e8f9f7 | 34 | #include "adc_sar.h" |
<> | 144:ef7eb2e8f9f7 | 35 | |
<> | 144:ef7eb2e8f9f7 | 36 | #if DEVICE_ANALOGIN |
<> | 144:ef7eb2e8f9f7 | 37 | |
<> | 144:ef7eb2e8f9f7 | 38 | /** |
<> | 144:ef7eb2e8f9f7 | 39 | * \defgroup hal_analogin Analogin hal functions |
<> | 144:ef7eb2e8f9f7 | 40 | * @{ |
<> | 144:ef7eb2e8f9f7 | 41 | */ |
<> | 144:ef7eb2e8f9f7 | 42 | |
<> | 144:ef7eb2e8f9f7 | 43 | /** Initialize the analogin peripheral |
<> | 144:ef7eb2e8f9f7 | 44 | * |
<> | 144:ef7eb2e8f9f7 | 45 | * Configures the pin used by analogin. |
<> | 144:ef7eb2e8f9f7 | 46 | * @param obj The analogin object to initialize |
<> | 144:ef7eb2e8f9f7 | 47 | * @param pin The analogin pin name |
<> | 144:ef7eb2e8f9f7 | 48 | */ |
<> | 144:ef7eb2e8f9f7 | 49 | void analogin_init(analogin_t *obj, PinName pin) |
<> | 144:ef7eb2e8f9f7 | 50 | { |
<> | 144:ef7eb2e8f9f7 | 51 | CLOCK_ENABLE(CLOCK_ADC); |
<> | 144:ef7eb2e8f9f7 | 52 | ADCName adc; |
<> | 144:ef7eb2e8f9f7 | 53 | uint8_t adc_pin = 0; |
<> | 144:ef7eb2e8f9f7 | 54 | |
<> | 144:ef7eb2e8f9f7 | 55 | adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); |
<> | 144:ef7eb2e8f9f7 | 56 | MBED_ASSERT(adc != (ADCName)NC); |
<> | 144:ef7eb2e8f9f7 | 57 | |
<> | 144:ef7eb2e8f9f7 | 58 | obj->adcReg = (AdcReg_pt)adc; |
<> | 144:ef7eb2e8f9f7 | 59 | obj->pin = pin; |
<> | 144:ef7eb2e8f9f7 | 60 | obj->pinFlag = 1; |
<> | 144:ef7eb2e8f9f7 | 61 | |
<> | 144:ef7eb2e8f9f7 | 62 | switch (pin) { |
<> | 144:ef7eb2e8f9f7 | 63 | case A0: |
<> | 144:ef7eb2e8f9f7 | 64 | adc_pin=0; |
<> | 144:ef7eb2e8f9f7 | 65 | break; |
<> | 144:ef7eb2e8f9f7 | 66 | case A1: |
<> | 144:ef7eb2e8f9f7 | 67 | adc_pin = 1; |
<> | 144:ef7eb2e8f9f7 | 68 | break; |
<> | 144:ef7eb2e8f9f7 | 69 | case A2: |
<> | 144:ef7eb2e8f9f7 | 70 | adc_pin = 2; |
<> | 144:ef7eb2e8f9f7 | 71 | break; |
<> | 144:ef7eb2e8f9f7 | 72 | case A3: |
<> | 144:ef7eb2e8f9f7 | 73 | adc_pin = 3; |
<> | 144:ef7eb2e8f9f7 | 74 | break; |
<> | 144:ef7eb2e8f9f7 | 75 | default: |
<> | 144:ef7eb2e8f9f7 | 76 | break; |
<> | 144:ef7eb2e8f9f7 | 77 | } |
<> | 144:ef7eb2e8f9f7 | 78 | |
<> | 144:ef7eb2e8f9f7 | 79 | /* If no config parameters are passed on; assume default value */ |
<> | 144:ef7eb2e8f9f7 | 80 | if (obj->adcConf == Null) { |
<> | 144:ef7eb2e8f9f7 | 81 | /* Single sample, absolute conversion, scale = 1 */ |
<> | 144:ef7eb2e8f9f7 | 82 | obj->adcReg->CONTROL.WORD = ((0 << ADC_CONTROL_MODE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 83 | (1 << ADC_CONTROL_MEASTYPE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 84 | (1 << ADC_CONTROL_INPUTSCALE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 85 | (((uint8_t)adc_pin) << ADC_CONTROL_MEAS_CH_BIT_POS)); |
<> | 144:ef7eb2e8f9f7 | 86 | |
<> | 144:ef7eb2e8f9f7 | 87 | /* Prescaler enabled; set to 7 */ |
<> | 144:ef7eb2e8f9f7 | 88 | obj->adcReg->PRESCALE.WORD = ((True << ADC_PRESCALE_EN_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 89 | (7 << ADC_PRESCALE_VAL_BIT_POS)); /* ADC clock = 32MHz/(Prescale + 1) */ |
<> | 144:ef7eb2e8f9f7 | 90 | |
<> | 144:ef7eb2e8f9f7 | 91 | obj->adcReg->DELAY.WORD = ((0x34 << ADC_DELAY_SAMPLE_RATE_BIT_POS) | /** 25 uS Sets the sample rate in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 92 | (0x05 << ADC_DELAY_WARMUP_BIT_POS) | /** 12.5 uS Sets the measure time in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 93 | (0x1A << ADC_DELAY_SAMPLE_TIME_BIT_POS)); /** 2.5 uS Sets the warm-up time in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 94 | |
<> | 144:ef7eb2e8f9f7 | 95 | obj->adcReg->IR = 0; /** No interrupt generated */ |
<> | 144:ef7eb2e8f9f7 | 96 | } else { |
<> | 144:ef7eb2e8f9f7 | 97 | obj->adcConf->convCh = adc_pin; |
<> | 144:ef7eb2e8f9f7 | 98 | |
<> | 144:ef7eb2e8f9f7 | 99 | /* ADC register settings */ |
<> | 144:ef7eb2e8f9f7 | 100 | if((obj->adcConf->measurementType) == ADC_RELATIVE_MEAS) { |
<> | 144:ef7eb2e8f9f7 | 101 | obj->adcReg->CONTROL.WORD = ((obj->adcConf->mode << ADC_CONTROL_MODE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 102 | (obj->adcConf->measurementType << ADC_CONTROL_MEASTYPE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 103 | (obj->adcConf->inputScale << ADC_CONTROL_INPUTSCALE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 104 | (obj->adcConf->convCh << ADC_CONTROL_MEAS_CH_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 105 | (obj->adcConf->referenceCh << ADC_CONTROL_REF_CH_BIT_POS)); |
<> | 144:ef7eb2e8f9f7 | 106 | } else { |
<> | 144:ef7eb2e8f9f7 | 107 | obj->adcReg->CONTROL.WORD = ((obj->adcConf->mode << ADC_CONTROL_MODE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 108 | (obj->adcConf->measurementType << ADC_CONTROL_MEASTYPE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 109 | (obj->adcConf->inputScale << ADC_CONTROL_INPUTSCALE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 110 | (obj->adcConf->convCh << ADC_CONTROL_MEAS_CH_BIT_POS)); |
<> | 144:ef7eb2e8f9f7 | 111 | } |
<> | 144:ef7eb2e8f9f7 | 112 | |
<> | 144:ef7eb2e8f9f7 | 113 | obj->adcReg->PRESCALE.WORD = ((True << ADC_PRESCALE_EN_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 114 | (obj->adcConf->PrescaleVal << ADC_PRESCALE_VAL_BIT_POS)); /* ADC clock = 32MHz/(Prescale + 1) */ |
<> | 144:ef7eb2e8f9f7 | 115 | |
<> | 144:ef7eb2e8f9f7 | 116 | 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). */ |
<> | 144:ef7eb2e8f9f7 | 117 | (obj->adcConf->WarmUpTime << ADC_DELAY_WARMUP_BIT_POS) | /** 12.5 uS Sets the measure time in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 118 | (obj->adcConf->samplingTime << ADC_DELAY_SAMPLE_TIME_BIT_POS)); /** 2.5 uS Sets the warm-up time in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 119 | |
<> | 144:ef7eb2e8f9f7 | 120 | obj->adcReg->IR = obj->adcConf->interruptConfig; /** Interrupt setting */ |
<> | 144:ef7eb2e8f9f7 | 121 | } |
<> | 144:ef7eb2e8f9f7 | 122 | |
<> | 144:ef7eb2e8f9f7 | 123 | /* Enable interrupt */ |
<> | 144:ef7eb2e8f9f7 | 124 | NVIC_ClearPendingIRQ(Adc_IRQn); |
<> | 144:ef7eb2e8f9f7 | 125 | NVIC_EnableIRQ(Adc_IRQn); |
<> | 144:ef7eb2e8f9f7 | 126 | } |
<> | 144:ef7eb2e8f9f7 | 127 | |
<> | 144:ef7eb2e8f9f7 | 128 | /** Read the input voltage, represented as a float in the range [0.0, 1.0] |
<> | 144:ef7eb2e8f9f7 | 129 | * |
<> | 144:ef7eb2e8f9f7 | 130 | * @param obj The analogin object |
<> | 144:ef7eb2e8f9f7 | 131 | * @return A floating value representing the current input voltage |
<> | 144:ef7eb2e8f9f7 | 132 | */ |
<> | 144:ef7eb2e8f9f7 | 133 | float analogin_read(analogin_t *obj) |
<> | 144:ef7eb2e8f9f7 | 134 | { |
<> | 144:ef7eb2e8f9f7 | 135 | float retVal = 0.0; |
<> | 144:ef7eb2e8f9f7 | 136 | uint16_t value = analogin_read_u16(obj); |
<> | 144:ef7eb2e8f9f7 | 137 | retVal = (float)value * (1.0f / (float)0x03FF); |
<> | 144:ef7eb2e8f9f7 | 138 | return(retVal); |
<> | 144:ef7eb2e8f9f7 | 139 | } |
<> | 144:ef7eb2e8f9f7 | 140 | |
<> | 144:ef7eb2e8f9f7 | 141 | /** Read the value from analogin pin, represented as an unsigned 16bit value |
<> | 144:ef7eb2e8f9f7 | 142 | * |
<> | 144:ef7eb2e8f9f7 | 143 | * @param obj The analogin object |
<> | 144:ef7eb2e8f9f7 | 144 | * @return An unsigned 16bit value representing the current input voltage |
<> | 144:ef7eb2e8f9f7 | 145 | */ |
<> | 144:ef7eb2e8f9f7 | 146 | uint16_t analogin_read_u16(analogin_t *obj) |
<> | 144:ef7eb2e8f9f7 | 147 | { |
<> | 144:ef7eb2e8f9f7 | 148 | uint16_t adcData = 0; |
<> | 144:ef7eb2e8f9f7 | 149 | uint8_t adc_pin = 0; |
<> | 144:ef7eb2e8f9f7 | 150 | |
<> | 144:ef7eb2e8f9f7 | 151 | CLOCK_ENABLE(CLOCK_ADC); |
<> | 144:ef7eb2e8f9f7 | 152 | |
<> | 144:ef7eb2e8f9f7 | 153 | if (obj->pinFlag) { |
<> | 144:ef7eb2e8f9f7 | 154 | switch (obj->pin) { |
<> | 144:ef7eb2e8f9f7 | 155 | case A0: |
<> | 144:ef7eb2e8f9f7 | 156 | adc_pin=0; |
<> | 144:ef7eb2e8f9f7 | 157 | break; |
<> | 144:ef7eb2e8f9f7 | 158 | case A1: |
<> | 144:ef7eb2e8f9f7 | 159 | adc_pin = 1; |
<> | 144:ef7eb2e8f9f7 | 160 | break; |
<> | 144:ef7eb2e8f9f7 | 161 | case A2: |
<> | 144:ef7eb2e8f9f7 | 162 | adc_pin = 2; |
<> | 144:ef7eb2e8f9f7 | 163 | break; |
<> | 144:ef7eb2e8f9f7 | 164 | case A3: |
<> | 144:ef7eb2e8f9f7 | 165 | adc_pin = 3; |
<> | 144:ef7eb2e8f9f7 | 166 | break; |
<> | 144:ef7eb2e8f9f7 | 167 | default: |
<> | 144:ef7eb2e8f9f7 | 168 | break; |
<> | 144:ef7eb2e8f9f7 | 169 | } |
<> | 144:ef7eb2e8f9f7 | 170 | |
<> | 144:ef7eb2e8f9f7 | 171 | /* Re initialize the pin configured for ADC read */ |
<> | 144:ef7eb2e8f9f7 | 172 | obj->adcReg->CONTROL.BITS.CONV_CH = adc_pin; |
<> | 144:ef7eb2e8f9f7 | 173 | } |
<> | 144:ef7eb2e8f9f7 | 174 | |
<> | 144:ef7eb2e8f9f7 | 175 | obj->adcReg->CONTROL.BITS.START_CONV=1; /* Start The Conversion */ |
<> | 144:ef7eb2e8f9f7 | 176 | |
<> | 144:ef7eb2e8f9f7 | 177 | while((uint32_t)(obj->adcReg->STATUS)!=(uint32_t)1) { |
<> | 144:ef7eb2e8f9f7 | 178 | } |
<> | 144:ef7eb2e8f9f7 | 179 | adcData =(uint16_t)(obj->adcReg->DATA); |
<> | 144:ef7eb2e8f9f7 | 180 | CLOCK_DISABLE(CLOCK_ADC); |
<> | 144:ef7eb2e8f9f7 | 181 | |
<> | 144:ef7eb2e8f9f7 | 182 | return(adcData); |
<> | 144:ef7eb2e8f9f7 | 183 | } |
<> | 144:ef7eb2e8f9f7 | 184 | |
<> | 144:ef7eb2e8f9f7 | 185 | #endif // DEVICE_ANALOGIN |
<> | 144:ef7eb2e8f9f7 | 186 |