Skip to main content
SHoll.1
Associate
March 31, 2020
Question

Multiple "expected expression before 'do'" errors

  • March 31, 2020
  • 11 replies
  • 6399 views

I'm new to STM32 and trying to bring up the STM32L053-DISCO project in STM32CubeIDE. It mostly comiles fine, but has an issue with the HAL defines, such as below:

#define __HAL_RCC_GPIOA_CLK_ENABLE()  do { \

                    __IO uint32_t tmpreg; \

                    SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\

                    /* Delay after an RCC peripheral clock enabling */ \

                    tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\

                    UNUSED(tmpreg); \

                   } while(0)

I really don't see why it is being flagged as an error. I'm sure this must have been seen by someone else...

Best regards,

Stephen

11 replies

TDK
Super User
March 31, 2020

It says *before* do, so before the use of the macro.

"If you feel a post has answered your question, please click ""Accept as Solution""."
SHoll.1
SHoll.1Author
Associate
March 31, 2020

One function call upp from this is:

#define __GPIOA_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE

and before that, this:

#define KEY_BUTTON_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE()

and before that, this:

#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__)   (KEY_BUTTON_GPIO_CLK_ENABLE())

and above that, this:

BUTTONx_GPIO_CLK_ENABLE(Button);

The HAL code is littered with this usage, and it is from a STM sourced project, admittedly written some ago. It must be something obvious but I just don't see what it is.

TDK
Super User
March 31, 2020

Perhaps you can show the code where the compiler is complaining. The code at and a few lines before __HAL_RCC_GPIOA_CLK_ENABLE is used.

"If you feel a post has answered your question, please click ""Accept as Solution""."
SHoll.1
SHoll.1Author
Associate
March 31, 2020

This is where the original function call is from (BUTTONx_GPIO_CLK_ENABLE(Button). It is from the BSP files for the STM32L053-DISCO eval board.

void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)

{

 GPIO_InitTypeDef GPIO_InitStruct;

  

 /* Enable the BUTTON Clock */

 BUTTONx_GPIO_CLK_ENABLE(Button);

  

 if (ButtonMode == BUTTON_MODE_GPIO)

 {

  /* Configure Button pin as input */

  GPIO_InitStruct.Pin = BUTTON_PIN[Button];

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  GPIO_InitStruct.Pull = GPIO_PULLDOWN;

  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;

  HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);

 }

  

 if (ButtonMode == BUTTON_MODE_EXTI)

 {

  /* Configure Button pin as input with External interrupt */

  GPIO_InitStruct.Pin = BUTTON_PIN[Button];

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;

  HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);

   

  /* Enable and set Button EXTI Interrupt to the lowest priority */

  HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 3, 0);

  HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));

 }

}

TDK
Super User
March 31, 2020

The problem is

#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) (KEY_BUTTON_GPIO_CLK_ENABLE())

When this expands, it puts the code you want to execute within parentheses, which leads to invalid syntax. Just replace that line with the appropriate macro, e.g.

__HAL_RCC_GPIOA_CLK_ENABLE();

"If you feel a post has answered your question, please click ""Accept as Solution""."
SHoll.1
SHoll.1Author
Associate
March 31, 2020

So why can't the original code work? It is example code from ST. I would expect the example code to be able to cleanly compile without issue. Is it possibly because a different compiler may have been used? There aren't any compiler dependencies listed in the original code...

TDK
Super User
March 31, 2020

You're probably using different HAL includes than when the code was written. My guess is that at the time, __HAL_RCC_GPIOA_CLK_ENABLE was written as something that could be evaluated, e.g. REG->CR |= VALUE, instead of its current do/while loop.

You haven't really explained where you got the code, so one can only guess.

Here's one BSP_LED_Init example online that I found which does not use the syntax you're using, and which would compile correctly.

int32_t BSP_LED_Init (Led_TypeDef Led)
{
 GPIO_InitTypeDef gpio_init_structure;
 /* Enable the GPIO_LED Clock */
 switch (Led)
 {
 case LED1:
 LED1_GPIO_CLK_ENABLE ();
 break;
 (…)
 case LEDN:
 LEDN_GPIO_CLK_ENABLE ();
 break;
 default:
 break;
}
 /* configure the GPIO_LED pin */
 gpio_init_structure.Pin = LED_PIN [Led];
 gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
 gpio_init_structure.Pull = GPIO_PULLUP;
 gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 HAL_GPIO_Init (LED_PORT [Led], &gpio_init_structure);
 
 HAL_GPIO_WritePin (LED_PORT [Led], LED_PIN [Led], GPIO_PIN_RESET);
 return BSP_ERROR_NONE;
}

 Edit: I misread the code. This probably wouldn't compile either.

"If you feel a post has answered your question, please click ""Accept as Solution""."
SHoll.1
SHoll.1Author
Associate
March 31, 2020

Thanks for your help.

The code was downloaded from here:

https://www.st.com/en/embedded-software/stsw-stm32152.html

SHoll.1
SHoll.1Author
Associate
March 31, 2020

Also, just build the project from STM32CubeMX for the STM32L0538-DISCO and it will try to use the same macros above.

MBake.3
Visitor II
March 15, 2021

I found the same problem. I'm pretty sure the conditional operator doesn't let you declare variables. You also can't put a parenthesis around a do while loop. This change to the HAL code was broke these macros. Looks like the comment says this change was to "Delay after an RCC peripheral clock enabling." I can think of a few better ways to delay than this.

#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
 __IO uint32_t tmpreg; \
 SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
 /* Delay after an RCC peripheral clock enabling */ \
 tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
 UNUSED(tmpreg); \
 } while(0)

So you can either change it. Back to the way it was (you'll need to fix the name and this will probably break other things so don't do it

#define __GPIOA_CLK_ENABLE() (RCC->IOPENR |= (RCC_IOPENR_GPIOAEN))

The right way is the macros:

//#define LEDx_GPIO_CLK_ENABLE(__INDEX__) (((__INDEX__) == 0) ? LED3_GPIO_CLK_ENABLE() : LED4_GPIO_CLK_ENABLE())
#define LEDx_GPIO_CLK_ENABLE(__INDEX__)\
if (__INDEX__ == 0)\
{\
 LED3_GPIO_CLK_ENABLE();\
}else\
{\
 LED4_GPIO_CLK_ENABLE();\
}\
//#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) (KEY_BUTTON_GPIO_CLK_ENABLE())
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) KEY_BUTTON_GPIO_CLK_ENABLE()

File this one under the law of unintended consequences and a reason not to use the ternary operator in macros. You never know who is going to change what is fed into the macro.

LPetr.1
Senior
January 3, 2024

I have found this post from 2021. I have created an empty project for STM32L0538-Discovery using STM32CubeMX and copied the BSP folder from the https://www.st.com/en/embedded-software/stsw-stm32152.html (same as the thread owner).

 

After adding a BSP, I am getting the same errors:

 

12:07:19 **** Incremental Build of configuration Debug for project E-ink ****
make -j16 all 
arm-none-eabi-gcc "../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.c" -mcpu=cortex-m0plus -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L053xx -c -I../Core/Inc -I../Drivers/STM32L0xx_HAL_Driver/Inc -I../Drivers/STM32L0xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32L0xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.d" -MT"Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.o"
arm-none-eabi-gcc "../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery_epd.c" -mcpu=cortex-m0plus -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L053xx -c -I../Core/Inc -I../Drivers/STM32L0xx_HAL_Driver/Inc -I../Drivers/STM32L0xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32L0xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery_epd.d" -MT"Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery_epd.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery_epd.o"
In file included from ../Core/Inc/stm32l0xx_hal_conf.h:188,
 from ../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal.h:29,
 from ../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.h:48,
 from ../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.c:40:
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.c: In function 'BSP_LED_Init':
../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal_rcc.h:724:40: error: expected expression before 'do'
 724 | #define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
 | ^~
../Drivers/STM32L0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h:2829:28: note: in expansion of macro '__HAL_RCC_GPIOB_CLK_ENABLE'
 2829 | #define __GPIOB_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE
 | ^~~~~~~~~~~~~~~~~~~~~~~~~~
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.h:104:49: note: in expansion of macro '__GPIOB_CLK_ENABLE'
 104 | #define LED3_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE()
 | ^~~~~~~~~~~~~~~~~~
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.h:112:71: note: in expansion of macro 'LED3_GPIO_CLK_ENABLE'
 112 | #define LEDx_GPIO_CLK_ENABLE(__INDEX__) (((__INDEX__) == 0) ? LED3_GPIO_CLK_ENABLE() : LED4_GPIO_CLK_ENABLE())
 | ^~~~~~~~~~~~~~~~~~~~
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.c:154:3: note: in expansion of macro 'LEDx_GPIO_CLK_ENABLE'
 154 | LEDx_GPIO_CLK_ENABLE(Led);
 | ^~~~~~~~~~~~~~~~~~~~
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.c: In function 'BSP_PB_Init':
../Drivers/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal_rcc.h:716:40: error: expected expression before 'do'
 716 | #define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
 | ^~
../Drivers/STM32L0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h:2823:28: note: in expansion of macro '__HAL_RCC_GPIOA_CLK_ENABLE'
 2823 | #define __GPIOA_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE
 | ^~~~~~~~~~~~~~~~~~~~~~~~~~
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.h:128:49: note: in expansion of macro '__GPIOA_CLK_ENABLE'
 128 | #define KEY_BUTTON_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()
 | ^~~~~~~~~~~~~~~~~~
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.h:136:50: note: in expansion of macro 'KEY_BUTTON_GPIO_CLK_ENABLE'
 136 | #define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) (KEY_BUTTON_GPIO_CLK_ENABLE())
 | ^~~~~~~~~~~~~~~~~~~~~~~~~~
../Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.c:222:3: note: in expansion of macro 'BUTTONx_GPIO_CLK_ENABLE'
 222 | BUTTONx_GPIO_CLK_ENABLE(Button);
 | ^~~~~~~~~~~~~~~~~~~~~~~
make: *** [Drivers/BSP/STM32L0538-Discovery/subdir.mk:34: Drivers/BSP/STM32L0538-Discovery/stm32l0538_discovery.o] Error 1
make: *** Waiting for unfinished jobs....
"make -j16 all" terminated with exit code 2. Build might be incomplete.

12:07:19 Build Failed. 4 errors, 0 warnings. (took 564ms)

 

As has been mentioned above, the errors could be related the macros 

#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) (KEY_BUTTON_GPIO_CLK_ENABLE())
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (KEY_BUTTON_GPIO_CLK_DISABLE())

 

But is not fully clear to me from the response above what I should replace them with in order to get the project to compile