diff --git a/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch b/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch deleted file mode 100644 index aae18bf4..00000000 --- a/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch +++ /dev/null @@ -1,6860 +0,0 @@ -From b45bdbbbfe3d084d069da99b98116991923f5eb6 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Thu, 26 Apr 2018 13:20:38 -0700 -Subject: [PATCH] Add I2C files and settings - ---- - .../Inc/stm32f4xx_hal_i2c.h | 649 ++ - .../Inc/stm32f4xx_hal_i2c_ex.h | 137 + - .../Src/stm32f4xx_hal_i2c.c | 5494 +++++++++++++++++ - .../Src/stm32f4xx_hal_i2c_ex.c | 204 + - Firmware/Board/v3/Inc/i2c.h | 91 + - Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h | 2 +- - Firmware/Board/v3/Odrive.ioc | 5 + - Firmware/Board/v3/Src/i2c.c | 198 + - Firmware/Board/v3/Src/main.c | 1 - - 11 files changed, 6811 insertions(+), 2 deletions(-) - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c - create mode 100644 Firmware/Board/v3/Inc/i2c.h - create mode 100644 Firmware/Board/v3/Src/i2c.c - -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h -new file mode 100644 -index 0000000..5452a50 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h -@@ -0,0 +1,649 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c.h -+ * @author MCD Application Team -+ * @brief Header file of I2C HAL module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* 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 -+ * @{ -+ */ -+ -+/** -+ * @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; -+ -+/** -+ * @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 IP initilisation status -+ * 0 : Reset (IP not initialized) -+ * 1 : Init done (IP 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 (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_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; -+ -+/** -+ * @brief HAL Mode structure definition -+ * @note HAL I2C Mode value coding follow below described bitmap : -+ * b7 (not used) -+ * x : Should be set to 0 -+ * b6 -+ * 0 : None -+ * 1 : Memory (HAL I2C communication is in Memory Mode) -+ * b5 -+ * 0 : None -+ * 1 : Slave (HAL I2C communication is in Slave Mode) -+ * b4 -+ * 0 : None -+ * 1 : Master (HAL I2C communication is in Master Mode) -+ * b3-b2-b1-b0 (not used) -+ * 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; -+ -+/** -+ * @brief I2C handle Structure definition -+ */ -+typedef struct -+{ -+ 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 */ -+ -+}I2C_HandleTypeDef; -+ -+/** -+ * @} -+ */ -+ -+/* Exported constants --------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Constants I2C Exported Constants -+ * @{ -+ */ -+ -+/** @defgroup I2C_Error_Code I2C Error Code -+ * @brief I2C Error Code -+ * @{ -+ */ -+#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 */ -+/** -+ * @} -+ */ -+ -+/** @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_NEXT_FRAME 0x00000002U -+#define I2C_FIRST_AND_LAST_FRAME 0x00000004U -+#define I2C_LAST_FRAME 0x00000008U -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition -+ * @{ -+ */ -+#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_SMBALERT 0x00018000U -+#define I2C_FLAG_TIMEOUT 0x00014000U -+#define I2C_FLAG_PECERR 0x00011000U -+#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_SMBHOST 0x00100040U -+#define I2C_FLAG_SMBDEFAULT 0x00100020U -+#define I2C_FLAG_GENCALL 0x00100010U -+#define I2C_FLAG_TRA 0x00100004U -+#define I2C_FLAG_BUSY 0x00100002U -+#define I2C_FLAG_MSL 0x00100001U -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Exported macro ------------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Macros I2C Exported Macros -+ * @{ -+ */ -+ -+/** @brief Reset I2C handle state -+ * @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_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) -+ -+/** @brief Enable or disable the specified I2C interrupts. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @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__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) -+#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) -+ -+/** @brief Checks if the specified I2C interrupt source is enabled or disabled. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @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. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __FLAG__ specifies the flag to check. -+ * This parameter can be one of the following values: -+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag -+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag -+ * @arg I2C_FLAG_PECERR: PEC error in reception flag -+ * @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_SMBHOST: SMBus host header -+ * @arg I2C_FLAG_SMBDEFAULT: SMBus default header -+ * @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)): \ -+ ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) -+ -+/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __FLAG__ specifies the flag to clear. -+ * This parameter can be any combination of the following values: -+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag -+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag -+ * @arg I2C_FLAG_PECERR: PEC error in reception flag -+ * @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. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_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 I2C peripheral. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) -+ -+/** @brief Disable the I2C peripheral. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_DISABLE(__HANDLE__) ((__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/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); -+/** -+ * @} -+ */ -+ -+/** @addtogroup I2C_Exported_Functions_Group2 -+ * @{ -+ */ -+/* I/O 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_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); -+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); -+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); -+ -+/******* 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); -+ -+/******* 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 Errors 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 -+/** -+ * @} -+ */ -+ -+/* Private macros ------------------------------------------------------------*/ -+/** @defgroup I2C_Private_Macros I2C Private Macros -+ * @{ -+ */ -+ -+#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__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) -+#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__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__) & (~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_NEXT_FRAME) || \ -+ ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ -+ ((REQUEST) == I2C_LAST_FRAME)) -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Private functions ---------------------------------------------------------*/ -+/** @defgroup I2C_Private_Functions I2C Private Functions -+ * @{ -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+ -+#endif /* __STM32F4xx_HAL_I2C_H */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h -new file mode 100644 -index 0000000..ff47d5c ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h -@@ -0,0 +1,137 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c_ex.h -+ * @author MCD Application Team -+ * @brief Header file of I2C HAL Extension module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __STM32F4xx_HAL_I2C_EX_H -+#define __STM32F4xx_HAL_I2C_EX_H -+ -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ -+ defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ -+ defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -+/* 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 /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ -+ STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx ||\ -+ STM32F413xx || STM32F423xx */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* __STM32F4xx_HAL_I2C_EX_H */ -+ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c -new file mode 100644 -index 0000000..da18520 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c -@@ -0,0 +1,5494 @@ -+/** -+ ****************************************************************************** -+ * @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(&hi2c) 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 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 @ref I2C_XFEROPTIONS and are listed below: -+ (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal 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_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 -+ -+ (+) Differents sequential I2C interfaces are listed below: -+ (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT() -+ (+++) 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_Sequential_Receive_IT() -+ (+++) 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 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_Sequential_Transmit_IT() -+ (+++) 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_Sequential_Receive_IT() -+ (+++) 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() -+ (++) 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 IO MEM operation *** -+ ======================================= -+ [..] -+ (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using -+ HAL_I2C_Mem_Write_IT() -+ (+) At MEM 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 no-blocking mode with Interrupt from a specific memory address using -+ HAL_I2C_Mem_Read_IT() -+ (+) At MEM 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 no-blocking mode with DMA to a specific memory address using -+ HAL_I2C_Mem_Write_DMA() -+ (+) At MEM 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 no-blocking mode with DMA from a specific memory address using -+ HAL_I2C_Mem_Read_DMA() -+ (+) At MEM 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 -+ -+ [..] -+ (@) You can refer to the I2C HAL driver header file for more useful macros -+ -+ -+ @endverbatim -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* 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_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ -+ -+/* Private define for @ref PreviousState usage */ -+#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(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)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ -+ -+/** -+ * @} -+ */ -+ -+/* Private macro -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private function prototypes -----------------------------------------------*/ -+/** @addtogroup 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); -+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_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c); -+ -+/* Private functions for I2C transfer IRQ handler */ -+static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c); -+ -+static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_AF(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 -+ de-initialize 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 create the associated handle. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) -+{ -+ uint32_t freqrange = 0U; -+ uint32_t pclk1 = 0U; -+ -+ /* 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; -+ /* Init the low level hardware : GPIO, CLOCK, NVIC */ -+ HAL_I2C_MspInit(hi2c); -+ } -+ -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the selected I2C peripheral */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Get PCLK1 frequency */ -+ pclk1 = HAL_RCC_GetPCLK1Freq(); -+ -+ /* Calculate frequency range */ -+ freqrange = I2C_FREQRANGE(pclk1); -+ -+ /*---------------------------- I2Cx CR2 Configuration ----------------------*/ -+ /* Configure I2Cx: Frequency range */ -+ hi2c->Instance->CR2 = freqrange; -+ -+ /*---------------------------- I2Cx TRISE Configuration --------------------*/ -+ /* Configure I2Cx: Rise Time */ -+ hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); -+ -+ /*---------------------------- I2Cx CCR Configuration ----------------------*/ -+ /* Configure I2Cx: Speed */ -+ hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); -+ -+ /*---------------------------- I2Cx CR1 Configuration ----------------------*/ -+ /* Configure I2Cx: Generalcall and NoStretch mode */ -+ hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); -+ -+ /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ -+ /* Configure I2Cx: Own Address1 and addressing mode */ -+ hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); -+ -+ /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ -+ /* Configure I2Cx: Dual mode and Own Address2 */ -+ hi2c->Instance->OAR2 = (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 DeInitializes the I2C peripheral. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @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); -+ -+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ -+ HAL_I2C_MspDeInit(hi2c); -+ -+ 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 I2C MSP Init. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @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 I2C MSP DeInit -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @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 -+ */ -+} -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Exported_Functions_Group2 IO operation functions -+ * @brief Data transfers functions -+ * -+@verbatim -+ =============================================================================== -+ ##### IO operation functions ##### -+ =============================================================================== -+ [..] -+ This subsection provides a set of functions allowing to manage the 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_Master_Sequential_Transmit_IT() -+ (++) HAL_I2C_Master_Sequential_Receive_IT() -+ (++) HAL_I2C_Slave_Sequential_Transmit_IT() -+ (++) HAL_I2C_Slave_Sequential_Receive_IT() -+ (++) HAL_I2C_Mem_Write_IT() -+ (++) HAL_I2C_Mem_Read_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() -+ -+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: -+ (++) HAL_I2C_MemTxCpltCallback() -+ (++) HAL_I2C_MemRxCpltCallback() -+ (++) HAL_I2C_MasterTxCpltCallback() -+ (++) HAL_I2C_MasterRxCpltCallback() -+ (++) HAL_I2C_SlaveTxCpltCallback() -+ (++) HAL_I2C_SlaveRxCpltCallback() -+ (++) 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) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address */ -+ if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ 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++); -+ 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ -+ /* Generate Stop */ -+ 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) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address */ -+ if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(hi2c->XferSize == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ 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_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ 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_TIMEOUT; -+ } -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ else -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ 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) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ 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_TIMEOUT; -+ } -+ -+ /* 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_TIMEOUT; -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ 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++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ } -+ } -+ -+ /* Wait until AF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Disable Address Acknowledge */ -+ 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) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ 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_TIMEOUT; -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ -+ /* Wait until STOP flag is set */ -+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear STOP flag */ -+ __HAL_I2C_CLEAR_STOPFLAG(hi2c); -+ -+ /* Disable Address Acknowledge */ -+ 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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ /* Generate Start */ -+ 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 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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ 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 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_Sequential_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((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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ Prev_State = hi2c->PreviousState; -+ -+ /* Generate Start */ -+ if((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) -+ { -+ /* Generate Start condition if first transfer */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else -+ { -+ /* Generate ReStart */ -+ 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 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_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ __IO uint32_t count = 0U; -+ -+ /* 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((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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) -+ { -+ /* Generate Start condition if first transfer */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate ReStart */ -+ 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 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) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ 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) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ /* Enable Address Acknowledge */ -+ 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 Sequential transmit in slave mode an amount of data in no-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 I2C module -+ * @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_Sequential_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(hi2c->State == 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 */ -+ 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->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* 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 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_Sequential_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(hi2c->State == 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 */ -+ 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->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* 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 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 */ -+ 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 */ -+ 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 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; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* 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 */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ 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 */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ 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; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* 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 */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ 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 */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ 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 Abort a master I2C process communication with Interrupt. -+ * @note This abort can be called only if state is ready -+ * @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) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(DevAddress); -+ -+ /* Abort Master transfer during Receive or Transmit process */ -+ if(hi2c->Mode == HAL_I2C_MODE_MASTER) -+ { -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_ABORT; -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate Stop */ -+ 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 */ -+ return HAL_ERROR; -+ } -+} -+ -+/** -+ * @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) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* 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 */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Enable Address Acknowledge */ -+ 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 -+ { -+ 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) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* 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 */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Enable Address Acknowledge */ -+ 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 -+ { -+ 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 -+ * @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) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ 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++); -+ 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Generate Stop */ -+ 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 -+ * @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) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(hi2c->XferSize == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ 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_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ 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_TIMEOUT; -+ } -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ else -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ 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 -+ * @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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->Devaddress = DevAddress; -+ hi2c->Memaddress = MemAddress; -+ hi2c->MemaddSize = MemAddSize; -+ hi2c->EventCount = 0U; -+ -+ /* Generate Start */ -+ 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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->Devaddress = DevAddress; -+ hi2c->Memaddress = MemAddress; -+ hi2c->MemaddSize = MemAddSize; -+ hi2c->EventCount = 0U; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ 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 -+ * @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; -+ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ 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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* 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 */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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; -+ } -+ return HAL_OK; -+ } -+ 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 -+ * @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) -+{ -+ uint32_t tickstart = 0x00U; -+ __IO uint32_t count = 0U; -+ -+ /* Init tickstart for timeout management*/ -+ 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 -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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 */ -+ 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->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* 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 */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(Size == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ } -+ else -+ { -+ /* Enable Last DMA 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 -+ { -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ 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 -+ * @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) -+{ -+ uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U; -+ -+ /* Get tick */ -+ 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 */ -+ 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ 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); -+ tmp3 = hi2c->State; -+ while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) -+ { -+ hi2c->State = HAL_I2C_STATE_TIMEOUT; -+ } -+ tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); -+ tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); -+ tmp3 = hi2c->State; -+ } -+ -+ 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 */ -+ 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_TIMEOUT; -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ /* Generate Stop */ -+ 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_TIMEOUT; -+ } -+ } -+ }while(I2C_Trials++ < Trials); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @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 sr2itflags = READ_REG(hi2c->Instance->SR2); -+ uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); -+ uint32_t itsources = READ_REG(hi2c->Instance->CR2); -+ -+ uint32_t CurrentMode = hi2c->Mode; -+ -+ /* Master or Memory mode selected */ -+ if((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) -+ { -+ /* SB Set ----------------------------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_SB(hi2c); -+ } -+ /* ADD10 Set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_ADD10) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_ADD10(hi2c); -+ } -+ /* ADDR Set --------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_ADDR(hi2c); -+ } -+ -+ /* I2C in mode Transmitter -----------------------------------------------*/ -+ if((sr2itflags & I2C_FLAG_TRA) != RESET) -+ { -+ /* TXE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_MasterTransmit_TXE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_MasterTransmit_BTF(hi2c); -+ } -+ } -+ /* I2C in mode Receiver --------------------------------------------------*/ -+ else -+ { -+ /* RXNE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_MasterReceive_RXNE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_MasterReceive_BTF(hi2c); -+ } -+ } -+ } -+ /* Slave mode selected */ -+ else -+ { -+ /* ADDR set --------------------------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Slave_ADDR(hi2c); -+ } -+ /* STOPF set --------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Slave_STOPF(hi2c); -+ } -+ /* I2C in mode Transmitter -----------------------------------------------*/ -+ else if((sr2itflags & I2C_FLAG_TRA) != RESET) -+ { -+ /* TXE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_SlaveTransmit_TXE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_SlaveTransmit_BTF(hi2c); -+ } -+ } -+ /* I2C in mode Receiver --------------------------------------------------*/ -+ else -+ { -+ /* RXNE set and BTF reset ----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_SlaveReceive_RXNE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_SlaveReceive_BTF(hi2c); -+ } -+ } -+ } -+} -+ -+/** -+ * @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) -+{ -+ uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U; -+ uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); -+ uint32_t itsources = READ_REG(hi2c->Instance->CR2); -+ -+ /* I2C Bus error interrupt occurred ----------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; -+ -+ /* Clear BERR flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); -+ } -+ -+ /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ -+ if(((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; -+ -+ /* Clear ARLO flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); -+ } -+ -+ /* I2C Acknowledge failure error interrupt occurred ------------------------*/ -+ if(((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ tmp1 = hi2c->Mode; -+ 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 -+ { -+ hi2c->ErrorCode |= 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(hi2c->Mode == HAL_I2C_MODE_MASTER) -+ { -+ /* Generate Stop */ -+ SET_BIT(hi2c->Instance->CR1,I2C_CR1_STOP); -+ } -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ } -+ } -+ -+ /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= 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(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ 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 can 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 can 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 can 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 can 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_XferOptions_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 can 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 can 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 can 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 can 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 can 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 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 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 Return 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; -+} -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @brief Handle TXE flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t 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; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ 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 */ -+ 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; -+ HAL_I2C_MemTxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ } -+ } -+ 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) -+ { -+ if(hi2c->EventCount == 0) -+ { -+ /* 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 += 2; -+ } -+ /* 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 == 1) -+ { -+ /* Send LSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); -+ -+ hi2c->EventCount++; -+ } -+ else if(hi2c->EventCount == 2) -+ { -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ } -+ } -+ else -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Master transmitter -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef 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++); -+ 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; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ 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 */ -+ 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; -+ -+ HAL_I2C_MemTxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle RXNE flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ uint32_t tmp = 0U; -+ -+ tmp = hi2c->XferCount; -+ if(tmp > 3U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ if(hi2c->XferCount == 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((tmp == 1U) || (tmp == 0U)) -+ { -+ /* Disable Acknowledge */ -+ 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++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Master receiver -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef 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++) = hi2c->Instance->DR; -+ 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); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ else if(hi2c->XferCount == 2U) -+ { -+ /* Prepare next transfer or stop current transfer */ -+ if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ /* Disable EVT and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ else -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle SB flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef 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); -+ } -+ } -+ 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); -+ } -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADD10 flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c) -+{ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADDR flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ hi2c->EventCount++; -+ } -+ else -+ { -+ if(hi2c->XferCount == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferCount == 1U) -+ { -+ if(CurrentXferOptions == I2C_NO_OPTION_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Disable Acknowledge */ -+ 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 */ -+ 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)) -+ { -+ if(hi2c->XferOptions != I2C_NEXT_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ } -+ else if(hi2c->XferCount == 2U) -+ { -+ if(hi2c->XferOptions != I2C_NEXT_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ } -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Enable Last DMA bit */ -+ hi2c->Instance->CR2 |= I2C_CR2_LAST; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Enable Last DMA 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); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle TXE flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ 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 Tx complete callback to inform upper layer of the end of receive process */ -+ HAL_I2C_SlaveTxCpltCallback(hi2c); -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Slave transmitter -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle RXNE flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ 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 Rx complete callback to inform upper layer of the end of receive process */ -+ HAL_I2C_SlaveRxCpltCallback(hi2c); -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Slave receiver -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADD flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) -+{ -+ uint8_t TransferDirection = I2C_DIRECTION_RECEIVE; -+ uint16_t SlaveAddrCode = 0U; -+ -+ /* Transfer Direction requested by Master */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == RESET) -+ { -+ TransferDirection = I2C_DIRECTION_TRANSMIT; -+ } -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DUALF) == RESET) -+ { -+ SlaveAddrCode = hi2c->Init.OwnAddress1; -+ } -+ else -+ { -+ SlaveAddrCode = hi2c->Init.OwnAddress2; -+ } -+ -+ /* Call Slave Addr callback */ -+ HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle STOPF flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t 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 */ -+ 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((hi2c->State == HAL_I2C_STATE_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) -+ { -+ hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmarx); -+ } -+ else -+ { -+ hi2c->XferCount = __HAL_DMA_GET_COUNTER(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++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ -+ /* 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_LISTEN ) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN) || \ -+ (CurrentState == HAL_I2C_STATE_BUSY_TX_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 */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+ 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; -+ -+ HAL_I2C_SlaveRxCpltCallback(hi2c); -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t 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 */ -+ 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 */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+ 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 */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ HAL_I2C_SlaveTxCpltCallback(hi2c); -+ } -+ else -+ { -+ /* Clear AF flag only */ -+ /* State Listen, but XferOptions == FIRST or NEXT */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @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 */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_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((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ } -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ } -+ -+ /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ /* Abort DMA transfer */ -+ if((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++) = hi2c->Instance->DR; -+ } -+ -+ /* 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++) = hi2c->Instance->DR; -+ } -+ -+ /* 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 */ -+ HAL_I2C_AbortCpltCallback(hi2c); -+ } -+ else -+ { -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ } -+ -+ /* Call user error callback */ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+ /* STOP Flag is not set after a NACK reception */ -+ /* So may inform upper layer that listen phase is stopped */ -+ /* during NACK error treatment */ -+ if((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) -+ { -+ 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 */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+} -+ -+/** -+ * @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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ 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 */ -+ 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ 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 -+ * @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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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 -+ * @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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ 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) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ 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; -+ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t CurrentMode = hi2c->Mode; -+ -+ if((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) -+ { -+ /* Disable DMA Request */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ } -+ else -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Disable Last DMA */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_LAST; -+ -+ /* Disable DMA Request */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Check if Errors has been detected during transfer */ -+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+ else -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ } -+} -+ -+/** -+ * @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; -+ -+ /* 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; -+ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+} -+ -+/** -+ * @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) -+{ -+ I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Reset XferAbortCallback */ -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* 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; -+ -+ /* 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 */ -+ HAL_I2C_AbortCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* 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 */ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+} -+ -+/** -+ * @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) ? SET : RESET) == Status) -+ { -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ -+ 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 */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Clear AF Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_AF; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ 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((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ 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((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ 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((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ 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->ErrorCode = HAL_I2C_ERROR_AF; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ return HAL_OK; -+} -+/** -+ * @} -+ */ -+ -+#endif /* HAL_I2C_MODULE_ENABLED */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c -new file mode 100644 -index 0000000..de8f160 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c -@@ -0,0 +1,204 @@ -+/** -+ ****************************************************************************** -+ * @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 -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @defgroup I2CEx I2CEx -+ * @brief I2C HAL module driver -+ * @{ -+ */ -+ -+#ifdef HAL_I2C_MODULE_ENABLED -+ -+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ -+ defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ -+ defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -+/* 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 /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ -+ STM32F401xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx ||\ -+ STM32F423xx */ -+ -+#endif /* HAL_I2C_MODULE_ENABLED */ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Inc/i2c.h b/Firmware/Board/v3/Inc/i2c.h -new file mode 100644 -index 0000000..f449b88 ---- /dev/null -+++ b/Firmware/Board/v3/Inc/i2c.h -@@ -0,0 +1,91 @@ -+/** -+ ****************************************************************************** -+ * File Name : I2C.h -+ * Description : This file provides code for the configuration -+ * of the I2C instances. -+ ****************************************************************************** -+ * This notice applies to any and all portions of this file -+ * that are not between comment pairs USER CODE BEGIN and -+ * USER CODE END. Other portions of this file, whether -+ * inserted by the user or by software development tools -+ * are owned by their respective copyright owners. -+ * -+ * Copyright (c) 2018 STMicroelectronics International N.V. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted, provided that the following conditions are met: -+ * -+ * 1. Redistribution of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of other -+ * contributors to this software may be used to endorse or promote products -+ * derived from this software without specific written permission. -+ * 4. This software, including modifications and/or derivative works of this -+ * software, must execute solely and exclusively on microcontroller or -+ * microprocessor devices manufactured by or for STMicroelectronics. -+ * 5. Redistribution and use of this software other than as permitted under -+ * this license is void and will automatically terminate your rights under -+ * this license. -+ * -+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY -+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT -+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __i2c_H -+#define __i2c_H -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+#include "main.h" -+ -+/* USER CODE BEGIN Includes */ -+ -+/* USER CODE END Includes */ -+ -+extern I2C_HandleTypeDef hi2c1; -+ -+/* USER CODE BEGIN Private defines */ -+ -+/* USER CODE END Private defines */ -+ -+extern void _Error_Handler(char *, int); -+ -+void MX_I2C1_Init(uint8_t addr); -+ -+/* USER CODE BEGIN Prototypes */ -+ -+/* USER CODE END Prototypes */ -+ -+#ifdef __cplusplus -+} -+#endif -+#endif /*__ i2c_H */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -index d0f48f5..b3ef59a 100644 ---- a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -+++ b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -@@ -65,7 +65,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 */ -diff --git a/Firmware/Board/v3/Src/i2c.c b/Firmware/Board/v3/Src/i2c.c -new file mode 100644 -index 0000000..bae77f1 ---- /dev/null -+++ b/Firmware/Board/v3/Src/i2c.c -@@ -0,0 +1,198 @@ -+/** -+ ****************************************************************************** -+ * File Name : I2C.c -+ * Description : This file provides code for the configuration -+ * of the I2C instances. -+ ****************************************************************************** -+ * This notice applies to any and all portions of this file -+ * that are not between comment pairs USER CODE BEGIN and -+ * USER CODE END. Other portions of this file, whether -+ * inserted by the user or by software development tools -+ * are owned by their respective copyright owners. -+ * -+ * Copyright (c) 2018 STMicroelectronics International N.V. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted, provided that the following conditions are met: -+ * -+ * 1. Redistribution of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of other -+ * contributors to this software may be used to endorse or promote products -+ * derived from this software without specific written permission. -+ * 4. This software, including modifications and/or derivative works of this -+ * software, must execute solely and exclusively on microcontroller or -+ * microprocessor devices manufactured by or for STMicroelectronics. -+ * 5. Redistribution and use of this software other than as permitted under -+ * this license is void and will automatically terminate your rights under -+ * this license. -+ * -+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY -+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT -+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "i2c.h" -+ -+#include "gpio.h" -+#include "dma.h" -+ -+/* USER CODE BEGIN 0 */ -+ -+/* USER CODE END 0 */ -+ -+I2C_HandleTypeDef hi2c1; -+DMA_HandleTypeDef hdma_i2c1_rx; -+DMA_HandleTypeDef hdma_i2c1_tx; -+ -+/* I2C1 init function */ -+void MX_I2C1_Init(uint8_t addr) -+{ -+ -+ hi2c1.Instance = I2C1; -+ hi2c1.Init.ClockSpeed = 100000; -+ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; -+ hi2c1.Init.OwnAddress1 = addr << 1; -+ 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(__FILE__, __LINE__); -+ } -+ -+} -+ -+void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) -+{ -+ -+ GPIO_InitTypeDef GPIO_InitStruct; -+ if(i2cHandle->Instance==I2C1) -+ { -+ /* USER CODE BEGIN I2C1_MspInit 0 */ -+ -+ /* USER CODE END I2C1_MspInit 0 */ -+ -+ /**I2C1 GPIO Configuration -+ PB8 ------> I2C1_SCL -+ PB9 ------> I2C1_SDA -+ */ -+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; -+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; -+ GPIO_InitStruct.Pull = GPIO_PULLUP; -+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; -+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; -+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); -+ -+ /* I2C1 clock enable */ -+ __HAL_RCC_I2C1_CLK_ENABLE(); -+ -+ /* I2C1 DMA Init */ -+ /* I2C1_RX Init */ -+ hdma_i2c1_rx.Instance = DMA1_Stream0; -+ hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1; -+ hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; -+ hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE; -+ hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE; -+ hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; -+ hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; -+ hdma_i2c1_rx.Init.Mode = DMA_CIRCULAR; -+ hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW; -+ hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; -+ if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+ __HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c1_rx); -+ -+ /* I2C1_TX Init */ -+ hdma_i2c1_tx.Instance = DMA1_Stream6; -+ hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_1; -+ hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; -+ hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE; -+ hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE; -+ hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; -+ hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; -+ hdma_i2c1_tx.Init.Mode = DMA_NORMAL; -+ hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW; -+ hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; -+ if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+ __HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c1_tx); -+ -+ /* I2C1 interrupt Init */ -+ HAL_NVIC_SetPriority(I2C1_EV_IRQn, 5, 0); -+ HAL_NVIC_EnableIRQ(I2C1_EV_IRQn); -+ HAL_NVIC_SetPriority(I2C1_ER_IRQn, 5, 0); -+ HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); -+ /* USER CODE BEGIN I2C1_MspInit 1 */ -+ -+ /* USER CODE END I2C1_MspInit 1 */ -+ } -+} -+ -+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle) -+{ -+ -+ if(i2cHandle->Instance==I2C1) -+ { -+ /* USER CODE BEGIN I2C1_MspDeInit 0 */ -+ -+ /* USER CODE END I2C1_MspDeInit 0 */ -+ /* Peripheral clock disable */ -+ __HAL_RCC_I2C1_CLK_DISABLE(); -+ -+ /**I2C1 GPIO Configuration -+ PB8 ------> I2C1_SCL -+ PB9 ------> I2C1_SDA -+ */ -+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9); -+ -+ /* I2C1 DMA DeInit */ -+ HAL_DMA_DeInit(i2cHandle->hdmarx); -+ HAL_DMA_DeInit(i2cHandle->hdmatx); -+ -+ /* I2C1 interrupt Deinit */ -+ HAL_NVIC_DisableIRQ(I2C1_EV_IRQn); -+ HAL_NVIC_DisableIRQ(I2C1_ER_IRQn); -+ /* USER CODE BEGIN I2C1_MspDeInit 1 */ -+ -+ /* USER CODE END I2C1_MspDeInit 1 */ -+ } -+} -+ -+/* USER CODE BEGIN 1 */ -+ -+/* USER CODE END 1 */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c -index 987e0bd..efaeef1 100644 ---- a/Firmware/Board/v3/Src/main.c -+++ b/Firmware/Board/v3/Src/main.c -@@ -187,7 +187,6 @@ int main(void) - MX_ADC3_Init(); - MX_TIM2_Init(); - MX_UART4_Init(); -- MX_CAN1_Init(); - /* USER CODE BEGIN 2 */ - - //Required to use OC4 for ADC triggering. --- -2.17.0 - diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h new file mode 100644 index 00000000..5452a507 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h @@ -0,0 +1,649 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c.h + * @author MCD Application Team + * @brief Header file of I2C HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* 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 + * @{ + */ + +/** + * @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; + +/** + * @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 IP initilisation status + * 0 : Reset (IP not initialized) + * 1 : Init done (IP 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 (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_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; + +/** + * @brief HAL Mode structure definition + * @note HAL I2C Mode value coding follow below described bitmap : + * b7 (not used) + * x : Should be set to 0 + * b6 + * 0 : None + * 1 : Memory (HAL I2C communication is in Memory Mode) + * b5 + * 0 : None + * 1 : Slave (HAL I2C communication is in Slave Mode) + * b4 + * 0 : None + * 1 : Master (HAL I2C communication is in Master Mode) + * b3-b2-b1-b0 (not used) + * 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; + +/** + * @brief I2C handle Structure definition + */ +typedef struct +{ + 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 */ + +}I2C_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_Error_Code I2C Error Code + * @brief I2C Error Code + * @{ + */ +#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 */ +/** + * @} + */ + +/** @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_NEXT_FRAME 0x00000002U +#define I2C_FIRST_AND_LAST_FRAME 0x00000004U +#define I2C_LAST_FRAME 0x00000008U +/** + * @} + */ + +/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition + * @{ + */ +#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_SMBALERT 0x00018000U +#define I2C_FLAG_TIMEOUT 0x00014000U +#define I2C_FLAG_PECERR 0x00011000U +#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_SMBHOST 0x00100040U +#define I2C_FLAG_SMBDEFAULT 0x00100020U +#define I2C_FLAG_GENCALL 0x00100010U +#define I2C_FLAG_TRA 0x00100004U +#define I2C_FLAG_BUSY 0x00100002U +#define I2C_FLAG_MSL 0x00100001U +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state + * @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_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) + +/** @brief Enable or disable the specified I2C interrupts. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @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__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) +#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) + +/** @brief Checks if the specified I2C interrupt source is enabled or disabled. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @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. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @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_SMBHOST: SMBus host header + * @arg I2C_FLAG_SMBDEFAULT: SMBus default header + * @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)): \ + ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) + +/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @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. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_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 I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) + +/** @brief Disable the I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_DISABLE(__HANDLE__) ((__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/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); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group2 + * @{ + */ +/* I/O 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_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); + +/******* 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); + +/******* 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 Errors 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 +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macros I2C Private Macros + * @{ + */ + +#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__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) +#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__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__) & (~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_NEXT_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME)) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_I2C_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h new file mode 100644 index 00000000..ff47d5cc --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h @@ -0,0 +1,137 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c_ex.h + * @author MCD Application Team + * @brief Header file of I2C HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_I2C_EX_H +#define __STM32F4xx_HAL_I2C_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) +/* 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 /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ + STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx ||\ + STM32F413xx || STM32F423xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_I2C_EX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c new file mode 100644 index 00000000..da185200 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c @@ -0,0 +1,5494 @@ +/** + ****************************************************************************** + * @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(&hi2c) 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 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 @ref I2C_XFEROPTIONS and are listed below: + (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal 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_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 + + (+) Differents sequential I2C interfaces are listed below: + (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT() + (+++) 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_Sequential_Receive_IT() + (+++) 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 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_Sequential_Transmit_IT() + (+++) 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_Sequential_Receive_IT() + (+++) 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() + (++) 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 IO MEM operation *** + ======================================= + [..] + (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using + HAL_I2C_Mem_Write_IT() + (+) At MEM 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 no-blocking mode with Interrupt from a specific memory address using + HAL_I2C_Mem_Read_IT() + (+) At MEM 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 no-blocking mode with DMA to a specific memory address using + HAL_I2C_Mem_Write_DMA() + (+) At MEM 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 no-blocking mode with DMA from a specific memory address using + HAL_I2C_Mem_Read_DMA() + (+) At MEM 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 + + [..] + (@) You can refer to the I2C HAL driver header file for more useful macros + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* 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_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ + +/* Private define for @ref PreviousState usage */ +#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(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)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup 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); +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_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c); + +/* Private functions for I2C transfer IRQ handler */ +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c); + +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_AF(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 + de-initialize 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 create the associated handle. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) +{ + uint32_t freqrange = 0U; + uint32_t pclk1 = 0U; + + /* 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; + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_I2C_MspInit(hi2c); + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get PCLK1 frequency */ + pclk1 = HAL_RCC_GetPCLK1Freq(); + + /* Calculate frequency range */ + freqrange = I2C_FREQRANGE(pclk1); + + /*---------------------------- I2Cx CR2 Configuration ----------------------*/ + /* Configure I2Cx: Frequency range */ + hi2c->Instance->CR2 = freqrange; + + /*---------------------------- I2Cx TRISE Configuration --------------------*/ + /* Configure I2Cx: Rise Time */ + hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); + + /*---------------------------- I2Cx CCR Configuration ----------------------*/ + /* Configure I2Cx: Speed */ + hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); + + /*---------------------------- I2Cx CR1 Configuration ----------------------*/ + /* Configure I2Cx: Generalcall and NoStretch mode */ + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + + /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ + /* Configure I2Cx: Own Address1 and addressing mode */ + hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); + + /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ + /* Configure I2Cx: Dual mode and Own Address2 */ + hi2c->Instance->OAR2 = (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 DeInitializes the I2C peripheral. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @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); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_I2C_MspDeInit(hi2c); + + 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 I2C MSP Init. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @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 I2C MSP DeInit + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @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 + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the 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_Master_Sequential_Transmit_IT() + (++) HAL_I2C_Master_Sequential_Receive_IT() + (++) HAL_I2C_Slave_Sequential_Transmit_IT() + (++) HAL_I2C_Slave_Sequential_Receive_IT() + (++) HAL_I2C_Mem_Write_IT() + (++) HAL_I2C_Mem_Read_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() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2C_MemTxCpltCallback() + (++) HAL_I2C_MemRxCpltCallback() + (++) HAL_I2C_MasterTxCpltCallback() + (++) HAL_I2C_MasterRxCpltCallback() + (++) HAL_I2C_SlaveTxCpltCallback() + (++) HAL_I2C_SlaveRxCpltCallback() + (++) 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) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + 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++); + 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + } + + /* Generate Stop */ + 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) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferSize == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 2U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + 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_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + 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_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + 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) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + 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_TIMEOUT; + } + + /* 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_TIMEOUT; + } + + /* 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 */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + 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++); + hi2c->XferCount--; + hi2c->XferSize--; + } + } + + /* Wait until AF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Address Acknowledge */ + 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) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + 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_TIMEOUT; + } + + /* 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 */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + + /* Wait until STOP flag is set */ + if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Address Acknowledge */ + 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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + /* Generate Start */ + 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 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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + 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 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_Sequential_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((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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + Prev_State = hi2c->PreviousState; + + /* Generate Start */ + if((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) + { + /* Generate Start condition if first transfer */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else + { + /* Generate ReStart */ + 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 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_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + __IO uint32_t count = 0U; + + /* 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((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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) + { + /* Generate Start condition if first transfer */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate ReStart */ + 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 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) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + 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) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + /* Enable Address Acknowledge */ + 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 Sequential transmit in slave mode an amount of data in no-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 I2C module + * @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_Sequential_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(hi2c->State == 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 */ + 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->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + + /* 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 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_Sequential_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(hi2c->State == 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 */ + 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->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + + /* 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 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 */ + 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 */ + 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 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; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if(hi2c->XferSize > 0U) + { + /* 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 */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + 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 */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + 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; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if(hi2c->XferSize > 0U) + { + /* 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 */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + 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 */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + 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 Abort a master I2C process communication with Interrupt. + * @note This abort can be called only if state is ready + * @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) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(DevAddress); + + /* Abort Master transfer during Receive or Transmit process */ + if(hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_ABORT; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + 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 */ + return HAL_ERROR; + } +} + +/** + * @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) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* 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 */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Enable Address Acknowledge */ + 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 + { + 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) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* 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 */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Enable Address Acknowledge */ + 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 + { + 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 + * @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) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + 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++); + 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Generate Stop */ + 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 + * @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) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferSize == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 2U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + 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_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + 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_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + 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 + * @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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->Devaddress = DevAddress; + hi2c->Memaddress = MemAddress; + hi2c->MemaddSize = MemAddSize; + hi2c->EventCount = 0U; + + /* Generate Start */ + 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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->Devaddress = DevAddress; + hi2c->Memaddress = MemAddress; + hi2c->MemaddSize = MemAddSize; + hi2c->EventCount = 0U; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + 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 + * @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; + + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + 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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + if(hi2c->XferSize > 0U) + { + /* 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 */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* 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; + } + return HAL_OK; + } + 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 + * @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) +{ + uint32_t tickstart = 0x00U; + __IO uint32_t count = 0U; + + /* Init tickstart for timeout management*/ + 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 + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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 */ + 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->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + if(hi2c->XferSize > 0U) + { + /* 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 */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(Size == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Last DMA 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 + { + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + 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 + * @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) +{ + uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U; + + /* Get tick */ + 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 */ + 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 */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) + { + 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); + tmp3 = hi2c->State; + while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) + { + if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hi2c->State = HAL_I2C_STATE_TIMEOUT; + } + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp3 = hi2c->State; + } + + 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 */ + 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_TIMEOUT; + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + /* Generate Stop */ + 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_TIMEOUT; + } + } + }while(I2C_Trials++ < Trials); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + else + { + return HAL_BUSY; + } +} + +/** + * @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 sr2itflags = READ_REG(hi2c->Instance->SR2); + uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); + uint32_t itsources = READ_REG(hi2c->Instance->CR2); + + uint32_t CurrentMode = hi2c->Mode; + + /* Master or Memory mode selected */ + if((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) + { + /* SB Set ----------------------------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_SB(hi2c); + } + /* ADD10 Set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_ADD10) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_ADD10(hi2c); + } + /* ADDR Set --------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_ADDR(hi2c); + } + + /* I2C in mode Transmitter -----------------------------------------------*/ + if((sr2itflags & I2C_FLAG_TRA) != RESET) + { + /* TXE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_MasterTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_MasterTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + /* RXNE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_MasterReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_MasterReceive_BTF(hi2c); + } + } + } + /* Slave mode selected */ + else + { + /* ADDR set --------------------------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Slave_ADDR(hi2c); + } + /* STOPF set --------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Slave_STOPF(hi2c); + } + /* I2C in mode Transmitter -----------------------------------------------*/ + else if((sr2itflags & I2C_FLAG_TRA) != RESET) + { + /* TXE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_SlaveTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_SlaveTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + /* RXNE set and BTF reset ----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_SlaveReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_SlaveReceive_BTF(hi2c); + } + } + } +} + +/** + * @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) +{ + uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U; + uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); + uint32_t itsources = READ_REG(hi2c->Instance->CR2); + + /* I2C Bus error interrupt occurred ----------------------------------------*/ + if(((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); + } + + /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ + if(((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); + } + + /* I2C Acknowledge failure error interrupt occurred ------------------------*/ + if(((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + tmp1 = hi2c->Mode; + 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 + { + hi2c->ErrorCode |= 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(hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Generate Stop */ + SET_BIT(hi2c->Instance->CR1,I2C_CR1_STOP); + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + + /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ + if(((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= 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(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + 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 can 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 can 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 can 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 can 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_XferOptions_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 can 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 can 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 can 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 can 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 can 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 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 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 Return 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; +} + +/** + * @} + */ + +/** + * @brief Handle TXE flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t 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; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + 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 */ + 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; + HAL_I2C_MemTxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MasterTxCpltCallback(hi2c); + } + } + } + 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) + { + if(hi2c->EventCount == 0) + { + /* 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 += 2; + } + /* 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 == 1) + { + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); + + hi2c->EventCount++; + } + else if(hi2c->EventCount == 2) + { + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + } + } + else + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master transmitter + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef 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++); + 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; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + 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 */ + 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; + + HAL_I2C_MemTxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + } + } + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + uint32_t tmp = 0U; + + tmp = hi2c->XferCount; + if(tmp > 3U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + if(hi2c->XferCount == 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((tmp == 1U) || (tmp == 0U)) + { + /* Disable Acknowledge */ + 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++) = hi2c->Instance->DR; + hi2c->XferCount--; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master receiver + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef 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++) = hi2c->Instance->DR; + 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); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + else if(hi2c->XferCount == 2U) + { + /* Prepare next transfer or stop current transfer */ + if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Disable EVT and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + else + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle SB flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef 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); + } + } + 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); + } + } + } + + return HAL_OK; +} + +/** + * @brief Handle ADD10 flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c) +{ + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress); + + return HAL_OK; +} + +/** + * @brief Handle ADDR flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t 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 */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + hi2c->EventCount++; + } + else + { + if(hi2c->XferCount == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferCount == 1U) + { + if(CurrentXferOptions == I2C_NO_OPTION_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Disable Acknowledge */ + 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 */ + 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)) + { + if(hi2c->XferOptions != I2C_NEXT_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + } + else if(hi2c->XferCount == 2U) + { + if(hi2c->XferOptions != I2C_NEXT_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + } + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Enable Last DMA 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); + } + + return HAL_OK; +} + +/** + * @brief Handle TXE flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + 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 Tx complete callback to inform upper layer of the end of receive process */ + HAL_I2C_SlaveTxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave transmitter + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if(hi2c->XferCount != 0U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + 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 Rx complete callback to inform upper layer of the end of receive process */ + HAL_I2C_SlaveRxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave receiver + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle ADD flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) +{ + uint8_t TransferDirection = I2C_DIRECTION_RECEIVE; + uint16_t SlaveAddrCode = 0U; + + /* Transfer Direction requested by Master */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == RESET) + { + TransferDirection = I2C_DIRECTION_TRANSMIT; + } + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DUALF) == RESET) + { + SlaveAddrCode = hi2c->Init.OwnAddress1; + } + else + { + SlaveAddrCode = hi2c->Init.OwnAddress2; + } + + /* Call Slave Addr callback */ + HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode); + + return HAL_OK; +} + +/** + * @brief Handle STOPF flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t 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 */ + 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((hi2c->State == HAL_I2C_STATE_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmarx); + } + else + { + hi2c->XferCount = __HAL_DMA_GET_COUNTER(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++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + + /* 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_LISTEN ) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN) || \ + (CurrentState == HAL_I2C_STATE_BUSY_TX_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 */ + HAL_I2C_ListenCpltCallback(hi2c); + } + 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; + + HAL_I2C_SlaveRxCpltCallback(hi2c); + } + } + } + return HAL_OK; +} + +/** + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t 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 */ + 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 */ + HAL_I2C_ListenCpltCallback(hi2c); + } + 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 */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + HAL_I2C_SlaveTxCpltCallback(hi2c); + } + else + { + /* Clear AF flag only */ + /* State Listen, but XferOptions == FIRST or NEXT */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + + return HAL_OK; +} + +/** + * @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 */ + uint32_t CurrentState = hi2c->State; + + if((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_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((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) + { + hi2c->State = HAL_I2C_STATE_READY; + } + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + } + + /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + /* Abort DMA transfer */ + if((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++) = hi2c->Instance->DR; + } + + /* 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++) = hi2c->Instance->DR; + } + + /* 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 */ + HAL_I2C_AbortCpltCallback(hi2c); + } + else + { + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + } + + /* Call user error callback */ + HAL_I2C_ErrorCallback(hi2c); + } + /* STOP Flag is not set after a NACK reception */ + /* So may inform upper layer that listen phase is stopped */ + /* during NACK error treatment */ + if((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) + { + 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 */ + HAL_I2C_ListenCpltCallback(hi2c); + } +} + +/** + * @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 */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + 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 */ + 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 */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + 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 + * @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 */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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 + * @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 */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + 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) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + 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; + + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t CurrentMode = hi2c->Mode; + + if((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) + { + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0U; + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + } + else + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Disable Last DMA */ + hi2c->Instance->CR2 &= ~I2C_CR2_LAST; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0U; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + } +} + +/** + * @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; + + /* 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; + + HAL_I2C_ErrorCallback(hi2c); + } +} + +/** + * @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) +{ + I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->XferCount = 0U; + + /* Reset XferAbortCallback */ + hi2c->hdmatx->XferAbortCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* 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; + + /* 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 */ + HAL_I2C_AbortCpltCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* 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 */ + HAL_I2C_ErrorCallback(hi2c); + } +} + +/** + * @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) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + + 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 */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + 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((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + 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((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + 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((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + 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->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + return HAL_OK; +} +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c new file mode 100644 index 00000000..de8f1602 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c @@ -0,0 +1,204 @@ +/** + ****************************************************************************** + * @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 + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup I2CEx I2CEx + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) +/* 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 /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ + STM32F401xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx ||\ + STM32F423xx */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h index e518489f..ed26bf39 100644 --- a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h +++ b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h @@ -65,7 +65,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 */ diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index e390af58..154c98af 100644 --- a/Firmware/Board/v3/Src/main.c +++ b/Firmware/Board/v3/Src/main.c @@ -180,7 +180,7 @@ int main(void) MX_DMA_Init(); MX_ADC1_Init(); MX_ADC2_Init(); - MX_CAN1_Init(); + // MX_CAN1_Init(); // CAN or I2C called in main.cpp instead MX_TIM1_Init(); MX_TIM8_Init(); MX_TIM3_Init();