Search code examples
cmacrosmicrocontrollerstm32f4

Why all other GPIO's are fine with RCC but this one gives error?


I was writing simple GPIO driver for my STM32F446RE and interestingly i have encountered with a problem. So there are macros i'm defining and a struct to hold RCC's registers. Every port of GPIO are pointed to RCC's registers to connect to the proper bus. But GPIOB gives the following error when i'm trying to set the bit to 1. "error: invalid type argument of '->' (have 'int')"

#define GPIOB_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 1)  )

typedef struct{
__vo    uint32_t RCC_CR;                //RCC clock control register
__vo    uint32_t RCC_PLLCFGR;           //RCC PLL configuration register
__vo    uint32_t RCC_CFGR;              //RCC clock configuration register
__vo    uint32_t RCC_CIR;               //RCC clock interrupt register
__vo    uint32_t RCC_AHB1RSTR;          //RCC AHB1 peripheral reset register
__vo    uint32_t RCC_AHB2RSTR;          //RCC AHB2 peripheral reset register
__vo    uint32_t RCC_AHB3RSTR;          //RCC AHB3 peripheral reset register
uint32_t RESERVED0;             //RESERVED
__vo    uint32_t RCC_APB1RSTR;          //RCC APB1 peripheral reset register
__vo    uint32_t RCC_APB2RSTR;          //RCC APB2 peripheral reset register
uint32_t RESERVED1[2];              //RESERVED
__vo    uint32_t RCC_AHB1ENR;           //RCC AHB1 peripheral clock enable register
__vo    uint32_t RCC_AHB2ENR;           //RCC AHB2 peripheral clock enable register
__vo    uint32_t RCC_AHB3ENR;           //RCC AHB3 peripheral clock enable register

__vo    uint32_t RCC_APB1ENR;           //RCC APB1 peripheral clock enable register
__vo    uint32_t RCC_APB2ENR;           //RCC APB2 peripheral clock enable register
uint32_t RESERVED2[2];              //RESERVED
__vo    uint32_t RCC_AHB1LPENR;         //RCC AHB1 peripheral clock enable in low power mode register
__vo    uint32_t RCC_AHB2LPENR;         //RCC AHB2 peripheral clock enable in low power mode register
__vo    uint32_t RCC_AHB3LPENR;         //RCC AHB3 peripheral clock enable in low power mode register
uint32_t RESERVED3;             //RESERVED
__vo    uint32_t RCC_APB1LPENR;         //RCC APB1 peripheral clock enable in low power mode register
__vo    uint32_t RCC_APB2LPENR;         //RCC APB2 peripheral clock enabled in low power mode register
uint32_t RESERVED4[2];              //RESERVED
__vo    uint32_t RCC_BDCR;              //RCC Backup domain control register
__vo    uint32_t RCC_CSR;               //RCC clock control & status register
uint32_t RESERVED5[2];              //RESERVED
__vo    uint32_t RCC_SSCGR;             //RCC spread spectrum clock generation register
__vo    uint32_t RCC_PLLI2SCFGR;        //RCC PLLI2S configuration register
__vo    uint32_t RCC_PLLSAICFGR;        //RCC PLL configuration register
__vo    uint32_t RCC_DCKCFGR;           //RCC Dedicated Clock Configuration Register
__vo    uint32_t CKGATENR;              //RCC clocks gated enable register
__vo    uint32_t DCKCFGR2;              //RCC dedicated clocks configuration register 2


}RCC_RegDef_t;

#define RCC     (RCC_RegDef_t*) RCC_BASEADDR


/*Clock Enable Presets For GPIAOs*/

#define GPIOA_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 0)  )
//#define GPIOB_PCLOCK_EN           (RCC -> RCC_AHB1ENR |= (1 << 1)  )
#define GPIOC_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 2)  )
#define GPIOD_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 3)  )
#define GPIOE_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 4)  )
#define GPIOF_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 5)  )
#define GPIOG_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 6)  )
#define GPIOH_PCLOCK_EN()       (RCC -> RCC_AHB1ENR |= (1 << 7)  )

Solution

  • You need to put parentheses around the replacement text of RCC like this:

    #define RCC ((RCC_RegDef_t*) RCC_BASEADDR)
    

    Expression precedences are such that -> has a higher precedence than the cast.

    With your definition the compiler tries to use the LHS operand of -> as a pointer, but it is an integer.