2025-03-29 12:58 AM - edited 2025-03-29 1:01 AM
Hello,
I have designed a custom STM32 module using the STM32H7A3RGT6 microcontroller. In my design, PB9 is connected to an LED, and to verify the module's functionality, I attempted to toggle this LED.
Here’s where the issue arises: According to the STM32H7A3RGT6 reference manual, GPIOB is connected to the AHB4 bus, meaning its peripheral clock should be enabled using RCC_AHB4ENR. The manual specifies an offset of 0x140 for this register. However, when I use this offset in my code, the LED does not toggle, suggesting that the address is incorrect.
Interestingly, when I asked ChatGPT for the correct offset, it provided 0xE0—and when I used this value, the LED toggled successfully!
This raises concerns about the correctness of the reference manual or suggests that I may be missing something. Could you clarify why there is a discrepancy in the RCC_AHB4ENR address?
Here are my codes:
GPIO_DRIVER.H Code
#ifndef INC_STM32H7A3XX_GPIO_DRIVER_H_
#define INC_STM32H7A3XX_GPIO_DRIVER_H_
#ifndef GPIO_H
#define GPIO_H
#include <stdint.h>
// Base Addresses
#define RCC_BASE (0x58024400UL)
#define GPIOB_BASE (0x58020400UL)
// RCC Register
#define RCC_AHB4ENR (*(volatile uint32_t *)(RCC_BASE + 0xE0))
#define RCC_GPIOB_EN (1 << 1) // Bit 1 enables GPIOB clock
// GPIO Registers
#define GPIOB_MODER (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
#define GPIOB_ODR (*(volatile uint32_t *)(GPIOB_BASE + 0x14))
// Function Prototypes
void GPIOB_Init(void);
void GPIOB_TogglePin(void);
#endif // GPIO_H
#endif /* INC_STM32H7A3XX_GPIO_DRIVER_H_ */
GPIO_DRIVER.c code
#include "stm32h7a3xx_gpio_driver.h"
// Enable GPIOB clock and configure PB9 as output
void GPIOB_Init(void) {
RCC_AHB4ENR |= RCC_GPIOB_EN; // Enable GPIOB clock
// Set PB9 as output (MODER9 = 01)
GPIOB_MODER &= ~(0b11 << (9 * 2)); // Clear MODER9 bits
GPIOB_MODER |= (0b01 << (9 * 2)); // Set MODER9 to 01 (output)
}
// Toggle PB9
void GPIOB_TogglePin(void) {
GPIOB_ODR ^= (1 << 9); // Toggle PB9
}
LEDtoggle.c code
#include "Stm32h7a3xx_gpio_driver.h"
void delay(void) {
for (volatile int i = 0; i < 500000; i++);
}
int main(void) {
GPIOB_Init(); // Initialize PB9
while (1) {
GPIOB_TogglePin(); // Toggle LED on PB9
delay();
}
return 0;
}
Solved! Go to Solution.
2025-03-29 5:04 AM
Dear @FELM ,
Welcome in our Worldwide STCommunity and very pleased to introduce you to our members, your contribution is very appreciated and very detailed !
Most probably this is a Reference Manual defect/typo in Table 63 - Page 479 of RM0455 Rev11. We created an internal (#ticket number 206465 for future follow-up),
If you look to our HAL CMSIS cmsis-device-h7/Include/stm32h7a3xx.h at master · STMicroelectronics/cmsis-device-h7 · GitHub the RCC definition Registers is inline with your Comments and it seems an offset is created in the Documentation map starting from Address of CKGAENR register
__IO uint32_t CKGAENR; /*!< AXI Clocks Gating Enable Register, Address offset: 0xB0 */
uint32_t RESERVED10[31]; /*!< Reserved, 0xAC-0xAF Address offset: 0xAC */
__IO uint32_t RSR; /*!< RCC Reset status register, Address offset: 0xD0 */
__IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0xD4 */
__IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0xD8 */
__IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0xDC */
__IO uint32_t AHB4ENR; /*!< RCC AHB4 peripheral clock register, Address offset: 0xE0 */
__IO uint32_t APB3ENR; /*!< RCC APB3 peripheral clock register, Address offset: 0xE4 */
__IO uint32_t APB1LENR; /*!< RCC APB1 peripheral clock Low Word register, Address offset: 0xE8 */
__IO uint32_t APB1HENR; /*!< RCC APB1 peripheral clock High Word register, Address offset: 0xEC */
__IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock register, Address offset: 0xF0 */
__IO uint32_t APB4ENR; /*!< RCC APB4 peripheral clock register, Address offset: 0xF4 */
uint32_t RESERVED12; /*!< Reserved, Address offset: 0xF8 */
__IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral sleep clock register, Address offset: 0xFC */
__IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral sleep clock register, Address offset: 0x100 */
__IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral sleep clock register, Address offset: 0x104 */
__IO uint32_t AHB4LPENR; /*!< RCC AHB4 peripheral sleep clock register, Address offset: 0x108 */
__IO uint32_t APB3LPENR; /*!< RCC APB3 peripheral sleep clock register, Address offset: 0x10C */
__IO uint32_t APB1LLPENR; /*!< RCC APB1 peripheral sleep clock Low Word register, Address offset: 0x110 */
__IO uint32_t APB1HLPENR; /*!< RCC APB1 peripheral sleep clock High Word register, Address offset: 0x114 */
__IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral sleep clock register, Address offset: 0x118 */
__IO uint32_t APB4LPENR; /*!< RCC APB4 peripheral sleep clock register, Address offset: 0x11C */
uint32_t RESERVED13[4]; /*!< Reserved, 0x120-0x12C Address offset: 0x120 */
} RCC_TypeDef;
Thank you again.
STOne-32.
2025-03-29 5:04 AM
Dear @FELM ,
Welcome in our Worldwide STCommunity and very pleased to introduce you to our members, your contribution is very appreciated and very detailed !
Most probably this is a Reference Manual defect/typo in Table 63 - Page 479 of RM0455 Rev11. We created an internal (#ticket number 206465 for future follow-up),
If you look to our HAL CMSIS cmsis-device-h7/Include/stm32h7a3xx.h at master · STMicroelectronics/cmsis-device-h7 · GitHub the RCC definition Registers is inline with your Comments and it seems an offset is created in the Documentation map starting from Address of CKGAENR register
__IO uint32_t CKGAENR; /*!< AXI Clocks Gating Enable Register, Address offset: 0xB0 */
uint32_t RESERVED10[31]; /*!< Reserved, 0xAC-0xAF Address offset: 0xAC */
__IO uint32_t RSR; /*!< RCC Reset status register, Address offset: 0xD0 */
__IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0xD4 */
__IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0xD8 */
__IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0xDC */
__IO uint32_t AHB4ENR; /*!< RCC AHB4 peripheral clock register, Address offset: 0xE0 */
__IO uint32_t APB3ENR; /*!< RCC APB3 peripheral clock register, Address offset: 0xE4 */
__IO uint32_t APB1LENR; /*!< RCC APB1 peripheral clock Low Word register, Address offset: 0xE8 */
__IO uint32_t APB1HENR; /*!< RCC APB1 peripheral clock High Word register, Address offset: 0xEC */
__IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock register, Address offset: 0xF0 */
__IO uint32_t APB4ENR; /*!< RCC APB4 peripheral clock register, Address offset: 0xF4 */
uint32_t RESERVED12; /*!< Reserved, Address offset: 0xF8 */
__IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral sleep clock register, Address offset: 0xFC */
__IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral sleep clock register, Address offset: 0x100 */
__IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral sleep clock register, Address offset: 0x104 */
__IO uint32_t AHB4LPENR; /*!< RCC AHB4 peripheral sleep clock register, Address offset: 0x108 */
__IO uint32_t APB3LPENR; /*!< RCC APB3 peripheral sleep clock register, Address offset: 0x10C */
__IO uint32_t APB1LLPENR; /*!< RCC APB1 peripheral sleep clock Low Word register, Address offset: 0x110 */
__IO uint32_t APB1HLPENR; /*!< RCC APB1 peripheral sleep clock High Word register, Address offset: 0x114 */
__IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral sleep clock register, Address offset: 0x118 */
__IO uint32_t APB4LPENR; /*!< RCC APB4 peripheral sleep clock register, Address offset: 0x11C */
uint32_t RESERVED13[4]; /*!< Reserved, 0x120-0x12C Address offset: 0x120 */
} RCC_TypeDef;
Thank you again.
STOne-32.
2025-03-29 6:18 AM
Thank you, this is really helpful.