apache-mynewt-bot commented on pull request #2332: URL: https://github.com/apache/mynewt-core/pull/2332#issuecomment-659015477
<!-- style-bot --> ## Style check summary ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md) #### hw/mcu/stm/stm32_common/src/stm32_driver_mod_i2c_v1.c <details> ```diff @@ -42,865 +43,760 @@ static const uint8_t HAL_I2C_MODE_MASTER_SEL = 0x11; /** - * @brief This function handles I2C Communication Timeout. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param Flag specifies the I2C flag to check. - * @param Status The new Flag status (SET or RESET). - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, - uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) -{ - /* Wait until flag is set */ - while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) - { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) - { + * @brief This function handles I2C Communication Timeout. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag specifies the I2C flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, + uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) +{ + /* Wait until flag is set */ + while ((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) { + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for Master addressing phase. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag specifies the I2C flag to check. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, + uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) { + if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + /* Generate Start condition if first transfer */ + if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || + (CurrentXferOptions == I2C_NO_OPTION_FRAME)) { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) { + return HAL_TIMEOUT; + } + + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + } else { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + return HAL_ERROR; + } else { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + } + + /* Wait until ADDR flag is set */ + if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + return HAL_ERROR; + } else { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief This function handles Acknowledge failed detection during an I2C Communication. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) +{ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) { + /* Clear NACKF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->State = HAL_I2C_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - } - - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for Master addressing phase. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param Flag specifies the I2C flag to check. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, - uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) - { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Clear AF Flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - hi2c->ErrorCode = HAL_I2C_ERROR_AF; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_ERROR; - } - - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; + return HAL_ERROR; + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of TXE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) { + /* Check if a NACK is detected */ + if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) { + if ((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of BTF flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) { + /* Check if a NACK is detected */ + if (I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) { + if ((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) { + /* Check if a STOPF is detected */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) { + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if ((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @param LastOp If set sends STOP, otherwise no STOP + * @retval HAL status + */ +HAL_StatusTypeDef +HAL_I2C_Master_Transmit_Custom(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout, + uint8_t LastOp) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (hi2c->State == HAL_I2C_STATE_READY) { + if (hi2c->Mode != HAL_I2C_MODE_MASTER_SEL) { + /* Wait until BUSY flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) { + return HAL_BUSY; + } + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if (I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } else { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + while (hi2c->XferSize > 0U) { + /* Wait until TXE flag is set */ + if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } else { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + } + + /* Wait until BTF flag is set */ + if (I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } else { + return HAL_TIMEOUT; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + + if (LastOp) { + hi2c->Instance->CR1 |= I2C_CR1_STOP; + hi2c->Mode = HAL_I2C_MODE_NONE; + } else { + hi2c->Mode = HAL_I2C_MODE_MASTER_SEL; + } /* Process Unlocked */ __HAL_UNLOCK(hi2c); + return HAL_OK; + } else { + return HAL_BUSY; + } +} + +/** + * @brief Master sends target device address for read request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef +I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start condition if first transfer */ + if ((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || + (CurrentXferOptions == I2C_NO_OPTION_FRAME)) { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } else if (hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) { return HAL_TIMEOUT; - } - } - } - return HAL_OK; -} - -/** - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, - uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -{ - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentXferOptions = hi2c->XferOptions; - - /* Generate Start condition if first transfer */ - if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) - { - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) - { - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) - { - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); - } - else - { - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); - - /* Wait until ADD10 flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); - } - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - return HAL_OK; -} - -/** - * @brief This function handles Acknowledge failed detection during an I2C Communication. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) -{ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) - { - /* Clear NACKF Flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - hi2c->ErrorCode = HAL_I2C_ERROR_AF; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_ERROR; - } - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for specific usage of TXE flag. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) - { - /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) - { - return HAL_ERROR; - } - - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - } - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for specific usage of BTF flag. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) - { - /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) - { - return HAL_ERROR; - } - - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - } - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) - { - /* Check if a STOPF is detected */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) - { - /* Clear STOP Flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); - - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_ERROR; - } - - /* Check for the Timeout */ - if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - return HAL_OK; -} - -/** - * @brief Transmits in master mode an amount of data in blocking mode. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @param LastOp If set sends STOP, otherwise no STOP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Transmit_Custom(I2C_HandleTypeDef *hi2c, - uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout, - uint8_t LastOp) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if (hi2c->Mode != HAL_I2C_MODE_MASTER_SEL) - { - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_BUSY; - } - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Send Slave Address */ - if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - while(hi2c->XferSize > 0U) - { - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - hi2c->XferSize--; - - if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - hi2c->XferSize--; - } - - /* Wait until BTF flag is set */ - if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - } - - hi2c->State = HAL_I2C_STATE_READY; - - if (LastOp) - { - hi2c->Instance->CR1 |= I2C_CR1_STOP; - hi2c->Mode = HAL_I2C_MODE_NONE; - } - else - { - hi2c->Mode = HAL_I2C_MODE_MASTER_SEL; - } - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); + } + + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); + } else { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + return HAL_ERROR; + } else { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + + /* Wait until ADDR flag is set */ + if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + return HAL_ERROR; + } else { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) { + return HAL_TIMEOUT; + } + + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); + } + + /* Wait until ADDR flag is set */ + if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + return HAL_ERROR; + } else { + return HAL_TIMEOUT; + } + } return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Master sends target device address for read request. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -{ - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentXferOptions = hi2c->XferOptions; - - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start condition if first transfer */ - if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) - { - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) - { - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) - { - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); - } - else - { - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); - - /* Wait until ADD10 flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Restart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); - } - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - return HAL_OK; -} - -/** - * @brief Receives in master mode an amount of data in blocking mode. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @param LastOp If set sends STOP, otherwise no STOP - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Receive_Custom(I2C_HandleTypeDef *hi2c, - uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout, - uint8_t LastOp) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if (hi2c->Mode != HAL_I2C_MODE_MASTER_SEL) - { - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_BUSY; - } - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Send Slave Address */ - if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - if(hi2c->XferSize == 0U) - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - if (LastOp) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - } - else if(hi2c->XferSize == 1U) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @param LastOp If set sends STOP, otherwise no STOP + * @retval HAL status + */ +HAL_StatusTypeDef +HAL_I2C_Master_Receive_Custom(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout, + uint8_t LastOp) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (hi2c->State == HAL_I2C_STATE_READY) { + if (hi2c->Mode != HAL_I2C_MODE_MASTER_SEL) { + /* Wait until BUSY flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) { + return HAL_BUSY; + } + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if ((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if (I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } else { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if (hi2c->XferSize == 0U) { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + if (LastOp) { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + } else if (hi2c->XferSize == 1U) { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; #if MYNEWT_VAL(MCU_STM32F1) - /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 - software sequence must complete before the current byte end of transfer */ - __disable_irq(); + /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 + software sequence must complete before the current byte end of transfer */ + __disable_irq(); #endif - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - if (LastOp) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } -#if MYNEWT_VAL(MCU_STM32F1) - /* Re-enable IRQs */ - __enable_irq(); -#endif - } - else if(hi2c->XferSize == 2U) - { -#if MYNEWT_VAL(MCU_STM32F1) - /* Enable Pos */ - hi2c->Instance->CR1 |= I2C_CR1_POS; - - /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 - software sequence must complete before the current byte end of transfer */ - __disable_irq(); - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Re-enable IRQs */ - __enable_irq(); -#else - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Enable Pos */ - hi2c->Instance->CR1 |= I2C_CR1_POS; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -#endif - } - else - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - - while(hi2c->XferSize > 0U) - { - if(hi2c->XferSize <= 3U) - { - /* One byte */ - if(hi2c->XferSize == 1U) - { - /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) - { - return HAL_TIMEOUT; - } - else - { - return HAL_ERROR; - } - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - /* Two bytes */ - else if(hi2c->XferSize == 2U) - { - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - -#if MYNEWT_VAL(MCU_STM32F1) - /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 - software sequence must complete before the current byte end of transfer */ - __disable_irq(); -#endif - - if (LastOp) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - -#if MYNEWT_VAL(MCU_STM32F1) - /* Re-enable IRQs */ - __enable_irq(); -#endif - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - /* 3 Last bytes */ - else - { - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - -#if MYNEWT_VAL(MCU_STM32F1) - /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 - software sequence must complete before the current byte end of transfer */ - __disable_irq(); -#endif - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + if (LastOp) { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } #if MYNEWT_VAL(MCU_STM32F1) /* Re-enable IRQs */ __enable_irq(); #endif - return HAL_TIMEOUT; - } - - if (LastOp) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - + } else if (hi2c->XferSize == 2U) { #if MYNEWT_VAL(MCU_STM32F1) - /* Re-enable IRQs */ - __enable_irq(); + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 + software sequence must complete before the current byte end of transfer */ + __disable_irq(); + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Re-enable IRQs */ + __enable_irq(); +#else + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); #endif - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - } - else - { - /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) - { - return HAL_TIMEOUT; - } - else - { - return HAL_ERROR; - } - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - } - } - - hi2c->State = HAL_I2C_STATE_READY; - - if (LastOp) { - hi2c->Mode = HAL_I2C_MODE_NONE; + } else { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while (hi2c->XferSize > 0U) { + if (hi2c->XferSize <= 3U) { + /* One byte */ + if (hi2c->XferSize == 1U) { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) { + return HAL_TIMEOUT; + } else { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* Two bytes */ + else if (hi2c->XferSize == 2U) { + /* Wait until BTF flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) { + return HAL_TIMEOUT; + } + +#if MYNEWT_VAL(MCU_STM32F1) + /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 + software sequence must complete before the current byte end of transfer */ + __disable_irq(); +#endif + + if (LastOp) { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + +#if MYNEWT_VAL(MCU_STM32F1) + /* Re-enable IRQs */ + __enable_irq(); +#endif + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* 3 Last bytes */ + else { + /* Wait until BTF flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) { + return HAL_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + +#if MYNEWT_VAL(MCU_STM32F1) + /* Disable all active IRQs around ADDR clearing and STOP programming because the EV6_3 + software sequence must complete before the current byte end of transfer */ + __disable_irq(); +#endif + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Wait until BTF flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) { +#if MYNEWT_VAL(MCU_STM32F1) + /* Re-enable IRQs */ + __enable_irq(); +#endif + return HAL_TIMEOUT; + } + + if (LastOp) { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + +#if MYNEWT_VAL(MCU_STM32F1) + /* Re-enable IRQs */ + __enable_irq(); +#endif + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } else { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) { + if (hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) { + return HAL_TIMEOUT; + } else { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + + if (LastOp) { + hi2c->Mode = HAL_I2C_MODE_NONE; + } else { + hi2c->Mode = HAL_I2C_MODE_MASTER_SEL; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; } else { - hi2c->Mode = HAL_I2C_MODE_MASTER_SEL; - } - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } + return HAL_BUSY; + } } #endif /* MYNEWT_VAL(STM32_HAL_I2C_HAS_CLOCKSPEED) */ ``` </details> ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org