-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ULP-RISCV I2C does not work when reading/writing multiple bytes (IDFGH-11056) #12235
Comments
Issue split from #12214 |
@aircable I'm following up from the issue you reported here. May I ask which I2C sensor are you using for the multi-byte read/write test? Also, would it be possible to try out with the IDF example which uses a BMP180 sensor, just to rule out any setup related issues. Thanks! |
Of course, the sensor is the KXTJ3 accelerometer. It is able to automatic advance the address and return consecutive results as you can see when using the I2C driver (works fine) and not the RTC hardware. Sorry I don't have a BMP180 but I bet it has the same issue. BTW it appears that when using the ULP for multiple data read it also fails, but I cannot see any error messages, obviously. The second byte read is always zero. |
Thanks for the reply. I don't have the KXTJ3 at hand but I'll try to scour for one or something similar to reproduce the issue. The error message In the meantime, what would give me some more insight is a logic analyzer capture in case you have one at hand. Basically, what I would like to know is if the sensor is indeed sending the second byte during the read operation and if the driver is failing to capture it and then reports an error. |
Sorry, not yet. Don't have a LA, my Osci may do it, but the hardware is too much integrated.
multiple register read works just fine. |
I meet a lot of problems in ULP-RISCV I2C. Using ULP-RISCV I2C on the XTENSA core, main processor on an ESP32-S3 always get timeout error 0x107 return from ulp_riscv_i2c_wait_for_interrupt() in line 352 of components/ulp/ulp_riscv/ulp_riscv_i2c.c . I find a possible reason that vTaskDelay(1) is too long in line 367 of the same file. vTaskDelay(1) means 10ms with #define CONFIG_FREERTOS_HZ 100. But in ULP-RISCV I2C one byte is about 0.1ms in CLK 100khz. I edit vTaskDelay(1); to esp_rom_delay_us(1); , then no error display. The I2C slave device or sensor works correctly with the standard I2C master on Espressif SoCs. |
Thanks @aircable @shangke1988 for sharing the details. I can confirm that I can reproduce the issue of multiple byte read/write failing on the BMP180. At the moment, the workaround of doing the read/write in a loop of single-byte transactions should work. I shall investigate more to see if a better solution can be made as the HW is a bit limited in terms of capabilities. |
Hi @sudeep-mohanty, thanks for confirming. With respect to FreeRTOS, I always run with 1kHz and tickless idle. |
Any progress so far on this issue? I am running into problems as soon as I try to write multiple bytes in one go using ulp_riscv_i2c_master_write_to_device. This code: uint8_t config_values[6] = {0b11111110, 0b11111111, 0b01111110, 0b11110010, 0b00000000, 0b00000000}; causes my ESP32-S3 to initiate this I2C communication: 0xB0,W,0x02 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE (intercepted with logic analyzer). So it always just repeats the first byte for the number of bytes set with "size". I have confirmed this by setting different values for byte [1]. Is there any solution other than to revert to sending the data bytewise? I would like to avoid the overhead that comes with this. |
Pull latest version and many i2c bugs are solved |
Thank you for your reply, but I am on ESP-IDF v5.2.1. Or are you referring to the development master branch? Edit: I also found release v5.3, didn't know that existed. Will see how it goes, thank you. |
I am now using the latest master branch, but sadly the issue remains. I noticed that when I include "esp-idf\components\ulp\ulp_riscv\include\ulp_riscv_i2c.h" in my code, the called functions such as "ulp_riscv_i2c_master_write_to_device" are linked to "esp-idf\components\ulp\ulp_riscv\ulp_core\ulp_riscv_i2c.c", instead of to "esp-idf\components\ulp\ulp_riscv\ulp_riscv_i2c.c". Is this intended? If so, what is the other ulp_riscv_i2c.c for? |
Hello @Ethapus,
Unfortunately, the issue of RTC_I2C failing to perform multiple bytes read/write operations exists on the mainline as well as the release branches currently.
The functions in Finally, after debugging the multi-byte read/write issue further, I could see that the Xtensa core APIs are the ones which get stuck doing the multi-byte read or write. This seems to be because of non-atomic peripheral operations. The following patch adds atomicity to the APIs and in my tests I could see successful multi-byte reads/writes. Additionally, I found that the ULP RISC-V core APIs do not suffer from this problem. Before I could finalize the bugfix, it would be great if you could test it out at your end and let me know if it fixes your problem. The following patch is generated on the latest master branch but should also be applicable to any previous release branches as well. Thank you! |
Thank you very much for looking into the matter! Sadly applying the patch fails on my master branch esp-idf. Here is the CMD log: C:\Users\johnl\esp\master\esp-idf>git pull C:\Users\johnl\esp\master\esp-idf>git apply rtc_i2c_multi_byte.patch -v static esp_err_t i2c_gpio_is_cfg_valid(gpio_num_t sda_io_num, gpio_num_t scl_io_num) error: patch failed: components/ulp/ulp_riscv/ulp_riscv_i2c.c:47 |
Interestingly the functions in components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c seems to get linked to the main core application binary (Xtensa core) in my code before the ulp application binary is even loaded. Not sure if that is an error on my part or a bug? Anyways, it does work, so long as only byte is written at a time... |
Okay, something must have been awry in my local files, "git reset --hard origin/master" solved the issue. Sorry for not checking that before. Anyways, I successfully installed the patch and am happy to report that my esp32 s3 now flawlessly reads and writes multiple bytes using ulp_riscv_i2c_master_read_from_device respectively ulp_riscv_i2c_master_write_to_device. This works from both main core application as well as ulp application, even though the main core application still seems to reference components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c for some reason. But it works, and that is what matters. I thank you very much for the quick response and for solving the issue! |
Thanks for the confirmation @Ethapus. I shall add the fix after a few more tests. |
…SC-V This commit fixes an issue where multi-byte reads and writes over the RTC I2C peripheral got stuck on the esp32s2 and esp32s3. Closes #12235
…SC-V This commit fixes an issue where multi-byte reads and writes over the RTC I2C peripheral got stuck on the esp32s2 and esp32s3. Closes #12235
…SC-V This commit fixes an issue where multi-byte reads and writes over the RTC I2C peripheral got stuck on the esp32s2 and esp32s3. Closes #12235
Answers checklist.
IDF version.
master 5.2.2
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
ESP32S3-PICO-1
Power Supply used.
External 3.3V
What is the expected behavior?
I expected to be able to read multiple bytes with
ulp_riscv_i2c_master_read_from_device
What is the actual behavior?
The first byte read (or write) works, but he second one fails with those errors,
Steps to reproduce.
Debug Logs.
No response
More Information.
No response
The text was updated successfully, but these errors were encountered: