ESP32ULP wakeup question
Posted: Wed Jan 13, 2021 1:28 pm
Hi all,
I'm using esp32-pico chip, on custom designed board. i'm trying to implement ulp with rtc-gpio pulse wakeup.
Below is my code.
I'm unable to wakeup by ulp. i have interfaced button on GPIO_36.
Same pin, with assembly code of esp-idf is working with same board. but i need to run it on my esp32 arduino framework. I port assembly code into MACRO LEGACY, but it's not waking my system from deep sleep mode.
Attachments are the files which i'm refering. This is a example code given in esp-idf "......\esp\esp-idf\examples\system\ulp"
Please i'm new for using esp32(also with ulp).
Any suggestion is appreciate.
I'm using esp32-pico chip, on custom designed board. i'm trying to implement ulp with rtc-gpio pulse wakeup.
Below is my code.
I'm unable to wakeup by ulp. i have interfaced button on GPIO_36.
Same pin, with assembly code of esp-idf is working with same board. but i need to run it on my esp32 arduino framework. I port assembly code into MACRO LEGACY, but it's not waking my system from deep sleep mode.
Attachments are the files which i'm refering. This is a example code given in esp-idf "......\esp\esp-idf\examples\system\ulp"
Please i'm new for using esp32(also with ulp).
Any suggestion is appreciate.
Code: Select all
void init_ulp_program(uint32_t us) {
uint32_t _rsm_size = ( ( (uint32_t)(&RSM_END) - (uint32_t)(&(RTC_SLOW_MEM[0])) )/4 ) + 1;
// device by 4 as all RSM is 32bit
// add to be safe
_log("BURNING ULP CODE, RMS_OFFSET should be = %u", _rsm_size);
_log("init_ulp_program - before entry");
const ulp_insn_t ulp_pulse[] = {
//entry
M_LABEL(entry), // BEGIN
/* Load io_number */
I_MOVI(R3, io_number),
I_LD(R3, R3, 0), // R3 <- RTC_SLOW_MEM[R3 + 0]
/* Lower 16 IOs and higher need to be handled separately,
* because R0-R3 registers are 16 bit wide.
* Check which IO this is.
*/
I_MOVR(R0, R3),
M_BGE(read_io_high, 16), //I_BXZI(read_io_high);//EQ – jump if last ALU operation result was zero
/* Read the value of lower 16 RTC IOs into R0 */
//READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S, 16),
//I_RD_REG((((RTC_GPIO_IN_REG) - DR_REG_RTCCNTL_BASE) / 4), ((RTC_GPIO_IN_NEXT_S) + (16) - 1), (RTC_GPIO_IN_NEXT_S)),
I_RD_REG(RTC_GPIO_IN_REG,RTC_GPIO_IN_NEXT_S,16),
I_RSHR(R0, R0, R3),
M_BX(read_done),//I_BXI(read_done);// GOTO M_LABEL(2)
/* Read the value of RTC IOs 16-17, into R0 */
M_LABEL(read_io_high), //read_io_high
//READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 16, 2),
//I_RD_REG((((RTC_GPIO_IN_REG) - DR_REG_RTCCNTL_BASE) / 4), ((RTC_GPIO_IN_NEXT_S+16) + (2) - 1), (RTC_GPIO_IN_NEXT_S+16)),
I_RD_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 16, 2),
I_SUBI(R3, R3, 16),
I_RSHR(R0, R0, R3),
M_LABEL(read_done),//read_done
I_ANDI(R0, R0, 1),
/* State of input changed? */
I_MOVI(R3, next_edge),
I_LD(R3, R3, 0),
I_ADDR(R3, R0, R3),
I_ANDI(R3, R3, 1),
M_BXZ(changed),//I_BXZI(changed);//EQ – jump if last ALU operation result was zero
/* Not changed */
/* Reset debounce_counter to debounce_max_count */
I_MOVI(R3,debounce_max_count),
I_MOVI(R2,debounce_counter),
I_LD(R3,R3,0),
I_ST(R3,R2,0),
/* End program */
I_HALT(),//halt
M_LABEL(changed),//changed
/* Input state changed */
/* Has debounce_counter reached zero? */
I_MOVI(R3,debounce_counter),
I_LD(R2,R3,0),
I_ANDI(R2, R2, 0),/* dummy ADD to use "jump if ALU result is zero" */
M_BXZ(edge_detected),//I_BXZI(edge_detected);
/* Not yet. Decrement debounce_counter */
I_SUBI(R2,R2,1),
I_ST(R2,R3,0),
/* End program */
I_HALT(),//halt
M_LABEL(edge_detected), //edge_detected
/* Reset debounce_counter to
debounce_max_count */
I_MOVI(R3,debounce_max_count),
I_MOVI(R2,debounce_counter),
I_LD(R3,R3,0),
I_ST(R3,R2,0),
// Flip next_edge //
I_MOVI(R3,next_edge),
I_LD(R2,R3,0),
I_ADDI(R2, R2, 1),
I_ANDI(R2, R2, 1),
I_ST(R2,R3,0),
// Increment edge_count //
I_MOVI(R3,edge_count),
I_LD(R2,R3,0),
I_ADDI(R2, R2, 1),
I_ST(R2,R3,0),
// Compare edge_count to edge_count_to_wake_up //
I_MOVI(R3,edge_count_to_wake_up),
I_LD(R3,R3,0),
I_SUBR(R3,R3,R2),
M_BXZ(wake_up),//I_BXZI(wake_up);
// Not yet. End program //
I_HALT(),//halt
M_LABEL(wake_up), //wake_up
/*
I_MOVI(R3,edge_count_original),
I_MOVI(R2,edge_count),
I_LD(R3,R3,0),
I_ST(R3,R2,0),
// Wake up the SoC, end program //
I_WAKE(),//wake
I_HALT()//halt
*/
/* Check if the system can be woken up */
//READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP),
I_RD_REG(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP, RTC_CNTL_RDY_FOR_WAKEUP),
//READ_RTC_REG(RTC_CNTL_DIAG0_REG, 19, 1)
//I_RD_REG(RTC_CNTL_DIAG0_REG, RTC_CNTL_RDY_FOR_WAKEUP_S, 1),
I_ANDI(R0, R0, 1),
//M_BL(wake_up, 16),
M_BXZ(wake_up),
/* Wake up the SoC, end program */
I_WAKE(),//wake
I_HALT()//halt
};
/* GPIO used for pulse counting. */
gpio_num_t gpio_num = GPIO_NUM_36;
int rtcio_num = rtc_io_number_get(gpio_num);
assert(rtc_gpio_is_valid_gpio(gpio_num) && "GPIO used for pulse counting must be an RTC IO");
/* Initialize some variables used by ULP program.
* Each 'ulp_xyz' variable corresponds to 'xyz' variable in the ULP program.
* These variables are declared in an auto generated header file,
* 'ulp_main.h', name of this file is defined in component.mk as ULP_APP_NAME.
* These variables are located in RTC_SLOW_MEM and can be accessed both by the
* ULP and the main CPUs.
*
* Note that the ULP reads only the lower 16 bits of these variables.
*/
ulp_debounce_counter = 3;
ulp_debounce_max_count = 3;
ulp_next_edge = 0;
ulp_edge_count_original = 0;
ulp_io_number = rtcio_num; /* map from GPIO# to RTC_IO# *//* GPIO_36 is RTC_IO 0 */
ulp_edge_count_to_wake_up = 2;//10;
/* Initialize selected GPIO as RTC IO, enable input, disable pullup and pulldown */
rtc_gpio_init(gpio_num);
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_pulldown_dis(gpio_num);
rtc_gpio_pullup_dis(gpio_num);
rtc_gpio_hold_en(gpio_num);
/* Disconnect GPIO12 and GPIO15 to remove current drain through
* pullup/pulldown resistors.
* GPIO12 may be pulled high to select flash voltage.
*/
rtc_gpio_isolate(GPIO_NUM_12);
rtc_gpio_isolate(GPIO_NUM_15);
esp_deep_sleep_disable_rom_logging(); // suppress boot messages
/* Set ULP wake up period to T = 20ms.
* Minimum pulse width has to be T * (ulp_debounce_counter + 1) = 80ms.
*/
ulp_set_wakeup_period(0, us);
/* Start the program */
size_t size = sizeof(ulp_pulse) / sizeof(ulp_insn_t);
ulp_process_macros_and_load((&ulp_entry - RTC_SLOW_MEM), ulp_pulse, &size);
esp_err_t err = ulp_run(&ulp_entry - RTC_SLOW_MEM);
//ulp_process_macros_and_load(0, ulp_pulse, &size);
//esp_err_t err = ulp_run(0);
_log("ulp_run : err %d\r\n",err);
_log("init_ulp_program - passed\r\n");
}