cancel
Showing results for 
Search instead for 
Did you mean: 

STM32C011D6Y ADC input pin power consumption

SarcasticLama
Associate

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

3 REPLIES 3
Sarra.S
ST Employee

Hello, ensure that only the intended pin is configured for ADC input. You can explicitly disable other pins that could be internally connected to the same signal 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

AScha.3
Super User

Hi,

>All the other ports are set as analog inputs with no pulls.

So what happens, if you set this pin for ADC_in also to "analog" (=disable digital functions) ?

Should need no current then; and only switch to ADC_in , if just needed to measure.

If you feel a post has answered your question, please click "Accept as Solution".
SarcasticLama
Associate

Hi,

thanks a lot for the replies, I really appreciate it!

I think I already configure all the pins as analog.

I'm injecting a DC signal into E2 ball and I configured using the STMCubeMx the ball to be controlled by PA7, ADC_IN7.

If I look into the registers using the SWD debugger I can see:

 - GPIO PORT A (address 0x50000000):

        MODER: 0x2BFDF7F7

        PUPDR: 0x24000000

 - SYSCFG (address 0x40010000):

        CFGR1: 0x0

        CFGR3: 0x800

 

If I'm not misinterpreting I think that the 3 pins connected to E2 ball (PA7, PA10 and PA12) are all set as analog with no pull. There's no remapping of PA12 and the ball is assigned to PA7 (as CFGR3 says).

If I'm correct ADC configuration is not an alternate function so PA7 (the one I want to use) should be set as analog.

 

Now, with Vdd about 3V:

 1) if I inject 0.5V into E2:

       I measure the board supply current as 2.630 mA

       GPIOA IDR: 0x7F

 2) If I inject 2.5V into E2:

       I measure the board supply current as 2.630 mA

       GPIOA IDR: 0x107F

 3) If I inject 1.5V into E2:

       I measure the board supply current as 2.795 mA

       GPIOA IDR: 0x107F

 

So, the things I can't understand are why:

 - Why I see 165 uA of extra current if the digital  frontend (Schmitt trigger) is disabled?

 - Why i see the input data register of GPIOA reflecting on pin 12 the state of the input voltage if the digital  frontend is disabled? The reference manual (6.3.12, figure 18) says that the input should be read as 0

 

SarcasticLama_0-1747670460295.png

 

 

Also the bits of GPIOA IDR related to other pins don't look correct if I'm not missing anything: for example PA0 is set as analog (watching the same MODER register value as before) but into the IDR it is set to 1.

 

Am I missing something or the pins that should be set as unconnected are somehow left with the digital input stage enabled?

 

Thanks a lot

SarcasticLama