Skip to main content
boiled-potato
Associate
September 7, 2026
Question

[Feature Request / HAL Architecture] Proposal to expose public LL_FMC_Enable() / LL_FMC_Disable() in stm32_ll_fmc.h

  • September 7, 2026
  • 0 replies
  • 2 views

Introduction:

Hello ST Team and Community,

 

Following a recent architectural discussion on the Zephyr RTOS project (recommended by @erwango to be shared here), I would like to submit feedback and a feature proposal regarding how the Flexible Memory Controller (FMC) master controller enable gate is handled in the STM32Cube HAL/LL drivers.

  1. Background: 

On newer STM32 architectures (STM32H7, STM32U5, STM32H5, STM32H7RS, STM32N6, STM32MP1/2), the FMC block contains a master peripheral gate bit (FMC_BCR1_FMCEN or FMC_CFGR_FMCEN) which must be asserted for external bus transactions to occur.

 

Currently in the STM32Cube firmware:

  • There is no standalone HAL_FMC_Init() or public LL_FMC_Enable() API.
  • The master gate is only asserted  via the private macro __FMC_ENABLE() inside:

  HAL_SRAM_Init()

  HAL_SDRAM_Init()

  HAL_NOR_Init()

 

  1. Inversion of responsibility:

    • While this chip-centric approach works seamlessly in standard STM32CubeMX bare-metal projects with discrete SRAM/SDRAM chips, it creates architectural anti-pattern in modular operating systems (like Zephyr or Linux).
    • In OS driver tree, the parent bus controller driver typically configures clocks and pinmux and powers on the IP block, while child drivers configure their individual chip selects (MBKEN) and timings.
    • Currently, the parent controller cannot power on the bus without calling into a child memory module or directly modifying raw CMSIS bits, which is not a good from layered architecture perspective.

       
  2. Proposed Improvement: Public Low-Layer API in stm32_ll_fmc.h

     

    Could the ST software team consider officially exposing inline public macros or functions in the Low-Layer (LL) driver headers (e.g. stm32h7xx_ll_fmc.h, stm32h5xx_ll_fmc.h, etc.)?

     

    For example:

    /**

      * @brief  Enable the FMC Peripheral globally.

      * @param  None

      * @retval None

      */

    __STATIC_INLINE void LL_FMC_Enable(void)

    {

    #if defined(FMC_CFGR_FMCEN)

      SET_BIT(FMC_Bank1_R->CFGR, FMC_CFGR_FMCEN);

    #elif defined(FMC_BCR1_FMCEN)

      SET_BIT(FMC_Bank1_R->BTCR[0], FMC_BCR1_FMCEN);

    #endif

    }

     

    /**

      * @brief  Disable the FMC Peripheral globally.

      * @param  None

      * @retval None

      */

    __STATIC_INLINE void LL_FMC_Disable(void)

    {

    #if defined(FMC_CFGR_FMCEN)

      CLEAR_BIT(FMC_Bank1_R->CFGR, FMC_CFGR_FMCEN);

    #elif defined(FMC_BCR1_FMCEN)

      CLEAR_BIT(FMC_Bank1_R->BTCR[0], FMC_BCR1_FMCEN);

    #endif

    }

     

  3. Key Benefits to the ST Ecosystem

     

    • 100% Backward Compatible: Existing HAL_SRAM_Init() and HAL_SDRAM_Init() calls continue to work completely untouched.
    • Clean OS Integration: Operating systems and advanced firmware projects can gate the FMC block at the bus controller layer cleanly through the official LL interface, without resorting to private macros or unabstracted cmsis register manipulation.
    • First-Class Support for Displays and Custom Hardware: Gives developers an official, clean path to initialize the FMC parallel bus when not using traditional memory chips.