STM32F070x6 hard faults while initializing GPIOD Topic is solved

Report here problems in any of ChibiOS components. This forum is NOT for support.
apmorton
Posts: 36
Joined: Fri Sep 29, 2017 10:26 am
Been thanked: 17 times

STM32F070x6 hard faults while initializing GPIOD

Post 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
Jacon
Posts: 143
Joined: Wed Dec 08, 2010 7:52 am
Has thanked: 50 times
Been thanked: 5 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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.pdf

Table 1 on page 10 explain all differences, including lack of high GPIO's in '6s...

Error in registry.h is without question, BTW ;)
apmorton
Posts: 36
Joined: Fri Sep 29, 2017 10:26 am
Been thanked: 17 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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
User avatar
Cesare
Posts: 38
Joined: Tue Jul 11, 2017 11:51 am
Has thanked: 4 times
Been thanked: 4 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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

Code: Select all

#define STM32F070x6

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.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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
User avatar
Cesare
Posts: 38
Joined: Tue Jul 11, 2017 11:51 am
Has thanked: 4 times
Been thanked: 4 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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 :roll: .

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
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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
User avatar
Cesare
Posts: 38
Joined: Tue Jul 11, 2017 11:51 am
Has thanked: 4 times
Been thanked: 4 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F070x6 hard faults while initializing GPIOD

Post 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
Post Reply