static I2C_StatusType I2C_WaitOnFlagUntilTimeout(I2C_Type *I2Cx, uint32_t Flag, FlagStatus Status, uint32_t EventCheck, uint32_t Timeout)
{
/* delay 10 us = ms * 100 */
Timeout *= 100;
while (I2C_GetFlagStatus(I2Cx, Flag) == Status)
{
if (EventCheck & I2C_EVT_CHECK_ACKFAIL)
{
if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_ACKFAIL) == SET)
{
I2C_GenerateSTOP(I2Cx, ENABLE);
I2C_ClearFlag(I2Cx, I2C_FLAG_ACKFAIL);
return I2C_ERROR;
}
}
if (EventCheck & I2C_EVT_CHECK_STOP)
{
if (I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF) == SET)
{
I2C_ClearSTOPFlag(I2Cx);
return I2C_ERROR;
}
}
I2C_Delay(10);
if ((Timeout--) == 0)
{
return I2C_TIMEOUT;
}
}
return I2C_OK;
}
I2C_StatusType hw_i2c_read_reg(I2C_Type *I2Cx, uint8_t slave_addr, uint8_t reg, uint8_t *rd_value, uint32_t Timeout)
{
/* Wait until BUSY flag is reset */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, I2C_TIMEOUT_BUSY_FLAG) != I2C_OK)
{
return I2C_ERROR_STEP_1;
}
/* Disable Pos */
I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);
/* Enable Acknowledge */
I2C_AcknowledgeConfig(I2Cx, ENABLE);
/* Send START condition */
I2C_GenerateSTART(I2Cx, ENABLE);
/* Wait until SB flag is set */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_2;
}
/* Send slave address for write */
I2C_Send7bitAddress(I2Cx, slave_addr, I2C_Direction_Transmit);
/* Wait until ADDR flag is set */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_3;
}
/* Clear ADDR flag */
I2C_ClearADDRFlag(I2Cx);
/* Wait until TDE flag is set */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_4;
}
/* Send Memory Address */
I2C_SendData(I2Cx, reg);
/* Wait until TDE flag is set */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_5;
}
/* Send START condition */
I2C_GenerateSTART(I2Cx, ENABLE);
/* Wait until SB flag is set */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_6;
}
/* Send slave address for read */
I2C_Send7bitAddress(I2Cx, slave_addr, I2C_Direction_Receive);
/* Wait until ADDR flag is set */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_7;
}
/* Disable Acknowledge */
I2C_AcknowledgeConfig(I2Cx, DISABLE);
/* Clear ADDR flag */
I2C_ClearADDRFlag(I2Cx);
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
/* Wait until RXNE flag is set */
if (I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_8;
}
/* Read data from DR */
(*rd_value) = I2C_ReceiveData(I2Cx);
return I2C_OK;
}