commit 2b0c170e9c9ead6241e2a039bf2d195f5cfb2b7b
parent 7782b67cdcedfa1176aa6a05d7541ad1840ccb43
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Fri, 27 Mar 2026 19:08:19 -0300
Agregar módulo para controlar display por I2C
Diffstat:
15 files changed, 10547 insertions(+), 152 deletions(-)
diff --git a/firmware/.mxproject b/firmware/.mxproject
@@ -1,8 +1,8 @@
[PreviousLibFiles]
-LibFiles=Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.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_uart.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_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/Src/stm32f1xx_hal_uart.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.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_uart.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_usart.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_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_compiler.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm1.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_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.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_rtc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_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_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_rtc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rtc_ex.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/stm32f103xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_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_compiler.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_cm1.h;
[PreviousUsedCubeIDEFiles]
-SourceFiles=Core/Src/main.c;Core/Src/stm32f1xx_it.c;Core/Src/stm32f1xx_hal_msp.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_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/Src/stm32f1xx_hal_uart.c;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Core/Src/system_stm32f1xx.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_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/Src/stm32f1xx_hal_uart.c;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Core/Src/system_stm32f1xx.c;;;
+SourceFiles=Core/Src/main.c;Core/Src/stm32f1xx_it.c;Core/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_rtc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Core/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_rtc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Core/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;Core/Inc;
CDefines=USE_HAL_DRIVER;STM32F103xB;USE_HAL_DRIVER;USE_HAL_DRIVER;
diff --git a/firmware/Core/Inc/main.h b/firmware/Core/Inc/main.h
@@ -31,8 +31,9 @@ extern "C" {
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
-extern UART_HandleTypeDef huart1;
+extern I2C_HandleTypeDef hi2c1;
extern RTC_HandleTypeDef hrtc;
+extern UART_HandleTypeDef huart1;
extern RTC_TimeTypeDef s_time;
extern RTC_DateTypeDef s_date;
@@ -72,14 +73,8 @@ void Error_Handler(void);
#define USART_RX_GPIO_Port GPIOA
#define LD2_Pin GPIO_PIN_5
#define LD2_GPIO_Port GPIOA
-#define D7_Pin GPIO_PIN_6
-#define D7_GPIO_Port GPIOA
-#define D6_Pin GPIO_PIN_7
-#define D6_GPIO_Port GPIOA
#define BTN_B_Pin GPIO_PIN_10
#define BTN_B_GPIO_Port GPIOB
-#define D4_Pin GPIO_PIN_7
-#define D4_GPIO_Port GPIOC
#define TMS_Pin GPIO_PIN_13
#define TMS_GPIO_Port GPIOA
#define TCK_Pin GPIO_PIN_14
@@ -90,12 +85,6 @@ void Error_Handler(void);
#define BTN_C_GPIO_Port GPIOB
#define BTN_D_Pin GPIO_PIN_5
#define BTN_D_GPIO_Port GPIOB
-#define D5_Pin GPIO_PIN_6
-#define D5_GPIO_Port GPIOB
-#define D9_Pin GPIO_PIN_8
-#define D9_GPIO_Port GPIOB
-#define D8_Pin GPIO_PIN_9
-#define D8_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */
diff --git a/firmware/Core/Inc/stm32f1xx_hal_conf.h b/firmware/Core/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 */
diff --git a/firmware/Core/Src/main.c b/firmware/Core/Src/main.c
@@ -44,6 +44,8 @@
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
+I2C_HandleTypeDef hi2c1;
+
RTC_HandleTypeDef hrtc;
UART_HandleTypeDef huart1;
@@ -60,6 +62,7 @@ static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_RTC_Init(void);
+static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
@@ -109,6 +112,7 @@ int main(void)
MX_DMA_Init();
MX_USART1_UART_Init();
MX_RTC_Init();
+ MX_I2C1_Init();
/* USER CODE BEGIN 2 */
/* Application Init */
@@ -183,6 +187,40 @@ void SystemClock_Config(void)
}
/**
+ * @brief I2C1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_I2C1_Init(void)
+{
+
+ /* USER CODE BEGIN I2C1_Init 0 */
+
+ /* USER CODE END I2C1_Init 0 */
+
+ /* USER CODE BEGIN I2C1_Init 1 */
+
+ /* USER CODE END I2C1_Init 1 */
+ hi2c1.Instance = I2C1;
+ hi2c1.Init.ClockSpeed = 100000;
+ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
+ hi2c1.Init.OwnAddress1 = 0;
+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+ hi2c1.Init.OwnAddress2 = 0;
+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+ if (HAL_I2C_Init(&hi2c1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN I2C1_Init 2 */
+
+ /* USER CODE END I2C1_Init 2 */
+
+}
+
+/**
* @brief RTC Initialization Function
* @param None
* @retval None
@@ -315,13 +353,7 @@ static void MX_GPIO_Init(void)
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOA, LD2_Pin|D7_Pin|D6_Pin, GPIO_PIN_RESET);
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, GPIO_PIN_RESET);
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOB, D5_Pin|D9_Pin|D8_Pin, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : BTN_A_Pin */
GPIO_InitStruct.Pin = BTN_A_Pin;
@@ -342,33 +374,12 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
- /*Configure GPIO pins : D7_Pin D6_Pin */
- GPIO_InitStruct.Pin = D7_Pin|D6_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
/*Configure GPIO pins : BTN_B_Pin BTN_C_Pin BTN_D_Pin */
GPIO_InitStruct.Pin = BTN_B_Pin|BTN_C_Pin|BTN_D_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- /*Configure GPIO pin : D4_Pin */
- GPIO_InitStruct.Pin = D4_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(D4_GPIO_Port, &GPIO_InitStruct);
-
- /*Configure GPIO pins : D5_Pin D9_Pin D8_Pin */
- GPIO_InitStruct.Pin = D5_Pin|D9_Pin|D8_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
diff --git a/firmware/Core/Src/stm32f1xx_hal_msp.c b/firmware/Core/Src/stm32f1xx_hal_msp.c
@@ -85,6 +85,74 @@ void HAL_MspInit(void)
}
/**
+ * @brief I2C MSP Initialization
+ * This function configures the hardware resources used in this example
+ * @param hi2c: I2C handle pointer
+ * @retval None
+ */
+void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspInit 0 */
+
+ /* USER CODE END I2C1_MspInit 0 */
+
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**I2C1 GPIO Configuration
+ PB8 ------> I2C1_SCL
+ PB9 ------> I2C1_SDA
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ __HAL_AFIO_REMAP_I2C1_ENABLE();
+
+ /* Peripheral clock enable */
+ __HAL_RCC_I2C1_CLK_ENABLE();
+ /* USER CODE BEGIN I2C1_MspInit 1 */
+
+ /* USER CODE END I2C1_MspInit 1 */
+
+ }
+
+}
+
+/**
+ * @brief I2C MSP De-Initialization
+ * This function freeze the hardware resources used in this example
+ * @param hi2c: I2C handle pointer
+ * @retval None
+ */
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
+{
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspDeInit 0 */
+
+ /* USER CODE END I2C1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_I2C1_CLK_DISABLE();
+
+ /**I2C1 GPIO Configuration
+ PB8 ------> I2C1_SCL
+ PB9 ------> I2C1_SDA
+ */
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8);
+
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
+
+ /* USER CODE BEGIN I2C1_MspDeInit 1 */
+
+ /* USER CODE END I2C1_MspDeInit 1 */
+ }
+
+}
+
+/**
* @brief RTC MSP Initialization
* This function configures the hardware resources used in this example
* @param hrtc: RTC handle pointer
diff --git a/firmware/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h b/firmware/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/firmware/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_i2c.h b/firmware/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/firmware/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c b/firmware/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c
@@ -0,0 +1,7669 @@
+/**
+ ******************************************************************************
+ * @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 or memory 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 or memory 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 or memory 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)
+ {
+ 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 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 or memory 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) ||
+ (CurrentMode == HAL_I2C_MODE_MEM)))
+ {
+ /* 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;
+ uint32_t CurrentXferOptions;
+
+ CurrentXferOptions = hi2c->XferOptions;
+ 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;
+ if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ }
+ else
+ {
+ 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
+ {
+ /* 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->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;
+ if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ }
+ else
+ {
+ 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;
+ if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME))
+ {
+ hi2c->PreviousState = I2C_STATE_NONE;
+ }
+ else
+ {
+ 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/firmware/app/inc/display_i2c.h b/firmware/app/inc/display_i2c.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef _DISPLAY_I2C_H_
+#define _DISPLAY_I2C_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void display_i2c_init();
+void display_i2c_set_cursor_pos(uint8_t x, uint8_t y);
+void display_i2c_write_string(const char *str);
+void display_i2c_clear(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DISPLAY_I2C_H_ */
diff --git a/firmware/app/src/app.c b/firmware/app/src/app.c
@@ -138,6 +138,7 @@ void HAL_SYSTICK_Callback(void)
g_task_buttons_tick_cnt++;
g_task_led_tick_cnt++;
g_task_menu_tick_cnt++;
+
// g_task_temp_sensor_tick_cnt++;
// g_task_actuator_tick_cnt++;
}
diff --git a/firmware/app/src/display.c b/firmware/app/src/display.c
@@ -72,6 +72,19 @@
#define DISPLAY_PIN_D6 13
#define DISPLAY_PIN_D7 14
+#define DISPLAY_PIN_D4_PORT 0
+#define DISPLAY_PIN_D4_PIN 0
+#define DISPLAY_PIN_D5_PORT 0
+#define DISPLAY_PIN_D5_PIN 0
+#define DISPLAY_PIN_D6_PORT 0
+#define DISPLAY_PIN_D6_PIN 0
+#define DISPLAY_PIN_D7_PORT 0
+#define DISPLAY_PIN_D7_PIN 0
+#define DISPLAY_PIN_EN_PORT 0
+#define DISPLAY_PIN_EN_PIN 0
+#define DISPLAY_PIN_RS_PORT 0
+#define DISPLAY_PIN_RS_PIN 0
+
#define DISPLAY_DEL_37US 37ul
#define DISPLAY_DEL_US 5ul
@@ -272,22 +285,22 @@ static void display_pin_write(uint8_t pin_name, int value)
switch(pin_name)
{
case DISPLAY_PIN_D4:
- HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, value);
+ HAL_GPIO_WritePin(DISPLAY_PIN_D4_PORT, DISPLAY_PIN_D4_PIN, value);
break;
case DISPLAY_PIN_D5:
- HAL_GPIO_WritePin(D5_GPIO_Port, D5_Pin, value);
+ HAL_GPIO_WritePin(DISPLAY_PIN_D5_PORT, DISPLAY_PIN_D5_PIN, value);
break;
case DISPLAY_PIN_D6:
- HAL_GPIO_WritePin(D6_GPIO_Port, D6_Pin, value);
+ HAL_GPIO_WritePin(DISPLAY_PIN_D6_PORT, DISPLAY_PIN_D6_PIN, value);
break;
case DISPLAY_PIN_D7:
- HAL_GPIO_WritePin(D7_GPIO_Port, D7_Pin, value);
+ HAL_GPIO_WritePin(DISPLAY_PIN_D7_PORT, DISPLAY_PIN_D7_PIN, value);
break;
case DISPLAY_PIN_RS:
- HAL_GPIO_WritePin(D8_GPIO_Port, D8_Pin, value);
+ HAL_GPIO_WritePin(DISPLAY_PIN_RS_PORT, DISPLAY_PIN_RS_PIN, value);
break;
case DISPLAY_PIN_EN:
- HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, value);
+ HAL_GPIO_WritePin(DISPLAY_PIN_EN_PORT, DISPLAY_PIN_EN_PIN, value);
break;
case DISPLAY_PIN_RW:
diff --git a/firmware/app/src/display_i2c.c b/firmware/app/src/display_i2c.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#include "main.h"
+#include "display_i2c.h"
+#include <stdbool.h>
+
+// Demo includes
+#include "logger.h"
+#include "dwt.h"
+#include "systick.h"
+
+#define DISPLAY_I2C_ADDRESS 0x27
+
+#define DISPLAY_CMD_CLEAR_DISPLAY 0b00000001
+#define DISPLAY_CMD_SET_CURSOR_HOME 0b00000010
+#define DISPLAY_CMD_ENTRY_MODE_SET 0b00000100
+#define DISPLAY_CMD_DISPLAY_CONTROL 0b00001000
+#define DISPLAY_CMD_FUNCTION_SET 0b00100000
+#define DISPLAY_DDRAM_ADDR 0b10000000
+
+#define DISPLAY_CMD_FUNCTION_SET_8BITS 0b00010000
+#define DISPLAY_CMD_FUNCTION_SET_4BITS 0b00100000
+#define DISPLAY_CMD_FUNCTION_SET_5x8DOTS 0b00000000
+#define DISPLAY_CMD_FUNCTION_SET_2LINES 0b00001000
+
+#define DISPLAY_CMD_ENTRY_MODE_SET_INCREMENT_CURSOR 0b00000010
+#define DISPLAY_CMD_ENTRY_MODE_SET_DECREMENT_CURSOR 0b00000000
+#define DISPLAY_CMD_ENTRY_MODE_SET_SHIFT 0b00000001
+#define DISPLAY_CMD_ENTRY_MODE_SET_NO_SHIFT 0b00000000
+
+#define DISPLAY_CMD_DISPLAY_CONTROL_DISPLAY_ON 0b00000100
+#define DISPLAY_CMD_DISPLAY_CONTROL_DISPLAY_OFF 0b00000000
+#define DISPLAY_CMD_DISPLAY_CONTROL_CURSOR_ON 0b00000010
+#define DISPLAY_CMD_DISPLAY_CONTROL_CURSOR_OFF 0b00000000
+#define DISPLAY_CMD_DISPLAY_CONTROL_BLINK_ON 0b00000001
+#define DISPLAY_CMD_DISPLAY_CONTROL_BLINK_OFF 0b00000000
+
+#define DISPLAY_LINE1_FIRST_CHARACTER_ADDRESS 0
+#define DISPLAY_LINE2_FIRST_CHARACTER_ADDRESS 64
+#define DISPLAY_LINE3_FIRST_CHARACTER_ADDRESS 20
+#define DISPLAY_LINE4_FIRST_CHARACTER_ADDRESS 84
+
+// Private functions declaration
+void display_i2c_send_cmd(uint8_t cmd);
+void display_i2c_send_data(uint8_t data);
+
+// Public functions definition
+void display_i2c_init(void)
+{
+ HAL_Delay(50);
+
+ display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
+ DISPLAY_CMD_FUNCTION_SET_8BITS);
+ HAL_Delay(5);
+
+ display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
+ DISPLAY_CMD_FUNCTION_SET_8BITS);
+ HAL_Delay(1);
+
+ display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
+ DISPLAY_CMD_FUNCTION_SET_8BITS);
+ HAL_Delay(1);
+
+ display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
+ DISPLAY_CMD_FUNCTION_SET_4BITS);
+ HAL_Delay(1);
+
+ display_i2c_send_cmd(DISPLAY_CMD_FUNCTION_SET |
+ DISPLAY_CMD_FUNCTION_SET_4BITS |
+ DISPLAY_CMD_FUNCTION_SET_2LINES |
+ DISPLAY_CMD_FUNCTION_SET_5x8DOTS);
+ HAL_Delay(1);
+
+ display_i2c_send_cmd(DISPLAY_CMD_DISPLAY_CONTROL |
+ DISPLAY_CMD_DISPLAY_CONTROL_DISPLAY_OFF |
+ DISPLAY_CMD_DISPLAY_CONTROL_CURSOR_OFF |
+ DISPLAY_CMD_DISPLAY_CONTROL_BLINK_OFF);
+ HAL_Delay(1);
+
+ display_i2c_send_cmd(DISPLAY_CMD_CLEAR_DISPLAY);
+ HAL_Delay(1);
+
+ display_i2c_send_cmd(DISPLAY_CMD_ENTRY_MODE_SET |
+ DISPLAY_CMD_ENTRY_MODE_SET_INCREMENT_CURSOR |
+ DISPLAY_CMD_ENTRY_MODE_SET_NO_SHIFT);
+ HAL_Delay(1);
+
+ display_i2c_send_cmd(DISPLAY_CMD_DISPLAY_CONTROL |
+ DISPLAY_CMD_DISPLAY_CONTROL_DISPLAY_ON |
+ DISPLAY_CMD_DISPLAY_CONTROL_CURSOR_OFF |
+ DISPLAY_CMD_DISPLAY_CONTROL_BLINK_OFF);
+ HAL_Delay(1);
+}
+
+void display_i2c_set_cursor_pos(uint8_t x, uint8_t y)
+{
+ switch (y)
+ {
+ case 0:
+ display_i2c_send_cmd(DISPLAY_DDRAM_ADDR |
+ (DISPLAY_LINE1_FIRST_CHARACTER_ADDRESS + x));
+ break;
+ case 1:
+ display_i2c_send_cmd(DISPLAY_DDRAM_ADDR |
+ (DISPLAY_LINE2_FIRST_CHARACTER_ADDRESS + x));
+ break;
+ }
+}
+
+void display_i2c_clear(void)
+{
+ display_i2c_send_cmd(DISPLAY_CMD_CLEAR_DISPLAY);
+ HAL_Delay(1);
+}
+
+void display_i2c_write_string(const char *str)
+{
+ while (*str)
+ {
+ display_i2c_send_data(*str++);
+ }
+}
+
+// Private functions definitions
+void display_i2c_send_cmd(uint8_t cmd)
+{
+ uint8_t data_t[4], data_u, data_l;
+
+ data_u = (cmd & 0xF0); // extract upper 4 bits
+ data_l = ((cmd << 4) & 0xF0); // extract lower 4 bits
+
+ // send upper 4 bits with enable pulse
+ data_t[0] = data_u | 0x0C; // EN=1, RS=0 -> bxxxx1100
+ data_t[1] = data_u | 0x08; // EN=0, RS=0 -> bxxxx1000
+
+ // send lower 4 bits with enable pulse
+ data_t[2] = data_l | 0x0C; // EN=1, RS=0 -> bxxxx1100
+ data_t[3] = data_l | 0x08; // EN=0, RS=0 -> bxxxx1000
+
+ HAL_I2C_Master_Transmit(&hi2c1, DISPLAY_I2C_ADDRESS<<1, (uint8_t*)data_t, 4, 100);
+}
+
+void display_i2c_send_data(uint8_t data)
+{
+ uint8_t data_u, data_l;
+ uint8_t data_t[4];
+
+ data_u = (data & 0xF0);
+ data_l = ((data << 4) & 0XF0);
+
+ data_t[0] = data_u | 0x0D;
+ data_t[1] = data_u | 0x09;
+ data_t[2] = data_l | 0x0D;
+ data_t[3] = data_l | 0x09;
+
+ HAL_I2C_Master_Transmit(&hi2c1, DISPLAY_I2C_ADDRESS<<1, (uint8_t *)data_t, 4, 100);
+}
diff --git a/firmware/app/src/task_menu.c b/firmware/app/src/task_menu.c
@@ -16,7 +16,7 @@
#include "app.h"
#include "task_menu_attribute.h"
#include "task_menu_interface.h"
-#include "display.h"
+#include "display_i2c.h"
#define G_TASK_MEN_TICK_INI 0ul
#define G_TASK_MEN_TICK_CNT_INI 0ul
@@ -26,8 +26,6 @@ task_menu_dta_t task_menu_dta = {
G_TASK_MEN_TICK_INI, ST_MEN_IDLE, EV_MEN_ST_IDLE, false
};
-#define MENU_DTA_QTY (sizeof(task_menu_dta)/sizeof(task_menu_dta_t))
-
// Private functions declaration
void task_menu_statechart(void);
@@ -52,17 +50,17 @@ void task_menu_init(void *parameters)
init_queue_event_task_menu();
+ g_menu_prev_state = ST_MEN_IDLE;
p_task_menu_dta = &task_menu_dta;
-
p_task_menu_dta->state = ST_MEN_IDLE;
- g_menu_prev_state = ST_MEN_IDLE;
-
p_task_menu_dta->event = EV_MEN_ST_IDLE;
p_task_menu_dta->event_flag = false;
- display_init(DISPLAY_CONNECTION_GPIO_4BITS);
- display_set_cursor_pos(0, 0);
- display_write_string("Idle");
+ display_i2c_init();
+ display_i2c_set_cursor_pos(0, 0);
+ display_i2c_write_string("Idle");
+ display_i2c_set_cursor_pos(0, 1);
+ display_i2c_write_string("Hello!");
g_display_update = false;
LOGGER_INFO("Done initializing `task_menu`");
@@ -118,28 +116,6 @@ void menu_set_state(task_menu_st_t new_state)
}
}
-int count_digits(int n) {
- int count = 0;
-
- if (n == 0)
- {
- return 1;
- }
-
- if (n < 0)
- {
- n = -n;
- }
-
- while (n > 0)
- {
- n /= 10;
- count++;
- }
-
- return count;
-}
-
void task_menu_statechart(void)
{
task_menu_dta_t *p_task_menu_dta;
@@ -175,21 +151,11 @@ void task_menu_statechart(void)
if (g_display_update)
{
g_display_update = false;
- display_clear();
+ display_i2c_clear();
memset(menu_row_str, '\0', sizeof(menu_row_str));
- /*
- uint8_t temp_digits = count_digits(g_DS18B20_temp);
- snprintf(menu_row_str, 20, "%-*d%cC%*d",
- temp_digits, g_DS18B20_temp, 0xDF,
- 16-temp_digits-2, g_DS18B20_update_count);
- display_write_string(menu_row_str);
- display_set_cursor_pos(16-4, 1);
- snprintf(menu_row_str, 20, "%4d", g_DS18B20_DMA_error_count);
- */
-
snprintf(menu_row_str, 20, "Idle");
- display_write_string(menu_row_str);
+ display_i2c_write_string(menu_row_str);
}
if (true == p_task_menu_dta->event_flag)
@@ -221,14 +187,14 @@ void task_menu_statechart(void)
if (g_display_update)
{
g_display_update = false;
- display_clear();
+ display_i2c_clear();
memset(menu_row_str, '\0', sizeof(menu_row_str));
HAL_RTC_GetTime(&hrtc, &s_time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &s_date, RTC_FORMAT_BIN);
sprintf(menu_row_str, "%02d:%02d:%02d",
s_time.Hours, s_time.Minutes, s_time.Seconds);
- display_write_string(menu_row_str);
+ display_i2c_write_string(menu_row_str);
}
if (true == p_task_menu_dta->event_flag)
diff --git a/firmware/app/src/task_system.c b/firmware/app/src/task_system.c
@@ -155,6 +155,7 @@ void task_system_statechart(void)
case EV_SYS_BTN_D_ACTIVE:
p_task_system_dta->state = ST_SYS_CLOCK;
put_event_task_menu(EV_MEN_ST_CLOCK);
+ put_event_task_led(EV_LED_XX_BLINK, ID_LED_A);
break;
default: break;
}
@@ -168,8 +169,10 @@ void task_system_statechart(void)
switch (p_task_system_dta->event)
{
case EV_SYS_BTN_A_ACTIVE:
+ case EV_SYS_BTN_D_ACTIVE:
p_task_system_dta->state = ST_SYS_IDLE;
put_event_task_menu(EV_MEN_ST_IDLE);
+ put_event_task_led(EV_LED_XX_OFF, ID_LED_A);
break;
case EV_SYS_BTN_B_ACTIVE:
task_system_rtc_increment_hour();
@@ -179,8 +182,6 @@ void task_system_statechart(void)
task_system_rtc_increment_min();
put_event_task_menu(EV_MEN_DISPLAY_UPDATE);
break;
- case EV_SYS_BTN_D_ACTIVE:
- break;
default: break;
}
}
diff --git a/firmware/tdse-tf_3-02.ioc b/firmware/tdse-tf_3-02.ioc
@@ -29,40 +29,37 @@ KeepUserPlacement=false
Mcu.CPN=STM32F103RBT6
Mcu.Family=STM32F1
Mcu.IP0=DMA
-Mcu.IP1=NVIC
-Mcu.IP2=RCC
-Mcu.IP3=RTC
-Mcu.IP4=SYS
-Mcu.IP5=USART1
-Mcu.IPNb=6
+Mcu.IP1=I2C1
+Mcu.IP2=NVIC
+Mcu.IP3=RCC
+Mcu.IP4=RTC
+Mcu.IP5=SYS
+Mcu.IP6=USART1
+Mcu.IPNb=7
Mcu.Name=STM32F103R(8-B)Tx
Mcu.Package=LQFP64
Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PC14-OSC32_IN
-Mcu.Pin10=PB10
-Mcu.Pin11=PC7
-Mcu.Pin12=PA9
-Mcu.Pin13=PA13
-Mcu.Pin14=PA14
-Mcu.Pin15=PB3
-Mcu.Pin16=PB4
-Mcu.Pin17=PB5
-Mcu.Pin18=PB6
-Mcu.Pin19=PB8
+Mcu.Pin10=PA13
+Mcu.Pin11=PA14
+Mcu.Pin12=PB3
+Mcu.Pin13=PB4
+Mcu.Pin14=PB5
+Mcu.Pin15=PB8
+Mcu.Pin16=PB9
+Mcu.Pin17=VP_RTC_VS_RTC_Activate
+Mcu.Pin18=VP_RTC_VS_RTC_Calendar
+Mcu.Pin19=VP_RTC_No_RTC_Output
Mcu.Pin2=PC15-OSC32_OUT
-Mcu.Pin20=PB9
-Mcu.Pin21=VP_RTC_VS_RTC_Activate
-Mcu.Pin22=VP_RTC_VS_RTC_Calendar
-Mcu.Pin23=VP_RTC_No_RTC_Output
-Mcu.Pin24=VP_SYS_VS_Systick
+Mcu.Pin20=VP_SYS_VS_Systick
Mcu.Pin3=PD0-OSC_IN
Mcu.Pin4=PD1-OSC_OUT
Mcu.Pin5=PA2
Mcu.Pin6=PA3
Mcu.Pin7=PA5
-Mcu.Pin8=PA6
-Mcu.Pin9=PA7
-Mcu.PinsNb=25
+Mcu.Pin8=PB10
+Mcu.Pin9=PA9
+Mcu.PinsNb=21
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103RBTx
@@ -114,16 +111,6 @@ PA5.GPIO_PuPd=GPIO_NOPULL
PA5.GPIO_Speed=GPIO_SPEED_FREQ_LOW
PA5.Locked=true
PA5.Signal=GPIO_Output
-PA6.GPIOParameters=GPIO_PuPd,GPIO_Label
-PA6.GPIO_Label=D7
-PA6.GPIO_PuPd=GPIO_PULLUP
-PA6.Locked=true
-PA6.Signal=GPIO_Output
-PA7.GPIOParameters=GPIO_PuPd,GPIO_Label
-PA7.GPIO_Label=D6
-PA7.GPIO_PuPd=GPIO_PULLUP
-PA7.Locked=true
-PA7.Signal=GPIO_Output
PA9.GPIOParameters=GPIO_Mode
PA9.GPIO_Mode=GPIO_MODE_AF_OD
PA9.Mode=Half_duplex(single_wire_mode)
@@ -147,23 +134,12 @@ PB5.GPIO_Label=BTN_D
PB5.GPIO_PuPd=GPIO_PULLUP
PB5.Locked=true
PB5.Signal=GPIO_Input
-PB6.GPIOParameters=GPIO_PuPd,GPIO_Label
-PB6.GPIO_Label=D5
-PB6.GPIO_PuPd=GPIO_PULLUP
-PB6.Locked=true
-PB6.Signal=GPIO_Output
-PB8.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
-PB8.GPIO_Label=D9
-PB8.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
-PB8.GPIO_PuPd=GPIO_PULLUP
PB8.Locked=true
-PB8.Signal=GPIO_Output
-PB9.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
-PB9.GPIO_Label=D8
-PB9.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
-PB9.GPIO_PuPd=GPIO_PULLUP
+PB8.Mode=I2C
+PB8.Signal=I2C1_SCL
PB9.Locked=true
-PB9.Signal=GPIO_Output
+PB9.Mode=I2C
+PB9.Signal=I2C1_SDA
PC13-TAMPER-RTC.GPIOParameters=GPIO_PuPd,GPIO_Label
PC13-TAMPER-RTC.GPIO_Label=BTN_A
PC13-TAMPER-RTC.GPIO_PuPd=GPIO_NOPULL
@@ -175,11 +151,6 @@ PC14-OSC32_IN.Signal=RCC_OSC32_IN
PC15-OSC32_OUT.Locked=true
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
-PC7.GPIOParameters=GPIO_PuPd,GPIO_Label
-PC7.GPIO_Label=D4
-PC7.GPIO_PuPd=GPIO_PULLUP
-PC7.Locked=true
-PC7.Signal=GPIO_Output
PD0-OSC_IN.Locked=true
PD0-OSC_IN.Mode=HSE-External-Clock-Source
PD0-OSC_IN.Signal=RCC_OSC_IN
@@ -218,7 +189,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true,6-MX_I2C1_Init-I2C1-false-HAL-true
RCC.ADCFreqValue=32000000
RCC.AHBFreq_Value=64000000
RCC.APB1CLKDivider=RCC_HCLK_DIV2