-
Notifications
You must be signed in to change notification settings - Fork 7.3k
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
Unable to call ulp_risv_i2c_master_init
from ULP code (IDFGH-13699)
#14571
Comments
ulp_risv_i2c_master_init
from ULP codeulp_risv_i2c_master_init
from ULP code (IDFGH-13699)
One thing that just occurred to me is that I'm using the Am I able to use the |
Hello @sidwarkd,
|
@sudeep-mohanty As always, I appreciate the quick response. Unfortunately I can't swap pins at this stage of the product's release but that's good to know as an option. So it looks like my option is to re-init the peripheral in the ULP domain. Any guidance the team can provide would be greatly appreciated on what portions of the init I need to recreate or if I basically have to copy the entire thing. Thanks again. |
@sudeep-mohanty Follow up ping to see if there is any guidance on peripheral init in the ULP domain. Thanks again for the help. |
Hi @sidwarkd. Apologies! I was off-work for a few days so I couldn't progress on this. I shall get back to you as soon as I have some updates. |
Hi @sidwarkd, As I understand, since you multiplex pin 3 for reading the sensor, the pin configuration probably is not open-drain anymore, which is why the I2C peripheral does not read any data correctly after you switch it back. So the approach I have is that you could re-initialize the pins for the I2C peripheral from the ULP RISC-V core. There are few assumptions to this approach -
With this in mind, you could use this new API, like below, to re-initialize the IOs for the I2C peripheral from the ULP RISC-V core -
In my limited testing, it works as expected. However, it would be nice to have this run in your setup before I could incorporate the changes. Please find a patch attached. |
@sudeep-mohanty Sorry for the delayed response. I was finally able to test this today. Thank you for providing a patch to try. Unfortunately, I am still having the issue and I think the reason is because the I2C state machine is in a bad state after switching to the one-wire device. I moved my entire logic out of the ULP domain and into the main CPU domain. The following sequence works:
If I repeat steps 1-6 I can read the I2C device and the one-wire device attached to pin 3 continuously over and over. However, if I remove step 1 and do not call the master_init on the I2C bus every time I switch between devices, I see the same behavior as in the ULP and the I2C device is unable to read. So it appears it's more than just re-configuring the pins. Is there some I2C state that also needs to be reset that we can do in the ULP domain? I very much appreciate your support and efforts on this issue. |
@sudeep-mohanty One other thought is if there is a way to pause the I2C peripheral while using one-wire from the ULP domain. Since the pin is shared it really feels like the one-wire communication is putting the I2C peripheral in a bad state that can only be recovered by calling the master_init function again. |
Hi @sidwarkd, On main core:
On ULP core:
The reason for suggesting this approach was the assumption that I2C peripheral is not in a "bad" state and can recover just by re-initializing the pins. Do let me know if this doesn't solve it and I can explore more on how can I get the complete re-initialization of the I2C from the ULP going. |
@sudeep-mohanty Sorry the confusion. I tried |
Thanks for the clarification @sidwarkd. I shall investigate it more and get back to you. |
Hi @sidwarkd, |
@sudeep-mohanty I tried to apply the patch but it failed. I reset my working directory and pulled the latest 5.3 but it still didn't apply. Here is the output of a few commands I ran showing the error message, IDF version, and which commit I'm on. Please let me know if I'm doing something wrong or if I should be on a different commit of IDF. |
@sidwarkd My bad. The patch I shared was for the latest |
@sudeep-mohanty I have now successfully read both I2C and one-wire devices repeatedly in the ULP domain. I'd still like to do some more testing but the preliminary results look very good. Due to some other commitments it will take me about a week to do more testing but I will post results here as soon as I'm able. Thank you for your continued support. |
Thanks for the confirmation, @sidwarkd! The changes are not final yet so I'd be grateful for any tests that you could do and let me know the results! Thank you! I shall work on finalizing the changes and will also be doing more tests at my end. |
@sudeep-mohanty Have run both types of sensors in the ULP domain without any issue. One strange behavior I saw was that calling the init function from the app domain a single time followed by the ulp domain caused issues trying to read from the I2C device (ENS210) unless I called the one-wire code in between. The following flow did not work:
The following flow, however, did work.
Unfortunately I don't have a lot of cycles to do more in-depth testing on this. The patch provided is working as long as I maintain the order of operations described and has my project unblocked. I very much appreciate your diligent efforts in identifying and providing a fix. If there are specific tests you would like me to run I will do my best to accommodate and help out. |
Thank you for the feedback @sidwarkd. One suggestion here is, it looks like it is not necessary to initialize the I2C from the app code. If it avoids the first incorrect read then that is one update you could make to your flow. |
@sudeep-mohanty Just as a follow up we have been running code in the ULP to read both an I2C sensor and one-wire sensor that share a muxed pin 3 and everything has been working fine. No other issues to report. |
@sudeep-mohanty One additional follow up here. Everything is working great but the addition of the call to Is there any way to reduce this impact? |
@sudeep-mohanty More information here. Before entering deep sleep our firmware calls |
HI @sidwarkd, Thanks for these updates. I haven't had the time to look in to this support since my last update. 300 uA is pretty high and isn't what I expected. I don't have an explanation currently to suggest what could be drawing the excess current. The patch itself is a proof-of-concept and isn't well tested so such unusual behavior can't be ruled out. I don't really have a timeline by when we could have this fully tested and merged though. |
Thanks for the response @sudeep-mohanty . I will post any updates here as we research it more on our end. |
Answers checklist.
IDF version.
v5.3
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
What is the expected behavior?
Should be able to call
ulp_riscv_i2c_master_init
from ULP C code.What is the actual behavior?
A linker error is returned
Steps to reproduce.
ulp_riscv_i2c_master_init
Project will fail to build.
Build or installation Logs.
More Information.
In our use case we have muxed pin 3 to also serve as a 1-wire interface. In the ULP domain we use I2C to interact with a temperature sensor, mux pin 3 to the 1-wire bus and read a sensor there. This works as expected. After reading the 1-wire device we mux pin 3 back to the I2C SDA line but all future readings fail.
After reading the 1-wire device I put pin 3 back into the IO state it needs to be for SDA (INPUT_OUTPUT_OD). My guess is that the 1-wire traffic puts the peripheral in a bad state. I can resolve this state by calling
ulp_riscv_i2c_master_init
from the app code. However, the point of the ULP is to be able to continuously do readings without the main application running. This is the reason why I'm trying to callulp_riscv_i2c_master_init
from ULP code.If there is some other way to effectively reset the RISCV I2C peripheral from the ULP domain that would also work.
The text was updated successfully, but these errors were encountered: