summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-03-04 12:33:17 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-10-20 17:57:54 +0200
commit44c8a1777f4a3bd619676c16852cb8764369a8ec (patch)
treed85e571c49271310bc58c7d10d28c4af45ae0cf6
parente39da486b8b8b783ffd9a2159164f047bbeed561 (diff)
bsp/stm32h7: Import from STM32CubeMX-5.6.0
Update #3910.
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal.c1276
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c3713
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_adc_ex.c2492
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_cec.c1001
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_comp.c1250
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_cortex.c533
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_crc.c518
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_crc_ex.c225
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_cryp.c5145
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_cryp_ex.c446
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dac.c1534
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dac_ex.c869
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dcmi.c1227
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dfsdm.c3798
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dfsdm_ex.c135
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dma.c2055
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dma2d.c2167
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dma_ex.c714
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dsi.c2705
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_dts.c823
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c2998
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_eth_ex.c559
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_exti.c877
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_fdcan.c6169
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_flash.c1099
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_flash_ex.c1709
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_gfxmmu.c893
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_gpio.c560
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_hash.c3445
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_hash_ex.c1030
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_hcd.c1648
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_hrtim.c9277
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_hsem.c441
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_i2c.c6635
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_i2c_ex.c339
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_i2s.c1946
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_i2s_ex.c28
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_irda.c2898
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_iwdg.c265
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_jpeg.c4199
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_lptim.c2540
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_ltdc.c2163
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_ltdc_ex.c149
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_mdios.c957
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_mdma.c1901
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_mmc.c3054
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_mmc_ex.c304
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_nand.c2183
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_nor.c1285
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_opamp.c1163
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_opamp_ex.c435
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_ospi.c3068
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_otfdec.c998
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_pcd.c2201
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_pcd_ex.c348
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_pssi.c1798
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_pwr.c868
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_pwr_ex.c2100
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_qspi.c2645
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_ramecc.c692
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_rcc.c1775
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_rcc_ex.c3437
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c927
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_rng_ex.c299
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_rtc.c2144
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_rtc_ex.c3017
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_sai.c2920
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_sai_ex.c135
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_sd.c3942
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_sd_ex.c305
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_sdram.c1312
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_smartcard.c3136
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_smartcard_ex.c494
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_smbus.c2673
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_spdifrx.c1635
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_spi.c3836
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_spi_ex.c229
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_sram.c1113
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_swpmi.c1949
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_tim.c7047
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_tim_ex.c2324
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_uart.c4115
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_uart_ex.c729
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_usart.c3684
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_usart_ex.c538
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_wwdg.c414
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_adc.c1080
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_bdma.c346
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_comp.c296
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_crc.c115
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_crs.c86
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_dac.c349
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_delayblock.c210
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_dma.c423
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_dma2d.c635
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_exti.c458
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_fmc.c1090
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_gpio.c307
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_hrtim.c83
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_i2c.c243
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_lptim.c355
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_lpuart.c283
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_mdma.c782
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_opamp.c230
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_pwr.c82
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_rcc.c1770
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_rng.c158
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_rtc.c894
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_sdmmc.c1582
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_spi.c738
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_swpmi.c179
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_tim.c1380
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_usart.c496
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_usb.c1989
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_ll_utils.c975
-rw-r--r--bsps/arm/stm32h7/include/Legacy/stm32_hal_legacy.h3775
-rw-r--r--bsps/arm/stm32h7/include/stm32_assert_template.h57
-rw-r--r--bsps/arm/stm32h7/include/stm32h742xx.h25638
-rw-r--r--bsps/arm/stm32h7/include/stm32h743xx.h26288
-rw-r--r--bsps/arm/stm32h7/include/stm32h745xx.h27061
-rw-r--r--bsps/arm/stm32h7/include/stm32h747xx.h30234
-rw-r--r--bsps/arm/stm32h7/include/stm32h750xx.h26574
-rw-r--r--bsps/arm/stm32h7/include/stm32h753xx.h26575
-rw-r--r--bsps/arm/stm32h7/include/stm32h755xx.h27348
-rw-r--r--bsps/arm/stm32h7/include/stm32h757xx.h30521
-rw-r--r--bsps/arm/stm32h7/include/stm32h7a3xx.h22404
-rw-r--r--bsps/arm/stm32h7/include/stm32h7a3xxq.h22416
-rw-r--r--bsps/arm/stm32h7/include/stm32h7b0xx.h22894
-rw-r--r--bsps/arm/stm32h7/include/stm32h7b0xxq.h22906
-rw-r--r--bsps/arm/stm32h7/include/stm32h7b3xx.h22895
-rw-r--r--bsps/arm/stm32h7/include/stm32h7b3xxq.h22907
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx.h224
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal.h1078
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_adc.h1817
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_adc_ex.h1242
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_cec.h794
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_comp.h954
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_conf_template.h501
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_cortex.h461
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_crc.h343
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_crc_ex.h153
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_cryp.h556
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_cryp_ex.h123
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dac.h546
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dac_ex.h273
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dcmi.h671
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_def.h188
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dfsdm.h851
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dfsdm_ex.h93
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dma.h1290
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dma2d.h706
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dma_ex.h312
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dsi.h1352
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_dts.h483
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_eth.h1680
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_eth_ex.h357
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_exti.h507
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_fdcan.h2414
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_flash.h829
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_flash_ex.h910
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_gfxmmu.h453
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_gpio.h346
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_gpio_ex.h428
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_hash.h621
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_hash_ex.h165
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_hcd.h329
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_hrtim.h3646
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_hsem.h214
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_i2c.h782
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_i2c_ex.h181
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_i2s.h631
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_i2s_ex.h20
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_irda.h884
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_irda_ex.h650
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_iwdg.h242
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_jpeg.h655
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_lptim.h810
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_ltdc.h688
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_ltdc_ex.h86
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_mdios.h610
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_mdma.h855
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_mmc.h756
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_mmc_ex.h113
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_nand.h367
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_nor.h321
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_opamp.h458
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_opamp_ex.h83
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_ospi.h1076
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_otfdec.h444
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_pcd.h436
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_pcd_ex.h91
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_pssi.h506
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_pwr.h774
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_pwr_ex.h743
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_qspi.h747
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_ramecc.h358
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_rcc.h7973
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_rcc_ex.h4262
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_rng.h384
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_rng_ex.h241
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_rtc.h1241
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_rtc_ex.h2089
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_sai.h983
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_sai_ex.h105
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_sd.h797
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_sd_ex.h113
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_sdram.h228
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_smartcard.h1368
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_smartcard_ex.h338
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_smbus.h743
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_spdifrx.h606
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_spi.h1092
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_spi_ex.h77
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_sram.h222
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_swpmi.h520
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_tim.h2285
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_tim_ex.h529
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_uart.h1649
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_uart_ex.h864
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_usart.h1181
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_usart_ex.h284
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_hal_wwdg.h308
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_adc.h7222
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_bdma.h2415
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_bus.h6635
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_comp.h863
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_cortex.h669
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_crc.h464
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_crs.h783
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_dac.h1839
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_delayblock.h88
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_dma.h3246
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_dma2d.h2174
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_dmamux.h2363
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_exti.h3159
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_fmc.h1148
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_gpio.h985
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_hrtim.h10479
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_hsem.h901
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_i2c.h2228
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_iwdg.h342
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_lptim.h1494
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_lpuart.h2634
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_mdma.h4360
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_opamp.h825
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_pwr.h2249
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_rcc.h6326
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_rng.h682
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_rtc.h5378
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_sdmmc.h1102
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_spi.h3712
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_swpmi.h1242
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_system.h2274
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_tim.h4929
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_usart.h4385
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_usb.h510
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_utils.h382
-rw-r--r--bsps/arm/stm32h7/include/stm32h7xx_ll_wwdg.h331
-rw-r--r--bsps/arm/stm32h7/include/system_stm32h7xx.h105
259 files changed, 706411 insertions, 0 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal.c
new file mode 100644
index 0000000000..3e92312e99
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal.c
@@ -0,0 +1,1276 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal.c
+ * @author MCD Application Team
+ * @brief HAL module driver.
+ * This is the common part of the HAL initialization
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The common HAL driver contains a set of generic and common APIs that can be
+ used by the PPP peripheral drivers and the user to start using the HAL.
+ [..]
+ The HAL contains two APIs' categories:
+ (+) Common HAL APIs
+ (+) Services HAL APIs
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup HAL HAL
+ * @brief HAL module driver.
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/**
+ * @brief STM32H7xx HAL Driver version number V1.8.0
+ */
+#define __STM32H7xx_HAL_VERSION_MAIN (0x01UL) /*!< [31:24] main version */
+#define __STM32H7xx_HAL_VERSION_SUB1 (0x08UL) /*!< [23:16] sub1 version */
+#define __STM32H7xx_HAL_VERSION_SUB2 (0x00UL) /*!< [15:8] sub2 version */
+#define __STM32H7xx_HAL_VERSION_RC (0x00UL) /*!< [7:0] release candidate */
+#define __STM32H7xx_HAL_VERSION ((__STM32H7xx_HAL_VERSION_MAIN << 24)\
+ |(__STM32H7xx_HAL_VERSION_SUB1 << 16)\
+ |(__STM32H7xx_HAL_VERSION_SUB2 << 8 )\
+ |(__STM32H7xx_HAL_VERSION_RC))
+
+#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF)
+#define VREFBUF_TIMEOUT_VALUE (uint32_t)10 /* 10 ms */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Exported variables --------------------------------------------------------*/
+
+/** @defgroup HAL_Exported_Variables HAL Exported Variables
+ * @{
+ */
+__IO uint32_t uwTick;
+uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
+HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_Private_Functions HAL Private Functions
+ * @{
+ */
+
+/** @defgroup HAL_Group1 Initialization and de-initialization Functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initializes the Flash interface the NVIC allocation and initial clock
+ configuration. It initializes the systick also when timeout is needed
+ and the backup domain when enabled.
+ (+) De-Initializes common part of the HAL.
+ (+) Configure The time base source to have 1ms time base with a dedicated
+ Tick interrupt priority.
+ (++) SysTick timer is used by default as source of time base, but user
+ can eventually implement his proper time base source (a general purpose
+ timer for example or other time source), keeping in mind that Time base
+ duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
+ handled in milliseconds basis.
+ (++) Time base configuration function (HAL_InitTick ()) is called automatically
+ at the beginning of the program after reset by HAL_Init() or at any time
+ when clock is configured, by HAL_RCC_ClockConfig().
+ (++) Source of time base is configured to generate interrupts at regular
+ time intervals. Care must be taken if HAL_Delay() is called from a
+ peripheral ISR process, the Tick interrupt line must have higher priority
+ (numerically lower) than the peripheral interrupt. Otherwise the caller
+ ISR process will be blocked.
+ (++) functions affecting time base configurations are declared as __weak
+ to make override possible in case of other implementations in user file.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief This function is used to initialize the HAL Library; it must be the first
+ * instruction to be executed in the main program (before to call any other
+ * HAL function), it performs the following:
+ * Configures the SysTick to generate an interrupt each 1 millisecond,
+ * which is clocked by the HSI (at this stage, the clock is not yet
+ * configured and thus the system is running from the internal HSI at 16 MHz).
+ * Set NVIC Group Priority to 4.
+ * Calls the HAL_MspInit() callback function defined in user file
+ * "stm32h7xx_hal_msp.c" to do the global low level hardware initialization
+ *
+ * @note SysTick is used as time base for the HAL_Delay() function, the application
+ * need to ensure that the SysTick time base is always set to 1 millisecond
+ * to have correct HAL operation.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_Init(void)
+{
+
+uint32_t common_system_clock;
+
+#if defined(DUAL_CORE) && defined(CORE_CM4)
+ /* Configure Cortex-M4 Instruction cache through ART accelerator */
+ __HAL_RCC_ART_CLK_ENABLE(); /* Enable the Cortex-M4 ART Clock */
+ __HAL_ART_CONFIG_BASE_ADDRESS(0x08100000UL); /* Configure the Cortex-M4 ART Base address to the Flash Bank 2 : */
+ __HAL_ART_ENABLE(); /* Enable the Cortex-M4 ART */
+#endif /* DUAL_CORE && CORE_CM4 */
+
+ /* Set Interrupt Group Priority */
+ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /* Update the SystemCoreClock global variable */
+#if defined(RCC_D1CFGR_D1CPRE)
+ common_system_clock = HAL_RCC_GetSysClockFreq() >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos]) & 0x1FU);
+#else
+ common_system_clock = HAL_RCC_GetSysClockFreq() >> ((D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_CDCPRE)>> RCC_CDCFGR1_CDCPRE_Pos]) & 0x1FU);
+#endif
+
+ /* Update the SystemD2Clock global variable */
+#if defined(RCC_D1CFGR_HPRE)
+ SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU));
+#else
+ SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->CDCFGR1 & RCC_CDCFGR1_HPRE)>> RCC_CDCFGR1_HPRE_Pos]) & 0x1FU));
+#endif
+
+#if defined(DUAL_CORE) && defined(CORE_CM4)
+ SystemCoreClock = SystemD2Clock;
+#else
+ SystemCoreClock = common_system_clock;
+#endif /* DUAL_CORE && CORE_CM4 */
+
+ /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
+ if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Init the low level hardware */
+ HAL_MspInit();
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief This function de-Initializes common part of the HAL and stops the systick.
+ * This function is optional.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DeInit(void)
+{
+ /* Reset of all peripherals */
+ __HAL_RCC_AHB3_FORCE_RESET();
+ __HAL_RCC_AHB3_RELEASE_RESET();
+
+ __HAL_RCC_AHB1_FORCE_RESET();
+ __HAL_RCC_AHB1_RELEASE_RESET();
+
+ __HAL_RCC_AHB2_FORCE_RESET();
+ __HAL_RCC_AHB2_RELEASE_RESET();
+
+ __HAL_RCC_AHB4_FORCE_RESET();
+ __HAL_RCC_AHB4_RELEASE_RESET();
+
+ __HAL_RCC_APB3_FORCE_RESET();
+ __HAL_RCC_APB3_RELEASE_RESET();
+
+ __HAL_RCC_APB1L_FORCE_RESET();
+ __HAL_RCC_APB1L_RELEASE_RESET();
+
+ __HAL_RCC_APB1H_FORCE_RESET();
+ __HAL_RCC_APB1H_RELEASE_RESET();
+
+ __HAL_RCC_APB2_FORCE_RESET();
+ __HAL_RCC_APB2_RELEASE_RESET();
+
+ __HAL_RCC_APB4_FORCE_RESET();
+ __HAL_RCC_APB4_RELEASE_RESET();
+
+ /* De-Init the low level hardware */
+ HAL_MspDeInit();
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the MSP.
+ * @retval None
+ */
+__weak void HAL_MspInit(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes the MSP.
+ * @retval None
+ */
+__weak void HAL_MspDeInit(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief This function configures the source of the time base.
+ * The time source is configured to have 1ms time base with a dedicated
+ * Tick interrupt priority.
+ * @note This function is called automatically at the beginning of program after
+ * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
+ * @note In the default implementation, SysTick timer is the source of time base.
+ * It is used to generate interrupts at regular time intervals.
+ * Care must be taken if HAL_Delay() is called from a peripheral ISR process,
+ * The the SysTick interrupt must have higher priority (numerically lower)
+ * than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
+ * The function is declared as __weak to be overwritten in case of other
+ * implementation in user file.
+ * @param TickPriority: Tick interrupt priority.
+ * @retval HAL status
+ */
+__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
+{
+ /* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that don't take the value zero)*/
+ if((uint32_t)uwTickFreq == 0UL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Configure the SysTick to have interrupt in 1ms time basis*/
+ if (HAL_SYSTICK_Config(SystemCoreClock / (1000UL / (uint32_t)uwTickFreq)) > 0U)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Configure the SysTick IRQ priority */
+ if (TickPriority < (1UL << __NVIC_PRIO_BITS))
+ {
+ HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
+ uwTickPrio = TickPriority;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_Group2 HAL Control functions
+ * @brief HAL Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### HAL Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Provide a tick value in millisecond
+ (+) Provide a blocking delay in millisecond
+ (+) Suspend the time base source interrupt
+ (+) Resume the time base source interrupt
+ (+) Get the HAL API driver version
+ (+) Get the device identifier
+ (+) Get the device revision identifier
+ (+) Enable/Disable Debug module during SLEEP mode
+ (+) Enable/Disable Debug module during STOP mode
+ (+) Enable/Disable Debug module during STANDBY mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief This function is called to increment a global variable "uwTick"
+ * used as application time base.
+ * @note In the default implementation, this variable is incremented each 1ms
+ * in Systick ISR.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_IncTick(void)
+{
+ uwTick += (uint32_t)uwTickFreq;
+}
+
+/**
+ * @brief Provides a tick value in millisecond.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval tick value
+ */
+__weak uint32_t HAL_GetTick(void)
+{
+ return uwTick;
+}
+
+/**
+ * @brief This function returns a tick priority.
+ * @retval tick priority
+ */
+uint32_t HAL_GetTickPrio(void)
+{
+ return uwTickPrio;
+}
+
+/**
+ * @brief Set new tick Freq.
+ * @retval Status
+ */
+HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ HAL_TickFreqTypeDef prevTickFreq;
+
+ assert_param(IS_TICKFREQ(Freq));
+
+ if (uwTickFreq != Freq)
+ {
+
+ /* Back up uwTickFreq frequency */
+ prevTickFreq = uwTickFreq;
+
+ /* Update uwTickFreq global variable used by HAL_InitTick() */
+ uwTickFreq = Freq;
+
+ /* Apply the new tick Freq */
+ status = HAL_InitTick(uwTickPrio);
+ if (status != HAL_OK)
+ {
+ /* Restore previous tick frequency */
+ uwTickFreq = prevTickFreq;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Return tick frequency.
+ * @retval tick period in Hz
+ */
+HAL_TickFreqTypeDef HAL_GetTickFreq(void)
+{
+ return uwTickFreq;
+}
+
+/**
+ * @brief This function provides minimum delay (in milliseconds) based
+ * on variable incremented.
+ * @note In the default implementation , SysTick timer is the source of time base.
+ * It is used to generate interrupts at regular time intervals where uwTick
+ * is incremented.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @param Delay specifies the delay time length, in milliseconds.
+ * @retval None
+ */
+__weak void HAL_Delay(uint32_t Delay)
+{
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t wait = Delay;
+
+ /* Add a freq to guarantee minimum wait */
+ if (wait < HAL_MAX_DELAY)
+ {
+ wait += (uint32_t)(uwTickFreq);
+ }
+
+ while ((HAL_GetTick() - tickstart) < wait)
+ {
+ }
+}
+
+/**
+ * @brief Suspend Tick increment.
+ * @note In the default implementation , SysTick timer is the source of time base. It is
+ * used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
+ * is called, the the SysTick interrupt will be disabled and so Tick increment
+ * is suspended.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_SuspendTick(void)
+{
+ /* Disable SysTick Interrupt */
+ SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
+}
+
+/**
+ * @brief Resume Tick increment.
+ * @note In the default implementation , SysTick timer is the source of time base. It is
+ * used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
+ * is called, the the SysTick interrupt will be enabled and so Tick increment
+ * is resumed.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_ResumeTick(void)
+{
+ /* Enable SysTick Interrupt */
+ SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
+}
+
+/**
+ * @brief Returns the HAL revision
+ * @retval version : 0xXYZR (8bits for each decimal, R for RC)
+ */
+uint32_t HAL_GetHalVersion(void)
+{
+ return __STM32H7xx_HAL_VERSION;
+}
+
+/**
+ * @brief Returns the device revision identifier.
+ * @retval Device revision identifier
+ */
+uint32_t HAL_GetREVID(void)
+{
+ return((DBGMCU->IDCODE) >> 16);
+}
+
+/**
+ * @brief Returns the device identifier.
+ * @retval Device identifier
+ */
+uint32_t HAL_GetDEVID(void)
+{
+ return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
+}
+
+/**
+ * @brief Return the first word of the unique device identifier (UID based on 96 bits)
+ * @retval Device identifier
+ */
+uint32_t HAL_GetUIDw0(void)
+{
+ return(READ_REG(*((uint32_t *)UID_BASE)));
+}
+
+/**
+ * @brief Return the second word of the unique device identifier (UID based on 96 bits)
+ * @retval Device identifier
+ */
+uint32_t HAL_GetUIDw1(void)
+{
+ return(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
+}
+
+/**
+ * @brief Return the third word of the unique device identifier (UID based on 96 bits)
+ * @retval Device identifier
+ */
+uint32_t HAL_GetUIDw2(void)
+{
+ return(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
+}
+
+/**
+ * @brief Configure the internal voltage reference buffer voltage scale.
+ * @param VoltageScaling specifies the output voltage to achieve
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_VREFBUF_VOLTAGE_SCALE0: VREF_OUT1 around 2.048 V.
+ * This requires VDDA equal to or higher than 2.4 V.
+ * @arg SYSCFG_VREFBUF_VOLTAGE_SCALE1: VREF_OUT2 around 2.5 V.
+ * This requires VDDA equal to or higher than 2.8 V.
+ * @arg SYSCFG_VREFBUF_VOLTAGE_SCALE2: VREF_OUT3 around 1.5 V.
+ * This requires VDDA equal to or higher than 1.8 V.
+ * @arg SYSCFG_VREFBUF_VOLTAGE_SCALE3: VREF_OUT4 around 1.8 V.
+ * This requires VDDA equal to or higher than 2.1 V.
+ * @retval None
+ */
+void HAL_SYSCFG_VREFBUF_VoltageScalingConfig(uint32_t VoltageScaling)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_VREFBUF_VOLTAGE_SCALE(VoltageScaling));
+
+ MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_VRS, VoltageScaling);
+}
+
+/**
+ * @brief Configure the internal voltage reference buffer high impedance mode.
+ * @param Mode specifies the high impedance mode
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE: VREF+ pin is internally connect to VREFINT output.
+ * @arg SYSCFG_VREFBUF_HIGH_IMPEDANCE_ENABLE: VREF+ pin is high impedance.
+ * @retval None
+ */
+void HAL_SYSCFG_VREFBUF_HighImpedanceConfig(uint32_t Mode)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_VREFBUF_HIGH_IMPEDANCE(Mode));
+
+ MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_HIZ, Mode);
+}
+
+/**
+ * @brief Tune the Internal Voltage Reference buffer (VREFBUF).
+ * @retval None
+ */
+void HAL_SYSCFG_VREFBUF_TrimmingConfig(uint32_t TrimmingValue)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_VREFBUF_TRIMMING(TrimmingValue));
+
+ MODIFY_REG(VREFBUF->CCR, VREFBUF_CCR_TRIM, TrimmingValue);
+}
+
+/**
+ * @brief Enable the Internal Voltage Reference buffer (VREFBUF).
+ * @retval HAL_OK/HAL_TIMEOUT
+ */
+HAL_StatusTypeDef HAL_SYSCFG_EnableVREFBUF(void)
+{
+ uint32_t tickstart;
+
+ SET_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR);
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait for VRR bit */
+ while(READ_BIT(VREFBUF->CSR, VREFBUF_CSR_VRR) == 0UL)
+ {
+ if((HAL_GetTick() - tickstart) > VREFBUF_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disable the Internal Voltage Reference buffer (VREFBUF).
+ *
+ * @retval None
+ */
+void HAL_SYSCFG_DisableVREFBUF(void)
+{
+ CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR);
+}
+
+#if defined(SYSCFG_PMCR_EPIS_SEL)
+/**
+ * @brief Ethernet PHY Interface Selection either MII or RMII
+ * @param SYSCFG_ETHInterface: Selects the Ethernet PHY interface
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_ETH_MII : Select the Media Independent Interface
+ * @arg SYSCFG_ETH_RMII: Select the Reduced Media Independent Interface
+ * @retval None
+ */
+void HAL_SYSCFG_ETHInterfaceSelect(uint32_t SYSCFG_ETHInterface)
+{
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_ETHERNET_CONFIG(SYSCFG_ETHInterface));
+
+ MODIFY_REG(SYSCFG->PMCR, SYSCFG_PMCR_EPIS_SEL, (uint32_t)(SYSCFG_ETHInterface));
+}
+#endif /* SYSCFG_PMCR_EPIS_SEL */
+
+/**
+ * @brief Analog Switch control for dual analog pads.
+ * @param SYSCFG_AnalogSwitch: Selects the analog pad
+ * This parameter can be one or a combination of the following values:
+ * @arg SYSCFG_SWITCH_PA0 : Select PA0 analog switch
+ * @arg SYSCFG_SWITCH_PA1: Select PA1 analog switch
+ * @arg SYSCFG_SWITCH_PC2 : Select PC2 analog switch
+ * @arg SYSCFG_SWITCH_PC3: Select PC3 analog switch
+ * @param SYSCFG_SwitchState: Open or Close the analog switch between dual pads (PXn and PXn_C)
+ * This parameter can be one or a combination of the following values:
+ * @arg SYSCFG_SWITCH_PA0_OPEN
+ * @arg SYSCFG_SWITCH_PA0_CLOSE
+ * @arg SYSCFG_SWITCH_PA1_OPEN
+ * @arg SYSCFG_SWITCH_PA1_CLOSE
+ * @arg SYSCFG_SWITCH_PC2_OPEN
+ * @arg SYSCFG_SWITCH_PC2_CLOSE
+ * @arg SYSCFG_SWITCH_PC3_OPEN
+ * @arg SYSCFG_SWITCH_PC3_CLOSE
+ * @retval None
+ */
+
+void HAL_SYSCFG_AnalogSwitchConfig(uint32_t SYSCFG_AnalogSwitch , uint32_t SYSCFG_SwitchState )
+{
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_ANALOG_SWITCH(SYSCFG_AnalogSwitch));
+ assert_param(IS_SYSCFG_SWITCH_STATE(SYSCFG_SwitchState));
+
+ MODIFY_REG(SYSCFG->PMCR, (uint32_t) SYSCFG_AnalogSwitch, (uint32_t)(SYSCFG_SwitchState));
+}
+
+#if defined(SYSCFG_PMCR_BOOSTEN)
+/**
+ * @brief Enables the booster to reduce the total harmonic distortion of the analog
+ * switch when the supply voltage is lower than 2.7 V.
+ * @note Activating the booster allows to guaranty the analog switch AC performance
+ * when the supply voltage is below 2.7 V: in this case, the analog switch
+ * performance is the same on the full voltage range
+ * @retval None
+ */
+void HAL_SYSCFG_EnableBOOST(void)
+{
+ SET_BIT(SYSCFG->PMCR, SYSCFG_PMCR_BOOSTEN) ;
+}
+
+/**
+ * @brief Disables the booster
+ * @note Activating the booster allows to guaranty the analog switch AC performance
+ * when the supply voltage is below 2.7 V: in this case, the analog switch
+ * performance is the same on the full voltage range
+ * @retval None
+ */
+void HAL_SYSCFG_DisableBOOST(void)
+{
+ CLEAR_BIT(SYSCFG->PMCR, SYSCFG_PMCR_BOOSTEN) ;
+}
+#endif /* SYSCFG_PMCR_BOOSTEN */
+
+#if defined (SYSCFG_UR2_BOOT_ADD0) || defined (SYSCFG_UR2_BCM7_ADD0)
+/**
+ * @brief BootCM7 address 0 configuration
+ * @param BootRegister :Specifies the Boot Address register (Address0 or Address1)
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_BOOT_ADDR0 : Select the boot address0
+ * @arg SYSCFG_BOOT_ADDR1: Select the boot address1
+ * @param BootAddress :Specifies the CM7 Boot Address to be loaded in Address0 or Address1
+ * @retval None
+ */
+void HAL_SYSCFG_CM7BootAddConfig(uint32_t BootRegister, uint32_t BootAddress)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_BOOT_REGISTER(BootRegister));
+ assert_param(IS_SYSCFG_BOOT_ADDRESS(BootAddress));
+ if ( BootRegister == SYSCFG_BOOT_ADDR0 )
+ {
+ /* Configure CM7 BOOT ADD0 */
+#if defined(DUAL_CORE)
+ MODIFY_REG(SYSCFG->UR2, SYSCFG_UR2_BCM7_ADD0, ((BootAddress >> 16) << SYSCFG_UR2_BCM7_ADD0_Pos));
+#else
+ MODIFY_REG(SYSCFG->UR2, SYSCFG_UR2_BOOT_ADD0, ((BootAddress >> 16) << SYSCFG_UR2_BOOT_ADD0_Pos));
+#endif /*DUAL_CORE*/
+ }
+ else
+ {
+ /* Configure CM7 BOOT ADD1 */
+#if defined(DUAL_CORE)
+ MODIFY_REG(SYSCFG->UR3, SYSCFG_UR3_BCM7_ADD1, (BootAddress >> 16));
+#else
+ MODIFY_REG(SYSCFG->UR3, SYSCFG_UR3_BOOT_ADD1, (BootAddress >> 16));
+#endif /*DUAL_CORE*/
+ }
+}
+#endif /* SYSCFG_UR2_BOOT_ADD0 || SYSCFG_UR2_BCM7_ADD0 */
+
+#if defined(DUAL_CORE)
+/**
+ * @brief BootCM4 address 0 configuration
+ * @param BootRegister :Specifies the Boot Address register (Address0 or Address1)
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_BOOT_ADDR0 : Select the boot address0
+ * @arg SYSCFG_BOOT_ADDR1: Select the boot address1
+ * @param BootAddress :Specifies the CM4 Boot Address to be loaded in Address0 or Address1
+ * @retval None
+ */
+void HAL_SYSCFG_CM4BootAddConfig(uint32_t BootRegister, uint32_t BootAddress)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_BOOT_REGISTER(BootRegister));
+ assert_param(IS_SYSCFG_BOOT_ADDRESS(BootAddress));
+
+ if ( BootRegister == SYSCFG_BOOT_ADDR0 )
+ {
+ /* Configure CM4 BOOT ADD0 */
+ MODIFY_REG(SYSCFG->UR3, SYSCFG_UR3_BCM4_ADD0, ((BootAddress >> 16)<< SYSCFG_UR3_BCM4_ADD0_Pos));
+ }
+
+ else
+ {
+ /* Configure CM4 BOOT ADD1 */
+ MODIFY_REG(SYSCFG->UR4, SYSCFG_UR4_BCM4_ADD1, (BootAddress >> 16));
+ }
+}
+
+/**
+ * @brief Enables the Cortex-M7 boot
+ * @retval None
+ */
+void HAL_SYSCFG_EnableCM7BOOT(void)
+{
+ SET_BIT(SYSCFG->UR1, SYSCFG_UR1_BCM7);
+}
+
+/**
+ * @brief Disables the Cortex-M7 boot
+ * @note Disabling the boot will gate the CPU clock
+ * @retval None
+ */
+void HAL_SYSCFG_DisableCM7BOOT(void)
+{
+ CLEAR_BIT(SYSCFG->UR1, SYSCFG_UR1_BCM7) ;
+}
+
+/**
+ * @brief Enables the Cortex-M4 boot
+ * @retval None
+ */
+void HAL_SYSCFG_EnableCM4BOOT(void)
+{
+ SET_BIT(SYSCFG->UR1, SYSCFG_UR1_BCM4);
+}
+
+/**
+ * @brief Disables the Cortex-M4 boot
+ * @note Disabling the boot will gate the CPU clock
+ * @retval None
+ */
+void HAL_SYSCFG_DisableCM4BOOT(void)
+{
+ CLEAR_BIT(SYSCFG->UR1, SYSCFG_UR1_BCM4);
+}
+#endif /*DUAL_CORE*/
+/**
+ * @brief Enables the I/O Compensation Cell.
+ * @note The I/O compensation cell can be used only when the device supply
+ * voltage ranges from 2.4 to 3.6 V.
+ * @retval None
+ */
+void HAL_EnableCompensationCell(void)
+{
+ SET_BIT(SYSCFG->CCCSR, SYSCFG_CCCSR_EN) ;
+}
+
+/**
+ * @brief Power-down the I/O Compensation Cell.
+ * @note The I/O compensation cell can be used only when the device supply
+ * voltage ranges from 2.4 to 3.6 V.
+ * @retval None
+ */
+void HAL_DisableCompensationCell(void)
+{
+ CLEAR_BIT(SYSCFG->CCCSR, SYSCFG_CCCSR_EN);
+}
+
+
+/**
+ * @brief To Enable optimize the I/O speed when the product voltage is low.
+ * @note This bit is active only if PRODUCT_BELOW_25V user option bit is set. It must be
+ * used only if the product supply voltage is below 2.5 V. Setting this bit when VDD is
+ * higher than 2.5 V might be destructive.
+ * @retval None
+ */
+void HAL_SYSCFG_EnableIOSpeedOptimize(void)
+{
+#if defined(SYSCFG_CCCSR_HSLV)
+ SET_BIT(SYSCFG->CCCSR, SYSCFG_CCCSR_HSLV);
+#else
+ SET_BIT(SYSCFG->CCCSR, (SYSCFG_CCCSR_HSLV0| SYSCFG_CCCSR_HSLV1 | SYSCFG_CCCSR_HSLV2 | SYSCFG_CCCSR_HSLV3));
+#endif /* SYSCFG_CCCSR_HSLV */
+}
+
+/**
+ * @brief To Disable optimize the I/O speed when the product voltage is low.
+ * @note This bit is active only if PRODUCT_BELOW_25V user option bit is set. It must be
+ * used only if the product supply voltage is below 2.5 V. Setting this bit when VDD is
+ * higher than 2.5 V might be destructive.
+ * @retval None
+ */
+void HAL_SYSCFG_DisableIOSpeedOptimize(void)
+{
+#if defined(SYSCFG_CCCSR_HSLV)
+ CLEAR_BIT(SYSCFG->CCCSR, SYSCFG_CCCSR_HSLV);
+#else
+ CLEAR_BIT(SYSCFG->CCCSR, (SYSCFG_CCCSR_HSLV0| SYSCFG_CCCSR_HSLV1 | SYSCFG_CCCSR_HSLV2 | SYSCFG_CCCSR_HSLV3));
+#endif /* SYSCFG_CCCSR_HSLV */
+}
+
+/**
+ * @brief Code selection for the I/O Compensation cell
+ * @param SYSCFG_CompCode: Selects the code to be applied for the I/O compensation cell
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_CELL_CODE : Select Code from the cell (available in the SYSCFG_CCVR)
+ * @arg SYSCFG_REGISTER_CODE: Select Code from the SYSCFG compensation cell code register (SYSCFG_CCCR)
+ * @retval None
+ */
+void HAL_SYSCFG_CompensationCodeSelect(uint32_t SYSCFG_CompCode)
+{
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_CODE_SELECT(SYSCFG_CompCode));
+ MODIFY_REG(SYSCFG->CCCSR, SYSCFG_CCCSR_CS, (uint32_t)(SYSCFG_CompCode));
+}
+
+/**
+ * @brief Code selection for the I/O Compensation cell
+ * @param SYSCFG_PMOSCode: PMOS compensation code
+ * This code is applied to the I/O compensation cell when the CS bit of the
+ * SYSCFG_CMPCR is set
+ * @param SYSCFG_NMOSCode: NMOS compensation code
+ * This code is applied to the I/O compensation cell when the CS bit of the
+ * SYSCFG_CMPCR is set
+ * @retval None
+ */
+void HAL_SYSCFG_CompensationCodeConfig(uint32_t SYSCFG_PMOSCode, uint32_t SYSCFG_NMOSCode )
+{
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_CODE_CONFIG(SYSCFG_PMOSCode));
+ assert_param(IS_SYSCFG_CODE_CONFIG(SYSCFG_NMOSCode));
+ MODIFY_REG(SYSCFG->CCCR, SYSCFG_CCCR_NCC|SYSCFG_CCCR_PCC, (((uint32_t)(SYSCFG_PMOSCode)<< 4)|(uint32_t)(SYSCFG_NMOSCode)) );
+}
+
+#if defined(SYSCFG_CCCR_NCC_MMC)
+/**
+ * @brief Code selection for the I/O Compensation cell
+ * @param SYSCFG_PMOSCode: VDDMMC PMOS compensation code
+ * This code is applied to the I/O compensation cell when the CS bit of the
+ * SYSCFG_CMPCR is set
+ * @param SYSCFG_NMOSCode: VDDMMC NMOS compensation code
+ * This code is applied to the I/O compensation cell when the CS bit of the
+ * SYSCFG_CMPCR is set
+ * @retval None
+ */
+void HAL_SYSCFG_VDDMMC_CompensationCodeConfig(uint32_t SYSCFG_PMOSCode, uint32_t SYSCFG_NMOSCode )
+{
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_CODE_CONFIG(SYSCFG_PMOSCode));
+ assert_param(IS_SYSCFG_CODE_CONFIG(SYSCFG_NMOSCode));
+ MODIFY_REG(SYSCFG->CCCR, (SYSCFG_CCCR_NCC_MMC | SYSCFG_CCCR_PCC_MMC), (((uint32_t)(SYSCFG_PMOSCode)<< 4)|(uint32_t)(SYSCFG_NMOSCode)) );
+}
+#endif /* SYSCFG_CCCR_NCC_MMC */
+
+/**
+ * @brief Enable the Debug Module during Domain1/CDomain SLEEP mode
+ * @retval None
+ */
+void HAL_EnableDBGSleepMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEPD1);
+}
+
+/**
+ * @brief Disable the Debug Module during Domain1/CDomain SLEEP mode
+ * @retval None
+ */
+void HAL_DisableDBGSleepMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEPD1);
+}
+
+
+/**
+ * @brief Enable the Debug Module during Domain1/CDomain STOP mode
+ * @retval None
+ */
+void HAL_EnableDBGStopMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOPD1);
+}
+
+/**
+ * @brief Disable the Debug Module during Domain1/CDomain STOP mode
+ * @retval None
+ */
+void HAL_DisableDBGStopMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOPD1);
+}
+
+/**
+ * @brief Enable the Debug Module during Domain1/CDomain STANDBY mode
+ * @retval None
+ */
+void HAL_EnableDBGStandbyMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBYD1);
+}
+
+/**
+ * @brief Disable the Debug Module during Domain1/CDomain STANDBY mode
+ * @retval None
+ */
+void HAL_DisableDBGStandbyMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBYD1);
+}
+
+#if defined(DUAL_CORE)
+/**
+ * @brief Enable the Debug Module during Domain1 SLEEP mode
+ * @retval None
+ */
+void HAL_EnableDomain2DBGSleepMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEPD2);
+}
+
+/**
+ * @brief Disable the Debug Module during Domain2 SLEEP mode
+ * @retval None
+ */
+void HAL_DisableDomain2DBGSleepMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEPD2);
+}
+
+/**
+ * @brief Enable the Debug Module during Domain2 STOP mode
+ * @retval None
+ */
+void HAL_EnableDomain2DBGStopMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOPD2);
+}
+
+/**
+ * @brief Disable the Debug Module during Domain2 STOP mode
+ * @retval None
+ */
+void HAL_DisableDomain2DBGStopMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOPD2);
+}
+
+/**
+ * @brief Enable the Debug Module during Domain2 STANDBY mode
+ * @retval None
+ */
+void HAL_EnableDomain2DBGStandbyMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBYD2);
+}
+
+/**
+ * @brief Disable the Debug Module during Domain2 STANDBY mode
+ * @retval None
+ */
+void HAL_DisableDomain2DBGStandbyMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBYD2);
+}
+#endif /*DUAL_CORE*/
+
+/**
+ * @brief Enable the Debug Module during Domain3/SRDomain STOP mode
+ * @retval None
+ */
+void HAL_EnableDomain3DBGStopMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOPD3);
+}
+/**
+ * @brief Disable the Debug Module during Domain3/SRDomain STOP mode
+ * @retval None
+ */
+void HAL_DisableDomain3DBGStopMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOPD3);
+}
+
+/**
+ * @brief Enable the Debug Module during Domain3/SRDomain STANDBY mode
+ * @retval None
+ */
+void HAL_EnableDomain3DBGStandbyMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBYD3);
+}
+
+/**
+ * @brief Disable the Debug Module during Domain3/SRDomain STANDBY mode
+ * @retval None
+ */
+void HAL_DisableDomain3DBGStandbyMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBYD3);
+}
+
+/**
+ * @brief Set the FMC Memory Mapping Swapping config.
+ * @param BankMapConfig: Defines the FMC Bank mapping configuration. This parameter can be
+ FMC_SWAPBMAP_DISABLE, FMC_SWAPBMAP_SDRAM_SRAM, FMC_SWAPBMAP_SDRAMB2
+ * @retval HAL state
+ */
+void HAL_SetFMCMemorySwappingConfig(uint32_t BankMapConfig)
+{
+ /* Check the parameter */
+ assert_param(IS_FMC_SWAPBMAP_MODE(BankMapConfig));
+ MODIFY_REG(FMC_Bank1_R->BTCR[0], FMC_BCR1_BMAP, BankMapConfig);
+}
+
+/**
+ * @brief Get FMC Bank mapping mode.
+ * @retval The FMC Bank mapping mode. This parameter can be
+ FMC_SWAPBMAP_DISABLE, FMC_SWAPBMAP_SDRAM_SRAM, FMC_SWAPBMAP_SDRAMB2
+*/
+uint32_t HAL_GetFMCMemorySwappingConfig(void)
+{
+ return READ_BIT(FMC_Bank1_R->BTCR[0], FMC_BCR1_BMAP);
+}
+
+/**
+ * @brief Configure the EXTI input event line edge
+ * @note No edge configuration for direct lines but for configurable lines:(EXTI_LINE0..EXTI_LINE21),
+ * EXTI_LINE49,EXTI_LINE51,EXTI_LINE82,EXTI_LINE84,EXTI_LINE85 and EXTI_LINE86.
+ * @param EXTI_Line: Specifies the EXTI LINE, it can be one of the following values,
+ * (EXTI_LINE0....EXTI_LINE87)excluding :line45, line81,line83 which are reserved
+ * @param EXTI_Edge: Specifies EXTI line Edge used.
+ * This parameter can be one of the following values :
+ * @arg EXTI_RISING_EDGE : Configurable line, with Rising edge trigger detection
+ * @arg EXTI_FALLING_EDGE: Configurable line, with Falling edge trigger detection
+ * @retval None
+ */
+void HAL_EXTI_EdgeConfig(uint32_t EXTI_Line , uint32_t EXTI_Edge )
+{
+ /* Check the parameter */
+ assert_param(IS_HAL_EXTI_CONFIG_LINE(EXTI_Line));
+ assert_param(IS_EXTI_EDGE_LINE(EXTI_Edge));
+
+ /* Clear Rising Falling edge configuration */
+ CLEAR_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI->FTSR1)) + ((EXTI_Line >> 5 ) * 0x20UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ CLEAR_BIT( *(__IO uint32_t *) (((uint32_t) &(EXTI->RTSR1)) + ((EXTI_Line >> 5 ) * 0x20UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+
+ if( (EXTI_Edge & EXTI_RISING_EDGE) == EXTI_RISING_EDGE)
+ {
+ SET_BIT( *(__IO uint32_t *) (((uint32_t) &(EXTI->RTSR1)) + ((EXTI_Line >> 5 ) * 0x20UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+ if( (EXTI_Edge & EXTI_FALLING_EDGE) == EXTI_FALLING_EDGE)
+ {
+ SET_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI->FTSR1)) + ((EXTI_Line >> 5 ) * 0x20UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+}
+
+/**
+ * @brief Generates a Software interrupt on selected EXTI line.
+ * @param EXTI_Line: Specifies the EXTI LINE, it can be one of the following values,
+ * (EXTI_LINE0..EXTI_LINE21),EXTI_LINE49,EXTI_LINE51,EXTI_LINE82,EXTI_LINE84,EXTI_LINE85 and EXTI_LINE86.
+ * @retval None
+ */
+void HAL_EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_HAL_EXTI_CONFIG_LINE(EXTI_Line));
+
+ SET_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI->SWIER1)) + ((EXTI_Line >> 5 ) * 0x20UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+}
+
+
+/**
+ * @brief Clears the EXTI's line pending flags for Domain D1
+ * @param EXTI_Line: Specifies the EXTI LINE, it can be one of the following values,
+ * (EXTI_LINE0....EXTI_LINE87)excluding :line45, line81,line83 which are reserved
+ * @retval None
+ */
+void HAL_EXTI_D1_ClearFlag(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_D1_LINE(EXTI_Line));
+ WRITE_REG(*(__IO uint32_t *) (((uint32_t) &(EXTI_D1->PR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+
+}
+
+#if defined(DUAL_CORE)
+/**
+ * @brief Clears the EXTI's line pending flags for Domain D2
+ * @param EXTI_Line: Specifies the EXTI LINE, it can be one of the following values,
+ * (EXTI_LINE0....EXTI_LINE87)excluding :line45, line81,line83 which are reserved
+ * @retval None
+ */
+void HAL_EXTI_D2_ClearFlag(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_D2_LINE(EXTI_Line));
+ WRITE_REG(*(__IO uint32_t *) (((uint32_t) &(EXTI_D2->PR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+}
+
+#endif /*DUAL_CORE*/
+/**
+ * @brief Configure the EXTI input event line for Domain D1
+ * @param EXTI_Line: Specifies the EXTI LINE, it can be one of the following values,
+ * (EXTI_LINE0....EXTI_LINE87)excluding :line45, line81,line83 which are reserved
+ * @param EXTI_Mode: Specifies which EXTI line is used as interrupt or an event.
+ * This parameter can be one or a combination of the following values :
+ * @arg EXTI_MODE_IT : Interrupt Mode selected
+ * @arg EXTI_MODE_EVT : Event Mode selected
+ * @param EXTI_LineCmd controls (Enable/Disable) the EXTI line.
+
+ * @retval None
+ */
+void HAL_EXTI_D1_EventInputConfig(uint32_t EXTI_Line , uint32_t EXTI_Mode, uint32_t EXTI_LineCmd )
+{
+ /* Check the parameter */
+ assert_param(IS_EXTI_D1_LINE(EXTI_Line));
+ assert_param(IS_EXTI_MODE_LINE(EXTI_Mode));
+
+ if( (EXTI_Mode & EXTI_MODE_IT) == EXTI_MODE_IT)
+ {
+ if( EXTI_LineCmd == 0UL)
+ {
+ /* Clear EXTI line configuration */
+ CLEAR_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI_D1->IMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)),(uint32_t)(1UL << (EXTI_Line & 0x1FUL)) );
+ }
+ else
+ {
+ SET_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI_D1->IMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+ }
+
+ if( (EXTI_Mode & EXTI_MODE_EVT) == EXTI_MODE_EVT)
+ {
+ if( EXTI_LineCmd == 0UL)
+ {
+ /* Clear EXTI line configuration */
+ CLEAR_BIT( *(__IO uint32_t *) (((uint32_t) &(EXTI_D1->EMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+ else
+ {
+ SET_BIT( *(__IO uint32_t *) (((uint32_t) &(EXTI_D1->EMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+ }
+}
+
+#if defined(DUAL_CORE)
+/**
+ * @brief Configure the EXTI input event line for Domain D2
+ * @param EXTI_Line: Specifies the EXTI LINE, it can be one of the following values,
+ * (EXTI_LINE0....EXTI_LINE87)excluding :line45, line81,line83 which are reserved
+ * @param EXTI_Mode: Specifies which EXTI line is used as interrupt or an event.
+ * This parameter can be one or a combination of the following values :
+ * @arg EXTI_MODE_IT : Interrupt Mode selected
+ * @arg EXTI_MODE_EVT : Event Mode selected
+ * @param EXTI_LineCmd controls (Enable/Disable) the EXTI line.
+
+ * @retval None
+ */
+void HAL_EXTI_D2_EventInputConfig(uint32_t EXTI_Line , uint32_t EXTI_Mode, uint32_t EXTI_LineCmd )
+{
+ /* Check the parameter */
+ assert_param(IS_EXTI_D2_LINE(EXTI_Line));
+ assert_param(IS_EXTI_MODE_LINE(EXTI_Mode));
+
+ if( (EXTI_Mode & EXTI_MODE_IT) == EXTI_MODE_IT)
+ {
+ if( EXTI_LineCmd == 0UL)
+ {
+ /* Clear EXTI line configuration */
+ CLEAR_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI_D2->IMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)),(uint32_t)(1UL << (EXTI_Line & 0x1FUL)) );
+ }
+ else
+ {
+ SET_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI_D2->IMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+ }
+
+ if( (EXTI_Mode & EXTI_MODE_EVT) == EXTI_MODE_EVT)
+ {
+ if( EXTI_LineCmd == 0UL)
+ {
+ /* Clear EXTI line configuration */
+ CLEAR_BIT( *(__IO uint32_t *) (((uint32_t) &(EXTI_D2->EMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+ else
+ {
+ SET_BIT( *(__IO uint32_t *) (((uint32_t) &(EXTI_D2->EMR1)) + ((EXTI_Line >> 5 ) * 0x10UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+ }
+}
+#endif /*DUAL_CORE*/
+
+/**
+ * @brief Configure the EXTI input event line for Domain D3
+ * @param EXTI_Line: Specifies the EXTI LINE, it can be one of the following values,
+ * (EXTI_LINE0...EXTI_LINE15),(EXTI_LINE19...EXTI_LINE21),EXTI_LINE25, EXTI_LINE34,
+ * EXTI_LINE35,EXTI_LINE41,(EXTI_LINE48...EXTI_LINE53)
+ * @param EXTI_LineCmd controls (Enable/Disable) the EXTI line.
+ * @param EXTI_ClearSrc: Specifies the clear source of D3 pending event.
+ * This parameter can be one of the following values :
+ * @arg BDMA_CH6_CLEAR : BDMA ch6 event selected as D3 domain pendclear source
+ * @arg BDMA_CH7_CLEAR : BDMA ch7 event selected as D3 domain pendclear source
+ * @arg LPTIM4_OUT_CLEAR : LPTIM4 out selected as D3 domain pendclear source
+ * @arg LPTIM5_OUT_CLEAR : LPTIM5 out selected as D3 domain pendclear source
+ * @retval None
+ */
+void HAL_EXTI_D3_EventInputConfig(uint32_t EXTI_Line, uint32_t EXTI_LineCmd , uint32_t EXTI_ClearSrc )
+{
+ __IO uint32_t *pRegv;
+
+ /* Check the parameter */
+ assert_param(IS_EXTI_D3_LINE(EXTI_Line));
+ assert_param(IS_EXTI_D3_CLEAR(EXTI_ClearSrc));
+
+ if( EXTI_LineCmd == 0UL)
+ {
+ /* Clear EXTI line configuration */
+ CLEAR_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI->D3PMR1)) + ((EXTI_Line >> 5 ) * 0x20UL)),(uint32_t)(1UL << (EXTI_Line & 0x1FUL)) );
+ }
+ else
+ {
+ SET_BIT(*(__IO uint32_t *) (((uint32_t) &(EXTI->D3PMR1)) +((EXTI_Line >> 5 ) * 0x20UL)), (uint32_t)(1UL << (EXTI_Line & 0x1FUL)));
+ }
+
+ if(((EXTI_Line>>4)%2UL) == 0UL)
+ {
+ pRegv = (__IO uint32_t *) (((uint32_t) &(EXTI->D3PCR1L)) + ((EXTI_Line >> 5 ) * 0x20UL));
+ }
+ else
+ {
+ pRegv = (__IO uint32_t *) (((uint32_t) &(EXTI->D3PCR1H)) + ((EXTI_Line >> 5 ) * 0x20UL));
+ }
+ MODIFY_REG(*pRegv, (uint32_t)(3UL << ((EXTI_Line*2UL) & 0x1FUL)), (uint32_t)(EXTI_ClearSrc << ((EXTI_Line*2UL) & 0x1FUL)));
+
+}
+
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c
new file mode 100644
index 0000000000..cce8bf9baa
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc.c
@@ -0,0 +1,3713 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_adc.c
+ * @author MCD Application Team
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Analog to Digital Convertor (ADC)
+ * peripheral:
+ * + Initialization and de-initialization functions
+ * ++ Initialization and Configuration of ADC
+ * + Operation functions
+ * ++ Start, stop, get result of conversions of regular
+ * group, using 3 possible modes: polling, interruption or DMA.
+ * + Control functions
+ * ++ Channels configuration on regular group
+ * ++ Analog Watchdog configuration
+ * + State functions
+ * ++ ADC state machine management
+ * ++ Interrupts and flags management
+ * Other functions (extended functions) are available in file
+ * "stm32h7xx_hal_adc_ex.c".
+ *
+ @verbatim
+ ==============================================================================
+ ##### ADC peripheral features #####
+ ==============================================================================
+ [..]
+ (+) 16-bit, 14-bit, 12-bit, 10-bit or 8-bit configurable resolution.
+
+ (+) Interrupt generation at the end of regular conversion and in case of
+ analog watchdog or overrun events.
+
+ (+) Single and continuous conversion modes.
+
+ (+) Scan mode for conversion of several channels sequentially.
+
+ (+) Data alignment with in-built data coherency.
+
+ (+) Programmable sampling time (channel wise)
+
+ (+) External trigger (timer or EXTI) with configurable polarity
+
+ (+) DMA request generation for transfer of conversions data of regular group.
+
+ (+) Configurable delay between conversions in Dual interleaved mode.
+
+ (+) ADC channels selectable single/differential input.
+
+ (+) ADC offset shared on 4 offset instances.
+ (+) ADC calibration
+
+ (+) ADC conversion of regular group.
+
+ (+) ADC supply requirements: 1.62 V to 3.6 V.
+
+ (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to
+ Vdda or to an external voltage reference).
+
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+
+ *** Configuration of top level parameters related to ADC ***
+ ============================================================
+ [..]
+
+ (#) Enable the ADC interface
+ (++) As prerequisite, ADC clock must be configured at RCC top level.
+
+ (++) Two clock settings are mandatory:
+ (+++) ADC clock (core clock, also possibly conversion clock).
+
+ (+++) ADC clock (conversions clock).
+ Two possible clock sources: synchronous clock derived from AHB clock
+ or asynchronous clock derived from system clock, the PLL2 or the PLL3 running up to 400MHz.
+
+ (+++) Example:
+ Into HAL_ADC_MspInit() (recommended code location) or with
+ other device clock parameters configuration:
+ (+++) __HAL_RCC_ADC_CLK_ENABLE(); (mandatory)
+
+ RCC_ADCCLKSOURCE_PLL2 enable: (optional: if asynchronous clock selected)
+ (+++) RCC_PeriphClkInitTypeDef RCC_PeriphClkInit;
+ (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
+ (+++) PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
+ (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
+
+ (++) ADC clock source and clock prescaler are configured at ADC level with
+ parameter "ClockPrescaler" using function HAL_ADC_Init().
+
+ (#) ADC pins configuration
+ (++) Enable the clock for the ADC GPIOs
+ using macro __HAL_RCC_GPIOx_CLK_ENABLE()
+ (++) Configure these ADC pins in analog mode
+ using function HAL_GPIO_Init()
+
+ (#) Optionally, in case of usage of ADC with interruptions:
+ (++) Configure the NVIC for ADC
+ using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
+ (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
+ into the function of corresponding ADC interruption vector
+ ADCx_IRQHandler().
+
+ (#) Optionally, in case of usage of DMA:
+ (++) Configure the DMA (DMA channel, mode normal or circular, ...)
+ using function HAL_DMA_Init().
+ (++) Configure the NVIC for DMA
+ using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
+ (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
+ into the function of corresponding DMA interruption vector
+ DMAx_Channelx_IRQHandler().
+
+ *** Configuration of ADC, group regular, channels parameters ***
+ ================================================================
+ [..]
+
+ (#) Configure the ADC parameters (resolution, data alignment, ...)
+ and regular group parameters (conversion trigger, sequencer, ...)
+ using function HAL_ADC_Init().
+
+ (#) Configure the channels for regular group parameters (channel number,
+ channel rank into sequencer, ..., into regular group)
+ using function HAL_ADC_ConfigChannel().
+
+ (#) Optionally, configure the analog watchdog parameters (channels
+ monitored, thresholds, ...)
+ using function HAL_ADC_AnalogWDGConfig().
+
+ *** Execution of ADC conversions ***
+ ====================================
+ [..]
+
+ (#) Optionally, perform an automatic ADC calibration to improve the
+ conversion accuracy
+ using function HAL_ADCEx_Calibration_Start().
+
+ (#) ADC driver can be used among three modes: polling, interruption,
+ transfer by DMA.
+
+ (++) ADC conversion by polling:
+ (+++) Activate the ADC peripheral and start conversions
+ using function HAL_ADC_Start()
+ (+++) Wait for ADC conversion completion
+ using function HAL_ADC_PollForConversion()
+ (+++) Retrieve conversion results
+ using function HAL_ADC_GetValue()
+ (+++) Stop conversion and disable the ADC peripheral
+ using function HAL_ADC_Stop()
+
+ (++) ADC conversion by interruption:
+ (+++) Activate the ADC peripheral and start conversions
+ using function HAL_ADC_Start_IT()
+ (+++) Wait for ADC conversion completion by call of function
+ HAL_ADC_ConvCpltCallback()
+ (this function must be implemented in user program)
+ (+++) Retrieve conversion results
+ using function HAL_ADC_GetValue()
+ (+++) Stop conversion and disable the ADC peripheral
+ using function HAL_ADC_Stop_IT()
+
+ (++) ADC conversion with transfer by DMA:
+ (+++) Activate the ADC peripheral and start conversions
+ using function HAL_ADC_Start_DMA()
+ (+++) Wait for ADC conversion completion by call of function
+ HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback()
+ (these functions must be implemented in user program)
+ (+++) Conversion results are automatically transferred by DMA into
+ destination variable address.
+ (+++) Stop conversion and disable the ADC peripheral
+ using function HAL_ADC_Stop_DMA()
+
+ [..]
+
+ (@) Callback functions must be implemented in user program:
+ (+@) HAL_ADC_ErrorCallback()
+ (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog)
+ (+@) HAL_ADC_ConvCpltCallback()
+ (+@) HAL_ADC_ConvHalfCpltCallback
+
+ *** Deinitialization of ADC ***
+ ============================================================
+ [..]
+
+ (#) Disable the ADC interface
+ (++) ADC clock can be hard reset and disabled at RCC top level.
+ (++) Hard reset of ADC peripherals
+ using macro __HAL_RCC_ADCx_FORCE_RESET(), __HAL_RCC_ADCx_RELEASE_RESET().
+ (++) ADC clock disable
+ using the equivalent macro/functions as configuration step.
+ (+++) Example:
+ Into HAL_ADC_MspDeInit() (recommended code location) or with
+ other device clock parameters configuration:
+ (+++) __HAL_RCC_ADC_CLK_DISABLE(); (if not used anymore)
+ RCC_ADCCLKSOURCE_CLKP restore: (optional)
+ (+++) RCC_PeriphClkInitTypeDef RCC_PeriphClkInit;
+ (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
+ (+++) PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_CLKP;
+ (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
+
+ (#) ADC pins configuration
+ (++) Disable the clock for the ADC GPIOs
+ using macro __HAL_RCC_GPIOx_CLK_DISABLE()
+
+ (#) Optionally, in case of usage of ADC with interruptions:
+ (++) Disable the NVIC for ADC
+ using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
+
+ (#) Optionally, in case of usage of DMA:
+ (++) Deinitialize the DMA
+ using function HAL_DMA_Init().
+ (++) Disable the NVIC for DMA
+ using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
+
+ [..]
+
+ *** Callback registration ***
+ =============================================
+ [..]
+
+ The compilation flag USE_HAL_ADC_REGISTER_CALLBACKS, when set to 1,
+ allows the user to configure dynamically the driver callbacks.
+ Use Functions @ref HAL_ADC_RegisterCallback()
+ to register an interrupt callback.
+ [..]
+
+ Function @ref HAL_ADC_RegisterCallback() allows to register following callbacks:
+ (+) ConvCpltCallback : ADC conversion complete callback
+ (+) ConvHalfCpltCallback : ADC conversion DMA half-transfer callback
+ (+) LevelOutOfWindowCallback : ADC analog watchdog 1 callback
+ (+) ErrorCallback : ADC error callback
+ (+) InjectedConvCpltCallback : ADC group injected conversion complete callback
+ (+) InjectedQueueOverflowCallback : ADC group injected context queue overflow callback
+ (+) LevelOutOfWindow2Callback : ADC analog watchdog 2 callback
+ (+) LevelOutOfWindow3Callback : ADC analog watchdog 3 callback
+ (+) EndOfSamplingCallback : ADC end of sampling callback
+ (+) MspInitCallback : ADC Msp Init callback
+ (+) MspDeInitCallback : ADC Msp DeInit callback
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+ [..]
+
+ Use function @ref HAL_ADC_UnRegisterCallback to reset a callback to the default
+ weak function.
+ [..]
+
+ @ref HAL_ADC_UnRegisterCallback takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) ConvCpltCallback : ADC conversion complete callback
+ (+) ConvHalfCpltCallback : ADC conversion DMA half-transfer callback
+ (+) LevelOutOfWindowCallback : ADC analog watchdog 1 callback
+ (+) ErrorCallback : ADC error callback
+ (+) InjectedConvCpltCallback : ADC group injected conversion complete callback
+ (+) InjectedQueueOverflowCallback : ADC group injected context queue overflow callback
+ (+) LevelOutOfWindow2Callback : ADC analog watchdog 2 callback
+ (+) LevelOutOfWindow3Callback : ADC analog watchdog 3 callback
+ (+) EndOfSamplingCallback : ADC end of sampling callback
+ (+) MspInitCallback : ADC Msp Init callback
+ (+) MspDeInitCallback : ADC Msp DeInit callback
+ [..]
+
+ By default, after the @ref HAL_ADC_Init() and when the state is @ref HAL_ADC_STATE_RESET
+ all callbacks are set to the corresponding weak functions:
+ examples @ref HAL_ADC_ConvCpltCallback(), @ref HAL_ADC_ErrorCallback().
+ Exception done for MspInit and MspDeInit functions that are
+ reset to the legacy weak functions in the @ref HAL_ADC_Init()/ @ref HAL_ADC_DeInit() only when
+ these callbacks are null (not registered beforehand).
+ [..]
+
+ If MspInit or MspDeInit are not null, the @ref HAL_ADC_Init()/ @ref HAL_ADC_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
+ [..]
+
+ Callbacks can be registered/unregistered in @ref HAL_ADC_STATE_READY state only.
+ Exception done MspInit/MspDeInit functions that can be registered/unregistered
+ in @ref HAL_ADC_STATE_READY or @ref HAL_ADC_STATE_RESET state,
+ thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
+ [..]
+
+ Then, the user first registers the MspInit/MspDeInit user callbacks
+ using @ref HAL_ADC_RegisterCallback() before calling @ref HAL_ADC_DeInit()
+ or @ref HAL_ADC_Init() function.
+ [..]
+
+ When the compilation flag USE_HAL_ADC_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registration feature is not available and all callbacks
+ are set to the corresponding weak functions.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup ADC ADC
+ * @brief ADC HAL module driver
+ * @{
+ */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup ADC_Private_Constants ADC Private Constants
+ * @{
+ */
+#define ADC_CFGR_FIELDS_1 ((uint32_t)(ADC_CFGR_RES |\
+ ADC_CFGR_CONT | ADC_CFGR_OVRMOD |\
+ ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM |\
+ ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL)) /*!< ADC_CFGR fields of parameters that can be updated
+ when no regular conversion is on-going */
+
+#define ADC_CFGR2_FIELDS ((uint32_t)(ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR |\
+ ADC_CFGR2_OVSS | ADC_CFGR2_TROVS |\
+ ADC_CFGR2_ROVSM)) /*!< ADC_CFGR2 fields of parameters that can be updated when no conversion
+ (neither regular nor injected) is on-going */
+
+/* Timeout values for ADC operations (enable settling time, */
+/* disable settling time, ...). */
+/* Values defined to be higher than worst cases: low clock frequency, */
+/* maximum prescalers. */
+#define ADC_ENABLE_TIMEOUT (2UL) /*!< ADC enable time-out value */
+#define ADC_DISABLE_TIMEOUT (2UL) /*!< ADC disable time-out value */
+
+/* Timeout to wait for current conversion on going to be completed. */
+/* Timeout fixed to worst case, for 1 channel. */
+/* - maximum sampling time (830.5 adc_clk) */
+/* - ADC resolution (Tsar 16 bits= 16.5 adc_clk) */
+/* - ADC clock with prescaler 256 */
+/* 823 * 256 = 210688 clock cycles max */
+/* Unit: cycles of CPU clock. */
+#define ADC_CONVERSION_TIME_MAX_CPU_CYCLES ((uint32_t) 210688) /*!< ADC conversion completion time-out value */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup ADC_Exported_Functions ADC Exported Functions
+ * @{
+ */
+
+/** @defgroup ADC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief ADC Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize and configure the ADC.
+ (+) De-initialize the ADC.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the ADC peripheral and regular group according to
+ * parameters specified in structure "ADC_InitTypeDef".
+ * @note As prerequisite, ADC clock must be configured at RCC top level
+ * (refer to description of RCC configuration for ADC
+ * in header of this file).
+ * @note Possibility to update parameters on the fly:
+ * This function initializes the ADC MSP (HAL_ADC_MspInit()) only when
+ * coming from ADC state reset. Following calls to this function can
+ * be used to reconfigure some parameters of ADC_InitTypeDef
+ * structure on the fly, without modifying MSP configuration. If ADC
+ * MSP has to be modified again, HAL_ADC_DeInit() must be called
+ * before HAL_ADC_Init().
+ * The setting of these parameters is conditioned to ADC state.
+ * For parameters constraints, see comments of structure
+ * "ADC_InitTypeDef".
+ * @note This function configures the ADC within 2 scopes: scope of entire
+ * ADC and scope of regular group. For parameters details, see comments
+ * of structure "ADC_InitTypeDef".
+ * @note Parameters related to common ADC registers (ADC clock mode) are set
+ * only if all ADCs are disabled.
+ * If this is not the case, these common parameters setting are
+ * bypassed without error reporting: it can be the intended behaviour in
+ * case of update of a parameter of ADC_InitTypeDef on the fly,
+ * without disabling the other ADCs.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t tmpCFGR;
+ uint32_t tmp_adc_reg_is_conversion_on_going;
+ __IO uint32_t wait_loop_index = 0UL;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+
+ /* Check ADC handle */
+ if (hadc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler));
+ assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution));
+ assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
+ assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
+ assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv));
+ assert_param(IS_ADC_CONVERSIONDATAMGT(hadc->Init.ConversionDataManagement));
+ assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));
+ assert_param(IS_ADC_OVERRUN(hadc->Init.Overrun));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoWait));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.OversamplingMode));
+
+ if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
+ {
+ assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
+
+ if (hadc->Init.DiscontinuousConvMode == ENABLE)
+ {
+ assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(hadc->Init.NbrOfDiscConversion));
+ }
+ }
+
+ /* DISCEN and CONT bits cannot be set at the same time */
+ assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (hadc->Init.ContinuousConvMode == ENABLE)));
+
+ /* Actions performed only if ADC is coming from state reset: */
+ /* - Initialization of ADC MSP */
+ if (hadc->State == HAL_ADC_STATE_RESET)
+ {
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ /* Init the ADC Callback settings */
+ hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback; /* Legacy weak callback */
+ hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback; /* Legacy weak callback */
+ hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback; /* Legacy weak callback */
+ hadc->ErrorCallback = HAL_ADC_ErrorCallback; /* Legacy weak callback */
+ hadc->InjectedConvCpltCallback = HAL_ADCEx_InjectedConvCpltCallback; /* Legacy weak callback */
+ hadc->InjectedQueueOverflowCallback = HAL_ADCEx_InjectedQueueOverflowCallback; /* Legacy weak callback */
+ hadc->LevelOutOfWindow2Callback = HAL_ADCEx_LevelOutOfWindow2Callback; /* Legacy weak callback */
+ hadc->LevelOutOfWindow3Callback = HAL_ADCEx_LevelOutOfWindow3Callback; /* Legacy weak callback */
+ hadc->EndOfSamplingCallback = HAL_ADCEx_EndOfSamplingCallback; /* Legacy weak callback */
+
+ if (hadc->MspInitCallback == NULL)
+ {
+ hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */
+ }
+
+ /* Init the low level hardware */
+ hadc->MspInitCallback(hadc);
+#else
+ /* Init the low level hardware */
+ HAL_ADC_MspInit(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+
+ /* Initialize Lock */
+ hadc->Lock = HAL_UNLOCKED;
+ }
+
+ /* - Exit from deep-power-down mode and ADC voltage regulator enable */
+ if (LL_ADC_IsDeepPowerDownEnabled(hadc->Instance) != 0UL)
+ {
+ /* Disable ADC deep power down mode */
+ LL_ADC_DisableDeepPowerDown(hadc->Instance);
+
+ /* System was in deep power down mode, calibration must
+ be relaunched or a previously saved calibration factor
+ re-applied once the ADC voltage regulator is enabled */
+ }
+
+ if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL)
+ {
+ /* Enable ADC internal voltage regulator */
+ LL_ADC_EnableInternalRegulator(hadc->Instance);
+
+ /* Note: Variable divided by 2 to compensate partially */
+ /* CPU processing cycles, scaling in us split to not */
+ /* exceed 32 bits register capacity and handle low frequency. */
+ wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
+ while (wait_loop_index != 0UL)
+ {
+ wait_loop_index--;
+ }
+ }
+
+ /* Verification that ADC voltage regulator is correctly enabled, whether */
+ /* or not ADC is coming from state reset (if any potential problem of */
+ /* clocking, voltage regulator would not be enabled). */
+ if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Configuration of ADC parameters if previous preliminary actions are */
+ /* correctly completed and if there is no conversion on going on regular */
+ /* group (ADC may already be enabled at this point if HAL_ADC_Init() is */
+ /* called to update a parameter on the fly). */
+ tmp_adc_reg_is_conversion_on_going = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+
+ if (((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
+ && (tmp_adc_reg_is_conversion_on_going == 0UL)
+ )
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY,
+ HAL_ADC_STATE_BUSY_INTERNAL);
+
+ /* Configuration of common ADC parameters */
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated only when ADC is disabled: */
+ /* - clock configuration */
+ if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
+ {
+ /* Reset configuration of ADC common register CCR: */
+ /* */
+ /* - ADC clock mode and ACC prescaler (CKMODE and PRESC bits)are set */
+ /* according to adc->Init.ClockPrescaler. It selects the clock */
+ /* source and sets the clock division factor. */
+ /* */
+ /* Some parameters of this register are not reset, since they are set */
+ /* by other functions and must be kept in case of usage of this */
+ /* function on the fly (update of a parameter of ADC_InitTypeDef */
+ /* without needing to reconfigure all other ADC groups/channels */
+ /* parameters): */
+ /* - when multimode feature is available, multimode-related */
+ /* parameters: MDMA, DMACFG, DELAY, DUAL (set by API */
+ /* HAL_ADCEx_MultiModeConfigChannel() ) */
+ /* - internal measurement paths: Vbat, temperature sensor, Vref */
+ /* (set into HAL_ADC_ConfigChannel() or */
+ /* HAL_ADCEx_InjectedConfigChannel() ) */
+ LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(hadc->Instance), hadc->Init.ClockPrescaler);
+ }
+ }
+
+ /* Configuration of ADC: */
+ /* - resolution Init.Resolution */
+ /* - external trigger to start conversion Init.ExternalTrigConv */
+ /* - external trigger polarity Init.ExternalTrigConvEdge */
+ /* - continuous conversion mode Init.ContinuousConvMode */
+ /* - overrun Init.Overrun */
+ /* - discontinuous mode Init.DiscontinuousConvMode */
+ /* - discontinuous mode channel count Init.NbrOfDiscConversion */
+#if defined(ADC_VER_V5_3)
+ tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
+ hadc->Init.Overrun |
+ hadc->Init.Resolution |
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode) );
+
+#else
+ if((HAL_GetREVID() > REV_ID_Y) && (ADC_RESOLUTION_8B == hadc->Init.Resolution))
+ {
+ /* for STM32H7 silicon rev.B and above , ADC_CFGR_RES value for 8bits resolution is : b111 */
+ tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
+ hadc->Init.Overrun |
+ hadc->Init.Resolution |(ADC_CFGR_RES_1|ADC_CFGR_RES_0) |
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode) );
+ }
+ else
+ {
+ tmpCFGR = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
+ hadc->Init.Overrun |
+ hadc->Init.Resolution |
+ ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode) );
+ }
+
+#endif /* ADC_VER_V5_3 */
+
+ if (hadc->Init.DiscontinuousConvMode == ENABLE)
+ {
+ tmpCFGR |= ADC_CFGR_DISCONTINUOUS_NUM(hadc->Init.NbrOfDiscConversion);
+ }
+
+ /* Enable external trigger if trigger selection is different of software */
+ /* start. */
+ /* Note: This configuration keeps the hardware feature of parameter */
+ /* ExternalTrigConvEdge "trigger edge none" equivalent to */
+ /* software start. */
+ if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START)
+ {
+ tmpCFGR |= ((hadc->Init.ExternalTrigConv & ADC_CFGR_EXTSEL)
+ | hadc->Init.ExternalTrigConvEdge
+ );
+ }
+
+ /* Update Configuration Register CFGR */
+ MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_1, tmpCFGR);
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on regular and injected groups: */
+ /* - Conversion data management Init.ConversionDataManagement */
+ /* - LowPowerAutoWait feature Init.LowPowerAutoWait */
+ /* - Oversampling parameters Init.Oversampling */
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+ if ((tmp_adc_is_conversion_on_going_regular == 0UL)
+ && (tmp_adc_is_conversion_on_going_injected == 0UL)
+ )
+ {
+ tmpCFGR = (
+ ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) |
+ ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.ConversionDataManagement));
+
+ MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_2, tmpCFGR);
+
+ if (hadc->Init.OversamplingMode == ENABLE)
+ {
+ assert_param(IS_ADC_OVERSAMPLING_RATIO(hadc->Init.Oversampling.Ratio));
+ assert_param(IS_ADC_RIGHT_BIT_SHIFT(hadc->Init.Oversampling.RightBitShift));
+ assert_param(IS_ADC_TRIGGERED_OVERSAMPLING_MODE(hadc->Init.Oversampling.TriggeredMode));
+ assert_param(IS_ADC_REGOVERSAMPLING_MODE(hadc->Init.Oversampling.OversamplingStopReset));
+
+ if ((hadc->Init.ExternalTrigConv == ADC_SOFTWARE_START)
+ || (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE))
+ {
+ /* Multi trigger is not applicable to software-triggered conversions */
+ assert_param((hadc->Init.Oversampling.TriggeredMode == ADC_TRIGGEREDMODE_SINGLE_TRIGGER));
+ }
+
+ /* Configuration of Oversampler: */
+ /* - Oversampling Ratio */
+ /* - Right bit shift */
+ /* - Left bit shift */
+ /* - Triggered mode */
+ /* - Oversampling mode (continued/resumed) */
+ MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_FIELDS,
+ ADC_CFGR2_ROVSE |
+ ((hadc->Init.Oversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
+ hadc->Init.Oversampling.RightBitShift |
+ hadc->Init.Oversampling.TriggeredMode |
+ hadc->Init.Oversampling.OversamplingStopReset);
+
+ }
+ else
+ {
+ /* Disable ADC oversampling scope on ADC group regular */
+ CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE);
+ }
+
+ /* Set the LeftShift parameter: it is applied to the final result with or without oversampling */
+ MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_LSHIFT, hadc->Init.LeftBitShift);
+
+ /* Configure the BOOST Mode */
+ ADC_ConfigureBoostMode(hadc);
+ }
+
+ /* Configuration of regular group sequencer: */
+ /* - if scan mode is disabled, regular channels sequence length is set to */
+ /* 0x00: 1 channel converted (channel on regular rank 1) */
+ /* Parameter "NbrOfConversion" is discarded. */
+ /* Note: Scan mode is not present by hardware on this device, but */
+ /* emulated by software for alignment over all STM32 devices. */
+ /* - if scan mode is enabled, regular channels sequence length is set to */
+ /* parameter "NbrOfConversion". */
+
+ if (hadc->Init.ScanConvMode == ADC_SCAN_ENABLE)
+ {
+ /* Set number of ranks in regular group sequencer */
+ MODIFY_REG(hadc->Instance->SQR1, ADC_SQR1_L, (hadc->Init.NbrOfConversion - (uint8_t)1));
+ }
+ else
+ {
+ CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L);
+ }
+
+ /* Initialize the ADC state */
+ /* Clear HAL_ADC_STATE_BUSY_INTERNAL bit, set HAL_ADC_STATE_READY bit */
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_READY);
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Deinitialize the ADC peripheral registers to their default reset
+ * values, with deinitialization of the ADC MSP.
+ * @note For devices with several ADCs: reset of ADC common registers is done
+ * only if all ADCs sharing the same common group are disabled.
+ * (function "HAL_ADC_MspDeInit()" is also called under the same conditions:
+ * all ADC instances use the same core clock at RCC level, disabling
+ * the core clock reset all ADC instances).
+ * If this is not the case, reset of these common parameters reset is
+ * bypassed without error reporting: it can be the intended behavior in
+ * case of reset of a single ADC while the other ADCs sharing the same
+ * common group is still running.
+ * @note By default, HAL_ADC_DeInit() set ADC in mode deep power-down:
+ * this saves more power by reducing leakage currents
+ * and is particularly interesting before entering MCU low-power modes.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check ADC handle */
+ if (hadc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL);
+
+ /* Stop potential conversion on going */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped */
+ /* Flush register JSQR: reset the queue sequencer when injected */
+ /* queue sequencer is enabled and ADC disabled. */
+ /* The software and hardware triggers of the injected sequence are both */
+ /* internally disabled just after the completion of the last valid */
+ /* injected sequence. */
+ SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JQM);
+
+ /* Disable ADC peripheral if conversions are effectively stopped */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Disable the ADC peripheral */
+ tmp_hal_status = ADC_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Change ADC state */
+ hadc->State = HAL_ADC_STATE_READY;
+ }
+ }
+
+ /* Note: HAL ADC deInit is done independently of ADC conversion stop */
+ /* and disable return status. In case of status fail, attempt to */
+ /* perform deinitialization anyway and it is up user code in */
+ /* in HAL_ADC_MspDeInit() to reset the ADC peripheral using */
+ /* system RCC hard reset. */
+
+ /* ========== Reset ADC registers ========== */
+ /* Reset register IER */
+ __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_AWD3 | ADC_IT_AWD2 | ADC_IT_AWD1 |
+ ADC_IT_JQOVF | ADC_IT_OVR |
+ ADC_IT_JEOS | ADC_IT_JEOC |
+ ADC_IT_EOS | ADC_IT_EOC |
+ ADC_IT_EOSMP | ADC_IT_RDY));
+
+ /* Reset register ISR */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD3 | ADC_FLAG_AWD2 | ADC_FLAG_AWD1 |
+ ADC_FLAG_JQOVF | ADC_FLAG_OVR |
+ ADC_FLAG_JEOS | ADC_FLAG_JEOC |
+ ADC_FLAG_EOS | ADC_FLAG_EOC |
+ ADC_FLAG_EOSMP | ADC_FLAG_RDY));
+
+ /* Reset register CR */
+ /* Bits ADC_CR_JADSTP, ADC_CR_ADSTP, ADC_CR_JADSTART, ADC_CR_ADSTART,
+ ADC_CR_ADCAL, ADC_CR_ADDIS and ADC_CR_ADEN are in access mode "read-set":
+ no direct reset applicable.
+ Update CR register to reset value where doable by software */
+ CLEAR_BIT(hadc->Instance->CR, ADC_CR_ADVREGEN | ADC_CR_ADCALDIF);
+ SET_BIT(hadc->Instance->CR, ADC_CR_DEEPPWD);
+
+ /* Reset register CFGR */
+ CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_AWD1CH | ADC_CFGR_JAUTO | ADC_CFGR_JAWD1EN |
+ ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL | ADC_CFGR_JQM |
+ ADC_CFGR_JDISCEN | ADC_CFGR_DISCNUM | ADC_CFGR_DISCEN |
+ ADC_CFGR_AUTDLY | ADC_CFGR_CONT | ADC_CFGR_OVRMOD |
+ ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL |
+ ADC_CFGR_RES | ADC_CFGR_DMNGT);
+ SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
+
+ /* Reset register CFGR2 */
+ CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSM | ADC_CFGR2_TROVS | ADC_CFGR2_OVSS |
+ ADC_CFGR2_OVSR | ADC_CFGR2_JOVSE | ADC_CFGR2_ROVSE);
+
+ /* Reset register SMPR1 */
+ CLEAR_BIT(hadc->Instance->SMPR1, ADC_SMPR1_FIELDS);
+
+ /* Reset register SMPR2 */
+ CLEAR_BIT(hadc->Instance->SMPR2, ADC_SMPR2_SMP18 | ADC_SMPR2_SMP17 | ADC_SMPR2_SMP16 |
+ ADC_SMPR2_SMP15 | ADC_SMPR2_SMP14 | ADC_SMPR2_SMP13 |
+ ADC_SMPR2_SMP12 | ADC_SMPR2_SMP11 | ADC_SMPR2_SMP10);
+
+ /* Reset register LTR1 and HTR1 */
+ CLEAR_BIT(hadc->Instance->LTR1, ADC_LTR_LT);
+ CLEAR_BIT(hadc->Instance->HTR1, ADC_HTR_HT);
+
+ /* Reset register LTR2 and HTR2*/
+ CLEAR_BIT(hadc->Instance->LTR2, ADC_LTR_LT);
+ CLEAR_BIT(hadc->Instance->HTR2, ADC_HTR_HT);
+
+ /* Reset register LTR3 and HTR3 */
+ CLEAR_BIT(hadc->Instance->LTR3, ADC_LTR_LT);
+ CLEAR_BIT(hadc->Instance->HTR3, ADC_HTR_HT);
+
+ /* Reset register SQR1 */
+ CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_SQ4 | ADC_SQR1_SQ3 | ADC_SQR1_SQ2 |
+ ADC_SQR1_SQ1 | ADC_SQR1_L);
+
+ /* Reset register SQR2 */
+ CLEAR_BIT(hadc->Instance->SQR2, ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7 |
+ ADC_SQR2_SQ6 | ADC_SQR2_SQ5);
+
+ /* Reset register SQR3 */
+ CLEAR_BIT(hadc->Instance->SQR3, ADC_SQR3_SQ14 | ADC_SQR3_SQ13 | ADC_SQR3_SQ12 |
+ ADC_SQR3_SQ11 | ADC_SQR3_SQ10);
+
+ /* Reset register SQR4 */
+ CLEAR_BIT(hadc->Instance->SQR4, ADC_SQR4_SQ16 | ADC_SQR4_SQ15);
+
+ /* Register JSQR was reset when the ADC was disabled */
+
+ /* Reset register DR */
+ /* bits in access mode read only, no direct reset applicable*/
+
+ /* Reset register OFR1 */
+ CLEAR_BIT(hadc->Instance->OFR1, ADC_OFR1_SSATE | ADC_OFR1_OFFSET1_CH | ADC_OFR1_OFFSET1);
+ /* Reset register OFR2 */
+ CLEAR_BIT(hadc->Instance->OFR2, ADC_OFR2_SSATE | ADC_OFR2_OFFSET2_CH | ADC_OFR2_OFFSET2);
+ /* Reset register OFR3 */
+ CLEAR_BIT(hadc->Instance->OFR3, ADC_OFR3_SSATE | ADC_OFR3_OFFSET3_CH | ADC_OFR3_OFFSET3);
+ /* Reset register OFR4 */
+ CLEAR_BIT(hadc->Instance->OFR4, ADC_OFR4_SSATE | ADC_OFR4_OFFSET4_CH | ADC_OFR4_OFFSET4);
+
+ /* Reset registers JDR1, JDR2, JDR3, JDR4 */
+ /* bits in access mode read only, no direct reset applicable*/
+
+ /* Reset register AWD2CR */
+ CLEAR_BIT(hadc->Instance->AWD2CR, ADC_AWD2CR_AWD2CH);
+
+ /* Reset register AWD3CR */
+ CLEAR_BIT(hadc->Instance->AWD3CR, ADC_AWD3CR_AWD3CH);
+
+ /* Reset register DIFSEL */
+ CLEAR_BIT(hadc->Instance->DIFSEL, ADC_DIFSEL_DIFSEL);
+
+ /* Reset register CALFACT */
+ CLEAR_BIT(hadc->Instance->CALFACT, ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S);
+
+
+ /* ========== Reset common ADC registers ========== */
+
+ /* Software is allowed to change common parameters only when all the other
+ ADCs are disabled. */
+ if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
+ {
+ /* Reset configuration of ADC common register CCR:
+ - clock mode: CKMODE, PRESCEN
+ - multimode related parameters(when this feature is available): DELAY, DUAL
+ (set into HAL_ADCEx_MultiModeConfigChannel() API)
+ - internal measurement paths: Vbat, temperature sensor, Vref (set into
+ HAL_ADC_ConfigChannel() or HAL_ADCEx_InjectedConfigChannel() )
+ */
+ ADC_CLEAR_COMMON_CONTROL_REGISTER(hadc);
+ }
+
+ /* DeInit the low level hardware.
+
+ For example:
+ __HAL_RCC_ADC_FORCE_RESET();
+ __HAL_RCC_ADC_RELEASE_RESET();
+ __HAL_RCC_ADC_CLK_DISABLE();
+
+ Keep in mind that all ADCs use the same clock: disabling
+ the clock will reset all ADCs.
+
+ */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ if (hadc->MspDeInitCallback == NULL)
+ {
+ hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
+ }
+
+ /* DeInit the low level hardware: RCC clock, NVIC */
+ hadc->MspDeInitCallback(hadc);
+#else
+ /* DeInit the low level hardware: RCC clock, NVIC */
+ HAL_ADC_MspDeInit(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+
+ /* Reset injected channel configuration parameters */
+ hadc->InjectionConfig.ContextQueue = 0;
+ hadc->InjectionConfig.ChannelCount = 0;
+
+ /* Set ADC state */
+ hadc->State = HAL_ADC_STATE_RESET;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Initialize the ADC MSP.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_MspInit must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief DeInitialize the ADC MSP.
+ * @param hadc ADC handle
+ * @note All ADC instances use the same core clock at RCC level, disabling
+ * the core clock reset all ADC instances).
+ * @retval None
+ */
+__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_MspDeInit must be implemented in the user file.
+ */
+}
+
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User ADC Callback
+ * To be used instead of the weak predefined callback
+ * @param hadc Pointer to a ADC_HandleTypeDef structure that contains
+ * the configuration information for the specified ADC.
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID
+ * @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion DMA half-transfer callback ID
+ * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID
+ * @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID
+ * @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID
+ * @arg @ref HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID ADC group injected context queue overflow callback ID
+ * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID ADC analog watchdog 2 callback ID
+ * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID ADC analog watchdog 3 callback ID
+ * @arg @ref HAL_ADC_END_OF_SAMPLING_CB_ID ADC end of sampling callback ID
+ * @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID
+ * @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID, pADC_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+
+ if ((hadc->State & HAL_ADC_STATE_READY) != 0UL)
+ {
+ switch (CallbackID)
+ {
+ case HAL_ADC_CONVERSION_COMPLETE_CB_ID :
+ hadc->ConvCpltCallback = pCallback;
+ break;
+
+ case HAL_ADC_CONVERSION_HALF_CB_ID :
+ hadc->ConvHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID :
+ hadc->LevelOutOfWindowCallback = pCallback;
+ break;
+
+ case HAL_ADC_ERROR_CB_ID :
+ hadc->ErrorCallback = pCallback;
+ break;
+
+ case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID :
+ hadc->InjectedConvCpltCallback = pCallback;
+ break;
+
+ case HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID :
+ hadc->InjectedQueueOverflowCallback = pCallback;
+ break;
+
+ case HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID :
+ hadc->LevelOutOfWindow2Callback = pCallback;
+ break;
+
+ case HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID :
+ hadc->LevelOutOfWindow3Callback = pCallback;
+ break;
+
+ case HAL_ADC_END_OF_SAMPLING_CB_ID :
+ hadc->EndOfSamplingCallback = pCallback;
+ break;
+
+ case HAL_ADC_MSPINIT_CB_ID :
+ hadc->MspInitCallback = pCallback;
+ break;
+
+ case HAL_ADC_MSPDEINIT_CB_ID :
+ hadc->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_ADC_STATE_RESET == hadc->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_ADC_MSPINIT_CB_ID :
+ hadc->MspInitCallback = pCallback;
+ break;
+
+ case HAL_ADC_MSPDEINIT_CB_ID :
+ hadc->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister a ADC Callback
+ * ADC callback is redirected to the weak predefined callback
+ * @param hadc Pointer to a ADC_HandleTypeDef structure that contains
+ * the configuration information for the specified ADC.
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID
+ * @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion DMA half-transfer callback ID
+ * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID
+ * @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID
+ * @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID
+ * @arg @ref HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID ADC group injected context queue overflow callback ID
+ * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID ADC analog watchdog 2 callback ID
+ * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID ADC analog watchdog 3 callback ID
+ * @arg @ref HAL_ADC_END_OF_SAMPLING_CB_ID ADC end of sampling callback ID
+ * @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID
+ * @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if ((hadc->State & HAL_ADC_STATE_READY) != 0UL)
+ {
+ switch (CallbackID)
+ {
+ case HAL_ADC_CONVERSION_COMPLETE_CB_ID :
+ hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback;
+ break;
+
+ case HAL_ADC_CONVERSION_HALF_CB_ID :
+ hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback;
+ break;
+
+ case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID :
+ hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback;
+ break;
+
+ case HAL_ADC_ERROR_CB_ID :
+ hadc->ErrorCallback = HAL_ADC_ErrorCallback;
+ break;
+
+ case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID :
+ hadc->InjectedConvCpltCallback = HAL_ADCEx_InjectedConvCpltCallback;
+ break;
+
+ case HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID :
+ hadc->InjectedQueueOverflowCallback = HAL_ADCEx_InjectedQueueOverflowCallback;
+ break;
+
+ case HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID :
+ hadc->LevelOutOfWindow2Callback = HAL_ADCEx_LevelOutOfWindow2Callback;
+ break;
+
+ case HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID :
+ hadc->LevelOutOfWindow3Callback = HAL_ADCEx_LevelOutOfWindow3Callback;
+ break;
+
+ case HAL_ADC_END_OF_SAMPLING_CB_ID :
+ hadc->EndOfSamplingCallback = HAL_ADCEx_EndOfSamplingCallback;
+ break;
+
+ case HAL_ADC_MSPINIT_CB_ID :
+ hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_ADC_MSPDEINIT_CB_ID :
+ hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_ADC_STATE_RESET == hadc->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_ADC_MSPINIT_CB_ID :
+ hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_ADC_MSPDEINIT_CB_ID :
+ hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Exported_Functions_Group2 ADC Input and Output operation functions
+ * @brief ADC IO operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Start conversion of regular group.
+ (+) Stop conversion of regular group.
+ (+) Poll for conversion complete on regular group.
+ (+) Poll for conversion event.
+ (+) Get result of regular channel conversion.
+ (+) Start conversion of regular group and enable interruptions.
+ (+) Stop conversion of regular group and disable interruptions.
+ (+) Handle ADC interrupt request
+ (+) Start conversion of regular group and enable DMA transfer.
+ (+) Stop conversion of regular group and disable ADC DMA transfer.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enable ADC, start conversion of regular group.
+ * @note Interruptions enabled in this function: None.
+ * @note Case of multimode enabled (when multimode feature is available):
+ * if ADC is Slave, ADC is enabled but conversion is not started,
+ * if ADC is master, ADC is enabled and multimode conversion is started.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ const ADC_TypeDef *tmpADC_Master;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Perform ADC enable and conversion start if no conversion is on going */
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit
+ - if ADC instance is master or if multimode feature is not available
+ - if multimode setting is disabled (ADC instance slave in independent mode) */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ )
+ {
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ /* Set ADC error code */
+ /* Check if a conversion is on going on ADC group injected */
+ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
+ {
+ /* Reset ADC error code fields related to regular conversions only */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset all ADC error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Clear ADC group regular conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Enable conversion of regular group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Case of multimode enabled (when multimode feature is available): */
+ /* - if ADC is slave and dual regular conversions are enabled, ADC is */
+ /* enabled only (conversion is not started), */
+ /* - if ADC is master, ADC is enabled and conversion is started. */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN)
+ )
+ {
+ /* ADC instance is not a multimode slave instance with multimode regular conversions enabled */
+ if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO) != 0UL)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+
+ /* Start ADC group regular conversion */
+ LL_ADC_REG_StartConversion(hadc->Instance);
+ }
+ else
+ {
+ /* ADC instance is a multimode slave instance with multimode regular conversions enabled */
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ /* if Master ADC JAUTO bit is set, update Slave State in setting
+ HAL_ADC_STATE_INJ_BUSY bit and in resetting HAL_ADC_STATE_INJ_EOC bit */
+ tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance);
+ if (READ_BIT(tmpADC_Master->CFGR, ADC_CFGR_JAUTO) != 0UL)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ }
+
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+ }
+ else
+ {
+ tmp_hal_status = HAL_BUSY;
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected channels in
+ * case of auto_injection mode), disable ADC peripheral.
+ * @note: ADC peripheral disable is forcing stop of potential
+ * conversion on injected group. If injected group is under use, it
+ * should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential conversion on going, on ADC groups regular and injected */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* 2. Disable the ADC peripheral */
+ tmp_hal_status = ADC_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Wait for regular group conversion to be completed.
+ * @note ADC conversion flags EOS (end of sequence) and EOC (end of
+ * conversion) are cleared by this function, with an exception:
+ * if low power feature "LowPowerAutoWait" is enabled, flags are
+ * not cleared to not interfere with this feature until data register
+ * is read using function HAL_ADC_GetValue().
+ * @note This function cannot be used in a particular setup: ADC configured
+ * in DMA mode and polling for end of each conversion (ADC init
+ * parameter "EOCSelection" set to ADC_EOC_SINGLE_CONV).
+ * In this case, DMA resets the flag EOC and polling cannot be
+ * performed on each conversion. Nevertheless, polling can still
+ * be performed on the complete sequence (ADC init
+ * parameter "EOCSelection" set to ADC_EOC_SEQ_CONV).
+ * @param hadc ADC handle
+ * @param Timeout Timeout value in millisecond.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)
+{
+ uint32_t tickstart;
+ uint32_t tmp_Flag_End;
+ uint32_t tmp_cfgr;
+ const ADC_TypeDef *tmpADC_Master;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* If end of conversion selected to end of sequence conversions */
+ if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
+ {
+ tmp_Flag_End = ADC_FLAG_EOS;
+ }
+ /* If end of conversion selected to end of unitary conversion */
+ else /* ADC_EOC_SINGLE_CONV */
+ {
+ /* Verification that ADC configuration is compliant with polling for */
+ /* each conversion: */
+ /* Particular case is ADC configured in DMA mode and ADC sequencer with */
+ /* several ranks and polling for end of each conversion. */
+ /* For code simplicity sake, this particular case is generalized to */
+ /* ADC configured in DMA mode and and polling for end of each conversion. */
+ if ((tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN)
+ )
+ {
+ /* Check DMNGT bit in handle ADC CFGR register */
+ if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMNGT_0) != 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+ return HAL_ERROR;
+ }
+ else
+ {
+ tmp_Flag_End = (ADC_FLAG_EOC);
+ }
+ }
+ else
+ {
+ /* Check ADC DMA mode in multimode on ADC group regular */
+ if (LL_ADC_GetMultiDMATransfer(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) != LL_ADC_MULTI_REG_DMA_EACH_ADC)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+ return HAL_ERROR;
+ }
+ else
+ {
+ tmp_Flag_End = (ADC_FLAG_EOC);
+ }
+ }
+ }
+
+ /* Get tick count */
+ tickstart = HAL_GetTick();
+
+ /* Wait until End of unitary conversion or sequence conversions flag is raised */
+ while ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Update ADC state machine */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
+
+ /* Determine whether any further conversion upcoming on group regular */
+ /* by external trigger, continuous mode or scan sequence on going. */
+ if ((LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
+ && (hadc->Init.ContinuousConvMode == DISABLE)
+ )
+ {
+ /* Check whether end of sequence is reached */
+ if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
+ {
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+ }
+
+ /* Get relevant register CFGR in ADC instance of ADC master or slave */
+ /* in function of multimode state (for devices with multimode */
+ /* available). */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN)
+ )
+ {
+ /* Retrieve handle ADC CFGR register */
+ tmp_cfgr = READ_REG(hadc->Instance->CFGR);
+ }
+ else
+ {
+ /* Retrieve Master ADC CFGR register */
+ tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance);
+ tmp_cfgr = READ_REG(tmpADC_Master->CFGR);
+ }
+
+ /* Clear polled flag */
+ if (tmp_Flag_End == ADC_FLAG_EOS)
+ {
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOS);
+ }
+ else
+ {
+ /* Clear end of conversion EOC flag of regular group if low power feature */
+ /* "LowPowerAutoWait " is disabled, to not interfere with this feature */
+ /* until data register is read using function HAL_ADC_GetValue(). */
+ if (READ_BIT(tmp_cfgr, ADC_CFGR_AUTDLY) == 0UL)
+ {
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS));
+ }
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Poll for ADC event.
+ * @param hadc ADC handle
+ * @param EventType the ADC event type.
+ * This parameter can be one of the following values:
+ * @arg @ref ADC_EOSMP_EVENT ADC End of Sampling event
+ * @arg @ref ADC_AWD1_EVENT ADC Analog watchdog 1 event (main analog watchdog, present on all STM32 devices)
+ * @arg @ref ADC_AWD2_EVENT ADC Analog watchdog 2 event (additional analog watchdog, not present on all STM32 families)
+ * @arg @ref ADC_AWD3_EVENT ADC Analog watchdog 3 event (additional analog watchdog, not present on all STM32 families)
+ * @arg @ref ADC_OVR_EVENT ADC Overrun event
+ * @arg @ref ADC_JQOVF_EVENT ADC Injected context queue overflow event
+ * @param Timeout Timeout value in millisecond.
+ * @note The relevant flag is cleared if found to be set, except for ADC_FLAG_OVR.
+ * Indeed, the latter is reset only if hadc->Init.Overrun field is set
+ * to ADC_OVR_DATA_OVERWRITTEN. Otherwise, data register may be potentially overwritten
+ * by a new converted data as soon as OVR is cleared.
+ * To reset OVR flag once the preserved data is retrieved, the user can resort
+ * to macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef *hadc, uint32_t EventType, uint32_t Timeout)
+{
+ uint32_t tickstart;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_EVENT_TYPE(EventType));
+
+ /* Get tick count */
+ tickstart = HAL_GetTick();
+
+ /* Check selected event flag */
+ while (__HAL_ADC_GET_FLAG(hadc, EventType) == 0UL)
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ switch (EventType)
+ {
+ /* End Of Sampling event */
+ case ADC_EOSMP_EVENT:
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOSMP);
+
+ /* Clear the End Of Sampling flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP);
+
+ break;
+
+ /* Analog watchdog (level out of window) event */
+ /* Note: In case of several analog watchdog enabled, if needed to know */
+ /* which one triggered and on which ADCx, test ADC state of analog watchdog */
+ /* flags HAL_ADC_STATE_AWD1/2/3 using function "HAL_ADC_GetState()". */
+ /* For example: */
+ /* " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD1) != 0UL) " */
+ /* " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD2) != 0UL) " */
+ /* " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD3) != 0UL) " */
+
+ /* Check analog watchdog 1 flag */
+ case ADC_AWD_EVENT:
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
+
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD1);
+
+ break;
+
+ /* Check analog watchdog 2 flag */
+ case ADC_AWD2_EVENT:
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD2);
+
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD2);
+
+ break;
+
+ /* Check analog watchdog 3 flag */
+ case ADC_AWD3_EVENT:
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD3);
+
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD3);
+
+ break;
+
+ /* Injected context queue overflow event */
+ case ADC_JQOVF_EVENT:
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);
+
+ /* Set ADC error code to Injected context queue overflow */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
+
+ /* Clear ADC Injected context queue overflow flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JQOVF);
+
+ break;
+
+ /* Overrun event */
+ default: /* Case ADC_OVR_EVENT */
+ /* If overrun is set to overwrite previous data, overrun event is not */
+ /* considered as an error. */
+ /* (cf ref manual "Managing conversions without using the DMA and without */
+ /* overrun ") */
+ if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR);
+
+ /* Set ADC error code to overrun */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
+ }
+ else
+ {
+ /* Clear ADC Overrun flag only if Overrun is set to ADC_OVR_DATA_OVERWRITTEN
+ otherwise, data register is potentially overwritten by new converted data as soon
+ as OVR is cleared. */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
+ }
+ break;
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Enable ADC, start conversion of regular group with interruption.
+ * @note Interruptions enabled in this function according to initialization
+ * setting : EOC (end of conversion), EOS (end of sequence),
+ * OVR overrun.
+ * Each of these interruptions has its dedicated callback function.
+ * @note Case of multimode enabled (when multimode feature is available):
+ * HAL_ADC_Start_IT() must be called for ADC Slave first, then for
+ * ADC Master.
+ * For ADC Slave, ADC is enabled only (conversion is not started).
+ * For ADC Master, ADC is enabled and multimode conversion is started.
+ * @note To guarantee a proper reset of all interruptions once all the needed
+ * conversions are obtained, HAL_ADC_Stop_IT() must be called to ensure
+ * a correct stop of the IT-based conversions.
+ * @note By default, HAL_ADC_Start_IT() does not enable the End Of Sampling
+ * interruption. If required (e.g. in case of oversampling with trigger
+ * mode), the user must:
+ * 1. first clear the EOSMP flag if set with macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP)
+ * 2. then enable the EOSMP interrupt with macro __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOSMP)
+ * before calling HAL_ADC_Start_IT().
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ const ADC_TypeDef *tmpADC_Master;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Perform ADC enable and conversion start if no conversion is on going */
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit
+ - if ADC instance is master or if multimode feature is not available
+ - if multimode setting is disabled (ADC instance slave in independent mode) */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ )
+ {
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ /* Set ADC error code */
+ /* Check if a conversion is on going on ADC group injected */
+ if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) != 0UL)
+ {
+ /* Reset ADC error code fields related to regular conversions only */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset all ADC error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Clear ADC group regular conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Disable all interruptions before enabling the desired ones */
+ __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
+
+ /* Enable ADC end of conversion interrupt */
+ switch (hadc->Init.EOCSelection)
+ {
+ case ADC_EOC_SEQ_CONV:
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOS);
+ break;
+ /* case ADC_EOC_SINGLE_CONV */
+ default:
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC);
+ break;
+ }
+
+ /* Enable ADC overrun interrupt */
+ /* If hadc->Init.Overrun is set to ADC_OVR_DATA_PRESERVED, only then is
+ ADC_IT_OVR enabled; otherwise data overwrite is considered as normal
+ behavior and no CPU time is lost for a non-processed interruption */
+ if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
+ {
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
+ }
+
+ /* Enable conversion of regular group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Case of multimode enabled (when multimode feature is available): */
+ /* - if ADC is slave and dual regular conversions are enabled, ADC is */
+ /* enabled only (conversion is not started), */
+ /* - if ADC is master, ADC is enabled and conversion is started. */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN)
+ )
+ {
+ /* ADC instance is not a multimode slave instance with multimode regular conversions enabled */
+ if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO) != 0UL)
+ {
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+
+ /* Enable as well injected interruptions in case
+ HAL_ADCEx_InjectedStart_IT() has not been called beforehand. This
+ allows to start regular and injected conversions when JAUTO is
+ set with a single call to HAL_ADC_Start_IT() */
+ switch (hadc->Init.EOCSelection)
+ {
+ case ADC_EOC_SEQ_CONV:
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS);
+ break;
+ /* case ADC_EOC_SINGLE_CONV */
+ default:
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS);
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
+ break;
+ }
+ }
+
+ /* Start ADC group regular conversion */
+ LL_ADC_REG_StartConversion(hadc->Instance);
+ }
+ else
+ {
+ /* ADC instance is a multimode slave instance with multimode regular conversions enabled */
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ /* if Master ADC JAUTO bit is set, Slave injected interruptions
+ are enabled nevertheless (for same reason as above) */
+ tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance);
+ if (READ_BIT(tmpADC_Master->CFGR, ADC_CFGR_JAUTO) != 0UL)
+ {
+ /* First, update Slave State in setting HAL_ADC_STATE_INJ_BUSY bit
+ and in resetting HAL_ADC_STATE_INJ_EOC bit */
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
+ /* Next, set Slave injected interruptions */
+ switch (hadc->Init.EOCSelection)
+ {
+ case ADC_EOC_SEQ_CONV:
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS);
+ break;
+ /* case ADC_EOC_SINGLE_CONV */
+ default:
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS);
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ }
+ else
+ {
+ tmp_hal_status = HAL_BUSY;
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected group in
+ * case of auto_injection mode), disable interrution of
+ * end-of-conversion, disable ADC peripheral.
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential conversion on going, on ADC groups regular and injected */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Disable ADC end of conversion interrupt for regular group */
+ /* Disable ADC overrun interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
+
+ /* 2. Disable the ADC peripheral */
+ tmp_hal_status = ADC_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enable ADC, start conversion of regular group and transfer result through DMA.
+ * @note Interruptions enabled in this function:
+ * overrun (if applicable), DMA half transfer, DMA transfer complete.
+ * Each of these interruptions has its dedicated callback function.
+ * @note Case of multimode enabled (when multimode feature is available): HAL_ADC_Start_DMA()
+ * is designed for single-ADC mode only. For multimode, the dedicated
+ * HAL_ADCEx_MultiModeStart_DMA() function must be used.
+ * @param hadc ADC handle
+ * @param pData Destination Buffer address.
+ * @param Length Number of data to be transferred from ADC peripheral to memory
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Perform ADC enable and conversion start if no conversion is on going */
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Ensure that multimode regular conversions are not enabled. */
+ /* Otherwise, dedicated API HAL_ADCEx_MultiModeStart_DMA() must be used. */
+ if ((tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN)
+ )
+ {
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ /* - Clear state bitfield related to regular group conversion results */
+ /* - Set state bitfield related to regular operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit
+ - if ADC instance is master or if multimode feature is not available
+ - if multimode setting is disabled (ADC instance slave in independent mode) */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ )
+ {
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ /* Check if a conversion is on going on ADC group injected */
+ if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) != 0UL)
+ {
+ /* Reset ADC error code fields related to regular conversions only */
+ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
+ }
+ else
+ {
+ /* Reset all ADC error code fields */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Set the DMA transfer complete callback */
+ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
+
+ /* Set the DMA half transfer complete callback */
+ hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
+
+ /* Set the DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
+
+
+ /* Manage ADC and DMA start: ADC overrun interruption, DMA start, */
+ /* ADC start (in case of SW start): */
+
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC */
+ /* operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* With DMA, overrun event is always considered as an error even if
+ hadc->Init.Overrun is set to ADC_OVR_DATA_OVERWRITTEN. Therefore,
+ ADC_IT_OVR is enabled. */
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
+
+ /* Enable ADC DMA mode*/
+ LL_ADC_REG_SetDataTransferMode(hadc->Instance, (uint32_t)hadc->Init.ConversionDataManagement);
+
+ /* Start the DMA channel */
+ tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
+
+ /* Enable conversion of regular group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Start ADC group regular conversion */
+ LL_ADC_REG_StartConversion(hadc->Instance);
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ }
+ else
+ {
+ tmp_hal_status = HAL_ERROR;
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+ }
+ else
+ {
+ tmp_hal_status = HAL_BUSY;
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected group in
+ * case of auto_injection mode), disable ADC DMA transfer, disable
+ * ADC peripheral.
+ * @note: ADC peripheral disable is forcing stop of potential
+ * conversion on ADC group injected. If ADC group injected is under use, it
+ * should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
+ * @note Case of multimode enabled (when multimode feature is available):
+ * HAL_ADC_Stop_DMA() function is dedicated to single-ADC mode only.
+ * For multimode, the dedicated HAL_ADCEx_MultiModeStop_DMA() API must be used.
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential ADC group regular conversion on going */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Disable ADC DMA (ADC DMA configuration of continous requests is kept) */
+ MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_DMNGT_0 |ADC_CFGR_DMNGT_1, 0UL);
+
+ /* Disable the DMA channel (in case of DMA in circular mode or stop */
+ /* while DMA transfer is on going) */
+ if (hadc->DMA_Handle->State == HAL_DMA_STATE_BUSY)
+ {
+ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
+
+ /* Check if DMA channel effectively disabled */
+ if (tmp_hal_status != HAL_OK)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
+ }
+ }
+
+ /* Disable ADC overrun interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
+
+ /* 2. Disable the ADC peripheral */
+ /* Update "tmp_hal_status" only if DMA channel disabling passed, */
+ /* to keep in memory a potential failing status. */
+ if (tmp_hal_status == HAL_OK)
+ {
+ tmp_hal_status = ADC_Disable(hadc);
+ }
+ else
+ {
+ (void)ADC_Disable(hadc);
+ }
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Get ADC regular group conversion result.
+ * @note Reading register DR automatically clears ADC flag EOC
+ * (ADC group regular end of unitary conversion).
+ * @note This function does not clear ADC flag EOS
+ * (ADC group regular end of sequence conversion).
+ * Occurrence of flag EOS rising:
+ * - If sequencer is composed of 1 rank, flag EOS is equivalent
+ * to flag EOC.
+ * - If sequencer is composed of several ranks, during the scan
+ * sequence flag EOC only is raised, at the end of the scan sequence
+ * both flags EOC and EOS are raised.
+ * To clear this flag, either use function:
+ * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
+ * model polling: @ref HAL_ADC_PollForConversion()
+ * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS).
+ * @param hadc ADC handle
+ * @retval ADC group regular conversion data
+ */
+uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Note: EOC flag is not cleared here by software because automatically */
+ /* cleared by hardware when reading register DR. */
+
+ /* Return ADC converted value */
+ return hadc->Instance->DR;
+}
+
+/**
+ * @brief Handle ADC interrupt request.
+ * @param hadc ADC handle
+ * @retval None
+ */
+void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc)
+{
+ uint32_t overrun_error = 0UL; /* flag set if overrun occurrence has to be considered as an error */
+ uint32_t tmp_isr = hadc->Instance->ISR;
+ uint32_t tmp_ier = hadc->Instance->IER;
+ uint32_t tmp_adc_inj_is_trigger_source_sw_start;
+ uint32_t tmp_adc_reg_is_trigger_source_sw_start;
+ uint32_t tmp_cfgr;
+ const ADC_TypeDef *tmpADC_Master;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));
+
+ /* ========== Check End of Sampling flag for ADC group regular ========== */
+ if (((tmp_isr & ADC_FLAG_EOSMP) == ADC_FLAG_EOSMP) && ((tmp_ier & ADC_IT_EOSMP) == ADC_IT_EOSMP))
+ {
+ /* Update state machine on end of sampling status if not in error state */
+ if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOSMP);
+ }
+
+ /* End Of Sampling callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->EndOfSamplingCallback(hadc);
+#else
+ HAL_ADCEx_EndOfSamplingCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Clear regular group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP);
+ }
+
+ /* ====== Check ADC group regular end of unitary conversion sequence conversions ===== */
+ if ((((tmp_isr & ADC_FLAG_EOC) == ADC_FLAG_EOC) && ((tmp_ier & ADC_IT_EOC) == ADC_IT_EOC)) ||
+ (((tmp_isr & ADC_FLAG_EOS) == ADC_FLAG_EOS) && ((tmp_ier & ADC_IT_EOS) == ADC_IT_EOS)))
+ {
+ /* Update state machine on conversion status if not in error state */
+ if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
+ }
+
+ /* Determine whether any further conversion upcoming on group regular */
+ /* by external trigger, continuous mode or scan sequence on going */
+ /* to disable interruption. */
+ if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
+ {
+ /* Get relevant register CFGR in ADC instance of ADC master or slave */
+ /* in function of multimode state (for devices with multimode */
+ /* available). */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN)
+ )
+ {
+ /* check CONT bit directly in handle ADC CFGR register */
+ tmp_cfgr = READ_REG(hadc->Instance->CFGR);
+ }
+ else
+ {
+ /* else need to check Master ADC CONT bit */
+ tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance);
+ tmp_cfgr = READ_REG(tmpADC_Master->CFGR);
+ }
+
+ /* Carry on if continuous mode is disabled */
+ if (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) != ADC_CFGR_CONT)
+ {
+ /* If End of Sequence is reached, disable interrupts */
+ if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
+ {
+ /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */
+ /* ADSTART==0 (no conversion on going) */
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* Disable ADC end of sequence conversion interrupt */
+ /* Note: Overrun interrupt was enabled with EOC interrupt in */
+ /* HAL_Start_IT(), but is not disabled here because can be used */
+ /* by overrun IRQ process below. */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);
+
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+ else
+ {
+ /* Change ADC state to error state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ }
+ }
+ }
+ }
+
+ /* Conversion complete callback */
+ /* Note: Into callback function "HAL_ADC_ConvCpltCallback()", */
+ /* to determine if conversion has been triggered from EOC or EOS, */
+ /* possibility to use: */
+ /* " if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) " */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->ConvCpltCallback(hadc);
+#else
+ HAL_ADC_ConvCpltCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Clear regular group conversion flag */
+ /* Note: in case of overrun set to ADC_OVR_DATA_PRESERVED, end of */
+ /* conversion flags clear induces the release of the preserved data.*/
+ /* Therefore, if the preserved data value is needed, it must be */
+ /* read preliminarily into HAL_ADC_ConvCpltCallback(). */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS));
+ }
+
+ /* ====== Check ADC group injected end of unitary conversion sequence conversions ===== */
+ if ((((tmp_isr & ADC_FLAG_JEOC) == ADC_FLAG_JEOC) && ((tmp_ier & ADC_IT_JEOC) == ADC_IT_JEOC)) ||
+ (((tmp_isr & ADC_FLAG_JEOS) == ADC_FLAG_JEOS) && ((tmp_ier & ADC_IT_JEOS) == ADC_IT_JEOS)))
+ {
+ /* Update state machine on conversion status if not in error state */
+ if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
+ }
+
+ /* Retrieve ADC configuration */
+ tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance);
+ tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance);
+ /* Get relevant register CFGR in ADC instance of ADC master or slave */
+ /* in function of multimode state (for devices with multimode */
+ /* available). */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL)
+ )
+ {
+ tmp_cfgr = READ_REG(hadc->Instance->CFGR);
+ }
+ else
+ {
+ tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance);
+ tmp_cfgr = READ_REG(tmpADC_Master->CFGR);
+ }
+
+ /* Disable interruption if no further conversion upcoming by injected */
+ /* external trigger or by automatic injected conversion with regular */
+ /* group having no further conversion upcoming (same conditions as */
+ /* regular group interruption disabling above), */
+ /* and if injected scan sequence is completed. */
+ if ((tmp_adc_inj_is_trigger_source_sw_start != 0UL) ||
+ ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) &&
+ ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
+ (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL))))
+ {
+ /* If End of Sequence is reached, disable interrupts */
+ if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
+ {
+ /* Particular case if injected contexts queue is enabled: */
+ /* when the last context has been fully processed, JSQR is reset */
+ /* by the hardware. Even if no injected conversion is planned to come */
+ /* (queue empty, triggers are ignored), it can start again */
+ /* immediately after setting a new context (JADSTART is still set). */
+ /* Therefore, state of HAL ADC injected group is kept to busy. */
+ if (READ_BIT(tmp_cfgr, ADC_CFGR_JQM) == 0UL)
+ {
+ /* Allowed to modify bits ADC_IT_JEOC/ADC_IT_JEOS only if bit */
+ /* JADSTART==0 (no conversion on going) */
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* Disable ADC end of sequence conversion interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC | ADC_IT_JEOS);
+
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+
+ if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+ }
+ }
+ }
+ }
+
+ /* Injected Conversion complete callback */
+ /* Note: HAL_ADCEx_InjectedConvCpltCallback can resort to
+ if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOS)) or
+ if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOC)) to determine whether
+ interruption has been triggered by end of conversion or end of
+ sequence. */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->InjectedConvCpltCallback(hadc);
+#else
+ HAL_ADCEx_InjectedConvCpltCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Clear injected group conversion flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC | ADC_FLAG_JEOS);
+ }
+
+ /* ========== Check Analog watchdog 1 flag ========== */
+ if (((tmp_isr & ADC_FLAG_AWD1) == ADC_FLAG_AWD1) && ((tmp_ier & ADC_IT_AWD1) == ADC_IT_AWD1))
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
+
+ /* Level out of window 1 callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->LevelOutOfWindowCallback(hadc);
+#else
+ HAL_ADC_LevelOutOfWindowCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD1);
+ }
+
+ /* ========== Check analog watchdog 2 flag ========== */
+ if (((tmp_isr & ADC_FLAG_AWD2) == ADC_FLAG_AWD2) && ((tmp_ier & ADC_IT_AWD2) == ADC_IT_AWD2))
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD2);
+
+ /* Level out of window 2 callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->LevelOutOfWindow2Callback(hadc);
+#else
+ HAL_ADCEx_LevelOutOfWindow2Callback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD2);
+ }
+
+ /* ========== Check analog watchdog 3 flag ========== */
+ if (((tmp_isr & ADC_FLAG_AWD3) == ADC_FLAG_AWD3) && ((tmp_ier & ADC_IT_AWD3) == ADC_IT_AWD3))
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_AWD3);
+
+ /* Level out of window 3 callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->LevelOutOfWindow3Callback(hadc);
+#else
+ HAL_ADCEx_LevelOutOfWindow3Callback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+
+ /* Clear ADC analog watchdog flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD3);
+ }
+
+ /* ========== Check Overrun flag ========== */
+ if (((tmp_isr & ADC_FLAG_OVR) == ADC_FLAG_OVR) && ((tmp_ier & ADC_IT_OVR) == ADC_IT_OVR))
+ {
+ /* If overrun is set to overwrite previous data (default setting), */
+ /* overrun event is not considered as an error. */
+ /* (cf ref manual "Managing conversions without using the DMA and without */
+ /* overrun ") */
+ /* Exception for usage with DMA overrun event always considered as an */
+ /* error. */
+ if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
+ {
+ overrun_error = 1UL;
+ }
+ else
+ {
+ /* Check DMA configuration */
+ if (tmp_multimode_config != LL_ADC_MULTI_INDEPENDENT)
+ {
+ /* Multimode (when feature is available) is enabled,
+ Common Control Register MDMA bits must be checked. */
+ if (LL_ADC_GetMultiDMATransfer(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) != LL_ADC_MULTI_REG_DMA_EACH_ADC)
+ {
+ overrun_error = 1UL;
+ }
+ }
+ else
+ {
+ /* Multimode not set or feature not available or ADC independent */
+ if ((hadc->Instance->CFGR & ADC_CFGR_DMNGT) != 0UL)
+ {
+ overrun_error = 1UL;
+ }
+ }
+ }
+
+ if (overrun_error == 1UL)
+ {
+ /* Change ADC state to error state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR);
+
+ /* Set ADC error code to overrun */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
+
+ /* Error callback */
+ /* Note: In case of overrun, ADC conversion data is preserved until */
+ /* flag OVR is reset. */
+ /* Therefore, old ADC conversion data can be retrieved in */
+ /* function "HAL_ADC_ErrorCallback()". */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->ErrorCallback(hadc);
+#else
+ HAL_ADC_ErrorCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+ }
+
+ /* Clear ADC overrun flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
+ }
+
+ /* ========== Check Injected context queue overflow flag ========== */
+ if (((tmp_isr & ADC_FLAG_JQOVF) == ADC_FLAG_JQOVF) && ((tmp_ier & ADC_IT_JQOVF) == ADC_IT_JQOVF))
+ {
+ /* Change ADC state to overrun state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);
+
+ /* Set ADC error code to Injected context queue overflow */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
+
+ /* Clear the Injected context queue overflow flag */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JQOVF);
+
+ /* Injected context queue overflow callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->InjectedQueueOverflowCallback(hadc);
+#else
+ HAL_ADCEx_InjectedQueueOverflowCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+ }
+
+}
+
+/**
+ * @brief Conversion complete callback in non-blocking mode.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_ConvCpltCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Conversion DMA half-transfer callback in non-blocking mode.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Analog watchdog 1 callback in non-blocking mode.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief ADC error callback in non-blocking mode
+ * (ADC conversion with interruption or transfer by DMA).
+ * @note In case of error due to overrun when using ADC with DMA transfer
+ * (HAL ADC handle parameter "ErrorCode" to state "HAL_ADC_ERROR_OVR"):
+ * - Reinitialize the DMA using function "HAL_ADC_Stop_DMA()".
+ * - If needed, restart a new ADC conversion using function
+ * "HAL_ADC_Start_DMA()"
+ * (this function is also clearing overrun flag)
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADC_ErrorCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure channels on regular group
+ (+) Configure the analog watchdog
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configure a channel to be assigned to ADC group regular.
+ * @note In case of usage of internal measurement channels:
+ * Vbat/VrefInt/TempSensor.
+ * These internal paths can be disabled using function
+ * HAL_ADC_DeInit().
+ * @note Possibility to update parameters on the fly:
+ * This function initializes channel into ADC group regular,
+ * following calls to this function can be used to reconfigure
+ * some parameters of structure "ADC_ChannelConfTypeDef" on the fly,
+ * without resetting the ADC.
+ * The setting of these parameters is conditioned to ADC state:
+ * Refer to comments of structure "ADC_ChannelConfTypeDef".
+ * @param hadc ADC handle
+ * @param sConfig Structure of ADC channel assigned to ADC group regular.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConfTypeDef *sConfig)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t tmpOffsetShifted;
+ uint32_t tmp_config_internal_channel;
+ __IO uint32_t wait_loop_index = 0;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));
+ assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime));
+ assert_param(IS_ADC_SINGLE_DIFFERENTIAL(sConfig->SingleDiff));
+ assert_param(IS_ADC_OFFSET_NUMBER(sConfig->OffsetNumber));
+ /* Check offset range according to oversampling setting */
+ if (hadc->Init.OversamplingMode == ENABLE)
+ {
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset/(hadc->Init.Oversampling.Ratio+1U)));
+ }
+ else
+ {
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset));
+ }
+
+ /* if ROVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is
+ ignored (considered as reset) */
+ assert_param(!((sConfig->OffsetNumber != ADC_OFFSET_NONE) && (hadc->Init.OversamplingMode == ENABLE)));
+
+ /* Verification of channel number */
+ if (sConfig->SingleDiff != ADC_DIFFERENTIAL_ENDED)
+ {
+ assert_param(IS_ADC_CHANNEL(sConfig->Channel));
+ }
+ else
+ {
+ if (hadc->Instance == ADC1)
+ {
+ assert_param(IS_ADC1_DIFF_CHANNEL(sConfig->Channel));
+ }
+ if (hadc->Instance == ADC2)
+ {
+ assert_param(IS_ADC2_DIFF_CHANNEL(sConfig->Channel));
+ }
+#if defined(ADC3)
+ /* ADC3 is not available on some STM32H7 products */
+ if (hadc->Instance == ADC3)
+ {
+ assert_param(IS_ADC3_DIFF_CHANNEL(sConfig->Channel));
+ }
+#endif
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on regular group: */
+ /* - Channel number */
+ /* - Channel rank */
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* ADC channels preselection */
+ hadc->Instance->PCSEL |= (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfig->Channel) & 0x1FUL));
+
+ /* Set ADC group regular sequence: channel on the selected scan sequence rank */
+ LL_ADC_REG_SetSequencerRanks(hadc->Instance, sConfig->Rank, sConfig->Channel);
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on regular group: */
+ /* - Channel sampling time */
+ /* - Channel offset */
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+ if ((tmp_adc_is_conversion_on_going_regular == 0UL)
+ && (tmp_adc_is_conversion_on_going_injected == 0UL)
+ )
+ {
+ /* Set sampling time of the selected ADC channel */
+ LL_ADC_SetChannelSamplingTime(hadc->Instance, sConfig->Channel, sConfig->SamplingTime);
+
+ /* Configure the offset: offset enable/disable, channel, offset value */
+
+ /* Shift the offset with respect to the selected ADC resolution. */
+ /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
+ tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, (uint32_t)sConfig->Offset);
+
+ if (sConfig->OffsetNumber != ADC_OFFSET_NONE)
+ {
+ /* Set ADC selected offset number */
+ LL_ADC_SetOffset(hadc->Instance, sConfig->OffsetNumber, sConfig->Channel, tmpOffsetShifted);
+
+ assert_param(IS_FUNCTIONAL_STATE(sConfig->OffsetSignedSaturation));
+ /* Set ADC selected offset signed saturation */
+ LL_ADC_SetOffsetSignedSaturation(hadc->Instance, sConfig->OffsetNumber, (sConfig->OffsetSignedSaturation == ENABLE) ? LL_ADC_OFFSET_SIGNED_SATURATION_ENABLE : LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
+
+ assert_param(IS_FUNCTIONAL_STATE(sConfig->OffsetRightShift));
+ /* Set ADC selected offset right shift */
+ LL_ADC_SetDataRightShift(hadc->Instance, sConfig->OffsetNumber, (sConfig->OffsetRightShift == ENABLE) ? LL_ADC_OFFSET_RSHIFT_ENABLE : LL_ADC_OFFSET_RSHIFT_DISABLE);
+
+ }
+ else
+ {
+ /* Scan OFR1, OFR2, OFR3, OFR4 to check if the selected channel is enabled.
+ If this is the case, offset OFRx is disabled since
+ sConfig->OffsetNumber = ADC_OFFSET_NONE. */
+ if (((hadc->Instance->OFR1) & ADC_OFR1_OFFSET1_CH) == ADC_OFR_CHANNEL(sConfig->Channel))
+ {
+ CLEAR_BIT(hadc->Instance->OFR1, ADC_OFR1_SSATE);
+ }
+ if (((hadc->Instance->OFR2) & ADC_OFR2_OFFSET2_CH) == ADC_OFR_CHANNEL(sConfig->Channel))
+ {
+ CLEAR_BIT(hadc->Instance->OFR2, ADC_OFR2_SSATE);
+ }
+ if (((hadc->Instance->OFR3) & ADC_OFR3_OFFSET3_CH) == ADC_OFR_CHANNEL(sConfig->Channel))
+ {
+ CLEAR_BIT(hadc->Instance->OFR3, ADC_OFR3_SSATE);
+ }
+ if (((hadc->Instance->OFR4) & ADC_OFR4_OFFSET4_CH) == ADC_OFR_CHANNEL(sConfig->Channel))
+ {
+ CLEAR_BIT(hadc->Instance->OFR4, ADC_OFR4_SSATE);
+ }
+ }
+ }
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated only when ADC is disabled: */
+ /* - Single or differential mode */
+ /* - Internal measurement channels: Vbat/VrefInt/TempSensor */
+ if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ /* Set mode single-ended or differential input of the selected ADC channel */
+ LL_ADC_SetChannelSingleDiff(hadc->Instance, sConfig->Channel, sConfig->SingleDiff);
+
+ /* Configuration of differential mode */
+ if (sConfig->SingleDiff == ADC_DIFFERENTIAL_ENDED)
+ {
+ /* Set sampling time of the selected ADC channel */
+ /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */
+ LL_ADC_SetChannelSamplingTime(hadc->Instance,
+ (uint32_t)(__LL_ADC_DECIMAL_NB_TO_CHANNEL((__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfig->Channel) + 1UL) & 0x1FUL)),
+ sConfig->SamplingTime);
+ }
+
+ /* Management of internal measurement channels: Vbat/VrefInt/TempSensor. */
+ /* If internal channel selected, enable dedicated internal buffers and */
+ /* paths. */
+ /* Note: these internal measurement paths can be disabled using */
+ /* HAL_ADC_DeInit(). */
+
+ if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
+ {
+ /* Configuration of common ADC parameters */
+
+ tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Software is allowed to change common parameters only when all ADCs */
+ /* of the common group are disabled. */
+ if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
+ {
+ /* If the requested internal measurement path has already been enabled, */
+ /* bypass the configuration processing. */
+ if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL))
+ {
+ if (ADC_TEMPERATURE_SENSOR_INSTANCE(hadc))
+ {
+ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel);
+
+ /* Delay for temperature sensor stabilization time */
+ /* Wait loop initialization and execution */
+ /* Note: Variable divided by 2 to compensate partially */
+ /* CPU processing cycles, scaling in us split to not */
+ /* exceed 32 bits register capacity and handle low frequency. */
+ wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
+ while(wait_loop_index != 0UL)
+ {
+ wait_loop_index--;
+ }
+ }
+ }
+ else if ((sConfig->Channel == ADC_CHANNEL_VBAT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL))
+ {
+ if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc))
+ {
+ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel);
+ }
+ }
+ else if ((sConfig->Channel == ADC_CHANNEL_VREFINT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL))
+ {
+ if (ADC_VREFINT_INSTANCE(hadc))
+ {
+ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel);
+ }
+ }
+ else
+ {
+ /* nothing to do */
+ }
+ }
+ /* If the requested internal measurement path has already been */
+ /* enabled and other ADC of the common group are enabled, internal */
+ /* measurement paths cannot be enabled. */
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ }
+ }
+ }
+
+ /* If a conversion is on going on regular group, no update on regular */
+ /* channel could be done on neither of the channel configuration structure */
+ /* parameters. */
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Configure the analog watchdog.
+ * @note Possibility to update parameters on the fly:
+ * This function initializes the selected analog watchdog, successive
+ * calls to this function can be used to reconfigure some parameters
+ * of structure "ADC_AnalogWDGConfTypeDef" on the fly, without resetting
+ * the ADC.
+ * The setting of these parameters is conditioned to ADC state.
+ * For parameters constraints, see comments of structure
+ * "ADC_AnalogWDGConfTypeDef".
+ * @note On this STM32 serie, analog watchdog thresholds cannot be modified
+ * while ADC conversion is on going.
+ * @param hadc ADC handle
+ * @param AnalogWDGConfig Structure of ADC analog watchdog configuration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDGConfTypeDef *AnalogWDGConfig)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t tmpAWDHighThresholdShifted;
+ uint32_t tmpAWDLowThresholdShifted;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_ANALOG_WATCHDOG_NUMBER(AnalogWDGConfig->WatchdogNumber));
+ assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode));
+ assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode));
+
+ if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) ||
+ (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) ||
+ (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC))
+ {
+ assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
+ }
+
+ /* Verify thresholds range */
+ if (hadc->Init.OversamplingMode == ENABLE)
+ {
+ /* Case of oversampling enabled: thresholds are compared to oversampling
+ intermediate computation (after ratio, before shift application) */
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold / (hadc->Init.Oversampling.Ratio + 1UL)));
+ }
+ else
+ {
+ /* Verify if thresholds are within the selected ADC resolution */
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold));
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold));
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on ADC groups regular and injected: */
+ /* - Analog watchdog channels */
+ /* - Analog watchdog thresholds */
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+ if ((tmp_adc_is_conversion_on_going_regular == 0UL)
+ && (tmp_adc_is_conversion_on_going_injected == 0UL)
+ )
+ {
+ /* Analog watchdog configuration */
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_1)
+ {
+ /* Configuration of analog watchdog: */
+ /* - Set the analog watchdog enable mode: one or overall group of */
+ /* channels, on groups regular and-or injected. */
+ switch (AnalogWDGConfig->WatchdogMode)
+ {
+ case ADC_ANALOGWATCHDOG_SINGLE_REG:
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, __LL_ADC_ANALOGWD_CHANNEL_GROUP(AnalogWDGConfig->Channel,
+ LL_ADC_GROUP_REGULAR));
+ break;
+
+ case ADC_ANALOGWATCHDOG_SINGLE_INJEC:
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, __LL_ADC_ANALOGWD_CHANNEL_GROUP(AnalogWDGConfig->Channel,
+ LL_ADC_GROUP_INJECTED));
+ break;
+
+ case ADC_ANALOGWATCHDOG_SINGLE_REGINJEC:
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, __LL_ADC_ANALOGWD_CHANNEL_GROUP(AnalogWDGConfig->Channel,
+ LL_ADC_GROUP_REGULAR_INJECTED));
+ break;
+
+ case ADC_ANALOGWATCHDOG_ALL_REG:
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_REG);
+ break;
+
+ case ADC_ANALOGWATCHDOG_ALL_INJEC:
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_INJ);
+ break;
+
+ case ADC_ANALOGWATCHDOG_ALL_REGINJEC:
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_REG_INJ);
+ break;
+
+ default: /* ADC_ANALOGWATCHDOG_NONE */
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_DISABLE);
+ break;
+ }
+
+ /* Shift the offset in function of the selected ADC resolution: */
+ /* Thresholds have to be left-aligned on bit 11, the LSB (right bits) */
+ /* are set to 0 */
+ tmpAWDHighThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold);
+ tmpAWDLowThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
+
+ /* Set the high and low thresholds */
+ MODIFY_REG(hadc->Instance->LTR1, ADC_LTR_LT , tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR1, ADC_HTR_HT , tmpAWDHighThresholdShifted);
+
+ /* Update state, clear previous result related to AWD1 */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD1);
+
+ /* Clear flag ADC analog watchdog */
+ /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */
+ /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent() */
+ /* (in case left enabled by previous ADC operations). */
+ LL_ADC_ClearFlag_AWD1(hadc->Instance);
+
+ /* Configure ADC analog watchdog interrupt */
+ if (AnalogWDGConfig->ITMode == ENABLE)
+ {
+ LL_ADC_EnableIT_AWD1(hadc->Instance);
+ }
+ else
+ {
+ LL_ADC_DisableIT_AWD1(hadc->Instance);
+ }
+ }
+ /* Case of ADC_ANALOGWATCHDOG_2 or ADC_ANALOGWATCHDOG_3 */
+ else
+ {
+ switch (AnalogWDGConfig->WatchdogMode)
+ {
+ case ADC_ANALOGWATCHDOG_SINGLE_REG:
+ case ADC_ANALOGWATCHDOG_SINGLE_INJEC:
+ case ADC_ANALOGWATCHDOG_SINGLE_REGINJEC:
+ /* Update AWD by bitfield to keep the possibility to monitor */
+ /* several channels by successive calls of this function. */
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+ {
+ SET_BIT(hadc->Instance->AWD2CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+ }
+ else
+ {
+ SET_BIT(hadc->Instance->AWD3CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+ }
+ break;
+
+ case ADC_ANALOGWATCHDOG_ALL_REG:
+ case ADC_ANALOGWATCHDOG_ALL_INJEC:
+ case ADC_ANALOGWATCHDOG_ALL_REGINJEC:
+ /* Update AWD by bitfield to keep the possibility to monitor */
+ /* several channels by successive calls of this function. */
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+ {
+ SET_BIT(hadc->Instance->AWD2CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+ }
+ else
+ {
+ SET_BIT(hadc->Instance->AWD3CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
+ }
+ break;
+
+ default: /* ADC_ANALOGWATCHDOG_NONE */
+ LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, AnalogWDGConfig->WatchdogNumber, LL_ADC_AWD_DISABLE);
+ break;
+ }
+
+ /* Shift the thresholds in function of the selected ADC resolution */
+ /* have to be left-aligned on bit 15, the LSB (right bits) are set to 0 */
+ tmpAWDHighThresholdShifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold);
+ tmpAWDLowThresholdShifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
+
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+ {
+ /* Set ADC analog watchdog thresholds value of both thresholds high and low */
+ MODIFY_REG(hadc->Instance->LTR2, ADC_LTR_LT , tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR2, ADC_HTR_HT , tmpAWDHighThresholdShifted);
+ }
+ else
+ {
+ /* Set ADC analog watchdog thresholds value of both thresholds high and low */
+ MODIFY_REG(hadc->Instance->LTR3, ADC_LTR_LT , tmpAWDLowThresholdShifted);
+ MODIFY_REG(hadc->Instance->HTR3, ADC_HTR_HT , tmpAWDHighThresholdShifted);
+ }
+
+ if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
+ {
+ /* Update state, clear previous result related to AWD2 */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD2);
+
+ /* Clear flag ADC analog watchdog */
+ /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */
+ /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent() */
+ /* (in case left enabled by previous ADC operations). */
+ LL_ADC_ClearFlag_AWD2(hadc->Instance);
+
+ /* Configure ADC analog watchdog interrupt */
+ if (AnalogWDGConfig->ITMode == ENABLE)
+ {
+ LL_ADC_EnableIT_AWD2(hadc->Instance);
+ }
+ else
+ {
+ LL_ADC_DisableIT_AWD2(hadc->Instance);
+ }
+ }
+ /* (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_3) */
+ else
+ {
+ /* Update state, clear previous result related to AWD3 */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD3);
+
+ /* Clear flag ADC analog watchdog */
+ /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */
+ /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent() */
+ /* (in case left enabled by previous ADC operations). */
+ LL_ADC_ClearFlag_AWD3(hadc->Instance);
+
+ /* Configure ADC analog watchdog interrupt */
+ if (AnalogWDGConfig->ITMode == ENABLE)
+ {
+ LL_ADC_EnableIT_AWD3(hadc->Instance);
+ }
+ else
+ {
+ LL_ADC_DisableIT_AWD3(hadc->Instance);
+ }
+ }
+ }
+
+ }
+ /* If a conversion is on going on ADC group regular or injected, no update */
+ /* could be done on neither of the AWD configuration structure parameters. */
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions
+ * @brief ADC Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral state and errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions to get in run-time the status of the
+ peripheral.
+ (+) Check the ADC state
+ (+) Check the ADC error code
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the ADC handle state.
+ * @note ADC state machine is managed by bitfields, ADC status must be
+ * compared with states bits.
+ * For example:
+ * " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_REG_BUSY) != 0UL) "
+ * " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD1) != 0UL) "
+ * @param hadc ADC handle
+ * @retval ADC handle state (bitfield on 32 bits)
+ */
+uint32_t HAL_ADC_GetState(ADC_HandleTypeDef *hadc)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Return ADC handle state */
+ return hadc->State;
+}
+
+/**
+ * @brief Return the ADC error code.
+ * @param hadc ADC handle
+ * @retval ADC error code (bitfield on 32 bits)
+ */
+uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ return hadc->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Private_Functions ADC Private Functions
+ * @{
+ */
+
+/**
+ * @brief Stop ADC conversion.
+ * @param hadc ADC handle
+ * @param ConversionGroup ADC group regular and/or injected.
+ * This parameter can be one of the following values:
+ * @arg @ref ADC_REGULAR_GROUP ADC regular conversion type.
+ * @arg @ref ADC_INJECTED_GROUP ADC injected conversion type.
+ * @arg @ref ADC_REGULAR_INJECTED_GROUP ADC regular and injected conversion type.
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef *hadc, uint32_t ConversionGroup)
+{
+ uint32_t tickstart;
+ uint32_t Conversion_Timeout_CPU_cycles = 0UL;
+ uint32_t conversion_group_reassigned = ConversionGroup;
+ uint32_t tmp_ADC_CR_ADSTART_JADSTART;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_CONVERSION_GROUP(ConversionGroup));
+
+ /* Verification if ADC is not already stopped (on regular and injected */
+ /* groups) to bypass this function if not needed. */
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+ if ((tmp_adc_is_conversion_on_going_regular != 0UL)
+ || (tmp_adc_is_conversion_on_going_injected != 0UL)
+ )
+ {
+ /* Particular case of continuous auto-injection mode combined with */
+ /* auto-delay mode. */
+ /* In auto-injection mode, regular group stop ADC_CR_ADSTP is used (not */
+ /* injected group stop ADC_CR_JADSTP). */
+ /* Procedure to be followed: Wait until JEOS=1, clear JEOS, set ADSTP=1 */
+ /* (see reference manual). */
+ if (((hadc->Instance->CFGR & ADC_CFGR_JAUTO) != 0UL)
+ && (hadc->Init.ContinuousConvMode == ENABLE)
+ && (hadc->Init.LowPowerAutoWait == ENABLE)
+ )
+ {
+ /* Use stop of regular group */
+ conversion_group_reassigned = ADC_REGULAR_GROUP;
+
+ /* Wait until JEOS=1 (maximum Timeout: 4 injected conversions) */
+ while (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS) == 0UL)
+ {
+ if (Conversion_Timeout_CPU_cycles >= (ADC_CONVERSION_TIME_MAX_CPU_CYCLES * 4UL))
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+ Conversion_Timeout_CPU_cycles ++;
+ }
+
+ /* Clear JEOS */
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOS);
+ }
+
+ /* Stop potential conversion on going on ADC group regular */
+ if (conversion_group_reassigned != ADC_INJECTED_GROUP)
+ {
+ /* Software is allowed to set ADSTP only when ADSTART=1 and ADDIS=0 */
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
+ {
+ if (LL_ADC_IsDisableOngoing(hadc->Instance) == 0UL)
+ {
+ /* Stop ADC group regular conversion */
+ LL_ADC_REG_StopConversion(hadc->Instance);
+ }
+ }
+ }
+
+ /* Stop potential conversion on going on ADC group injected */
+ if (conversion_group_reassigned != ADC_REGULAR_GROUP)
+ {
+ /* Software is allowed to set JADSTP only when JADSTART=1 and ADDIS=0 */
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
+ {
+ if (LL_ADC_IsDisableOngoing(hadc->Instance) == 0UL)
+ {
+ /* Stop ADC group injected conversion */
+ LL_ADC_INJ_StopConversion(hadc->Instance);
+ }
+ }
+ }
+
+ /* Selection of start and stop bits with respect to the regular or injected group */
+ switch (conversion_group_reassigned)
+ {
+ case ADC_REGULAR_INJECTED_GROUP:
+ tmp_ADC_CR_ADSTART_JADSTART = (ADC_CR_ADSTART | ADC_CR_JADSTART);
+ break;
+ case ADC_INJECTED_GROUP:
+ tmp_ADC_CR_ADSTART_JADSTART = ADC_CR_JADSTART;
+ break;
+ /* Case ADC_REGULAR_GROUP only*/
+ default:
+ tmp_ADC_CR_ADSTART_JADSTART = ADC_CR_ADSTART;
+ break;
+ }
+
+ /* Wait for conversion effectively stopped */
+ tickstart = HAL_GetTick();
+
+ while ((hadc->Instance->CR & tmp_ADC_CR_ADSTART_JADSTART) != 0UL)
+ {
+ if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+ }
+
+ }
+
+ /* Return HAL status */
+ return HAL_OK;
+}
+
+
+
+/**
+ * @brief Enable the selected ADC.
+ * @note Prerequisite condition to use this function: ADC must be disabled
+ * and voltage regulator must be enabled (done into HAL_ADC_Init()).
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc)
+{
+ uint32_t tickstart;
+
+ /* ADC enable and wait for ADC ready (in case of ADC is disabled or */
+ /* enabling phase not yet completed: flag ADC ready not yet set). */
+ /* Timeout implemented to not be stuck if ADC cannot be enabled (possible */
+ /* causes: ADC clock not running, ...). */
+ if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ /* Check if conditions to enable the ADC are fulfilled */
+ if ((hadc->Instance->CR & (ADC_CR_ADCAL | ADC_CR_JADSTP | ADC_CR_ADSTP | ADC_CR_JADSTART | ADC_CR_ADSTART | ADC_CR_ADDIS | ADC_CR_ADEN)) != 0UL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+
+ /* Enable the ADC peripheral */
+ LL_ADC_Enable(hadc->Instance);
+
+ /* Wait for ADC effectively enabled */
+ tickstart = HAL_GetTick();
+
+ /* Poll for ADC ready flag raised except case of multimode enabled
+ and ADC slave selected. */
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+ if ( (__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ )
+ {
+ while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
+ {
+ /* If ADEN bit is set less than 4 ADC clock cycles after the ADCAL bit
+ has been cleared (after a calibration), ADEN bit is reset by the
+ calibration logic.
+ The workaround is to continue setting ADEN until ADRDY is becomes 1.
+ Additionally, ADC_ENABLE_TIMEOUT is defined to encompass this
+ 4 ADC clock cycle duration */
+ /* Note: Test of ADC enabled required due to hardware constraint to */
+ /* not enable ADC if already enabled. */
+ if(LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ LL_ADC_Enable(hadc->Instance);
+ }
+
+ if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ }
+
+ /* Return HAL status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Disable the selected ADC.
+ * @note Prerequisite condition to use this function: ADC conversions must be
+ * stopped.
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef *hadc)
+{
+ uint32_t tickstart;
+ const uint32_t tmp_adc_is_disable_on_going = LL_ADC_IsDisableOngoing(hadc->Instance);
+
+ /* Verification if ADC is not already disabled: */
+ /* Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already */
+ /* disabled. */
+ if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL)
+ && (tmp_adc_is_disable_on_going == 0UL)
+ )
+ {
+ /* Check if conditions to disable the ADC are fulfilled */
+ if ((hadc->Instance->CR & (ADC_CR_JADSTART | ADC_CR_ADSTART | ADC_CR_ADEN)) == ADC_CR_ADEN)
+ {
+ /* Disable the ADC peripheral */
+ LL_ADC_Disable(hadc->Instance);
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOSMP | ADC_FLAG_RDY));
+ }
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+
+ /* Wait for ADC effectively disabled */
+ /* Get tick count */
+ tickstart = HAL_GetTick();
+
+ while ((hadc->Instance->CR & ADC_CR_ADEN) != 0UL)
+ {
+ if ((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ /* Return HAL status */
+ return HAL_OK;
+}
+
+/**
+ * @brief DMA transfer complete callback.
+ * @param hdma pointer to DMA handle.
+ * @retval None
+ */
+void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
+{
+ /* Retrieve ADC handle corresponding to current DMA handle */
+ ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Update state machine on conversion status if not in error state */
+ if ((hadc->State & (HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) == 0UL)
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
+
+ /* Determine whether any further conversion upcoming on group regular */
+ /* by external trigger, continuous mode or scan sequence on going */
+ /* to disable interruption. */
+ /* Is it the end of the regular sequence ? */
+ if ((hadc->Instance->ISR & ADC_FLAG_EOS) != 0UL)
+ {
+ /* Are conversions software-triggered ? */
+ if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
+ {
+ /* Is CONT bit set ? */
+ if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_CONT) == 0UL)
+ {
+ /* CONT bit is not set, no more conversions expected */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+ if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* DMA End of Transfer interrupt was triggered but conversions sequence
+ is not over. If DMACFG is set to 0, conversions are stopped. */
+ if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMNGT) == 0UL)
+ {
+ /* DMACFG bit is not set, conversions are stopped. */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+ if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+ }
+
+ /* Conversion complete callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->ConvCpltCallback(hadc);
+#else
+ HAL_ADC_ConvCpltCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+ }
+ else /* DMA and-or internal error occurred */
+ {
+ if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) != 0UL)
+ {
+ /* Call HAL ADC Error Callback function */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->ErrorCallback(hadc);
+#else
+ HAL_ADC_ErrorCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Call ADC DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback(hdma);
+ }
+ }
+}
+
+/**
+ * @brief DMA half transfer complete callback.
+ * @param hdma pointer to DMA handle.
+ * @retval None
+ */
+void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
+{
+ /* Retrieve ADC handle corresponding to current DMA handle */
+ ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Half conversion callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->ConvHalfCpltCallback(hadc);
+#else
+ HAL_ADC_ConvHalfCpltCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA error callback.
+ * @param hdma pointer to DMA handle.
+ * @retval None
+ */
+void ADC_DMAError(DMA_HandleTypeDef *hdma)
+{
+ /* Retrieve ADC handle corresponding to current DMA handle */
+ ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
+
+ /* Set ADC error code to DMA error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA);
+
+ /* Error callback */
+#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
+ hadc->ErrorCallback(hadc);
+#else
+ HAL_ADC_ErrorCallback(hadc);
+#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief Configure boost mode of selected ADC.
+ * @note Prerequisite condition to use this function: ADC conversions must be
+ * stopped.
+ * @param hadc ADC handle
+ * @retval None.
+ */
+void ADC_ConfigureBoostMode(ADC_HandleTypeDef* hadc)
+{
+ uint32_t freq;
+ if(ADC_IS_SYNCHRONOUS_CLOCK_MODE(hadc))
+ {
+ freq = HAL_RCC_GetHCLKFreq();
+ switch(hadc->Init.ClockPrescaler)
+ {
+ case ADC_CLOCK_SYNC_PCLK_DIV1:
+ case ADC_CLOCK_SYNC_PCLK_DIV2:
+ freq /= (hadc->Init.ClockPrescaler >> ADC_CCR_CKMODE_Pos);
+ break;
+ case ADC_CLOCK_SYNC_PCLK_DIV4:
+ freq /= 4UL;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC);
+ switch(hadc->Init.ClockPrescaler)
+ {
+ case ADC_CLOCK_ASYNC_DIV2:
+ case ADC_CLOCK_ASYNC_DIV4:
+ case ADC_CLOCK_ASYNC_DIV6:
+ case ADC_CLOCK_ASYNC_DIV8:
+ case ADC_CLOCK_ASYNC_DIV10:
+ case ADC_CLOCK_ASYNC_DIV12:
+ freq /= ((hadc->Init.ClockPrescaler >> ADC_CCR_PRESC_Pos) << 1UL);
+ break;
+ case ADC_CLOCK_ASYNC_DIV16:
+ freq /= 16UL;
+ break;
+ case ADC_CLOCK_ASYNC_DIV32:
+ freq /= 32UL;
+ break;
+ case ADC_CLOCK_ASYNC_DIV64:
+ freq /= 64UL;
+ break;
+ case ADC_CLOCK_ASYNC_DIV128:
+ freq /= 128UL;
+ break;
+ case ADC_CLOCK_ASYNC_DIV256:
+ freq /= 256UL;
+ break;
+ default:
+ break;
+ }
+ }
+
+#if defined(ADC_VER_V5_3)
+ freq /= 2U;
+
+ if (freq <= 6250000UL)
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, 0UL);
+ }
+ else if(freq <= 12500000UL)
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_0);
+ }
+ else if(freq <= 25000000UL)
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_1);
+ }
+ else /* if(freq > 25000000UL) */
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_1 | ADC_CR_BOOST_0);
+ }
+#else
+ if(HAL_GetREVID() <= REV_ID_Y) /* STM32H7 silicon Rev.Y */
+ {
+ if(freq > 20000000UL)
+ {
+ SET_BIT(hadc->Instance->CR, ADC_CR_BOOST_0);
+ }
+ else
+ {
+ CLEAR_BIT(hadc->Instance->CR, ADC_CR_BOOST_0);
+ }
+ }
+ else /* STM32H7 silicon Rev.V */
+ {
+ freq /= 2U; /* divider by 2 for Rev.V */
+
+ if (freq <= 6250000UL)
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, 0UL);
+ }
+ else if(freq <= 12500000UL)
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_0);
+ }
+ else if(freq <= 25000000UL)
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_1);
+ }
+ else /* if(freq > 25000000UL) */
+ {
+ MODIFY_REG(hadc->Instance->CR, ADC_CR_BOOST, ADC_CR_BOOST_1 | ADC_CR_BOOST_0);
+ }
+ }
+#endif /* ADC_VER_V5_3 */
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_ADC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc_ex.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc_ex.c
new file mode 100644
index 0000000000..8aa0815044
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_adc_ex.c
@@ -0,0 +1,2492 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_adc_ex.c
+ * @author MCD Application Team
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Analog to Digital Convertor (ADC)
+ * peripheral:
+ * + Operation functions
+ * ++ Start, stop, get result of conversions of ADC group injected,
+ * using 2 possible modes: polling, interruption.
+ * ++ Calibration
+ * +++ ADC automatic self-calibration
+ * +++ Calibration factors get or set
+ * ++ Multimode feature when available
+ * + Control functions
+ * ++ Channels configuration on ADC group injected
+ * + State functions
+ * ++ ADC group injected contexts queue management
+ * Other functions (generic functions) are available in file
+ * "stm32h7xx_hal_adc.c".
+ *
+ @verbatim
+ [..]
+ (@) Sections "ADC peripheral features" and "How to use this driver" are
+ available in file of generic functions "stm32h7xx_hal_adc.c".
+ [..]
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup ADCEx ADCEx
+ * @brief ADC Extended HAL module driver
+ * @{
+ */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup ADCEx_Private_Constants ADC Extended Private Constants
+ * @{
+ */
+
+#define ADC_JSQR_FIELDS ((ADC_JSQR_JL | ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN |\
+ ADC_JSQR_JSQ1 | ADC_JSQR_JSQ2 |\
+ ADC_JSQR_JSQ3 | ADC_JSQR_JSQ4 )) /*!< ADC_JSQR fields of parameters that can be updated anytime
+ once the ADC is enabled */
+
+/* Fixed timeout value for ADC calibration. */
+/* Fixed timeout value for ADC calibration. */
+/* Values defined to be higher than worst cases: low clock frequency, */
+/* maximum prescalers. */
+/* Ex of profile low frequency : f_ADC at 0.125 Mhz (minimum value */
+/* according to Data sheet), calibration_time MAX = 165010 / f_ADC */
+/* 165010 / 125000 = 1.32s */
+/* At maximum CPU speed (480 MHz), this means */
+/* 1.32 * 480 MHz = 633600000 CPU cycles */
+#define ADC_CALIBRATION_TIMEOUT (633600000U) /*!< ADC calibration time-out value */
+
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions
+ * @{
+ */
+
+/** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions
+ * @brief Extended IO operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+
+ (+) Perform the ADC self-calibration for single or differential ending.
+ (+) Get calibration factors for single or differential ending.
+ (+) Set calibration factors for single or differential ending.
+
+ (+) Start conversion of ADC group injected.
+ (+) Stop conversion of ADC group injected.
+ (+) Poll for conversion complete on ADC group injected.
+ (+) Get result of ADC group injected channel conversion.
+ (+) Start conversion of ADC group injected and enable interruptions.
+ (+) Stop conversion of ADC group injected and disable interruptions.
+
+ (+) When multimode feature is available, start multimode and enable DMA transfer.
+ (+) Stop multimode and disable ADC DMA transfer.
+ (+) Get result of multimode conversion.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Perform an ADC automatic self-calibration
+ * Calibration prerequisite: ADC must be disabled (execute this
+ * function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
+ * @param hadc ADC handle
+* @param CalibrationMode Selection of calibration offset or
+ * linear calibration offset.
+ * @arg ADC_CALIB_OFFSET Channel in mode calibration offset
+ * @arg ADC_CALIB_OFFSET_LINEARITY Channel in mode linear calibration offset
+ * @param SingleDiff Selection of single-ended or differential input
+ * This parameter can be one of the following values:
+ * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
+ * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc, uint32_t CalibrationMode, uint32_t SingleDiff)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ __IO uint32_t wait_loop_index = 0UL;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Calibration prerequisite: ADC must be disabled. */
+
+ /* Disable the ADC (if not already disabled) */
+ tmp_hal_status = ADC_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_BUSY_INTERNAL);
+
+ /* Start ADC calibration in mode single-ended or differential */
+ LL_ADC_StartCalibration(hadc->Instance , CalibrationMode, SingleDiff );
+
+ /* Wait for calibration completion */
+ while (LL_ADC_IsCalibrationOnGoing(hadc->Instance) != 0UL)
+ {
+ wait_loop_index++;
+ if (wait_loop_index >= ADC_CALIBRATION_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_BUSY_INTERNAL,
+ HAL_ADC_STATE_READY);
+ }
+ else
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Note: No need to update variable "tmp_hal_status" here: already set */
+ /* to state "HAL_ERROR" by function disabling the ADC. */
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Get the calibration factor.
+ * @param hadc ADC handle.
+ * @param SingleDiff This parameter can be only:
+ * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
+ * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended
+ * @retval Calibration value.
+ */
+uint32_t HAL_ADCEx_Calibration_GetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
+
+ /* Return the selected ADC calibration value */
+ return LL_ADC_GetCalibrationOffsetFactor(hadc->Instance, SingleDiff);
+}
+
+/**
+ * @brief Get the calibration factor from automatic conversion result
+ * @param hadc ADC handle
+ * @param LinearCalib_Buffer: Linear calibration factor
+ * @retval HAL state
+ */
+HAL_StatusTypeDef HAL_ADCEx_LinearCalibration_GetValue(ADC_HandleTypeDef* hadc, uint32_t* LinearCalib_Buffer)
+{
+ uint32_t cnt;
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t temp_REG_IsConversionOngoing = 0UL;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Enable the ADC ADEN = 1 to be able to read the linear calibration factor */
+ if(LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ tmp_hal_status = ADC_Enable(hadc);
+ }
+
+ if (tmp_hal_status == HAL_OK)
+ {
+ if(LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
+ {
+ LL_ADC_REG_StopConversion(hadc->Instance);
+ temp_REG_IsConversionOngoing = 1UL;
+ }
+ for(cnt = ADC_LINEAR_CALIB_REG_COUNT; cnt > 0UL; cnt--)
+ {
+ LinearCalib_Buffer[cnt-1U]=LL_ADC_GetCalibrationLinearFactor(hadc->Instance, ADC_CR_LINCALRDYW6 >> (ADC_LINEAR_CALIB_REG_COUNT-cnt));
+ }
+ if(temp_REG_IsConversionOngoing != 0UL)
+ {
+ LL_ADC_REG_StartConversion(hadc->Instance);
+ }
+ }
+
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Set the calibration factor to overwrite automatic conversion result.
+ * ADC must be enabled and no conversion is ongoing.
+ * @param hadc ADC handle
+ * @param SingleDiff This parameter can be only:
+ * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
+ * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended
+ * @param CalibrationFactor Calibration factor (coded on 7 bits maximum)
+ * @retval HAL state
+ */
+HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff, uint32_t CalibrationFactor)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
+ assert_param(IS_ADC_CALFACT(CalibrationFactor));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Verification of hardware constraints before modifying the calibration */
+ /* factors register: ADC must be enabled, no conversion on going. */
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+
+ if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL)
+ && (tmp_adc_is_conversion_on_going_regular == 0UL)
+ && (tmp_adc_is_conversion_on_going_injected == 0UL)
+ )
+ {
+ /* Set the selected ADC calibration value */
+ LL_ADC_SetCalibrationOffsetFactor(hadc->Instance, SingleDiff, CalibrationFactor);
+ }
+ else
+ {
+ /* Update ADC state machine */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+ /* Update ADC error code */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ /* Update ADC state machine to error */
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Set the linear calibration factor
+ * @param hadc ADC handle
+ * @param LinearCalib_Buffer: Linear calibration factor
+ * @retval HAL state
+ */
+HAL_StatusTypeDef HAL_ADCEx_LinearCalibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t* LinearCalib_Buffer)
+{
+ uint32_t cnt;
+ __IO uint32_t wait_loop_index = 0;
+ uint32_t temp_REG_IsConversionOngoing = 0UL;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* - Exit from deep-power-down mode and ADC voltage regulator enable */
+ /* Exit deep power down mode if still in that state */
+ if (HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_DEEPPWD))
+ {
+ /* Exit deep power down mode */
+ CLEAR_BIT(hadc->Instance->CR, ADC_CR_DEEPPWD);
+
+ /* System was in deep power down mode, calibration must
+ be relaunched or a previously saved calibration factor
+ re-applied once the ADC voltage regulator is enabled */
+ }
+
+
+ if (HAL_IS_BIT_CLR(hadc->Instance->CR, ADC_CR_ADVREGEN))
+ {
+ /* Enable ADC internal voltage regulator */
+ SET_BIT(hadc->Instance->CR, ADC_CR_ADVREGEN);
+ /* Delay for ADC stabilization time */
+ /* Wait loop initialization and execution */
+ /* Note: Variable divided by 2 to compensate partially */
+ /* CPU processing cycles. */
+ wait_loop_index = (ADC_STAB_DELAY_US * (SystemCoreClock / (1000000UL * 2UL)));
+ while(wait_loop_index != 0UL)
+ {
+ wait_loop_index--;
+ }
+ }
+
+
+ /* Verification that ADC voltage regulator is correctly enabled, whether */
+ /* or not ADC is coming from state reset (if any potential problem of */
+ /* clocking, voltage regulator would not be enabled). */
+ if (HAL_IS_BIT_CLR(hadc->Instance->CR, ADC_CR_ADVREGEN))
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Set ADC error code to ADC peripheral internal error */
+ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
+
+ return HAL_ERROR;
+ }
+/* Enable the ADC peripheral */
+ if(LL_ADC_IsEnabled(hadc->Instance) == 0UL) /* Enable the ADC if it is disabled */
+ {
+ if (ADC_Enable(hadc) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ for(cnt = ADC_LINEAR_CALIB_REG_COUNT; cnt > 0UL ; cnt--)
+ {
+ LL_ADC_SetCalibrationLinearFactor(hadc->Instance, ADC_CR_LINCALRDYW6 >> (ADC_LINEAR_CALIB_REG_COUNT-cnt), LinearCalib_Buffer[cnt-1U]);
+ }
+ (void)ADC_Disable(hadc);
+ }
+ }else /* ADC is already enabled, so no need to enable it but need to stop conversion */
+ {
+ if(LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
+ {
+ LL_ADC_REG_StopConversion(hadc->Instance);
+ temp_REG_IsConversionOngoing = 1UL;
+ }
+ for(cnt = ADC_LINEAR_CALIB_REG_COUNT; cnt > 0UL ; cnt--)
+ {
+ LL_ADC_SetCalibrationLinearFactor(hadc->Instance, ADC_CR_LINCALRDYW6 >> (ADC_LINEAR_CALIB_REG_COUNT-cnt), LinearCalib_Buffer[cnt-1U]);
+ }
+ if(temp_REG_IsConversionOngoing != 0UL)
+ {
+ LL_ADC_REG_StartConversion(hadc->Instance);
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Load the calibration factor from engi bytes
+ * @param hadc ADC handle
+ * @retval HAL state
+ */
+HAL_StatusTypeDef HAL_ADCEx_LinearCalibration_FactorLoad(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t cnt, FactorOffset;
+ uint32_t LinearCalib_Buffer[ADC_LINEAR_CALIB_REG_COUNT];
+
+ /* Linearity calibration is retrieved from engi bytes
+ read values from registers and put them to the CALFACT2 register */
+ /* If needed linearity calibration can be done in runtime using
+ LL_ADC_GetCalibrationLinearFactor() */
+ if(hadc->Instance == ADC1)
+ {
+ FactorOffset = 0UL;
+ }else if(hadc->Instance == ADC2)
+ {
+ FactorOffset = 8UL;
+ }else /*Case ADC3*/
+ {
+ FactorOffset = 16UL;
+ }
+
+ for (cnt = 0UL; cnt < ADC_LINEAR_CALIB_REG_COUNT; cnt++)
+ {
+ LinearCalib_Buffer[cnt] = *(uint32_t*)(ADC_LINEAR_CALIB_REG_1_ADDR + FactorOffset + cnt);
+ }
+ if (HAL_ADCEx_LinearCalibration_SetValue(hadc,(uint32_t*)LinearCalib_Buffer) != HAL_OK)
+ {
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enable ADC, start conversion of injected group.
+ * @note Interruptions enabled in this function: None.
+ * @note Case of multimode enabled when multimode feature is available:
+ * HAL_ADCEx_InjectedStart() API must be called for ADC slave first,
+ * then for ADC master.
+ * For ADC slave, ADC is enabled only (conversion is not started).
+ * For ADC master, ADC is enabled and multimode conversion is started.
+ * @param hadc ADC handle.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ uint32_t tmp_config_injected_queue;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
+ {
+ return HAL_BUSY;
+ }
+ else
+ {
+ /* In case of software trigger detection enabled, JQDIS must be set
+ (which can be done only if ADSTART and JADSTART are both cleared).
+ If JQDIS is not set at that point, returns an error
+ - since software trigger detection is disabled. User needs to
+ resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS.
+ - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means
+ the queue is empty */
+ tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
+
+ if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL)
+ && (tmp_config_injected_queue == 0UL)
+ )
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+ return HAL_ERROR;
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Check if a regular conversion is ongoing */
+ if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL)
+ {
+ /* Reset ADC error code field related to injected conversions only */
+ CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
+ }
+ else
+ {
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Set ADC state */
+ /* - Clear state bitfield related to injected group conversion results */
+ /* - Set state bitfield related to injected operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
+ HAL_ADC_STATE_INJ_BUSY);
+
+ /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit
+ - if ADC instance is master or if multimode feature is not available
+ - if multimode setting is disabled (ADC instance slave in independent mode) */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ )
+ {
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ /* Clear ADC group injected group conversion flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Enable conversion of injected group, if automatic injected conversion */
+ /* is disabled. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Case of multimode enabled (when multimode feature is available): */
+ /* if ADC is slave, */
+ /* - ADC is enabled only (conversion is not started), */
+ /* - if multimode only concerns regular conversion, ADC is enabled */
+ /* and conversion is started. */
+ /* If ADC is master or independent, */
+ /* - ADC is enabled and conversion is started. */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL)
+ )
+ {
+ /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
+ if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
+ {
+ LL_ADC_INJ_StartConversion(hadc->Instance);
+ }
+ }
+ else
+ {
+ /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+ }
+}
+
+/**
+ * @brief Stop conversion of injected channels. Disable ADC peripheral if
+ * no regular conversion is on going.
+ * @note If ADC must be disabled and if conversion is on going on
+ * regular group, function HAL_ADC_Stop must be used to stop both
+ * injected and regular groups, and disable the ADC.
+ * @note If injected group mode auto-injection is enabled,
+ * function HAL_ADC_Stop must be used.
+ * @note In case of multimode enabled (when multimode feature is available),
+ * HAL_ADCEx_InjectedStop() must be called for ADC master first, then for ADC slave.
+ * For ADC master, conversion is stopped and ADC is disabled.
+ * For ADC slave, ADC is disabled only (conversion stop of ADC master
+ * has already stopped conversion of ADC slave).
+ * @param hadc ADC handle.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential conversion on going on injected group only. */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
+
+ /* Disable ADC peripheral if injected conversions are effectively stopped */
+ /* and if no conversion on regular group is on-going */
+ if (tmp_hal_status == HAL_OK)
+ {
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* 2. Disable the ADC peripheral */
+ tmp_hal_status = ADC_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+ /* Conversion on injected group is stopped, but ADC not disabled since */
+ /* conversion on regular group is still running. */
+ else
+ {
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Wait for injected group conversion to be completed.
+ * @param hadc ADC handle
+ * @param Timeout Timeout value in millisecond.
+ * @note Depending on hadc->Init.EOCSelection, JEOS or JEOC is
+ * checked and cleared depending on AUTDLY bit status.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)
+{
+ uint32_t tickstart;
+ uint32_t tmp_Flag_End;
+ uint32_t tmp_adc_inj_is_trigger_source_sw_start;
+ uint32_t tmp_adc_reg_is_trigger_source_sw_start;
+ uint32_t tmp_cfgr;
+ const ADC_TypeDef *tmpADC_Master;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* If end of sequence selected */
+ if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
+ {
+ tmp_Flag_End = ADC_FLAG_JEOS;
+ }
+ else /* end of conversion selected */
+ {
+ tmp_Flag_End = ADC_FLAG_JEOC;
+ }
+
+ /* Get timeout */
+ tickstart = HAL_GetTick();
+
+ /* Wait until End of Conversion or Sequence flag is raised */
+ while ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
+ {
+ /* Check if timeout is disabled (set to infinite wait) */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
+ {
+ /* Update ADC state machine to timeout */
+ SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Retrieve ADC configuration */
+ tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance);
+ tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance);
+ /* Get relevant register CFGR in ADC instance of ADC master or slave */
+ /* in function of multimode state (for devices with multimode */
+ /* available). */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL)
+ )
+ {
+ tmp_cfgr = READ_REG(hadc->Instance->CFGR);
+ }
+ else
+ {
+ tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance);
+ tmp_cfgr = READ_REG(tmpADC_Master->CFGR);
+ }
+
+ /* Update ADC state machine */
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
+
+ /* Determine whether any further conversion upcoming on group injected */
+ /* by external trigger or by automatic injected conversion */
+ /* from group regular. */
+ if ((tmp_adc_inj_is_trigger_source_sw_start != 0UL) ||
+ ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) &&
+ ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
+ (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL))))
+ {
+ /* Check whether end of sequence is reached */
+ if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
+ {
+ /* Particular case if injected contexts queue is enabled: */
+ /* when the last context has been fully processed, JSQR is reset */
+ /* by the hardware. Even if no injected conversion is planned to come */
+ /* (queue empty, triggers are ignored), it can start again */
+ /* immediately after setting a new context (JADSTART is still set). */
+ /* Therefore, state of HAL ADC injected group is kept to busy. */
+ if (READ_BIT(tmp_cfgr, ADC_CFGR_JQM) == 0UL)
+ {
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+
+ if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_READY);
+ }
+ }
+ }
+ }
+
+ /* Clear polled flag */
+ if (tmp_Flag_End == ADC_FLAG_JEOS)
+ {
+ /* Clear end of sequence JEOS flag of injected group if low power feature */
+ /* "LowPowerAutoWait " is disabled, to not interfere with this feature. */
+ /* For injected groups, no new conversion will start before JEOS is */
+ /* cleared. */
+ if (READ_BIT(tmp_cfgr, ADC_CFGR_AUTDLY) == 0UL)
+ {
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
+ }
+ }
+ else
+ {
+ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
+ }
+
+ /* Return API HAL status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Enable ADC, start conversion of injected group with interruption.
+ * @note Interruptions enabled in this function according to initialization
+ * setting : JEOC (end of conversion) or JEOS (end of sequence)
+ * @note Case of multimode enabled (when multimode feature is enabled):
+ * HAL_ADCEx_InjectedStart_IT() API must be called for ADC slave first,
+ * then for ADC master.
+ * For ADC slave, ADC is enabled only (conversion is not started).
+ * For ADC master, ADC is enabled and multimode conversion is started.
+ * @param hadc ADC handle.
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ uint32_t tmp_config_injected_queue;
+ uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
+ {
+ return HAL_BUSY;
+ }
+ else
+ {
+ /* In case of software trigger detection enabled, JQDIS must be set
+ (which can be done only if ADSTART and JADSTART are both cleared).
+ If JQDIS is not set at that point, returns an error
+ - since software trigger detection is disabled. User needs to
+ resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS.
+ - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means
+ the queue is empty */
+ tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
+
+ if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL)
+ && (tmp_config_injected_queue == 0UL)
+ )
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+ return HAL_ERROR;
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Enable the ADC peripheral */
+ tmp_hal_status = ADC_Enable(hadc);
+
+ /* Start conversion if ADC is effectively enabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Check if a regular conversion is ongoing */
+ if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL)
+ {
+ /* Reset ADC error code field related to injected conversions only */
+ CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
+ }
+ else
+ {
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+ }
+
+ /* Set ADC state */
+ /* - Clear state bitfield related to injected group conversion results */
+ /* - Set state bitfield related to injected operation */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
+ HAL_ADC_STATE_INJ_BUSY);
+
+ /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit
+ - if ADC instance is master or if multimode feature is not available
+ - if multimode setting is disabled (ADC instance slave in independent mode) */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ )
+ {
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ /* Clear ADC group injected group conversion flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Enable ADC Injected context queue overflow interrupt if this feature */
+ /* is enabled. */
+ if ((hadc->Instance->CFGR & ADC_CFGR_JQM) != 0UL)
+ {
+ __HAL_ADC_ENABLE_IT(hadc, ADC_FLAG_JQOVF);
+ }
+
+ /* Enable ADC end of conversion interrupt */
+ switch (hadc->Init.EOCSelection)
+ {
+ case ADC_EOC_SEQ_CONV:
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS);
+ break;
+ /* case ADC_EOC_SINGLE_CONV */
+ default:
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS);
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
+ break;
+ }
+
+ /* Enable conversion of injected group, if automatic injected conversion */
+ /* is disabled. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Case of multimode enabled (when multimode feature is available): */
+ /* if ADC is slave, */
+ /* - ADC is enabled only (conversion is not started), */
+ /* - if multimode only concerns regular conversion, ADC is enabled */
+ /* and conversion is started. */
+ /* If ADC is master or independent, */
+ /* - ADC is enabled and conversion is started. */
+ if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
+ || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT)
+ || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL)
+ )
+ {
+ /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
+ if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
+ {
+ LL_ADC_INJ_StartConversion(hadc->Instance);
+ }
+ }
+ else
+ {
+ /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
+ SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
+ }
+
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+ }
+}
+
+/**
+ * @brief Stop conversion of injected channels, disable interruption of
+ * end-of-conversion. Disable ADC peripheral if no regular conversion
+ * is on going.
+ * @note If ADC must be disabled and if conversion is on going on
+ * regular group, function HAL_ADC_Stop must be used to stop both
+ * injected and regular groups, and disable the ADC.
+ * @note If injected group mode auto-injection is enabled,
+ * function HAL_ADC_Stop must be used.
+ * @note Case of multimode enabled (when multimode feature is available):
+ * HAL_ADCEx_InjectedStop_IT() API must be called for ADC master first,
+ * then for ADC slave.
+ * For ADC master, conversion is stopped and ADC is disabled.
+ * For ADC slave, ADC is disabled only (conversion stop of ADC master
+ * has already stopped conversion of ADC slave).
+ * @note In case of auto-injection mode, HAL_ADC_Stop() must be used.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential conversion on going on injected group only. */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
+
+ /* Disable ADC peripheral if injected conversions are effectively stopped */
+ /* and if no conversion on the other group (regular group) is intended to */
+ /* continue. */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Disable ADC end of conversion interrupt for injected channels */
+ __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_JEOC | ADC_IT_JEOS | ADC_FLAG_JQOVF));
+
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* 2. Disable the ADC peripheral */
+ tmp_hal_status = ADC_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+ /* Conversion on injected group is stopped, but ADC not disabled since */
+ /* conversion on regular group is still running. */
+ else
+ {
+ /* Set ADC state */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enable ADC, start MultiMode conversion and transfer regular results through DMA.
+ * @note Multimode must have been previously configured using
+ * HAL_ADCEx_MultiModeConfigChannel() function.
+ * Interruptions enabled in this function:
+ * overrun, DMA half transfer, DMA transfer complete.
+ * Each of these interruptions has its dedicated callback function.
+ * @note State field of Slave ADC handle is not updated in this configuration:
+ * user should not rely on it for information related to Slave regular
+ * conversions.
+ * @param hadc ADC handle of ADC master (handle of ADC slave must not be used)
+ * @param pData Destination Buffer address.
+ * @param Length Length of data to be transferred from ADC peripheral to memory (in bytes).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ ADC_HandleTypeDef tmphadcSlave;
+ ADC_Common_TypeDef *tmpADC_Common;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
+ assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
+
+ if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
+ {
+ return HAL_BUSY;
+ }
+ else
+ {
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Set a temporary handle of the ADC slave associated to the ADC master */
+ ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
+
+ if (tmphadcSlave.Instance == NULL)
+ {
+ /* Set ADC state */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ /* Enable the ADC peripherals: master and slave (in case if not already */
+ /* enabled previously) */
+ tmp_hal_status = ADC_Enable(hadc);
+ if (tmp_hal_status == HAL_OK)
+ {
+ tmp_hal_status = ADC_Enable(&tmphadcSlave);
+ }
+
+ /* Start multimode conversion of ADCs pair */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ (HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP),
+ HAL_ADC_STATE_REG_BUSY);
+
+ /* Set ADC error code to none */
+ ADC_CLEAR_ERRORCODE(hadc);
+
+ /* Set the DMA transfer complete callback */
+ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
+
+ /* Set the DMA half transfer complete callback */
+ hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
+
+ /* Set the DMA error callback */
+ hadc->DMA_Handle->XferErrorCallback = ADC_DMAError ;
+
+ /* Pointer to the common control register */
+ tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance);
+
+ /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
+ /* start (in case of SW start): */
+
+ /* Clear regular group conversion flag and overrun flag */
+ /* (To ensure of no unknown state from potential previous ADC operations) */
+ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
+
+ /* Process unlocked */
+ /* Unlock before starting ADC conversions: in case of potential */
+ /* interruption, to let the process to ADC IRQ Handler. */
+ __HAL_UNLOCK(hadc);
+
+ /* Enable ADC overrun interrupt */
+ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
+
+ /* Start the DMA channel */
+ tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&tmpADC_Common->CDR, (uint32_t)pData, Length);
+
+ /* Enable conversion of regular group. */
+ /* If software start has been selected, conversion starts immediately. */
+ /* If external trigger has been selected, conversion will start at next */
+ /* trigger event. */
+ /* Start ADC group regular conversion */
+ LL_ADC_REG_StartConversion(hadc->Instance);
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+ }
+
+ /* Return function status */
+ return tmp_hal_status;
+ }
+}
+
+/**
+ * @brief Stop multimode ADC conversion, disable ADC DMA transfer, disable ADC peripheral.
+ * @note Multimode is kept enabled after this function. MultiMode DMA bits
+ * (MDMA and DMACFG bits of common CCR register) are maintained. To disable
+ * Multimode (set with HAL_ADCEx_MultiModeConfigChannel()), ADC must be
+ * reinitialized using HAL_ADC_Init() or HAL_ADC_DeInit(), or the user can
+ * resort to HAL_ADCEx_DisableMultiMode() API.
+ * @note In case of DMA configured in circular mode, function
+ * HAL_ADC_Stop_DMA() must be called after this function with handle of
+ * ADC slave, to properly disable the DMA channel.
+ * @param hadc ADC handle of ADC master (handle of ADC slave must not be used)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ uint32_t tickstart;
+ ADC_HandleTypeDef tmphadcSlave;
+ uint32_t tmphadcSlave_conversion_on_going;
+ HAL_StatusTypeDef tmphadcSlave_disable_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+
+ /* 1. Stop potential multimode conversion on going, on regular and injected groups */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set a temporary handle of the ADC slave associated to the ADC master */
+ ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
+
+ if (tmphadcSlave.Instance == NULL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ /* Procedure to disable the ADC peripheral: wait for conversions */
+ /* effectively stopped (ADC master and ADC slave), then disable ADC */
+
+ /* 1. Wait for ADC conversion completion for ADC master and ADC slave */
+ tickstart = HAL_GetTick();
+
+ tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
+ while ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL)
+ || (tmphadcSlave_conversion_on_going == 1UL)
+ )
+ {
+ if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
+ }
+
+ /* Disable the DMA channel (in case of DMA in circular mode or stop */
+ /* while DMA transfer is on going) */
+ /* Note: DMA channel of ADC slave should be stopped after this function */
+ /* with HAL_ADC_Stop_DMA() API. */
+ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
+
+ /* Check if DMA channel effectively disabled */
+ if (tmp_hal_status == HAL_ERROR)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
+ }
+
+ /* Disable ADC overrun interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
+
+ /* 2. Disable the ADC peripherals: master and slave */
+ /* Update "tmp_hal_status" only if DMA channel disabling passed, to keep in */
+ /* memory a potential failing status. */
+ if (tmp_hal_status == HAL_OK)
+ {
+ tmphadcSlave_disable_status = ADC_Disable(&tmphadcSlave);
+ if ((ADC_Disable(hadc) == HAL_OK) &&
+ (tmphadcSlave_disable_status == HAL_OK))
+ {
+ tmp_hal_status = HAL_OK;
+ }
+ }
+ else
+ {
+ /* In case of error, attempt to disable ADC master and slave without status assert */
+ (void) ADC_Disable(hadc);
+ (void) ADC_Disable(&tmphadcSlave);
+ }
+
+ /* Set ADC state (ADC master) */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Return the last ADC Master and Slave regular conversions results when in multimode configuration.
+ * @param hadc ADC handle of ADC Master (handle of ADC Slave must not be used)
+ * @retval The converted data values.
+ */
+uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef *hadc)
+{
+ const ADC_Common_TypeDef *tmpADC_Common;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+
+ /* Prevent unused argument(s) compilation warning if no assert_param check */
+ /* and possible no usage in __LL_ADC_COMMON_INSTANCE() below */
+ UNUSED(hadc);
+
+ /* Pointer to the common control register */
+ tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance);
+
+ /* Return the multi mode conversion value */
+ return tmpADC_Common->CDR;
+}
+
+/**
+ * @brief Get ADC injected group conversion result.
+ * @note Reading register JDRx automatically clears ADC flag JEOC
+ * (ADC group injected end of unitary conversion).
+ * @note This function does not clear ADC flag JEOS
+ * (ADC group injected end of sequence conversion)
+ * Occurrence of flag JEOS rising:
+ * - If sequencer is composed of 1 rank, flag JEOS is equivalent
+ * to flag JEOC.
+ * - If sequencer is composed of several ranks, during the scan
+ * sequence flag JEOC only is raised, at the end of the scan sequence
+ * both flags JEOC and EOS are raised.
+ * Flag JEOS must not be cleared by this function because
+ * it would not be compliant with low power features
+ * (feature low power auto-wait, not available on all STM32 families).
+ * To clear this flag, either use function:
+ * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
+ * model polling: @ref HAL_ADCEx_InjectedPollForConversion()
+ * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS).
+ * @param hadc ADC handle
+ * @param InjectedRank the converted ADC injected rank.
+ * This parameter can be one of the following values:
+ * @arg @ref ADC_INJECTED_RANK_1 ADC group injected rank 1
+ * @arg @ref ADC_INJECTED_RANK_2 ADC group injected rank 2
+ * @arg @ref ADC_INJECTED_RANK_3 ADC group injected rank 3
+ * @arg @ref ADC_INJECTED_RANK_4 ADC group injected rank 4
+ * @retval ADC group injected conversion data
+ */
+uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef *hadc, uint32_t InjectedRank)
+{
+ uint32_t tmp_jdr;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
+
+ /* Get ADC converted value */
+ switch (InjectedRank)
+ {
+ case ADC_INJECTED_RANK_4:
+ tmp_jdr = hadc->Instance->JDR4;
+ break;
+ case ADC_INJECTED_RANK_3:
+ tmp_jdr = hadc->Instance->JDR3;
+ break;
+ case ADC_INJECTED_RANK_2:
+ tmp_jdr = hadc->Instance->JDR2;
+ break;
+ case ADC_INJECTED_RANK_1:
+ default:
+ tmp_jdr = hadc->Instance->JDR1;
+ break;
+ }
+
+ /* Return ADC converted value */
+ return tmp_jdr;
+}
+
+/**
+ * @brief Injected conversion complete callback in non-blocking mode.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADCEx_InjectedConvCpltCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Injected context queue overflow callback.
+ * @note This callback is called if injected context queue is enabled
+ (parameter "QueueInjectedContext" in injected channel configuration)
+ and if a new injected context is set when queue is full (maximum 2
+ contexts).
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADCEx_InjectedQueueOverflowCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADCEx_InjectedQueueOverflowCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Analog watchdog 2 callback in non-blocking mode.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADCEx_LevelOutOfWindow2Callback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Analog watchdog 3 callback in non-blocking mode.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADCEx_LevelOutOfWindow3Callback must be implemented in the user file.
+ */
+}
+
+
+/**
+ * @brief End Of Sampling callback in non-blocking mode.
+ * @param hadc ADC handle
+ * @retval None
+ */
+__weak void HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef *hadc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hadc);
+
+ /* NOTE : This function should not be modified. When the callback is needed,
+ function HAL_ADCEx_EndOfSamplingCallback must be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected channels in
+ * case of auto_injection mode), disable ADC peripheral if no
+ * conversion is on going on injected group.
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADCEx_RegularStop(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential regular conversion on going */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
+
+ /* Disable ADC peripheral if regular conversions are effectively stopped
+ and if no injected conversions are on-going */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Clear HAL_ADC_STATE_REG_BUSY bit */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* 2. Disable the ADC peripheral */
+ tmp_hal_status = ADC_Disable(hadc);
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+ /* Conversion on injected group is stopped, but ADC not disabled since */
+ /* conversion on regular group is still running. */
+ else
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+
+/**
+ * @brief Stop ADC conversion of ADC groups regular and injected,
+ * disable interrution of end-of-conversion,
+ * disable ADC peripheral if no conversion is on going
+ * on injected group.
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential regular conversion on going */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped
+ and if no injected conversion is on-going */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Clear HAL_ADC_STATE_REG_BUSY bit */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ /* Disable all regular-related interrupts */
+ __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
+
+ /* 2. Disable ADC peripheral if no injected conversions are on-going */
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ tmp_hal_status = ADC_Disable(hadc);
+ /* if no issue reported */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+ else
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop ADC conversion of regular group (and injected group in
+ * case of auto_injection mode), disable ADC DMA transfer, disable
+ * ADC peripheral if no conversion is on going
+ * on injected group.
+ * @note HAL_ADCEx_RegularStop_DMA() function is dedicated to single-ADC mode only.
+ * For multimode (when multimode feature is available),
+ * HAL_ADCEx_RegularMultiModeStop_DMA() API must be used.
+ * @param hadc ADC handle
+ * @retval HAL status.
+ */
+HAL_StatusTypeDef HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* 1. Stop potential regular conversion on going */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped
+ and if no injected conversion is on-going */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Clear HAL_ADC_STATE_REG_BUSY bit */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ /* Disable ADC DMA (ADC DMA configuration ADC_CFGR_DMACFG is kept) */
+ MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_DMNGT_0 |ADC_CFGR_DMNGT_1, 0UL);
+
+ /* Disable the DMA channel (in case of DMA in circular mode or stop while */
+ /* while DMA transfer is on going) */
+ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
+
+ /* Check if DMA channel effectively disabled */
+ if (tmp_hal_status != HAL_OK)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
+ }
+
+ /* Disable ADC overrun interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
+
+ /* 2. Disable the ADC peripheral */
+ /* Update "tmp_hal_status" only if DMA channel disabling passed, */
+ /* to keep in memory a potential failing status. */
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ if (tmp_hal_status == HAL_OK)
+ {
+ tmp_hal_status = ADC_Disable(hadc);
+ }
+ else
+ {
+ (void)ADC_Disable(hadc);
+ }
+
+ /* Check if ADC is effectively disabled */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Set ADC state */
+ ADC_STATE_CLR_SET(hadc->State,
+ HAL_ADC_STATE_INJ_BUSY,
+ HAL_ADC_STATE_READY);
+ }
+ }
+ else
+ {
+ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Stop DMA-based multimode ADC conversion, disable ADC DMA transfer, disable ADC peripheral if no injected conversion is on-going.
+ * @note Multimode is kept enabled after this function. Multimode DMA bits
+ * (MDMA and DMACFG bits of common CCR register) are maintained. To disable
+ * multimode (set with HAL_ADCEx_MultiModeConfigChannel()), ADC must be
+ * reinitialized using HAL_ADC_Init() or HAL_ADC_DeInit(), or the user can
+ * resort to HAL_ADCEx_DisableMultiMode() API.
+ * @note In case of DMA configured in circular mode, function
+ * HAL_ADCEx_RegularStop_DMA() must be called after this function with handle of
+ * ADC slave, to properly disable the DMA channel.
+ * @param hadc ADC handle of ADC master (handle of ADC slave must not be used)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_RegularMultiModeStop_DMA(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ uint32_t tickstart;
+ ADC_HandleTypeDef tmphadcSlave;
+ uint32_t tmphadcSlave_conversion_on_going;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+
+ /* 1. Stop potential multimode conversion on going, on regular groups */
+ tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
+
+ /* Disable ADC peripheral if conversions are effectively stopped */
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Clear HAL_ADC_STATE_REG_BUSY bit */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
+
+ /* Set a temporary handle of the ADC slave associated to the ADC master */
+ ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
+
+ if (tmphadcSlave.Instance == NULL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ /* Procedure to disable the ADC peripheral: wait for conversions */
+ /* effectively stopped (ADC master and ADC slave), then disable ADC */
+
+ /* 1. Wait for ADC conversion completion for ADC master and ADC slave */
+ tickstart = HAL_GetTick();
+
+ tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
+ while ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL)
+ || (tmphadcSlave_conversion_on_going == 1UL)
+ )
+ {
+ if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
+ }
+
+ /* Disable the DMA channel (in case of DMA in circular mode or stop */
+ /* while DMA transfer is on going) */
+ /* Note: DMA channel of ADC slave should be stopped after this function */
+ /* with HAL_ADCEx_RegularStop_DMA() API. */
+ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
+
+ /* Check if DMA channel effectively disabled */
+ if (tmp_hal_status != HAL_OK)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
+ }
+
+ /* Disable ADC overrun interrupt */
+ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
+
+ /* 2. Disable the ADC peripherals: master and slave if no injected */
+ /* conversion is on-going. */
+ /* Update "tmp_hal_status" only if DMA channel disabling passed, to keep in */
+ /* memory a potential failing status. */
+ if (tmp_hal_status == HAL_OK)
+ {
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ tmp_hal_status = ADC_Disable(hadc);
+ if (tmp_hal_status == HAL_OK)
+ {
+ if (LL_ADC_INJ_IsConversionOngoing((&tmphadcSlave)->Instance) == 0UL)
+ {
+ tmp_hal_status = ADC_Disable(&tmphadcSlave);
+ }
+ }
+ }
+
+ if (tmp_hal_status == HAL_OK)
+ {
+ /* Both Master and Slave ADC's could be disabled. Update Master State */
+ /* Clear HAL_ADC_STATE_INJ_BUSY bit, set HAL_ADC_STATE_READY bit */
+ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_READY);
+ }
+ else
+ {
+ /* injected (Master or Slave) conversions are still on-going,
+ no Master State change */
+ }
+ }
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADCEx_Exported_Functions_Group2 ADC Extended Peripheral Control functions
+ * @brief ADC Extended Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure channels on injected group
+ (+) Configure multimode when multimode feature is available
+ (+) Enable or Disable Injected Queue
+ (+) Disable ADC voltage regulator
+ (+) Enter ADC deep-power-down mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configure a channel to be assigned to ADC group injected.
+ * @note Possibility to update parameters on the fly:
+ * This function initializes injected group, following calls to this
+ * function can be used to reconfigure some parameters of structure
+ * "ADC_InjectionConfTypeDef" on the fly, without resetting the ADC.
+ * The setting of these parameters is conditioned to ADC state:
+ * Refer to comments of structure "ADC_InjectionConfTypeDef".
+ * @note In case of usage of internal measurement channels:
+ * Vbat/VrefInt/TempSensor.
+ * These internal paths can be disabled using function
+ * HAL_ADC_DeInit().
+ * @note Caution: For Injected Context Queue use, a context must be fully
+ * defined before start of injected conversion. All channels are configured
+ * consecutively for the same ADC instance. Therefore, the number of calls to
+ * HAL_ADCEx_InjectedConfigChannel() must be equal to the value of parameter
+ * InjectedNbrOfConversion for each context.
+ * - Example 1: If 1 context is intended to be used (or if there is no use of the
+ * Injected Queue Context feature) and if the context contains 3 injected ranks
+ * (InjectedNbrOfConversion = 3), HAL_ADCEx_InjectedConfigChannel() must be
+ * called once for each channel (i.e. 3 times) before starting a conversion.
+ * This function must not be called to configure a 4th injected channel:
+ * it would start a new context into context queue.
+ * - Example 2: If 2 contexts are intended to be used and each of them contains
+ * 3 injected ranks (InjectedNbrOfConversion = 3),
+ * HAL_ADCEx_InjectedConfigChannel() must be called once for each channel and
+ * for each context (3 channels x 2 contexts = 6 calls). Conversion can
+ * start once the 1st context is set, that is after the first three
+ * HAL_ADCEx_InjectedConfigChannel() calls. The 2nd context can be set on the fly.
+ * @param hadc ADC handle
+ * @param sConfigInjected Structure of ADC injected group and ADC channel for
+ * injected group.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_InjectionConfTypeDef *sConfigInjected)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ uint32_t tmpOffsetShifted;
+ uint32_t tmp_config_internal_channel;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+ __IO uint32_t wait_loop_index = 0;
+
+ uint32_t tmp_JSQR_ContextQueueBeingBuilt = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
+ assert_param(IS_ADC_SINGLE_DIFFERENTIAL(sConfigInjected->InjectedSingleDiff));
+ assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
+ assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->QueueInjectedContext));
+ assert_param(IS_ADC_EXTTRIGINJEC_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));
+ assert_param(IS_ADC_EXTTRIGINJEC(sConfigInjected->ExternalTrigInjecConv));
+ assert_param(IS_ADC_OFFSET_NUMBER(sConfigInjected->InjectedOffsetNumber));
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfigInjected->InjectedOffset));
+ assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjecOversamplingMode));
+
+ if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
+ {
+ assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
+ assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion));
+ assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
+ }
+
+ /* Check offset range according to oversampling setting */
+ if (hadc->Init.OversamplingMode == ENABLE)
+ {
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfigInjected->InjectedOffset/(hadc->Init.Oversampling.Ratio+1U)));
+ }
+ else
+ {
+ assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfigInjected->InjectedOffset));
+ }
+
+ /* JDISCEN and JAUTO bits can't be set at the same time */
+ assert_param(!((sConfigInjected->InjectedDiscontinuousConvMode == ENABLE) && (sConfigInjected->AutoInjectedConv == ENABLE)));
+
+ /* DISCEN and JAUTO bits can't be set at the same time */
+ assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (sConfigInjected->AutoInjectedConv == ENABLE)));
+
+ /* Verification of channel number */
+ if (sConfigInjected->InjectedSingleDiff != ADC_DIFFERENTIAL_ENDED)
+ {
+ assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel));
+ }
+ else
+ {
+ if (hadc->Instance == ADC1)
+ {
+ assert_param(IS_ADC1_DIFF_CHANNEL(sConfigInjected->InjectedChannel));
+ }
+ if (hadc->Instance == ADC2)
+ {
+ assert_param(IS_ADC2_DIFF_CHANNEL(sConfigInjected->InjectedChannel));
+ }
+#if defined (ADC3)
+ if (hadc->Instance == ADC3)
+ {
+ assert_param(IS_ADC3_DIFF_CHANNEL(sConfigInjected->InjectedChannel));
+ }
+#endif
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ /* Configuration of injected group sequencer: */
+ /* Hardware constraint: Must fully define injected context register JSQR */
+ /* before make it entering into injected sequencer queue. */
+ /* */
+ /* - if scan mode is disabled: */
+ /* * Injected channels sequence length is set to 0x00: 1 channel */
+ /* converted (channel on injected rank 1) */
+ /* Parameter "InjectedNbrOfConversion" is discarded. */
+ /* * Injected context register JSQR setting is simple: register is fully */
+ /* defined on one call of this function (for injected rank 1) and can */
+ /* be entered into queue directly. */
+ /* - if scan mode is enabled: */
+ /* * Injected channels sequence length is set to parameter */
+ /* "InjectedNbrOfConversion". */
+ /* * Injected context register JSQR setting more complex: register is */
+ /* fully defined over successive calls of this function, for each */
+ /* injected channel rank. It is entered into queue only when all */
+ /* injected ranks have been set. */
+ /* Note: Scan mode is not present by hardware on this device, but used */
+ /* by software for alignment over all STM32 devices. */
+
+ if ((hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) ||
+ (sConfigInjected->InjectedNbrOfConversion == 1U))
+ {
+ /* Configuration of context register JSQR: */
+ /* - number of ranks in injected group sequencer: fixed to 1st rank */
+ /* (scan mode disabled, only rank 1 used) */
+ /* - external trigger to start conversion */
+ /* - external trigger polarity */
+ /* - channel set to rank 1 (scan mode disabled, only rank 1 can be used) */
+
+ if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
+ {
+ /* Enable external trigger if trigger selection is different of */
+ /* software start. */
+ /* Note: This configuration keeps the hardware feature of parameter */
+ /* ExternalTrigInjecConvEdge "trigger edge none" equivalent to */
+ /* software start. */
+ if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
+ {
+ tmp_JSQR_ContextQueueBeingBuilt = (ADC_JSQR_RK(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1)
+ | (sConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
+ | sConfigInjected->ExternalTrigInjecConvEdge
+ );
+ }
+ else
+ {
+ tmp_JSQR_ContextQueueBeingBuilt = (ADC_JSQR_RK(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1));
+ }
+
+ MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, tmp_JSQR_ContextQueueBeingBuilt);
+ /* For debug and informative reasons, hadc handle saves JSQR setting */
+ hadc->InjectionConfig.ContextQueue = tmp_JSQR_ContextQueueBeingBuilt;
+
+ }
+ }
+ else
+ {
+ /* Case of scan mode enabled, several channels to set into injected group */
+ /* sequencer. */
+ /* */
+ /* Procedure to define injected context register JSQR over successive */
+ /* calls of this function, for each injected channel rank: */
+ /* 1. Start new context and set parameters related to all injected */
+ /* channels: injected sequence length and trigger. */
+
+ /* if hadc->InjectionConfig.ChannelCount is equal to 0, this is the first */
+ /* call of the context under setting */
+ if (hadc->InjectionConfig.ChannelCount == 0U)
+ {
+ /* Initialize number of channels that will be configured on the context */
+ /* being built */
+ hadc->InjectionConfig.ChannelCount = sConfigInjected->InjectedNbrOfConversion;
+ /* Handle hadc saves the context under build up over each HAL_ADCEx_InjectedConfigChannel()
+ call, this context will be written in JSQR register at the last call.
+ At this point, the context is merely reset */
+ hadc->InjectionConfig.ContextQueue = 0x00000000U;
+
+ /* Configuration of context register JSQR: */
+ /* - number of ranks in injected group sequencer */
+ /* - external trigger to start conversion */
+ /* - external trigger polarity */
+
+ /* Enable external trigger if trigger selection is different of */
+ /* software start. */
+ /* Note: This configuration keeps the hardware feature of parameter */
+ /* ExternalTrigInjecConvEdge "trigger edge none" equivalent to */
+ /* software start. */
+ if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
+ {
+ tmp_JSQR_ContextQueueBeingBuilt = ((sConfigInjected->InjectedNbrOfConversion - 1U)
+ | (sConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
+ | sConfigInjected->ExternalTrigInjecConvEdge
+ );
+ }
+ else
+ {
+ tmp_JSQR_ContextQueueBeingBuilt = ((sConfigInjected->InjectedNbrOfConversion - 1U));
+ }
+
+ }
+
+ /* 2. Continue setting of context under definition with parameter */
+ /* related to each channel: channel rank sequence */
+ /* Clear the old JSQx bits for the selected rank */
+ tmp_JSQR_ContextQueueBeingBuilt &= ~ADC_JSQR_RK(ADC_SQR3_SQ10, sConfigInjected->InjectedRank);
+
+ /* Set the JSQx bits for the selected rank */
+ tmp_JSQR_ContextQueueBeingBuilt |= ADC_JSQR_RK(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank);
+
+ /* Decrease channel count */
+ hadc->InjectionConfig.ChannelCount--;
+
+ /* 3. tmp_JSQR_ContextQueueBeingBuilt is fully built for this HAL_ADCEx_InjectedConfigChannel()
+ call, aggregate the setting to those already built during the previous
+ HAL_ADCEx_InjectedConfigChannel() calls (for the same context of course) */
+ hadc->InjectionConfig.ContextQueue |= tmp_JSQR_ContextQueueBeingBuilt;
+
+ /* 4. End of context setting: if this is the last channel set, then write context
+ into register JSQR and make it enter into queue */
+ if (hadc->InjectionConfig.ChannelCount == 0U)
+ {
+ MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, hadc->InjectionConfig.ContextQueue);
+ }
+ }
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on injected group: */
+ /* - Injected context queue: Queue disable (active context is kept) or */
+ /* enable (context decremented, up to 2 contexts queued) */
+ /* - Injected discontinuous mode: can be enabled only if auto-injected */
+ /* mode is disabled. */
+ if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
+ {
+ /* ADC channels preselection */
+ hadc->Instance->PCSEL |= (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel) & 0x1FUL));
+
+ /* If auto-injected mode is disabled: no constraint */
+ if (sConfigInjected->AutoInjectedConv == DISABLE)
+ {
+ MODIFY_REG(hadc->Instance->CFGR,
+ ADC_CFGR_JQM | ADC_CFGR_JDISCEN,
+ ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)sConfigInjected->QueueInjectedContext) |
+ ADC_CFGR_INJECT_DISCCONTINUOUS((uint32_t)sConfigInjected->InjectedDiscontinuousConvMode));
+ }
+ /* If auto-injected mode is enabled: Injected discontinuous setting is */
+ /* discarded. */
+ else
+ {
+ MODIFY_REG(hadc->Instance->CFGR,
+ ADC_CFGR_JQM | ADC_CFGR_JDISCEN,
+ ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)sConfigInjected->QueueInjectedContext));
+ }
+
+ }
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on regular and injected groups: */
+ /* - Automatic injected conversion: can be enabled if injected group */
+ /* external triggers are disabled. */
+ /* - Channel sampling time */
+ /* - Channel offset */
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+
+ if ((tmp_adc_is_conversion_on_going_regular == 0UL)
+ && (tmp_adc_is_conversion_on_going_injected == 0UL)
+ )
+ {
+ /* If injected group external triggers are disabled (set to injected */
+ /* software start): no constraint */
+ if ((sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START)
+ || (sConfigInjected->ExternalTrigInjecConvEdge == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE))
+ {
+ if (sConfigInjected->AutoInjectedConv == ENABLE)
+ {
+ SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
+ }
+ else
+ {
+ CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
+ }
+ }
+ /* If Automatic injected conversion was intended to be set and could not */
+ /* due to injected group external triggers enabled, error is reported. */
+ else
+ {
+ if (sConfigInjected->AutoInjectedConv == ENABLE)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ else
+ {
+ CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
+ }
+ }
+
+ if (sConfigInjected->InjecOversamplingMode == ENABLE)
+ {
+ assert_param(IS_ADC_OVERSAMPLING_RATIO(sConfigInjected->InjecOversampling.Ratio));
+ assert_param(IS_ADC_RIGHT_BIT_SHIFT(sConfigInjected->InjecOversampling.RightBitShift));
+
+ /* JOVSE must be reset in case of triggered regular mode */
+ assert_param(!(READ_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS) == (ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS)));
+
+ /* Configuration of Injected Oversampler: */
+ /* - Oversampling Ratio */
+ /* - Right bit shift */
+
+ /* Enable OverSampling mode */
+ MODIFY_REG(hadc->Instance->CFGR2,
+ ADC_CFGR2_JOVSE |
+ ADC_CFGR2_OVSR |
+ ADC_CFGR2_OVSS,
+ ADC_CFGR2_JOVSE |
+ ((sConfigInjected->InjecOversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
+ sConfigInjected->InjecOversampling.RightBitShift
+ );
+ }
+ else
+ {
+ /* Disable Regular OverSampling */
+ CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_JOVSE);
+ }
+
+ /* Set sampling time of the selected ADC channel */
+ LL_ADC_SetChannelSamplingTime(hadc->Instance, sConfigInjected->InjectedChannel, sConfigInjected->InjectedSamplingTime);
+
+ /* Configure the offset: offset enable/disable, channel, offset value */
+
+ /* Shift the offset with respect to the selected ADC resolution. */
+ /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
+ tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, sConfigInjected->InjectedOffset);
+
+ if (sConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE)
+ {
+ /* Set ADC selected offset number */
+ LL_ADC_SetOffset(hadc->Instance, sConfigInjected->InjectedOffsetNumber, sConfigInjected->InjectedChannel,
+ tmpOffsetShifted);
+
+ /* Set ADC selected offset signed saturation */
+ LL_ADC_SetOffsetSignedSaturation(hadc->Instance, sConfigInjected->InjectedOffsetNumber, (sConfigInjected->InjectedOffsetSignedSaturation == ENABLE) ? LL_ADC_OFFSET_SIGNED_SATURATION_ENABLE : LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
+
+ /* Set ADC selected offset right shift */
+ LL_ADC_SetDataRightShift(hadc->Instance, sConfigInjected->InjectedOffsetNumber, (sConfigInjected->InjectedOffsetRightShift == (uint32_t)ENABLE) ? LL_ADC_OFFSET_RSHIFT_ENABLE : LL_ADC_OFFSET_RSHIFT_DISABLE);
+
+ }
+ else
+ {
+ /* Scan each offset register to check if the selected channel is targeted. */
+ /* If this is the case, the corresponding offset number is disabled. */
+ if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
+ {
+ LL_ADC_SetOffset(hadc->Instance, LL_ADC_OFFSET_1, sConfigInjected->InjectedChannel, LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
+ }
+ if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
+ {
+ LL_ADC_SetOffset(hadc->Instance, LL_ADC_OFFSET_2, sConfigInjected->InjectedChannel, LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
+ }
+ if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
+ {
+ LL_ADC_SetOffset(hadc->Instance, LL_ADC_OFFSET_4, sConfigInjected->InjectedChannel, LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
+ }
+ if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
+ {
+ LL_ADC_SetOffset(hadc->Instance, LL_ADC_OFFSET_4, sConfigInjected->InjectedChannel, LL_ADC_OFFSET_SIGNED_SATURATION_DISABLE);
+ }
+ }
+
+ }
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated only when ADC is disabled: */
+ /* - Single or differential mode */
+ /* - Internal measurement channels: Vbat/VrefInt/TempSensor */
+ if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ /* Set mode single-ended or differential input of the selected ADC channel */
+ LL_ADC_SetChannelSingleDiff(hadc->Instance, sConfigInjected->InjectedChannel, sConfigInjected->InjectedSingleDiff);
+
+ /* Configuration of differential mode */
+ /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */
+ if (sConfigInjected->InjectedSingleDiff == ADC_DIFFERENTIAL_ENDED)
+ {
+ /* Set sampling time of the selected ADC channel */
+ LL_ADC_SetChannelSamplingTime(hadc->Instance, (uint32_t)(__LL_ADC_DECIMAL_NB_TO_CHANNEL((__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfigInjected->InjectedChannel) + 1UL) & 0x1FUL)), sConfigInjected->InjectedSamplingTime);
+ }
+
+ /* Management of internal measurement channels: Vbat/VrefInt/TempSensor */
+ /* internal measurement paths enable: If internal channel selected, */
+ /* enable dedicated internal buffers and path. */
+ /* Note: these internal measurement paths can be disabled using */
+ /* HAL_ADC_DeInit(). */
+
+ if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfigInjected->InjectedChannel))
+ {
+ /* Configuration of common ADC parameters (continuation) */
+ /* Software is allowed to change common parameters only when all ADCs */
+ /* of the common group are disabled. */
+ if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
+ {
+ tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
+
+ /* If the requested internal measurement path has already been enabled, */
+ /* bypass the configuration processing. */
+ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL))
+ {
+ if (ADC_TEMPERATURE_SENSOR_INSTANCE(hadc))
+ {
+ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel);
+
+ /* Delay for temperature sensor stabilization time */
+ /* Wait loop initialization and execution */
+ /* Note: Variable divided by 2 to compensate partially */
+ /* CPU processing cycles, scaling in us split to not */
+ /* exceed 32 bits register capacity and handle low frequency. */
+ wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
+ while(wait_loop_index != 0UL)
+ {
+ wait_loop_index--;
+ }
+ }
+ }
+ else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL))
+ {
+ if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc))
+ {
+ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel);
+ }
+ }
+ else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL))
+ {
+ if (ADC_VREFINT_INSTANCE(hadc))
+ {
+ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel);
+ }
+ }
+ else
+ {
+ /* nothing to do */
+ }
+ }
+ /* If the requested internal measurement path has already been enabled */
+ /* and other ADC of the common group are enabled, internal */
+ /* measurement paths cannot be enabled. */
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+ }
+
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enable ADC multimode and configure multimode parameters
+ * @note Possibility to update parameters on the fly:
+ * This function initializes multimode parameters, following
+ * calls to this function can be used to reconfigure some parameters
+ * of structure "ADC_MultiModeTypeDef" on the fly, without resetting
+ * the ADCs.
+ * The setting of these parameters is conditioned to ADC state.
+ * For parameters constraints, see comments of structure
+ * "ADC_MultiModeTypeDef".
+ * @note To move back configuration from multimode to single mode, ADC must
+ * be reset (using function HAL_ADC_Init() ).
+ * @param hadc Master ADC handle
+ * @param multimode Structure of ADC multimode configuration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, ADC_MultiModeTypeDef *multimode)
+{
+ HAL_StatusTypeDef tmp_hal_status = HAL_OK;
+ ADC_Common_TypeDef *tmpADC_Common;
+ ADC_HandleTypeDef tmphadcSlave;
+ uint32_t tmphadcSlave_conversion_on_going;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
+ assert_param(IS_ADC_MULTIMODE(multimode->Mode));
+ if (multimode->Mode != ADC_MODE_INDEPENDENT)
+ {
+ assert_param(IS_ADC_DUAL_DATA_MODE(multimode->DualModeData));
+ assert_param(IS_ADC_SAMPLING_DELAY(multimode->TwoSamplingDelay));
+ }
+
+ /* Process locked */
+ __HAL_LOCK(hadc);
+
+ ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
+
+ if (tmphadcSlave.Instance == NULL)
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ return HAL_ERROR;
+ }
+
+ /* Parameters update conditioned to ADC state: */
+ /* Parameters that can be updated when ADC is disabled or enabled without */
+ /* conversion on going on regular group: */
+ /* - Multimode DATA Format configuration */
+ tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
+ if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
+ && (tmphadcSlave_conversion_on_going == 0UL))
+ {
+ /* Pointer to the common control register */
+ tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance);
+
+ /* If multimode is selected, configure all multimode parameters. */
+ /* Otherwise, reset multimode parameters (can be used in case of */
+ /* transition from multimode to independent mode). */
+ if (multimode->Mode != ADC_MODE_INDEPENDENT)
+ {
+ MODIFY_REG(tmpADC_Common->CCR, ADC_CCR_DAMDF, multimode->DualModeData);
+
+ /* Parameters that can be updated only when ADC is disabled: */
+ /* - Multimode mode selection */
+ /* - Multimode delay */
+ /* Note: Delay range depends on selected resolution: */
+ /* from 1 to 9 clock cycles for 16 bits */
+ /* from 1 to 9 clock cycles for 14 bits, */
+ /* from 1 to 8 clock cycles for 12 bits */
+ /* from 1 to 6 clock cycles for 10 and 8 bits */
+ /* If a higher delay is selected, it will be clipped to maximum delay */
+ /* range */
+
+ if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
+ {
+ MODIFY_REG(tmpADC_Common->CCR,
+ ADC_CCR_DUAL |
+ ADC_CCR_DELAY,
+ multimode->Mode |
+ multimode->TwoSamplingDelay
+ );
+ }
+ }
+ else /* ADC_MODE_INDEPENDENT */
+ {
+ CLEAR_BIT(tmpADC_Common->CCR, ADC_CCR_DAMDF);
+
+ /* Parameters that can be updated only when ADC is disabled: */
+ /* - Multimode mode selection */
+ /* - Multimode delay */
+ if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
+ {
+ CLEAR_BIT(tmpADC_Common->CCR, ADC_CCR_DUAL | ADC_CCR_DELAY);
+ }
+ }
+ }
+ /* If one of the ADC sharing the same common group is enabled, no update */
+ /* could be done on neither of the multimode structure parameters. */
+ else
+ {
+ /* Update ADC state machine to error */
+ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
+
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hadc);
+
+ /* Return function status */
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enable Injected Queue
+ * @note This function resets CFGR register JQDIS bit in order to enable the
+ * Injected Queue. JQDIS can be written only when ADSTART and JDSTART
+ * are both equal to 0 to ensure that no regular nor injected
+ * conversion is ongoing.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_EnableInjectedQueue(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+
+ /* Parameter can be set only if no conversion is on-going */
+ if ((tmp_adc_is_conversion_on_going_regular == 0UL)
+ && (tmp_adc_is_conversion_on_going_injected == 0UL)
+ )
+ {
+ CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
+
+ /* Update state, clear previous result related to injected queue overflow */
+ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);
+
+ tmp_hal_status = HAL_OK;
+ }
+ else
+ {
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Disable Injected Queue
+ * @note This function sets CFGR register JQDIS bit in order to disable the
+ * Injected Queue. JQDIS can be written only when ADSTART and JDSTART
+ * are both equal to 0 to ensure that no regular nor injected
+ * conversion is ongoing.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_DisableInjectedQueue(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+ uint32_t tmp_adc_is_conversion_on_going_regular;
+ uint32_t tmp_adc_is_conversion_on_going_injected;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
+ tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
+
+ /* Parameter can be set only if no conversion is on-going */
+ if ((tmp_adc_is_conversion_on_going_regular == 0UL)
+ && (tmp_adc_is_conversion_on_going_injected == 0UL)
+ )
+ {
+ LL_ADC_INJ_SetQueueMode(hadc->Instance, LL_ADC_INJ_QUEUE_DISABLE);
+ tmp_hal_status = HAL_OK;
+ }
+ else
+ {
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Disable ADC voltage regulator.
+ * @note Disabling voltage regulator allows to save power. This operation can
+ * be carried out only when ADC is disabled.
+ * @note To enable again the voltage regulator, the user is expected to
+ * resort to HAL_ADC_Init() API.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
+ if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ LL_ADC_DisableInternalRegulator(hadc->Instance);
+ tmp_hal_status = HAL_OK;
+ }
+ else
+ {
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ return tmp_hal_status;
+}
+
+/**
+ * @brief Enter ADC deep-power-down mode
+ * @note This mode is achieved in setting DEEPPWD bit and allows to save power
+ * in reducing leakage currents. It is particularly interesting before
+ * entering stop modes.
+ * @note Setting DEEPPWD automatically clears ADVREGEN bit and disables the
+ * ADC voltage regulator. This means that this API encompasses
+ * HAL_ADCEx_DisableVoltageRegulator(). Additionally, the internal
+ * calibration is lost.
+ * @note To exit the ADC deep-power-down mode, the user is expected to
+ * resort to HAL_ADC_Init() API as well as to relaunch a calibration
+ * with HAL_ADCEx_Calibration_Start() API or to re-apply a previously
+ * saved calibration factor.
+ * @param hadc ADC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef *hadc)
+{
+ HAL_StatusTypeDef tmp_hal_status;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
+
+ /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
+ if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
+ {
+ LL_ADC_EnableDeepPowerDown(hadc->Instance);
+ tmp_hal_status = HAL_OK;
+ }
+ else
+ {
+ tmp_hal_status = HAL_ERROR;
+ }
+
+ return tmp_hal_status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_ADC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_cec.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_cec.c
new file mode 100644
index 0000000000..1b87bac84e
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_cec.c
@@ -0,0 +1,1001 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_cec.c
+ * @author MCD Application Team
+ * @brief CEC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the High Definition Multimedia Interface
+ * Consumer Electronics Control Peripheral (CEC).
+ * + Initialization and de-initialization function
+ * + IO operation function
+ * + Peripheral Control function
+ *
+ *
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ The CEC HAL driver can be used as follow:
+
+ (#) Declare a CEC_HandleTypeDef handle structure.
+ (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API:
+ (##) Enable the CEC interface clock.
+ (##) CEC pins configuration:
+ (+++) Enable the clock for the CEC GPIOs.
+ (+++) Configure these CEC pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT()
+ and HAL_CEC_Receive_IT() APIs):
+ (+++) Configure the CEC interrupt priority.
+ (+++) Enable the NVIC CEC IRQ handle.
+ (+++) The specific CEC interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit
+ and receive process.
+
+ (#) Program the Signal Free Time (SFT) and SFT option, Tolerance, reception stop in
+ in case of Bit Rising Error, Error-Bit generation conditions, device logical
+ address and Listen mode in the hcec Init structure.
+
+ (#) Initialize the CEC registers by calling the HAL_CEC_Init() API.
+
+ [..]
+ (@) This API (HAL_CEC_Init()) configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc)
+ by calling the customed HAL_CEC_MspInit() API.
+ *** Callback registration ***
+ =============================================
+
+ The compilation define USE_HAL_CEC_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+ Use Functions @ref HAL_CEC_RegisterCallback() or HAL_CEC_RegisterXXXCallback()
+ to register an interrupt callback.
+
+ Function @ref HAL_CEC_RegisterCallback() allows to register following callbacks:
+ (+) TxCpltCallback : Tx Transfer completed callback.
+ (+) ErrorCallback : callback for error detection.
+ (+) MspInitCallback : CEC MspInit.
+ (+) MspDeInitCallback : CEC MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ For specific callback HAL_CEC_RxCpltCallback use dedicated register callbacks
+ @ref HAL_CEC_RegisterRxCpltCallback().
+
+ Use function @ref HAL_CEC_UnRegisterCallback() to reset a callback to the default
+ weak function.
+ @ref HAL_CEC_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) TxCpltCallback : Tx Transfer completed callback.
+ (+) ErrorCallback : callback for error detection.
+ (+) MspInitCallback : CEC MspInit.
+ (+) MspDeInitCallback : CEC MspDeInit.
+
+ For callback HAL_CEC_RxCpltCallback use dedicated unregister callback :
+ @ref HAL_CEC_UnRegisterRxCpltCallback().
+
+ By default, after the @ref HAL_CEC_Init() and when the state is HAL_CEC_STATE_RESET
+ all callbacks are set to the corresponding weak functions :
+ examples @ref HAL_CEC_TxCpltCallback() , @ref HAL_CEC_RxCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are
+ reset to the legacy weak function in the @ref HAL_CEC_Init()/ @ref HAL_CEC_DeInit() only when
+ these callbacks are null (not registered beforehand).
+ if not, MspInit or MspDeInit are not null, the @ref HAL_CEC_Init() / @ref HAL_CEC_DeInit()
+ keep and use the user MspInit/MspDeInit functions (registered beforehand)
+
+ Callbacks can be registered/unregistered in HAL_CEC_STATE_READY state only.
+ Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
+ in HAL_CEC_STATE_READY or HAL_CEC_STATE_RESET state,
+ thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using @ref HAL_CEC_RegisterCallback() before calling @ref HAL_CEC_DeInit()
+ or @ref HAL_CEC_Init() function.
+
+ When the compilation define USE_HAL_CEC_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registration feature is not available and all callbacks
+ are set to the corresponding weak functions.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CEC CEC
+ * @brief HAL CEC module driver
+ * @{
+ */
+#ifdef HAL_CEC_MODULE_ENABLED
+#if defined (CEC)
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup CEC_Private_Constants CEC Private Constants
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup CEC_Private_Functions CEC Private Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup CEC_Exported_Functions CEC Exported Functions
+ * @{
+ */
+
+/** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the CEC
+ (+) The following parameters need to be configured:
+ (++) SignalFreeTime
+ (++) Tolerance
+ (++) BRERxStop (RX stopped or not upon Bit Rising Error)
+ (++) BREErrorBitGen (Error-Bit generation in case of Bit Rising Error)
+ (++) LBPEErrorBitGen (Error-Bit generation in case of Long Bit Period Error)
+ (++) BroadcastMsgNoErrorBitGen (Error-bit generation in case of broadcast message error)
+ (++) SignalFreeTimeOption (SFT Timer start definition)
+ (++) OwnAddress (CEC device address)
+ (++) ListenMode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the CEC mode according to the specified
+ * parameters in the CEC_InitTypeDef and creates the associated handle .
+ * @param hcec CEC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec)
+{
+ /* Check the CEC handle allocation */
+ if ((hcec == NULL) || (hcec->Init.RxBuffer == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
+ assert_param(IS_CEC_SIGNALFREETIME(hcec->Init.SignalFreeTime));
+ assert_param(IS_CEC_TOLERANCE(hcec->Init.Tolerance));
+ assert_param(IS_CEC_BRERXSTOP(hcec->Init.BRERxStop));
+ assert_param(IS_CEC_BREERRORBITGEN(hcec->Init.BREErrorBitGen));
+ assert_param(IS_CEC_LBPEERRORBITGEN(hcec->Init.LBPEErrorBitGen));
+ assert_param(IS_CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION(hcec->Init.BroadcastMsgNoErrorBitGen));
+ assert_param(IS_CEC_SFTOP(hcec->Init.SignalFreeTimeOption));
+ assert_param(IS_CEC_LISTENING_MODE(hcec->Init.ListenMode));
+ assert_param(IS_CEC_OWN_ADDRESS(hcec->Init.OwnAddress));
+
+#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1)
+ if (hcec->gState == HAL_CEC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcec->Lock = HAL_UNLOCKED;
+
+ hcec->TxCpltCallback = HAL_CEC_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ hcec->RxCpltCallback = HAL_CEC_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ hcec->ErrorCallback = HAL_CEC_ErrorCallback; /* Legacy weak ErrorCallback */
+
+ if (hcec->MspInitCallback == NULL)
+ {
+ hcec->MspInitCallback = HAL_CEC_MspInit; /* Legacy weak MspInit */
+ }
+
+ /* Init the low level hardware */
+ hcec->MspInitCallback(hcec);
+ }
+#else
+ if (hcec->gState == HAL_CEC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcec->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_CEC_MspInit(hcec);
+ }
+#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
+
+ hcec->gState = HAL_CEC_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_CEC_DISABLE(hcec);
+
+ /* Write to CEC Control Register */
+ hcec->Instance->CFGR = hcec->Init.SignalFreeTime | hcec->Init.Tolerance | hcec->Init.BRERxStop | \
+ hcec->Init.BREErrorBitGen | hcec->Init.LBPEErrorBitGen | hcec->Init.BroadcastMsgNoErrorBitGen | \
+ hcec->Init.SignalFreeTimeOption | ((uint32_t)(hcec->Init.OwnAddress) << 16U) | \
+ hcec->Init.ListenMode;
+
+ /* Enable the following CEC Transmission/Reception interrupts as
+ * well as the following CEC Transmission/Reception Errors interrupts
+ * Rx Byte Received IT
+ * End of Reception IT
+ * Rx overrun
+ * Rx bit rising error
+ * Rx short bit period error
+ * Rx long bit period error
+ * Rx missing acknowledge
+ * Tx Byte Request IT
+ * End of Transmission IT
+ * Tx Missing Acknowledge IT
+ * Tx-Error IT
+ * Tx-Buffer Underrun IT
+ * Tx arbitration lost */
+ __HAL_CEC_ENABLE_IT(hcec, CEC_IT_RXBR | CEC_IT_RXEND | CEC_IER_RX_ALL_ERR | CEC_IT_TXBR | CEC_IT_TXEND |
+ CEC_IER_TX_ALL_ERR);
+
+ /* Enable the CEC Peripheral */
+ __HAL_CEC_ENABLE(hcec);
+
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+ hcec->gState = HAL_CEC_STATE_READY;
+ hcec->RxState = HAL_CEC_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the CEC peripheral
+ * @param hcec CEC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec)
+{
+ /* Check the CEC handle allocation */
+ if (hcec == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance));
+
+ hcec->gState = HAL_CEC_STATE_BUSY;
+
+#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1)
+ if (hcec->MspDeInitCallback == NULL)
+ {
+ hcec->MspDeInitCallback = HAL_CEC_MspDeInit; /* Legacy weak MspDeInit */
+ }
+
+ /* DeInit the low level hardware */
+ hcec->MspDeInitCallback(hcec);
+
+#else
+ /* DeInit the low level hardware */
+ HAL_CEC_MspDeInit(hcec);
+#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
+
+ /* Disable the Peripheral */
+ __HAL_CEC_DISABLE(hcec);
+
+ /* Clear Flags */
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXEND | CEC_FLAG_TXBR | CEC_FLAG_RXBR | CEC_FLAG_RXEND | CEC_ISR_ALL_ERROR);
+
+ /* Disable the following CEC Transmission/Reception interrupts as
+ * well as the following CEC Transmission/Reception Errors interrupts
+ * Rx Byte Received IT
+ * End of Reception IT
+ * Rx overrun
+ * Rx bit rising error
+ * Rx short bit period error
+ * Rx long bit period error
+ * Rx missing acknowledge
+ * Tx Byte Request IT
+ * End of Transmission IT
+ * Tx Missing Acknowledge IT
+ * Tx-Error IT
+ * Tx-Buffer Underrun IT
+ * Tx arbitration lost */
+ __HAL_CEC_DISABLE_IT(hcec, CEC_IT_RXBR | CEC_IT_RXEND | CEC_IER_RX_ALL_ERR | CEC_IT_TXBR | CEC_IT_TXEND |
+ CEC_IER_TX_ALL_ERR);
+
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+ hcec->gState = HAL_CEC_STATE_RESET;
+ hcec->RxState = HAL_CEC_STATE_RESET;
+
+ /* Process Unlock */
+ __HAL_UNLOCK(hcec);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the Own Address of the CEC device
+ * @param hcec CEC handle
+ * @param CEC_OwnAddress The CEC own address.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress)
+{
+ /* Check the parameters */
+ assert_param(IS_CEC_OWN_ADDRESS(CEC_OwnAddress));
+
+ if ((hcec->gState == HAL_CEC_STATE_READY) && (hcec->RxState == HAL_CEC_STATE_READY))
+ {
+ /* Process Locked */
+ __HAL_LOCK(hcec);
+
+ hcec->gState = HAL_CEC_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_CEC_DISABLE(hcec);
+
+ if (CEC_OwnAddress != CEC_OWN_ADDRESS_NONE)
+ {
+ hcec->Instance->CFGR |= ((uint32_t)CEC_OwnAddress << 16);
+ }
+ else
+ {
+ hcec->Instance->CFGR &= ~(CEC_CFGR_OAR);
+ }
+
+ hcec->gState = HAL_CEC_STATE_READY;
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcec);
+
+ /* Enable the Peripheral */
+ __HAL_CEC_ENABLE(hcec);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief CEC MSP Init
+ * @param hcec CEC handle
+ * @retval None
+ */
+__weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_MspInit can be implemented in the user file
+ */
+}
+
+/**
+ * @brief CEC MSP DeInit
+ * @param hcec CEC handle
+ * @retval None
+ */
+__weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_MspDeInit can be implemented in the user file
+ */
+}
+#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User CEC Callback
+ * To be used instead of the weak predefined callback
+ * @param hcec CEC handle
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_CEC_TX_CPLT_CB_ID Tx Complete callback ID
+ * @arg @ref HAL_CEC_ERROR_CB_ID Error callback ID
+ * @arg @ref HAL_CEC_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_RegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID,
+ pCEC_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(hcec);
+
+ if (hcec->gState == HAL_CEC_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CEC_TX_CPLT_CB_ID :
+ hcec->TxCpltCallback = pCallback;
+ break;
+
+ case HAL_CEC_ERROR_CB_ID :
+ hcec->ErrorCallback = pCallback;
+ break;
+
+ case HAL_CEC_MSPINIT_CB_ID :
+ hcec->MspInitCallback = pCallback;
+ break;
+
+ case HAL_CEC_MSPDEINIT_CB_ID :
+ hcec->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hcec->gState == HAL_CEC_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CEC_MSPINIT_CB_ID :
+ hcec->MspInitCallback = pCallback;
+ break;
+
+ case HAL_CEC_MSPDEINIT_CB_ID :
+ hcec->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcec);
+
+ return status;
+}
+
+/**
+ * @brief Unregister an CEC Callback
+ * CEC callabck is redirected to the weak predefined callback
+ * @param hcec uart handle
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_CEC_TX_CPLT_CB_ID Tx Complete callback ID
+ * @arg @ref HAL_CEC_ERROR_CB_ID Error callback ID
+ * @arg @ref HAL_CEC_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_CEC_UnRegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hcec);
+
+ if (hcec->gState == HAL_CEC_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CEC_TX_CPLT_CB_ID :
+ hcec->TxCpltCallback = HAL_CEC_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ break;
+
+ case HAL_CEC_ERROR_CB_ID :
+ hcec->ErrorCallback = HAL_CEC_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_CEC_MSPINIT_CB_ID :
+ hcec->MspInitCallback = HAL_CEC_MspInit;
+ break;
+
+ case HAL_CEC_MSPDEINIT_CB_ID :
+ hcec->MspDeInitCallback = HAL_CEC_MspDeInit;
+ break;
+
+ default :
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hcec->gState == HAL_CEC_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CEC_MSPINIT_CB_ID :
+ hcec->MspInitCallback = HAL_CEC_MspInit;
+ break;
+
+ case HAL_CEC_MSPDEINIT_CB_ID :
+ hcec->MspDeInitCallback = HAL_CEC_MspDeInit;
+ break;
+
+ default :
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcec);
+
+ return status;
+}
+
+/**
+ * @brief Register CEC RX complete Callback
+ * To be used instead of the weak HAL_CEC_RxCpltCallback() predefined callback
+ * @param hcec CEC handle
+ * @param pCallback pointer to the Rx transfer compelete Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_RegisterRxCpltCallback(CEC_HandleTypeDef *hcec, pCEC_RxCallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(hcec);
+
+ if (HAL_CEC_STATE_READY == hcec->RxState)
+ {
+ hcec->RxCpltCallback = pCallback;
+ }
+ else
+ {
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcec);
+ return status;
+}
+
+/**
+ * @brief UnRegister CEC RX complete Callback
+ * CEC RX complete Callback is redirected to the weak HAL_CEC_RxCpltCallback() predefined callback
+ * @param hcec CEC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_UnRegisterRxCpltCallback(CEC_HandleTypeDef *hcec)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hcec);
+
+ if (HAL_CEC_STATE_READY == hcec->RxState)
+ {
+ hcec->RxCpltCallback = HAL_CEC_RxCpltCallback; /* Legacy weak CEC RxCpltCallback */
+ }
+ else
+ {
+ /* Update the error code */
+ hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcec);
+ return status;
+}
+#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions
+ * @brief CEC Transmit/Receive functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ This subsection provides a set of functions allowing to manage the CEC data transfers.
+
+ (#) The CEC handle must contain the initiator (TX side) and the destination (RX side)
+ logical addresses (4-bit long addresses, 0xF for broadcast messages destination)
+
+ (#) The communication is performed using Interrupts.
+ These API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated CEC IRQ when using Interrupt mode.
+ The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or Receive process
+ The HAL_CEC_ErrorCallback() user callback will be executed when a communication
+ error is detected
+
+ (#) API's with Interrupt are :
+ (+) HAL_CEC_Transmit_IT()
+ (+) HAL_CEC_IRQHandler()
+
+ (#) A set of User Callbacks are provided:
+ (+) HAL_CEC_TxCpltCallback()
+ (+) HAL_CEC_RxCpltCallback()
+ (+) HAL_CEC_ErrorCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Send data in interrupt mode
+ * @param hcec CEC handle
+ * @param InitiatorAddress Initiator address
+ * @param DestinationAddress destination logical address
+ * @param pData pointer to input byte data buffer
+ * @param Size amount of data to be sent in bytes (without counting the header).
+ * 0 means only the header is sent (ping operation).
+ * Maximum TX size is 15 bytes (1 opcode and up to 14 operands).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress, uint8_t DestinationAddress,
+ uint8_t *pData, uint32_t Size)
+{
+ /* if the IP isn't already busy and if there is no previous transmission
+ already pending due to arbitration lost */
+ if (hcec->gState == HAL_CEC_STATE_READY)
+ {
+ if ((pData == NULL) && (Size > 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ assert_param(IS_CEC_ADDRESS(DestinationAddress));
+ assert_param(IS_CEC_ADDRESS(InitiatorAddress));
+ assert_param(IS_CEC_MSGSIZE(Size));
+
+ /* Process Locked */
+ __HAL_LOCK(hcec);
+ hcec->pTxBuffPtr = pData;
+ hcec->gState = HAL_CEC_STATE_BUSY_TX;
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+
+ /* initialize the number of bytes to send,
+ * 0 means only one header is sent (ping operation) */
+ hcec->TxXferCount = (uint16_t)Size;
+
+ /* in case of no payload (Size = 0), sender is only pinging the system;
+ Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */
+ if (Size == 0U)
+ {
+ __HAL_CEC_LAST_BYTE_TX_SET(hcec);
+ }
+
+ /* send header block */
+ hcec->Instance->TXDR = (uint32_t)(((uint32_t)InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress);
+
+ /* Set TX Start of Message (TXSOM) bit */
+ __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcec);
+
+ return HAL_OK;
+
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Get size of the received frame.
+ * @param hcec CEC handle
+ * @retval Frame size
+ */
+uint32_t HAL_CEC_GetLastReceivedFrameSize(CEC_HandleTypeDef *hcec)
+{
+ return hcec->RxXferSize;
+}
+
+/**
+ * @brief Change Rx Buffer.
+ * @param hcec CEC handle
+ * @param Rxbuffer Rx Buffer
+ * @note This function can be called only inside the HAL_CEC_RxCpltCallback()
+ * @retval Frame size
+ */
+void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t *Rxbuffer)
+{
+ hcec->Init.RxBuffer = Rxbuffer;
+}
+
+/**
+ * @brief This function handles CEC interrupt requests.
+ * @param hcec CEC handle
+ * @retval None
+ */
+void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec)
+{
+
+ /* save interrupts register for further error or interrupts handling purposes */
+ uint32_t reg;
+ reg = hcec->Instance->ISR;
+
+
+ /* ----------------------------Arbitration Lost Management----------------------------------*/
+ /* CEC TX arbitration error interrupt occurred --------------------------------------*/
+ if ((reg & CEC_FLAG_ARBLST) != 0U)
+ {
+ hcec->ErrorCode = HAL_CEC_ERROR_ARBLST;
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_ARBLST);
+ }
+
+ /* ----------------------------Rx Management----------------------------------*/
+ /* CEC RX byte received interrupt ---------------------------------------------------*/
+ if ((reg & CEC_FLAG_RXBR) != 0U)
+ {
+ /* reception is starting */
+ hcec->RxState = HAL_CEC_STATE_BUSY_RX;
+ hcec->RxXferSize++;
+ /* read received byte */
+ *hcec->Init.RxBuffer = (uint8_t) hcec->Instance->RXDR;
+ hcec->Init.RxBuffer++;
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR);
+ }
+
+ /* CEC RX end received interrupt ---------------------------------------------------*/
+ if ((reg & CEC_FLAG_RXEND) != 0U)
+ {
+ /* clear IT */
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXEND);
+
+ /* Rx process is completed, restore hcec->RxState to Ready */
+ hcec->RxState = HAL_CEC_STATE_READY;
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+ hcec->Init.RxBuffer -= hcec->RxXferSize;
+#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U)
+ hcec->RxCpltCallback(hcec, hcec->RxXferSize);
+#else
+ HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize);
+#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
+ hcec->RxXferSize = 0U;
+ }
+
+ /* ----------------------------Tx Management----------------------------------*/
+ /* CEC TX byte request interrupt ------------------------------------------------*/
+ if ((reg & CEC_FLAG_TXBR) != 0U)
+ {
+ if (hcec->TxXferCount == 0U)
+ {
+ /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */
+ __HAL_CEC_LAST_BYTE_TX_SET(hcec);
+ hcec->Instance->TXDR = *hcec->pTxBuffPtr;
+ hcec->pTxBuffPtr++;
+ }
+ else
+ {
+ hcec->Instance->TXDR = *hcec->pTxBuffPtr;
+ hcec->pTxBuffPtr++;
+ hcec->TxXferCount--;
+ }
+ /* clear Tx-Byte request flag */
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR);
+ }
+
+ /* CEC TX end interrupt ------------------------------------------------*/
+ if ((reg & CEC_FLAG_TXEND) != 0U)
+ {
+ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXEND);
+
+ /* Tx process is ended, restore hcec->gState to Ready */
+ hcec->gState = HAL_CEC_STATE_READY;
+ /* Call the Process Unlocked before calling the Tx call back API to give the possibility to
+ start again the Transmission under the Tx call back API */
+ __HAL_UNLOCK(hcec);
+ hcec->ErrorCode = HAL_CEC_ERROR_NONE;
+#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U)
+ hcec->TxCpltCallback(hcec);
+#else
+ HAL_CEC_TxCpltCallback(hcec);
+#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
+ }
+
+ /* ----------------------------Rx/Tx Error Management----------------------------------*/
+ if ((reg & (CEC_ISR_RXOVR | CEC_ISR_BRE | CEC_ISR_SBPE | CEC_ISR_LBPE | CEC_ISR_RXACKE | CEC_ISR_TXUDR | CEC_ISR_TXERR |
+ CEC_ISR_TXACKE)) != 0U)
+ {
+ hcec->ErrorCode = reg;
+ __HAL_CEC_CLEAR_FLAG(hcec, HAL_CEC_ERROR_RXOVR | HAL_CEC_ERROR_BRE | CEC_FLAG_LBPE | CEC_FLAG_SBPE |
+ HAL_CEC_ERROR_RXACKE | HAL_CEC_ERROR_TXUDR | HAL_CEC_ERROR_TXERR | HAL_CEC_ERROR_TXACKE);
+
+
+ if ((reg & (CEC_ISR_RXOVR | CEC_ISR_BRE | CEC_ISR_SBPE | CEC_ISR_LBPE | CEC_ISR_RXACKE)) != 0U)
+ {
+ hcec->Init.RxBuffer -= hcec->RxXferSize;
+ hcec->RxXferSize = 0U;
+ hcec->RxState = HAL_CEC_STATE_READY;
+ }
+ else if (((reg & CEC_ISR_ARBLST) == 0U) && ((reg & (CEC_ISR_TXUDR | CEC_ISR_TXERR | CEC_ISR_TXACKE)) != 0U))
+ {
+ /* Set the CEC state ready to be able to start again the process */
+ hcec->gState = HAL_CEC_STATE_READY;
+ }
+ else
+ {
+ /* Nothing todo*/
+ }
+#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U)
+ hcec->ErrorCallback(hcec);
+#else
+ /* Error Call Back */
+ HAL_CEC_ErrorCallback(hcec);
+#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Nothing todo*/
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callback
+ * @param hcec CEC handle
+ * @retval None
+ */
+__weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_TxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callback
+ * @param hcec CEC handle
+ * @param RxFrameSize Size of frame
+ * @retval None
+ */
+__weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ UNUSED(RxFrameSize);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_RxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief CEC error callbacks
+ * @param hcec CEC handle
+ * @retval None
+ */
+__weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcec);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CEC_ErrorCallback can be implemented in the user file
+ */
+}
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control function
+ * @brief CEC control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control function #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the CEC.
+ (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral.
+ (+) HAL_CEC_GetError() API can be helpful to check in run-time the error of the CEC peripheral.
+@endverbatim
+ * @{
+ */
+/**
+ * @brief return the CEC state
+ * @param hcec pointer to a CEC_HandleTypeDef structure that contains
+ * the configuration information for the specified CEC module.
+ * @retval HAL state
+ */
+HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec)
+{
+ uint32_t temp1, temp2;
+ temp1 = hcec->gState;
+ temp2 = hcec->RxState;
+
+ return (HAL_CEC_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+ * @brief Return the CEC error code
+ * @param hcec pointer to a CEC_HandleTypeDef structure that contains
+ * the configuration information for the specified CEC.
+ * @retval CEC Error Code
+ */
+uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec)
+{
+ return hcec->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif /* CEC */
+#endif /* HAL_CEC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_comp.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_comp.c
new file mode 100644
index 0000000000..8033926129
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_comp.c
@@ -0,0 +1,1250 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_comp.c
+ * @author MCD Application Team
+ * @brief COMP HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the COMP peripheral:
+ * + Initialization and de-initialization functions
+ * + Start/Stop operation functions in polling mode
+ * + Start/Stop operation functions in interrupt mode
+ * + Peripheral control functions
+ * + Peripheral state functions
+ @verbatim
+ ================================================================================
+ ##### COMP Peripheral features #####
+ ================================================================================
+
+ [..]
+ The STM32H7xx device family integrates two analog comparators instances
+ COMP1 and COMP2:
+ (#) The COMP input minus (inverting input) and input plus (non inverting input)
+ can be set to internal references or to GPIO pins
+ (refer to GPIO list in reference manual).
+
+ (#) The COMP output level is available using HAL_COMP_GetOutputLevel()
+ and can be redirected to other peripherals: GPIO pins (in mode
+ alternate functions for comparator), timers.
+ (refer to GPIO list in reference manual).
+
+ (#) Pairs of comparators instances can be combined in window mode
+ (2 consecutive instances odd and even COMP<x> and COMP<x+1>).
+
+ (#) The comparators have interrupt capability through the EXTI controller
+ with wake-up from sleep and stop modes:
+ (++) COMP1 is internally connected to EXTI Line 20
+ (++) COMP2 is internally connected to EXTI Line 21
+
+ [..]
+ From the corresponding IRQ handler, the right interrupt source can be retrieved
+ using macro __HAL_COMP_COMP1_EXTI_GET_FLAG() and __HAL_COMP_COMP2_EXTI_GET_FLAG().
+
+
+
+ ##### How to use this driver #####
+ ================================================================================
+ [..]
+ This driver provides functions to configure and program the comparator instances of
+ STM32H7xx devices.
+
+ To use the comparator, perform the following steps:
+
+ (#) Initialize the COMP low level resources by implementing the HAL_COMP_MspInit():
+ (++) Configure the GPIO connected to comparator inputs plus and minus in analog mode
+ using HAL_GPIO_Init().
+ (++) If needed, configure the GPIO connected to comparator output in alternate function mode
+ using HAL_GPIO_Init().
+ (++) If required enable the COMP interrupt by configuring and enabling EXTI line in Interrupt mode and
+ selecting the desired sensitivity level using HAL_GPIO_Init() function. After that enable the comparator
+ interrupt vector using HAL_NVIC_EnableIRQ() function.
+
+ (#) Configure the comparator using HAL_COMP_Init() function:
+ (++) Select the input minus (inverting input)
+ (++) Select the input plus (non-inverting input)
+ (++) Select the hysteresis
+ (++) Select the blanking source
+ (++) Select the output polarity
+ (++) Select the power mode
+ (++) Select the window mode
+ -@@- HAL_COMP_Init() calls internally __HAL_RCC_SYSCFG_CLK_ENABLE()
+ to enable internal control clock of the comparators.
+ However, this is a legacy strategy.
+ Therefore, for compatibility anticipation, it is recommended to
+ implement __HAL_RCC_SYSCFG_CLK_ENABLE() in "HAL_COMP_MspInit()".
+ In STM32H7,COMP clock enable __HAL_RCC_COMP12_CLK_ENABLE() must
+ be implemented by user in "HAL_COMP_MspInit()".
+ (#) Reconfiguration on-the-fly of comparator can be done by calling again
+ function HAL_COMP_Init() with new input structure parameters values.
+
+ (#) Enable the comparator using HAL_COMP_Start() or HAL_COMP_Start_IT()to be enabled
+ with the interrupt through NVIC of the CPU.
+ Note: HAL_COMP_Start_IT() must be called after each interrupt otherwise the interrupt
+ mode will stay disabled.
+
+ (#) Use HAL_COMP_GetOutputLevel() or HAL_COMP_TriggerCallback()
+ functions to manage comparator outputs(output level or events)
+
+ (#) Disable the comparator using HAL_COMP_Stop() or HAL_COMP_Stop_IT()
+ to disable the interrupt too.
+
+ (#) De-initialize the comparator using HAL_COMP_DeInit() function.
+
+ (#) For safety purpose, comparator configuration can be locked using HAL_COMP_Lock() function.
+ The only way to unlock the comparator is a device hardware reset.
+
+ *** Callback registration ***
+ =============================================
+ [..]
+
+ The compilation flag USE_HAL_COMP_REGISTER_CALLBACKS, when set to 1,
+ allows the user to configure dynamically the driver callbacks.
+ Use Functions @ref HAL_COMP_RegisterCallback()
+ to register an interrupt callback.
+ [..]
+
+ Function @ref HAL_COMP_RegisterCallback() allows to register following callbacks:
+ (+) TriggerCallback : callback for COMP trigger.
+ (+) MspInitCallback : callback for Msp Init.
+ (+) MspDeInitCallback : callback for Msp DeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+ [..]
+
+ Use function @ref HAL_COMP_UnRegisterCallback to reset a callback to the default
+ weak function.
+ [..]
+
+ @ref HAL_COMP_UnRegisterCallback takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) TriggerCallback : callback for COMP trigger.
+ (+) MspInitCallback : callback for Msp Init.
+ (+) MspDeInitCallback : callback for Msp DeInit.
+ [..]
+
+ By default, after the @ref HAL_COMP_Init() and when the state is @ref HAL_COMP_STATE_RESET
+ all callbacks are set to the corresponding weak functions:
+ example @ref HAL_COMP_TriggerCallback().
+ Exception done for MspInit and MspDeInit functions that are
+ reset to the legacy weak functions in the @ref HAL_COMP_Init()/ @ref HAL_COMP_DeInit() only when
+ these callbacks are null (not registered beforehand).
+ [..]
+
+ If MspInit or MspDeInit are not null, the @ref HAL_COMP_Init()/ @ref HAL_COMP_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
+ [..]
+
+ Callbacks can be registered/unregistered in @ref HAL_COMP_STATE_READY state only.
+ Exception done MspInit/MspDeInit functions that can be registered/unregistered
+ in @ref HAL_COMP_STATE_READY or @ref HAL_COMP_STATE_RESET state,
+ thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
+ [..]
+
+ Then, the user first registers the MspInit/MspDeInit user callbacks
+ using @ref HAL_COMP_RegisterCallback() before calling @ref HAL_COMP_DeInit()
+ or @ref HAL_COMP_Init() function.
+ [..]
+
+ When the compilation flag USE_HAL_COMP_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registration feature is not available and all callbacks
+ are set to the corresponding weak functions.
+
+ @endverbatim
+ ******************************************************************************
+
+ Table 1. COMP inputs and output for STM32H7xx devices
+ +---------------------------------------------------------+
+ | | | COMP1 | COMP2 |
+ |----------------|----------------|-----------|-----------|
+ | | IO1 | PB0 | PE9 |
+ | Input plus | IO2 | PB2 | PE11 |
+ | | | | |
+ |----------------|----------------|-----------------------|
+ | | 1/4 VrefInt | Available | Available |
+ | | 1/2 VrefInt | Available | Available |
+ | | 3/4 VrefInt | Available | Available |
+ | Input minus | VrefInt | Available | Available |
+ | | DAC1 channel 1 | Available | Available |
+ | | DAC1 channel 2 | Available | Available |
+ | | IO1 | PB1 | PE10 |
+ | | IO2 | PC4 | PE7 |
+ | | | | |
+ | | | | |
+ | | | | |
+ +---------------------------------------------------------+
+ | Output | | PC5 (1) | PE8 (1) |
+ | | | PE12 (1) | PE13 (1) |
+ | | | TIM (2) | TIM (2) |
+ +---------------------------------------------------------+
+ (1) GPIO must be set to alternate function for comparator
+ (2) Comparators output to timers is set in timers instances.
+
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup COMP COMP
+ * @brief COMP HAL module driver
+ * @{
+ */
+
+#ifdef HAL_COMP_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup COMP_Private_Constants
+ * @{
+ */
+
+/* Delay for COMP startup time. */
+/* Note: Delay required to reach propagation delay specification. */
+/* Literal set to maximum value (refer to device datasheet, */
+/* parameter "tSTART"). */
+/* Unit: us */
+#define COMP_DELAY_STARTUP_US (80UL) /*!< Delay for COMP startup time */
+
+/* Delay for COMP voltage scaler stabilization time. */
+/* Literal set to maximum value (refer to device datasheet, */
+/* parameter "tSTART_SCALER"). */
+/* Unit: us */
+#define COMP_DELAY_VOLTAGE_SCALER_STAB_US (200UL) /*!< Delay for COMP voltage scaler stabilization time */
+
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup COMP_Exported_Functions COMP Exported Functions
+ * @{
+ */
+
+/** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions
+ * @brief Initialization and de-initialization functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions to initialize and de-initialize comparators
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the COMP according to the specified
+ * parameters in the COMP_InitTypeDef and initialize the associated handle.
+ * @note If the selected comparator is locked, initialization can't be performed.
+ * To unlock the configuration, perform a system reset.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
+{
+ uint32_t tmp_csr ;
+ uint32_t exti_line ;
+ uint32_t comp_voltage_scaler_initialized; /* Value "0" is comparator voltage scaler is not initialized */
+ __IO uint32_t wait_loop_index = 0UL;
+
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the COMP handle allocation and lock status */
+ if(hcomp == NULL)
+ {
+ status = HAL_ERROR;
+ }
+ else if(__HAL_COMP_IS_LOCKED(hcomp))
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameters */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+ assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.NonInvertingInput));
+ assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InvertingInput));
+ assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
+ assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
+ assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis));
+ assert_param(IS_COMP_BLANKINGSRCE(hcomp->Init.BlankingSrce));
+ assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
+ assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
+
+ if(hcomp->State == HAL_COMP_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcomp->Lock = HAL_UNLOCKED;
+
+ /* Set COMP error code to none */
+ COMP_CLEAR_ERRORCODE(hcomp);
+
+#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
+ /* Init the COMP Callback settings */
+ hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
+
+ if (hcomp->MspInitCallback == NULL)
+ {
+ hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
+ }
+
+ /* Init the low level hardware */
+ hcomp->MspInitCallback(hcomp);
+#else
+ /* Init the low level hardware */
+ HAL_COMP_MspInit(hcomp);
+#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
+ }
+ /* Memorize voltage scaler state before initialization */
+ comp_voltage_scaler_initialized = READ_BIT(hcomp->Instance->CFGR, COMP_CFGRx_SCALEN);
+
+ /* Set COMP parameters */
+ /* Set INMSEL bits according to hcomp->Init.InvertingInput value */
+ /* Set INPSEL bits according to hcomp->Init.NonInvertingInput value */
+ /* Set BLANKING bits according to hcomp->Init.BlankingSrce value */
+ /* Set HYST bits according to hcomp->Init.Hysteresis value */
+ /* Set POLARITY bit according to hcomp->Init.OutputPol value */
+ /* Set POWERMODE bits according to hcomp->Init.Mode value */
+
+ tmp_csr = (hcomp->Init.InvertingInput | \
+ hcomp->Init.NonInvertingInput | \
+ hcomp->Init.BlankingSrce | \
+ hcomp->Init.Hysteresis | \
+ hcomp->Init.OutputPol | \
+ hcomp->Init.Mode );
+
+ /* Set parameters in COMP register */
+ /* Note: Update all bits except read-only, lock and enable bits */
+#if defined (COMP_CFGRx_INP2SEL)
+ MODIFY_REG(hcomp->Instance->CFGR,
+ COMP_CFGRx_PWRMODE | COMP_CFGRx_INMSEL | COMP_CFGRx_INPSEL |
+ COMP_CFGRx_INP2SEL | COMP_CFGRx_WINMODE | COMP_CFGRx_POLARITY | COMP_CFGRx_HYST |
+ COMP_CFGRx_BLANKING | COMP_CFGRx_BRGEN | COMP_CFGRx_SCALEN,
+ tmp_csr
+ );
+#else
+ MODIFY_REG(hcomp->Instance->CFGR,
+ COMP_CFGRx_PWRMODE | COMP_CFGRx_INMSEL | COMP_CFGRx_INPSEL |
+ COMP_CFGRx_WINMODE | COMP_CFGRx_POLARITY | COMP_CFGRx_HYST |
+ COMP_CFGRx_BLANKING | COMP_CFGRx_BRGEN | COMP_CFGRx_SCALEN,
+ tmp_csr
+ );
+#endif
+ /* Set window mode */
+ /* Note: Window mode bit is located into 1 out of the 2 pairs of COMP */
+ /* instances. Therefore, this function can update another COMP */
+ /* instance that the one currently selected. */
+ if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
+ {
+ SET_BIT(hcomp->Instance->CFGR, COMP_CFGRx_WINMODE);
+ }
+ else
+ {
+ CLEAR_BIT(hcomp->Instance->CFGR, COMP_CFGRx_WINMODE);
+ }
+ /* Delay for COMP scaler bridge voltage stabilization */
+ /* Apply the delay if voltage scaler bridge is enabled for the first time */
+ if ((READ_BIT(hcomp->Instance->CFGR, COMP_CFGRx_SCALEN) != 0UL) &&
+ (comp_voltage_scaler_initialized != 0UL) )
+ {
+ /* Wait loop initialization and execution */
+ /* Note: Variable divided by 2 to compensate partially */
+ /* CPU processing cycles.*/
+
+ wait_loop_index = (COMP_DELAY_VOLTAGE_SCALER_STAB_US * (SystemCoreClock / (1000000UL * 2UL)));
+
+ while(wait_loop_index != 0UL)
+ {
+ wait_loop_index --;
+ }
+ }
+
+ /* Get the EXTI line corresponding to the selected COMP instance */
+ exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
+
+ /* Manage EXTI settings */
+ if((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != 0UL)
+ {
+ /* Configure EXTI rising edge */
+ if((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != 0UL)
+ {
+ SET_BIT(EXTI->RTSR1, exti_line);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->RTSR1, exti_line);
+ }
+
+ /* Configure EXTI falling edge */
+ if((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != 0UL)
+ {
+ SET_BIT(EXTI->FTSR1, exti_line);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->FTSR1, exti_line);
+ }
+
+#if !defined (CORE_CM4)
+ /* Clear COMP EXTI pending bit (if any) */
+ WRITE_REG(EXTI->PR1, exti_line);
+
+ /* Configure EXTI event mode */
+ if((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != 0UL)
+ {
+ SET_BIT(EXTI->EMR1, exti_line);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->EMR1, exti_line);
+ }
+
+ /* Configure EXTI interrupt mode */
+ if((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
+ {
+ SET_BIT(EXTI->IMR1, exti_line);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->IMR1, exti_line);
+ }
+ }
+ else
+ {
+ /* Disable EXTI event mode */
+ CLEAR_BIT(EXTI->EMR1, exti_line);
+
+ /* Disable EXTI interrupt mode */
+ CLEAR_BIT(EXTI->IMR1, exti_line);
+ }
+#else
+ /* Clear COMP EXTI pending bit (if any) */
+ WRITE_REG(EXTI->C2PR1, exti_line);
+
+ /* Configure EXTI event mode */
+ if((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != 0UL)
+ {
+ SET_BIT(EXTI->C2EMR1, exti_line);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->C2EMR1, exti_line);
+ }
+
+ /* Configure EXTI interrupt mode */
+ if((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
+ {
+ SET_BIT(EXTI->C2IMR1, exti_line);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->C2IMR1, exti_line);
+ }
+ }
+ else
+ {
+ /* Disable EXTI event mode */
+ CLEAR_BIT(EXTI->C2EMR1, exti_line);
+
+ /* Disable EXTI interrupt mode */
+ CLEAR_BIT(EXTI->C2IMR1, exti_line);
+ }
+#endif
+ /* Set HAL COMP handle state */
+ /* Note: Transition from state reset to state ready, */
+ /* otherwise (coming from state ready or busy) no state update. */
+ if (hcomp->State == HAL_COMP_STATE_RESET)
+ {
+
+ hcomp->State = HAL_COMP_STATE_READY;
+ }
+
+ }
+
+ return status;
+}
+
+/**
+ * @brief DeInitialize the COMP peripheral.
+ * @note Deinitialization cannot be performed if the COMP configuration is locked.
+ * To unlock the configuration, perform a system reset.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the COMP handle allocation and lock status */
+ if(hcomp == NULL)
+ {
+ status = HAL_ERROR;
+ }
+ else if(__HAL_COMP_IS_LOCKED(hcomp))
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+
+ /* Set COMP_CFGR register to reset value */
+ WRITE_REG(hcomp->Instance->CFGR, 0x00000000UL);
+
+#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
+ if (hcomp->MspDeInitCallback == NULL)
+ {
+ hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
+ }
+
+ /* DeInit the low level hardware */
+ hcomp->MspDeInitCallback(hcomp);
+#else
+ /* DeInit the low level hardware */
+ HAL_COMP_MspDeInit(hcomp);
+#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
+
+ /* Set HAL COMP handle state */
+ hcomp->State = HAL_COMP_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcomp);
+ }
+
+ return status;
+}
+
+/**
+ * @brief Initialize the COMP MSP.
+ * @param hcomp COMP handle
+ * @retval None
+ */
+__weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcomp);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_COMP_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitialize the COMP MSP.
+ * @param hcomp COMP handle
+ * @retval None
+ */
+__weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcomp);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_COMP_MspDeInit could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User COMP Callback
+ * To be used instead of the weak predefined callback
+ * @param hcomp Pointer to a COMP_HandleTypeDef structure that contains
+ * the configuration information for the specified COMP.
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
+ * @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, pCOMP_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+
+ if (HAL_COMP_STATE_READY == hcomp->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_COMP_TRIGGER_CB_ID :
+ hcomp->TriggerCallback = pCallback;
+ break;
+
+ case HAL_COMP_MSPINIT_CB_ID :
+ hcomp->MspInitCallback = pCallback;
+ break;
+
+ case HAL_COMP_MSPDEINIT_CB_ID :
+ hcomp->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_COMP_STATE_RESET == hcomp->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_COMP_MSPINIT_CB_ID :
+ hcomp->MspInitCallback = pCallback;
+ break;
+
+ case HAL_COMP_MSPDEINIT_CB_ID :
+ hcomp->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister a COMP Callback
+ * COMP callback is redirected to the weak predefined callback
+ * @param hcomp Pointer to a COMP_HandleTypeDef structure that contains
+ * the configuration information for the specified COMP.
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
+ * @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (HAL_COMP_STATE_READY == hcomp->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_COMP_TRIGGER_CB_ID :
+ hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
+ break;
+
+ case HAL_COMP_MSPINIT_CB_ID :
+ hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_COMP_MSPDEINIT_CB_ID :
+ hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_COMP_STATE_RESET == hcomp->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_COMP_MSPINIT_CB_ID :
+ hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_COMP_MSPDEINIT_CB_ID :
+ hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
+ * @brief Start-Stop operation functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Start a Comparator instance without interrupt.
+ (+) Stop a Comparator instance without interrupt.
+ (+) Start a Comparator instance with interrupt generation.
+ (+) Stop a Comparator instance with interrupt generation.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Start the comparator.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
+{
+ __IO uint32_t wait_loop_index = 0UL;
+
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the COMP handle allocation and lock status */
+ if(hcomp == NULL)
+ {
+ status = HAL_ERROR;
+ }
+ else if(__HAL_COMP_IS_LOCKED(hcomp))
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+
+ if(hcomp->State == HAL_COMP_STATE_READY)
+ {
+ /* Enable the selected comparator */
+ SET_BIT(hcomp->Instance->CFGR, COMP_CFGRx_EN);
+
+ /* Set HAL COMP handle state */
+ hcomp->State = HAL_COMP_STATE_BUSY;
+
+ /* Delay for COMP startup time */
+ /* Wait loop initialization and execution */
+ /* Note: Variable divided by 2 to compensate partially */
+ /* CPU processing cycles. */
+
+ wait_loop_index = (COMP_DELAY_STARTUP_US * (SystemCoreClock / (1000000UL * 2UL)));
+ while(wait_loop_index != 0UL)
+ {
+ wait_loop_index--;
+ }
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Stop the comparator.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the COMP handle allocation and lock status */
+ if(hcomp == NULL)
+ {
+ status = HAL_ERROR;
+ }
+ else if(__HAL_COMP_IS_LOCKED(hcomp))
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+
+ /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY */
+ /* (all states except HAL_COMP_STATE_RESET and except locked status. */
+ if(hcomp->State != HAL_COMP_STATE_RESET)
+ {
+
+ /* Disable the selected comparator */
+ CLEAR_BIT(hcomp->Instance->CFGR, COMP_CFGRx_EN);
+
+ /* Set HAL COMP handle state */
+ hcomp->State = HAL_COMP_STATE_READY;
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Enable the interrupt and start the comparator.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_Start_IT(COMP_HandleTypeDef *hcomp)
+{
+
+ __IO uint32_t wait_loop_index = 0UL;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the COMP handle allocation and lock status */
+ if(hcomp == NULL)
+ {
+ status = HAL_ERROR;
+ }
+ else if(__HAL_COMP_IS_LOCKED(hcomp))
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+ /* Set HAL COMP handle state */
+ if(hcomp->State == HAL_COMP_STATE_READY)
+ {
+
+ /* Enable the selected comparator */
+ SET_BIT(hcomp->Instance->CFGR, COMP_CFGRx_EN);
+ /* Enable the Interrupt comparator */
+ SET_BIT(hcomp->Instance->CFGR, COMP_CFGRx_ITEN);
+
+ hcomp->State = HAL_COMP_STATE_BUSY;
+ /* Delay for COMP startup time */
+ /* Wait loop initialization and execution */
+ /* Note: Variable divided by 2 to compensate partially */
+ /* CPU processing cycles. */
+
+ wait_loop_index = (COMP_DELAY_STARTUP_US * (SystemCoreClock / (1000000UL * 2UL)));
+ while(wait_loop_index != 0UL)
+ {
+ wait_loop_index--;
+ }
+
+ }
+ else
+ {
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Disable the interrupt and Stop the comparator.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_Stop_IT(COMP_HandleTypeDef *hcomp)
+{
+ HAL_StatusTypeDef status;
+ /* Disable the EXTI Line interrupt mode */
+#if !defined (CORE_CM4)
+ CLEAR_BIT(EXTI->IMR1, COMP_GET_EXTI_LINE(hcomp->Instance));
+#else
+ CLEAR_BIT(EXTI->C2IMR1, COMP_GET_EXTI_LINE(hcomp->Instance));
+#endif
+ /* Disable the Interrupt comparator */
+ CLEAR_BIT(hcomp->Instance->CFGR, COMP_CFGRx_ITEN);
+
+ status = HAL_COMP_Stop(hcomp);
+
+ return status;
+
+}
+
+/**
+ * @brief Comparator IRQ Handler.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
+{
+ /* Get the EXTI line corresponding to the selected COMP instance */
+ uint32_t exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
+
+
+#if defined(DUAL_CORE)
+ /* EXTI line interrupt detected */
+ if (HAL_GetCurrentCPUID() == CM7_CPUID)
+ {
+ /* Check COMP EXTI flag */
+ if(READ_BIT(EXTI->PR1, exti_line) != 0UL)
+ {
+ /* Check whether comparator is in independent or window mode */
+ if(READ_BIT(COMP12_COMMON->CFGR, COMP_CFGRx_WINMODE) != 0UL)
+ {
+ /* Clear COMP EXTI line pending bit of the pair of comparators */
+ /* in window mode. */
+ /* Note: Pair of comparators in window mode can both trig IRQ when */
+ /* input voltage is changing from "out of window" area */
+ /* (low or high ) to the other "out of window" area (high or low).*/
+ /* Both flags must be cleared to call comparator trigger */
+ /* callback is called once. */
+ WRITE_REG(EXTI->PR1, (COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
+ }
+ else
+ {
+ /* Clear COMP EXTI line pending bit */
+ WRITE_REG(EXTI->PR1, exti_line);
+ }
+
+ /* COMP trigger user callback */
+#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
+ hcomp->TriggerCallback(hcomp);
+#else
+ HAL_COMP_TriggerCallback(hcomp);
+#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
+ }
+
+
+ }
+ else
+ {
+ /* Check COMP EXTI flag */
+ if(READ_BIT(EXTI->C2PR1, exti_line) != 0UL)
+ {
+ /* Check whether comparator is in independent or window mode */
+ if(READ_BIT(COMP12_COMMON->CFGR, COMP_CFGRx_WINMODE) != 0UL)
+ {
+ /* Clear COMP EXTI line pending bit of the pair of comparators */
+ /* in window mode. */
+ /* Note: Pair of comparators in window mode can both trig IRQ when */
+ /* input voltage is changing from "out of window" area */
+ /* (low or high ) to the other "out of window" area (high or low).*/
+ /* Both flags must be cleared to call comparator trigger */
+ /* callback is called once. */
+ WRITE_REG(EXTI->C2PR1, (COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
+ }
+ else
+ {
+ /* Clear COMP EXTI line pending bit */
+ WRITE_REG(EXTI->C2PR1, exti_line);
+ }
+
+ /* COMP trigger user callback */
+#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
+ hcomp->TriggerCallback(hcomp);
+#else
+ HAL_COMP_TriggerCallback(hcomp);
+#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
+ }
+
+
+ }
+#else
+ /* Check COMP EXTI flag */
+ if(READ_BIT(EXTI->PR1, exti_line) != 0UL)
+ {
+ /* Check whether comparator is in independent or window mode */
+ if(READ_BIT(COMP12_COMMON->CFGR, COMP_CFGRx_WINMODE) != 0UL)
+ {
+ /* Clear COMP EXTI line pending bit of the pair of comparators */
+ /* in window mode. */
+ /* Note: Pair of comparators in window mode can both trig IRQ when */
+ /* input voltage is changing from "out of window" area */
+ /* (low or high ) to the other "out of window" area (high or low).*/
+ /* Both flags must be cleared to call comparator trigger */
+ /* callback is called once. */
+ WRITE_REG(EXTI->PR1, (COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
+ }
+ else
+ {
+ /* Clear COMP EXTI line pending bit */
+ WRITE_REG(EXTI->PR1, exti_line);
+ }
+
+ /* COMP trigger user callback */
+#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
+ hcomp->TriggerCallback(hcomp);
+#else
+ HAL_COMP_TriggerCallback(hcomp);
+#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
+ }
+#endif /*DUAL_CORE*/
+
+ /* Get COMP interrupt source */
+ if (__HAL_COMP_GET_IT_SOURCE(hcomp, COMP_IT_EN) != RESET)
+ {
+
+ if((__HAL_COMP_GET_FLAG( COMP_FLAG_C1I)) != 0UL)
+ {
+ /* Clear the COMP channel 1 interrupt flag */
+ __HAL_COMP_CLEAR_C1IFLAG();
+
+ /* Disable COMP interrupt */
+ __HAL_COMP_DISABLE_IT(hcomp,COMP_IT_EN);
+
+ }
+ if((__HAL_COMP_GET_FLAG( COMP_FLAG_C2I)) != 0UL)
+ {
+ /* Clear the COMP channel 2 interrupt flag */
+ __HAL_COMP_CLEAR_C2IFLAG();
+
+ /* Disable COMP interrupt */
+ __HAL_COMP_DISABLE_IT(hcomp,COMP_IT_EN);
+
+ }
+
+ /* Change COMP state */
+ hcomp->State = HAL_COMP_STATE_READY;
+
+ /* COMP trigger user callback */
+#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
+ hcomp->TriggerCallback(hcomp);
+#else
+ HAL_COMP_TriggerCallback(hcomp);
+#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
+ }
+
+
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
+ * @brief Management functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the comparators.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Lock the selected comparator configuration.
+ * @note A system reset is required to unlock the comparator configuration.
+ * @param hcomp COMP handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the COMP handle allocation and lock status */
+ if(hcomp == NULL)
+ {
+ status = HAL_ERROR;
+ }
+ else if(__HAL_COMP_IS_LOCKED(hcomp))
+ {
+ status = HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+
+ /* Set HAL COMP handle state */
+ switch(hcomp->State)
+ {
+ case HAL_COMP_STATE_RESET:
+ hcomp->State = HAL_COMP_STATE_RESET_LOCKED;
+ break;
+ case HAL_COMP_STATE_READY:
+ hcomp->State = HAL_COMP_STATE_READY_LOCKED;
+ break;
+ default: /* HAL_COMP_STATE_BUSY */
+ hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
+ break;
+ }
+ }
+
+ if(status == HAL_OK)
+ {
+ /* Set the lock bit corresponding to selected comparator */
+ __HAL_COMP_LOCK(hcomp);
+ }
+
+ return status;
+}
+
+/**
+ * @brief Return the output level (high or low) of the selected comparator.
+ * @note The output level depends on the selected polarity.
+ * If the polarity is not inverted:
+ * - Comparator output is low when the input plus is at a lower
+ * voltage than the input minus
+ * - Comparator output is high when the input plus is at a higher
+ * voltage than the input minus
+ * If the polarity is inverted:
+ * - Comparator output is high when the input plus is at a lower
+ * voltage than the input minus
+ * - Comparator output is low when the input plus is at a higher
+ * voltage than the input minus
+ * @param hcomp COMP handle
+ * @retval Returns the selected comparator output level:
+ * @arg @ref COMP_OUTPUT_LEVEL_LOW
+ * @arg @ref COMP_OUTPUT_LEVEL_HIGH
+ *
+ */
+uint32_t HAL_COMP_GetOutputLevel(COMP_HandleTypeDef *hcomp)
+{
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+
+ if (hcomp->Instance == COMP1)
+ {
+ return (uint32_t)(READ_BIT(COMP12->SR, COMP_SR_C1VAL));
+ }
+ else
+ {
+ return (uint32_t)((READ_BIT(COMP12->SR, COMP_SR_C2VAL))>> 1UL);
+ }
+}
+
+/**
+ * @brief Comparator trigger callback.
+ * @param hcomp COMP handle
+ * @retval None
+ */
+__weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcomp);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_COMP_TriggerCallback should be implemented in the user file
+ */
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection permit to get in run-time the status of the peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the COMP handle state.
+ * @param hcomp COMP handle
+ * @retval HAL state
+ */
+HAL_COMP_StateTypeDef HAL_COMP_GetState(COMP_HandleTypeDef *hcomp)
+{
+ /* Check the COMP handle allocation */
+ if(hcomp == NULL)
+ {
+ return HAL_COMP_STATE_RESET;
+ }
+
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+
+ /* Return HAL COMP handle state */
+ return hcomp->State;
+}
+
+/**
+ * @brief Return the COMP error code.
+ * @param hcomp COMP handle
+ * @retval COMP error code
+ */
+uint32_t HAL_COMP_GetError(COMP_HandleTypeDef *hcomp)
+{
+ /* Check the parameters */
+ assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
+
+ return hcomp->ErrorCode;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_COMP_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_cortex.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_cortex.c
new file mode 100644
index 0000000000..631f432f7e
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_cortex.c
@@ -0,0 +1,533 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_cortex.c
+ * @author MCD Application Team
+ * @brief CORTEX HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the CORTEX:
+ * + Initialization and de-initialization functions
+ * + Peripheral Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+
+ [..]
+ *** How to configure Interrupts using CORTEX HAL driver ***
+ ===========================================================
+ [..]
+ This section provides functions allowing to configure the NVIC interrupts (IRQ).
+ The Cortex-M exceptions are managed by CMSIS functions.
+
+ (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
+ function according to the following table.
+ (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
+ (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
+ (#) please refer to programming manual for details in how to configure priority.
+
+ -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible.
+ The pending IRQ priority will be managed only by the sub priority.
+
+ -@- IRQ priority order (sorted by highest to lowest priority):
+ (+@) Lowest preemption priority
+ (+@) Lowest sub priority
+ (+@) Lowest hardware priority (IRQ number)
+
+ [..]
+ *** How to configure Systick using CORTEX HAL driver ***
+ ========================================================
+ [..]
+ Setup SysTick Timer for time base.
+
+ (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
+ is a CMSIS function that:
+ (++) Configures the SysTick Reload register with value passed as function parameter.
+ (++) Configures the SysTick IRQ priority to the lowest value (0x0F).
+ (++) Resets the SysTick Counter register.
+ (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
+ (++) Enables the SysTick Interrupt.
+ (++) Starts the SysTick Counter.
+
+ (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
+ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
+ HAL_SYSTICK_Config() function call. The HAL_SYSTICK_CLKSourceConfig() macro is defined
+ inside the stm32h7xx_hal_cortex.h file.
+
+ (+) You can change the SysTick IRQ priority by calling the
+ HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
+ call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
+
+ (+) To adjust the SysTick time base, use the following formula:
+
+ Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
+ (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
+ (++) Reload Value should not exceed 0xFFFFFF
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CORTEX CORTEX
+ * @brief CORTEX HAL module driver
+ * @{
+ */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
+ * @{
+ */
+
+
+/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provides the CORTEX HAL driver functions allowing to configure Interrupts
+ Systick functionalities
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Sets the priority grouping field (preemption priority and subpriority)
+ * using the required unlock sequence.
+ * @param PriorityGroup The priority grouping bits length.
+ * This parameter can be one of the following values:
+ * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
+ * 4 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
+ * 3 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
+ * 2 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
+ * 1 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
+ * 0 bits for subpriority
+ * @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
+ * The pending IRQ priority will be managed only by the subpriority.
+ * @retval None
+ */
+void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
+
+ /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
+ NVIC_SetPriorityGrouping(PriorityGroup);
+}
+
+/**
+ * @brief Sets the priority of an interrupt.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @param PreemptPriority The preemption priority for the IRQn channel.
+ * This parameter can be a value between 0 and 15
+ * A lower priority value indicates a higher priority
+ * @param SubPriority the subpriority level for the IRQ channel.
+ * This parameter can be a value between 0 and 15
+ * A lower priority value indicates a higher priority.
+ * @retval None
+ */
+void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t prioritygroup;
+
+ /* Check the parameters */
+ assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
+ assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
+
+ prioritygroup = NVIC_GetPriorityGrouping();
+
+ NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
+}
+
+/**
+ * @brief Enables a device specific interrupt in the NVIC interrupt controller.
+ * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
+ * function should be called before.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @retval None
+ */
+void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Enable interrupt */
+ NVIC_EnableIRQ(IRQn);
+}
+
+/**
+ * @brief Disables a device specific interrupt in the NVIC interrupt controller.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @retval None
+ */
+void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Disable interrupt */
+ NVIC_DisableIRQ(IRQn);
+}
+
+/**
+ * @brief Initiates a system reset request to reset the MCU.
+ * @retval None
+ */
+void HAL_NVIC_SystemReset(void)
+{
+ /* System Reset */
+ NVIC_SystemReset();
+}
+
+/**
+ * @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ * Counter is in free running mode to generate periodic interrupts.
+ * @param TicksNumb Specifies the ticks Number of ticks between two interrupts.
+ * @retval status - 0 Function succeeded.
+ * - 1 Function failed.
+ */
+uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
+{
+ return SysTick_Config(TicksNumb);
+}
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
+ * @brief Cortex control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the CORTEX
+ (NVIC, SYSTICK, MPU) functionalities.
+
+
+@endverbatim
+ * @{
+ */
+#if (__MPU_PRESENT == 1)
+/**
+ * @brief Disables the MPU
+ * @retval None
+ */
+void HAL_MPU_Disable(void)
+{
+ /* Make sure outstanding transfers are done */
+ __DMB();
+
+ /* Disable fault exceptions */
+ SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
+
+ /* Disable the MPU and clear the control register*/
+ MPU->CTRL = 0;
+}
+
+/**
+ * @brief Enables the MPU
+ * @param MPU_Control Specifies the control mode of the MPU during hard fault,
+ * NMI, FAULTMASK and privileged access to the default memory
+ * This parameter can be one of the following values:
+ * @arg MPU_HFNMI_PRIVDEF_NONE
+ * @arg MPU_HARDFAULT_NMI
+ * @arg MPU_PRIVILEGED_DEFAULT
+ * @arg MPU_HFNMI_PRIVDEF
+ * @retval None
+ */
+void HAL_MPU_Enable(uint32_t MPU_Control)
+{
+ /* Enable the MPU */
+ MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
+
+ /* Enable fault exceptions */
+ SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
+
+ /* Ensure MPU setting take effects */
+ __DSB();
+ __ISB();
+}
+/**
+ * @brief Initializes and configures the Region and the memory to be protected.
+ * @param MPU_Init Pointer to a MPU_Region_InitTypeDef structure that contains
+ * the initialization and configuration information.
+ * @retval None
+ */
+void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
+{
+ /* Check the parameters */
+ assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
+ assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
+
+ /* Set the Region number */
+ MPU->RNR = MPU_Init->Number;
+
+ if ((MPU_Init->Enable) != 0UL)
+ {
+ /* Check the parameters */
+ assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
+ assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
+ assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
+ assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
+ assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
+ assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
+ assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
+ assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
+
+ MPU->RBAR = MPU_Init->BaseAddress;
+ MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
+ ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
+ ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
+ ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
+ ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
+ ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
+ ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
+ ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
+ ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
+ }
+ else
+ {
+ MPU->RBAR = 0x00;
+ MPU->RASR = 0x00;
+ }
+}
+#endif /* __MPU_PRESENT */
+
+/**
+ * @brief Gets the priority grouping field from the NVIC Interrupt Controller.
+ * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
+ */
+uint32_t HAL_NVIC_GetPriorityGrouping(void)
+{
+ /* Get the PRIGROUP[10:8] field value */
+ return NVIC_GetPriorityGrouping();
+}
+
+/**
+ * @brief Gets the priority of an interrupt.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @param PriorityGroup the priority grouping bits length.
+ * This parameter can be one of the following values:
+ * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
+ * 4 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
+ * 3 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
+ * 2 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
+ * 1 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
+ * 0 bits for subpriority
+ * @param pPreemptPriority Pointer on the Preemptive priority value (starting from 0).
+ * @param pSubPriority Pointer on the Subpriority value (starting from 0).
+ * @retval None
+ */
+void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
+ /* Get priority for Cortex-M system or device specific interrupts */
+ NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
+}
+
+/**
+ * @brief Sets Pending bit of an external interrupt.
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @retval None
+ */
+void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Set interrupt pending */
+ NVIC_SetPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Gets Pending Interrupt (reads the pending register in the NVIC
+ * and returns the pending bit for the specified interrupt).
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @retval status - 0 Interrupt status is not pending.
+ * - 1 Interrupt status is pending.
+ */
+uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Return 1 if pending else 0 */
+ return NVIC_GetPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Clears the pending bit of an external interrupt.
+ * @param IRQn External interrupt number.
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @retval None
+ */
+void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Clear pending interrupt */
+ NVIC_ClearPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32h7xxxx.h))
+ * @retval status - 0 Interrupt status is not pending.
+ * - 1 Interrupt status is pending.
+ */
+uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Return 1 if active else 0 */
+ return NVIC_GetActive(IRQn);
+}
+
+/**
+ * @brief Configures the SysTick clock source.
+ * @param CLKSource specifies the SysTick clock source.
+ * This parameter can be one of the following values:
+ * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
+ * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
+ * @retval None
+ */
+void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
+ if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
+ {
+ SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
+ }
+ else
+ {
+ SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
+ }
+}
+
+/**
+ * @brief This function handles SYSTICK interrupt request.
+ * @retval None
+ */
+void HAL_SYSTICK_IRQHandler(void)
+{
+ HAL_SYSTICK_Callback();
+}
+
+/**
+ * @brief SYSTICK callback.
+ * @retval None
+ */
+__weak void HAL_SYSTICK_Callback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SYSTICK_Callback could be implemented in the user file
+ */
+}
+
+#if defined(DUAL_CORE)
+
+/**
+ * @brief Returns the current CPU ID.
+ * @retval CPU identifier
+ */
+uint32_t HAL_GetCurrentCPUID(void)
+{
+ if (((SCB->CPUID & 0x000000F0U) >> 4 )== 0x7U)
+ {
+ return CM7_CPUID;
+ }
+ else
+ {
+ return CM4_CPUID;
+ }
+}
+
+#else
+
+/**
+* @brief Returns the current CPU ID.
+* @retval CPU identifier
+*/
+uint32_t HAL_GetCurrentCPUID(void)
+{
+ return CM7_CPUID;
+}
+
+#endif /*DUAL_CORE*/
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_crc.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_crc.c
new file mode 100644
index 0000000000..5d12b7f610
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_crc.c
@@ -0,0 +1,518 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_crc.c
+ * @author MCD Application Team
+ * @brief CRC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Cyclic Redundancy Check (CRC) peripheral:
+ * + Initialization and de-initialization functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ (+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
+ (+) Initialize CRC calculator
+ (++) specify generating polynomial (peripheral default or non-default one)
+ (++) specify initialization value (peripheral default or non-default one)
+ (++) specify input data format
+ (++) specify input or output data inversion mode if any
+ (+) Use HAL_CRC_Accumulate() function to compute the CRC value of the
+ input data buffer starting with the previously computed CRC as
+ initialization value
+ (+) Use HAL_CRC_Calculate() function to compute the CRC value of the
+ input data buffer starting with the defined initialization value
+ (default or non-default) to initiate CRC calculation
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CRC CRC
+ * @brief CRC HAL module driver.
+ * @{
+ */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup CRC_Private_Functions CRC Private Functions
+ * @{
+ */
+static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength);
+static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup CRC_Exported_Functions CRC Exported Functions
+ * @{
+ */
+
+/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize the CRC according to the specified parameters
+ in the CRC_InitTypeDef and create the associated handle
+ (+) DeInitialize the CRC peripheral
+ (+) Initialize the CRC MSP (MCU Specific Package)
+ (+) DeInitialize the CRC MSP
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the CRC according to the specified
+ * parameters in the CRC_InitTypeDef and create the associated handle.
+ * @param hcrc CRC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
+{
+ /* Check the CRC handle allocation */
+ if (hcrc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
+
+ if (hcrc->State == HAL_CRC_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcrc->Lock = HAL_UNLOCKED;
+ /* Init the low level hardware */
+ HAL_CRC_MspInit(hcrc);
+ }
+
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* check whether or not non-default generating polynomial has been
+ * picked up by user */
+ assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse));
+ if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE)
+ {
+ /* initialize peripheral with default generating polynomial */
+ WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY);
+ MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B);
+ }
+ else
+ {
+ /* initialize CRC peripheral with generating polynomial defined by user */
+ if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ /* check whether or not non-default CRC initial value has been
+ * picked up by user */
+ assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse));
+ if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE)
+ {
+ WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE);
+ }
+ else
+ {
+ WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue);
+ }
+
+
+ /* set input data inversion mode */
+ assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode));
+ MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode);
+
+ /* set output data inversion mode */
+ assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode));
+ MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode);
+
+ /* makes sure the input data format (bytes, halfwords or words stream)
+ * is properly specified by user */
+ assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat));
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the CRC peripheral.
+ * @param hcrc CRC handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
+{
+ /* Check the CRC handle allocation */
+ if (hcrc == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
+
+ /* Check the CRC peripheral state */
+ if (hcrc->State == HAL_CRC_STATE_BUSY)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* Reset CRC calculation unit */
+ __HAL_CRC_DR_RESET(hcrc);
+
+ /* Reset IDR register content */
+ CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR);
+
+ /* DeInit the low level hardware */
+ HAL_CRC_MspDeInit(hcrc);
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_RESET;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcrc);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the CRC MSP.
+ * @param hcrc CRC handle
+ * @retval None
+ */
+__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcrc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CRC_MspInit can be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitialize the CRC MSP.
+ * @param hcrc CRC handle
+ * @retval None
+ */
+__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcrc);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_CRC_MspDeInit can be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
+ * @brief management functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
+ using combination of the previous CRC value and the new one.
+
+ [..] or
+
+ (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
+ independently of the previous CRC value.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
+ * starting with the previously computed CRC as initialization value.
+ * @param hcrc CRC handle
+ * @param pBuffer pointer to the input data buffer, exact input data format is
+ * provided by hcrc->InputDataFormat.
+ * @param BufferLength input data buffer length (number of bytes if pBuffer
+ * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
+ * number of words if pBuffer type is * uint32_t).
+ * @note By default, the API expects a uint32_t pointer as input buffer parameter.
+ * Input buffer pointers with other types simply need to be cast in uint32_t
+ * and the API will internally adjust its input data processing based on the
+ * handle field hcrc->InputDataFormat.
+ * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
+ */
+uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t index; /* CRC input data buffer index */
+ uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ switch (hcrc->InputDataFormat)
+ {
+ case CRC_INPUTDATA_FORMAT_WORDS:
+ /* Enter Data to the CRC calculator */
+ for (index = 0U; index < BufferLength; index++)
+ {
+ hcrc->Instance->DR = pBuffer[index];
+ }
+ temp = hcrc->Instance->DR;
+ break;
+
+ case CRC_INPUTDATA_FORMAT_BYTES:
+ temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength);
+ break;
+
+ case CRC_INPUTDATA_FORMAT_HALFWORDS:
+ temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength); /* Derogation MisraC2012 R.11.5 */
+ break;
+ default:
+ break;
+ }
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Return the CRC computed value */
+ return temp;
+}
+
+/**
+ * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer
+ * starting with hcrc->Instance->INIT as initialization value.
+ * @param hcrc CRC handle
+ * @param pBuffer pointer to the input data buffer, exact input data format is
+ * provided by hcrc->InputDataFormat.
+ * @param BufferLength input data buffer length (number of bytes if pBuffer
+ * type is * uint8_t, number of half-words if pBuffer type is * uint16_t,
+ * number of words if pBuffer type is * uint32_t).
+ * @note By default, the API expects a uint32_t pointer as input buffer parameter.
+ * Input buffer pointers with other types simply need to be cast in uint32_t
+ * and the API will internally adjust its input data processing based on the
+ * handle field hcrc->InputDataFormat.
+ * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
+ */
+uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t index; /* CRC input data buffer index */
+ uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* Reset CRC Calculation Unit (hcrc->Instance->INIT is
+ * written in hcrc->Instance->DR) */
+ __HAL_CRC_DR_RESET(hcrc);
+
+ switch (hcrc->InputDataFormat)
+ {
+ case CRC_INPUTDATA_FORMAT_WORDS:
+ /* Enter 32-bit input data to the CRC calculator */
+ for (index = 0U; index < BufferLength; index++)
+ {
+ hcrc->Instance->DR = pBuffer[index];
+ }
+ temp = hcrc->Instance->DR;
+ break;
+
+ case CRC_INPUTDATA_FORMAT_BYTES:
+ /* Specific 8-bit input data handling */
+ temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength);
+ break;
+
+ case CRC_INPUTDATA_FORMAT_HALFWORDS:
+ /* Specific 16-bit input data handling */
+ temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength); /* Derogation MisraC2012 R.11.5 */
+ break;
+
+ default:
+ break;
+ }
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Return the CRC computed value */
+ return temp;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
+ * @brief Peripheral State functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the CRC handle state.
+ * @param hcrc CRC handle
+ * @retval HAL state
+ */
+HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
+{
+ /* Return CRC handle state */
+ return hcrc->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup CRC_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Enter 8-bit input data to the CRC calculator.
+ * Specific data handling to optimize processing time.
+ * @param hcrc CRC handle
+ * @param pBuffer pointer to the input data buffer
+ * @param BufferLength input data buffer length
+ * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
+ */
+static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t i; /* input data buffer index */
+ uint16_t data;
+ __IO uint16_t *pReg;
+
+ /* Processing time optimization: 4 bytes are entered in a row with a single word write,
+ * last bytes must be carefully fed to the CRC calculator to ensure a correct type
+ * handling by the peripheral */
+ for (i = 0U; i < (BufferLength / 4U); i++)
+ {
+ hcrc->Instance->DR = ((uint32_t)pBuffer[4U * i] << 24U) | \
+ ((uint32_t)pBuffer[(4U * i) + 1U] << 16U) | \
+ ((uint32_t)pBuffer[(4U * i) + 2U] << 8U) | \
+ (uint32_t)pBuffer[(4U * i) + 3U];
+ }
+ /* last bytes specific handling */
+ if ((BufferLength % 4U) != 0U)
+ {
+ if ((BufferLength % 4U) == 1U)
+ {
+ *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[4U * i]; /* Derogation MisraC2012 R.11.5 */
+ }
+ if ((BufferLength % 4U) == 2U)
+ {
+ data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U];
+ pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */
+ *pReg = data;
+ }
+ if ((BufferLength % 4U) == 3U)
+ {
+ data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U];
+ pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */
+ *pReg = data;
+
+ *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[(4U * i) + 2U]; /* Derogation MisraC2012 R.11.5 */
+ }
+ }
+
+ /* Return the CRC computed value */
+ return hcrc->Instance->DR;
+}
+
+/**
+ * @brief Enter 16-bit input data to the CRC calculator.
+ * Specific data handling to optimize processing time.
+ * @param hcrc CRC handle
+ * @param pBuffer pointer to the input data buffer
+ * @param BufferLength input data buffer length
+ * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
+ */
+static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t i; /* input data buffer index */
+ __IO uint16_t *pReg;
+
+ /* Processing time optimization: 2 HalfWords are entered in a row with a single word write,
+ * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure
+ * a correct type handling by the peripheral */
+ for (i = 0U; i < (BufferLength / 2U); i++)
+ {
+ hcrc->Instance->DR = ((uint32_t)pBuffer[2U * i] << 16U) | (uint32_t)pBuffer[(2U * i) + 1U];
+ }
+ if ((BufferLength % 2U) != 0U)
+ {
+ pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */
+ *pReg = pBuffer[2U * i];
+ }
+
+ /* Return the CRC computed value */
+ return hcrc->Instance->DR;
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_CRC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_crc_ex.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_crc_ex.c
new file mode 100644
index 0000000000..2ce184e5d5
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_crc_ex.c
@@ -0,0 +1,225 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_crc_ex.c
+ * @author MCD Application Team
+ * @brief Extended CRC HAL module driver.
+ * This file provides firmware functions to manage the extended
+ * functionalities of the CRC peripheral.
+ *
+ @verbatim
+================================================================================
+ ##### How to use this driver #####
+================================================================================
+ [..]
+ (+) Set user-defined generating polynomial thru HAL_CRCEx_Polynomial_Set()
+ (+) Configure Input or Output data inversion
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CRCEx CRCEx
+ * @brief CRC Extended HAL module driver
+ * @{
+ */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup CRCEx_Exported_Functions CRC Extended Exported Functions
+ * @{
+ */
+
+/** @defgroup CRCEx_Exported_Functions_Group1 Extended Initialization/de-initialization functions
+ * @brief Extended Initialization and Configuration functions.
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure the generating polynomial
+ (+) Configure the input data inversion
+ (+) Configure the output data inversion
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Initialize the CRC polynomial if different from default one.
+ * @param hcrc CRC handle
+ * @param Pol CRC generating polynomial (7, 8, 16 or 32-bit long).
+ * This parameter is written in normal representation, e.g.
+ * @arg for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 is written 0x65
+ * @arg for a polynomial of degree 16, X^16 + X^12 + X^5 + 1 is written 0x1021
+ * @param PolyLength CRC polynomial length.
+ * This parameter can be one of the following values:
+ * @arg @ref CRC_POLYLENGTH_7B 7-bit long CRC (generating polynomial of degree 7)
+ * @arg @ref CRC_POLYLENGTH_8B 8-bit long CRC (generating polynomial of degree 8)
+ * @arg @ref CRC_POLYLENGTH_16B 16-bit long CRC (generating polynomial of degree 16)
+ * @arg @ref CRC_POLYLENGTH_32B 32-bit long CRC (generating polynomial of degree 32)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef *hcrc, uint32_t Pol, uint32_t PolyLength)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint32_t msb = 31U; /* polynomial degree is 32 at most, so msb is initialized to max value */
+
+ /* Check the parameters */
+ assert_param(IS_CRC_POL_LENGTH(PolyLength));
+
+ /* check polynomial definition vs polynomial size:
+ * polynomial length must be aligned with polynomial
+ * definition. HAL_ERROR is reported if Pol degree is
+ * larger than that indicated by PolyLength.
+ * Look for MSB position: msb will contain the degree of
+ * the second to the largest polynomial member. E.g., for
+ * X^7 + X^6 + X^5 + X^2 + 1, msb = 6. */
+ while ((msb-- > 0U) && ((Pol & ((uint32_t)(0x1U) << (msb & 0x1FU))) == 0U))
+ {
+ }
+
+ switch (PolyLength)
+ {
+ case CRC_POLYLENGTH_7B:
+ if (msb >= HAL_CRC_LENGTH_7B)
+ {
+ status = HAL_ERROR;
+ }
+ break;
+ case CRC_POLYLENGTH_8B:
+ if (msb >= HAL_CRC_LENGTH_8B)
+ {
+ status = HAL_ERROR;
+ }
+ break;
+ case CRC_POLYLENGTH_16B:
+ if (msb >= HAL_CRC_LENGTH_16B)
+ {
+ status = HAL_ERROR;
+ }
+ break;
+
+ case CRC_POLYLENGTH_32B:
+ /* no polynomial definition vs. polynomial length issue possible */
+ break;
+ default:
+ status = HAL_ERROR;
+ break;
+ }
+ if (status == HAL_OK)
+ {
+ /* set generating polynomial */
+ WRITE_REG(hcrc->Instance->POL, Pol);
+
+ /* set generating polynomial size */
+ MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, PolyLength);
+ }
+ /* Return function status */
+ return status;
+}
+
+/**
+ * @brief Set the Reverse Input data mode.
+ * @param hcrc CRC handle
+ * @param InputReverseMode Input Data inversion mode.
+ * This parameter can be one of the following values:
+ * @arg @ref CRC_INPUTDATA_INVERSION_NONE no change in bit order (default value)
+ * @arg @ref CRC_INPUTDATA_INVERSION_BYTE Byte-wise bit reversal
+ * @arg @ref CRC_INPUTDATA_INVERSION_HALFWORD HalfWord-wise bit reversal
+ * @arg @ref CRC_INPUTDATA_INVERSION_WORD Word-wise bit reversal
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRCEx_Input_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t InputReverseMode)
+{
+ /* Check the parameters */
+ assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(InputReverseMode));
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* set input data inversion mode */
+ MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, InputReverseMode);
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Set the Reverse Output data mode.
+ * @param hcrc CRC handle
+ * @param OutputReverseMode Output Data inversion mode.
+ * This parameter can be one of the following values:
+ * @arg @ref CRC_OUTPUTDATA_INVERSION_DISABLE no CRC inversion (default value)
+ * @arg @ref CRC_OUTPUTDATA_INVERSION_ENABLE bit-level inversion (e.g. for a 8-bit CRC: 0xB5 becomes 0xAD)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRCEx_Output_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t OutputReverseMode)
+{
+ /* Check the parameters */
+ assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(OutputReverseMode));
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_BUSY;
+
+ /* set output data inversion mode */
+ MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, OutputReverseMode);
+
+ /* Change CRC peripheral state */
+ hcrc->State = HAL_CRC_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+#endif /* HAL_CRC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_cryp.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_cryp.c
new file mode 100644
index 0000000000..abf8584a2c
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_cryp.c
@@ -0,0 +1,5145 @@
+/**
+ ******************************************************************************
+ * @file stm32h7xx_hal_cryp.c
+ * @author MCD Application Team
+ * @brief CRYP HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Cryptography (CRYP) peripheral:
+ * + Initialization and de-initialization functions
+ * + AES processing functions
+ * + DES processing functions
+ * + TDES processing functions
+ * + DMA callback functions
+ * + CRYP IRQ handler management
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The CRYP HAL driver can be used in CRYP IP as follows:
+
+ (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit():
+ (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()
+ (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT())
+ (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority()
+ (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ()
+ (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler()
+ (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA())
+ (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE()
+ (+++) Configure and enable two DMA streams one for managing data transfer from
+ memory to peripheral (input stream) and another stream for managing data
+ transfer from peripheral to memory (output stream)
+ (+++) Associate the initialized DMA handle to the CRYP DMA handle
+ using __HAL_LINKDMA()
+ (+++) Configure the priority and enable the NVIC for the transfer complete
+ interrupt on the two DMA Streams. The output stream should have higher
+ priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ()
+
+ (#)Initialize the CRYP according to the specified parameters :
+ (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit.
+ (##) The key size: 128, 192 or 256.
+ (##) The AlgoMode DES/ TDES Algorithm ECB/CBC or AES Algorithm ECB/CBC/CTR/GCM or CCM.
+ (##) The initialization vector (counter). It is not used in ECB mode.
+ (##) The key buffer used for encryption/decryption.
+ (##) The Header used only in AES GCM and CCM Algorithm for authentication.
+ (##) The HeaderSize The size of header buffer in word.
+ (##) The B0 block is the first authentication block used only in AES CCM mode.
+
+ (#)Three processing (encryption/decryption) functions are available:
+ (##) Polling mode: encryption and decryption APIs are blocking functions
+ i.e. they process the data and wait till the processing is finished,
+ e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
+ (##) Interrupt mode: encryption and decryption APIs are not blocking functions
+ i.e. they process the data under interrupt,
+ e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
+ (##) DMA mode: encryption and decryption APIs are not blocking functions
+ i.e. the data transfer is ensured by DMA,
+ e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
+
+ (#)When the processing function is called at first time after HAL_CRYP_Init()
+ the CRYP peripheral is configured and processes the buffer in input.
+ At second call, no need to Initialize the CRYP, user have to get current configuration via
+ HAL_CRYP_GetConfig() API, then only HAL_CRYP_SetConfig() is requested to set
+ new parametres, finally user can start encryption/decryption.
+
+ (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral.
+
+ (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt()
+ without having to configure again the Key or the Initialization Vector between each API call,
+ the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE.
+ Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA()
+ or HAL_CRYP_Decrypt_DMA().
+
+ [..]
+ The cryptographic processor supports following standards:
+ (#) The data encryption standard (DES) and Triple-DES (TDES) supported only by CRYP1 IP:
+ (##)64-bit data block processing
+ (##) chaining modes supported :
+ (+++) Electronic Code Book(ECB)
+ (+++) Cipher Block Chaining (CBC)
+ (##) keys length supported :64-bit, 128-bit and 192-bit.
+ (#) The advanced encryption standard (AES) supported by CRYP1:
+ (##)128-bit data block processing
+ (##) chaining modes supported :
+ (+++) Electronic Code Book(ECB)
+ (+++) Cipher Block Chaining (CBC)
+ (+++) Counter mode (CTR)
+ (+++) Galois/counter mode (GCM/GMAC)
+ (+++) Counter with Cipher Block Chaining-Message(CCM)
+ (##) keys length Supported :
+ (+++) for CRYP1 IP: 128-bit, 192-bit and 256-bit.
+
+ [..] This section describes the AES Galois/counter mode (GCM) supported by both CRYP1 IP:
+ (#) Algorithm supported :
+ (##) Galois/counter mode (GCM)
+ (##) Galois message authentication code (GMAC) :is exactly the same as
+ GCM algorithm composed only by an header.
+ (#) Four phases are performed in GCM :
+ (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
+ (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
+ computation only.
+ (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
+ encryption + data XORing. It works in a similar way for ciphertext (C).
+ (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
+ (#) structure of message construction in GCM is defined as below :
+ (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter
+ (##) The authenticated header A (also knows as Additional Authentication Data AAD)
+ this part of the message is only authenticated, not encrypted.
+ (##) The plaintext message P is both authenticated and encrypted as ciphertext.
+ GCM standard specifies that ciphertext has same bit length as the plaintext.
+ (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext
+ (on 64 bits)
+
+ [..] This section describe The AES Counter with Cipher Block Chaining-Message
+ Authentication Code (CCM) supported by both CRYP1 IP:
+ (#) Specific parameters for CCM :
+
+ (##) B0 block : According to NIST Special Publication 800-38C,
+ The first block B0 is formatted as follows, where l(m) is encoded in
+ most-significant-byte first order(see below table 3)
+
+ (+++) Q: a bit string representation of the octet length of P (plaintext)
+ (+++) q The octet length of the binary representation of the octet length of the payload
+ (+++) A nonce (N), n The octet length of the where n+q=15.
+ (+++) Flags: most significant octet containing four flags for control information,
+ (+++) t The octet length of the MAC.
+ (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A)
+ the associated data length expressed in bytes (a) defined as below:
+ (+++) If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets
+ (+++) If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets
+ (+++) If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets
+ (##) CTRx block : control blocks
+ (+++) Generation of CTR1 from first block B0 information :
+ equal to B0 with first 5 bits zeroed and most significant bits storing octet
+ length of P also zeroed, then incremented by one ( see below Table 4)
+ (+++) Generation of CTR0: same as CTR1 with bit[0] set to zero.
+
+ (#) Four phases are performed in CCM for CRYP1 IP:
+ (##) Init phase: IP prepares the GCM hash subkey (H) and do the IV processing
+ (##) Header phase: IP processes the Additional Authenticated Data (AAD), with hash
+ computation only.
+ (##) Payload phase: IP processes the plaintext (P) with hash computation + keystream
+ encryption + data XORing. It works in a similar way for ciphertext (C).
+ (##) Final phase: IP generates the authenticated tag (T) using the last block of data.
+
+ *** Callback registration ***
+ =============================
+
+ [..]
+ The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+ Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback()
+ to register an interrupt callback.
+
+ [..]
+ Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks:
+ (+) InCpltCallback : Input FIFO transfer completed callback.
+ (+) OutCpltCallback : Output FIFO transfer completed callback.
+ (+) ErrorCallback : callback for error detection.
+ (+) MspInitCallback : CRYP MspInit.
+ (+) MspDeInitCallback : CRYP MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ [..]
+ Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default
+ weak function.
+ @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) InCpltCallback : Input FIFO transfer completed callback.
+ (+) OutCpltCallback : Output FIFO transfer completed callback.
+ (+) ErrorCallback : callback for error detection.
+ (+) MspInitCallback : CRYP MspInit.
+ (+) MspDeInitCallback : CRYP MspDeInit.
+
+ [..]
+ By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET
+ all callbacks are set to the corresponding weak functions :
+ examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are
+ reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when
+ these callbacks are null (not registered beforehand).
+ if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit()
+ keep and use the user MspInit/MspDeInit functions (registered beforehand)
+
+ [..]
+ Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only.
+ Exception done MspInit/MspDeInit callbacks that can be registered/unregistered
+ in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state,
+ thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
+ In that case first register the MspInit/MspDeInit user callbacks
+ using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit()
+ or @ref HAL_CRYP_Init() function.
+
+ [..]
+ When The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registration feature is not available and all callbacks
+ are set to the corresponding weak functions.
+
+ @endverbatim
+
+ Table 1. Initial Counter Block (ICB)
+ +-------------------------------------------------------+
+ | Initialization vector (IV) | Counter |
+ |----------------|----------------|-----------|---------|
+ 127 95 63 31 0
+
+
+ Bit Number Register Contents
+ ---------- --------------- -----------
+ 127 ...96 CRYP_IV1R[31:0] ICB[127:96]
+ 95 ...64 CRYP_IV1L[31:0] B0[95:64]
+ 63 ... 32 CRYP_IV0R[31:0] ICB[63:32]
+ 31 ... 0 CRYP_IV0L[31:0] ICB[31:0], where 32-bit counter= 0x2
+
+ Table 2. GCM last block definition
+
+ +-------------------------------------------------------------------+
+ | Bit[0] | Bit[32] | Bit[64] | Bit[96] |
+ |-----------|--------------------|-----------|----------------------|
+ | 0x0 | Header length[31:0]| 0x0 | Payload length[31:0] |
+ |-----------|--------------------|-----------|----------------------|
+
+ Table 3. B0 block
+ Octet Number Contents
+ ------------ ---------
+ 0 Flags
+ 1 ... 15-q Nonce N
+ 16-q ... 15 Q
+
+ the Flags field is formatted as follows:
+
+ Bit Number Contents
+ ---------- ----------------------
+ 7 Reserved (always zero)
+ 6 Adata
+ 5 ... 3 (t-2)/2
+ 2 ... 0 [q-1]3
+
+ Table 4. CTRx block
+ Bit Number Register Contents
+ ---------- --------------- -----------
+ 127 ...96 CRYP_IV1R[31:0] B0[127:96], where Q length bits are set to 0, except for
+ bit 0 that is set to 1
+ 95 ...64 CRYP_IV1L[31:0] B0[95:64]
+ 63 ... 32 CRYP_IV0R[31:0] B0[63:32]
+ 31 ... 0 CRYP_IV0L[31:0] B0[31:0], where flag bits set to 0
+
+
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+#if defined (CRYP)
+
+/** @defgroup CRYP CRYP
+ * @brief CRYP HAL module driver.
+ * @{
+ */
+
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup CRYP_Private_Defines
+ * @{
+ */
+#define CRYP_TIMEOUT_KEYPREPARATION 82U /*The latency of key preparation operation is 82 clock cycles.*/
+#define CRYP_TIMEOUT_GCMCCMINITPHASE 299U /* The latency of GCM/CCM init phase to prepare hash subkey is 299 clock cycles.*/
+#define CRYP_TIMEOUT_GCMCCMHEADERPHASE 290U /* The latency of GCM/CCM header phase is 290 clock cycles.*/
+
+#define CRYP_PHASE_READY 0x00000001U /*!< CRYP peripheral is ready for initialization. */
+#define CRYP_PHASE_PROCESS 0x00000002U /*!< CRYP peripheral is in processing phase */
+
+#define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */
+#define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0 /*!< GCM/GMAC or CCM header phase */
+#define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1 /*!< GCM(/CCM) payload phase */
+#define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH /*!< GCM/GMAC or CCM final phase */
+#define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */
+#define CRYP_OPERATINGMODE_DECRYPT CRYP_CR_ALGODIR /*!< Decryption */
+
+
+/* CTR1 information to use in CCM algorithm */
+#define CRYP_CCM_CTR1_0 0x07FFFFFFU
+#define CRYP_CCM_CTR1_1 0xFFFFFF00U
+#define CRYP_CCM_CTR1_2 0x00000001U
+
+/**
+ * @}
+ */
+
+
+/* Private macro -------------------------------------------------------------*/
+/** @addtogroup CRYP_Private_Macros
+ * @{
+ */
+
+#define CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\
+ (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\
+ }while(0)
+
+#define HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRYP_CR_FFLUSH)
+
+
+/**
+ * @}
+ */
+
+/* Private struct -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup CRYP_Private_Functions_prototypes
+ * @{
+ */
+
+static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr);
+static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma);
+static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma);
+static void CRYP_DMAError(DMA_HandleTypeDef *hdma);
+static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize);
+static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp);
+static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp);
+#if !defined (CRYP_VER_2_2)
+static void CRYP_Workaround(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+#endif /*End of not defined CRYP_VER_2_2*/
+static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp);
+static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp);
+static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp);
+static HAL_StatusTypeDef CRYP_WaitOnIFEMFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_WaitOnBUSYFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_WaitOnOFNEFlag(const CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout);
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup CRYP_Exported_Functions CRYP Exported Functions
+ * @{
+ */
+
+
+/** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief CRYP Initialization and Configuration functions.
+ *
+@verbatim
+ ========================================================================================
+ ##### Initialization, de-initialization and Set and Get configuration functions #####
+ ========================================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize the CRYP
+ (+) DeInitialize the CRYP
+ (+) Initialize the CRYP MSP
+ (+) DeInitialize the CRYP MSP
+ (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef
+ Parameters which are configured in This section are :
+ (++) Key size
+ (++) Data Type : 32,16, 8 or 1bit
+ (++) AlgoMode : for CRYP1 IP
+ ECB and CBC in DES/TDES Standard
+ ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard.
+ (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef
+
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Initializes the CRYP according to the specified
+ * parameters in the CRYP_ConfigTypeDef and creates the associated handle.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp)
+{
+ /* Check the CRYP handle allocation */
+ if (hcryp == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check parameters */
+ assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize));
+ assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType));
+ assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm));
+ assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip));
+
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ if (hcryp->State == HAL_CRYP_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcryp->Lock = HAL_UNLOCKED;
+
+ hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
+ hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
+ hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
+
+ if (hcryp->MspInitCallback == NULL)
+ {
+ hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit */
+ }
+
+ /* Init the low level hardware */
+ hcryp->MspInitCallback(hcryp);
+ }
+#else
+ if (hcryp->State == HAL_CRYP_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hcryp->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_CRYP_MspInit(hcryp);
+ }
+#endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */
+
+ /* Set the key size(This bit field is ‘don’t care’ in the DES or TDES modes) data type and Algorithm */
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
+ hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
+#if !defined (CRYP_VER_2_2)
+ /* Read Device ID to indicate CRYP1 IP Version */
+ hcryp->Version = HAL_GetREVID();
+#endif /*End of not defined CRYP_VER_2_2*/
+ /* Reset Error Code field */
+ hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
+
+ /* Reset peripheral Key and IV configuration flag */
+ hcryp->KeyIVConfig = 0U;
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Set the default CRYP phase */
+ hcryp->Phase = CRYP_PHASE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief De-Initializes the CRYP peripheral.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp)
+{
+ /* Check the CRYP handle allocation */
+ if (hcryp == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set the default CRYP phase */
+ hcryp->Phase = CRYP_PHASE_READY;
+
+ /* Reset CrypInCount and CrypOutCount */
+ hcryp->CrypInCount = 0;
+ hcryp->CrypOutCount = 0;
+ hcryp->CrypHeaderCount = 0;
+
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ if (hcryp->MspDeInitCallback == NULL)
+ {
+ hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit */
+ }
+ /* DeInit the low level hardware */
+ hcryp->MspDeInitCallback(hcryp);
+
+#else
+ /* DeInit the low level hardware: CLOCK, NVIC.*/
+ HAL_CRYP_MspDeInit(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcryp);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Configure the CRYP according to the specified
+ * parameters in the CRYP_ConfigTypeDef
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure
+ * @param pConf: pointer to a CRYP_ConfigTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
+{
+ /* Check the CRYP handle allocation */
+ if ((hcryp == NULL) || (pConf == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check parameters */
+ assert_param(IS_CRYP_KEYSIZE(pConf->KeySize));
+ assert_param(IS_CRYP_DATATYPE(pConf->DataType));
+ assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm));
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Set CRYP parameters */
+ hcryp->Init.DataType = pConf->DataType;
+ hcryp->Init.pKey = pConf->pKey;
+ hcryp->Init.Algorithm = pConf->Algorithm;
+ hcryp->Init.KeySize = pConf->KeySize;
+ hcryp->Init.pInitVect = pConf->pInitVect;
+ hcryp->Init.Header = pConf->Header;
+ hcryp->Init.HeaderSize = pConf->HeaderSize;
+ hcryp->Init.B0 = pConf->B0;
+ hcryp->Init.DataWidthUnit = pConf->DataWidthUnit;
+
+ /* Set the key size(This bit field is ‘don’t care’ in the DES or TDES modes) data type, AlgoMode and operating mode*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_DATATYPE | CRYP_CR_KEYSIZE | CRYP_CR_ALGOMODE,
+ hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Reset Error Code field */
+ hcryp->ErrorCode = HAL_CRYP_ERROR_NONE;
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Set the default CRYP phase */
+ hcryp->Phase = CRYP_PHASE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Get CRYP Configuration parameters in associated handle.
+ * @param pConf: pointer to a CRYP_ConfigTypeDef structure
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf)
+{
+ /* Check the CRYP handle allocation */
+ if ((hcryp == NULL) || (pConf == NULL))
+ {
+ return HAL_ERROR;
+ }
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Get CRYP parameters */
+ pConf->DataType = hcryp->Init.DataType;
+ pConf->pKey = hcryp->Init.pKey;
+ pConf->Algorithm = hcryp->Init.Algorithm;
+ pConf->KeySize = hcryp->Init.KeySize ;
+ pConf->pInitVect = hcryp->Init.pInitVect;
+ pConf->Header = hcryp->Init.Header ;
+ pConf->HeaderSize = hcryp->Init.HeaderSize;
+ pConf->B0 = hcryp->Init.B0;
+ pConf->DataWidthUnit = hcryp->Init.DataWidthUnit;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ return HAL_ERROR;
+ }
+}
+/**
+ * @brief Initializes the CRYP MSP.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval None
+ */
+__weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcryp);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CRYP_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes CRYP MSP.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval None
+ */
+__weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcryp);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CRYP_MspDeInit could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User CRYP Callback
+ * To be used instead of the weak predefined callback
+ * @param hcryp cryp handle
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
+ * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
+ * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
+ * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID,
+ pCRYP_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CRYP_INPUT_COMPLETE_CB_ID :
+ hcryp->InCpltCallback = pCallback;
+ break;
+
+ case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
+ hcryp->OutCpltCallback = pCallback;
+ break;
+
+ case HAL_CRYP_ERROR_CB_ID :
+ hcryp->ErrorCallback = pCallback;
+ break;
+
+ case HAL_CRYP_MSPINIT_CB_ID :
+ hcryp->MspInitCallback = pCallback;
+ break;
+
+ case HAL_CRYP_MSPDEINIT_CB_ID :
+ hcryp->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hcryp->State == HAL_CRYP_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CRYP_MSPINIT_CB_ID :
+ hcryp->MspInitCallback = pCallback;
+ break;
+
+ case HAL_CRYP_MSPDEINIT_CB_ID :
+ hcryp->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcryp);
+
+ return status;
+}
+
+/**
+ * @brief Unregister an CRYP Callback
+ * CRYP callabck is redirected to the weak predefined callback
+ * @param hcryp cryp handle
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID
+ * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID
+ * @arg @ref HAL_CRYP_ERROR_CB_ID Rx Half Error callback ID
+ * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @retval status
+ */
+HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CRYP_INPUT_COMPLETE_CB_ID :
+ hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */
+ break;
+
+ case HAL_CRYP_OUTPUT_COMPLETE_CB_ID :
+ hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */
+ break;
+
+ case HAL_CRYP_ERROR_CB_ID :
+ hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_CRYP_MSPINIT_CB_ID :
+ hcryp->MspInitCallback = HAL_CRYP_MspInit;
+ break;
+
+ case HAL_CRYP_MSPDEINIT_CB_ID :
+ hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
+ break;
+
+ default :
+ /* Update the error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (hcryp->State == HAL_CRYP_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_CRYP_MSPINIT_CB_ID :
+ hcryp->MspInitCallback = HAL_CRYP_MspInit;
+ break;
+
+ case HAL_CRYP_MSPDEINIT_CB_ID :
+ hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit;
+ break;
+
+ default :
+ /* Update the error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;;
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hcryp);
+
+ return status;
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Exported_Functions_Group2 Encrypt Decrypt functions
+ * @brief CRYP processing functions.
+ *
+@verbatim
+ ==============================================================================
+ ##### Encrypt Decrypt functions #####
+ ==============================================================================
+ [..] This section provides API allowing to Encrypt/Decrypt Data following
+ Standard DES/TDES or AES, and Algorithm configured by the user:
+ (+) Standard DES/TDES only supported by CRYP1 IP, below list of Algorithm supported :
+ (++) Electronic Code Book(ECB)
+ (++) Cipher Block Chaining (CBC)
+ (+) Standard AES supported by CRYP1 IP , list of Algorithm supported:
+ (++) Electronic Code Book(ECB)
+ (++) Cipher Block Chaining (CBC)
+ (++) Counter mode (CTR)
+ (++) Cipher Block Chaining (CBC)
+ (++) Counter mode (CTR)
+ (++) Galois/counter mode (GCM)
+ (++) Counter with Cipher Block Chaining-Message(CCM)
+ [..] Three processing functions are available:
+ (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt
+ (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT
+ (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Encryption mode.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Input: Pointer to the input buffer (plaintext)
+ * @param Size: Length of the plaintext buffer in word.
+ * @param Output: Pointer to the output buffer(ciphertext)
+ * @param Timeout: Specify Timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
+ uint32_t Timeout)
+{
+ uint32_t algo;
+ HAL_StatusTypeDef status;
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change state Busy */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
+ hcryp->CrypInCount = 0U;
+ hcryp->CrypOutCount = 0U;
+ hcryp->pCrypInBuffPtr = Input;
+ hcryp->pCrypOutBuffPtr = Output;
+
+ /* Calculate Size parameter in Byte*/
+ if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
+ {
+ hcryp->Size = Size * 4U;
+ }
+ else
+ {
+ hcryp->Size = Size;
+ }
+
+ /* Set Encryption operating mode*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
+
+ /* algo get algorithm selected */
+ algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
+
+ switch (algo)
+ {
+ case CRYP_DES_ECB:
+ case CRYP_DES_CBC:
+ case CRYP_TDES_ECB:
+ case CRYP_TDES_CBC:
+
+ /*Set Key */
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ }
+
+ /*Set Initialization Vector (IV)*/
+ if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ }
+
+ /* Flush FIFO */
+ HAL_CRYP_FIFO_FLUSH(hcryp);
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Statrt DES/TDES encryption process */
+ status = CRYP_TDES_Process(hcryp, Timeout);
+ break;
+
+ case CRYP_AES_ECB:
+ case CRYP_AES_CBC:
+ case CRYP_AES_CTR:
+
+ /* AES encryption */
+ status = CRYP_AES_Encrypt(hcryp, Timeout);
+ break;
+
+ case CRYP_AES_GCM:
+
+ /* AES GCM encryption */
+ status = CRYP_AESGCM_Process(hcryp, Timeout);
+ break;
+
+ case CRYP_AES_CCM:
+
+ /* AES CCM encryption */
+ status = CRYP_AESCCM_Process(hcryp, Timeout);
+ break;
+
+ default:
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ status = HAL_ERROR;
+ break;
+ }
+
+ if (status == HAL_OK)
+ {
+ /* Change the CRYP peripheral state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return status ;
+}
+
+/**
+ * @brief Decryption mode.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Input: Pointer to the input buffer (ciphertext )
+ * @param Size: Length of the plaintext buffer in word.
+ * @param Output: Pointer to the output buffer(plaintext)
+ * @param Timeout: Specify Timeout value
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output,
+ uint32_t Timeout)
+{
+ HAL_StatusTypeDef status;
+ uint32_t algo;
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change state Busy */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
+ hcryp->CrypInCount = 0U;
+ hcryp->CrypOutCount = 0U;
+ hcryp->pCrypInBuffPtr = Input;
+ hcryp->pCrypOutBuffPtr = Output;
+
+ /* Calculate Size parameter in Byte*/
+ if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
+ {
+ hcryp->Size = Size * 4U;
+ }
+ else
+ {
+ hcryp->Size = Size;
+ }
+
+ /* Set Decryption operating mode*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
+
+ /* algo get algorithm selected */
+ algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
+
+ switch (algo)
+ {
+ case CRYP_DES_ECB:
+ case CRYP_DES_CBC:
+ case CRYP_TDES_ECB:
+ case CRYP_TDES_CBC:
+
+ /*Set Key */
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ }
+
+ /*Set Initialization Vector (IV)*/
+ if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ }
+
+ /* Flush FIFO */
+ HAL_CRYP_FIFO_FLUSH(hcryp);
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Start DES/TDES decryption process */
+ status = CRYP_TDES_Process(hcryp, Timeout);
+
+ break;
+
+ case CRYP_AES_ECB:
+ case CRYP_AES_CBC:
+ case CRYP_AES_CTR:
+
+ /* AES decryption */
+ status = CRYP_AES_Decrypt(hcryp, Timeout);
+ break;
+
+ case CRYP_AES_GCM:
+
+ /* AES GCM decryption */
+ status = CRYP_AESGCM_Process(hcryp, Timeout) ;
+ break;
+
+ case CRYP_AES_CCM:
+
+ /* AES CCM decryption */
+ status = CRYP_AESCCM_Process(hcryp, Timeout);
+ break;
+
+ default:
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ status = HAL_ERROR;
+ break;
+ }
+
+ if (status == HAL_OK)
+ {
+ /* Change the CRYP peripheral state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return status;
+}
+
+/**
+ * @brief Encryption in interrupt mode.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Input: Pointer to the input buffer (plaintext)
+ * @param Size: Length of the plaintext buffer in word
+ * @param Output: Pointer to the output buffer(ciphertext)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
+{
+ uint32_t algo;
+ HAL_StatusTypeDef status;
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change state Busy */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
+ hcryp->CrypInCount = 0U;
+ hcryp->CrypOutCount = 0U;
+ hcryp->pCrypInBuffPtr = Input;
+ hcryp->pCrypOutBuffPtr = Output;
+
+ /* Calculate Size parameter in Byte*/
+ if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
+ {
+ hcryp->Size = Size * 4U;
+ }
+ else
+ {
+ hcryp->Size = Size;
+ }
+
+ /* Set encryption operating mode*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
+
+ /* algo get algorithm selected */
+ algo = (hcryp->Instance->CR & CRYP_CR_ALGOMODE);
+
+ switch (algo)
+ {
+ case CRYP_DES_ECB:
+ case CRYP_DES_CBC:
+ case CRYP_TDES_ECB:
+ case CRYP_TDES_CBC:
+
+ /*Set Key */
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ }
+ /* Set the Initialization Vector*/
+ if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ }
+
+ /* Flush FIFO */
+ HAL_CRYP_FIFO_FLUSH(hcryp);
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Enable interrupts */
+ __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
+
+ /* Enable CRYP to start DES/TDES process*/
+ __HAL_CRYP_ENABLE(hcryp);
+
+ status = HAL_OK;
+ break;
+
+ case CRYP_AES_ECB:
+ case CRYP_AES_CBC:
+ case CRYP_AES_CTR:
+
+ status = CRYP_AES_Encrypt_IT(hcryp);
+ break;
+
+ case CRYP_AES_GCM:
+
+ status = CRYP_AESGCM_Process_IT(hcryp) ;
+ break;
+
+ case CRYP_AES_CCM:
+
+ status = CRYP_AESCCM_Process_IT(hcryp);
+ break;
+
+ default:
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return status ;
+}
+
+/**
+ * @brief Decryption in itnterrupt mode.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Input: Pointer to the input buffer (ciphertext )
+ * @param Size: Length of the plaintext buffer in word.
+ * @param Output: Pointer to the output buffer(plaintext)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
+{
+ uint32_t algo;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change state Busy */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
+ hcryp->CrypInCount = 0U;
+ hcryp->CrypOutCount = 0U;
+ hcryp->pCrypInBuffPtr = Input;
+ hcryp->pCrypOutBuffPtr = Output;
+
+ /* Calculate Size parameter in Byte*/
+ if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
+ {
+ hcryp->Size = Size * 4U;
+ }
+ else
+ {
+ hcryp->Size = Size;
+ }
+
+ /* Set decryption operating mode*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
+
+ /* algo get algorithm selected */
+ algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
+
+ switch (algo)
+ {
+ case CRYP_DES_ECB:
+ case CRYP_DES_CBC:
+ case CRYP_TDES_ECB:
+ case CRYP_TDES_CBC:
+
+ /*Set Key */
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ }
+
+ /* Set the Initialization Vector*/
+ if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ }
+ /* Flush FIFO */
+ HAL_CRYP_FIFO_FLUSH(hcryp);
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Enable interrupts */
+ __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
+
+ /* Enable CRYP and start DES/TDES process*/
+ __HAL_CRYP_ENABLE(hcryp);
+
+ break;
+
+ case CRYP_AES_ECB:
+ case CRYP_AES_CBC:
+ case CRYP_AES_CTR:
+
+ /* AES decryption */
+ status = CRYP_AES_Decrypt_IT(hcryp);
+ break;
+
+ case CRYP_AES_GCM:
+
+ /* AES GCM decryption */
+ status = CRYP_AESGCM_Process_IT(hcryp) ;
+ break;
+
+ case CRYP_AES_CCM:
+
+ /* AES CCMdecryption */
+ status = CRYP_AESCCM_Process_IT(hcryp);
+ break;
+
+ default:
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return status;
+}
+
+/**
+ * @brief Encryption in DMA mode.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Input: Pointer to the input buffer (plaintext)
+ * @param Size: Length of the plaintext buffer in word.
+ * @param Output: Pointer to the output buffer(ciphertext)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint32_t algo;
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change state Busy */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
+ hcryp->CrypInCount = 0U;
+ hcryp->CrypOutCount = 0U;
+ hcryp->pCrypInBuffPtr = Input;
+ hcryp->pCrypOutBuffPtr = Output;
+
+ /* Calculate Size parameter in Byte*/
+ if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
+ {
+ hcryp->Size = Size * 4U;
+ }
+ else
+ {
+ hcryp->Size = Size;
+ }
+
+ /* Set encryption operating mode*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_ENCRYPT);
+
+ /* algo get algorithm selected */
+ algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
+
+ switch (algo)
+ {
+ case CRYP_DES_ECB:
+ case CRYP_DES_CBC:
+ case CRYP_TDES_ECB:
+ case CRYP_TDES_CBC:
+
+ /*Set Key */
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ }
+
+ /* Set the Initialization Vector*/
+ if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ }
+
+ /* Flush FIFO */
+ HAL_CRYP_FIFO_FLUSH(hcryp);
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Start DMA process transfer for DES/TDES */
+ CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
+
+ break;
+
+ case CRYP_AES_ECB:
+ case CRYP_AES_CBC:
+ case CRYP_AES_CTR:
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ }
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Set the Initialization Vector*/
+ if (hcryp->Init.Algorithm != CRYP_AES_ECB)
+ {
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
+ }
+ } /* if (DoKeyIVConfig == 1U) */
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Start DMA process transfer for AES */
+ CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
+ break;
+
+ case CRYP_AES_GCM:
+
+ /* AES GCM encryption */
+ status = CRYP_AESGCM_Process_DMA(hcryp) ;
+ break;
+
+ case CRYP_AES_CCM:
+
+ /* AES CCM encryption */
+ status = CRYP_AESCCM_Process_DMA(hcryp);
+ break;
+
+ default:
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return status;
+}
+
+/**
+ * @brief Decryption in DMA mode.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Input: Pointer to the input buffer (ciphertext )
+ * @param Size: Length of the plaintext buffer in word
+ * @param Output: Pointer to the output buffer(plaintext)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *Input, uint16_t Size, uint32_t *Output)
+{
+ uint32_t algo;
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (hcryp->State == HAL_CRYP_STATE_READY)
+ {
+ /* Change state Busy */
+ hcryp->State = HAL_CRYP_STATE_BUSY;
+
+ /* Process locked */
+ __HAL_LOCK(hcryp);
+
+ /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/
+ hcryp->CrypInCount = 0U;
+ hcryp->CrypOutCount = 0U;
+ hcryp->pCrypInBuffPtr = Input;
+ hcryp->pCrypOutBuffPtr = Output;
+
+ /* Calculate Size parameter in Byte*/
+ if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)
+ {
+ hcryp->Size = Size * 4U;
+ }
+ else
+ {
+ hcryp->Size = Size;
+ }
+
+ /* Set decryption operating mode*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGODIR, CRYP_OPERATINGMODE_DECRYPT);
+
+ /* algo get algorithm selected */
+ algo = hcryp->Instance->CR & CRYP_CR_ALGOMODE;
+
+ switch (algo)
+ {
+ case CRYP_DES_ECB:
+ case CRYP_DES_CBC:
+ case CRYP_TDES_ECB:
+ case CRYP_TDES_CBC:
+
+ /*Set Key */
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ if ((hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ }
+
+ /* Set the Initialization Vector*/
+ if ((hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ }
+
+ /* Flush FIFO */
+ HAL_CRYP_FIFO_FLUSH(hcryp);
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Start DMA process transfer for DES/TDES */
+ CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
+ break;
+
+ case CRYP_AES_ECB:
+ case CRYP_AES_CBC:
+ case CRYP_AES_CTR:
+
+ /* AES decryption */
+ status = CRYP_AES_Decrypt_DMA(hcryp);
+ break;
+
+ case CRYP_AES_GCM:
+
+ /* AES GCM decryption */
+ status = CRYP_AESGCM_Process_DMA(hcryp) ;
+
+ break;
+
+ case CRYP_AES_CCM:
+
+ /* AES CCM decryption */
+ status = CRYP_AESCCM_Process_DMA(hcryp);
+ break;
+
+ default:
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED;
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+ status = HAL_ERROR;
+ }
+
+ /* Return function status */
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management
+ * @brief CRYP IRQ handler.
+ *
+@verbatim
+ ==============================================================================
+ ##### CRYP IRQ handler management #####
+ ==============================================================================
+[..] This section provides CRYP IRQ handler and callback functions.
+ (+) HAL_CRYP_IRQHandler CRYP interrupt request
+ (+) HAL_CRYP_InCpltCallback input data transfer complete callback
+ (+) HAL_CRYP_OutCpltCallback output data transfer complete callback
+ (+) HAL_CRYP_ErrorCallback CRYP error callback
+ (+) HAL_CRYP_GetState return the CRYP state
+ (+) HAL_CRYP_GetError return the CRYP error code
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief This function handles cryptographic interrupt request.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval None
+ */
+void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp)
+{
+ uint32_t itstatus = hcryp->Instance->MISR;
+
+ if ((itstatus & (CRYP_IT_INI | CRYP_IT_OUTI)) != 0U)
+ {
+ if ((hcryp->Init.Algorithm == CRYP_DES_ECB) || (hcryp->Init.Algorithm == CRYP_DES_CBC) || (hcryp->Init.Algorithm == CRYP_TDES_ECB) || (hcryp->Init.Algorithm == CRYP_TDES_CBC))
+ {
+ CRYP_TDES_IT(hcryp); /* DES or TDES*/
+ }
+ else if ((hcryp->Init.Algorithm == CRYP_AES_ECB) || (hcryp->Init.Algorithm == CRYP_AES_CBC) || (hcryp->Init.Algorithm == CRYP_AES_CTR))
+ {
+ CRYP_AES_IT(hcryp); /*AES*/
+ }
+
+ else if ((hcryp->Init.Algorithm == CRYP_AES_GCM) || (hcryp->Init.Algorithm == CRYP_CR_ALGOMODE_AES_CCM))
+ {
+ /* if header phase */
+ if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER)
+ {
+ CRYP_GCMCCM_SetHeaderPhase_IT(hcryp);
+ }
+ else /* if payload phase */
+ {
+ CRYP_GCMCCM_SetPayloadPhase_IT(hcryp);
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+}
+
+/**
+ * @brief Return the CRYP error code.
+ * @param hcryp : pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for the CRYP IP
+ * @retval CRYP error code
+ */
+uint32_t HAL_CRYP_GetError(CRYP_HandleTypeDef *hcryp)
+{
+ return hcryp->ErrorCode;
+}
+
+/**
+ * @brief Returns the CRYP state.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module.
+ * @retval HAL state
+ */
+HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp)
+{
+ return hcryp->State;
+}
+
+/**
+ * @brief Input FIFO transfer completed callback.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module.
+ * @retval None
+ */
+__weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcryp);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CRYP_InCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Output FIFO transfer completed callback.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module.
+ * @retval None
+ */
+__weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcryp);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CRYP_OutCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief CRYP error callback.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module.
+ * @retval None
+ */
+__weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hcryp);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_CRYP_ErrorCallback could be implemented in the user file
+ */
+}
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @addtogroup CRYP_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Encryption in ECB/CBC Algorithm with DES/TDES standard.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Timeout: Timeout value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_TDES_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
+{
+
+ uint32_t temp; /* Temporary CrypOutBuff */
+ uint16_t incount; /* Temporary CrypInCount Value */
+ uint16_t outcount; /* Temporary CrypOutCount Value */
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ /*Start processing*/
+ while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
+ {
+ /* Temporary CrypInCount Value */
+ incount = hcryp->CrypInCount;
+ /* Write plain data and get cipher data */
+ if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
+ {
+ /* Write the input block in the IN FIFO */
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ }
+
+ /* Wait for OFNE flag to be raised */
+ if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state & errorCode*/
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
+ {
+ /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */
+ temp = hcryp->Instance->DOUT;
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
+ hcryp->CrypOutCount++;
+ temp = hcryp->Instance->DOUT;
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
+ hcryp->CrypOutCount++;
+ }
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+ }
+ /* Disable CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief CRYP block input/output data handling under interruption with DES/TDES standard.
+ * @note The function is called under interruption only, once
+ * interruptions have been enabled by CRYP_Decrypt_IT() and CRYP_Encrypt_IT().
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module.
+ * @retval HAL status
+ */
+static void CRYP_TDES_IT(CRYP_HandleTypeDef *hcryp)
+{
+ uint32_t temp; /* Temporary CrypOutBuff */
+
+ if (hcryp->State == HAL_CRYP_STATE_BUSY)
+ {
+ if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI) != 0x0U)
+ {
+ if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_INRIS) != 0x0U)
+ {
+ /* Write input block in the IN FIFO */
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+
+ if (hcryp->CrypInCount == (hcryp->Size / 4U))
+ {
+ /* Disable interruption */
+ __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
+
+ /* Call the input data transfer complete callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered Input complete callback*/
+ hcryp->InCpltCallback(hcryp);
+#else
+ /*Call legacy weak Input complete callback*/
+ HAL_CRYP_InCpltCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ }
+ }
+
+ if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI) != 0x0U)
+ {
+ if(__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_OUTRIS) != 0x0U)
+ {
+ /* Read the output block from the Output FIFO and put them in temporary Buffer then get CrypOutBuff from temporary buffer */
+ temp = hcryp->Instance->DOUT;
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
+ hcryp->CrypOutCount++;
+ temp = hcryp->Instance->DOUT;
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
+ hcryp->CrypOutCount++;
+ if (hcryp->CrypOutCount == (hcryp->Size / 4U))
+ {
+ /* Disable interruption */
+ __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
+
+ /* Disable CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Call output transfer complete callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered Output complete callback*/
+ hcryp->OutCpltCallback(hcryp);
+#else
+ /*Call legacy weak Output complete callback*/
+ HAL_CRYP_OutCpltCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief Encryption in ECB/CBC & CTR Algorithm with AES Standard
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure
+ * @param Timeout: specify Timeout value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
+{
+ uint16_t outcount; /* Temporary CrypOutCount Value */
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ }
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ if (hcryp->Init.Algorithm != CRYP_AES_ECB)
+ {
+ /* Set the Initialization Vector*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
+ }
+ } /* if (DoKeyIVConfig == 1U) */
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
+ {
+ /* Write plain Ddta and get cipher data */
+ CRYP_AES_ProcessData(hcryp, Timeout);
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+ }
+
+ /* Disable CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp)
+{
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ }
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ if (hcryp->Init.Algorithm != CRYP_AES_ECB)
+ {
+ /* Set the Initialization Vector*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1U);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2U);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3U);
+ }
+ } /* if (DoKeyIVConfig == 1U) */
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ if (hcryp->Size != 0U)
+ {
+ /* Enable interrupts */
+ __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+ }
+ else
+ {
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Decryption in ECB/CBC & CTR mode with AES Standard
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure
+ * @param Timeout: Specify Timeout value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
+{
+ uint16_t outcount; /* Temporary CrypOutCount Value */
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ }
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Key preparation for ECB/CBC */
+ if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/
+ {
+ /* change ALGOMODE to key preparation for decryption*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
+
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Wait for BUSY flag to be raised */
+ if (CRYP_WaitOnBUSYFlag(hcryp, Timeout) != HAL_OK)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ /* Turn back to ALGOMODE of the configuration */
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
+ }
+ else /*Algorithm CTR */
+ {
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+ }
+
+ /* Set IV */
+ if (hcryp->Init.Algorithm != CRYP_AES_ECB)
+ {
+ /* Set the Initialization Vector*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
+ }
+} /* if (DoKeyIVConfig == 1U) */
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ while ((hcryp->CrypInCount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U)))
+ {
+ /* Write plain data and get cipher data */
+ CRYP_AES_ProcessData(hcryp, Timeout);
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+ }
+
+ /* Disable CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+/**
+ * @brief Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp)
+{
+ __IO uint32_t count = 0U;
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ }
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Key preparation for ECB/CBC */
+ if (hcryp->Init.Algorithm != CRYP_AES_CTR)
+ {
+ /* change ALGOMODE to key preparation for decryption*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
+
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Wait for BUSY flag to be raised */
+ count = CRYP_TIMEOUT_KEYPREPARATION;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
+
+ /* Turn back to ALGOMODE of the configuration */
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
+ }
+ else /*Algorithm CTR */
+ {
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+ }
+
+ /* Set IV */
+ if (hcryp->Init.Algorithm != CRYP_AES_ECB)
+ {
+ /* Set the Initialization Vector*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
+ }
+} /* if (DoKeyIVConfig == 1U) */
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+ if (hcryp->Size != 0U)
+ {
+ /* Enable interrupts */
+ __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+ }
+ else
+ {
+ /* Process locked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+ }
+ /* Return function status */
+ return HAL_OK;
+}
+/**
+ * @brief Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp)
+{
+ __IO uint32_t count = 0U;
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ }
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Key preparation for ECB/CBC */
+ if (hcryp->Init.Algorithm != CRYP_AES_CTR)
+ {
+ /* change ALGOMODE to key preparation for decryption*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, CRYP_CR_ALGOMODE_AES_KEY);
+
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Wait for BUSY flag to be raised */
+ count = CRYP_TIMEOUT_KEYPREPARATION;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ } while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY));
+
+ /* Turn back to ALGOMODE of the configuration */
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_ALGOMODE, hcryp->Init.Algorithm);
+ }
+ else /*Algorithm CTR */
+ {
+ /* Set the Key*/
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+ }
+
+ if (hcryp->Init.Algorithm != CRYP_AES_ECB)
+ {
+ /* Set the Initialization Vector*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
+ }
+} /* if (DoKeyIVConfig == 1U) */
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ if (hcryp->Size != 0U)
+ {
+ /* Set the input and output addresses and start DMA transfer */
+ CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size / 4U), (uint32_t)(hcryp->pCrypOutBuffPtr));
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+
+/**
+ * @brief DMA CRYP input data process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma)
+{
+ CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit
+ in the DMACR register */
+ hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN);
+
+ /* Call input data transfer complete callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered Input complete callback*/
+ hcryp->InCpltCallback(hcryp);
+#else
+ /*Call legacy weak Input complete callback*/
+ HAL_CRYP_InCpltCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA CRYP output data process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma)
+{
+ uint32_t count;
+ uint32_t npblb;
+ uint32_t lastwordsize;
+ uint32_t temp; /* Temporary CrypOutBuff */
+ uint32_t temp_cr_algodir;
+ CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+
+ /* Disable the DMA transfer for output FIFO */
+ hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN);
+
+ /* Last block transfer in case of GCM or CCM with Size not %16*/
+ if (((hcryp->Size) % 16U) != 0U)
+ {
+ /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA */
+ hcryp->CrypInCount = (hcryp->Size / 16U) * 4U ;
+ hcryp->CrypOutCount = hcryp->CrypInCount;
+
+ /* Compute the number of padding bytes in last block of payload */
+ npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
+
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Case of AES GCM payload encryption or AES CCM payload decryption to get right tag */
+ temp_cr_algodir = hcryp->Instance->CR & CRYP_CR_ALGODIR;
+ if (((temp_cr_algodir == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM)) ||
+ ((temp_cr_algodir == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM)))
+ {
+ /* Disable the CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Specify the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
+
+ /* Enable CRYP to start the final phase */
+ __HAL_CRYP_ENABLE(hcryp);
+ }
+ }
+
+ /* Number of valid words (lastwordsize) in last block */
+ if ((npblb % 4U) == 0U)
+ {
+ lastwordsize = (16U - npblb) / 4U;
+ }
+ else
+ {
+ lastwordsize = ((16U - npblb) / 4U) + 1U;
+ }
+ /* Write the last input block in the IN FIFO */
+ for (count = 0U; count < lastwordsize; count ++)
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ }
+ /* Pad the data with zeros to have a complete block */
+ while (count < 4U)
+ {
+ hcryp->Instance->DIN = 0U;
+ count++;
+ }
+ /* Wait for OFNE flag to be raised */
+ count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
+
+ /*Read the output block from the output FIFO */
+ for (count = 0U; count < 4U; count++)
+ {
+ /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
+ temp = hcryp->Instance->DOUT;
+
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp;
+ hcryp->CrypOutCount++;
+ }
+ } /*End of last block transfer in case of GCM or CCM */
+
+ if ((hcryp->Init.Algorithm & CRYP_AES_GCM) != CRYP_AES_GCM)
+ {
+ /* Disable CRYP (not allowed in GCM)*/
+ __HAL_CRYP_DISABLE(hcryp);
+ }
+
+ /* Change the CRYP state to ready */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Call output data transfer complete callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered Output complete callback*/
+ hcryp->OutCpltCallback(hcryp);
+#else
+ /*Call legacy weak Output complete callback*/
+ HAL_CRYP_OutCpltCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA CRYP communication error callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void CRYP_DMAError(DMA_HandleTypeDef *hdma)
+{
+ CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Change the CRYP peripheral state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* DMA error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
+
+ /* Call error callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief Set the DMA configuration and start the DMA transfer
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param inputaddr: address of the input buffer
+ * @param Size: size of the input buffer, must be a multiple of 16.
+ * @param outputaddr: address of the output buffer
+ * @retval None
+ */
+static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr)
+{
+ /* Set the CRYP DMA transfer complete callback */
+ hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt;
+
+ /* Set the DMA input error callback */
+ hcryp->hdmain->XferErrorCallback = CRYP_DMAError;
+
+ /* Set the CRYP DMA transfer complete callback */
+ hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt;
+
+ /* Set the DMA output error callback */
+ hcryp->hdmaout->XferErrorCallback = CRYP_DMAError;
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Enable the input DMA Stream */
+ if (HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DIN, Size) != HAL_OK)
+ {
+ /* DMA error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
+
+ /* Call error callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+
+ /* Enable the output DMA Stream */
+ if (HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size) != HAL_OK)
+ {
+ /* DMA error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA;
+
+ /* Call error callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ /* Enable In/Out DMA request */
+ hcryp->Instance->DMACR = CRYP_DMACR_DOEN | CRYP_DMACR_DIEN;
+}
+
+/**
+ * @brief Process Data: Write Input data in polling mode and used in AES functions.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Timeout: Specify Timeout value
+ * @retval None
+ */
+static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
+{
+
+ uint32_t temp[4]; /* Temporary CrypOutBuff */
+ uint16_t incount; /* Temporary CrypInCount Value */
+ uint16_t outcount; /* Temporary CrypOutCount Value */
+ uint32_t i;
+
+ /*Temporary CrypOutCount Value*/
+ incount = hcryp->CrypInCount;
+
+ if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < ((hcryp->Size) / 4U)))
+ {
+ /* Write the input block in the IN FIFO */
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ }
+
+ /* Wait for OFNE flag to be raised */
+ if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state & error code*/
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < ((hcryp->Size) / 4U)))
+ {
+ /* Read the output block from the Output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
+ for (i = 0U; i < 4U; i++)
+ {
+ temp[i] = hcryp->Instance->DOUT;
+ }
+ i = 0U;
+ while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
+ {
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
+ hcryp->CrypOutCount++;
+ i++;
+ }
+ }
+}
+
+/**
+ * @brief Handle CRYP block input/output data handling under interruption.
+ * @note The function is called under interruption only, once
+ * interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module.
+ * @retval HAL status
+ */
+static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp)
+{
+ uint32_t temp[4]; /* Temporary CrypOutBuff */
+ uint16_t incount; /* Temporary CrypInCount Value */
+ uint16_t outcount; /* Temporary CrypOutCount Value */
+ uint32_t i;
+
+ if (hcryp->State == HAL_CRYP_STATE_BUSY)
+ {
+ /*Temporary CrypOutCount Value*/
+ incount = hcryp->CrypInCount;
+
+ if (((hcryp->Instance->SR & CRYP_FLAG_IFNF) != 0x0U) && (incount < (hcryp->Size / 4U)))
+ {
+ /* Write the input block in the IN FIFO */
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ if (hcryp->CrypInCount == (hcryp->Size / 4U))
+ {
+ /* Disable interrupts */
+ __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI);
+
+ /* Call the input data transfer complete callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered Input complete callback*/
+ hcryp->InCpltCallback(hcryp);
+#else
+ /*Call legacy weak Input complete callback*/
+ HAL_CRYP_InCpltCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ }
+
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ if (((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U) && (outcount < (hcryp->Size / 4U)))
+ {
+ /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
+ for (i = 0U; i < 4U; i++)
+ {
+ temp[i] = hcryp->Instance->DOUT;
+ }
+ i = 0U;
+ while(((hcryp->CrypOutCount < ((hcryp->Size)/4U))) && (i<4U))
+ {
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i];
+ hcryp->CrypOutCount++;
+ i++;
+ }
+ if (hcryp->CrypOutCount == (hcryp->Size / 4U))
+ {
+ /* Disable interrupts */
+ __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Disable CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Call output transfer complete callback */
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered Output complete callback*/
+ hcryp->OutCpltCallback(hcryp);
+#else
+ /*Call legacy weak Output complete callback*/
+ HAL_CRYP_OutCpltCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ }
+ }
+ else
+ {
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ /* Busy error code field */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY;
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief Writes Key in Key registers.
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param KeySize: Size of Key
+ * @retval None
+ */
+static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize)
+{
+ switch (KeySize)
+ {
+ case CRYP_KEYSIZE_256B:
+ hcryp->Instance->K0LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K0RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 6);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 7);
+ break;
+ case CRYP_KEYSIZE_192B:
+ hcryp->Instance->K1LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K1RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 4);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 5);
+ break;
+ case CRYP_KEYSIZE_128B:
+ hcryp->Instance->K2LR = *(uint32_t *)(hcryp->Init.pKey);
+ hcryp->Instance->K2RR = *(uint32_t *)(hcryp->Init.pKey + 1);
+ hcryp->Instance->K3LR = *(uint32_t *)(hcryp->Init.pKey + 2);
+ hcryp->Instance->K3RR = *(uint32_t *)(hcryp->Init.pKey + 3);
+
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
+{
+ uint32_t tickstart;
+ uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
+ uint32_t npblb ;
+ uint32_t temp[4]; /* Temporary CrypOutBuff */
+ uint32_t index ;
+ uint32_t lastwordsize ;
+ uint16_t outcount; /* Temporary CrypOutCount Value */
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
+ }
+ }
+ else
+ {
+ hcryp->SizesSum = hcryp->Size;
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Reset CrypHeaderCount */
+ hcryp->CrypHeaderCount = 0U;
+
+ /****************************** Init phase **********************************/
+
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
+
+ /* Set the key */
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /*Wait for the CRYPEN bit to be cleared*/
+ while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ /************************ Header phase *************************************/
+
+ if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /*************************Payload phase ************************************/
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Disable the CRYP peripheral */
+ __HAL_CRYP_DISABLE(hcryp);
+
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Set to 0 the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
+ }
+
+ /* Select payload phase once the header phase is performed */
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+} /* if (DoKeyIVConfig == 1U) */
+
+ if ((hcryp->Size % 16U) != 0U)
+ {
+ /* recalculate wordsize */
+ wordsize = ((wordsize / 4U) * 4U) ;
+ }
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ /* Write input data and get output Data */
+ while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
+ {
+ /* Write plain data and get cipher data */
+ CRYP_AES_ProcessData(hcryp, Timeout);
+
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state & error code */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ if ((hcryp->Size % 16U) != 0U)
+ {
+
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Compute the number of padding bytes in last block of payload */
+ npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
+
+ /* Set Npblb in case of AES GCM payload encryption to get right tag*/
+ if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
+ {
+ /* Disable the CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Specify the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
+
+ /* Enable CRYP to start the final phase */
+ __HAL_CRYP_ENABLE(hcryp);
+ }
+ /* Number of valid words (lastwordsize) in last block */
+ if ((npblb % 4U) == 0U)
+ {
+ lastwordsize = (16U - npblb) / 4U;
+ }
+ else
+ {
+ lastwordsize = ((16U - npblb) / 4U) + 1U;
+ }
+
+ /* Write the last input block in the IN FIFO */
+ for (index = 0U; index < lastwordsize; index ++)
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ }
+
+ /* Pad the data with zeros to have a complete block */
+ while (index < 4U)
+ {
+ hcryp->Instance->DIN = 0U;
+ index++;
+ }
+
+ /* Wait for OFNE flag to be raised */
+ if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcryp);
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+
+ /*Read the output block from the output FIFO */
+ if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
+ {
+ for (index = 0U; index < 4U; index++)
+ {
+ /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
+ temp[index] = hcryp->Instance->DOUT;
+ }
+ for (index=0; index<lastwordsize; index++)
+ {
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index];
+ hcryp->CrypOutCount++;
+ }
+ }
+ }
+#if !defined (CRYP_VER_2_2)
+ else /* Workaround to be used */
+ {
+ /* Workaround 2 for STM32H7 below rev.B To generate correct TAG only when size of the last block of
+ payload is inferior to 128 bits, in case of GCM encryption or CCM decryption*/
+ CRYP_Workaround(hcryp, Timeout);
+ } /* end of NPBLB or Workaround*/
+#endif /*End of not defined CRYP_VER_2_2*/
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp)
+{
+ __IO uint32_t count = 0U;
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
+ }
+ }
+ else
+ {
+ hcryp->SizesSum = hcryp->Size;
+ }
+
+ /* Configure Key, IV and process message (header and payload) */
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Reset CrypHeaderCount */
+ hcryp->CrypHeaderCount = 0U;
+
+ /******************************* Init phase *********************************/
+
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
+
+ /* Set the key */
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /*Wait for the CRYPEN bit to be cleared*/
+ count = CRYP_TIMEOUT_GCMCCMINITPHASE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
+
+ /***************************** Header phase *********************************/
+
+ /* Select header phase */
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
+ } /* end of if (DoKeyIVConfig == 1U) */
+ /* Enable interrupts */
+ __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
+{
+ __IO uint32_t count = 0U;
+ uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
+ uint32_t index;
+ uint32_t npblb;
+ uint32_t lastwordsize;
+ uint32_t temp[4]; /* Temporary CrypOutBuff */
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
+ }
+ }
+ else
+ {
+ hcryp->SizesSum = hcryp->Size;
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Reset CrypHeaderCount */
+ hcryp->CrypHeaderCount = 0U;
+
+ /*************************** Init phase ************************************/
+
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
+
+ /* Set the key */
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/
+ hcryp->Instance->IV0LR = *(uint32_t *)(hcryp->Init.pInitVect);
+ hcryp->Instance->IV0RR = *(uint32_t *)(hcryp->Init.pInitVect + 1);
+ hcryp->Instance->IV1LR = *(uint32_t *)(hcryp->Init.pInitVect + 2);
+ hcryp->Instance->IV1RR = *(uint32_t *)(hcryp->Init.pInitVect + 3);
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /*Wait for the CRYPEN bit to be cleared*/
+ count = CRYP_TIMEOUT_GCMCCMINITPHASE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
+
+ /************************ Header phase *************************************/
+
+ if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /************************ Payload phase ************************************/
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Disable the CRYP peripheral */
+ __HAL_CRYP_DISABLE(hcryp);
+
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Set to 0 the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
+ }
+
+ /* Select payload phase once the header phase is performed */
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
+
+} /* if (DoKeyIVConfig == 1U) */
+
+ if (hcryp->Size == 0U)
+ {
+ /* Process unLocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Change the CRYP state and phase */
+ hcryp->State = HAL_CRYP_STATE_READY;
+ }
+ else if (hcryp->Size >= 16U)
+ {
+ /* for STM32H7 below rev.B : Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption:
+ Workaround is implemented in polling mode, so if last block of payload <128bit don't use DMA mode otherwise TAG is incorrectly generated */
+
+ /*DMA transfer must not include the last block in case of Size is not %16 */
+ wordsize = wordsize - (wordsize % 4U);
+
+ /*DMA transfer */
+ CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
+ }
+ else /* length of input data is < 16 */
+ {
+ /* Compute the number of padding bytes in last block of payload */
+ npblb = 16U - (uint32_t)hcryp->Size;
+
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Set Npblb in case of AES GCM payload encryption to get right tag*/
+ if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_ENCRYPT)
+ {
+ /* Specify the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
+ }
+ }
+ /* Enable CRYP to start the final phase */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Number of valid words (lastwordsize) in last block */
+ if ((npblb % 4U) == 0U)
+ {
+ lastwordsize = (16U - npblb) / 4U;
+ }
+ else
+ {
+ lastwordsize = ((16U - npblb) / 4U) + 1U;
+ }
+
+ /* Write the last input block in the IN FIFO */
+ for (index = 0; index < lastwordsize; index ++)
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ }
+
+ /* Pad the data with zeros to have a complete block */
+ while (index < 4U)
+ {
+ hcryp->Instance->DIN = 0U;
+ index++;
+ }
+
+ /* Wait for OFNE flag to be raised */
+ count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
+
+ /*Read the output block from the output FIFO */
+ for (index = 0U; index < 4U; index++)
+ {
+ /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
+ temp[index] = hcryp->Instance->DOUT;
+ }
+ for (index=0; index<lastwordsize; index++)
+ {
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
+ hcryp->CrypOutCount++;
+ }
+
+ /* Change the CRYP state to ready */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+
+/**
+ * @brief AES CCM encryption/decryption processing in polling mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout)
+{
+ uint32_t tickstart;
+ uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U;
+ uint32_t npblb ;
+ uint32_t lastwordsize ;
+ uint32_t temp[4] ; /* Temporary CrypOutBuff */
+ uint32_t index ;
+ uint16_t outcount; /* Temporary CrypOutCount Value */
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
+ }
+ }
+ else
+ {
+ hcryp->SizesSum = hcryp->Size;
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Reset CrypHeaderCount */
+ hcryp->CrypHeaderCount = 0U;
+
+ /********************** Init phase ******************************************/
+
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
+
+ /* Set the key */
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Set the initialization vector (IV) with CTR1 information */
+ hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
+ hcryp->Instance->IV0RR = hcryp->Init.B0[1];
+ hcryp->Instance->IV1LR = hcryp->Init.B0[2];
+ hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+
+#if defined (CRYP_VER_2_2)
+ {
+ /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
+ }
+#else
+ if (hcryp->Version >= REV_ID_B)
+ {
+ /* for STM32H7 rev.B and above Write B0 packet into CRYP_DR*/
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
+ }
+ else /* data has to be swapped according to the DATATYPE */
+ {
+ if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
+ {
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
+ }
+ else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
+ {
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
+ }
+ else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
+ {
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
+ }
+ else
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
+ }
+ }
+#endif
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /*Wait for the CRYPEN bit to be cleared*/
+ while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ /************************* Header phase *************************************/
+ /* Header block(B1) : associated data length expressed in bytes concatenated
+ with Associated Data (A)*/
+
+ if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ /********************** Payload phase ***************************************/
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Disable the CRYP peripheral */
+ __HAL_CRYP_DISABLE(hcryp);
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Set to 0 the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
+ }
+
+ /* Select payload phase once the header phase is performed */
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+
+} /* if (DoKeyIVConfig == 1U) */
+
+ if ((hcryp->Size % 16U) != 0U)
+ {
+ /* recalculate wordsize */
+ wordsize = ((wordsize / 4U) * 4U) ;
+ }
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ /* Write input data and get output data */
+ while ((hcryp->CrypInCount < wordsize) && (outcount < wordsize))
+ {
+ /* Write plain data and get cipher data */
+ CRYP_AES_ProcessData(hcryp, Timeout);
+
+ /*Temporary CrypOutCount Value*/
+ outcount = hcryp->CrypOutCount;
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ if ((hcryp->Size % 16U) != 0U)
+ {
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Compute the number of padding bytes in last block of payload */
+ npblb = ((((uint32_t)(hcryp->Size) / 16U) + 1U) * 16U) - (uint32_t)(hcryp->Size);
+
+ if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
+ {
+ /* Disable the CRYP */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Set Npblb in case of AES CCM payload decryption to get right tag */
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
+
+ /* Enable CRYP to start the final phase */
+ __HAL_CRYP_ENABLE(hcryp);
+ }
+
+ /* Number of valid words (lastwordsize) in last block */
+ if ((npblb % 4U) == 0U)
+ {
+ lastwordsize = (16U - npblb) / 4U;
+ }
+ else
+ {
+ lastwordsize = ((16U - npblb) / 4U) + 1U;
+ }
+
+ /* Write the last input block in the IN FIFO */
+ for (index = 0U; index < lastwordsize; index ++)
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ }
+
+ /* Pad the data with zeros to have a complete block */
+ while (index < 4U)
+ {
+ hcryp->Instance->DIN = 0U;
+ index++;
+ }
+
+ /* Wait for OFNE flag to be raised */
+ if (CRYP_WaitOnOFNEFlag(hcryp, Timeout) != HAL_OK)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hcryp);
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+
+ /*Read the output block from the output FIFO */
+ if ((hcryp->Instance->SR & CRYP_FLAG_OFNE) != 0x0U)
+ {
+ for (index = 0U; index < 4U; index++)
+ {
+ /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
+ temp[index] = hcryp->Instance->DOUT;
+ }
+ for (index=0; index<lastwordsize; index++)
+ {
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
+ hcryp->CrypOutCount++;
+ }
+ }
+ }
+#if !defined (CRYP_VER_2_2)
+ else /* No NPBLB, Workaround to be used */
+ {
+ /* CRYP Workaround : CRYP1 generates correct TAG during CCM decryption only when ciphertext blocks size is multiple of
+ 128 bits. If lthe size of the last block of payload is inferior to 128 bits, when CCM decryption
+ is selected, then the TAG message will be wrong.*/
+ CRYP_Workaround(hcryp, Timeout);
+ }
+#endif /*End of not defined CRYP_VER_2_2*/
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief AES CCM encryption/decryption process in interrupt mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp)
+{
+ __IO uint32_t count = 0U;
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
+ }
+ }
+ else
+ {
+ hcryp->SizesSum = hcryp->Size;
+ }
+
+ /* Configure Key, IV and process message (header and payload) */
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Reset CrypHeaderCount */
+ hcryp->CrypHeaderCount = 0U;
+
+ /************ Init phase ************/
+
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
+
+ /* Set the key */
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Set the initialization vector (IV) with CTR1 information */
+ hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
+ hcryp->Instance->IV0RR = hcryp->Init.B0[1];
+ hcryp->Instance->IV1LR = hcryp->Init.B0[2];
+ hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /*Write the B0 packet into CRYP_DR*/
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* for STM32H7 rev.B and above data has not to be swapped */
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
+ }
+#if !defined (CRYP_VER_2_2)
+ else /* data has to be swapped according to the DATATYPE */
+ {
+ if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
+ {
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
+ }
+ else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
+ {
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
+ }
+ else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
+ {
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
+ }
+ else
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
+ }
+ }
+#endif /*End of not defined CRYP_VER_2_2*/
+ /*Wait for the CRYPEN bit to be cleared*/
+ count = CRYP_TIMEOUT_GCMCCMINITPHASE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
+
+ /* Select header phase */
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER);
+} /* end of if (DoKeyIVConfig == 1U) */
+ /* Enable interrupts */
+ __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI);
+
+ /* Enable CRYP */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Return function status */
+ return HAL_OK;
+}
+/**
+ * @brief AES CCM encryption/decryption process in DMA mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp)
+{
+ __IO uint32_t count = 0U;
+ uint32_t wordsize = (uint32_t)(hcryp->Size) / 4U ;
+ uint32_t index;
+ uint32_t npblb;
+ uint32_t lastwordsize;
+ uint32_t temp[4]; /* Temporary CrypOutBuff */
+ uint32_t DoKeyIVConfig = 1U; /* By default, carry out peripheral Key and IV configuration */
+
+ if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE)
+ {
+ if (hcryp->KeyIVConfig == 1U)
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has already been done, skip it */
+ DoKeyIVConfig = 0U;
+ hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */
+ }
+ else
+ {
+ /* If the Key and IV configuration has to be done only once
+ and if it has not been done already, do it and set KeyIVConfig
+ to keep track it won't have to be done again next time */
+ hcryp->KeyIVConfig = 1U;
+ hcryp->SizesSum = hcryp->Size; /* Merely store payload length */
+ }
+ }
+ else
+ {
+ hcryp->SizesSum = hcryp->Size;
+ }
+
+ if (DoKeyIVConfig == 1U)
+ {
+ /* Reset CrypHeaderCount */
+ hcryp->CrypHeaderCount = 0U;
+
+ /************************** Init phase **************************************/
+
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT);
+
+ /* Set the key */
+ CRYP_SetKey(hcryp, hcryp->Init.KeySize);
+
+ /* Set the initialization vector (IV) with CTR1 information */
+ hcryp->Instance->IV0LR = (hcryp->Init.B0[0]) & CRYP_CCM_CTR1_0;
+ hcryp->Instance->IV0RR = hcryp->Init.B0[1];
+ hcryp->Instance->IV1LR = hcryp->Init.B0[2];
+ hcryp->Instance->IV1RR = (hcryp->Init.B0[3] & CRYP_CCM_CTR1_1) | CRYP_CCM_CTR1_2;
+
+ /* Enable the CRYP peripheral */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /*Write the B0 packet into CRYP_DR*/
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* for STM32H7 rev.B and above data has not to be swapped */
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
+ }
+#if !defined (CRYP_VER_2_2)
+ else /* data has to be swapped according to the DATATYPE */
+ {
+ if (hcryp->Init.DataType == CRYP_DATATYPE_8B)
+ {
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 1));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 2));
+ hcryp->Instance->DIN = __REV(*(uint32_t *)(hcryp->Init.B0 + 3));
+ }
+ else if (hcryp->Init.DataType == CRYP_DATATYPE_16B)
+ {
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 1), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 2), 16);
+ hcryp->Instance->DIN = __ROR(*(uint32_t *)(hcryp->Init.B0 + 3), 16);
+ }
+ else if (hcryp->Init.DataType == CRYP_DATATYPE_1B)
+ {
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 1));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 2));
+ hcryp->Instance->DIN = __RBIT(*(uint32_t *)(hcryp->Init.B0 + 3));
+ }
+ else
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 1);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 2);
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->Init.B0 + 3);
+ }
+ }
+#endif /*End of not defined CRYP_VER_2_2*/
+ /*Wait for the CRYPEN bit to be cleared*/
+ count = CRYP_TIMEOUT_GCMCCMINITPHASE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ return HAL_ERROR;
+ }
+ } while ((hcryp->Instance->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN);
+
+ /********************* Header phase *****************************************/
+
+ if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /******************** Payload phase *****************************************/
+
+ /* Set the phase */
+ hcryp->Phase = CRYP_PHASE_PROCESS;
+
+ /* Disable the CRYP peripheral */
+ __HAL_CRYP_DISABLE(hcryp);
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Set to 0 the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, 0U);
+ }
+
+ /* Select payload phase once the header phase is performed */
+ CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD);
+ } /* if (DoKeyIVConfig == 1U) */
+
+ if (hcryp->Size == 0U)
+ {
+ /* Process unLocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Change the CRYP state and phase */
+ hcryp->State = HAL_CRYP_STATE_READY;
+ }
+ else if (hcryp->Size >= 16U)
+ {
+ /* for STM32H7 below rev.B :: Size should be %4 otherwise Tag will be incorrectly generated for CCM Decryption, Workaround is implemented in polling mode*/
+ /*DMA transfer must not include the last block in case of Size is not %16 */
+ wordsize = wordsize - (wordsize % 4U);
+
+ /*DMA transfer */
+ CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t) wordsize, (uint32_t)(hcryp->pCrypOutBuffPtr));
+ }
+ else /* length of input data is < 16U */
+ {
+ /* Compute the number of padding bytes in last block of payload */
+ npblb = 16U - (uint32_t)(hcryp->Size);
+
+#if !defined (CRYP_VER_2_2)
+ if (hcryp->Version >= REV_ID_B)
+#endif /*End of not defined CRYP_VER_2_2*/
+ {
+ /* Set Npblb in case of AES CCM payload decryption to get right tag*/
+ if ((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT)
+ {
+ /* Specify the number of non-valid bytes using NPBLB register*/
+ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_NPBLB, npblb << 20);
+ }
+ }
+ /* Enable CRYP to start the final phase */
+ __HAL_CRYP_ENABLE(hcryp);
+
+ /* Number of valid words (lastwordsize) in last block */
+ if ((npblb % 4U) == 0U)
+ {
+ lastwordsize = (16U - npblb) / 4U;
+ }
+ else
+ {
+ lastwordsize = ((16U - npblb) / 4U) + 1U;
+ }
+
+ /* Write the last input block in the IN FIFO */
+ for (index = 0U; index < lastwordsize; index ++)
+ {
+ hcryp->Instance->DIN = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+ hcryp->CrypInCount++;
+ }
+
+ /* Pad the data with zeros to have a complete block */
+ while (index < 4U)
+ {
+ hcryp->Instance->DIN = 0U;
+ index++;
+ }
+
+ /* Wait for OFNE flag to be raised */
+ count = CRYP_TIMEOUT_GCMCCMHEADERPHASE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ /* Disable the CRYP peripheral clock */
+ __HAL_CRYP_DISABLE(hcryp);
+
+ /* Change state */
+ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT;
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ hcryp->ErrorCallback(hcryp);
+#else
+ /*Call legacy weak error callback*/
+ HAL_CRYP_ErrorCallback(hcryp);
+#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */
+ }
+ } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE));
+
+ /*Read the output block from the output FIFO */
+ for (index = 0U; index < 4U; index++)
+ {
+ /* Read the output block from the output FIFO and put them in temporary buffer then get CrypOutBuff from temporary buffer */
+ temp[index] = hcryp->Instance->DOUT;
+ }
+ for (index=0; index<lastwordsize; index++)
+ {
+ *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index];
+ hcryp->CrypOutCount++;
+ }
+
+ /* Change the CRYP state to ready */
+ hcryp->State = HAL_CRYP_STATE_READY;
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Sets the payload phase in interrupt mode
+ * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains
+ * the configuration information for CRYP module
+ * @retval state
+ */
+static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp)
+{
+ uint32_t loopcounter;
+ uint32_t temp[4]; /* Temporary CrypOutBuff */
+ uint32_t lastwordsize;
+ uint32_t npblb;
+ uint32_t temp_cr_algodir;
+ uint8_t negative = 0U;
+ uint32_t i;
+
+ /***************************** Payload phase *******************************/
+
+ if ((hcryp->Size / 4U) < hcryp->CrypInCount)
+ {
+ negative = 1U;
+ }
+
+ if (hcryp->Size == 0U)
+ {
+ /* Disable interrupts */
+ __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI);
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hcryp);
+
+ /* Change the CRYP state */
+ hcryp->State = HAL_CRYP_STATE_READY;
+ }
+
+ else if ((((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) &&