I have an ULP program to wake the CPU when an RTC GPIO has been high for a full second (5 iterations of 200ms).
However, as shown in the IDF examples, there must be a loop awaiting the RTC_CNTL_RDY_FOR_WAKEUP flag before we can call wake.
It seems that this loop keeps spinning forever for some reason. What could be the cause?
In the code below the 'num_high' will reach 'num_thres' and then the code is stuck in the 'loop_rdy' loop. This is seen as 'num_high' never incremented further and 'helloworld is set to 0xBEEF, but never 0xACED as one would expect.
Any help apprecieted!
/Flemming
Code: Select all
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/soc_ulp.h"
/* ------ Define variables, which go into .bss section (zero-initialized data) ------ */
.bss
/* Number of logical '1's read so far. Wake up when we pass num_thres */
.global num_high
num_high:
.long 0
/* Number of successive highs before wake. Set by main program. */
.global num_thres
num_thres:
.long 0
/* RTC IO number used to sample the input signal. Set by main program. */
.global io_psdown
io_psdown:
.long 0
.global helloworld
helloworld:
.long 0
/* ------ Code goes into .text section ------ */
.text
.global entry
entry:
/* Say hello */
move r3, helloworld
move r2, 0xC0DE;
st r2, r3, 0 // helloworld = 0xC0DE;
/* Load io_number */ // R0:1 = gpio_rtc[io_number]
move r3, io_psdown
ld r3, 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.
*/
move r0, r3
jumpr read_io_high, 16, ge
/* Read the value of lower 16 RTC IOs into R0 */
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S, 16)
rsh r0, r0, r3
jump read_done
/* Read the value of RTC IOs 16-17, into R0 */
read_io_high:
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 16, 2)
sub r3, r3, 16
rsh r0, r0, r3
read_done:
and r0, r0, 1 // if (R0:1) goto is_low else:
jump is_low, eq
/* Load counter */
move r3, num_high // num_high = num_high + 1 (part 1)
ld r3, r3, 0
add r0, r3, 1
/* Save counter */
move r3, num_high // num_high = num_high + 1 (part 2)
st r0, r3, 0
/* Load threshold */
move r3, num_thres
ld r3, r3, 0
sub r0, r3, r0
jump wake_up, ov // if (R0 > num_thres) goto wake_up else:
/* End program */
halt
is_low:
/* Reset counter */
move r0, 0 // num_high = 0
move r3, num_high
st r0, r3, 0
exit:
/* End program */
halt
wake_up:
move r3, helloworld // helloworld = 0xBEEF
move r2, 0xBEEF;
st r2, r3, 0
/* Loop until the system can be woken up */
loop_rdy:
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP)
and r0, r0, 1
jump loop_rdy, eq
//jump exit, eq
move r3, helloworld // helloworld = 0xACED
move r2, 0xACED;
st r2, r3, 0
/* Wake up the SoC, end program */
wake
WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
halt