Skip to main content
Mujtaba
Associate III
March 11, 2019
Question

I2C3 Bus Busy issue!

  • March 11, 2019
  • 13 replies
  • 2711 views

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.

This topic has been closed for replies.

13 replies

Amel NASRI
ST Technical Moderator
March 11, 2019

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 "Best Answer" on the reply which solved your issue or answered your question.
Mujtaba
MujtabaAuthor
Associate III
March 11, 2019

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.

Amel NASRI
ST Technical Moderator
March 11, 2019

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 "Best Answer" on the reply which solved your issue or answered your question.
AvaTar
Senior III
March 11, 2019

> 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 ?

Mujtaba
MujtabaAuthor
Associate III
March 11, 2019

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.

AvaTar
Senior III
March 11, 2019

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.