ulptool icon indicating copy to clipboard operation
ulptool copied to clipboard

GPIO Control in ULP C Compiler

Open khawajamechatronics opened this issue 5 years ago • 16 comments

Hi,

I am trying to control GPIO using ULP Co Processor. I am using ULP C Compiler Option. GPIO is controlled in main program but unable to do so in ULP. THIS Does fine, I think may be at that point ULP is not started. `

static void init_run_ulp(uint32_t usec) {
rtc_gpio_init(GPIO_NUM_33);
rtc_gpio_set_direction(GPIO_NUM_33, RTC_GPIO_MODE_OUTPUT_ONLY);
for (i = 0; i < 8; i++) {
ets_delay_us(1);
rtc_gpio_set_level(GPIO_NUM_33, 1);
ets_delay_us(1);

rtc_gpio_set_level(GPIO_NUM_33, 0);

}
ulp_set_wakeup_period(GPIO_NUM_4, usec);
esp_err_t err = ulptool_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
err = ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t));

if (err) Serial.println("Error Starting ULP Coprocessor");
}`

Now when I try to change level in ULPC Entry Program it doesnt responds. `

void entry() {
for (i = 0; i < 8; i++) {
ets_delay_us(1);
rtc_gpio_set_level(33, 1);
ets_delay_us(1);
rtc_gpio_set_level(33, 0);

}
}`

Several Queries 1- rtc_gpio_set_level(33, 1); // this doesnt accept GPIO_NUM_33 according to a documentation GPIO_NUM_33 corresponds to RTC GPIO 8 should I change to 8? what is correct passing constant? 2- Do I need to do any other pre or post function to get the GPIO changed? 3- Does function will remain the same if I enable sleep or does not enable sleep?

Thanks

khawajamechatronics avatar Feb 10 '20 21:02 khawajamechatronics

It seems I am able to change GPIO using this code `

void entry() {
if(temp)
{
WRITE_RTC_REG(RTC_IO_TOUCH_PAD4_REG,RTC_IO_TOUCH_PAD4_HOLD_S,1,0);

WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG,RTC_GPIO_OUT_DATA_W1TS_S+8,1,1);
temp=0;
}
else
{
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG,RTC_GPIO_OUT_DATA_W1TC_S+8,1,1);
WRITE_RTC_REG(RTC_IO_TOUCH_PAD4_REG,RTC_IO_TOUCH_PAD4_HOLD_S,1,1);
temp=1;
}
}`

khawajamechatronics avatar Feb 10 '20 22:02 khawajamechatronics

Basically I am trying to bitband I2C. in ULPCC

I see there is example in assembly which is bit hard to understand for me.

What functions should I add to above function to replicate this? `

for (i = 0; i < 8; i++) {
ets_delay_us(1); // This doesnt seems to work Any function for Wait?
rtc_gpio_set_level(33, 1);
//WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG,RTC_GPIO_OUT_DATA_W1TS_S+8,1,1);

//READ GPIO 32 ///NEED HELP HERE
data2 |= rtc_gpio_get_level(32) << (7 - i);

ets_delay_us(1);// This doesnt seems to work Any function for Wait?
rtc_gpio_set_level(33, 0);
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG,RTC_GPIO_OUT_DATA_W1TC_S+8,1,1);
}

`

khawajamechatronics avatar Feb 10 '20 23:02 khawajamechatronics

Sorry I thought this was for helping you fix your code, I guess I didn't read through all of it. But I'm not sure at current moment.

duff2013 avatar Feb 11 '20 16:02 duff2013

The equivalent of rtc_gpio_get_level(32) should be: READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 9 /rtc9==gpio32/, 1)

The equivalent of ets_delay_us(1); should be wait(8); (The units for wait are 0.125 us because the ULP runs at 8MHz.)

jasonful avatar Feb 11 '20 17:02 jasonful

Thanks, @jasonful!

duff2013 avatar Feb 11 '20 17:02 duff2013

Hi I hope you are doing well @duff2013 and @jasonful I have few more issues. I am trying to setup deepsleep and ULP wake Up.`

 if (cause != ESP_SLEEP_WAKEUP_ULP) {
 Serial.printf("Not ULP wakeup, initializing ULP\n");
 init_run_ulp(10000*1000);
 } 
else{ }
Serial.printf("Entering deep sleep\n\n");
start_ulp_program();
rtc_gpio_hold_en(GPIO_NUM_14);

ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
esp_deep_sleep_start();`

ISSUE 1: If I configure below then it doesn wake up but I see there is 2 ULP Calls. first at 9.922 seconds and other after 1.154 seconds. I have set ULP wakeup at 10 seconds. otherwise it seems works fine.

void entry() { wake(); halt();} ISSUE 2: If I use below code then it doesnt wake up. void entry() { halt();} wake();

I am trying to wake up on threshold can you give me example code that works?

Thanks

khawajamechatronics avatar Mar 07 '20 15:03 khawajamechatronics

Try wake_when_ready() instead of wake().


From: Khawaja Muhammad Abdur Rehman [email protected] Sent: Saturday, March 7, 2020 7:51:35 AM To: duff2013/ulptool [email protected] Cc: jasonful [email protected]; Mention [email protected] Subject: Re: [duff2013/ulptool] GPIO Control in ULP C Compiler (#56)

Hi I hope you are doing well @duff2013https://github.com/duff2013 and @jasonfulhttps://github.com/jasonful I have few more issues. I am trying to setup deepsleep and ULP wake Up.`

if (cause != ESP_SLEEP_WAKEUP_ULP) { Serial.printf("Not ULP wakeup, initializing ULP\n"); init_run_ulp(10000*1000); } else{ } Serial.printf("Entering deep sleep\n\n"); start_ulp_program(); rtc_gpio_hold_en(GPIO_NUM_14);

ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() ); esp_deep_sleep_start();`

ISSUE 1: If I configure below then it doesn wake up but I see there is 2 ULP Calls. first at 9.922 seconds and other after 1.154 seconds. I have set ULP wakeup at 10 seconds. otherwise it seems works fine.

void entry() { wake(); halt();} ISSUE 2: If I use below code then it doesnt wake up. void entry() { halt();} wake();

I am trying to wake up on threshold can you give me example code that works?

Thanks

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/duff2013/ulptool/issues/56?email_source=notifications&email_token=AHJTJWRVCVVNTZ2PAVQV4PDRGJUQPA5CNFSM4KSWF5E2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOD4WCY#issuecomment-596101899, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AHJTJWWX4W5XTC5NDT6COMLRGJUQPANCNFSM4KSWF5EQ.

jasonful avatar Mar 07 '20 17:03 jasonful

It resets very quickly on wake_when_ready image

khawajamechatronics avatar Mar 07 '20 21:03 khawajamechatronics

I am not sure what's wrong. Do you have a repo where I could look at all of your code?


From: Khawaja Muhammad Abdur Rehman [email protected] Sent: Saturday, March 7, 2020 1:19:47 PM To: duff2013/ulptool [email protected] Cc: jasonful [email protected]; Mention [email protected] Subject: Re: [duff2013/ulptool] GPIO Control in ULP C Compiler (#56)

It resets very quickly on wake_when_ready [image]https://user-images.githubusercontent.com/5573931/76152613-3f0ed200-60e3-11ea-9e19-44495f749396.png

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/duff2013/ulptool/issues/56?email_source=notifications&email_token=AHJTJWUR5W76T74JCYO2SKTRGK27HA5CNFSM4KSWF5E2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOEFUSQ#issuecomment-596138570, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AHJTJWUM7A3E33DY3FCFHLTRGK27HANCNFSM4KSWF5EQ.

jasonful avatar Mar 09 '20 00:03 jasonful

Thanks for prompt response.

I have shared snippet of code above, I will also share repo soon.

Here is more insight

When I remove wakeup in ulp image

When I add wakeup

image

1.154+9.934=11.093

Strange as whole length becomes 11.093 May be because of initial 1s delay but it sometime divides into 2 ulp run.

When I reduce initial delay to 200ms, 1.154 is reduced to 0.35 image when I remove delay function then it is reduced to 0.15, its seems but it then happens sometime not all the time

When I use wake_when_ready then it seems ulp time doesnt run it just fire ulp immediately.

khawajamechatronics avatar Mar 09 '20 22:03 khawajamechatronics

I agree, we need to see all the code for any help.

duff2013 avatar Mar 11 '20 20:03 duff2013

https://github.com/khawajamechatronics/ULPProject

khawajamechatronics avatar Mar 11 '20 21:03 khawajamechatronics

I think I can wake up on min or max. What I need to figure out is

  • why it fires ulp call on wakeup?
  • Does it reset all the variables on wakeup?
  • How much data I can log from ulp?
  • How to store data in a list from ULP in deepsleep.

I shall be very thankful for your guidance.

khawajamechatronics avatar Mar 11 '20 22:03 khawajamechatronics

  1. I still don't understand the timing issues.
  2. The ulp_* global variables are preserved. All the regular variables in your .ino file are lost.
  3. The ulp_* globals are stored in the RTC_SLOW_MEM region which is a maximum of 8192 bytes. (the size (<= 8192) is set by the CONFIG_ULP_COPROC_RESERVE_MEM variable in the sdkconfig file when building with the IDF. @duff2013, can you verify what size ulptool uses?) This RTC_SLOW_MEM region, from 0x5000000 to 0x50001FFFF also holds your entry() code, so that will consume some space. And, of course, you can only effectively use the lower 16 bits of each 32 bits of the rest of the memory.
  4. ulpcc supports arrays, so I would make a ulp_mydatalist[] array as big as I can fit in RTC_SLOW_MEM.

jasonful avatar Mar 12 '20 00:03 jasonful

Arduino defaults to 512 but you can change it in sdkconfig.h

duff2013 avatar Mar 12 '20 01:03 duff2013

Thanks for response @jasonful @jasonful Can you check the wake_when_ready can you give me a working example?

khawajamechatronics avatar Mar 13 '20 18:03 khawajamechatronics