cancel
Showing results for 
Search instead for 
Did you mean: 

I2C3 Bus Busy issue!

Mujtaba
Senior

Dear friends,

I am trying to read data from DS3231 RTC using SPI3 peripheral of STM32407VGt6 MCU.

At first I used the latest version of HAL drivers and Cube and easily could read/wrtie the DS3231 RTC module.

But now I need to use Standard Peripheral libraries to read data from RTC module and also read data from it.

The problem is as soon as the APB1 peripheral clock of I2C3 is set, the Busy bit is set too while there is no ongoing communications since the MCU acts as the Master device and provides the clock for the module and the MCU has not yet START the communication.

I have checked the RCC, GPIO and I2C3 peripheral registers in debug mode and all are the same in HAL written program and StdPeriLib written program.

The initialization code for I2C3 is as follows:

void Ds3231_Low_Level_Init(void)

{

   GPIO_InitTypeDef  ds3231_gpio_initstruct;

   I2C_InitTypeDef   ds3231_i2c_initstruct;

 /* DS3231_I2C_SCL_GPIO_CLK and DS3231_I2C_SDA_GPIO_CLK Periph clock enable */

 RCC_AHB1PeriphClockCmd(DS3231_I2Cx_SCL_RCC_AHB_PERIPH | DS3231_I2Cx_SDA_RCC_AHB_PERIPH, ENABLE);

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 /* DS3231_I2C Periph clock enable */

 RCC_APB1PeriphClockCmd(DS3231_I2Cx_CLK, ENABLE);

   /* DS3231 Peripheral Disable */

   I2C_Cmd(DS3231_I2Cx ,DISABLE);

   /* DS3231 DeInit */

   I2C_DeInit(DS3231_I2Cx);

// /* Reset DS3231_I2C IP */

// RCC_APB1PeriphResetCmd(DS3231_I2Cx_CLK, ENABLE);

// 

// /* Release reset signal of DS3231_I2C IP */

// RCC_APB1PeriphResetCmd(DS3231_I2Cx_CLK, DISABLE);

 /* GPIO configuration */

 /* Connect PXx to I2C_SCL*/

 GPIO_PinAFConfig(DS3231_I2Cx_SCL_GPIO_PORT, DS3231_I2Cx_SCL_SOURCE, DS3231_I2Cx_SCL_AF);

 /* Connect PXx to I2C_SDA*/

 GPIO_PinAFConfig(DS3231_I2Cx_SDA_GPIO_PORT, DS3231_I2Cx_SDA_SOURCE, DS3231_I2Cx_SDA_AF); 

// 

   /* Configure DS3231_I2C pins: SCL */

   ds3231_gpio_initstruct.GPIO_Pin   = DS3231_I2Cx_SCL_GPIO_PIN;

  ds3231_gpio_initstruct.GPIO_Mode   = GPIO_Mode_AF;

 ds3231_gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;

  ds3231_gpio_initstruct.GPIO_OType = GPIO_OType_OD;

 ds3231_gpio_initstruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

   GPIO_Init(DS3231_I2Cx_SCL_GPIO_PORT, &ds3231_gpio_initstruct);

   /* Configure DS3231_I2C pins: SDA */

   ds3231_gpio_initstruct.GPIO_Pin   = DS3231_I2Cx_SDA_GPIO_PIN;

   GPIO_Init(DS3231_I2Cx_SCL_GPIO_PORT, &ds3231_gpio_initstruct);

   /* I2C configuration */

 /* DS3231_I2C configuration */

 ds3231_i2c_initstruct.I2C_Mode = I2C_Mode_I2C;

 ds3231_i2c_initstruct.I2C_DutyCycle = I2C_DutyCycle_2;

 ds3231_i2c_initstruct.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;

 ds3231_i2c_initstruct.I2C_Ack = I2C_Ack_Enable;

 ds3231_i2c_initstruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

 ds3231_i2c_initstruct.I2C_ClockSpeed = I2C_SPEED;

 /* DS3231_I2C Peripheral Enable */

 I2C_Cmd(DS3231_I2Cx, ENABLE);

 /* Apply DS3231_I2C configuration after enabling it */

 I2C_Init(DS3231_I2Cx, &ds3231_i2c_initstruct);

}

As soon as RCC_APB1PeriphClockCmd(DS3231_I2Cx_CLK, ENABLE); is called the Busy bit in I2C3->SR2 register is set.

Could anyone help me where the problem is?

Any helps would be appreciated.

I am using standard peripheral library version 1.8.0.

13 REPLIES 13
Amel NASRI
ST Employee

Hello @Mujtaba​ ,

You need to configure GPIOs first, then enable I2C clock.

void Ds3231_Low_Level_Init(void)
{
   GPIO_InitTypeDef  ds3231_gpio_initstruct;
   I2C_InitTypeDef   ds3231_i2c_initstruct;
 
 /* DS3231_I2C_SCL_GPIO_CLK and DS3231_I2C_SDA_GPIO_CLK Periph clock enable */
 RCC_AHB1PeriphClockCmd(DS3231_I2Cx_SCL_RCC_AHB_PERIPH | 
 DS3231_I2Cx_SDA_RCC_AHB_PERIPH, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
 
 /* GPIO configuration */
 /* Connect PXx to I2C_SCL*/
 GPIO_PinAFConfig(DS3231_I2Cx_SCL_GPIO_PORT, DS3231_I2Cx_SCL_SOURCE, 
 DS3231_I2Cx_SCL_AF);
 
 /* Connect PXx to I2C_SDA*/
 GPIO_PinAFConfig(DS3231_I2Cx_SDA_GPIO_PORT, DS3231_I2Cx_SDA_SOURCE, 
 DS3231_I2Cx_SDA_AF); 
 
   /* Configure DS3231_I2C pins: SCL */
  ds3231_gpio_initstruct.GPIO_Pin   = DS3231_I2Cx_SCL_GPIO_PIN;
  ds3231_gpio_initstruct.GPIO_Mode   = GPIO_Mode_AF;
  ds3231_gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
  ds3231_gpio_initstruct.GPIO_OType = GPIO_OType_OD;
  ds3231_gpio_initstruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(DS3231_I2Cx_SCL_GPIO_PORT, &ds3231_gpio_initstruct);
 
   /* Configure DS3231_I2C pins: SDA */
   ds3231_gpio_initstruct.GPIO_Pin   = DS3231_I2Cx_SDA_GPIO_PIN;
   GPIO_Init(DS3231_I2Cx_SCL_GPIO_PORT, &ds3231_gpio_initstruct);
 
 /* I2C configuration */
 /* DS3231_I2C Periph clock enable */
 RCC_APB1PeriphClockCmd(DS3231_I2Cx_CLK, ENABLE);
 
   /* DS3231 Peripheral Disable */
   I2C_Cmd(DS3231_I2Cx ,DISABLE);
 
   /* DS3231 DeInit */
   I2C_DeInit(DS3231_I2Cx);
 
 /* DS3231_I2C configuration */
 ds3231_i2c_initstruct.I2C_Mode = I2C_Mode_I2C;
 ds3231_i2c_initstruct.I2C_DutyCycle = I2C_DutyCycle_2;
 ds3231_i2c_initstruct.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
 ds3231_i2c_initstruct.I2C_Ack = I2C_Ack_Enable;
 ds3231_i2c_initstruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
 ds3231_i2c_initstruct.I2C_ClockSpeed = I2C_SPEED;
 
 /* DS3231_I2C Peripheral Enable */
 I2C_Cmd(DS3231_I2Cx, ENABLE);
 
 /* Apply DS3231_I2C configuration after enabling it */
 I2C_Init(DS3231_I2Cx, &ds3231_i2c_initstruct);
}

-Amel

PS: You can use the "Code snippet" option when formatting your question so that code section becomes more readable.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

AvaTar
Lead

> As soon as RCC_APB1PeriphClockCmd(DS3231_I2Cx_CLK, ENABLE); is called the Busy bit in I2C3->SR2 register is set.

Even after POR ?

Do you have proper pull-up resistors, and have you physically checked the lines at this state ?

Dear @Amel NASRI​ ,

Thanks for your quick reply.

I've changed the code line as you said, but still after enabling I2C3 clock, the busy bit is set.

I don't have this problem with HAL drivers.

Dear @Community member​ ,

there is a reset button on the board, when I press it while I'm in debug mode, the Busy bit is reset and as soon as I release the button, the Busy bit is set.

There are pull-up resistors in the board. As I said when I use HAL libraries there is no problem so the board works fine but when using SPL drivers or even when I write the read and write functions in registry , the Busy bit is set after enabling the I2C3 clock.

A power-on-reset and a reset via NRST pin are not exactly the same.

> As I said when I use HAL libraries there is no problem so the board works fine but when using SPL drivers or even when I write the read and write functions in registry , the Busy bit is set after enabling the I2C3 clock.

You might have missed or changed something in the configuration.

One quick way would be to make "snapshot" of the I2C3 config register values after init for both variants in the debugger, and compare.

> You might have missed or changed something in the configuration.

One quick way would be to make "snapshot" of the I2C3 config register values after init for both variants in the debugger, and compare.

I've already investigated that but both configurations are the same except for the SR2 ( Busy bit is set) and in CR1, ACK bit is set in SPL configurations.

I'm very confused why it happens.

I've also checked the GPIO and RCC registers and they are the same too!

I don't know ...

Perhaps a difference in the clock tree setup ?

The RCC clock initialization code is as follows:

void RCC_Init(void)
{
	ErrorStatus hse_startup;
	
	RCC_DeInit();
	
	RCC_HSEConfig(RCC_HSE_ON);
	hse_startup = RCC_WaitForHSEStartUp();
	
	if(hse_startup != ERROR)
	{
 
		RCC_PLLConfig(RCC_PLLSource_HSE, PLLM_DIV_FACTOR, PLLN_MUL_FACTOR, PLLP_DIV_FACTOR, PLLQ_DIV_FACTOR);
		RCC_PLLCmd(ENABLE);
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != SET);
		/* Configure SYSCLK to 168MHz */
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		/* Wait until the PLLCLK is used for SYSCLK */
		while(RCC_GetSYSCLKSource() != 0x08);
		/* Configures the AHB clock (HCLK) to 168MHz */
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		/* Configures the Low Speed APB clock (PCLK1) to 42MHz */
		RCC_PCLK1Config(RCC_HCLK_Div4);
		/* Configures the High Speed APB clock (PCLK2) to 84MHz */
		RCC_PCLK2Config(RCC_HCLK_Div2);
	}
		
}

where:

#define PLLM_DIV_FACTOR            (25UL)

#define PLLN_MUL_FACTOR           (336UL)

#define PLLP_DIV_FACTOR            (2UL)

#define PLLQ_DIV_FACTOR             (4UL)

With above configurations the system clock and AHB1 clock will be 168MHz.

(The HSE input clock is 25MHz)

Does the behavior change if you move the calls of GPIO_PinAFConfig after GPIO_Init or after I2C_Init?

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.