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_STM32F1/analogin_device.c@182:57724642e740, 2018-02-16 (annotated)
- Committer:
- AnnaBridge
- Date:
- Fri Feb 16 16:09:33 2018 +0000
- Revision:
- 182:57724642e740
- Parent:
- 181:96ed750bd169
mbed-dev library. Release version 159.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anna Bridge |
181:96ed750bd169 | 1 | /* mbed Microcontroller Library |
Anna Bridge |
181:96ed750bd169 | 2 | * Copyright (c) 2016, STMicroelectronics |
Anna Bridge |
181:96ed750bd169 | 3 | * All rights reserved. |
Anna Bridge |
181:96ed750bd169 | 4 | * |
Anna Bridge |
181:96ed750bd169 | 5 | * Redistribution and use in source and binary forms, with or without |
Anna Bridge |
181:96ed750bd169 | 6 | * modification, are permitted provided that the following conditions are met: |
Anna Bridge |
181:96ed750bd169 | 7 | * |
Anna Bridge |
181:96ed750bd169 | 8 | * 1. Redistributions of source code must retain the above copyright notice, |
Anna Bridge |
181:96ed750bd169 | 9 | * this list of conditions and the following disclaimer. |
Anna Bridge |
181:96ed750bd169 | 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
Anna Bridge |
181:96ed750bd169 | 11 | * this list of conditions and the following disclaimer in the documentation |
Anna Bridge |
181:96ed750bd169 | 12 | * and/or other materials provided with the distribution. |
Anna Bridge |
181:96ed750bd169 | 13 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
Anna Bridge |
181:96ed750bd169 | 14 | * may be used to endorse or promote products derived from this software |
Anna Bridge |
181:96ed750bd169 | 15 | * without specific prior written permission. |
Anna Bridge |
181:96ed750bd169 | 16 | * |
Anna Bridge |
181:96ed750bd169 | 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
Anna Bridge |
181:96ed750bd169 | 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
Anna Bridge |
181:96ed750bd169 | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
Anna Bridge |
181:96ed750bd169 | 20 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
Anna Bridge |
181:96ed750bd169 | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
Anna Bridge |
181:96ed750bd169 | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
Anna Bridge |
181:96ed750bd169 | 23 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
Anna Bridge |
181:96ed750bd169 | 24 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
Anna Bridge |
181:96ed750bd169 | 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
Anna Bridge |
181:96ed750bd169 | 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Anna Bridge |
181:96ed750bd169 | 27 | */ |
Anna Bridge |
181:96ed750bd169 | 28 | #include "mbed_assert.h" |
Anna Bridge |
181:96ed750bd169 | 29 | #include "analogin_api.h" |
Anna Bridge |
181:96ed750bd169 | 30 | |
Anna Bridge |
181:96ed750bd169 | 31 | #if DEVICE_ANALOGIN |
Anna Bridge |
181:96ed750bd169 | 32 | |
Anna Bridge |
181:96ed750bd169 | 33 | #include "mbed_wait_api.h" |
Anna Bridge |
181:96ed750bd169 | 34 | #include "cmsis.h" |
Anna Bridge |
181:96ed750bd169 | 35 | #include "pinmap.h" |
Anna Bridge |
181:96ed750bd169 | 36 | #include "mbed_error.h" |
Anna Bridge |
181:96ed750bd169 | 37 | #include "PeripheralPins.h" |
Anna Bridge |
181:96ed750bd169 | 38 | #include <stdbool.h> |
Anna Bridge |
181:96ed750bd169 | 39 | |
Anna Bridge |
181:96ed750bd169 | 40 | void analogin_init(analogin_t *obj, PinName pin) |
Anna Bridge |
181:96ed750bd169 | 41 | { |
Anna Bridge |
181:96ed750bd169 | 42 | static bool adc_calibrated = false; |
Anna Bridge |
181:96ed750bd169 | 43 | RCC_PeriphCLKInitTypeDef PeriphClkInit; |
Anna Bridge |
181:96ed750bd169 | 44 | uint32_t function = (uint32_t)NC; |
Anna Bridge |
181:96ed750bd169 | 45 | |
Anna Bridge |
181:96ed750bd169 | 46 | // ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...) |
Anna Bridge |
181:96ed750bd169 | 47 | // are described in PinNames.h and PeripheralPins.c |
Anna Bridge |
181:96ed750bd169 | 48 | // Pin value must be between 0xF0 and 0xFF |
Anna Bridge |
181:96ed750bd169 | 49 | if ((pin < 0xF0) || (pin >= 0x100)) { |
Anna Bridge |
181:96ed750bd169 | 50 | // Normal channels |
Anna Bridge |
181:96ed750bd169 | 51 | // Get the peripheral name from the pin and assign it to the object |
Anna Bridge |
181:96ed750bd169 | 52 | obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC); |
Anna Bridge |
181:96ed750bd169 | 53 | // Get the functions (adc channel) from the pin and assign it to the object |
Anna Bridge |
181:96ed750bd169 | 54 | function = pinmap_function(pin, PinMap_ADC); |
Anna Bridge |
181:96ed750bd169 | 55 | // Configure GPIO |
Anna Bridge |
181:96ed750bd169 | 56 | pinmap_pinout(pin, PinMap_ADC); |
Anna Bridge |
181:96ed750bd169 | 57 | } else { |
Anna Bridge |
181:96ed750bd169 | 58 | // Internal channels |
Anna Bridge |
181:96ed750bd169 | 59 | obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC_Internal); |
Anna Bridge |
181:96ed750bd169 | 60 | function = pinmap_function(pin, PinMap_ADC_Internal); |
Anna Bridge |
181:96ed750bd169 | 61 | // No GPIO configuration for internal channels |
Anna Bridge |
181:96ed750bd169 | 62 | } |
Anna Bridge |
181:96ed750bd169 | 63 | MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC); |
Anna Bridge |
181:96ed750bd169 | 64 | MBED_ASSERT(function != (uint32_t)NC); |
Anna Bridge |
181:96ed750bd169 | 65 | |
Anna Bridge |
181:96ed750bd169 | 66 | obj->channel = STM_PIN_CHANNEL(function); |
Anna Bridge |
181:96ed750bd169 | 67 | |
Anna Bridge |
181:96ed750bd169 | 68 | // Save pin number for the read function |
Anna Bridge |
181:96ed750bd169 | 69 | obj->pin = pin; |
Anna Bridge |
181:96ed750bd169 | 70 | |
Anna Bridge |
181:96ed750bd169 | 71 | // Enable ADC clock |
Anna Bridge |
181:96ed750bd169 | 72 | __HAL_RCC_ADC1_CLK_ENABLE(); |
Anna Bridge |
181:96ed750bd169 | 73 | |
Anna Bridge |
181:96ed750bd169 | 74 | // Configure ADC object structures |
Anna Bridge |
181:96ed750bd169 | 75 | obj->handle.State = HAL_ADC_STATE_RESET; |
Anna Bridge |
181:96ed750bd169 | 76 | obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; |
Anna Bridge |
181:96ed750bd169 | 77 | obj->handle.Init.ScanConvMode = DISABLE; |
Anna Bridge |
181:96ed750bd169 | 78 | obj->handle.Init.ContinuousConvMode = DISABLE; |
Anna Bridge |
181:96ed750bd169 | 79 | obj->handle.Init.NbrOfConversion = 1; |
Anna Bridge |
181:96ed750bd169 | 80 | obj->handle.Init.DiscontinuousConvMode = DISABLE; |
Anna Bridge |
181:96ed750bd169 | 81 | obj->handle.Init.NbrOfDiscConversion = 0; |
Anna Bridge |
181:96ed750bd169 | 82 | obj->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; |
Anna Bridge |
181:96ed750bd169 | 83 | |
Anna Bridge |
181:96ed750bd169 | 84 | if (HAL_ADC_Init(&obj->handle) != HAL_OK) { |
Anna Bridge |
181:96ed750bd169 | 85 | error("Cannot initialize ADC"); |
Anna Bridge |
181:96ed750bd169 | 86 | } |
Anna Bridge |
181:96ed750bd169 | 87 | |
Anna Bridge |
181:96ed750bd169 | 88 | // This section is done only once |
Anna Bridge |
181:96ed750bd169 | 89 | if (!adc_calibrated) { |
Anna Bridge |
181:96ed750bd169 | 90 | adc_calibrated = true; |
Anna Bridge |
181:96ed750bd169 | 91 | // Configure ADC clock prescaler |
Anna Bridge |
181:96ed750bd169 | 92 | // Caution: On STM32F1, ADC clock frequency max is 14 MHz (refer to device datasheet). |
Anna Bridge |
181:96ed750bd169 | 93 | // Therefore, ADC clock prescaler must be configured in function |
Anna Bridge |
181:96ed750bd169 | 94 | // of ADC clock source frequency to remain below this maximum frequency. |
Anna Bridge |
181:96ed750bd169 | 95 | // with 8 MHz external xtal: PCLK2 = 72 MHz --> ADC clock = 72/6 = 12 MHz |
Anna Bridge |
181:96ed750bd169 | 96 | // with internal clock : PCLK2 = 64 MHz --> ADC clock = 64/6 = 10.67 MHz |
Anna Bridge |
181:96ed750bd169 | 97 | PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; |
Anna Bridge |
181:96ed750bd169 | 98 | PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; |
Anna Bridge |
181:96ed750bd169 | 99 | HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); |
Anna Bridge |
181:96ed750bd169 | 100 | // Calibration |
Anna Bridge |
181:96ed750bd169 | 101 | HAL_ADCEx_Calibration_Start(&obj->handle); |
Anna Bridge |
181:96ed750bd169 | 102 | } |
Anna Bridge |
181:96ed750bd169 | 103 | } |
Anna Bridge |
181:96ed750bd169 | 104 | |
Anna Bridge |
181:96ed750bd169 | 105 | uint16_t adc_read(analogin_t *obj) |
Anna Bridge |
181:96ed750bd169 | 106 | { |
Anna Bridge |
181:96ed750bd169 | 107 | ADC_ChannelConfTypeDef sConfig = {0}; |
Anna Bridge |
181:96ed750bd169 | 108 | |
Anna Bridge |
181:96ed750bd169 | 109 | // Configure ADC channel |
Anna Bridge |
181:96ed750bd169 | 110 | sConfig.Rank = 1; |
Anna Bridge |
181:96ed750bd169 | 111 | sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5; |
Anna Bridge |
181:96ed750bd169 | 112 | |
Anna Bridge |
181:96ed750bd169 | 113 | switch (obj->channel) { |
Anna Bridge |
181:96ed750bd169 | 114 | case 0: |
Anna Bridge |
181:96ed750bd169 | 115 | sConfig.Channel = ADC_CHANNEL_0; |
Anna Bridge |
181:96ed750bd169 | 116 | break; |
Anna Bridge |
181:96ed750bd169 | 117 | case 1: |
Anna Bridge |
181:96ed750bd169 | 118 | sConfig.Channel = ADC_CHANNEL_1; |
Anna Bridge |
181:96ed750bd169 | 119 | break; |
Anna Bridge |
181:96ed750bd169 | 120 | case 2: |
Anna Bridge |
181:96ed750bd169 | 121 | sConfig.Channel = ADC_CHANNEL_2; |
Anna Bridge |
181:96ed750bd169 | 122 | break; |
Anna Bridge |
181:96ed750bd169 | 123 | case 3: |
Anna Bridge |
181:96ed750bd169 | 124 | sConfig.Channel = ADC_CHANNEL_3; |
Anna Bridge |
181:96ed750bd169 | 125 | break; |
Anna Bridge |
181:96ed750bd169 | 126 | case 4: |
Anna Bridge |
181:96ed750bd169 | 127 | sConfig.Channel = ADC_CHANNEL_4; |
Anna Bridge |
181:96ed750bd169 | 128 | break; |
Anna Bridge |
181:96ed750bd169 | 129 | case 5: |
Anna Bridge |
181:96ed750bd169 | 130 | sConfig.Channel = ADC_CHANNEL_5; |
Anna Bridge |
181:96ed750bd169 | 131 | break; |
Anna Bridge |
181:96ed750bd169 | 132 | case 6: |
Anna Bridge |
181:96ed750bd169 | 133 | sConfig.Channel = ADC_CHANNEL_6; |
Anna Bridge |
181:96ed750bd169 | 134 | break; |
Anna Bridge |
181:96ed750bd169 | 135 | case 7: |
Anna Bridge |
181:96ed750bd169 | 136 | sConfig.Channel = ADC_CHANNEL_7; |
Anna Bridge |
181:96ed750bd169 | 137 | break; |
Anna Bridge |
181:96ed750bd169 | 138 | case 8: |
Anna Bridge |
181:96ed750bd169 | 139 | sConfig.Channel = ADC_CHANNEL_8; |
Anna Bridge |
181:96ed750bd169 | 140 | break; |
Anna Bridge |
181:96ed750bd169 | 141 | case 9: |
Anna Bridge |
181:96ed750bd169 | 142 | sConfig.Channel = ADC_CHANNEL_9; |
Anna Bridge |
181:96ed750bd169 | 143 | break; |
Anna Bridge |
181:96ed750bd169 | 144 | case 10: |
Anna Bridge |
181:96ed750bd169 | 145 | sConfig.Channel = ADC_CHANNEL_10; |
Anna Bridge |
181:96ed750bd169 | 146 | break; |
Anna Bridge |
181:96ed750bd169 | 147 | case 11: |
Anna Bridge |
181:96ed750bd169 | 148 | sConfig.Channel = ADC_CHANNEL_11; |
Anna Bridge |
181:96ed750bd169 | 149 | break; |
Anna Bridge |
181:96ed750bd169 | 150 | case 12: |
Anna Bridge |
181:96ed750bd169 | 151 | sConfig.Channel = ADC_CHANNEL_12; |
Anna Bridge |
181:96ed750bd169 | 152 | break; |
Anna Bridge |
181:96ed750bd169 | 153 | case 13: |
Anna Bridge |
181:96ed750bd169 | 154 | sConfig.Channel = ADC_CHANNEL_13; |
Anna Bridge |
181:96ed750bd169 | 155 | break; |
Anna Bridge |
181:96ed750bd169 | 156 | case 14: |
Anna Bridge |
181:96ed750bd169 | 157 | sConfig.Channel = ADC_CHANNEL_14; |
Anna Bridge |
181:96ed750bd169 | 158 | break; |
Anna Bridge |
181:96ed750bd169 | 159 | case 15: |
Anna Bridge |
181:96ed750bd169 | 160 | sConfig.Channel = ADC_CHANNEL_15; |
Anna Bridge |
181:96ed750bd169 | 161 | break; |
Anna Bridge |
181:96ed750bd169 | 162 | case 16: |
Anna Bridge |
181:96ed750bd169 | 163 | sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; |
Anna Bridge |
181:96ed750bd169 | 164 | break; |
Anna Bridge |
181:96ed750bd169 | 165 | case 17: |
Anna Bridge |
181:96ed750bd169 | 166 | sConfig.Channel = ADC_CHANNEL_VREFINT; |
Anna Bridge |
181:96ed750bd169 | 167 | break; |
Anna Bridge |
181:96ed750bd169 | 168 | default: |
Anna Bridge |
181:96ed750bd169 | 169 | return 0; |
Anna Bridge |
181:96ed750bd169 | 170 | } |
Anna Bridge |
181:96ed750bd169 | 171 | |
Anna Bridge |
181:96ed750bd169 | 172 | HAL_ADC_ConfigChannel(&obj->handle, &sConfig); |
Anna Bridge |
181:96ed750bd169 | 173 | |
Anna Bridge |
181:96ed750bd169 | 174 | HAL_ADC_Start(&obj->handle); // Start conversion |
Anna Bridge |
181:96ed750bd169 | 175 | |
Anna Bridge |
181:96ed750bd169 | 176 | // Wait end of conversion and get value |
Anna Bridge |
181:96ed750bd169 | 177 | if (HAL_ADC_PollForConversion(&obj->handle, 10) == HAL_OK) { |
Anna Bridge |
181:96ed750bd169 | 178 | return (uint16_t)HAL_ADC_GetValue(&obj->handle); |
Anna Bridge |
181:96ed750bd169 | 179 | } else { |
Anna Bridge |
181:96ed750bd169 | 180 | return 0; |
Anna Bridge |
181:96ed750bd169 | 181 | } |
Anna Bridge |
181:96ed750bd169 | 182 | } |
Anna Bridge |
181:96ed750bd169 | 183 | |
Anna Bridge |
181:96ed750bd169 | 184 | #endif |