diff --git a/.mxproject b/.mxproject
index f90a1ce..37c7c2b 100644
--- a/.mxproject
+++ b/.mxproject
@@ -1,17 +1,17 @@
[PreviousLibFiles]
-LibFiles=Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f103xe.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
+LibFiles=Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_i2c.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_i2c.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_i2c.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_i2c.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_i2c.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f103xe.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
[]
SourceFiles=;;
[PreviousUsedKeilFiles]
-SourceFiles=..\Src\main.c;..\Src\gpio.c;..\Src\tim.c;..\Src\stm32f1xx_it.c;..\Src\stm32f1xx_hal_msp.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\\Src\system_stm32f1xx.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\\Src\system_stm32f1xx.c;;;
+SourceFiles=..\Src\main.c;..\Src\gpio.c;..\Src\i2c.c;..\Src\spi.c;..\Src\tim.c;..\Src\usart.c;..\Src\stm32f1xx_it.c;..\Src\stm32f1xx_hal_msp.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_i2c.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\\Src\system_stm32f1xx.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_i2c.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\\Src\system_stm32f1xx.c;;;
HeaderPath=..\Drivers\STM32F1xx_HAL_Driver\Inc;..\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F1xx\Include;..\Drivers\CMSIS\Include;..\Inc;
CDefines=USE_HAL_DRIVER;STM32F103xE;USE_HAL_DRIVER;USE_HAL_DRIVER;
[PreviousGenFiles]
HeaderPath=..\Inc
-HeaderFiles=gpio.h;tim.h;stm32f1xx_it.h;stm32f1xx_hal_conf.h;main.h;
+HeaderFiles=gpio.h;i2c.h;spi.h;tim.h;usart.h;stm32f1xx_it.h;stm32f1xx_hal_conf.h;main.h;
SourcePath=..\Src
-SourceFiles=gpio.c;tim.c;stm32f1xx_it.c;stm32f1xx_hal_msp.c;main.c;
+SourceFiles=gpio.c;i2c.c;spi.c;tim.c;usart.c;stm32f1xx_it.c;stm32f1xx_hal_msp.c;main.c;
diff --git a/.vscode/settings.json b/.vscode/settings.json
index fc4c15b..70e34ec 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,3 @@
{
- "C_Cpp.errorSquiggles": "enabled"
+ "C_Cpp.errorSquiggles": "disabled"
}
\ No newline at end of file
diff --git a/App/Inc/key.h b/App/Inc/key.h
new file mode 100644
index 0000000..205b4d8
--- /dev/null
+++ b/App/Inc/key.h
@@ -0,0 +1,13 @@
+#ifndef _KEY_H
+#define _KEY_H
+
+void Key_Init(void);
+void Key_Scan(void);
+
+extern int Key_State[3]; // 使用一个三维数组描述K1-K3的状态,1为按下,0为抬起,例:[1 0 0]->[K1按下 K2抬起 K3抬起]
+extern int Key_Mode[3]; // 模式0:按住执行,抬起停止;
+ // 模式1:只要按下就执行,不考虑抬起;
+ // 模式2:完成(按下+抬起)的动作才执行。
+ // K1, K2, K3三者模式独立
+
+#endif
diff --git a/App/Src/key.c b/App/Src/key.c
new file mode 100644
index 0000000..5d52680
--- /dev/null
+++ b/App/Src/key.c
@@ -0,0 +1,258 @@
+#include "key.h"
+#include "main.h"
+
+int Key_State[3]; // 使用一个三维数组描述K1-K3的状态,1为按下,0为抬起,例:[1 0 0]->[K1按下 K2抬起 K3抬起]
+int Key_Mode[3]; // 模式0:按住执行,抬起停止;
+ // 模式1:只要按下就执行,不考虑抬起;
+ // 模式2:完成(按下+抬起)的动作才执行。
+ // K1, K2, K3三者模式独立
+int Key_Busy[3] = {0, 0, 0};
+
+void Key_Init(void) // 按键状态&模式初始化
+{
+ Key_State[0] = 0;
+ Key_State[1] = 0;
+ Key_State[2] = 1;
+ Key_Mode[0] = 0;
+ Key_Mode[1] = 2;
+ Key_Mode[2] = 2;
+}
+
+void Key_Scan(void) // 扫描K1-K3的状态
+{
+ int i = 0;
+ if (Key_State[2] == 0)//K3使能K1,K2 begin
+ {
+ /*********************************** K1 begin **************************************/
+ // mode 0 begin
+ if (Key_Mode[0] == 0)
+ {
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
+ {
+ Key_State[0] = 1;
+ }
+ }
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 抬起延时防抖
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
+ {
+ Key_State[0] = 0;
+ }
+ }
+ }
+ // mode 0 end
+
+ // mode 1 begin
+ if (Key_Mode[0] == 1)
+ {
+ if ((HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0) && (Key_Busy[0] == 0))
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
+ {
+ Key_State[0] = !Key_State[0];
+ Key_Busy[0] = 1;
+ }
+ }
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 抬起延时防抖
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
+ {
+ Key_Busy[0] = 0;
+ }
+ }
+ }
+ // mode 1 end
+
+ // mode 2 begin
+ if (Key_Mode[0] == 2)
+ {
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0)
+ {
+ Key_Busy[0] = 1; // 完成按下
+ }
+ }
+ if ((HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1) && (Key_Busy[0] == 1))
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
+ {
+ // 完成抬起
+ Key_State[0] = !Key_State[0];
+ Key_Busy[0] = 0;
+ }
+ }
+ }
+ // mode 2 end
+ /*********************************** K1 end **************************************/
+
+ /*********************************** K2 begin **************************************/
+ // mode 0 begin
+ if (Key_Mode[1] == 0)
+ {
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 0)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 0)
+ {
+ Key_State[1] = 1;
+ }
+ }
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 抬起延时防抖
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
+ {
+ Key_State[1] = 0;
+ }
+ }
+ }
+ // mode 0 end
+
+ // mode 1 begin
+ if (Key_Mode[1] == 1)
+ {
+ if ((HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 0) && (Key_Busy[1] == 0))
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 0)
+ {
+ Key_State[1] = !Key_State[1];
+ Key_Busy[1] = 1;
+ }
+ }
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 抬起延时防抖
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
+ {
+ Key_Busy[1] = 0;
+ }
+ }
+ }
+ // mode 1 end
+
+ // mode 2 begin
+ if (Key_Mode[1] == 2)
+ {
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 0)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 0)
+ {
+ Key_Busy[1] = 1; // 完成按下
+ }
+ }
+ if ((HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1) && (Key_Busy[1] == 1))
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
+ {
+ // 完成抬起
+ Key_Mode[0] = (Key_Mode[0] + 1) * ((Key_Mode[0] + 1) < 3); // 使用K2切换K1模式
+ Key_State[1] = !Key_State[1];
+ Key_Busy[1] = 0;
+ }
+ }
+ }
+ // mode 2 end
+ /*********************************** K2 end **************************************/
+ }//K3使能K1,K2 begin
+
+ /*********************************** K3 begin **************************************/
+ // mode 0 begin
+ if (Key_Mode[2] == 0)
+ {
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 0)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 0)
+ {
+ Key_State[2] = 1;
+ }
+ }
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 1)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 抬起延时防抖
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 1)
+ {
+ Key_State[2] = 0;
+ }
+ }
+ }
+ // mode 0 end
+
+ // mode 1 begin
+ if (Key_Mode[2] == 1)
+ {
+ if ((HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 0) && (Key_Busy[2] == 0))
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 0)
+ {
+ Key_State[2] = !Key_State[2];
+ Key_Busy[2] = 1;
+ }
+ }
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 1)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 抬起延时防抖
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 1)
+ {
+ Key_Busy[2] = 0;
+ }
+ }
+ }
+ // mode 1 end
+
+ // mode 2 begin
+ if (Key_Mode[2] == 2)
+ {
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 0)
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 0)
+ {
+ Key_Busy[2] = 1; // 完成按下
+ }
+ }
+ if ((HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 1) && (Key_Busy[2] == 1))
+ {
+ for (i = 0; i < 10000; i++)
+ ; // 按下延时防抖
+ if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == 1)
+ {
+ // 完成抬起
+ Key_State[2] = !Key_State[2];
+ Key_Busy[2] = 0;
+ }
+ }
+ }
+ // mode 2 end
+ /*********************************** K3 end **************************************/
+}
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
new file mode 100644
index 0000000..e48232d
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
@@ -0,0 +1,738 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_i2c.h
+ * @author MCD Application Team
+ * @brief Header file of I2C HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_I2C_H
+#define __STM32F1xx_HAL_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup I2C
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup I2C_Exported_Types I2C Exported Types
+ * @{
+ */
+
+/** @defgroup I2C_Configuration_Structure_definition I2C Configuration Structure definition
+ * @brief I2C Configuration Structure definition
+ * @{
+ */
+typedef struct
+{
+ uint32_t ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz */
+
+ uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
+ This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
+
+ uint32_t OwnAddress1; /*!< Specifies the first device own address.
+ This parameter can be a 7-bit or 10-bit address. */
+
+ uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
+ This parameter can be a value of @ref I2C_addressing_mode */
+
+ uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
+ This parameter can be a value of @ref I2C_dual_addressing_mode */
+
+ uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
+ This parameter can be a 7-bit address. */
+
+ uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
+ This parameter can be a value of @ref I2C_general_call_addressing_mode */
+
+ uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
+ This parameter can be a value of @ref I2C_nostretch_mode */
+
+} I2C_InitTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_state_structure_definition HAL state structure definition
+ * @brief HAL State structure definition
+ * @note HAL I2C State value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : Abort (Abort user request on going)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 Peripheral initialization status
+ * 0 : Reset (Peripheral not initialized)
+ * 1 : Init done (Peripheral initialized and ready to use. HAL I2C Init function called)
+ * b4 (not used)
+ * x : Should be set to 0
+ * b3
+ * 0 : Ready or Busy (No Listen mode ongoing)
+ * 1 : Listen (Peripheral in Address Listen Mode)
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (Peripheral busy with some configuration or internal operations)
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * @{
+ */
+typedef enum
+{
+ HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */
+ HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */
+ HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */
+ HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */
+ HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
+ HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */
+ HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission
+ process is ongoing */
+ HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception
+ process is ongoing */
+ HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */
+ HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */
+ HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */
+
+} HAL_I2C_StateTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_mode_structure_definition HAL mode structure definition
+ * @brief HAL Mode structure definition
+ * @note HAL I2C Mode value coding follow below described bitmap :\n
+ * b7 (not used)\n
+ * x : Should be set to 0\n
+ * b6\n
+ * 0 : None\n
+ * 1 : Memory (HAL I2C communication is in Memory Mode)\n
+ * b5\n
+ * 0 : None\n
+ * 1 : Slave (HAL I2C communication is in Slave Mode)\n
+ * b4\n
+ * 0 : None\n
+ * 1 : Master (HAL I2C communication is in Master Mode)\n
+ * b3-b2-b1-b0 (not used)\n
+ * xxxx : Should be set to 0000
+ * @{
+ */
+typedef enum
+{
+ HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
+ HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
+ HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
+ HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
+
+} HAL_I2C_ModeTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Error_Code_definition I2C Error Code definition
+ * @brief I2C Error Code definition
+ * @{
+ */
+#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */
+#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */
+#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */
+#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */
+#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */
+#define HAL_I2C_ERROR_SIZE 0x00000040U /*!< Size Management error */
+#define HAL_I2C_ERROR_DMA_PARAM 0x00000080U /*!< DMA Parameter Error */
+#define HAL_I2C_WRONG_START 0x00000200U /*!< Wrong start Error */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+#define HAL_I2C_ERROR_INVALID_CALLBACK 0x00000100U /*!< Invalid Callback error */
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_handle_Structure_definition I2C handle Structure definition
+ * @brief I2C handle Structure definition
+ * @{
+ */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+typedef struct __I2C_HandleTypeDef
+#else
+typedef struct
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+{
+ I2C_TypeDef *Instance; /*!< I2C registers base address */
+
+ I2C_InitTypeDef Init; /*!< I2C communication parameters */
+
+ uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
+
+ uint16_t XferSize; /*!< I2C transfer size */
+
+ __IO uint16_t XferCount; /*!< I2C transfer counter */
+
+ __IO uint32_t XferOptions; /*!< I2C transfer options */
+
+ __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode
+ context for internal usage */
+
+ DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< I2C locking object */
+
+ __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
+
+ __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
+
+ __IO uint32_t ErrorCode; /*!< I2C Error code */
+
+ __IO uint32_t Devaddress; /*!< I2C Target device address */
+
+ __IO uint32_t Memaddress; /*!< I2C Target memory address */
+
+ __IO uint32_t MemaddSize; /*!< I2C Target memory address size */
+
+ __IO uint32_t EventCount; /*!< I2C Event counter */
+
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ void (* MasterTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Master Tx Transfer completed callback */
+ void (* MasterRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Master Rx Transfer completed callback */
+ void (* SlaveTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Slave Tx Transfer completed callback */
+ void (* SlaveRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Slave Rx Transfer completed callback */
+ void (* ListenCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Listen Complete callback */
+ void (* MemTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Memory Tx Transfer completed callback */
+ void (* MemRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Memory Rx Transfer completed callback */
+ void (* ErrorCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Error callback */
+ void (* AbortCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Abort callback */
+
+ void (* AddrCallback)(struct __I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); /*!< I2C Slave Address Match callback */
+
+ void (* MspInitCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Msp Init callback */
+ void (* MspDeInitCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Msp DeInit callback */
+
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+} I2C_HandleTypeDef;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+/**
+ * @brief HAL I2C Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_I2C_MASTER_TX_COMPLETE_CB_ID = 0x00U, /*!< I2C Master Tx Transfer completed callback ID */
+ HAL_I2C_MASTER_RX_COMPLETE_CB_ID = 0x01U, /*!< I2C Master Rx Transfer completed callback ID */
+ HAL_I2C_SLAVE_TX_COMPLETE_CB_ID = 0x02U, /*!< I2C Slave Tx Transfer completed callback ID */
+ HAL_I2C_SLAVE_RX_COMPLETE_CB_ID = 0x03U, /*!< I2C Slave Rx Transfer completed callback ID */
+ HAL_I2C_LISTEN_COMPLETE_CB_ID = 0x04U, /*!< I2C Listen Complete callback ID */
+ HAL_I2C_MEM_TX_COMPLETE_CB_ID = 0x05U, /*!< I2C Memory Tx Transfer callback ID */
+ HAL_I2C_MEM_RX_COMPLETE_CB_ID = 0x06U, /*!< I2C Memory Rx Transfer completed callback ID */
+ HAL_I2C_ERROR_CB_ID = 0x07U, /*!< I2C Error callback ID */
+ HAL_I2C_ABORT_CB_ID = 0x08U, /*!< I2C Abort callback ID */
+
+ HAL_I2C_MSPINIT_CB_ID = 0x09U, /*!< I2C Msp Init callback ID */
+ HAL_I2C_MSPDEINIT_CB_ID = 0x0AU /*!< I2C Msp DeInit callback ID */
+
+} HAL_I2C_CallbackIDTypeDef;
+
+/**
+ * @brief HAL I2C Callback pointer definition
+ */
+typedef void (*pI2C_CallbackTypeDef)(I2C_HandleTypeDef *hi2c); /*!< pointer to an I2C callback function */
+typedef void (*pI2C_AddrCallbackTypeDef)(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); /*!< pointer to an I2C Address Match callback function */
+
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup I2C_Exported_Constants I2C Exported Constants
+ * @{
+ */
+
+/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode
+ * @{
+ */
+#define I2C_DUTYCYCLE_2 0x00000000U
+#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY
+/**
+ * @}
+ */
+
+/** @defgroup I2C_addressing_mode I2C addressing mode
+ * @{
+ */
+#define I2C_ADDRESSINGMODE_7BIT 0x00004000U
+#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode
+ * @{
+ */
+#define I2C_DUALADDRESS_DISABLE 0x00000000U
+#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL
+/**
+ * @}
+ */
+
+/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode
+ * @{
+ */
+#define I2C_GENERALCALL_DISABLE 0x00000000U
+#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC
+/**
+ * @}
+ */
+
+/** @defgroup I2C_nostretch_mode I2C nostretch mode
+ * @{
+ */
+#define I2C_NOSTRETCH_DISABLE 0x00000000U
+#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size
+ * @{
+ */
+#define I2C_MEMADD_SIZE_8BIT 0x00000001U
+#define I2C_MEMADD_SIZE_16BIT 0x00000010U
+/**
+ * @}
+ */
+
+/** @defgroup I2C_XferDirection_definition I2C XferDirection definition
+ * @{
+ */
+#define I2C_DIRECTION_RECEIVE 0x00000000U
+#define I2C_DIRECTION_TRANSMIT 0x00000001U
+/**
+ * @}
+ */
+
+/** @defgroup I2C_XferOptions_definition I2C XferOptions definition
+ * @{
+ */
+#define I2C_FIRST_FRAME 0x00000001U
+#define I2C_FIRST_AND_NEXT_FRAME 0x00000002U
+#define I2C_NEXT_FRAME 0x00000004U
+#define I2C_FIRST_AND_LAST_FRAME 0x00000008U
+#define I2C_LAST_FRAME_NO_STOP 0x00000010U
+#define I2C_LAST_FRAME 0x00000020U
+
+/* List of XferOptions in usage of :
+ * 1- Restart condition in all use cases (direction change or not)
+ */
+#define I2C_OTHER_FRAME (0x00AA0000U)
+#define I2C_OTHER_AND_LAST_FRAME (0xAA000000U)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition
+ * @brief I2C Interrupt definition
+ * Elements values convention: 0xXXXXXXXX
+ * - XXXXXXXX : Interrupt control mask
+ * @{
+ */
+#define I2C_IT_BUF I2C_CR2_ITBUFEN
+#define I2C_IT_EVT I2C_CR2_ITEVTEN
+#define I2C_IT_ERR I2C_CR2_ITERREN
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Flag_definition I2C Flag definition
+ * @{
+ */
+
+#define I2C_FLAG_OVR 0x00010800U
+#define I2C_FLAG_AF 0x00010400U
+#define I2C_FLAG_ARLO 0x00010200U
+#define I2C_FLAG_BERR 0x00010100U
+#define I2C_FLAG_TXE 0x00010080U
+#define I2C_FLAG_RXNE 0x00010040U
+#define I2C_FLAG_STOPF 0x00010010U
+#define I2C_FLAG_ADD10 0x00010008U
+#define I2C_FLAG_BTF 0x00010004U
+#define I2C_FLAG_ADDR 0x00010002U
+#define I2C_FLAG_SB 0x00010001U
+#define I2C_FLAG_DUALF 0x00100080U
+#define I2C_FLAG_GENCALL 0x00100010U
+#define I2C_FLAG_TRA 0x00100004U
+#define I2C_FLAG_BUSY 0x00100002U
+#define I2C_FLAG_MSL 0x00100001U
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+
+/** @defgroup I2C_Exported_Macros I2C Exported Macros
+ * @{
+ */
+
+/** @brief Reset I2C handle state.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->State = HAL_I2C_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET)
+#endif
+
+/** @brief Enable or disable the specified I2C interrupts.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __INTERRUPT__ specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt enable
+ * @arg I2C_IT_EVT: Event interrupt enable
+ * @arg I2C_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__))
+#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CR2, (__INTERRUPT__))
+
+/** @brief Checks if the specified I2C interrupt source is enabled or disabled.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __INTERRUPT__ specifies the I2C interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt enable
+ * @arg I2C_IT_EVT: Event interrupt enable
+ * @arg I2C_IT_ERR: Error interrupt enable
+ * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
+ */
+#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks whether the specified I2C flag is set or not.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag
+ * @arg I2C_FLAG_BERR: Bus error flag
+ * @arg I2C_FLAG_TXE: Data register empty flag
+ * @arg I2C_FLAG_RXNE: Data register not empty flag
+ * @arg I2C_FLAG_STOPF: Stop detection flag
+ * @arg I2C_FLAG_ADD10: 10-bit header sent flag
+ * @arg I2C_FLAG_BTF: Byte transfer finished flag
+ * @arg I2C_FLAG_ADDR: Address sent flag
+ * Address matched flag
+ * @arg I2C_FLAG_SB: Start bit flag
+ * @arg I2C_FLAG_DUALF: Dual flag
+ * @arg I2C_FLAG_GENCALL: General call header flag
+ * @arg I2C_FLAG_TRA: Transmitter/Receiver flag
+ * @arg I2C_FLAG_BUSY: Bus busy flag
+ * @arg I2C_FLAG_MSL: Master/Slave flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U) ? \
+ (((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET) : \
+ (((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET))
+
+/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __FLAG__ specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_FLAG_BERR: Bus error flag
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK))
+
+/** @brief Clears the I2C ADDR pending flag.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR1; \
+ tmpreg = (__HANDLE__)->Instance->SR2; \
+ UNUSED(tmpreg); \
+ } while(0)
+
+/** @brief Clears the I2C STOPF pending flag.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR1; \
+ SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE); \
+ UNUSED(tmpreg); \
+ } while(0)
+
+/** @brief Enable the specified I2C peripheral.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#define __HAL_I2C_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
+
+/** @brief Disable the specified I2C peripheral.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#define __HAL_I2C_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2C_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+/* Initialization and de-initialization functions******************************/
+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c);
+
+/* Callbacks Register/UnRegister functions ***********************************/
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID, pI2C_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID);
+
+HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group2 Input and Output operation functions
+ * @{
+ */
+/* IO operation functions ****************************************************/
+/******* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
+
+/******* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress);
+
+/******* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
+ * @{
+ */
+/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode);
+void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
+ * @{
+ */
+/* Peripheral State, Mode and Error functions *********************************/
+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c);
+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c);
+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2C_Private_Constants I2C Private Constants
+ * @{
+ */
+#define I2C_FLAG_MASK 0x0000FFFFU
+#define I2C_MIN_PCLK_FREQ_STANDARD 2000000U /*!< 2 MHz */
+#define I2C_MIN_PCLK_FREQ_FAST 4000000U /*!< 4 MHz */
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2C_Private_Macros I2C Private Macros
+ * @{
+ */
+
+#define I2C_MIN_PCLK_FREQ(__PCLK__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__PCLK__) < I2C_MIN_PCLK_FREQ_STANDARD) : ((__PCLK__) < I2C_MIN_PCLK_FREQ_FAST))
+#define I2C_CCR_CALCULATION(__PCLK__, __SPEED__, __COEFF__) (((((__PCLK__) - 1U)/((__SPEED__) * (__COEFF__))) + 1U) & I2C_CCR_CCR)
+#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U)
+#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
+#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) ((I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U) < 4U)? 4U:I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U))
+#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 3U) : (I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 25U) | I2C_DUTYCYCLE_16_9))
+#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \
+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \
+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS))
+
+#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (uint8_t)(~I2C_OAR1_ADD0)))
+#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))
+
+#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
+#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0)))
+#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1))))
+
+#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8)))
+#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
+
+/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters
+ * @{
+ */
+#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \
+ ((CYCLE) == I2C_DUTYCYCLE_16_9))
+#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \
+ ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT))
+#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \
+ ((ADDRESS) == I2C_DUALADDRESS_ENABLE))
+#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \
+ ((CALL) == I2C_GENERALCALL_ENABLE))
+#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \
+ ((STRETCH) == I2C_NOSTRETCH_ENABLE))
+#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \
+ ((SIZE) == I2C_MEMADD_SIZE_16BIT))
+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0U) && ((SPEED) <= 400000U))
+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & 0xFFFFFC00U) == 0U)
+#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & 0xFFFFFF01U) == 0U)
+#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \
+ ((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \
+ ((REQUEST) == I2C_NEXT_FRAME) || \
+ ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \
+ ((REQUEST) == I2C_LAST_FRAME) || \
+ ((REQUEST) == I2C_LAST_FRAME_NO_STOP) || \
+ IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST))
+
+#define IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_OTHER_FRAME) || \
+ ((REQUEST) == I2C_OTHER_AND_LAST_FRAME))
+
+#define I2C_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET)
+#define I2C_CHECK_IT_SOURCE(__CR1__, __IT__) ((((__CR1__) & (__IT__)) == (__IT__)) ? SET : RESET)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup I2C_Private_Functions I2C Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F1xx_HAL_I2C_H */
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
new file mode 100644
index 0000000..73073fc
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
@@ -0,0 +1,730 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_spi.h
+ * @author MCD Application Team
+ * @brief Header file of SPI HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F1xx_HAL_SPI_H
+#define STM32F1xx_HAL_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup SPI
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SPI_Exported_Types SPI Exported Types
+ * @{
+ */
+
+/**
+ * @brief SPI Configuration Structure definition
+ */
+typedef struct
+{
+ uint32_t Mode; /*!< Specifies the SPI operating mode.
+ This parameter can be a value of @ref SPI_Mode */
+
+ uint32_t Direction; /*!< Specifies the SPI bidirectional mode state.
+ This parameter can be a value of @ref SPI_Direction */
+
+ uint32_t DataSize; /*!< Specifies the SPI data size.
+ This parameter can be a value of @ref SPI_Data_Size */
+
+ uint32_t CLKPolarity; /*!< Specifies the serial clock steady state.
+ This parameter can be a value of @ref SPI_Clock_Polarity */
+
+ uint32_t CLKPhase; /*!< Specifies the clock active edge for the bit capture.
+ This parameter can be a value of @ref SPI_Clock_Phase */
+
+ uint32_t NSS; /*!< Specifies whether the NSS signal is managed by
+ hardware (NSS pin) or by software using the SSI bit.
+ This parameter can be a value of @ref SPI_Slave_Select_management */
+
+ uint32_t BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be
+ used to configure the transmit and receive SCK clock.
+ This parameter can be a value of @ref SPI_BaudRate_Prescaler
+ @note The communication clock is derived from the master
+ clock. The slave clock does not need to be set. */
+
+ uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit.
+ This parameter can be a value of @ref SPI_MSB_LSB_transmission */
+
+ uint32_t TIMode; /*!< Specifies if the TI mode is enabled or not.
+ This parameter can be a value of @ref SPI_TI_mode */
+
+ uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not.
+ This parameter can be a value of @ref SPI_CRC_Calculation */
+
+ uint32_t CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation.
+ This parameter must be an odd number between Min_Data = 1 and Max_Data = 65535 */
+} SPI_InitTypeDef;
+
+/**
+ * @brief HAL SPI State structure definition
+ */
+typedef enum
+{
+ HAL_SPI_STATE_RESET = 0x00U, /*!< Peripheral not Initialized */
+ HAL_SPI_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
+ HAL_SPI_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */
+ HAL_SPI_STATE_BUSY_TX = 0x03U, /*!< Data Transmission process is ongoing */
+ HAL_SPI_STATE_BUSY_RX = 0x04U, /*!< Data Reception process is ongoing */
+ HAL_SPI_STATE_BUSY_TX_RX = 0x05U, /*!< Data Transmission and Reception process is ongoing */
+ HAL_SPI_STATE_ERROR = 0x06U, /*!< SPI error state */
+ HAL_SPI_STATE_ABORT = 0x07U /*!< SPI abort is ongoing */
+} HAL_SPI_StateTypeDef;
+
+/**
+ * @brief SPI handle Structure definition
+ */
+typedef struct __SPI_HandleTypeDef
+{
+ SPI_TypeDef *Instance; /*!< SPI registers base address */
+
+ SPI_InitTypeDef Init; /*!< SPI communication parameters */
+
+ uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< SPI Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< SPI Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */
+
+ void (*RxISR)(struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Rx ISR */
+
+ void (*TxISR)(struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Tx ISR */
+
+ DMA_HandleTypeDef *hdmatx; /*!< SPI Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< SPI Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_SPI_StateTypeDef State; /*!< SPI communication state */
+
+ __IO uint32_t ErrorCode; /*!< SPI Error code */
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ void (* TxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Completed callback */
+ void (* RxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Completed callback */
+ void (* TxRxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Completed callback */
+ void (* TxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Half Completed callback */
+ void (* RxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Half Completed callback */
+ void (* TxRxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Half Completed callback */
+ void (* ErrorCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Error callback */
+ void (* AbortCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Abort callback */
+ void (* MspInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp Init callback */
+ void (* MspDeInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp DeInit callback */
+
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+} SPI_HandleTypeDef;
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+/**
+ * @brief HAL SPI Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_SPI_TX_COMPLETE_CB_ID = 0x00U, /*!< SPI Tx Completed callback ID */
+ HAL_SPI_RX_COMPLETE_CB_ID = 0x01U, /*!< SPI Rx Completed callback ID */
+ HAL_SPI_TX_RX_COMPLETE_CB_ID = 0x02U, /*!< SPI TxRx Completed callback ID */
+ HAL_SPI_TX_HALF_COMPLETE_CB_ID = 0x03U, /*!< SPI Tx Half Completed callback ID */
+ HAL_SPI_RX_HALF_COMPLETE_CB_ID = 0x04U, /*!< SPI Rx Half Completed callback ID */
+ HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID = 0x05U, /*!< SPI TxRx Half Completed callback ID */
+ HAL_SPI_ERROR_CB_ID = 0x06U, /*!< SPI Error callback ID */
+ HAL_SPI_ABORT_CB_ID = 0x07U, /*!< SPI Abort callback ID */
+ HAL_SPI_MSPINIT_CB_ID = 0x08U, /*!< SPI Msp Init callback ID */
+ HAL_SPI_MSPDEINIT_CB_ID = 0x09U /*!< SPI Msp DeInit callback ID */
+
+} HAL_SPI_CallbackIDTypeDef;
+
+/**
+ * @brief HAL SPI Callback pointer definition
+ */
+typedef void (*pSPI_CallbackTypeDef)(SPI_HandleTypeDef *hspi); /*!< pointer to an SPI callback function */
+
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup SPI_Exported_Constants SPI Exported Constants
+ * @{
+ */
+
+/** @defgroup SPI_Error_Code SPI Error Code
+ * @{
+ */
+#define HAL_SPI_ERROR_NONE (0x00000000U) /*!< No error */
+#define HAL_SPI_ERROR_MODF (0x00000001U) /*!< MODF error */
+#define HAL_SPI_ERROR_CRC (0x00000002U) /*!< CRC error */
+#define HAL_SPI_ERROR_OVR (0x00000004U) /*!< OVR error */
+#define HAL_SPI_ERROR_DMA (0x00000010U) /*!< DMA transfer error */
+#define HAL_SPI_ERROR_FLAG (0x00000020U) /*!< Error on RXNE/TXE/BSY Flag */
+#define HAL_SPI_ERROR_ABORT (0x00000040U) /*!< Error during SPI Abort procedure */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+#define HAL_SPI_ERROR_INVALID_CALLBACK (0x00000080U) /*!< Invalid Callback error */
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Mode SPI Mode
+ * @{
+ */
+#define SPI_MODE_SLAVE (0x00000000U)
+#define SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI)
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Direction SPI Direction Mode
+ * @{
+ */
+#define SPI_DIRECTION_2LINES (0x00000000U)
+#define SPI_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY
+#define SPI_DIRECTION_1LINE SPI_CR1_BIDIMODE
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Data_Size SPI Data Size
+ * @{
+ */
+#define SPI_DATASIZE_8BIT (0x00000000U)
+#define SPI_DATASIZE_16BIT SPI_CR1_DFF
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Polarity SPI Clock Polarity
+ * @{
+ */
+#define SPI_POLARITY_LOW (0x00000000U)
+#define SPI_POLARITY_HIGH SPI_CR1_CPOL
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Phase SPI Clock Phase
+ * @{
+ */
+#define SPI_PHASE_1EDGE (0x00000000U)
+#define SPI_PHASE_2EDGE SPI_CR1_CPHA
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Slave_Select_management SPI Slave Select Management
+ * @{
+ */
+#define SPI_NSS_SOFT SPI_CR1_SSM
+#define SPI_NSS_HARD_INPUT (0x00000000U)
+#define SPI_NSS_HARD_OUTPUT (SPI_CR2_SSOE << 16U)
+/**
+ * @}
+ */
+
+/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler
+ * @{
+ */
+#define SPI_BAUDRATEPRESCALER_2 (0x00000000U)
+#define SPI_BAUDRATEPRESCALER_4 (SPI_CR1_BR_0)
+#define SPI_BAUDRATEPRESCALER_8 (SPI_CR1_BR_1)
+#define SPI_BAUDRATEPRESCALER_16 (SPI_CR1_BR_1 | SPI_CR1_BR_0)
+#define SPI_BAUDRATEPRESCALER_32 (SPI_CR1_BR_2)
+#define SPI_BAUDRATEPRESCALER_64 (SPI_CR1_BR_2 | SPI_CR1_BR_0)
+#define SPI_BAUDRATEPRESCALER_128 (SPI_CR1_BR_2 | SPI_CR1_BR_1)
+#define SPI_BAUDRATEPRESCALER_256 (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0)
+/**
+ * @}
+ */
+
+/** @defgroup SPI_MSB_LSB_transmission SPI MSB LSB Transmission
+ * @{
+ */
+#define SPI_FIRSTBIT_MSB (0x00000000U)
+#define SPI_FIRSTBIT_LSB SPI_CR1_LSBFIRST
+/**
+ * @}
+ */
+
+/** @defgroup SPI_TI_mode SPI TI Mode
+ * @{
+ */
+#define SPI_TIMODE_DISABLE (0x00000000U)
+/**
+ * @}
+ */
+
+/** @defgroup SPI_CRC_Calculation SPI CRC Calculation
+ * @{
+ */
+#define SPI_CRCCALCULATION_DISABLE (0x00000000U)
+#define SPI_CRCCALCULATION_ENABLE SPI_CR1_CRCEN
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition
+ * @{
+ */
+#define SPI_IT_TXE SPI_CR2_TXEIE
+#define SPI_IT_RXNE SPI_CR2_RXNEIE
+#define SPI_IT_ERR SPI_CR2_ERRIE
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Flags_definition SPI Flags Definition
+ * @{
+ */
+#define SPI_FLAG_RXNE SPI_SR_RXNE /* SPI status flag: Rx buffer not empty flag */
+#define SPI_FLAG_TXE SPI_SR_TXE /* SPI status flag: Tx buffer empty flag */
+#define SPI_FLAG_BSY SPI_SR_BSY /* SPI status flag: Busy flag */
+#define SPI_FLAG_CRCERR SPI_SR_CRCERR /* SPI Error flag: CRC error flag */
+#define SPI_FLAG_MODF SPI_SR_MODF /* SPI Error flag: Mode fault flag */
+#define SPI_FLAG_OVR SPI_SR_OVR /* SPI Error flag: Overrun flag */
+#define SPI_FLAG_MASK (SPI_SR_RXNE | SPI_SR_TXE | SPI_SR_BSY\
+ | SPI_SR_CRCERR | SPI_SR_MODF | SPI_SR_OVR)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup SPI_Exported_Macros SPI Exported Macros
+ * @{
+ */
+
+/** @brief Reset SPI handle state.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->State = HAL_SPI_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SPI_STATE_RESET)
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+
+/** @brief Enable the specified SPI interrupts.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __INTERRUPT__ specifies the interrupt source to enable.
+ * This parameter can be one of the following values:
+ * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
+ * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg SPI_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CR2, (__INTERRUPT__))
+
+/** @brief Disable the specified SPI interrupts.
+ * @param __HANDLE__ specifies the SPI handle.
+ * This parameter can be SPIx where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __INTERRUPT__ specifies the interrupt source to disable.
+ * This parameter can be one of the following values:
+ * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
+ * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg SPI_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CR2, (__INTERRUPT__))
+
+/** @brief Check whether the specified SPI interrupt source is enabled or not.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __INTERRUPT__ specifies the SPI interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
+ * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg SPI_IT_ERR: Error interrupt enable
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2\
+ & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Check whether the specified SPI flag is set or not.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_FLAG_RXNE: Receive buffer not empty flag
+ * @arg SPI_FLAG_TXE: Transmit buffer empty flag
+ * @arg SPI_FLAG_CRCERR: CRC error flag
+ * @arg SPI_FLAG_MODF: Mode fault flag
+ * @arg SPI_FLAG_OVR: Overrun flag
+ * @arg SPI_FLAG_BSY: Busy flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clear the SPI CRCERR pending flag.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) ((__HANDLE__)->Instance->SR = (uint16_t)(~SPI_FLAG_CRCERR))
+
+/** @brief Clear the SPI MODF pending flag.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg_modf = 0x00U; \
+ tmpreg_modf = (__HANDLE__)->Instance->SR; \
+ CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE); \
+ UNUSED(tmpreg_modf); \
+ } while(0U)
+
+/** @brief Clear the SPI OVR pending flag.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg_ovr = 0x00U; \
+ tmpreg_ovr = (__HANDLE__)->Instance->DR; \
+ tmpreg_ovr = (__HANDLE__)->Instance->SR; \
+ UNUSED(tmpreg_ovr); \
+ } while(0U)
+
+/** @brief Enable the SPI peripheral.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE)
+
+/** @brief Disable the SPI peripheral.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define __HAL_SPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE)
+
+/**
+ * @}
+ */
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup SPI_Private_Constants SPI Private Constants
+ * @{
+ */
+#define SPI_INVALID_CRC_ERROR 0U /* CRC error wrongly detected */
+#define SPI_VALID_CRC_ERROR 1U /* CRC error is true */
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup SPI_Private_Macros SPI Private Macros
+ * @{
+ */
+
+/** @brief Set the SPI transmit-only mode.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define SPI_1LINE_TX(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIOE)
+
+/** @brief Set the SPI receive-only mode.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define SPI_1LINE_RX(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIOE)
+
+/** @brief Reset the CRC calculation of the SPI.
+ * @param __HANDLE__ specifies the SPI Handle.
+ * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+ * @retval None
+ */
+#define SPI_RESET_CRC(__HANDLE__) do{CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_CRCEN);\
+ SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_CRCEN);}while(0U)
+
+/** @brief Check whether the specified SPI flag is set or not.
+ * @param __SR__ copy of SPI SR register.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_FLAG_RXNE: Receive buffer not empty flag
+ * @arg SPI_FLAG_TXE: Transmit buffer empty flag
+ * @arg SPI_FLAG_CRCERR: CRC error flag
+ * @arg SPI_FLAG_MODF: Mode fault flag
+ * @arg SPI_FLAG_OVR: Overrun flag
+ * @arg SPI_FLAG_BSY: Busy flag
+ * @retval SET or RESET.
+ */
+#define SPI_CHECK_FLAG(__SR__, __FLAG__) ((((__SR__) & ((__FLAG__) & SPI_FLAG_MASK)) == \
+ ((__FLAG__) & SPI_FLAG_MASK)) ? SET : RESET)
+
+/** @brief Check whether the specified SPI Interrupt is set or not.
+ * @param __CR2__ copy of SPI CR2 register.
+ * @param __INTERRUPT__ specifies the SPI interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_IT_TXE: Tx buffer empty interrupt enable
+ * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg SPI_IT_ERR: Error interrupt enable
+ * @retval SET or RESET.
+ */
+#define SPI_CHECK_IT_SOURCE(__CR2__, __INTERRUPT__) ((((__CR2__) & (__INTERRUPT__)) == \
+ (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks if SPI Mode parameter is in allowed range.
+ * @param __MODE__ specifies the SPI Mode.
+ * This parameter can be a value of @ref SPI_Mode
+ * @retval None
+ */
+#define IS_SPI_MODE(__MODE__) (((__MODE__) == SPI_MODE_SLAVE) || \
+ ((__MODE__) == SPI_MODE_MASTER))
+
+/** @brief Checks if SPI Direction Mode parameter is in allowed range.
+ * @param __MODE__ specifies the SPI Direction Mode.
+ * This parameter can be a value of @ref SPI_Direction
+ * @retval None
+ */
+#define IS_SPI_DIRECTION(__MODE__) (((__MODE__) == SPI_DIRECTION_2LINES) || \
+ ((__MODE__) == SPI_DIRECTION_2LINES_RXONLY) || \
+ ((__MODE__) == SPI_DIRECTION_1LINE))
+
+/** @brief Checks if SPI Direction Mode parameter is 2 lines.
+ * @param __MODE__ specifies the SPI Direction Mode.
+ * @retval None
+ */
+#define IS_SPI_DIRECTION_2LINES(__MODE__) ((__MODE__) == SPI_DIRECTION_2LINES)
+
+/** @brief Checks if SPI Direction Mode parameter is 1 or 2 lines.
+ * @param __MODE__ specifies the SPI Direction Mode.
+ * @retval None
+ */
+#define IS_SPI_DIRECTION_2LINES_OR_1LINE(__MODE__) (((__MODE__) == SPI_DIRECTION_2LINES) || \
+ ((__MODE__) == SPI_DIRECTION_1LINE))
+
+/** @brief Checks if SPI Data Size parameter is in allowed range.
+ * @param __DATASIZE__ specifies the SPI Data Size.
+ * This parameter can be a value of @ref SPI_Data_Size
+ * @retval None
+ */
+#define IS_SPI_DATASIZE(__DATASIZE__) (((__DATASIZE__) == SPI_DATASIZE_16BIT) || \
+ ((__DATASIZE__) == SPI_DATASIZE_8BIT))
+
+/** @brief Checks if SPI Serial clock steady state parameter is in allowed range.
+ * @param __CPOL__ specifies the SPI serial clock steady state.
+ * This parameter can be a value of @ref SPI_Clock_Polarity
+ * @retval None
+ */
+#define IS_SPI_CPOL(__CPOL__) (((__CPOL__) == SPI_POLARITY_LOW) || \
+ ((__CPOL__) == SPI_POLARITY_HIGH))
+
+/** @brief Checks if SPI Clock Phase parameter is in allowed range.
+ * @param __CPHA__ specifies the SPI Clock Phase.
+ * This parameter can be a value of @ref SPI_Clock_Phase
+ * @retval None
+ */
+#define IS_SPI_CPHA(__CPHA__) (((__CPHA__) == SPI_PHASE_1EDGE) || \
+ ((__CPHA__) == SPI_PHASE_2EDGE))
+
+/** @brief Checks if SPI Slave Select parameter is in allowed range.
+ * @param __NSS__ specifies the SPI Slave Select management parameter.
+ * This parameter can be a value of @ref SPI_Slave_Select_management
+ * @retval None
+ */
+#define IS_SPI_NSS(__NSS__) (((__NSS__) == SPI_NSS_SOFT) || \
+ ((__NSS__) == SPI_NSS_HARD_INPUT) || \
+ ((__NSS__) == SPI_NSS_HARD_OUTPUT))
+
+/** @brief Checks if SPI Baudrate prescaler parameter is in allowed range.
+ * @param __PRESCALER__ specifies the SPI Baudrate prescaler.
+ * This parameter can be a value of @ref SPI_BaudRate_Prescaler
+ * @retval None
+ */
+#define IS_SPI_BAUDRATE_PRESCALER(__PRESCALER__) (((__PRESCALER__) == SPI_BAUDRATEPRESCALER_2) || \
+ ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_4) || \
+ ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_8) || \
+ ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_16) || \
+ ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_32) || \
+ ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_64) || \
+ ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_128) || \
+ ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_256))
+
+/** @brief Checks if SPI MSB LSB transmission parameter is in allowed range.
+ * @param __BIT__ specifies the SPI MSB LSB transmission (whether data transfer starts from MSB or LSB bit).
+ * This parameter can be a value of @ref SPI_MSB_LSB_transmission
+ * @retval None
+ */
+#define IS_SPI_FIRST_BIT(__BIT__) (((__BIT__) == SPI_FIRSTBIT_MSB) || \
+ ((__BIT__) == SPI_FIRSTBIT_LSB))
+
+/** @brief Checks if SPI TI mode parameter is disabled.
+ * @param __MODE__ SPI_TIMODE_DISABLE. Device not support Ti Mode.
+ * This parameter can be a value of @ref SPI_TI_mode
+ * @retval None
+ */
+#define IS_SPI_TIMODE(__MODE__) ((__MODE__) == SPI_TIMODE_DISABLE)
+
+/** @brief Checks if SPI CRC calculation enabled state is in allowed range.
+ * @param __CALCULATION__ specifies the SPI CRC calculation enable state.
+ * This parameter can be a value of @ref SPI_CRC_Calculation
+ * @retval None
+ */
+#define IS_SPI_CRC_CALCULATION(__CALCULATION__) (((__CALCULATION__) == SPI_CRCCALCULATION_DISABLE) || \
+ ((__CALCULATION__) == SPI_CRCCALCULATION_ENABLE))
+
+/** @brief Checks if SPI polynomial value to be used for the CRC calculation, is in allowed range.
+ * @param __POLYNOMIAL__ specifies the SPI polynomial value to be used for the CRC calculation.
+ * This parameter must be a number between Min_Data = 0 and Max_Data = 65535
+ * @retval None
+ */
+#define IS_SPI_CRC_POLYNOMIAL(__POLYNOMIAL__) (((__POLYNOMIAL__) >= 0x1U) && \
+ ((__POLYNOMIAL__) <= 0xFFFFU) && \
+ (((__POLYNOMIAL__)&0x1U) != 0U))
+
+/** @brief Checks if DMA handle is valid.
+ * @param __HANDLE__ specifies a DMA Handle.
+ * @retval None
+ */
+#define IS_SPI_DMA_HANDLE(__HANDLE__) ((__HANDLE__) != NULL)
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup SPI_Private_Functions SPI Private Functions
+ * @{
+ */
+uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SPI_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup SPI_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions ********************************/
+HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi);
+void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi);
+
+/* Callbacks Register/UnRegister functions ***********************************/
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
+ pSPI_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @addtogroup SPI_Exported_Functions_Group2
+ * @{
+ */
+/* I/O operation functions ***************************************************/
+HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,
+ uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,
+ uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,
+ uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi);
+
+void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi);
+/**
+ * @}
+ */
+
+/** @addtogroup SPI_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral State and Error functions ***************************************/
+HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi);
+uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F1xx_HAL_SPI_H */
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
new file mode 100644
index 0000000..7fe76e3
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
@@ -0,0 +1,915 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_uart.h
+ * @author MCD Application Team
+ * @brief Header file of UART HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_HAL_UART_H
+#define __STM32F1xx_HAL_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal_def.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup UART
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup UART_Exported_Types UART Exported Types
+ * @{
+ */
+
+/**
+ * @brief UART Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This member configures the UART communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (16 * (huart->Init.BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */
+
+ uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref UART_Word_Length */
+
+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref UART_Stop_Bits */
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref UART_Parity
+ @note When parity is enabled, the computed parity is inserted
+ at the MSB position of the transmitted data (9th bit when
+ the word length is set to 9 data bits; 8th bit when the
+ word length is set to 8 data bits). */
+
+ uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref UART_Mode */
+
+ uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
+ This parameter can be a value of @ref UART_Hardware_Flow_Control */
+
+ uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).
+ This parameter can be a value of @ref UART_Over_Sampling. This feature is only available
+ on STM32F100xx family, so OverSampling parameter should always be set to 16. */
+} UART_InitTypeDef;
+
+/**
+ * @brief HAL UART State structures definition
+ * @note HAL UART State value is a combination of 2 different substates: gState and RxState.
+ * - gState contains UART state information related to global Handle management
+ * and also information related to Tx operations.
+ * gState value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : (Not Used)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 Peripheral initialization status
+ * 0 : Reset (Peripheral not initialized)
+ * 1 : Init done (Peripheral initialized. HAL UART Init function already called)
+ * b4-b3 (not used)
+ * xx : Should be set to 00
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (Peripheral busy with some configuration or internal operations)
+ * b1 (not used)
+ * x : Should be set to 0
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * - RxState contains information related to Rx operations.
+ * RxState value coding follow below described bitmap :
+ * b7-b6 (not used)
+ * xx : Should be set to 00
+ * b5 Peripheral initialization status
+ * 0 : Reset (Peripheral not initialized)
+ * 1 : Init done (Peripheral initialized)
+ * b4-b2 (not used)
+ * xxx : Should be set to 000
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 (not used)
+ * x : Should be set to 0.
+ */
+typedef enum
+{
+ HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
+ Value is allowed for gState and RxState */
+ HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
+ Value is allowed for gState and RxState */
+ HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
+ Value is allowed for gState only */
+ HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
+ Value is allowed for gState only */
+ HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
+ Value is allowed for RxState only */
+ HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
+ Not to be used for neither gState nor RxState.
+ Value is result of combination (Or) between gState and RxState values */
+ HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
+ Value is allowed for gState only */
+ HAL_UART_STATE_ERROR = 0xE0U /*!< Error
+ Value is allowed for gState only */
+} HAL_UART_StateTypeDef;
+
+/**
+ * @brief HAL UART Reception type definition
+ * @note HAL UART Reception type value aims to identify which type of Reception is ongoing.
+ * This parameter can be a value of @ref UART_Reception_Type_Values :
+ * HAL_UART_RECEPTION_STANDARD = 0x00U,
+ * HAL_UART_RECEPTION_TOIDLE = 0x01U,
+ */
+typedef uint32_t HAL_UART_RxTypeTypeDef;
+
+/**
+ * @brief HAL UART Rx Event type definition
+ * @note HAL UART Rx Event type value aims to identify which type of Event has occurred
+ * leading to call of the RxEvent callback.
+ * This parameter can be a value of @ref UART_RxEvent_Type_Values :
+ * HAL_UART_RXEVENT_TC = 0x00U,
+ * HAL_UART_RXEVENT_HT = 0x01U,
+ * HAL_UART_RXEVENT_IDLE = 0x02U,
+ */
+typedef uint32_t HAL_UART_RxEventTypeTypeDef;
+
+/**
+ * @brief UART handle Structure definition
+ */
+typedef struct __UART_HandleTypeDef
+{
+ USART_TypeDef *Instance; /*!< UART registers base address */
+
+ UART_InitTypeDef Init; /*!< UART communication parameters */
+
+ const uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
+
+ uint16_t TxXferSize; /*!< UART Tx Transfer size */
+
+ __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
+
+ uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
+
+ uint16_t RxXferSize; /*!< UART Rx Transfer size */
+
+ __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
+
+ __IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */
+
+ __IO HAL_UART_RxEventTypeTypeDef RxEventType; /*!< Type of Rx Event */
+
+ DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< Locking object */
+
+ __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
+ and also related to Tx operations.
+ This parameter can be a value of @ref HAL_UART_StateTypeDef */
+
+ __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
+ This parameter can be a value of @ref HAL_UART_StateTypeDef */
+
+ __IO uint32_t ErrorCode; /*!< UART Error code */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Half Complete Callback */
+ void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Complete Callback */
+ void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Half Complete Callback */
+ void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Complete Callback */
+ void (* ErrorCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Error Callback */
+ void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Complete Callback */
+ void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */
+ void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Receive Complete Callback */
+ void (* WakeupCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Wakeup Callback */
+ void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback */
+
+ void (* MspInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp Init callback */
+ void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp DeInit callback */
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+} UART_HandleTypeDef;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+ * @brief HAL UART Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_UART_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< UART Tx Half Complete Callback ID */
+ HAL_UART_TX_COMPLETE_CB_ID = 0x01U, /*!< UART Tx Complete Callback ID */
+ HAL_UART_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< UART Rx Half Complete Callback ID */
+ HAL_UART_RX_COMPLETE_CB_ID = 0x03U, /*!< UART Rx Complete Callback ID */
+ HAL_UART_ERROR_CB_ID = 0x04U, /*!< UART Error Callback ID */
+ HAL_UART_ABORT_COMPLETE_CB_ID = 0x05U, /*!< UART Abort Complete Callback ID */
+ HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U, /*!< UART Abort Transmit Complete Callback ID */
+ HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID = 0x07U, /*!< UART Abort Receive Complete Callback ID */
+ HAL_UART_WAKEUP_CB_ID = 0x08U, /*!< UART Wakeup Callback ID */
+
+ HAL_UART_MSPINIT_CB_ID = 0x0BU, /*!< UART MspInit callback ID */
+ HAL_UART_MSPDEINIT_CB_ID = 0x0CU /*!< UART MspDeInit callback ID */
+
+} HAL_UART_CallbackIDTypeDef;
+
+/**
+ * @brief HAL UART Callback pointer definition
+ */
+typedef void (*pUART_CallbackTypeDef)(UART_HandleTypeDef *huart); /*!< pointer to an UART callback function */
+typedef void (*pUART_RxEventCallbackTypeDef)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< pointer to a UART Rx Event specific callback function */
+
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup UART_Exported_Constants UART Exported Constants
+ * @{
+ */
+
+/** @defgroup UART_Error_Code UART Error Code
+ * @{
+ */
+#define HAL_UART_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_UART_ERROR_PE 0x00000001U /*!< Parity error */
+#define HAL_UART_ERROR_NE 0x00000002U /*!< Noise error */
+#define HAL_UART_ERROR_FE 0x00000004U /*!< Frame error */
+#define HAL_UART_ERROR_ORE 0x00000008U /*!< Overrun error */
+#define HAL_UART_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+#define HAL_UART_ERROR_INVALID_CALLBACK 0x00000020U /*!< Invalid Callback error */
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup UART_Word_Length UART Word Length
+ * @{
+ */
+#define UART_WORDLENGTH_8B 0x00000000U
+#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Stop_Bits UART Number of Stop Bits
+ * @{
+ */
+#define UART_STOPBITS_1 0x00000000U
+#define UART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Parity UART Parity
+ * @{
+ */
+#define UART_PARITY_NONE 0x00000000U
+#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE)
+#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control
+ * @{
+ */
+#define UART_HWCONTROL_NONE 0x00000000U
+#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE)
+#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE)
+#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Mode UART Transfer Mode
+ * @{
+ */
+#define UART_MODE_RX ((uint32_t)USART_CR1_RE)
+#define UART_MODE_TX ((uint32_t)USART_CR1_TE)
+#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE | USART_CR1_RE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_State UART State
+ * @{
+ */
+#define UART_STATE_DISABLE 0x00000000U
+#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Over_Sampling UART Over Sampling
+ * @{
+ */
+#define UART_OVERSAMPLING_16 0x00000000U
+#if defined(USART_CR1_OVER8)
+#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8)
+#endif /* USART_CR1_OVER8 */
+/**
+ * @}
+ */
+
+/** @defgroup UART_LIN_Break_Detection_Length UART LIN Break Detection Length
+ * @{
+ */
+#define UART_LINBREAKDETECTLENGTH_10B 0x00000000U
+#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)USART_CR2_LBDL)
+/**
+ * @}
+ */
+
+/** @defgroup UART_WakeUp_functions UART Wakeup Functions
+ * @{
+ */
+#define UART_WAKEUPMETHOD_IDLELINE 0x00000000U
+#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)USART_CR1_WAKE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Flags UART FLags
+ * Elements values convention: 0xXXXX
+ * - 0xXXXX : Flag mask in the SR register
+ * @{
+ */
+#define UART_FLAG_CTS ((uint32_t)USART_SR_CTS)
+#define UART_FLAG_LBD ((uint32_t)USART_SR_LBD)
+#define UART_FLAG_TXE ((uint32_t)USART_SR_TXE)
+#define UART_FLAG_TC ((uint32_t)USART_SR_TC)
+#define UART_FLAG_RXNE ((uint32_t)USART_SR_RXNE)
+#define UART_FLAG_IDLE ((uint32_t)USART_SR_IDLE)
+#define UART_FLAG_ORE ((uint32_t)USART_SR_ORE)
+#define UART_FLAG_NE ((uint32_t)USART_SR_NE)
+#define UART_FLAG_FE ((uint32_t)USART_SR_FE)
+#define UART_FLAG_PE ((uint32_t)USART_SR_PE)
+/**
+ * @}
+ */
+
+/** @defgroup UART_Interrupt_definition UART Interrupt Definitions
+ * Elements values convention: 0xY000XXXX
+ * - XXXX : Interrupt mask (16 bits) in the Y register
+ * - Y : Interrupt source register (2bits)
+ * - 0001: CR1 register
+ * - 0010: CR2 register
+ * - 0011: CR3 register
+ * @{
+ */
+
+#define UART_IT_PE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_PEIE))
+#define UART_IT_TXE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TXEIE))
+#define UART_IT_TC ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_TCIE))
+#define UART_IT_RXNE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_RXNEIE))
+#define UART_IT_IDLE ((uint32_t)(UART_CR1_REG_INDEX << 28U | USART_CR1_IDLEIE))
+
+#define UART_IT_LBD ((uint32_t)(UART_CR2_REG_INDEX << 28U | USART_CR2_LBDIE))
+
+#define UART_IT_CTS ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_CTSIE))
+#define UART_IT_ERR ((uint32_t)(UART_CR3_REG_INDEX << 28U | USART_CR3_EIE))
+/**
+ * @}
+ */
+
+/** @defgroup UART_Reception_Type_Values UART Reception type values
+ * @{
+ */
+#define HAL_UART_RECEPTION_STANDARD (0x00000000U) /*!< Standard reception */
+#define HAL_UART_RECEPTION_TOIDLE (0x00000001U) /*!< Reception till completion or IDLE event */
+/**
+ * @}
+ */
+
+/** @defgroup UART_RxEvent_Type_Values UART RxEvent type values
+ * @{
+ */
+#define HAL_UART_RXEVENT_TC (0x00000000U) /*!< RxEvent linked to Transfer Complete event */
+#define HAL_UART_RXEVENT_HT (0x00000001U) /*!< RxEvent linked to Half Transfer event */
+#define HAL_UART_RXEVENT_IDLE (0x00000002U)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup UART_Exported_Macros UART Exported Macros
+ * @{
+ */
+
+/** @brief Reset UART handle gstate & RxState
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_UART_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0U)
+#else
+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->gState = HAL_UART_STATE_RESET; \
+ (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \
+ } while(0U)
+#endif /*USE_HAL_UART_REGISTER_CALLBACKS */
+
+/** @brief Flushes the UART DR register
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ */
+#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)
+
+/** @brief Checks whether the specified UART flag is set or not.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
+ * @arg UART_FLAG_LBD: LIN Break detection flag
+ * @arg UART_FLAG_TXE: Transmit data register empty flag
+ * @arg UART_FLAG_TC: Transmission Complete flag
+ * @arg UART_FLAG_RXNE: Receive data register not empty flag
+ * @arg UART_FLAG_IDLE: Idle Line detection flag
+ * @arg UART_FLAG_ORE: Overrun Error flag
+ * @arg UART_FLAG_NE: Noise Error flag
+ * @arg UART_FLAG_FE: Framing Error flag
+ * @arg UART_FLAG_PE: Parity Error flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clears the specified UART pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be any combination of the following values:
+ * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
+ * @arg UART_FLAG_LBD: LIN Break detection flag.
+ * @arg UART_FLAG_TC: Transmission Complete flag.
+ * @arg UART_FLAG_RXNE: Receive data register not empty flag.
+ *
+ * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (Overrun
+ * error) and IDLE (Idle line detected) flags are cleared by software
+ * sequence: a read operation to USART_SR register followed by a read
+ * operation to USART_DR register.
+ * @note RXNE flag can be also cleared by a read to the USART_DR register.
+ * @note TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register followed by a write operation to USART_DR register.
+ * @note TXE flag is cleared only by a write to the USART_DR register.
+ *
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
+
+/** @brief Clears the UART PE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR; \
+ tmpreg = (__HANDLE__)->Instance->DR; \
+ UNUSED(tmpreg); \
+ } while(0U)
+
+/** @brief Clears the UART FE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART NE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART ORE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Clears the UART IDLE pending flag.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @retval None
+ */
+#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
+
+/** @brief Enable the specified UART interrupt.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__ specifies the UART interrupt source to enable.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_PE: Parity Error interrupt
+ * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ * @retval None
+ */
+#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
+
+/** @brief Disable the specified UART interrupt.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __INTERRUPT__ specifies the UART interrupt source to disable.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_PE: Parity Error interrupt
+ * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ * @retval None
+ */
+#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
+ (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
+ ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))
+
+/** @brief Checks whether the specified UART interrupt source is enabled or not.
+ * @param __HANDLE__ specifies the UART Handle.
+ * UART Handle selects the USARTx or UARTy peripheral
+ * (USART,UART availability and x,y values depending on device).
+ * @param __IT__ specifies the UART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
+ * @arg UART_IT_LBD: LIN Break detection interrupt
+ * @arg UART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg UART_IT_TC: Transmission complete interrupt
+ * @arg UART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg UART_IT_IDLE: Idle line detection interrupt
+ * @arg UART_IT_ERR: Error interrupt
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == UART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == UART_CR2_REG_INDEX)? \
+ (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & UART_IT_MASK))
+
+/** @brief Enable CTS flow control
+ * @note This macro allows to enable CTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \
+ } while(0U)
+
+/** @brief Disable CTS flow control
+ * @note This macro allows to disable CTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \
+ } while(0U)
+
+/** @brief Enable RTS flow control
+ * This macro allows to enable RTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \
+ (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \
+ } while(0U)
+
+/** @brief Disable RTS flow control
+ * This macro allows to disable RTS hardware flow control for a given UART instance,
+ * without need to call HAL_UART_Init() function.
+ * As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+ * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+ * for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+ * - UART instance should have already been initialised (through call of HAL_UART_Init() )
+ * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__))
+ * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)).
+ * @param __HANDLE__ specifies the UART Handle.
+ * The Handle Instance can be any USARTx (supporting the HW Flow control feature).
+ * It is used to select the USART peripheral (USART availability and x value depending on device).
+ * @retval None
+ */
+#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \
+ do{ \
+ ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\
+ (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \
+ } while(0U)
+#if defined(USART_CR3_ONEBIT)
+
+/** @brief Macro to enable the UART's one bit sample method
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT)
+
+/** @brief Macro to disable the UART's one bit sample method
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3\
+ &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT))
+#endif /* UART_ONE_BIT_SAMPLE_Feature */
+
+/** @brief Enable UART
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
+
+/** @brief Disable UART
+ * @param __HANDLE__ specifies the UART Handle.
+ * @retval None
+ */
+#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup UART_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+
+/* Initialization/de-initialization functions **********************************/
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);
+void HAL_UART_MspInit(UART_HandleTypeDef *huart);
+void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);
+
+/* Callbacks Register/UnRegister functions ***********************************/
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
+ pUART_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID);
+
+HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group2 IO operation functions
+ * @{
+ */
+
+/* IO operation functions *******************************************************/
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
+
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
+ uint32_t Timeout);
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+
+HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart);
+
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);
+
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
+void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart);
+
+void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);
+
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral Control functions ************************************************/
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/** @addtogroup UART_Exported_Functions_Group4
+ * @{
+ */
+/* Peripheral State functions **************************************************/
+HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart);
+uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup UART_Private_Constants UART Private Constants
+ * @{
+ */
+/** @brief UART interruptions flag mask
+ *
+ */
+#define UART_IT_MASK 0x0000FFFFU
+
+#define UART_CR1_REG_INDEX 1U
+#define UART_CR2_REG_INDEX 2U
+#define UART_CR3_REG_INDEX 3U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup UART_Private_Macros UART Private Macros
+ * @{
+ */
+#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B) || \
+ ((LENGTH) == UART_WORDLENGTH_9B))
+#define IS_UART_LIN_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B))
+#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \
+ ((STOPBITS) == UART_STOPBITS_2))
+#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \
+ ((PARITY) == UART_PARITY_EVEN) || \
+ ((PARITY) == UART_PARITY_ODD))
+#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\
+ (((CONTROL) == UART_HWCONTROL_NONE) || \
+ ((CONTROL) == UART_HWCONTROL_RTS) || \
+ ((CONTROL) == UART_HWCONTROL_CTS) || \
+ ((CONTROL) == UART_HWCONTROL_RTS_CTS))
+#define IS_UART_MODE(MODE) ((((MODE) & 0x0000FFF3U) == 0x00U) && ((MODE) != 0x00U))
+#define IS_UART_STATE(STATE) (((STATE) == UART_STATE_DISABLE) || \
+ ((STATE) == UART_STATE_ENABLE))
+#if defined(USART_CR1_OVER8)
+#define IS_UART_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16) || \
+ ((SAMPLING) == UART_OVERSAMPLING_8))
+#endif /* USART_CR1_OVER8 */
+#define IS_UART_LIN_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16))
+#define IS_UART_LIN_BREAK_DETECT_LENGTH(LENGTH) (((LENGTH) == UART_LINBREAKDETECTLENGTH_10B) || \
+ ((LENGTH) == UART_LINBREAKDETECTLENGTH_11B))
+#define IS_UART_WAKEUPMETHOD(WAKEUP) (((WAKEUP) == UART_WAKEUPMETHOD_IDLELINE) || \
+ ((WAKEUP) == UART_WAKEUPMETHOD_ADDRESSMARK))
+#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) <= 4500000U)
+#define IS_UART_ADDRESS(ADDRESS) ((ADDRESS) <= 0x0FU)
+
+#define UART_DIV_SAMPLING16(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(4U*(_BAUD_)))
+#define UART_DIVMANT_SAMPLING16(_PCLK_, _BAUD_) (UART_DIV_SAMPLING16((_PCLK_), (_BAUD_))/100U)
+#define UART_DIVFRAQ_SAMPLING16(_PCLK_, _BAUD_) ((((UART_DIV_SAMPLING16((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) * 100U)) * 16U)\
+ + 50U) / 100U)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + (UART DIVFRAQ & 0xF0) + (UART DIVFRAQ & 0x0FU) */
+#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) << 4U) + \
+ (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0xF0U)) + \
+ (UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0x0FU))
+
+#define UART_DIV_SAMPLING8(_PCLK_, _BAUD_) (((_PCLK_)*25U)/(2U*(_BAUD_)))
+#define UART_DIVMANT_SAMPLING8(_PCLK_, _BAUD_) (UART_DIV_SAMPLING8((_PCLK_), (_BAUD_))/100U)
+#define UART_DIVFRAQ_SAMPLING8(_PCLK_, _BAUD_) ((((UART_DIV_SAMPLING8((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) * 100U)) * 8U)\
+ + 50U) / 100U)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07U) */
+#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_) (((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4U) + \
+ ((UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0xF8U) << 1U)) + \
+ (UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x07U))
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_HAL_UART_H */
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
new file mode 100644
index 0000000..e00e918
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h
@@ -0,0 +1,1782 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_i2c.h
+ * @author MCD Application Team
+ * @brief Header file of I2C LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_I2C_H
+#define __STM32F1xx_LL_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (I2C1) || defined (I2C2)
+
+/** @defgroup I2C_LL I2C
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2C_LL_Private_Constants I2C Private Constants
+ * @{
+ */
+
+/* Defines used to perform compute and check in the macros */
+#define LL_I2C_MAX_SPEED_STANDARD 100000U
+#define LL_I2C_MAX_SPEED_FAST 400000U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2C_LL_Private_Macros I2C Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2C_LL_ES_INIT I2C Exported Init structure
+ * @{
+ */
+typedef struct
+{
+ uint32_t PeripheralMode; /*!< Specifies the peripheral mode.
+ This parameter can be a value of @ref I2C_LL_EC_PERIPHERAL_MODE
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetMode(). */
+
+ uint32_t ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz (in Hz)
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetClockPeriod()
+ or @ref LL_I2C_SetDutyCycle() or @ref LL_I2C_SetClockSpeedMode() or @ref LL_I2C_ConfigSpeed(). */
+
+ uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
+ This parameter can be a value of @ref I2C_LL_EC_DUTYCYCLE
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetDutyCycle(). */
+
+ uint32_t OwnAddress1; /*!< Specifies the device own address 1.
+ This parameter must be a value between Min_Data = 0x00 and Max_Data = 0x3FF
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetOwnAddress1(). */
+
+ uint32_t TypeAcknowledge; /*!< Specifies the ACKnowledge or Non ACKnowledge condition after the address receive match code or next received byte.
+ This parameter can be a value of @ref I2C_LL_EC_I2C_ACKNOWLEDGE
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_AcknowledgeNextData(). */
+
+ uint32_t OwnAddrSize; /*!< Specifies the device own address 1 size (7-bit or 10-bit).
+ This parameter can be a value of @ref I2C_LL_EC_OWNADDRESS1
+
+ This feature can be modified afterwards using unitary function @ref LL_I2C_SetOwnAddress1(). */
+} LL_I2C_InitTypeDef;
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2C_LL_Exported_Constants I2C Exported Constants
+ * @{
+ */
+
+/** @defgroup I2C_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_I2C_ReadReg function
+ * @{
+ */
+#define LL_I2C_SR1_SB I2C_SR1_SB /*!< Start Bit (master mode) */
+#define LL_I2C_SR1_ADDR I2C_SR1_ADDR /*!< Address sent (master mode) or
+ Address matched flag (slave mode) */
+#define LL_I2C_SR1_BTF I2C_SR1_BTF /*!< Byte Transfer Finished flag */
+#define LL_I2C_SR1_ADD10 I2C_SR1_ADD10 /*!< 10-bit header sent (master mode) */
+#define LL_I2C_SR1_STOPF I2C_SR1_STOPF /*!< Stop detection flag (slave mode) */
+#define LL_I2C_SR1_RXNE I2C_SR1_RXNE /*!< Data register not empty (receivers) */
+#define LL_I2C_SR1_TXE I2C_SR1_TXE /*!< Data register empty (transmitters) */
+#define LL_I2C_SR1_BERR I2C_SR1_BERR /*!< Bus error */
+#define LL_I2C_SR1_ARLO I2C_SR1_ARLO /*!< Arbitration lost */
+#define LL_I2C_SR1_AF I2C_SR1_AF /*!< Acknowledge failure flag */
+#define LL_I2C_SR1_OVR I2C_SR1_OVR /*!< Overrun/Underrun */
+#define LL_I2C_SR1_PECERR I2C_ISR_PECERR /*!< PEC Error in reception (SMBus mode) */
+#define LL_I2C_SR1_TIMEOUT I2C_ISR_TIMEOUT /*!< Timeout detection flag (SMBus mode) */
+#define LL_I2C_SR1_SMALERT I2C_ISR_SMALERT /*!< SMBus alert (SMBus mode) */
+#define LL_I2C_SR2_MSL I2C_SR2_MSL /*!< Master/Slave flag */
+#define LL_I2C_SR2_BUSY I2C_SR2_BUSY /*!< Bus busy flag */
+#define LL_I2C_SR2_TRA I2C_SR2_TRA /*!< Transmitter/receiver direction */
+#define LL_I2C_SR2_GENCALL I2C_SR2_GENCALL /*!< General call address (Slave mode) */
+#define LL_I2C_SR2_SMBDEFAULT I2C_SR2_SMBDEFAULT /*!< SMBus Device default address (Slave mode) */
+#define LL_I2C_SR2_SMBHOST I2C_SR2_SMBHOST /*!< SMBus Host address (Slave mode) */
+#define LL_I2C_SR2_DUALF I2C_SR2_DUALF /*!< Dual flag (Slave mode) */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_I2C_ReadReg and LL_I2C_WriteReg functions
+ * @{
+ */
+#define LL_I2C_CR2_ITEVTEN I2C_CR2_ITEVTEN /*!< Events interrupts enable */
+#define LL_I2C_CR2_ITBUFEN I2C_CR2_ITBUFEN /*!< Buffer interrupts enable */
+#define LL_I2C_CR2_ITERREN I2C_CR2_ITERREN /*!< Error interrupts enable */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_OWNADDRESS1 Own Address 1 Length
+ * @{
+ */
+#define LL_I2C_OWNADDRESS1_7BIT 0x00004000U /*!< Own address 1 is a 7-bit address. */
+#define LL_I2C_OWNADDRESS1_10BIT (uint32_t)(I2C_OAR1_ADDMODE | 0x00004000U) /*!< Own address 1 is a 10-bit address. */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_DUTYCYCLE Fast Mode Duty Cycle
+ * @{
+ */
+#define LL_I2C_DUTYCYCLE_2 0x00000000U /*!< I2C fast mode Tlow/Thigh = 2 */
+#define LL_I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY /*!< I2C fast mode Tlow/Thigh = 16/9 */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_CLOCK_SPEED_MODE Master Clock Speed Mode
+ * @{
+ */
+#define LL_I2C_CLOCK_SPEED_STANDARD_MODE 0x00000000U /*!< Master clock speed range is standard mode */
+#define LL_I2C_CLOCK_SPEED_FAST_MODE I2C_CCR_FS /*!< Master clock speed range is fast mode */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_PERIPHERAL_MODE Peripheral Mode
+ * @{
+ */
+#define LL_I2C_MODE_I2C 0x00000000U /*!< I2C Master or Slave mode */
+#define LL_I2C_MODE_SMBUS_HOST (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP) /*!< SMBus Host address acknowledge */
+#define LL_I2C_MODE_SMBUS_DEVICE I2C_CR1_SMBUS /*!< SMBus Device default mode (Default address not acknowledge) */
+#define LL_I2C_MODE_SMBUS_DEVICE_ARP (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_ENARP) /*!< SMBus Device Default address acknowledge */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_I2C_ACKNOWLEDGE Acknowledge Generation
+ * @{
+ */
+#define LL_I2C_ACK I2C_CR1_ACK /*!< ACK is sent after current received byte. */
+#define LL_I2C_NACK 0x00000000U /*!< NACK is sent after current received byte.*/
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EC_DIRECTION Read Write Direction
+ * @{
+ */
+#define LL_I2C_DIRECTION_WRITE I2C_SR2_TRA /*!< Bus is in write transfer */
+#define LL_I2C_DIRECTION_READ 0x00000000U /*!< Bus is in read transfer */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup I2C_LL_Exported_Macros I2C Exported Macros
+ * @{
+ */
+
+/** @defgroup I2C_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in I2C register
+ * @param __INSTANCE__ I2C Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_I2C_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in I2C register
+ * @param __INSTANCE__ I2C Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_I2C_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EM_Exported_Macros_Helper Exported Macros Helper
+ * @{
+ */
+
+/**
+ * @brief Convert Peripheral Clock Frequency in Mhz.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @retval Value of peripheral clock (in Mhz)
+ */
+#define __LL_I2C_FREQ_HZ_TO_MHZ(__PCLK__) (uint32_t)((__PCLK__)/1000000U)
+
+/**
+ * @brief Convert Peripheral Clock Frequency in Hz.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Mhz).
+ * @retval Value of peripheral clock (in Hz)
+ */
+#define __LL_I2C_FREQ_MHZ_TO_HZ(__PCLK__) (uint32_t)((__PCLK__)*1000000U)
+
+/**
+ * @brief Compute I2C Clock rising time.
+ * @param __FREQRANGE__ This parameter must be a value of peripheral clock (in Mhz).
+ * @param __SPEED__ This parameter must be a value lower than 400kHz (in Hz).
+ * @retval Value between Min_Data=0x02 and Max_Data=0x3F
+ */
+#define __LL_I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (uint32_t)(((__SPEED__) <= LL_I2C_MAX_SPEED_STANDARD) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
+
+/**
+ * @brief Compute Speed clock range to a Clock Control Register (I2C_CCR_CCR) value.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @param __SPEED__ This parameter must be a value lower than 400kHz (in Hz).
+ * @param __DUTYCYCLE__ This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval Value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
+ */
+#define __LL_I2C_SPEED_TO_CCR(__PCLK__, __SPEED__, __DUTYCYCLE__) (uint32_t)(((__SPEED__) <= LL_I2C_MAX_SPEED_STANDARD)? \
+ (__LL_I2C_SPEED_STANDARD_TO_CCR((__PCLK__), (__SPEED__))) : \
+ (__LL_I2C_SPEED_FAST_TO_CCR((__PCLK__), (__SPEED__), (__DUTYCYCLE__))))
+
+/**
+ * @brief Compute Speed Standard clock range to a Clock Control Register (I2C_CCR_CCR) value.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @param __SPEED__ This parameter must be a value lower than 100kHz (in Hz).
+ * @retval Value between Min_Data=0x004 and Max_Data=0xFFF.
+ */
+#define __LL_I2C_SPEED_STANDARD_TO_CCR(__PCLK__, __SPEED__) (uint32_t)(((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U)))
+
+/**
+ * @brief Compute Speed Fast clock range to a Clock Control Register (I2C_CCR_CCR) value.
+ * @param __PCLK__ This parameter must be a value of peripheral clock (in Hz).
+ * @param __SPEED__ This parameter must be a value between Min_Data=100Khz and Max_Data=400Khz (in Hz).
+ * @param __DUTYCYCLE__ This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval Value between Min_Data=0x001 and Max_Data=0xFFF
+ */
+#define __LL_I2C_SPEED_FAST_TO_CCR(__PCLK__, __SPEED__, __DUTYCYCLE__) (uint32_t)(((__DUTYCYCLE__) == LL_I2C_DUTYCYCLE_2)? \
+ (((((__PCLK__) / ((__SPEED__) * 3U)) & I2C_CCR_CCR) == 0U)? 1U:((__PCLK__) / ((__SPEED__) * 3U))) : \
+ (((((__PCLK__) / ((__SPEED__) * 25U)) & I2C_CCR_CCR) == 0U)? 1U:((__PCLK__) / ((__SPEED__) * 25U))))
+
+/**
+ * @brief Get the Least significant bits of a 10-Bits address.
+ * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+#define __LL_I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FF))))
+
+/**
+ * @brief Convert a 10-Bits address to a 10-Bits header with Write direction.
+ * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
+ * @retval Value between Min_Data=0xF0 and Max_Data=0xF6
+ */
+#define __LL_I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF0))))
+
+/**
+ * @brief Convert a 10-Bits address to a 10-Bits header with Read direction.
+ * @param __ADDRESS__ This parameter must be a value of a 10-Bits slave address.
+ * @retval Value between Min_Data=0xF1 and Max_Data=0xF7
+ */
+#define __LL_I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF1))))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup I2C_LL_Exported_Functions I2C Exported Functions
+ * @{
+ */
+
+/** @defgroup I2C_LL_EF_Configuration Configuration
+ * @{
+ */
+
+/**
+ * @brief Enable I2C peripheral (PE = 1).
+ * @rmtoll CR1 PE LL_I2C_Enable
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_Enable(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_PE);
+}
+
+/**
+ * @brief Disable I2C peripheral (PE = 0).
+ * @rmtoll CR1 PE LL_I2C_Disable
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_Disable(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_PE);
+}
+
+/**
+ * @brief Check if the I2C peripheral is enabled or disabled.
+ * @rmtoll CR1 PE LL_I2C_IsEnabled
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabled(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_PE) == (I2C_CR1_PE));
+}
+
+
+/**
+ * @brief Enable DMA transmission requests.
+ * @rmtoll CR2 DMAEN LL_I2C_EnableDMAReq_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableDMAReq_TX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Disable DMA transmission requests.
+ * @rmtoll CR2 DMAEN LL_I2C_DisableDMAReq_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableDMAReq_TX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Check if DMA transmission requests are enabled or disabled.
+ * @rmtoll CR2 DMAEN LL_I2C_IsEnabledDMAReq_TX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_TX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_DMAEN) == (I2C_CR2_DMAEN));
+}
+
+/**
+ * @brief Enable DMA reception requests.
+ * @rmtoll CR2 DMAEN LL_I2C_EnableDMAReq_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableDMAReq_RX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Disable DMA reception requests.
+ * @rmtoll CR2 DMAEN LL_I2C_DisableDMAReq_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableDMAReq_RX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_DMAEN);
+}
+
+/**
+ * @brief Check if DMA reception requests are enabled or disabled.
+ * @rmtoll CR2 DMAEN LL_I2C_IsEnabledDMAReq_RX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_RX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_DMAEN) == (I2C_CR2_DMAEN));
+}
+
+/**
+ * @brief Get the data register address used for DMA transfer.
+ * @rmtoll DR DR LL_I2C_DMA_GetRegAddr
+ * @param I2Cx I2C Instance.
+ * @retval Address of data register
+ */
+__STATIC_INLINE uint32_t LL_I2C_DMA_GetRegAddr(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t) & (I2Cx->DR);
+}
+
+/**
+ * @brief Enable Clock stretching.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CR1 NOSTRETCH LL_I2C_EnableClockStretching
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableClockStretching(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH);
+}
+
+/**
+ * @brief Disable Clock stretching.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CR1 NOSTRETCH LL_I2C_DisableClockStretching
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableClockStretching(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH);
+}
+
+/**
+ * @brief Check if Clock stretching is enabled or disabled.
+ * @rmtoll CR1 NOSTRETCH LL_I2C_IsEnabledClockStretching
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledClockStretching(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH) != (I2C_CR1_NOSTRETCH));
+}
+
+/**
+ * @brief Enable General Call.
+ * @note When enabled the Address 0x00 is ACKed.
+ * @rmtoll CR1 ENGC LL_I2C_EnableGeneralCall
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableGeneralCall(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_ENGC);
+}
+
+/**
+ * @brief Disable General Call.
+ * @note When disabled the Address 0x00 is NACKed.
+ * @rmtoll CR1 ENGC LL_I2C_DisableGeneralCall
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableGeneralCall(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_ENGC);
+}
+
+/**
+ * @brief Check if General Call is enabled or disabled.
+ * @rmtoll CR1 ENGC LL_I2C_IsEnabledGeneralCall
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledGeneralCall(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_ENGC) == (I2C_CR1_ENGC));
+}
+
+/**
+ * @brief Set the Own Address1.
+ * @rmtoll OAR1 ADD0 LL_I2C_SetOwnAddress1\n
+ * OAR1 ADD1_7 LL_I2C_SetOwnAddress1\n
+ * OAR1 ADD8_9 LL_I2C_SetOwnAddress1\n
+ * OAR1 ADDMODE LL_I2C_SetOwnAddress1
+ * @param I2Cx I2C Instance.
+ * @param OwnAddress1 This parameter must be a value between Min_Data=0 and Max_Data=0x3FF.
+ * @param OwnAddrSize This parameter can be one of the following values:
+ * @arg @ref LL_I2C_OWNADDRESS1_7BIT
+ * @arg @ref LL_I2C_OWNADDRESS1_10BIT
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetOwnAddress1(I2C_TypeDef *I2Cx, uint32_t OwnAddress1, uint32_t OwnAddrSize)
+{
+ MODIFY_REG(I2Cx->OAR1, I2C_OAR1_ADD0 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD8_9 | I2C_OAR1_ADDMODE, OwnAddress1 | OwnAddrSize);
+}
+
+/**
+ * @brief Set the 7bits Own Address2.
+ * @note This action has no effect if own address2 is enabled.
+ * @rmtoll OAR2 ADD2 LL_I2C_SetOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @param OwnAddress2 This parameter must be a value between Min_Data=0 and Max_Data=0x7F.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetOwnAddress2(I2C_TypeDef *I2Cx, uint32_t OwnAddress2)
+{
+ MODIFY_REG(I2Cx->OAR2, I2C_OAR2_ADD2, OwnAddress2);
+}
+
+/**
+ * @brief Enable acknowledge on Own Address2 match address.
+ * @rmtoll OAR2 ENDUAL LL_I2C_EnableOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableOwnAddress2(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL);
+}
+
+/**
+ * @brief Disable acknowledge on Own Address2 match address.
+ * @rmtoll OAR2 ENDUAL LL_I2C_DisableOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableOwnAddress2(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL);
+}
+
+/**
+ * @brief Check if Own Address1 acknowledge is enabled or disabled.
+ * @rmtoll OAR2 ENDUAL LL_I2C_IsEnabledOwnAddress2
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledOwnAddress2(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->OAR2, I2C_OAR2_ENDUAL) == (I2C_OAR2_ENDUAL));
+}
+
+/**
+ * @brief Configure the Peripheral clock frequency.
+ * @rmtoll CR2 FREQ LL_I2C_SetPeriphClock
+ * @param I2Cx I2C Instance.
+ * @param PeriphClock Peripheral Clock (in Hz)
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetPeriphClock(I2C_TypeDef *I2Cx, uint32_t PeriphClock)
+{
+ MODIFY_REG(I2Cx->CR2, I2C_CR2_FREQ, __LL_I2C_FREQ_HZ_TO_MHZ(PeriphClock));
+}
+
+/**
+ * @brief Get the Peripheral clock frequency.
+ * @rmtoll CR2 FREQ LL_I2C_GetPeriphClock
+ * @param I2Cx I2C Instance.
+ * @retval Value of Peripheral Clock (in Hz)
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetPeriphClock(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(__LL_I2C_FREQ_MHZ_TO_HZ(READ_BIT(I2Cx->CR2, I2C_CR2_FREQ)));
+}
+
+/**
+ * @brief Configure the Duty cycle (Fast mode only).
+ * @rmtoll CCR DUTY LL_I2C_SetDutyCycle
+ * @param I2Cx I2C Instance.
+ * @param DutyCycle This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetDutyCycle(I2C_TypeDef *I2Cx, uint32_t DutyCycle)
+{
+ MODIFY_REG(I2Cx->CCR, I2C_CCR_DUTY, DutyCycle);
+}
+
+/**
+ * @brief Get the Duty cycle (Fast mode only).
+ * @rmtoll CCR DUTY LL_I2C_GetDutyCycle
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetDutyCycle(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_DUTY));
+}
+
+/**
+ * @brief Configure the I2C master clock speed mode.
+ * @rmtoll CCR FS LL_I2C_SetClockSpeedMode
+ * @param I2Cx I2C Instance.
+ * @param ClockSpeedMode This parameter can be one of the following values:
+ * @arg @ref LL_I2C_CLOCK_SPEED_STANDARD_MODE
+ * @arg @ref LL_I2C_CLOCK_SPEED_FAST_MODE
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetClockSpeedMode(I2C_TypeDef *I2Cx, uint32_t ClockSpeedMode)
+{
+ MODIFY_REG(I2Cx->CCR, I2C_CCR_FS, ClockSpeedMode);
+}
+
+/**
+ * @brief Get the the I2C master speed mode.
+ * @rmtoll CCR FS LL_I2C_GetClockSpeedMode
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_CLOCK_SPEED_STANDARD_MODE
+ * @arg @ref LL_I2C_CLOCK_SPEED_FAST_MODE
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetClockSpeedMode(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_FS));
+}
+
+/**
+ * @brief Configure the SCL, SDA rising time.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll TRISE TRISE LL_I2C_SetRiseTime
+ * @param I2Cx I2C Instance.
+ * @param RiseTime This parameter must be a value between Min_Data=0x02 and Max_Data=0x3F.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetRiseTime(I2C_TypeDef *I2Cx, uint32_t RiseTime)
+{
+ MODIFY_REG(I2Cx->TRISE, I2C_TRISE_TRISE, RiseTime);
+}
+
+/**
+ * @brief Get the SCL, SDA rising time.
+ * @rmtoll TRISE TRISE LL_I2C_GetRiseTime
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x02 and Max_Data=0x3F
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetRiseTime(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->TRISE, I2C_TRISE_TRISE));
+}
+
+/**
+ * @brief Configure the SCL high and low period.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CCR CCR LL_I2C_SetClockPeriod
+ * @param I2Cx I2C Instance.
+ * @param ClockPeriod This parameter must be a value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetClockPeriod(I2C_TypeDef *I2Cx, uint32_t ClockPeriod)
+{
+ MODIFY_REG(I2Cx->CCR, I2C_CCR_CCR, ClockPeriod);
+}
+
+/**
+ * @brief Get the SCL high and low period.
+ * @rmtoll CCR CCR LL_I2C_GetClockPeriod
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x004 and Max_Data=0xFFF, except in FAST DUTY mode where Min_Data=0x001.
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetClockPeriod(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CCR, I2C_CCR_CCR));
+}
+
+/**
+ * @brief Configure the SCL speed.
+ * @note This bit can only be programmed when the I2C is disabled (PE = 0).
+ * @rmtoll CR2 FREQ LL_I2C_ConfigSpeed\n
+ * TRISE TRISE LL_I2C_ConfigSpeed\n
+ * CCR FS LL_I2C_ConfigSpeed\n
+ * CCR DUTY LL_I2C_ConfigSpeed\n
+ * CCR CCR LL_I2C_ConfigSpeed
+ * @param I2Cx I2C Instance.
+ * @param PeriphClock Peripheral Clock (in Hz)
+ * @param ClockSpeed This parameter must be a value lower than 400kHz (in Hz).
+ * @param DutyCycle This parameter can be one of the following values:
+ * @arg @ref LL_I2C_DUTYCYCLE_2
+ * @arg @ref LL_I2C_DUTYCYCLE_16_9
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ConfigSpeed(I2C_TypeDef *I2Cx, uint32_t PeriphClock, uint32_t ClockSpeed,
+ uint32_t DutyCycle)
+{
+ uint32_t freqrange = 0x0U;
+ uint32_t clockconfig = 0x0U;
+
+ /* Compute frequency range */
+ freqrange = __LL_I2C_FREQ_HZ_TO_MHZ(PeriphClock);
+
+ /* Configure I2Cx: Frequency range register */
+ MODIFY_REG(I2Cx->CR2, I2C_CR2_FREQ, freqrange);
+
+ /* Configure I2Cx: Rise Time register */
+ MODIFY_REG(I2Cx->TRISE, I2C_TRISE_TRISE, __LL_I2C_RISE_TIME(freqrange, ClockSpeed));
+
+ /* Configure Speed mode, Duty Cycle and Clock control register value */
+ if (ClockSpeed > LL_I2C_MAX_SPEED_STANDARD)
+ {
+ /* Set Speed mode at fast and duty cycle for Clock Speed request in fast clock range */
+ clockconfig = LL_I2C_CLOCK_SPEED_FAST_MODE | \
+ __LL_I2C_SPEED_FAST_TO_CCR(PeriphClock, ClockSpeed, DutyCycle) | \
+ DutyCycle;
+ }
+ else
+ {
+ /* Set Speed mode at standard for Clock Speed request in standard clock range */
+ clockconfig = LL_I2C_CLOCK_SPEED_STANDARD_MODE | \
+ __LL_I2C_SPEED_STANDARD_TO_CCR(PeriphClock, ClockSpeed);
+ }
+
+ /* Configure I2Cx: Clock control register */
+ MODIFY_REG(I2Cx->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), clockconfig);
+}
+
+/**
+ * @brief Configure peripheral mode.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 SMBUS LL_I2C_SetMode\n
+ * CR1 SMBTYPE LL_I2C_SetMode\n
+ * CR1 ENARP LL_I2C_SetMode
+ * @param I2Cx I2C Instance.
+ * @param PeripheralMode This parameter can be one of the following values:
+ * @arg @ref LL_I2C_MODE_I2C
+ * @arg @ref LL_I2C_MODE_SMBUS_HOST
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_SetMode(I2C_TypeDef *I2Cx, uint32_t PeripheralMode)
+{
+ MODIFY_REG(I2Cx->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP, PeripheralMode);
+}
+
+/**
+ * @brief Get peripheral mode.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 SMBUS LL_I2C_GetMode\n
+ * CR1 SMBTYPE LL_I2C_GetMode\n
+ * CR1 ENARP LL_I2C_GetMode
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_MODE_I2C
+ * @arg @ref LL_I2C_MODE_SMBUS_HOST
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE
+ * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetMode(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->CR1, I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP));
+}
+
+/**
+ * @brief Enable SMBus alert (Host or Device mode)
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note SMBus Device mode:
+ * - SMBus Alert pin is drived low and
+ * Alert Response Address Header acknowledge is enabled.
+ * SMBus Host mode:
+ * - SMBus Alert pin management is supported.
+ * @rmtoll CR1 ALERT LL_I2C_EnableSMBusAlert
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableSMBusAlert(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_ALERT);
+}
+
+/**
+ * @brief Disable SMBus alert (Host or Device mode)
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note SMBus Device mode:
+ * - SMBus Alert pin is not drived (can be used as a standard GPIO) and
+ * Alert Response Address Header acknowledge is disabled.
+ * SMBus Host mode:
+ * - SMBus Alert pin management is not supported.
+ * @rmtoll CR1 ALERT LL_I2C_DisableSMBusAlert
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableSMBusAlert(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_ALERT);
+}
+
+/**
+ * @brief Check if SMBus alert (Host or Device mode) is enabled or disabled.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ALERT LL_I2C_IsEnabledSMBusAlert
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusAlert(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_ALERT) == (I2C_CR1_ALERT));
+}
+
+/**
+ * @brief Enable SMBus Packet Error Calculation (PEC).
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ENPEC LL_I2C_EnableSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_ENPEC);
+}
+
+/**
+ * @brief Disable SMBus Packet Error Calculation (PEC).
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ENPEC LL_I2C_DisableSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_ENPEC);
+}
+
+/**
+ * @brief Check if SMBus Packet Error Calculation (PEC) is enabled or disabled.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 ENPEC LL_I2C_IsEnabledSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_ENPEC) == (I2C_CR1_ENPEC));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EF_IT_Management IT_Management
+ * @{
+ */
+
+/**
+ * @brief Enable TXE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_TX\n
+ * CR2 ITBUFEN LL_I2C_EnableIT_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_TX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Disable TXE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_TX\n
+ * CR2 ITBUFEN LL_I2C_DisableIT_TX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_TX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Check if the TXE Interrupt is enabled or disabled.
+ * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_TX\n
+ * CR2 ITBUFEN LL_I2C_IsEnabledIT_TX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_TX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN) == (I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN));
+}
+
+/**
+ * @brief Enable RXNE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_RX\n
+ * CR2 ITBUFEN LL_I2C_EnableIT_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_RX(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Disable RXNE interrupt.
+ * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_RX\n
+ * CR2 ITBUFEN LL_I2C_DisableIT_RX
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_RX(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Check if the RXNE Interrupt is enabled or disabled.
+ * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_RX\n
+ * CR2 ITBUFEN LL_I2C_IsEnabledIT_RX
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_RX(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN) == (I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN));
+}
+
+/**
+ * @brief Enable Events interrupts.
+ * @note Any of these events will generate interrupt :
+ * Start Bit (SB)
+ * Address sent, Address matched (ADDR)
+ * 10-bit header sent (ADD10)
+ * Stop detection (STOPF)
+ * Byte transfer finished (BTF)
+ *
+ * @note Any of these events will generate interrupt if Buffer interrupts are enabled too(using unitary function @ref LL_I2C_EnableIT_BUF()) :
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITEVTEN LL_I2C_EnableIT_EVT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_EVT(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN);
+}
+
+/**
+ * @brief Disable Events interrupts.
+ * @note Any of these events will generate interrupt :
+ * Start Bit (SB)
+ * Address sent, Address matched (ADDR)
+ * 10-bit header sent (ADD10)
+ * Stop detection (STOPF)
+ * Byte transfer finished (BTF)
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITEVTEN LL_I2C_DisableIT_EVT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_EVT(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN);
+}
+
+/**
+ * @brief Check if Events interrupts are enabled or disabled.
+ * @rmtoll CR2 ITEVTEN LL_I2C_IsEnabledIT_EVT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_EVT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITEVTEN) == (I2C_CR2_ITEVTEN));
+}
+
+/**
+ * @brief Enable Buffer interrupts.
+ * @note Any of these Buffer events will generate interrupt if Events interrupts are enabled too(using unitary function @ref LL_I2C_EnableIT_EVT()) :
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITBUFEN LL_I2C_EnableIT_BUF
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_BUF(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Disable Buffer interrupts.
+ * @note Any of these Buffer events will generate interrupt :
+ * Receive buffer not empty (RXNE)
+ * Transmit buffer empty (TXE)
+ * @rmtoll CR2 ITBUFEN LL_I2C_DisableIT_BUF
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_BUF(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN);
+}
+
+/**
+ * @brief Check if Buffer interrupts are enabled or disabled.
+ * @rmtoll CR2 ITBUFEN LL_I2C_IsEnabledIT_BUF
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_BUF(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITBUFEN) == (I2C_CR2_ITBUFEN));
+}
+
+/**
+ * @brief Enable Error interrupts.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note Any of these errors will generate interrupt :
+ * Bus Error detection (BERR)
+ * Arbitration Loss (ARLO)
+ * Acknowledge Failure(AF)
+ * Overrun/Underrun (OVR)
+ * SMBus Timeout detection (TIMEOUT)
+ * SMBus PEC error detection (PECERR)
+ * SMBus Alert pin event detection (SMBALERT)
+ * @rmtoll CR2 ITERREN LL_I2C_EnableIT_ERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableIT_ERR(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_ITERREN);
+}
+
+/**
+ * @brief Disable Error interrupts.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note Any of these errors will generate interrupt :
+ * Bus Error detection (BERR)
+ * Arbitration Loss (ARLO)
+ * Acknowledge Failure(AF)
+ * Overrun/Underrun (OVR)
+ * SMBus Timeout detection (TIMEOUT)
+ * SMBus PEC error detection (PECERR)
+ * SMBus Alert pin event detection (SMBALERT)
+ * @rmtoll CR2 ITERREN LL_I2C_DisableIT_ERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableIT_ERR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_ITERREN);
+}
+
+/**
+ * @brief Check if Error interrupts are enabled or disabled.
+ * @rmtoll CR2 ITERREN LL_I2C_IsEnabledIT_ERR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_ERR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_ITERREN) == (I2C_CR2_ITERREN));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EF_FLAG_management FLAG_management
+ * @{
+ */
+
+/**
+ * @brief Indicate the status of Transmit data register empty flag.
+ * @note RESET: When next data is written in Transmit data register.
+ * SET: When Transmit data register is empty.
+ * @rmtoll SR1 TXE LL_I2C_IsActiveFlag_TXE
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TXE(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_TXE) == (I2C_SR1_TXE));
+}
+
+/**
+ * @brief Indicate the status of Byte Transfer Finished flag.
+ * RESET: When Data byte transfer not done.
+ * SET: When Data byte transfer succeeded.
+ * @rmtoll SR1 BTF LL_I2C_IsActiveFlag_BTF
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BTF(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_BTF) == (I2C_SR1_BTF));
+}
+
+/**
+ * @brief Indicate the status of Receive data register not empty flag.
+ * @note RESET: When Receive data register is read.
+ * SET: When the received data is copied in Receive data register.
+ * @rmtoll SR1 RXNE LL_I2C_IsActiveFlag_RXNE
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_RXNE(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_RXNE) == (I2C_SR1_RXNE));
+}
+
+/**
+ * @brief Indicate the status of Start Bit (master mode).
+ * @note RESET: When No Start condition.
+ * SET: When Start condition is generated.
+ * @rmtoll SR1 SB LL_I2C_IsActiveFlag_SB
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_SB(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_SB) == (I2C_SR1_SB));
+}
+
+/**
+ * @brief Indicate the status of Address sent (master mode) or Address matched flag (slave mode).
+ * @note RESET: Clear default value.
+ * SET: When the address is fully sent (master mode) or when the received slave address matched with one of the enabled slave address (slave mode).
+ * @rmtoll SR1 ADDR LL_I2C_IsActiveFlag_ADDR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ADDR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_ADDR) == (I2C_SR1_ADDR));
+}
+
+/**
+ * @brief Indicate the status of 10-bit header sent (master mode).
+ * @note RESET: When no ADD10 event occurred.
+ * SET: When the master has sent the first address byte (header).
+ * @rmtoll SR1 ADD10 LL_I2C_IsActiveFlag_ADD10
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ADD10(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_ADD10) == (I2C_SR1_ADD10));
+}
+
+/**
+ * @brief Indicate the status of Acknowledge failure flag.
+ * @note RESET: No acknowledge failure.
+ * SET: When an acknowledge failure is received after a byte transmission.
+ * @rmtoll SR1 AF LL_I2C_IsActiveFlag_AF
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_AF(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_AF) == (I2C_SR1_AF));
+}
+
+/**
+ * @brief Indicate the status of Stop detection flag (slave mode).
+ * @note RESET: Clear default value.
+ * SET: When a Stop condition is detected.
+ * @rmtoll SR1 STOPF LL_I2C_IsActiveFlag_STOP
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_STOP(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_STOPF) == (I2C_SR1_STOPF));
+}
+
+/**
+ * @brief Indicate the status of Bus error flag.
+ * @note RESET: Clear default value.
+ * SET: When a misplaced Start or Stop condition is detected.
+ * @rmtoll SR1 BERR LL_I2C_IsActiveFlag_BERR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BERR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_BERR) == (I2C_SR1_BERR));
+}
+
+/**
+ * @brief Indicate the status of Arbitration lost flag.
+ * @note RESET: Clear default value.
+ * SET: When arbitration lost.
+ * @rmtoll SR1 ARLO LL_I2C_IsActiveFlag_ARLO
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ARLO(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_ARLO) == (I2C_SR1_ARLO));
+}
+
+/**
+ * @brief Indicate the status of Overrun/Underrun flag.
+ * @note RESET: Clear default value.
+ * SET: When an overrun/underrun error occurs (Clock Stretching Disabled).
+ * @rmtoll SR1 OVR LL_I2C_IsActiveFlag_OVR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_OVR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_OVR) == (I2C_SR1_OVR));
+}
+
+/**
+ * @brief Indicate the status of SMBus PEC error flag in reception.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 PECERR LL_I2C_IsActiveSMBusFlag_PECERR
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_PECERR(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_PECERR) == (I2C_SR1_PECERR));
+}
+
+/**
+ * @brief Indicate the status of SMBus Timeout detection flag.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 TIMEOUT LL_I2C_IsActiveSMBusFlag_TIMEOUT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_TIMEOUT) == (I2C_SR1_TIMEOUT));
+}
+
+/**
+ * @brief Indicate the status of SMBus alert flag.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 SMBALERT LL_I2C_IsActiveSMBusFlag_ALERT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_ALERT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR1, I2C_SR1_SMBALERT) == (I2C_SR1_SMBALERT));
+}
+
+/**
+ * @brief Indicate the status of Bus Busy flag.
+ * @note RESET: Clear default value.
+ * SET: When a Start condition is detected.
+ * @rmtoll SR2 BUSY LL_I2C_IsActiveFlag_BUSY
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BUSY(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_BUSY) == (I2C_SR2_BUSY));
+}
+
+/**
+ * @brief Indicate the status of Dual flag.
+ * @note RESET: Received address matched with OAR1.
+ * SET: Received address matched with OAR2.
+ * @rmtoll SR2 DUALF LL_I2C_IsActiveFlag_DUAL
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_DUAL(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_DUALF) == (I2C_SR2_DUALF));
+}
+
+/**
+ * @brief Indicate the status of SMBus Host address reception (Slave mode).
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note RESET: No SMBus Host address
+ * SET: SMBus Host address received.
+ * @note This status is cleared by hardware after a STOP condition or repeated START condition.
+ * @rmtoll SR2 SMBHOST LL_I2C_IsActiveSMBusFlag_SMBHOST
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_SMBHOST(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_SMBHOST) == (I2C_SR2_SMBHOST));
+}
+
+/**
+ * @brief Indicate the status of SMBus Device default address reception (Slave mode).
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note RESET: No SMBus Device default address
+ * SET: SMBus Device default address received.
+ * @note This status is cleared by hardware after a STOP condition or repeated START condition.
+ * @rmtoll SR2 SMBDEFAULT LL_I2C_IsActiveSMBusFlag_SMBDEFAULT
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_SMBDEFAULT(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_SMBDEFAULT) == (I2C_SR2_SMBDEFAULT));
+}
+
+/**
+ * @brief Indicate the status of General call address reception (Slave mode).
+ * @note RESET: No General call address
+ * SET: General call address received.
+ * @note This status is cleared by hardware after a STOP condition or repeated START condition.
+ * @rmtoll SR2 GENCALL LL_I2C_IsActiveFlag_GENCALL
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_GENCALL(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_GENCALL) == (I2C_SR2_GENCALL));
+}
+
+/**
+ * @brief Indicate the status of Master/Slave flag.
+ * @note RESET: Slave Mode.
+ * SET: Master Mode.
+ * @rmtoll SR2 MSL LL_I2C_IsActiveFlag_MSL
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_MSL(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->SR2, I2C_SR2_MSL) == (I2C_SR2_MSL));
+}
+
+/**
+ * @brief Clear Address Matched flag.
+ * @note Clearing this flag is done by a read access to the I2Cx_SR1
+ * register followed by a read access to the I2Cx_SR2 register.
+ * @rmtoll SR1 ADDR LL_I2C_ClearFlag_ADDR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_ADDR(I2C_TypeDef *I2Cx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = I2Cx->SR1;
+ (void) tmpreg;
+ tmpreg = I2Cx->SR2;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Acknowledge failure flag.
+ * @rmtoll SR1 AF LL_I2C_ClearFlag_AF
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_AF(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_AF);
+}
+
+/**
+ * @brief Clear Stop detection flag.
+ * @note Clearing this flag is done by a read access to the I2Cx_SR1
+ * register followed by a write access to I2Cx_CR1 register.
+ * @rmtoll SR1 STOPF LL_I2C_ClearFlag_STOP\n
+ * CR1 PE LL_I2C_ClearFlag_STOP
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_STOP(I2C_TypeDef *I2Cx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = I2Cx->SR1;
+ (void) tmpreg;
+ SET_BIT(I2Cx->CR1, I2C_CR1_PE);
+}
+
+/**
+ * @brief Clear Bus error flag.
+ * @rmtoll SR1 BERR LL_I2C_ClearFlag_BERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_BERR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_BERR);
+}
+
+/**
+ * @brief Clear Arbitration lost flag.
+ * @rmtoll SR1 ARLO LL_I2C_ClearFlag_ARLO
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_ARLO(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_ARLO);
+}
+
+/**
+ * @brief Clear Overrun/Underrun flag.
+ * @rmtoll SR1 OVR LL_I2C_ClearFlag_OVR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearFlag_OVR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_OVR);
+}
+
+/**
+ * @brief Clear SMBus PEC error flag.
+ * @rmtoll SR1 PECERR LL_I2C_ClearSMBusFlag_PECERR
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearSMBusFlag_PECERR(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_PECERR);
+}
+
+/**
+ * @brief Clear SMBus Timeout detection flag.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 TIMEOUT LL_I2C_ClearSMBusFlag_TIMEOUT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_TIMEOUT);
+}
+
+/**
+ * @brief Clear SMBus Alert flag.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR1 SMBALERT LL_I2C_ClearSMBusFlag_ALERT
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_ClearSMBusFlag_ALERT(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->SR1, I2C_SR1_SMBALERT);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_LL_EF_Data_Management Data_Management
+ * @{
+ */
+
+/**
+ * @brief Enable Reset of I2C peripheral.
+ * @rmtoll CR1 SWRST LL_I2C_EnableReset
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableReset(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_SWRST);
+}
+
+/**
+ * @brief Disable Reset of I2C peripheral.
+ * @rmtoll CR1 SWRST LL_I2C_DisableReset
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableReset(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_SWRST);
+}
+
+/**
+ * @brief Check if the I2C peripheral is under reset state or not.
+ * @rmtoll CR1 SWRST LL_I2C_IsResetEnabled
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsResetEnabled(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_SWRST) == (I2C_CR1_SWRST));
+}
+
+/**
+ * @brief Prepare the generation of a ACKnowledge or Non ACKnowledge condition after the address receive match code or next received byte.
+ * @note Usage in Slave or Master mode.
+ * @rmtoll CR1 ACK LL_I2C_AcknowledgeNextData
+ * @param I2Cx I2C Instance.
+ * @param TypeAcknowledge This parameter can be one of the following values:
+ * @arg @ref LL_I2C_ACK
+ * @arg @ref LL_I2C_NACK
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_AcknowledgeNextData(I2C_TypeDef *I2Cx, uint32_t TypeAcknowledge)
+{
+ MODIFY_REG(I2Cx->CR1, I2C_CR1_ACK, TypeAcknowledge);
+}
+
+/**
+ * @brief Generate a START or RESTART condition
+ * @note The START bit can be set even if bus is BUSY or I2C is in slave mode.
+ * This action has no effect when RELOAD is set.
+ * @rmtoll CR1 START LL_I2C_GenerateStartCondition
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_GenerateStartCondition(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_START);
+}
+
+/**
+ * @brief Generate a STOP condition after the current byte transfer (master mode).
+ * @rmtoll CR1 STOP LL_I2C_GenerateStopCondition
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_GenerateStopCondition(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_STOP);
+}
+
+/**
+ * @brief Enable bit POS (master/host mode).
+ * @note In that case, the ACK bit controls the (N)ACK of the next byte received or the PEC bit indicates that the next byte in shift register is a PEC.
+ * @rmtoll CR1 POS LL_I2C_EnableBitPOS
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableBitPOS(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_POS);
+}
+
+/**
+ * @brief Disable bit POS (master/host mode).
+ * @note In that case, the ACK bit controls the (N)ACK of the current byte received or the PEC bit indicates that the current byte in shift register is a PEC.
+ * @rmtoll CR1 POS LL_I2C_DisableBitPOS
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableBitPOS(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_POS);
+}
+
+/**
+ * @brief Check if bit POS is enabled or disabled.
+ * @rmtoll CR1 POS LL_I2C_IsEnabledBitPOS
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledBitPOS(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_POS) == (I2C_CR1_POS));
+}
+
+/**
+ * @brief Indicate the value of transfer direction.
+ * @note RESET: Bus is in read transfer (peripheral point of view).
+ * SET: Bus is in write transfer (peripheral point of view).
+ * @rmtoll SR2 TRA LL_I2C_GetTransferDirection
+ * @param I2Cx I2C Instance.
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_I2C_DIRECTION_WRITE
+ * @arg @ref LL_I2C_DIRECTION_READ
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetTransferDirection(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->SR2, I2C_SR2_TRA));
+}
+
+/**
+ * @brief Enable DMA last transfer.
+ * @note This action mean that next DMA EOT is the last transfer.
+ * @rmtoll CR2 LAST LL_I2C_EnableLastDMA
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableLastDMA(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR2, I2C_CR2_LAST);
+}
+
+/**
+ * @brief Disable DMA last transfer.
+ * @note This action mean that next DMA EOT is not the last transfer.
+ * @rmtoll CR2 LAST LL_I2C_DisableLastDMA
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableLastDMA(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR2, I2C_CR2_LAST);
+}
+
+/**
+ * @brief Check if DMA last transfer is enabled or disabled.
+ * @rmtoll CR2 LAST LL_I2C_IsEnabledLastDMA
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledLastDMA(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR2, I2C_CR2_LAST) == (I2C_CR2_LAST));
+}
+
+/**
+ * @brief Enable transfer or internal comparison of the SMBus Packet Error byte (transmission or reception mode).
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @note This feature is cleared by hardware when the PEC byte is transferred or compared,
+ * or by a START or STOP condition, it is also cleared by software.
+ * @rmtoll CR1 PEC LL_I2C_EnableSMBusPECCompare
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_EnableSMBusPECCompare(I2C_TypeDef *I2Cx)
+{
+ SET_BIT(I2Cx->CR1, I2C_CR1_PEC);
+}
+
+/**
+ * @brief Disable transfer or internal comparison of the SMBus Packet Error byte (transmission or reception mode).
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 PEC LL_I2C_DisableSMBusPECCompare
+ * @param I2Cx I2C Instance.
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_DisableSMBusPECCompare(I2C_TypeDef *I2Cx)
+{
+ CLEAR_BIT(I2Cx->CR1, I2C_CR1_PEC);
+}
+
+/**
+ * @brief Check if the SMBus Packet Error byte transfer or internal comparison is requested or not.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll CR1 PEC LL_I2C_IsEnabledSMBusPECCompare
+ * @param I2Cx I2C Instance.
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPECCompare(I2C_TypeDef *I2Cx)
+{
+ return (READ_BIT(I2Cx->CR1, I2C_CR1_PEC) == (I2C_CR1_PEC));
+}
+
+/**
+ * @brief Get the SMBus Packet Error byte calculated.
+ * @note Macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not
+ * SMBus feature is supported by the I2Cx Instance.
+ * @rmtoll SR2 PEC LL_I2C_GetSMBusPEC
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint32_t LL_I2C_GetSMBusPEC(I2C_TypeDef *I2Cx)
+{
+ return (uint32_t)(READ_BIT(I2Cx->SR2, I2C_SR2_PEC) >> I2C_SR2_PEC_Pos);
+}
+
+/**
+ * @brief Read Receive Data register.
+ * @rmtoll DR DR LL_I2C_ReceiveData8
+ * @param I2Cx I2C Instance.
+ * @retval Value between Min_Data=0x0 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint8_t LL_I2C_ReceiveData8(I2C_TypeDef *I2Cx)
+{
+ return (uint8_t)(READ_BIT(I2Cx->DR, I2C_DR_DR));
+}
+
+/**
+ * @brief Write in Transmit Data Register .
+ * @rmtoll DR DR LL_I2C_TransmitData8
+ * @param I2Cx I2C Instance.
+ * @param Data Value between Min_Data=0x0 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_I2C_TransmitData8(I2C_TypeDef *I2Cx, uint8_t Data)
+{
+ MODIFY_REG(I2Cx->DR, I2C_DR_DR, Data);
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup I2C_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+
+uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct);
+uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx);
+void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct);
+
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* I2C1 || I2C2 */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_I2C_H */
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h
new file mode 100644
index 0000000..ffe4192
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h
@@ -0,0 +1,2569 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_usart.h
+ * @author MCD Application Team
+ * @brief Header file of USART LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F1xx_LL_USART_H
+#define __STM32F1xx_LL_USART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx.h"
+
+/** @addtogroup STM32F1xx_LL_Driver
+ * @{
+ */
+
+#if defined (USART1) || defined (USART2) || defined (USART3) || defined (UART4) || defined (UART5)
+
+/** @defgroup USART_LL USART
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup USART_LL_Private_Constants USART Private Constants
+ * @{
+ */
+
+/* Defines used for the bit position in the register and perform offsets*/
+#define USART_POSITION_GTPR_GT USART_GTPR_GT_Pos
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_Private_Macros USART Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_ES_INIT USART Exported Init structures
+ * @{
+ */
+
+/**
+ * @brief LL USART Init Structure definition
+ */
+typedef struct
+{
+ uint32_t BaudRate; /*!< This field defines expected Usart communication baud rate.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetBaudRate().*/
+
+ uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref USART_LL_EC_DATAWIDTH.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetDataWidth().*/
+
+ uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref USART_LL_EC_STOPBITS.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetStopBitsLength().*/
+
+ uint32_t Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref USART_LL_EC_PARITY.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetParity().*/
+
+ uint32_t TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref USART_LL_EC_DIRECTION.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetTransferDirection().*/
+
+ uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
+ This parameter can be a value of @ref USART_LL_EC_HWCONTROL.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetHWFlowCtrl().*/
+
+ uint32_t OverSampling; /*!< Specifies whether USART oversampling mode is 16 or 8.
+ This parameter can be a value of @ref USART_LL_EC_OVERSAMPLING.
+
+ This feature can be modified afterwards using unitary function @ref LL_USART_SetOverSampling().*/
+
+} LL_USART_InitTypeDef;
+
+/**
+ * @brief LL USART Clock Init Structure definition
+ */
+typedef struct
+{
+ uint32_t ClockOutput; /*!< Specifies whether the USART clock is enabled or disabled.
+ This parameter can be a value of @ref USART_LL_EC_CLOCK.
+
+ USART HW configuration can be modified afterwards using unitary functions
+ @ref LL_USART_EnableSCLKOutput() or @ref LL_USART_DisableSCLKOutput().
+ For more details, refer to description of this function. */
+
+ uint32_t ClockPolarity; /*!< Specifies the steady state of the serial clock.
+ This parameter can be a value of @ref USART_LL_EC_POLARITY.
+
+ USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetClockPolarity().
+ For more details, refer to description of this function. */
+
+ uint32_t ClockPhase; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref USART_LL_EC_PHASE.
+
+ USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetClockPhase().
+ For more details, refer to description of this function. */
+
+ uint32_t LastBitClockPulse; /*!< Specifies whether the clock pulse corresponding to the last transmitted
+ data bit (MSB) has to be output on the SCLK pin in synchronous mode.
+ This parameter can be a value of @ref USART_LL_EC_LASTCLKPULSE.
+
+ USART HW configuration can be modified afterwards using unitary functions @ref LL_USART_SetLastClkPulseOutput().
+ For more details, refer to description of this function. */
+
+} LL_USART_ClockInitTypeDef;
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup USART_LL_Exported_Constants USART Exported Constants
+ * @{
+ */
+
+/** @defgroup USART_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_USART_ReadReg function
+ * @{
+ */
+#define LL_USART_SR_PE USART_SR_PE /*!< Parity error flag */
+#define LL_USART_SR_FE USART_SR_FE /*!< Framing error flag */
+#define LL_USART_SR_NE USART_SR_NE /*!< Noise detected flag */
+#define LL_USART_SR_ORE USART_SR_ORE /*!< Overrun error flag */
+#define LL_USART_SR_IDLE USART_SR_IDLE /*!< Idle line detected flag */
+#define LL_USART_SR_RXNE USART_SR_RXNE /*!< Read data register not empty flag */
+#define LL_USART_SR_TC USART_SR_TC /*!< Transmission complete flag */
+#define LL_USART_SR_TXE USART_SR_TXE /*!< Transmit data register empty flag */
+#define LL_USART_SR_LBD USART_SR_LBD /*!< LIN break detection flag */
+#define LL_USART_SR_CTS USART_SR_CTS /*!< CTS flag */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_USART_ReadReg and LL_USART_WriteReg functions
+ * @{
+ */
+#define LL_USART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */
+#define LL_USART_CR1_RXNEIE USART_CR1_RXNEIE /*!< Read data register not empty interrupt enable */
+#define LL_USART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */
+#define LL_USART_CR1_TXEIE USART_CR1_TXEIE /*!< Transmit data register empty interrupt enable */
+#define LL_USART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */
+#define LL_USART_CR2_LBDIE USART_CR2_LBDIE /*!< LIN break detection interrupt enable */
+#define LL_USART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */
+#define LL_USART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_DIRECTION Communication Direction
+ * @{
+ */
+#define LL_USART_DIRECTION_NONE 0x00000000U /*!< Transmitter and Receiver are disabled */
+#define LL_USART_DIRECTION_RX USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */
+#define LL_USART_DIRECTION_TX USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */
+#define LL_USART_DIRECTION_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< Transmitter and Receiver are enabled */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_PARITY Parity Control
+ * @{
+ */
+#define LL_USART_PARITY_NONE 0x00000000U /*!< Parity control disabled */
+#define LL_USART_PARITY_EVEN USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */
+#define LL_USART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_WAKEUP Wakeup
+ * @{
+ */
+#define LL_USART_WAKEUP_IDLELINE 0x00000000U /*!< USART wake up from Mute mode on Idle Line */
+#define LL_USART_WAKEUP_ADDRESSMARK USART_CR1_WAKE /*!< USART wake up from Mute mode on Address Mark */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_DATAWIDTH Datawidth
+ * @{
+ */
+#define LL_USART_DATAWIDTH_8B 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */
+#define LL_USART_DATAWIDTH_9B USART_CR1_M /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_OVERSAMPLING Oversampling
+ * @{
+ */
+#define LL_USART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */
+#if defined(USART_CR1_OVER8)
+#define LL_USART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */
+#endif /* USART_OverSampling_Feature */
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_EC_CLOCK Clock Signal
+ * @{
+ */
+
+#define LL_USART_CLOCK_DISABLE 0x00000000U /*!< Clock signal not provided */
+#define LL_USART_CLOCK_ENABLE USART_CR2_CLKEN /*!< Clock signal provided */
+/**
+ * @}
+ */
+#endif /*USE_FULL_LL_DRIVER*/
+
+/** @defgroup USART_LL_EC_LASTCLKPULSE Last Clock Pulse
+ * @{
+ */
+#define LL_USART_LASTCLKPULSE_NO_OUTPUT 0x00000000U /*!< The clock pulse of the last data bit is not output to the SCLK pin */
+#define LL_USART_LASTCLKPULSE_OUTPUT USART_CR2_LBCL /*!< The clock pulse of the last data bit is output to the SCLK pin */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_PHASE Clock Phase
+ * @{
+ */
+#define LL_USART_PHASE_1EDGE 0x00000000U /*!< The first clock transition is the first data capture edge */
+#define LL_USART_PHASE_2EDGE USART_CR2_CPHA /*!< The second clock transition is the first data capture edge */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_POLARITY Clock Polarity
+ * @{
+ */
+#define LL_USART_POLARITY_LOW 0x00000000U /*!< Steady low value on SCLK pin outside transmission window*/
+#define LL_USART_POLARITY_HIGH USART_CR2_CPOL /*!< Steady high value on SCLK pin outside transmission window */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_STOPBITS Stop Bits
+ * @{
+ */
+#define LL_USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< 0.5 stop bit */
+#define LL_USART_STOPBITS_1 0x00000000U /*!< 1 stop bit */
+#define LL_USART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< 1.5 stop bits */
+#define LL_USART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_HWCONTROL Hardware Control
+ * @{
+ */
+#define LL_USART_HWCONTROL_NONE 0x00000000U /*!< CTS and RTS hardware flow control disabled */
+#define LL_USART_HWCONTROL_RTS USART_CR3_RTSE /*!< RTS output enabled, data is only requested when there is space in the receive buffer */
+#define LL_USART_HWCONTROL_CTS USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted when the nCTS input is asserted (tied to 0) */
+#define LL_USART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_IRDA_POWER IrDA Power
+ * @{
+ */
+#define LL_USART_IRDA_POWER_NORMAL 0x00000000U /*!< IrDA normal power mode */
+#define LL_USART_IRDA_POWER_LOW USART_CR3_IRLP /*!< IrDA low power mode */
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EC_LINBREAK_DETECT LIN Break Detection Length
+ * @{
+ */
+#define LL_USART_LINBREAK_DETECT_10B 0x00000000U /*!< 10-bit break detection method selected */
+#define LL_USART_LINBREAK_DETECT_11B USART_CR2_LBDL /*!< 11-bit break detection method selected */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup USART_LL_Exported_Macros USART Exported Macros
+ * @{
+ */
+
+/** @defgroup USART_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in USART register
+ * @param __INSTANCE__ USART Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_USART_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in USART register
+ * @param __INSTANCE__ USART Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_USART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EM_Exported_Macros_Helper Exported_Macros_Helper
+ * @{
+ */
+
+/**
+ * @brief Compute USARTDIV value according to Peripheral Clock and
+ * expected Baud Rate in 8 bits sampling mode (32 bits value of USARTDIV is returned)
+ * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance
+ * @param __BAUDRATE__ Baud rate value to achieve
+ * @retval USARTDIV value to be used for BRR register filling in OverSampling_8 case
+ */
+#define __LL_USART_DIV_SAMPLING8_100(__PERIPHCLK__, __BAUDRATE__) (((__PERIPHCLK__)*25)/(2*(__BAUDRATE__)))
+#define __LL_USART_DIVMANT_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (__LL_USART_DIV_SAMPLING8_100((__PERIPHCLK__), (__BAUDRATE__))/100)
+#define __LL_USART_DIVFRAQ_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIV_SAMPLING8_100((__PERIPHCLK__), (__BAUDRATE__)) - (__LL_USART_DIVMANT_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) * 100)) * 8\
+ + 50) / 100)
+/* UART BRR = mantissa + overflow + fraction
+ = (UART DIVMANT << 4) + ((UART DIVFRAQ & 0xF8) << 1) + (UART DIVFRAQ & 0x07) */
+#define __LL_USART_DIV_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIVMANT_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) << 4) + \
+ ((__LL_USART_DIVFRAQ_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) & 0xF8) << 1)) + \
+ (__LL_USART_DIVFRAQ_SAMPLING8((__PERIPHCLK__), (__BAUDRATE__)) & 0x07))
+
+/**
+ * @brief Compute USARTDIV value according to Peripheral Clock and
+ * expected Baud Rate in 16 bits sampling mode (32 bits value of USARTDIV is returned)
+ * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance
+ * @param __BAUDRATE__ Baud rate value to achieve
+ * @retval USARTDIV value to be used for BRR register filling in OverSampling_16 case
+ */
+#define __LL_USART_DIV_SAMPLING16_100(__PERIPHCLK__, __BAUDRATE__) (((__PERIPHCLK__)*25)/(4*(__BAUDRATE__)))
+#define __LL_USART_DIVMANT_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) (__LL_USART_DIV_SAMPLING16_100((__PERIPHCLK__), (__BAUDRATE__))/100)
+#define __LL_USART_DIVFRAQ_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) ((((__LL_USART_DIV_SAMPLING16_100((__PERIPHCLK__), (__BAUDRATE__)) - (__LL_USART_DIVMANT_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) * 100)) * 16)\
+ + 50) / 100)
+/* USART BRR = mantissa + overflow + fraction
+ = (USART DIVMANT << 4) + (USART DIVFRAQ & 0xF0) + (USART DIVFRAQ & 0x0F) */
+#define __LL_USART_DIV_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) (((__LL_USART_DIVMANT_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) << 4) + \
+ (__LL_USART_DIVFRAQ_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) & 0xF0)) + \
+ (__LL_USART_DIVFRAQ_SAMPLING16((__PERIPHCLK__), (__BAUDRATE__)) & 0x0F))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup USART_LL_Exported_Functions USART Exported Functions
+ * @{
+ */
+
+/** @defgroup USART_LL_EF_Configuration Configuration functions
+ * @{
+ */
+
+/**
+ * @brief USART Enable
+ * @rmtoll CR1 UE LL_USART_Enable
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR1, USART_CR1_UE);
+}
+
+/**
+ * @brief USART Disable (all USART prescalers and outputs are disabled)
+ * @note When USART is disabled, USART prescalers and outputs are stopped immediately,
+ * and current operations are discarded. The configuration of the USART is kept, but all the status
+ * flags, in the USARTx_SR are set to their default values.
+ * @rmtoll CR1 UE LL_USART_Disable
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR1, USART_CR1_UE);
+}
+
+/**
+ * @brief Indicate if USART is enabled
+ * @rmtoll CR1 UE LL_USART_IsEnabled
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabled(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_UE) == (USART_CR1_UE));
+}
+
+/**
+ * @brief Receiver Enable (Receiver is enabled and begins searching for a start bit)
+ * @rmtoll CR1 RE LL_USART_EnableDirectionRx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDirectionRx(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RE);
+}
+
+/**
+ * @brief Receiver Disable
+ * @rmtoll CR1 RE LL_USART_DisableDirectionRx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDirectionRx(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RE);
+}
+
+/**
+ * @brief Transmitter Enable
+ * @rmtoll CR1 TE LL_USART_EnableDirectionTx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TE);
+}
+
+/**
+ * @brief Transmitter Disable
+ * @rmtoll CR1 TE LL_USART_DisableDirectionTx
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TE);
+}
+
+/**
+ * @brief Configure simultaneously enabled/disabled states
+ * of Transmitter and Receiver
+ * @rmtoll CR1 RE LL_USART_SetTransferDirection\n
+ * CR1 TE LL_USART_SetTransferDirection
+ * @param USARTx USART Instance
+ * @param TransferDirection This parameter can be one of the following values:
+ * @arg @ref LL_USART_DIRECTION_NONE
+ * @arg @ref LL_USART_DIRECTION_RX
+ * @arg @ref LL_USART_DIRECTION_TX
+ * @arg @ref LL_USART_DIRECTION_TX_RX
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetTransferDirection(USART_TypeDef *USARTx, uint32_t TransferDirection)
+{
+ ATOMIC_MODIFY_REG(USARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection);
+}
+
+/**
+ * @brief Return enabled/disabled states of Transmitter and Receiver
+ * @rmtoll CR1 RE LL_USART_GetTransferDirection\n
+ * CR1 TE LL_USART_GetTransferDirection
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_DIRECTION_NONE
+ * @arg @ref LL_USART_DIRECTION_RX
+ * @arg @ref LL_USART_DIRECTION_TX
+ * @arg @ref LL_USART_DIRECTION_TX_RX
+ */
+__STATIC_INLINE uint32_t LL_USART_GetTransferDirection(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_RE | USART_CR1_TE));
+}
+
+/**
+ * @brief Configure Parity (enabled/disabled and parity mode if enabled).
+ * @note This function selects if hardware parity control (generation and detection) is enabled or disabled.
+ * When the parity control is enabled (Odd or Even), computed parity bit is inserted at the MSB position
+ * (9th or 8th bit depending on data width) and parity is checked on the received data.
+ * @rmtoll CR1 PS LL_USART_SetParity\n
+ * CR1 PCE LL_USART_SetParity
+ * @param USARTx USART Instance
+ * @param Parity This parameter can be one of the following values:
+ * @arg @ref LL_USART_PARITY_NONE
+ * @arg @ref LL_USART_PARITY_EVEN
+ * @arg @ref LL_USART_PARITY_ODD
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetParity(USART_TypeDef *USARTx, uint32_t Parity)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity);
+}
+
+/**
+ * @brief Return Parity configuration (enabled/disabled and parity mode if enabled)
+ * @rmtoll CR1 PS LL_USART_GetParity\n
+ * CR1 PCE LL_USART_GetParity
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_PARITY_NONE
+ * @arg @ref LL_USART_PARITY_EVEN
+ * @arg @ref LL_USART_PARITY_ODD
+ */
+__STATIC_INLINE uint32_t LL_USART_GetParity(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE));
+}
+
+/**
+ * @brief Set Receiver Wake Up method from Mute mode.
+ * @rmtoll CR1 WAKE LL_USART_SetWakeUpMethod
+ * @param USARTx USART Instance
+ * @param Method This parameter can be one of the following values:
+ * @arg @ref LL_USART_WAKEUP_IDLELINE
+ * @arg @ref LL_USART_WAKEUP_ADDRESSMARK
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetWakeUpMethod(USART_TypeDef *USARTx, uint32_t Method)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_WAKE, Method);
+}
+
+/**
+ * @brief Return Receiver Wake Up method from Mute mode
+ * @rmtoll CR1 WAKE LL_USART_GetWakeUpMethod
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_WAKEUP_IDLELINE
+ * @arg @ref LL_USART_WAKEUP_ADDRESSMARK
+ */
+__STATIC_INLINE uint32_t LL_USART_GetWakeUpMethod(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_WAKE));
+}
+
+/**
+ * @brief Set Word length (i.e. nb of data bits, excluding start and stop bits)
+ * @rmtoll CR1 M LL_USART_SetDataWidth
+ * @param USARTx USART Instance
+ * @param DataWidth This parameter can be one of the following values:
+ * @arg @ref LL_USART_DATAWIDTH_8B
+ * @arg @ref LL_USART_DATAWIDTH_9B
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetDataWidth(USART_TypeDef *USARTx, uint32_t DataWidth)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_M, DataWidth);
+}
+
+/**
+ * @brief Return Word length (i.e. nb of data bits, excluding start and stop bits)
+ * @rmtoll CR1 M LL_USART_GetDataWidth
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_DATAWIDTH_8B
+ * @arg @ref LL_USART_DATAWIDTH_9B
+ */
+__STATIC_INLINE uint32_t LL_USART_GetDataWidth(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_M));
+}
+
+#if defined(USART_CR1_OVER8)
+/**
+ * @brief Set Oversampling to 8-bit or 16-bit mode
+ * @rmtoll CR1 OVER8 LL_USART_SetOverSampling
+ * @param USARTx USART Instance
+ * @param OverSampling This parameter can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetOverSampling(USART_TypeDef *USARTx, uint32_t OverSampling)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_OVER8, OverSampling);
+}
+
+/**
+ * @brief Return Oversampling mode
+ * @rmtoll CR1 OVER8 LL_USART_GetOverSampling
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ */
+__STATIC_INLINE uint32_t LL_USART_GetOverSampling(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_OVER8));
+}
+
+#endif /* USART_OverSampling_Feature */
+/**
+ * @brief Configure if Clock pulse of the last data bit is output to the SCLK pin or not
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 LBCL LL_USART_SetLastClkPulseOutput
+ * @param USARTx USART Instance
+ * @param LastBitClockPulse This parameter can be one of the following values:
+ * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
+ * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetLastClkPulseOutput(USART_TypeDef *USARTx, uint32_t LastBitClockPulse)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_LBCL, LastBitClockPulse);
+}
+
+/**
+ * @brief Retrieve Clock pulse of the last data bit output configuration
+ * (Last bit Clock pulse output to the SCLK pin or not)
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 LBCL LL_USART_GetLastClkPulseOutput
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
+ * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
+ */
+__STATIC_INLINE uint32_t LL_USART_GetLastClkPulseOutput(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBCL));
+}
+
+/**
+ * @brief Select the phase of the clock output on the SCLK pin in synchronous mode
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPHA LL_USART_SetClockPhase
+ * @param USARTx USART Instance
+ * @param ClockPhase This parameter can be one of the following values:
+ * @arg @ref LL_USART_PHASE_1EDGE
+ * @arg @ref LL_USART_PHASE_2EDGE
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetClockPhase(USART_TypeDef *USARTx, uint32_t ClockPhase)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_CPHA, ClockPhase);
+}
+
+/**
+ * @brief Return phase of the clock output on the SCLK pin in synchronous mode
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPHA LL_USART_GetClockPhase
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_PHASE_1EDGE
+ * @arg @ref LL_USART_PHASE_2EDGE
+ */
+__STATIC_INLINE uint32_t LL_USART_GetClockPhase(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPHA));
+}
+
+/**
+ * @brief Select the polarity of the clock output on the SCLK pin in synchronous mode
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPOL LL_USART_SetClockPolarity
+ * @param USARTx USART Instance
+ * @param ClockPolarity This parameter can be one of the following values:
+ * @arg @ref LL_USART_POLARITY_LOW
+ * @arg @ref LL_USART_POLARITY_HIGH
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetClockPolarity(USART_TypeDef *USARTx, uint32_t ClockPolarity)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_CPOL, ClockPolarity);
+}
+
+/**
+ * @brief Return polarity of the clock output on the SCLK pin in synchronous mode
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CPOL LL_USART_GetClockPolarity
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_POLARITY_LOW
+ * @arg @ref LL_USART_POLARITY_HIGH
+ */
+__STATIC_INLINE uint32_t LL_USART_GetClockPolarity(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPOL));
+}
+
+/**
+ * @brief Configure Clock signal format (Phase Polarity and choice about output of last bit clock pulse)
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clock Phase configuration using @ref LL_USART_SetClockPhase() function
+ * - Clock Polarity configuration using @ref LL_USART_SetClockPolarity() function
+ * - Output of Last bit Clock pulse configuration using @ref LL_USART_SetLastClkPulseOutput() function
+ * @rmtoll CR2 CPHA LL_USART_ConfigClock\n
+ * CR2 CPOL LL_USART_ConfigClock\n
+ * CR2 LBCL LL_USART_ConfigClock
+ * @param USARTx USART Instance
+ * @param Phase This parameter can be one of the following values:
+ * @arg @ref LL_USART_PHASE_1EDGE
+ * @arg @ref LL_USART_PHASE_2EDGE
+ * @param Polarity This parameter can be one of the following values:
+ * @arg @ref LL_USART_POLARITY_LOW
+ * @arg @ref LL_USART_POLARITY_HIGH
+ * @param LBCPOutput This parameter can be one of the following values:
+ * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT
+ * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigClock(USART_TypeDef *USARTx, uint32_t Phase, uint32_t Polarity, uint32_t LBCPOutput)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL, Phase | Polarity | LBCPOutput);
+}
+
+/**
+ * @brief Enable Clock output on SCLK pin
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CLKEN LL_USART_EnableSCLKOutput
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableSCLKOutput(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR2, USART_CR2_CLKEN);
+}
+
+/**
+ * @brief Disable Clock output on SCLK pin
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CLKEN LL_USART_DisableSCLKOutput
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableSCLKOutput(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN);
+}
+
+/**
+ * @brief Indicate if Clock output on SCLK pin is enabled
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @rmtoll CR2 CLKEN LL_USART_IsEnabledSCLKOutput
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledSCLKOutput(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR2, USART_CR2_CLKEN) == (USART_CR2_CLKEN));
+}
+
+/**
+ * @brief Set the length of the stop bits
+ * @rmtoll CR2 STOP LL_USART_SetStopBitsLength
+ * @param USARTx USART Instance
+ * @param StopBits This parameter can be one of the following values:
+ * @arg @ref LL_USART_STOPBITS_0_5
+ * @arg @ref LL_USART_STOPBITS_1
+ * @arg @ref LL_USART_STOPBITS_1_5
+ * @arg @ref LL_USART_STOPBITS_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetStopBitsLength(USART_TypeDef *USARTx, uint32_t StopBits)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits);
+}
+
+/**
+ * @brief Retrieve the length of the stop bits
+ * @rmtoll CR2 STOP LL_USART_GetStopBitsLength
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_STOPBITS_0_5
+ * @arg @ref LL_USART_STOPBITS_1
+ * @arg @ref LL_USART_STOPBITS_1_5
+ * @arg @ref LL_USART_STOPBITS_2
+ */
+__STATIC_INLINE uint32_t LL_USART_GetStopBitsLength(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_STOP));
+}
+
+/**
+ * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits)
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Data Width configuration using @ref LL_USART_SetDataWidth() function
+ * - Parity Control and mode configuration using @ref LL_USART_SetParity() function
+ * - Stop bits configuration using @ref LL_USART_SetStopBitsLength() function
+ * @rmtoll CR1 PS LL_USART_ConfigCharacter\n
+ * CR1 PCE LL_USART_ConfigCharacter\n
+ * CR1 M LL_USART_ConfigCharacter\n
+ * CR2 STOP LL_USART_ConfigCharacter
+ * @param USARTx USART Instance
+ * @param DataWidth This parameter can be one of the following values:
+ * @arg @ref LL_USART_DATAWIDTH_8B
+ * @arg @ref LL_USART_DATAWIDTH_9B
+ * @param Parity This parameter can be one of the following values:
+ * @arg @ref LL_USART_PARITY_NONE
+ * @arg @ref LL_USART_PARITY_EVEN
+ * @arg @ref LL_USART_PARITY_ODD
+ * @param StopBits This parameter can be one of the following values:
+ * @arg @ref LL_USART_STOPBITS_0_5
+ * @arg @ref LL_USART_STOPBITS_1
+ * @arg @ref LL_USART_STOPBITS_1_5
+ * @arg @ref LL_USART_STOPBITS_2
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigCharacter(USART_TypeDef *USARTx, uint32_t DataWidth, uint32_t Parity,
+ uint32_t StopBits)
+{
+ MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, Parity | DataWidth);
+ MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits);
+}
+
+/**
+ * @brief Set Address of the USART node.
+ * @note This is used in multiprocessor communication during Mute mode or Stop mode,
+ * for wake up with address mark detection.
+ * @rmtoll CR2 ADD LL_USART_SetNodeAddress
+ * @param USARTx USART Instance
+ * @param NodeAddress 4 bit Address of the USART node.
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetNodeAddress(USART_TypeDef *USARTx, uint32_t NodeAddress)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_ADD, (NodeAddress & USART_CR2_ADD));
+}
+
+/**
+ * @brief Return 4 bit Address of the USART node as set in ADD field of CR2.
+ * @note only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant)
+ * @rmtoll CR2 ADD LL_USART_GetNodeAddress
+ * @param USARTx USART Instance
+ * @retval Address of the USART node (Value between Min_Data=0 and Max_Data=255)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetNodeAddress(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADD));
+}
+
+/**
+ * @brief Enable RTS HW Flow Control
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_EnableRTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableRTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_RTSE);
+}
+
+/**
+ * @brief Disable RTS HW Flow Control
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_DisableRTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableRTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_RTSE);
+}
+
+/**
+ * @brief Enable CTS HW Flow Control
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSE LL_USART_EnableCTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableCTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_CTSE);
+}
+
+/**
+ * @brief Disable CTS HW Flow Control
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSE LL_USART_DisableCTSHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableCTSHWFlowCtrl(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_CTSE);
+}
+
+/**
+ * @brief Configure HW Flow Control mode (both CTS and RTS)
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_SetHWFlowCtrl\n
+ * CR3 CTSE LL_USART_SetHWFlowCtrl
+ * @param USARTx USART Instance
+ * @param HardwareFlowControl This parameter can be one of the following values:
+ * @arg @ref LL_USART_HWCONTROL_NONE
+ * @arg @ref LL_USART_HWCONTROL_RTS
+ * @arg @ref LL_USART_HWCONTROL_CTS
+ * @arg @ref LL_USART_HWCONTROL_RTS_CTS
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetHWFlowCtrl(USART_TypeDef *USARTx, uint32_t HardwareFlowControl)
+{
+ MODIFY_REG(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl);
+}
+
+/**
+ * @brief Return HW Flow Control configuration (both CTS and RTS)
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 RTSE LL_USART_GetHWFlowCtrl\n
+ * CR3 CTSE LL_USART_GetHWFlowCtrl
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_HWCONTROL_NONE
+ * @arg @ref LL_USART_HWCONTROL_RTS
+ * @arg @ref LL_USART_HWCONTROL_CTS
+ * @arg @ref LL_USART_HWCONTROL_RTS_CTS
+ */
+__STATIC_INLINE uint32_t LL_USART_GetHWFlowCtrl(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE));
+}
+
+#if defined(USART_CR3_ONEBIT)
+/**
+ * @brief Enable One bit sampling method
+ * @rmtoll CR3 ONEBIT LL_USART_EnableOneBitSamp
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableOneBitSamp(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_ONEBIT);
+}
+
+/**
+ * @brief Disable One bit sampling method
+ * @rmtoll CR3 ONEBIT LL_USART_DisableOneBitSamp
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableOneBitSamp(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_ONEBIT);
+}
+
+/**
+ * @brief Indicate if One bit sampling method is enabled
+ * @rmtoll CR3 ONEBIT LL_USART_IsEnabledOneBitSamp
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledOneBitSamp(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_ONEBIT) == (USART_CR3_ONEBIT));
+}
+#endif /* USART_OneBitSampling_Feature */
+
+#if defined(USART_CR1_OVER8)
+/**
+ * @brief Configure USART BRR register for achieving expected Baud Rate value.
+ * @note Compute and set USARTDIV value in BRR Register (full BRR content)
+ * according to used Peripheral Clock, Oversampling mode, and expected Baud Rate values
+ * @note Peripheral clock and Baud rate values provided as function parameters should be valid
+ * (Baud rate value != 0)
+ * @rmtoll BRR BRR LL_USART_SetBaudRate
+ * @param USARTx USART Instance
+ * @param PeriphClk Peripheral Clock
+ * @param OverSampling This parameter can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ * @param BaudRate Baud Rate
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling,
+ uint32_t BaudRate)
+{
+ if (OverSampling == LL_USART_OVERSAMPLING_8)
+ {
+ USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING8(PeriphClk, BaudRate));
+ }
+ else
+ {
+ USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, BaudRate));
+ }
+}
+
+/**
+ * @brief Return current Baud Rate value, according to USARTDIV present in BRR register
+ * (full BRR content), and to used Peripheral Clock and Oversampling mode values
+ * @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned.
+ * @rmtoll BRR BRR LL_USART_GetBaudRate
+ * @param USARTx USART Instance
+ * @param PeriphClk Peripheral Clock
+ * @param OverSampling This parameter can be one of the following values:
+ * @arg @ref LL_USART_OVERSAMPLING_16
+ * @arg @ref LL_USART_OVERSAMPLING_8
+ * @retval Baud Rate
+ */
+__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling)
+{
+ uint32_t usartdiv = 0x0U;
+ uint32_t brrresult = 0x0U;
+
+ usartdiv = USARTx->BRR;
+
+ if (OverSampling == LL_USART_OVERSAMPLING_8)
+ {
+ if ((usartdiv & 0xFFF7U) != 0U)
+ {
+ usartdiv = (uint16_t)((usartdiv & 0xFFF0U) | ((usartdiv & 0x0007U) << 1U)) ;
+ brrresult = (PeriphClk * 2U) / usartdiv;
+ }
+ }
+ else
+ {
+ if ((usartdiv & 0xFFFFU) != 0U)
+ {
+ brrresult = PeriphClk / usartdiv;
+ }
+ }
+ return (brrresult);
+}
+#else
+/**
+ * @brief Configure USART BRR register for achieving expected Baud Rate value.
+ * @note Compute and set USARTDIV value in BRR Register (full BRR content)
+ * according to used Peripheral Clock, Oversampling mode, and expected Baud Rate values
+ * @note Peripheral clock and Baud rate values provided as function parameters should be valid
+ * (Baud rate value != 0)
+ * @rmtoll BRR BRR LL_USART_SetBaudRate
+ * @param USARTx USART Instance
+ * @param PeriphClk Peripheral Clock
+ * @param BaudRate Baud Rate
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t BaudRate)
+{
+ USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, BaudRate));
+}
+
+/**
+ * @brief Return current Baud Rate value, according to USARTDIV present in BRR register
+ * (full BRR content), and to used Peripheral Clock and Oversampling mode values
+ * @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned.
+ * @rmtoll BRR BRR LL_USART_GetBaudRate
+ * @param USARTx USART Instance
+ * @param PeriphClk Peripheral Clock
+ * @retval Baud Rate
+ */
+__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk)
+{
+ uint32_t usartdiv = 0x0U;
+ uint32_t brrresult = 0x0U;
+
+ usartdiv = USARTx->BRR;
+
+ if ((usartdiv & 0xFFFFU) != 0U)
+ {
+ brrresult = PeriphClk / usartdiv;
+ }
+ return (brrresult);
+}
+#endif /* USART_OverSampling_Feature */
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_IRDA Configuration functions related to Irda feature
+ * @{
+ */
+
+/**
+ * @brief Enable IrDA mode
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IREN LL_USART_EnableIrda
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIrda(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_IREN);
+}
+
+/**
+ * @brief Disable IrDA mode
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IREN LL_USART_DisableIrda
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIrda(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_IREN);
+}
+
+/**
+ * @brief Indicate if IrDA mode is enabled
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IREN LL_USART_IsEnabledIrda
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIrda(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_IREN) == (USART_CR3_IREN));
+}
+
+/**
+ * @brief Configure IrDA Power Mode (Normal or Low Power)
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IRLP LL_USART_SetIrdaPowerMode
+ * @param USARTx USART Instance
+ * @param PowerMode This parameter can be one of the following values:
+ * @arg @ref LL_USART_IRDA_POWER_NORMAL
+ * @arg @ref LL_USART_IRDA_POWER_LOW
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetIrdaPowerMode(USART_TypeDef *USARTx, uint32_t PowerMode)
+{
+ MODIFY_REG(USARTx->CR3, USART_CR3_IRLP, PowerMode);
+}
+
+/**
+ * @brief Retrieve IrDA Power Mode configuration (Normal or Low Power)
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll CR3 IRLP LL_USART_GetIrdaPowerMode
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_IRDA_POWER_NORMAL
+ * @arg @ref LL_USART_PHASE_2EDGE
+ */
+__STATIC_INLINE uint32_t LL_USART_GetIrdaPowerMode(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_IRLP));
+}
+
+/**
+ * @brief Set Irda prescaler value, used for dividing the USART clock source
+ * to achieve the Irda Low Power frequency (8 bits value)
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_SetIrdaPrescaler
+ * @param USARTx USART Instance
+ * @param PrescalerValue Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetIrdaPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue)
+{
+ MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, PrescalerValue);
+}
+
+/**
+ * @brief Return Irda prescaler value, used for dividing the USART clock source
+ * to achieve the Irda Low Power frequency (8 bits value)
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_GetIrdaPrescaler
+ * @param USARTx USART Instance
+ * @retval Irda prescaler value (Value between Min_Data=0x00 and Max_Data=0xFF)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetIrdaPrescaler(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_Smartcard Configuration functions related to Smartcard feature
+ * @{
+ */
+
+/**
+ * @brief Enable Smartcard NACK transmission
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 NACK LL_USART_EnableSmartcardNACK
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableSmartcardNACK(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_NACK);
+}
+
+/**
+ * @brief Disable Smartcard NACK transmission
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 NACK LL_USART_DisableSmartcardNACK
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableSmartcardNACK(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_NACK);
+}
+
+/**
+ * @brief Indicate if Smartcard NACK transmission is enabled
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 NACK LL_USART_IsEnabledSmartcardNACK
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcardNACK(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_NACK) == (USART_CR3_NACK));
+}
+
+/**
+ * @brief Enable Smartcard mode
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 SCEN LL_USART_EnableSmartcard
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableSmartcard(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_SCEN);
+}
+
+/**
+ * @brief Disable Smartcard mode
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 SCEN LL_USART_DisableSmartcard
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableSmartcard(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_SCEN);
+}
+
+/**
+ * @brief Indicate if Smartcard mode is enabled
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll CR3 SCEN LL_USART_IsEnabledSmartcard
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcard(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_SCEN) == (USART_CR3_SCEN));
+}
+
+/**
+ * @brief Set Smartcard prescaler value, used for dividing the USART clock
+ * source to provide the SMARTCARD Clock (5 bits value)
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_SetSmartcardPrescaler
+ * @param USARTx USART Instance
+ * @param PrescalerValue Value between Min_Data=0 and Max_Data=31
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetSmartcardPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue)
+{
+ MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, PrescalerValue);
+}
+
+/**
+ * @brief Return Smartcard prescaler value, used for dividing the USART clock
+ * source to provide the SMARTCARD Clock (5 bits value)
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR PSC LL_USART_GetSmartcardPrescaler
+ * @param USARTx USART Instance
+ * @retval Smartcard prescaler value (Value between Min_Data=0 and Max_Data=31)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetSmartcardPrescaler(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC));
+}
+
+/**
+ * @brief Set Smartcard Guard time value, expressed in nb of baud clocks periods
+ * (GT[7:0] bits : Guard time value)
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR GT LL_USART_SetSmartcardGuardTime
+ * @param USARTx USART Instance
+ * @param GuardTime Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetSmartcardGuardTime(USART_TypeDef *USARTx, uint32_t GuardTime)
+{
+ MODIFY_REG(USARTx->GTPR, USART_GTPR_GT, GuardTime << USART_POSITION_GTPR_GT);
+}
+
+/**
+ * @brief Return Smartcard Guard time value, expressed in nb of baud clocks periods
+ * (GT[7:0] bits : Guard time value)
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @rmtoll GTPR GT LL_USART_GetSmartcardGuardTime
+ * @param USARTx USART Instance
+ * @retval Smartcard Guard time value (Value between Min_Data=0x00 and Max_Data=0xFF)
+ */
+__STATIC_INLINE uint32_t LL_USART_GetSmartcardGuardTime(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_GT) >> USART_POSITION_GTPR_GT);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_HalfDuplex Configuration functions related to Half Duplex feature
+ * @{
+ */
+
+/**
+ * @brief Enable Single Wire Half-Duplex mode
+ * @note Macro @ref IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @rmtoll CR3 HDSEL LL_USART_EnableHalfDuplex
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableHalfDuplex(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR3, USART_CR3_HDSEL);
+}
+
+/**
+ * @brief Disable Single Wire Half-Duplex mode
+ * @note Macro @ref IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @rmtoll CR3 HDSEL LL_USART_DisableHalfDuplex
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableHalfDuplex(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL);
+}
+
+/**
+ * @brief Indicate if Single Wire Half-Duplex mode is enabled
+ * @note Macro @ref IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @rmtoll CR3 HDSEL LL_USART_IsEnabledHalfDuplex
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledHalfDuplex(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Configuration_LIN Configuration functions related to LIN feature
+ * @{
+ */
+
+/**
+ * @brief Set LIN Break Detection Length
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDL LL_USART_SetLINBrkDetectionLen
+ * @param USARTx USART Instance
+ * @param LINBDLength This parameter can be one of the following values:
+ * @arg @ref LL_USART_LINBREAK_DETECT_10B
+ * @arg @ref LL_USART_LINBREAK_DETECT_11B
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_SetLINBrkDetectionLen(USART_TypeDef *USARTx, uint32_t LINBDLength)
+{
+ MODIFY_REG(USARTx->CR2, USART_CR2_LBDL, LINBDLength);
+}
+
+/**
+ * @brief Return LIN Break Detection Length
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDL LL_USART_GetLINBrkDetectionLen
+ * @param USARTx USART Instance
+ * @retval Returned value can be one of the following values:
+ * @arg @ref LL_USART_LINBREAK_DETECT_10B
+ * @arg @ref LL_USART_LINBREAK_DETECT_11B
+ */
+__STATIC_INLINE uint32_t LL_USART_GetLINBrkDetectionLen(const USART_TypeDef *USARTx)
+{
+ return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBDL));
+}
+
+/**
+ * @brief Enable LIN mode
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LINEN LL_USART_EnableLIN
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableLIN(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR2, USART_CR2_LINEN);
+}
+
+/**
+ * @brief Disable LIN mode
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LINEN LL_USART_DisableLIN
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableLIN(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR2, USART_CR2_LINEN);
+}
+
+/**
+ * @brief Indicate if LIN mode is enabled
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LINEN LL_USART_IsEnabledLIN
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledLIN(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR2, USART_CR2_LINEN) == (USART_CR2_LINEN));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_AdvancedConfiguration Advanced Configurations services
+ * @{
+ */
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Asynchronous Mode (UART)
+ * @note In UART mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - CLKEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * @note Other remaining configurations items related to Asynchronous Mode
+ * (as Baud Rate, Word length, Parity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigAsyncMode\n
+ * CR2 CLKEN LL_USART_ConfigAsyncMode\n
+ * CR3 SCEN LL_USART_ConfigAsyncMode\n
+ * CR3 IREN LL_USART_ConfigAsyncMode\n
+ * CR3 HDSEL LL_USART_ConfigAsyncMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigAsyncMode(USART_TypeDef *USARTx)
+{
+ /* In Asynchronous mode, the following bits must be kept cleared:
+ - LINEN, CLKEN bits in the USART_CR2 register,
+ - SCEN, IREN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL));
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Synchronous Mode
+ * @note In Synchronous mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also sets the USART in Synchronous mode.
+ * @note Macro @ref IS_USART_INSTANCE(USARTx) can be used to check whether or not
+ * Synchronous mode is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function
+ * @note Other remaining configurations items related to Synchronous Mode
+ * (as Baud Rate, Word length, Parity, Clock Polarity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigSyncMode\n
+ * CR2 CLKEN LL_USART_ConfigSyncMode\n
+ * CR3 SCEN LL_USART_ConfigSyncMode\n
+ * CR3 IREN LL_USART_ConfigSyncMode\n
+ * CR3 HDSEL LL_USART_ConfigSyncMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigSyncMode(USART_TypeDef *USARTx)
+{
+ /* In Synchronous mode, the following bits must be kept cleared:
+ - LINEN bit in the USART_CR2 register,
+ - SCEN, IREN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL));
+ /* set the UART/USART in Synchronous mode */
+ SET_BIT(USARTx->CR2, USART_CR2_CLKEN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in LIN Mode
+ * @note In LIN mode, the following bits must be kept cleared:
+ * - STOP and CLKEN bits in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also set the UART/USART in LIN mode.
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Set LINEN in CR2 using @ref LL_USART_EnableLIN() function
+ * @note Other remaining configurations items related to LIN Mode
+ * (as Baud Rate, Word length, LIN Break Detection Length, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 CLKEN LL_USART_ConfigLINMode\n
+ * CR2 STOP LL_USART_ConfigLINMode\n
+ * CR2 LINEN LL_USART_ConfigLINMode\n
+ * CR3 IREN LL_USART_ConfigLINMode\n
+ * CR3 SCEN LL_USART_ConfigLINMode\n
+ * CR3 HDSEL LL_USART_ConfigLINMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigLINMode(USART_TypeDef *USARTx)
+{
+ /* In LIN mode, the following bits must be kept cleared:
+ - STOP and CLKEN bits in the USART_CR2 register,
+ - IREN, SCEN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_CLKEN | USART_CR2_STOP));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL));
+ /* Set the UART/USART in LIN mode */
+ SET_BIT(USARTx->CR2, USART_CR2_LINEN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Half Duplex Mode
+ * @note In Half Duplex mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - CLKEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * This function also sets the UART/USART in Half Duplex mode.
+ * @note Macro @ref IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not
+ * Half-Duplex mode is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Set HDSEL in CR3 using @ref LL_USART_EnableHalfDuplex() function
+ * @note Other remaining configurations items related to Half Duplex Mode
+ * (as Baud Rate, Word length, Parity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigHalfDuplexMode\n
+ * CR2 CLKEN LL_USART_ConfigHalfDuplexMode\n
+ * CR3 HDSEL LL_USART_ConfigHalfDuplexMode\n
+ * CR3 SCEN LL_USART_ConfigHalfDuplexMode\n
+ * CR3 IREN LL_USART_ConfigHalfDuplexMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigHalfDuplexMode(USART_TypeDef *USARTx)
+{
+ /* In Half Duplex mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN));
+ /* set the UART/USART in Half Duplex mode */
+ SET_BIT(USARTx->CR3, USART_CR3_HDSEL);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Smartcard Mode
+ * @note In Smartcard mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also configures Stop bits to 1.5 bits and
+ * sets the USART in Smartcard mode (SCEN bit).
+ * Clock Output is also enabled (CLKEN).
+ * @note Macro @ref IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not
+ * Smartcard feature is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
+ * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function
+ * - Set SCEN in CR3 using @ref LL_USART_EnableSmartcard() function
+ * @note Other remaining configurations items related to Smartcard Mode
+ * (as Baud Rate, Word length, Parity, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigSmartcardMode\n
+ * CR2 STOP LL_USART_ConfigSmartcardMode\n
+ * CR2 CLKEN LL_USART_ConfigSmartcardMode\n
+ * CR3 HDSEL LL_USART_ConfigSmartcardMode\n
+ * CR3 SCEN LL_USART_ConfigSmartcardMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigSmartcardMode(USART_TypeDef *USARTx)
+{
+ /* In Smartcard mode, the following bits must be kept cleared:
+ - LINEN bit in the USART_CR2 register,
+ - IREN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
+ /* Configure Stop bits to 1.5 bits */
+ /* Synchronous mode is activated by default */
+ SET_BIT(USARTx->CR2, (USART_CR2_STOP_0 | USART_CR2_STOP_1 | USART_CR2_CLKEN));
+ /* set the UART/USART in Smartcard mode */
+ SET_BIT(USARTx->CR3, USART_CR3_SCEN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Irda Mode
+ * @note In IRDA mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - STOP and CLKEN bits in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * This function also sets the UART/USART in IRDA mode (IREN bit).
+ * @note Macro @ref IS_IRDA_INSTANCE(USARTx) can be used to check whether or not
+ * IrDA feature is supported by the USARTx instance.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function
+ * - Set IREN in CR3 using @ref LL_USART_EnableIrda() function
+ * @note Other remaining configurations items related to Irda Mode
+ * (as Baud Rate, Word length, Power mode, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigIrdaMode\n
+ * CR2 CLKEN LL_USART_ConfigIrdaMode\n
+ * CR2 STOP LL_USART_ConfigIrdaMode\n
+ * CR3 SCEN LL_USART_ConfigIrdaMode\n
+ * CR3 HDSEL LL_USART_ConfigIrdaMode\n
+ * CR3 IREN LL_USART_ConfigIrdaMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigIrdaMode(USART_TypeDef *USARTx)
+{
+ /* In IRDA mode, the following bits must be kept cleared:
+ - LINEN, STOP and CLKEN bits in the USART_CR2 register,
+ - SCEN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
+ /* set the UART/USART in IRDA mode */
+ SET_BIT(USARTx->CR3, USART_CR3_IREN);
+}
+
+/**
+ * @brief Perform basic configuration of USART for enabling use in Multi processor Mode
+ * (several USARTs connected in a network, one of the USARTs can be the master,
+ * its TX output connected to the RX inputs of the other slaves USARTs).
+ * @note In MultiProcessor mode, the following bits must be kept cleared:
+ * - LINEN bit in the USART_CR2 register,
+ * - CLKEN bit in the USART_CR2 register,
+ * - SCEN bit in the USART_CR3 register,
+ * - IREN bit in the USART_CR3 register,
+ * - HDSEL bit in the USART_CR3 register.
+ * @note Call of this function is equivalent to following function call sequence :
+ * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function
+ * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function
+ * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function
+ * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function
+ * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function
+ * @note Other remaining configurations items related to Multi processor Mode
+ * (as Baud Rate, Wake Up Method, Node address, ...) should be set using
+ * dedicated functions
+ * @rmtoll CR2 LINEN LL_USART_ConfigMultiProcessMode\n
+ * CR2 CLKEN LL_USART_ConfigMultiProcessMode\n
+ * CR3 SCEN LL_USART_ConfigMultiProcessMode\n
+ * CR3 HDSEL LL_USART_ConfigMultiProcessMode\n
+ * CR3 IREN LL_USART_ConfigMultiProcessMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ConfigMultiProcessMode(USART_TypeDef *USARTx)
+{
+ /* In Multi Processor mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - IREN, SCEN and HDSEL bits in the USART_CR3 register.*/
+ CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_FLAG_Management FLAG_Management
+ * @{
+ */
+
+/**
+ * @brief Check if the USART Parity Error Flag is set or not
+ * @rmtoll SR PE LL_USART_IsActiveFlag_PE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_PE) == (USART_SR_PE));
+}
+
+/**
+ * @brief Check if the USART Framing Error Flag is set or not
+ * @rmtoll SR FE LL_USART_IsActiveFlag_FE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_FE) == (USART_SR_FE));
+}
+
+/**
+ * @brief Check if the USART Noise error detected Flag is set or not
+ * @rmtoll SR NF LL_USART_IsActiveFlag_NE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_NE) == (USART_SR_NE));
+}
+
+/**
+ * @brief Check if the USART OverRun Error Flag is set or not
+ * @rmtoll SR ORE LL_USART_IsActiveFlag_ORE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_ORE) == (USART_SR_ORE));
+}
+
+/**
+ * @brief Check if the USART IDLE line detected Flag is set or not
+ * @rmtoll SR IDLE LL_USART_IsActiveFlag_IDLE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_IDLE) == (USART_SR_IDLE));
+}
+
+/**
+ * @brief Check if the USART Read Data Register Not Empty Flag is set or not
+ * @rmtoll SR RXNE LL_USART_IsActiveFlag_RXNE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_RXNE) == (USART_SR_RXNE));
+}
+
+/**
+ * @brief Check if the USART Transmission Complete Flag is set or not
+ * @rmtoll SR TC LL_USART_IsActiveFlag_TC
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_TC) == (USART_SR_TC));
+}
+
+/**
+ * @brief Check if the USART Transmit Data Register Empty Flag is set or not
+ * @rmtoll SR TXE LL_USART_IsActiveFlag_TXE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_TXE) == (USART_SR_TXE));
+}
+
+/**
+ * @brief Check if the USART LIN Break Detection Flag is set or not
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll SR LBD LL_USART_IsActiveFlag_LBD
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_LBD(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_LBD) == (USART_SR_LBD));
+}
+
+/**
+ * @brief Check if the USART CTS Flag is set or not
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll SR CTS LL_USART_IsActiveFlag_nCTS
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_nCTS(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->SR, USART_SR_CTS) == (USART_SR_CTS));
+}
+
+/**
+ * @brief Check if the USART Send Break Flag is set or not
+ * @rmtoll CR1 SBK LL_USART_IsActiveFlag_SBK
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_SBK(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_SBK) == (USART_CR1_SBK));
+}
+
+/**
+ * @brief Check if the USART Receive Wake Up from mute mode Flag is set or not
+ * @rmtoll CR1 RWU LL_USART_IsActiveFlag_RWU
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RWU(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_RWU) == (USART_CR1_RWU));
+}
+
+/**
+ * @brief Clear Parity Error Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * NE, FE, ORE, IDLE would also be cleared.
+ * @rmtoll SR PE LL_USART_ClearFlag_PE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Framing Error Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, NE, ORE, IDLE would also be cleared.
+ * @rmtoll SR FE LL_USART_ClearFlag_FE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Noise detected Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, FE, ORE, IDLE would also be cleared.
+ * @rmtoll SR NF LL_USART_ClearFlag_NE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear OverRun Error Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, NE, FE, IDLE would also be cleared.
+ * @rmtoll SR ORE LL_USART_ClearFlag_ORE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear IDLE line detected Flag
+ * @note Clearing this flag is done by a read access to the USARTx_SR
+ * register followed by a read access to the USARTx_DR register.
+ * @note Please also consider that when clearing this flag, other flags as
+ * PE, NE, FE, ORE would also be cleared.
+ * @rmtoll SR IDLE LL_USART_ClearFlag_IDLE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx)
+{
+ __IO uint32_t tmpreg;
+ tmpreg = USARTx->SR;
+ (void) tmpreg;
+ tmpreg = USARTx->DR;
+ (void) tmpreg;
+}
+
+/**
+ * @brief Clear Transmission Complete Flag
+ * @rmtoll SR TC LL_USART_ClearFlag_TC
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_TC));
+}
+
+/**
+ * @brief Clear RX Not Empty Flag
+ * @rmtoll SR RXNE LL_USART_ClearFlag_RXNE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_RXNE(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_RXNE));
+}
+
+/**
+ * @brief Clear LIN Break Detection Flag
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll SR LBD LL_USART_ClearFlag_LBD
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_LBD(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_LBD));
+}
+
+/**
+ * @brief Clear CTS Interrupt Flag
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll SR CTS LL_USART_ClearFlag_nCTS
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_ClearFlag_nCTS(USART_TypeDef *USARTx)
+{
+ WRITE_REG(USARTx->SR, ~(USART_SR_CTS));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_IT_Management IT_Management
+ * @{
+ */
+
+/**
+ * @brief Enable IDLE Interrupt
+ * @rmtoll CR1 IDLEIE LL_USART_EnableIT_IDLE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_IDLEIE);
+}
+
+/**
+ * @brief Enable RX Not Empty Interrupt
+ * @rmtoll CR1 RXNEIE LL_USART_EnableIT_RXNE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_RXNE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXNEIE);
+}
+
+/**
+ * @brief Enable Transmission Complete Interrupt
+ * @rmtoll CR1 TCIE LL_USART_EnableIT_TC
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TCIE);
+}
+
+/**
+ * @brief Enable TX Empty Interrupt
+ * @rmtoll CR1 TXEIE LL_USART_EnableIT_TXE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_TXE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXEIE);
+}
+
+/**
+ * @brief Enable Parity Error Interrupt
+ * @rmtoll CR1 PEIE LL_USART_EnableIT_PE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_PEIE);
+}
+
+/**
+ * @brief Enable LIN Break Detection Interrupt
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDIE LL_USART_EnableIT_LBD
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_LBD(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR2, USART_CR2_LBDIE);
+}
+
+/**
+ * @brief Enable Error Interrupt
+ * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing
+ * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_SR register).
+ * 0: Interrupt is inhibited
+ * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_SR register.
+ * @rmtoll CR3 EIE LL_USART_EnableIT_ERROR
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_ERROR(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_EIE);
+}
+
+/**
+ * @brief Enable CTS Interrupt
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSIE LL_USART_EnableIT_CTS
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableIT_CTS(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_CTSIE);
+}
+
+/**
+ * @brief Disable IDLE Interrupt
+ * @rmtoll CR1 IDLEIE LL_USART_DisableIT_IDLE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_IDLE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_IDLEIE);
+}
+
+/**
+ * @brief Disable RX Not Empty Interrupt
+ * @rmtoll CR1 RXNEIE LL_USART_DisableIT_RXNE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_RXNE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXNEIE);
+}
+
+/**
+ * @brief Disable Transmission Complete Interrupt
+ * @rmtoll CR1 TCIE LL_USART_DisableIT_TC
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_TC(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TCIE);
+}
+
+/**
+ * @brief Disable TX Empty Interrupt
+ * @rmtoll CR1 TXEIE LL_USART_DisableIT_TXE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_TXE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXEIE);
+}
+
+/**
+ * @brief Disable Parity Error Interrupt
+ * @rmtoll CR1 PEIE LL_USART_DisableIT_PE
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_PE(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_PEIE);
+}
+
+/**
+ * @brief Disable LIN Break Detection Interrupt
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDIE LL_USART_DisableIT_LBD
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_LBD(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR2, USART_CR2_LBDIE);
+}
+
+/**
+ * @brief Disable Error Interrupt
+ * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing
+ * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_SR register).
+ * 0: Interrupt is inhibited
+ * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_SR register.
+ * @rmtoll CR3 EIE LL_USART_DisableIT_ERROR
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_ERROR(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_EIE);
+}
+
+/**
+ * @brief Disable CTS Interrupt
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSIE LL_USART_DisableIT_CTS
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableIT_CTS(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_CTSIE);
+}
+
+/**
+ * @brief Check if the USART IDLE Interrupt source is enabled or disabled.
+ * @rmtoll CR1 IDLEIE LL_USART_IsEnabledIT_IDLE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_IDLE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE));
+}
+
+/**
+ * @brief Check if the USART RX Not Empty Interrupt is enabled or disabled.
+ * @rmtoll CR1 RXNEIE LL_USART_IsEnabledIT_RXNE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXNE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_RXNEIE) == (USART_CR1_RXNEIE));
+}
+
+/**
+ * @brief Check if the USART Transmission Complete Interrupt is enabled or disabled.
+ * @rmtoll CR1 TCIE LL_USART_IsEnabledIT_TC
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TC(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE));
+}
+
+/**
+ * @brief Check if the USART TX Empty Interrupt is enabled or disabled.
+ * @rmtoll CR1 TXEIE LL_USART_IsEnabledIT_TXE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_TXEIE) == (USART_CR1_TXEIE));
+}
+
+/**
+ * @brief Check if the USART Parity Error Interrupt is enabled or disabled.
+ * @rmtoll CR1 PEIE LL_USART_IsEnabledIT_PE
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_PE(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE));
+}
+
+/**
+ * @brief Check if the USART LIN Break Detection Interrupt is enabled or disabled.
+ * @note Macro @ref IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not
+ * LIN feature is supported by the USARTx instance.
+ * @rmtoll CR2 LBDIE LL_USART_IsEnabledIT_LBD
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_LBD(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR2, USART_CR2_LBDIE) == (USART_CR2_LBDIE));
+}
+
+/**
+ * @brief Check if the USART Error Interrupt is enabled or disabled.
+ * @rmtoll CR3 EIE LL_USART_IsEnabledIT_ERROR
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_ERROR(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE));
+}
+
+/**
+ * @brief Check if the USART CTS Interrupt is enabled or disabled.
+ * @note Macro @ref IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not
+ * Hardware Flow control feature is supported by the USARTx instance.
+ * @rmtoll CR3 CTSIE LL_USART_IsEnabledIT_CTS
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CTS(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_DMA_Management DMA_Management
+ * @{
+ */
+
+/**
+ * @brief Enable DMA Mode for reception
+ * @rmtoll CR3 DMAR LL_USART_EnableDMAReq_RX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAR);
+}
+
+/**
+ * @brief Disable DMA Mode for reception
+ * @rmtoll CR3 DMAR LL_USART_DisableDMAReq_RX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDMAReq_RX(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAR);
+}
+
+/**
+ * @brief Check if DMA Mode is enabled for reception
+ * @rmtoll CR3 DMAR LL_USART_IsEnabledDMAReq_RX
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_RX(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR));
+}
+
+/**
+ * @brief Enable DMA Mode for transmission
+ * @rmtoll CR3 DMAT LL_USART_EnableDMAReq_TX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx)
+{
+ ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAT);
+}
+
+/**
+ * @brief Disable DMA Mode for transmission
+ * @rmtoll CR3 DMAT LL_USART_DisableDMAReq_TX
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_DisableDMAReq_TX(USART_TypeDef *USARTx)
+{
+ ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAT);
+}
+
+/**
+ * @brief Check if DMA Mode is enabled for transmission
+ * @rmtoll CR3 DMAT LL_USART_IsEnabledDMAReq_TX
+ * @param USARTx USART Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_TX(const USART_TypeDef *USARTx)
+{
+ return (READ_BIT(USARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT));
+}
+
+/**
+ * @brief Get the data register address used for DMA transfer
+ * @rmtoll DR DR LL_USART_DMA_GetRegAddr
+ * @note Address of Data Register is valid for both Transmit and Receive transfers.
+ * @param USARTx USART Instance
+ * @retval Address of data register
+ */
+__STATIC_INLINE uint32_t LL_USART_DMA_GetRegAddr(const USART_TypeDef *USARTx)
+{
+ /* return address of DR register */
+ return ((uint32_t) &(USARTx->DR));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Data_Management Data_Management
+ * @{
+ */
+
+/**
+ * @brief Read Receiver Data register (Receive Data value, 8 bits)
+ * @rmtoll DR DR LL_USART_ReceiveData8
+ * @param USARTx USART Instance
+ * @retval Value between Min_Data=0x00 and Max_Data=0xFF
+ */
+__STATIC_INLINE uint8_t LL_USART_ReceiveData8(const USART_TypeDef *USARTx)
+{
+ return (uint8_t)(READ_BIT(USARTx->DR, USART_DR_DR));
+}
+
+/**
+ * @brief Read Receiver Data register (Receive Data value, 9 bits)
+ * @rmtoll DR DR LL_USART_ReceiveData9
+ * @param USARTx USART Instance
+ * @retval Value between Min_Data=0x00 and Max_Data=0x1FF
+ */
+__STATIC_INLINE uint16_t LL_USART_ReceiveData9(const USART_TypeDef *USARTx)
+{
+ return (uint16_t)(READ_BIT(USARTx->DR, USART_DR_DR));
+}
+
+/**
+ * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits)
+ * @rmtoll DR DR LL_USART_TransmitData8
+ * @param USARTx USART Instance
+ * @param Value between Min_Data=0x00 and Max_Data=0xFF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value)
+{
+ USARTx->DR = Value;
+}
+
+/**
+ * @brief Write in Transmitter Data Register (Transmit Data value, 9 bits)
+ * @rmtoll DR DR LL_USART_TransmitData9
+ * @param USARTx USART Instance
+ * @param Value between Min_Data=0x00 and Max_Data=0x1FF
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_TransmitData9(USART_TypeDef *USARTx, uint16_t Value)
+{
+ USARTx->DR = Value & 0x1FFU;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_LL_EF_Execution Execution
+ * @{
+ */
+
+/**
+ * @brief Request Break sending
+ * @rmtoll CR1 SBK LL_USART_RequestBreakSending
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_RequestBreakSending(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR1, USART_CR1_SBK);
+}
+
+/**
+ * @brief Put USART in Mute mode
+ * @rmtoll CR1 RWU LL_USART_RequestEnterMuteMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_RequestEnterMuteMode(USART_TypeDef *USARTx)
+{
+ SET_BIT(USARTx->CR1, USART_CR1_RWU);
+}
+
+/**
+ * @brief Put USART in Active mode
+ * @rmtoll CR1 RWU LL_USART_RequestExitMuteMode
+ * @param USARTx USART Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_USART_RequestExitMuteMode(USART_TypeDef *USARTx)
+{
+ CLEAR_BIT(USARTx->CR1, USART_CR1_RWU);
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup USART_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx);
+ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, const LL_USART_InitTypeDef *USART_InitStruct);
+void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct);
+ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct);
+void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct);
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* USART1 || USART2 || USART3 || UART4 || UART5 */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F1xx_LL_USART_H */
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
new file mode 100644
index 0000000..0651e86
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
@@ -0,0 +1,7644 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_i2c.c
+ * @author MCD Application Team
+ * @brief I2C HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Inter Integrated Circuit (I2C) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral State, Mode and Error functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The I2C HAL driver can be used as follows:
+
+ (#) Declare a I2C_HandleTypeDef handle structure, for example:
+ I2C_HandleTypeDef hi2c;
+
+ (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API:
+ (##) Enable the I2Cx interface clock
+ (##) I2C pins configuration
+ (+++) Enable the clock for the I2C GPIOs
+ (+++) Configure I2C pins as alternate function open-drain
+ (##) NVIC configuration if you need to use interrupt process
+ (+++) Configure the I2Cx interrupt priority
+ (+++) Enable the NVIC I2C IRQ Channel
+ (##) DMA Configuration if you need to use DMA process
+ (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive channel
+ (+++) Enable the DMAx interface clock using
+ (+++) Configure the DMA handle parameters
+ (+++) Configure the DMA Tx or Rx channel
+ (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
+ the DMA Tx or Rx channel
+
+ (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,
+ Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure.
+
+ (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware
+ (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit() API.
+
+ (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady()
+
+ (#) For I2C IO and IO MEM operations, three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit()
+ (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive()
+ (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit()
+ (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive()
+
+ *** Polling mode IO MEM operation ***
+ =====================================
+ [..]
+ (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write()
+ (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read()
+
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Transmit in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Transmit_IT()
+ (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
+ (+) Receive in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Receive_IT()
+ (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
+ (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Transmit_IT()
+ (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
+ (+) Receive in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Receive_IT()
+ (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+ (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
+ (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
+
+ *** Interrupt mode or DMA mode IO sequential operation ***
+ ==========================================================
+ [..]
+ (@) These interfaces allow to manage a sequential transfer with a repeated start condition
+ when a direction change during transfer
+ [..]
+ (+) A specific option field manage the different steps of a sequential transfer
+ (+) Option field values are defined through I2C_XferOptions_definition and are listed below:
+ (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in no sequential mode
+ (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
+ and data to transfer without a final stop condition
+ (++) I2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address
+ and data to transfer without a final stop condition, an then permit a call the same master sequential interface
+ several times (like HAL_I2C_Master_Seq_Transmit_IT() then HAL_I2C_Master_Seq_Transmit_IT()
+ or HAL_I2C_Master_Seq_Transmit_DMA() then HAL_I2C_Master_Seq_Transmit_DMA())
+ (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
+ and with new data to transfer if the direction change or manage only the new data to transfer
+ if no direction change and without a final stop condition in both cases
+ (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
+ and with new data to transfer if the direction change or manage only the new data to transfer
+ if no direction change and with a final stop condition in both cases
+ (++) I2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition after several call of the same master sequential
+ interface several times (link with option I2C_FIRST_AND_NEXT_FRAME).
+ Usage can, transfer several bytes one by one using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
+ or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
+ or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
+ or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME).
+ Then usage of this option I2C_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the opposite interface Receive or Transmit
+ without stopping the communication and so generate a restart condition.
+ (++) I2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after each call of the same master sequential
+ interface.
+ Usage can, transfer several bytes one by one with a restart with slave address between each bytes using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
+ or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
+ or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
+ or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME).
+ Then usage of this option I2C_OTHER_AND_LAST_FRAME at the last frame to help automatic generation of STOP condition.
+
+ (+) Different sequential I2C interfaces are listed below:
+ (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Seq_Transmit_IT()
+ or using HAL_I2C_Master_Seq_Transmit_DMA()
+ (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
+ (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Seq_Receive_IT()
+ or using HAL_I2C_Master_Seq_Receive_DMA()
+ (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
+ (++) Abort a master IT or DMA I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
+ (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
+ (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT()
+ (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can
+ add his own code to check the Address Match Code and the transmission direction request by master (Write/Read).
+ (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_ListenCpltCallback()
+ (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Seq_Transmit_IT()
+ or using HAL_I2C_Slave_Seq_Transmit_DMA()
+ (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
+ (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Seq_Receive_IT()
+ or using HAL_I2C_Slave_Seq_Receive_DMA()
+ (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
+ (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+
+ *** Interrupt mode IO MEM operation ***
+ =======================================
+ [..]
+ (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
+ HAL_I2C_Mem_Write_IT()
+ (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
+ (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
+ HAL_I2C_Mem_Read_IT()
+ (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
+ HAL_I2C_Master_Transmit_DMA()
+ (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
+ (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
+ HAL_I2C_Master_Receive_DMA()
+ (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
+ (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
+ HAL_I2C_Slave_Transmit_DMA()
+ (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
+ (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
+ HAL_I2C_Slave_Receive_DMA()
+ (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+ (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
+ (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
+
+ *** DMA mode IO MEM operation ***
+ =================================
+ [..]
+ (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
+ HAL_I2C_Mem_Write_DMA()
+ (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
+ (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
+ HAL_I2C_Mem_Read_DMA()
+ (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+
+
+ *** I2C HAL driver macros list ***
+ ==================================
+ [..]
+ Below the list of most used macros in I2C HAL driver.
+
+ (+) __HAL_I2C_ENABLE: Enable the I2C peripheral
+ (+) __HAL_I2C_DISABLE: Disable the I2C peripheral
+ (+) __HAL_I2C_GET_FLAG: Checks whether the specified I2C flag is set or not
+ (+) __HAL_I2C_CLEAR_FLAG: Clear the specified I2C pending flag
+ (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt
+ (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt
+
+ *** Callback registration ***
+ =============================================
+ [..]
+ The compilation flag USE_HAL_I2C_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+ Use Functions HAL_I2C_RegisterCallback() or HAL_I2C_RegisterAddrCallback()
+ to register an interrupt callback.
+ [..]
+ Function HAL_I2C_RegisterCallback() allows to register following callbacks:
+ (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
+ (+) MasterRxCpltCallback : callback for Master reception end of transfer.
+ (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
+ (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
+ (+) ListenCpltCallback : callback for end of listen mode.
+ (+) MemTxCpltCallback : callback for Memory transmission end of transfer.
+ (+) MemRxCpltCallback : callback for Memory reception end of transfer.
+ (+) ErrorCallback : callback for error detection.
+ (+) AbortCpltCallback : callback for abort completion process.
+ (+) 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.
+ [..]
+ For specific callback AddrCallback use dedicated register callbacks : HAL_I2C_RegisterAddrCallback().
+ [..]
+ Use function HAL_I2C_UnRegisterCallback to reset a callback to the default
+ weak function.
+ HAL_I2C_UnRegisterCallback takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
+ (+) MasterRxCpltCallback : callback for Master reception end of transfer.
+ (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
+ (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
+ (+) ListenCpltCallback : callback for end of listen mode.
+ (+) MemTxCpltCallback : callback for Memory transmission end of transfer.
+ (+) MemRxCpltCallback : callback for Memory reception end of transfer.
+ (+) ErrorCallback : callback for error detection.
+ (+) AbortCpltCallback : callback for abort completion process.
+ (+) MspInitCallback : callback for Msp Init.
+ (+) MspDeInitCallback : callback for Msp DeInit.
+ [..]
+ For callback AddrCallback use dedicated register callbacks : HAL_I2C_UnRegisterAddrCallback().
+ [..]
+ By default, after the HAL_I2C_Init() and when the state is HAL_I2C_STATE_RESET
+ all callbacks are set to the corresponding weak functions:
+ examples HAL_I2C_MasterTxCpltCallback(), HAL_I2C_MasterRxCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are
+ reset to the legacy weak functions in the HAL_I2C_Init()/ HAL_I2C_DeInit() only when
+ these callbacks are null (not registered beforehand).
+ If MspInit or MspDeInit are not null, the HAL_I2C_Init()/ HAL_I2C_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
+ [..]
+ Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only.
+ Exception done MspInit/MspDeInit functions that can be registered/unregistered
+ in HAL_I2C_STATE_READY or HAL_I2C_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 HAL_I2C_RegisterCallback() before calling HAL_I2C_DeInit()
+ or HAL_I2C_Init() function.
+ [..]
+ When the compilation flag USE_HAL_I2C_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.
+
+
+ *** I2C Workarounds linked to Silicon Limitation ***
+ ====================================================
+ [..]
+ Below the list of all silicon limitations implemented for HAL on STM32F1xx product.
+ (@) See ErrataSheet to know full silicon limitation list of your product.
+
+ (+) Workarounds Implemented inside I2C HAL Driver
+ (++) Wrong data read into data register (Polling and Interrupt mode)
+ (++) Start cannot be generated after a misplaced Stop
+ (++) Some software events must be managed before the current byte is being transferred:
+ Workaround: Use DMA in general, except when the Master is receiving a single byte.
+ For Interrupt mode, I2C should have the highest priority in the application.
+ (++) Mismatch on the "Setup time for a repeated Start condition" timing parameter:
+ Workaround: Reduce the frequency down to 88 kHz or use the I2C Fast-mode if
+ supported by the slave.
+ (++) Data valid time (tVD;DAT) violated without the OVR flag being set:
+ Workaround: If the slave device allows it, use the clock stretching mechanism
+ by programming NoStretchMode = I2C_NOSTRETCH_DISABLE in HAL_I2C_Init.
+
+ [..]
+ (@) You can refer to the I2C HAL driver header file for more useful macros
+
+ @endverbatim
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup I2C I2C
+ * @brief I2C HAL module driver
+ * @{
+ */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup I2C_Private_Define I2C Private Define
+ * @{
+ */
+#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */
+#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */
+#define I2C_TIMEOUT_STOP_FLAG 5U /*!< Timeout 5 ms */
+#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */
+
+/* Private define for @ref PreviousState usage */
+#define I2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_I2C_STATE_BUSY_TX | (uint32_t)HAL_I2C_STATE_BUSY_RX) & (uint32_t)(~((uint32_t)HAL_I2C_STATE_READY)))) /*!< Mask State define, keep only RX and TX bits */
+#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */
+#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */
+#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */
+#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */
+#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @addtogroup I2C_Private_Macros
+ * @{
+ */
+/* Macro to get remaining data to transfer on DMA side */
+#define I2C_GET_DMA_REMAIN_DATA(__HANDLE__) __HAL_DMA_GET_COUNTER(__HANDLE__)
+/**
+ * @}
+ */
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+
+/** @defgroup I2C_Private_Functions I2C Private Functions
+ * @{
+ */
+/* Private functions to handle DMA transfer */
+static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma);
+static void I2C_DMAError(DMA_HandleTypeDef *hdma);
+static void I2C_DMAAbort(DMA_HandleTypeDef *hdma);
+
+static void I2C_ITError(I2C_HandleTypeDef *hi2c);
+
+static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
+
+/* Private functions to handle flags during polling transfer */
+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnSTOPRequestThroughIT(I2C_HandleTypeDef *hi2c);
+static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c);
+
+/* Private functions for I2C transfer IRQ handler */
+static void I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c);
+static void I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c);
+static void I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c);
+static void I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c);
+static void I2C_Master_SB(I2C_HandleTypeDef *hi2c);
+static void I2C_Master_ADD10(I2C_HandleTypeDef *hi2c);
+static void I2C_Master_ADDR(I2C_HandleTypeDef *hi2c);
+
+static void I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c);
+static void I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c);
+static void I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c);
+static void I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c);
+static void I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c, uint32_t IT2Flags);
+static void I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c);
+static void I2C_Slave_AF(I2C_HandleTypeDef *hi2c);
+
+static void I2C_MemoryTransmit_TXE_BTF(I2C_HandleTypeDef *hi2c);
+
+/* Private function to Convert Specific options */
+static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c);
+
+/* Private function to flush DR register */
+static void I2C_Flush_DR(I2C_HandleTypeDef *hi2c);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup I2C_Exported_Functions I2C Exported Functions
+ * @{
+ */
+
+/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to initialize and
+ deinitialize the I2Cx peripheral:
+
+ (+) User must Implement HAL_I2C_MspInit() function in which he configures
+ all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC).
+
+ (+) Call the function HAL_I2C_Init() to configure the selected device with
+ the selected configuration:
+ (++) Communication Speed
+ (++) Duty cycle
+ (++) Addressing mode
+ (++) Own Address 1
+ (++) Dual Addressing mode
+ (++) Own Address 2
+ (++) General call mode
+ (++) Nostretch mode
+
+ (+) Call the function HAL_I2C_DeInit() to restore the default configuration
+ of the selected I2Cx peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the I2C according to the specified parameters
+ * in the I2C_InitTypeDef and initialize the associated handle.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
+{
+ uint32_t freqrange;
+ uint32_t pclk1;
+
+ /* Check the I2C handle allocation */
+ if (hi2c == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
+ assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed));
+ assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle));
+ assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1));
+ assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode));
+ assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode));
+ assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2));
+ assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode));
+ assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode));
+
+ if (hi2c->State == HAL_I2C_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hi2c->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ /* Init the I2C Callback settings */
+ hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
+ hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
+ hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
+ hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
+ hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
+ hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */
+ hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */
+ hi2c->ErrorCallback = HAL_I2C_ErrorCallback; /* Legacy weak ErrorCallback */
+ hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback */
+
+ if (hi2c->MspInitCallback == NULL)
+ {
+ hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */
+ }
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC */
+ hi2c->MspInitCallback(hi2c);
+#else
+ /* Init the low level hardware : GPIO, CLOCK, NVIC */
+ HAL_I2C_MspInit(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+
+ hi2c->State = HAL_I2C_STATE_BUSY;
+
+ /* Disable the selected I2C peripheral */
+ __HAL_I2C_DISABLE(hi2c);
+
+ /*Reset I2C*/
+ hi2c->Instance->CR1 |= I2C_CR1_SWRST;
+ hi2c->Instance->CR1 &= ~I2C_CR1_SWRST;
+
+ /* Get PCLK1 frequency */
+ pclk1 = HAL_RCC_GetPCLK1Freq();
+
+ /* Check the minimum allowed PCLK1 frequency */
+ if (I2C_MIN_PCLK_FREQ(pclk1, hi2c->Init.ClockSpeed) == 1U)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Calculate frequency range */
+ freqrange = I2C_FREQRANGE(pclk1);
+
+ /*---------------------------- I2Cx CR2 Configuration ----------------------*/
+ /* Configure I2Cx: Frequency range */
+ MODIFY_REG(hi2c->Instance->CR2, I2C_CR2_FREQ, freqrange);
+
+ /*---------------------------- I2Cx TRISE Configuration --------------------*/
+ /* Configure I2Cx: Rise Time */
+ MODIFY_REG(hi2c->Instance->TRISE, I2C_TRISE_TRISE, I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed));
+
+ /*---------------------------- I2Cx CCR Configuration ----------------------*/
+ /* Configure I2Cx: Speed */
+ MODIFY_REG(hi2c->Instance->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle));
+
+ /*---------------------------- I2Cx CR1 Configuration ----------------------*/
+ /* Configure I2Cx: Generalcall and NoStretch mode */
+ MODIFY_REG(hi2c->Instance->CR1, (I2C_CR1_ENGC | I2C_CR1_NOSTRETCH), (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode));
+
+ /*---------------------------- I2Cx OAR1 Configuration ---------------------*/
+ /* Configure I2Cx: Own Address1 and addressing mode */
+ MODIFY_REG(hi2c->Instance->OAR1, (I2C_OAR1_ADDMODE | I2C_OAR1_ADD8_9 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD0), (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1));
+
+ /*---------------------------- I2Cx OAR2 Configuration ---------------------*/
+ /* Configure I2Cx: Dual mode and Own Address2 */
+ MODIFY_REG(hi2c->Instance->OAR2, (I2C_OAR2_ENDUAL | I2C_OAR2_ADD2), (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2));
+
+ /* Enable the selected I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitialize the I2C peripheral.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
+{
+ /* Check the I2C handle allocation */
+ if (hi2c == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
+
+ hi2c->State = HAL_I2C_STATE_BUSY;
+
+ /* Disable the I2C Peripheral Clock */
+ __HAL_I2C_DISABLE(hi2c);
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ if (hi2c->MspDeInitCallback == NULL)
+ {
+ hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */
+ }
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
+ hi2c->MspDeInitCallback(hi2c);
+#else
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
+ HAL_I2C_MspDeInit(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ hi2c->State = HAL_I2C_STATE_RESET;
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the I2C MSP.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitialize the I2C MSP.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MspDeInit could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User I2C Callback
+ * To be used instead of the weak predefined callback
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
+ * @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
+ * @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
+ * @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
+ * @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
+ * @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
+ * @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
+ * @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID
+ * @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID
+ * @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID, pI2C_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(hi2c);
+
+ if (HAL_I2C_STATE_READY == hi2c->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2C_MASTER_TX_COMPLETE_CB_ID :
+ hi2c->MasterTxCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_MASTER_RX_COMPLETE_CB_ID :
+ hi2c->MasterRxCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID :
+ hi2c->SlaveTxCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID :
+ hi2c->SlaveRxCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_LISTEN_COMPLETE_CB_ID :
+ hi2c->ListenCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_MEM_TX_COMPLETE_CB_ID :
+ hi2c->MemTxCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_MEM_RX_COMPLETE_CB_ID :
+ hi2c->MemRxCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_ERROR_CB_ID :
+ hi2c->ErrorCallback = pCallback;
+ break;
+
+ case HAL_I2C_ABORT_CB_ID :
+ hi2c->AbortCpltCallback = pCallback;
+ break;
+
+ case HAL_I2C_MSPINIT_CB_ID :
+ hi2c->MspInitCallback = pCallback;
+ break;
+
+ case HAL_I2C_MSPDEINIT_CB_ID :
+ hi2c->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_I2C_STATE_RESET == hi2c->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2C_MSPINIT_CB_ID :
+ hi2c->MspInitCallback = pCallback;
+ break;
+
+ case HAL_I2C_MSPDEINIT_CB_ID :
+ hi2c->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2c);
+ return status;
+}
+
+/**
+ * @brief Unregister an I2C Callback
+ * I2C callback is redirected to the weak predefined callback
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
+ * @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
+ * @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
+ * @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
+ * @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
+ * @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
+ * @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
+ * @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID
+ * @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID
+ * @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID
+ * @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hi2c);
+
+ if (HAL_I2C_STATE_READY == hi2c->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2C_MASTER_TX_COMPLETE_CB_ID :
+ hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
+ break;
+
+ case HAL_I2C_MASTER_RX_COMPLETE_CB_ID :
+ hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
+ break;
+
+ case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID :
+ hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
+ break;
+
+ case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID :
+ hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
+ break;
+
+ case HAL_I2C_LISTEN_COMPLETE_CB_ID :
+ hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
+ break;
+
+ case HAL_I2C_MEM_TX_COMPLETE_CB_ID :
+ hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */
+ break;
+
+ case HAL_I2C_MEM_RX_COMPLETE_CB_ID :
+ hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */
+ break;
+
+ case HAL_I2C_ERROR_CB_ID :
+ hi2c->ErrorCallback = HAL_I2C_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_I2C_ABORT_CB_ID :
+ hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ break;
+
+ case HAL_I2C_MSPINIT_CB_ID :
+ hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_I2C_MSPDEINIT_CB_ID :
+ hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_I2C_STATE_RESET == hi2c->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2C_MSPINIT_CB_ID :
+ hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_I2C_MSPDEINIT_CB_ID :
+ hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2c);
+ return status;
+}
+
+/**
+ * @brief Register the Slave Address Match I2C Callback
+ * To be used instead of the weak HAL_I2C_AddrCallback() predefined callback
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pCallback pointer to the Address Match Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(hi2c);
+
+ if (HAL_I2C_STATE_READY == hi2c->State)
+ {
+ hi2c->AddrCallback = pCallback;
+ }
+ else
+ {
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2c);
+ return status;
+}
+
+/**
+ * @brief UnRegister the Slave Address Match I2C Callback
+ * Info Ready I2C Callback is redirected to the weak HAL_I2C_AddrCallback() predefined callback
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hi2c);
+
+ if (HAL_I2C_STATE_READY == hi2c->State)
+ {
+ hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback */
+ }
+ else
+ {
+ /* Update the error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2c);
+ return status;
+}
+
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+
+/**
+ * @brief I2C data register flush process.
+ * @param hi2c I2C handle.
+ * @retval None
+ */
+static void I2C_Flush_DR(I2C_HandleTypeDef *hi2c)
+{
+ /* Write a dummy data in DR to clear TXE flag */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) != RESET)
+ {
+ hi2c->Instance->DR = 0x00U;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Exported_Functions_Group2 Input and Output operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the I2C data
+ transfers.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode : The communication is performed in the polling mode.
+ The status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) No-Blocking mode : The communication is performed using Interrupts
+ or DMA. These functions return the status of the transfer startup.
+ The end of the data processing will be indicated through the
+ dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+
+ (#) Blocking mode functions are :
+ (++) HAL_I2C_Master_Transmit()
+ (++) HAL_I2C_Master_Receive()
+ (++) HAL_I2C_Slave_Transmit()
+ (++) HAL_I2C_Slave_Receive()
+ (++) HAL_I2C_Mem_Write()
+ (++) HAL_I2C_Mem_Read()
+ (++) HAL_I2C_IsDeviceReady()
+
+ (#) No-Blocking mode functions with Interrupt are :
+ (++) HAL_I2C_Master_Transmit_IT()
+ (++) HAL_I2C_Master_Receive_IT()
+ (++) HAL_I2C_Slave_Transmit_IT()
+ (++) HAL_I2C_Slave_Receive_IT()
+ (++) HAL_I2C_Mem_Write_IT()
+ (++) HAL_I2C_Mem_Read_IT()
+ (++) HAL_I2C_Master_Seq_Transmit_IT()
+ (++) HAL_I2C_Master_Seq_Receive_IT()
+ (++) HAL_I2C_Slave_Seq_Transmit_IT()
+ (++) HAL_I2C_Slave_Seq_Receive_IT()
+ (++) HAL_I2C_EnableListen_IT()
+ (++) HAL_I2C_DisableListen_IT()
+ (++) HAL_I2C_Master_Abort_IT()
+
+ (#) No-Blocking mode functions with DMA are :
+ (++) HAL_I2C_Master_Transmit_DMA()
+ (++) HAL_I2C_Master_Receive_DMA()
+ (++) HAL_I2C_Slave_Transmit_DMA()
+ (++) HAL_I2C_Slave_Receive_DMA()
+ (++) HAL_I2C_Mem_Write_DMA()
+ (++) HAL_I2C_Mem_Read_DMA()
+ (++) HAL_I2C_Master_Seq_Transmit_DMA()
+ (++) HAL_I2C_Master_Seq_Receive_DMA()
+ (++) HAL_I2C_Slave_Seq_Transmit_DMA()
+ (++) HAL_I2C_Slave_Seq_Receive_DMA()
+
+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
+ (++) HAL_I2C_MasterTxCpltCallback()
+ (++) HAL_I2C_MasterRxCpltCallback()
+ (++) HAL_I2C_SlaveTxCpltCallback()
+ (++) HAL_I2C_SlaveRxCpltCallback()
+ (++) HAL_I2C_MemTxCpltCallback()
+ (++) HAL_I2C_MemRxCpltCallback()
+ (++) HAL_I2C_AddrCallback()
+ (++) HAL_I2C_ListenCpltCallback()
+ (++) HAL_I2C_ErrorCallback()
+ (++) HAL_I2C_AbortCpltCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits in master mode an amount of data in blocking mode.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Send Slave Address */
+ if (I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ while (hi2c->XferSize > 0U)
+ {
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ hi2c->XferSize--;
+
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U))
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ hi2c->XferSize--;
+ }
+
+ /* Wait until BTF flag is set */
+ if (I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+ }
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives in master mode an amount of data in blocking mode.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ __IO uint32_t count = 0U;
+
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Send Slave Address */
+ if (I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hi2c->XferSize == 0U)
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ else if (hi2c->XferSize == 1U)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Re-enable IRQs */
+ __enable_irq();
+ }
+ else if (hi2c->XferSize == 2U)
+ {
+ /* Enable Pos */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Re-enable IRQs */
+ __enable_irq();
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+
+ while (hi2c->XferSize > 0U)
+ {
+ if (hi2c->XferSize <= 3U)
+ {
+ /* One byte */
+ if (hi2c->XferSize == 1U)
+ {
+ /* Wait until RXNE flag is set */
+ if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ /* Two bytes */
+ else if (hi2c->XferSize == 2U)
+ {
+ /* Wait until BTF flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ /* Re-enable IRQs */
+ __enable_irq();
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ /* 3 Last bytes */
+ else
+ {
+ /* Wait until BTF flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ /* Wait until BTF flag is set */
+ count = I2C_TIMEOUT_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Re-enable IRQs */
+ __enable_irq();
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ /* Re-enable IRQs */
+ __enable_irq();
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ }
+ else
+ {
+ /* Wait until RXNE flag is set */
+ if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET)
+ {
+
+ if (hi2c->XferSize == 3U)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ }
+ }
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Transmits in slave mode an amount of data in blocking mode.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* If 10bit addressing mode is selected */
+ if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
+ {
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+
+ while (hi2c->XferSize > 0U)
+ {
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ /* Disable Address Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ return HAL_ERROR;
+ }
+
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ hi2c->XferSize--;
+
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U))
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ hi2c->XferSize--;
+ }
+ }
+
+ /* Wait until AF flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear AF flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ /* Disable Address Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive in slave mode an amount of data in blocking mode
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == (uint16_t)0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ while (hi2c->XferSize > 0U)
+ {
+ /* Wait until RXNE flag is set */
+ if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ /* Disable Address Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ return HAL_ERROR;
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U))
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ }
+
+ /* Wait until STOP flag is set */
+ if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ /* Disable Address Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ return HAL_ERROR;
+ }
+
+ /* Clear STOP flag */
+ __HAL_I2C_CLEAR_STOPFLAG(hi2c);
+
+ /* Disable Address Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
+{
+ __IO uint32_t count = 0U;
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
+{
+ __IO uint32_t count = 0U;
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
+{
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
+{
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Transmit in master mode an amount of data in non-blocking mode with DMA
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
+{
+ __IO uint32_t count = 0U;
+ HAL_StatusTypeDef dmaxferstatus;
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+
+ if (hi2c->XferSize > 0U)
+ {
+ if (hi2c->hdmatx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive in master mode an amount of data in non-blocking mode with DMA
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
+{
+ __IO uint32_t count = 0U;
+ HAL_StatusTypeDef dmaxferstatus;
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+
+ if (hi2c->XferSize > 0U)
+ {
+ if (hi2c->hdmarx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef dmaxferstatus;
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ if (hi2c->hdmatx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* Enable DMA Request */
+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive in slave mode an amount of data in non-blocking mode with DMA
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef dmaxferstatus;
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ if (hi2c->hdmarx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Write an amount of data in blocking mode to a specific memory address
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+
+ /* Check the parameters */
+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MEM;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Send Slave Address and Memory Address */
+ if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ while (hi2c->XferSize > 0U)
+ {
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U))
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ }
+
+ /* Wait until BTF flag is set */
+ if (I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Read an amount of data in blocking mode from a specific memory address
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ __IO uint32_t count = 0U;
+
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+
+ /* Check the parameters */
+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MEM;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Send Slave Address and Memory Address */
+ if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ if (hi2c->XferSize == 0U)
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ else if (hi2c->XferSize == 1U)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Re-enable IRQs */
+ __enable_irq();
+ }
+ else if (hi2c->XferSize == 2U)
+ {
+ /* Enable Pos */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Re-enable IRQs */
+ __enable_irq();
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+
+ while (hi2c->XferSize > 0U)
+ {
+ if (hi2c->XferSize <= 3U)
+ {
+ /* One byte */
+ if (hi2c->XferSize == 1U)
+ {
+ /* Wait until RXNE flag is set */
+ if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ /* Two bytes */
+ else if (hi2c->XferSize == 2U)
+ {
+ /* Wait until BTF flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ /* Re-enable IRQs */
+ __enable_irq();
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ /* 3 Last bytes */
+ else
+ {
+ /* Wait until BTF flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3
+ software sequence must complete before the current byte end of transfer */
+ __disable_irq();
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ /* Wait until BTF flag is set */
+ count = I2C_TIMEOUT_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Re-enable IRQs */
+ __enable_irq();
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ /* Re-enable IRQs */
+ __enable_irq();
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ }
+ else
+ {
+ /* Wait until RXNE flag is set */
+ if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ }
+ }
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
+{
+ __IO uint32_t count = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MEM;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+ hi2c->Memaddress = MemAddress;
+ hi2c->MemaddSize = MemAddSize;
+ hi2c->EventCount = 0U;
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
+{
+ __IO uint32_t count = 0U;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MEM;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+ hi2c->Memaddress = MemAddress;
+ hi2c->MemaddSize = MemAddSize;
+ hi2c->EventCount = 0U;
+
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ if (hi2c->XferSize > 0U)
+ {
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
+{
+ __IO uint32_t count = 0U;
+ HAL_StatusTypeDef dmaxferstatus;
+
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+
+ /* Check the parameters */
+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MEM;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+ hi2c->Memaddress = MemAddress;
+ hi2c->MemaddSize = MemAddSize;
+ hi2c->EventCount = 0U;
+
+ if (hi2c->XferSize > 0U)
+ {
+ if (hi2c->hdmatx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Send Slave Address and Memory Address */
+ if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
+ {
+ /* Abort the ongoing DMA */
+ dmaxferstatus = HAL_DMA_Abort_IT(hi2c->hdmatx);
+
+ /* Prevent unused argument(s) compilation and MISRA warning */
+ UNUSED(dmaxferstatus);
+
+ /* Set the unused I2C DMA transfer complete callback to NULL */
+ hi2c->hdmatx->XferCpltCallback = NULL;
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ hi2c->XferSize = 0U;
+ hi2c->XferCount = 0U;
+
+ /* Disable I2C peripheral to prevent dummy data in buffer */
+ __HAL_I2C_DISABLE(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+ /* Enable ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR);
+
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_SIZE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be read
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
+{
+ /* Init tickstart for timeout management*/
+ uint32_t tickstart = HAL_GetTick();
+ __IO uint32_t count = 0U;
+ HAL_StatusTypeDef dmaxferstatus;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MEM;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->Devaddress = DevAddress;
+ hi2c->Memaddress = MemAddress;
+ hi2c->MemaddSize = MemAddSize;
+ hi2c->EventCount = 0U;
+
+ if (hi2c->XferSize > 0U)
+ {
+ if (hi2c->hdmarx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Send Slave Address and Memory Address */
+ if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
+ {
+ /* Abort the ongoing DMA */
+ dmaxferstatus = HAL_DMA_Abort_IT(hi2c->hdmarx);
+
+ /* Prevent unused argument(s) compilation and MISRA warning */
+ UNUSED(dmaxferstatus);
+
+ /* Set the unused I2C DMA transfer complete callback to NULL */
+ hi2c->hdmarx->XferCpltCallback = NULL;
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ hi2c->XferSize = 0U;
+ hi2c->XferCount = 0U;
+
+ /* Disable I2C peripheral to prevent dummy data in buffer */
+ __HAL_I2C_DISABLE(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (hi2c->XferSize == 1U)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+ else
+ {
+ /* Enable Last DMA bit */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+ /* Enable ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR);
+
+ /* Enable DMA Request */
+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Send Slave Address and Memory Address */
+ if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Checks if target device is ready for communication.
+ * @note This function is used with Memory devices
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param Trials Number of trials
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
+{
+ /* Get tick */
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t I2C_Trials = 0U;
+ FlagStatus tmp1;
+ FlagStatus tmp2;
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Wait until BUSY flag is reset */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_BUSY;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ do
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Wait until SB flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)
+ {
+ if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+ {
+ hi2c->ErrorCode = HAL_I2C_WRONG_START;
+ }
+ return HAL_TIMEOUT;
+ }
+
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
+
+ /* Wait until ADDR or AF flag are set */
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
+ tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
+ while ((hi2c->State != HAL_I2C_STATE_TIMEOUT) && (tmp1 == RESET) && (tmp2 == RESET))
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ hi2c->State = HAL_I2C_STATE_TIMEOUT;
+ }
+ tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
+ tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
+ }
+
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ /* Check if the ADDR flag has been set */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Clear ADDR Flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Wait until BUSY flag is reset */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Clear AF Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ /* Wait until BUSY flag is reset */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ /* Increment Trials */
+ I2C_Trials++;
+ }
+ while (I2C_Trials < Trials);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential transmit in master I2C mode an amount of data in non-blocking mode with Interrupt.
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ __IO uint32_t Prev_State = 0x00U;
+ __IO uint32_t count = 0x00U;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Check Busy Flag only if FIRST call of Master interface */
+ if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+ hi2c->Devaddress = DevAddress;
+
+ Prev_State = hi2c->PreviousState;
+
+ /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if ((Prev_State != I2C_STATE_MASTER_BUSY_TX) || (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 1))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential transmit in master I2C mode an amount of data in non-blocking mode with DMA.
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ __IO uint32_t Prev_State = 0x00U;
+ __IO uint32_t count = 0x00U;
+ HAL_StatusTypeDef dmaxferstatus;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Check Busy Flag only if FIRST call of Master interface */
+ if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+ hi2c->Devaddress = DevAddress;
+
+ Prev_State = hi2c->PreviousState;
+
+ if (hi2c->XferSize > 0U)
+ {
+ if (hi2c->hdmatx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if ((Prev_State != I2C_STATE_MASTER_BUSY_TX) || (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 1))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* If XferOptions is not associated to a new frame, mean no start bit is request, enable directly the DMA request */
+ /* In other cases, DMA request is enabled after Slave address treatment in IRQHandler */
+ if ((XferOptions == I2C_NEXT_FRAME) || (XferOptions == I2C_LAST_FRAME) || (XferOptions == I2C_LAST_FRAME_NO_STOP))
+ {
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+ }
+
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if ((Prev_State != I2C_STATE_MASTER_BUSY_TX) || (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 1))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+ }
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential receive in master I2C mode an amount of data in non-blocking mode with Interrupt
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ __IO uint32_t Prev_State = 0x00U;
+ __IO uint32_t count = 0U;
+ uint32_t enableIT = (I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Check Busy Flag only if FIRST call of Master interface */
+ if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+ hi2c->Devaddress = DevAddress;
+
+ Prev_State = hi2c->PreviousState;
+
+ if ((hi2c->XferCount == 2U) && ((XferOptions == I2C_LAST_FRAME) || (XferOptions == I2C_LAST_FRAME_NO_STOP)))
+ {
+ if (Prev_State == I2C_STATE_MASTER_BUSY_RX)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Enable Pos */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ /* Remove Enabling of IT_BUF, mean RXNE treatment, treat the 2 bytes through BTF */
+ enableIT &= ~I2C_IT_BUF;
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+
+ /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if ((Prev_State != I2C_STATE_MASTER_BUSY_RX) || (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 1))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable interrupts */
+ __HAL_I2C_ENABLE_IT(hi2c, enableIT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential receive in master mode an amount of data in non-blocking mode with DMA
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ __IO uint32_t Prev_State = 0x00U;
+ __IO uint32_t count = 0U;
+ uint32_t enableIT = (I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+ HAL_StatusTypeDef dmaxferstatus;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Check Busy Flag only if FIRST call of Master interface */
+ if ((READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP) || (XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME))
+ {
+ /* Wait until BUSY flag is reset */
+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_BUSY;
+ }
+ }
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ /* Clear Last DMA bit */
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+ hi2c->Devaddress = DevAddress;
+
+ Prev_State = hi2c->PreviousState;
+
+ if (hi2c->XferSize > 0U)
+ {
+ if ((hi2c->XferCount == 2U) && ((XferOptions == I2C_LAST_FRAME) || (XferOptions == I2C_LAST_FRAME_NO_STOP)))
+ {
+ if (Prev_State == I2C_STATE_MASTER_BUSY_RX)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Enable Pos */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ /* Enable Last DMA bit */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ if ((XferOptions == I2C_LAST_FRAME) || (XferOptions == I2C_OTHER_AND_LAST_FRAME) || (XferOptions == I2C_LAST_FRAME_NO_STOP))
+ {
+ /* Enable Last DMA bit */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+ }
+ }
+ if (hi2c->hdmarx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if ((Prev_State != I2C_STATE_MASTER_BUSY_RX) || (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 1))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Update interrupt for only EVT and ERR */
+ enableIT = (I2C_IT_EVT | I2C_IT_ERR);
+ }
+ else
+ {
+ /* Update interrupt for only ERR */
+ enableIT = I2C_IT_ERR;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* If XferOptions is not associated to a new frame, mean no start bit is request, enable directly the DMA request */
+ /* In other cases, DMA request is enabled after Slave address treatment in IRQHandler */
+ if ((XferOptions == I2C_NEXT_FRAME) || (XferOptions == I2C_LAST_FRAME) || (XferOptions == I2C_LAST_FRAME_NO_STOP))
+ {
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+ }
+
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, enableIT);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if ((Prev_State != I2C_STATE_MASTER_BUSY_RX) || (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 1))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable interrupts */
+ __HAL_I2C_ENABLE_IT(hi2c, enableIT);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential transmit in slave mode an amount of data in non-blocking mode with Interrupt
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential transmit in slave mode an amount of data in non-blocking mode with DMA
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ HAL_StatusTypeDef dmaxferstatus;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
+ /* and then toggle the HAL slave RX state to TX state */
+ if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
+ {
+ if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+ {
+ /* Abort DMA Xfer if any */
+ if (hi2c->hdmarx != NULL)
+ {
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
+ }
+ }
+ }
+ }
+ else if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
+ {
+ if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+ {
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Abort DMA Xfer if any */
+ if (hi2c->hdmatx != NULL)
+ {
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+
+ if (hi2c->hdmatx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* Enable DMA Request */
+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential receive in slave mode an amount of data in non-blocking mode with Interrupt
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+
+ /* Enable EVT, BUF and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sequential receive in slave mode an amount of data in non-blocking mode with DMA
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData Pointer to data buffer
+ * @param Size Amount of data to be sent
+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
+{
+ HAL_StatusTypeDef dmaxferstatus;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
+ /* and then toggle the HAL slave RX state to TX state */
+ if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
+ {
+ if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+ {
+ /* Abort DMA Xfer if any */
+ if (hi2c->hdmarx != NULL)
+ {
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
+ }
+ }
+ }
+ }
+ else if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
+ {
+ if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+ {
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Abort DMA Xfer if any */
+ if (hi2c->hdmatx != NULL)
+ {
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Disable Pos */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+
+ if (hi2c->hdmarx != NULL)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt;
+
+ /* Set the DMA error callback */
+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
+
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ if (dmaxferstatus == HAL_OK)
+ {
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Note : The I2C interrupts must be enabled after unlocking current process
+ to avoid the risk of I2C interrupt handle execution before current
+ process unlock */
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Update I2C state */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Update I2C error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Enable the Address listen mode with Interrupt.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c)
+{
+ if (hi2c->State == HAL_I2C_STATE_READY)
+ {
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+
+ /* Check if the I2C is already enabled */
+ if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+ {
+ /* Enable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+ }
+
+ /* Enable Address Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Enable EVT and ERR interrupt */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Disable the Address listen mode with Interrupt.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of tmp to prevent undefined behavior of volatile usage */
+ uint32_t tmp;
+
+ /* Disable Address listen mode only if a transfer is not ongoing */
+ if (hi2c->State == HAL_I2C_STATE_LISTEN)
+ {
+ tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
+ hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Disable Address Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Disable EVT and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Abort a master I2C IT or DMA process communication with Interrupt.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(DevAddress);
+
+ /* Abort Master transfer during Receive or Transmit process */
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && (CurrentMode == HAL_I2C_MODE_MASTER))
+ {
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_ABORT;
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ hi2c->XferCount = 0U;
+
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c);
+
+ return HAL_OK;
+ }
+ else
+ {
+ /* Wrong usage of abort function */
+ /* This function should be used only in case of abort monitored by master device */
+ /* Or periphal is not in busy state, mean there is no active sequence to be abort */
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
+ * @{
+ */
+
+/**
+ * @brief This function handles I2C event interrupt request.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
+{
+ uint32_t sr1itflags;
+ uint32_t sr2itflags = 0U;
+ uint32_t itsources = READ_REG(hi2c->Instance->CR2);
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+ HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+ /* Master or Memory mode selected */
+ if ((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM))
+ {
+ sr2itflags = READ_REG(hi2c->Instance->SR2);
+ sr1itflags = READ_REG(hi2c->Instance->SR1);
+
+ /* Exit IRQ event until Start Bit detected in case of Other frame requested */
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_SB) == RESET) && (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(CurrentXferOptions) == 1U))
+ {
+ return;
+ }
+
+ /* SB Set ----------------------------------------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_SB) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ /* Convert OTHER_xxx XferOptions if any */
+ I2C_ConvertOtherXferOptions(hi2c);
+
+ I2C_Master_SB(hi2c);
+ }
+ /* ADD10 Set -------------------------------------------------------------*/
+ else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_ADD10) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ I2C_Master_ADD10(hi2c);
+ }
+ /* ADDR Set --------------------------------------------------------------*/
+ else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_ADDR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ I2C_Master_ADDR(hi2c);
+ }
+ /* I2C in mode Transmitter -----------------------------------------------*/
+ else if (I2C_CHECK_FLAG(sr2itflags, I2C_FLAG_TRA) != RESET)
+ {
+ /* Do not check buffer and BTF flag if a Xfer DMA is on going */
+ if (READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) != I2C_CR2_DMAEN)
+ {
+ /* TXE set and BTF reset -----------------------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_TXE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+ {
+ I2C_MasterTransmit_TXE(hi2c);
+ }
+ /* BTF set -------------------------------------------------------------*/
+ else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ if (CurrentState == HAL_I2C_STATE_BUSY_TX)
+ {
+ I2C_MasterTransmit_BTF(hi2c);
+ }
+ else /* HAL_I2C_MODE_MEM */
+ {
+ if (CurrentMode == HAL_I2C_MODE_MEM)
+ {
+ I2C_MemoryTransmit_TXE_BTF(hi2c);
+ }
+ }
+ }
+ else
+ {
+ /* Do nothing */
+ }
+ }
+ }
+ /* I2C in mode Receiver --------------------------------------------------*/
+ else
+ {
+ /* Do not check buffer and BTF flag if a Xfer DMA is on going */
+ if (READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) != I2C_CR2_DMAEN)
+ {
+ /* RXNE set and BTF reset -----------------------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_RXNE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+ {
+ I2C_MasterReceive_RXNE(hi2c);
+ }
+ /* BTF set -------------------------------------------------------------*/
+ else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ I2C_MasterReceive_BTF(hi2c);
+ }
+ else
+ {
+ /* Do nothing */
+ }
+ }
+ }
+ }
+ /* Slave mode selected */
+ else
+ {
+ /* If an error is detected, read only SR1 register to prevent */
+ /* a clear of ADDR flags by reading SR2 after reading SR1 in Error treatment */
+ if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ {
+ sr1itflags = READ_REG(hi2c->Instance->SR1);
+ }
+ else
+ {
+ sr2itflags = READ_REG(hi2c->Instance->SR2);
+ sr1itflags = READ_REG(hi2c->Instance->SR1);
+ }
+
+ /* ADDR set --------------------------------------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_ADDR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ /* Now time to read SR2, this will clear ADDR flag automatically */
+ if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ {
+ sr2itflags = READ_REG(hi2c->Instance->SR2);
+ }
+ I2C_Slave_ADDR(hi2c, sr2itflags);
+ }
+ /* STOPF set --------------------------------------------------------------*/
+ else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_STOPF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ I2C_Slave_STOPF(hi2c);
+ }
+ /* I2C in mode Transmitter -----------------------------------------------*/
+ else if ((CurrentState == HAL_I2C_STATE_BUSY_TX) || (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN))
+ {
+ /* TXE set and BTF reset -----------------------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_TXE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+ {
+ I2C_SlaveTransmit_TXE(hi2c);
+ }
+ /* BTF set -------------------------------------------------------------*/
+ else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ I2C_SlaveTransmit_BTF(hi2c);
+ }
+ else
+ {
+ /* Do nothing */
+ }
+ }
+ /* I2C in mode Receiver --------------------------------------------------*/
+ else
+ {
+ /* RXNE set and BTF reset ----------------------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_RXNE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+ {
+ I2C_SlaveReceive_RXNE(hi2c);
+ }
+ /* BTF set -------------------------------------------------------------*/
+ else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+ {
+ I2C_SlaveReceive_BTF(hi2c);
+ }
+ else
+ {
+ /* Do nothing */
+ }
+ }
+ }
+}
+
+/**
+ * @brief This function handles I2C error interrupt request.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
+{
+ HAL_I2C_ModeTypeDef tmp1;
+ uint32_t tmp2;
+ HAL_I2C_StateTypeDef tmp3;
+ uint32_t tmp4;
+ uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1);
+ uint32_t itsources = READ_REG(hi2c->Instance->CR2);
+ uint32_t error = HAL_I2C_ERROR_NONE;
+ HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+
+ /* I2C Bus error interrupt occurred ----------------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BERR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERR) != RESET))
+ {
+ error |= HAL_I2C_ERROR_BERR;
+
+ /* Clear BERR flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
+
+ /* Workaround: Start cannot be generated after a misplaced Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_SWRST);
+ }
+
+ /* I2C Arbitration Lost error interrupt occurred ---------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_ARLO) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERR) != RESET))
+ {
+ error |= HAL_I2C_ERROR_ARLO;
+
+ /* Clear ARLO flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
+ }
+
+ /* I2C Acknowledge failure error interrupt occurred ------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_AF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERR) != RESET))
+ {
+ tmp1 = CurrentMode;
+ tmp2 = hi2c->XferCount;
+ tmp3 = hi2c->State;
+ tmp4 = hi2c->PreviousState;
+ if ((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) && \
+ ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || \
+ ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX))))
+ {
+ I2C_Slave_AF(hi2c);
+ }
+ else
+ {
+ /* Clear AF flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ error |= HAL_I2C_ERROR_AF;
+
+ /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */
+ if ((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM))
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ }
+ }
+
+ /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/
+ if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_OVR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERR) != RESET))
+ {
+ error |= HAL_I2C_ERROR_OVR;
+ /* Clear OVR flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
+ }
+
+ /* Call the Error Callback in case of Error detected -----------------------*/
+ if (error != HAL_I2C_ERROR_NONE)
+ {
+ hi2c->ErrorCode |= error;
+ I2C_ITError(hi2c);
+ }
+}
+
+/**
+ * @brief Master Tx Transfer completed callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MasterTxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Master Rx Transfer completed callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MasterRxCpltCallback could be implemented in the user file
+ */
+}
+
+/** @brief Slave Tx Transfer completed callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Slave Rx Transfer completed callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Slave Address Match callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferDirection_definition
+ * @param AddrMatchCode Address Match Code
+ * @retval None
+ */
+__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+ UNUSED(TransferDirection);
+ UNUSED(AddrMatchCode);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_AddrCallback() could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Listen Complete callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_ListenCpltCallback() could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Memory Tx Transfer completed callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MemTxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Memory Rx Transfer completed callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MemRxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief I2C error callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief I2C abort callback.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_AbortCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
+ * @brief Peripheral State, Mode and Error functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State, Mode and Error functions #####
+ ===============================================================================
+ [..]
+ This subsection permit to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the I2C handle state.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL state
+ */
+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c)
+{
+ /* Return I2C handle state */
+ return hi2c->State;
+}
+
+/**
+ * @brief Returns the I2C Master, Slave, Memory or no mode.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval HAL mode
+ */
+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c)
+{
+ return hi2c->Mode;
+}
+
+/**
+ * @brief Return the I2C error code.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval I2C Error Code
+ */
+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c)
+{
+ return hi2c->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Handle TXE flag for Master
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+ HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+ if ((hi2c->XferSize == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX))
+ {
+ /* Call TxCpltCallback() directly if no stop mode is set */
+ if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME))
+ {
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MasterTxCpltCallback(hi2c);
+#else
+ HAL_I2C_MasterTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else /* Generate Stop condition then Call TxCpltCallback() */
+ {
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MemTxCpltCallback(hi2c);
+#else
+ HAL_I2C_MemTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MasterTxCpltCallback(hi2c);
+#else
+ HAL_I2C_MasterTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+ }
+ else if ((CurrentState == HAL_I2C_STATE_BUSY_TX) || \
+ ((CurrentMode == HAL_I2C_MODE_MEM) && (CurrentState == HAL_I2C_STATE_BUSY_RX)))
+ {
+ if (hi2c->XferCount == 0U)
+ {
+ /* Disable BUF interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+ }
+ else
+ {
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ I2C_MemoryTransmit_TXE_BTF(hi2c);
+ }
+ else
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+ }
+ }
+ else
+ {
+ /* Do nothing */
+ }
+}
+
+/**
+ * @brief Handle BTF flag for Master transmitter
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+ if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
+ {
+ if (hi2c->XferCount != 0U)
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+ else
+ {
+ /* Call TxCpltCallback() directly if no stop mode is set */
+ if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME))
+ {
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MasterTxCpltCallback(hi2c);
+#else
+ HAL_I2C_MasterTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else /* Generate Stop condition then Call TxCpltCallback() */
+ {
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MemTxCpltCallback(hi2c);
+#else
+ HAL_I2C_MemTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MasterTxCpltCallback(hi2c);
+#else
+ HAL_I2C_MasterTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Do nothing */
+ }
+}
+
+/**
+ * @brief Handle TXE and BTF flag for Memory transmitter
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_MemoryTransmit_TXE_BTF(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+ if (hi2c->EventCount == 0U)
+ {
+ /* If Memory address size is 8Bit */
+ if (hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT)
+ {
+ /* Send Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
+
+ hi2c->EventCount += 2U;
+ }
+ /* If Memory address size is 16Bit */
+ else
+ {
+ /* Send MSB of Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress);
+
+ hi2c->EventCount++;
+ }
+ }
+ else if (hi2c->EventCount == 1U)
+ {
+ /* Send LSB of Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress);
+
+ hi2c->EventCount++;
+ }
+ else if (hi2c->EventCount == 2U)
+ {
+ if (CurrentState == HAL_I2C_STATE_BUSY_RX)
+ {
+ /* Generate Restart */
+ hi2c->Instance->CR1 |= I2C_CR1_START;
+
+ hi2c->EventCount++;
+ }
+ else if ((hi2c->XferCount > 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX))
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+ else if ((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX))
+ {
+ /* Generate Stop condition then Call TxCpltCallback() */
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MemTxCpltCallback(hi2c);
+#else
+ HAL_I2C_MemTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Do nothing */
+ }
+ }
+ else
+ {
+ /* Clear TXE and BTF flags */
+ I2C_Flush_DR(hi2c);
+ }
+}
+
+/**
+ * @brief Handle RXNE flag for Master
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
+{
+ if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
+ {
+ uint32_t tmp;
+
+ tmp = hi2c->XferCount;
+ if (tmp > 3U)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+
+ if (hi2c->XferCount == (uint16_t)3)
+ {
+ /* Disable BUF interrupt, this help to treat correctly the last 4 bytes
+ on BTF subroutine */
+ /* Disable BUF interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+ }
+ }
+ else if ((hi2c->XferOptions != I2C_FIRST_AND_NEXT_FRAME) && ((tmp == 1U) || (tmp == 0U)))
+ {
+ if (I2C_WaitOnSTOPRequestThroughIT(hi2c) == HAL_OK)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->PreviousState = I2C_STATE_NONE;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MemRxCpltCallback(hi2c);
+#else
+ HAL_I2C_MemRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MasterRxCpltCallback(hi2c);
+#else
+ HAL_I2C_MasterRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Call user error callback */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ErrorCallback(hi2c);
+#else
+ HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
+ on BTF subroutine if there is a reception delay between N-1 and N byte */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+ }
+ }
+}
+
+/**
+ * @brief Handle BTF flag for Master receiver
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+ if (hi2c->XferCount == 4U)
+ {
+ /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
+ on BTF subroutine if there is a reception delay between N-1 and N byte */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+ else if (hi2c->XferCount == 3U)
+ {
+ /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
+ on BTF subroutine if there is a reception delay between N-1 and N byte */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+
+ if ((CurrentXferOptions != I2C_NEXT_FRAME) && (CurrentXferOptions != I2C_FIRST_AND_NEXT_FRAME))
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+ else if (hi2c->XferCount == 2U)
+ {
+ /* Prepare next transfer or stop current transfer */
+ if ((CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME_NO_STOP))
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+ else if ((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_AND_NEXT_FRAME))
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+ else if (CurrentXferOptions != I2C_LAST_FRAME_NO_STOP)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ else
+ {
+ /* Do nothing */
+ }
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+
+ /* Disable EVT and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->PreviousState = I2C_STATE_NONE;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MemRxCpltCallback(hi2c);
+#else
+ HAL_I2C_MemRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MasterRxCpltCallback(hi2c);
+#else
+ HAL_I2C_MasterRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+}
+
+/**
+ * @brief Handle SB flag for Master
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_Master_SB(I2C_HandleTypeDef *hi2c)
+{
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ if (hi2c->EventCount == 0U)
+ {
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
+ }
+ else
+ {
+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);
+ }
+ }
+ else
+ {
+ if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+ {
+ /* Send slave 7 Bits address */
+ if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
+ {
+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
+ }
+ else
+ {
+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);
+ }
+
+ if (((hi2c->hdmatx != NULL) && (hi2c->hdmatx->XferCpltCallback != NULL))
+ || ((hi2c->hdmarx != NULL) && (hi2c->hdmarx->XferCpltCallback != NULL)))
+ {
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+ }
+ }
+ else
+ {
+ if (hi2c->EventCount == 0U)
+ {
+ /* Send header of slave address */
+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress);
+ }
+ else if (hi2c->EventCount == 1U)
+ {
+ /* Send header of slave address */
+ hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress);
+ }
+ else
+ {
+ /* Do nothing */
+ }
+ }
+ }
+}
+
+/**
+ * @brief Handle ADD10 flag for Master
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_Master_ADD10(I2C_HandleTypeDef *hi2c)
+{
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress);
+
+ if (((hi2c->hdmatx != NULL) && (hi2c->hdmatx->XferCpltCallback != NULL))
+ || ((hi2c->hdmarx != NULL) && (hi2c->hdmarx->XferCpltCallback != NULL)))
+ {
+ /* Enable DMA Request */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+ }
+}
+
+/**
+ * @brief Handle ADDR flag for Master
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_Master_ADDR(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+ HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+ uint32_t Prev_State = hi2c->PreviousState;
+
+ if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
+ {
+ if ((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM))
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+ else if ((hi2c->EventCount == 0U) && (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT))
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Restart */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ hi2c->EventCount++;
+ }
+ else
+ {
+ if (hi2c->XferCount == 0U)
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ else if (hi2c->XferCount == 1U)
+ {
+ if (CurrentXferOptions == I2C_NO_OPTION_FRAME)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+ else
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ }
+ /* Prepare next transfer or stop current transfer */
+ else if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) \
+ && ((Prev_State != I2C_STATE_MASTER_BUSY_RX) || (CurrentXferOptions == I2C_FIRST_FRAME)))
+ {
+ if ((CurrentXferOptions != I2C_NEXT_FRAME) && (CurrentXferOptions != I2C_FIRST_AND_NEXT_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME_NO_STOP))
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+ else
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ }
+ else if (hi2c->XferCount == 2U)
+ {
+ if ((CurrentXferOptions != I2C_NEXT_FRAME) && (CurrentXferOptions != I2C_FIRST_AND_NEXT_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME_NO_STOP))
+ {
+ /* Enable Pos */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+
+ if (((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) && ((CurrentXferOptions == I2C_NO_OPTION_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME_NO_STOP) || (CurrentXferOptions == I2C_LAST_FRAME)))
+ {
+ /* Enable Last DMA bit */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+ }
+ }
+ else
+ {
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ if (((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) && ((CurrentXferOptions == I2C_NO_OPTION_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME_NO_STOP) || (CurrentXferOptions == I2C_LAST_FRAME)))
+ {
+ /* Enable Last DMA bit */
+ SET_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+
+ /* Reset Event counter */
+ hi2c->EventCount = 0U;
+ }
+ }
+ else
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+ }
+}
+
+/**
+ * @brief Handle TXE flag for Slave
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+ if (hi2c->XferCount != 0U)
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+
+ if ((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN))
+ {
+ /* Last Byte is received, disable Interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+
+ /* Set state at HAL_I2C_STATE_LISTEN */
+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->SlaveTxCpltCallback(hi2c);
+#else
+ HAL_I2C_SlaveTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief Handle BTF flag for Slave transmitter
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c)
+{
+ if (hi2c->XferCount != 0U)
+ {
+ /* Write data to DR */
+ hi2c->Instance->DR = *hi2c->pBuffPtr;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+}
+
+/**
+ * @brief Handle RXNE flag for Slave
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+ if (hi2c->XferCount != 0U)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+
+ if ((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN))
+ {
+ /* Last Byte is received, disable Interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+
+ /* Set state at HAL_I2C_STATE_LISTEN */
+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->SlaveRxCpltCallback(hi2c);
+#else
+ HAL_I2C_SlaveRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief Handle BTF flag for Slave receiver
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c)
+{
+ if (hi2c->XferCount != 0U)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+}
+
+/**
+ * @brief Handle ADD flag for Slave
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @param IT2Flags Interrupt2 flags to handle.
+ * @retval None
+ */
+static void I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c, uint32_t IT2Flags)
+{
+ uint8_t TransferDirection = I2C_DIRECTION_RECEIVE;
+ uint16_t SlaveAddrCode;
+
+ if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+ {
+ /* Disable BUF interrupt, BUF enabling is manage through slave specific interface */
+ __HAL_I2C_DISABLE_IT(hi2c, (I2C_IT_BUF));
+
+ /* Transfer Direction requested by Master */
+ if (I2C_CHECK_FLAG(IT2Flags, I2C_FLAG_TRA) == RESET)
+ {
+ TransferDirection = I2C_DIRECTION_TRANSMIT;
+ }
+
+ if (I2C_CHECK_FLAG(IT2Flags, I2C_FLAG_DUALF) == RESET)
+ {
+ SlaveAddrCode = (uint16_t)hi2c->Init.OwnAddress1;
+ }
+ else
+ {
+ SlaveAddrCode = (uint16_t)hi2c->Init.OwnAddress2;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Call Slave Addr callback */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->AddrCallback(hi2c, TransferDirection, SlaveAddrCode);
+#else
+ HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+ }
+}
+
+/**
+ * @brief Handle STOPF flag for Slave
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Clear STOPF flag */
+ __HAL_I2C_CLEAR_STOPFLAG(hi2c);
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* If a DMA is ongoing, Update handle size context */
+ if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+ {
+ if ((CurrentState == HAL_I2C_STATE_BUSY_RX) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN))
+ {
+ hi2c->XferCount = (uint16_t)(I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx));
+
+ if (hi2c->XferCount != 0U)
+ {
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+ }
+
+ /* Disable, stop the current DMA */
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Abort DMA Xfer if any */
+ if (HAL_DMA_GetState(hi2c->hdmarx) != HAL_DMA_STATE_READY)
+ {
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
+ }
+ }
+ }
+ else
+ {
+ hi2c->XferCount = (uint16_t)(I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx));
+
+ if (hi2c->XferCount != 0U)
+ {
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+ }
+
+ /* Disable, stop the current DMA */
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ /* Abort DMA Xfer if any */
+ if (HAL_DMA_GetState(hi2c->hdmatx) != HAL_DMA_STATE_READY)
+ {
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
+ }
+ }
+ }
+ }
+
+ /* All data are not transferred, so set error code accordingly */
+ if (hi2c->XferCount != 0U)
+ {
+ /* Store Last receive data if any */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+
+ /* Store Last receive data if any */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+
+ /* Update counter */
+ hi2c->XferCount--;
+ }
+
+ if (hi2c->XferCount != 0U)
+ {
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+ }
+ }
+
+ if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ {
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c);
+ }
+ else
+ {
+ if (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)
+ {
+ /* Set state at HAL_I2C_STATE_LISTEN */
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->SlaveRxCpltCallback(hi2c);
+#else
+ HAL_I2C_SlaveRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+
+ if (hi2c->State == HAL_I2C_STATE_LISTEN)
+ {
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ListenCpltCallback(hi2c);
+#else
+ HAL_I2C_ListenCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ if ((hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_RX) || (CurrentState == HAL_I2C_STATE_BUSY_RX))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->SlaveRxCpltCallback(hi2c);
+#else
+ HAL_I2C_SlaveRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+ }
+}
+
+/**
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval None
+ */
+static void I2C_Slave_AF(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+ if (((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME)) && \
+ (CurrentState == HAL_I2C_STATE_LISTEN))
+ {
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Clear AF flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ListenCpltCallback(hi2c);
+#else
+ HAL_I2C_ListenCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else if (CurrentState == HAL_I2C_STATE_BUSY_TX)
+ {
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+ /* Clear AF flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Clear TXE flag */
+ I2C_Flush_DR(hi2c);
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->SlaveTxCpltCallback(hi2c);
+#else
+ HAL_I2C_SlaveTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Clear AF flag only */
+ /* State Listen, but XferOptions == FIRST or NEXT */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+ }
+}
+
+/**
+ * @brief I2C interrupts error process
+ * @param hi2c I2C handle.
+ * @retval None
+ */
+static void I2C_ITError(I2C_HandleTypeDef *hi2c)
+{
+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+ HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+ uint32_t CurrentError;
+
+ if (((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) && (CurrentState == HAL_I2C_STATE_BUSY_RX))
+ {
+ /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */
+ hi2c->Instance->CR1 &= ~I2C_CR1_POS;
+ }
+
+ if (((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+ {
+ /* keep HAL_I2C_STATE_LISTEN */
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ }
+ else
+ {
+ /* If state is an abort treatment on going, don't change state */
+ /* This change will be do later */
+ if ((READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) != I2C_CR2_DMAEN) && (CurrentState != HAL_I2C_STATE_ABORT))
+ {
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ }
+ hi2c->PreviousState = I2C_STATE_NONE;
+ }
+
+ /* Abort DMA transfer */
+ if (READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+ {
+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN;
+
+ if (hi2c->hdmatx->State != HAL_DMA_STATE_READY)
+ {
+ /* Set the DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
+
+ if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
+ {
+ /* Disable I2C peripheral to prevent dummy data in buffer */
+ __HAL_I2C_DISABLE(hi2c);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
+ }
+ }
+ else
+ {
+ /* Set the DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
+
+ if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
+ {
+ /* Store Last receive data if any */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+ }
+
+ /* Disable I2C peripheral to prevent dummy data in buffer */
+ __HAL_I2C_DISABLE(hi2c);
+
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */
+ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
+ }
+ }
+ }
+ else if (hi2c->State == HAL_I2C_STATE_ABORT)
+ {
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Store Last receive data if any */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+ }
+
+ /* Disable I2C peripheral to prevent dummy data in buffer */
+ __HAL_I2C_DISABLE(hi2c);
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->AbortCpltCallback(hi2c);
+#else
+ HAL_I2C_AbortCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Store Last receive data if any */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+ {
+ /* Read data from DR */
+ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+ /* Increment Buffer pointer */
+ hi2c->pBuffPtr++;
+ }
+
+ /* Call user error callback */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ErrorCallback(hi2c);
+#else
+ HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+
+ /* STOP Flag is not set after a NACK reception, BusError, ArbitrationLost, OverRun */
+ CurrentError = hi2c->ErrorCode;
+
+ if (((CurrentError & HAL_I2C_ERROR_BERR) == HAL_I2C_ERROR_BERR) || \
+ ((CurrentError & HAL_I2C_ERROR_ARLO) == HAL_I2C_ERROR_ARLO) || \
+ ((CurrentError & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF) || \
+ ((CurrentError & HAL_I2C_ERROR_OVR) == HAL_I2C_ERROR_OVR))
+ {
+ /* Disable EVT, BUF and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+ }
+
+ /* So may inform upper layer that listen phase is stopped */
+ /* during NACK error treatment */
+ CurrentState = hi2c->State;
+ if (((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF) && (CurrentState == HAL_I2C_STATE_LISTEN))
+ {
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ListenCpltCallback(hi2c);
+#else
+ HAL_I2C_ListenCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart)
+{
+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+ /* Generate Start condition if first transfer */
+ if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+ else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
+ {
+ /* Generate ReStart */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+ else
+ {
+ /* Do nothing */
+ }
+
+ /* Wait until SB flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+ {
+ hi2c->ErrorCode = HAL_I2C_WRONG_START;
+ }
+ return HAL_TIMEOUT;
+ }
+
+ if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+ {
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
+ }
+ else
+ {
+ /* Send header of slave address */
+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress);
+
+ /* Wait until ADD10 flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress);
+ }
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Master sends target device address for read request.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart)
+{
+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start condition if first transfer */
+ if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME))
+ {
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+ else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX)
+ {
+ /* Generate ReStart */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+ }
+ else
+ {
+ /* Do nothing */
+ }
+
+ /* Wait until SB flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+ {
+ hi2c->ErrorCode = HAL_I2C_WRONG_START;
+ }
+ return HAL_TIMEOUT;
+ }
+
+ if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+ {
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
+ }
+ else
+ {
+ /* Send header of slave address */
+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress);
+
+ /* Wait until ADD10 flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress);
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Generate Restart */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Wait until SB flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+ {
+ hi2c->ErrorCode = HAL_I2C_WRONG_START;
+ }
+ return HAL_TIMEOUT;
+ }
+
+ /* Send header of slave address */
+ hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress);
+ }
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Master sends target device address followed by internal memory address for write request.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
+{
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Wait until SB flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+ {
+ hi2c->ErrorCode = HAL_I2C_WRONG_START;
+ }
+ return HAL_TIMEOUT;
+ }
+
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* If Memory address size is 8Bit */
+ if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
+ {
+ /* Send Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+ }
+ /* If Memory address size is 16Bit */
+ else
+ {
+ /* Send MSB of Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress);
+
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* Send LSB of Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Master sends target device address followed by internal memory address for read request.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shifted to the left before calling the interface
+ * @param MemAddress Internal memory address
+ * @param MemAddSize Size of internal memory address
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
+{
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* Generate Start */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Wait until SB flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+ {
+ hi2c->ErrorCode = HAL_I2C_WRONG_START;
+ }
+ return HAL_TIMEOUT;
+ }
+
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* If Memory address size is 8Bit */
+ if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
+ {
+ /* Send Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+ }
+ /* If Memory address size is 16Bit */
+ else
+ {
+ /* Send MSB of Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress);
+
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* Send LSB of Memory Address */
+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+ }
+
+ /* Wait until TXE flag is set */
+ if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+ {
+ if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+ return HAL_ERROR;
+ }
+
+ /* Generate Restart */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+ /* Wait until SB flag is set */
+ if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+ {
+ hi2c->ErrorCode = HAL_I2C_WRONG_START;
+ }
+ return HAL_TIMEOUT;
+ }
+
+ /* Send slave address */
+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
+
+ /* Wait until ADDR flag is set */
+ if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DMA I2C process complete callback.
+ * @param hdma DMA handle
+ * @retval None
+ */
+static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma)
+{
+ I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+ HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+ uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+ /* Disable EVT and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* Clear Complete callback */
+ if (hi2c->hdmatx != NULL)
+ {
+ hi2c->hdmatx->XferCpltCallback = NULL;
+ }
+ if (hi2c->hdmarx != NULL)
+ {
+ hi2c->hdmarx->XferCpltCallback = NULL;
+ }
+
+ if ((((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_BUSY_TX) == (uint32_t)HAL_I2C_STATE_BUSY_TX) || ((((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_BUSY_RX) == (uint32_t)HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE)))
+ {
+ /* Disable DMA Request */
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ hi2c->XferCount = 0U;
+
+ if (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)
+ {
+ /* Set state at HAL_I2C_STATE_LISTEN */
+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->SlaveTxCpltCallback(hi2c);
+#else
+ HAL_I2C_SlaveTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else if (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)
+ {
+ /* Set state at HAL_I2C_STATE_LISTEN */
+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->SlaveRxCpltCallback(hi2c);
+#else
+ HAL_I2C_SlaveRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Do nothing */
+ }
+
+ /* Enable EVT and ERR interrupt to treat end of transfer in IRQ handler */
+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+ }
+ /* Check current Mode, in case of treatment DMA handler have been preempted by a prior interrupt */
+ else if (hi2c->Mode != HAL_I2C_MODE_NONE)
+ {
+ if (hi2c->XferCount == (uint16_t)1)
+ {
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+ }
+
+ /* Disable EVT and ERR interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+ /* Prepare next transfer or stop current transfer */
+ if ((CurrentXferOptions == I2C_NO_OPTION_FRAME) || (CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_OTHER_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME))
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+ }
+
+ /* Disable Last DMA */
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+
+ /* Disable DMA Request */
+ CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+ hi2c->XferCount = 0U;
+
+ /* Check if Errors has been detected during transfer */
+ if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ {
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ErrorCallback(hi2c);
+#else
+ HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->PreviousState = I2C_STATE_NONE;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MemRxCpltCallback(hi2c);
+#else
+ HAL_I2C_MemRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->MasterRxCpltCallback(hi2c);
+#else
+ HAL_I2C_MasterRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ }
+ }
+ else
+ {
+ /* Do nothing */
+ }
+}
+
+/**
+ * @brief DMA I2C communication error callback.
+ * @param hdma DMA handle
+ * @retval None
+ */
+static void I2C_DMAError(DMA_HandleTypeDef *hdma)
+{
+ I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Clear Complete callback */
+ if (hi2c->hdmatx != NULL)
+ {
+ hi2c->hdmatx->XferCpltCallback = NULL;
+ }
+ if (hi2c->hdmarx != NULL)
+ {
+ hi2c->hdmarx->XferCpltCallback = NULL;
+ }
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ hi2c->XferCount = 0U;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ErrorCallback(hi2c);
+#else
+ HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA I2C communication abort callback
+ * (To be called at end of DMA Abort procedure).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void I2C_DMAAbort(DMA_HandleTypeDef *hdma)
+{
+ __IO uint32_t count = 0U;
+ I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+ HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+ /* During abort treatment, check that there is no pending STOP request */
+ /* Wait until STOP flag is reset */
+ count = I2C_TIMEOUT_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ if (count == 0U)
+ {
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+ break;
+ }
+ count--;
+ }
+ while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
+
+ /* Clear Complete callback */
+ if (hi2c->hdmatx != NULL)
+ {
+ hi2c->hdmatx->XferCpltCallback = NULL;
+ }
+ if (hi2c->hdmarx != NULL)
+ {
+ hi2c->hdmarx->XferCpltCallback = NULL;
+ }
+
+ /* Disable Acknowledge */
+ CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ hi2c->XferCount = 0U;
+
+ /* Reset XferAbortCallback */
+ if (hi2c->hdmatx != NULL)
+ {
+ hi2c->hdmatx->XferAbortCallback = NULL;
+ }
+ if (hi2c->hdmarx != NULL)
+ {
+ hi2c->hdmarx->XferAbortCallback = NULL;
+ }
+
+ /* Disable I2C peripheral to prevent dummy data in buffer */
+ __HAL_I2C_DISABLE(hi2c);
+
+ /* Check if come from abort from user */
+ if (hi2c->State == HAL_I2C_STATE_ABORT)
+ {
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->AbortCpltCallback(hi2c);
+#else
+ HAL_I2C_AbortCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ if (((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+ {
+ /* Renable I2C peripheral */
+ __HAL_I2C_ENABLE(hi2c);
+
+ /* Enable Acknowledge */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+ /* keep HAL_I2C_STATE_LISTEN */
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ }
+ else
+ {
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ }
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ hi2c->ErrorCallback(hi2c);
+#else
+ HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief This function handles I2C Communication Timeout.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @param Flag specifies the I2C flag to check.
+ * @param Status The new Flag status (SET or RESET).
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
+{
+ /* Wait until flag is set */
+ while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+ {
+ if ((__HAL_I2C_GET_FLAG(hi2c, Flag) == Status))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles I2C Communication Timeout for Master addressing phase.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @param Flag specifies the I2C flag to check.
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart)
+{
+ while (__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET)
+ {
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
+ {
+ /* Generate Stop */
+ SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+ /* Clear AF Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+ {
+ if ((__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles I2C Communication Timeout for specific usage of TXE flag.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
+{
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET)
+ {
+ /* Check if a NACK is detected */
+ if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+ {
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles I2C Communication Timeout for specific usage of BTF flag.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
+{
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET)
+ {
+ /* Check if a NACK is detected */
+ if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+ {
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles I2C Communication Timeout for specific usage of STOP flag.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
+{
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
+ {
+ /* Check if a NACK is detected */
+ if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check for the Timeout */
+ if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+ {
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles I2C Communication Timeout for specific usage of STOP request through Interrupt.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_WaitOnSTOPRequestThroughIT(I2C_HandleTypeDef *hi2c)
+{
+ __IO uint32_t count = 0U;
+
+ /* Wait until STOP flag is reset */
+ count = I2C_TIMEOUT_STOP_FLAG * (SystemCoreClock / 25U / 1000U);
+ do
+ {
+ count--;
+ if (count == 0U)
+ {
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ return HAL_ERROR;
+ }
+ }
+ while (READ_BIT(hi2c->Instance->CR1, I2C_CR1_STOP) == I2C_CR1_STOP);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param Timeout Timeout duration
+ * @param Tickstart Tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
+{
+
+ while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET)
+ {
+ /* Check if a STOPF is detected */
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
+ {
+ /* Clear STOP Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+
+ /* Check for the Timeout */
+ if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+ {
+ if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles Acknowledge failed detection during an I2C Communication.
+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c)
+{
+ if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
+ {
+ /* Clear NACKF Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ return HAL_ERROR;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Convert I2Cx OTHER_xxx XferOptions to functional XferOptions.
+ * @param hi2c I2C handle.
+ * @retval None
+ */
+static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c)
+{
+ /* if user set XferOptions to I2C_OTHER_FRAME */
+ /* it request implicitly to generate a restart condition */
+ /* set XferOptions to I2C_FIRST_FRAME */
+ if (hi2c->XferOptions == I2C_OTHER_FRAME)
+ {
+ hi2c->XferOptions = I2C_FIRST_FRAME;
+ }
+ /* else if user set XferOptions to I2C_OTHER_AND_LAST_FRAME */
+ /* it request implicitly to generate a restart condition */
+ /* then generate a stop condition at the end of transfer */
+ /* set XferOptions to I2C_FIRST_AND_LAST_FRAME */
+ else if (hi2c->XferOptions == I2C_OTHER_AND_LAST_FRAME)
+ {
+ hi2c->XferOptions = I2C_FIRST_AND_LAST_FRAME;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_I2C_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
new file mode 100644
index 0000000..cca5a57
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
@@ -0,0 +1,4019 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_spi.c
+ * @author MCD Application Team
+ * @brief SPI HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Serial Peripheral Interface (SPI) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The SPI HAL driver can be used as follows:
+
+ (#) Declare a SPI_HandleTypeDef handle structure, for example:
+ SPI_HandleTypeDef hspi;
+
+ (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
+ (##) Enable the SPIx interface clock
+ (##) SPI pins configuration
+ (+++) Enable the clock for the SPI GPIOs
+ (+++) Configure these SPI pins as alternate function push-pull
+ (##) NVIC configuration if you need to use interrupt process
+ (+++) Configure the SPIx interrupt priority
+ (+++) Enable the NVIC SPI IRQ handle
+ (##) DMA Configuration if you need to use DMA process
+ (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel
+ (+++) Enable the DMAx clock
+ (+++) Configure the DMA handle parameters
+ (+++) Configure the DMA Tx or Rx Stream/Channel
+ (+++) Associate the initialized hdma_tx(or _rx) handle to the hspi DMA Tx or Rx handle
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream/Channel
+
+ (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
+ management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
+
+ (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
+ (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
+ by calling the customized HAL_SPI_MspInit() API.
+ [..]
+ Circular mode restriction:
+ (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
+ (##) Master 2Lines RxOnly
+ (##) Master 1Line Rx
+ (#) The CRC feature is not managed when the DMA circular mode is enabled
+ (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
+ the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
+ [..]
+ Master Receive mode restriction:
+ (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=1) or
+ bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI
+ does not initiate a new transfer the following procedure has to be respected:
+ (##) HAL_SPI_DeInit()
+ (##) HAL_SPI_Init()
+ [..]
+ Callback registration:
+
+ (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1U
+ allows the user to configure dynamically the driver callbacks.
+ Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback.
+
+ Function HAL_SPI_RegisterCallback() allows to register following callbacks:
+ (++) TxCpltCallback : SPI Tx Completed callback
+ (++) RxCpltCallback : SPI Rx Completed callback
+ (++) TxRxCpltCallback : SPI TxRx Completed callback
+ (++) TxHalfCpltCallback : SPI Tx Half Completed callback
+ (++) RxHalfCpltCallback : SPI Rx Half Completed callback
+ (++) TxRxHalfCpltCallback : SPI TxRx Half Completed callback
+ (++) ErrorCallback : SPI Error callback
+ (++) AbortCpltCallback : SPI Abort callback
+ (++) MspInitCallback : SPI Msp Init callback
+ (++) MspDeInitCallback : SPI 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 HAL_SPI_UnRegisterCallback to reset a callback to the default
+ weak function.
+ HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (++) TxCpltCallback : SPI Tx Completed callback
+ (++) RxCpltCallback : SPI Rx Completed callback
+ (++) TxRxCpltCallback : SPI TxRx Completed callback
+ (++) TxHalfCpltCallback : SPI Tx Half Completed callback
+ (++) RxHalfCpltCallback : SPI Rx Half Completed callback
+ (++) TxRxHalfCpltCallback : SPI TxRx Half Completed callback
+ (++) ErrorCallback : SPI Error callback
+ (++) AbortCpltCallback : SPI Abort callback
+ (++) MspInitCallback : SPI Msp Init callback
+ (++) MspDeInitCallback : SPI Msp DeInit callback
+
+ [..]
+ By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET
+ all callbacks are set to the corresponding weak functions:
+ examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are
+ reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when
+ these callbacks are null (not registered beforehand).
+ If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
+
+ [..]
+ Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only.
+ Exception done MspInit/MspDeInit functions that can be registered/unregistered
+ in HAL_SPI_STATE_READY or HAL_SPI_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 HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit()
+ or HAL_SPI_Init() function.
+
+ [..]
+ When the compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registering feature is not available
+ and weak (surcharged) callbacks are used.
+
+ [..]
+ Using the HAL it is not possible to reach all supported SPI frequency with the different SPI Modes,
+ the following table resume the max SPI frequency reached with data size 8bits/16bits,
+ according to frequency of the APBx Peripheral Clock (fPCLK) used by the SPI instance.
+
+ @endverbatim
+
+ Additional table :
+
+ DataSize = SPI_DATASIZE_8BIT:
+ +----------------------------------------------------------------------------------------------+
+ | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
+ | Process | Transfer mode |---------------------|----------------------|----------------------|
+ | | | Master | Slave | Master | Slave | Master | Slave |
+ |==============================================================================================|
+ | T | Polling | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA |
+ | X |----------------|----------|----------|-----------|----------|-----------|----------|
+ | / | Interrupt | Fpclk/4 | Fpclk/8 | NA | NA | NA | NA |
+ | R |----------------|----------|----------|-----------|----------|-----------|----------|
+ | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA |
+ |=========|================|==========|==========|===========|==========|===========|==========|
+ | | Polling | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 |
+ | |----------------|----------|----------|-----------|----------|-----------|----------|
+ | R | Interrupt | Fpclk/8 | Fpclk/8 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 |
+ | X |----------------|----------|----------|-----------|----------|-----------|----------|
+ | | DMA | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/128 | Fpclk/2 |
+ |=========|================|==========|==========|===========|==========|===========|==========|
+ | | Polling | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/2 | Fpclk/64 |
+ | |----------------|----------|----------|-----------|----------|-----------|----------|
+ | T | Interrupt | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/2 | Fpclk/64 |
+ | X |----------------|----------|----------|-----------|----------|-----------|----------|
+ | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/128|
+ +----------------------------------------------------------------------------------------------+
+
+ DataSize = SPI_DATASIZE_16BIT:
+ +----------------------------------------------------------------------------------------------+
+ | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
+ | Process | Transfer mode |---------------------|----------------------|----------------------|
+ | | | Master | Slave | Master | Slave | Master | Slave |
+ |==============================================================================================|
+ | T | Polling | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA |
+ | X |----------------|----------|----------|-----------|----------|-----------|----------|
+ | / | Interrupt | Fpclk/4 | Fpclk/4 | NA | NA | NA | NA |
+ | R |----------------|----------|----------|-----------|----------|-----------|----------|
+ | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA |
+ |=========|================|==========|==========|===========|==========|===========|==========|
+ | | Polling | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/32 | Fpclk/2 |
+ | |----------------|----------|----------|-----------|----------|-----------|----------|
+ | R | Interrupt | Fpclk/4 | Fpclk/4 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 |
+ | X |----------------|----------|----------|-----------|----------|-----------|----------|
+ | | DMA | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/128 | Fpclk/2 |
+ |=========|================|==========|==========|===========|==========|===========|==========|
+ | | Polling | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/32 |
+ | |----------------|----------|----------|-----------|----------|-----------|----------|
+ | T | Interrupt | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/64 |
+ | X |----------------|----------|----------|-----------|----------|-----------|----------|
+ | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/128|
+ +----------------------------------------------------------------------------------------------+
+ @note The max SPI frequency depend on SPI data size (8bits, 16bits),
+ SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).
+ @note
+ (#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA()
+ (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()
+ (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA()
+
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup SPI SPI
+ * @brief SPI HAL module driver
+ * @{
+ */
+#ifdef HAL_SPI_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+#if (USE_SPI_CRC != 0U) && defined(SPI_CRC_ERROR_WORKAROUND_FEATURE)
+/* CRC WORKAROUND FEATURE: Variable used to determine if device is impacted by implementation
+ * of workaround related to wrong CRC errors detection on SPI2. Conditions in which this workaround
+ * has to be applied, are:
+ * - STM32F101CDE/STM32F103CDE
+ * - Revision ID : Z
+ * - SPI2
+ * - In receive only mode, with CRC calculation enabled, at the end of the CRC reception,
+ * the software needs to check the CRCERR flag. If it is found set, read back the SPI_RXCRC:
+ * + If the value is 0, the complete data transfer is successful.
+ * + Otherwise, one or more errors have been detected during the data transfer by CPU or DMA.
+ * If CRCERR is found reset, the complete data transfer is considered successful.
+ *
+ * Check RevisionID value for identifying if Device is Rev Z (0x0001) in order to enable workaround for
+ * CRC errors wrongly detected
+ */
+/* Pb is that ES_STM32F10xxCDE also identify an issue in Debug registers access while not in Debug mode
+ * Revision ID information is only available in Debug mode, so Workaround could not be implemented
+ * to distinguish Rev Z devices (issue present) from more recent version (issue fixed).
+ * So, in case of Revision Z F101 or F103 devices, below define should be assigned to 1.
+ */
+#define USE_SPI_CRC_ERROR_WORKAROUND 0U
+#endif /* USE_SPI_CRC */
+/** @defgroup SPI_Private_Constants SPI Private Constants
+ * @{
+ */
+#define SPI_DEFAULT_TIMEOUT 100U
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup SPI_Private_Functions SPI Private Functions
+ * @{
+ */
+static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAError(DMA_HandleTypeDef *hdma);
+static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State,
+ uint32_t Timeout, uint32_t Tickstart);
+static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
+#if (USE_SPI_CRC != 0U)
+static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
+static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
+#endif /* USE_SPI_CRC */
+static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi);
+static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi);
+static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup SPI_Exported_Functions SPI Exported Functions
+ * @{
+ */
+
+/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to initialize and
+ de-initialize the SPIx peripheral:
+
+ (+) User must implement HAL_SPI_MspInit() function in which he configures
+ all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
+
+ (+) Call the function HAL_SPI_Init() to configure the selected device with
+ the selected configuration:
+ (++) Mode
+ (++) Direction
+ (++) Data Size
+ (++) Clock Polarity and Phase
+ (++) NSS Management
+ (++) BaudRate Prescaler
+ (++) FirstBit
+ (++) TIMode
+ (++) CRC Calculation
+ (++) CRC Polynomial if CRC enabled
+
+ (+) Call the function HAL_SPI_DeInit() to restore the default configuration
+ of the selected SPIx peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initialize the SPI according to the specified parameters
+ * in the SPI_InitTypeDef and initialize the associated handle.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
+{
+ /* Check the SPI handle allocation */
+ if (hspi == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
+ assert_param(IS_SPI_MODE(hspi->Init.Mode));
+ assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
+ assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
+ assert_param(IS_SPI_NSS(hspi->Init.NSS));
+ assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
+ assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
+ /* TI mode is not supported on this device.
+ TIMode parameter is mandatory equal to SPI_TIMODE_DISABLE */
+ assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
+ if (hspi->Init.TIMode == SPI_TIMODE_DISABLE)
+ {
+ assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
+ assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
+
+ if (hspi->Init.Mode == SPI_MODE_MASTER)
+ {
+ assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
+ }
+ else
+ {
+ /* Baudrate prescaler not use in Motoraola Slave mode. force to default value */
+ hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
+ }
+ }
+ else
+ {
+ assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
+
+ /* Force polarity and phase to TI protocaol requirements */
+ hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
+ hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
+ }
+#if (USE_SPI_CRC != 0U)
+ assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
+ }
+#else
+ hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+#endif /* USE_SPI_CRC */
+
+ if (hspi->State == HAL_SPI_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hspi->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ /* Init the SPI Callback settings */
+ hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
+ hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
+ hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */
+ hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+
+ if (hspi->MspInitCallback == NULL)
+ {
+ hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
+ }
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ hspi->MspInitCallback(hspi);
+#else
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ HAL_SPI_MspInit(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+
+ hspi->State = HAL_SPI_STATE_BUSY;
+
+ /* Disable the selected SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
+ /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
+ Communication speed, First bit and CRC calculation state */
+ WRITE_REG(hspi->Instance->CR1, ((hspi->Init.Mode & (SPI_CR1_MSTR | SPI_CR1_SSI)) |
+ (hspi->Init.Direction & (SPI_CR1_RXONLY | SPI_CR1_BIDIMODE)) |
+ (hspi->Init.DataSize & SPI_CR1_DFF) |
+ (hspi->Init.CLKPolarity & SPI_CR1_CPOL) |
+ (hspi->Init.CLKPhase & SPI_CR1_CPHA) |
+ (hspi->Init.NSS & SPI_CR1_SSM) |
+ (hspi->Init.BaudRatePrescaler & SPI_CR1_BR_Msk) |
+ (hspi->Init.FirstBit & SPI_CR1_LSBFIRST) |
+ (hspi->Init.CRCCalculation & SPI_CR1_CRCEN)));
+
+ /* Configure : NSS management */
+ WRITE_REG(hspi->Instance->CR2, ((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE));
+
+#if (USE_SPI_CRC != 0U)
+ /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
+ /* Configure : CRC Polynomial */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ WRITE_REG(hspi->Instance->CRCPR, (hspi->Init.CRCPolynomial & SPI_CRCPR_CRCPOLY_Msk));
+ }
+#endif /* USE_SPI_CRC */
+
+#if defined(SPI_I2SCFGR_I2SMOD)
+ /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
+ CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
+#endif /* SPI_I2SCFGR_I2SMOD */
+
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->State = HAL_SPI_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-Initialize the SPI peripheral.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
+{
+ /* Check the SPI handle allocation */
+ if (hspi == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check SPI Instance parameter */
+ assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
+
+ hspi->State = HAL_SPI_STATE_BUSY;
+
+ /* Disable the SPI Peripheral Clock */
+ __HAL_SPI_DISABLE(hspi);
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ if (hspi->MspDeInitCallback == NULL)
+ {
+ hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
+ }
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+ hspi->MspDeInitCallback(hspi);
+#else
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+ HAL_SPI_MspDeInit(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->State = HAL_SPI_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initialize the SPI MSP.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_MspInit should be implemented in the user file
+ */
+}
+
+/**
+ * @brief De-Initialize the SPI MSP.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_MspDeInit should be implemented in the user file
+ */
+}
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+/**
+ * @brief Register a User SPI Callback
+ * To be used instead of the weak predefined callback
+ * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI.
+ * @param CallbackID ID of the callback to be registered
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
+ pSPI_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(hspi);
+
+ if (HAL_SPI_STATE_READY == hspi->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SPI_TX_COMPLETE_CB_ID :
+ hspi->TxCpltCallback = pCallback;
+ break;
+
+ case HAL_SPI_RX_COMPLETE_CB_ID :
+ hspi->RxCpltCallback = pCallback;
+ break;
+
+ case HAL_SPI_TX_RX_COMPLETE_CB_ID :
+ hspi->TxRxCpltCallback = pCallback;
+ break;
+
+ case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
+ hspi->TxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
+ hspi->RxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
+ hspi->TxRxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_SPI_ERROR_CB_ID :
+ hspi->ErrorCallback = pCallback;
+ break;
+
+ case HAL_SPI_ABORT_CB_ID :
+ hspi->AbortCpltCallback = pCallback;
+ break;
+
+ case HAL_SPI_MSPINIT_CB_ID :
+ hspi->MspInitCallback = pCallback;
+ break;
+
+ case HAL_SPI_MSPDEINIT_CB_ID :
+ hspi->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_SPI_STATE_RESET == hspi->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SPI_MSPINIT_CB_ID :
+ hspi->MspInitCallback = pCallback;
+ break;
+
+ case HAL_SPI_MSPDEINIT_CB_ID :
+ hspi->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hspi);
+ return status;
+}
+
+/**
+ * @brief Unregister an SPI Callback
+ * SPI callback is redirected to the weak predefined callback
+ * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI.
+ * @param CallbackID ID of the callback to be unregistered
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hspi);
+
+ if (HAL_SPI_STATE_READY == hspi->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SPI_TX_COMPLETE_CB_ID :
+ hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ break;
+
+ case HAL_SPI_RX_COMPLETE_CB_ID :
+ hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ break;
+
+ case HAL_SPI_TX_RX_COMPLETE_CB_ID :
+ hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
+ break;
+
+ case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
+ hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ break;
+
+ case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
+ hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ break;
+
+ case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
+ hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
+ break;
+
+ case HAL_SPI_ERROR_CB_ID :
+ hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_SPI_ABORT_CB_ID :
+ hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ break;
+
+ case HAL_SPI_MSPINIT_CB_ID :
+ hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_SPI_MSPDEINIT_CB_ID :
+ hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_SPI_STATE_RESET == hspi->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_SPI_MSPINIT_CB_ID :
+ hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_SPI_MSPDEINIT_CB_ID :
+ hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hspi);
+ return status;
+}
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Exported_Functions_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the SPI
+ data transfers.
+
+ [..] The SPI supports master and slave mode :
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) No-Blocking mode: The communication is performed using Interrupts
+ or DMA, These APIs return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or Receive process
+ The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
+
+ (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
+ exist for 1Line (simplex) and 2Lines (full duplex) modes.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmit an amount of data in blocking mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData pointer to data buffer
+ * @param Size amount of data to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tickstart;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+ uint16_t initial_TxXferCount;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+ initial_TxXferCount = Size;
+
+ if (hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_TX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->pRxBuffPtr = (uint8_t *)NULL;
+ hspi->RxXferSize = 0U;
+ hspi->RxXferCount = 0U;
+ hspi->TxISR = NULL;
+ hspi->RxISR = NULL;
+
+ /* Configure communication direction : 1Line */
+ if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
+ __HAL_SPI_DISABLE(hspi);
+ SPI_1LINE_TX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Transmit data in 16 Bit mode */
+ if (hspi->Init.DataSize == SPI_DATASIZE_16BIT)
+ {
+ if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
+ {
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ }
+ /* Transmit data in 16 Bit mode */
+ while (hspi->TxXferCount > 0U)
+ {
+ /* Wait until TXE flag is set to send data */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
+ {
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+ {
+ errorcode = HAL_TIMEOUT;
+ hspi->State = HAL_SPI_STATE_READY;
+ goto error;
+ }
+ }
+ }
+ }
+ /* Transmit data in 8 Bit mode */
+ else
+ {
+ if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
+ {
+ *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint8_t);
+ hspi->TxXferCount--;
+ }
+ while (hspi->TxXferCount > 0U)
+ {
+ /* Wait until TXE flag is set to send data */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
+ {
+ *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint8_t);
+ hspi->TxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+ {
+ errorcode = HAL_TIMEOUT;
+ hspi->State = HAL_SPI_STATE_READY;
+ goto error;
+ }
+ }
+ }
+ }
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK)
+ {
+ hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ errorcode = HAL_ERROR;
+ }
+ else
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ }
+
+error:
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData pointer to data buffer
+ * @param Size amount of data to be received
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+#if (USE_SPI_CRC != 0U)
+ __IO uint32_t tmpreg = 0U;
+#endif /* USE_SPI_CRC */
+ uint32_t tickstart;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ if (hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
+ return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->pTxBuffPtr = (uint8_t *)NULL;
+ hspi->TxXferSize = 0U;
+ hspi->TxXferCount = 0U;
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ /* this is done to handle the CRCNEXT before the latest data */
+ hspi->RxXferCount--;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Configure communication direction: 1Line */
+ if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
+ __HAL_SPI_DISABLE(hspi);
+ SPI_1LINE_RX(hspi);
+ }
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Receive data in 8 Bit mode */
+ if (hspi->Init.DataSize == SPI_DATASIZE_8BIT)
+ {
+ /* Transfer loop */
+ while (hspi->RxXferCount > 0U)
+ {
+ /* Check the RXNE flag */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
+ {
+ /* read the received data */
+ (* (uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR;
+ hspi->pRxBuffPtr += sizeof(uint8_t);
+ hspi->RxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+ {
+ errorcode = HAL_TIMEOUT;
+ hspi->State = HAL_SPI_STATE_READY;
+ goto error;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Transfer loop */
+ while (hspi->RxXferCount > 0U)
+ {
+ /* Check the RXNE flag */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
+ {
+ *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
+ hspi->pRxBuffPtr += sizeof(uint16_t);
+ hspi->RxXferCount--;
+ }
+ else
+ {
+ /* Timeout management */
+ if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+ {
+ errorcode = HAL_TIMEOUT;
+ hspi->State = HAL_SPI_STATE_READY;
+ goto error;
+ }
+ }
+ }
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Handle the CRC Transmission */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* freeze the CRC before the latest data */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+
+ /* Check if CRCNEXT is well reset by hardware */
+ if (READ_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT))
+ {
+ /* Workaround to force CRCNEXT bit to zero in case of CRCNEXT is not reset automatically by hardware */
+ CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+ /* Read the latest data */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ /* the latest data has not been received */
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+
+ /* Receive last data in 16 Bit mode */
+ if (hspi->Init.DataSize == SPI_DATASIZE_16BIT)
+ {
+ *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
+ }
+ /* Receive last data in 8 Bit mode */
+ else
+ {
+ (*(uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR;
+ }
+
+ /* Wait the CRC data */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+
+ /* Read CRC to Flush DR and RXNE flag */
+ tmpreg = READ_REG(hspi->Instance->DR);
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTransaction(hspi, Timeout, tickstart) != HAL_OK)
+ {
+ hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ errorcode = HAL_ERROR;
+ }
+ else
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ }
+
+error :
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit and Receive an amount of data in blocking mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pTxData pointer to transmission data buffer
+ * @param pRxData pointer to reception data buffer
+ * @param Size amount of data to be sent and received
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,
+ uint32_t Timeout)
+{
+ uint16_t initial_TxXferCount;
+ uint32_t tmp_mode;
+ HAL_SPI_StateTypeDef tmp_state;
+ uint32_t tickstart;
+#if (USE_SPI_CRC != 0U)
+ __IO uint32_t tmpreg = 0U;
+#endif /* USE_SPI_CRC */
+
+ /* Variable used to alternate Rx and Tx during transfer */
+ uint32_t txallowed = 1U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ /* Init temporary variables */
+ tmp_state = hspi->State;
+ tmp_mode = hspi->Init.Mode;
+ initial_TxXferCount = Size;
+
+ if (!((tmp_state == HAL_SPI_STATE_READY) || \
+ ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
+ if (hspi->State != HAL_SPI_STATE_BUSY_RX)
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
+ }
+
+ /* Set the transaction information */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pRxData;
+ hspi->RxXferCount = Size;
+ hspi->RxXferSize = Size;
+ hspi->pTxBuffPtr = (uint8_t *)pTxData;
+ hspi->TxXferCount = Size;
+ hspi->TxXferSize = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Transmit and Receive data in 16 Bit mode */
+ if (hspi->Init.DataSize == SPI_DATASIZE_16BIT)
+ {
+ if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
+ {
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ }
+ while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
+ {
+ /* Check TXE flag */
+ if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U))
+ {
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+ /* Next Data is a reception (Rx). Tx not allowed */
+ txallowed = 0U;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ }
+
+ /* Check RXNE flag */
+ if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U))
+ {
+ *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
+ hspi->pRxBuffPtr += sizeof(uint16_t);
+ hspi->RxXferCount--;
+ /* Next Data is a Transmission (Tx). Tx is allowed */
+ txallowed = 1U;
+ }
+ if (((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY))
+ {
+ errorcode = HAL_TIMEOUT;
+ hspi->State = HAL_SPI_STATE_READY;
+ goto error;
+ }
+ }
+ }
+ /* Transmit and Receive data in 8 Bit mode */
+ else
+ {
+ if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
+ {
+ *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint8_t);
+ hspi->TxXferCount--;
+ }
+ while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
+ {
+ /* Check TXE flag */
+ if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U))
+ {
+ *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr++;
+ hspi->TxXferCount--;
+ /* Next Data is a reception (Rx). Tx not allowed */
+ txallowed = 0U;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ }
+
+ /* Wait until RXNE flag is reset */
+ if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U))
+ {
+ (*(uint8_t *)hspi->pRxBuffPtr) = hspi->Instance->DR;
+ hspi->pRxBuffPtr++;
+ hspi->RxXferCount--;
+ /* Next Data is a Transmission (Tx). Tx is allowed */
+ txallowed = 1U;
+ }
+ if ((((HAL_GetTick() - tickstart) >= Timeout) && ((Timeout != HAL_MAX_DELAY))) || (Timeout == 0U))
+ {
+ errorcode = HAL_TIMEOUT;
+ hspi->State = HAL_SPI_STATE_READY;
+ goto error;
+ }
+ }
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Read CRC from DR to close CRC calculation process */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Wait until TXE flag */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
+ {
+ /* Error on the CRC reception */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ errorcode = HAL_TIMEOUT;
+ goto error;
+ }
+ /* Read CRC */
+ tmpreg = READ_REG(hspi->Instance->DR);
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+ }
+
+ /* Check if CRC error occurred */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+
+ errorcode = HAL_ERROR;
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK)
+ {
+ errorcode = HAL_ERROR;
+ hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
+ goto error;
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ errorcode = HAL_ERROR;
+ }
+ else
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ }
+
+error :
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with Interrupt.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData pointer to data buffer
+ * @param Size amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ if (hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_TX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->pRxBuffPtr = (uint8_t *)NULL;
+ hspi->RxXferSize = 0U;
+ hspi->RxXferCount = 0U;
+ hspi->RxISR = NULL;
+
+ /* Set the function for IT treatment */
+ if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+ {
+ hspi->TxISR = SPI_TxISR_16BIT;
+ }
+ else
+ {
+ hspi->TxISR = SPI_TxISR_8BIT;
+ }
+
+ /* Configure communication direction : 1Line */
+ if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
+ __HAL_SPI_DISABLE(hspi);
+ SPI_1LINE_TX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Enable TXE and ERR interrupt */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
+
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+error :
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with Interrupt.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData pointer to data buffer
+ * @param Size amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+
+ if (hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
+ return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->pTxBuffPtr = (uint8_t *)NULL;
+ hspi->TxXferSize = 0U;
+ hspi->TxXferCount = 0U;
+ hspi->TxISR = NULL;
+
+ /* Set the function for IT treatment */
+ if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+ {
+ hspi->RxISR = SPI_RxISR_16BIT;
+ }
+ else
+ {
+ hspi->RxISR = SPI_RxISR_8BIT;
+ }
+
+ /* Configure communication direction : 1Line */
+ if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
+ __HAL_SPI_DISABLE(hspi);
+ SPI_1LINE_RX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Enable TXE and ERR interrupt */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ /* Note : The SPI must be enabled after unlocking current process
+ to avoid the risk of SPI interrupt handle execution before current
+ process unlock */
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pTxData pointer to transmission data buffer
+ * @param pRxData pointer to reception data buffer
+ * @param Size amount of data to be sent and received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
+{
+ uint32_t tmp_mode;
+ HAL_SPI_StateTypeDef tmp_state;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+ /* Process locked */
+ __HAL_LOCK(hspi);
+
+ /* Init temporary variables */
+ tmp_state = hspi->State;
+ tmp_mode = hspi->Init.Mode;
+
+ if (!((tmp_state == HAL_SPI_STATE_READY) || \
+ ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
+ if (hspi->State != HAL_SPI_STATE_BUSY_RX)
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
+ }
+
+ /* Set the transaction information */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pTxData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+ hspi->pRxBuffPtr = (uint8_t *)pRxData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /* Set the function for IT treatment */
+ if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+ {
+ hspi->RxISR = SPI_2linesRxISR_16BIT;
+ hspi->TxISR = SPI_2linesTxISR_16BIT;
+ }
+ else
+ {
+ hspi->RxISR = SPI_2linesRxISR_8BIT;
+ hspi->TxISR = SPI_2linesTxISR_8BIT;
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Enable TXE, RXNE and ERR interrupt */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with DMA.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData pointer to data buffer
+ * @param Size amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check tx dma handle */
+ assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if (hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_TX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->pRxBuffPtr = (uint8_t *)NULL;
+ hspi->TxISR = NULL;
+ hspi->RxISR = NULL;
+ hspi->RxXferSize = 0U;
+ hspi->RxXferCount = 0U;
+
+ /* Configure communication direction : 1Line */
+ if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
+ __HAL_SPI_DISABLE(hspi);
+ SPI_1LINE_TX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Set the SPI TxDMA Half transfer complete callback */
+ hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
+
+ /* Set the SPI TxDMA transfer complete callback */
+ hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
+
+ /* Set the DMA error callback */
+ hspi->hdmatx->XferErrorCallback = SPI_DMAError;
+
+ /* Set the DMA AbortCpltCallback */
+ hspi->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the Tx DMA Stream/Channel */
+ if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR,
+ hspi->TxXferCount))
+ {
+ /* Update SPI error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ errorcode = HAL_ERROR;
+
+ goto error;
+ }
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Enable the SPI Error Interrupt Bit */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
+
+ /* Enable Tx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with DMA.
+ * @note In case of MASTER mode and SPI_DIRECTION_2LINES direction, hdmatx shall be defined.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pData pointer to data buffer
+ * @note When the CRC feature is enabled the pData Length must be Size + 1.
+ * @param Size amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check rx dma handle */
+ assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
+
+ if (hspi->State != HAL_SPI_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+
+ /* Check tx dma handle */
+ assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
+
+ /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
+ return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Set the transaction information */
+ hspi->State = HAL_SPI_STATE_BUSY_RX;
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pRxBuffPtr = (uint8_t *)pData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /*Init field not used in handle to zero */
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+ hspi->TxXferSize = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Configure communication direction : 1Line */
+ if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ {
+ /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
+ __HAL_SPI_DISABLE(hspi);
+ SPI_1LINE_RX(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Set the SPI RxDMA Half transfer complete callback */
+ hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
+
+ /* Set the SPI Rx DMA transfer complete callback */
+ hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
+
+ /* Set the DMA error callback */
+ hspi->hdmarx->XferErrorCallback = SPI_DMAError;
+
+ /* Set the DMA AbortCpltCallback */
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the Rx DMA Stream/Channel */
+ if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr,
+ hspi->RxXferCount))
+ {
+ /* Update SPI error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ errorcode = HAL_ERROR;
+
+ goto error;
+ }
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+
+ /* Enable the SPI Error Interrupt Bit */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
+
+ /* Enable Rx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
+
+error:
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Transmit and Receive an amount of data in non-blocking mode with DMA.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param pTxData pointer to transmission data buffer
+ * @param pRxData pointer to reception data buffer
+ * @note When the CRC feature is enabled the pRxData Length must be Size + 1
+ * @param Size amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,
+ uint16_t Size)
+{
+ uint32_t tmp_mode;
+ HAL_SPI_StateTypeDef tmp_state;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ /* Check rx & tx dma handles */
+ assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
+ assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
+
+ /* Check Direction parameter */
+ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+ /* Process locked */
+ __HAL_LOCK(hspi);
+
+ /* Init temporary variables */
+ tmp_state = hspi->State;
+ tmp_mode = hspi->Init.Mode;
+
+ if (!((tmp_state == HAL_SPI_STATE_READY) ||
+ ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+
+ /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
+ if (hspi->State != HAL_SPI_STATE_BUSY_RX)
+ {
+ hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
+ }
+
+ /* Set the transaction information */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ hspi->pTxBuffPtr = (uint8_t *)pTxData;
+ hspi->TxXferSize = Size;
+ hspi->TxXferCount = Size;
+ hspi->pRxBuffPtr = (uint8_t *)pRxData;
+ hspi->RxXferSize = Size;
+ hspi->RxXferCount = Size;
+
+ /* Init field not used in handle to zero */
+ hspi->RxISR = NULL;
+ hspi->TxISR = NULL;
+
+#if (USE_SPI_CRC != 0U)
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
+ if (hspi->State == HAL_SPI_STATE_BUSY_RX)
+ {
+ /* Set the SPI Rx DMA Half transfer complete callback */
+ hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
+ hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
+ }
+ else
+ {
+ /* Set the SPI Tx/Rx DMA Half transfer complete callback */
+ hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
+ hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
+ }
+
+ /* Set the DMA error callback */
+ hspi->hdmarx->XferErrorCallback = SPI_DMAError;
+
+ /* Set the DMA AbortCpltCallback */
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the Rx DMA Stream/Channel */
+ if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr,
+ hspi->RxXferCount))
+ {
+ /* Update SPI error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ errorcode = HAL_ERROR;
+
+ goto error;
+ }
+
+ /* Enable Rx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
+
+ /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
+ is performed in DMA reception complete callback */
+ hspi->hdmatx->XferHalfCpltCallback = NULL;
+ hspi->hdmatx->XferCpltCallback = NULL;
+ hspi->hdmatx->XferErrorCallback = NULL;
+ hspi->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the Tx DMA Stream/Channel */
+ if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR,
+ hspi->TxXferCount))
+ {
+ /* Update SPI error code */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ errorcode = HAL_ERROR;
+
+ goto error;
+ }
+
+ /* Check if the SPI is already enabled */
+ if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
+ {
+ /* Enable SPI peripheral */
+ __HAL_SPI_ENABLE(hspi);
+ }
+ /* Enable the SPI Error Interrupt Bit */
+ __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
+
+ /* Enable Tx DMA Request */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
+
+error :
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+ return errorcode;
+}
+
+/**
+ * @brief Abort ongoing transfer (blocking mode).
+ * @param hspi SPI handle.
+ * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
+ * started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable SPI Interrupts (depending of transfer direction)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
+{
+ HAL_StatusTypeDef errorcode;
+ __IO uint32_t count;
+ __IO uint32_t resetcount;
+
+ /* Initialized local variable */
+ errorcode = HAL_OK;
+ resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+ count = resetcount;
+
+ /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
+
+ /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
+ {
+ hspi->TxISR = SPI_AbortTx_ISR;
+ /* Wait HAL_SPI_STATE_ABORT state */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ break;
+ }
+ count--;
+ } while (hspi->State != HAL_SPI_STATE_ABORT);
+ /* Reset Timeout Counter */
+ count = resetcount;
+ }
+
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
+ {
+ hspi->RxISR = SPI_AbortRx_ISR;
+ /* Wait HAL_SPI_STATE_ABORT state */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ break;
+ }
+ count--;
+ } while (hspi->State != HAL_SPI_STATE_ABORT);
+ /* Reset Timeout Counter */
+ count = resetcount;
+ }
+
+ /* Disable the SPI DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
+ {
+ /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */
+ if (hspi->hdmatx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
+ hspi->hdmatx->XferAbortCallback = NULL;
+
+ /* Abort DMA Tx Handle linked to SPI Peripheral */
+ if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK)
+ {
+ hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
+ }
+
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN));
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ break;
+ }
+ count--;
+ } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+ }
+ }
+
+ /* Disable the SPI DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
+ {
+ /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */
+ if (hspi->hdmarx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Abort DMA Rx Handle linked to SPI Peripheral */
+ if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK)
+ {
+ hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
+ }
+
+ /* Disable peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ /* Disable Rx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN));
+ }
+ }
+ /* Reset Tx and Rx transfer counters */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Check error during Abort procedure */
+ if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT)
+ {
+ /* return HAL_Error in case of error during Abort procedure */
+ errorcode = HAL_ERROR;
+ }
+ else
+ {
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ }
+
+ /* Clear the Error flags in the SR register */
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+
+ /* Restore hspi->state to ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ return errorcode;
+}
+
+/**
+ * @brief Abort ongoing transfer (Interrupt mode).
+ * @param hspi SPI handle.
+ * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx),
+ * started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable SPI Interrupts (depending of transfer direction)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
+{
+ HAL_StatusTypeDef errorcode;
+ uint32_t abortcplt ;
+ __IO uint32_t count;
+ __IO uint32_t resetcount;
+
+ /* Initialized local variable */
+ errorcode = HAL_OK;
+ abortcplt = 1U;
+ resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+ count = resetcount;
+
+ /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
+
+ /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
+ {
+ hspi->TxISR = SPI_AbortTx_ISR;
+ /* Wait HAL_SPI_STATE_ABORT state */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ break;
+ }
+ count--;
+ } while (hspi->State != HAL_SPI_STATE_ABORT);
+ /* Reset Timeout Counter */
+ count = resetcount;
+ }
+
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
+ {
+ hspi->RxISR = SPI_AbortRx_ISR;
+ /* Wait HAL_SPI_STATE_ABORT state */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ break;
+ }
+ count--;
+ } while (hspi->State != HAL_SPI_STATE_ABORT);
+ /* Reset Timeout Counter */
+ count = resetcount;
+ }
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if (hspi->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
+ {
+ hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
+ }
+ else
+ {
+ hspi->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if (hspi->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
+ {
+ hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
+ }
+ else
+ {
+ hspi->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the SPI DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
+ {
+ /* Abort the SPI DMA Tx Stream/Channel */
+ if (hspi->hdmatx != NULL)
+ {
+ /* Abort DMA Tx Handle linked to SPI Peripheral */
+ if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
+ {
+ hspi->hdmatx->XferAbortCallback = NULL;
+ hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
+ }
+ else
+ {
+ abortcplt = 0U;
+ }
+ }
+ }
+ /* Disable the SPI DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
+ {
+ /* Abort the SPI DMA Rx Stream/Channel */
+ if (hspi->hdmarx != NULL)
+ {
+ /* Abort DMA Rx Handle linked to SPI Peripheral */
+ if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK)
+ {
+ hspi->hdmarx->XferAbortCallback = NULL;
+ hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
+ }
+ else
+ {
+ abortcplt = 0U;
+ }
+ }
+ }
+
+ if (abortcplt == 1U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Check error during Abort procedure */
+ if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT)
+ {
+ /* return HAL_Error in case of error during Abort procedure */
+ errorcode = HAL_ERROR;
+ }
+ else
+ {
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ }
+
+ /* Clear the Error flags in the SR register */
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+
+ /* Restore hspi->State to Ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->AbortCpltCallback(hspi);
+#else
+ HAL_SPI_AbortCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+
+ return errorcode;
+}
+
+/**
+ * @brief Pause the DMA Transfer.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
+{
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Disable the SPI DMA Tx & Rx requests */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resume the DMA Transfer.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
+{
+ /* Process Locked */
+ __HAL_LOCK(hspi);
+
+ /* Enable the SPI DMA Tx & Rx requests */
+ SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop the DMA Transfer.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback()
+ */
+
+ /* Abort the SPI DMA tx Stream/Channel */
+ if (hspi->hdmatx != NULL)
+ {
+ if (HAL_OK != HAL_DMA_Abort(hspi->hdmatx))
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ errorcode = HAL_ERROR;
+ }
+ }
+ /* Abort the SPI DMA rx Stream/Channel */
+ if (hspi->hdmarx != NULL)
+ {
+ if (HAL_OK != HAL_DMA_Abort(hspi->hdmarx))
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ errorcode = HAL_ERROR;
+ }
+ }
+
+ /* Disable the SPI DMA Tx & Rx requests */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+ hspi->State = HAL_SPI_STATE_READY;
+ return errorcode;
+}
+
+/**
+ * @brief Handle SPI interrupt request.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for the specified SPI module.
+ * @retval None
+ */
+void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
+{
+ uint32_t itsource = hspi->Instance->CR2;
+ uint32_t itflag = hspi->Instance->SR;
+
+ /* SPI in mode Receiver ----------------------------------------------------*/
+ if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) == RESET) &&
+ (SPI_CHECK_FLAG(itflag, SPI_FLAG_RXNE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_RXNE) != RESET))
+ {
+ hspi->RxISR(hspi);
+ return;
+ }
+
+ /* SPI in mode Transmitter -------------------------------------------------*/
+ if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_TXE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_TXE) != RESET))
+ {
+ hspi->TxISR(hspi);
+ return;
+ }
+
+ /* SPI in Error Treatment --------------------------------------------------*/
+ if (((SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) || (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET))
+ && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_ERR) != RESET))
+ {
+ /* SPI Overrun error interrupt occurred ----------------------------------*/
+ if (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET)
+ {
+ if (hspi->State != HAL_SPI_STATE_BUSY_TX)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ return;
+ }
+ }
+
+ /* SPI Mode Fault error interrupt occurred -------------------------------*/
+ if (SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
+ __HAL_SPI_CLEAR_MODFFLAG(hspi);
+ }
+
+ /* SPI Frame error interrupt occurred ------------------------------------*/
+
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ /* Disable all interrupts */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
+
+ hspi->State = HAL_SPI_STATE_READY;
+ /* Disable the SPI DMA requests if enabled */
+ if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN)))
+ {
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
+
+ /* Abort the SPI DMA Rx channel */
+ if (hspi->hdmarx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
+ hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
+ if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx))
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ }
+ }
+ /* Abort the SPI DMA Tx channel */
+ if (hspi->hdmatx != NULL)
+ {
+ /* Set the SPI DMA Abort callback :
+ will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
+ hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
+ if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx))
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ }
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+ }
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callback.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callback.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_RxCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx and Rx Transfer completed callback.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxRxCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callback.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callback.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx and Rx Half Transfer callback.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
+ */
+}
+
+/**
+ * @brief SPI error callback.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_ErrorCallback should be implemented in the user file
+ */
+ /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
+ and user can use HAL_SPI_GetError() API to check the latest error occurred
+ */
+}
+
+/**
+ * @brief SPI Abort Complete callback.
+ * @param hspi SPI handle.
+ * @retval None
+ */
+__weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_SPI_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief SPI control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the SPI.
+ (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
+ (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the SPI handle state.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval SPI state
+ */
+HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
+{
+ /* Return SPI handle state */
+ return hspi->State;
+}
+
+/**
+ * @brief Return the SPI error code.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval SPI error code in bitmap format
+ */
+uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
+{
+ /* Return SPI ErrorCode */
+ return hspi->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup SPI_Private_Functions
+ * @brief Private functions
+ * @{
+ */
+
+/**
+ * @brief DMA SPI transmit process complete callback.
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+ uint32_t tickstart;
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ /* DMA Normal Mode */
+ if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
+ {
+ /* Disable ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
+
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received data is not read */
+ if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+ hspi->TxXferCount = 0U;
+ hspi->State = HAL_SPI_STATE_READY;
+
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ return;
+ }
+ }
+ /* Call user Tx complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->TxCpltCallback(hspi);
+#else
+ HAL_SPI_TxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI receive process complete callback.
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+ uint32_t tickstart;
+#if (USE_SPI_CRC != 0U)
+ __IO uint32_t tmpreg = 0U;
+#endif /* USE_SPI_CRC */
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ /* DMA Normal Mode */
+ if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
+ {
+ /* Disable ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
+
+#if (USE_SPI_CRC != 0U)
+ /* CRC handling */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Wait until RXNE flag */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ /* Error on the CRC reception */
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ }
+ /* Read CRC */
+ tmpreg = READ_REG(hspi->Instance->DR);
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check if we are in Master RX 2 line mode */
+ if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
+ {
+ /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+ }
+ else
+ {
+ /* Normal case */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
+ }
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
+ }
+
+ hspi->RxXferCount = 0U;
+ hspi->State = HAL_SPI_STATE_READY;
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ return;
+ }
+ }
+ /* Call user Rx complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->RxCpltCallback(hspi);
+#else
+ HAL_SPI_RxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI transmit receive process complete callback.
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+ uint32_t tickstart;
+#if (USE_SPI_CRC != 0U)
+ __IO uint32_t tmpreg = 0U;
+#endif /* USE_SPI_CRC */
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ /* DMA Normal Mode */
+ if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
+ {
+ /* Disable ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
+
+#if (USE_SPI_CRC != 0U)
+ /* CRC handling */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Wait the CRC data */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+ }
+ /* Read CRC to Flush DR and RXNE flag */
+ tmpreg = READ_REG(hspi->Instance->DR);
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Disable Rx/Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ hspi->TxXferCount = 0U;
+ hspi->RxXferCount = 0U;
+ hspi->State = HAL_SPI_STATE_READY;
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+#endif /* USE_SPI_CRC */
+
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ return;
+ }
+ }
+ /* Call user TxRx complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->TxRxCpltCallback(hspi);
+#else
+ HAL_SPI_TxRxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI half transmit process complete callback.
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Call user Tx half complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->TxHalfCpltCallback(hspi);
+#else
+ HAL_SPI_TxHalfCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI half receive process complete callback
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Call user Rx half complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->RxHalfCpltCallback(hspi);
+#else
+ HAL_SPI_RxHalfCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI half transmit receive process complete callback.
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Call user TxRx half complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->TxRxHalfCpltCallback(hspi);
+#else
+ HAL_SPI_TxRxHalfCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI communication error callback.
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void SPI_DMAError(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Stop the disable DMA transfer on SPI side */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
+
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+ hspi->State = HAL_SPI_STATE_READY;
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+ __IO uint32_t count;
+
+ hspi->hdmatx->XferAbortCallback = NULL;
+ count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ break;
+ }
+ count--;
+ } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Check if an Abort process is still ongoing */
+ if (hspi->hdmarx != NULL)
+ {
+ if (hspi->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Check no error during Abort procedure */
+ if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT)
+ {
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ }
+
+ /* Clear the Error flags in the SR register */
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+
+ /* Restore hspi->State to Ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->AbortCpltCallback(hspi);
+#else
+ HAL_SPI_AbortCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA SPI Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma DMA handle.
+ * @retval None
+ */
+static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Disable SPI Peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ hspi->hdmarx->XferAbortCallback = NULL;
+
+ /* Disable Rx DMA Request */
+ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
+
+ /* Check Busy flag */
+ if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ }
+
+ /* Check if an Abort process is still ongoing */
+ if (hspi->hdmatx != NULL)
+ {
+ if (hspi->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */
+ hspi->RxXferCount = 0U;
+ hspi->TxXferCount = 0U;
+
+ /* Check no error during Abort procedure */
+ if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT)
+ {
+ /* Reset errorCode */
+ hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+ }
+
+ /* Clear the Error flags in the SR register */
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+
+ /* Restore hspi->State to Ready */
+ hspi->State = HAL_SPI_STATE_READY;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->AbortCpltCallback(hspi);
+#else
+ HAL_SPI_AbortCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Receive data in 8bit mode */
+ *hspi->pRxBuffPtr = *((__IO uint8_t *)&hspi->Instance->DR);
+ hspi->pRxBuffPtr++;
+ hspi->RxXferCount--;
+
+ /* Check end of the reception */
+ if (hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_2linesRxISR_8BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable RXNE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ if (hspi->TxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ __IO uint8_t *ptmpreg8;
+ __IO uint8_t tmpreg8 = 0;
+
+ /* Initialize the 8bit temporary pointer */
+ ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR;
+ /* Read 8bit CRC to flush Data Register */
+ tmpreg8 = *ptmpreg8;
+ /* To avoid GCC warning */
+ UNUSED(tmpreg8);
+
+ /* Disable RXNE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ if (hspi->TxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr++;
+ hspi->TxXferCount--;
+
+ /* Check the end of the transmission */
+ if (hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Set CRC Next Bit to send CRC */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ /* Disable TXE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable TXE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+
+ if (hspi->RxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+/**
+ * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Receive data in 16 Bit mode */
+ *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR);
+ hspi->pRxBuffPtr += sizeof(uint16_t);
+ hspi->RxXferCount--;
+
+ if (hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_2linesRxISR_16BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable RXNE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
+
+ if (hspi->TxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ __IO uint32_t tmpreg = 0U;
+
+ /* Read 16bit CRC to flush Data Register */
+ tmpreg = READ_REG(hspi->Instance->DR);
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+
+ /* Disable RXNE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
+
+ SPI_CloseRxTx_ISR(hspi);
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Transmit data in 16 Bit mode */
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+
+ /* Enable CRC Transmission */
+ if (hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Set CRC Next Bit to send CRC */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ /* Disable TXE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+ return;
+ }
+#endif /* USE_SPI_CRC */
+
+ /* Disable TXE interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
+
+ if (hspi->RxXferCount == 0U)
+ {
+ SPI_CloseRxTx_ISR(hspi);
+ }
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Manage the CRC 8-bit receive in Interrupt context.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ __IO uint8_t *ptmpreg8;
+ __IO uint8_t tmpreg8 = 0;
+
+ /* Initialize the 8bit temporary pointer */
+ ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR;
+ /* Read 8bit CRC to flush Data Register */
+ tmpreg8 = *ptmpreg8;
+ /* To avoid GCC warning */
+ UNUSED(tmpreg8);
+
+ SPI_CloseRx_ISR(hspi);
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Manage the receive 8-bit in Interrupt context.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *hspi->pRxBuffPtr = (*(__IO uint8_t *)&hspi->Instance->DR);
+ hspi->pRxBuffPtr++;
+ hspi->RxXferCount--;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if ((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+ /* Check if CRCNEXT is well reset by hardware */
+ if (READ_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT))
+ {
+ /* Workaround to force CRCNEXT bit to zero in case of CRCNEXT is not reset automatically by hardware */
+ CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+
+#endif /* USE_SPI_CRC */
+
+ if (hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_RxISR_8BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseRx_ISR(hspi);
+ }
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Manage the CRC 16-bit receive in Interrupt context.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
+{
+ __IO uint32_t tmpreg = 0U;
+
+ /* Read 16bit CRC to flush Data Register */
+ tmpreg = READ_REG(hspi->Instance->DR);
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+
+ /* Disable RXNE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ SPI_CloseRx_ISR(hspi);
+}
+#endif /* USE_SPI_CRC */
+
+/**
+ * @brief Manage the 16-bit receive in Interrupt context.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR);
+ hspi->pRxBuffPtr += sizeof(uint16_t);
+ hspi->RxXferCount--;
+
+#if (USE_SPI_CRC != 0U)
+ /* Enable CRC Transmission */
+ if ((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
+ {
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+ /* Check if CRCNEXT is well reset by hardware */
+ if (READ_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT))
+ {
+ /* Workaround to force CRCNEXT bit to zero in case of CRCNEXT is not reset automatically by hardware */
+ CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+
+#endif /* USE_SPI_CRC */
+
+ if (hspi->RxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ hspi->RxISR = SPI_RxISR_16BITCRC;
+ return;
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseRx_ISR(hspi);
+ }
+}
+
+/**
+ * @brief Handle the data 8-bit transmit in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr++;
+ hspi->TxXferCount--;
+
+ if (hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Enable CRC Transmission */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseTx_ISR(hspi);
+ }
+}
+
+/**
+ * @brief Handle the data 16-bit transmit in Interrupt mode.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
+{
+ /* Transmit data in 16 Bit mode */
+ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
+ hspi->pTxBuffPtr += sizeof(uint16_t);
+ hspi->TxXferCount--;
+
+ if (hspi->TxXferCount == 0U)
+ {
+#if (USE_SPI_CRC != 0U)
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ /* Enable CRC Transmission */
+ SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
+ }
+#endif /* USE_SPI_CRC */
+ SPI_CloseTx_ISR(hspi);
+ }
+}
+
+/**
+ * @brief Handle SPI Communication Timeout.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param Flag SPI flag to check
+ * @param State flag state to check
+ * @param Timeout Timeout duration
+ * @param Tickstart tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State,
+ uint32_t Timeout, uint32_t Tickstart)
+{
+ __IO uint32_t count;
+ uint32_t tmp_timeout;
+ uint32_t tmp_tickstart;
+
+ /* Adjust Timeout value in case of end of transfer */
+ tmp_timeout = Timeout - (HAL_GetTick() - Tickstart);
+ tmp_tickstart = HAL_GetTick();
+
+ /* Calculate Timeout based on a software loop to avoid blocking issue if Systick is disabled */
+ count = tmp_timeout * ((SystemCoreClock * 32U) >> 20U);
+
+ while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State)
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tmp_tickstart) >= tmp_timeout) || (tmp_timeout == 0U))
+ {
+ /* Disable the SPI and reset the CRC: the CRC value should be cleared
+ on both master and slave sides in order to resynchronize the master
+ and slave for their respective CRC calculation */
+
+ /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
+
+ if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
+ {
+ /* Disable SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+ }
+
+ /* Reset CRC Calculation */
+ if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+ {
+ SPI_RESET_CRC(hspi);
+ }
+
+ hspi->State = HAL_SPI_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hspi);
+
+ return HAL_TIMEOUT;
+ }
+ /* If Systick is disabled or not incremented, deactivate timeout to go in disable loop procedure */
+ if (count == 0U)
+ {
+ tmp_timeout = 0U;
+ }
+ count--;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Handle the check of the RX transaction complete.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @param Timeout Timeout duration
+ * @param Tickstart tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
+{
+ if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE)
+ || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
+ {
+ /* Disable SPI peripheral */
+ __HAL_SPI_DISABLE(hspi);
+ }
+
+ if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))
+ {
+ /* Wait the RXNE reset */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ return HAL_TIMEOUT;
+ }
+ }
+ else
+ {
+ /* Control the BSY flag */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ return HAL_TIMEOUT;
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Handle the check of the RXTX or TX transaction complete.
+ * @param hspi SPI handle
+ * @param Timeout Timeout duration
+ * @param Tickstart tick start value
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
+{
+ /* Control the BSY flag */
+ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ return HAL_TIMEOUT;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Handle the end of the RXTX transaction.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi)
+{
+ uint32_t tickstart;
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ /* Disable ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ break;
+ }
+ count--;
+ } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+ else
+ {
+#endif /* USE_SPI_CRC */
+ if (hspi->ErrorCode == HAL_SPI_ERROR_NONE)
+ {
+ if (hspi->State == HAL_SPI_STATE_BUSY_RX)
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ /* Call user Rx complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->RxCpltCallback(hspi);
+#else
+ HAL_SPI_RxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ /* Call user TxRx complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->TxRxCpltCallback(hspi);
+#else
+ HAL_SPI_TxRxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ hspi->State = HAL_SPI_STATE_READY;
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+#if (USE_SPI_CRC != 0U)
+ }
+#endif /* USE_SPI_CRC */
+}
+
+/**
+ * @brief Handle the end of the RX transaction.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi)
+{
+ /* Disable RXNE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+ hspi->State = HAL_SPI_STATE_READY;
+
+#if (USE_SPI_CRC != 0U)
+ /* Check if CRC error occurred */
+ if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
+ {
+ /* Check if CRC error is valid or not (workaround to be applied or not) */
+ if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+
+ /* Reset CRC Calculation */
+ SPI_RESET_CRC(hspi);
+
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+ }
+ }
+ else
+ {
+#endif /* USE_SPI_CRC */
+ if (hspi->ErrorCode == HAL_SPI_ERROR_NONE)
+ {
+ /* Call user Rx complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->RxCpltCallback(hspi);
+#else
+ HAL_SPI_RxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+#if (USE_SPI_CRC != 0U)
+ }
+#endif /* USE_SPI_CRC */
+}
+
+/**
+ * @brief Handle the end of the TX transaction.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi)
+{
+ uint32_t tickstart;
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ break;
+ }
+ count--;
+ } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Disable TXE and ERR interrupt */
+ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
+
+ /* Check the end of the transaction */
+ if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+ }
+
+ /* Clear overrun flag in 2 Lines communication mode because received is not read */
+ if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
+ {
+ __HAL_SPI_CLEAR_OVRFLAG(hspi);
+ }
+
+ hspi->State = HAL_SPI_STATE_READY;
+ if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+ {
+ /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->ErrorCallback(hspi);
+#else
+ HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Call user Rx complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+ hspi->TxCpltCallback(hspi);
+#else
+ HAL_SPI_TxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief Handle abort a Rx transaction.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi)
+{
+ __IO uint32_t tmpreg = 0U;
+ __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
+
+ /* Wait until TXE flag is set */
+ do
+ {
+ if (count == 0U)
+ {
+ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+ break;
+ }
+ count--;
+ } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
+
+ /* Disable SPI Peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
+
+ /* Flush Data Register by a blank read */
+ tmpreg = READ_REG(hspi->Instance->DR);
+ /* To avoid GCC warning */
+ UNUSED(tmpreg);
+
+ hspi->State = HAL_SPI_STATE_ABORT;
+}
+
+/**
+ * @brief Handle abort a Tx or Rx/Tx transaction.
+ * @param hspi pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval None
+ */
+static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi)
+{
+ /* Disable TXEIE interrupt */
+ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE));
+
+ /* Disable SPI Peripheral */
+ __HAL_SPI_DISABLE(hspi);
+
+ hspi->State = HAL_SPI_STATE_ABORT;
+}
+
+#if (USE_SPI_CRC != 0U)
+/**
+ * @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
+ * according to SPI instance, Device type, and revision ID.
+ * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+ * the configuration information for SPI module.
+ * @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
+ */
+uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
+{
+#if defined(SPI_CRC_ERROR_WORKAROUND_FEATURE) && (USE_SPI_CRC_ERROR_WORKAROUND != 0U)
+ /* Check how to handle this CRC error (workaround to be applied or not) */
+ /* If CRC errors could be wrongly detected (issue 2.15.2 in STM32F10xxC/D/E silicon limitations ES (DocID14732 Rev 13) */
+ if (hspi->Instance == SPI2)
+ {
+ if (hspi->Instance->RXCRCR == 0U)
+ {
+ return (SPI_INVALID_CRC_ERROR);
+ }
+ }
+#endif /* USE_SPI_CRC_ERROR_WORKAROUND */
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hspi);
+
+ return (SPI_VALID_CRC_ERROR);
+}
+#endif /* USE_SPI_CRC */
+/**
+ * @}
+ */
+
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
new file mode 100644
index 0000000..db1f087
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
@@ -0,0 +1,3756 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_uart.c
+ * @author MCD Application Team
+ * @brief UART HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The UART HAL driver can be used as follows:
+
+ (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
+ (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
+ (##) Enable the USARTx interface clock.
+ (##) UART pins configuration:
+ (+++) Enable the clock for the UART GPIOs.
+ (+++) Configure the UART TX/RX pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
+ and HAL_UART_Receive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
+ and HAL_UART_Receive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required
+ Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx channel.
+ (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete
+ interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) in the huart Init structure.
+
+ (#) For the UART asynchronous mode, initialize the UART registers by calling
+ the HAL_UART_Init() API.
+
+ (#) For the UART Half duplex mode, initialize the UART registers by calling
+ the HAL_HalfDuplex_Init() API.
+
+ (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
+
+ (#) For the Multi-Processor mode, initialize the UART registers by calling
+ the HAL_MultiProcessor_Init() API.
+
+ [..]
+ (@) The specific UART interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
+ and receive process.
+
+ [..]
+ (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
+ low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized
+ HAL_UART_MspInit() API.
+
+ ##### Callback registration #####
+ ==================================
+
+ [..]
+ The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
+ allows the user to configure dynamically the driver callbacks.
+
+ [..]
+ Use Function HAL_UART_RegisterCallback() to register a user callback.
+ Function HAL_UART_RegisterCallback() allows to register following callbacks:
+ (+) TxHalfCpltCallback : Tx Half Complete Callback.
+ (+) TxCpltCallback : Tx Complete Callback.
+ (+) RxHalfCpltCallback : Rx Half Complete Callback.
+ (+) RxCpltCallback : Rx Complete Callback.
+ (+) ErrorCallback : Error Callback.
+ (+) AbortCpltCallback : Abort Complete Callback.
+ (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+ (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
+ (+) MspInitCallback : UART MspInit.
+ (+) MspDeInitCallback : UART MspDeInit.
+ This function takes as parameters the HAL peripheral handle, the Callback ID
+ and a pointer to the user callback function.
+
+ [..]
+ Use function HAL_UART_UnRegisterCallback() to reset a callback to the default
+ weak (surcharged) function.
+ HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) TxHalfCpltCallback : Tx Half Complete Callback.
+ (+) TxCpltCallback : Tx Complete Callback.
+ (+) RxHalfCpltCallback : Rx Half Complete Callback.
+ (+) RxCpltCallback : Rx Complete Callback.
+ (+) ErrorCallback : Error Callback.
+ (+) AbortCpltCallback : Abort Complete Callback.
+ (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+ (+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
+ (+) MspInitCallback : UART MspInit.
+ (+) MspDeInitCallback : UART MspDeInit.
+
+ [..]
+ For specific callback RxEventCallback, use dedicated registration/reset functions:
+ respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback().
+
+ [..]
+ By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
+ all callbacks are set to the corresponding weak (surcharged) functions:
+ examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are respectively
+ reset to the legacy weak (surcharged) functions in the HAL_UART_Init()
+ and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
+
+ [..]
+ Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
+ Exception done MspInit/MspDeInit that can be registered/unregistered
+ in HAL_UART_STATE_READY or HAL_UART_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 HAL_UART_RegisterCallback() before calling HAL_UART_DeInit()
+ or HAL_UART_Init() function.
+
+ [..]
+ When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registration feature is not available
+ and weak (surcharged) callbacks are used.
+
+ [..]
+ Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
+ (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_UART_DMAPause()
+ (+) Resume the DMA Transfer using HAL_UART_DMAResume()
+ (+) Stop the DMA Transfer using HAL_UART_DMAStop()
+
+
+ [..] This subsection also provides a set of additional functions providing enhanced reception
+ services to user. (For example, these functions allow application to handle use cases
+ where number of data to be received is unknown).
+
+ (#) Compared to standard reception services which only consider number of received
+ data elements as reception completion criteria, these functions also consider additional events
+ as triggers for updating reception status to caller :
+ (+) Detection of inactivity period (RX line has not been active for a given period).
+ (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
+ for 1 frame time, after last received byte.
+
+ (#) There are two mode of transfer:
+ (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
+ or till IDLE event occurs. Reception is handled only during function execution.
+ When function exits, no data reception could occur. HAL status and number of actually received data elements,
+ are returned by function after finishing transfer.
+ (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
+ These API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
+ The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
+ The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
+
+ (#) Blocking mode API:
+ (+) HAL_UARTEx_ReceiveToIdle()
+
+ (#) Non-Blocking mode API with Interrupt:
+ (+) HAL_UARTEx_ReceiveToIdle_IT()
+
+ (#) Non-Blocking mode API with DMA:
+ (+) HAL_UARTEx_ReceiveToIdle_DMA()
+
+
+ *** UART HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in UART HAL driver.
+
+ (+) __HAL_UART_ENABLE: Enable the UART peripheral
+ (+) __HAL_UART_DISABLE: Disable the UART peripheral
+ (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
+ (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
+ (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
+ (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
+ (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
+
+ [..]
+ (@) You can refer to the UART HAL driver header file for more useful macros
+
+ @endverbatim
+ [..]
+ (@) Additional remark: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible UART frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | UART frame |
+ |---------------------|---------------------------------------|
+ | 0 | 0 | | SB | 8 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 0 | 1 | | SB | 7 bit data | PB | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 0 | | SB | 9 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | STB | |
+ +-------------------------------------------------------------+
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup UART UART
+ * @brief HAL UART module driver
+ * @{
+ */
+#ifdef HAL_UART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup UART_Private_Constants
+ * @{
+ */
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAError(DMA_HandleTypeDef *hdma);
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
+ uint32_t Tickstart, uint32_t Timeout);
+static void UART_SetConfig(UART_HandleTypeDef *huart);
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup UART_Exported_Functions UART Exported Functions
+ * @{
+ */
+
+/** @defgroup UART_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 USARTx or the UARTy
+ in asynchronous mode.
+ (+) For the asynchronous mode only these parameters can be configured:
+ (++) Baud Rate
+ (++) Word Length
+ (++) Stop Bit
+ (++) Parity: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ please refer to Reference manual for possible UART frame formats.
+ (++) Hardware flow control
+ (++) Receiver/transmitter modes
+ (++) Over Sampling Method
+ [..]
+ The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
+ follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor configuration
+ procedures (details for the procedures are available in reference manuals
+ (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the UART mode according to the specified parameters in
+ * the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
+ {
+ /* The hardware flow control is available only for USART1, USART2 and USART3 */
+ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
+ assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
+ }
+ else
+ {
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+ }
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In asynchronous mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the half-duplex mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In half-duplex mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the LIN mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param BreakDetectLength Specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
+ * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the LIN UART instance */
+ assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
+
+ /* Check the Break detection length parameter */
+ assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
+ assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In LIN mode, the following bits must be kept cleared:
+ - CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
+
+ /* Set the USART LIN Break detection length. */
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_LBDL);
+ SET_BIT(huart->Instance->CR2, BreakDetectLength);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the Multi-Processor mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Address USART address
+ * @param WakeUpMethod specifies the USART wake-up method.
+ * This parameter can be one of the following values:
+ * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
+ * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Check the Address & wake up method parameters */
+ assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
+ assert_param(IS_UART_ADDRESS(Address));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+#if defined(USART_CR1_OVER8)
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+#endif /* USART_CR1_OVER8 */
+
+ if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ UART_InitCallbacksToDefault(huart);
+
+ if (huart->MspInitCallback == NULL)
+ {
+ huart->MspInitCallback = HAL_UART_MspInit;
+ }
+
+ /* Init the low level hardware */
+ huart->MspInitCallback(huart);
+#else
+ /* Init the low level hardware : GPIO, CLOCK */
+ HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+ }
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In Multi-Processor mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register */
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Set the USART address node */
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD);
+ SET_BIT(huart->Instance->CR2, Address);
+
+ /* Set the wake up method by setting the WAKE bit in the CR1 register */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE);
+ SET_BIT(huart->Instance->CR1, WakeUpMethod);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the UART peripheral.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if (huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_UART_DISABLE(huart);
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ if (huart->MspDeInitCallback == NULL)
+ {
+ huart->MspDeInitCallback = HAL_UART_MspDeInit;
+ }
+ /* DeInit the low level hardware */
+ huart->MspDeInitCallback(huart);
+#else
+ /* DeInit the low level hardware */
+ HAL_UART_MspDeInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_RESET;
+ huart->RxState = HAL_UART_STATE_RESET;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Process Unlock */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief UART MSP Init.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART MSP DeInit.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspDeInit could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+ * @brief Register a User UART Callback
+ * To be used instead of the weak predefined callback
+ * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(),
+ * HAL_MultiProcessor_Init() to register callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
+ * @param huart uart handle
+ * @param CallbackID ID of the callback to be registered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+ * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+ * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+ * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+ * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+ * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+ * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+ * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
+ pUART_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+ huart->TxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_TX_COMPLETE_CB_ID :
+ huart->TxCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+ huart->RxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_RX_COMPLETE_CB_ID :
+ huart->RxCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ERROR_CB_ID :
+ huart->ErrorCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_COMPLETE_CB_ID :
+ huart->AbortCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+ huart->AbortTransmitCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+ huart->AbortReceiveCpltCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (huart->gState == HAL_UART_STATE_RESET)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = pCallback;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Unregister an UART Callback
+ * UART callaback is redirected to the weak predefined callback
+ * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
+ * HAL_LIN_Init(), HAL_MultiProcessor_Init() to un-register callbacks for HAL_UART_MSPINIT_CB_ID
+ * and HAL_UART_MSPDEINIT_CB_ID
+ * @param huart uart handle
+ * @param CallbackID ID of the callback to be unregistered
+ * This parameter can be one of the following values:
+ * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+ * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+ * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+ * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+ * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+ * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+ * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+ * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+ * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (HAL_UART_STATE_READY == huart->gState)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+ huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ break;
+
+ case HAL_UART_TX_COMPLETE_CB_ID :
+ huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ break;
+
+ case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+ huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ break;
+
+ case HAL_UART_RX_COMPLETE_CB_ID :
+ huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ break;
+
+ case HAL_UART_ERROR_CB_ID :
+ huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_UART_ABORT_COMPLETE_CB_ID :
+ huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ break;
+
+ case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+ huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
+ break;
+
+ case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+ huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
+ break;
+
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_UART_STATE_RESET == huart->gState)
+ {
+ switch (CallbackID)
+ {
+ case HAL_UART_MSPINIT_CB_ID :
+ huart->MspInitCallback = HAL_UART_MspInit;
+ break;
+
+ case HAL_UART_MSPDEINIT_CB_ID :
+ huart->MspDeInitCallback = HAL_UART_MspDeInit;
+ break;
+
+ default :
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Register a User UART Rx Event Callback
+ * To be used instead of the weak predefined callback
+ * @param huart Uart handle
+ * @param pCallback Pointer to the Rx Event Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ huart->RxEventCallback = pCallback;
+ }
+ else
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+
+ return status;
+}
+
+/**
+ * @brief UnRegister the UART Rx Event Callback
+ * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
+ * @param huart Uart handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(huart);
+
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */
+ }
+ else
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(huart);
+ return status;
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group2 IO operation functions
+ * @brief UART Transmit and Receive functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ This subsection provides a set of functions allowing to manage the UART asynchronous
+ and Half duplex data transfers.
+
+ (#) There are two modes of transfer:
+ (+) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (+) Non-Blocking mode: The communication is performed using Interrupts
+ or DMA, these API's return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or receive process
+ The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected.
+
+ (#) Blocking mode API's are :
+ (+) HAL_UART_Transmit()
+ (+) HAL_UART_Receive()
+
+ (#) Non-Blocking mode API's with Interrupt are :
+ (+) HAL_UART_Transmit_IT()
+ (+) HAL_UART_Receive_IT()
+ (+) HAL_UART_IRQHandler()
+
+ (#) Non-Blocking mode API's with DMA are :
+ (+) HAL_UART_Transmit_DMA()
+ (+) HAL_UART_Receive_DMA()
+ (+) HAL_UART_DMAPause()
+ (+) HAL_UART_DMAResume()
+ (+) HAL_UART_DMAStop()
+
+ (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
+ (+) HAL_UART_TxHalfCpltCallback()
+ (+) HAL_UART_TxCpltCallback()
+ (+) HAL_UART_RxHalfCpltCallback()
+ (+) HAL_UART_RxCpltCallback()
+ (+) HAL_UART_ErrorCallback()
+
+ (#) Non-Blocking mode transfers could be aborted using Abort API's :
+ (+) HAL_UART_Abort()
+ (+) HAL_UART_AbortTransmit()
+ (+) HAL_UART_AbortReceive()
+ (+) HAL_UART_Abort_IT()
+ (+) HAL_UART_AbortTransmit_IT()
+ (+) HAL_UART_AbortReceive_IT()
+
+ (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
+ (+) HAL_UART_AbortCpltCallback()
+ (+) HAL_UART_AbortTransmitCpltCallback()
+ (+) HAL_UART_AbortReceiveCpltCallback()
+
+ (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced reception services:
+ (+) HAL_UARTEx_RxEventCallback()
+
+ (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
+ Errors are handled as follows :
+ (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
+ to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
+ Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
+ and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
+ If user wants to abort it, Abort services should be called by user.
+ (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
+ This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
+ Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
+
+ -@- In the Half duplex communication, it is forbidden to run the transmit
+ and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends an amount of data in blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ const uint8_t *pdata8bits;
+ const uint16_t *pdata16bits;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (const uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ while (huart->TxXferCount > 0U)
+ {
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if (pdata8bits == NULL)
+ {
+ huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
+ pdata16bits++;
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
+ pdata8bits++;
+ }
+ huart->TxXferCount--;
+ }
+
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+ uint32_t tickstart = 0U;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ /* Check the remain data to be received */
+ while (huart->RxXferCount > 0U)
+ {
+ if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if (pdata8bits == NULL)
+ {
+ *pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF);
+ pdata16bits++;
+ }
+ else
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ pdata8bits++;
+ }
+ huart->RxXferCount--;
+ }
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Enable the UART Transmit data register empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to Standard reception */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return (UART_Start_Receive_IT(huart, pData, Size));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in DMA mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the sent data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 provided through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
+{
+ const uint32_t *tmp;
+
+ /* Check that a Tx process is not already ongoing */
+ if (huart->gState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->gState = HAL_UART_STATE_BUSY_TX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmatx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the UART transmit DMA channel */
+ tmp = (const uint32_t *)&pData;
+ HAL_DMA_Start_IT(huart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in DMA mode.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+ * the received data is handled as a set of u16. In this case, Size must indicate the number
+ * of u16 available through pData.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to Standard reception */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return (UART_Start_Receive_DMA(huart, pData, Size));
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ /* Disable the UART DMA Tx request */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the UART DMA Rx request */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
+{
+
+ if (huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ /* Enable the UART DMA Tx request */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+
+ if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ /* Clear the Overrun flag before resuming the Rx transfer*/
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ if (huart->Init.Parity != UART_PARITY_NONE)
+ {
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ }
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the UART DMA Rx request */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the DMA Transfer.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
+{
+ uint32_t dmarequest = 0x00U;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
+ */
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel */
+ if (huart->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmatx);
+ }
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel */
+ if (huart->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmarx);
+ }
+ UART_EndRxTransfer(huart);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode till either the expected number of data is received or an IDLE event occurs.
+ * @note HAL_OK is returned if reception is completed (expected number of data has been received)
+ * or if reception is stopped after IDLE event (less than the expected number of data has been received)
+ * In this case, RxLen output parameter indicates number of data available in reception buffer.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @param RxLen Number of data elements finally received (could be lower than Size, in case reception ends on IDLE event)
+ * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
+ uint32_t Timeout)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+ uint32_t tickstart;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Init tickstart for timeout management */
+ tickstart = HAL_GetTick();
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) pData;
+ }
+ else
+ {
+ pdata8bits = pData;
+ pdata16bits = NULL;
+ }
+
+ /* Initialize output number of received elements */
+ *RxLen = 0U;
+
+ /* as long as data have to be received */
+ while (huart->RxXferCount > 0U)
+ {
+ /* Check if IDLE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
+ {
+ /* Clear IDLE flag in ISR */
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+
+ /* If Set, but no data ever received, clear flag without exiting loop */
+ /* If Set, and data has already been received, this means Idle Event is valid : End reception */
+ if (*RxLen > 0U)
+ {
+ huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ }
+
+ /* Check if RXNE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
+ {
+ if (pdata8bits == NULL)
+ {
+ *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ pdata16bits++;
+ }
+ else
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+
+ pdata8bits++;
+ }
+ /* Increment number of received elements */
+ *RxLen += 1U;
+ huart->RxXferCount--;
+ }
+
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+ {
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Set number of received elements in output parameter : RxLen */
+ *RxLen = huart->RxXferSize - huart->RxXferCount;
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in interrupt mode till either the expected number of data is received or an IDLE event occurs.
+ * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
+ * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
+ * number of received data elements.
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to reception till IDLE Event*/
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ status = UART_Start_Receive_IT(huart, pData, Size);
+
+ /* Check Rx process has been successfully started */
+ if (status == HAL_OK)
+ {
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ else
+ {
+ /* In case of errors already pending when reception is started,
+ Interrupts may have already been raised and lead to reception abortion.
+ (Overrun error for instance).
+ In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs.
+ * @note Reception is initiated by this function call. Further progress of reception is achieved thanks
+ * to DMA services, transferring automatically received data elements in user reception buffer and
+ * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
+ * reception phase as ended. In all cases, callback execution will indicate number of received data elements.
+ * @note When the UART parity is enabled (PCE = 1), the received data contain
+ * the parity bit (MSB position).
+ * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
+ * the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+ * of uint16_t available through pData.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+ * @param Size Amount of data elements (uint8_t or uint16_t) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ HAL_StatusTypeDef status;
+
+ /* Check that a Rx process is not already ongoing */
+ if (huart->RxState == HAL_UART_STATE_READY)
+ {
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Set Reception type to reception till IDLE Event*/
+ huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ status = UART_Start_Receive_DMA(huart, pData, Size);
+
+ /* Check Rx process has been successfully started */
+ if (status == HAL_OK)
+ {
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ else
+ {
+ /* In case of errors already pending when reception is started,
+ Interrupts may have already been raised and lead to reception abortion.
+ (Overrun error for instance).
+ In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+ status = HAL_ERROR;
+ }
+ }
+
+ return status;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Provide Rx Event type that has lead to RxEvent callback execution.
+ * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
+ * of reception process is provided to application through calls of Rx Event callback (either default one
+ * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
+ * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
+ * to Rx Event callback execution.
+ * @note This function is expected to be called within the user implementation of Rx Event Callback,
+ * in order to provide the accurate value :
+ * In Interrupt Mode :
+ * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
+ * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
+ * received data is lower than expected one)
+ * In DMA Mode :
+ * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
+ * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
+ * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
+ * received data is lower than expected one).
+ * In DMA mode, RxEvent callback could be called several times;
+ * When DMA is configured in Normal Mode, HT event does not stop Reception process;
+ * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
+ * @param huart UART handle.
+ * @retval Rx Event Type (returned value will be a value of @ref UART_RxEvent_Type_Values)
+ */
+HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart)
+{
+ /* Return Rx Event type value, as stored in UART handle */
+ return(huart->RxEventType);
+}
+
+/**
+ * @brief Abort ongoing transfers (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx and Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel: use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel: use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->RxState and huart->gState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->gState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (blocking mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback to Null.
+ No call back execution at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+ {
+ if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+ {
+ /* Set error code to DMA */
+ huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing transfers (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx and Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
+{
+ uint32_t AbortCplt = 0x01U;
+
+ /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
+ before any call to DMA Abort functions */
+ /* DMA Tx Handle is valid */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
+ }
+ else
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ }
+ /* DMA Rx Handle is valid */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
+ Otherwise, set it to NULL */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
+ }
+ else
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ }
+ }
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ /* Disable DMA Tx at UART level */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* UART Tx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ huart->hdmatx->XferAbortCallback = NULL;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* UART Rx DMA Abort callback has already been initialised :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ huart->hdmarx->XferAbortCallback = NULL;
+ AbortCplt = 0x01U;
+ }
+ else
+ {
+ AbortCplt = 0x00U;
+ }
+ }
+ }
+
+ /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+ if (AbortCplt == 0x01U)
+ {
+ /* Reset Tx and Rx transfer counters */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Transmit transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Tx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* Disable the UART DMA Tx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmatx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
+
+ /* Abort DMA TX */
+ if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
+ huart->hdmatx->XferAbortCallback(huart->hdmatx);
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Reset Tx transfer counter */
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Abort ongoing Receive transfer (Interrupt mode).
+ * @param huart UART handle.
+ * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+ * This procedure performs following operations :
+ * - Disable UART Interrupts (Rx)
+ * - Disable the DMA transfer in the peripheral register (if enabled)
+ * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+ * - Set handle State to READY
+ * - At abort completion, call user abort complete callback
+ * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be
+ * considered as completed only when user abort complete callback is executed (not when exiting function).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+ }
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
+
+ /* Abort DMA RX */
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Reset Rx transfer counter */
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles UART interrupt request.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
+{
+ uint32_t isrflags = READ_REG(huart->Instance->SR);
+ uint32_t cr1its = READ_REG(huart->Instance->CR1);
+ uint32_t cr3its = READ_REG(huart->Instance->CR3);
+ uint32_t errorflags = 0x00U;
+ uint32_t dmarequest = 0x00U;
+
+ /* If no error occurs */
+ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
+ if (errorflags == RESET)
+ {
+ /* UART in mode Receiver -------------------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ return;
+ }
+ }
+
+ /* If some errors occur */
+ if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET)
+ || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
+ {
+ /* UART parity error interrupt occurred ----------------------------------*/
+ if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_PE;
+ }
+
+ /* UART noise error interrupt occurred -----------------------------------*/
+ if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_NE;
+ }
+
+ /* UART frame error interrupt occurred -----------------------------------*/
+ if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_FE;
+ }
+
+ /* UART Over-Run interrupt occurred --------------------------------------*/
+ if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET)
+ || ((cr3its & USART_CR3_EIE) != RESET)))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_ORE;
+ }
+
+ /* Call UART Error Call back function if need be --------------------------*/
+ if (huart->ErrorCode != HAL_UART_ERROR_NONE)
+ {
+ /* UART in mode Receiver -----------------------------------------------*/
+ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
+ {
+ UART_Receive_IT(huart);
+ }
+
+ /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+ consider error as blocking */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
+ {
+ /* Blocking error : transfer is aborted
+ Set the UART state ready to be able to start again the process,
+ Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+ UART_EndRxTransfer(huart);
+
+ /* Disable the UART DMA Rx request if enabled */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Abort the UART DMA Rx channel */
+ if (huart->hdmarx != NULL)
+ {
+ /* Set the UART DMA Abort callback :
+ will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
+ huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
+ if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+ {
+ /* Call Directly XferAbortCallback function in case of error */
+ huart->hdmarx->XferAbortCallback(huart->hdmarx);
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ }
+ else
+ {
+ /* Non Blocking error : transfer could go on.
+ Error is notified to user through user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ }
+ }
+ return;
+ } /* End if some error occurs */
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : */
+ if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ && ((isrflags & USART_SR_IDLE) != 0U)
+ && ((cr1its & USART_SR_IDLE) != 0U))
+ {
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+
+ /* Check if DMA mode is enabled in UART */
+ if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+ {
+ /* DMA mode enabled */
+ /* Check received length : If all expected data are received, do nothing,
+ (DMA cplt callback will be called).
+ Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+ uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
+ if ((nb_remaining_rx_data > 0U)
+ && (nb_remaining_rx_data < huart->RxXferSize))
+ {
+ /* Reception is not complete */
+ huart->RxXferCount = nb_remaining_rx_data;
+
+ /* In Normal mode, end DMA xfer and HAL UART Rx process*/
+ if (huart->hdmarx->Init.Mode != DMA_CIRCULAR)
+ {
+ /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
+ in the UART CR3 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Last bytes received, so no need as the abort is immediate */
+ (void)HAL_DMA_Abort(huart->hdmarx);
+ }
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Idle Event */
+ huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ return;
+ }
+ else
+ {
+ /* DMA mode not enabled */
+ /* Check received length : If all expected data are received, do nothing.
+ Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+ uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
+ if ((huart->RxXferCount > 0U)
+ && (nb_rx_data > 0U))
+ {
+ /* Disable the UART Parity Error Interrupt and RXNE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Rx process is completed, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Idle Event */
+ huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxEventCallback(huart, nb_rx_data);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ return;
+ }
+ }
+
+ /* UART in mode Transmitter ------------------------------------------------*/
+ if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
+ {
+ UART_Transmit_IT(huart);
+ return;
+ }
+
+ /* UART in mode Transmitter end --------------------------------------------*/
+ if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
+ {
+ UART_EndTransmit_IT(huart);
+ return;
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART error callbacks.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief UART Abort Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief UART Abort Receive Complete callback.
+ * @param huart UART handle.
+ * @retval None
+ */
+__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @brief Reception Event Callback (Rx event notification called after use of advanced reception service).
+ * @param huart UART handle
+ * @param Size Number of data available in application reception buffer (indicates a position in
+ * reception buffer until which, data are available)
+ * @retval None
+ */
+__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ UNUSED(Size);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_UARTEx_RxEventCallback can be implemented in the user file.
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
+ * @brief UART control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the UART:
+ (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
+ (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
+ (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
+ (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
+ (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits break characters.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Send break characters */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enters the UART in mute mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Exits the UART mute mode: wake up software.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART transmitter and disables the UART receiver.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_TE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART receiver and disables the UART transmitter.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00U;
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->gState = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = huart->Instance->CR1;
+
+ /* Clear TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
+
+ /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
+ tmpreg |= (uint32_t)USART_CR1_RE;
+
+ /* Write to USART CR1 */
+ WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
+
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
+ * @brief UART State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to return the State of
+ UART communication process, return Peripheral Errors occurred during communication
+ process
+ (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
+ (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the UART state.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL state
+ */
+HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
+{
+ uint32_t temp1 = 0x00U, temp2 = 0x00U;
+ temp1 = huart->gState;
+ temp2 = huart->RxState;
+
+ return (HAL_UART_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+ * @brief Return the UART error code
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART.
+ * @retval UART Error Code
+ */
+uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
+{
+ return huart->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the callbacks to their default values.
+ * @param huart UART handle.
+ * @retval none
+ */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
+{
+ /* Init the UART Callback settings */
+ huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
+ huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
+ huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
+ huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
+ huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */
+
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+ * @brief DMA UART transmit process complete callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ /* DMA Normal mode*/
+ if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ huart->TxXferCount = 0x00U;
+
+ /* Disable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+
+ }
+ /* DMA Circular mode */
+ else
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART transmit process half complete callback
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxHalfCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART receive process complete callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* DMA Normal mode*/
+ if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
+ {
+ huart->RxXferCount = 0U;
+
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+ }
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Transfer Complete */
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : use Rx Event callback */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* In other cases : use Rx Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxCpltCallback(huart);
+#else
+ /*Call legacy weak Rx complete callback*/
+ HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART receive process half complete callback
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+ In this case, Rx Event type is Half Transfer */
+ huart->RxEventType = HAL_UART_RXEVENT_HT;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : use Rx Event callback */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize / 2U);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* In other cases : use Rx Half Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Half complete callback*/
+ huart->RxHalfCpltCallback(huart);
+#else
+ /*Call legacy weak Rx Half complete callback*/
+ HAL_UART_RxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief DMA UART communication error callback.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAError(DMA_HandleTypeDef *hdma)
+{
+ uint32_t dmarequest = 0x00U;
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Stop UART DMA Tx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
+ if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
+ {
+ huart->TxXferCount = 0x00U;
+ UART_EndTxTransfer(huart);
+ }
+
+ /* Stop UART DMA Rx request if ongoing */
+ dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
+ if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
+ {
+ huart->RxXferCount = 0x00U;
+ UART_EndRxTransfer(huart);
+ }
+
+ huart->ErrorCode |= HAL_UART_ERROR_DMA;
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief This function handles UART Communication Timeout. It waits
+ * until a flag is no longer in the specified status.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Flag specifies the UART flag to check.
+ * @param Status The actual Flag status (SET or RESET).
+ * @param Tickstart Tick start value
+ * @param Timeout Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
+ uint32_t Tickstart, uint32_t Timeout)
+{
+ /* Wait until flag is set */
+ while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
+ {
+ /* Check for the Timeout */
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
+ {
+ /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Start Receive operation in interrupt mode.
+ * @note This function could be called by all HAL UART API providing reception in Interrupt mode.
+ * @note When calling this function, parameters validity is considered as already checked,
+ * i.e. Rx State, buffer address, ...
+ * UART Handle is assumed as Locked.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ if (huart->Init.Parity != UART_PARITY_NONE)
+ {
+ /* Enable the UART Parity Error Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
+ }
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
+
+ /* Enable the UART Data Register not empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Start Receive operation in DMA mode.
+ * @note This function could be called by all HAL UART API providing reception in DMA mode.
+ * @note When calling this function, parameters validity is considered as already checked,
+ * i.e. Rx State, buffer address, ...
+ * UART Handle is assumed as Locked.
+ * @param huart UART handle.
+ * @param pData Pointer to data buffer (u8 or u16 data elements).
+ * @param Size Amount of data elements (u8 or u16) to be received.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmarx->XferErrorCallback = UART_DMAError;
+
+ /* Set the DMA abort callback */
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA stream */
+ tmp = (uint32_t *)&pData;
+ HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t *)tmp, Size);
+
+ /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
+ __HAL_UART_CLEAR_OREFLAG(huart);
+
+ if (huart->Init.Parity != UART_PARITY_NONE)
+ {
+ /* Enable the UART Parity Error Interrupt */
+ ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+ }
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
+ * @param huart UART handle.
+ * @retval None
+ */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable TXEIE and TCIE interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
+
+ /* At end of Tx process, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+}
+
+/**
+ * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
+ * @param huart UART handle.
+ * @retval None
+ */
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
+{
+ /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
+ ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+ /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+ }
+
+ /* At end of Rx process, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+}
+
+/**
+ * @brief DMA UART communication abort callback, when initiated by HAL services on Error
+ * (To be called at end of DMA Abort procedure following error occurrence).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+ huart->RxXferCount = 0x00U;
+ huart->TxXferCount = 0x00U;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered error callback*/
+ huart->ErrorCallback(huart);
+#else
+ /*Call legacy weak error callback*/
+ HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user
+ * (To be called at end of DMA Tx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Rx DMA Handle.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->hdmatx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (huart->hdmarx != NULL)
+ {
+ if (huart->hdmarx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user
+ * (To be called at end of DMA Rx Abort procedure following user abort request).
+ * @note When this callback is executed, User Abort complete call back is called only if no
+ * Abort still ongoing for Tx DMA Handle.
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->hdmarx->XferAbortCallback = NULL;
+
+ /* Check if an Abort process is still ongoing */
+ if (huart->hdmatx != NULL)
+ {
+ if (huart->hdmatx->XferAbortCallback != NULL)
+ {
+ return;
+ }
+ }
+
+ /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+ huart->TxXferCount = 0x00U;
+ huart->RxXferCount = 0x00U;
+
+ /* Reset ErrorCode */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+ /* Restore huart->gState and huart->RxState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort complete callback */
+ huart->AbortCpltCallback(huart);
+#else
+ /* Call legacy weak Abort complete callback */
+ HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Tx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
+ * (This callback is executed at end of DMA Tx Abort procedure following user abort request,
+ * and leads to user Tx Abort Complete callback execution).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->TxXferCount = 0x00U;
+
+ /* Restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Transmit Complete Callback */
+ huart->AbortTransmitCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Transmit Complete Callback */
+ HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA UART Rx communication abort callback, when initiated by user by a call to
+ * HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
+ * (This callback is executed at end of DMA Rx Abort procedure following user abort request,
+ * and leads to user Rx Abort Complete callback execution).
+ * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ huart->RxXferCount = 0x00U;
+
+ /* Restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /* Call registered Abort Receive Complete Callback */
+ huart->AbortReceiveCpltCallback(huart);
+#else
+ /* Call legacy weak Abort Receive Complete Callback */
+ HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
+{
+ const uint16_t *tmp;
+
+ /* Check that a Tx process is ongoing */
+ if (huart->gState == HAL_UART_STATE_BUSY_TX)
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ tmp = (const uint16_t *) huart->pTxBuffPtr;
+ huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
+ huart->pTxBuffPtr += 2U;
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
+ }
+
+ if (--huart->TxXferCount == 0U)
+ {
+ /* Disable the UART Transmit Data Register Empty Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
+
+ /* Tx process is ended, restore huart->gState to Ready */
+ huart->gState = HAL_UART_STATE_READY;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Tx complete callback*/
+ huart->TxCpltCallback(huart);
+#else
+ /*Call legacy weak Tx complete callback*/
+ HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
+{
+ uint8_t *pdata8bits;
+ uint16_t *pdata16bits;
+
+ /* Check that a Rx process is ongoing */
+ if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+ {
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+ {
+ pdata8bits = NULL;
+ pdata16bits = (uint16_t *) huart->pRxBuffPtr;
+ *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ huart->pRxBuffPtr += 2U;
+ }
+ else
+ {
+ pdata8bits = (uint8_t *) huart->pRxBuffPtr;
+ pdata16bits = NULL;
+
+ if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ huart->pRxBuffPtr += 1U;
+ }
+
+ if (--huart->RxXferCount == 0U)
+ {
+ /* Disable the UART Data Register not empty Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
+
+ /* Disable the UART Parity Error Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
+
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
+
+ /* Rx process is completed, restore huart->RxState to Ready */
+ huart->RxState = HAL_UART_STATE_READY;
+
+ /* Initialize type of RxEvent to Transfer Complete */
+ huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+ /* Check current reception Mode :
+ If Reception till IDLE event has been selected : */
+ if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+ {
+ /* Set reception type to Standard */
+ huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+ /* Disable IDLE interrupt */
+ ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+ /* Check if IDLE flag is set */
+ if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
+ {
+ /* Clear IDLE flag in ISR */
+ __HAL_UART_CLEAR_IDLEFLAG(huart);
+ }
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx Event callback*/
+ huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+ /*Call legacy weak Rx Event callback*/
+ HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+ else
+ {
+ /* Standard reception API called */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ /*Call registered Rx complete callback*/
+ huart->RxCpltCallback(huart);
+#else
+ /*Call legacy weak Rx complete callback*/
+ HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+ }
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configures the UART peripheral.
+ * @param huart Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+static void UART_SetConfig(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg;
+ uint32_t pclk;
+
+ /* Check the parameters */
+ assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
+ assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
+ assert_param(IS_UART_PARITY(huart->Init.Parity));
+ assert_param(IS_UART_MODE(huart->Init.Mode));
+
+ /*-------------------------- USART CR2 Configuration -----------------------*/
+ /* Configure the UART Stop Bits: Set STOP[13:12] bits
+ according to huart->Init.StopBits value */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ /* Configure the UART Word Length, Parity and mode:
+ Set the M bits according to huart->Init.WordLength value
+ Set PCE and PS bits according to huart->Init.Parity value
+ Set TE and RE bits according to huart->Init.Mode value
+ Set OVER8 bit according to huart->Init.OverSampling value */
+
+#if defined(USART_CR1_OVER8)
+ tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
+ tmpreg);
+#else
+ tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
+ tmpreg);
+#endif /* USART_CR1_OVER8 */
+
+ /*-------------------------- USART CR3 Configuration -----------------------*/
+ /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
+ MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
+
+
+ if(huart->Instance == USART1)
+ {
+ pclk = HAL_RCC_GetPCLK2Freq();
+ }
+ else
+ {
+ pclk = HAL_RCC_GetPCLK1Freq();
+ }
+
+ /*-------------------------- USART BRR Configuration ---------------------*/
+#if defined(USART_CR1_OVER8)
+ if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
+ }
+ else
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
+ }
+#else
+ huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
+#endif /* USART_CR1_OVER8 */
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_UART_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/Inc/i2c.h b/Inc/i2c.h
new file mode 100644
index 0000000..84ed75d
--- /dev/null
+++ b/Inc/i2c.h
@@ -0,0 +1,52 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file i2c.h
+ * @brief This file contains all the function prototypes for
+ * the i2c.c file
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2024 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __I2C_H__
+#define __I2C_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern I2C_HandleTypeDef hi2c1;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_I2C1_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __I2C_H__ */
+
diff --git a/Inc/main.h b/Inc/main.h
index e6f5997..6076dd3 100644
--- a/Inc/main.h
+++ b/Inc/main.h
@@ -1,11 +1,3 @@
-/*
- * @Author: 吴俊潮 24472040@qq.com
- * @Date: 2024-03-25 14:33:19
- * @LastEditors: 吴俊潮 24472040@qq.com
- * @LastEditTime: 2024-03-25 16:04:07
- * @FilePath: \mfps\Inc\main.h
- * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
- */
/* USER CODE BEGIN Header */
/**
******************************************************************************
@@ -36,7 +28,7 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
-#include "stm32f103xe.h"
+
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
@@ -65,16 +57,52 @@ void Error_Handler(void);
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
+#define RS485_EN1_Pin GPIO_PIN_1
+#define RS485_EN1_GPIO_Port GPIOA
+#define RS485_TXD1_Pin GPIO_PIN_2
+#define RS485_TXD1_GPIO_Port GPIOA
+#define RS485_RXD1_Pin GPIO_PIN_3
+#define RS485_RXD1_GPIO_Port GPIOA
+#define CS1_Pin GPIO_PIN_4
+#define CS1_GPIO_Port GPIOA
+#define SPI_DRDY_Pin GPIO_PIN_4
+#define SPI_DRDY_GPIO_Port GPIOC
+#define OCIN1_Pin GPIO_PIN_5
+#define OCIN1_GPIO_Port GPIOC
+#define OCIN2_Pin GPIO_PIN_0
+#define OCIN2_GPIO_Port GPIOB
+#define OCIN3_Pin GPIO_PIN_1
+#define OCIN3_GPIO_Port GPIOB
+#define TXD3_Pin GPIO_PIN_10
+#define TXD3_GPIO_Port GPIOB
+#define RXD3_Pin GPIO_PIN_11
+#define RXD3_GPIO_Port GPIOB
+#define CS2_Pin GPIO_PIN_7
+#define CS2_GPIO_Port GPIOC
+#define STOP1_Pin GPIO_PIN_8
+#define STOP1_GPIO_Port GPIOC
+#define STOP2_Pin GPIO_PIN_9
+#define STOP2_GPIO_Port GPIOC
#define LED_ERR_Pin GPIO_PIN_11
#define LED_ERR_GPIO_Port GPIOA
#define LED_NOR_Pin GPIO_PIN_12
#define LED_NOR_GPIO_Port GPIOA
#define KEY3_Pin GPIO_PIN_15
#define KEY3_GPIO_Port GPIOA
+#define TEMP_TX_Pin GPIO_PIN_10
+#define TEMP_TX_GPIO_Port GPIOC
+#define TEMP_RX_Pin GPIO_PIN_11
+#define TEMP_RX_GPIO_Port GPIOC
#define KEY2_Pin GPIO_PIN_12
#define KEY2_GPIO_Port GPIOC
#define KEY1_Pin GPIO_PIN_2
#define KEY1_GPIO_Port GPIOD
+#define M_EN_A_Pin GPIO_PIN_3
+#define M_EN_A_GPIO_Port GPIOB
+#define M_DIR_A_Pin GPIO_PIN_4
+#define M_DIR_A_GPIO_Port GPIOB
+#define M_PUL_A_Pin GPIO_PIN_5
+#define M_PUL_A_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */
diff --git a/Inc/spi.h b/Inc/spi.h
new file mode 100644
index 0000000..43636ac
--- /dev/null
+++ b/Inc/spi.h
@@ -0,0 +1,55 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file spi.h
+ * @brief This file contains all the function prototypes for
+ * the spi.c file
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2024 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __SPI_H__
+#define __SPI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern SPI_HandleTypeDef hspi1;
+
+extern SPI_HandleTypeDef hspi2;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_SPI1_Init(void);
+void MX_SPI2_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SPI_H__ */
+
diff --git a/Inc/stm32f1xx_hal_conf.h b/Inc/stm32f1xx_hal_conf.h
index 33cc850..6732aec 100644
--- a/Inc/stm32f1xx_hal_conf.h
+++ b/Inc/stm32f1xx_hal_conf.h
@@ -46,7 +46,7 @@
/*#define HAL_ETH_MODULE_ENABLED */
/*#define HAL_FLASH_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
-/*#define HAL_I2C_MODULE_ENABLED */
+#define HAL_I2C_MODULE_ENABLED
/*#define HAL_I2S_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */
@@ -62,10 +62,10 @@
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_SDRAM_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
-/*#define HAL_SPI_MODULE_ENABLED */
+#define HAL_SPI_MODULE_ENABLED
/*#define HAL_SRAM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
-/*#define HAL_UART_MODULE_ENABLED */
+#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
diff --git a/Inc/stm32f1xx_it.h b/Inc/stm32f1xx_it.h
index 1135d3f..c4bd99e 100644
--- a/Inc/stm32f1xx_it.h
+++ b/Inc/stm32f1xx_it.h
@@ -55,6 +55,14 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
+void I2C1_EV_IRQHandler(void);
+void I2C1_ER_IRQHandler(void);
+void SPI1_IRQHandler(void);
+void SPI2_IRQHandler(void);
+void USART1_IRQHandler(void);
+void USART2_IRQHandler(void);
+void USART3_IRQHandler(void);
+void UART4_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
diff --git a/Inc/usart.h b/Inc/usart.h
new file mode 100644
index 0000000..2bfae13
--- /dev/null
+++ b/Inc/usart.h
@@ -0,0 +1,61 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file usart.h
+ * @brief This file contains all the function prototypes for
+ * the usart.c file
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2024 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USART_H__
+#define __USART_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern UART_HandleTypeDef huart4;
+
+extern UART_HandleTypeDef huart1;
+
+extern UART_HandleTypeDef huart2;
+
+extern UART_HandleTypeDef huart3;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_UART4_Init(void);
+void MX_USART1_UART_Init(void);
+void MX_USART2_UART_Init(void);
+void MX_USART3_UART_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USART_H__ */
+
diff --git a/MDK-ARM/mfps.uvguix.EthanWu b/MDK-ARM/mfps.uvguix.EthanWu
index 4985c3a..285d2dd 100644
--- a/MDK-ARM/mfps.uvguix.EthanWu
+++ b/MDK-ARM/mfps.uvguix.EthanWu
@@ -6,7 +6,7 @@
### uVision Project, (C) Keil Software
- C:\Users\EthanWu\Desktop\mfps\MDK-ARM
+ C:\Users\EthanWu\Desktop\work\2024.3.26\mfps\App\Inc
@@ -15,7 +15,7 @@
38003
Registers
- 115 67
+ 115 115
346
@@ -110,8 +110,8 @@
0
- 466
- 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000003000000000000000100000037433A5C55736572735C457468616E57755C4465736B746F705C776F726B5C323032342E332E32355C6D6670735C5372635C6D61696E2E6300000000066D61696E2E6300000000C5D4F200FFFFFFFF37433A5C55736572735C457468616E57755C4465736B746F705C776F726B5C323032342E332E32355C6D6670735C496E635C6D61696E2E6800000000066D61696E2E6800000000FFDC7800FFFFFFFF62433A5C55736572735C457468616E57755C4465736B746F705C776F726B5C323032342E332E32355C6D6670735C447269766572735C53544D3332463178785F48414C5F4472697665725C496E635C73746D3332663178785F68616C5F6770696F2E68000000001473746D3332663178785F68616C5F6770696F2E6800000000BECEA100FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000C400000066000000000600004E020000
+ 332
+ 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000002000000000000000100000037433A5C55736572735C457468616E57755C4465736B746F705C776F726B5C323032342E332E32365C6D6670735C5372635C6D61696E2E6300000000066D61696E2E6300000000C5D4F200FFFFFFFF3A433A5C55736572735C457468616E57755C4465736B746F705C776F726B5C323032342E332E32365C6D6670735C4170705C5372635C6B65792E6300000000056B65792E6300000000FFDC7800FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000F400000066000000000600001D020000
@@ -150,7 +150,7 @@
0
16
- 0300000066000000BD0000001E020000
+ 0300000066000000ED000000ED010000
16
@@ -170,7 +170,7 @@
0
16
- 0300000066000000BD0000001E020000
+ 0300000066000000ED000000ED010000
16
@@ -450,7 +450,7 @@
0
16
- 0300000066000000BD0000001E020000
+ 0300000066000000ED000000ED010000
16
@@ -470,7 +470,7 @@
0
16
- 0300000066000000BD0000001E020000
+ 0300000066000000ED000000ED010000
16
@@ -490,7 +490,7 @@
0
16
- 000000004F020000000600000E030000
+ 000000001E020000000600000E030000
16
@@ -530,7 +530,7 @@
0
16
- 0300000052020000FD050000F5020000
+ 0300000021020000FD050000F5020000
16
@@ -1150,7 +1150,7 @@
0
16
- 0300000066000000BD0000001E020000
+ 0300000066000000ED000000ED010000
16
@@ -1170,7 +1170,7 @@
0
16
- 0300000052020000FD050000F5020000
+ 0300000021020000FD050000F5020000
16
@@ -1190,7 +1190,7 @@
0
16
- 0300000052020000FD050000F5020000
+ 0300000021020000FD050000F5020000
16
@@ -1250,7 +1250,7 @@
0
16
- 0300000052020000FD050000F5020000
+ 0300000021020000FD050000F5020000
16
@@ -1270,7 +1270,7 @@
0
16
- 0300000052020000FD050000F5020000
+ 0300000021020000FD050000F5020000
16
@@ -1799,7 +1799,7 @@
3312
- 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFFC4000000BD00000070040000C1000000000000000100000004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E650020000000000000C40000006600000070040000D4000000C40000004F00000070040000BD0000000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFFAC0300004F000000B0030000A5010000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000B00300006600000070040000BC010000B00300004F00000070040000A501000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFFC00000004F000000C400000037020000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C400000073940000018000100000010000000000000066000000C00000004E020000000000004F000000C0000000370200000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF0000000091010000700400009501000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB0900000180008000000000000000000000AC010000700400002E0200000000000095010000700400001702000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFF38020000950100003C0200001702000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF0000000037020000000600003B02000001000000010000100400000001000000B8FDFFFF6C000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF010000779400000180008000000100000000000000520200000006000025030000000000003B020000000600000E0300000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000
+ 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFFC4000000BD00000070040000C1000000000000000100000004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E650020000000000000C40000006600000070040000D4000000C40000004F00000070040000BD0000000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFFAC0300004F000000B0030000A5010000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000B00300006600000070040000BC010000B00300004F00000070040000A501000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFFF00000004F000000F400000006020000010000000200001004000000010000001CFFFFFF11050000FFFFFFFF05000000ED0300006D000000C3000000C400000073940000018000100000010000000000000066000000F00000001D020000000000004F000000F0000000060200000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF0000000091010000700400009501000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB0900000180008000000000000000000000AC010000700400002E0200000000000095010000700400001702000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFF38020000950100003C0200001702000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF0000000006020000000600000A0200000100000001000010040000000100000016FEFFFFCA000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF010000779400000180008000000100000000000000210200000006000025030000000000000A020000000600000E0300000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000
59392
@@ -1822,7 +1822,7 @@
Build
968
- 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000002001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA0000000000000000000000000000000000000000000000000100000001000000960000000300205000000000046D66707396000000000000000100046D667073000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64DC010000
+ 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA0000000000000000000000000000000000000000000000000100000001000000960000000300205000000000046D66707396000000000000000100046D667073000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64DC010000
583
@@ -1865,27 +1865,18 @@
0
../Src/main.c
- 5
- 100
- 114
+ 4
+ 115
+ 121
1
0
- ../Inc/main.h
- 31
- 60
- 69
- 1
-
- 0
-
-
- ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
- 22
- 58
- 66
+ ..\App\Src\key.c
+ 21
+ 10
+ 15
1
0
diff --git a/MDK-ARM/mfps.uvoptx b/MDK-ARM/mfps.uvoptx
index 1aa7c17..3b806fb 100644
--- a/MDK-ARM/mfps.uvoptx
+++ b/MDK-ARM/mfps.uvoptx
@@ -125,7 +125,7 @@
0
ST-LINKIII-KEIL_SWO
- -U48001800150000504A51544E -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(1BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32F10x_512.FLM -FS08000000 -FL040000 -FP0($$Device:STM32F103RC$Flash\STM32F10x_512.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2 -WK0
+ -UH -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(1BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32F10x_512.FLM -FS08000000 -FL040000 -FP0($$Device:STM32F103RC$Flash\STM32F10x_512.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2 -WK0
@@ -172,7 +172,7 @@
- 1
+ 0
0
0
2
@@ -223,7 +223,7 @@
2
3
1
- 1
+ 0
0
0
../Src/gpio.c
@@ -238,6 +238,30 @@
0
0
0
+ ../Src/i2c.c
+ i2c.c
+ 0
+ 0
+
+
+ 2
+ 5
+ 1
+ 0
+ 0
+ 0
+ ../Src/spi.c
+ spi.c
+ 0
+ 0
+
+
+ 2
+ 6
+ 1
+ 0
+ 0
+ 0
../Src/tim.c
tim.c
0
@@ -245,7 +269,19 @@
2
- 5
+ 7
+ 1
+ 0
+ 0
+ 0
+ ../Src/usart.c
+ usart.c
+ 0
+ 0
+
+
+ 2
+ 8
1
0
0
@@ -257,7 +293,7 @@
2
- 6
+ 9
1
0
0
@@ -277,7 +313,7 @@
0
3
- 7
+ 10
1
0
0
@@ -289,31 +325,19 @@
3
- 8
+ 11
1
0
0
0
- ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
- stm32f1xx_hal_tim.c
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
+ stm32f1xx_hal_i2c.c
0
0
3
- 9
- 1
- 0
- 0
- 0
- ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
- stm32f1xx_hal_tim_ex.c
- 0
- 0
-
-
- 3
- 10
+ 12
1
0
0
@@ -325,7 +349,7 @@
3
- 11
+ 13
1
0
0
@@ -337,7 +361,7 @@
3
- 12
+ 14
1
0
0
@@ -349,7 +373,7 @@
3
- 13
+ 15
1
0
0
@@ -361,7 +385,7 @@
3
- 14
+ 16
1
0
0
@@ -373,7 +397,7 @@
3
- 15
+ 17
1
0
0
@@ -385,7 +409,7 @@
3
- 16
+ 18
1
0
0
@@ -397,7 +421,7 @@
3
- 17
+ 19
1
0
0
@@ -409,7 +433,7 @@
3
- 18
+ 20
1
0
0
@@ -421,7 +445,7 @@
3
- 19
+ 21
1
0
0
@@ -431,6 +455,54 @@
0
0
+
+ 3
+ 22
+ 1
+ 0
+ 0
+ 0
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
+ stm32f1xx_hal_spi.c
+ 0
+ 0
+
+
+ 3
+ 23
+ 1
+ 0
+ 0
+ 0
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
+ stm32f1xx_hal_tim.c
+ 0
+ 0
+
+
+ 3
+ 24
+ 1
+ 0
+ 0
+ 0
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
+ stm32f1xx_hal_tim_ex.c
+ 0
+ 0
+
+
+ 3
+ 25
+ 1
+ 0
+ 0
+ 0
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
+ stm32f1xx_hal_uart.c
+ 0
+ 0
+
@@ -441,7 +513,7 @@
0
4
- 20
+ 26
1
0
0
@@ -453,6 +525,38 @@
+
+ App
+ 1
+ 0
+ 0
+ 0
+
+ 5
+ 27
+ 1
+ 0
+ 0
+ 0
+ ..\App\Src\key.c
+ key.c
+ 0
+ 0
+
+
+ 5
+ 28
+ 5
+ 0
+ 0
+ 0
+ ..\App\Inc\key.h
+ key.h
+ 0
+ 0
+
+
+
::CMSIS
0
diff --git a/MDK-ARM/mfps.uvprojx b/MDK-ARM/mfps.uvprojx
index b1952d9..aa2514e 100644
--- a/MDK-ARM/mfps.uvprojx
+++ b/MDK-ARM/mfps.uvprojx
@@ -81,7 +81,7 @@
0
- 0
+ 1
0
@@ -340,7 +340,7 @@
STM32F103xE,USE_HAL_DRIVER
- ../Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy
+ ../Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;..\App\Src;..\App\Inc
@@ -404,6 +404,118 @@
1
../Src/gpio.c
+
+ i2c.c
+ 1
+ ../Src/i2c.c
+
+
+ 2
+ 0
+ 0
+ 0
+ 0
+ 1
+ 2
+ 2
+ 2
+ 2
+ 11
+
+
+ 1
+
+
+
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
+
+ spi.c
+ 1
+ ../Src/spi.c
+
+
+ 2
+ 0
+ 0
+ 0
+ 0
+ 1
+ 2
+ 2
+ 2
+ 2
+ 11
+
+
+ 1
+
+
+
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
tim.c
1
@@ -460,6 +572,62 @@
+
+ usart.c
+ 1
+ ../Src/usart.c
+
+
+ 2
+ 0
+ 0
+ 0
+ 0
+ 1
+ 2
+ 2
+ 2
+ 2
+ 11
+
+
+ 1
+
+
+
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
stm32f1xx_it.c
1
@@ -583,65 +751,9 @@
- stm32f1xx_hal_tim.c
+ stm32f1xx_hal_i2c.c
1
- ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
-
-
- 2
- 0
- 0
- 0
- 0
- 1
- 2
- 2
- 2
- 2
- 11
-
-
- 1
-
-
-
- 2
- 0
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 0
- 2
- 2
- 2
- 2
- 2
- 0
- 0
- 2
- 2
- 2
- 2
- 2
-
-
-
-
-
-
-
-
-
-
-
- stm32f1xx_hal_tim_ex.c
- 1
- ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
2
@@ -1254,6 +1366,230 @@
+
+ stm32f1xx_hal_spi.c
+ 1
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
+
+
+ 2
+ 0
+ 0
+ 0
+ 0
+ 1
+ 2
+ 2
+ 2
+ 2
+ 11
+
+
+ 1
+
+
+
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
+
+ stm32f1xx_hal_tim.c
+ 1
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
+
+
+ 2
+ 0
+ 0
+ 0
+ 0
+ 1
+ 2
+ 2
+ 2
+ 2
+ 11
+
+
+ 1
+
+
+
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
+
+ stm32f1xx_hal_tim_ex.c
+ 1
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
+
+
+ 2
+ 0
+ 0
+ 0
+ 0
+ 1
+ 2
+ 2
+ 2
+ 2
+ 11
+
+
+ 1
+
+
+
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
+
+ stm32f1xx_hal_uart.c
+ 1
+ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
+
+
+ 2
+ 0
+ 0
+ 0
+ 0
+ 1
+ 2
+ 2
+ 2
+ 2
+ 11
+
+
+ 1
+
+
+
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+ 0
+ 0
+ 2
+ 2
+ 2
+ 2
+ 2
+
+
+
+
+
+
+
+
+
+
@@ -1266,6 +1602,21 @@
+
+ App
+
+
+ key.c
+ 1
+ ..\App\Src\key.c
+
+
+ key.h
+ 5
+ ..\App\Inc\key.h
+
+
+
::CMSIS
@@ -1286,4 +1637,13 @@
+
+
+
+ mfps
+ 1
+
+
+
+
diff --git a/MDK-ARM/mfps/gpio.crf b/MDK-ARM/mfps/gpio.crf
index a61db70..6b35ba2 100644
Binary files a/MDK-ARM/mfps/gpio.crf and b/MDK-ARM/mfps/gpio.crf differ
diff --git a/MDK-ARM/mfps/gpio.d b/MDK-ARM/mfps/gpio.d
index 35d133b..0d96a1a 100644
--- a/MDK-ARM/mfps/gpio.d
+++ b/MDK-ARM/mfps/gpio.d
@@ -25,6 +25,9 @@ mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
+mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
+mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h
mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
+mfps\gpio.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
diff --git a/MDK-ARM/mfps/gpio.o b/MDK-ARM/mfps/gpio.o
index f4fd877..0507bd6 100644
Binary files a/MDK-ARM/mfps/gpio.o and b/MDK-ARM/mfps/gpio.o differ
diff --git a/MDK-ARM/mfps/i2c.crf b/MDK-ARM/mfps/i2c.crf
new file mode 100644
index 0000000..a4ee46a
Binary files /dev/null and b/MDK-ARM/mfps/i2c.crf differ
diff --git a/MDK-ARM/mfps/i2c.d b/MDK-ARM/mfps/i2c.d
new file mode 100644
index 0000000..b398c08
--- /dev/null
+++ b/MDK-ARM/mfps/i2c.d
@@ -0,0 +1,33 @@
+mfps\i2c.o: ../Src/i2c.c
+mfps\i2c.o: ../Inc/i2c.h
+mfps\i2c.o: ../Inc/main.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
+mfps\i2c.o: ../Inc/stm32f1xx_hal_conf.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
+mfps\i2c.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
+mfps\i2c.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h
+mfps\i2c.o: ../Drivers/CMSIS/Include/core_cm3.h
+mfps\i2c.o: C:\Keil_v5\ARM\ARM_Compiler_5.06u7\Bin\..\include\stdint.h
+mfps\i2c.o: ../Drivers/CMSIS/Include/cmsis_version.h
+mfps\i2c.o: ../Drivers/CMSIS/Include/cmsis_compiler.h
+mfps\i2c.o: ../Drivers/CMSIS/Include/cmsis_armcc.h
+mfps\i2c.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
+mfps\i2c.o: C:\Keil_v5\ARM\ARM_Compiler_5.06u7\Bin\..\include\stddef.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
+mfps\i2c.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
diff --git a/MDK-ARM/mfps/i2c.o b/MDK-ARM/mfps/i2c.o
new file mode 100644
index 0000000..2678ca7
Binary files /dev/null and b/MDK-ARM/mfps/i2c.o differ
diff --git a/MDK-ARM/mfps/key.crf b/MDK-ARM/mfps/key.crf
new file mode 100644
index 0000000..550820c
Binary files /dev/null and b/MDK-ARM/mfps/key.crf differ
diff --git a/MDK-ARM/mfps/key.d b/MDK-ARM/mfps/key.d
new file mode 100644
index 0000000..921775a
--- /dev/null
+++ b/MDK-ARM/mfps/key.d
@@ -0,0 +1,33 @@
+mfps\key.o: ..\App\Src\key.c
+mfps\key.o: ..\App\Inc\key.h
+mfps\key.o: ../Inc/main.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
+mfps\key.o: ../Inc/stm32f1xx_hal_conf.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
+mfps\key.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
+mfps\key.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h
+mfps\key.o: ../Drivers/CMSIS/Include/core_cm3.h
+mfps\key.o: C:\Keil_v5\ARM\ARM_Compiler_5.06u7\Bin\..\include\stdint.h
+mfps\key.o: ../Drivers/CMSIS/Include/cmsis_version.h
+mfps\key.o: ../Drivers/CMSIS/Include/cmsis_compiler.h
+mfps\key.o: ../Drivers/CMSIS/Include/cmsis_armcc.h
+mfps\key.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
+mfps\key.o: C:\Keil_v5\ARM\ARM_Compiler_5.06u7\Bin\..\include\stddef.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
+mfps\key.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
diff --git a/MDK-ARM/mfps/key.o b/MDK-ARM/mfps/key.o
new file mode 100644
index 0000000..360f68c
Binary files /dev/null and b/MDK-ARM/mfps/key.o differ
diff --git a/MDK-ARM/mfps/main.crf b/MDK-ARM/mfps/main.crf
index 56c0cfe..4dcae4e 100644
Binary files a/MDK-ARM/mfps/main.crf and b/MDK-ARM/mfps/main.crf differ
diff --git a/MDK-ARM/mfps/main.d b/MDK-ARM/mfps/main.d
index 9198ae8..25ed6a7 100644
--- a/MDK-ARM/mfps/main.d
+++ b/MDK-ARM/mfps/main.d
@@ -24,8 +24,15 @@ mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
+mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h
mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
+mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h
mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h
+mfps\main.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
+mfps\main.o: ../Inc/i2c.h
+mfps\main.o: ../Inc/spi.h
mfps\main.o: ../Inc/tim.h
+mfps\main.o: ../Inc/usart.h
mfps\main.o: ../Inc/gpio.h
+mfps\main.o: ..\App\Inc\key.h
diff --git a/MDK-ARM/mfps/main.o b/MDK-ARM/mfps/main.o
index 7390841..4988eb4 100644
Binary files a/MDK-ARM/mfps/main.o and b/MDK-ARM/mfps/main.o differ
diff --git a/MDK-ARM/mfps/mfps.axf b/MDK-ARM/mfps/mfps.axf
index 9988ccb..a7d223d 100644
Binary files a/MDK-ARM/mfps/mfps.axf and b/MDK-ARM/mfps/mfps.axf differ
diff --git a/MDK-ARM/mfps/mfps.build_log.htm b/MDK-ARM/mfps/mfps.build_log.htm
index 3bc7f7c..250e2ab 100644
--- a/MDK-ARM/mfps/mfps.build_log.htm
+++ b/MDK-ARM/mfps/mfps.build_log.htm
@@ -21,34 +21,41 @@ Target DLL: STLink\ST-LINKIII-KEIL_SWO.dll V3.2.0.0
Dialog DLL: TCM.DLL V1.56.4.0
Project:
-C:\Users\EthanWu\Desktop\work\2024.3.25\mfps\MDK-ARM\mfps.uvprojx
-Project File Date: 03/25/2024
+C:\Users\EthanWu\Desktop\work\2024.3.26\mfps\MDK-ARM\mfps.uvprojx
+Project File Date: 03/26/2024
Output:
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil_v5\ARM\ARM_Compiler_5.06u7\Bin'
Rebuild target 'mfps'
assembling startup_stm32f103xe.s...
-compiling stm32f1xx_hal_rcc_ex.c...
-compiling stm32f1xx_hal_pwr.c...
-compiling stm32f1xx_hal.c...
-compiling main.c...
+compiling stm32f1xx_hal_msp.c...
+compiling stm32f1xx_it.c...
+compiling spi.c...
compiling gpio.c...
+compiling stm32f1xx_hal_rcc_ex.c...
+compiling tim.c...
+compiling i2c.c...
+compiling stm32f1xx_hal.c...
+compiling stm32f1xx_hal_dma.c...
+compiling main.c...
+compiling usart.c...
+compiling stm32f1xx_hal_gpio_ex.c...
compiling stm32f1xx_hal_rcc.c...
compiling stm32f1xx_hal_gpio.c...
-compiling stm32f1xx_hal_gpio_ex.c...
-compiling stm32f1xx_hal_msp.c...
-compiling tim.c...
-compiling stm32f1xx_hal_cortex.c...
-compiling stm32f1xx_hal_dma.c...
-compiling stm32f1xx_it.c...
-compiling stm32f1xx_hal_tim_ex.c...
-compiling stm32f1xx_hal_flash.c...
-compiling stm32f1xx_hal_tim.c...
+compiling stm32f1xx_hal_i2c.c...
compiling system_stm32f1xx.c...
-compiling stm32f1xx_hal_exti.c...
compiling stm32f1xx_hal_flash_ex.c...
+compiling stm32f1xx_hal_cortex.c...
+compiling stm32f1xx_hal_exti.c...
+compiling key.c...
+compiling stm32f1xx_hal_pwr.c...
+compiling stm32f1xx_hal_flash.c...
+compiling stm32f1xx_hal_spi.c...
+compiling stm32f1xx_hal_tim_ex.c...
+compiling stm32f1xx_hal_uart.c...
+compiling stm32f1xx_hal_tim.c...
linking...
-Program Size: Code=3832 RO-data=372 RW-data=16 ZI-data=1704
+Program Size: Code=12000 RO-data=380 RW-data=16 ZI-data=2288
FromELF: creating hex file...
"mfps\mfps.axf" - 0 Error(s), 0 Warning(s).
@@ -73,7 +80,7 @@ Package Vendor: Keil
Collection of Component Files used:
* Component: ARM::CMSIS:CORE@5.6.0
-Build Time Elapsed: 00:00:04
+Build Time Elapsed: 00:00:06