cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H5xxLL_ADC.H bug in STM32Cube FW_H5 V1.6.0

JBrown
Associate II

Post edited by ST moderator to be compliant with the ST community rules especially for sharing a code.

The latest Cube H5 package (STM32Cube FW_H5 V1.6.0) has broken the use of ADC2_INP0 with the following changes to LL_ADC_EnableChannel0_GPIO and LL_ADC_DisableChannel0_GPIO in STM32H5xxLL_ADC.H.

 

Previous,

__STATIC_INLINE void LL_ADC_EnableChannel0_GPIO(const ADC_TypeDef *ADCx)
{
  /* Prevent unused argument(s) compilation warning */
  (void)(ADCx);
  SET_BIT(ADC1->OR, ADC_OR_OP0);
}

Current,

__STATIC_INLINE void LL_ADC_EnableChannel0_GPIO(ADC_TypeDef *ADCx)
{
  SET_BIT(ADCx->OR, ADC_OR_OP0);
}
 
Previous,
__STATIC_INLINE void LL_ADC_DisableChannel0_GPIO(const ADC_TypeDef *ADCx)
{
  /* Prevent unused argument(s) compilation warning */
  (void)(ADCx);
  CLEAR_BIT(ADC1->OR, ADC_OR_OP0);
}
 
Current,
__STATIC_INLINE void LL_ADC_DisableChannel0_GPIO(ADC_TypeDef *ADCx)
{
  CLEAR_BIT(ADCx->OR, ADC_OR_OP0);
}
 
According to the reference manual the OP0 bit is applicable to ADC1 only for control of INP0/INN1, which is consistent with the old code. However HAL_ADC_ConfigChannel() does not check that the ADC instance is ADC1 before calling LL_ADC_EnableChannel0_GPIO on CHANNEL_0, which means ADC2->OR bit OP0 is set, which is actually "VDDCORE channel" enable.
 
In current state reads of ADC2 channel 0 ADC give unexpected results; I guess ADC2-CH0 is now reading VDDCORE instead.
1 ACCEPTED SOLUTION

Accepted Solutions
FBL
ST Employee

Hi @JBrown 

 

Thank you for reporting the issue. An internal ticket CDM0060549 is submitted to dedicated team!

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.




Best regards,
FBL

View solution in original post

6 REPLIES 6
TDK
Super User

Looks like someone tried to fix something that wasn't broken. The comments of the function even say this isn't available on ADC2.

Arguably, since this is LL, maybe they shouldn't be holding your hand here and you just can't call this with ADC2 as an argument. LL should not do parameter checking.

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

In this case, it is the HAL that is calling the LL function with the incompatible peripheral.

In stm32h5xx_hal_adc.h,

HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, const ADC_ChannelConfTypeDef *pConfig)

 

No check is made which ADC is being passed,

if ((pConfig->Channel == ADC_CHANNEL_0)
|| ((pConfig->Channel == ADC_CHANNEL_1) && (pConfig->SingleDiff == ADC_DIFFERENTIAL_ENDED)))
{
LL_ADC_EnableChannel0_GPIO(hadc->Instance);
}

full_stack
Associate

手动修改验证,试试呢?

Ah, so then it's a question of whether the bug is in HAL or in LL.

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

The bug is in the LL driver.
When sampling channel 0, ADC1->OR bit 0 must be set regardless of whether ADC1 or ADC2 is sampling the channel.

The real villain here is the reference manual documentation itself, it says:

Bit 0 OP0: Option bit 0
For ADC1:
0: INP0/INN1 GPIO switch control disabled
1: INP0/INN1 GPIO switch control enabled
Note: This option bit must be set to 1 when ADCx_INP0 or ADCx_INN1 channel is selected.
For ADC2:
0: VDDCORE channel disabled
1: VDDCORE channel enabled

Leading you to believe that this only impacts ADC1, and not that both ADC1 and ADC2 depend on it.

FBL
ST Employee

Hi @JBrown 

 

Thank you for reporting the issue. An internal ticket CDM0060549 is submitted to dedicated team!

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.




Best regards,
FBL