2023-05-22 12:54 PM
Hello,
I have a very simple project to generate 50/60Hz PWM signal with MCO 3MHz output for other HW. So far my code is just turning on the PWM, everything else is generated by CubeMX. But the MCU falls into HardFault when MCO (Pin 4 PF2-NRST) is set as MCO. I found that HAL_GPIO_Init() causes this HatdFault on line 198 where the GPIO base address is 0x5000 0C00 (Port D). If I correct the address to 0x5000 0000 (Port A) by debugger, everything works fine. Apparently there is an error in the calculation of this base address in the HAL library.
Option byte NRST_MODE = 2
Exported project is attached.
2023-05-22 01:47 PM
The listing file suggests it is passing 0x50000000 (0xA0 << 23)
GPIOF passes as 0x50001400
You're enabling PA12
PA0/PA1/PA2/PF2-NRST are bonded to the same, sure there's no conflict there?
I'd probably watch the order of initialization very carefully, especially what's in SystemClock_Config() and then where you bind the pin. Is SYSCFG clock enabled?
2023-05-22 01:57 PM
Problems is how HAL_RCC_MCOConfig() stm32c0xx_hal_rcc.c determines which GPIO port it's supposed to be enabling.
You call
SystemClock_Config();
Before
MX_GPIO_Init();
and HAL_SYSCFG_SetPinBinding(HAL_BIND_SO8_PIN4_PF2);
@Piranha what a festering mess this all is..
2023-05-22 10:47 PM
Thanks for your response. I have no time to do some deeper investigation now. You're probably right about the port address, it also works with the base address of port F and there shouldn't be a conflict. The problem is probably in the function to calculate the base address, but it is a very unintuitive (for me) algorithm and it would take more time to find the source of the problem.
2023-05-23 10:12 AM - edited 2023-11-20 04:52 AM
So I found the bug in the HAL firmware. It is in stm32c0xx_hal_gpio_ex.h file. Line 302 has an ill-defined value because this MCU does not have port D and port E implemented.
// original code
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0uL :\
((__GPIOx__) == (GPIOB))? 1uL :\
((__GPIOx__) == (GPIOC))? 2uL :\
((__GPIOx__) == (GPIOF))? 3uL : 4uL)
//new code
#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0uL :\
((__GPIOx__) == (GPIOB))? 1uL :\
((__GPIOx__) == (GPIOC))? 2uL :\
((__GPIOx__) == (GPIOF))? 5uL : 6uL)
GPIOx port mapping is on the picture from reference manual.
2023-05-23 12:16 PM
@Sara BEN HADJ YAHYA @Imen DAHMEN @Amel NASRI
Can we get some development eyes on this.
The attached project calls these prior to pin binding.
https://github.com/STMicroelectronics/stm32c0xx_hal_driver/blob/main/Src/stm32c0xx_hal_rcc.c#L81
https://github.com/STMicroelectronics/stm32c0xx_hal_driver/blob/main/Src/stm32c0xx_hal_rcc.c#L785
It uses HAL_GPIO_Init() in THREE places, TWO in MX_GPIO_Init() and ONE in HAL_RCC_MCOConfig()
If as the OP notes GPIO_GET_INDEX() is used to determine an address, this will fail too.
2023-05-23 12:24 PM
If I'm not mistaken the GPIO_GET_INDEX() is used ONE place in the code, and that relates to an EXTICR bit map, NOT addresses of the PORT
https://github.com/STMicroelectronics/stm32c0xx_hal_driver/blob/main/Src/stm32c0xx_hal_gpio.c#L248
2023-05-25 06:58 AM
Thank you @Community member for noticing us. I will check this reported issue and take the necessary action for fix.
Imen