Some problems encountered in debugging I2C

Publisher:tgdddtLatest update time:2019-04-08 Source: eefocusKeywords:debug  i2c  mode Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)

{


  GPIO_InitTypeDef GPIO_InitStruct;

  if(hi2c->Instance==I2C2)

  {

  /* USER CODE BEGIN I2C2_MspInit 0 */


  /* USER CODE END I2C2_MspInit 0 */

  

    /**I2C2 GPIO Configuration    

    PB10     ------> I2C2_SCL

    PB3     ------> I2C2_SDA 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_10;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed ​​= GPIO_SPEED_FREQ_LOW; //This option can only be low, and an error will occur if it is other modes.

    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


    GPIO_InitStruct.Pin = GPIO_PIN_3;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF9_I2C2;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


    /* Peripheral clock enable */

    __HAL_RCC_I2C2_CLK_ENABLE();

  /* USER CODE BEGIN I2C2_MspInit 1 */


  /* USER CODE END I2C2_MspInit 1 */

  }


}


 


 


if(hi2c->Instance==I2C1)

  {

  /* USER CODE BEGIN I2C1_MspInit 0 */


  /* USER CODE END I2C1_MspInit 0 */

  

    /**I2C1 GPIO Configuration    

    PB6     ------> I2C1_SCL

    PB7     ------> I2C1_SDA 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


    /* Peripheral clock enable */

    __HAL_RCC_I2C1_CLK_ENABLE();

    /* Peripheral interrupt init */

    HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);

    HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);

  /* USER CODE BEGIN I2C1_MspInit 1 */


  /* USER CODE END I2C1_MspInit 1 */

  }

  else if(hi2c->Instance==I2C2)

  {

  /* USER CODE BEGIN I2C2_MspInit 0 */


  /* USER CODE END I2C2_MspInit 0 */

  

    /**I2C2 GPIO Configuration    

    PB10     ------> I2C2_SCL

    PB3     ------> I2C2_SDA 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_10;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


    GPIO_InitStruct.Pin = GPIO_PIN_3;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF9_I2C2; //Note that the mode setting is not a simple imitation of GPIO_AF4_I2C2, but the current mode

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


    /* Peripheral clock enable */

    __HAL_RCC_I2C2_CLK_ENABLE();

  /* USER CODE BEGIN I2C2_MspInit 1 */


  /* USER CODE END I2C2_MspInit 1 */

  }

  else if(hi2c->Instance==I2C3)

  {

  /* USER CODE BEGIN I2C3_MspInit 0 */


  /* USER CODE END I2C3_MspInit 0 */

  

    /**I2C3 GPIO Configuration    

    PC9     ------> I2C3_SDA

    PA8     ------> I2C3_SCL 

    */

    GPIO_InitStruct.Pin = GPIO_PIN_9;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


    GPIO_InitStruct.Pin = GPIO_PIN_8;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Pull = GPIO_PULLUP;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


    /* Peripheral clock enable */

    __HAL_RCC_I2C3_CLK_ENABLE();

  /* USER CODE BEGIN I2C3_MspInit 1 */


  /* USER CODE END I2C3_MspInit 1 */

  }


 


The second question is how to modify the library so that the first I2C write has only start but no stop, and the second I2C read has both start and stop.


status = HAL_I2C_Master_Transmit_touch(&hi2c2, TOUCH_ADDR, &WriteBuff[0], 1, 30 );

    

        status = HAL_I2C_Master_Receive_touch(&hi2c2, TOUCH_ADDR, &ReadBuff[0], 8, 30);


Modify the library functions marked in red to shield the code.


 


HAL_StatusTypeDef HAL_I2C_Master_Transmit_touch(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

{

  uint32_t tickstart = 0x00U;


  /* Init tickstart for timeout management*/

  tickstart = HAL_GetTick();


  if(hi2c->State == HAL_I2C_STATE_READY)

  {

    /* 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) && (Size != 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;

        }

      }

    }


    /* Generate Stop */

//    hi2c->Instance->CR1 |= I2C_CR1_STOP;


    hi2c->State = HAL_I2C_STATE_READY;

    hi2c->Mode = HAL_I2C_MODE_NONE;

    

    /* Process Unlocked */

    __HAL_UNLOCK(hi2c);


    return HAL_OK;

  }

  else

  {

    return HAL_BUSY;

  }

}


 


 


 


 


 


HAL_StatusTypeDef HAL_I2C_Master_Receive_touch(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

{

  uint32_t tickstart = 0x00U;


  /* Init tickstart for timeout management*/

  tickstart = HAL_GetTick();


  if(hi2c->State == HAL_I2C_STATE_READY)

  {

    /* 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);


      /* Generate Stop */

      hi2c->Instance->CR1 |= I2C_CR1_STOP;

    }

    else if(hi2c->XferSize == 1U)

    {

      /* Disable Acknowledge */

      hi2c->Instance->CR1 &= ~I2C_CR1_ACK;


      /* Clear ADDR flag */

      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);


      /* Generate Stop */

      hi2c->Instance->CR1 |= I2C_CR1_STOP;

    }

    else if(hi2c->XferSize == 2U)

    {

      /* Disable Acknowledge */

      hi2c->Instance->CR1 &= ~I2C_CR1_ACK;


      /* Enable Pos */

      hi2c->Instance->CR1 |= I2C_CR1_POS;


      /* Clear ADDR flag */

      __HAL_I2C_CLEAR_ADDRFLAG(hi2c);

    }

    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;

          }


          /* Generate Stop */

          hi2c->Instance->CR1 |= I2C_CR1_STOP;


          /* Read data from DR */

          (*hi2c->pBuffPtr++) = hi2c->Instance->DR;

          hi2c->XferSize--;

          hi2c->XferCount--;


          /* 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;


          /* 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)

          {

            return HAL_TIMEOUT;

          }


          /* Generate Stop */

          hi2c->Instance->CR1 |= I2C_CR1_STOP;


          /* Read data from DR */

          (*hi2c->pBuffPtr++) = hi2c->Instance->DR;

          hi2c->XferSize--;

          hi2c->XferCount--;


          /* 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;

    hi2c->Mode = HAL_I2C_MODE_NONE;


    /* Process Unlocked */

    __HAL_UNLOCK(hi2c);


    return HAL_OK;

  }

  else

  {

    return HAL_BUSY;

  }

}


Keywords:debug  i2c  mode Reference address:Some problems encountered in debugging I2C

Previous article:I2C deadlock causes and solutions
Next article:i2c bug

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号