Search code examples
stm32memory-addressgpio

Where is the specific address definition of the GPIO IDR register by STM32Cube resulting files?


I have read through the explanation of the STM32 project produced by the STM32Cube as in this website.

From this website, I have learned that: In the stm32f0xx.h file, for example, the origianl address of GPIOA is already declared by

"#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000U)"

then all the corresponding registers for GPIOA is declared by

"#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)"

By the information above, this head file has already defined the original adress of GPIOA, and declared the existance of the corresponding registers for GPIOA (like, IDR, MODER, ODR, etc).

But these codes have not defined clearly the address of these GPIOA corresponding registers. For example, GPIOA_IDR address should be defined as 0x40020000 + 0x10 = 0x40020010, but I haven't seen such definitions in the head file.

Where can one find the codes, which define the register addresses of the GOIP corresponding registers?


Solution

  • It is clearly defined. The GPIO registers are defined in the struct aliased to the GPIO_TypeDef type.

    The definition from your question just defines the pointer to the struct of type GPIO_TypeDef with address defined by the integer constant GPIOA_BASE. When you dereference this pointer by accessing the structure members the compiler knows where in the memory this particular member is.

    typedef struct
    {
      __IO uint32_t MODER;        /*!< GPIO port mode register,               Address offset: 0x00      */
      __IO uint32_t OTYPER;       /*!< GPIO port output type register,        Address offset: 0x04      */
      __IO uint32_t OSPEEDR;      /*!< GPIO port output speed register,       Address offset: 0x08      */
      __IO uint32_t PUPDR;        /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
      __IO uint32_t IDR;          /*!< GPIO port input data register,         Address offset: 0x10      */
      __IO uint32_t ODR;          /*!< GPIO port output data register,        Address offset: 0x14      */
      __IO uint32_t BSRR;         /*!< GPIO port bit set/reset register,      Address offset: 0x1A */
      __IO uint32_t LCKR;         /*!< GPIO port configuration lock register, Address offset: 0x1C      */
      __IO uint32_t AFR[2];       /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
      __IO uint32_t BRR;          /*!< GPIO bit reset register,               Address offset: 0x28 */
    }GPIO_TypeDef;
    

    so for example if you derefernce the pointer accessing the OSPEEDR register GPIOA -> OSPEEDR = 0x4567; the compiler knows that this member of the struct is at the offset 8 (in bytes - but machine code uses only byte addresses) from the beginning of the struct