Skip to main content
q123w123e123qweqwe
Associate III
June 4, 2020
Question

I2C data reading problem STM32F746

  • June 4, 2020
  • 5 replies
  • 1822 views

Hello I have a problem with reading data on I2C. My code goes HardFault error after this( while (hi2c->XferCount > 0U);)

line. I'm reallt stuck in here. Does anyone have idea about that?

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 tickstart;
 
 /* Check the parameters */
 assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
 
 if (hi2c->State == HAL_I2C_STATE_READY)
 {
 if ((pData == NULL) || (Size == 0U))
 {
 hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
 return HAL_ERROR;
 }
 
 /* Process Locked */
 __HAL_LOCK(hi2c);
 
 /* Init tickstart for timeout management*/
 tickstart = HAL_GetTick();
 
 if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
 {
 return HAL_ERROR;
 }
 
 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, tickstart) != HAL_OK)
 {
 /* Process Unlocked */
 __HAL_UNLOCK(hi2c);
 return HAL_ERROR;
 }
 
 /* Send Slave Address */
 /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
 if (hi2c->XferCount > MAX_NBYTE_SIZE)
 {
 hi2c->XferSize = MAX_NBYTE_SIZE;
 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
 }
 else
 {
 hi2c->XferSize = hi2c->XferCount;
 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)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, tickstart) != HAL_OK)
 {
 return HAL_ERROR;
 }
 
 /* Read data from RXDR */
 *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
 
 /* Increment Buffer pointer */
 hi2c->pBuffPtr++;
 
 hi2c->XferSize--;
 hi2c->XferCount--;
 
 if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
 {
 /* Wait until TCR flag is set */
 if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
 {
 return HAL_ERROR;
 }
 
 if (hi2c->XferCount > MAX_NBYTE_SIZE)
 {
 hi2c->XferSize = MAX_NBYTE_SIZE;
 I2C_TransferConfig(hi2c, DevAddress, (uint8_t) hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
 }
 else
 {
 hi2c->XferSize = hi2c->XferCount;
 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
 }
 }
 }
 while (hi2c->XferCount > 0U);//////////////////////////////////////////////////////////////
 
 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
 /* Wait until STOPF flag is reset */
 if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
 {
 return HAL_ERROR;
 }
 
 /* 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;
 hi2c->Mode = HAL_I2C_MODE_NONE;
 
 /* Process Unlocked */
 __HAL_UNLOCK(hi2c);
 
 return HAL_OK;
 }
 else
 {
 return HAL_BUSY;
 }
}

This topic has been closed for replies.

5 replies

Martin KJELDSEN
Principal III
June 4, 2020

Did you check registers for errors to see if there's a hint?

q123w123e123qweqwe
Associate III
June 4, 2020

Hi Martin,

After I wrote this I solve this issue it was just my bad. Thanks for reply.

Martin KJELDSEN
Principal III
June 4, 2020

Good news :)

TDK
June 4, 2020

Consider posting your solution so that others may learn.

"If you feel a post has answered your question, please click ""Accept as Solution""."
q123w123e123qweqwe
Associate III
June 4, 2020

it was just a problem caused by incorrectly sending the Length value to the reading function. Program goes into hard fault error because the value that should be 4 is much higher.