Clutchy Clutchy - 1 month ago 12
C Question

C - STM32f4 error on function call when initializing GPIO

I have written a program to initialize GPIO for STM32F4 but for some reason after I try to build this code:

Include ST's header:

#include "stm32f4_discovery.h"


Defining starting adresses of GPIO:

#define GPIOA ((struct GPIO *) 0x40020000)
#define GPIOB ((struct GPIO *) 0x40020400)
#define GPIOC ((struct GPIO *) 0x40020800)
#define GPIOD ((struct GPIO *) 0x40020C00)
#define GPIOE ((struct GPIO *) 0x40021000)
#define GPIOF ((struct GPIO *) 0x40021400)
#define GPIOG ((struct GPIO *) 0x40021800)
#define GPIOH ((struct GPIO *) 0x40021C00)
#define GPIOI ((struct GPIO *) 0x40022000)


Reset and Clock Control:

#define RCC ((uint32_t *) 0x40023830)

#define IN uint8_t 0
#define OUT uint8_t 1
#define NO_PULL uint8_t 0
#define PULL_UP uint8_t 1
#define PULL_DOWN uint8_t 2
#define PUSH_PULL uint8_t 0
#define OPEN_DRAIN uint8_t 1
#define S2MHz uint8_t 0
#define S25MHz uint8_t 1
#define S50MHz uint8_t 2
#define S100MHz uint8_t 3


Basic GPIO struct:

struct GPIO {
uint32_t MODER;
uint32_t TYPER;
uint32_t OSPEEDR;
uint32_t PUPDR;
uint32_t IDR;
uint32_t ODR;
uint16_t BSSR_SET;
uint16_t BSSR_RESET;
};

void Init_GPIO(struct GPIO *GPIO_Type, uint32_t GPIO_Mode, uint8_t in_out, uint8_t pull, uint8_t push_pull, uint8_t freq) {
// Set MODER:

if (in_out) {
GPIO_Type->MODER |= (1 << GPIO_Mode);
GPIO_Type->MODER &= ~(2 << GPIO_Mode);
}
else {
GPIO_Type->MODER &= ~(3 << GPIO_Mode);
}

// Set PUPDR:

if (!pull) {
GPIO_Type->PUPDR &= ~(3 << GPIO_Mode);
}
else if (pull == 1) {
GPIO_Type->PUPDR |= (1 << GPIO_Mode);
GPIO_Type->PUPDR &= ~(2 << GPIO_Mode);
}
else if (pull == 2) {
GPIO_Type->PUPDR |= (2 << GPIO_Mode);
GPIO_Type->PUPDR &= ~(1 << GPIO_Mode);
}

// Set TYPER:

if (push_pull) {
GPIO_Type->TYPER &= ~(1 << GPIO_Mode);
}
else {
GPIO_Type->TYPER |= (1 << GPIO_Mode);
}

// Set OSPEEDR:

if (!freq) {
GPIO_Type->OSPEEDR &= ~(3 << GPIO_Mode);
}
else if (freq == 1) {
GPIO_Type->OSPEEDR |= (1 << GPIO_Mode);
GPIO_Type->OSPEEDR &= (2 << GPIO_Mode);
}
else if (freq == 2) {
GPIO_Type->OSPEEDR |= (2 << GPIO_Mode);
GPIO_Type->OSPEEDR &= ~(1 << GPIO_Mode);
}
else {
GPIO_Type->OSPEEDR &= (3 << GPIO_Mode);
}
}

/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
Init_GPIO(GPIOD, 12, OUT, NO_PULL, PUSH_PULL, S2MHz);
Init_GPIO(GPIOA, 0, IN, NO_PULL, PUSH_PULL, S2MHz);

while (1) {

}
}


I get the following errors which refer to
Init_GPIO
fucntion call:

Error[Pe254]: type name is not allowed C:\Users\..\main.c 93
Error[Pe165]: too few arguments in function call C:\Users\..\main.c 93
Error[Pe018]: expected a ")" C:\Users\..\main.c 93
Error[Pe254]: type name is not allowed C:\Users\..\main.c 94
Error[Pe165]: too few arguments in function call C:\Users\..\main.c 94
Error[Pe018]: expected a ")" C:\Users\..\main.c 94
Error while running C/C++ Compiler

Answer

Your macros IN, OUT etc. are incorrectly defined and when expanded in the calls to Init_GPIO() make no syntactic sense.

Change:

#define IN              uint8_t 0

to

#define IN              ((uint8_t)0)

for example, and similarly for the other similarly define macros.

Alternatively, use the ST Standard Peripheral Library where GPIO initialisation and similar symbols, types and macros to those you have defined are already correctly defined. An example of using the standard peripheral library to access GPIO can be found here. The author refers to it as the CMSIS Library, but strictly it is merely CMSIS compliant but STM32 specific. Other examples are included with the library itself. The library is likely included with you toolchain (which appears to be IAR), but can be downloaded from ST here - you can probably ignore stuff about the library being superseded by STM32Cube unless you want that kind of hand-holding an code bloat and are not likley to ever want to port your code to non STM32 platforms.

Comments