2023-02-10 10:53 PM
I'm using I2C2 engine of the STM32F767ZI MCU on PF0 & PF1 pins as master to communicate with 4 slaves at 75khz. The operation is not using Interrupt on tx/rx or DMA and with FreeRTOS environment
SCL and SDA are pulled up on board with 4.99K.
The polling frequency for data with slaves is ~250msec. after few cycles,the I2C2 stops exchanging data (~1000 cycles) and always shows busy state. I tried different I2C frequency (50khz to 400 kHz), but behavior is persistent across all clock freq.
To recover, I've to reset entire i2c2 engine.
here is the code :
//@196 MHz clock freq.. if clock changes, these values will change
#define BSW_I2C2_SCL_CLOCK_50KHZ (0x001006E8)
#define BSW_I2C2_SCL_CLOCK_75KHZ (0x00100B91)
#define BSW_I2C2_SCL_CLOCK_100KHZ (0x00100B68)
#define BSW_I2C2_SCL_CLOCK_200KHZ (0x00100432)
#define BSW_I2C2_SCL_CLOCK_400KHZ (0x00100413)
UINT32 Init_I2C2(void)
{
stat_I2C2_Handle.Instance = I2C2;
stat_I2C2_Handle.Init.Timing = BSW_I2C2_SCL_CLOCK_100KHZ;
stat_I2C2_Handle.Init.OwnAddress1 = 0;
stat_I2C2_Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
stat_I2C2_Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
stat_I2C2_Handle.Init.OwnAddress2 = 0;
stat_I2C2_Handle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
stat_I2C2_Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
stat_I2C2_Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&stat_I2C2_Handle) != HAL_OK)
{
return I2C_ERROR_I2C2_INIT_FAILED;
}
return 0;
} //EOF
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance == I2C2)
{
I2C_NON_ISO_SCL_GPIO_CLK_ENABLE();
I2C_NON_ISO_SDA_GPIO_CLK_ENABLE();
// Peripheral clock enable
I2C_NON_ISO_CLK_ENABLE();
// I2C2 GPIO Configuration
// PF0 ------> I2C2_SDA
// PF1 ------> I2C2_SCL
GPIO_InitStruct.Pin = I2C_NON_ISO_SDA_PIN | I2C_NON_ISO_SCL_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = I2C_NON_ISO_SCL_SDA_AF;
HAL_GPIO_Init(I2C_NON_ISO_GPIO_PORT, &GPIO_InitStruct);
}
} //EOF
Is there any errata on i2c, I went through errata sheet and found there are few associated with i2c.
most notably : "Transmission stalled after first byte transfer". Is this same case of this errata ?
Or I'm missing something in configuration? The code is generated by Cube IDE
Note:
Different tasks are accessing I2C2 Engine and it is guarded by Mutex.
stm32 cube ide version : 1.10.1
firmware package : STM32Cube_FW_F7_V1.16.2
Any help on this would be helpful.
#STM32F7 #[STM32 MCUs]
2023-02-10 11:07 PM
Make sure the I2C signals are clean and there's no interference from surrounding circuitry. Try decreasing the pullup resistor's value.
JW
2023-02-10 11:27 PM
Thank you JW for your suggestion. I've attached logic analyser captures. signal's are looking clean. will play with pull up resistor values, but why I2C2 starts working again after resetting engine ?
I feel if it's hardware issue, then it shouldn't work/resume operation after resetting engine.
2023-02-11 12:29 AM
i have an I2C controlled dac and H743 at 200MHz; no rtos, use Cube+HAL lib.
100kHz i2c, about 70mm lines and 3k3 pullups.
after some time, 2 h or 15 min , no more communication.
some days ago was by chance pc connected, still in debug session; so i could see, whats going on - nothing. just I2C has busy bit set , so waiting for a new day or whatever.
solution was : reset I2C ->
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY))
{
/* Generate Stop */
hi2c->Instance->CR2 |= I2C_CR2_STOP;
__HAL_I2C_DISABLE(hi2c);
}
printf("I2C: restart \n");
drawText(108, 80, " I2Cerr " , RED , 0, 1);
__HAL_I2C_ENABLE(hi2c);
but this is no real solution that satisfies me .
the problem probably has the same cause.
+ i tried: