- I2C_StatusType I2C_Mem_Read(I2C_Type* I2Cx, uint8_t SlaAddr, uint32_t ReadAddr, uint8_t ReadAddrSize, uint8_t *pBuffer, uint16_t NumByteToRead, 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, SlaAddr, 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;
- }
- if(ReadAddrSize == I2C_MEMADD_SIZE_32BIT)
- {
- I2C_SendData(I2Cx, (uint8_t)(ReadAddr >> 24));
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
- {
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_ERROR_STEP_5;
- }
- ReadAddrSize -= 1;
- }
- if(ReadAddrSize == I2C_MEMADD_SIZE_24BIT)
- {
- I2C_SendData(I2Cx, (uint8_t)(ReadAddr >> 16));
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
- {
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_ERROR_STEP_5;
- }
- ReadAddrSize -= 1;
- }
- if(ReadAddrSize == I2C_MEMADD_SIZE_16BIT)
- {
- I2C_SendData(I2Cx, (uint8_t)(ReadAddr >> 8));
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
- {
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_ERROR_STEP_5;
- }
- }
- /* Send Memory Address */
- I2C_SendData(I2Cx, ReadAddr);
- /* 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, SlaAddr, 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;
- }
- if(NumByteToRead == 1)
- {
- /* Disable Acknowledge */
- I2C_AcknowledgeConfig(I2Cx, DISABLE);
- /* Clear ADDR flag */
- I2C_ClearADDRFlag(I2Cx);
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- }
- else if(NumByteToRead == 2)
- {
- /* Enable Pos */
- I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next);
- /* Clear ADDR flag */
- I2C_ClearADDRFlag(I2Cx);
- /* Disable Acknowledge */
- I2C_AcknowledgeConfig(I2Cx, DISABLE);
- }
- else
- {
- /* Enable Acknowledge */
- I2C_AcknowledgeConfig(I2Cx, ENABLE);
- /* Clear ADDR flag */
- I2C_ClearADDRFlag(I2Cx);
- }
- while(NumByteToRead > 0)
- {
- if(NumByteToRead <= 3)
- {
- /* One byte */
- if(NumByteToRead == 1)
- {
- /* 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 */
- (*pBuffer++) = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- }
- /* Two bytes */
- else if(NumByteToRead == 2)
- {
- /* Wait until BTF flag is set */
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
- {
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_ERROR_STEP_9;
- }
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- /* Read data from DR */
- (*pBuffer++) = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- /* Read data from DR */
- (*pBuffer++) = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- }
- /* 3 Last bytes */
- else
- {
- /* Wait until BTF flag is set */
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
- {
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_ERROR_STEP_10;
- }
- /* Disable Acknowledge */
- I2C_AcknowledgeConfig(I2Cx, DISABLE);
- /* Read data from DR */
- (*pBuffer++) = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- /* Wait until BTF flag is set */
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
- {
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_ERROR_STEP_11;
- }
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- /* Read data from DR */
- (*pBuffer++) = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- /* Read data from DR */
- (*pBuffer++) = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- }
- }
- else
- {
- /* 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_12;
- }
- /* Read data from DR */
- (*pBuffer++) = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- }
- }
- return I2C_OK;
- }