Page 1 of 2
STM32F070x6 hard faults while initializing GPIOD
Posted: Tue Aug 14, 2018 11:13 pm
by apmorton
According to the stm32_registry.h STM32F070x6 and STM32F070xB series parts are considered identical.
This is apparently not the case, although I can find no documentation from ST on the subject.
Parts in the STM32F070x6 series will hard fault when accessing any registers in GPIOD.
Parts in the STM32F070xB series work as expected.
https://github.com/ChibiOS/ChibiOS/blob ... ry.h#L1252
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Wed Aug 15, 2018 9:10 am
by Jacon
apmorton wrote:...although I can find no documentation from ST on the subject. ...
You (& Giovanni) should look into ST's datasheet:
https://www.st.com/resource/en/datasheet/stm32f070c6.pdfTable 1 on page 10 explain all differences, including lack of high GPIO's in '6s...
Error in registry.h is without question, BTW

Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Wed Aug 15, 2018 6:38 pm
by apmorton
to the contrary, that table shows both the STM32F070C6 and STM32F070CB parts as having the same number of GPIO (37) and being available in the same package (LQFP48).
Later in the datasheet they do show that PD2 (the only pin on PD in the entire series of chips) is only available on the LQFP64 packages.
However, it appears that GPIOD is actually implemented in silicon on the STM32F070CB part and *not* on the STM32F070C6 part - even though neither part actually exposes any pins on the port.
There is without question an issue in the chibios registry - since without modification chibios simply doesn't function on the STM32F070C6 part.
However, I think the blame is squarely in ST's corner on this one due to the incredibly subtle difference between the parts and lack of documentation on the subject.
I would not be surprised if this is a silicon errata that ST wasn't aware of since its not something that would come up with their own software. STM32CubeMX only generates init code for GPIO's that are used, and you can't use PD2 on either of these parts since there is no pin for it.
It is possible GPIOD was left on the STM32F070CB unintentionally, or that it was removed from STM32F070C6 unintentionally, because I doubt they intended for this difference to exist. In any case if they did, it should have been more clearly communicated.
In ChibiOS 18.x this can be worked around in your board.c thankfully. In older versions of ChibiOS the only workaround is to edit the registry file.
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Sun Aug 26, 2018 2:14 pm
by Giovanni
Hi,
I committed a tentative fix to the registry, could you confirm it is OK this way? I will back-port afterward.
Giovanni
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Wed Sep 12, 2018 9:14 am
by Cesare
Hi Giovanni,
I am developing with STM32F070F6, working on master branch of git, and I got the same issue as described by
apmorton.
I defined my
board.c and
board.h copying from demo
ST_NUCLEO64_F070RB which use STM32F070RB instead, then in the board file
/os/hal/boards/my_board/board.h I have defined
I can compile successfully but then at boot the debug session gets stuck when GPIOC are initialized and, in fact, GPIOC doesn't exist on STM32F070F6 but exists in STM32F070RB.
Everything works well if I remove this code parts in board.c:
Code: Select all
#if STM32_HAS_GPIOC || defined(__DOXYGEN__)
gpio_setup_t PCData;
#endif
#if STM32_HAS_GPIOD || defined(__DOXYGEN__)
gpio_setup_t PDData;
#endif
Code: Select all
#if STM32_HAS_GPIOC
{VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR,
VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH},
#endif
#if STM32_HAS_GPIOD
{VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR,
VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH},
#endif
Code: Select all
#if STM32_HAS_GPIOC
gpio_init(GPIOC, &gpio_default_config.PCData);
#endif
#if STM32_HAS_GPIOD
gpio_init(GPIOD, &gpio_default_config.PDData);
#endif
I have taken a look to
os/hal/ports/STM32/STM32F0xx/stm32_registry.h when STM32F070x6 and STM32F070xB capabilities are defined.
Code: Select all
/*===========================================================================*/
/* STM32F070x6, STM32F070xB. */
/*===========================================================================*/
#elif defined(STM32F070x6) || defined(STM32F070xB)
/* GPIO attributes.*/
#define STM32_HAS_GPIOA TRUE
#define STM32_HAS_GPIOB TRUE
#define STM32_HAS_GPIOC TRUE
#define STM32_HAS_GPIOD TRUE
#define STM32_HAS_GPIOE FALSE
#define STM32_HAS_GPIOF TRUE
#define STM32_HAS_GPIOG FALSE
#define STM32_HAS_GPIOH FALSE
#define STM32_HAS_GPIOI FALSE
#define STM32_HAS_GPIOJ FALSE
#define STM32_HAS_GPIOK FALSE
The issue is that the above define should depends on the microcontroller package, in fact:
STM32F070F6 is TSSOP (20 pins), has A, B, F ports
STM32F070C6 is LQFP (48 pins), has A, B, C, F ports
STM32F070CB is LQFP (48 pins), has A, B, C, F ports
STM32F070RB is LQFP (64 pins), has A, B, C, D, F ports
At the moment I experienced this issue, despite you have asked to check your tentative to fix the registry. Let me know if I can help you.
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Wed Sep 12, 2018 1:11 pm
by Giovanni
Hi,
Current code is:
Code: Select all
/* GPIO attributes.*/
#define STM32_HAS_GPIOA TRUE
#define STM32_HAS_GPIOB TRUE
#define STM32_HAS_GPIOC TRUE
#if defined(STM32F070x6)
#define STM32_HAS_GPIOD FALSE
#else
#define STM32_HAS_GPIOD TRUE
#endif
#define STM32_HAS_GPIOE FALSE
#define STM32_HAS_GPIOF TRUE
#define STM32_HAS_GPIOG FALSE
#define STM32_HAS_GPIOH FALSE
#define STM32_HAS_GPIOI FALSE
#define STM32_HAS_GPIOJ FALSE
#define STM32_HAS_GPIOK FALSE
You are looking at something else I think.
Giovanni
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Thu Sep 13, 2018 2:34 pm
by Cesare
I understood about the code difference.
When I clone the repository from GitHub, by default, I am on master branch but to get the code you were referring to I need to checkout origin/trunk.
Going back to your tentative to fix the registry, this code unfortunately doesn't solve all cases about STM32F070x6 because STM32F070F6 doesn't have GPIOC.
I guess here the code should handle all specific cases of all subfamilies which might increase the complexity as a maze

.
Code: Select all
/* GPIO attributes.*/
#define STM32_HAS_GPIOA TRUE
#define STM32_HAS_GPIOB TRUE
#define STM32_HAS_GPIOC TRUE
#if defined(STM32F070x6)
#define STM32_HAS_GPIOD FALSE
#else
#define STM32_HAS_GPIOD TRUE
#endif
#define STM32_HAS_GPIOE FALSE
#define STM32_HAS_GPIOF TRUE
#define STM32_HAS_GPIOG FALSE
#define STM32_HAS_GPIOH FALSE
#define STM32_HAS_GPIOI FALSE
#define STM32_HAS_GPIOJ FALSE
#define STM32_HAS_GPIOK FALSE
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Thu Sep 13, 2018 2:39 pm
by Giovanni
Does it not have GPIOC or does it not wire GPIOC to external pins? if the registers are accessible then the code is fine.
Giovanni
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Mon Sep 17, 2018 3:04 pm
by Cesare
Ok I've understood the policy,
so the question is, how can we be sure if a port is not present or is present but not connected?
As reported previously the F0 subfamily I am using is STM32F070x6 to which belong only two packages: TSSOP (port C not available) and LQFP (port C available).
So, TSSOP version should have port C but left connected but practically when I initialize the GPIOC port the debug session gets stuck.
If you are interested in this issues I can do more experiments.
Re: STM32F070x6 hard faults while initializing GPIOD
Posted: Mon Sep 17, 2018 4:07 pm
by Giovanni
Hi,
It is simple, if the silicon does not have a port at all then trying to access it causes an exception. If the code runs then it is fine (it is better to initialize ports even if not wired to outside).
Giovanni