Skip to main content
Visitor II
September 6, 2019
Question

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

  • September 6, 2019
  • 4 replies
  • 1805 views

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.

    This topic has been closed for replies.

    4 replies

    Technical Moderator
    September 26, 2019

    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

    Super User
    September 26, 2019

    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

    Technical Moderator
    September 26, 2019

    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).

    Super User
    September 26, 2019

    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

    Visitor II
    August 31, 2022

    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?

    Technical Moderator
    September 1, 2022

    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