HAL NAND Overview

Introducing NAND

group NAND_Introduction

  • The NAND hardware abstraction layer provides a set of APIs to interface with NAND flash memory devices via the STM32 Flexible Memory Controller (FMC) peripheral.

  • The NAND HAL driver streamlines common memory operations, such as read and program accesses, by handling peripheral initialization, configuration, command sequencing, and data transfers.

  • This abstraction layer ensures portability and ease of use across different STM32 series.

Module and files

The following diagram illustrates the NAND module and its associated files.

Module and files diagram

Component diagram

The following diagram illustrates the software components involved in the NAND module. It shows the interactions between the user application, HAL drivers, low-level drivers, and the hardware components.


@startuml

!$use_nand_core = 1
!$use_nand_ll = 0
!$use_nand_hal = 1

!$use_api_itf = 1
!$use_hal_itf = 1
!$use_ll_itf = 1
!$use_core_itf = 1

!$use_nand_isr = 1

!$use_hal_service = 1
!$use_hal_rcc = 1
!$use_hal_dma = 0

!$use_ll_rcc = 0

!$core = "FMC" + "_CORE"
!$nand = "NAND"
!$NAND = "FMC"
!$hal_api_itf = "HAL " + $nand + " API"
!$appli_itf = "User Callback"
!$nand_name = "HAL_"+$nand
!$nand_ISR = $nand+" ISR"
!$ll_nand = "LL_"+$nand

!$hal_dma_itf = "HAL_DMA_StartDirectXfer_IT_Opt()\nHAL_DMA_Abort_IT"
!$hal_rcc_itf = "\t\t\tHAL_RCC_GetSYSCLKFreq()\n\t\t\tHAL_RCC_"+$NAND+"_GetClockFreq()\n\t\t\tHAL_RCC_"+$NAND+"_EnableClock()"
!$hal_nand_itf = "Half transfer complete\nTransfer complete\nError callback\nAbort callback"
!$hal_generic_itf = "HAL_GetTick()"
!$ll_nand_itf = "LL " + $nand +" API"
!$nand_xIRQ = $nand+"x_IRQ"

<style>
componentDiagram {
arrow {
FontSize 8
}
interface {
FontSize 8
}
}
</style>

title $nand Software Component Diagram

Package "Application Layer" {

component [Appli]
interface "$appli_itf" as APPLI_Interface
[Appli] -r- APPLI_Interface
}

package "HAL" {
[$nand_name]
!if ($use_hal_dma == 1)
interface "$hal_nand_itf" as HAL_NAND_Interface
[$nand_name] -d- HAL_NAND_Interface
!endif
interface "$hal_api_itf" as HAL_NAND_APPLI_Interface
[$nand_name] -u- HAL_NAND_APPLI_Interface

!if ($use_hal_service == 1)
  [HAL_SERVICE]
  interface "$hal_generic_itf" as HAL_Service_Interface
  [HAL_SERVICE] -r- HAL_Service_Interface
  [$nand_name] -l-( HAL_Service_Interface
!endif

!if ($use_hal_dma == 1)
  [HAL_DMA]
  interface "$hal_dma_itf" as HAL_DMA_Interface
  [HAL_DMA] -u- HAL_DMA_Interface
  [HAL_DMA] -u-( HAL_NAND_Interface
  [$nand_name] --( HAL_DMA_Interface
!endif
!if ($use_hal_rcc == 1)
  [HAL_RCC]
  interface "$hal_rcc_itf" as HAL_RCC_Interface
  [HAL_RCC] -l- HAL_RCC_Interface
  [$nand_name] -r-( HAL_RCC_Interface
!endif
}

[Appli] -d-( HAL_NAND_APPLI_Interface
[$nand_name] -u-( APPLI_Interface
!if ($use_nand_core ==1)
Package "Core Layer" {
[$core]
interface "core API" as Core_api_itf
[$core] -u- Core_api_itf
}
[$nand_name] -d-( Core_api_itf
!endif
package "Low Layer" {

!if ($use_nand_ll == 1)
  [$ll_nand]
  interface "$ll_nand_itf" as LL_NAND_Interface
  [$ll_nand]  -u- LL_NAND_Interface
!endif

!if ($use_nand_isr == 1)
interface "$nand_ISR" as NAND_ISR
[$nand_ISR] -U- NAND_ISR
[$nand_ISR]
!endif

[CMSIS-Devices]
!if ($use_ll_rcc == 1)
  [LL_RCC]
  interface "LL RCC API" as LL_RCC_API
  [LL_RCC] -u- LL_RCC_API
  [HAL_RCC] -d-(LL_RCC_API
!endif

!if ($use_hal_dma == 1)
  [DMA ISR]
  interface "DMA ISR" as DMA_ISR
  [DMA ISR] -u- DMA_ISR
!endif
}

package "HW" {
[STM32_HW]
!if ($use_nand_isr == 1)
interface "$nand_xIRQ" as NANDx_IRQ
[STM32_HW] -u- NANDx_IRQ
!endif
!if ($use_hal_dma == 1)
interface "DMAx_IRQ_Ch" as DMA_IRQ_CH
[STM32_HW] -u- DMA_IRQ_CH
[DMA ISR] -d-( DMA_IRQ_CH
[HAL_DMA] --( DMA_ISR
!endif
}
!if ($use_nand_ll == 1)
[$nand_name] -d-( LL_NAND_Interface
[$ll_nand] .r.> [CMSIS-Devices]: $nand register def
[STM32_HW] <.u. [$ll_nand] : $nand registers R/W
!else
!if ($use_nand_core == 1)
[$core] .d.> [CMSIS-Devices]: $nand register def
[STM32_HW] <.l. [$core] : $nand registers R/W
!else
[$nand_name] .d.> [CMSIS-Devices]: $nand register def
[STM32_HW] <.l. [$nand_name] : $nand registers R/W
!endif
!endif
!if ($use_nand_isr == 1)
[$nand_ISR] -d-( NANDx_IRQ
[$nand_name] -d-( NAND_ISR
!endif
!if ($use_ll_rcc == 1)
[STM32_HW] <.u. [LL_RCC] : RCC registers R/W
!endif

@enduml

Configuration table

The following table lists the configuration defines for the HAL NAND module, specifying their locations, default values, and descriptions:

group NAND_Configuration_Table

Configuration inside the NAND driver

Config defines

Description

Default value

Note

USE_ASSERT_DBG_PARAM

from IDE

None

Allows to use the assert check parameters.

USE_ASSERT_DBG_STATE

from IDE

None

Allows to use the assert check states.

USE_HAL_CHECK_PARAM

from hal_conf.h

0

Allows to use the run-time check parameters.

USE_HAL_NAND_MODULE

from hal_conf.h

1

Allows to use the HAL NAND module.

USE_FMC_CLK_ENABLE_MODEL

from hal_conf.h

HAL_CLK_ENABLE_NO

Allows to enable the FMC clock.

USE_HAL_NAND_USER_DATA

from hal_conf.h

0

Allows to use user data.

USE_HAL_NAND_ECC

from hal_conf.h

1

Allows to use the FMC ECC mechanism computation.

USE_HAL_NAND_EXTRA_CMD

from hal_conf.h

1

Allows to use the extra command for read operation.