From 58f40b8feea3197379686b22dea46bc2fba1bbe5 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 8 Feb 2021 14:29:13 +0100 Subject: [PATCH 1/2] Add new bitfield to manage ADC channel bank For STM32L1xx, in Cat.3, Cat.4, Cat.5 and Cat.6 devices there are up to 42 multiplexed channels organized in 2 banks. Channels ADC_IN0 to ADC_IN31 are available in Bank A and channels ADC_IN0b to ADC_IN31b are available in Bank B. Signed-off-by: Frederic Pillon --- cores/arduino/stm32/PinNamesTypes.h | 73 +++++++++++++---------------- 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/cores/arduino/stm32/PinNamesTypes.h b/cores/arduino/stm32/PinNamesTypes.h index a1c1cca51f..47272256f5 100644 --- a/cores/arduino/stm32/PinNamesTypes.h +++ b/cores/arduino/stm32/PinNamesTypes.h @@ -1,29 +1,13 @@ -/* ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics +/* + ******************************************************************************* + * Copyright (c) 2016-2021, 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 component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause * - * 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. ******************************************************************************* */ #ifndef _PINNAMESTYPES_H @@ -42,7 +26,8 @@ extern "C" { * [19:15] Channel (Analog/Timer specific) * [20] Inverted (Analog/Timer specific) * [21] Analog ADC control - Only valid for specific families - * [32:22] Reserved + * [22] Analog channel bank B - Only valid for specific families + * [32:23] Reserved */ #define STM_PIN_FUNCTION_MASK 0x07 @@ -77,16 +62,21 @@ extern "C" { #define STM_PIN_AN_CTRL_SHIFT 21 #define STM_PIN_ANALOG_CONTROL_BIT (STM_PIN_AN_CTRL_MASK << STM_PIN_AN_CTRL_SHIFT) -#define STM_PIN_FUNCTION(X) (((X) >> STM_PIN_FUNCTION_SHIFT) & STM_PIN_FUNCTION_MASK) -#define STM_PIN_OD(X) (((X) >> STM_PIN_OD_SHIFT) & STM_PIN_OD_MASK) -#define STM_PIN_PUPD(X) (((X) >> STM_PIN_PUPD_SHIFT) & STM_PIN_PUPD_MASK) -#define STM_PIN_SPEED(X) (((X) >> STM_PIN_SPEED_SHIFT) & STM_PIN_SPEED_MASK) -#define STM_PIN_AFNUM(X) (((X) >> STM_PIN_AFNUM_SHIFT) & STM_PIN_AFNUM_MASK) -#define STM_PIN_CHANNEL(X) (((X) >> STM_PIN_CHAN_SHIFT) & STM_PIN_CHAN_MASK) -#define STM_PIN_INVERTED(X) (((X) >> STM_PIN_INV_SHIFT) & STM_PIN_INV_MASK) -#define STM_PIN_ANALOG_CONTROL(X) (((X) >> STM_PIN_AN_CTRL_SHIFT) & STM_PIN_AN_CTRL_MASK) -#define STM_PIN_MODE(X) ((STM_PIN_OD((X)) << 4) | \ - (STM_PIN_FUNCTION((X)) & (~STM_PIN_OD_BITS))) +#define STM_PIN_AN_CHAN_BANK_B_MASK 0x01 +#define STM_PIN_AN_CHAN_BANK_B_SHIFT 22 +#define STM_PIN_ANALOG_CHAN_BANK_B_BIT (STM_PIN_AN_CHAN_BANK_B_MASK << STM_PIN_AN_CHAN_BANK_B_SHIFT) + +#define STM_PIN_FUNCTION(X) (((X) >> STM_PIN_FUNCTION_SHIFT) & STM_PIN_FUNCTION_MASK) +#define STM_PIN_OD(X) (((X) >> STM_PIN_OD_SHIFT) & STM_PIN_OD_MASK) +#define STM_PIN_PUPD(X) (((X) >> STM_PIN_PUPD_SHIFT) & STM_PIN_PUPD_MASK) +#define STM_PIN_SPEED(X) (((X) >> STM_PIN_SPEED_SHIFT) & STM_PIN_SPEED_MASK) +#define STM_PIN_AFNUM(X) (((X) >> STM_PIN_AFNUM_SHIFT) & STM_PIN_AFNUM_MASK) +#define STM_PIN_CHANNEL(X) (((X) >> STM_PIN_CHAN_SHIFT) & STM_PIN_CHAN_MASK) +#define STM_PIN_INVERTED(X) (((X) >> STM_PIN_INV_SHIFT) & STM_PIN_INV_MASK) +#define STM_PIN_ANALOG_CONTROL(X) (((X) >> STM_PIN_AN_CTRL_SHIFT) & STM_PIN_AN_CTRL_MASK) +#define STM_PIN_ANALOG_CHANNEL_BANK_B(X) (((X) >> STM_PIN_AN_CHAN_BANK_B_SHIFT) & STM_PIN_AN_CHAN_BANK_B_MASK) +#define STM_PIN_MODE(X) ((STM_PIN_OD((X)) << 4) | \ + (STM_PIN_FUNCTION((X)) & (~STM_PIN_OD_BITS))) #define STM_PIN_DEFINE(FUNC_OD, PUPD, AFNUM) ((int)(FUNC_OD) |\ ((PUPD & STM_PIN_PUPD_MASK) << STM_PIN_PUPD_SHIFT) |\ @@ -116,13 +106,14 @@ typedef enum { STM_PIN_ANALOG = 3, } StmPinFunction; -#define STM_MODE_INPUT (STM_PIN_INPUT) -#define STM_MODE_OUTPUT_PP (STM_PIN_OUTPUT) -#define STM_MODE_OUTPUT_OD (STM_PIN_OUTPUT | STM_PIN_OD_BITS) -#define STM_MODE_AF_PP (STM_PIN_ALTERNATE) -#define STM_MODE_AF_OD (STM_PIN_ALTERNATE | STM_PIN_OD_BITS) -#define STM_MODE_ANALOG (STM_PIN_ANALOG) -#define STM_MODE_ANALOG_ADC_CONTROL (STM_PIN_ANALOG | STM_PIN_ANALOG_CONTROL_BIT) +#define STM_MODE_INPUT (STM_PIN_INPUT) +#define STM_MODE_OUTPUT_PP (STM_PIN_OUTPUT) +#define STM_MODE_OUTPUT_OD (STM_PIN_OUTPUT | STM_PIN_OD_BITS) +#define STM_MODE_AF_PP (STM_PIN_ALTERNATE) +#define STM_MODE_AF_OD (STM_PIN_ALTERNATE | STM_PIN_OD_BITS) +#define STM_MODE_ANALOG (STM_PIN_ANALOG) +#define STM_MODE_ANALOG_ADC_CONTROL (STM_PIN_ANALOG | STM_PIN_ANALOG_CONTROL_BIT) +#define STM_MODE_ANALOG_ADC_CHANNEL_BANK_B (STM_PIN_ANALOG | STM_PIN_ANALOG_CHAN_BANK_B_BIT) // High nibble = port number (FirstPort <= PortName <= LastPort) // Low nibble = pin number From 813edb9bb2454e4dfa101232ba5ab5b4ce31f0c9 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Mon, 8 Feb 2021 14:31:08 +0100 Subject: [PATCH 2/2] [ADC] Manage channel bank For STM32L1xx, in Cat.3, Cat.4, Cat.5 and Cat.6 devices there are up to 42 multiplexed channels organized in 2 banks. Channels ADC_IN0 to ADC_IN31 are available in Bank A and channels ADC_IN0b to ADC_IN31b are available in Bank B. Signed-off-by: Frederic Pillon --- libraries/SrcWrapper/src/stm32/analog.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/SrcWrapper/src/stm32/analog.cpp b/libraries/SrcWrapper/src/stm32/analog.cpp index 7c82481530..0871c25d4c 100644 --- a/libraries/SrcWrapper/src/stm32/analog.cpp +++ b/libraries/SrcWrapper/src/stm32/analog.cpp @@ -90,7 +90,7 @@ static PinName g_current_pin = NC; #endif /* Private Functions */ -static uint32_t get_adc_channel(PinName pin) +static uint32_t get_adc_channel(PinName pin, uint32_t *bank) { uint32_t function = pinmap_function(pin, PinMap_ADC); uint32_t channel = 0; @@ -207,6 +207,15 @@ static uint32_t get_adc_channel(PinName pin) channel = 0; break; } +#ifdef ADC_CHANNELS_BANK_B + if (STM_PIN_ANALOG_CHANNEL_BANK_B(function)) { + *bank = ADC_CHANNELS_BANK_B; + } else { + *bank = ADC_CHANNELS_BANK_A; + } +#else + UNUSED(bank); +#endif return channel; } @@ -746,6 +755,7 @@ uint16_t adc_read_value(PinName pin, uint32_t resolution) __IO uint16_t uhADCxConvertedValue = 0; uint32_t samplingTime = ADC_SAMPLINGTIME; uint32_t channel = 0; + uint32_t bank = 0; if ((pin & PADC_BASE) && (pin < ANA_START)) { #if defined(STM32H7xx) @@ -762,7 +772,7 @@ uint16_t adc_read_value(PinName pin, uint32_t resolution) samplingTime = ADC_SAMPLINGTIME_INTERNAL; } else { AdcHandle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC); - channel = get_adc_channel(pin); + channel = get_adc_channel(pin, &bank); } if (AdcHandle.Instance == NP) { @@ -824,7 +834,9 @@ uint16_t adc_read_value(PinName pin, uint32_t resolution) !defined(STM32MP1xx) && !defined(STM32WBxx) AdcHandle.Init.LowPowerAutoPowerOff = DISABLE; /* ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered */ #endif -#ifdef ADC_CHANNELS_BANK_A +#ifdef ADC_CHANNELS_BANK_B + AdcHandle.Init.ChannelsBank = bank; +#elif defined(ADC_CHANNELS_BANK_A) AdcHandle.Init.ChannelsBank = ADC_CHANNELS_BANK_A; #endif AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */