cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f103c6t6 I2C busy

Stequila93
Associate II

Hello,

I know that has been asked a lot of times but i cannot get i2c work on my original stm32f103c6t6 mcu on a blue pill board.

I tried to read a lot on internet but anything let me come out.

I modified HAL_I2C_MspInit() as i read that i2c clk enable needed to be before the gpio clk enable, added also the reset.

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hi2c->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */
	__HAL_RCC_I2C1_CLK_ENABLE();		//ADDED BEFORE GPIO CLK
	__HAL_RCC_I2C1_FORCE_RESET();		//RESET
	__HAL_RCC_I2C1_RELEASE_RESET();		//RESET
  /* USER CODE END I2C1_MspInit 0 */
 
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**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;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
    /* Peripheral clock enable */
    //__HAL_RCC_I2C1_CLK_ENABLE();	//REMOVED
  /* USER CODE BEGIN I2C1_MspInit 1 */
 
  /* USER CODE END I2C1_MspInit 1 */
  }
 
}

I tried as STM sais on errdata their workaroud about analog filter adding those functions that i hope are corrects.

void test(void){
	HAL_I2C_DeInit(&hi2c1);
	//1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
	hi2c1.Instance->CR1 &= ~(1 << 0);
	//2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
 
	GPIOB->CRL |= 3 << 24;
	GPIOB->CRL |= 3 << 28;
	GPIOB->CRL |= 1 << 26;
	GPIOB->CRL |= 1 << 30;
	GPIOB->BSRR |= 1 << 6;
	GPIOB->BSRR |= 1 << 7;
	//3. Check SCL and SDA High level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) != GPIO_PIN_SET && HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) != GPIO_PIN_SET){
 
	}
	//4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
	GPIOB->BSRR |= 1 << 23;
	//5. Check SDA Low level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET){
 
	}
	//6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
	GPIOB->BSRR |= 1 << 22;
	//7. Check SCL Low level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == GPIO_PIN_SET){
 
	}
	//8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
	GPIOB->BSRR |= 1 << 6;
	//9. Check SCL High level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) != GPIO_PIN_SET){
 
	}
	//10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
	GPIOB->BSRR |= 1 << 7;
	//11. Check SDA High level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) != GPIO_PIN_SET){
 
	}
	//12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
	GPIOB->CRL |= 3 << 26;
	GPIOB->CRL |= 3 << 30;
	//13. Set SWRST bit in I2Cx_CR1 register.
	hi2c1.Instance->CR1 |= 1 << 15;
	//14. Clear SWRST bit in I2Cx_CR1 register.
	hi2c1.Instance->CR1 &= ~(1 << 15);
	//15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
	hi2c1.Instance->CR1 |= 1 << 0;
 
	HAL_I2C_Init(&hi2c1);
}

Also tried in an other way as i saw.

void test_1(void){
	GPIO_InitTypeDef strutturaGPIO = {0};
 
 
	//1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
	hi2c1.Instance->CR1 &= ~(1 << 0);
	//2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
	HAL_I2C_DeInit(&hi2c1);
 
	strutturaGPIO.Pin = GPIO_PIN_6|GPIO_PIN_7;
	strutturaGPIO.Mode = GPIO_MODE_OUTPUT_OD;
	strutturaGPIO.Pull = GPIO_PULLUP;
	strutturaGPIO.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOB, &strutturaGPIO);
 
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
 
	//3. Check SCL and SDA High level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) != GPIO_PIN_SET && HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) != GPIO_PIN_SET){
 
	}
	//4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
	//5. Check SDA Low level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET){
 
	}
	//6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
	//7. Check SCL Low level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == GPIO_PIN_SET){
 
	}
	//8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
	//9. Check SCL High level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) != GPIO_PIN_SET){
 
	}
	//10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
	//11. Check SDA High level in GPIOx_IDR.
	while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) != GPIO_PIN_SET){
 
	}
	//12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
	strutturaGPIO.Pin = GPIO_PIN_6|GPIO_PIN_7;
	strutturaGPIO.Mode = GPIO_MODE_AF_OD;
	strutturaGPIO.Pull = GPIO_PULLUP;
	strutturaGPIO.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOB, &strutturaGPIO);
	//13. Set SWRST bit in I2Cx_CR1 register.
	hi2c1.Instance->CR1 |= 1 << 15;
	//14. Clear SWRST bit in I2Cx_CR1 register.
	hi2c1.Instance->CR1 &= ~(1 << 15);
	//15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
	hi2c1.Instance->CR1 |= 1 << 0;
 
	HAL_I2C_Init(&hi2c1);
}

I have my 4.7k pull up resistors on 3.3 V , i cannot get it work on both original STM MCU.

By the way i was working with i2c on a fake MCU CSK and it was working fine.

I use cubemx so i let it generate everything.

Debugging it seem that HAL_GPIO_Init(GPIOB, &GPIO_InitStruct) in HAL_I2C_MspInit() put Bus busy high.

I tried with nothing on the line or also with a ads1115.

Thanks a lot

1 ACCEPTED SOLUTION

Accepted Solutions
Stequila93
Associate II

Well thanks,

I found out that it was not setting up the speed of the gpio in the structure sent to the gpio init, so it was set up as input and not as output OD.

 0693W00000DqCKsQAN.jpgBy the way it's generated by stmcube so is it missing while generating or i missed something in cube?

Thanks again

View solution in original post

11 REPLIES 11

Yeah, got bad memories about the F1 / I2C

Seem to remember I needed to ENABLE the I2C via CR, before initializing, at least in SPL days

Would double check the AFIO, GPIO and I2C clocks.

Make sure I2C is properly mapped, and perhaps conflicting peripherals are remapped off those pins.

Check Errata

Make sure structure is properly cleared/initialized.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Stequila93
Associate II

Hello Thanks,

I tried to enable in the CR1 register but i keep getting error before initializing.

About AFIO i don't see anything of strange i would check it better tomorrow.

I checked in the register if was mapped at 0 for pin 6 7 and its fine, i have nothing over i2c1 its an empty project with just swd debug.

Errata was saying what i did (maybe i did it wrong).

Is fine that in GPIO_INIT set pin 6 and 7 as INPUT?

0693W00000Dq9JXQAZ.jpgI'm getting MODE 00 and CNF 11 on the table configuration is "reserved".

It doesnt match with what i set up on stmcube that was output open drain with no pullup.

I'll check more tomorrow.

Thanks a lot.

Stequila93
Associate II

Well thanks,

I found out that it was not setting up the speed of the gpio in the structure sent to the gpio init, so it was set up as input and not as output OD.

 0693W00000DqCKsQAN.jpgBy the way it's generated by stmcube so is it missing while generating or i missed something in cube?

Thanks again

Thank you a lot I was desperatly trying to understand why the I2C didn't work and your solution worked for me. In 2022 MxCube is still generating the I2C the wrong way.

Hi,

I am also facing similar issue with I2C not working when used from STMcubeMx and STM32cubeID...we should just change the GPIO_Initstruct.Speed ??

can we still use HAL_I2C_Transmit and Rx??

should we use the same code of bitbang and then change the code..

Kindly suggest as we are working with STM32TC6T6 here...

Thanks

regards

Ravi

RShiv.1
Senior

Hi,

attached is the code you had shared as above...but still facing issues with I2C..

I have chosen I2C as PB6 and PB7 ...do we need to change this to GPIO output..If so why in the above code HAL_I2C_INIT() is also present??....any change in the code let me know.

Thanks

Ravi

RShiv.1
Senior

Hi,

any update kindly let me know so that I can try the I2C changes and see whether this works..

You have defined GPIO as well as I2C ..wanted to know how you compiled and how this was run..

regards

Ravi

Hi ,

Any update here on how I2C can be worked out from updated CUbeMX such that I can use for STM32F103C6T6...we are using SCD30 sensor..kindly let me know if you have any suggestion or code which you can share..thanks

Ravi

HI,@RShiv.1​ 

I have also a stm32c6t6, the i2c code generated by the stm32cubeMX didn't works.

The solution is in the answer of this post.

The i2c initialization tree is:

  1. main.c: main()
  2. main.c: MX_I2C1_Init()
  3. ./Driver/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c: HAL_I2C_Init()
  4. Core/Src/stm32f1xx_hal_msp.c: HAL_I2C_MspInit() //<-- probleme here

You have to do:

  • open ./Core/Src/stm32f1xx_hal_msp.c
  • find HAL_I2C_MspInit(), about line 102

   GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;

   GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

   GPIO_InitStruct.Pull = GPIO_PULLUP;

   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  • add the missing Speed member of GPIO, you can set it LOW MEDIUM OR HIGH, all works, but you have to set something 😅