-
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_lp_core_i2c during deep sleep doesn't pull signal low enough (IDFGH-11883) #12969
Comments
Hello @JochemHomewizard, |
Thanks for your reply. I just tried running this code with deep sleep turned off, and I see the same kind of output with the logic low at ~900mV. It seems to be purely caused by LP_I2C. |
Thank you for the confirmation. We will look into this and keep the issue updated with our findings. |
I have tested on the same development board. When using a self-made I2C using simple GPIO-bitbanging we see the same behaviour. If we configure the GPIO using // main code
rtc_gpio_init(GPIO_I2C_SDA);
rtc_gpio_set_direction(GPIO_I2C_SDA, RTC_GPIO_MODE_INPUT_OUTPUT_OD);
rtc_gpio_set_direction_in_sleep(GPIO_I2C_SDA, RTC_GPIO_MODE_INPUT_OUTPUT_OD);
rtc_gpio_pulldown_dis(GPIO_I2C_SDA);
rtc_gpio_pullup_dis(GPIO_I2C_SDA);
rtc_gpio_init(GPIO_I2C_SCL);
rtc_gpio_set_direction(GPIO_I2C_SCL, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_direction_in_sleep(GPIO_I2C_SCL, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_pulldown_dis(GPIO_I2C_SCL);
rtc_gpio_pullup_dis(GPIO_I2C_SCL);
ulp_lp_core_load_binary(lp_core_main_bin_start, (lp_core_main_bin_end - lp_core_main_bin_start));
ulp_lp_core_cfg_t core_cfg = {
.wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_LP_TIMER,
.lp_timer_sleep_duration_us = MEASUREMENT_TIME * SEC_TO_USEC, // Wakes up every 'measurement time' seconds to measure once
};
ulp_lp_core_run(&core_cfg);
esp_deep_sleep_start(); // LP core code
void send_bit(uint8_t level)
{
rtcio_ll_set_level(GPIO_I2C_SDA, level);
ulp_lp_core_delay_us(250);
rtcio_ll_set_level(GPIO_I2C_SCL, 1);
ulp_lp_core_delay_us(250);
rtcio_ll_set_level(GPIO_I2C_SCL, 0);
ulp_lp_core_delay_us(250);
}
void get_ack(bool *ack_received)
{
rtcio_ll_set_level(GPIO_I2C_SDA, 1);
ulp_lp_core_delay_us(250);
rtcio_ll_set_level(GPIO_I2C_SCL, 1);
ulp_lp_core_delay_us(250);
*ack_received = rtcio_ll_get_level(GPIO_I2C_SDA);
rtcio_ll_set_level(GPIO_I2C_SCL, 0);
ulp_lp_core_delay_us(250);
}
void send_byte(uint8_t data)
{
for (uint8_t i = 0; i < 8; i++)
{
send_bit(data & 0x80);
data <<= 1;
}
bool ack_received;
get_ack(&ack_received);
}
send_start();
send_byte(AHT20_I2C_ADDR << 1); // 0x38 0b0111000
send_byte(AHT20_CMD_MEASURE_BYTE1);
send_byte(AHT20_CMD_MEASURE_BYTE2);
send_byte(AHT20_CMD_MEASURE_BYTE3);
send_stop(); When looking at this, we see no esp-idf/components/ulp/lp_core/lp_core_i2c.c Lines 46 to 64 in b3f7e2c
|
Hey @sudeep-mohanty, sorry to bother but do you have an update maybe? |
Hello @DCSBL, |
Thanks! It seems to be the case indeed, as fixing this while using direct GPIO bit-bang fixed the issue for us after selecting OD.
@JochemHomewizard can I assign this to you? After this we will get back to you Sudeep! |
@sudeep-mohanty Thanks for the patch! With your patch it works without any issues. This solved the problem. |
Thanks for testing out the patch @JochemHomewizard! Glad it worked. I shall do some further tests on the changes and formalize the fix asap! Thanks! |
…n-drain mode This commit fixes an issue where in the LP I2C IO lines were not initialized in open-drain mode. Closes #12969
…n-drain mode This commit fixes an issue where in the LP I2C IO lines were not initialized in open-drain mode. Closes #12969
Answers checklist.
General issue report
For my project I read a temperature sensor (AHT20) using I2C. It reads it's temperature during deep sleep using the ULP Core on the ESP32-C6. I noticed not all measurements are performed correctly and sometimes the values seem to be very off. In order to find the cause of this I used a logic analyser which showed the following signal:
From this logic output I was able to conclude that the logic low of the signal isn't always zero. Sometimes it's zero but often it sticks at ~900mV. This issue with the logic low always takes place at the same places during transmissions.
Also there seem to be small voltage spikes when the ACK is send.
This is the code I'm running in order to initialise the I2C communication before going into deep sleep:
The ULP uses the following functions to write and read data during deep sleep:
For the temperature sensor I used the recommended circuit:
A few things I tried:
Since this issue only occurs while reading the I2C sensor with the ULP core during deep sleep, it seems to be related to ulp_lp_core_i2c. Also note that the exact same thing happens with a completely different I2C sensor.
The text was updated successfully, but these errors were encountered: