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/TARGET_ONSEMI/TARGET_NCS36510/analogin_api.c@180:d79f997829d6, 2017-12-18 (annotated)
- Committer:
- Anythingconnected
- Date:
- Mon Dec 18 10:14:27 2017 +0000
- Revision:
- 180:d79f997829d6
- Parent:
- 161:2cc1468da177
Getting byte by byte read to work
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 | ****************************************************************************** |
<> | 147:30b64687e01f | 10 | * Copyright 2016 Semiconductor Components Industries LLC (d/b/a ON Semiconductor). |
<> | 147:30b64687e01f | 11 | * All rights reserved. This software and/or documentation is licensed by ON Semiconductor |
<> | 147:30b64687e01f | 12 | * under limited terms and conditions. The terms and conditions pertaining to the software |
<> | 147:30b64687e01f | 13 | * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf |
<> | 147:30b64687e01f | 14 | * (ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software) and |
<> | 147:30b64687e01f | 15 | * if applicable the software license agreement. Do not use this software and/or |
<> | 147:30b64687e01f | 16 | * documentation unless you have carefully read and you agree to the limited terms and |
<> | 147:30b64687e01f | 17 | * conditions. By using this software and/or documentation, you agree to the limited |
<> | 147:30b64687e01f | 18 | * terms and conditions. |
<> | 144:ef7eb2e8f9f7 | 19 | * |
<> | 144:ef7eb2e8f9f7 | 20 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED |
<> | 144:ef7eb2e8f9f7 | 21 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF |
<> | 144:ef7eb2e8f9f7 | 22 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. |
<> | 144:ef7eb2e8f9f7 | 23 | * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, |
<> | 144:ef7eb2e8f9f7 | 24 | * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
<> | 144:ef7eb2e8f9f7 | 25 | * @endinternal |
<> | 144:ef7eb2e8f9f7 | 26 | * |
<> | 144:ef7eb2e8f9f7 | 27 | * @ingroup adc_sar |
<> | 144:ef7eb2e8f9f7 | 28 | * |
<> | 144:ef7eb2e8f9f7 | 29 | * @details |
<> | 144:ef7eb2e8f9f7 | 30 | * <p> |
<> | 144:ef7eb2e8f9f7 | 31 | * </p> |
<> | 144:ef7eb2e8f9f7 | 32 | * |
<> | 144:ef7eb2e8f9f7 | 33 | */ |
<> | 144:ef7eb2e8f9f7 | 34 | |
<> | 144:ef7eb2e8f9f7 | 35 | #include "device.h" |
<> | 144:ef7eb2e8f9f7 | 36 | #include "analogin_api.h" |
<> | 144:ef7eb2e8f9f7 | 37 | #include "PeripheralPins.h" |
<> | 144:ef7eb2e8f9f7 | 38 | #include "mbed_assert.h" |
<> | 144:ef7eb2e8f9f7 | 39 | #include "clock.h" |
<> | 144:ef7eb2e8f9f7 | 40 | #include "adc_sar.h" |
<> | 144:ef7eb2e8f9f7 | 41 | |
<> | 144:ef7eb2e8f9f7 | 42 | #if DEVICE_ANALOGIN |
<> | 144:ef7eb2e8f9f7 | 43 | |
<> | 144:ef7eb2e8f9f7 | 44 | /** |
<> | 144:ef7eb2e8f9f7 | 45 | * \defgroup hal_analogin Analogin hal functions |
<> | 144:ef7eb2e8f9f7 | 46 | * @{ |
<> | 144:ef7eb2e8f9f7 | 47 | */ |
<> | 144:ef7eb2e8f9f7 | 48 | |
<> | 144:ef7eb2e8f9f7 | 49 | /** Initialize the analogin peripheral |
<> | 144:ef7eb2e8f9f7 | 50 | * |
<> | 144:ef7eb2e8f9f7 | 51 | * Configures the pin used by analogin. |
<> | 144:ef7eb2e8f9f7 | 52 | * @param obj The analogin object to initialize |
<> | 144:ef7eb2e8f9f7 | 53 | * @param pin The analogin pin name |
<> | 144:ef7eb2e8f9f7 | 54 | */ |
<> | 144:ef7eb2e8f9f7 | 55 | void analogin_init(analogin_t *obj, PinName pin) |
<> | 144:ef7eb2e8f9f7 | 56 | { |
<> | 144:ef7eb2e8f9f7 | 57 | CLOCK_ENABLE(CLOCK_ADC); |
<> | 144:ef7eb2e8f9f7 | 58 | ADCName adc; |
<> | 144:ef7eb2e8f9f7 | 59 | uint8_t adc_pin = 0; |
<> | 144:ef7eb2e8f9f7 | 60 | |
<> | 144:ef7eb2e8f9f7 | 61 | adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); |
<> | 144:ef7eb2e8f9f7 | 62 | MBED_ASSERT(adc != (ADCName)NC); |
<> | 144:ef7eb2e8f9f7 | 63 | |
<> | 144:ef7eb2e8f9f7 | 64 | obj->adcReg = (AdcReg_pt)adc; |
<> | 144:ef7eb2e8f9f7 | 65 | obj->pin = pin; |
<> | 144:ef7eb2e8f9f7 | 66 | obj->pinFlag = 1; |
<> | 153:fa9ff456f731 | 67 | obj->ADC_Offset_Value = TRIMREG->ADC_OFFSET_TRIM; |
<> | 153:fa9ff456f731 | 68 | |
<> | 144:ef7eb2e8f9f7 | 69 | switch (pin) { |
<> | 144:ef7eb2e8f9f7 | 70 | case A0: |
<> | 144:ef7eb2e8f9f7 | 71 | adc_pin=0; |
<> | 144:ef7eb2e8f9f7 | 72 | break; |
<> | 144:ef7eb2e8f9f7 | 73 | case A1: |
<> | 144:ef7eb2e8f9f7 | 74 | adc_pin = 1; |
<> | 144:ef7eb2e8f9f7 | 75 | break; |
<> | 144:ef7eb2e8f9f7 | 76 | case A2: |
<> | 144:ef7eb2e8f9f7 | 77 | adc_pin = 2; |
<> | 144:ef7eb2e8f9f7 | 78 | break; |
<> | 144:ef7eb2e8f9f7 | 79 | case A3: |
<> | 144:ef7eb2e8f9f7 | 80 | adc_pin = 3; |
<> | 144:ef7eb2e8f9f7 | 81 | break; |
<> | 144:ef7eb2e8f9f7 | 82 | default: |
<> | 144:ef7eb2e8f9f7 | 83 | break; |
<> | 144:ef7eb2e8f9f7 | 84 | } |
<> | 144:ef7eb2e8f9f7 | 85 | |
<> | 144:ef7eb2e8f9f7 | 86 | /* If no config parameters are passed on; assume default value */ |
<> | 144:ef7eb2e8f9f7 | 87 | if (obj->adcConf == Null) { |
<> | 144:ef7eb2e8f9f7 | 88 | /* Single sample, absolute conversion, scale = 1 */ |
<> | 144:ef7eb2e8f9f7 | 89 | obj->adcReg->CONTROL.WORD = ((0 << ADC_CONTROL_MODE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 90 | (1 << ADC_CONTROL_MEASTYPE_BIT_POS) | |
<> | 161:2cc1468da177 | 91 | (6 << ADC_CONTROL_INPUTSCALE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 92 | (((uint8_t)adc_pin) << ADC_CONTROL_MEAS_CH_BIT_POS)); |
<> | 144:ef7eb2e8f9f7 | 93 | |
<> | 144:ef7eb2e8f9f7 | 94 | /* Prescaler enabled; set to 7 */ |
<> | 144:ef7eb2e8f9f7 | 95 | obj->adcReg->PRESCALE.WORD = ((True << ADC_PRESCALE_EN_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 96 | (7 << ADC_PRESCALE_VAL_BIT_POS)); /* ADC clock = 32MHz/(Prescale + 1) */ |
<> | 144:ef7eb2e8f9f7 | 97 | |
<> | 144:ef7eb2e8f9f7 | 98 | 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 | 99 | (0x05 << ADC_DELAY_WARMUP_BIT_POS) | /** 12.5 uS Sets the measure time in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 100 | (0x1A << ADC_DELAY_SAMPLE_TIME_BIT_POS)); /** 2.5 uS Sets the warm-up time in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 101 | |
<> | 144:ef7eb2e8f9f7 | 102 | obj->adcReg->IR = 0; /** No interrupt generated */ |
<> | 144:ef7eb2e8f9f7 | 103 | } else { |
<> | 144:ef7eb2e8f9f7 | 104 | obj->adcConf->convCh = adc_pin; |
<> | 144:ef7eb2e8f9f7 | 105 | |
<> | 144:ef7eb2e8f9f7 | 106 | /* ADC register settings */ |
<> | 144:ef7eb2e8f9f7 | 107 | if((obj->adcConf->measurementType) == ADC_RELATIVE_MEAS) { |
<> | 144:ef7eb2e8f9f7 | 108 | obj->adcReg->CONTROL.WORD = ((obj->adcConf->mode << ADC_CONTROL_MODE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 109 | (obj->adcConf->measurementType << ADC_CONTROL_MEASTYPE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 110 | (obj->adcConf->inputScale << ADC_CONTROL_INPUTSCALE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 111 | (obj->adcConf->convCh << ADC_CONTROL_MEAS_CH_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 112 | (obj->adcConf->referenceCh << ADC_CONTROL_REF_CH_BIT_POS)); |
<> | 144:ef7eb2e8f9f7 | 113 | } else { |
<> | 144:ef7eb2e8f9f7 | 114 | obj->adcReg->CONTROL.WORD = ((obj->adcConf->mode << ADC_CONTROL_MODE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 115 | (obj->adcConf->measurementType << ADC_CONTROL_MEASTYPE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 116 | (obj->adcConf->inputScale << ADC_CONTROL_INPUTSCALE_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 117 | (obj->adcConf->convCh << ADC_CONTROL_MEAS_CH_BIT_POS)); |
<> | 144:ef7eb2e8f9f7 | 118 | } |
<> | 144:ef7eb2e8f9f7 | 119 | |
<> | 144:ef7eb2e8f9f7 | 120 | obj->adcReg->PRESCALE.WORD = ((True << ADC_PRESCALE_EN_BIT_POS) | |
<> | 144:ef7eb2e8f9f7 | 121 | (obj->adcConf->PrescaleVal << ADC_PRESCALE_VAL_BIT_POS)); /* ADC clock = 32MHz/(Prescale + 1) */ |
<> | 144:ef7eb2e8f9f7 | 122 | |
<> | 144:ef7eb2e8f9f7 | 123 | 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 | 124 | (obj->adcConf->WarmUpTime << ADC_DELAY_WARMUP_BIT_POS) | /** 12.5 uS Sets the measure time in units of PCLKperiod * (Prescale + 1). */ |
<> | 144:ef7eb2e8f9f7 | 125 | (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 | 126 | |
<> | 144:ef7eb2e8f9f7 | 127 | obj->adcReg->IR = obj->adcConf->interruptConfig; /** Interrupt setting */ |
<> | 144:ef7eb2e8f9f7 | 128 | } |
<> | 144:ef7eb2e8f9f7 | 129 | |
<> | 144:ef7eb2e8f9f7 | 130 | /* Enable interrupt */ |
<> | 144:ef7eb2e8f9f7 | 131 | NVIC_ClearPendingIRQ(Adc_IRQn); |
<> | 144:ef7eb2e8f9f7 | 132 | NVIC_EnableIRQ(Adc_IRQn); |
<> | 144:ef7eb2e8f9f7 | 133 | } |
<> | 144:ef7eb2e8f9f7 | 134 | |
<> | 144:ef7eb2e8f9f7 | 135 | /** Read the input voltage, represented as a float in the range [0.0, 1.0] |
<> | 144:ef7eb2e8f9f7 | 136 | * |
<> | 144:ef7eb2e8f9f7 | 137 | * @param obj The analogin object |
<> | 144:ef7eb2e8f9f7 | 138 | * @return A floating value representing the current input voltage |
<> | 144:ef7eb2e8f9f7 | 139 | */ |
<> | 144:ef7eb2e8f9f7 | 140 | float analogin_read(analogin_t *obj) |
<> | 144:ef7eb2e8f9f7 | 141 | { |
<> | 144:ef7eb2e8f9f7 | 142 | float retVal = 0.0; |
<> | 144:ef7eb2e8f9f7 | 143 | uint16_t value = analogin_read_u16(obj); |
<> | 144:ef7eb2e8f9f7 | 144 | retVal = (float)value * (1.0f / (float)0x03FF); |
<> | 144:ef7eb2e8f9f7 | 145 | return(retVal); |
<> | 144:ef7eb2e8f9f7 | 146 | } |
<> | 144:ef7eb2e8f9f7 | 147 | |
<> | 144:ef7eb2e8f9f7 | 148 | /** Read the value from analogin pin, represented as an unsigned 16bit value |
<> | 144:ef7eb2e8f9f7 | 149 | * |
<> | 144:ef7eb2e8f9f7 | 150 | * @param obj The analogin object |
<> | 144:ef7eb2e8f9f7 | 151 | * @return An unsigned 16bit value representing the current input voltage |
<> | 144:ef7eb2e8f9f7 | 152 | */ |
<> | 144:ef7eb2e8f9f7 | 153 | uint16_t analogin_read_u16(analogin_t *obj) |
<> | 144:ef7eb2e8f9f7 | 154 | { |
<> | 144:ef7eb2e8f9f7 | 155 | uint16_t adcData = 0; |
<> | 144:ef7eb2e8f9f7 | 156 | uint8_t adc_pin = 0; |
<> | 144:ef7eb2e8f9f7 | 157 | |
<> | 144:ef7eb2e8f9f7 | 158 | CLOCK_ENABLE(CLOCK_ADC); |
<> | 144:ef7eb2e8f9f7 | 159 | |
<> | 144:ef7eb2e8f9f7 | 160 | if (obj->pinFlag) { |
<> | 144:ef7eb2e8f9f7 | 161 | switch (obj->pin) { |
<> | 144:ef7eb2e8f9f7 | 162 | case A0: |
<> | 144:ef7eb2e8f9f7 | 163 | adc_pin=0; |
<> | 144:ef7eb2e8f9f7 | 164 | break; |
<> | 144:ef7eb2e8f9f7 | 165 | case A1: |
<> | 144:ef7eb2e8f9f7 | 166 | adc_pin = 1; |
<> | 144:ef7eb2e8f9f7 | 167 | break; |
<> | 144:ef7eb2e8f9f7 | 168 | case A2: |
<> | 144:ef7eb2e8f9f7 | 169 | adc_pin = 2; |
<> | 144:ef7eb2e8f9f7 | 170 | break; |
<> | 144:ef7eb2e8f9f7 | 171 | case A3: |
<> | 144:ef7eb2e8f9f7 | 172 | adc_pin = 3; |
<> | 144:ef7eb2e8f9f7 | 173 | break; |
<> | 144:ef7eb2e8f9f7 | 174 | default: |
<> | 144:ef7eb2e8f9f7 | 175 | break; |
<> | 144:ef7eb2e8f9f7 | 176 | } |
<> | 144:ef7eb2e8f9f7 | 177 | |
<> | 144:ef7eb2e8f9f7 | 178 | /* Re initialize the pin configured for ADC read */ |
<> | 144:ef7eb2e8f9f7 | 179 | obj->adcReg->CONTROL.BITS.CONV_CH = adc_pin; |
<> | 144:ef7eb2e8f9f7 | 180 | } |
<> | 144:ef7eb2e8f9f7 | 181 | |
<> | 144:ef7eb2e8f9f7 | 182 | obj->adcReg->CONTROL.BITS.START_CONV=1; /* Start The Conversion */ |
<> | 144:ef7eb2e8f9f7 | 183 | |
<> | 144:ef7eb2e8f9f7 | 184 | while((uint32_t)(obj->adcReg->STATUS)!=(uint32_t)1) { |
<> | 144:ef7eb2e8f9f7 | 185 | } |
<> | 144:ef7eb2e8f9f7 | 186 | adcData =(uint16_t)(obj->adcReg->DATA); |
<> | 153:fa9ff456f731 | 187 | |
<> | 153:fa9ff456f731 | 188 | /* Offset the ADC data with trim value */ |
<> | 153:fa9ff456f731 | 189 | if (obj->ADC_Offset_Value != 0xFFFFFFFF) { |
<> | 153:fa9ff456f731 | 190 | |
<> | 153:fa9ff456f731 | 191 | if(adcData >= obj->ADC_Offset_Value) { |
<> | 153:fa9ff456f731 | 192 | adcData -= obj->ADC_Offset_Value; |
<> | 153:fa9ff456f731 | 193 | } |
<> | 153:fa9ff456f731 | 194 | } |
<> | 144:ef7eb2e8f9f7 | 195 | |
<> | 144:ef7eb2e8f9f7 | 196 | return(adcData); |
<> | 144:ef7eb2e8f9f7 | 197 | } |
<> | 144:ef7eb2e8f9f7 | 198 | |
<> | 144:ef7eb2e8f9f7 | 199 | #endif // DEVICE_ANALOGIN |
<> | 144:ef7eb2e8f9f7 | 200 |