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

11 REPLIES 11
RShiv.1
Senior

Hi,

Thanks for your suggestion...currently we are using cubeMx to generate the code..instead of C6 our code worked on C8.

but as you suggested Core/Src/stm32f1xx_hal_msp.c this file itself is not generated now..

Inside HAL_I2C_Init function itself we have HAL_I2C_MspInit(hi2c);...if I flow through this we get one more function like this...

 */

__weak void HAL_MspInit(void)

{

 /* NOTE : This function should not be modified, when the callback is needed,

      the HAL_MspInit could be implemented in the user file

  */

}

can we modify the GPIO.speed here..for C6 ???...kindly let me know..so that we need not change to C8

thanks

Ravi

I just tried to generate the stm32f103C8T6 code from stm32cubeMX.

In the ./Core/Src, the file stm32f1xx_hal_msp.c is generated with:

```c

GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral clock enable */

__HAL_RCC_I2C1_CLK_ENABLE();

```

which have SPEED set. This is the missing line/param in the generated c6t6 code by stm32cubeMX.

ps: HAL_I2C_MspInit in the Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c have __weak attribute, which means, if there are two function with the same name, the __weak one will not be chosen. (e.g replaced by the same function in the ./Core/Src/stmf1xx_hal_msp.c: line 85, HAL_I2C_MspInit() )