STM32C011D6Y ADC input pin power consumption
Hi all,
I'm working on a very low power custom board powered by a STM32C011D6Y micro controller.
I must read an ADC input routed to F1 ball (PA3, PA4, PA5 or PA6) but I'm measuring some strange power consumption related to the input voltage on the pin.
For example:
- I configure PA5 as ADC_IN5
- I wire F1 directly to an external signal generator
When I inject with the signal generator about GND or Vdd (about 3V) on the ADC input pin, the board's power consumption seems to be fine. When I set the input voltage about at half scale (about 1.5V) I measure about 500 uA on the power supply side.
All the other ports are set as analog inputs with no pulls.
Trying to figure out the problem I tried to configure other ports, for example PA3 as ADC1_IN3 on the same ball but the power consumption is exactly the same.
I also tried to rewire the board so that the analog input is connected to ball E2 (PA7, PA10 or PA12). On this pin I measure the same issue but with less power consumption, about 150 uA.
I read on the errata that there's a bug in the revision A (2.2.2) that says that on PA11 the Schmitt trigger remains effective in analog input mode. The bug should be resolved on the revision Z of the silicon (the one I have). The behavior I'm observing seems to be exactly the same as the Schmitt trigger remains active but in all the pins I tested (PA3, PA4, PA5, PA6, PA7, PA10 and PA12).
In addition, when I configure ADC1_IN7 on PA7, ball E2, and set to analog input PA12 I can read the input signal on GPIO's IDR as PA12 was a digital input. From the datasheet I expected to read 0 because the input Schmitt trigger should be disabled and logic value forced to 0.
I suspect that I measure an higher current consumption on F1 ball because there are more pins connected to it respect to E2. Even if the pinmux selects PA5, the other 3 optional pins seem to be internally connected to input signal.
I attach the relevant part of the code, mostly generated by CubeMX. As I tried to show you it is the code of a single test while I tried a lot of different configurations and wiring, all showing the same behavior.
#define ULED_Pin GPIO_PIN_8
#define ULED_GPIO_Port GPIOA
#define OSC_Pin GPIO_PIN_7
#define OSC_GPIO_Port GPIOB
#define OUT1_Pin GPIO_PIN_5
#define OUT1_GPIO_Port GPIOA
#define ADCin_Pin GPIO_PIN_7
#define ADCin_GPIO_Port GPIOA
#define OUT2_Pin GPIO_PIN_1
#define OUT2_GPIO_Port GPIOA
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 3;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_39CYCLES_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(ULED_GPIO_Port, ULED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, OUT1_Pin|OUT2_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : PC15 */
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : ULED_Pin OUT1_Pin OUT2_Pin */
GPIO_InitStruct.Pin = ULED_Pin|OUT1_Pin|OUT2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PA11 PA12 PA3 PA4
PA6 PA0 PA2 */
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_3|GPIO_PIN_4
|GPIO_PIN_6|GPIO_PIN_0|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PF2 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/**/
HAL_SYSCFG_SetPinBinding(HAL_BIND_WLCSP12_PINE2_PA7|HAL_BIND_WLCSP12_PINF1_PA5);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA5 ------> ADC1_IN5
*/
GPIO_InitStruct.Pin = ADCin_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ADCin_GPIO_Port, &GPIO_InitStruct);
HAL_SYSCFG_SetPinBinding(HAL_BIND_WLCSP12_PINF1_PA5);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA1_Channel1;
hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
Sadly I have to squeeze any micro amps from my board so this behavior is very important. Am I doing something wrong in the configuration?
Thanks in advance
SarcasticLama
