HAL_I2C_Slave_Receive fails to read data from ESP32 waiting for I2C_FLAG_RXNE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-05-08 1:35 AM
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.
- Labels:
-
I2C
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-05-08 1:57 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-05-08 7:57 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2023-05-08 6:52 PM
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.
