HAL ADC Use Cases

HAL ADC Handle Initialization

@startuml
'skinparam handwritten true
title: Initialization

' Fix order of each column
participant "User Application" as appli
participant "HAL GENERIC" as GENERIC
participant "HAL RCC" as RCC
participant "HAL GPIO" as GPIO
participant "HAL CORTEX\n(NVIC)" as CORTEX
participant "HAL DMA" as DMA
participant "<font color=green><b>HAL ADC</b></font>" as ADC

appli->GENERIC : HAL_Init()
note right
Required to initialize HAL delay services,
used for time out in HAL ADC driver
end note
GENERIC --> appli
appli->RCC : Configure system clock
RCC --> appli

note across
Potential use case: Two ADC handles initialized
and corresponding to two ADC instances (noted **ADC_a** and **ADC_b** below) belonging to the same ADC common instance.
Each ADC instance must have its peripherals dependencies configured (kernel clock, DMA channel, ...)
end note

group#LemonChiffon #LightYellow Peripherals dependencies initialization

opt#lightgrey #LightYellow if USE_HAL_ADC_CLK_ENABLE_MODEL == HAL_CLK_ENABLE_NO
appli->RCC : Enable ADC kernel clock
RCC --> appli
end

opt#lightgrey #LightYellow if GPIO(s) needed
appli->GPIO : Initialization of GPIO(s)
GPIO-->appli
end

opt#lightgrey #LightYellow if interrupt needed
appli->CORTEX : Enable needed interrupt
CORTEX-->appli
end

opt#lightgrey #LightYellow if use DMA
appli->DMA : Initialization of DMA
DMA-->appli
end

end

group#LightBlue #AliceBlue ADC initialization
appli->ADC : HAL_ADC_Init(<handle **ADC_a**>)
opt#lightgrey #AliceBlue if USE_HAL_ADC_CLK_ENABLE_MODEL != HAL_CLK_ENABLE_NO
ADC->RCC : Enable **ADC_a** kernel clock
RCC --> ADC
end
ADC --> appli

opt#lightgrey #AliceBlue if multiple ADC instances used
appli->ADC : HAL_ADC_Init(<handle **ADC_b**>)
opt#lightgrey #AliceBlue If USE_HAL_ADC_CLK_ENABLE_MODEL != HAL_CLK_ENABLE_NO
ADC->RCC : Enable **ADC_b** kernel clock
RCC --> ADC
end
ADC --> appli

appli->ADC : HAL_ADC_SetLinkNextHandle(<handle **ADC_a**>, <handle **ADC_b**>)
ADC --> appli
end

end

@enduml

Called functions:

HAL ADC Deinitialization

@startuml

title: Deinitialization

participant "User application" as appli
participant "HAL RCC" as RCC
participant "HAL GPIO" as GPIO
participant "HAL CORTEX\n(NVIC)" as CORTEX
participant "HAL DMA" as DMA
participant "<font color=green><b>HAL ADC</b></font>" as ADC

group#LightBlue #AliceBlue ADC deinitialization
appli->ADC : HAL_ADC_DeInit()
appli<--ADC
end

group#LemonChiffon #LightYellow Peripherals dependencies deinitialization

appli->RCC : Disable ADC kernel clock
RCC --> appli

opt#lightgrey if use DMA
appli->DMA : Deinitialization of DMA
DMA-->appli
end

opt#lightgrey if interrupt enabled
appli->CORTEX : Disable enabled interrupt
CORTEX-->appli
end

opt#lightgrey if GPIO(s) configured
appli->GPIO : DeInitialization of GPIO(s)
GPIO-->appli
end

end

@enduml

Called functions:

ADC Basic Operation: Polling

@startuml
title: ADC basic operation using programming model: polling

participant "User Application" as appli
participant "<font color=green><b>HAL ADC</b></font>" as ADC

group#LightBlue #AliceBlue Initialization
appli->ADC : HAL ADC and peripherals dependencies initialization
note right
Refer to sequence diagram "Initialization"
end note
return
end

group#TECHNOLOGY #HoneyDew ADC configuration
appli->ADC : HAL_ADC_SetConfig()
ADC->ADC : Case multiple ADC instances:\ncheck cross instances compliance
ADC->appli
appli->ADC : HAL_ADC_REG_SetConfig()
note right
Can be bypassed to use minimalist configuration:
trigger SW start, 1 channel (HW defaut setup)
end note
return
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel()
return
end
end

group#Bisque #Linen ADC operation
appli->ADC : HAL_ADC_Start()
note right
From this point, ADC internal analog HW enable
(inducing slight current consumption)
end note
return
appli->ADC : HAL_ADC_Calibrate()
return
loop#lightgrey Possible multiple iterations
appli->ADC : HAL_ADC_REG_<color:red>StartConv</color>()
note right
Conversion trigger:
- SW start: function to call for each conversion
- from another peripheral (timer, ...): function to call once
end note
return
appli->ADC : HAL_ADC_REG_PollForConv()
return
appli->ADC : HAL_ADC_REG_GetValue()
ADC --> appli: Data 32 bits
opt#lightgrey if conversion trigger not SW start (from antoher peripheral: timer, ...)
appli->ADC : HAL_ADC_REG_<color:red>StopConv</color>()
return
end
end
appli->ADC : HAL_ADC_Stop()
return
end

group#LightBlue #AliceBlue Denitialization
appli->ADC : HAL ADC and peripherals dependencies deinitialization
note right
Refer to sequence diagram "Deinitialization"
end note
return
end

@enduml

Called functions:

ADC Basic Operation: Interruption

@startuml
title: ADC basic operation using programming model: interruption

participant "User Application\n(thread mode)" as appli
participant "User Application\n(handler mode)" as appli_IRQ
participant "<font color=green><b>HAL ADC</b></font>" as ADC
participant "System HW interruption" as interruption

group#LightBlue #AliceBlue Initialization
appli->ADC : HAL ADC and peripherals dependencies initialization
note right
Refer to sequence diagram "Initialization"
end note
return
end

group#TECHNOLOGY #HoneyDew ADC configuration
appli->ADC : HAL_ADC_SetConfig()
ADC->ADC : Case multiple ADC instances:\ncheck cross instances compliance
ADC->appli
appli->ADC : HAL_ADC_REG_SetConfig()
return
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel()
return
end
end

group#Bisque #Linen ADC operation
appli->ADC : HAL_ADC_Start()
note right
From this point, ADC internal analog HW enable
(inducing slight current consumption)
end note
return
appli->ADC : HAL_ADC_Calibrate()
return

loop#lightgrey Possible multiple iterations
appli->ADC : HAL_ADC_REG_<color:red>StartConv_IT</color>() / _IT_Opt()
note right
Conversion trigger:
- SW start: function to call for each conversion
- from another peripheral (timer, ...): function to call once
end note
return
ADC->ADC : Enable ADC selected interruptions\nEnable ADC conversion trigger
interruption <[#red]-x? : <font color=red><b>ADC IRQ event
interruption -> appli_IRQ : ADCx_IRQHandler()
activate appli_IRQ #DarkSalmon
appli_IRQ -> ADC : HAL_ADC_IRQHandler()
note right
Optimized IRQ handlers available for
specific processes: HAL_ADC_IRQHandler_AWD(), ...
end note
return
ADC -> ADC : Clear flag
ADC -> appli_IRQ: HAL_ADC_REG_UnitaryConvCpltCallback()
appli_IRQ->ADC : HAL_ADC_REG_GetValue()
ADC --> appli_IRQ: Data 32 bits
appli_IRQ -> interruption : (return from ISR)
deactivate appli_IRQ
opt#lightgrey if conversion trigger not SW start (from antoher peripheral: timer, ...)
appli->ADC : HAL_ADC_REG_<color:red>StopConv_IT</color>()
return
end
end
appli->ADC : HAL_ADC_Stop()
return
end

group#LightBlue #AliceBlue Denitialization
appli->ADC : HAL ADC and peripherals dependencies deinitialization
note right
Refer to sequence diagram "Deinitialization"
end note
return
end

@enduml

Called functions:

ADC Basic Operation: DMA

@startuml
title: ADC basic operation using programming model: data transfer by DMA

participant "User Application\n(thread mode)" as appli
participant "User Application\n(handler mode)" as appli_IRQ
participant "<font color=green><b>HAL ADC</b></font>" as ADC
participant "<font color=green><b>HAL DMA</b></font>" as DMA
participant "System HW interruption" as interruption

group#LightBlue #AliceBlue Initialization
appli->ADC : HAL ADC and peripherals dependencies initialization
note right
Refer to sequence diagram "Initialization"
end note
return
end

group#TECHNOLOGY #HoneyDew ADC configuration
appli->ADC : HAL_ADC_SetConfig()
ADC->ADC : Case multiple ADC instances:\ncheck cross instances compliance
ADC->appli
appli->ADC : HAL_ADC_REG_SetConfig()
return
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel()
return
end
end

group#Bisque #Linen ADC operation
appli->ADC : HAL_ADC_Start()
note right
From this point, ADC internal analog HW enable
(inducing slight current consumption)
end note
return
appli->ADC : HAL_ADC_Calibrate()
return

loop#lightgrey Possible multiple iterations
appli->ADC : HAL_ADC_REG_<color:red>StartConv_DMA</color>(<handle>, <buff_adr>, <buff_size>) / _DMA_Opt()
note right
Conversion trigger:
- SW start: function to call for the first conversion,
  then iterate with calls of HAL_ADC_REG_StartConv)
- from another peripheral (timer, ...): function to call once
end note
return
ADC->ADC : Enable ADC selected interruptions\nEnable DMA request\nEnable ADC conversion trigger
interruption <[#red]-x? : <font color=red><b>DMA IRQ event\n(transfer complete)
interruption -> appli_IRQ : DMAx_IRQHandler()
activate appli_IRQ #DarkSalmon
appli_IRQ -> DMA : HAL_DMA_IRQHandler()
DMA -> DMA : Clear flag
DMA->ADC : Callback function pointer
ADC -> appli_IRQ: HAL_ADC_REG_DataTransferCpltCallback()
appli_IRQ -> appli_IRQ : User appli processing
appli_IRQ -> interruption : (return from ISR)
deactivate appli_IRQ
opt#lightgrey if conversion trigger not SW start (from antoher peripheral: timer, ...)
appli->ADC : HAL_ADC_REG_<color:red>StopConv_DMA</color>()
return
end
end
appli->ADC : HAL_ADC_Stop()
return
end

group#LightBlue #AliceBlue Denitialization
appli->ADC : HAL ADC and peripherals dependencies deinitialization
note right
Refer to sequence diagram "Deinitialization"
end note
return
end

@enduml

Called functions:

ADC Features Operation: All Config

@startuml
title: ADC features operation: use all configuration features

participant "User Application" as appli
participant "<font color=green><b>HAL ADC</b></font>" as ADC

group#LightBlue #AliceBlue Initialization
appli->ADC : HAL ADC and peripherals dependencies initialization
note right
Refer to sequence diagram "Initialization"
end note
return
end

group#TECHNOLOGY #HoneyDew ADC configuration
appli->ADC : HAL_ADC_SetConfig()
ADC->ADC : Case multiple ADC instances:\ncheck cross instances compliance
ADC->appli
appli->ADC : HAL_ADC_SetConfig<color:red>PostProcessing</color>()
return
appli->ADC : HAL_ADC_SetConfig<color:red>LowPower</color>()
return
appli->ADC : HAL_ADC_REG_SetConfig()
return
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel()
return
end
appli->ADC : HAL_ADC_SetConfig<color:red>AnalogWD</color>()
return
appli->ADC : HAL_ADC_SetConfig<color:red>OverSampling</color>()
return
appli->ADC : HAL_ADC_SetConfig<color:red>Offset</color>()
return
end

group#Bisque #Linen ADC operation
appli->ADC : HAL ADC conversion management
note right
Refer to sequence diagrams "ADC basic operation"
end note
end

group#LightBlue #AliceBlue Denitialization
appli->ADC : HAL ADC and peripherals dependencies deinitialization
note right
Refer to sequence diagram "Deinitialization"
end note
return
end

@enduml

ADC Features Operation: Groups Regular and Injected

@startuml

title: ADC features operation: groups regular and injected

note across
Example using programming model polling. Can also be done with interruption or data transfer by DMA.
end note

participant "User Application" as appli
participant "<font color=green><b>HAL ADC</b></font>" as ADC

group#LightBlue #AliceBlue Initialization
appli->ADC : HAL ADC and peripherals dependencies initialization
note right
Refer to sequence diagram "Initialization"
end note
return
end

group#TECHNOLOGY #HoneyDew ADC configuration
appli->ADC : HAL_ADC_SetConfig()
ADC->ADC : Case multiple ADC instances:\ncheck cross instances compliance
ADC->appli
appli->ADC : HAL_ADC_REG_SetConfig()
return
appli->ADC : HAL_ADC_INJ_SetConfig()
return
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel()
return
end
end

group#Bisque #Linen ADC operation
appli->ADC : HAL_ADC_Start()
note right
From this point, ADC internal analog HW enable
(inducing slight current consumption)
end note
return
appli->ADC : HAL_ADC_Calibrate()
return
loop#lightgrey Possible multiple iterations
appli->ADC : HAL_ADC_<color:red>REG</color>_StartConv()
return
appli->ADC : HAL_ADC_<color:red>INJ</color>_StartConv()
note right
Operation on ADC groups regular injected
are independent
(calls order as example, can be changed)
end note
return
appli->ADC : HAL_ADC_<color:red>REG</color>_PollForConv()
return
appli->ADC : HAL_ADC_<color:red>INJ</color>_PollForConv()
return
appli->ADC : HAL_ADC_<color:red>REG</color>_GetValue()
ADC --> appli: Data 32 bits
appli->ADC : HAL_ADC_<color:red>INJ</color>_GetValue()
ADC --> appli: Data 32 bits
opt#lightgrey if conversion trigger not SW start (from antoher peripheral: timer, ...)
appli->ADC : HAL_ADC_<color:red>REG</color>_StopConv()
return
end
opt#lightgrey if conversion trigger not SW start (from antoher peripheral: timer, ...)
appli->ADC : HAL_ADC_<color:red>INJ</color>_StopConv()
return
end
end
appli->ADC : HAL_ADC_Stop()
return
end

group#LightBlue #AliceBlue Denitialization
appli->ADC : HAL ADC and peripherals dependencies deinitialization
note right
Refer to sequence diagram "Deinitialization"
end note
return
end

@enduml

ADC Features Operation: Multimode Single Buffer

@startuml
title: ADC features operation: multimode\n(case single buffer: data transfer using single DMA channel for all ADC instances)

participant "User Application\n(thread mode)" as appli
participant "User Application\n(handler mode)" as appli_IRQ
participant "<font color=green><b>HAL ADC</b></font>" as ADC
participant "HAL DMA" as DMA
participant "System HW interruption" as interruption

note across #Bisque
Requirement for this use case: Two ADC handles initialized
and corresponding to two ADC instances (noted **ADC_a** and **ADC_b** below) belonging to the same ADC common instance.
end note
note across
In diagram delow: By default, if no argument specified in HAL ADC functions, argument can be handle of **ADC_a** or handle of **ADC_b**.
end note

group#LightBlue #AliceBlue Initialization
appli->ADC : HAL ADC and peripherals dependencies initialization
note right
Refer to sequence diagram "Initialization".
A single DMA channel is configured.
end note
return
appli->ADC : HAL_ADC_SetLinkNextHandle(<handle **ADC_a**>, <handle **ADC_b**>)
ADC --> appli
end

group#TECHNOLOGY #HoneyDew ADC configuration
appli->ADC : HAL_ADC_MM_SetConfig()
return
appli->ADC : HAL_ADC_REG_SetConfig()
return
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel(<handle **ADC_a**>)
return
end
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel(<handle **ADC_b**>)
return
end
end

group#Bisque #Linen ADC operation
appli->ADC : HAL_ADC_MM_Start()
note right
From this point, ADC internal analog HW enable
(inducing slight current consumption)
end note
ADC -> ADC : Enable all relevant ADC instances
appli->ADC : HAL_ADC_MM_StartCalibration()
return

loop#lightgrey Possible multiple iterations
appli->ADC : <color:red>HAL_ADC_MM_REG_StartConv_DMA</color>(<handle>, <buff_adr>, <buff_size>) / _DMA_Opt()
note right
Conversion trigger:
- SW start: function to call for the first conversion,
  then iterate with calls of HAL_ADC_MM_REG_StartConv)
- from another peripheral (timer, ...): function to call once
end note
return
ADC->ADC : Enable ADC selected interruptions\nEnable DMA request\nEnable ADC conversion trigger
interruption <[#red]-x? : <font color=red><b>DMA IRQ event\n(transfer complete)
interruption -> appli_IRQ : DMAx_IRQHandler()
activate appli_IRQ #DarkSalmon
activate appli_IRQ #DarkSalmon
appli_IRQ -> DMA : HAL_DMA_IRQHandler()
DMA -> DMA : Clear flag
DMA->ADC : Callback function pointer
ADC -> appli_IRQ: HAL_ADC_REG_DataTransferCpltCallback()
appli_IRQ -> appli_IRQ : User appli processing
appli_IRQ -> interruption : (return from ISR)
deactivate appli_IRQ
deactivate appli_IRQ
opt#lightgrey if conversion trigger not SW start (from antoher peripheral: timer, ...)
appli->ADC : <color:red>HAL_ADC_MM_REG_StopConv_DMA</color>()
return
end
end
appli->ADC : HAL_ADC_MM_Stop()
return
end

group#LightBlue #AliceBlue Denitialization
appli->ADC : HAL ADC and peripherals dependencies deinitialization
note right
Refer to sequence diagram "Deinitialization"
end note
return
end

@enduml

ADC Features Operation: Multimode

@startuml
title: ADC advanced operation: multimode multi buffer\n(data transfer using a DMA channel for each ADC instance)

participant "User Application\n(thread mode)" as appli
participant "User Application\n(handler mode)" as appli_IRQ
participant "<font color=green><b>HAL ADC</b></font>" as ADC
participant "HAL DMA" as DMA
participant "System HW interruption" as interruption

note across #Bisque
Requirement for this use case: Two ADC handles initialized
and corresponding to two ADC instances (noted **ADC_a** and **ADC_b** below) belonging to the same ADC common instance.
end note
note across
In diagram delow: By default, if no argument specified in HAL ADC functions, argument can be handle of **ADC_a** or handle of **ADC_b**.
end note

group#LightBlue #AliceBlue Initialization
appli->ADC : HAL ADC and peripherals dependencies initialization
note right
Refer to sequence diagram "Initialization"
Two DMA channels are configured.
end note
return
appli->ADC : HAL_ADC_SetLinkNextHandle(<handle **ADC_a**>, <handle **ADC_b**>)
ADC --> appli
end

group#TECHNOLOGY #HoneyDew ADC configuration
appli->ADC : HAL_ADC_MM_SetConfig()
return
appli->ADC : HAL_ADC_REG_SetConfig()
return
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel(<handle **ADC_a**>)
return
end
loop#lightgrey For each ADC channel to be configured
appli->ADC : HAL_ADC_SetConfigChannel(<handle **ADC_b**>)
return
end
loop#lightgrey For each ADC instance
appli->ADC : <color:red>HAL_ADC_MM_REG_SetConfigMultiBufferDMA</color>(<handle>, <buff_adr>, <buff_size>)
return
end
end

group#Bisque #Linen ADC operation
appli->ADC : HAL_ADC_MM_Start()
note right
From this point, ADC internal analog HW enable
(inducing slight current consumption)
end note
ADC -> ADC : Enable all relevant ADC instances
appli->ADC : HAL_ADC_MM_StartCalibration()
return

loop#lightgrey Possible multiple iterations
appli->ADC : <color:red>HAL_ADC_MM_REG_StartConvM_DMA / _DMA_Opt</color>()
note right
Conversion trigger:
- SW start: function to call for the first conversion,
  then iterate with calls of HAL_ADC_MM_REG_StartConv)
- from another peripheral (timer, ...): function to call once
end note
return
ADC->ADC : Enable ADC selected interruptions\nEnable DMA request\nEnable ADC conversion trigger
loop#lightgrey For each ADC instances (and DMA channel)
interruption <[#red]-x? : <font color=red><b>DMA IRQ event\n(transfer complete)
interruption -> appli_IRQ : DMAx_IRQHandler()
activate appli_IRQ #DarkSalmon
appli_IRQ -> DMA : HAL_DMA_IRQHandler()
DMA -> DMA : Clear flag
DMA->ADC : Callback function pointer
ADC -> appli_IRQ: HAL_ADC_REG_DataTransferCpltCallback()
appli_IRQ -> appli_IRQ : User appli processing
appli_IRQ -> interruption : (return from ISR)
deactivate appli_IRQ
end
opt#lightgrey if conversion trigger not SW start (from antoher peripheral: timer, ...)
appli->ADC : <color:red>HAL_ADC_MM_REG_StopConv_DMA</color>()
return
end
end
appli->ADC : HAL_ADC_MM_Stop()
return
end

group#LightBlue #AliceBlue Denitialization
appli->ADC : HAL ADC and peripherals dependencies deinitialization
note right
Refer to sequence diagram "Deinitialization"
end note
return
end

@enduml