cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_Slave_Receive fails to read data from ESP32 waiting for I2C_FLAG_RXNE

Nicklas B
Associate II

Hi!

I am having trouble using HAL_I2C_Slave_Receive for receiving data. Troubleshooting, I am finding that HAL_I2C_Slave_Receive times out or gets a I2C_FLAG_STOPF flag in I2C_WaitOnRXNEFlagUntilTimeout.

I know that the I2C network and pull-ups work, because:

  • The STM32 is successfully communicating with ESP32s as a master, both writing and reading.
  • The ESP32s are successfully communicating in between themselves in both roles
  • If I tell HAL_I2C_Slave_Receive the exact number of bytes to read, in this case 14, I then see that the correct data ends up in the buffer, even though the HAL_I2C_Slave_Receive returns an error. Like:
HAL_I2C_Slave_Receive(&I2cHandle, data, 14, 5000);

However, there seems to be some incompatibility, and as the ESP32:s are happy with what HAL_I2C_Master_Transmit sends them, so I am suspecting that the problem is on the STM32 side.

I have tried with:

  • I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_ENABLED and *DISABLED
  • Different speeds (10000-400000)
  • Changing the duty cycles
  • Different stuff on the ESP32 side

My config:

GPIO_InitTypeDef GPIO_InitStruct = {0};
 
    __HAL_RCC_GPIOB_CLK_ENABLE();
 
    GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    // GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  
    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
    __HAL_RCC_SYSCFG_CLK_ENABLE();
    __HAL_RCC_PWR_CLK_ENABLE();
 
    HAL_Init();
 
    I2cHandle.Instance = I2C1;
    I2cHandle.Init.OwnAddress1 = CONFIG_I2C_ADDR << 1; // This needs to be left-shifted. 
    I2cHandle.Init.ClockSpeed = 100000; 
    I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
    I2cHandle.Init.OwnAddress2 = 0;
    //I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
    I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
    I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
 
 
    int init_ret = HAL_I2C_Init(&I2cHandle);

Versions:

I am using the current ststm32-platform (https://github.com/platformio/platform-ststm32) for PlatformIO, specifically, stm32f1xx_hal_i2c.c. However it seems to me that this might not be a distribution issue.

3 REPLIES 3
Foued_KH
ST Employee

Hello @Nicklas Börjesson​ ,

Look at the I2C lines with a scope instead of a logic analyzer to see the SDA and SCL behavior.

I think you are using the wrong address for the transmission.

Foued

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.

Hi Foued,

Thanks for your reply; I have tried all kinds of variants with the addresses, If I change the address, I won't get as far (ADDR flag won't be set). Which I interpret as I am using the right one.

Or is it more to the addressing?

Don't have a very good oscilloscope, I am afraid..

Kind regards, Nicklas

Harvey White
Senior III

For debugging, you can get an inexpensive logic analyzer, 8 bits. Should be (in the US) about 10 USD or so. It has both 8 bit logic channels, and a decode function. You take data or data/clock and connect one or two channels to it. You can then decode such things as I2C, SPI, etc. There are limitations to this, but the price is not too bad, and it only requires a USB port to run. I'm assuming WIndows here, not sure about the availability of the program for other OS.