ULP WakeUP

barosu
Posts: 8
Joined: Fri Oct 06, 2017 3:14 pm

ULP WakeUP

Postby barosu » Tue Oct 17, 2017 10:15 pm

Playing around with the wake instruction of the ULP I found some strange behaviour. Maybe someone can explain. So I came across this testing the I2C code from tomtor: https://github.com/tomtor/ulp-i2c/blob/ ... ulp/main.S
The critical part is the disabling of the ULP Wakup Timer with:
WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
When I included this line in my code. The Main processor didn't seem to wakeup at all. I tried to isolate the problem. A small delay between between the wake call and the WRITE_RTC_FIELD seems to solve it. At least I thought so. When I used the delay as a function with tomtors "ret" macro it worked. With just a simple jump instruction it didn't. So I simplified the problem even further in one small example. I managed to build 2 nearly identical assembler codes. One working as expected the other one not.
So the non working one:

Code: Select all

#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/soc_ulp.h"


.bss
.text
.global entry
entry:
	nop
	wake

	move r2,2000
	jump myWait
myEnd:
	//disable rtc timer wakeup
	WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
	halt
	// Wait for r2 milliseconds
myWait:
	wait 8000
	sub r2,r2,1
	jump doneMyWait,eq
	jump myWait
doneMyWait:
	move r1,myEnd
	jump myEnd

So when I change the last jump to using a register (which also would happen when using tomtors "ret" macro):

Code: Select all

doneMyWait:
	move r1,myEnd
	jump r1
it suddenly works although both jumps should definitely do the same.
Here is also the code for the main (lightly modified from the examples):

Code: Select all

/* Hello World Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "esp_sleep.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp32/ulp.h"
#include "ulp_main.h"

extern const uint8_t bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t bin_end[]   asm("_binary_ulp_main_bin_end");

static void init_ulp_program();

void app_main()
{
	esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
	if (cause != ESP_SLEEP_WAKEUP_ULP) {
		printf("Not ULP wakeup, initializing ULP\n");
		init_ulp_program();
	} else {
		printf("ULP wakeup \n");
	}
	printf("Entering deep sleep\n\n");
	ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
	esp_deep_sleep_start();
}

void init_ulp_program()
{
	ESP_ERROR_CHECK(ulp_load_binary(0, bin_start,
            (bin_end - bin_start) / sizeof(uint32_t)));
	ulp_set_wakeup_period(0, 150);
	ESP_ERROR_CHECK( ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t)) );
}
When its working there should appear the wakeup message every 2 seconds. If I use the first assembler code I just see how the processor goes to sleep and then nothing happens. So my question is if someone can reproduce this behaviour and if someone has any idea why this is happening. For me this really makes no sense at all.

User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP WakeUP

Postby urbanze » Wed Oct 18, 2017 2:27 am

You tried just "jump myend"? Without using register to hold a label...

barosu
Posts: 8
Joined: Fri Oct 06, 2017 3:14 pm

Re: ULP WakeUP

Postby barosu » Wed Oct 18, 2017 8:59 am

Yes. Jump and then an immediate value. This should work. Shouldn't it?

User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP WakeUP

Postby urbanze » Wed Oct 18, 2017 11:50 am

barosu wrote:Yes. Jump and then an immediate value. This should work. Shouldn't it?
If I'm not mistaken, Tomtor was having errors to jump with positions stored in registers. I always used the label directly and I never had any problems, if you have not tried to use the jump without register, test!

barosu
Posts: 8
Joined: Fri Oct 06, 2017 3:14 pm

Re: ULP WakeUP

Postby barosu » Thu Oct 19, 2017 12:58 pm

Well I will test it a little bit more. I am still more confused why the main CPU doesn't wake up when I use the label and not the register.
It's not that important. But I just started a bigger project and I wanted to understand whats actually going on here.

barosu
Posts: 8
Joined: Fri Oct 06, 2017 3:14 pm

Re: ULP WakeUP

Postby barosu » Thu Oct 19, 2017 3:00 pm

Well something seems to be odd about jumping using a register. I played around with it and it just doesn't work. Whatever is happening the program doesn't jump to the right position The sad part about it that this means I also can't use tomtors Stack macros. In general it's impossible to implement actual function calls without it.

Is this a bug? Maybe Windows specific, or what is happening?

barosu
Posts: 8
Joined: Fri Oct 06, 2017 3:14 pm

Re: ULP WakeUP

Postby barosu » Thu Oct 19, 2017 6:52 pm

Ah Ok there seem to be a new version of the ulp toolchain on github. The windows build is just still not updated so I have to build it my own.

tomtor
Posts: 22
Joined: Thu May 11, 2017 6:15 am

Re: ULP WakeUP

Postby tomtor » Fri Oct 20, 2017 8:02 am

barosu wrote:Playing around with the wake instruction of the ULP I found some strange behaviour.
....

When its working there should appear the wakeup message every 2 seconds. If I use the first assembler code I just see how the processor goes to sleep and then nothing happens. So my question is if someone can reproduce this behaviour and if someone has any idea why this is happening. For me this really makes no sense at all.
There is some issue with jump instructions inside macros. They do not work, it looks as if the relocation info is messed up. It could be that in some situations a jump does also not work outside macros.

I am trying to find the root cause, but have not been successful.

tomtor
Posts: 22
Joined: Thu May 11, 2017 6:15 am

Re: ULP WakeUP

Postby tomtor » Sun Oct 22, 2017 10:59 am

barosu wrote:Ah Ok there seem to be a new version of the ulp toolchain on github. The windows build is just still not updated so I have to build it my own.
Yes, that's correct. Without that fix jumps via a register do not work.

Note that in addition to this fixed issue jumps of all kinds within a macro do NOT work.

That 's the reason I have a PSR macro to prepare a subroutine jump, because creating a JSR macro which combines the push of the return address with the jump instruction did not work... :(

User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP WakeUP

Postby urbanze » Sun Oct 22, 2017 3:46 pm

tomtor wrote:
barosu wrote:Ah Ok there seem to be a new version of the ulp toolchain on github. The windows build is just still not updated so I have to build it my own.
Yes, that's correct. Without that fix jumps via a register do not work.

Note that in addition to this fixed issue jumps of all kinds within a macro do NOT work.

That 's the reason I have a PSR macro to prepare a subroutine jump, because creating a JSR macro which combines the push of the return address with the jump instruction did not work... :(
why these "basic" commands do not exist in this ulp assembly? and why has not it been added yet? I would really like to see the ulp assembly more functional

Who is online

Users browsing this forum: Dennie and 117 guests