Unable to use IS_xxx_xCLK macros in a preprocesor directives
Describe the set-up
- Issue encountered while programming NUCLEO-H723ZG
- compiler: arm-none-eabi-gcc 10.3.1 20210824 (release)
Describe the bug Due to type casting in the bit definitions of the clock dividers, for example RCC_D1CFGR_HPRE_DIV1 (file stm32h723xx.h: 14596)
#define RCC_D1CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< AHB3 Clock not divided */
macros like for example IS_RCC_HCLK(HCLK) (file stm32h7xx_hal_rcc.h: 8112)
#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_HCLK_DIV1) || ((HCLK) == RCC_HCLK_DIV2) || \
((HCLK) == RCC_HCLK_DIV4) || ((HCLK) == RCC_HCLK_DIV8) || \
((HCLK) == RCC_HCLK_DIV16) || ((HCLK) == RCC_HCLK_DIV64) || \
((HCLK) == RCC_HCLK_DIV128) || ((HCLK) == RCC_HCLK_DIV256) || \
((HCLK) == RCC_HCLK_DIV512))
cannot be used within a preprocessor directives.
Here is an example code, that generates the preprocessor error:
#if !IS_RCC_HCLK(RCC_HCLK_DIV2)
#error "AHB clock divider is invalid"
#endif
And here is the preprocessor error itself:
Error: In file included from repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/ext/Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h7xx.h:167,
from repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/ext/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h:29,
from repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/ext/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h:28,
from repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/clock_stm32h7xx.c:27:
repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/clock_stm32h7xx.c: In function 'SystemClock_Config':
repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/ext/Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h723xx.h:14596:59: error: missing binary operator before token "0x00000000"
14596 | #define RCC_D1CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< AHB3 Clock not divided */
| ^~~~~~~~~~
repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/ext/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h:379:38: note: in expansion of macro 'RCC_D1CFGR_HPRE_DIV1'
379 | #define RCC_HCLK_DIV1 RCC_D1CFGR_HPRE_DIV1
| ^~~~~~~~~~~~~~~~~~~~
repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/ext/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h:8112:39: note: in expansion of macro 'RCC_HCLK_DIV1'
8112 | #define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_HCLK_DIV1) || ((HCLK) == RCC_HCLK_DIV2) || \
| ^~~~~~~~~~~~~
repos/apache-mynewt-core/hw/mcu/stm/stm32h7xx/src/clock_stm32h7xx.c:214:6: note: in expansion of macro 'IS_RCC_HCLK'
214 | #if !IS_RCC_HCLK(RCC_HCLK_DIV2)
| ^~~~~~~~~~~
How To Reproduce It seems like just getting rid of the type cast in those bit definitions will solve the problem, as without typecasting the preprocessor will recognize the binary operators and execute the macros. So all of the bit definitions of clock dividers should look for example like this:
#define RCC_D1CFGR_HPRE_DIV1 (0x00000000UL) /*!< AHB3 Clock not divided */
Note that this is only an example and this way of defining clock dividers should be applied in all defines used in IS_xxx_xCLK macros in order for them to work properly within preprocessor directives.
ST Internal Reference: 136605