From c687ae312f57df88f60d66398c4dc62402769f1e Mon Sep 17 00:00:00 2001 From: George Beckstein Date: Thu, 20 Feb 2020 12:32:00 -0500 Subject: [PATCH] Added missing analogin_device.c file and configured for STM32G4xx series --- .../TARGET_STM32G4/analogin_device.c | 277 ++++++++++++++++++ targets/TARGET_STM/TARGET_STM32G4/todo.txt | 2 +- 2 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 targets/TARGET_STM/TARGET_STM32G4/analogin_device.c diff --git a/targets/TARGET_STM/TARGET_STM32G4/analogin_device.c b/targets/TARGET_STM/TARGET_STM32G4/analogin_device.c new file mode 100644 index 0000000000..3dde9a3eae --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32G4/analogin_device.c @@ -0,0 +1,277 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "mbed_assert.h" +#include "analogin_api.h" + +#if DEVICE_ANALOGIN + +#include "mbed_wait_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "mbed_error.h" +#include "mbed_debug.h" +#include "PeripheralPins.h" + +#if STATIC_PINMAP_READY +#define ANALOGIN_INIT_DIRECT analogin_init_direct +void analogin_init_direct(analogin_t *obj, const PinMap *pinmap) +#else +#define ANALOGIN_INIT_DIRECT _analogin_init_direct +static void _analogin_init_direct(analogin_t *obj, const PinMap *pinmap) +#endif +{ + uint32_t function = (uint32_t)pinmap->function; + + // Get the peripheral name from the pin and assign it to the object + obj->handle.Instance = (ADC_TypeDef *)pinmap->peripheral; + + // ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...) + // are described in PinNames.h and PeripheralPins.c + // Pin value must be between 0xF0 and 0xFF + if ((pinmap->pin < 0xF0) || (pinmap->pin >= 0x100)) { + // Normal channels + // Configure GPIO + pin_function(pinmap->pin, pinmap->function); + pin_mode(pinmap->pin, PullNone); + } else { + // Internal channels + // No GPIO configuration for internal channels + } + MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC); + MBED_ASSERT(function != (uint32_t)NC); + + obj->channel = STM_PIN_CHANNEL(function); + + // Save pin number for the read function + obj->pin = pinmap->pin; + + // Configure ADC object structures + obj->handle.State = HAL_ADC_STATE_RESET; + obj->handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; + obj->handle.Init.Resolution = ADC_RESOLUTION_12B; + obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; + obj->handle.Init.ScanConvMode = DISABLE; + obj->handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + obj->handle.Init.LowPowerAutoWait = DISABLE; + obj->handle.Init.ContinuousConvMode = DISABLE; + obj->handle.Init.NbrOfConversion = 1; + obj->handle.Init.DiscontinuousConvMode = DISABLE; + obj->handle.Init.NbrOfDiscConversion = 0; + obj->handle.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1; + obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + obj->handle.Init.DMAContinuousRequests = DISABLE; + obj->handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; + +#if defined(ADC1) + if ((ADCName)obj->handle.Instance == ADC_1) { + __HAL_RCC_ADC12_CONFIG(RCC_ADC12CLKSOURCE_SYSCLK); // TODO - which clock? + // SYSCLK or PLL? + } +#endif +#if defined(ADC2) + if ((ADCName)obj->handle.Instance == ADC_2) { + __HAL_RCC_ADC12_CONFIG(RCC_ADC12CLKSOURCE_SYSCLK); // TODO - which clock? + // SYSCLK or PLL? + } +#endif +#if defined(ADC3) + if ((ADCName)obj->handle.Instance == ADC_3) { + __HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK); // TODO - which clock? + // SYSCLK or PLL? + } +#endif +#if defined(ADC4) + if ((ADCName)obj->handle.Instance == ADC_4) { + __HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK); // TODO - which clock? + // SYSCLK or PLL? + } +#endif + +#if defined(ADC5) + if ((ADCName)obj->handle.Instance == ADC_4) { + __HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK); // TODO - which clock? + // SYSCLK or PLL? + } + +#endif + + if (HAL_ADC_Init(&obj->handle) != HAL_OK) { + error("Cannot initialize ADC\n"); + } + + if (!HAL_ADCEx_Calibration_GetValue(&obj->handle, ADC_SINGLE_ENDED)) { + HAL_ADCEx_Calibration_Start(&obj->handle, ADC_SINGLE_ENDED); + } +} + +void analogin_init(analogin_t *obj, PinName pin) +{ + int peripheral; + int function; + + if ((pin < 0xF0) || (pin >= 0x100)) { + peripheral = (int)pinmap_peripheral(pin, PinMap_ADC); + function = (int)pinmap_find_function(pin, PinMap_ADC); + } else { + peripheral = (int)pinmap_peripheral(pin, PinMap_ADC_Internal); + function = (int)pinmap_find_function(pin, PinMap_ADC_Internal); + } + + const PinMap static_pinmap = {pin, peripheral, function}; + + ANALOGIN_INIT_DIRECT(obj, &static_pinmap); +} + +uint16_t adc_read(analogin_t *obj) +{ + ADC_ChannelConfTypeDef sConfig = {0}; + + // Configure ADC channel + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; + + switch (obj->channel) { + case 1: + sConfig.Channel = ADC_CHANNEL_1; + break; + case 2: + sConfig.Channel = ADC_CHANNEL_2; + break; + case 3: + sConfig.Channel = ADC_CHANNEL_3; + break; + case 4: + sConfig.Channel = ADC_CHANNEL_4; + break; + case 5: + sConfig.Channel = ADC_CHANNEL_5; + break; + case 6: + sConfig.Channel = ADC_CHANNEL_6; + break; + case 7: + sConfig.Channel = ADC_CHANNEL_7; + break; + case 8: + sConfig.Channel = ADC_CHANNEL_8; + break; + case 9: + sConfig.Channel = ADC_CHANNEL_9; + break; + case 10: + sConfig.Channel = ADC_CHANNEL_10; + break; + case 11: + sConfig.Channel = ADC_CHANNEL_11; + break; + case 12: + sConfig.Channel = ADC_CHANNEL_12; + break; + case 13: + sConfig.Channel = ADC_CHANNEL_13; + break; + case 14: + sConfig.Channel = ADC_CHANNEL_14; + break; + case 15: + if ((ADCName)obj->handle.Instance == ADC_1) { + sConfig.Channel = ADC_CHANNEL_VOPAMP1; + sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; + } else { + sConfig.Channel = ADC_CHANNEL_15; + } + break; + case 16: + if ((ADCName)obj->handle.Instance == ADC_1) { + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR_ADC1; + sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; + } else { + sConfig.Channel = ADC_CHANNEL_16; + } + break; + case 17: + sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; + if ((ADCName)obj->handle.Instance == ADC_1) { + sConfig.Channel = ADC_CHANNEL_VBAT; + } +#if defined(ADC2) + if ((ADCName)obj->handle.Instance == ADC_2) { + sConfig.Channel = ADC_CHANNEL_VOPAMP2; + } +#endif +#if defined(ADC3) + if ((ADCName)obj->handle.Instance == ADC_3) { + sConfig.Channel = ADC_CHANNEL_VOPAMP3_ADC3; + } +#endif +#if defined(ADC4) + if ((ADCName)obj->handle.Instance == ADC_4) { + sConfig.Channel = ADC_CHANNEL_VOPAMP4; + } +#endif + break; + case 18: + sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; + sConfig.Channel = ADC_CHANNEL_VREFINT; + break; + default: + return 0; + } + + if (HAL_ADC_ConfigChannel(&obj->handle, &sConfig) != HAL_OK) { + debug("HAL_ADC_ConfigChannel issue\n");; + } + + if (HAL_ADC_Start(&obj->handle) != HAL_OK) { + debug("HAL_ADC_Start issue\n");; + } + + uint16_t MeasuredValue = 0; + + if (HAL_ADC_PollForConversion(&obj->handle, 10) == HAL_OK) { + MeasuredValue = (uint16_t)HAL_ADC_GetValue(&obj->handle); + } else { + debug("HAL_ADC_PollForConversion issue\n"); + } + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE((&obj->handle)->Instance), LL_ADC_PATH_INTERNAL_NONE); + if (HAL_ADC_Stop(&obj->handle) != HAL_OK) { + debug("HAL_ADC_Stop issue\n");; + } + + return MeasuredValue; +} + +const PinMap *analogin_pinmap() +{ + return PinMap_ADC; +} + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32G4/todo.txt b/targets/TARGET_STM/TARGET_STM32G4/todo.txt index c50f76e4e4..b336d743fe 100644 --- a/targets/TARGET_STM/TARGET_STM32G4/todo.txt +++ b/targets/TARGET_STM/TARGET_STM32G4/todo.txt @@ -1 +1 @@ -Still to be added: CAN, USBDEVICE, ANALOGOUT, QSPI, CRC(?), TRNG +Still to be added: CAN, USBDEVICE, QSPI, CRC(?), TRNG