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_STM/TARGET_STM32F4/analogin_device.c@180:96ed750bd169, 2018-01-17 (annotated)
- Committer:
- Anna Bridge
- Date:
- Wed Jan 17 15:23:54 2018 +0000
- Revision:
- 180:96ed750bd169
- Child:
- 186:707f6e361f3e
mbed-dev libray. Release version 158
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anna Bridge |
180:96ed750bd169 | 1 | /* mbed Microcontroller Library |
Anna Bridge |
180:96ed750bd169 | 2 | * Copyright (c) 2016, STMicroelectronics |
Anna Bridge |
180:96ed750bd169 | 3 | * All rights reserved. |
Anna Bridge |
180:96ed750bd169 | 4 | * |
Anna Bridge |
180:96ed750bd169 | 5 | * Redistribution and use in source and binary forms, with or without |
Anna Bridge |
180:96ed750bd169 | 6 | * modification, are permitted provided that the following conditions are met: |
Anna Bridge |
180:96ed750bd169 | 7 | * |
Anna Bridge |
180:96ed750bd169 | 8 | * 1. Redistributions of source code must retain the above copyright notice, |
Anna Bridge |
180:96ed750bd169 | 9 | * this list of conditions and the following disclaimer. |
Anna Bridge |
180:96ed750bd169 | 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
Anna Bridge |
180:96ed750bd169 | 11 | * this list of conditions and the following disclaimer in the documentation |
Anna Bridge |
180:96ed750bd169 | 12 | * and/or other materials provided with the distribution. |
Anna Bridge |
180:96ed750bd169 | 13 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
Anna Bridge |
180:96ed750bd169 | 14 | * may be used to endorse or promote products derived from this software |
Anna Bridge |
180:96ed750bd169 | 15 | * without specific prior written permission. |
Anna Bridge |
180:96ed750bd169 | 16 | * |
Anna Bridge |
180:96ed750bd169 | 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
Anna Bridge |
180:96ed750bd169 | 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
Anna Bridge |
180:96ed750bd169 | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
Anna Bridge |
180:96ed750bd169 | 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
Anna Bridge |
180:96ed750bd169 | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
Anna Bridge |
180:96ed750bd169 | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
Anna Bridge |
180:96ed750bd169 | 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
Anna Bridge |
180:96ed750bd169 | 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
Anna Bridge |
180:96ed750bd169 | 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
Anna Bridge |
180:96ed750bd169 | 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Anna Bridge |
180:96ed750bd169 | 27 | */ |
Anna Bridge |
180:96ed750bd169 | 28 | #include "mbed_assert.h" |
Anna Bridge |
180:96ed750bd169 | 29 | #include "analogin_api.h" |
Anna Bridge |
180:96ed750bd169 | 30 | |
Anna Bridge |
180:96ed750bd169 | 31 | #if DEVICE_ANALOGIN |
Anna Bridge |
180:96ed750bd169 | 32 | |
Anna Bridge |
180:96ed750bd169 | 33 | #include "mbed_wait_api.h" |
Anna Bridge |
180:96ed750bd169 | 34 | #include "cmsis.h" |
Anna Bridge |
180:96ed750bd169 | 35 | #include "pinmap.h" |
Anna Bridge |
180:96ed750bd169 | 36 | #include "mbed_error.h" |
Anna Bridge |
180:96ed750bd169 | 37 | #include "PeripheralPins.h" |
Anna Bridge |
180:96ed750bd169 | 38 | |
Anna Bridge |
180:96ed750bd169 | 39 | void analogin_init(analogin_t *obj, PinName pin) |
Anna Bridge |
180:96ed750bd169 | 40 | { |
Anna Bridge |
180:96ed750bd169 | 41 | uint32_t function = (uint32_t)NC; |
Anna Bridge |
180:96ed750bd169 | 42 | |
Anna Bridge |
180:96ed750bd169 | 43 | // ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...) |
Anna Bridge |
180:96ed750bd169 | 44 | // are described in PinNames.h and PeripheralPins.c |
Anna Bridge |
180:96ed750bd169 | 45 | // Pin value must be between 0xF0 and 0xFF |
Anna Bridge |
180:96ed750bd169 | 46 | if ((pin < 0xF0) || (pin >= 0x100)) { |
Anna Bridge |
180:96ed750bd169 | 47 | // Normal channels |
Anna Bridge |
180:96ed750bd169 | 48 | // Get the peripheral name from the pin and assign it to the object |
Anna Bridge |
180:96ed750bd169 | 49 | obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC); |
Anna Bridge |
180:96ed750bd169 | 50 | // Get the functions (adc channel) from the pin and assign it to the object |
Anna Bridge |
180:96ed750bd169 | 51 | function = pinmap_function(pin, PinMap_ADC); |
Anna Bridge |
180:96ed750bd169 | 52 | // Configure GPIO |
Anna Bridge |
180:96ed750bd169 | 53 | pinmap_pinout(pin, PinMap_ADC); |
Anna Bridge |
180:96ed750bd169 | 54 | } else { |
Anna Bridge |
180:96ed750bd169 | 55 | // Internal channels |
Anna Bridge |
180:96ed750bd169 | 56 | obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC_Internal); |
Anna Bridge |
180:96ed750bd169 | 57 | function = pinmap_function(pin, PinMap_ADC_Internal); |
Anna Bridge |
180:96ed750bd169 | 58 | // No GPIO configuration for internal channels |
Anna Bridge |
180:96ed750bd169 | 59 | } |
Anna Bridge |
180:96ed750bd169 | 60 | MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC); |
Anna Bridge |
180:96ed750bd169 | 61 | MBED_ASSERT(function != (uint32_t)NC); |
Anna Bridge |
180:96ed750bd169 | 62 | |
Anna Bridge |
180:96ed750bd169 | 63 | obj->channel = STM_PIN_CHANNEL(function); |
Anna Bridge |
180:96ed750bd169 | 64 | |
Anna Bridge |
180:96ed750bd169 | 65 | // Save pin number for the read function |
Anna Bridge |
180:96ed750bd169 | 66 | obj->pin = pin; |
Anna Bridge |
180:96ed750bd169 | 67 | |
Anna Bridge |
180:96ed750bd169 | 68 | // Configure ADC object structures |
Anna Bridge |
180:96ed750bd169 | 69 | obj->handle.State = HAL_ADC_STATE_RESET; |
Anna Bridge |
180:96ed750bd169 | 70 | obj->handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; |
Anna Bridge |
180:96ed750bd169 | 71 | obj->handle.Init.Resolution = ADC_RESOLUTION_12B; |
Anna Bridge |
180:96ed750bd169 | 72 | obj->handle.Init.ScanConvMode = DISABLE; |
Anna Bridge |
180:96ed750bd169 | 73 | obj->handle.Init.ContinuousConvMode = DISABLE; |
Anna Bridge |
180:96ed750bd169 | 74 | obj->handle.Init.DiscontinuousConvMode = DISABLE; |
Anna Bridge |
180:96ed750bd169 | 75 | obj->handle.Init.NbrOfDiscConversion = 0; |
Anna Bridge |
180:96ed750bd169 | 76 | obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; |
Anna Bridge |
180:96ed750bd169 | 77 | obj->handle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; |
Anna Bridge |
180:96ed750bd169 | 78 | obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; |
Anna Bridge |
180:96ed750bd169 | 79 | obj->handle.Init.NbrOfConversion = 1; |
Anna Bridge |
180:96ed750bd169 | 80 | obj->handle.Init.DMAContinuousRequests = DISABLE; |
Anna Bridge |
180:96ed750bd169 | 81 | obj->handle.Init.EOCSelection = DISABLE; |
Anna Bridge |
180:96ed750bd169 | 82 | |
Anna Bridge |
180:96ed750bd169 | 83 | #if defined(ADC1) |
Anna Bridge |
180:96ed750bd169 | 84 | if ((ADCName)obj->handle.Instance == ADC_1) { |
Anna Bridge |
180:96ed750bd169 | 85 | __HAL_RCC_ADC1_CLK_ENABLE(); |
Anna Bridge |
180:96ed750bd169 | 86 | } |
Anna Bridge |
180:96ed750bd169 | 87 | #endif |
Anna Bridge |
180:96ed750bd169 | 88 | #if defined(ADC2) |
Anna Bridge |
180:96ed750bd169 | 89 | if ((ADCName)obj->handle.Instance == ADC_2) { |
Anna Bridge |
180:96ed750bd169 | 90 | __HAL_RCC_ADC2_CLK_ENABLE(); |
Anna Bridge |
180:96ed750bd169 | 91 | } |
Anna Bridge |
180:96ed750bd169 | 92 | #endif |
Anna Bridge |
180:96ed750bd169 | 93 | #if defined(ADC3) |
Anna Bridge |
180:96ed750bd169 | 94 | if ((ADCName)obj->handle.Instance == ADC_3) { |
Anna Bridge |
180:96ed750bd169 | 95 | __HAL_RCC_ADC3_CLK_ENABLE(); |
Anna Bridge |
180:96ed750bd169 | 96 | } |
Anna Bridge |
180:96ed750bd169 | 97 | #endif |
Anna Bridge |
180:96ed750bd169 | 98 | |
Anna Bridge |
180:96ed750bd169 | 99 | if (HAL_ADC_Init(&obj->handle) != HAL_OK) { |
Anna Bridge |
180:96ed750bd169 | 100 | error("Cannot initialize ADC"); |
Anna Bridge |
180:96ed750bd169 | 101 | } |
Anna Bridge |
180:96ed750bd169 | 102 | } |
Anna Bridge |
180:96ed750bd169 | 103 | |
Anna Bridge |
180:96ed750bd169 | 104 | uint16_t adc_read(analogin_t *obj) |
Anna Bridge |
180:96ed750bd169 | 105 | { |
Anna Bridge |
180:96ed750bd169 | 106 | ADC_ChannelConfTypeDef sConfig = {0}; |
Anna Bridge |
180:96ed750bd169 | 107 | |
Anna Bridge |
180:96ed750bd169 | 108 | // Configure ADC channel |
Anna Bridge |
180:96ed750bd169 | 109 | sConfig.Rank = 1; |
Anna Bridge |
180:96ed750bd169 | 110 | sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES; |
Anna Bridge |
180:96ed750bd169 | 111 | sConfig.Offset = 0; |
Anna Bridge |
180:96ed750bd169 | 112 | |
Anna Bridge |
180:96ed750bd169 | 113 | switch (obj->channel) { |
Anna Bridge |
180:96ed750bd169 | 114 | case 0: |
Anna Bridge |
180:96ed750bd169 | 115 | sConfig.Channel = ADC_CHANNEL_0; |
Anna Bridge |
180:96ed750bd169 | 116 | break; |
Anna Bridge |
180:96ed750bd169 | 117 | case 1: |
Anna Bridge |
180:96ed750bd169 | 118 | sConfig.Channel = ADC_CHANNEL_1; |
Anna Bridge |
180:96ed750bd169 | 119 | break; |
Anna Bridge |
180:96ed750bd169 | 120 | case 2: |
Anna Bridge |
180:96ed750bd169 | 121 | sConfig.Channel = ADC_CHANNEL_2; |
Anna Bridge |
180:96ed750bd169 | 122 | break; |
Anna Bridge |
180:96ed750bd169 | 123 | case 3: |
Anna Bridge |
180:96ed750bd169 | 124 | sConfig.Channel = ADC_CHANNEL_3; |
Anna Bridge |
180:96ed750bd169 | 125 | break; |
Anna Bridge |
180:96ed750bd169 | 126 | case 4: |
Anna Bridge |
180:96ed750bd169 | 127 | sConfig.Channel = ADC_CHANNEL_4; |
Anna Bridge |
180:96ed750bd169 | 128 | break; |
Anna Bridge |
180:96ed750bd169 | 129 | case 5: |
Anna Bridge |
180:96ed750bd169 | 130 | sConfig.Channel = ADC_CHANNEL_5; |
Anna Bridge |
180:96ed750bd169 | 131 | break; |
Anna Bridge |
180:96ed750bd169 | 132 | case 6: |
Anna Bridge |
180:96ed750bd169 | 133 | sConfig.Channel = ADC_CHANNEL_6; |
Anna Bridge |
180:96ed750bd169 | 134 | break; |
Anna Bridge |
180:96ed750bd169 | 135 | case 7: |
Anna Bridge |
180:96ed750bd169 | 136 | sConfig.Channel = ADC_CHANNEL_7; |
Anna Bridge |
180:96ed750bd169 | 137 | break; |
Anna Bridge |
180:96ed750bd169 | 138 | case 8: |
Anna Bridge |
180:96ed750bd169 | 139 | sConfig.Channel = ADC_CHANNEL_8; |
Anna Bridge |
180:96ed750bd169 | 140 | break; |
Anna Bridge |
180:96ed750bd169 | 141 | case 9: |
Anna Bridge |
180:96ed750bd169 | 142 | sConfig.Channel = ADC_CHANNEL_9; |
Anna Bridge |
180:96ed750bd169 | 143 | break; |
Anna Bridge |
180:96ed750bd169 | 144 | case 10: |
Anna Bridge |
180:96ed750bd169 | 145 | sConfig.Channel = ADC_CHANNEL_10; |
Anna Bridge |
180:96ed750bd169 | 146 | break; |
Anna Bridge |
180:96ed750bd169 | 147 | case 11: |
Anna Bridge |
180:96ed750bd169 | 148 | sConfig.Channel = ADC_CHANNEL_11; |
Anna Bridge |
180:96ed750bd169 | 149 | break; |
Anna Bridge |
180:96ed750bd169 | 150 | case 12: |
Anna Bridge |
180:96ed750bd169 | 151 | sConfig.Channel = ADC_CHANNEL_12; |
Anna Bridge |
180:96ed750bd169 | 152 | break; |
Anna Bridge |
180:96ed750bd169 | 153 | case 13: |
Anna Bridge |
180:96ed750bd169 | 154 | sConfig.Channel = ADC_CHANNEL_13; |
Anna Bridge |
180:96ed750bd169 | 155 | break; |
Anna Bridge |
180:96ed750bd169 | 156 | case 14: |
Anna Bridge |
180:96ed750bd169 | 157 | sConfig.Channel = ADC_CHANNEL_14; |
Anna Bridge |
180:96ed750bd169 | 158 | break; |
Anna Bridge |
180:96ed750bd169 | 159 | case 15: |
Anna Bridge |
180:96ed750bd169 | 160 | sConfig.Channel = ADC_CHANNEL_15; |
Anna Bridge |
180:96ed750bd169 | 161 | break; |
Anna Bridge |
180:96ed750bd169 | 162 | case 16: |
Anna Bridge |
180:96ed750bd169 | 163 | sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; |
Anna Bridge |
180:96ed750bd169 | 164 | break; |
Anna Bridge |
180:96ed750bd169 | 165 | case 17: |
Anna Bridge |
180:96ed750bd169 | 166 | sConfig.Channel = ADC_CHANNEL_VREFINT; |
Anna Bridge |
180:96ed750bd169 | 167 | /* From experiment, measurement needs max sampling time to be valid */ |
Anna Bridge |
180:96ed750bd169 | 168 | sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; |
Anna Bridge |
180:96ed750bd169 | 169 | break; |
Anna Bridge |
180:96ed750bd169 | 170 | case 18: |
Anna Bridge |
180:96ed750bd169 | 171 | sConfig.Channel = ADC_CHANNEL_VBAT; |
Anna Bridge |
180:96ed750bd169 | 172 | /* From experiment, measurement needs max sampling time to be valid */ |
Anna Bridge |
180:96ed750bd169 | 173 | sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; |
Anna Bridge |
180:96ed750bd169 | 174 | break; |
Anna Bridge |
180:96ed750bd169 | 175 | default: |
Anna Bridge |
180:96ed750bd169 | 176 | return 0; |
Anna Bridge |
180:96ed750bd169 | 177 | } |
Anna Bridge |
180:96ed750bd169 | 178 | |
Anna Bridge |
180:96ed750bd169 | 179 | // Measuring VBAT sets the ADC_CCR_VBATE bit in ADC->CCR, and there is not |
Anna Bridge |
180:96ed750bd169 | 180 | // possibility with the ST HAL driver to clear it. If it isn't cleared, |
Anna Bridge |
180:96ed750bd169 | 181 | // VBAT remains connected to the ADC channel in preference to temperature, |
Anna Bridge |
180:96ed750bd169 | 182 | // so VBAT readings are returned in place of temperature. |
Anna Bridge |
180:96ed750bd169 | 183 | ADC->CCR &= ~(ADC_CCR_VBATE | ADC_CCR_TSVREFE); |
Anna Bridge |
180:96ed750bd169 | 184 | |
Anna Bridge |
180:96ed750bd169 | 185 | HAL_ADC_ConfigChannel(&obj->handle, &sConfig); |
Anna Bridge |
180:96ed750bd169 | 186 | |
Anna Bridge |
180:96ed750bd169 | 187 | HAL_ADC_Start(&obj->handle); // Start conversion |
Anna Bridge |
180:96ed750bd169 | 188 | |
Anna Bridge |
180:96ed750bd169 | 189 | // Wait end of conversion and get value |
Anna Bridge |
180:96ed750bd169 | 190 | if (HAL_ADC_PollForConversion(&obj->handle, 10) == HAL_OK) { |
Anna Bridge |
180:96ed750bd169 | 191 | return (uint16_t)HAL_ADC_GetValue(&obj->handle); |
Anna Bridge |
180:96ed750bd169 | 192 | } else { |
Anna Bridge |
180:96ed750bd169 | 193 | return 0; |
Anna Bridge |
180:96ed750bd169 | 194 | } |
Anna Bridge |
180:96ed750bd169 | 195 | } |
Anna Bridge |
180:96ed750bd169 | 196 | |
Anna Bridge |
180:96ed750bd169 | 197 | #endif |