Showing results for 
Search instead for 
Did you mean: 

STM32F1 I2C1 Alt Functions Drive Low

Associate III
Posted on November 16, 2016 at 02:39

I am running into an issue with I2C on an STM32F103 that is driving me crazy.  The code worked on the same processor with the normal pin mapping, however on new hardware with the alternate pin mapping for I2C1 (PortB 8 and 9) the I2C bus drives SCL and SDA low and no data is written to the bus.  I have the SCL and SDA lines pulled out to a external breadboard where I have 10K pull-ups to 3.3v and a logic analyser attached to the lines to see the signals.  There is no slave device connected to the lines. With a breakpoint at the start of the application, the SCL and SDA lines are high.  Once I start start configuring the GPIO lines and call HAL_GPIO_Init() they drop low and never change states.  Here is the configuration for the pins:

  // Configure pins for I2C

  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


We are using the HAL provided by ST:

The HAL_GPIO_Init function is here:

It appears setting them to AltFunction Open Drain really drives them low.

The project is open source and the full code repo can be found here:

Configuration starts in the src/labwiz/labwiz_entry.c file, main function with the MX_GPIO_Init() function. The HAL_Init() function before the GPIO setup calls HAL_MspInit(void) which is in the stm3f1xx_hal_msp.c file in the labwiz folder.

I have no idea why the lines are driving low. Am I missing something obvious? Has anyone else used the Alternate Function for I2C1 on an STM32F1 successfully?

Thank you.
Arnold Bischof
Associate III
Posted on November 16, 2016 at 18:18


I have I2C access for an external eeprom implemented on a STM32F103 using the cubeMX and the HAL driver.

I had similar problems with the interface as I started with the setup.

Following HAL_I2C_MspInit() code helpes to solve the problem in my case:

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)


  GPIO_InitTypeDef GPIO_InitStruct;



  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */


    /**I2C1 GPIO Configuration    

    PB8     ------> I2C1_SCL

    PB9     ------> I2C1_SDA


    GPIO_InitStruct.Pin = I2CINT_CLK_Pin|I2CINT_DATA_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);



    /* Peripheral clock enable */


  /* USER CODE BEGIN I2C1_MspInit 1 */

    // work around which solves I2C initial busy problem.

    // I2C gets busy during setup, just after I2C clock enable.

    // force/release reset at this point helps to reset the busy

    // flag of the I2C and lets the I2C interface work as expected.   





  /* USER CODE END I2C1_MspInit 1 */



I hope it helps in your case too.

Regards AB   

Associate III
Posted on November 22, 2016 at 01:01

Perfect! Fixed the issue. Thank you!