cancel
Showing results for 
Search instead for 
Did you mean: 

Why I2C pins are always low in STM32F0?

MSalv.1
Associate II

Hello, I have a SMT32F042, i'm trying to use I2C. I used STM32 CubeMX to generale a new blank project with only i2c (see attached). I2C on non standard pins. 0693W00000KcOSeQAN.pngThe problem is that they always stay low, it does not transfer anything.

This is what I captured with the logic analyzer, after starting the debug, it goes low.

0693W00000KcOStQAN.pngI attach the code, but it is really standard: https://pastebin.com/ijX9RLEG

I tried also to configure everything as output pin with external pull up (9,5k) and open drain... it works, so my pull up resistor are working.

I really don't know what to check next. THe same come with nucleo works perfectly.

Thank you,

UPDATE 1:

I tried with i2c1 normal pins (PF0 and PF1), and it worked. For my configuration (PB14+PB13) the result is still the same. I ended up that maybe is a but in stm32cube with setting alternate function. Anybody can see something strange?

In addition with main.c code, I am posting here the hal_msp.c code involved:

/**
* @brief I2C MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hi2c->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */
 
  /* USER CODE END I2C1_MspInit 0 */
  
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration    
    PB13     ------> I2C1_SCL
    PB14     ------> I2C1_SDA 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */
 
  /* USER CODE END I2C1_MspInit 1 */
  }
 
}

8 REPLIES 8
lbthomsen
Associate II

I2C pins are generally - as you point out yourself - configured as open drain, so they don't normally pull the pin high actively. It _is_ possible to use the internal pull up resistor, but those are in the 50 k range, which would be considered a "weak pull up". It will "probably" work if the transmission lines are short, but in general I2C should be pulled high more aggressively (10k or even lower).

KnarfB
Principal III

If you have configured a pin as I2C, the HAL_GPIO_WritePin functions do not have an effect anymore. The pin is either GPIO or alternate function (like I2C) or else.

hth

KnarfB

MM..1
Chief II

Check is interrupt for I2C peripheral enabled and ofcourse all pin Vdd and Vss is OK.

Hello, sorry, I was not clear. In another try and another code, I tried to reconfigure everything as GPIO and I tried WritePin to assure that the pin was not broken and the external pull up was working correctly. And it was working as expected, so I excluded the pullup damage/pin damage/connection issues.

Hello, thank you for your answer. I have a 9,5k pullup resistor. I tried (in a parallet attempt) configuring the pins as GPIO (open drain), and it correctly worked, so I have excluded the pullup damage/pin damage/connection issues.

I am starting to try in blocking mode, using HAL_I2C_Master_Transmit, but HAL_I2C_Master_Transmit_IT does nothing as well. Vdd and Vss are connected correctly

MSalv.1
Associate II

FOUND! As expected, was a stm32cubemx bug. It did everything for setting up the i2c but did not enable the alternate function registry.

It started working with:

GPIO_InitStruct.Alternate = ((uint8_t)0x05U);

inside hal_msc.c.

OTedd.1
Associate II

I had the same problem on the Nucleo F767Zi board using STM32CubeIDE:

Version: 1.12.0

Build: 14980_20230301_1550 (UTC)

when trying to get the I2C lines to work.

Adding these lines (manually) worked:

#define 	GPIO_AF4_I2C1   ((uint8_t)0x04) /* I2C1 Alternate Function mapping */
#define 	GPIO_AF4_I2C2   ((uint8_t)0x04) /* I2C2 Alternate Function mapping */
#define 	GPIO_AF4_I2C3   ((uint8_t)0x04) /* I2C3 Alternate Function mapping */
  /*Configure I2C1_SDA_Pin pin : I2C1_SDA_Pin */
  GPIO_InitStruct.Pin = I2C1_SDA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
  HAL_GPIO_Init(I2C1_SDA_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure I2C1_SCL_Pin pin : I2C1_SCL_Pin */
	GPIO_InitStruct.Pin = I2C1_SCL_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
	HAL_GPIO_Init(I2C1_SCL_GPIO_Port, &GPIO_InitStruct);
/* USER CODE END MX_GPIO_Init_2 */