cancel
Showing results for 
Search instead for 
Did you mean: 

Has the error in the function LL_ADC_SetChannelSingleDiff() been fixed?

WNybe
Associate

The function LL_ADC_SetChannelSingleDiff() in stm32l4xx_ll_adc.h relies on

shifting a 32 bit value 32 postions in order to clear a bit field.

Shifting a word with >= the word size is undefined in the C standard and this 

generates erronous code when compiled with for example gcc 7.2.1 and optimzation -O1.

This error is manifested in the function HAL_ADC_ConfigChannel() when initiating an ADC channel as single-ended it will be initiated as differential.

Complete compiler command used when problem occurred:

arm-none-eabi-gcc-7.2.1.exe -DARM_MATH_CM4 -DSTM32L432xx=1 -D__FPU_PRESENT=1 -D__FPU_USED=1U -mfloat-abi=hard -mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -ffunction-sections -std=c99 -fdata-sections -fverbose-asm -Wall -Wstrict-prototypes -Wdouble-promotion -g -gdwarf-2  -O1 -save-temps -Werror xxxx\stm32l4xx_hal_adc.c

Compiling with optimization -Og generates correct code.

Have tried both STM32Cube_FW_L4_V1.10.0 and STM32Cube_FW_L4_V1.14.0, which have slightly different implementations of "LL_ADC_SetChannelSingleDiff()", though both have undefined behavior according to the C standard, see for example:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

In section 6.5.7 Bitwise shift operators:

If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

6 REPLIES 6
Amel NASRI
ST Employee

Hi @WNybe​ ,

I'll report this issue to our development team who should take relevant actions to fix it.

Thanks for bringing it to our attention.

-Amel

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.

Hi @Amel NASRI​ 

https://community.st.com/s/question/0D50X00009bLP0eSAG/adc-init-bug-with-optimization-o1-stm32l4

That's like more than a year.

Probably that's why Wilhelm fomulated this as a "has it been fixed?" question.

JW

Hi @Community member​ ,

As said by @WNybe​ , an update is done but didn't fixed the issue. I'll report it again.

-Amel

Internal ticket number: 72919 (This is an internal tracking number and is not accessible or usable by customers).

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.

Hi @Amel NASRI​ ,

Sorry for being rough.

Indeed, v1.14 has a different formula, instead of the standard-"violating" (0x7F<<0x20) in v1.12, this time reducing to

MODIFY_REG(ADCx->DIFSEL, Channel & 0x0007FFFF,   (Channel & 0x0007FFFF) & (0x0007FFFF >> (0x7F & 0x18)));

or

MODIFY_REG(ADCx->DIFSEL, Channel & 0x0007FFFF,   (Channel & 0x0007FFFF) & (0x0007FFFF >> (0x7F0000 & 0x18)));

and both should be OK as far as the quoted standard paragraph goes.

@WNybe​ ,

can you please post the disassembly at around the problematic place, preferrably mixed with the C source, exhibiting the problem, i.e. that incorrect value is written into ADCx->DIFSEL ?

Thanks

JW

DBroo.1
Associate III

The problem still exists in STM32Cube_FW_G4_V1.5.1. Has a work-around been posted? Or is the problem now with LL_ADC_GetChannelSingleDiff?

Hi @Community member​ ,

I received an answer from development team in 2019 saying that the problem wasn't reproduced using following configuration at that time:

  • SW4STM32 tool chain v2.8.1
  • gcc version v9.2.1
  • NUCLEO-L412-RB ADC_Sequencer example with compilation optimization option set to -O1 or -Os

In your current situation, could you please create a new thread where you describe your issue with more details (what you face exactly as issue? what are you using as environment? ...)

-Amel

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.