Closed Ankith-A-Muralidhar closed 3 years ago
I am also facing this issue @boarchuz Thanks for the help
I am also facing this issue. I hope someone will have some way to look at it. Thank you.
Try calling hulp_peripherals_on() any time before entering sleep. Also ensure your program ends with a halt instruction.
Try calling hulp_peripherals_on() any time before entering sleep. Also ensure your program ends with a halt instruction.
I tried it. still the issue persisits.
Hi @Ankith-A-Muralidhar , This is working as expected for me:
#include "esp_sleep.h"
#include "hulp.h"
#define PIN_LED GPIO_NUM_25
void init_ulp()
{
enum {
LBL_SET_1MIN,
LBL_SET_1SEC,
};
const ulp_insn_t program[] = {
M_GPIO_TOGGLE(PIN_LED),
M_BGE(LBL_SET_1SEC, 1),
M_LABEL(LBL_SET_1MIN),
M_SET_WAKEUP_PERIOD(1, 60000000),
I_SLEEP_CYCLE_SEL(1),
I_HALT(),
M_LABEL(LBL_SET_1SEC),
M_SET_WAKEUP_PERIOD(1, 5000000),
I_SLEEP_CYCLE_SEL(1),
I_HALT(),
};
hulp_configure_pin(PIN_LED, RTC_GPIO_MODE_OUTPUT_ONLY, GPIO_FLOATING, 0);
hulp_ulp_load(program, sizeof(program), 12345678); // The time value here doesn't matter, ULP will set its own
hulp_ulp_run();
}
extern "C" void app_main()
{
init_ulp();
hulp_peripherals_on();
esp_deep_sleep_start();
}
The likely culprit at this point is that I2C transaction. If the bus is misconfigured or in an error-state (eg. slave holding a pin low) then the ULP can and will lock up on that instruction.
So this is what is happening. If I send the esp to deep sleep, it doesn't wake up even after calling I_WAKE() in the ulp program. Else the same issue, doesn't wait for the timer, just keeps running. So if you have any insights to this problem, please let me know. Thank you for your help!
With my code above? Or some other program?
Can you share your code here?
The program I am running. Here is the program
//adc for the new esp32
//SCL = 2 or 4
//SDA = 0 or 15
RTC_DATA_ATTR ulp_var_t Check;
void init_ulp() { const ulp_insn_t program[] = { I_WAKE(), I_MOVI(R2, 0), I_I2C_WRITE(0, SLAVE1_SUBADDR5, 0x14), I_I2C_READ(0, SLAVE1_SUBADDR1), I_MOVR(R1, R0), I_PUT(R1,R2,check), M_SET_WAKEUP_PERIOD (1, 60000000), I_SLEEP_CYCLE_SEL(1), I_HALT(), }; hulp_register_i2c_slave(0, SLAVE1_ADDR); hulp_configure_i2c_pins(SCL_PIN, SDA_PIN); hulp_configure_i2c_controller(); vTaskDelay(1000 / portTICK_PERIOD_MS); hulp_ulp_load(program, sizeof(program), ULP_WAKEUP_INTERVAL_MS * 1000); hulp_ulp_run(); } extern "C" void app_main() { init_ulp(); hulp_peripherals_on(); printf("Check data: %u\n", Check.val); vTaskDelay(1000 / portTICK_PERIOD_MS); esp_deep_sleep_start(); }
The few header files are extra because I need them to do the next parts. I also tried I_WAKE(), before the I_HALT(). I also put the printf statement in the for loop. If I put it inside the for loop and no deepsleep, then it keeps running but if I add the deepsleep, then it runs once and doesn't wake up. same when it is outside the for loop as well.
Don't forget to enable ULP wakeup:
esp_sleep_enable_ulp_wakeup()
I had done that too, same result as before.
I've had a look at this today and the issue seems to be with hulp_configure_i2c_pins, especially in open-drain configuration (with push-pull configuration I can see the ESP32 transmission on my oscilloscope, but there's nothing in open-drain).
You might consider using HULP's I2C bitbanging stuff (which I highly recommend). Note that if there is ever an issue with hardware I2C in the field (eg. slave fault causes SDA or SCL to be low), it can and most likely will lock up your ULP just like this.
I'll try find a fix later this week.
@Ankith-A-Muralidhar I just pushed a change to the pin init which will hopefully be more reliable. ULP I2C works fine for me now.
I came across this issue where the ULP does not go to sleep for the requested time. I used the M_SET_WAKEUP_PERIOD instruction to set the register index 1 to one minute( in micro seconds). And then selected the sleep cycle using I_SLEEP_CYCLE_SEL(1). But the ULP does not sleep for 1 min after the I_HALT and before rerunning the code. Here is the Code:
const ulp_insn_t program[] = { M_SET_WAKEUP_PERIOD (1, 60000000), I_SLEEP_CYCLE_SEL(1), I_I2C_READ(0, SLAVE_SUBADDR), // Reading a data from a slave I_MOVI(R2,0), I_PUT(R0, R2, data), };
Any help would be appreciated!