mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Apr 19 17:12:19 2018 +0100
Revision:
184:08ed48f1de7f
Parent:
180:96ed750bd169
Child:
186:707f6e361f3e
mbed-dev library. Release version 161

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 #include <stdbool.h>
Anna Bridge 180:96ed750bd169 39
Anna Bridge 180:96ed750bd169 40 void analogin_init(analogin_t *obj, PinName pin)
Anna Bridge 180:96ed750bd169 41 {
Anna Bridge 180:96ed750bd169 42 static bool adc_calibrated = false;
Anna Bridge 180:96ed750bd169 43 uint32_t function = (uint32_t)NC;
Anna Bridge 180:96ed750bd169 44
Anna Bridge 180:96ed750bd169 45 // ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...)
Anna Bridge 180:96ed750bd169 46 // are described in PinNames.h and PeripheralPins.c
Anna Bridge 180:96ed750bd169 47 // Pin value must be between 0xF0 and 0xFF
Anna Bridge 180:96ed750bd169 48 if ((pin < 0xF0) || (pin >= 0x100)) {
Anna Bridge 180:96ed750bd169 49 // Normal channels
Anna Bridge 180:96ed750bd169 50 // Get the peripheral name from the pin and assign it to the object
Anna Bridge 180:96ed750bd169 51 obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC);
Anna Bridge 180:96ed750bd169 52 // Get the functions (adc channel) from the pin and assign it to the object
Anna Bridge 180:96ed750bd169 53 function = pinmap_function(pin, PinMap_ADC);
Anna Bridge 180:96ed750bd169 54 // Configure GPIO
Anna Bridge 180:96ed750bd169 55 pinmap_pinout(pin, PinMap_ADC);
Anna Bridge 180:96ed750bd169 56 } else {
Anna Bridge 180:96ed750bd169 57 // Internal channels
Anna Bridge 180:96ed750bd169 58 obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC_Internal);
Anna Bridge 180:96ed750bd169 59 function = pinmap_function(pin, PinMap_ADC_Internal);
Anna Bridge 180:96ed750bd169 60 // No GPIO configuration for internal channels
Anna Bridge 180:96ed750bd169 61 }
Anna Bridge 180:96ed750bd169 62 MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC);
Anna Bridge 180:96ed750bd169 63 MBED_ASSERT(function != (uint32_t)NC);
Anna Bridge 180:96ed750bd169 64
Anna Bridge 180:96ed750bd169 65 obj->channel = STM_PIN_CHANNEL(function);
Anna Bridge 180:96ed750bd169 66
Anna Bridge 180:96ed750bd169 67 // Save pin number for the read function
Anna Bridge 180:96ed750bd169 68 obj->pin = pin;
Anna Bridge 180:96ed750bd169 69
Anna Bridge 180:96ed750bd169 70 // Configure ADC object structures
Anna Bridge 180:96ed750bd169 71 obj->handle.State = HAL_ADC_STATE_RESET;
Anna Bridge 180:96ed750bd169 72 obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; // Asynchronous clock mode, input ADC clock
Anna Bridge 180:96ed750bd169 73 obj->handle.Init.Resolution = ADC_RESOLUTION_12B;
Anna Bridge 180:96ed750bd169 74 obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
Anna Bridge 180:96ed750bd169 75 obj->handle.Init.ScanConvMode = DISABLE; // Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1)
Anna Bridge 180:96ed750bd169 76 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 77 obj->handle.Init.LowPowerAutoWait = DISABLE;
Anna Bridge 180:96ed750bd169 78 obj->handle.Init.ContinuousConvMode = DISABLE; // Continuous mode disabled to have only 1 conversion at each conversion trig
Anna Bridge 180:96ed750bd169 79 obj->handle.Init.NbrOfConversion = 1; // Parameter discarded because sequencer is disabled
Anna Bridge 180:96ed750bd169 80 obj->handle.Init.DiscontinuousConvMode = DISABLE; // Parameter discarded because sequencer is disabled
Anna Bridge 180:96ed750bd169 81 obj->handle.Init.NbrOfDiscConversion = 1; // Parameter discarded because sequencer is disabled
Anna Bridge 180:96ed750bd169 82 obj->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; // Software start to trig the 1st conversion manually, without external event
Anna Bridge 180:96ed750bd169 83 obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
Anna Bridge 180:96ed750bd169 84 obj->handle.Init.DMAContinuousRequests = DISABLE;
Anna Bridge 180:96ed750bd169 85 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 86 obj->handle.Init.OversamplingMode = DISABLE; // No oversampling
Anna Bridge 180:96ed750bd169 87
Anna Bridge 180:96ed750bd169 88 // Enable ADC clock
Anna Bridge 180:96ed750bd169 89 __HAL_RCC_ADC_CLK_ENABLE();
Anna Bridge 180:96ed750bd169 90 __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);
Anna Bridge 180:96ed750bd169 91
Anna Bridge 180:96ed750bd169 92 if (HAL_ADC_Init(&obj->handle) != HAL_OK) {
Anna Bridge 180:96ed750bd169 93 error("Cannot initialize ADC");
Anna Bridge 180:96ed750bd169 94 }
Anna Bridge 180:96ed750bd169 95
Anna Bridge 180:96ed750bd169 96 // ADC calibration is done only once
Anna Bridge 180:96ed750bd169 97 if (!adc_calibrated) {
Anna Bridge 180:96ed750bd169 98 adc_calibrated = true;
Anna Bridge 180:96ed750bd169 99 HAL_ADCEx_Calibration_Start(&obj->handle, ADC_SINGLE_ENDED);
Anna Bridge 180:96ed750bd169 100 }
Anna Bridge 180:96ed750bd169 101 }
Anna Bridge 180:96ed750bd169 102
Anna Bridge 180:96ed750bd169 103 uint16_t adc_read(analogin_t *obj)
Anna Bridge 180:96ed750bd169 104 {
Anna Bridge 180:96ed750bd169 105 ADC_ChannelConfTypeDef sConfig = {0};
Anna Bridge 180:96ed750bd169 106
Anna Bridge 180:96ed750bd169 107 // Configure ADC channel
AnnaBridge 184:08ed48f1de7f 108 sConfig.Rank = ADC_REGULAR_RANK_1;
AnnaBridge 184:08ed48f1de7f 109 sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; // default value (1.5 us for 80MHz clock)
AnnaBridge 184:08ed48f1de7f 110 sConfig.SingleDiff = ADC_SINGLE_ENDED;
AnnaBridge 184:08ed48f1de7f 111 sConfig.OffsetNumber = ADC_OFFSET_NONE;
AnnaBridge 184:08ed48f1de7f 112 sConfig.Offset = 0;
AnnaBridge 184:08ed48f1de7f 113
Anna Bridge 180:96ed750bd169 114 switch (obj->channel) {
Anna Bridge 180:96ed750bd169 115 case 0:
Anna Bridge 180:96ed750bd169 116 sConfig.Channel = ADC_CHANNEL_VREFINT;
AnnaBridge 184:08ed48f1de7f 117 sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; // Minimum ADC sampling time when reading the internal reference voltage is 4us
Anna Bridge 180:96ed750bd169 118 break;
Anna Bridge 180:96ed750bd169 119 case 1:
Anna Bridge 180:96ed750bd169 120 sConfig.Channel = ADC_CHANNEL_1;
Anna Bridge 180:96ed750bd169 121 break;
Anna Bridge 180:96ed750bd169 122 case 2:
Anna Bridge 180:96ed750bd169 123 sConfig.Channel = ADC_CHANNEL_2;
Anna Bridge 180:96ed750bd169 124 break;
Anna Bridge 180:96ed750bd169 125 case 3:
Anna Bridge 180:96ed750bd169 126 sConfig.Channel = ADC_CHANNEL_3;
Anna Bridge 180:96ed750bd169 127 break;
Anna Bridge 180:96ed750bd169 128 case 4:
Anna Bridge 180:96ed750bd169 129 sConfig.Channel = ADC_CHANNEL_4;
Anna Bridge 180:96ed750bd169 130 break;
Anna Bridge 180:96ed750bd169 131 case 5:
Anna Bridge 180:96ed750bd169 132 sConfig.Channel = ADC_CHANNEL_5;
Anna Bridge 180:96ed750bd169 133 break;
Anna Bridge 180:96ed750bd169 134 case 6:
Anna Bridge 180:96ed750bd169 135 sConfig.Channel = ADC_CHANNEL_6;
Anna Bridge 180:96ed750bd169 136 break;
Anna Bridge 180:96ed750bd169 137 case 7:
Anna Bridge 180:96ed750bd169 138 sConfig.Channel = ADC_CHANNEL_7;
Anna Bridge 180:96ed750bd169 139 break;
Anna Bridge 180:96ed750bd169 140 case 8:
Anna Bridge 180:96ed750bd169 141 sConfig.Channel = ADC_CHANNEL_8;
Anna Bridge 180:96ed750bd169 142 break;
Anna Bridge 180:96ed750bd169 143 case 9:
Anna Bridge 180:96ed750bd169 144 sConfig.Channel = ADC_CHANNEL_9;
Anna Bridge 180:96ed750bd169 145 break;
Anna Bridge 180:96ed750bd169 146 case 10:
Anna Bridge 180:96ed750bd169 147 sConfig.Channel = ADC_CHANNEL_10;
Anna Bridge 180:96ed750bd169 148 break;
Anna Bridge 180:96ed750bd169 149 case 11:
Anna Bridge 180:96ed750bd169 150 sConfig.Channel = ADC_CHANNEL_11;
Anna Bridge 180:96ed750bd169 151 break;
Anna Bridge 180:96ed750bd169 152 case 12:
Anna Bridge 180:96ed750bd169 153 sConfig.Channel = ADC_CHANNEL_12;
Anna Bridge 180:96ed750bd169 154 break;
Anna Bridge 180:96ed750bd169 155 case 13:
Anna Bridge 180:96ed750bd169 156 sConfig.Channel = ADC_CHANNEL_13;
Anna Bridge 180:96ed750bd169 157 break;
Anna Bridge 180:96ed750bd169 158 case 14:
Anna Bridge 180:96ed750bd169 159 sConfig.Channel = ADC_CHANNEL_14;
Anna Bridge 180:96ed750bd169 160 break;
Anna Bridge 180:96ed750bd169 161 case 15:
Anna Bridge 180:96ed750bd169 162 sConfig.Channel = ADC_CHANNEL_15;
Anna Bridge 180:96ed750bd169 163 break;
Anna Bridge 180:96ed750bd169 164 case 16:
Anna Bridge 180:96ed750bd169 165 sConfig.Channel = ADC_CHANNEL_16;
Anna Bridge 180:96ed750bd169 166 break;
Anna Bridge 180:96ed750bd169 167 case 17:
Anna Bridge 180:96ed750bd169 168 sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
AnnaBridge 184:08ed48f1de7f 169 sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; // Minimum ADC sampling time when reading the temperature is 5us
Anna Bridge 180:96ed750bd169 170 break;
Anna Bridge 180:96ed750bd169 171 case 18:
Anna Bridge 180:96ed750bd169 172 sConfig.Channel = ADC_CHANNEL_VBAT;
AnnaBridge 184:08ed48f1de7f 173 sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5; // Minimum ADC sampling time when reading the VBAT is 12us
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 HAL_ADC_ConfigChannel(&obj->handle, &sConfig);
Anna Bridge 180:96ed750bd169 180
Anna Bridge 180:96ed750bd169 181 HAL_ADC_Start(&obj->handle); // Start conversion
Anna Bridge 180:96ed750bd169 182
Anna Bridge 180:96ed750bd169 183 // Wait end of conversion and get value
Anna Bridge 180:96ed750bd169 184 if (HAL_ADC_PollForConversion(&obj->handle, 10) == HAL_OK) {
Anna Bridge 180:96ed750bd169 185 return (uint16_t)HAL_ADC_GetValue(&obj->handle);
Anna Bridge 180:96ed750bd169 186 } else {
Anna Bridge 180:96ed750bd169 187 return 0;
Anna Bridge 180:96ed750bd169 188 }
Anna Bridge 180:96ed750bd169 189 }
Anna Bridge 180:96ed750bd169 190
Anna Bridge 180:96ed750bd169 191 #endif