summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal/hal/f7/src/stm32f7xx_hal_i2c.c
diff options
context:
space:
mode:
authorRami Ali <flowergrass@users.noreply.github.com>2016-12-05 17:04:56 +1100
committerDamien George <damien.p.george@gmail.com>2016-12-07 17:28:33 +1100
commitb9741cd8f84a2f49e3ea00382bfa71d994bc83ff (patch)
treeaba9f61737351866c9f049ea1b45b33e8a7c330c /stmhal/hal/f7/src/stm32f7xx_hal_i2c.c
parentd9677f4098b91a6e1df71897ffc835ddf601b0f2 (diff)
downloadmicropython-b9741cd8f84a2f49e3ea00382bfa71d994bc83ff.tar.gz
micropython-b9741cd8f84a2f49e3ea00382bfa71d994bc83ff.zip
stmhal/hal: Update ST32CubeF7 HAL files to V1.1.2.
These files originate from the STM32Cube_FW_F7_V1.5.0 software package from ST. Newlines are unixified and trailing whitespace is removed.
Diffstat (limited to 'stmhal/hal/f7/src/stm32f7xx_hal_i2c.c')
-rw-r--r--stmhal/hal/f7/src/stm32f7xx_hal_i2c.c3906
1 files changed, 2285 insertions, 1621 deletions
diff --git a/stmhal/hal/f7/src/stm32f7xx_hal_i2c.c b/stmhal/hal/f7/src/stm32f7xx_hal_i2c.c
index 2c51ee21da..66a154edc3 100644
--- a/stmhal/hal/f7/src/stm32f7xx_hal_i2c.c
+++ b/stmhal/hal/f7/src/stm32f7xx_hal_i2c.c
@@ -2,8 +2,8 @@
******************************************************************************
* @file stm32f7xx_hal_i2c.c
* @author MCD Application Team
- * @version V1.0.1
- * @date 25-June-2015
+ * @version V1.1.2
+ * @date 23-September-2016
* @brief I2C HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the Inter Integrated Circuit (I2C) peripheral:
@@ -21,7 +21,7 @@
(#) Declare a I2C_HandleTypeDef handle structure, for example:
I2C_HandleTypeDef hi2c;
- (#)Initialize the I2C low level resources by implement the HAL_I2C_MspInit ()API:
+ (#)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
@@ -33,15 +33,16 @@
(+++) 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
+ (+++) 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 priority and enable the NVIC for the transfer complete interrupt on
+ the DMA Tx or Rx stream
- (#) Configure the Communication Clock Timing, Own Address1, Master Addressing Mode, Dual Addressing mode,
+ (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
Own Address2, Own Address2 Mask, 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 customed HAL_I2C_MspInit(&hi2c) API.
+ (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()
@@ -65,70 +66,133 @@
*** 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
+ (+) 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
+ 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_MasterRxCpltCallback() or HAL_I2C_MasterTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() or HAL_I2C_MasterTxCpltCallback()
+ (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
+ This action will inform Master to generate a Stop condition to discard the communication.
+
+
+ *** 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 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_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address
+ and data to transfer without a final stop condition, an then permit a call the same master sequential interface
+ several times (like HAL_I2C_Master_Sequential_Transmit_IT() then HAL_I2C_Master_Sequential_Transmit_IT())
+ (++) 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()
+ (+++) mean HAL_I2C_MasterTxCpltCallback() in case of previous state was master transmit
+ (+++) mean HAL_I2c_MasterRxCpltCallback() in case of previous state was master receive
+ (++) 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()
+ (++) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
+ This action will inform Master to generate a Stop condition to discard the communication.
*** Interrupt mode IO MEM operation ***
=======================================
[..]
- (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using
+ (+) Write an amount of data in non-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
+ (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
+ (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
HAL_I2C_Mem_Read_IT()
- (+) At 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
+ (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
(+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2C_ErrorCallback
+ 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
+ (+) 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
+ (+) 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
+ (+) 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
+ (+) 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
+ (+) 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
+ 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_MasterRxCpltCallback() or HAL_I2C_MasterTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() or HAL_I2C_MasterTxCpltCallback()
+ (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
+ This action will inform Master to generate a Stop condition to discard the communication.
*** DMA mode IO MEM operation ***
=================================
[..]
- (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using
+ (+) Write an amount of data in non-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
+ (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
+ (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
HAL_I2C_Mem_Read_DMA()
- (+) At 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
+ (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and user can
+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
(+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can
- add his own code by customization of function pointer HAL_I2C_ErrorCallback
+ add his own code by customization of function pointer HAL_I2C_ErrorCallback()
*** I2C HAL driver macros list ***
@@ -138,8 +202,9 @@
(+) __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_GENERATE_NACK: Generate a Non-Acknowledge I2C peripheral in Slave mode
+ (+) __HAL_I2C_GET_FLAG: Check 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
@@ -150,7 +215,7 @@
******************************************************************************
* @attention
*
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@@ -192,52 +257,104 @@
#ifdef HAL_I2C_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @addtogroup I2C_Private_Constants I2C Private Constants
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup I2C_Private_Define I2C Private Define
* @{
*/
-#define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFF) /*<! I2C TIMING clear register Mask */
-#define I2C_TIMEOUT_ADDR ((uint32_t)10000) /* 10 s */
-#define I2C_TIMEOUT_BUSY ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_DIR ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_RXNE ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_STOPF ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_TC ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_TCR ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_TXIS ((uint32_t)25) /* 25 ms */
-#define I2C_TIMEOUT_FLAG ((uint32_t)25) /* 25 ms */
+#define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFFU) /*!< I2C TIMING clear register Mask */
+#define I2C_TIMEOUT_ADDR ((uint32_t)10000U) /*!< 10 s */
+#define I2C_TIMEOUT_BUSY ((uint32_t)25U) /*!< 25 ms */
+#define I2C_TIMEOUT_DIR ((uint32_t)25U) /*!< 25 ms */
+#define I2C_TIMEOUT_RXNE ((uint32_t)25U) /*!< 25 ms */
+#define I2C_TIMEOUT_STOPF ((uint32_t)25U) /*!< 25 ms */
+#define I2C_TIMEOUT_TC ((uint32_t)25U) /*!< 25 ms */
+#define I2C_TIMEOUT_TCR ((uint32_t)25U) /*!< 25 ms */
+#define I2C_TIMEOUT_TXIS ((uint32_t)25U) /*!< 25 ms */
+#define I2C_TIMEOUT_FLAG ((uint32_t)25U) /*!< 25 ms */
+
+#define MAX_NBYTE_SIZE 255U
+#define SlaveAddr_SHIFT 7U
+#define SlaveAddr_MSK 0x06U
+
+/* 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 */
+#define I2C_STATE_MEM_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MEM)) /*!< Memory Busy TX, combinaison of State LSB and Mode enum */
+#define I2C_STATE_MEM_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MEM)) /*!< Memory Busy RX, combinaison of State LSB and Mode enum */
+
+/* Private define to centralize the enable/disable of Interrupts */
+#define I2C_XFER_TX_IT ((uint32_t)0x00000001U)
+#define I2C_XFER_RX_IT ((uint32_t)0x00000002U)
+#define I2C_XFER_LISTEN_IT ((uint32_t)0x00000004U)
+
+#define I2C_XFER_ERROR_IT ((uint32_t)0x00000011U)
+#define I2C_XFER_CPLT_IT ((uint32_t)0x00000012U)
+#define I2C_XFER_RELOAD_IT ((uint32_t)0x00000012U)
+
+/* Private define Sequential Transfer Options default/reset value */
+#define I2C_NO_OPTION_FRAME ((uint32_t)0xFFFF0000U)
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
+#define I2C_GET_DMA_REMAIN_DATA(__HANDLE__) ((((__HANDLE__)->State) == HAL_I2C_STATE_BUSY_TX) ? \
+ ((uint32_t)((__HANDLE__)->hdmatx->Instance->NDTR)) : \
+ ((uint32_t)((__HANDLE__)->hdmarx->Instance->NDTR)))
+
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup I2C_Private_Functions I2C Private Functions
+
+/** @defgroup I2C_Private_Functions I2C Private Functions
* @{
*/
+/* Private functions to handle DMA transfer */
static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
-static void I2C_DMAMemTransmitCplt(DMA_HandleTypeDef *hdma);
-static void I2C_DMAMemReceiveCplt(DMA_HandleTypeDef *hdma);
static void I2C_DMAError(DMA_HandleTypeDef *hdma);
-
-static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout);
-static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout);
-static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
-static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
-static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
-static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
-static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
-
-static HAL_StatusTypeDef I2C_MasterTransmit_ISR(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef I2C_MasterReceive_ISR(I2C_HandleTypeDef *hi2c);
-
-static HAL_StatusTypeDef I2C_SlaveTransmit_ISR(I2C_HandleTypeDef *hi2c);
-static HAL_StatusTypeDef I2C_SlaveReceive_ISR(I2C_HandleTypeDef *hi2c);
-
+static void I2C_DMAAbort(DMA_HandleTypeDef *hdma);
+
+/* Private functions to handle IT transfer */
+static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
+static void I2C_ITMasterSequentialCplt(I2C_HandleTypeDef *hi2c);
+static void I2C_ITSlaveSequentialCplt(I2C_HandleTypeDef *hi2c);
+static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
+static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
+static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
+static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode);
+
+/* Private functions to handle IT transfer */
+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
+
+/* Private functions for I2C transfer IRQ handler */
+static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources);
+static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources);
+static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources);
+static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources);
+
+/* Private functions to handle flags during polling transfer */
+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
+static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(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, uint32_t Timeout, uint32_t Tickstart);
+
+/* Private functions to centralize the enable/disable of Interrupts */
+static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest);
+static HAL_StatusTypeDef I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest);
+
+/* Private functions to flush TXDR register */
+static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c);
+
+/* Private functions to handle start, restart or stop a transfer */
static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
/**
* @}
@@ -257,7 +374,7 @@ static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, ui
##### Initialization and de-initialization functions #####
===============================================================================
[..] This subsection provides a set of functions allowing to initialize and
- de-initialize the I2Cx peripheral:
+ deinitialize the I2Cx peripheral:
(+) User must Implement HAL_I2C_MspInit() function in which he configures
all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
@@ -282,9 +399,9 @@ static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, ui
/**
* @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 the specified I2C.
+ * in the I2C_InitTypeDef and initialize the associated handle.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
@@ -309,6 +426,7 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
{
/* Allocate lock resource and initialize it */
hi2c->Lock = HAL_UNLOCKED;
+
/* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
HAL_I2C_MspInit(hi2c);
}
@@ -323,18 +441,17 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK;
/*---------------------------- I2Cx OAR1 Configuration ---------------------*/
- /* Configure I2Cx: Own Address1 and ack own address1 mode */
+ /* Disable Own Address1 before set the Own Address1 configuration */
hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
- if(hi2c->Init.OwnAddress1 != 0)
+
+ /* Configure I2Cx: Own Address1 and ack own address1 mode */
+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
{
- if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
- {
- hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1);
- }
- else /* I2C_ADDRESSINGMODE_10BIT */
- {
- hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1);
- }
+ hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1);
+ }
+ else /* I2C_ADDRESSINGMODE_10BIT */
+ {
+ hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1);
}
/*---------------------------- I2Cx CR2 Configuration ----------------------*/
@@ -347,6 +464,9 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
/*---------------------------- I2Cx OAR2 Configuration ---------------------*/
+ /* Disable Own Address2 before set the Own Address2 configuration */
+ hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE;
+
/* Configure I2Cx: Dual mode and Own Address2 */
hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | (hi2c->Init.OwnAddress2Masks << 8));
@@ -359,14 +479,16 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *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 the specified I2C.
+ * @brief DeInitialize the I2C peripheral.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
@@ -389,8 +511,9 @@ HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
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);
@@ -399,27 +522,33 @@ HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
}
/**
- * @brief I2C MSP Init.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @brief Initialize the I2C MSP.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
* @retval None
*/
- __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
+__weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
+ /* 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 the specified I2C.
+ * @brief DeInitialize the I2C MSP.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
* @retval None
*/
- __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
+__weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
+ /* 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
*/
}
@@ -489,9 +618,10 @@ HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
/**
* @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
+ * @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 shift at right before call interface
* @param pData: Pointer to data buffer
* @param Size: Amount of data to be sent
* @param Timeout: Timeout duration
@@ -499,44 +629,47 @@ HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
*/
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
- uint32_t sizetmp = 0;
+ uint32_t tickstart = 0;
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL ) || (Size == 0))
- {
- return HAL_ERROR;
- }
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
{
- return HAL_BUSY;
+ return HAL_TIMEOUT;
}
- /* Process Locked */
- __HAL_LOCK(hi2c);
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->State = HAL_I2C_STATE_MASTER_BUSY_TX;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferISR = NULL;
/* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- /* Size > 255, need to set RELOAD bit */
- if(Size > 255)
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
- sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE);
- sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE);
}
- do
+ while(hi2c->XferSize > 0)
{
/* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -548,35 +681,34 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA
}
}
/* Write data to TXDR */
- hi2c->Instance->TXDR = (*pData++);
- sizetmp--;
- Size--;
+ hi2c->Instance->TXDR = (*hi2c->pBuffPtr++);
+ hi2c->XferCount--;
+ hi2c->XferSize--;
- if((sizetmp == 0)&&(Size!=0))
+ if((hi2c->XferSize == 0) && (hi2c->XferCount!=0))
{
- /* Wait until TXE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
+ /* Wait until TCR flag is set */
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
- if(Size > 255)
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
}
}
-
- }while(Size > 0);
+ }
/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
/* Wait until STOPF flag is set */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -595,6 +727,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA
I2C_RESET_CR2(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -609,9 +742,10 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA
/**
* @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
+ * @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 shift at right before call interface
* @param pData: Pointer to data buffer
* @param Size: Amount of data to be sent
* @param Timeout: Timeout duration
@@ -619,78 +753,87 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevA
*/
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
- uint32_t sizetmp = 0;
+ uint32_t tickstart = 0;
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL ) || (Size == 0))
- {
- return HAL_ERROR;
- }
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
{
- return HAL_BUSY;
+ return HAL_TIMEOUT;
}
- /* Process Locked */
- __HAL_LOCK(hi2c);
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->State = HAL_I2C_STATE_MASTER_BUSY_RX;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferISR = NULL;
/* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- /* Size > 255, need to set RELOAD bit */
- if(Size > 255)
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
- sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
- sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
}
- do
+ while(hi2c->XferSize > 0)
{
/* Wait until RXNE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
- return HAL_TIMEOUT;
+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ return HAL_TIMEOUT;
+ }
}
- /* Write data to RXDR */
- (*pData++) =hi2c->Instance->RXDR;
- sizetmp--;
- Size--;
+ /* Read data from RXDR */
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
+ hi2c->XferSize--;
+ hi2c->XferCount--;
- if((sizetmp == 0)&&(Size!=0))
+ if((hi2c->XferSize == 0) && (hi2c->XferCount != 0))
{
/* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
- if(Size > 255)
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
}
}
-
- }while(Size > 0);
+ }
/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
/* Wait until STOPF flag is set */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -709,6 +852,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd
I2C_RESET_CR2(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -723,8 +867,8 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd
/**
* @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 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
@@ -732,24 +876,34 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAd
*/
HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
+ uint32_t tickstart = 0;
+
if(hi2c->State == HAL_I2C_STATE_READY)
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
-
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_SLAVE_BUSY_RX;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ 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->XferISR = NULL;
/* Enable Address Acknowledge */
hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
/* Wait until ADDR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
@@ -763,7 +917,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
{
/* Wait until ADDR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
@@ -775,17 +929,17 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
}
/* Wait until DIR flag is set Transmitter mode */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
return HAL_TIMEOUT;
}
- do
+ while(hi2c->XferCount > 0)
{
/* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
@@ -800,22 +954,22 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
}
}
- /* Read data from TXDR */
- hi2c->Instance->TXDR = (*pData++);
- Size--;
- }while(Size > 0);
+ /* Write data to TXDR */
+ hi2c->Instance->TXDR = (*hi2c->pBuffPtr++);
+ hi2c->XferCount--;
+ }
/* Wait until STOP flag is set */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
- /* Normal use case for Transmitter mode */
- /* A NACK is generated to confirm the end of transfer */
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ /* Normal use case for Transmitter mode */
+ /* A NACK is generated to confirm the end of transfer */
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
}
else
{
@@ -827,7 +981,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
__HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_STOPF);
/* Wait until BUSY flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
@@ -838,6 +992,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
hi2c->Instance->CR2 |= I2C_CR2_NACK;
hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -852,8 +1007,8 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
/**
* @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 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
@@ -861,24 +1016,34 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
*/
HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
+ uint32_t tickstart = 0;
+
if(hi2c->State == HAL_I2C_STATE_READY)
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
-
- /* Process Locked */
+ /* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_SLAVE_BUSY_RX;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ 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->XferISR = NULL;
/* Enable Address Acknowledge */
hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
/* Wait until ADDR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
@@ -889,20 +1054,29 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData,
__HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
/* Wait until DIR flag is reset Receiver mode */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
return HAL_TIMEOUT;
}
- while(Size > 0)
+ while(hi2c->XferCount > 0)
{
/* Wait until RXNE flag is set */
- if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
+
+ /* Store Last receive data if any */
+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+ {
+ /* Read data from RXDR */
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
+ hi2c->XferCount--;
+ }
+
if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
{
return HAL_TIMEOUT;
@@ -914,12 +1088,12 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData,
}
/* Read data from RXDR */
- (*pData++) = hi2c->Instance->RXDR;
- Size--;
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
+ hi2c->XferCount--;
}
/* Wait until STOP flag is set */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
@@ -938,18 +1112,18 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData,
__HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_STOPF);
/* Wait until BUSY flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
{
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
return HAL_TIMEOUT;
}
-
/* Disable Address Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -963,23 +1137,21 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData,
}
/**
- * @brief Transmit in master mode an amount of data in no-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
+ * @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 shift at right before call 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)
{
+ uint32_t xfermode = 0;
+
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL) || (Size == 0))
- {
- return HAL_ERROR;
- }
-
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
{
return HAL_BUSY;
@@ -988,30 +1160,30 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t D
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MASTER_BUSY_TX;
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Master_ISR_IT;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
/* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE);
- }
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE);
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1020,11 +1192,10 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t D
to avoid the risk of I2C interrupt handle execution before current
process unlock */
-
/* Enable ERR, TC, STOP, NACK, TXI interrupt */
/* possible to enable all of these */
/* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
- __HAL_I2C_ENABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_TXI );
+ I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
return HAL_OK;
}
@@ -1035,23 +1206,21 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t D
}
/**
- * @brief Receive in master mode an amount of data in no-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
+ * @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 shift at right before call 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)
{
+ uint32_t xfermode = 0;
+
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL) || (Size == 0))
- {
- return HAL_ERROR;
- }
-
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
{
return HAL_BUSY;
@@ -1060,30 +1229,30 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MASTER_BUSY_RX;
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Master_ISR_IT;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
/* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
- }
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1095,7 +1264,7 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De
/* Enable ERR, TC, STOP, NACK, RXI interrupt */
/* possible to enable all of these */
/* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
- __HAL_I2C_ENABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI );
+ I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
return HAL_OK;
}
@@ -1106,9 +1275,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t De
}
/**
- * @brief Transmit in slave mode an amount of data in no-blocking mode with Interrupt
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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
@@ -1117,23 +1286,22 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pD
{
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL) || (Size == 0))
- {
- return HAL_ERROR;
- }
-
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_SLAVE_BUSY_TX;
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
/* Enable Address Acknowledge */
hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
- hi2c->pBuffPtr = pData;
- hi2c->XferSize = Size;
- hi2c->XferCount = Size;
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Slave_ISR_IT;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1145,7 +1313,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pD
/* Enable ERR, TC, STOP, NACK, TXI interrupt */
/* possible to enable all of these */
/* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
- __HAL_I2C_ENABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_TXI );
+ I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
return HAL_OK;
}
@@ -1156,9 +1324,9 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pD
}
/**
- * @brief Receive in slave mode an amount of data in no-blocking mode with Interrupt
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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
@@ -1167,23 +1335,22 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pDa
{
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL) || (Size == 0))
- {
- return HAL_ERROR;
- }
-
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_SLAVE_BUSY_RX;
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
/* Enable Address Acknowledge */
hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
- hi2c->pBuffPtr = pData;
- hi2c->XferSize = Size;
- hi2c->XferCount = Size;
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Slave_ISR_IT;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1195,7 +1362,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pDa
/* Enable ERR, TC, STOP, NACK, RXI interrupt */
/* possible to enable all of these */
/* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
- __HAL_I2C_ENABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI);
+ I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
return HAL_OK;
}
@@ -1206,23 +1373,21 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pDa
}
/**
- * @brief Transmit in master mode an amount of data in no-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
+ * @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 shift at right before call 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)
{
+ uint32_t xfermode = 0;
+
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL) || (Size == 0))
- {
- return HAL_ERROR;
- }
-
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
{
return HAL_BUSY;
@@ -1231,18 +1396,25 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MASTER_BUSY_TX;
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Master_ISR_DMA;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
/* Set the I2C DMA transfer complete callback */
@@ -1251,43 +1423,32 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t
/* Set the DMA error callback */
hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
/* Enable the DMA channel */
HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
/* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE);
- }
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE);
- /* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, I2C_TIMEOUT_TXIS) != HAL_OK)
- {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
+ /* Update XferCount value */
+ hi2c->XferCount -= hi2c->XferSize;
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- return HAL_ERROR;
- }
- else
- {
- return HAL_TIMEOUT;
- }
- }
+ /* 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 and NACK interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
/* Enable DMA Request */
hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
return HAL_OK;
}
else
@@ -1297,23 +1458,21 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t
}
/**
- * @brief Receive in master mode an amount of data in no-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
+ * @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 shift at right before call 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)
{
+ uint32_t xfermode = 0;
+
if(hi2c->State == HAL_I2C_STATE_READY)
{
- if((pData == NULL) || (Size == 0))
- {
- return HAL_ERROR;
- }
-
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
{
return HAL_BUSY;
@@ -1322,53 +1481,69 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MASTER_BUSY_RX;
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_MASTER;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Master_ISR_DMA;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
+ if(hi2c->XferSize > 0)
+ {
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
- /* Set the DMA error callback */
- hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
+ /* Set the DMA error callback */
+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize);
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
- /* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
- }
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize);
- /* Wait until RXNE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, I2C_TIMEOUT_RXNE) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
+ /* Send Slave Address */
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
+ /* Update XferCount value */
+ hi2c->XferCount -= hi2c->XferSize;
- /* Enable DMA Request */
- hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
+ /* Process Unlocked */
+ __HAL_UNLOCK(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 and NACK interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
+
+ /* Enable DMA Request */
+ hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
+ }
+ else
+ {
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+ }
return HAL_OK;
}
else
@@ -1378,9 +1553,9 @@ HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t D
}
/**
- * @brief Transmit in slave mode an amount of data in no-blocking mode with DMA
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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
@@ -1396,12 +1571,16 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *p
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_SLAVE_BUSY_TX;
+ hi2c->State = HAL_I2C_STATE_BUSY_TX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- hi2c->XferSize = Size;
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Slave_ISR_DMA;
/* Set the I2C DMA transfer complete callback */
hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt;
@@ -1409,52 +1588,28 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *p
/* Set the DMA error callback */
hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
/* Enable the DMA channel */
HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
/* Enable Address Acknowledge */
hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
- /* Wait until ADDR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, I2C_TIMEOUT_ADDR) != HAL_OK)
- {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
- return HAL_TIMEOUT;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
-
- /* If 10bits 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, I2C_TIMEOUT_ADDR) != HAL_OK)
- {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
- return HAL_TIMEOUT;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
- }
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Wait until DIR flag is set Transmitter mode */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, I2C_TIMEOUT_BUSY) != HAL_OK)
- {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
- return HAL_TIMEOUT;
- }
+ /* 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, STOP, NACK, ADDR interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
/* Enable DMA Request */
hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
return HAL_OK;
}
else
@@ -1464,9 +1619,9 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *p
}
/**
- * @brief Receive in slave mode an amount of data in no-blocking mode with DMA
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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
@@ -1482,12 +1637,16 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pD
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_SLAVE_BUSY_RX;
+ hi2c->State = HAL_I2C_STATE_BUSY_RX;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- hi2c->pBuffPtr = pData;
- hi2c->XferSize = Size;
- hi2c->XferCount = Size;
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferISR = I2C_Slave_ISR_DMA;
/* Set the I2C DMA transfer complete callback */
hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt;
@@ -1495,37 +1654,28 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pD
/* Set the DMA error callback */
hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
+
/* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, Size);
+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize);
/* Enable Address Acknowledge */
hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
- /* Wait until ADDR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, I2C_TIMEOUT_ADDR) != HAL_OK)
- {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
- return HAL_TIMEOUT;
- }
-
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Wait until DIR flag is set Receiver mode */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, I2C_TIMEOUT_DIR) != HAL_OK)
- {
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
- return HAL_TIMEOUT;
- }
+ /* 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, STOP, NACK, ADDR interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
/* Enable DMA Request */
hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
return HAL_OK;
}
else
@@ -1535,8 +1685,8 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pD
}
/**
* @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 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
@@ -1547,7 +1697,7 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pD
*/
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 Sizetmp = 0;
+ uint32_t tickstart = 0;
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
@@ -1559,19 +1709,28 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress
return HAL_ERROR;
}
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
- {
- return HAL_BUSY;
- }
-
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MEM_BUSY_TX;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ 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->XferISR = NULL;
+
/* Send Slave Address and Memory Address */
- if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)
+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -1587,23 +1746,22 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress
}
}
- /* Set NBYTES to write and reload if size > 255 */
- /* Size > 255, need to set RELOAD bit */
- if(Size > 255)
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- Sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- Sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
}
do
{
/* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -1615,37 +1773,36 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress
}
}
- /* Write data to DR */
- hi2c->Instance->TXDR = (*pData++);
- Sizetmp--;
- Size--;
+ /* Write data to TXDR */
+ hi2c->Instance->TXDR = (*hi2c->pBuffPtr++);
+ hi2c->XferCount--;
+ hi2c->XferSize--;
- if((Sizetmp == 0)&&(Size!=0))
+ if((hi2c->XferSize == 0) && (hi2c->XferCount!=0))
{
/* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
-
- if(Size > 255)
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- Sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- Sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
}
}
- }while(Size > 0);
+ }while(hi2c->XferCount > 0);
/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
/* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -1664,6 +1821,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress
I2C_RESET_CR2(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1678,8 +1836,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress
/**
* @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 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
@@ -1690,7 +1848,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress
*/
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 Sizetmp = 0;
+ uint32_t tickstart = 0;
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
@@ -1702,19 +1860,28 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
return HAL_ERROR;
}
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
- {
- return HAL_BUSY;
- }
-
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
+
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ 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->XferISR = NULL;
+
/* Send Slave Address and Memory Address */
- if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)
+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -1731,59 +1898,55 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
}
/* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- /* Size > 255, need to set RELOAD bit */
- if(Size > 255)
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
- Sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
- Sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
}
do
{
/* Wait until RXNE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
/* Read data from RXDR */
- (*pData++) = hi2c->Instance->RXDR;
-
- /* Decrement the Size counter */
- Sizetmp--;
- Size--;
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
+ hi2c->XferSize--;
+ hi2c->XferCount--;
- if((Sizetmp == 0)&&(Size!=0))
+ if((hi2c->XferSize == 0) && (hi2c->XferCount != 0))
{
/* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
- if(Size > 255)
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- Sizetmp = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- Sizetmp = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
}
}
-
- }while(Size > 0);
+ }while(hi2c->XferCount > 0);
/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
/* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -1802,6 +1965,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
I2C_RESET_CR2(hi2c);
hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1814,9 +1978,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
}
}
/**
- * @brief Write an amount of data in no-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.
+ * @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
@@ -1826,6 +1990,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
*/
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)
{
+ uint32_t tickstart = 0;
+ uint32_t xfermode = 0;
+
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
@@ -1844,22 +2011,32 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MEM_BUSY_TX;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ 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->XferISR = I2C_Master_ISR_IT;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
/* Send Slave Address and Memory Address */
- if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK)
+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -1875,16 +2052,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
}
}
- /* Set NBYTES to write and reload if size > 255 */
- /* Size > 255, need to set RELOAD bit */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- }
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ I2C_TransferConfig(hi2c,DevAddress, hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1896,7 +2065,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
/* Enable ERR, TC, STOP, NACK, TXI interrupt */
/* possible to enable all of these */
/* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
- __HAL_I2C_ENABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_TXI );
+ I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
return HAL_OK;
}
@@ -1907,9 +2076,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
}
/**
- * @brief Read an amount of data in no-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.
+ * @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
@@ -1919,6 +2088,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
*/
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)
{
+ uint32_t tickstart = 0;
+ uint32_t xfermode = 0;
+
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
@@ -1937,21 +2109,32 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ 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->XferISR = I2C_Master_ISR_IT;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
/* Send Slave Address and Memory Address */
- if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK)
+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -1967,16 +2150,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre
}
}
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- /* Size > 255, need to set RELOAD bit */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
- }
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -1988,7 +2163,7 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre
/* Enable ERR, TC, STOP, NACK, RXI interrupt */
/* possible to enable all of these */
/* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
- __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_RXI );
+ I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
return HAL_OK;
}
@@ -1998,9 +2173,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre
}
}
/**
- * @brief Write an amount of data in no-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.
+ * @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
@@ -2010,6 +2185,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddre
*/
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)
{
+ uint32_t tickstart = 0;
+ uint32_t xfermode = 0;
+
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
@@ -2028,31 +2206,32 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MEM_BUSY_TX;
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ 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->XferISR = I2C_Master_ISR_DMA;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmatx->XferCpltCallback = I2C_DMAMemTransmitCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
-
/* Send Slave Address and Memory Address */
- if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK)
+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -2068,36 +2247,38 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
}
}
- /* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- }
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
- /* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, I2C_TIMEOUT_TXIS) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- return HAL_ERROR;
- }
- else
- {
- return HAL_TIMEOUT;
- }
- }
+ /* Set the DMA error callback */
+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
- /* Enable DMA Request */
- hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmatx->XferHalfCpltCallback = NULL;
+ hi2c->hdmatx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
+
+ /* Send Slave Address */
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
+
+ /* Update XferCount value */
+ hi2c->XferCount -= hi2c->XferSize;
/* 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 and NACK interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
+
+ /* Enable DMA Request */
+ hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
+
return HAL_OK;
}
else
@@ -2107,9 +2288,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
}
/**
- * @brief Reads an amount of data in no-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.
+ * @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
@@ -2119,6 +2300,9 @@ HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
*/
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 = 0;
+ uint32_t xfermode = 0;
+
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
@@ -2137,30 +2321,32 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
/* Process Locked */
__HAL_LOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX;
+ /* Init tickstart for timeout management*/
+ tickstart = HAL_GetTick();
- hi2c->pBuffPtr = pData;
- hi2c->XferCount = Size;
- if(Size > 255)
+ 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->XferISR = I2C_Master_ISR_DMA;
+
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
else
{
- hi2c->XferSize = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
}
- /* Set the I2C DMA transfer complete callback */
- hi2c->hdmarx->XferCpltCallback = I2C_DMAMemReceiveCplt;
-
- /* Set the DMA error callback */
- hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize);
-
/* Send Slave Address and Memory Address */
- if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK)
+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -2176,28 +2362,37 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
}
}
- /* Set NBYTES to write and reload if size > 255 and generate RESTART */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
- }
+ /* Set the I2C DMA transfer complete callback */
+ hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
- /* Wait until RXNE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, I2C_TIMEOUT_RXNE) != HAL_OK)
- {
- return HAL_TIMEOUT;
- }
+ /* Set the DMA error callback */
+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
- /* Enable DMA Request */
- hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
+ /* Set the unused DMA callbacks to NULL */
+ hi2c->hdmarx->XferHalfCpltCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize);
+
+ /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
+ I2C_TransferConfig(hi2c,DevAddress, hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
+
+ /* Update XferCount value */
+ hi2c->XferCount -= hi2c->XferSize;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
+ /* Enable DMA Request */
+ hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
+
+ /* 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 and NACK interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
+
return HAL_OK;
}
else
@@ -2209,8 +2404,8 @@ HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddr
/**
* @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 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
@@ -2262,7 +2457,7 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET)
{
/* Wait until STOPF flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
@@ -2281,7 +2476,7 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
else
{
/* Wait until STOPF flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
@@ -2300,7 +2495,7 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
hi2c->Instance->CR2 |= I2C_CR2_STOP;
/* Wait until STOPF flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
@@ -2322,70 +2517,424 @@ HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAdd
return HAL_BUSY;
}
}
+
/**
- * @}
+ * @brief Sequential transmit in master I2C mode an amount of data in non-blocking mode with Interrupt.
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress: Target device address. The device 7 bits address value
+ * in datasheet must be shift at right before call 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
+ * @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)
+{
+ uint32_t xfermode = 0;
+ uint32_t xferrequest = I2C_GENERATE_START_WRITE;
-/** @defgroup IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
- * @{
- */
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if(hi2c->State == HAL_I2C_STATE_READY)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ 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->XferISR = I2C_Master_ISR_IT;
+
+ /* If size > MAX_NBYTE_SIZE, use reload mode */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
+ {
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
+ }
+ else
+ {
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = hi2c->XferOptions;
+ }
+
+ /* If transfer direction not change, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX)
+ {
+ xferrequest = I2C_NO_STARTSTOP;
+ }
+
+ /* Send Slave Address and set NBYTES to write */
+ I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, xfermode, xferrequest);
+
+ /* 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 */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
+
+ return HAL_OK;
+ }
+ 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
+ * @brief Sequential receive in master I2C mode an amount of data in non-blocking mode with Interrupt
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress: Target device address. The device 7 bits address value
+ * in datasheet must be shift at right before call 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
+ * @retval HAL status
*/
-void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
{
- /* I2C in mode Transmitter ---------------------------------------------------*/
- if (((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI | I2C_IT_ADDRI)) == SET))
+ uint32_t xfermode = 0;
+ uint32_t xferrequest = I2C_GENERATE_START_READ;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
+
+ if(hi2c->State == HAL_I2C_STATE_READY)
{
- /* Slave mode selected */
- if (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_TX)
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ 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->XferISR = I2C_Master_ISR_IT;
+
+ /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_SlaveTransmit_ISR(hi2c);
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
}
- }
+ else
+ {
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = hi2c->XferOptions;
+ }
- if (((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI)) == SET))
- {
- /* Master mode selected */
- if ((hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MEM_BUSY_TX))
+ /* If transfer direction not change, do not generate Restart Condition */
+ /* Mean Previous state is same as current state */
+ if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX)
{
- I2C_MasterTransmit_ISR(hi2c);
+ xferrequest = I2C_NO_STARTSTOP;
}
+
+ /* Send Slave Address and set NBYTES to read */
+ I2C_TransferConfig(hi2c,DevAddress, hi2c->XferSize, xfermode, xferrequest);
+
+ /* 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 */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
+
+ return HAL_OK;
}
+ else
+ {
+ return HAL_BUSY;
+ }
+}
- /* I2C in mode Receiver ----------------------------------------------------*/
- if (((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_RXI | I2C_IT_ADDRI)) == SET))
+/**
+ * @brief Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @param XferOptions: Options of Transfer, value of @ref I2C_XFEROPTIONS
+ * @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)
{
- /* Slave mode selected */
- if (hi2c->State == HAL_I2C_STATE_SLAVE_BUSY_RX)
+ if((pData == NULL) || (Size == 0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Enable Address Acknowledge */
+ hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+ hi2c->XferISR = I2C_Slave_ISR_IT;
+
+ if(I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
{
- I2C_SlaveReceive_ISR(hi2c);
+ /* Clear ADDR flag after prepare the transfer parameters */
+ /* This action will generate an acknowledge to the Master */
+ __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
}
+
+ /* 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 */
+ /* REnable ADDR interrupt */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
+
+ return HAL_OK;
}
- if (((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) || (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)) && (__HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_RXI)) == SET))
+ else
+ {
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
+ * @note This interface allow to manage repeated start condition when a direction change during transfer
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @param XferOptions: Options of Transfer, value of @ref I2C_XFEROPTIONS
+ * @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)
{
- /* Master mode selected */
- if ((hi2c->State == HAL_I2C_STATE_MASTER_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_MEM_BUSY_RX))
+ if((pData == NULL) || (Size == 0))
{
- I2C_MasterReceive_ISR(hi2c);
+ return HAL_ERROR;
}
+
+ /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
+
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN;
+ hi2c->Mode = HAL_I2C_MODE_SLAVE;
+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
+
+ /* Enable Address Acknowledge */
+ hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
+
+ /* Prepare transfer parameters */
+ hi2c->pBuffPtr = pData;
+ hi2c->XferCount = Size;
+ hi2c->XferSize = hi2c->XferCount;
+ hi2c->XferOptions = XferOptions;
+ hi2c->XferISR = I2C_Slave_ISR_IT;
+
+ if(I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT)
+ {
+ /* Clear ADDR flag after prepare the transfer parameters */
+ /* This action will generate an acknowledge to the Master */
+ __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
+ }
+
+ /* 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 */
+ /* REnable ADDR interrupt */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @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;
+ hi2c->XferISR = I2C_Slave_ISR_IT;
+
+ /* Enable the Address Match interrupt */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
+
+ 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;
+ hi2c->XferISR = NULL;
+
+ /* Disable the Address Match interrupt */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Abort a master I2C IT or DMA process communication with Interrupt.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param DevAddress Target device address: The device 7 bits address value
+ * in datasheet must be shift at right before call interface
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
+{
+ if(hi2c->Mode == HAL_I2C_MODE_MASTER)
+ {
+ /* Process Locked */
+ __HAL_LOCK(hi2c);
+
+ /* Disable Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
+ I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
+
+ /* Set State at HAL_I2C_STATE_ABORT */
+ hi2c->State = HAL_I2C_STATE_ABORT;
+
+ /* Set NBYTES to 1 to generate a dummy read on I2C peripheral */
+ /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
+ I2C_TransferConfig(hi2c, 0, 1, I2C_AUTOEND_MODE, I2C_GENERATE_STOP);
+
+ /* 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 */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
+
+ 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;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
+ * @{
+ */
+
+/**
+ * @brief This function handles I2C event interrupt request.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
+{
+ /* Get current IT Flags and IT sources value */
+ uint32_t itflags = READ_REG(hi2c->Instance->ISR);
+ uint32_t itsources = READ_REG(hi2c->Instance->CR1);
+
+ /* I2C events treatment -------------------------------------*/
+ if(hi2c->XferISR != NULL)
+ {
+ hi2c->XferISR(hi2c, itflags, itsources);
}
}
/**
* @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.
+ * @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 itflags = READ_REG(hi2c->Instance->ISR);
+ uint32_t itsources = READ_REG(hi2c->Instance->CR1);
+
/* I2C Bus error interrupt occurred ------------------------------------*/
- if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BERR) == SET) && (__HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ERRI) == SET))
+ if(((itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERRI) != RESET))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_BERR;
@@ -2394,7 +2943,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
}
/* I2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
- if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_OVR) == SET) && (__HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ERRI) == SET))
+ if(((itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERRI) != RESET))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_OVR;
@@ -2403,7 +2952,7 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
}
/* I2C Arbitration Loss error interrupt occurred -------------------------------------*/
- if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ARLO) == SET) && (__HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ERRI) == SET))
+ if(((itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERRI) != RESET))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO;
@@ -2412,114 +2961,185 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
}
/* Call the Error Callback in case of Error detected */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ if((hi2c->ErrorCode & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) != HAL_I2C_ERROR_NONE)
{
- hi2c->State = HAL_I2C_STATE_READY;
-
- HAL_I2C_ErrorCallback(hi2c);
+ I2C_ITError(hi2c, hi2c->ErrorCode);
}
}
/**
- * @brief Master Tx Transfer completed callbacks.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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)
+__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_TxCpltCallback could be implemented in the user file
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MasterTxCpltCallback could be implemented in the user file
*/
}
/**
- * @brief Master Rx Transfer completed callbacks.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_TxCpltCallback could be implemented in the user file
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MasterRxCpltCallback could be implemented in the user file
*/
}
-/** @brief Slave Tx Transfer completed callbacks.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+/** @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)
+__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_TxCpltCallback could be implemented in the user file
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file
*/
}
/**
- * @brief Slave Rx Transfer completed callbacks.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_TxCpltCallback could be implemented in the user file
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file
*/
}
/**
- * @brief Memory Tx Transfer completed callbacks.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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
+ * @param AddrMatchCode: Address Match Code
* @retval None
*/
- __weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
+__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_TxCpltCallback could be implemented in the user file
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+ UNUSED(TransferDirection);
+ UNUSED(AddrMatchCode);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_AddrCallback() could be implemented in the user file
*/
}
/**
- * @brief Memory Rx Transfer completed callbacks.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @brief Listen Complete callback.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_ListenCpltCallback() could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Memory Tx Transfer completed callback.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MemTxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Memory Rx Transfer completed callback.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
* @retval None
*/
__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_I2C_TxCpltCallback could be implemented in the user file
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_MemRxCpltCallback could be implemented in the user file
*/
}
/**
- * @brief I2C error callbacks.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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)
+__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
- /* NOTE : This function Should not be modified, when the callback is needed,
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
the HAL_I2C_ErrorCallback could be implemented in the user file
*/
}
/**
+ * @brief I2C abort callback.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @retval None
+ */
+__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2c);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2C_AbortCpltCallback could be implemented in the user file
+ */
+}
+
+/**
* @}
*/
-/** @defgroup I2C_Exported_Functions_Group3 Peripheral State and Errors functions
- * @brief Peripheral State and Errors functions
+/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
+ * @brief Peripheral State, Mode and Error functions
*
@verbatim
===============================================================================
- ##### Peripheral State and Errors functions #####
+ ##### Peripheral State, Mode and Error functions #####
===============================================================================
[..]
This subsection permit to get in run-time the status of the peripheral
@@ -2530,19 +3150,31 @@ __weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
*/
/**
- * @brief Returns the I2C state.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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 error code
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
+ * @brief Returns the I2C Master, Slave, Memory or no mode.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for I2C module
+ * @retval HAL mode
+ */
+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c)
+{
+ return hi2c->Mode;
+}
+
+/**
+* @brief Return the I2C error code.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
* the configuration information for the specified I2C.
* @retval I2C Error Code
*/
@@ -2564,104 +3196,109 @@ uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c)
*/
/**
- * @brief Handle Interrupt Flags Master Transmit Mode
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param ITFlags: Interrupt flags to handle.
+ * @param ITSources: Interrupt sources enabled.
* @retval HAL status
*/
-static HAL_StatusTypeDef I2C_MasterTransmit_ISR(I2C_HandleTypeDef *hi2c)
+static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources)
{
- uint16_t DevAddress;
+ uint16_t devaddress = 0;
/* Process Locked */
__HAL_LOCK(hi2c);
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == SET)
+ if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET))
+ {
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ /* Set corresponding Error Code */
+ /* No need to generate STOP, it is automatically done */
+ /* Error callback will be send during stop flag treatment */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+
+ /* Flush TX register */
+ I2C_Flush_TXDR(hi2c);
+ }
+ else if(((ITFlags & I2C_FLAG_RXNE) != RESET) && ((ITSources & I2C_IT_RXI) != RESET))
+ {
+ /* Read data from RXDR */
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+ }
+ else if(((ITFlags & I2C_FLAG_TXIS) != RESET) && ((ITSources & I2C_IT_TXI) != RESET))
{
/* Write data to TXDR */
hi2c->Instance->TXDR = (*hi2c->pBuffPtr++);
hi2c->XferSize--;
hi2c->XferCount--;
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET)
+ else if(((ITFlags & I2C_FLAG_TCR) != RESET) && ((ITSources & I2C_IT_TCI) != RESET))
{
- if((hi2c->XferSize == 0)&&(hi2c->XferCount!=0))
+ if((hi2c->XferSize == 0) && (hi2c->XferCount != 0))
{
- DevAddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
+ devaddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
- if(hi2c->XferCount > 255)
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- hi2c->XferSize = 255;
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ I2C_TransferConfig(hi2c, devaddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferCount, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
hi2c->XferSize = hi2c->XferCount;
+ if(hi2c->XferOptions != I2C_NO_OPTION_FRAME)
+ {
+ I2C_TransferConfig(hi2c, devaddress, hi2c->XferSize, hi2c->XferOptions, I2C_NO_STARTSTOP);
+ }
+ else
+ {
+ I2C_TransferConfig(hi2c, devaddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
+ }
}
}
else
{
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Wrong size Status regarding TCR flag event */
- hi2c->ErrorCode |= HAL_I2C_ERROR_SIZE;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Call TxCpltCallback() if no stop mode is set */
+ if((I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)&&(hi2c->Mode == HAL_I2C_MODE_MASTER))
+ {
+ /* Call I2C Master Sequential complete process */
+ I2C_ITMasterSequentialCplt(hi2c);
+ }
+ else
+ {
+ /* Wrong size Status regarding TCR flag event */
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
+ }
}
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET)
+ else if(((ITFlags & I2C_FLAG_TC) != RESET) && ((ITSources & I2C_IT_TCI) != RESET))
{
if(hi2c->XferCount == 0)
{
- /* Generate Stop */
- hi2c->Instance->CR2 |= I2C_CR2_STOP;
+ if((I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)&&(hi2c->Mode == HAL_I2C_MODE_MASTER))
+ {
+ /* Call I2C Master Sequential complete process */
+ I2C_ITMasterSequentialCplt(hi2c);
+ }
}
else
{
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- /* Wrong size Status regarding TCR flag event */
- hi2c->ErrorCode |= HAL_I2C_ERROR_SIZE;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Wrong size Status regarding TC flag event */
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
}
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
- {
- /* Disable ERR, TC, STOP, NACK, TXI interrupt */
- __HAL_I2C_DISABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_TXI );
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- if(hi2c->State == HAL_I2C_STATE_MEM_BUSY_TX)
- {
- HAL_I2C_MemTxCpltCallback(hi2c);
- }
- else
- {
- HAL_I2C_MasterTxCpltCallback(hi2c);
- }
- }
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
+ if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET))
{
- /* Clear NACK Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Call I2C Master complete process */
+ I2C_ITMasterCplt(hi2c, ITFlags);
}
/* Process Unlocked */
@@ -2671,192 +3308,200 @@ static HAL_StatusTypeDef I2C_MasterTransmit_ISR(I2C_HandleTypeDef *hi2c)
}
/**
- * @brief Handle Interrupt Flags Master Receive Mode
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param ITFlags: Interrupt flags to handle.
+ * @param ITSources: Interrupt sources enabled.
* @retval HAL status
*/
-static HAL_StatusTypeDef I2C_MasterReceive_ISR(I2C_HandleTypeDef *hi2c)
+static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources)
{
- uint16_t DevAddress;
-
- /* Process Locked */
+ /* Process locked */
__HAL_LOCK(hi2c);
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+ if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET))
{
- /* Read data from RXDR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TCR) == SET)
- {
- if((hi2c->XferSize == 0)&&(hi2c->XferCount!=0))
+ /* Check that I2C transfer finished */
+ /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
+ /* Mean XferCount == 0*/
+ /* So clear Flag NACKF only */
+ if(hi2c->XferCount == 0)
{
- DevAddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
-
- if(hi2c->XferCount > 255)
+ if(((hi2c->XferOptions == I2C_FIRST_AND_LAST_FRAME) || (hi2c->XferOptions == I2C_LAST_FRAME)) && \
+ (hi2c->State == HAL_I2C_STATE_LISTEN))
{
- I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- hi2c->XferSize = 255;
+ /* Call I2C Listen complete process */
+ I2C_ITListenCplt(hi2c, ITFlags);
+ }
+ else if((hi2c->XferOptions != I2C_NO_OPTION_FRAME) && (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN))
+ {
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+
+ /* Flush TX register */
+ I2C_Flush_TXDR(hi2c);
+
+ /* Last Byte is Transmitted */
+ /* Call I2C Slave Sequential complete process */
+ I2C_ITSlaveSequentialCplt(hi2c);
}
else
{
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferCount, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- hi2c->XferSize = hi2c->XferCount;
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
}
}
else
{
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
+ /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
- /* Wrong size Status regarding TCR flag event */
- hi2c->ErrorCode |= HAL_I2C_ERROR_SIZE;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
}
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TC) == SET)
+ else if(((ITFlags & I2C_FLAG_RXNE) != RESET) && ((ITSources & I2C_IT_RXI) != RESET))
{
- if(hi2c->XferCount == 0)
+ if(hi2c->XferCount > 0)
{
- /* Generate Stop */
- hi2c->Instance->CR2 |= I2C_CR2_STOP;
+ /* Read data from RXDR */
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
+ hi2c->XferSize--;
+ hi2c->XferCount--;
}
- else
- {
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- /* Wrong size Status regarding TCR flag event */
- hi2c->ErrorCode |= HAL_I2C_ERROR_SIZE;
- HAL_I2C_ErrorCallback(hi2c);
- }
+ if((hi2c->XferCount == 0) && \
+ (hi2c->XferOptions != I2C_NO_OPTION_FRAME))
+ {
+ /* Call I2C Slave Sequential complete process */
+ I2C_ITSlaveSequentialCplt(hi2c);
+ }
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
+ else if(((ITFlags & I2C_FLAG_ADDR) != RESET) && ((ITSources & I2C_IT_ADDRI) != RESET))
{
- /* Disable ERR, TC, STOP, NACK, TXI interrupt */
- __HAL_I2C_DISABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_RXI );
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- if(hi2c->State == HAL_I2C_STATE_MEM_BUSY_RX)
+ I2C_ITAddrCplt(hi2c, ITFlags);
+ }
+ else if(((ITFlags & I2C_FLAG_TXIS) != RESET) && ((ITSources & I2C_IT_TXI) != RESET))
+ {
+ /* Write data to TXDR only if XferCount not reach "0" */
+ /* A TXIS flag can be set, during STOP treatment */
+ /* Check if all Datas have already been sent */
+ /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
+ if(hi2c->XferCount > 0)
{
- HAL_I2C_MemRxCpltCallback(hi2c);
+ /* Write data to TXDR */
+ hi2c->Instance->TXDR = (*hi2c->pBuffPtr++);
+ hi2c->XferCount--;
+ hi2c->XferSize--;
}
else
{
- HAL_I2C_MasterRxCpltCallback(hi2c);
+ if((hi2c->XferOptions == I2C_NEXT_FRAME) || (hi2c->XferOptions == I2C_FIRST_FRAME))
+ {
+ /* Last Byte is Transmitted */
+ /* Call I2C Slave Sequential complete process */
+ I2C_ITSlaveSequentialCplt(hi2c);
+ }
}
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
- {
- /* Clear NACK Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Check if STOPF is set */
+ if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET))
+ {
+ /* Call I2C Slave complete process */
+ I2C_ITSlaveCplt(hi2c, ITFlags);
}
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
-
}
/**
- * @brief Handle Interrupt Flags Slave Transmit Mode
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param ITFlags: Interrupt flags to handle.
+ * @param ITSources: Interrupt sources enabled.
* @retval HAL status
*/
-static HAL_StatusTypeDef I2C_SlaveTransmit_ISR(I2C_HandleTypeDef *hi2c)
+static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources)
{
- /* Process locked */
+ uint16_t devaddress = 0;
+ uint32_t xfermode = 0;
+
+ /* Process Locked */
__HAL_LOCK(hi2c);
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) != RESET)
+ if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET))
{
- /* Check that I2C transfer finished */
- /* if yes, normal usecase, a NACK is sent by the MASTER when Transfer is finished */
- /* Mean XferCount == 0*/
- /* So clear Flag NACKF only */
- if(hi2c->XferCount == 0)
- {
- /* Clear NACK Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- }
- else
- {
- /* if no, error usecase, a Non-Acknowledge of last Data is generated by the MASTER*/
- /* Clear NACK Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
- /* Set ErrorCode corresponding to a Non-Acknowledge */
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+ /* Set corresponding Error Code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
+ /* No need to generate STOP, it is automatically done */
+ /* But enable STOP interrupt, to treat it */
+ /* Error callback will be send during stop flag treatment */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
- /* Call the Error callback to prevent upper layer */
- HAL_I2C_ErrorCallback(hi2c);
- }
+ /* Flush TX register */
+ I2C_Flush_TXDR(hi2c);
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)
+ else if(((ITFlags & I2C_FLAG_TCR) != RESET) && ((ITSources & I2C_IT_TCI) != RESET))
{
- /* Clear ADDR flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
- }
- /* Check first if STOPF is set */
- /* to prevent a Write Data in TX buffer */
- /* which is stuck in TXDR until next */
- /* communication with Master */
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
- {
- /* Disable ERRI, TCI, STOPI, NACKI, ADDRI, RXI, TXI interrupt */
- __HAL_I2C_DISABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI );
+ /* Disable TC interrupt */
+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_TCI);
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
+ if(hi2c->XferCount != 0)
+ {
+ /* Recover Slave address */
+ devaddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ /* Prepare the new XferSize to transfer */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
+ {
+ hi2c->XferSize = MAX_NBYTE_SIZE;
+ xfermode = I2C_RELOAD_MODE;
+ }
+ else
+ {
+ hi2c->XferSize = hi2c->XferCount;
+ xfermode = I2C_AUTOEND_MODE;
+ }
- hi2c->State = HAL_I2C_STATE_READY;
+ /* Set the new XferSize in Nbytes register */
+ I2C_TransferConfig(hi2c, devaddress, hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
+ /* Update XferCount value */
+ hi2c->XferCount -= hi2c->XferSize;
- HAL_I2C_SlaveTxCpltCallback(hi2c);
- }
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == SET)
- {
- /* Write data to TXDR only if XferCount not reach "0" */
- /* A TXIS flag can be set, during STOP treatment */
- if(hi2c->XferCount > 0)
+ /* Enable DMA Request */
+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX)
+ {
+ hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
+ }
+ else
+ {
+ hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
+ }
+ }
+ else
{
- /* Write data to TXDR */
- hi2c->Instance->TXDR = (*hi2c->pBuffPtr++);
- hi2c->XferCount--;
+ /* Wrong size Status regarding TCR flag event */
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
}
}
+ else if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET))
+ {
+ /* Call I2C Master complete process */
+ I2C_ITMasterCplt(hi2c, ITFlags);
+ }
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -2865,56 +3510,48 @@ static HAL_StatusTypeDef I2C_SlaveTransmit_ISR(I2C_HandleTypeDef *hi2c)
}
/**
- * @brief Handle Interrupt Flags Slave Receive Mode
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param ITFlags: Interrupt flags to handle.
+ * @param ITSources: Interrupt sources enabled.
* @retval HAL status
*/
-static HAL_StatusTypeDef I2C_SlaveReceive_ISR(I2C_HandleTypeDef *hi2c)
+static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources)
{
- /* Process Locked */
+ /* Process locked */
__HAL_LOCK(hi2c);
- if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) != RESET)
+ if(((ITFlags & I2C_FLAG_AF) != RESET) && ((ITSources & I2C_IT_NACKI) != RESET))
{
- /* Clear NACK Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
+ /* Check that I2C transfer finished */
+ /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
+ /* Mean XferCount == 0 */
+ /* So clear Flag NACKF only */
+ if(I2C_GET_DMA_REMAIN_DATA(hi2c) == 0)
+ {
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
+ }
+ else
+ {
+ /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+ }
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET)
+ else if(((ITFlags & I2C_FLAG_ADDR) != RESET) && ((ITSources & I2C_IT_ADDRI) != RESET))
{
/* Clear ADDR flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
}
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
+ else if(((ITFlags & I2C_FLAG_STOPF) != RESET) && ((ITSources & I2C_IT_STOPI) != RESET))
{
- /* Read data from RXDR */
- (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
- hi2c->XferSize--;
- hi2c->XferCount--;
- }
- else if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
- {
- /* Disable ERRI, TCI, STOPI, NACKI, ADDRI, RXI, TXI interrupt */
- __HAL_I2C_DISABLE_IT(hi2c,I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_RXI );
-
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
-
- HAL_I2C_SlaveRxCpltCallback(hi2c);
+ /* Call I2C Slave complete process */
+ I2C_ITSlaveCplt(hi2c, ITFlags);
}
/* Process Unlocked */
@@ -2925,20 +3562,21 @@ static HAL_StatusTypeDef I2C_SlaveReceive_ISR(I2C_HandleTypeDef *hi2c)
/**
* @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 the specified I2C.
+ * @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 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)
+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
{
I2C_TransferConfig(hi2c,DevAddress,MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
/* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -2963,7 +3601,7 @@ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_
hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
/* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -2980,7 +3618,7 @@ static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_
}
/* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
@@ -2990,20 +3628,21 @@ 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 the specified I2C.
+ * @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 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)
+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
{
I2C_TransferConfig(hi2c,DevAddress,MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
/* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -3028,7 +3667,7 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t
hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
/* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
+ if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
@@ -3045,7 +3684,7 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t
}
/* Wait until TC flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout) != HAL_OK)
+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
{
return HAL_TIMEOUT;
}
@@ -3054,748 +3693,642 @@ static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t
}
/**
- * @brief DMA I2C master transmit process complete callback.
- * @param hdma: DMA handle
+ * @brief I2C Address complete process callback.
+ * @param hi2c: I2C handle.
+ * @param ITFlags: Interrupt flags to handle.
* @retval None
*/
-static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
+static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
{
- uint16_t DevAddress;
- I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+ uint8_t transferdirection = 0;
+ uint16_t slaveaddrcode = 0;
+ uint16_t ownadd1code = 0;
+ uint16_t ownadd2code = 0;
- /* Check if last DMA request was done with RELOAD */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
+ /* In case of Listen state, need to inform upper layer of address match code event */
+ if((hi2c->State & HAL_I2C_STATE_LISTEN) == HAL_I2C_STATE_LISTEN)
{
- /* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, I2C_TIMEOUT_TCR) != HAL_OK)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
-
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
+ transferdirection = I2C_GET_DIR(hi2c);
+ slaveaddrcode = I2C_GET_ADDR_MATCH(hi2c);
+ ownadd1code = I2C_GET_OWN_ADDRESS1(hi2c);
+ ownadd2code = I2C_GET_OWN_ADDRESS2(hi2c);
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ /* If 10bits addressing mode is selected */
+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
{
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
+ if((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK))
{
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
+ slaveaddrcode = ownadd1code;
+ hi2c->AddrEventCount++;
+ if(hi2c->AddrEventCount == 2)
{
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ /* Reset Address Event counter */
+ hi2c->AddrEventCount = 0;
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
- hi2c->XferCount = 0;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_READY;
- HAL_I2C_ErrorCallback(hi2c);
- }
- else
- {
- hi2c->pBuffPtr += hi2c->XferSize;
- hi2c->XferCount -= hi2c->XferSize;
- if(hi2c->XferCount > 255)
- {
- hi2c->XferSize = 255;
+ /* Call Slave Addr callback */
+ HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
+ }
}
else
{
- hi2c->XferSize = hi2c->XferCount;
- }
+ slaveaddrcode = ownadd2code;
- DevAddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
+ /* Disable ADDR Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
+ /* Call Slave Addr callback */
+ HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
}
+ }
+ /* else 7 bits addressing mode is selected */
+ else
+ {
+ /* Disable ADDR Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
- /* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, I2C_TIMEOUT_TXIS) != HAL_OK)
- {
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
-
- hi2c->XferCount = 0;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- hi2c->State = HAL_I2C_STATE_READY;
- HAL_I2C_ErrorCallback(hi2c);
- }
- else
- {
- /* Enable DMA Request */
- hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
- }
+ /* Call Slave Addr callback */
+ HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
}
}
+ /* Else clear address flag only */
else
{
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
-
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
-
- hi2c->XferCount = 0;
-
- hi2c->State = HAL_I2C_STATE_READY;
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
- {
- HAL_I2C_ErrorCallback(hi2c);
- }
- else
- {
- HAL_I2C_MasterTxCpltCallback(hi2c);
- }
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
}
}
/**
- * @brief DMA I2C slave transmit process complete callback.
- * @param hdma: DMA handle
+ * @brief I2C Master sequential complete process.
+ * @param hi2c: I2C handle.
* @retval None
*/
-static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
+static void I2C_ITMasterSequentialCplt(I2C_HandleTypeDef *hi2c)
{
- I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
-
- /* Wait until STOP flag is set */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- /* Normal Use case, a AF is generated by master */
- /* to inform slave the end of transfer */
- hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
-
- /* Clear STOP flag */
- __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_STOPF);
+ /* Reset I2C handle mode */
+ hi2c->Mode = HAL_I2C_MODE_NONE;
- /* Wait until BUSY flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY) != HAL_OK)
+ /* No Generate Stop, to permit restart mode */
+ /* The stop will be done at the end of transfer, when I2C_AUTOEND_MODE enable */
+ if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
{
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
+ hi2c->XferISR = NULL;
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
+ /* Disable Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
- hi2c->XferCount = 0;
-
- hi2c->State = HAL_I2C_STATE_READY;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
- {
- HAL_I2C_ErrorCallback(hi2c);
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ HAL_I2C_MasterTxCpltCallback(hi2c);
}
+ /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
else
{
- HAL_I2C_SlaveTxCpltCallback(hi2c);
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
+ hi2c->XferISR = NULL;
+
+ /* Disable Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ HAL_I2C_MasterRxCpltCallback(hi2c);
}
}
/**
- * @brief DMA I2C master receive process complete callback
- * @param hdma: DMA handle
+ * @brief I2C Slave sequential complete process.
+ * @param hi2c: I2C handle.
* @retval None
*/
-static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
+static void I2C_ITSlaveSequentialCplt(I2C_HandleTypeDef *hi2c)
{
- I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
- uint16_t DevAddress;
+ /* Reset I2C handle mode */
+ hi2c->Mode = HAL_I2C_MODE_NONE;
- /* Check if last DMA request was done with RELOAD */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
+ if(hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
{
- /* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, I2C_TIMEOUT_TCR) != HAL_OK)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
+ /* Remove HAL_I2C_STATE_SLAVE_BUSY_TX, keep only HAL_I2C_STATE_LISTEN */
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
+ /* Disable Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
- {
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ /* Call the Tx complete callback to inform upper layer of the end of transmit process */
+ HAL_I2C_SlaveTxCpltCallback(hi2c);
+ }
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+ else if(hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
+ {
+ /* Remove HAL_I2C_STATE_SLAVE_BUSY_RX, keep only HAL_I2C_STATE_LISTEN */
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
- hi2c->XferCount = 0;
+ /* Disable Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
- hi2c->State = HAL_I2C_STATE_READY;
- HAL_I2C_ErrorCallback(hi2c);
- }
- else
- {
- hi2c->pBuffPtr += hi2c->XferSize;
- hi2c->XferCount -= hi2c->XferSize;
- if(hi2c->XferCount > 255)
- {
- hi2c->XferSize = 255;
- }
- else
- {
- hi2c->XferSize = hi2c->XferCount;
- }
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- DevAddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
+ /* Call the Rx complete callback to inform upper layer of the end of receive process */
+ HAL_I2C_SlaveRxCpltCallback(hi2c);
+ }
+}
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+/**
+ * @brief I2C Master complete process.
+ * @param hi2c: I2C handle.
+ * @param ITFlags: Interrupt flags to handle.
+ * @retval None
+ */
+static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
+{
+ /* Clear STOP Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
- /* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- }
+ /* Clear Configuration Register 2 */
+ I2C_RESET_CR2(hi2c);
- /* Wait until RXNE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, I2C_TIMEOUT_RXNE) != HAL_OK)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
+ /* Reset handle parameters */
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->XferISR = NULL;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
- {
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ if((ITFlags & I2C_FLAG_AF) != RESET)
+ {
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+ /* Set acknowledge error code */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
+ }
- hi2c->XferCount = 0;
+ /* Flush TX register */
+ I2C_Flush_TXDR(hi2c);
- hi2c->State = HAL_I2C_STATE_READY;
+ /* Disable Interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT| I2C_XFER_RX_IT);
- HAL_I2C_ErrorCallback(hi2c);
- }
- else
- {
- /* Enable DMA Request */
- hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
- }
- }
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ {
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c, hi2c->ErrorCode);
}
- else
+ /* hi2c->State == HAL_I2C_STATE_BUSY_TX */
+ else if(hi2c->State == HAL_I2C_STATE_BUSY_TX)
{
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
+ hi2c->State = HAL_I2C_STATE_READY;
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ HAL_I2C_MemTxCpltCallback(hi2c);
+ }
+ else
+ {
+ hi2c->Mode = HAL_I2C_MODE_NONE;
- hi2c->XferCount = 0;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ HAL_I2C_MasterTxCpltCallback(hi2c);
+ }
+ }
+ /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
+ else if(hi2c->State == HAL_I2C_STATE_BUSY_RX)
+ {
hi2c->State = HAL_I2C_STATE_READY;
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ if (hi2c->Mode == HAL_I2C_MODE_MEM)
{
- HAL_I2C_ErrorCallback(hi2c);
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ HAL_I2C_MemRxCpltCallback(hi2c);
}
else
{
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
HAL_I2C_MasterRxCpltCallback(hi2c);
}
}
}
/**
- * @brief DMA I2C slave receive process complete callback.
- * @param hdma: DMA handle
+ * @brief I2C Slave complete process.
+ * @param hi2c: I2C handle.
+ * @param ITFlags: Interrupt flags to handle.
* @retval None
*/
-static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
+static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
{
- I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+ /* Clear STOP Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+
+ /* Clear ADDR flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c,I2C_FLAG_ADDR);
+
+ /* Disable all interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT | I2C_XFER_RX_IT);
+
+ /* Disable Address Acknowledge */
+ hi2c->Instance->CR2 |= I2C_CR2_NACK;
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
+ /* Clear Configuration Register 2 */
+ I2C_RESET_CR2(hi2c);
+
+ /* Flush TX register */
+ I2C_Flush_TXDR(hi2c);
+
+ /* If a DMA is ongoing, Update handle size context */
+ if(((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) ||
+ ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN))
{
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
+ if((hi2c->XferSize - I2C_GET_DMA_REMAIN_DATA(hi2c)) != hi2c->XferSize)
{
+ hi2c->XferSize = I2C_GET_DMA_REMAIN_DATA(hi2c);
+ hi2c->XferCount += hi2c->XferSize;
+
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
}
- else
+ }
+
+ /* Store Last receive data if any */
+ if(((ITFlags & I2C_FLAG_RXNE) != RESET))
+ {
+ /* Read data from RXDR */
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
+
+ if((hi2c->XferSize > 0))
{
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
+ hi2c->XferSize--;
+ hi2c->XferCount--;
+
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
}
}
- /* Clear STOPF flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->XferISR = NULL;
- /* Wait until BUSY flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY) != HAL_OK)
+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
{
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->State = HAL_I2C_STATE_READY;
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c, hi2c->ErrorCode);
+ }
+ else if(hi2c->XferOptions != I2C_NO_OPTION_FRAME)
+ {
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->State = HAL_I2C_STATE_READY;
- /* Disable Address Acknowledge */
- hi2c->Instance->CR2 |= I2C_CR2_NACK;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- hi2c->XferCount = 0;
+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
+ HAL_I2C_ListenCpltCallback(hi2c);
+ }
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ else if(hi2c->State == HAL_I2C_STATE_BUSY_RX)
+ {
+ hi2c->State = HAL_I2C_STATE_READY;
- hi2c->State = HAL_I2C_STATE_READY;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
- {
- HAL_I2C_ErrorCallback(hi2c);
+ /* Call the Slave Rx Complete callback */
+ HAL_I2C_SlaveRxCpltCallback(hi2c);
}
else
{
- HAL_I2C_SlaveRxCpltCallback(hi2c);
+ hi2c->State = HAL_I2C_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Call the Slave Tx Complete callback */
+ HAL_I2C_SlaveTxCpltCallback(hi2c);
}
}
/**
- * @brief DMA I2C Memory Write process complete callback
- * @param hdma : DMA handle
+ * @brief I2C Listen complete process.
+ * @param hi2c: I2C handle.
+ * @param ITFlags: Interrupt flags to handle.
* @retval None
*/
-static void I2C_DMAMemTransmitCplt(DMA_HandleTypeDef *hdma)
+static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
{
- uint16_t DevAddress;
- I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* Reset handle parameters */
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->XferISR = NULL;
- /* Check if last DMA request was done with RELOAD */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
+ /* Store Last receive data if any */
+ if(((ITFlags & I2C_FLAG_RXNE) != RESET))
{
- /* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, I2C_TIMEOUT_TCR) != HAL_OK)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
-
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
+ /* Read data from RXDR */
+ (*hi2c->pBuffPtr++) = hi2c->Instance->RXDR;
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ if((hi2c->XferSize > 0))
{
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
-
- hi2c->XferCount = 0;
+ hi2c->XferSize--;
+ hi2c->XferCount--;
- hi2c->State = HAL_I2C_STATE_READY;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Set ErrorCode corresponding to a Non-Acknowledge */
+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
}
- else
- {
- hi2c->pBuffPtr += hi2c->XferSize;
- hi2c->XferCount -= hi2c->XferSize;
- if(hi2c->XferCount > 255)
- {
- hi2c->XferSize = 255;
- }
- else
- {
- hi2c->XferSize = hi2c->XferCount;
- }
-
- DevAddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
+ }
- /* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- }
+ /* Disable all Interrupts*/
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
- /* Wait until TXIS flag is set */
- if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, I2C_TIMEOUT_TXIS) != HAL_OK)
- {
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
+ /* Clear NACK Flag */
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
+ HAL_I2C_ListenCpltCallback(hi2c);
+}
- hi2c->XferCount = 0;
+/**
+ * @brief I2C interrupts error process.
+ * @param hi2c: I2C handle.
+ * @param ErrorCode: Error code to handle.
+ * @retval None
+ */
+static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode)
+{
+ /* Reset handle parameters */
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+ hi2c->XferOptions = I2C_NO_OPTION_FRAME;
+ hi2c->XferCount = 0;
+
+ /* Set new error code */
+ hi2c->ErrorCode |= ErrorCode;
+
+ /* Disable Interrupts */
+ if((hi2c->State == HAL_I2C_STATE_LISTEN) ||
+ (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) ||
+ (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN))
+ {
+ /* Disable all interrupts, except interrupts related to LISTEN state */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_TX_IT);
- hi2c->State = HAL_I2C_STATE_READY;
- HAL_I2C_ErrorCallback(hi2c);
- }
- else
- {
- /* Enable DMA Request */
- hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
- }
- }
+ /* keep HAL_I2C_STATE_LISTEN if set */
+ hi2c->State = HAL_I2C_STATE_LISTEN;
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->XferISR = I2C_Slave_ISR_IT;
}
else
{
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
+ /* Disable all interrupts */
+ I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
-
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+ /* Set HAL_I2C_STATE_READY */
+ hi2c->State = HAL_I2C_STATE_READY;
+ hi2c->PreviousState = I2C_STATE_NONE;
+ hi2c->XferISR = NULL;
+ }
- /* Disable DMA Request */
+ /* Abort DMA TX transfer if any */
+ if((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
+ {
hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
- hi2c->XferCount = 0;
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
- hi2c->State = HAL_I2C_STATE_READY;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ /* Abort DMA TX */
+ if(HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
{
- HAL_I2C_ErrorCallback(hi2c);
+ /* Call Directly XferAbortCallback function in case of error */
+ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
}
- else
+ }
+ /* Abort DMA RX transfer if any */
+ else if((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
+ {
+ hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
+
+ /* Set the I2C DMA Abort callback :
+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
+ hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Abort DMA RX */
+ if(HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
{
- HAL_I2C_MemTxCpltCallback(hi2c);
+ /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */
+ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
}
}
+ else if(hi2c->ErrorCode == HAL_I2C_ERROR_ABORT)
+ {
+ hi2c->ErrorCode &= ~HAL_I2C_ERROR_ABORT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ HAL_I2C_AbortCpltCallback(hi2c);
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ HAL_I2C_ErrorCallback(hi2c);
+ }
}
/**
- * @brief DMA I2C Memory Read process complete callback
- * @param hdma: DMA handle
+ * @brief I2C Tx data register flush process.
+ * @param hi2c: I2C handle.
* @retval None
*/
-static void I2C_DMAMemReceiveCplt(DMA_HandleTypeDef *hdma)
+static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c)
{
- I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
- uint16_t DevAddress;
-
- /* Check if last DMA request was done with RELOAD */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
+ /* If a pending TXIS flag is set */
+ /* Write a dummy data in TXDR to clear it */
+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET)
{
- /* Wait until TCR flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, I2C_TIMEOUT_TCR) != HAL_OK)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
-
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
+ hi2c->Instance->TXDR = 0x00;
+ }
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
- {
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
+ /* Flush TX register if not empty */
+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET)
+ {
+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE);
+ }
+}
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+/**
+ * @brief DMA I2C master transmit process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+ /* Disable DMA Request */
+ hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
- hi2c->XferCount = 0;
+ /* If last transfer, enable STOP interrupt */
+ if(hi2c->XferCount == 0)
+ {
+ /* Enable STOP interrupt */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
+ }
+ /* else prepare a new DMA transfer and enable TCReload interrupt */
+ else
+ {
+ /* Update Buffer pointer */
+ hi2c->pBuffPtr += hi2c->XferSize;
- hi2c->State = HAL_I2C_STATE_READY;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Set the XferSize to transfer */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
+ {
+ hi2c->XferSize = MAX_NBYTE_SIZE;
}
else
{
- hi2c->pBuffPtr += hi2c->XferSize;
- hi2c->XferCount -= hi2c->XferSize;
- if(hi2c->XferCount > 255)
- {
- hi2c->XferSize = 255;
- }
- else
- {
- hi2c->XferSize = hi2c->XferCount;
- }
-
- DevAddress = (hi2c->Instance->CR2 & I2C_CR2_SADD);
-
- /* Enable the DMA channel */
- HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
-
- /* Send Slave Address */
- /* Set NBYTES to write and reload if size > 255 */
- if( (hi2c->XferSize == 255) && (hi2c->XferSize < hi2c->XferCount) )
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
- }
- else
- {
- I2C_TransferConfig(hi2c,DevAddress,hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
- }
+ hi2c->XferSize = hi2c->XferCount;
+ }
- /* Wait until RXNE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, I2C_TIMEOUT_RXNE) != HAL_OK)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
- {
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
+ /* Enable TC interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
+ }
+}
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+/**
+ * @brief DMA I2C slave transmit process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ /* No specific action, Master fully manage the generation of STOP condition */
+ /* Mean that this generation can arrive at any time, at the end or during DMA process */
+ /* So STOP condition should be manage through Interrupt treatment */
+}
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
+/**
+ * @brief DMA I2C master receive process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
- hi2c->XferCount = 0;
+ /* Disable DMA Request */
+ hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
- hi2c->State = HAL_I2C_STATE_READY;
- HAL_I2C_ErrorCallback(hi2c);
- }
- else
- {
- /* Enable DMA Request */
- hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
- }
- }
+ /* If last transfer, enable STOP interrupt */
+ if(hi2c->XferCount == 0)
+ {
+ /* Enable STOP interrupt */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
}
+ /* else prepare a new DMA transfer and enable TCReload interrupt */
else
{
- /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
- /* Wait until STOPF flag is reset */
- if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
- {
- if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
- }
- else
- {
- hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
- }
- }
-
- /* Clear STOP Flag */
- __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ /* Update Buffer pointer */
+ hi2c->pBuffPtr += hi2c->XferSize;
- /* Clear Configuration Register 2 */
- I2C_RESET_CR2(hi2c);
-
- /* Disable DMA Request */
- hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
-
- hi2c->XferCount = 0;
-
- hi2c->State = HAL_I2C_STATE_READY;
-
- /* Check if Errors has been detected during transfer */
- if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
+ /* Set the XferSize to transfer */
+ if(hi2c->XferCount > MAX_NBYTE_SIZE)
{
- HAL_I2C_ErrorCallback(hi2c);
+ hi2c->XferSize = MAX_NBYTE_SIZE;
}
else
{
- HAL_I2C_MemRxCpltCallback(hi2c);
+ hi2c->XferSize = hi2c->XferCount;
}
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize);
+
+ /* Enable TC interrupts */
+ I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
}
}
/**
+ * @brief DMA I2C slave receive process complete callback.
+ * @param hdma: DMA handle
+ * @retval None
+ */
+static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ /* No specific action, Master fully manage the generation of STOP condition */
+ /* Mean that this generation can arrive at any time, at the end or during DMA process */
+ /* So STOP condition should be manage through Interrupt treatment */
+}
+
+/**
* @brief DMA I2C communication error callback.
- * @param hdma : DMA handle
+ * @param hdma: DMA handle
* @retval None
*/
static void I2C_DMAError(DMA_HandleTypeDef *hdma)
@@ -3805,60 +4338,67 @@ static void I2C_DMAError(DMA_HandleTypeDef *hdma)
/* Disable Acknowledge */
hi2c->Instance->CR2 |= I2C_CR2_NACK;
- hi2c->XferCount = 0;
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
+}
- hi2c->State = HAL_I2C_STATE_READY;
+/**
+ * @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->CR2 |= I2C_CR2_NACK;
- hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
+ /* Reset AbortCpltCallback */
+ hi2c->hdmatx->XferAbortCallback = NULL;
+ hi2c->hdmarx->XferAbortCallback = NULL;
- HAL_I2C_ErrorCallback(hi2c);
+ /* Check if come from abort from user */
+ if(hi2c->ErrorCode == HAL_I2C_ERROR_ABORT)
+ {
+ hi2c->ErrorCode &= ~HAL_I2C_ERROR_ABORT;
+
+ /* Call the corresponding callback to inform upper layer of End of Transfer */
+ HAL_I2C_AbortCpltCallback(hi2c);
+ }
+ else
+ {
+ /* 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 the specified I2C.
- * @param Flag: specifies the I2C flag to check.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @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)
+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
{
- uint32_t tickstart = HAL_GetTick();
-
- /* Wait until flag is set */
- if(Status == RESET)
- {
- while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET)
- {
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
- {
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- hi2c->State= HAL_I2C_STATE_READY;
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
- }
- }
- }
- else
+ while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status)
{
- while(__HAL_I2C_GET_FLAG(hi2c, Flag) != RESET)
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
{
- /* Check for the Timeout */
- if(Timeout != HAL_MAX_DELAY)
+ if((Timeout == 0)||((HAL_GetTick() - Tickstart ) > Timeout))
{
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
- {
- hi2c->State= HAL_I2C_STATE_READY;
- /* Process Unlocked */
- __HAL_UNLOCK(hi2c);
- return HAL_TIMEOUT;
- }
+ hi2c->State= HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2c);
+ return HAL_TIMEOUT;
}
}
}
@@ -3867,19 +4407,18 @@ static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uin
/**
* @brief This function handles I2C Communication Timeout for specific usage of TXIS flag.
- * @param hi2c : Pointer to a I2C_HandleTypeDef structure that contains
- * the configuration information for the specified I2C.
+ * @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_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout)
+static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
{
- uint32_t tickstart = HAL_GetTick();
-
while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET)
{
/* Check if a NACK is detected */
- if(I2C_IsAcknowledgeFailed(hi2c, Timeout) != HAL_OK)
+ if(I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
{
return HAL_ERROR;
}
@@ -3887,10 +4426,11 @@ static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
/* Check for the Timeout */
if(Timeout != HAL_MAX_DELAY)
{
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ if((Timeout == 0)||((HAL_GetTick() - Tickstart) > Timeout))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
hi2c->State= HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -3904,29 +4444,28 @@ static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
/**
* @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 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)
+static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
{
- uint32_t tickstart = 0x00;
- tickstart = HAL_GetTick();
-
while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
{
/* Check if a NACK is detected */
- if(I2C_IsAcknowledgeFailed(hi2c, Timeout) != HAL_OK)
+ if(I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
{
return HAL_ERROR;
}
/* Check for the Timeout */
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ if((Timeout == 0)||((HAL_GetTick() - Tickstart) > Timeout))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
hi2c->State= HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -3939,18 +4478,22 @@ static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
/**
* @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 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)
+static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
{
- uint32_t tickstart = 0x00;
- tickstart = HAL_GetTick();
-
while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET)
{
+ /* Check if a NACK is detected */
+ if(I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
+ {
+ return HAL_ERROR;
+ }
+
/* Check if a STOPF is detected */
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
{
@@ -3962,6 +4505,7 @@ static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
hi2c->State= HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -3970,7 +4514,7 @@ static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
}
/* Check for the Timeout */
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ if((Timeout == 0)||((HAL_GetTick() - Tickstart) > Timeout))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
hi2c->State= HAL_I2C_STATE_READY;
@@ -3986,31 +4530,16 @@ static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c,
/**
* @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.
+ * @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_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout)
+static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
{
- uint32_t tickstart = 0x00;
- tickstart = HAL_GetTick();
-
if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
{
- /* Generate stop if necessary only in case of I2C peripheral in MASTER mode */
- if((hi2c->State == HAL_I2C_STATE_MASTER_BUSY_TX) || (hi2c->State == HAL_I2C_STATE_MEM_BUSY_TX)
- || (hi2c->State == HAL_I2C_STATE_MEM_BUSY_RX))
- {
- /* No need to generate the STOP condition if AUTOEND mode is enabled */
- /* Generate the STOP condition only in case of SOFTEND mode is enabled */
- if((hi2c->Instance->CR2 & I2C_AUTOEND_MODE) != I2C_AUTOEND_MODE)
- {
- /* Generate Stop */
- hi2c->Instance->CR2 |= I2C_CR2_STOP;
- }
- }
-
/* Wait until STOP Flag is reset */
/* AutoEnd should be initiate after AF */
while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
@@ -4018,9 +4547,11 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32
/* Check for the Timeout */
if(Timeout != HAL_MAX_DELAY)
{
- if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ if((Timeout == 0)||((HAL_GetTick() - Tickstart) > Timeout))
{
hi2c->State= HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
+
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_TIMEOUT;
@@ -4034,11 +4565,15 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32
/* Clear STOP Flag */
__HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
+ /* Flush TX register */
+ I2C_Flush_TXDR(hi2c);
+
/* Clear Configuration Register 2 */
I2C_RESET_CR2(hi2c);
hi2c->ErrorCode = HAL_I2C_ERROR_AF;
hi2c->State= HAL_I2C_STATE_READY;
+ hi2c->Mode = HAL_I2C_MODE_NONE;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
@@ -4051,20 +4586,13 @@ static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32
/**
* @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
* @param hi2c: I2C handle.
- * @param DevAddress: specifies the slave address to be programmed.
- * @param Size: specifies the number of bytes to be programmed.
+ * @param DevAddress: Specifies the slave address to be programmed.
+ * @param Size: Specifies the number of bytes to be programmed.
* This parameter must be a value between 0 and 255.
- * @param Mode: new state of the I2C START condition generation.
- * This parameter can be one of the following values:
- * @arg I2C_RELOAD_MODE: Enable Reload mode .
- * @arg I2C_AUTOEND_MODE: Enable Automatic end mode.
- * @arg I2C_SOFTEND_MODE: Enable Software end mode.
- * @param Request: new state of the I2C START condition generation.
- * This parameter can be one of the following values:
- * @arg I2C_NO_STARTSTOP: Don't Generate stop and start condition.
- * @arg I2C_GENERATE_STOP: Generate stop condition (Size should be set to 0).
- * @arg I2C_GENERATE_START_READ: Generate Restart for read request.
- * @arg I2C_GENERATE_START_WRITE: Generate Restart for write request.
+ * @param Mode: New state of the I2C START condition generation.
+ * This parameter can be a value of @ref I2C_RELOAD_END_MODE.
+ * @param Request: New state of the I2C START condition generation.
+ * This parameter can be a value of I2C_START_STOP_MODE.
* @retval None
*/
static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
@@ -4091,8 +4619,144 @@ static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, ui
}
/**
- * @}
+ * @brief Manage the enabling of Interrupts.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param InterruptRequest: Value of @ref I2C_Interrupt_configuration_definition.
+ * @retval HAL status
*/
+static HAL_StatusTypeDef I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
+{
+ uint32_t tmpisr = 0;
+
+ if((hi2c->XferISR == I2C_Master_ISR_DMA) || \
+ (hi2c->XferISR == I2C_Slave_ISR_DMA))
+ {
+ if((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
+ {
+ /* Enable ERR, STOP, NACK and ADDR interrupts */
+ tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
+ }
+
+ if((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT)
+ {
+ /* Enable ERR and NACK interrupts */
+ tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
+ }
+
+ if((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT)
+ {
+ /* Enable STOP interrupts */
+ tmpisr |= I2C_IT_STOPI;
+ }
+
+ if((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT)
+ {
+ /* Enable TC interrupts */
+ tmpisr |= I2C_IT_TCI;
+ }
+ }
+ else
+ {
+ if((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
+ {
+ /* Enable ERR, STOP, NACK, and ADDR interrupts */
+ tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
+ }
+
+ if((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
+ {
+ /* Enable ERR, TC, STOP, NACK and RXI interrupts */
+ tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI;
+ }
+
+ if((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
+ {
+ /* Enable ERR, TC, STOP, NACK and TXI interrupts */
+ tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI;
+ }
+
+ if((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT)
+ {
+ /* Enable STOP interrupts */
+ tmpisr |= I2C_IT_STOPI;
+ }
+ }
+
+ /* Enable interrupts only at the end */
+ /* to avoid the risk of I2C interrupt handle execution before */
+ /* all interrupts requested done */
+ __HAL_I2C_ENABLE_IT(hi2c, tmpisr);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Manage the disabling of Interrupts.
+ * @param hi2c: Pointer to a I2C_HandleTypeDef structure that contains
+ * the configuration information for the specified I2C.
+ * @param InterruptRequest: Value of @ref I2C_Interrupt_configuration_definition.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
+{
+ uint32_t tmpisr = 0;
+
+ if((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
+ {
+ /* Disable TC and TXI interrupts */
+ tmpisr |= I2C_IT_TCI | I2C_IT_TXI;
+
+ if((hi2c->State & HAL_I2C_STATE_LISTEN) != HAL_I2C_STATE_LISTEN)
+ {
+ /* Disable NACK and STOP interrupts */
+ tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
+ }
+ }
+
+ if((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
+ {
+ /* Disable TC and RXI interrupts */
+ tmpisr |= I2C_IT_TCI | I2C_IT_RXI;
+
+ if((hi2c->State & HAL_I2C_STATE_LISTEN) != HAL_I2C_STATE_LISTEN)
+ {
+ /* Disable NACK and STOP interrupts */
+ tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
+ }
+ }
+
+ if((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
+ {
+ /* Disable ADDR, NACK and STOP interrupts */
+ tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
+ }
+
+ if((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT)
+ {
+ /* Enable ERR and NACK interrupts */
+ tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
+ }
+
+ if((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT)
+ {
+ /* Enable STOP interrupts */
+ tmpisr |= I2C_IT_STOPI;
+ }
+
+ if((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT)
+ {
+ /* Enable TC interrupts */
+ tmpisr |= I2C_IT_TCI;
+ }
+
+ /* Disable interrupts only at the end */
+ /* to avoid a breaking situation like at "t" time */
+ /* all disable interrupts request are not done */
+ __HAL_I2C_DISABLE_IT(hi2c, tmpisr);
+
+ return HAL_OK;
+}
/**
* @}