HAL CRC Overview

Introducing CRC

group CRC_Introduction

The CRC hardware abstraction layer provides a set of APIs to configure and control the CRC peripheral on STM32 microcontrollers.

The CRC (Cyclic Redundancy Check) calculation unit is used to compute a CRC code from 8-, 16-, or 32-bit data words and a generator polynomial.

Among other applications, CRC-based techniques are used to verify data transmission or storage integrity. Within the scope of functional safety standards, they offer a means of verifying flash memory integrity.

The CRC calculation unit helps compute a software signature at runtime, to be compared with a reference signature generated at link time and stored at a given memory location.

Module and files

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

Module and files diagram

Component diagram

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

@startuml

' The Driver name to be csutomized according to the driver
' Example CRC, I2C, NVM, FLASH, ....
!$ppp = "CRC"

' The HAL driver use a core driver - default value 0
!$use_ppp_core = 0

' When using a core driver : the core driver name
!$core = "XXX" + "_CORE"

' enable/disable LL RCC interfaces depandencies - default value 0
!$use_ll_rcc = 0

' the driver provide an LL layer : default value 1
' Set to 0 if core is set to 1
!if ($use_ppp_core == 1)
!$use_ppp_ll = 0
!else
!$use_ppp_ll = 1
!endif
' the driver provide a HAL Layer : default value 1
!$use_ppp_hal = 1

' the HAL driver use HAL services : default value 1
!$use_hal_service = 0

' the HAL driver use HAL RCC services : default value 1
!$use_hal_rcc = 1

' the HAL driver use HAL DMA services : default value 1
!$use_hal_dma = 0

' The driver use HAL_RCC_PPP_GetClockFreq()
!$use_kernel_clock = 0

' HAL driver use depandencies with generic instead of interfaces
!$use_hal_generic_dep = 0

' The driver use interrupts : defautl value 1
' Example CCB --> no interrupts
!$use_ppp_isr = 0

' The driver use an extented file : default value 0
' Example of Usage NVM, FLASH
!$use_hal_ppp_extend = 0

' The HAL Driver extension name
!$ppp_extend = "ITF"

' The HAL Driver interface
!$hal_api_itf = "HAL " + $ppp + " API"

' The HAL Driver extended interface
!$hal_api_ext_itf = "HAL " + $ppp + " " + $ppp_extend + " API"

' The Use Application Interface
!$appli_itf = $ppp+ " User Callback"
!$appli_ext_itf = "\n" + $ppp+ " " + $ppp_extend + " User Callback"

' The HAL PPP name
!$ppp_name = "HAL_" + $ppp
!$ppp_ext_name = "HAL_" + $ppp+ "_" + $ppp_extend

' The PPP isr
!$ppp_ISR = $ppp + " ISR"
!$ppp_ext_ISR = $ppp+ " " + $ppp_extend + " ISR"

' The LL Driver name
!$ll_ppp = "LL_" + $ppp

!$hal_dma_itf = "HAL_DMA_StartDirectXfer_IT_Opt()\nHAL_DMA_Abort_IT"
!if ($use_kernel_clock == 1)
!if (defined GENERATOR_CRC2_NOT_AVAILABLE)
!$hal_rcc_itf = "\t\t\tHAL_RCC_"+$ppp+"_GetClockFreq()\n\t\t\tHAL_RCC_"+$ppp+"_EnableClock()"
!else
!$hal_rcc_itf = "\t\t\tHAL_RCC_"+$ppp+"_GetClockFreq()\n\t\t\tHAL_RCC_"+$ppp+"1_EnableClock()\n\t\t\tHAL_RCC_"+$ppp+"2_EnableClock()"
!endif
!else
!if <(defined GENERATOR_CRC2_NOT_AVAILABLE)
!$hal_rcc_itf = "\t\t\tHAL_RCC_"+$ppp+"_EnableClock()"
!else
!$hal_rcc_itf = "\t\t\tHAL_RCC_"+$ppp+"1_EnableClock()\n\t\t\tHAL_RCC_"+$ppp+"2_EnableClock()"
!endif
!endif

!$hal_ppp_itf = "Half transfer complete\nTransfer complete\nError callback\nAbort callback"

' HAL Generic interface for the PPP driver
!$hal_generic_itf = "HAL_GetTick()\n"

!$ll_ppp_itf = "LL " + $ppp +" API"

' HW
!$ppp_xIRQ = $ppp+"x_IRQ"

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

title $ppp Software Component Diagram

Package "Application Layer" {

component [Appli]
!if ($use_ppp_isr == 1)
interface "$appli_itf" as APPLI_Interface
[Appli] -r- APPLI_Interface
!if ($use_hal_ppp_extend == 1)
interface "$appli_ext_itf" as APPLI_EXT_Interface
[Appli] -l- APPLI_EXT_Interface
!endif
!endif
}

package "HAL" {
!if ($use_hal_ppp_extend == 1)
[$ppp_name]
[$ppp_ext_name]
!else
[$ppp_name]
!endif
!if ($use_hal_dma == 1)
interface "$hal_ppp_itf" as HAL_PPP_Interface
[$ppp_name] -d- HAL_PPP_Interface
!endif
interface "$hal_api_itf" as HAL_PPP_APPLI_Interface
!if ($use_hal_ppp_extend == 1)
interface "$hal_api_ext_itf" as HAL_PPP_APPLI_EXT_Interface
[$ppp_name] -u- HAL_PPP_APPLI_Interface
[$ppp_ext_name] -u- HAL_PPP_APPLI_EXT_Interface
'[$ppp_ext_name] -u-(
[$ppp_name] ..> [$ppp_ext_name] : <<include>>
!else
[$ppp_name] -u- HAL_PPP_APPLI_Interface
!endif
!if ($use_hal_generic_dep == 0)
!if ($use_hal_service == 1)
[HAL_SERVICE]
interface "$hal_generic_itf" as HAL_Service_Interface
[HAL_SERVICE] -r- HAL_Service_Interface
[$ppp_name] -l-( HAL_Service_Interface
!if ($use_hal_ppp_extend == 1)
[$ppp_ext_name] -r-( HAL_Service_Interface
!endif
!endif
!else
[HAL_SERVICE]
[$ppp_name] ..> [HAL_SERVICE]
!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_PPP_Interface
[$ppp_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
[$ppp_name] -r-( HAL_RCC_Interface
!endif

}

[Appli] -d-( HAL_PPP_APPLI_Interface
!if ($use_hal_ppp_extend == 1)
[Appli] -d-( HAL_PPP_APPLI_EXT_Interface
!endif
!if ($use_ppp_isr == 1)
[$ppp_name] -u-( APPLI_Interface
!if ($use_hal_ppp_extend == 1)
[$ppp_ext_name] -u-( APPLI_EXT_Interface
!endif
!endif
!if ($use_ppp_core ==1)
Package "Core Layer" {
[$core]
interface "core API" as Core_api_itf
[$core] -u- Core_api_itf
}
[$ppp_name] -d-( Core_api_itf
!endif
package "Low Layer" {
[CMSIS-Devices]
!if ($use_ppp_ll == 1)
[$ll_ppp]
interface "$ll_ppp_itf" as LL_PPP_Interface
[$ll_ppp] -u- LL_PPP_Interface
!endif

!if ($use_ppp_isr == 1)
interface "$ppp_ISR" as PPP_ISR
[$ppp_ISR] -u- PPP_ISR
[$ppp_ISR]
!if ($use_hal_ppp_extend == 1)
interface "$ppp_ext_ISR" as PPP_EXT_ISR
[$ppp_ISR] -u- PPP_EXT_ISR
[$ppp_ext_name] -d-( PPP_EXT_ISR
!endif
!endif

!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_ppp_isr == 1)
interface "$ppp_xIRQ" as PPPx_IRQ
[STM32_HW] -u- PPPx_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_ppp_ll == 1)
!if ($use_hal_ppp_extend == 1)
[$ppp_ext_name] -d-( LL_PPP_Interface
!else
[$ppp_name] -d-( LL_PPP_Interface
!endif
[$ll_ppp] .r.> [CMSIS-Devices]: $ppp register def
[STM32_HW] <.u. [$ll_ppp] : $ppp registers R/W
!else
!if ($use_ppp_core == 1)
[$core] .l.> [CMSIS-Devices]: $ppp register def
[STM32_HW] <.u. [$core] : $ppp registers R/W
!else
[$ppp_name] .d.> [CMSIS-Devices]: $ppp register def
[STM32_HW] <.l. [$ppp_name] : $ppp registers R/W
!endif
!endif
!if ($use_ppp_isr == 1)
[$ppp_ISR] -d-( PPPx_IRQ
[$ppp_name] -d-( PPP_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 CRC module, specifying their locations, default values, and descriptions:

group CRC_Configuration_Table

Configuration inside the CRC driver

Config defines

Description

Default value

Note

PRODUCT

from IDE

NA

Example: STM32H7PXX

USE_ASSERT_DBG_PARAM

from IDE

NA

Enable parameter asserts

USE_ASSERT_DBG_STATE

from IDE

NA

Enable state asserts

USE_HAL_CHECK_PARAM

from stm32h7pxx_hal_conf.h

0

Runtime parameter check

USE_HAL_CRC_MODULE

from stm32h7pxx_hal_conf.h

1

Enable the HAL CRC module

USE_HAL_CRC_CLK_ENABLE_MODEL

from stm32h7pxx_hal_conf.h

HAL_CLK_ENABLE_PERIPH_ONLY

Enable HAL_CRC_CLK

USE_HAL_CRC_USER_DATA

from stm32h7pxx_hal_conf.h

0

Allow user data usage