mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew 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_ASYNC_DIV2; // Asynchronous clock mode, input ADC clock
Anna Bridge 180:96ed750bd169 71 obj->handle.Init.Resolution = ADC_RESOLUTION_12B;
Anna Bridge 180:96ed750bd169 72 obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
Anna Bridge 180:96ed750bd169 73 obj->handle.Init.ScanConvMode = DISABLE; // Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1)
Anna Bridge 180:96ed750bd169 74 obj->handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; // On STM32L1xx ADC, overrun detection is enabled only if EOC selection is set to each conversion (or transfer by DMA enabled, this is not the case in this example).
Anna Bridge 180:96ed750bd169 75 obj->handle.Init.LowPowerAutoWait = DISABLE;
Anna Bridge 180:96ed750bd169 76 obj->handle.Init.ContinuousConvMode = DISABLE; // Continuous mode disabled to have only 1 conversion at each conversion trig
Anna Bridge 180:96ed750bd169 77 obj->handle.Init.NbrOfConversion = 1; // Parameter discarded because sequencer is disabled
Anna Bridge 180:96ed750bd169 78 obj->handle.Init.DiscontinuousConvMode = DISABLE; // Parameter discarded because sequencer is disabled
Anna Bridge 180:96ed750bd169 79 obj->handle.Init.NbrOfDiscConversion = 1; // Parameter discarded because sequencer is disabled
Anna Bridge 180:96ed750bd169 80 obj->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; // Software start to trig the 1st conversion manually, without external event
Anna Bridge 180:96ed750bd169 81 obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
Anna Bridge 180:96ed750bd169 82 obj->handle.Init.DMAContinuousRequests = DISABLE;
Anna Bridge 180:96ed750bd169 83 obj->handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; // DR register is overwritten with the last conversion result in case of overrun
Anna Bridge 180:96ed750bd169 84 obj->handle.Init.OversamplingMode = DISABLE; // No oversampling
AnnaBridge 188:bcfe06ba3d64 85 #if defined(ADC_CFGR_DFSDMCFG) &&defined(DFSDM1_Channel0)
AnnaBridge 188:bcfe06ba3d64 86 obj->handle.Init.DFSDMConfig = 0;
AnnaBridge 188:bcfe06ba3d64 87 #endif
AnnaBridge 188:bcfe06ba3d64 88
AnnaBridge 188:bcfe06ba3d64 89 #if defined(TARGET_DISCO_L496AG)
AnnaBridge 188:bcfe06ba3d64 90 /* VREF+ is not connected to VDDA by default */
AnnaBridge 188:bcfe06ba3d64 91 /* Use 2.5V as reference (instead of 3.3V) for internal channels calculation */
AnnaBridge 188:bcfe06ba3d64 92 __HAL_RCC_SYSCFG_CLK_ENABLE();
AnnaBridge 188:bcfe06ba3d64 93 HAL_SYSCFG_VREFBUF_VoltageScalingConfig(SYSCFG_VREFBUF_VOLTAGE_SCALE1); /* VREF_OUT2 = 2.5 V */
AnnaBridge 188:bcfe06ba3d64 94 HAL_SYSCFG_VREFBUF_HighImpedanceConfig(SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE);
AnnaBridge 188:bcfe06ba3d64 95 if (HAL_SYSCFG_EnableVREFBUF() != HAL_OK) {
AnnaBridge 188:bcfe06ba3d64 96 error("HAL_SYSCFG_EnableVREFBUF issue\n");
AnnaBridge 188:bcfe06ba3d64 97 }
AnnaBridge 188:bcfe06ba3d64 98 #endif /* TARGET_DISCO_L496AG */
Anna Bridge 180:96ed750bd169 99
Anna Bridge 180:96ed750bd169 100 // Enable ADC clock
Anna Bridge 180:96ed750bd169 101 __HAL_RCC_ADC_CLK_ENABLE();
Anna Bridge 180:96ed750bd169 102 __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);
Anna Bridge 180:96ed750bd169 103
Anna Bridge 180:96ed750bd169 104 if (HAL_ADC_Init(&obj->handle) != HAL_OK) {
AnnaBridge 188:bcfe06ba3d64 105 error("Cannot initialize ADC\n");
Anna Bridge 180:96ed750bd169 106 }
Anna Bridge 180:96ed750bd169 107
Anna Bridge 180:96ed750bd169 108 // ADC calibration is done only once
Anna Bridge 186:707f6e361f3e 109 if (!HAL_ADCEx_Calibration_GetValue(&obj->handle, ADC_SINGLE_ENDED)) {
Anna Bridge 180:96ed750bd169 110 HAL_ADCEx_Calibration_Start(&obj->handle, ADC_SINGLE_ENDED);
Anna Bridge 180:96ed750bd169 111 }
Anna Bridge 180:96ed750bd169 112 }
Anna Bridge 180:96ed750bd169 113
Anna Bridge 180:96ed750bd169 114 uint16_t adc_read(analogin_t *obj)
Anna Bridge 180:96ed750bd169 115 {
Anna Bridge 180:96ed750bd169 116 ADC_ChannelConfTypeDef sConfig = {0};
Anna Bridge 180:96ed750bd169 117
Anna Bridge 180:96ed750bd169 118 // Configure ADC channel
AnnaBridge 184:08ed48f1de7f 119 sConfig.Rank = ADC_REGULAR_RANK_1;
AnnaBridge 184:08ed48f1de7f 120 sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; // default value (1.5 us for 80MHz clock)
AnnaBridge 184:08ed48f1de7f 121 sConfig.SingleDiff = ADC_SINGLE_ENDED;
AnnaBridge 184:08ed48f1de7f 122 sConfig.OffsetNumber = ADC_OFFSET_NONE;
AnnaBridge 184:08ed48f1de7f 123 sConfig.Offset = 0;
AnnaBridge 184:08ed48f1de7f 124
Anna Bridge 180:96ed750bd169 125 switch (obj->channel) {
Anna Bridge 180:96ed750bd169 126 case 0:
Anna Bridge 180:96ed750bd169 127 sConfig.Channel = ADC_CHANNEL_VREFINT;
AnnaBridge 184:08ed48f1de7f 128 sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; // Minimum ADC sampling time when reading the internal reference voltage is 4us
Anna Bridge 180:96ed750bd169 129 break;
Anna Bridge 180:96ed750bd169 130 case 1:
Anna Bridge 180:96ed750bd169 131 sConfig.Channel = ADC_CHANNEL_1;
Anna Bridge 180:96ed750bd169 132 break;
Anna Bridge 180:96ed750bd169 133 case 2:
Anna Bridge 180:96ed750bd169 134 sConfig.Channel = ADC_CHANNEL_2;
Anna Bridge 180:96ed750bd169 135 break;
Anna Bridge 180:96ed750bd169 136 case 3:
Anna Bridge 180:96ed750bd169 137 sConfig.Channel = ADC_CHANNEL_3;
Anna Bridge 180:96ed750bd169 138 break;
Anna Bridge 180:96ed750bd169 139 case 4:
Anna Bridge 180:96ed750bd169 140 sConfig.Channel = ADC_CHANNEL_4;
Anna Bridge 180:96ed750bd169 141 break;
Anna Bridge 180:96ed750bd169 142 case 5:
Anna Bridge 180:96ed750bd169 143 sConfig.Channel = ADC_CHANNEL_5;
Anna Bridge 180:96ed750bd169 144 break;
Anna Bridge 180:96ed750bd169 145 case 6:
Anna Bridge 180:96ed750bd169 146 sConfig.Channel = ADC_CHANNEL_6;
Anna Bridge 180:96ed750bd169 147 break;
Anna Bridge 180:96ed750bd169 148 case 7:
Anna Bridge 180:96ed750bd169 149 sConfig.Channel = ADC_CHANNEL_7;
Anna Bridge 180:96ed750bd169 150 break;
Anna Bridge 180:96ed750bd169 151 case 8:
Anna Bridge 180:96ed750bd169 152 sConfig.Channel = ADC_CHANNEL_8;
Anna Bridge 180:96ed750bd169 153 break;
Anna Bridge 180:96ed750bd169 154 case 9:
Anna Bridge 180:96ed750bd169 155 sConfig.Channel = ADC_CHANNEL_9;
Anna Bridge 180:96ed750bd169 156 break;
Anna Bridge 180:96ed750bd169 157 case 10:
Anna Bridge 180:96ed750bd169 158 sConfig.Channel = ADC_CHANNEL_10;
Anna Bridge 180:96ed750bd169 159 break;
Anna Bridge 180:96ed750bd169 160 case 11:
Anna Bridge 180:96ed750bd169 161 sConfig.Channel = ADC_CHANNEL_11;
Anna Bridge 180:96ed750bd169 162 break;
Anna Bridge 180:96ed750bd169 163 case 12:
Anna Bridge 180:96ed750bd169 164 sConfig.Channel = ADC_CHANNEL_12;
Anna Bridge 180:96ed750bd169 165 break;
Anna Bridge 180:96ed750bd169 166 case 13:
Anna Bridge 180:96ed750bd169 167 sConfig.Channel = ADC_CHANNEL_13;
Anna Bridge 180:96ed750bd169 168 break;
Anna Bridge 180:96ed750bd169 169 case 14:
Anna Bridge 180:96ed750bd169 170 sConfig.Channel = ADC_CHANNEL_14;
Anna Bridge 180:96ed750bd169 171 break;
Anna Bridge 180:96ed750bd169 172 case 15:
Anna Bridge 180:96ed750bd169 173 sConfig.Channel = ADC_CHANNEL_15;
Anna Bridge 180:96ed750bd169 174 break;
Anna Bridge 180:96ed750bd169 175 case 16:
Anna Bridge 180:96ed750bd169 176 sConfig.Channel = ADC_CHANNEL_16;
Anna Bridge 180:96ed750bd169 177 break;
Anna Bridge 180:96ed750bd169 178 case 17:
Anna Bridge 180:96ed750bd169 179 sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
AnnaBridge 184:08ed48f1de7f 180 sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; // Minimum ADC sampling time when reading the temperature is 5us
Anna Bridge 180:96ed750bd169 181 break;
Anna Bridge 180:96ed750bd169 182 case 18:
Anna Bridge 180:96ed750bd169 183 sConfig.Channel = ADC_CHANNEL_VBAT;
AnnaBridge 184:08ed48f1de7f 184 sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5; // Minimum ADC sampling time when reading the VBAT is 12us
Anna Bridge 180:96ed750bd169 185 break;
Anna Bridge 180:96ed750bd169 186 default:
Anna Bridge 180:96ed750bd169 187 return 0;
Anna Bridge 180:96ed750bd169 188 }
Anna Bridge 180:96ed750bd169 189
Anna Bridge 180:96ed750bd169 190 HAL_ADC_ConfigChannel(&obj->handle, &sConfig);
Anna Bridge 180:96ed750bd169 191
Anna Bridge 180:96ed750bd169 192 HAL_ADC_Start(&obj->handle); // Start conversion
Anna Bridge 180:96ed750bd169 193
Anna Bridge 180:96ed750bd169 194 // Wait end of conversion and get value
Anna Bridge 180:96ed750bd169 195 if (HAL_ADC_PollForConversion(&obj->handle, 10) == HAL_OK) {
AnnaBridge 189:f392fc9709a3 196
AnnaBridge 189:f392fc9709a3 197 /* Ref Manual: To prevent any unwanted consumption on the battery,
AnnaBridge 189:f392fc9709a3 198 it is recommended to enable the bridge divider only when needed for ADC conversion */
AnnaBridge 189:f392fc9709a3 199 if (sConfig.Channel == ADC_CHANNEL_VBAT) {
AnnaBridge 189:f392fc9709a3 200 CLEAR_BIT(__LL_ADC_COMMON_INSTANCE(obj->handle.Instance)->CCR, LL_ADC_PATH_INTERNAL_VBAT);
AnnaBridge 189:f392fc9709a3 201 }
AnnaBridge 189:f392fc9709a3 202
Anna Bridge 180:96ed750bd169 203 return (uint16_t)HAL_ADC_GetValue(&obj->handle);
Anna Bridge 180:96ed750bd169 204 } else {
Anna Bridge 180:96ed750bd169 205 return 0;
Anna Bridge 180:96ed750bd169 206 }
Anna Bridge 180:96ed750bd169 207 }
Anna Bridge 180:96ed750bd169 208
Anna Bridge 180:96ed750bd169 209 #endif