ULP Clock issues/details/explanations

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

ULP Clock issues/details/explanations

Postby urbanze » Sun Jan 07, 2018 5:32 pm

1-) Why changing the Main Core clock, is the ULP reading frequency of the ADC also influenced? Since ULP clock is ~8MHz ???

I get frequency results with an ADC reading from ULP 74kHz with 240MHz and 50kHz with 160MHz. As far as I imagine, this should not happen for the simple fact that the ULP cclock is "fixed" ~8MHz.

The code used to read the frequency of the ADC is a simple pin toggle interrupted by the WAKE of the ULP, see codes:

Code: Select all

extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
void ulp();


void IRAM_ATTR wk(void*z)
{
	(*(volatile uint32_t *)(GPIO_OUT_REG)) ^= (1<<2);
}

extern "C" void app_main()
{
	REG_WRITE(GPIO_ENABLE_REG, BIT2);
	
	
	ulp();

}


void ulp()
{
	adc1_config_channel_atten(ADC1_CHANNEL_5, ADC_ATTEN_0db);
	adc1_config_width(ADC_WIDTH_12Bit);
	adc1_ulp_enable();
	
	rtc_isr_register(wk, NULL, RTC_CNTL_SAR_INT_ST_M);
	REG_WRITE(RTC_CNTL_INT_ENA_REG, BIT5);
	//esp_sleep_enable_ulp_wakeup();

	ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
	ulp_run((&ulp_main - RTC_SLOW_MEM) / sizeof(uint32_t));
}

Code: Select all

.bss
.global value
		value:.long 0

.text


	.global main
	main:
		move r3, value

	jump lop
	
	
	lop:
		
		adc r0, 0, 5+1
		
		jumpr wkup, 20, lt
		jump lop
		

	wkup:
		wake
		jump lop
2-) I put a question that could be a correction to the datasheet in the wrong place (pull request in git) (sorry), but the datasheet says that the ULP clock is 8MHz, however, several sites introduce the idea of calibration or frequency checking, assuming it is not 8MHz. In the file RTC.H has a comment about 8.5MHz +-7%.

Code: Select all

// calibrate 8M/256 clock against XTAL, get 8M/256 clock period
uint32_t rtc_8md256_period = rtc_clk_cal(RTC_CAL_8MD256, 100);
uint32_t rtc_fast_freq_hz = 1000000ULL * (1 << RTC_CLK_CAL_FRACT) * 256 / rtc_8md256_period;
With this code, the variable returns me 8.833MHz, which is within the range above and well outside the 8MHz of the datasheet. Why does this discrepancy occur between information? What's the true clock of ulp?

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: ULP Clock issues/details/explanations

Postby ESP_igrr » Mon Jan 08, 2018 2:06 pm

Regarding the first question: i suggest toggling GPIO directly from the ULP code, not from the ISR on the main CPU. Interrupts have certain latency, calling "ulp" function needs some time — in total, you are measuring T(on ULP) + T(on main CPU), and T(on main CPU) will obviously depend on the main CPU frequency.

Regarding the second one: ULP is clocked from RTC_FAST_CLK, which is approximately 8MHz. In fact, it is most often set to 8-8.5MHz. This section of documentation mentions how to obtain ULP coprocessor clock frequency:
http://esp-idf.readthedocs.io/en/latest ... ution-time

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

Re: ULP Clock issues/details/explanations

Postby urbanze » Mon Jan 08, 2018 3:23 pm

ESP_igrr wrote:Regarding the first question: i suggest toggling GPIO directly from the ULP code, not from the ISR on the main CPU. Interrupts have certain latency, calling "ulp" function needs some time — in total, you are measuring T(on ULP) + T(on main CPU), and T(on main CPU) will obviously depend on the main CPU frequency.

Regarding the second one: ULP is clocked from RTC_FAST_CLK, which is approximately 8MHz. In fact, it is most often set to 8-8.5MHz. This section of documentation mentions how to obtain ULP coprocessor clock frequency:
http://esp-idf.readthedocs.io/en/latest ... ution-time
I suggested an observation or even fix the datasheet in github, but I did in the wrong place and deleted it, though they said they would pass it to developers. The fix would only write better about this approximate ULP clock, at least speaking that it is approximate and with error margins in %. (I'm quoting this again only if it has not come to you)

I did the tests with the toggle direct by the ULP and changing the frequency of the Main Core, did not change the toggle frequency, however, the frequency of toggle was lower than the Main Core doing it. I think it is because the instructions to write in the reg take several cycles and it is easier to activate a single-bit for the Main Core do toggle (various cycles), than the ULP do this in less clock, causing the lower frequency when do toggle with ULP.

Thanks for listening!
Last edited by urbanze on Mon Jan 08, 2018 3:24 pm, edited 1 time in total.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: ULP Clock issues/details/explanations

Postby WiFive » Mon Jan 08, 2018 3:23 pm

Internal RC oscillator you can expect to not give a stable frequency like a crystal. Supposedly the default frequency setting was chosen to have the best temperature stability.

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

Re: ULP Clock issues/details/explanations

Postby urbanze » Mon Jan 08, 2018 3:32 pm

WiFive wrote:Internal RC oscillator you can expect to not give a stable frequency like a crystal. Supposedly the default frequency setting was chosen to have the best temperature stability.
1-) If this clock varies by temperature "more easily," my delay's in a "hostile" environment would never be the same. How can I ensure a more stable clock to ULP? I know there are some functions in RTC_CLK_CAL(), would they work to always stabilize the clock at an approximately equal value regardless of temperature? Calibrating by APB, Main crystal or anyone more stable...

2-) This "internal 8MHz osc" (https://i.imgur.com/OwcqZsu.png) it's not ulp's right? This writing is turned off in Sleep, but the ULP keeps running. If it is another oscillator, is it more stable than the ULP and is it possible to use it?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: ULP Clock issues/details/explanations

Postby WiFive » Mon Jan 08, 2018 4:11 pm

Yes there is only one internal 8mhz oscillator, it is shared. You can use the xtal/4 clock source for ulp but not sure if you can leave it enabled in deepsleep, although there are some registers that suggest maybe you can.

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

Re: ULP Clock issues/details/explanations

Postby urbanze » Mon Jan 08, 2018 10:20 pm

The NOP instruction is described with: "2 (fetch) + 1 (execute)"
The JUMP instruction is described with: "2 (fetch) + 2 (execute)"
The WAIT instruction is described with: "2 (fetch) + Cycles (execute)"

Logically, it was for the jump to increment a greater delay to the code (comparing with NOP and WAIT 1), however, it happened instead, see the codes and the frequencies obtained:

Base code, 315.6KHz:

Code: Select all

	main:
		REG_WR (0x3ff48404-0x3ff48000)/4, 26, 26, 1
		REG_WR (0x3ff48408-0x3ff48000)/4, 26, 26, 1
		jump main

NOP code, 260KHz:

Code: Select all

	main:
		REG_WR (0x3ff48404-0x3ff48000)/4, 26, 26, 1
		nop
		REG_WR (0x3ff48408-0x3ff48000)/4, 26, 26, 1
		jump main

JUMP code, 276KHz:

Code: Select all

	main:
		REG_WR (0x3ff48404-0x3ff48000)/4, 26, 26, 1
		jump bla
	bla:
		REG_WR (0x3ff48408-0x3ff48000)/4, 26, 26, 1
		jump main
WAIT code, 252KHz:

Code: Select all

	main:
		REG_WR (0x3ff48404-0x3ff48000)/4, 26, 26, 1
		wait 1
		REG_WR (0x3ff48408-0x3ff48000)/4, 26, 26, 1
		jump main
1-) Why is JUMP faster than NOP, since JUMP takes more instructions?
2-) Why is WAIT 1 different from NOP, since both have the same instructions?

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

Re: ULP Clock issues/details/explanations

Postby urbanze » Fri Dec 14, 2018 1:36 pm

Hi guys. How can I "shutdown" ULP by main core (C code)? In ULP ASM, just need to be halted, but how can I force ulp to be shutdown? I can't find this register.

PS: I already use one variable set by main core to control some states of ulp when he reads this variable, but I need a real shutdown by main core.

Who is online

Users browsing this forum: No registered users and 95 guests