ソースを参照

Basic logic ADC, DAC, Timer

Aleksandr Nagaev 3 年 前
コミット
b3e1f760b2

+ 11 - 3
stm32workspace/dosimeter-fw/.cproject

@@ -23,7 +23,8 @@
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.1319660060" name="Floating-point unit" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/>
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.56698211" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.991454248" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.315895780" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F446RCTx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Drivers/CMSIS/Include | ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy | ../USB_DEVICE/App | ../USB_DEVICE/Target | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc ||  ||  || USE_HAL_DRIVER | STM32F446xx ||  || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE ||  ||  || ${workspace_loc:/${ProjName}/STM32F446RCTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.315895780" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F446RCTx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../USB_DEVICE/Target | ../Drivers/CMSIS/Include | ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc | ../USB_DEVICE/App | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy ||  ||  || USE_HAL_DRIVER | STM32F446xx ||  || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE ||  ||  || ${workspace_loc:/${ProjName}/STM32F446RCTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.586039653" name="Use float with printf from newlib-nano (-u _printf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="true" valueType="boolean"/>
 							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.115815271" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
 							<builder buildPath="${workspace_loc:/dosimeter-test}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.1086190477" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
 							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.189327650" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
@@ -109,7 +110,7 @@
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.772578890" name="Floating-point unit" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/>
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.112962376" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.529295804" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.1045921442" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F446RCTx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Drivers/CMSIS/Include | ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy | ../USB_DEVICE/App | ../USB_DEVICE/Target | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc ||  ||  || USE_HAL_DRIVER | STM32F446xx ||  || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE ||  ||  || ${workspace_loc:/${ProjName}/STM32F446RCTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.1045921442" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32F446RCTx || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../USB_DEVICE/Target | ../Drivers/CMSIS/Include | ../Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc | ../USB_DEVICE/App | ../Drivers/CMSIS/Device/ST/STM32F4xx/Include | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc | ../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy ||  ||  || USE_HAL_DRIVER | STM32F446xx ||  || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE ||  ||  || ${workspace_loc:/${ProjName}/STM32F446RCTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/>
 							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1745157795" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
 							<builder buildPath="${workspace_loc:/dosimeter-test}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.1915635962" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
 							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.9631759" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
@@ -184,5 +185,12 @@
 			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
 		</scannerConfigBuildInfo>
 	</storageModule>
-	<storageModule moduleId="refreshScope"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/dosimeter-fw"/>
+		</configuration>
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/dosimeter-fw"/>
+		</configuration>
+	</storageModule>
 </cproject>

ファイルの差分が大きいため隠しています
+ 0 - 0
stm32workspace/dosimeter-fw/.mxproject


+ 11 - 1
stm32workspace/dosimeter-fw/Core/Inc/main.h

@@ -54,11 +54,21 @@ extern "C" {
 void Error_Handler(void);
 
 /* USER CODE BEGIN EFP */
-
+void LED_TurnOn(uint8_t);
+void LED_TurnOff(uint8_t);
+void LED_Toggle(uint8_t);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
 /* USER CODE BEGIN Private defines */
+enum LED_Colors { LED_BLUE=0, LED_GREEN, LED_YELLOW };
+enum BTN_Positions { BTN_LEFT, BTN_RIGHT, BTN_UP, BTN_DOWN, BTN_CENTER };
+
+#define LM73_I2C_ADDR	0x92
+
+#define SIPM_VBR        24650
+#define SIPM_OVER_MIN   1000
+#define SIPM_OVER_MAX   5000
 
 /* USER CODE END Private defines */
 

+ 2 - 2
stm32workspace/dosimeter-fw/Core/Inc/stm32f4xx_hal_conf.h

@@ -52,7 +52,7 @@
 /* #define HAL_SRAM_MODULE_ENABLED   */
 /* #define HAL_SDRAM_MODULE_ENABLED   */
 /* #define HAL_HASH_MODULE_ENABLED   */
-/* #define HAL_I2C_MODULE_ENABLED   */
+#define HAL_I2C_MODULE_ENABLED
 /* #define HAL_I2S_MODULE_ENABLED   */
 /* #define HAL_IWDG_MODULE_ENABLED   */
 /* #define HAL_LTDC_MODULE_ENABLED   */
@@ -67,7 +67,7 @@
 /* #define HAL_USART_MODULE_ENABLED   */
 /* #define HAL_IRDA_MODULE_ENABLED   */
 /* #define HAL_SMARTCARD_MODULE_ENABLED   */
-#define HAL_SMBUS_MODULE_ENABLED
+/* #define HAL_SMBUS_MODULE_ENABLED   */
 /* #define HAL_WWDG_MODULE_ENABLED   */
 #define HAL_PCD_MODULE_ENABLED
 /* #define HAL_HCD_MODULE_ENABLED   */

+ 4 - 1
stm32workspace/dosimeter-fw/Core/Inc/stm32f4xx_it.h

@@ -47,7 +47,6 @@
 /* USER CODE END EM */
 
 /* Exported functions prototypes ---------------------------------------------*/
-void NMI_Handler(void);
 void HardFault_Handler(void);
 void MemManage_Handler(void);
 void BusFault_Handler(void);
@@ -56,6 +55,10 @@ void SVC_Handler(void);
 void DebugMon_Handler(void);
 void PendSV_Handler(void);
 void SysTick_Handler(void);
+void EXTI1_IRQHandler(void);
+void ADC_IRQHandler(void);
+void EXTI9_5_IRQHandler(void);
+void TIM3_IRQHandler(void);
 void OTG_FS_IRQHandler(void);
 /* USER CODE BEGIN EFP */
 

+ 246 - 25
stm32workspace/dosimeter-fw/Core/Src/main.c

@@ -46,7 +46,7 @@ ADC_HandleTypeDef hadc2;
 
 DAC_HandleTypeDef hdac;
 
-SMBUS_HandleTypeDef hsmbus1;
+I2C_HandleTypeDef hi2c1;
 
 RTC_HandleTypeDef hrtc;
 
@@ -54,11 +54,18 @@ SPI_HandleTypeDef hspi1;
 SPI_HandleTypeDef hspi2;
 
 TIM_HandleTypeDef htim2;
+TIM_HandleTypeDef htim3;
 
 UART_HandleTypeDef huart1;
 
 /* USER CODE BEGIN PV */
+struct FlagsStr {
+  uint8_t Adc1_CC;
+  uint8_t Adc2_CC;
+  uint8_t Tim3_PE;
+} Flags;
 
+uint32_t VccVal_mV;
 /* USER CODE END PV */
 
 /* Private function prototypes -----------------------------------------------*/
@@ -67,18 +74,129 @@ static void MX_GPIO_Init(void);
 static void MX_ADC1_Init(void);
 static void MX_ADC2_Init(void);
 static void MX_DAC_Init(void);
-static void MX_I2C1_SMBUS_Init(void);
+static void MX_I2C1_Init(void);
 static void MX_RTC_Init(void);
 static void MX_SPI1_Init(void);
 static void MX_SPI2_Init(void);
 static void MX_USART1_UART_Init(void);
 static void MX_TIM2_Init(void);
+static void MX_TIM3_Init(void);
 /* USER CODE BEGIN PFP */
 
 /* USER CODE END PFP */
 
 /* Private user code ---------------------------------------------------------*/
 /* USER CODE BEGIN 0 */
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+  switch(GPIO_Pin)
+  {
+    case GPIO_PIN_1:
+      LED_Toggle(LED_BLUE);
+      if(HAL_ADC_GetState(&hadc2) & HAL_ADC_STATE_READY)
+        HAL_ADC_Start_IT(&hadc2);
+      break;
+    case GPIO_PIN_6:
+      break;
+    case GPIO_PIN_7:
+      break;
+    case GPIO_PIN_8:
+      break;
+    case GPIO_PIN_9:
+      break;
+    default:
+      break;
+  }
+}
+
+void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
+{
+  if(hadc->Instance == ADC1)
+  {
+    Flags.Adc1_CC = 1;
+  }
+
+  if(hadc->Instance == ADC2)
+  {
+    Flags.Adc2_CC = 1;
+  }
+}
+
+void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
+{
+  if(htim->Instance == TIM3)
+    Flags.Tim3_PE = 1;
+}
+
+void LED_TurnOn(uint8_t color)
+{
+  switch(color)
+  {
+    case LED_BLUE:
+      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
+      break;
+    case LED_GREEN:
+      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
+      break;
+    case LED_YELLOW:
+      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
+      break;
+  }
+}
+
+void LED_TurnOff(uint8_t color)
+{
+  switch(color)
+  {
+    case LED_BLUE:
+      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
+      break;
+    case LED_GREEN:
+      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
+      break;
+    case LED_YELLOW:
+      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
+      break;
+  }
+}
+
+void LED_Toggle(uint8_t color)
+{
+  switch(color)
+  {
+    case LED_BLUE:
+      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
+      break;
+    case LED_GREEN:
+      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
+      break;
+    case LED_YELLOW:
+      HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
+      break;
+  }
+}
+
+float LM73_GetTemp()
+{
+  uint8_t temp[2] = { 0, 0 };
+  HAL_I2C_Master_Transmit(&hi2c1, LM73_I2C_ADDR, &temp[0], 1, 10);
+  HAL_I2C_Master_Receive(&hi2c1, LM73_I2C_ADDR, &temp[0], 2, 10);
+  uint16_t temp_result = (((uint16_t)temp[0] << 8) | (uint16_t)temp[1]) >> 5;
+  return ((float)temp_result / 4.0);
+}
+
+void SetSIPMVoltage(uint32_t voltage)
+{
+  voltage = voltage / 11; // OpAmp gain = 11;
+  uint32_t dac_val = (voltage * 4095UL) / VccVal_mV;
+  HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, dac_val);
+}
+
+void SetThresholdVoltage(uint32_t voltage)
+{
+  uint32_t dac_val = (voltage * 4095UL) / VccVal_mV;
+  HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, dac_val);
+}
 
 /* USER CODE END 0 */
 
@@ -113,23 +231,65 @@ int main(void)
   MX_ADC1_Init();
   MX_ADC2_Init();
   MX_DAC_Init();
-  MX_I2C1_SMBUS_Init();
+  MX_I2C1_Init();
   MX_RTC_Init();
   MX_SPI1_Init();
   MX_SPI2_Init();
   MX_USART1_UART_Init();
   MX_USB_DEVICE_Init();
   MX_TIM2_Init();
+  MX_TIM3_Init();
   /* USER CODE BEGIN 2 */
   ST7735_Init();
-
+  ST7735_FillScreen(ST7735_BLACK);
   ST7735_WriteString(0, 0, "Display ready", Font_7x10, ST7735_GREEN, ST7735_BLACK);
   /* USER CODE END 2 */
 
   /* Infinite loop */
   /* USER CODE BEGIN WHILE */
+  HAL_TIM_Base_Start_IT(&htim3);
+  HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
+  HAL_DAC_Start(&hdac, DAC_CHANNEL_2);
+  HAL_ADC_Start_IT(&hadc1);
+
+  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET);
+
+  char tempstr[32];
+  uint8_t counts = 0;
+  uint8_t spectrum[4096];
+
   while (1)
   {
+    sprintf(tempstr, "Temp: - %06.2f -", LM73_GetTemp());
+
+    if(Flags.Adc1_CC)
+    {
+      Flags.Adc1_CC = 0;
+      VccVal_mV = *VREFINT_CAL_ADDR * VREFINT_CAL_VREF / HAL_ADC_GetValue(&hadc1);
+      SetSIPMVoltage(SIPM_VBR + 2500);
+      SetThresholdVoltage(100);
+      HAL_ADC_Start_IT(&hadc1);
+    }
+
+    if(Flags.Adc2_CC)
+    {
+      Flags.Adc2_CC = 0;
+      spectrum[HAL_ADC_GetValue(&hadc2)]++;
+      counts++;
+    }
+
+    if(Flags.Tim3_PE)
+    {
+      Flags.Tim3_PE = 0;
+      ST7735_WriteString(0, 10, tempstr, Font_7x10, ST7735_CYAN, ST7735_BLACK);
+      sprintf(tempstr, "Vcc:  - %04.2f -", (float)VccVal_mV / 1000.0);
+      ST7735_WriteString(0, 20, tempstr, Font_7x10, ST7735_RED, ST7735_BLACK);
+
+      sprintf(tempstr, "- %.3u -", counts);
+      ST7735_WriteString(0, 50, tempstr, Font_16x26, ST7735_RED, ST7735_BLACK);
+    }
+
+    //HAL_Delay(100);
 
     /* USER CODE END WHILE */
 
@@ -222,7 +382,7 @@ static void MX_ADC1_Init(void)
   */
   sConfig.Channel = ADC_CHANNEL_VREFINT;
   sConfig.Rank = 1;
-  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
   {
     Error_Handler();
@@ -272,7 +432,7 @@ static void MX_ADC2_Init(void)
   */
   sConfig.Channel = ADC_CHANNEL_14;
   sConfig.Rank = 1;
-  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+  sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
   if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
   {
     Error_Handler();
@@ -310,7 +470,7 @@ static void MX_DAC_Init(void)
   /** DAC channel OUT1 config
   */
   sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
-  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
   if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
   {
     Error_Handler();
@@ -332,7 +492,7 @@ static void MX_DAC_Init(void)
   * @param None
   * @retval None
   */
-static void MX_I2C1_SMBUS_Init(void)
+static void MX_I2C1_Init(void)
 {
 
   /* USER CODE BEGIN I2C1_Init 0 */
@@ -342,17 +502,16 @@ static void MX_I2C1_SMBUS_Init(void)
   /* USER CODE BEGIN I2C1_Init 1 */
 
   /* USER CODE END I2C1_Init 1 */
-  hsmbus1.Instance = I2C1;
-  hsmbus1.Init.ClockSpeed = 100000;
-  hsmbus1.Init.OwnAddress1 = 0;
-  hsmbus1.Init.AddressingMode = SMBUS_ADDRESSINGMODE_7BIT;
-  hsmbus1.Init.DualAddressMode = SMBUS_DUALADDRESS_DISABLE;
-  hsmbus1.Init.OwnAddress2 = 0;
-  hsmbus1.Init.GeneralCallMode = SMBUS_GENERALCALL_DISABLE;
-  hsmbus1.Init.NoStretchMode = SMBUS_NOSTRETCH_DISABLE;
-  hsmbus1.Init.PacketErrorCheckMode = SMBUS_PEC_DISABLE;
-  hsmbus1.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE;
-  if (HAL_SMBUS_Init(&hsmbus1) != HAL_OK)
+  hi2c1.Instance = I2C1;
+  hi2c1.Init.ClockSpeed = 50000;
+  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();
   }
@@ -549,6 +708,51 @@ static void MX_TIM2_Init(void)
 
 }
 
+/**
+  * @brief TIM3 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_TIM3_Init(void)
+{
+
+  /* USER CODE BEGIN TIM3_Init 0 */
+
+  /* USER CODE END TIM3_Init 0 */
+
+  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
+  TIM_MasterConfigTypeDef sMasterConfig = {0};
+
+  /* USER CODE BEGIN TIM3_Init 1 */
+
+  /* USER CODE END TIM3_Init 1 */
+  htim3.Instance = TIM3;
+  htim3.Init.Prescaler = 1000;
+  htim3.Init.CounterMode = TIM_COUNTERMODE_DOWN;
+  htim3.Init.Period = 8000;
+  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
+  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
+  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  /* USER CODE BEGIN TIM3_Init 2 */
+
+  /* USER CODE END TIM3_Init 2 */
+
+}
+
 /**
   * @brief USART1 Initialization Function
   * @param None
@@ -621,10 +825,8 @@ static void MX_GPIO_Init(void)
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
-  /*Configure GPIO pins : PC2 PC6 PC7 PC8
-                           PC9 */
-  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
-                          |GPIO_PIN_9;
+  /*Configure GPIO pin : PC2 */
+  GPIO_InitStruct.Pin = GPIO_PIN_2;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
@@ -644,10 +846,22 @@ static void MX_GPIO_Init(void)
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
-  /*Configure GPIO pin : PA8 */
+  /*Configure GPIO pins : PC6 PC7 PC9 */
+  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_9;
+  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+  /*Configure GPIO pin : PC8 */
   GPIO_InitStruct.Pin = GPIO_PIN_8;
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+  /*Configure GPIO pin : PA8 */
+  GPIO_InitStruct.Pin = GPIO_PIN_8;
+  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
   /*Configure GPIO pin : PA15 */
@@ -664,6 +878,13 @@ static void MX_GPIO_Init(void)
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
+  /* EXTI interrupt init*/
+  HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
+  HAL_NVIC_EnableIRQ(EXTI1_IRQn);
+
+  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
+  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
+
 }
 
 /* USER CODE BEGIN 4 */

+ 61 - 8
stm32workspace/dosimeter-fw/Core/Src/stm32f4xx_hal_msp.c

@@ -93,6 +93,9 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
   /* USER CODE END ADC1_MspInit 0 */
     /* Peripheral clock enable */
     __HAL_RCC_ADC1_CLK_ENABLE();
+    /* ADC1 interrupt Init */
+    HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
+    HAL_NVIC_EnableIRQ(ADC_IRQn);
   /* USER CODE BEGIN ADC1_MspInit 1 */
 
   /* USER CODE END ADC1_MspInit 1 */
@@ -114,6 +117,9 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
+    /* ADC2 interrupt Init */
+    HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
+    HAL_NVIC_EnableIRQ(ADC_IRQn);
   /* USER CODE BEGIN ADC2_MspInit 1 */
 
   /* USER CODE END ADC2_MspInit 1 */
@@ -136,6 +142,16 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
   /* USER CODE END ADC1_MspDeInit 0 */
     /* Peripheral clock disable */
     __HAL_RCC_ADC1_CLK_DISABLE();
+
+    /* ADC1 interrupt DeInit */
+  /* USER CODE BEGIN ADC1:ADC_IRQn disable */
+    /**
+    * Uncomment the line below to disable the "ADC_IRQn" interrupt
+    * Be aware, disabling shared interrupt may affect other IPs
+    */
+    /* HAL_NVIC_DisableIRQ(ADC_IRQn); */
+  /* USER CODE END ADC1:ADC_IRQn disable */
+
   /* USER CODE BEGIN ADC1_MspDeInit 1 */
 
   /* USER CODE END ADC1_MspDeInit 1 */
@@ -153,6 +169,15 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
     */
     HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4);
 
+    /* ADC2 interrupt DeInit */
+  /* USER CODE BEGIN ADC2:ADC_IRQn disable */
+    /**
+    * Uncomment the line below to disable the "ADC_IRQn" interrupt
+    * Be aware, disabling shared interrupt may affect other IPs
+    */
+    /* HAL_NVIC_DisableIRQ(ADC_IRQn); */
+  /* USER CODE END ADC2:ADC_IRQn disable */
+
   /* USER CODE BEGIN ADC2_MspDeInit 1 */
 
   /* USER CODE END ADC2_MspDeInit 1 */
@@ -224,15 +249,15 @@ void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac)
 }
 
 /**
-* @brief SMBUS MSP Initialization
+* @brief I2C MSP Initialization
 * This function configures the hardware resources used in this example
-* @param hsmbus: SMBUS handle pointer
+* @param hi2c: I2C handle pointer
 * @retval None
 */
-void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef* hsmbus)
+void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
 {
   GPIO_InitTypeDef GPIO_InitStruct = {0};
-  if(hsmbus->Instance==I2C1)
+  if(hi2c->Instance==I2C1)
   {
   /* USER CODE BEGIN I2C1_MspInit 0 */
 
@@ -260,14 +285,14 @@ void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef* hsmbus)
 }
 
 /**
-* @brief SMBUS MSP De-Initialization
+* @brief I2C MSP De-Initialization
 * This function freeze the hardware resources used in this example
-* @param hsmbus: SMBUS handle pointer
+* @param hi2c: I2C handle pointer
 * @retval None
 */
-void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef* hsmbus)
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
 {
-  if(hsmbus->Instance==I2C1)
+  if(hi2c->Instance==I2C1)
   {
   /* USER CODE BEGIN I2C1_MspDeInit 0 */
 
@@ -487,6 +512,20 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
 
   /* USER CODE END TIM2_MspInit 1 */
   }
+  else if(htim_base->Instance==TIM3)
+  {
+  /* USER CODE BEGIN TIM3_MspInit 0 */
+
+  /* USER CODE END TIM3_MspInit 0 */
+    /* Peripheral clock enable */
+    __HAL_RCC_TIM3_CLK_ENABLE();
+    /* TIM3 interrupt Init */
+    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
+    HAL_NVIC_EnableIRQ(TIM3_IRQn);
+  /* USER CODE BEGIN TIM3_MspInit 1 */
+
+  /* USER CODE END TIM3_MspInit 1 */
+  }
 
 }
 
@@ -515,6 +554,20 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
 
   /* USER CODE END TIM2_MspDeInit 1 */
   }
+  else if(htim_base->Instance==TIM3)
+  {
+  /* USER CODE BEGIN TIM3_MspDeInit 0 */
+
+  /* USER CODE END TIM3_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __HAL_RCC_TIM3_CLK_DISABLE();
+
+    /* TIM3 interrupt DeInit */
+    HAL_NVIC_DisableIRQ(TIM3_IRQn);
+  /* USER CODE BEGIN TIM3_MspDeInit 1 */
+
+  /* USER CODE END TIM3_MspDeInit 1 */
+  }
 
 }
 

+ 63 - 15
stm32workspace/dosimeter-fw/Core/Src/stm32f4xx_it.c

@@ -57,6 +57,9 @@
 
 /* External variables --------------------------------------------------------*/
 extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
+extern ADC_HandleTypeDef hadc1;
+extern ADC_HandleTypeDef hadc2;
+extern TIM_HandleTypeDef htim3;
 /* USER CODE BEGIN EV */
 
 /* USER CODE END EV */
@@ -64,21 +67,6 @@ extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
 /******************************************************************************/
 /*           Cortex-M4 Processor Interruption and Exception Handlers          */
 /******************************************************************************/
-/**
-  * @brief This function handles Non maskable interrupt.
-  */
-void NMI_Handler(void)
-{
-  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
-
-  /* USER CODE END NonMaskableInt_IRQn 0 */
-  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
-  while (1)
-  {
-  }
-  /* USER CODE END NonMaskableInt_IRQn 1 */
-}
-
 /**
   * @brief This function handles Hard fault interrupt.
   */
@@ -199,6 +187,66 @@ void SysTick_Handler(void)
 /* please refer to the startup file (startup_stm32f4xx.s).                    */
 /******************************************************************************/
 
+/**
+  * @brief This function handles EXTI line 1 interrupt.
+  */
+void EXTI1_IRQHandler(void)
+{
+  /* USER CODE BEGIN EXTI1_IRQn 0 */
+
+  /* USER CODE END EXTI1_IRQn 0 */
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
+  /* USER CODE BEGIN EXTI1_IRQn 1 */
+
+  /* USER CODE END EXTI1_IRQn 1 */
+}
+
+/**
+  * @brief This function handles ADC1, ADC2 and ADC3 interrupts.
+  */
+void ADC_IRQHandler(void)
+{
+  /* USER CODE BEGIN ADC_IRQn 0 */
+
+  /* USER CODE END ADC_IRQn 0 */
+  HAL_ADC_IRQHandler(&hadc1);
+  HAL_ADC_IRQHandler(&hadc2);
+  /* USER CODE BEGIN ADC_IRQn 1 */
+
+  /* USER CODE END ADC_IRQn 1 */
+}
+
+/**
+  * @brief This function handles EXTI line[9:5] interrupts.
+  */
+void EXTI9_5_IRQHandler(void)
+{
+  /* USER CODE BEGIN EXTI9_5_IRQn 0 */
+
+  /* USER CODE END EXTI9_5_IRQn 0 */
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
+  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
+  /* USER CODE BEGIN EXTI9_5_IRQn 1 */
+
+  /* USER CODE END EXTI9_5_IRQn 1 */
+}
+
+/**
+  * @brief This function handles TIM3 global interrupt.
+  */
+void TIM3_IRQHandler(void)
+{
+  /* USER CODE BEGIN TIM3_IRQn 0 */
+
+  /* USER CODE END TIM3_IRQn 0 */
+  HAL_TIM_IRQHandler(&htim3);
+  /* USER CODE BEGIN TIM3_IRQn 1 */
+
+  /* USER CODE END TIM3_IRQn 1 */
+}
+
 /**
   * @brief This function handles USB On The Go FS global interrupt.
   */

+ 8 - 0
stm32workspace/dosimeter-fw/Drivers/AT45DB041E/at45db041e.c

@@ -0,0 +1,8 @@
+/*
+ * at45db041e.c
+ *
+ *  Created on: Oct 11, 2021
+ *      Author: radioman
+ */
+
+

+ 26 - 0
stm32workspace/dosimeter-fw/Drivers/AT45DB041E/at45db041e.h

@@ -0,0 +1,26 @@
+/*
+ * at45db041e.h
+ *
+ *  Created on: Oct 11, 2021
+ *      Author: radioman
+ */
+
+#ifndef AT45DB041E_AT45DB041E_H_
+#define AT45DB041E_AT45DB041E_H_
+
+#define AT45CMD_MEM_PAGE_READ		0xD2
+#define AT45CMD_CONT_ARRAY_READ_LP	0x01
+#define AT45CMD_CONT_ARRAY_READ_LF	0x03
+#define AT45CMD_CONT_ARRAY_READ_HF	0x0B
+#define AT45CMD_BUF1_READ_LF		0xD1
+#define AT45CMD_BUF2_READ_LF		0xD3
+#define AT45CMD_BUF1_READ_HF		0xD4
+#define AT45CMD_BUF2_READ_HF		0xD6
+
+#define AT45CMD_BUF1_WRITE		0x84
+#define AT45CMD_BUF2_WRITE		0x87
+
+#define AT45CMD_STATREG_READ		0xD7
+#define AT45CMD_DEVID_READ		0x9F
+
+#endif /* AT45DB041E_AT45DB041E_H_ */

+ 743 - 0
stm32workspace/dosimeter-fw/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h

@@ -0,0 +1,743 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_hal_i2c.h
+  * @author  MCD Application Team
+  * @brief   Header file of I2C HAL module.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_I2C_H
+#define __STM32F4xx_HAL_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_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)
+
+/**
+  * @}
+  */
+
+/* Include I2C HAL Extension module */
+#include "stm32f4xx_hal_i2c_ex.h"
+
+/* 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 /* __STM32F4xx_HAL_I2C_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 117 - 0
stm32workspace/dosimeter-fw/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h

@@ -0,0 +1,117 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_hal_i2c_ex.h
+  * @author  MCD Application Team
+  * @brief   Header file of I2C HAL Extension module.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_I2C_EX_H
+#define __STM32F4xx_HAL_I2C_EX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if  defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+  * @{
+  */
+
+/** @addtogroup I2CEx
+  * @{
+  */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2CEx_Exported_Constants I2C Exported Constants
+  * @{
+  */
+
+/** @defgroup I2CEx_Analog_Filter I2C Analog Filter
+  * @{
+  */
+#define I2C_ANALOGFILTER_ENABLE        0x00000000U
+#define I2C_ANALOGFILTER_DISABLE       I2C_FLTR_ANOFF
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2CEx_Exported_Functions
+  * @{
+  */
+
+/** @addtogroup I2CEx_Exported_Functions_Group1
+  * @{
+  */
+/* Peripheral Control functions  ************************************************/
+HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter);
+HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter);
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2CEx_Private_Constants I2C Private Constants
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2CEx_Private_Macros I2C Private Macros
+  * @{
+  */
+#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \
+                                      ((FILTER) == I2C_ANALOGFILTER_DISABLE))
+#define IS_I2C_DIGITAL_FILTER(FILTER)   ((FILTER) <= 0x0000000FU)
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_I2C_EX_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 0 - 733
stm32workspace/dosimeter-fw/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_smbus.h

@@ -1,733 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32f4xx_hal_smbus.h
-  * @author  MCD Application Team
-  * @brief   Header file of SMBUS HAL module.
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under BSD 3-Clause license,
-  * the "License"; You may not use this file except in compliance with the
-  * License. You may obtain a copy of the License at:
-  *                        opensource.org/licenses/BSD-3-Clause
-  *
-  ******************************************************************************
-  */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F4xx_HAL_SMBUS_H
-#define __STM32F4xx_HAL_SMBUS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f4xx_hal_def.h"
-
-/** @addtogroup STM32F4xx_HAL_Driver
-  * @{
-  */
-
-/** @addtogroup SMBUS
-  * @{
-  */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup SMBUS_Exported_Types SMBUS Exported Types
-  * @{
-  */
-
-/**
-  * @brief  SMBUS Configuration Structure definition
-  */
-typedef struct
-{
-  uint32_t ClockSpeed;           /*!< Specifies the clock frequency.
-                                    This parameter must be set to a value lower than 100kHz                  */
-
-  uint32_t AnalogFilter;         /*!< Specifies if Analog Filter is enable or not.
-                                  This parameter can be a value of @ref SMBUS_Analog_Filter                  */
-
-  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 SMBUS_addressing_mode              */
-
-  uint32_t DualAddressMode;      /*!< Specifies if dual addressing mode is selected.
-                                    This parameter can be a value of @ref SMBUS_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 SMBUS_general_call_addressing_mode */
-
-  uint32_t NoStretchMode;        /*!< Specifies if nostretch mode is selected.
-                                    This parameter can be a value of @ref SMBUS_nostretch_mode               */
-
-  uint32_t PacketErrorCheckMode; /*!< Specifies if Packet Error Check mode is selected.
-                                     This parameter can be a value of @ref SMBUS_packet_error_check_mode     */
-
-  uint32_t PeripheralMode;       /*!< Specifies which mode of Periphal is selected.
-                                     This parameter can be a value of @ref SMBUS_peripheral_mode             */
-
-} SMBUS_InitTypeDef;
-
-/**
-  * @brief  HAL State structure definition
-  * @note  HAL SMBUS 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     IP initialisation status
-  *             0  : Reset (IP not initialized)
-  *             1  : Init done (IP initialized and ready to use. HAL SMBUS Init function called)
-  *          b4     (not used)
-  *             x  : Should be set to 0
-  *          b3
-  *             0  : Ready or Busy (No Listen mode ongoing)
-  *             1  : Listen (IP in Address Listen Mode)
-  *          b2     Intrinsic process state
-  *             0  : Ready
-  *             1  : Busy (IP 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_SMBUS_STATE_RESET             = 0x00U,   /*!< Peripheral is not yet Initialized         */
-  HAL_SMBUS_STATE_READY             = 0x20U,   /*!< Peripheral Initialized and ready for use  */
-  HAL_SMBUS_STATE_BUSY              = 0x24U,   /*!< An internal process is ongoing            */
-  HAL_SMBUS_STATE_BUSY_TX           = 0x21U,   /*!< Data Transmission process is ongoing      */
-  HAL_SMBUS_STATE_BUSY_RX           = 0x22U,   /*!< Data Reception process is ongoing         */
-  HAL_SMBUS_STATE_LISTEN            = 0x28U,   /*!< Address Listen Mode is ongoing            */
-  HAL_SMBUS_STATE_BUSY_TX_LISTEN    = 0x29U,   /*!< Address Listen Mode and Data Transmission
-                                                 process is ongoing                           */
-  HAL_SMBUS_STATE_BUSY_RX_LISTEN    = 0x2AU,   /*!< Address Listen Mode and Data Reception
-                                                 process is ongoing                           */
-  HAL_SMBUS_STATE_ABORT             = 0x60U,   /*!< Abort user request ongoing                */
-  HAL_SMBUS_STATE_TIMEOUT           = 0xA0U,   /*!< Timeout state                             */
-  HAL_SMBUS_STATE_ERROR             = 0xE0U    /*!< Error                                     */
-} HAL_SMBUS_StateTypeDef;
-
-/**
-  * @brief  HAL Mode structure definition
-  * @note   HAL SMBUS Mode value coding follow below described bitmap :
-  *          b7     (not used)
-  *             x  : Should be set to 0
-  *          b6     (not used)
-  *             x  : Should be set to 0
-  *          b5
-  *             0  : None
-  *             1  : Slave (HAL SMBUS communication is in Slave/Device Mode)
-  *          b4
-  *             0  : None
-  *             1  : Master (HAL SMBUS communication is in Master/Host Mode)
-  *          b3-b2-b1-b0  (not used)
-  *             xxxx : Should be set to 0000
-  */
-typedef enum
-{
-  HAL_SMBUS_MODE_NONE               = 0x00U,   /*!< No SMBUS communication on going              */
-  HAL_SMBUS_MODE_MASTER             = 0x10U,   /*!< SMBUS communication is in Master Mode        */
-  HAL_SMBUS_MODE_SLAVE              = 0x20U,   /*!< SMBUS communication is in Slave Mode         */
-
-} HAL_SMBUS_ModeTypeDef;
-
-/**
-  * @brief  SMBUS handle Structure definition
-  */
-typedef struct __SMBUS_HandleTypeDef
-{
-  I2C_TypeDef                 *Instance;        /*!< SMBUS registers base address                  */
-
-  SMBUS_InitTypeDef             Init;           /*!< SMBUS communication parameters              */
-
-  uint8_t                       *pBuffPtr;      /*!< Pointer to SMBUS transfer buffer            */
-
-  uint16_t                      XferSize;       /*!< SMBUS transfer size                         */
-
-  __IO uint16_t                 XferCount;      /*!< SMBUS transfer counter                      */
-
-  __IO uint32_t                 XferOptions;    /*!< SMBUS transfer options this parameter can
-                                                     be a value of @ref SMBUS_OPTIONS            */
-
-  __IO uint32_t                 PreviousState;  /*!< SMBUS communication Previous state and mode
-                                                     context for internal usage                  */
-
-  HAL_LockTypeDef               Lock;           /*!< SMBUS locking object                        */
-
-  __IO HAL_SMBUS_StateTypeDef   State;          /*!< SMBUS communication state                   */
-
-  __IO HAL_SMBUS_ModeTypeDef    Mode;           /*!< SMBUS communication mode                    */
-
-  __IO uint32_t                 ErrorCode;      /*!< SMBUS Error code                            */
-
-  __IO uint32_t                 Devaddress;     /*!< SMBUS Target device address                 */
-
-  __IO uint32_t                 EventCount;     /*!< SMBUS Event counter                         */
-
-  uint8_t                       XferPEC;        /*!< SMBUS PEC data in reception mode            */
-
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-  void (* MasterTxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);           /*!< SMBUS Master Tx Transfer completed callback */
-  void (* MasterRxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);           /*!< SMBUS Master Rx Transfer completed callback */
-  void (* SlaveTxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);            /*!< SMBUS Slave Tx Transfer completed callback  */
-  void (* SlaveRxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);            /*!< SMBUS Slave Rx Transfer completed callback  */
-  void (* ListenCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);             /*!< SMBUS Listen Complete callback              */
-  void (* MemTxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);              /*!< SMBUS Memory Tx Transfer completed callback */
-  void (* MemRxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);              /*!< SMBUS Memory Rx Transfer completed callback */
-  void (* ErrorCallback)(struct __SMBUS_HandleTypeDef *hsmbus);                  /*!< SMBUS Error callback                        */
-  void (* AbortCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus);              /*!< SMBUS Abort callback                        */
-  void (* AddrCallback)(struct __SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode);  /*!< SMBUS Slave Address Match callback */
-  void (* MspInitCallback)(struct __SMBUS_HandleTypeDef *hsmbus);                /*!< SMBUS Msp Init callback                     */
-  void (* MspDeInitCallback)(struct __SMBUS_HandleTypeDef *hsmbus);              /*!< SMBUS Msp DeInit callback                   */
-
-#endif  /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-} SMBUS_HandleTypeDef;
-
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-/**
-  * @brief  HAL SMBUS Callback ID enumeration definition
-  */
-typedef enum
-{
-  HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID      = 0x00U,    /*!< SMBUS Master Tx Transfer completed callback ID  */
-  HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID      = 0x01U,    /*!< SMBUS Master Rx Transfer completed callback ID  */
-  HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID       = 0x02U,    /*!< SMBUS Slave Tx Transfer completed callback ID   */
-  HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID       = 0x03U,    /*!< SMBUS Slave Rx Transfer completed callback ID   */
-  HAL_SMBUS_LISTEN_COMPLETE_CB_ID         = 0x04U,    /*!< SMBUS Listen Complete callback ID               */
-  HAL_SMBUS_ERROR_CB_ID                   = 0x07U,    /*!< SMBUS Error callback ID                         */
-  HAL_SMBUS_ABORT_CB_ID                   = 0x08U,    /*!< SMBUS Abort callback ID                         */
-  HAL_SMBUS_MSPINIT_CB_ID                 = 0x09U,    /*!< SMBUS Msp Init callback ID                      */
-  HAL_SMBUS_MSPDEINIT_CB_ID               = 0x0AU     /*!< SMBUS Msp DeInit callback ID                    */
-
-} HAL_SMBUS_CallbackIDTypeDef;
-
-/**
-  * @brief  HAL SMBUS Callback pointer definition
-  */
-typedef  void (*pSMBUS_CallbackTypeDef)(SMBUS_HandleTypeDef *hsmbus); /*!< pointer to an I2C callback function */
-typedef  void (*pSMBUS_AddrCallbackTypeDef)(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode); /*!< pointer to an I2C Address Match callback function */
-
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup SMBUS_Exported_Constants SMBUS Exported Constants
-  * @{
-  */
-
-/** @defgroup SMBUS_Error_Code_definition SMBUS Error Code
-  * @brief    SMBUS Error Code
-  * @{
-  */
-#define HAL_SMBUS_ERROR_NONE              0x00000000U    /*!< No error               */
-#define HAL_SMBUS_ERROR_BERR              0x00000001U    /*!< BERR error             */
-#define HAL_SMBUS_ERROR_ARLO              0x00000002U    /*!< ARLO error             */
-#define HAL_SMBUS_ERROR_AF                0x00000004U    /*!< AF error               */
-#define HAL_SMBUS_ERROR_OVR               0x00000008U    /*!< OVR error              */
-#define HAL_SMBUS_ERROR_TIMEOUT           0x00000010U    /*!< Timeout Error          */
-#define HAL_SMBUS_ERROR_ALERT             0x00000020U    /*!< Alert error            */
-#define HAL_SMBUS_ERROR_PECERR            0x00000040U    /*!< PEC error              */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-#define HAL_SMBUS_ERROR_INVALID_CALLBACK  0x00000080U    /*!< Invalid Callback error */
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_Analog_Filter SMBUS Analog Filter
-  * @{
-  */
-#define SMBUS_ANALOGFILTER_ENABLE        0x00000000U
-#define SMBUS_ANALOGFILTER_DISABLE       I2C_FLTR_ANOFF
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_addressing_mode SMBUS addressing mode
- * @{
- */
-#define SMBUS_ADDRESSINGMODE_7BIT        0x00004000U
-#define SMBUS_ADDRESSINGMODE_10BIT       (I2C_OAR1_ADDMODE | 0x00004000U)
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_dual_addressing_mode  SMBUS dual addressing mode
-  * @{
-  */
-#define SMBUS_DUALADDRESS_DISABLE        0x00000000U
-#define SMBUS_DUALADDRESS_ENABLE         I2C_OAR2_ENDUAL
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_general_call_addressing_mode SMBUS general call addressing mode
-  * @{
-  */
-#define SMBUS_GENERALCALL_DISABLE        0x00000000U
-#define SMBUS_GENERALCALL_ENABLE         I2C_CR1_ENGC
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_nostretch_mode SMBUS nostretch mode
-  * @{
-  */
-#define SMBUS_NOSTRETCH_DISABLE          0x00000000U
-#define SMBUS_NOSTRETCH_ENABLE           I2C_CR1_NOSTRETCH
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_packet_error_check_mode SMBUS packet error check mode
-  * @{
-  */
-#define SMBUS_PEC_DISABLE                0x00000000U
-#define SMBUS_PEC_ENABLE                 I2C_CR1_ENPEC
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_peripheral_mode SMBUS peripheral mode
-* @{
-*/
-#define SMBUS_PERIPHERAL_MODE_SMBUS_HOST        (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_SMBTYPE | I2C_CR1_ENARP)
-#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE       I2C_CR1_SMBUS
-#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP   (uint32_t)(I2C_CR1_SMBUS | I2C_CR1_ENARP)
-/**
-* @}
-*/
-
-/** @defgroup SMBUS_XferDirection_definition SMBUS XferDirection definition
-  * @{
-  */
-#define SMBUS_DIRECTION_RECEIVE           0x00000000U
-#define SMBUS_DIRECTION_TRANSMIT          0x00000001U
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_XferOptions_definition SMBUS XferOptions definition
-  * @{
-  */
-#define  SMBUS_FIRST_FRAME                       0x00000001U
-#define  SMBUS_NEXT_FRAME                        0x00000002U
-#define  SMBUS_FIRST_AND_LAST_FRAME_NO_PEC       0x00000003U
-#define  SMBUS_LAST_FRAME_NO_PEC                 0x00000004U
-#define  SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC     0x00000005U
-#define  SMBUS_LAST_FRAME_WITH_PEC               0x00000006U
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_Interrupt_configuration_definition SMBUS Interrupt configuration definition
-  * @{
-  */
-#define SMBUS_IT_BUF                      I2C_CR2_ITBUFEN
-#define SMBUS_IT_EVT                      I2C_CR2_ITEVTEN
-#define SMBUS_IT_ERR                      I2C_CR2_ITERREN
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_Flag_definition SMBUS Flag definition
-  * @{
-  */
-#define SMBUS_FLAG_SMBALERT               0x00018000U
-#define SMBUS_FLAG_TIMEOUT                0x00014000U
-#define SMBUS_FLAG_PECERR                 0x00011000U
-#define SMBUS_FLAG_OVR                    0x00010800U
-#define SMBUS_FLAG_AF                     0x00010400U
-#define SMBUS_FLAG_ARLO                   0x00010200U
-#define SMBUS_FLAG_BERR                   0x00010100U
-#define SMBUS_FLAG_TXE                    0x00010080U
-#define SMBUS_FLAG_RXNE                   0x00010040U
-#define SMBUS_FLAG_STOPF                  0x00010010U
-#define SMBUS_FLAG_ADD10                  0x00010008U
-#define SMBUS_FLAG_BTF                    0x00010004U
-#define SMBUS_FLAG_ADDR                   0x00010002U
-#define SMBUS_FLAG_SB                     0x00010001U
-#define SMBUS_FLAG_DUALF                  0x00100080U
-#define SMBUS_FLAG_SMBHOST                0x00100040U
-#define SMBUS_FLAG_SMBDEFAULT             0x00100020U
-#define SMBUS_FLAG_GENCALL                0x00100010U
-#define SMBUS_FLAG_TRA                    0x00100004U
-#define SMBUS_FLAG_BUSY                   0x00100002U
-#define SMBUS_FLAG_MSL                    0x00100001U
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup SMBUS_Exported_Macros SMBUS Exported Macros
-  * @{
-  */
-
-/** @brief Reset SMBUS handle state
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUS where x: 1, 2, or 3 to select the SMBUS peripheral.
-  * @retval None
-  */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-#define __HAL_SMBUS_RESET_HANDLE_STATE(__HANDLE__)          do{                                                  \
-                                                                (__HANDLE__)->State = HAL_SMBUS_STATE_RESET;     \
-                                                                (__HANDLE__)->MspInitCallback = NULL;            \
-                                                                (__HANDLE__)->MspDeInitCallback = NULL;          \
-                                                              } while(0)
-#else
-#define __HAL_SMBUS_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SMBUS_STATE_RESET)
-#endif
-
-/** @brief  Enable or disable the specified SMBUS interrupts.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUS where x: 1, 2, or 3 to select the SMBUS peripheral.
-  * @param  __INTERRUPT__ specifies the interrupt source to enable or disable.
-  *         This parameter can be one of the following values:
-  *            @arg SMBUS_IT_BUF: Buffer interrupt enable
-  *            @arg SMBUS_IT_EVT: Event interrupt enable
-  *            @arg SMBUS_IT_ERR: Error interrupt enable
-  * @retval None
-  */
-#define __HAL_SMBUS_ENABLE_IT(__HANDLE__, __INTERRUPT__)   ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__))
-#define __HAL_SMBUS_DISABLE_IT(__HANDLE__, __INTERRUPT__)  ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__)))
-
-/** @brief  Checks if the specified SMBUS interrupt source is enabled or disabled.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUS where x: 1, 2, or 3 to select the SMBUS peripheral.
-  * @param  __INTERRUPT__ specifies the SMBUS interrupt source to check.
-  *          This parameter can be one of the following values:
-  *            @arg SMBUS_IT_BUF: Buffer interrupt enable
-  *            @arg SMBUS_IT_EVT: Event interrupt enable
-  *            @arg SMBUS_IT_ERR: Error interrupt enable
-  * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
-  */
-#define __HAL_SMBUS_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
-
-/** @brief  Checks whether the specified SMBUS flag is set or not.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUS where x: 1, 2, or 3 to select the SMBUS peripheral.
-  * @param  __FLAG__ specifies the flag to check.
-  *         This parameter can be one of the following values:
-  *            @arg SMBUS_FLAG_SMBALERT: SMBus Alert flag
-  *            @arg SMBUS_FLAG_TIMEOUT: Timeout or Tlow error flag
-  *            @arg SMBUS_FLAG_PECERR: PEC error in reception flag
-  *            @arg SMBUS_FLAG_OVR: Overrun/Underrun flag
-  *            @arg SMBUS_FLAG_AF: Acknowledge failure flag
-  *            @arg SMBUS_FLAG_ARLO: Arbitration lost flag
-  *            @arg SMBUS_FLAG_BERR: Bus error flag
-  *            @arg SMBUS_FLAG_TXE: Data register empty flag
-  *            @arg SMBUS_FLAG_RXNE: Data register not empty flag
-  *            @arg SMBUS_FLAG_STOPF: Stop detection flag
-  *            @arg SMBUS_FLAG_ADD10: 10-bit header sent flag
-  *            @arg SMBUS_FLAG_BTF: Byte transfer finished flag
-  *            @arg SMBUS_FLAG_ADDR: Address sent flag
-  *                                Address matched flag
-  *            @arg SMBUS_FLAG_SB: Start bit flag
-  *            @arg SMBUS_FLAG_DUALF: Dual flag
-  *            @arg SMBUS_FLAG_SMBHOST: SMBus host header
-  *            @arg SMBUS_FLAG_SMBDEFAULT: SMBus default header
-  *            @arg SMBUS_FLAG_GENCALL: General call header flag
-  *            @arg SMBUS_FLAG_TRA: Transmitter/Receiver flag
-  *            @arg SMBUS_FLAG_BUSY: Bus busy flag
-  *            @arg SMBUS_FLAG_MSL: Master/Slave flag
-  * @retval The new state of __FLAG__ (TRUE or FALSE).
-  */
-#define __HAL_SMBUS_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & SMBUS_FLAG_MASK)) == ((__FLAG__) & SMBUS_FLAG_MASK)): \
-                                                 ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & SMBUS_FLAG_MASK)) == ((__FLAG__) & SMBUS_FLAG_MASK)))
-
-/** @brief  Clears the SMBUS pending flags which are cleared by writing 0 in a specific bit.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUS where x: 1, 2, or 3 to select the SMBUS peripheral.
-  * @param  __FLAG__ specifies the flag to clear.
-  *         This parameter can be any combination of the following values:
-  *            @arg SMBUS_FLAG_SMBALERT: SMBus Alert flag
-  *            @arg SMBUS_FLAG_TIMEOUT: Timeout or Tlow error flag
-  *            @arg SMBUS_FLAG_PECERR: PEC error in reception flag
-  *            @arg SMBUS_FLAG_OVR: Overrun/Underrun flag (Slave mode)
-  *            @arg SMBUS_FLAG_AF: Acknowledge failure flag
-  *            @arg SMBUS_FLAG_ARLO: Arbitration lost flag (Master mode)
-  *            @arg SMBUS_FLAG_BERR: Bus error flag
-  * @retval None
-  */
-#define __HAL_SMBUS_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & SMBUS_FLAG_MASK))
-
-/** @brief  Clears the SMBUS ADDR pending flag.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUS where x: 1, 2, or 3 to select the SMBUS peripheral.
-  * @retval None
-  */
-#define __HAL_SMBUS_CLEAR_ADDRFLAG(__HANDLE__)    \
-  do{                                           \
-    __IO uint32_t tmpreg = 0x00U;               \
-    tmpreg = (__HANDLE__)->Instance->SR1;       \
-    tmpreg = (__HANDLE__)->Instance->SR2;       \
-    UNUSED(tmpreg);                             \
-  } while(0)
-
-/** @brief  Clears the SMBUS STOPF pending flag.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUS where x: 1, 2, or 3 to select the SMBUS peripheral.
-  * @retval None
-  */
-#define __HAL_SMBUS_CLEAR_STOPFLAG(__HANDLE__)    \
-  do{                                           \
-    __IO uint32_t tmpreg = 0x00U;               \
-    tmpreg = (__HANDLE__)->Instance->SR1;       \
-    (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE;  \
-    UNUSED(tmpreg);                             \
-  } while(0)
-
-/** @brief  Enable the SMBUS peripheral.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUSx where x: 1 or 2  to select the SMBUS peripheral.
-  * @retval None
-  */
-#define __HAL_SMBUS_ENABLE(__HANDLE__)           ((__HANDLE__)->Instance->CR1 |=  I2C_CR1_PE)
-
-/** @brief  Disable the SMBUS peripheral.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  *         This parameter can be SMBUSx where x: 1 or 2  to select the SMBUS peripheral.
-  * @retval None
-  */
-#define __HAL_SMBUS_DISABLE(__HANDLE__)          ((__HANDLE__)->Instance->CR1 &=  ~I2C_CR1_PE)
-
-/** @brief  Generate a Non-Acknowledge SMBUS peripheral in Slave mode.
-  * @param  __HANDLE__ specifies the SMBUS Handle.
-  * @retval None
-  */
-#define __HAL_SMBUS_GENERATE_NACK(__HANDLE__)    (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_ACK))
-
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup SMBUS_Exported_Functions
-  * @{
-  */
-
-/** @addtogroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
- * @{
- */
-
-/* Initialization/de-initialization functions  **********************************/
-HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus);
-HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus);
-
-/* Callbacks Register/UnRegister functions  ************************************/
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID, pSMBUS_CallbackTypeDef pCallback);
-HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID);
-
-HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, pSMBUS_AddrCallbackTypeDef pCallback);
-HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-/** @addtogroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
-  * @{
-  */
-
-/* IO operation functions  *****************************************************/
-/** @addtogroup Blocking_mode_Polling Blocking mode Polling
- * @{
- */
-/******* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
-/**
-  * @}
-  */
-
-/** @addtogroup Non-Blocking_mode_Interrupt Non-Blocking mode Interrupt
- * @{
- */
-/******* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress);
-HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
-
-HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus);
-HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus);
-HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus);
-HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus);
-
-/****** Filter Configuration functions  */
-#if  defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
-HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter);
-HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter);
-#endif
-/**
-  * @}
-  */
-
-/** @addtogroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
- * @{
- */
-/******* SMBUS IRQHandler and Callbacks used in non blocking modes (Interrupt) */
-void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode);
-void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus);
-void HAL_SMBUS_AbortCpltCallback(SMBUS_HandleTypeDef *hsmbus);
-
-/**
-  * @}
-  */
-
-/** @addtogroup SMBUS_Exported_Functions_Group3 Peripheral State, Mode and Error functions
-  * @{
-  */
-
-/* Peripheral State, mode and Errors functions  **************************************************/
-HAL_SMBUS_StateTypeDef HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus);
-HAL_SMBUS_ModeTypeDef HAL_SMBUS_GetMode(SMBUS_HandleTypeDef *hsmbus);
-uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus);
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup SMBUS_Private_Constants SMBUS Private Constants
-  * @{
-  */
-#define SMBUS_FLAG_MASK  0x0000FFFFU
-/**
-  * @}
-  */
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup SMBUS_Private_Macros SMBUS Private Macros
-  * @{
-  */
-
-#define SMBUS_FREQRANGE(__PCLK__)                  ((__PCLK__)/1000000U)
-
-#define SMBUS_RISE_TIME(__FREQRANGE__)             ( ((__FREQRANGE__) + 1U))
-
-#define SMBUS_SPEED_STANDARD(__PCLK__, __SPEED__)  (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U)))
-
-#define SMBUS_7BIT_ADD_WRITE(__ADDRESS__)          ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0)))
-
-#define SMBUS_7BIT_ADD_READ(__ADDRESS__)           ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))
-
-#define SMBUS_10BIT_ADDRESS(__ADDRESS__)           ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
-
-#define SMBUS_10BIT_HEADER_WRITE(__ADDRESS__)      ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0)))
-
-#define SMBUS_10BIT_HEADER_READ(__ADDRESS__)       ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1))))
-
-#define SMBUS_GET_PEC_MODE(__HANDLE__)             ((__HANDLE__)->Instance->CR1 & I2C_CR1_ENPEC)
-
-#define SMBUS_GET_PEC_VALUE(__HANDLE__)             ((__HANDLE__)->XferPEC)
-
-#if  defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
-#define IS_SMBUS_ANALOG_FILTER(FILTER)             (((FILTER) == SMBUS_ANALOGFILTER_ENABLE) || \
-                                                    ((FILTER) == SMBUS_ANALOGFILTER_DISABLE))
-#define IS_SMBUS_DIGITAL_FILTER(FILTER)            ((FILTER) <= 0x0000000FU)
-#endif
-#define IS_SMBUS_ADDRESSING_MODE(ADDRESS)          (((ADDRESS) == SMBUS_ADDRESSINGMODE_7BIT) || \
-                                                    ((ADDRESS) == SMBUS_ADDRESSINGMODE_10BIT))
-
-#define IS_SMBUS_DUAL_ADDRESS(ADDRESS)             (((ADDRESS) == SMBUS_DUALADDRESS_DISABLE) || \
-                                                    ((ADDRESS) == SMBUS_DUALADDRESS_ENABLE))
-
-#define IS_SMBUS_GENERAL_CALL(CALL)                (((CALL) == SMBUS_GENERALCALL_DISABLE)    || \
-                                                    ((CALL) == SMBUS_GENERALCALL_ENABLE))
-
-#define IS_SMBUS_NO_STRETCH(STRETCH)               (((STRETCH) == SMBUS_NOSTRETCH_DISABLE)   || \
-                                                    ((STRETCH) == SMBUS_NOSTRETCH_ENABLE))
-
-#define IS_SMBUS_PEC(PEC)                          (((PEC) == SMBUS_PEC_DISABLE) || \
-                                                     ((PEC) == SMBUS_PEC_ENABLE))
-
-#define IS_SMBUS_PERIPHERAL_MODE(MODE)             (((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_HOST)      || \
-                                                    ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE)     || \
-                                                    ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP))
-
-#define IS_SMBUS_CLOCK_SPEED(SPEED)                (((SPEED) > 0U) && ((SPEED) <= 100000U))
-
-#define IS_SMBUS_OWN_ADDRESS1(ADDRESS1)            (((ADDRESS1) & 0xFFFFFC00U) == 0U)
-
-#define IS_SMBUS_OWN_ADDRESS2(ADDRESS2)            (((ADDRESS2) & 0xFFFFFF01U) == 0U)
-
-#define IS_SMBUS_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == SMBUS_FIRST_FRAME)                   || \
-                                                    ((REQUEST) == SMBUS_NEXT_FRAME)                    || \
-                                                    ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC)   || \
-                                                    ((REQUEST) == SMBUS_LAST_FRAME_NO_PEC)             || \
-                                                    ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \
-                                                    ((REQUEST) == SMBUS_LAST_FRAME_WITH_PEC))
-
-/**
-  * @}
-  */
-
-/* Private Functions ---------------------------------------------------------*/
-/** @defgroup SMBUS_Private_Functions SMBUS Private Functions
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-* @}
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __STM32F4xx_HAL_SMBUS_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 7524 - 0
stm32workspace/dosimeter-fw/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c

@@ -0,0 +1,7524 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_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
+  *
+  @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 stream
+            (+++) Enable the DMAx interface clock using
+            (+++) Configure the DMA handle parameters
+            (+++) Configure the DMA Tx or Rx stream
+            (+++) 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 stream
+
+    (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,
+        Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure.
+
+    (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware
+        (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit() API.
+
+    (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady()
+
+    (#) For I2C IO and IO MEM operations, three operation modes are available within this driver :
+
+    *** Polling mode IO operation ***
+    =================================
+    [..]
+      (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit()
+      (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive()
+      (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit()
+      (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive()
+
+    *** Polling mode IO MEM operation ***
+    =====================================
+    [..]
+      (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write()
+      (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read()
+
+
+    *** Interrupt mode IO operation ***
+    ===================================
+    [..]
+      (+) Transmit in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Transmit_IT()
+      (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
+      (+) Receive in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Receive_IT()
+      (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
+      (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Transmit_IT()
+      (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
+      (+) Receive in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Receive_IT()
+      (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
+      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+           add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+      (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
+      (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
+
+    *** Interrupt mode or DMA mode IO sequential operation ***
+    ==========================================================
+    [..]
+      (@) These interfaces allow to manage a sequential transfer with a repeated start condition
+          when a direction change during transfer
+    [..]
+      (+) A specific option field manage the different steps of a sequential transfer
+      (+) Option field values are defined through I2C_XferOptions_definition and are listed below:
+      (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in no sequential mode
+      (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
+                            and data to transfer without a final stop condition
+      (++) I2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address
+                            and data to transfer without a final stop condition, an then permit a call the same master sequential interface
+                            several times (like HAL_I2C_Master_Seq_Transmit_IT() then HAL_I2C_Master_Seq_Transmit_IT()
+                            or HAL_I2C_Master_Seq_Transmit_DMA() then HAL_I2C_Master_Seq_Transmit_DMA())
+      (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
+                            and with new data to transfer if the direction change or manage only the new data to transfer
+                            if no direction change and without a final stop condition in both cases
+      (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
+                            and with new data to transfer if the direction change or manage only the new data to transfer
+                            if no direction change and with a final stop condition in both cases
+      (++) I2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition after several call of the same master sequential
+                            interface several times (link with option I2C_FIRST_AND_NEXT_FRAME).
+                            Usage can, transfer several bytes one by one using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
+                              or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
+                              or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME)
+                              or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME).
+                            Then usage of this option I2C_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the opposite interface Receive or Transmit
+                              without stopping the communication and so generate a restart condition.
+      (++) I2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after each call of the same master sequential
+                            interface.
+                            Usage can, transfer several bytes one by one with a restart with slave address between each bytes using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
+                              or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
+                              or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME)
+                              or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME).
+                            Then usage of this option I2C_OTHER_AND_LAST_FRAME at the last frame to help automatic generation of STOP condition.
+
+      (+) Different sequential I2C interfaces are listed below:
+      (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Seq_Transmit_IT()
+            or using HAL_I2C_Master_Seq_Transmit_DMA()
+      (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
+      (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Seq_Receive_IT()
+            or using HAL_I2C_Master_Seq_Receive_DMA()
+      (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
+      (++) Abort a master IT or DMA I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
+      (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
+      (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT()
+      (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can
+           add his own code to check the Address Match Code and the transmission direction request by master (Write/Read).
+      (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_ListenCpltCallback()
+      (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Seq_Transmit_IT()
+            or using HAL_I2C_Slave_Seq_Transmit_DMA()
+      (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
+      (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Seq_Receive_IT()
+            or using HAL_I2C_Slave_Seq_Receive_DMA()
+      (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
+      (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+           add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+
+    *** Interrupt mode IO MEM operation ***
+    =======================================
+    [..]
+      (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
+          HAL_I2C_Mem_Write_IT()
+      (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
+      (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
+          HAL_I2C_Mem_Read_IT()
+      (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
+      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+           add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+
+    *** DMA mode IO operation ***
+    ==============================
+    [..]
+      (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
+          HAL_I2C_Master_Transmit_DMA()
+      (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
+      (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
+          HAL_I2C_Master_Receive_DMA()
+      (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
+      (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
+          HAL_I2C_Slave_Transmit_DMA()
+      (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
+      (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
+          HAL_I2C_Slave_Receive_DMA()
+      (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
+      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+           add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+      (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
+      (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_AbortCpltCallback()
+
+    *** DMA mode IO MEM operation ***
+    =================================
+    [..]
+      (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
+          HAL_I2C_Mem_Write_DMA()
+      (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
+      (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
+          HAL_I2C_Mem_Read_DMA()
+      (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and user can
+           add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
+      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
+           add his own code by customization of function pointer HAL_I2C_ErrorCallback()
+
+
+     *** I2C HAL driver macros list ***
+     ==================================
+     [..]
+       Below the list of most used macros in I2C HAL driver.
+
+      (+) __HAL_I2C_ENABLE:     Enable the I2C peripheral
+      (+) __HAL_I2C_DISABLE:    Disable the I2C peripheral
+      (+) __HAL_I2C_GET_FLAG:   Checks whether the specified I2C flag is set or not
+      (+) __HAL_I2C_CLEAR_FLAG: Clear the specified I2C pending flag
+      (+) __HAL_I2C_ENABLE_IT:  Enable the specified I2C interrupt
+      (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt
+
+     *** Callback registration ***
+     =============================================
+    [..]
+     The compilation flag USE_HAL_I2C_REGISTER_CALLBACKS when set to 1
+     allows the user to configure dynamically the driver callbacks.
+     Use Functions HAL_I2C_RegisterCallback() or HAL_I2C_RegisterAddrCallback()
+     to register an interrupt callback.
+    [..]
+     Function HAL_I2C_RegisterCallback() allows to register following callbacks:
+       (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
+       (+) MasterRxCpltCallback : callback for Master reception end of transfer.
+       (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
+       (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
+       (+) ListenCpltCallback   : callback for end of listen mode.
+       (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
+       (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
+       (+) ErrorCallback        : callback for error detection.
+       (+) AbortCpltCallback    : callback for abort completion process.
+       (+) MspInitCallback      : callback for Msp Init.
+       (+) MspDeInitCallback    : callback for Msp DeInit.
+     This function takes as parameters the HAL peripheral handle, the Callback ID
+     and a pointer to the user callback function.
+    [..]
+     For specific callback AddrCallback use dedicated register callbacks : HAL_I2C_RegisterAddrCallback().
+    [..]
+     Use function HAL_I2C_UnRegisterCallback to reset a callback to the default
+     weak function.
+     HAL_I2C_UnRegisterCallback takes as parameters the HAL peripheral handle,
+     and the Callback ID.
+     This function allows to reset following callbacks:
+       (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
+       (+) MasterRxCpltCallback : callback for Master reception end of transfer.
+       (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
+       (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
+       (+) ListenCpltCallback   : callback for end of listen mode.
+       (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
+       (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
+       (+) ErrorCallback        : callback for error detection.
+       (+) AbortCpltCallback    : callback for abort completion process.
+       (+) MspInitCallback      : callback for Msp Init.
+       (+) MspDeInitCallback    : callback for Msp DeInit.
+    [..]
+     For callback AddrCallback use dedicated register callbacks : HAL_I2C_UnRegisterAddrCallback().
+    [..]
+     By default, after the HAL_I2C_Init() and when the state is HAL_I2C_STATE_RESET
+     all callbacks are set to the corresponding weak functions:
+     examples HAL_I2C_MasterTxCpltCallback(), HAL_I2C_MasterRxCpltCallback().
+     Exception done for MspInit and MspDeInit functions that are
+     reset to the legacy weak functions in the HAL_I2C_Init()/ HAL_I2C_DeInit() only when
+     these callbacks are null (not registered beforehand).
+     If MspInit or MspDeInit are not null, the HAL_I2C_Init()/ HAL_I2C_DeInit()
+     keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
+    [..]
+     Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only.
+     Exception done MspInit/MspDeInit functions that can be registered/unregistered
+     in HAL_I2C_STATE_READY or HAL_I2C_STATE_RESET state,
+     thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
+     Then, the user first registers the MspInit/MspDeInit user callbacks
+     using HAL_I2C_RegisterCallback() before calling HAL_I2C_DeInit()
+     or HAL_I2C_Init() function.
+    [..]
+     When the compilation flag USE_HAL_I2C_REGISTER_CALLBACKS is set to 0 or
+     not defined, the callback registration feature is not available and all callbacks
+     are set to the corresponding weak functions.
+
+
+
+     [..]
+       (@) You can refer to the I2C HAL driver header file for more useful macros
+
+  @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup I2C I2C
+  * @brief I2C HAL module driver
+  * @{
+  */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @addtogroup 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 -------------------------------------------------------------*/
+/* 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);
+/**
+  * @}
+  */
+
+/* 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 */
+
+/**
+  * @}
+  */
+
+/** @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)
+{
+  /* 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);
+
+      /* Clear ADDR flag */
+      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+    }
+    else if (hi2c->XferSize == 2U)
+    {
+      /* Disable Acknowledge */
+      CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+      /* Enable Pos */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+      /* Clear ADDR flag */
+      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+    }
+    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;
+          }
+
+          /* 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--;
+
+          /* 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);
+
+          /* 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 */
+          if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+          {
+            return HAL_ERROR;
+          }
+
+          /* 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--;
+
+          /* Read data from DR */
+          *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+          /* Increment Buffer pointer */
+          hi2c->pBuffPtr++;
+
+          /* Update counter */
+          hi2c->XferSize--;
+          hi2c->XferCount--;
+        }
+      }
+      else
+      {
+        /* Wait until RXNE flag is set */
+        if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+        {
+          return HAL_ERROR;
+        }
+
+        /* Read data from DR */
+        *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+        /* Increment Buffer pointer */
+        hi2c->pBuffPtr++;
+
+        /* Update counter */
+        hi2c->XferSize--;
+        hi2c->XferCount--;
+
+        if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET)
+        {
+          /* Read data from DR */
+          *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+          /* Increment Buffer pointer */
+          hi2c->pBuffPtr++;
+
+          /* Update counter */
+          hi2c->XferSize--;
+          hi2c->XferCount--;
+        }
+      }
+    }
+
+    hi2c->State = HAL_I2C_STATE_READY;
+    hi2c->Mode = HAL_I2C_MODE_NONE;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hi2c);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  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;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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->XferM1CpltCallback = NULL;
+        hi2c->hdmatx->XferM1HalfCpltCallback = NULL;
+        hi2c->hdmatx->XferAbortCallback = NULL;
+
+        /* Enable the DMA stream */
+        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;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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->XferM1CpltCallback = NULL;
+        hi2c->hdmarx->XferM1HalfCpltCallback = NULL;
+        hi2c->hdmarx->XferAbortCallback = NULL;
+
+        /* Enable the DMA stream */
+        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->XferM1CpltCallback = NULL;
+      hi2c->hdmatx->XferM1HalfCpltCallback = NULL;
+      hi2c->hdmatx->XferAbortCallback = NULL;
+
+      /* Enable the DMA stream */
+      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->XferM1CpltCallback = NULL;
+      hi2c->hdmarx->XferM1HalfCpltCallback = NULL;
+      hi2c->hdmarx->XferAbortCallback = NULL;
+
+      /* Enable the DMA stream */
+      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)
+{
+  /* 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);
+
+      /* Clear ADDR flag */
+      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+    }
+    else if (hi2c->XferSize == 2U)
+    {
+      /* Disable Acknowledge */
+      CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+      /* Enable Pos */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+
+      /* Clear ADDR flag */
+      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+    }
+    else
+    {
+      /* 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;
+          }
+
+          /* 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--;
+
+          /* 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);
+
+          /* 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 */
+          if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK)
+          {
+            return HAL_ERROR;
+          }
+
+          /* 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--;
+
+          /* Read data from DR */
+          *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+          /* Increment Buffer pointer */
+          hi2c->pBuffPtr++;
+
+          /* Update counter */
+          hi2c->XferSize--;
+          hi2c->XferCount--;
+        }
+      }
+      else
+      {
+        /* Wait until RXNE flag is set */
+        if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
+        {
+          return HAL_ERROR;
+        }
+
+        /* Read data from DR */
+        *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+        /* Increment Buffer pointer */
+        hi2c->pBuffPtr++;
+
+        /* Update counter */
+        hi2c->XferSize--;
+        hi2c->XferCount--;
+
+        if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET)
+        {
+          /* Read data from DR */
+          *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+          /* Increment Buffer pointer */
+          hi2c->pBuffPtr++;
+
+          /* Update counter */
+          hi2c->XferSize--;
+          hi2c->XferCount--;
+        }
+      }
+    }
+
+    hi2c->State = HAL_I2C_STATE_READY;
+    hi2c->Mode = HAL_I2C_MODE_NONE;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hi2c);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Write an amount of data in non-blocking mode with Interrupt to a specific memory address
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2C.
+  * @param  DevAddress Target device address: The device 7 bits address value
+  *         in datasheet must be shifted to the left before calling the interface
+  * @param  MemAddress Internal memory address
+  * @param  MemAddSize Size of internal memory address
+  * @param  pData Pointer to data buffer
+  * @param  Size Amount of data to be sent
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
+{
+  __IO uint32_t count = 0U;
+
+  /* Check the parameters */
+  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
+
+  if (hi2c->State == HAL_I2C_STATE_READY)
+  {
+    /* Wait until BUSY flag is reset */
+    count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
+    do
+    {
+      count--;
+      if (count == 0U)
+      {
+        hi2c->PreviousState       = I2C_STATE_NONE;
+        hi2c->State               = HAL_I2C_STATE_READY;
+        hi2c->Mode                = HAL_I2C_MODE_NONE;
+        hi2c->ErrorCode           |= HAL_I2C_ERROR_TIMEOUT;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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->XferM1CpltCallback = NULL;
+        hi2c->hdmatx->XferM1HalfCpltCallback = NULL;
+        hi2c->hdmatx->XferAbortCallback = NULL;
+
+        /* Enable the DMA stream */
+        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;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hi2c);
+
+        return HAL_ERROR;
+      }
+    }
+    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->XferM1CpltCallback = NULL;
+        hi2c->hdmarx->XferM1HalfCpltCallback = NULL;
+        hi2c->hdmarx->XferAbortCallback = NULL;
+
+        /* Enable the DMA stream */
+        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 = 1U;
+  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;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(hi2c);
+
+          return HAL_ERROR;
+        }
+      }
+      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;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(hi2c);
+
+          return HAL_ERROR;
+        }
+      }
+      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 stream */
+        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;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(hi2c);
+
+          return HAL_ERROR;
+        }
+      }
+      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;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(hi2c);
+
+          return HAL_ERROR;
+        }
+      }
+      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 stream */
+        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 stream */
+      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 stream */
+      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+    }
+    else
+    {
+      /* Update I2C state */
+      hi2c->State     = HAL_I2C_STATE_LISTEN;
+      hi2c->Mode      = HAL_I2C_MODE_NONE;
+
+      /* Update I2C error code */
+      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(hi2c);
+
+      return HAL_ERROR;
+    }
+
+    if (dmaxferstatus == HAL_OK)
+    {
+      /* Enable Address Acknowledge */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+      /* Clear ADDR flag */
+      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(hi2c);
+
+      /* Enable DMA Request */
+      SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+      /* Note : The I2C interrupts must be enabled after unlocking current process
+      to avoid the risk of I2C interrupt handle execution before current
+      process unlock */
+      /* Enable EVT and ERR interrupt */
+      __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+      return HAL_OK;
+    }
+    else
+    {
+      /* Update I2C state */
+      hi2c->State     = HAL_I2C_STATE_READY;
+      hi2c->Mode      = HAL_I2C_MODE_NONE;
+
+      /* Update I2C error code */
+      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(hi2c);
+
+      return HAL_ERROR;
+    }
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Enable the Address listen mode with Interrupt.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2C.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c)
+{
+  if (hi2c->State == HAL_I2C_STATE_READY)
+  {
+    hi2c->State = HAL_I2C_STATE_LISTEN;
+
+    /* Check if the I2C is already enabled */
+    if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
+    {
+      /* Enable I2C peripheral */
+      __HAL_I2C_ENABLE(hi2c);
+    }
+
+    /* Enable Address Acknowledge */
+    SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+    /* Enable EVT and ERR interrupt */
+    __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Disable the Address listen mode with Interrupt.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2C.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c)
+{
+  /* Declaration of tmp to prevent undefined behavior of volatile usage */
+  uint32_t tmp;
+
+  /* Disable Address listen mode only if a transfer is not ongoing */
+  if (hi2c->State == HAL_I2C_STATE_LISTEN)
+  {
+    tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
+    hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
+    hi2c->State = HAL_I2C_STATE_READY;
+    hi2c->Mode = HAL_I2C_MODE_NONE;
+
+    /* Disable Address Acknowledge */
+    CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+    /* Disable EVT and ERR interrupt */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Abort a master I2C IT or DMA process communication with Interrupt.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for the specified I2C.
+  * @param  DevAddress Target device address: The device 7 bits address value
+  *         in datasheet must be shifted to the left before calling the interface
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
+{
+  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+  HAL_I2C_ModeTypeDef CurrentMode   = hi2c->Mode;
+
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(DevAddress);
+
+  /* Abort Master transfer during Receive or Transmit process    */
+  if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && (CurrentMode == HAL_I2C_MODE_MASTER))
+  {
+    /* Process Locked */
+    __HAL_LOCK(hi2c);
+
+    hi2c->PreviousState = I2C_STATE_NONE;
+    hi2c->State = HAL_I2C_STATE_ABORT;
+
+    /* Disable Acknowledge */
+    CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+    /* Generate Stop */
+    SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+
+    hi2c->XferCount = 0U;
+
+    /* Disable EVT, BUF and ERR interrupt */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hi2c);
+
+    /* Call the corresponding callback to inform upper layer of End of Transfer */
+    I2C_ITError(hi2c);
+
+    return HAL_OK;
+  }
+  else
+  {
+    /* Wrong usage of abort function */
+    /* This function should be used only in case of abort monitored by master device */
+    /* Or periphal is not in busy state, mean there is no active sequence to be abort */
+    return HAL_ERROR;
+  }
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
+ * @{
+ */
+
+/**
+  * @brief  This function handles I2C event interrupt request.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2C.
+  * @retval None
+  */
+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
+{
+  uint32_t sr1itflags;
+  uint32_t sr2itflags               = 0U;
+  uint32_t itsources                = READ_REG(hi2c->Instance->CR2);
+  uint32_t CurrentXferOptions       = hi2c->XferOptions;
+  HAL_I2C_ModeTypeDef CurrentMode   = hi2c->Mode;
+  HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+
+  /* Master or Memory mode selected */
+  if ((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM))
+  {
+    sr2itflags   = READ_REG(hi2c->Instance->SR2);
+    sr1itflags   = READ_REG(hi2c->Instance->SR1);
+
+    /* Exit IRQ event until Start Bit detected in case of Other frame requested */
+    if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_SB) == RESET) && (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(CurrentXferOptions) == 1U))
+    {
+      return;
+    }
+
+    /* SB Set ----------------------------------------------------------------*/
+    if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_SB) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+    {
+      /* Convert OTHER_xxx XferOptions if any */
+      I2C_ConvertOtherXferOptions(hi2c);
+
+      I2C_Master_SB(hi2c);
+    }
+    /* ADD10 Set -------------------------------------------------------------*/
+    else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_ADD10) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+    {
+      I2C_Master_ADD10(hi2c);
+    }
+    /* ADDR Set --------------------------------------------------------------*/
+    else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_ADDR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+    {
+      I2C_Master_ADDR(hi2c);
+    }
+    /* I2C in mode Transmitter -----------------------------------------------*/
+    else if (I2C_CHECK_FLAG(sr2itflags, I2C_FLAG_TRA) != RESET)
+    {
+      /* Do not check buffer and BTF flag if a Xfer DMA is on going */
+      if (READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) != I2C_CR2_DMAEN)
+      {
+        /* TXE set and BTF reset -----------------------------------------------*/
+        if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_TXE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+        {
+          I2C_MasterTransmit_TXE(hi2c);
+        }
+        /* BTF set -------------------------------------------------------------*/
+        else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+        {
+          if (CurrentState == HAL_I2C_STATE_BUSY_TX)
+          {
+            I2C_MasterTransmit_BTF(hi2c);
+          }
+          else /* HAL_I2C_MODE_MEM */
+          {
+            if (CurrentMode == HAL_I2C_MODE_MEM)
+            {
+              I2C_MemoryTransmit_TXE_BTF(hi2c);
+            }
+          }
+        }
+        else
+        {
+          /* Do nothing */
+        }
+      }
+    }
+    /* I2C in mode Receiver --------------------------------------------------*/
+    else
+    {
+      /* Do not check buffer and BTF flag if a Xfer DMA is on going */
+      if (READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) != I2C_CR2_DMAEN)
+      {
+        /* RXNE set and BTF reset -----------------------------------------------*/
+        if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_RXNE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+        {
+          I2C_MasterReceive_RXNE(hi2c);
+        }
+        /* BTF set -------------------------------------------------------------*/
+        else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+        {
+          I2C_MasterReceive_BTF(hi2c);
+        }
+        else
+        {
+          /* Do nothing */
+        }
+      }
+    }
+  }
+  /* Slave mode selected */
+  else
+  {
+    /* If an error is detected, read only SR1 register to prevent */
+    /* a clear of ADDR flags by reading SR2 after reading SR1 in Error treatment */
+    if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+    {
+      sr1itflags   = READ_REG(hi2c->Instance->SR1);
+    }
+    else
+    {
+      sr2itflags   = READ_REG(hi2c->Instance->SR2);
+      sr1itflags   = READ_REG(hi2c->Instance->SR1);
+    }
+
+    /* ADDR set --------------------------------------------------------------*/
+    if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_ADDR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+    {
+      /* Now time to read SR2, this will clear ADDR flag automatically */
+      if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+      {
+        sr2itflags   = READ_REG(hi2c->Instance->SR2);
+      }
+      I2C_Slave_ADDR(hi2c, sr2itflags);
+    }
+    /* STOPF set --------------------------------------------------------------*/
+    else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_STOPF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+    {
+      I2C_Slave_STOPF(hi2c);
+    }
+    /* I2C in mode Transmitter -----------------------------------------------*/
+    else if ((CurrentState == HAL_I2C_STATE_BUSY_TX) || (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN))
+    {
+      /* TXE set and BTF reset -----------------------------------------------*/
+      if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_TXE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+      {
+        I2C_SlaveTransmit_TXE(hi2c);
+      }
+      /* BTF set -------------------------------------------------------------*/
+      else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+      {
+        I2C_SlaveTransmit_BTF(hi2c);
+      }
+      else
+      {
+        /* Do nothing */
+      }
+    }
+    /* I2C in mode Receiver --------------------------------------------------*/
+    else
+    {
+      /* RXNE set and BTF reset ----------------------------------------------*/
+      if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_RXNE) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_BUF) != RESET) && (I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) == RESET))
+      {
+        I2C_SlaveReceive_RXNE(hi2c);
+      }
+      /* BTF set -------------------------------------------------------------*/
+      else if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BTF) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_EVT) != RESET))
+      {
+        I2C_SlaveReceive_BTF(hi2c);
+      }
+      else
+      {
+        /* Do nothing */
+      }
+    }
+  }
+}
+
+/**
+  * @brief  This function handles I2C error interrupt request.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2C.
+  * @retval None
+  */
+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
+{
+  HAL_I2C_ModeTypeDef tmp1;
+  uint32_t tmp2;
+  HAL_I2C_StateTypeDef tmp3;
+  uint32_t tmp4;
+  uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1);
+  uint32_t itsources  = READ_REG(hi2c->Instance->CR2);
+  uint32_t error      = HAL_I2C_ERROR_NONE;
+  HAL_I2C_ModeTypeDef CurrentMode   = hi2c->Mode;
+
+  /* I2C Bus error interrupt occurred ----------------------------------------*/
+  if ((I2C_CHECK_FLAG(sr1itflags, I2C_FLAG_BERR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERR) != RESET))
+  {
+    error |= HAL_I2C_ERROR_BERR;
+
+    /* Clear BERR flag */
+    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
+  }
+
+  /* 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
+  {
+    /* Do nothing */
+  }
+}
+
+/**
+  * @brief  Handle RXNE flag for Master
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @retval None
+  */
+static void I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c)
+{
+  if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
+  {
+    uint32_t tmp;
+
+    tmp = hi2c->XferCount;
+    if (tmp > 3U)
+    {
+      /* Read data from DR */
+      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+      /* Increment Buffer pointer */
+      hi2c->pBuffPtr++;
+
+      /* Update counter */
+      hi2c->XferCount--;
+
+      if (hi2c->XferCount == (uint16_t)3)
+      {
+        /* Disable BUF interrupt, this help to treat correctly the last 4 bytes
+        on BTF subroutine */
+        /* Disable BUF interrupt */
+        __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+      }
+    }
+    else if ((hi2c->XferOptions != I2C_FIRST_AND_NEXT_FRAME) && ((tmp == 1U) || (tmp == 0U)))
+    {
+      if (I2C_WaitOnSTOPRequestThroughIT(hi2c) == HAL_OK)
+      {
+        /* Disable Acknowledge */
+        CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+        /* Disable EVT, BUF and ERR interrupt */
+        __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+        /* Read data from DR */
+        *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+        /* Increment Buffer pointer */
+        hi2c->pBuffPtr++;
+
+        /* Update counter */
+        hi2c->XferCount--;
+
+        hi2c->State = HAL_I2C_STATE_READY;
+
+        if (hi2c->Mode == HAL_I2C_MODE_MEM)
+        {
+          hi2c->Mode = HAL_I2C_MODE_NONE;
+          hi2c->PreviousState = I2C_STATE_NONE;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+          hi2c->MemRxCpltCallback(hi2c);
+#else
+          HAL_I2C_MemRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+        }
+        else
+        {
+          hi2c->Mode = HAL_I2C_MODE_NONE;
+          hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+          hi2c->MasterRxCpltCallback(hi2c);
+#else
+          HAL_I2C_MasterRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+        }
+      }
+      else
+      {
+        /* Disable EVT, BUF and ERR interrupt */
+        __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+
+        /* Read data from DR */
+        *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+        /* Increment Buffer pointer */
+        hi2c->pBuffPtr++;
+
+        /* Update counter */
+        hi2c->XferCount--;
+
+        hi2c->State = HAL_I2C_STATE_READY;
+        hi2c->Mode = HAL_I2C_MODE_NONE;
+
+        /* Call user error callback */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+        hi2c->ErrorCallback(hi2c);
+#else
+        HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+      }
+    }
+    else
+    {
+      /* Do nothing */
+    }
+  }
+}
+
+/**
+  * @brief  Handle BTF flag for Master receiver
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @retval None
+  */
+static void I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c)
+{
+  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
+  uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+  if (hi2c->XferCount == 4U)
+  {
+    /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
+       on BTF subroutine if there is a reception delay between N-1 and N byte */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+
+    /* Read data from DR */
+    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+    /* Increment Buffer pointer */
+    hi2c->pBuffPtr++;
+
+    /* Update counter */
+    hi2c->XferCount--;
+  }
+  else if (hi2c->XferCount == 3U)
+  {
+    /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
+       on BTF subroutine if there is a reception delay between N-1 and N byte */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
+
+    if ((CurrentXferOptions != I2C_NEXT_FRAME) && (CurrentXferOptions != I2C_FIRST_AND_NEXT_FRAME))
+    {
+      /* Disable Acknowledge */
+      CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+    }
+
+    /* Read data from DR */
+    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+    /* Increment Buffer pointer */
+    hi2c->pBuffPtr++;
+
+    /* Update counter */
+    hi2c->XferCount--;
+  }
+  else if (hi2c->XferCount == 2U)
+  {
+    /* Prepare next transfer or stop current transfer */
+    if ((CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME_NO_STOP))
+    {
+      /* Disable Acknowledge */
+      CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+    }
+    else if ((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_AND_NEXT_FRAME))
+    {
+      /* Enable Acknowledge */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+    }
+    else if (CurrentXferOptions != I2C_LAST_FRAME_NO_STOP)
+    {
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+    }
+    else
+    {
+      /* Do nothing */
+    }
+
+    /* Read data from DR */
+    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+    /* Increment Buffer pointer */
+    hi2c->pBuffPtr++;
+
+    /* Update counter */
+    hi2c->XferCount--;
+
+    /* Read data from DR */
+    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+    /* Increment Buffer pointer */
+    hi2c->pBuffPtr++;
+
+    /* Update counter */
+    hi2c->XferCount--;
+
+    /* Disable EVT and ERR interrupt */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+    hi2c->State = HAL_I2C_STATE_READY;
+    if (hi2c->Mode == HAL_I2C_MODE_MEM)
+    {
+      hi2c->Mode = HAL_I2C_MODE_NONE;
+      hi2c->PreviousState = I2C_STATE_NONE;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+      hi2c->MemRxCpltCallback(hi2c);
+#else
+      HAL_I2C_MemRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+    }
+    else
+    {
+      hi2c->Mode = HAL_I2C_MODE_NONE;
+      hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+      hi2c->MasterRxCpltCallback(hi2c);
+#else
+      HAL_I2C_MasterRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+    }
+  }
+  else
+  {
+    /* Read data from DR */
+    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+    /* Increment Buffer pointer */
+    hi2c->pBuffPtr++;
+
+    /* Update counter */
+    hi2c->XferCount--;
+  }
+}
+
+/**
+  * @brief  Handle SB flag for Master
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @retval None
+  */
+static void I2C_Master_SB(I2C_HandleTypeDef *hi2c)
+{
+  if (hi2c->Mode == HAL_I2C_MODE_MEM)
+  {
+    if (hi2c->EventCount == 0U)
+    {
+      /* Send slave address */
+      hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
+    }
+    else
+    {
+      hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);
+    }
+  }
+  else
+  {
+    if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+    {
+      /* Send slave 7 Bits address */
+      if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
+      {
+        hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress);
+      }
+      else
+      {
+        hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress);
+      }
+
+      if (((hi2c->hdmatx != NULL) && (hi2c->hdmatx->XferCpltCallback != NULL))
+          || ((hi2c->hdmarx != NULL) && (hi2c->hdmarx->XferCpltCallback != NULL)))
+      {
+        /* Enable DMA Request */
+        SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+      }
+    }
+    else
+    {
+      if (hi2c->EventCount == 0U)
+      {
+        /* Send header of slave address */
+        hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress);
+      }
+      else if (hi2c->EventCount == 1U)
+      {
+        /* Send header of slave address */
+        hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress);
+      }
+      else
+      {
+        /* Do nothing */
+      }
+    }
+  }
+}
+
+/**
+  * @brief  Handle ADD10 flag for Master
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @retval None
+  */
+static void I2C_Master_ADD10(I2C_HandleTypeDef *hi2c)
+{
+  /* Send slave address */
+  hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress);
+
+  if (((hi2c->hdmatx != NULL) && (hi2c->hdmatx->XferCpltCallback != NULL))
+      || ((hi2c->hdmarx != NULL) && (hi2c->hdmarx->XferCpltCallback != NULL)))
+  {
+    /* Enable DMA Request */
+    SET_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+  }
+}
+
+/**
+  * @brief  Handle ADDR flag for Master
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @retval None
+  */
+static void I2C_Master_ADDR(I2C_HandleTypeDef *hi2c)
+{
+  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+  HAL_I2C_ModeTypeDef CurrentMode       = hi2c->Mode;
+  uint32_t CurrentXferOptions           = hi2c->XferOptions;
+  uint32_t Prev_State                   = hi2c->PreviousState;
+
+  if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
+  {
+    if ((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM))
+    {
+      /* Clear ADDR flag */
+      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+    }
+    else if ((hi2c->EventCount == 0U) && (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT))
+    {
+      /* Clear ADDR flag */
+      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+      /* Generate Restart */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+      hi2c->EventCount++;
+    }
+    else
+    {
+      if (hi2c->XferCount == 0U)
+      {
+        /* Clear ADDR flag */
+        __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+        /* Generate Stop */
+        SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+      }
+      else if (hi2c->XferCount == 1U)
+      {
+        if (CurrentXferOptions == I2C_NO_OPTION_FRAME)
+        {
+          /* Disable Acknowledge */
+          CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+          if ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+          {
+            /* Disable Acknowledge */
+            CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+            /* Clear ADDR flag */
+            __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+          }
+          else
+          {
+            /* Clear ADDR flag */
+            __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+            /* Generate Stop */
+            SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+          }
+        }
+        /* Prepare next transfer or stop current transfer */
+        else if ((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) \
+                 && ((Prev_State != I2C_STATE_MASTER_BUSY_RX) || (CurrentXferOptions == I2C_FIRST_FRAME)))
+        {
+          if ((CurrentXferOptions != I2C_NEXT_FRAME) && (CurrentXferOptions != I2C_FIRST_AND_NEXT_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME_NO_STOP))
+          {
+            /* Disable Acknowledge */
+            CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+          }
+          else
+          {
+            /* Enable Acknowledge */
+            SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+          }
+
+          /* Clear ADDR flag */
+          __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+        }
+        else
+        {
+          /* Disable Acknowledge */
+          CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+          /* Clear ADDR flag */
+          __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+          /* Generate Stop */
+          SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+        }
+      }
+      else if (hi2c->XferCount == 2U)
+      {
+        if ((CurrentXferOptions != I2C_NEXT_FRAME) && (CurrentXferOptions != I2C_FIRST_AND_NEXT_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME_NO_STOP))
+        {
+          /* Disable Acknowledge */
+          CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+          /* Enable Pos */
+          SET_BIT(hi2c->Instance->CR1, I2C_CR1_POS);
+        }
+        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);
+      }
+      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)(__HAL_DMA_GET_COUNTER(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)(__HAL_DMA_GET_COUNTER(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);
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+    hi2c->SlaveTxCpltCallback(hi2c);
+#else
+    HAL_I2C_SlaveTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+  }
+  else
+  {
+    /* Clear AF flag only */
+    /* State Listen, but XferOptions == FIRST or NEXT */
+    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+  }
+}
+
+/**
+  * @brief  I2C interrupts error process
+  * @param  hi2c I2C handle.
+  * @retval None
+  */
+static void I2C_ITError(I2C_HandleTypeDef *hi2c)
+{
+  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+  HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+  HAL_I2C_ModeTypeDef CurrentMode = hi2c->Mode;
+  uint32_t CurrentError;
+
+  if (((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) && (CurrentState == HAL_I2C_STATE_BUSY_RX))
+  {
+    /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */
+    hi2c->Instance->CR1 &= ~I2C_CR1_POS;
+  }
+
+  if (((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
+  {
+    /* keep HAL_I2C_STATE_LISTEN */
+    hi2c->PreviousState = I2C_STATE_NONE;
+    hi2c->State = HAL_I2C_STATE_LISTEN;
+  }
+  else
+  {
+    /* If state is an abort treatment on going, don't change state */
+    /* This change will be do later */
+    if ((READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) != I2C_CR2_DMAEN) && (CurrentState != HAL_I2C_STATE_ABORT))
+    {
+      hi2c->State = HAL_I2C_STATE_READY;
+      hi2c->Mode = HAL_I2C_MODE_NONE;
+    }
+    hi2c->PreviousState = I2C_STATE_NONE;
+  }
+
+  /* Abort DMA transfer */
+  if (READ_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN) == I2C_CR2_DMAEN)
+  {
+    hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN;
+
+    if (hi2c->hdmatx->State != HAL_DMA_STATE_READY)
+    {
+      /* Set the DMA Abort callback :
+      will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+      hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
+
+      if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
+      {
+        /* Disable I2C peripheral to prevent dummy data in buffer */
+        __HAL_I2C_DISABLE(hi2c);
+
+        hi2c->State = HAL_I2C_STATE_READY;
+
+        /* Call Directly XferAbortCallback function in case of error */
+        hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
+      }
+    }
+    else
+    {
+      /* Set the DMA Abort callback :
+      will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+      hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
+
+      if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
+      {
+        /* Store Last receive data if any */
+        if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+        {
+          /* Read data from DR */
+          *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+          /* Increment Buffer pointer */
+          hi2c->pBuffPtr++;
+        }
+
+        /* Disable I2C peripheral to prevent dummy data in buffer */
+        __HAL_I2C_DISABLE(hi2c);
+
+        hi2c->State = HAL_I2C_STATE_READY;
+
+        /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */
+        hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
+      }
+    }
+  }
+  else if (hi2c->State == HAL_I2C_STATE_ABORT)
+  {
+    hi2c->State = HAL_I2C_STATE_READY;
+    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+    /* Store Last receive data if any */
+    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+    {
+      /* Read data from DR */
+      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+      /* Increment Buffer pointer */
+      hi2c->pBuffPtr++;
+    }
+
+    /* Disable I2C peripheral to prevent dummy data in buffer */
+    __HAL_I2C_DISABLE(hi2c);
+
+    /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+    hi2c->AbortCpltCallback(hi2c);
+#else
+    HAL_I2C_AbortCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+  }
+  else
+  {
+    /* Store Last receive data if any */
+    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+    {
+      /* Read data from DR */
+      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;
+
+      /* Increment Buffer pointer */
+      hi2c->pBuffPtr++;
+    }
+
+    /* Call user error callback */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+    hi2c->ErrorCallback(hi2c);
+#else
+    HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+  }
+
+  /* STOP Flag is not set after a NACK reception, BusError, ArbitrationLost, OverRun */
+  CurrentError = hi2c->ErrorCode;
+
+  if (((CurrentError & HAL_I2C_ERROR_BERR) == HAL_I2C_ERROR_BERR) || \
+      ((CurrentError & HAL_I2C_ERROR_ARLO) == HAL_I2C_ERROR_ARLO) || \
+      ((CurrentError & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)     || \
+      ((CurrentError & HAL_I2C_ERROR_OVR) == HAL_I2C_ERROR_OVR))
+  {
+    /* Disable EVT, BUF and ERR interrupt */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
+  }
+
+  /* So may inform upper layer that listen phase is stopped */
+  /* during NACK error treatment */
+  CurrentState = hi2c->State;
+  if (((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF) && (CurrentState == HAL_I2C_STATE_LISTEN))
+  {
+    hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
+    hi2c->PreviousState = I2C_STATE_NONE;
+    hi2c->State         = HAL_I2C_STATE_READY;
+    hi2c->Mode          = HAL_I2C_MODE_NONE;
+
+    /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+    hi2c->ListenCpltCallback(hi2c);
+#else
+    HAL_I2C_ListenCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+  }
+}
+
+/**
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @param  DevAddress Target device address: The device 7 bits address value
+  *         in datasheet must be shifted to the left before calling the interface
+  * @param  Timeout Timeout duration
+  * @param  Tickstart Tick start value
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart)
+{
+  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+  uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+  /* Generate Start condition if first transfer */
+  if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME))
+  {
+    /* Generate Start */
+    SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+  }
+  else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
+  {
+    /* Generate ReStart */
+    SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+  }
+  else
+  {
+    /* Do nothing */
+  }
+
+  /* Wait until SB flag is set */
+  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+  {
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
+  }
+
+  if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+  {
+    /* Send slave address */
+    hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
+  }
+  else
+  {
+    /* Send header of slave address */
+    hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress);
+
+    /* Wait until ADD10 flag is set */
+    if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK)
+    {
+      return HAL_ERROR;
+    }
+
+    /* Send slave address */
+    hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress);
+  }
+
+  /* Wait until ADDR flag is set */
+  if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+  {
+    return HAL_ERROR;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Master sends target device address for read request.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @param  DevAddress Target device address: The device 7 bits address value
+  *         in datasheet must be shifted to the left before calling the interface
+  * @param  Timeout Timeout duration
+  * @param  Tickstart Tick start value
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart)
+{
+  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+  uint32_t CurrentXferOptions = hi2c->XferOptions;
+
+  /* Enable Acknowledge */
+  SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+  /* Generate Start condition if first transfer */
+  if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)  || (CurrentXferOptions == I2C_NO_OPTION_FRAME))
+  {
+    /* Generate Start */
+    SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+  }
+  else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX)
+  {
+    /* Generate ReStart */
+    SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+  }
+  else
+  {
+    /* Do nothing */
+  }
+
+  /* Wait until SB flag is set */
+  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+  {
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
+  }
+
+  if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
+  {
+    /* Send slave address */
+    hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
+  }
+  else
+  {
+    /* Send header of slave address */
+    hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress);
+
+    /* Wait until ADD10 flag is set */
+    if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK)
+    {
+      return HAL_ERROR;
+    }
+
+    /* Send slave address */
+    hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress);
+
+    /* Wait until ADDR flag is set */
+    if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+    {
+      return HAL_ERROR;
+    }
+
+    /* Clear ADDR flag */
+    __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+    /* Generate Restart */
+    SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+    /* Wait until SB flag is set */
+    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+    {
+      if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+      {
+        hi2c->ErrorCode = HAL_I2C_WRONG_START;
+      }
+      return HAL_TIMEOUT;
+    }
+
+    /* Send header of slave address */
+    hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress);
+  }
+
+  /* Wait until ADDR flag is set */
+  if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+  {
+    return HAL_ERROR;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Master sends target device address followed by internal memory address for write request.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @param  DevAddress Target device address: The device 7 bits address value
+  *         in datasheet must be shifted to the left before calling the interface
+  * @param  MemAddress Internal memory address
+  * @param  MemAddSize Size of internal memory address
+  * @param  Timeout Timeout duration
+  * @param  Tickstart Tick start value
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
+{
+  /* Generate Start */
+  SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+  /* Wait until SB flag is set */
+  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+  {
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
+  }
+
+  /* Send slave address */
+  hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
+
+  /* Wait until ADDR flag is set */
+  if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Clear ADDR flag */
+  __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+  /* Wait until TXE flag is set */
+  if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+  {
+    if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+    {
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+    }
+    return HAL_ERROR;
+  }
+
+  /* If Memory address size is 8Bit */
+  if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
+  {
+    /* Send Memory Address */
+    hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+  }
+  /* If Memory address size is 16Bit */
+  else
+  {
+    /* Send MSB of Memory Address */
+    hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress);
+
+    /* Wait until TXE flag is set */
+    if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+    {
+      if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+      {
+        /* Generate Stop */
+        SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+      }
+      return HAL_ERROR;
+    }
+
+    /* Send LSB of Memory Address */
+    hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Master sends target device address followed by internal memory address for read request.
+  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
+  *         the configuration information for I2C module
+  * @param  DevAddress Target device address: The device 7 bits address value
+  *         in datasheet must be shifted to the left before calling the interface
+  * @param  MemAddress Internal memory address
+  * @param  MemAddSize Size of internal memory address
+  * @param  Timeout Timeout duration
+  * @param  Tickstart Tick start value
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
+{
+  /* Enable Acknowledge */
+  SET_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+
+  /* Generate Start */
+  SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+  /* Wait until SB flag is set */
+  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+  {
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
+  }
+
+  /* Send slave address */
+  hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
+
+  /* Wait until ADDR flag is set */
+  if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Clear ADDR flag */
+  __HAL_I2C_CLEAR_ADDRFLAG(hi2c);
+
+  /* Wait until TXE flag is set */
+  if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+  {
+    if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+    {
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+    }
+    return HAL_ERROR;
+  }
+
+  /* If Memory address size is 8Bit */
+  if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
+  {
+    /* Send Memory Address */
+    hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+  }
+  /* If Memory address size is 16Bit */
+  else
+  {
+    /* Send MSB of Memory Address */
+    hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress);
+
+    /* Wait until TXE flag is set */
+    if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+    {
+      if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+      {
+        /* Generate Stop */
+        SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+      }
+      return HAL_ERROR;
+    }
+
+    /* Send LSB of Memory Address */
+    hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress);
+  }
+
+  /* Wait until TXE flag is set */
+  if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
+  {
+    if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+    {
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+    }
+    return HAL_ERROR;
+  }
+
+  /* Generate Restart */
+  SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
+
+  /* Wait until SB flag is set */
+  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
+  {
+    if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
+    {
+      hi2c->ErrorCode = HAL_I2C_WRONG_START;
+    }
+    return HAL_TIMEOUT;
+  }
+
+  /* Send slave address */
+  hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
+
+  /* Wait until ADDR flag is set */
+  if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK)
+  {
+    return HAL_ERROR;
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  DMA I2C process complete callback.
+  * @param  hdma DMA handle
+  * @retval None
+  */
+static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma)
+{
+  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
+  HAL_I2C_StateTypeDef CurrentState = hi2c->State;
+  HAL_I2C_ModeTypeDef CurrentMode   = hi2c->Mode;
+  uint32_t CurrentXferOptions       = hi2c->XferOptions;
+
+  /* Disable EVT and ERR interrupt */
+  __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+  /* Clear Complete callback */
+  if (hi2c->hdmatx != NULL)
+  {
+    hi2c->hdmatx->XferCpltCallback = NULL;
+  }
+  if (hi2c->hdmarx != NULL)
+  {
+    hi2c->hdmarx->XferCpltCallback = NULL;
+  }
+
+  if ((((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_BUSY_TX) == (uint32_t)HAL_I2C_STATE_BUSY_TX) || ((((uint32_t)CurrentState & (uint32_t)HAL_I2C_STATE_BUSY_RX) == (uint32_t)HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE)))
+  {
+    /* Disable DMA Request */
+    CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+    hi2c->XferCount = 0U;
+
+    if (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)
+    {
+      /* Set state at HAL_I2C_STATE_LISTEN */
+      hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
+      hi2c->State = HAL_I2C_STATE_LISTEN;
+
+      /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+      hi2c->SlaveTxCpltCallback(hi2c);
+#else
+      HAL_I2C_SlaveTxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+    }
+    else if (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)
+    {
+      /* Set state at HAL_I2C_STATE_LISTEN */
+      hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
+      hi2c->State = HAL_I2C_STATE_LISTEN;
+
+      /* Call the corresponding callback to inform upper layer of End of Transfer */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+      hi2c->SlaveRxCpltCallback(hi2c);
+#else
+      HAL_I2C_SlaveRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+    }
+    else
+    {
+      /* Do nothing */
+    }
+
+    /* Enable EVT and ERR interrupt to treat end of transfer in IRQ handler */
+    __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+  }
+  /* Check current Mode, in case of treatment DMA handler have been preempted by a prior interrupt */
+  else if (hi2c->Mode != HAL_I2C_MODE_NONE)
+  {
+    if (hi2c->XferCount == (uint16_t)1)
+    {
+      /* Disable Acknowledge */
+      CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
+    }
+
+    /* Disable EVT and ERR interrupt */
+    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR);
+
+    /* Prepare next transfer or stop current transfer */
+    if ((CurrentXferOptions == I2C_NO_OPTION_FRAME) || (CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_OTHER_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME))
+    {
+      /* Generate Stop */
+      SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
+    }
+
+    /* Disable Last DMA */
+    CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_LAST);
+
+    /* Disable DMA Request */
+    CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_DMAEN);
+
+    hi2c->XferCount = 0U;
+
+    /* Check if Errors has been detected during transfer */
+    if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+    {
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+      hi2c->ErrorCallback(hi2c);
+#else
+      HAL_I2C_ErrorCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+    }
+    else
+    {
+      hi2c->State = HAL_I2C_STATE_READY;
+
+      if (hi2c->Mode == HAL_I2C_MODE_MEM)
+      {
+        hi2c->Mode = HAL_I2C_MODE_NONE;
+        hi2c->PreviousState = I2C_STATE_NONE;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+        hi2c->MemRxCpltCallback(hi2c);
+#else
+        HAL_I2C_MemRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+      }
+      else
+      {
+        hi2c->Mode = HAL_I2C_MODE_NONE;
+        hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+        hi2c->MasterRxCpltCallback(hi2c);
+#else
+        HAL_I2C_MasterRxCpltCallback(hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+      }
+    }
+  }
+  else
+  {
+    /* Do nothing */
+  }
+}
+
+/**
+  * @brief  DMA I2C communication error callback.
+  * @param  hdma DMA handle
+  * @retval None
+  */
+static void I2C_DMAError(DMA_HandleTypeDef *hdma)
+{
+  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+  /* Clear Complete callback */
+  if (hi2c->hdmatx != NULL)
+  {
+    hi2c->hdmatx->XferCpltCallback = NULL;
+  }
+  if (hi2c->hdmarx != NULL)
+  {
+    hi2c->hdmarx->XferCpltCallback = NULL;
+  }
+
+  /* Ignore DMA FIFO error */
+  if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
+  {
+    /* Disable Acknowledge */
+    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))
+      {
+        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))
+      {
+        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))
+      {
+        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))
+      {
+        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))
+    {
+      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))
+    {
+      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 */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 184 - 0
stm32workspace/dosimeter-fw/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c

@@ -0,0 +1,184 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_hal_i2c_ex.c
+  * @author  MCD Application Team
+  * @brief   I2C Extension HAL module driver.
+  *          This file provides firmware functions to manage the following
+  *          functionalities of I2C extension peripheral:
+  *           + Extension features functions
+  *
+  @verbatim
+  ==============================================================================
+               ##### I2C peripheral extension features  #####
+  ==============================================================================
+
+  [..] Comparing to other previous devices, the I2C interface for STM32F427xx/437xx/
+       429xx/439xx devices contains the following additional features :
+
+       (+) Possibility to disable or enable Analog Noise Filter
+       (+) Use of a configured Digital Noise Filter
+
+                     ##### How to use this driver #####
+  ==============================================================================
+  [..] This driver provides functions to configure Noise Filter
+    (#) Configure I2C Analog noise filter using the function HAL_I2C_AnalogFilter_Config()
+    (#) Configure I2C Digital noise filter using the function HAL_I2C_DigitalFilter_Config()
+
+  @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup I2CEx I2CEx
+  * @brief I2C HAL module driver
+  * @{
+  */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+
+#if  defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup I2CEx_Exported_Functions I2C Exported Functions
+  * @{
+  */
+
+
+/** @defgroup I2CEx_Exported_Functions_Group1 Extension features functions
+ *  @brief   Extension features functions
+ *
+@verbatim
+ ===============================================================================
+                      ##### Extension features functions #####
+ ===============================================================================
+    [..] This section provides functions allowing to:
+      (+) Configure Noise Filters
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Configures I2C Analog noise filter.
+  * @param  hi2c pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2Cx peripheral.
+  * @param  AnalogFilter new state of the Analog filter.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter)
+{
+  /* Check the parameters */
+  assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
+  assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter));
+
+  if (hi2c->State == HAL_I2C_STATE_READY)
+  {
+    hi2c->State = HAL_I2C_STATE_BUSY;
+
+    /* Disable the selected I2C peripheral */
+    __HAL_I2C_DISABLE(hi2c);
+
+    /* Reset I2Cx ANOFF bit */
+    hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF);
+
+    /* Disable the analog filter */
+    hi2c->Instance->FLTR |= AnalogFilter;
+
+    __HAL_I2C_ENABLE(hi2c);
+
+    hi2c->State = HAL_I2C_STATE_READY;
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Configures I2C Digital noise filter.
+  * @param  hi2c pointer to a I2C_HandleTypeDef structure that contains
+  *                the configuration information for the specified I2Cx peripheral.
+  * @param  DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter)
+{
+  uint16_t tmpreg = 0;
+
+  /* Check the parameters */
+  assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
+  assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter));
+
+  if (hi2c->State == HAL_I2C_STATE_READY)
+  {
+    hi2c->State = HAL_I2C_STATE_BUSY;
+
+    /* Disable the selected I2C peripheral */
+    __HAL_I2C_DISABLE(hi2c);
+
+    /* Get the old register value */
+    tmpreg = hi2c->Instance->FLTR;
+
+    /* Reset I2Cx DNF bit [3:0] */
+    tmpreg &= ~(I2C_FLTR_DNF);
+
+    /* Set I2Cx DNF coefficient */
+    tmpreg |= DigitalFilter;
+
+    /* Store the new register value */
+    hi2c->Instance->FLTR = tmpreg;
+
+    __HAL_I2C_ENABLE(hi2c);
+
+    hi2c->State = HAL_I2C_STATE_READY;
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+#endif
+
+#endif /* HAL_I2C_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 0 - 2786
stm32workspace/dosimeter-fw/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smbus.c

@@ -1,2786 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32f4xx_hal_smbus.c
-  * @author  MCD Application Team
-  * @brief   SMBUS HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities of the System Management Bus (SMBus) peripheral,
-  *          based on SMBUS principals of operation :
-  *           + Initialization and de-initialization functions
-  *           + IO operation functions
-  *           + Peripheral State, Mode and Error functions
-  *
-  @verbatim
-  ==============================================================================
-                        ##### How to use this driver #####
-  ==============================================================================
-  [..]
-    The SMBUS HAL driver can be used as follows:
-
-    (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
-        SMBUS_HandleTypeDef  hsmbus;
-
-    (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
-        (##) Enable the SMBUSx interface clock
-        (##) SMBUS pins configuration
-            (+++) Enable the clock for the SMBUS GPIOs
-            (+++) Configure SMBUS pins as alternate function open-drain
-        (##) NVIC configuration if you need to use interrupt process
-            (+++) Configure the SMBUSx interrupt priority
-            (+++) Enable the NVIC SMBUS IRQ Channel
-
-    (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,
-        Dual Addressing mode, Own Address2, General call and Nostretch mode in the hsmbus Init structure.
-
-    (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init(), configures also the low level Hardware
-        (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
-
-    (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
-
-    (#) For SMBUS IO operations, only one mode of operations is available within this driver :
-
-
-    *** Interrupt mode IO operation ***
-    ===================================
-
-  [..]
-      (+) Transmit in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Transmit_IT()
-      (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
-      (+) Receive in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Receive_IT()
-      (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
-      (+) Abort a master/Host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
-      (++) End of abort process, HAL_SMBUS_AbortCpltCallback() is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_AbortCpltCallback()
-      (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
-           using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
-      (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and user can
-           add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
-      (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
-      (+) Transmit in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Transmit_IT()
-      (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
-      (+) Receive in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Receive_IT()
-      (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
-      (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() and HAL_SMBUS_DisableAlert_IT()
-      (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
-           to check the Alert Error Code using function HAL_SMBUS_GetError()
-      (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
-      (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can
-           add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
-           to check the Error Code using function HAL_SMBUS_GetError()
-
-
-     *** SMBUS HAL driver macros list ***
-     ==================================
-     [..]
-       Below the list of most used macros in SMBUS HAL driver.
-
-      (+) __HAL_SMBUS_ENABLE    : Enable the SMBUS peripheral
-      (+) __HAL_SMBUS_DISABLE   : Disable the SMBUS peripheral
-      (+) __HAL_SMBUS_GET_FLAG  : Checks whether the specified SMBUS flag is set or not
-      (+) __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag
-      (+) __HAL_SMBUS_ENABLE_IT : Enable the specified SMBUS interrupt
-      (+) __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt
-
-     [..]
-       (@) You can refer to the SMBUS HAL driver header file for more useful macros
-
-     *** Callback registration ***
-     =============================================
-    [..]
-     The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
-     allows the user to configure dynamically the driver callbacks.
-     Use Functions HAL_SMBUS_RegisterCallback() or HAL_SMBUS_RegisterXXXCallback()
-     to register an interrupt callback.
-
-     Function HAL_SMBUS_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.
-       (+) 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_SMBUS_RegisterAddrCallback().
-    [..]
-     Use function HAL_SMBUS_UnRegisterCallback to reset a callback to the default
-     weak function.
-     HAL_SMBUS_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.
-       (+) 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_SMBUS_UnRegisterAddrCallback().
-    [..]
-     By default, after the HAL_SMBUS_Init() and when the state is HAL_SMBUS_STATE_RESET
-     all callbacks are set to the corresponding weak functions:
-     examples HAL_SMBUS_MasterTxCpltCallback(), HAL_SMBUS_MasterRxCpltCallback().
-     Exception done for MspInit and MspDeInit functions that are
-     reset to the legacy weak functions in the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() only when
-     these callbacks are null (not registered beforehand).
-     If MspInit or MspDeInit are not null, the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit()
-     keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
-    [..]
-     Callbacks can be registered/unregistered in HAL_SMBUS_STATE_READY state only.
-     Exception done MspInit/MspDeInit functions that can be registered/unregistered
-     in HAL_SMBUS_STATE_READY or HAL_SMBUS_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_SMBUS_RegisterCallback() before calling HAL_SMBUS_DeInit()
-     or HAL_SMBUS_Init() function.
-    [..]
-     When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
-     not defined, the callback registration feature is not available and all callbacks
-     are set to the corresponding weak functions.
-
-  @endverbatim
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under BSD 3-Clause license,
-  * the "License"; You may not use this file except in compliance with the
-  * License. You may obtain a copy of the License at:
-  *                        opensource.org/licenses/BSD-3-Clause
-  *
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f4xx_hal.h"
-
-/** @addtogroup STM32F4xx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup SMBUS SMBUS
-  * @brief SMBUS HAL module driver
-  * @{
-  */
-
-#ifdef HAL_SMBUS_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup SMBUS_Private_Define
-  * @{
-  */
-#define SMBUS_TIMEOUT_FLAG          35U         /*!< Timeout 35 ms             */
-#define SMBUS_TIMEOUT_BUSY_FLAG     25U         /*!< Timeout 25 ms             */
-#define SMBUS_NO_OPTION_FRAME       0xFFFF0000U /*!< XferOptions default value */
-
-#define SMBUS_SENDPEC_MODE          I2C_CR1_PEC
-#define SMBUS_GET_PEC(__HANDLE__)             (((__HANDLE__)->Instance->SR2 & I2C_SR2_PEC) >> 8)
-
-/* Private define for @ref PreviousState usage */
-#define SMBUS_STATE_MSK             ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX | HAL_SMBUS_STATE_BUSY_RX) & (~(uint32_t)HAL_SMBUS_STATE_READY))) /*!< Mask State define, keep only RX and TX bits            */
-#define SMBUS_STATE_NONE            ((uint32_t)(HAL_SMBUS_MODE_NONE))                                                                      /*!< Default Value                                          */
-#define SMBUS_STATE_MASTER_BUSY_TX  ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_MASTER))                      /*!< Master Busy TX, combinaison of State LSB and Mode enum */
-#define SMBUS_STATE_MASTER_BUSY_RX  ((uint32_t)((HAL_SMBUS_STATE_BUSY_RX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_MASTER))                      /*!< Master Busy RX, combinaison of State LSB and Mode enum */
-#define SMBUS_STATE_SLAVE_BUSY_TX   ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_SLAVE))                       /*!< Slave Busy TX, combinaison of State LSB and Mode enum  */
-#define SMBUS_STATE_SLAVE_BUSY_RX   ((uint32_t)((HAL_SMBUS_STATE_BUSY_RX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_SLAVE))                       /*!< Slave Busy RX, combinaison of State LSB and Mode enum  */
-
-/**
-  * @}
-  */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-
-/** @addtogroup SMBUS_Private_Functions
-  * @{
-  */
-
-static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
-static void SMBUS_ITError(SMBUS_HandleTypeDef *hsmbus);
-
-/* Private functions for SMBUS transfer IRQ handler */
-static HAL_StatusTypeDef SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_Master_SB(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_Master_ADD10(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_Master_ADDR(SMBUS_HandleTypeDef *hsmbus);
-
-static HAL_StatusTypeDef SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_Slave_ADDR(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_Slave_STOPF(SMBUS_HandleTypeDef *hsmbus);
-static HAL_StatusTypeDef SMBUS_Slave_AF(SMBUS_HandleTypeDef *hsmbus);
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
-  * @{
-  */
-
-/** @defgroup SMBUS_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 SMBUSx peripheral:
-
-      (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
-          all related peripherals resources (CLOCK, GPIO, IT and NVIC).
-
-      (+) Call the function HAL_SMBUS_Init() to configure the selected device with
-          the selected configuration:
-        (++) Communication Speed
-        (++) Addressing mode
-        (++) Own Address 1
-        (++) Dual Addressing mode
-        (++) Own Address 2
-        (++) General call mode
-        (++) Nostretch mode
-        (++) Packet Error Check mode
-        (++) Peripheral mode
-
-      (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
-          of the selected SMBUSx peripheral.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Initializes the SMBUS according to the specified parameters
-  *         in the SMBUS_InitTypeDef and initialize the associated handle.
-  * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
-{
-  uint32_t freqrange = 0U;
-  uint32_t pclk1 = 0U;
-
-  /* Check the SMBUS handle allocation */
-  if (hsmbus == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
-#if  defined(I2C_FLTR_ANOFF)
-  assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
-#endif
-  assert_param(IS_SMBUS_CLOCK_SPEED(hsmbus->Init.ClockSpeed));
-  assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
-  assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
-  assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
-  assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
-  assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
-  assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
-  assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
-  assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
-
-  if (hsmbus->State == HAL_SMBUS_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    hsmbus->Lock = HAL_UNLOCKED;
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-    /* Init the SMBUS Callback settings */
-    hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
-    hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
-    hsmbus->SlaveTxCpltCallback  = HAL_SMBUS_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
-    hsmbus->SlaveRxCpltCallback  = HAL_SMBUS_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
-    hsmbus->ListenCpltCallback   = HAL_SMBUS_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
-    hsmbus->ErrorCallback        = HAL_SMBUS_ErrorCallback;        /* Legacy weak ErrorCallback        */
-    hsmbus->AbortCpltCallback    = HAL_SMBUS_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
-    hsmbus->AddrCallback         = HAL_SMBUS_AddrCallback;         /* Legacy weak AddrCallback         */
-
-    if (hsmbus->MspInitCallback == NULL)
-    {
-      hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit  */
-    }
-
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    hsmbus->MspInitCallback(hsmbus);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    HAL_SMBUS_MspInit(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-  }
-
-  hsmbus->State = HAL_SMBUS_STATE_BUSY;
-
-  /* Disable the selected SMBUS peripheral */
-  __HAL_SMBUS_DISABLE(hsmbus);
-
-  /* Get PCLK1 frequency */
-  pclk1 = HAL_RCC_GetPCLK1Freq();
-
-  /* Calculate frequency range */
-  freqrange = SMBUS_FREQRANGE(pclk1);
-
-  /*---------------------------- SMBUSx CR2 Configuration ----------------------*/
-  /* Configure SMBUSx: Frequency range */
-  MODIFY_REG(hsmbus->Instance->CR2, I2C_CR2_FREQ, freqrange);
-
-  /*---------------------------- SMBUSx TRISE Configuration --------------------*/
-  /* Configure SMBUSx: Rise Time */
-  MODIFY_REG(hsmbus->Instance->TRISE, I2C_TRISE_TRISE, SMBUS_RISE_TIME(freqrange));
-
-  /*---------------------------- SMBUSx CCR Configuration ----------------------*/
-  /* Configure SMBUSx: Speed */
-  MODIFY_REG(hsmbus->Instance->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), SMBUS_SPEED_STANDARD(pclk1, hsmbus->Init.ClockSpeed));
-
-  /*---------------------------- SMBUSx CR1 Configuration ----------------------*/
-  /* Configure SMBUSx: Generalcall , PEC , Peripheral mode and  NoStretch mode */
-  MODIFY_REG(hsmbus->Instance->CR1, (I2C_CR1_NOSTRETCH | I2C_CR1_ENGC | I2C_CR1_ENPEC | I2C_CR1_ENARP | I2C_CR1_SMBTYPE | I2C_CR1_SMBUS), (hsmbus->Init.NoStretchMode | hsmbus->Init.GeneralCallMode |  hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode));
-
-  /*---------------------------- SMBUSx OAR1 Configuration ---------------------*/
-  /* Configure SMBUSx: Own Address1 and addressing mode */
-  MODIFY_REG(hsmbus->Instance->OAR1, (I2C_OAR1_ADDMODE | I2C_OAR1_ADD8_9 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD0), (hsmbus->Init.AddressingMode | hsmbus->Init.OwnAddress1));
-
-  /*---------------------------- SMBUSx OAR2 Configuration ---------------------*/
-  /* Configure SMBUSx: Dual mode and Own Address2 */
-  MODIFY_REG(hsmbus->Instance->OAR2, (I2C_OAR2_ENDUAL | I2C_OAR2_ADD2), (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2));
-#if  defined(I2C_FLTR_ANOFF)
-  /*---------------------------- SMBUSx FLTR Configuration ------------------------*/
-  /* Configure SMBUSx: Analog noise filter */
-  SET_BIT(hsmbus->Instance->FLTR, hsmbus->Init.AnalogFilter);
-#endif
-
-  /* Enable the selected SMBUS peripheral */
-  __HAL_SMBUS_ENABLE(hsmbus);
-
-  hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-  hsmbus->State = HAL_SMBUS_STATE_READY;
-  hsmbus->PreviousState = SMBUS_STATE_NONE;
-  hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-  hsmbus->XferPEC = 0x00;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitializes the SMBUS peripheral.
-  * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Check the SMBUS handle allocation */
-  if (hsmbus == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
-
-  hsmbus->State = HAL_SMBUS_STATE_BUSY;
-
-  /* Disable the SMBUS Peripheral Clock */
-  __HAL_SMBUS_DISABLE(hsmbus);
-
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-  if (hsmbus->MspDeInitCallback == NULL)
-  {
-    hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit  */
-  }
-
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
-  hsmbus->MspDeInitCallback(hsmbus);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
-  HAL_SMBUS_MspDeInit(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-
-  hsmbus->ErrorCode     = HAL_SMBUS_ERROR_NONE;
-  hsmbus->State         = HAL_SMBUS_STATE_RESET;
-  hsmbus->PreviousState = SMBUS_STATE_NONE;
-  hsmbus->Mode          = HAL_SMBUS_MODE_NONE;
-
-  /* Release Lock */
-  __HAL_UNLOCK(hsmbus);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initialize the SMBUS MSP.
-  * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS
-  * @retval None
-  */
-__weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-  /* NOTE : This function Should not be modified, when the callback is needed,
-            the HAL_SMBUS_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitialize the SMBUS MSP.
-  * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS
-  * @retval None
-  */
-__weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-  /* NOTE : This function Should not be modified, when the callback is needed,
-            the HAL_SMBUS_MspDeInit could be implemented in the user file
-   */
-}
-
-#if  defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
-/**
-  * @brief  Configures SMBUS Analog noise filter.
-  * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUSx peripheral.
-  * @param  AnalogFilter new state of the Analog filter.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter)
-{
-  /* Check the parameters */
-  assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
-  assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter));
-
-  if (hsmbus->State == HAL_SMBUS_STATE_READY)
-  {
-    hsmbus->State = HAL_SMBUS_STATE_BUSY;
-
-    /* Disable the selected SMBUS peripheral */
-    __HAL_SMBUS_DISABLE(hsmbus);
-
-    /* Reset SMBUSx ANOFF bit */
-    hsmbus->Instance->FLTR &= ~(I2C_FLTR_ANOFF);
-
-    /* Disable the analog filter */
-    hsmbus->Instance->FLTR |= AnalogFilter;
-
-    __HAL_SMBUS_ENABLE(hsmbus);
-
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-/**
-  * @brief  Configures SMBUS Digital noise filter.
-  * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUSx peripheral.
-  * @param  DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter)
-{
-  uint16_t tmpreg = 0;
-
-  /* Check the parameters */
-  assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
-  assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter));
-
-  if (hsmbus->State == HAL_SMBUS_STATE_READY)
-  {
-    hsmbus->State = HAL_SMBUS_STATE_BUSY;
-
-    /* Disable the selected SMBUS peripheral */
-    __HAL_SMBUS_DISABLE(hsmbus);
-
-    /* Get the old register value */
-    tmpreg = hsmbus->Instance->FLTR;
-
-    /* Reset SMBUSx DNF bit [3:0] */
-    tmpreg &= ~(I2C_FLTR_DNF);
-
-    /* Set SMBUSx DNF coefficient */
-    tmpreg |= DigitalFilter;
-
-    /* Store the new register value */
-    hsmbus->Instance->FLTR = tmpreg;
-
-    __HAL_SMBUS_ENABLE(hsmbus);
-
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-#endif
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-/**
-  * @brief  Register a User SMBUS Callback
-  *         To be used instead of the weak predefined callback
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @param  CallbackID ID of the callback to be registered
-  *         This parameter can be one of the following values:
-  *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
-  *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
-  *          @arg @ref HAL_SMBUS_ABORT_CB_ID Abort callback ID
-  *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
-  *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
-  * @param  pCallback pointer to the Callback function
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID, pSMBUS_CallbackTypeDef pCallback)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  if (pCallback == NULL)
-  {
-    /* Update the error code */
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-    return HAL_ERROR;
-  }
-  /* Process locked */
-  __HAL_LOCK(hsmbus);
-
-  if (HAL_SMBUS_STATE_READY == hsmbus->State)
-  {
-    switch (CallbackID)
-    {
-      case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
-        hsmbus->MasterTxCpltCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
-        hsmbus->MasterRxCpltCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
-        hsmbus->SlaveTxCpltCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
-        hsmbus->SlaveRxCpltCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
-        hsmbus->ListenCpltCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_ERROR_CB_ID :
-        hsmbus->ErrorCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_ABORT_CB_ID :
-        hsmbus->AbortCpltCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_MSPINIT_CB_ID :
-        hsmbus->MspInitCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_MSPDEINIT_CB_ID :
-        hsmbus->MspDeInitCallback = pCallback;
-        break;
-
-      default :
-        /* Update the error code */
-        hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status =  HAL_ERROR;
-        break;
-    }
-  }
-  else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
-  {
-    switch (CallbackID)
-    {
-      case HAL_SMBUS_MSPINIT_CB_ID :
-        hsmbus->MspInitCallback = pCallback;
-        break;
-
-      case HAL_SMBUS_MSPDEINIT_CB_ID :
-        hsmbus->MspDeInitCallback = pCallback;
-        break;
-
-      default :
-        /* Update the error code */
-        hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status =  HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    /* Update the error code */
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-    /* Return error status */
-    status =  HAL_ERROR;
-  }
-
-  /* Release Lock */
-  __HAL_UNLOCK(hsmbus);
-  return status;
-}
-
-/**
-  * @brief  Unregister an SMBUS Callback
-  *         SMBUS callback is redirected to the weak predefined callback
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @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_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
-  *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
-  *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
-  *          @arg @ref HAL_SMBUS_ABORT_CB_ID Abort callback ID
-  *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
-  *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Process locked */
-  __HAL_LOCK(hsmbus);
-
-  if (HAL_SMBUS_STATE_READY == hsmbus->State)
-  {
-    switch (CallbackID)
-    {
-      case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
-        hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
-        break;
-
-      case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
-        hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
-        break;
-
-      case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
-        hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
-        break;
-
-      case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
-        hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
-        break;
-
-      case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
-        hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
-        break;
-
-      case HAL_SMBUS_ERROR_CB_ID :
-        hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback;               /* Legacy weak ErrorCallback        */
-        break;
-
-      case HAL_SMBUS_ABORT_CB_ID :
-        hsmbus->AbortCpltCallback = HAL_SMBUS_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
-        break;
-
-      case HAL_SMBUS_MSPINIT_CB_ID :
-        hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
-        break;
-
-      case HAL_SMBUS_MSPDEINIT_CB_ID :
-        hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
-        break;
-
-      default :
-        /* Update the error code */
-        hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status =  HAL_ERROR;
-        break;
-    }
-  }
-  else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
-  {
-    switch (CallbackID)
-    {
-      case HAL_SMBUS_MSPINIT_CB_ID :
-        hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
-        break;
-
-      case HAL_SMBUS_MSPDEINIT_CB_ID :
-        hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
-        break;
-
-      default :
-        /* Update the error code */
-        hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status =  HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    /* Update the error code */
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-    /* Return error status */
-    status =  HAL_ERROR;
-  }
-
-  /* Release Lock */
-  __HAL_UNLOCK(hsmbus);
-  return status;
-}
-
-/**
-  * @brief  Register the Slave Address Match SMBUS Callback
-  *         To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @param  pCallback pointer to the Address Match Callback function
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, pSMBUS_AddrCallbackTypeDef pCallback)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  if (pCallback == NULL)
-  {
-    return HAL_ERROR;
-  }
-  /* Process locked */
-  __HAL_LOCK(hsmbus);
-
-  if (HAL_SMBUS_STATE_READY == hsmbus->State)
-  {
-    hsmbus->AddrCallback = pCallback;
-  }
-  else
-  {
-    /* Update the error code */
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-    /* Return error status */
-    status =  HAL_ERROR;
-  }
-
-  /* Release Lock */
-  __HAL_UNLOCK(hsmbus);
-  return status;
-}
-
-/**
-  * @brief  UnRegister the Slave Address Match SMBUS Callback
-  *         Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Process locked */
-  __HAL_LOCK(hsmbus);
-
-  if (HAL_SMBUS_STATE_READY == hsmbus->State)
-  {
-    hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback  */
-  }
-  else
-  {
-    /* Update the error code */
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
-
-    /* Return error status */
-    status =  HAL_ERROR;
-  }
-
-  /* Release Lock */
-  __HAL_UNLOCK(hsmbus);
-  return status;
-}
-
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-/** @defgroup SMBUS_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 SMBUS data
-    transfers.
-
-    (#) Blocking mode function to check if device is ready for usage is :
-        (++) HAL_SMBUS_IsDeviceReady()
-
-    (#) There is only one mode of transfer:
-       (++) Non Blocking mode : The communication is performed using Interrupts.
-            These functions return the status of the transfer startup.
-            The end of the data processing will be indicated through the
-            dedicated SMBUS IRQ when using Interrupt mode.
-
-    (#) Non Blocking mode functions with Interrupt are :
-        (++) HAL_SMBUS_Master_Transmit_IT()
-        (++) HAL_SMBUS_Master_Receive_IT()
-        (++) HAL_SMBUS_Master_Abort_IT()
-        (++) HAL_SMBUS_Slave_Transmit_IT()
-        (++) HAL_SMBUS_Slave_Receive_IT()
-        (++) HAL_SMBUS_EnableAlert_IT()
-        (++) HAL_SMBUS_DisableAlert_IT()
-
-    (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
-        (++) HAL_SMBUS_MasterTxCpltCallback()
-        (++) HAL_SMBUS_MasterRxCpltCallback()
-        (++) HAL_SMBUS_SlaveTxCpltCallback()
-        (++) HAL_SMBUS_SlaveRxCpltCallback()
-        (++) HAL_SMBUS_AddrCallback()
-        (++) HAL_SMBUS_ListenCpltCallback()
-        (++) HAL_SMBUS_ErrorCallback()
-        (++) HAL_SMBUS_AbortCpltCallback()
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Transmits in master mode an amount of data in blocking mode.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @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
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
-{
-  uint32_t count      = 0x00U;
-
-  /* Check the parameters */
-  assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
-  if (hsmbus->State == HAL_SMBUS_STATE_READY)
-  {
-    /* Check Busy Flag only if FIRST call of Master interface */
-    if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
-    {
-      /* Wait until BUSY flag is reset */
-      count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-      do
-      {
-        if (count-- == 0U)
-        {
-          hsmbus->PreviousState = SMBUS_STATE_NONE;
-          hsmbus->State = HAL_SMBUS_STATE_READY;
-
-          /* Process Unlocked */
-          __HAL_UNLOCK(hsmbus);
-
-          return HAL_TIMEOUT;
-        }
-      }
-      while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
-    }
-
-    /* Process Locked */
-    __HAL_LOCK(hsmbus);
-
-    /* Check if the SMBUS is already enabled */
-    if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
-    {
-      /* Enable SMBUS peripheral */
-      __HAL_SMBUS_ENABLE(hsmbus);
-    }
-
-    /* Disable Pos */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
-
-    hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX;
-    hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-    hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
-
-    /* Prepare transfer parameters */
-    hsmbus->pBuffPtr    = pData;
-    hsmbus->XferCount   = Size;
-    hsmbus->XferOptions = XferOptions;
-    hsmbus->XferSize    = hsmbus->XferCount;
-    hsmbus->Devaddress  = DevAddress;
-
-    /* Generate Start */
-    SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hsmbus);
-
-    /* Note : The SMBUS interrupts must be enabled after unlocking current process
-    to avoid the risk of hsmbus interrupt handle execution before current
-    process unlock */
-
-    /* Enable EVT, BUF and ERR interrupt */
-    __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-/**
-  * @brief  Receive in master/host SMBUS mode an amount of data in non blocking mode with Interrupt.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @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 SMBUS_XferOptions_definition
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
-{
-  __IO uint32_t count = 0U;
-
-  /* Check the parameters */
-  assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
-  if (hsmbus->State == HAL_SMBUS_STATE_READY)
-  {
-    /* Check Busy Flag only if FIRST call of Master interface */
-    if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
-    {
-      /* Wait until BUSY flag is reset */
-      count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
-      do
-      {
-        if (count-- == 0U)
-        {
-          hsmbus->PreviousState = SMBUS_STATE_NONE;
-          hsmbus->State = HAL_SMBUS_STATE_READY;
-
-          /* Process Unlocked */
-          __HAL_UNLOCK(hsmbus);
-
-          return HAL_TIMEOUT;
-        }
-      }
-      while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
-    }
-
-    /* Process Locked */
-    __HAL_LOCK(hsmbus);
-
-    /* Check if the SMBUS is already enabled */
-    if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
-    {
-      /* Enable SMBUS peripheral */
-      __HAL_SMBUS_ENABLE(hsmbus);
-    }
-
-    /* Disable Pos */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
-
-    hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX;
-    hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-    hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
-
-    /* Prepare transfer parameters */
-    hsmbus->pBuffPtr    = pData;
-    hsmbus->XferCount   = Size;
-    hsmbus->XferOptions = XferOptions;
-    hsmbus->XferSize    = hsmbus->XferCount;
-    hsmbus->Devaddress  = DevAddress;
-
-    if ((hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX) || (hsmbus->PreviousState == SMBUS_STATE_NONE))
-    {
-      /* Generate Start condition if first transfer */
-      if ((XferOptions == SMBUS_NEXT_FRAME)  || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME)  || (XferOptions == SMBUS_NO_OPTION_FRAME))
-      {
-        /* Enable Acknowledge */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-        /* Generate Start */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
-      }
-
-      if ((XferOptions == SMBUS_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_LAST_FRAME_WITH_PEC))
-      {
-        if (hsmbus->PreviousState == SMBUS_STATE_NONE)
-        {
-          /* Enable Acknowledge */
-          SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-        }
-
-        if (hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX)
-        {
-          /* Enable Acknowledge */
-          SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-          /* Generate Start */
-          SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
-        }
-      }
-    }
-
-
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hsmbus);
-
-    /* Note : The SMBUS interrupts must be enabled after unlocking current process
-    to avoid the risk of SMBUS interrupt handle execution before current
-    process unlock */
-
-    /* Enable EVT, BUF and ERR interrupt */
-    __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-/**
-  * @brief  Abort a master/host SMBUS process communication with Interrupt.
-  * @note   This abort can be called only if state is ready
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @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_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(DevAddress);
-  if (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_HOST)
-  {
-    /* Process Locked */
-    __HAL_LOCK(hsmbus);
-
-    hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-
-    hsmbus->PreviousState = SMBUS_STATE_NONE;
-    hsmbus->State = HAL_SMBUS_STATE_ABORT;
-
-
-    /* Disable Acknowledge */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-    /* Generate Stop */
-    SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-
-    hsmbus->XferCount = 0U;
-
-    /* Disable EVT, BUF and ERR interrupt */
-    __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hsmbus);
-
-    /* Call the corresponding callback to inform upper layer of End of Transfer */
-    SMBUS_ITError(hsmbus);
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-
-/**
-  * @brief  Transmit in slave/device SMBUS mode an amount of data in non blocking mode with Interrupt.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @param  pData Pointer to data buffer
-  * @param  Size Amount of data to be sent
-  * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
-{
-  /* Check the parameters */
-  assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
-  if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
-  {
-    if ((pData == NULL) || (Size == 0U))
-    {
-      return  HAL_ERROR;
-    }
-
-    /* Process Locked */
-    __HAL_LOCK(hsmbus);
-
-    /* Check if the SMBUS is already enabled */
-    if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
-    {
-      /* Enable SMBUS peripheral */
-      __HAL_SMBUS_ENABLE(hsmbus);
-    }
-
-    /* Disable Pos */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
-
-    hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX_LISTEN;
-    hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-    hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
-
-    /* Prepare transfer parameters */
-    hsmbus->pBuffPtr    = pData;
-    hsmbus->XferCount   = Size;
-    hsmbus->XferOptions = XferOptions;
-    hsmbus->XferSize    = hsmbus->XferCount;
-
-    /* Clear ADDR flag after prepare the transfer parameters */
-    /* This action will generate an acknowledge to the HOST */
-    __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hsmbus);
-
-    /* Note : The SMBUS interrupts must be enabled after unlocking current process
-              to avoid the risk of SMBUS interrupt handle execution before current
-              process unlock */
-
-    /* Enable EVT, BUF and ERR interrupt */
-    __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-/**
-  * @brief  Enable the Address listen mode with Interrupt.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @param  pData Pointer to data buffer
-  * @param  Size Amount of data to be sent
-  * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
-{
-  /* Check the parameters */
-  assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
-
-  if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
-  {
-    if ((pData == NULL) || (Size == 0U))
-    {
-      return  HAL_ERROR;
-    }
-
-    /* Process Locked */
-    __HAL_LOCK(hsmbus);
-
-    /* Check if the SMBUS is already enabled */
-    if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
-    {
-      /* Enable SMBUS peripheral */
-      __HAL_SMBUS_ENABLE(hsmbus);
-    }
-
-    /* Disable Pos */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
-
-    hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX_LISTEN;
-    hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-    hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
-
-
-
-    /* Prepare transfer parameters */
-    hsmbus->pBuffPtr = pData;
-    hsmbus->XferCount = Size;
-    hsmbus->XferOptions = XferOptions;
-    hsmbus->XferSize    = hsmbus->XferCount;
-
-    __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hsmbus);
-
-    /* Note : The SMBUS interrupts must be enabled after unlocking current process
-              to avoid the risk of SMBUS interrupt handle execution before current
-              process unlock */
-
-    /* Enable EVT, BUF and ERR interrupt */
-    __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-
-/**
-  * @brief  Enable the Address listen mode with Interrupt.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
-{
-  if (hsmbus->State == HAL_SMBUS_STATE_READY)
-  {
-    hsmbus->State = HAL_SMBUS_STATE_LISTEN;
-
-    /* Check if the SMBUS is already enabled */
-    if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
-    {
-      /* Enable SMBUS peripheral */
-      __HAL_SMBUS_ENABLE(hsmbus);
-    }
-
-    /* Enable Address Acknowledge */
-    SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-    /* Enable EVT and ERR interrupt */
-    __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-/**
-  * @brief  Disable the Address listen mode with Interrupt.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* 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 (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
-  {
-    tmp = (uint32_t)(hsmbus->State) & SMBUS_STATE_MSK;
-    hsmbus->PreviousState = tmp | (uint32_t)(hsmbus->Mode);
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-    hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-
-    /* Disable Address Acknowledge */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-    /* Disable EVT and ERR interrupt */
-    __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
-
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-/**
-  * @brief  Enable the SMBUS alert mode with Interrupt.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUSx peripheral.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Enable SMBus alert */
-  SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
-
-  /* Clear ALERT flag */
-  __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
-
-  /* Enable Alert Interrupt */
-  __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_ERR);
-
-  return HAL_OK;
-}
-/**
-  * @brief  Disable the SMBUS alert mode with Interrupt.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUSx peripheral.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Disable SMBus alert */
-  CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
-
-  /* Disable Alert Interrupt */
-  __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ERR);
-
-  return HAL_OK;
-}
-
-
-/**
-  * @brief  Check if target device is ready for communication.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for the specified SMBUS.
-  * @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_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
-{
-  uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, SMBUS_Trials = 1U;
-
-  /* Get tick */
-  tickstart = HAL_GetTick();
-
-  if (hsmbus->State == HAL_SMBUS_STATE_READY)
-  {
-    /* Wait until BUSY flag is reset */
-    if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
-    {
-      return HAL_BUSY;
-    }
-
-    /* Process Locked */
-    __HAL_LOCK(hsmbus);
-
-    /* Check if the SMBUS is already enabled */
-    if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
-    {
-      /* Enable SMBUS peripheral */
-      __HAL_SMBUS_ENABLE(hsmbus);
-    }
-
-    /* Disable Pos */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
-
-    hsmbus->State = HAL_SMBUS_STATE_BUSY;
-    hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-    hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
-
-    do
-    {
-      /* Generate Start */
-      SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
-
-      /* Wait until SB flag is set */
-      if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)
-      {
-        return HAL_TIMEOUT;
-      }
-
-      /* Send slave address */
-      hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(DevAddress);
-
-      /* Wait until ADDR or AF flag are set */
-      /* Get tick */
-      tickstart = HAL_GetTick();
-
-      tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
-      tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
-      tmp3 = hsmbus->State;
-      while ((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_SMBUS_STATE_TIMEOUT))
-      {
-        if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
-        {
-          hsmbus->State = HAL_SMBUS_STATE_TIMEOUT;
-        }
-        tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
-        tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
-        tmp3 = hsmbus->State;
-      }
-
-      hsmbus->State = HAL_SMBUS_STATE_READY;
-
-      /* Check if the ADDR flag has been set */
-      if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) == SET)
-      {
-        /* Generate Stop */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-
-        /* Clear ADDR Flag */
-        __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-
-        /* Wait until BUSY flag is reset */
-        if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
-        {
-          return HAL_TIMEOUT;
-        }
-
-        hsmbus->State = HAL_SMBUS_STATE_READY;
-
-        /* Process Unlocked */
-        __HAL_UNLOCK(hsmbus);
-
-        return HAL_OK;
-      }
-      else
-      {
-        /* Generate Stop */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-
-        /* Clear AF Flag */
-        __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
-
-        /* Wait until BUSY flag is reset */
-        if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-    while (SMBUS_Trials++ < Trials);
-
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hsmbus);
-
-    return HAL_ERROR;
-  }
-  else
-  {
-    return HAL_BUSY;
-  }
-}
-
-/**
-  * @brief  This function handles SMBUS event interrupt request.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
-{
-  uint32_t sr2itflags   = READ_REG(hsmbus->Instance->SR2);
-  uint32_t sr1itflags   = READ_REG(hsmbus->Instance->SR1);
-  uint32_t itsources    = READ_REG(hsmbus->Instance->CR2);
-
-  uint32_t CurrentMode  = hsmbus->Mode;
-
-  /* Master mode selected */
-  if (CurrentMode == HAL_SMBUS_MODE_MASTER)
-  {
-    /* SB Set ----------------------------------------------------------------*/
-    if (((sr1itflags & SMBUS_FLAG_SB) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-    {
-      SMBUS_Master_SB(hsmbus);
-    }
-    /* ADD10 Set -------------------------------------------------------------*/
-    else if (((sr1itflags & SMBUS_FLAG_ADD10) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-    {
-      SMBUS_Master_ADD10(hsmbus);
-    }
-    /* ADDR Set --------------------------------------------------------------*/
-    else if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-    {
-      SMBUS_Master_ADDR(hsmbus);
-    }
-    /* SMBUS in mode Transmitter -----------------------------------------------*/
-    if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
-    {
-      /* TXE set and BTF reset -----------------------------------------------*/
-      if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
-      {
-        SMBUS_MasterTransmit_TXE(hsmbus);
-      }
-      /* BTF set -------------------------------------------------------------*/
-      else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-      {
-        SMBUS_MasterTransmit_BTF(hsmbus);
-      }
-    }
-    /* SMBUS in mode Receiver --------------------------------------------------*/
-    else
-    {
-      /* RXNE set and BTF reset -----------------------------------------------*/
-      if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
-      {
-        SMBUS_MasterReceive_RXNE(hsmbus);
-      }
-      /* BTF set -------------------------------------------------------------*/
-      else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-      {
-        SMBUS_MasterReceive_BTF(hsmbus);
-      }
-    }
-  }
-  /* Slave mode selected */
-  else
-  {
-    /* ADDR set --------------------------------------------------------------*/
-    if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-    {
-      SMBUS_Slave_ADDR(hsmbus);
-    }
-    /* STOPF set --------------------------------------------------------------*/
-    else if (((sr1itflags & SMBUS_FLAG_STOPF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-    {
-      SMBUS_Slave_STOPF(hsmbus);
-    }
-    /* SMBUS in mode Transmitter -----------------------------------------------*/
-    else if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
-    {
-      /* TXE set and BTF reset -----------------------------------------------*/
-      if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
-      {
-        SMBUS_SlaveTransmit_TXE(hsmbus);
-      }
-      /* BTF set -------------------------------------------------------------*/
-      else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-      {
-        SMBUS_SlaveTransmit_BTF(hsmbus);
-      }
-    }
-    /* SMBUS in mode Receiver --------------------------------------------------*/
-    else
-    {
-      /* RXNE set and BTF reset ----------------------------------------------*/
-      if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
-      {
-        SMBUS_SlaveReceive_RXNE(hsmbus);
-      }
-      /* BTF set -------------------------------------------------------------*/
-      else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
-      {
-        SMBUS_SlaveReceive_BTF(hsmbus);
-      }
-    }
-  }
-}
-
-/**
-  * @brief  This function handles SMBUS error interrupt request.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
-{
-  uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U;
-  uint32_t sr1itflags = READ_REG(hsmbus->Instance->SR1);
-  uint32_t itsources  = READ_REG(hsmbus->Instance->CR2);
-
-  /* SMBUS Bus error interrupt occurred ------------------------------------*/
-  if (((sr1itflags & SMBUS_FLAG_BERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
-  {
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
-
-    /* Clear BERR flag */
-    __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
-
-  }
-
-  /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
-  if (((sr1itflags & SMBUS_FLAG_OVR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
-  {
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
-
-    /* Clear OVR flag */
-    __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
-  }
-
-  /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
-  if (((sr1itflags & SMBUS_FLAG_ARLO) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
-  {
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
-
-    /* Clear ARLO flag */
-    __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
-  }
-
-  /* SMBUS Acknowledge failure error interrupt occurred ------------------------------------*/
-  if (((sr1itflags & SMBUS_FLAG_AF) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
-  {
-    tmp1 = hsmbus->Mode;
-    tmp2 = hsmbus->XferCount;
-    tmp3 = hsmbus->State;
-    tmp4 = hsmbus->PreviousState;
-
-    if ((tmp1 == HAL_SMBUS_MODE_SLAVE) && (tmp2 == 0U) && \
-        ((tmp3 == HAL_SMBUS_STATE_BUSY_TX) || (tmp3 == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || \
-         ((tmp3 == HAL_SMBUS_STATE_LISTEN) && (tmp4 == SMBUS_STATE_SLAVE_BUSY_TX))))
-    {
-      SMBUS_Slave_AF(hsmbus);
-    }
-    else
-    {
-      hsmbus->ErrorCode |= HAL_SMBUS_ERROR_AF;
-
-      /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */
-      if (hsmbus->Mode == HAL_SMBUS_MODE_MASTER)
-      {
-        /* Generate Stop */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-
-      }
-
-      /* Clear AF flag */
-      __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
-    }
-  }
-
-  /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
-  if (((sr1itflags & SMBUS_FLAG_TIMEOUT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
-  {
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_TIMEOUT;
-
-    /* Clear TIMEOUT flag */
-    __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
-
-  }
-
-  /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
-  if (((sr1itflags & SMBUS_FLAG_SMBALERT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
-  {
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
-
-    /* Clear ALERT flag */
-    __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
-  }
-
-  /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
-  if (((sr1itflags & SMBUS_FLAG_PECERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
-  {
-    hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
-
-    /* Clear PEC error flag */
-    __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
-  }
-
-  /* Call the Error Callback in case of Error detected -----------------------*/
-  if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
-  {
-    SMBUS_ITError(hsmbus);
-  }
-}
-
-/**
-  * @brief  Master Tx Transfer completed callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-__weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SMBUS_MasterTxCpltCallback can be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Master Rx Transfer completed callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-__weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SMBUS_MasterRxCpltCallback can be implemented in the user file
-   */
-}
-
-/** @brief  Slave Tx Transfer completed callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-__weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SMBUS_SlaveTxCpltCallback can be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Slave Rx Transfer completed callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-__weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SMBUS_SlaveRxCpltCallback can be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Slave Address Match callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref SMBUS_XferOptions_definition
-  * @param  AddrMatchCode Address Match Code
-  * @retval None
-  */
-__weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-  UNUSED(TransferDirection);
-  UNUSED(AddrMatchCode);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SMBUS_AddrCallback can be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Listen Complete callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-__weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-          the HAL_SMBUS_ListenCpltCallback can be implemented in the user file
-  */
-}
-
-/**
-  * @brief  SMBUS error callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-__weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SMBUS_ErrorCallback can be implemented in the user file
-   */
-}
-
-/**
-  * @brief  SMBUS abort callback.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval None
-  */
-__weak void HAL_SMBUS_AbortCpltCallback(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hsmbus);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SMBUS_AbortCpltCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup   SMBUS_Exported_Functions_Group3 Peripheral State, Mode and Error functions
-  *  @brief   Peripheral State and Errors functions
-  *
-@verbatim
- ===============================================================================
-            ##### Peripheral State, Mode and Error functions #####
- ===============================================================================
-    [..]
-    This subsection permits to get in run-time the status of the peripheral
-    and the data flow.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Return the SMBUS handle state.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for the specified SMBUS.
-  * @retval HAL state
-  */
-HAL_SMBUS_StateTypeDef HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Return SMBUS handle state */
-  return hsmbus->State;
-}
-
-/**
-  * @brief  Return the SMBUS Master, Slave or no mode.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *                the configuration information for SMBUS module
-  * @retval HAL mode
-  */
-HAL_SMBUS_ModeTypeDef HAL_SMBUS_GetMode(SMBUS_HandleTypeDef *hsmbus)
-{
-  return hsmbus->Mode;
-}
-
-/**
-  * @brief  Return the SMBUS error code
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *              the configuration information for the specified SMBUS.
-  * @retval SMBUS Error Code
-  */
-uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
-{
-  return hsmbus->ErrorCode;
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/** @addtogroup SMBUS_Private_Functions
-  * @{
-  */
-
-/**
-  * @brief  Handle TXE flag for Master
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
-  uint32_t CurrentState       = hsmbus->State;
-  uint32_t CurrentXferOptions = hsmbus->XferOptions;
-
-  if ((hsmbus->XferSize == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_TX))
-  {
-    /* Call TxCpltCallback() directly if no stop mode is set */
-    if (((CurrentXferOptions == SMBUS_FIRST_FRAME) || (CurrentXferOptions == SMBUS_NEXT_FRAME)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
-    {
-      __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-      hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
-      hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-      hsmbus->State = HAL_SMBUS_STATE_READY;
-
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-      hsmbus->MasterTxCpltCallback(hsmbus);
-#else
-      HAL_SMBUS_MasterTxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-    }
-    else /* Generate Stop condition then Call TxCpltCallback() */
-    {
-      /* Disable EVT, BUF and ERR interrupt */
-      __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-      /* Generate Stop */
-      SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-
-      hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
-      hsmbus->State = HAL_SMBUS_STATE_READY;
-
-      hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-      hsmbus->MasterTxCpltCallback(hsmbus);
-#else
-      HAL_SMBUS_MasterTxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-    }
-  }
-  else if (CurrentState == HAL_SMBUS_STATE_BUSY_TX)
-  {
-
-    if ((hsmbus->XferCount == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
-    {
-      hsmbus->XferCount--;
-    }
-
-    if (hsmbus->XferCount == 0U)
-    {
-
-      /* Disable BUF interrupt */
-      __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
-
-      if ((SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
-      {
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
-      }
-
-    }
-    else
-    {
-      /* Write data to DR */
-      hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
-      hsmbus->XferCount--;
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle BTF flag for Master transmitter
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
-  uint32_t CurrentXferOptions = hsmbus->XferOptions;
-
-  if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
-  {
-    if (hsmbus->XferCount != 0U)
-    {
-      /* Write data to DR */
-      hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
-      hsmbus->XferCount--;
-    }
-    else
-    {
-      /* Call TxCpltCallback() directly if no stop mode is set */
-      if (((CurrentXferOptions == SMBUS_FIRST_FRAME) || (CurrentXferOptions == SMBUS_NEXT_FRAME)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
-      {
-        __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-        hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
-        hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-        hsmbus->State = HAL_SMBUS_STATE_READY;
-
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-        hsmbus->MasterTxCpltCallback(hsmbus);
-#else
-        HAL_SMBUS_MasterTxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-      }
-      else /* Generate Stop condition then Call TxCpltCallback() */
-      {
-        /* Disable EVT, BUF and ERR interrupt */
-        __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-        /* Generate Stop */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-
-        hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
-        hsmbus->State = HAL_SMBUS_STATE_READY;
-        hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-        hsmbus->MasterTxCpltCallback(hsmbus);
-#else
-        HAL_SMBUS_MasterTxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-      }
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle RXNE flag for Master
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
-  uint32_t CurrentXferOptions = hsmbus->XferOptions;
-
-  if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
-  {
-    uint32_t tmp = hsmbus->XferCount;
-
-    if (tmp > 3U)
-    {
-      /* Read data from DR */
-      (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-      hsmbus->XferCount--;
-
-      if (hsmbus->XferCount == 3)
-      {
-        /* Disable BUF interrupt, this help to treat correctly the last 4 bytes
-        on BTF subroutine */
-        /* Disable BUF interrupt */
-        __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
-      }
-    }
-
-    else if (tmp == 2U)
-    {
-
-      /* Read data from DR */
-      (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-      hsmbus->XferCount--;
-
-      if ((CurrentXferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (CurrentXferOptions == SMBUS_LAST_FRAME_WITH_PEC))
-      {
-        /* PEC of slave */
-        hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
-
-      }
-      /* Generate Stop */
-      SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-    }
-
-    else if ((tmp == 1U) || (tmp == 0U))
-    {
-      /* Disable Acknowledge */
-      CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-      /* Disable EVT, BUF and ERR interrupt */
-      __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-      /* Read data from DR */
-      (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-      hsmbus->XferCount--;
-
-      hsmbus->State = HAL_SMBUS_STATE_READY;
-      hsmbus->PreviousState = SMBUS_STATE_NONE;
-      hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-      hsmbus->MasterRxCpltCallback(hsmbus);
-#else
-      HAL_SMBUS_MasterRxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-    }
-  }
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle BTF flag for Master receiver
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
-  uint32_t CurrentXferOptions = hsmbus->XferOptions;
-
-  if (hsmbus->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_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
-
-    /* Read data from DR */
-    (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    hsmbus->XferCount--;
-    hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
-  }
-  else if (hsmbus->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_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
-
-    /* Disable Acknowledge */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-    /* Read data from DR */
-    (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    hsmbus->XferCount--;
-    hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
-  }
-  else if (hsmbus->XferCount == 2U)
-  {
-    /* Prepare next transfer or stop current transfer */
-    if ((CurrentXferOptions == SMBUS_NEXT_FRAME) || (CurrentXferOptions == SMBUS_FIRST_FRAME))
-    {
-      /* Disable Acknowledge */
-      CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-      /* Generate ReStart */
-      SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
-    }
-    else
-    {
-      /* Generate Stop */
-      SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-    }
-
-    /* Read data from DR */
-    (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    hsmbus->XferCount--;
-
-    /* Read data from DR */
-    (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    hsmbus->XferCount--;
-
-    /* Disable EVT and ERR interrupt */
-    __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
-
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-    hsmbus->PreviousState = SMBUS_STATE_NONE;
-    hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-    hsmbus->MasterRxCpltCallback(hsmbus);
-#else
-    HAL_SMBUS_MasterRxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-  }
-  else
-  {
-    /* Read data from DR */
-    (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    hsmbus->XferCount--;
-  }
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle SB flag for Master
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_Master_SB(SMBUS_HandleTypeDef *hsmbus)
-{
-  if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
-  {
-    /* Send slave 7 Bits address */
-    if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
-    {
-      hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(hsmbus->Devaddress);
-    }
-    else
-    {
-      hsmbus->Instance->DR = SMBUS_7BIT_ADD_READ(hsmbus->Devaddress);
-    }
-  }
-  else
-  {
-    if (hsmbus->EventCount == 0U)
-    {
-      /* Send header of slave address */
-      hsmbus->Instance->DR = SMBUS_10BIT_HEADER_WRITE(hsmbus->Devaddress);
-    }
-    else if (hsmbus->EventCount == 1U)
-    {
-      /* Send header of slave address */
-      hsmbus->Instance->DR = SMBUS_10BIT_HEADER_READ(hsmbus->Devaddress);
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle ADD10 flag for Master
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_Master_ADD10(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Send slave address */
-  hsmbus->Instance->DR = SMBUS_10BIT_ADDRESS(hsmbus->Devaddress);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle ADDR flag for Master
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_Master_ADDR(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
-  uint32_t Prev_State         = hsmbus->PreviousState;
-
-  if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
-  {
-    if ((hsmbus->EventCount == 0U) && (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT))
-    {
-      /* Clear ADDR flag */
-      __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-
-      /* Generate Restart */
-      SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
-
-      hsmbus->EventCount++;
-    }
-    else
-    {
-      /*  In the case of the Quick Command, the ADDR flag is cleared and a stop is generated */
-      if (hsmbus->XferCount == 0U)
-      {
-        /* Clear ADDR flag */
-        __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-
-        /* Generate Stop */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-      }
-      else if (hsmbus->XferCount == 1U)
-      {
-        /* Prepare next transfer or stop current transfer */
-        if ((hsmbus->XferOptions == SMBUS_FIRST_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
-        {
-          /* Disable Acknowledge */
-          CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-          /* Clear ADDR flag */
-          __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-        }
-        else if ((hsmbus->XferOptions == SMBUS_NEXT_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
-        {
-          /* Enable Acknowledge */
-          SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-          /* Clear ADDR flag */
-          __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-        }
-        else
-        {
-          /* Disable Acknowledge */
-          CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-          /* Clear ADDR flag */
-          __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-
-          /* Generate Stop */
-          SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
-        }
-      }
-      else if (hsmbus->XferCount == 2U)
-      {
-        if (hsmbus->XferOptions != SMBUS_NEXT_FRAME)
-        {
-          /* Disable Acknowledge */
-          CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-          /* Enable Pos */
-          SET_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
-
-
-        }
-        else
-        {
-          /* Enable Acknowledge */
-          SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-        }
-
-        /* Clear ADDR flag */
-        __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-      }
-      else
-      {
-        /* Enable Acknowledge */
-        SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-        /* Clear ADDR flag */
-        __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-      }
-
-      /* Reset Event counter  */
-      hsmbus->EventCount = 0U;
-    }
-  }
-  else
-  {
-    /* Clear ADDR flag */
-    __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
-  }
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle TXE flag for Slave
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
-  uint32_t CurrentState = hsmbus->State;
-
-  if (hsmbus->XferCount != 0U)
-  {
-    /* Write data to DR */
-    hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
-    hsmbus->XferCount--;
-
-    if ((hsmbus->XferCount == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
-    {
-      hsmbus->XferCount--;
-    }
-
-    if ((hsmbus->XferCount == 0U) && (CurrentState == (HAL_SMBUS_STATE_BUSY_TX_LISTEN)))
-    {
-      /* Last Byte is received, disable Interrupt */
-      __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
-
-      /* Set state at HAL_SMBUS_STATE_LISTEN */
-      hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_TX;
-      hsmbus->State = HAL_SMBUS_STATE_LISTEN;
-
-      /* Call the corresponding callback to inform upper layer of End of Transfer */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-      hsmbus->SlaveTxCpltCallback(hsmbus);
-#else
-      HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle BTF flag for Slave transmitter
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
-{
-  if (hsmbus->XferCount != 0U)
-  {
-    /* Write data to DR */
-    hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
-    hsmbus->XferCount--;
-  }
-
-
-
-  else if ((hsmbus->XferCount == 0U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
-  {
-    SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
-  }
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle RXNE flag for Slave
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
-  uint32_t CurrentState = hsmbus->State;
-
-  if (hsmbus->XferCount != 0U)
-  {
-    /* Read data from DR */
-    (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    hsmbus->XferCount--;
-
-    if ((hsmbus->XferCount == 1U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
-    {
-      SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
-      hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
-    }
-    if ((hsmbus->XferCount == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
-    {
-      /* Last Byte is received, disable Interrupt */
-      __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
-
-      /* Set state at HAL_SMBUS_STATE_LISTEN */
-      hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_RX;
-      hsmbus->State = HAL_SMBUS_STATE_LISTEN;
-
-      /* Call the corresponding callback to inform upper layer of End of Transfer */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-      hsmbus->SlaveRxCpltCallback(hsmbus);
-#else
-      HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle BTF flag for Slave receiver
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
-{
-  if (hsmbus->XferCount != 0U)
-  {
-    /* Read data from DR */
-    (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    hsmbus->XferCount--;
-  }
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle ADD flag for Slave
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_Slave_ADDR(SMBUS_HandleTypeDef *hsmbus)
-{
-  uint8_t TransferDirection = SMBUS_DIRECTION_RECEIVE ;
-  uint16_t SlaveAddrCode = 0U;
-
-  /* Transfer Direction requested by Master */
-  if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TRA) == RESET)
-  {
-    TransferDirection = SMBUS_DIRECTION_TRANSMIT;
-  }
-
-  if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_DUALF) == RESET)
-  {
-    SlaveAddrCode = hsmbus->Init.OwnAddress1;
-  }
-  else
-  {
-    SlaveAddrCode = hsmbus->Init.OwnAddress2;
-  }
-
-  /* Call Slave Addr callback */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-  hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
-#else
-  HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle STOPF flag for Slave
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_Slave_STOPF(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
-  uint32_t CurrentState = hsmbus->State;
-
-  /* Disable EVT, BUF and ERR interrupt */
-  __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-  /* Clear STOPF flag */
-  __HAL_SMBUS_CLEAR_STOPFLAG(hsmbus);
-
-  /* Disable Acknowledge */
-  CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-  /* All data are not transferred, so set error code accordingly */
-  if (hsmbus->XferCount != 0U)
-  {
-    /* Store Last receive data if any */
-    if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BTF) == SET)
-    {
-      /* Read data from DR */
-      (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-
-      if (hsmbus->XferCount > 0)
-      {
-        hsmbus->XferSize--;
-        hsmbus->XferCount--;
-      }
-    }
-
-    /* Store Last receive data if any */
-    if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
-    {
-      /* Read data from DR */
-      (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-
-      if (hsmbus->XferCount > 0)
-      {
-        hsmbus->XferSize--;
-        hsmbus->XferCount--;
-      }
-    }
-  }
-
-  if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
-  {
-    /* Call the corresponding callback to inform upper layer of End of Transfer */
-    SMBUS_ITError(hsmbus);
-  }
-  else
-  {
-    if ((CurrentState == HAL_SMBUS_STATE_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN)  || \
-        (CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN))
-    {
-      hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
-      hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
-      hsmbus->State = HAL_SMBUS_STATE_READY;
-      hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-      hsmbus->ListenCpltCallback(hsmbus);
-#else
-      HAL_SMBUS_ListenCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef SMBUS_Slave_AF(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
-  uint32_t CurrentState       = hsmbus->State;
-  uint32_t CurrentXferOptions = hsmbus->XferOptions;
-
-  if (((CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \
-       (CurrentXferOptions == SMBUS_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_LAST_FRAME_WITH_PEC)) && \
-      (CurrentState == HAL_SMBUS_STATE_LISTEN))
-  {
-    hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
-
-    /* Disable EVT, BUF and ERR interrupt */
-    __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
-
-    /* Clear AF flag */
-    __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
-
-    /* Disable Acknowledge */
-    CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
-
-    hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-    hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-
-    /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-    hsmbus->ListenCpltCallback(hsmbus);
-#else
-    HAL_SMBUS_ListenCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-  }
-  return HAL_OK;
-}
-
-
-
-/**
-  * @brief SMBUS interrupts error process
-  * @param  hsmbus SMBUS handle.
-  * @retval None
-  */
-static void SMBUS_ITError(SMBUS_HandleTypeDef *hsmbus)
-{
-  /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
-  uint32_t CurrentState = hsmbus->State;
-
-  if ((CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
-  {
-    /* keep HAL_SMBUS_STATE_LISTEN */
-    hsmbus->PreviousState = SMBUS_STATE_NONE;
-    hsmbus->State = HAL_SMBUS_STATE_LISTEN;
-  }
-  else
-  {
-    /* If state is an abort treatment on going, don't change state */
-    /* This change will be done later */
-    if (hsmbus->State != HAL_SMBUS_STATE_ABORT)
-    {
-      hsmbus->State = HAL_SMBUS_STATE_READY;
-    }
-    hsmbus->PreviousState = SMBUS_STATE_NONE;
-    hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-  }
-
-  /* Disable Pos bit in SMBUS CR1 when error occurred in Master/Mem Receive IT Process */
-  CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
-
-  if (hsmbus->State == HAL_SMBUS_STATE_ABORT)
-  {
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-    hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
-
-    /* Store Last receive data if any */
-    if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
-    {
-      /* Read data from DR */
-      (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    }
-
-    /* Disable SMBUS peripheral to prevent dummy data in buffer */
-    __HAL_SMBUS_DISABLE(hsmbus);
-
-    /* Call the corresponding callback to inform upper layer of End of Transfer */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-    hsmbus->AbortCpltCallback(hsmbus);
-#else
-    HAL_SMBUS_AbortCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-  }
-  else
-  {
-    /* Store Last receive data if any */
-    if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
-    {
-      /* Read data from DR */
-      (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
-    }
-
-    /* Call user error callback */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-    hsmbus->ErrorCallback(hsmbus);
-#else
-    HAL_SMBUS_ErrorCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-  }
-  /* STOP Flag is not set after a NACK reception */
-  /* So may inform upper layer that listen phase is stopped */
-  /* during NACK error treatment */
-  if ((hsmbus->State == HAL_SMBUS_STATE_LISTEN) && ((hsmbus->ErrorCode & HAL_SMBUS_ERROR_AF) == HAL_SMBUS_ERROR_AF))
-  {
-    hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
-    hsmbus->PreviousState = SMBUS_STATE_NONE;
-    hsmbus->State = HAL_SMBUS_STATE_READY;
-    hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-
-    /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
-#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
-    hsmbus->ListenCpltCallback(hsmbus);
-#else
-    HAL_SMBUS_ListenCpltCallback(hsmbus);
-#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
-  }
-}
-
-/**
-  * @brief  This function handles SMBUS Communication Timeout.
-  * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
-  *         the configuration information for SMBUS module
-  * @param  Flag specifies the SMBUS 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 SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
-{
-  /* Wait until flag is set */
-  if (Status == RESET)
-  {
-    while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
-    {
-      /* Check for the Timeout */
-      if (Timeout != HAL_MAX_DELAY)
-      {
-        if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
-        {
-          hsmbus->PreviousState = SMBUS_STATE_NONE;
-          hsmbus->State = HAL_SMBUS_STATE_READY;
-          hsmbus->Mode = HAL_SMBUS_MODE_NONE;
-
-          /* Process Unlocked */
-          __HAL_UNLOCK(hsmbus);
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-
-
-#endif /* HAL_SMBUS_MODULE_ENABLED */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 42 - 0
stm32workspace/dosimeter-fw/dosimeter-fw Debug.cfg

@@ -0,0 +1,42 @@
+# This is an genericBoard board with a single STM32F446RCTx chip
+#
+# Generated by STM32CubeIDE
+# Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s)
+
+source [find interface/stlink-dap.cfg]
+
+
+set WORKAREASIZE 0x8000
+
+transport select "dapdirect_swd"
+
+set CHIPNAME STM32F446RCTx
+set BOARDNAME genericBoard
+
+# Enable debug when in low power modes
+set ENABLE_LOW_POWER 1
+
+# Stop Watchdog counters when halt
+set STOP_WATCHDOG 1
+
+# STlink Debug clock frequency
+set CLOCK_FREQ 8000
+
+# Reset configuration
+# use hardware reset, connect under reset
+# connect_assert_srst needed if low power mode application running (WFI...)
+reset_config srst_only srst_nogate connect_assert_srst
+set CONNECT_UNDER_RESET 1
+set CORE_RESET 0
+
+# ACCESS PORT NUMBER
+set AP_NUM 0
+# GDB PORT
+set GDB_PORT 3333
+
+
+
+# BCTM CPU variables
+
+source [find target/stm32f4x.cfg]
+

+ 79 - 0
stm32workspace/dosimeter-fw/dosimeter-fw Debug.launch

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="com.st.stm32cube.ide.mcu.debug.launch.launchConfigurationType">
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.access_port_id" value="0"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.enable_live_expr" value="true"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.enable_swv" value="false"/>
+    <intAttribute key="com.st.stm32cube.ide.mcu.debug.launch.formatVersion" value="2"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.ip_address_local" value="localhost"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.enabled" value="false"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.limit_swo_clock.value" value=""/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.loadList" value="{&quot;fItems&quot;:[{&quot;fIsFromMainTab&quot;:true,&quot;fPath&quot;:&quot;Debug/dosimeter-fw.elf&quot;,&quot;fProjectName&quot;:&quot;dosimeter-fw&quot;,&quot;fPerformBuild&quot;:true,&quot;fDownload&quot;:true,&quot;fLoadSymbols&quot;:true}]}"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.override_start_address_mode" value="default"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.remoteCommand" value="target remote"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startServer" value="true"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startuptab.exception.divby0" value="true"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startuptab.exception.unaligned" value="false"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.startuptab.haltonexception" value="true"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.swd_mode" value="true"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.swv_port" value="61235"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.swv_trace_hclk" value="16000000"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.useRemoteTarget" value="true"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.launch.vector_table" value=""/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.launch.verify_flash_download" value="true"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.cti_allow_halt" value="false"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.cti_signal_halt" value="false"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.enable_external_loader" value="false"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.enable_logging" value="false"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.enable_max_halt_delay" value="false"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.enable_shared_stlink" value="false"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.external_loader" value=""/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.external_loader_init" value="false"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.frequency" value="0"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.halt_all_on_reset" value="false"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.log_file" value="/home/radioman/work/detector/dosimeter/stm32workspace/dosimeter-fw/Debug/st-link_gdbserver_log.txt"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.low_power_debug" value="none"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.max_halt_delay" value="2"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.reset_strategy" value="system_reset"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.stlink_check_serial_number" value="true"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.stlink_txt_serial_number" value="51FF6C064882575131211587"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlink.watchdog_config" value="none"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.debug.stlinkenable_rtos" value="false"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.debug.stlinkrestart_configurations" value="{&quot;fItems&quot;:[{&quot;fDisplayName&quot;:&quot;Reset&quot;,&quot;fIsSuppressible&quot;:false,&quot;fResetAttribute&quot;:&quot;Software system reset&quot;,&quot;fResetStrategies&quot;:[{&quot;fDisplayName&quot;:&quot;Software system reset&quot;,&quot;fLaunchAttribute&quot;:&quot;system_reset&quot;,&quot;fGdbCommands&quot;:[&quot;monitor reset\n&quot;],&quot;fCmdOptions&quot;:[&quot;-g&quot;]},{&quot;fDisplayName&quot;:&quot;Hardware reset&quot;,&quot;fLaunchAttribute&quot;:&quot;hardware_reset&quot;,&quot;fGdbCommands&quot;:[&quot;monitor reset hardware\n&quot;],&quot;fCmdOptions&quot;:[&quot;-g&quot;]},{&quot;fDisplayName&quot;:&quot;Core reset&quot;,&quot;fLaunchAttribute&quot;:&quot;core_reset&quot;,&quot;fGdbCommands&quot;:[&quot;monitor reset core\n&quot;],&quot;fCmdOptions&quot;:[&quot;-g&quot;]},{&quot;fDisplayName&quot;:&quot;None&quot;,&quot;fLaunchAttribute&quot;:&quot;no_reset&quot;,&quot;fGdbCommands&quot;:[],&quot;fCmdOptions&quot;:[&quot;-g&quot;]}],&quot;fGdbCommandGroup&quot;:{&quot;name&quot;:&quot;Additional commands&quot;,&quot;commands&quot;:[]}}]}"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.enableRtosProxy" value="false"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyCustomProperties" value=""/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyDriver" value="threadx"/>
+    <booleanAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyDriverAuto" value="false"/>
+    <stringAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyDriverPort" value="cortex_m0"/>
+    <intAttribute key="com.st.stm32cube.ide.mcu.rtosproxy.rtosProxyPort" value="60000"/>
+    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="false"/>
+    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="false"/>
+    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value=""/>
+    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
+    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDeviceId" value="com.st.stm32cube.ide.mcu.debug.stlink"/>
+    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
+    <intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="61234"/>
+    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
+    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
+    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
+    <booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
+    <stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
+    <stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
+    <booleanAttribute key="org.eclipse.cdt.dsf.gdb.NON_STOP" value="true"/>
+    <booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
+    <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
+    <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
+    <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
+    <booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
+    <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
+    <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/dosimeter-fw.elf"/>
+    <stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="dosimeter-fw"/>
+    <booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
+    <stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.7202629"/>
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+        <listEntry value="/dosimeter-fw"/>
+    </listAttribute>
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+        <listEntry value="4"/>
+    </listAttribute>
+    <stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
+</launchConfiguration>

+ 66 - 25
stm32workspace/dosimeter-fw/dosimeter-fw.ioc

@@ -1,26 +1,36 @@
 #MicroXplorer Configuration settings - do not modify
 ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_VREFINT
-ADC1.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4
-ADC1.IPParameters=Rank-0\#ChannelRegularConversion,master,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler
+ADC1.ContinuousConvMode=DISABLE
+ADC1.DMAContinuousRequests=DISABLE
+ADC1.EOCSelection=ADC_EOC_SINGLE_CONV
+ADC1.IPParameters=Rank-0\#ChannelRegularConversion,master,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,NbrOfConversion,ContinuousConvMode,DMAContinuousRequests,EOCSelection
+ADC1.NbrOfConversion=1
 ADC1.NbrOfConversionFlag=1
 ADC1.Rank-0\#ChannelRegularConversion=1
-ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES
+ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_480CYCLES
 ADC1.master=1
 ADC2.Channel-5\#ChannelRegularConversion=ADC_CHANNEL_14
 ADC2.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4
 ADC2.IPParameters=Rank-5\#ChannelRegularConversion,Channel-5\#ChannelRegularConversion,SamplingTime-5\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler
 ADC2.NbrOfConversionFlag=1
 ADC2.Rank-5\#ChannelRegularConversion=1
-ADC2.SamplingTime-5\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES
+ADC2.SamplingTime-5\#ChannelRegularConversion=ADC_SAMPLETIME_15CYCLES
+DAC.DAC_OutputBuffer=DAC_OUTPUTBUFFER_DISABLE
+DAC.DAC_OutputBuffer2=DAC_OUTPUTBUFFER_DISABLE
+DAC.IPParameters=DAC_OutputBuffer2,DAC_OutputBuffer
 File.Version=6
+GPIO.groupedBy=Group By Peripherals
+I2C1.ClockSpeed=50000
+I2C1.IPParameters=ClockSpeed
 KeepUserPlacement=false
 Mcu.Family=STM32F4
 Mcu.IP0=ADC1
 Mcu.IP1=ADC2
 Mcu.IP10=TIM2
-Mcu.IP11=USART1
-Mcu.IP12=USB_DEVICE
-Mcu.IP13=USB_OTG_FS
+Mcu.IP11=TIM3
+Mcu.IP12=USART1
+Mcu.IP13=USB_DEVICE
+Mcu.IP14=USB_OTG_FS
 Mcu.IP2=DAC
 Mcu.IP3=I2C1
 Mcu.IP4=NVIC
@@ -29,7 +39,7 @@ Mcu.IP6=RTC
 Mcu.IP7=SPI1
 Mcu.IP8=SPI2
 Mcu.IP9=SYS
-Mcu.IPNb=14
+Mcu.IPNb=15
 Mcu.Name=STM32F446R(C-E)Tx
 Mcu.Package=LQFP64
 Mcu.Pin0=PC13
@@ -72,11 +82,11 @@ Mcu.Pin41=PB7
 Mcu.Pin42=PB8
 Mcu.Pin43=PB9
 Mcu.Pin44=VP_ADC1_Vref_Input
-Mcu.Pin45=VP_ADC1_Vbat_Input
-Mcu.Pin46=VP_RTC_VS_RTC_Activate
-Mcu.Pin47=VP_RTC_VS_RTC_Calendar
-Mcu.Pin48=VP_SYS_VS_Systick
-Mcu.Pin49=VP_TIM2_VS_ControllerModeClock
+Mcu.Pin45=VP_RTC_VS_RTC_Activate
+Mcu.Pin46=VP_RTC_VS_RTC_Calendar
+Mcu.Pin47=VP_SYS_VS_Systick
+Mcu.Pin48=VP_TIM2_VS_ControllerModeClock
+Mcu.Pin49=VP_TIM3_VS_ClockSourceINT
 Mcu.Pin5=PC0
 Mcu.Pin50=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
 Mcu.Pin6=PC1
@@ -89,17 +99,21 @@ Mcu.UserConstants=
 Mcu.UserName=STM32F446RCTx
 MxCube.Version=6.3.0
 MxDb.Version=DB.6.0.30
+NVIC.ADC_IRQn=true\:0\:0\:false\:false\:true\:true\:true
 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
 NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+NVIC.EXTI1_IRQn=true\:0\:0\:false\:false\:true\:true\:true
+NVIC.EXTI9_5_IRQn=true\:0\:0\:false\:false\:true\:true\:true
 NVIC.ForceEnableDMAVector=true
 NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
 NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
-NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:false\:false\:false
 NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:false\:true
 NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
 NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false
 NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true
+NVIC.TIM3_IRQn=true\:0\:0\:false\:false\:true\:true\:true
 NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
 PA0-WKUP.Locked=true
 PA0-WKUP.Signal=S_TIM2_CH1_ETR
@@ -120,8 +134,11 @@ PA15.Locked=true
 PA15.Signal=GPIO_Output
 PA4.Signal=COMP_DAC1_group
 PA5.Signal=COMP_DAC2_group
+PA8.GPIOParameters=GPIO_PuPd,GPIO_ModeDefaultEXTI
+PA8.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
+PA8.GPIO_PuPd=GPIO_PULLUP
 PA8.Locked=true
-PA8.Signal=GPIO_Input
+PA8.Signal=GPXTI8
 PA9.Mode=Asynchronous
 PA9.Signal=USART1_TX
 PB1.Locked=true
@@ -154,10 +171,10 @@ PB6.Signal=GPIO_Output
 PB7.Locked=true
 PB7.Signal=GPIO_Output
 PB8.Locked=true
-PB8.Mode=SMBus-two-wire-Interface
+PB8.Mode=I2C
 PB8.Signal=I2C1_SCL
 PB9.Locked=true
-PB9.Mode=SMBus-two-wire-Interface
+PB9.Mode=I2C
 PB9.Signal=I2C1_SDA
 PC0.Locked=true
 PC0.Signal=GPIO_Output
@@ -181,14 +198,25 @@ PC3.Locked=true
 PC3.Signal=GPIO_Output
 PC4.Locked=true
 PC4.Signal=ADCx_IN14
+PC6.GPIOParameters=GPIO_PuPd,GPIO_ModeDefaultEXTI
+PC6.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
+PC6.GPIO_PuPd=GPIO_PULLUP
 PC6.Locked=true
-PC6.Signal=GPIO_Input
+PC6.Signal=GPXTI6
+PC7.GPIOParameters=GPIO_PuPd,GPIO_ModeDefaultEXTI
+PC7.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
+PC7.GPIO_PuPd=GPIO_PULLUP
 PC7.Locked=true
-PC7.Signal=GPIO_Input
+PC7.Signal=GPXTI7
+PC8.GPIOParameters=GPIO_PuPd
+PC8.GPIO_PuPd=GPIO_PULLUP
 PC8.Locked=true
 PC8.Signal=GPIO_Input
+PC9.GPIOParameters=GPIO_PuPd,GPIO_ModeDefaultEXTI
+PC9.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING
+PC9.GPIO_PuPd=GPIO_PULLUP
 PC9.Locked=true
-PC9.Signal=GPIO_Input
+PC9.Signal=GPXTI9
 PD2.Locked=true
 PD2.Signal=GPIO_Output
 PH0-OSC_IN.Mode=HSE-External-Oscillator
@@ -216,14 +244,14 @@ ProjectManager.MainLocation=Core/Src
 ProjectManager.NoMain=false
 ProjectManager.PreviousToolchain=
 ProjectManager.ProjectBuild=false
-ProjectManager.ProjectFileName=dosimeter-test.ioc
-ProjectManager.ProjectName=dosimeter-test
+ProjectManager.ProjectFileName=dosimeter-fw.ioc
+ProjectManager.ProjectName=dosimeter-fw
 ProjectManager.RegisterCallBack=
 ProjectManager.StackSize=0x400
 ProjectManager.TargetToolchain=STM32CubeIDE
 ProjectManager.ToolChainLocation=
 ProjectManager.UnderRoot=true
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_ADC2_Init-ADC2-false-HAL-true,5-MX_DAC_Init-DAC-false-HAL-true,6-MX_I2C1_SMBUS_Init-I2C1-false-HAL-true,7-MX_RTC_Init-RTC-false-HAL-true,8-MX_SPI1_Init-SPI1-false-HAL-true,9-MX_SPI2_Init-SPI2-false-HAL-true,10-MX_USART1_UART_Init-USART1-false-HAL-true,11-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_ADC2_Init-ADC2-false-HAL-true,5-MX_DAC_Init-DAC-false-HAL-true,6-MX_I2C1_Init-I2C1-false-HAL-true,7-MX_RTC_Init-RTC-false-HAL-true,8-MX_SPI1_Init-SPI1-false-HAL-true,9-MX_SPI2_Init-SPI2-false-HAL-true,10-MX_USART1_UART_Init-USART1-false-HAL-true,11-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,12-MX_TIM2_Init-TIM2-false-HAL-true,13-MX_TIM3_Init-TIM3-false-HAL-true
 RCC.AHBFreq_Value=160000000
 RCC.APB1CLKDivider=RCC_HCLK_DIV4
 RCC.APB1Freq_Value=40000000
@@ -281,6 +309,14 @@ SH.COMP_DAC2_group.0=DAC_OUT2,DAC_OUT2
 SH.COMP_DAC2_group.ConfNb=1
 SH.GPXTI1.0=GPIO_EXTI1
 SH.GPXTI1.ConfNb=1
+SH.GPXTI6.0=GPIO_EXTI6
+SH.GPXTI6.ConfNb=1
+SH.GPXTI7.0=GPIO_EXTI7
+SH.GPXTI7.ConfNb=1
+SH.GPXTI8.0=GPIO_EXTI8
+SH.GPXTI8.ConfNb=1
+SH.GPXTI9.0=GPIO_EXTI9
+SH.GPXTI9.ConfNb=1
 SH.S_TIM2_CH1_ETR.0=TIM2_ETR,TriggerSource_ETR
 SH.S_TIM2_CH1_ETR.ConfNb=1
 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2
@@ -295,6 +331,11 @@ SPI2.Direction=SPI_DIRECTION_2LINES
 SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
 SPI2.Mode=SPI_MODE_MASTER
 SPI2.VirtualType=VM_MASTER
+TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
+TIM3.CounterMode=TIM_COUNTERMODE_DOWN
+TIM3.IPParameters=Prescaler,Period,AutoReloadPreload,CounterMode
+TIM3.Period=8000
+TIM3.Prescaler=1000
 USART1.IPParameters=VirtualMode
 USART1.VirtualMode=VM_ASYNC
 USB_DEVICE.CLASS_NAME_FS=CDC
@@ -303,8 +344,6 @@ USB_DEVICE.VirtualMode-CDC_FS=Cdc
 USB_DEVICE.VirtualModeFS=Cdc_FS
 USB_OTG_FS.IPParameters=VirtualMode
 USB_OTG_FS.VirtualMode=Device_Only
-VP_ADC1_Vbat_Input.Mode=IN-Vbat
-VP_ADC1_Vbat_Input.Signal=ADC1_Vbat_Input
 VP_ADC1_Vref_Input.Mode=IN-Vrefint
 VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input
 VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
@@ -315,6 +354,8 @@ VP_SYS_VS_Systick.Mode=SysTick
 VP_SYS_VS_Systick.Signal=SYS_VS_Systick
 VP_TIM2_VS_ControllerModeClock.Mode=Clock Mode
 VP_TIM2_VS_ControllerModeClock.Signal=TIM2_VS_ControllerModeClock
+VP_TIM3_VS_ClockSourceINT.Mode=Internal
+VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
 VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS
 VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS
 board=custom

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません