- 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;
- }