How the set RTC as wake up source and set a specific time on all the days using sys file system - imx6 sabresd

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How the set RTC as wake up source and set a specific time on all the days using sys file system - imx6 sabresd

Jump to solution
24,227 Views
sebimohan
Contributor III

I am using a imx6 SabreSD. I need to set the RTC as the wake up source, and I need to set a specific time on all the day,say 12 midnight(may not be in power down mode at that time) I have a sample

       echo +x > /sys/class/rtc/rtc0/wakealarm; RTC will wake up system after x seconds

using this i can wake up system after x seconds. But i need this as 00:00:01 as time

I go to suspend state by echo standby > /sys/power/state

Is there any way. Please help

Thanks in advance

Labels (5)
1 Solution
5,834 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, S M

     It should be easy to write an script to achieve that, I am not sure whether there is an application that can meet your requirement, but I did write a script which can work, you can refer to it as below, the default wakeup time I set is 23:37:00, you can change it as you want.

  1 #set wakeup time to 23:37:00

  2 wakeup_time_h=23;

  3 wakeup_time_m=37;

  4 wakeup_time_s=00;

  5

  6 #get curent seconds based on 1970 00:00:00

  7 cur_s=`date +%s`;

  8

  9 #seconds will write to rtc alarm

10 sec=0;

11

12 cur_s_left=0;

13 wakeup_total_s=0;

14 waketime_s_left=0;

15 day_sec=24*3600;

16

17 #see how many seconds has passed since last 00:00:00

18 cur_s_left=`expr $[cur_s % day_sec]`;

19 echo cur_s_left is $cur_s_left;

20

21 #get how many seconds we need to set alarm since last 00:00:00

22 wakeup_total_s=`expr $[wakeup_time_h * 3600 + wakeup_time_m * 60 + wakeup_time_s]`;

23 echo wakeup_time_total is $wakeup_total_s;

24 wakeup_time_s_left=`expr $[wakeup_total_s % day_sec]`;

25 echo wakeup_time_s_left is $wakeup_time_s_left;

26

27 if [ "$wakeup_time_s_left" -lt "$cur_s_left" ]; then

28         sec=`expr $[wakeup_time_s_left + day_sec - cur_s_left]`;

29 else

30         sec=`expr $[wakeup_time_s_left - cur_s_left]`;

31 fi

32

33 echo alarm time is $sec;

34 echo +$sec > /sys/class/rtc/rtc0/wakealarm;

35 echo mem > /sys/power/state;

View solution in original post

0 Kudos
18 Replies
5,834 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, S M

     I think you can write a script to get current date, and use the wakeup time to count the exact second you want to wake up system.

5,834 Views
sebimohan
Contributor III

Thanks for the replay,

But I would like to know is there any way such that on every day it wakes up on a specific time.

0 Kudos
5,835 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, S M

     It should be easy to write an script to achieve that, I am not sure whether there is an application that can meet your requirement, but I did write a script which can work, you can refer to it as below, the default wakeup time I set is 23:37:00, you can change it as you want.

  1 #set wakeup time to 23:37:00

  2 wakeup_time_h=23;

  3 wakeup_time_m=37;

  4 wakeup_time_s=00;

  5

  6 #get curent seconds based on 1970 00:00:00

  7 cur_s=`date +%s`;

  8

  9 #seconds will write to rtc alarm

10 sec=0;

11

12 cur_s_left=0;

13 wakeup_total_s=0;

14 waketime_s_left=0;

15 day_sec=24*3600;

16

17 #see how many seconds has passed since last 00:00:00

18 cur_s_left=`expr $[cur_s % day_sec]`;

19 echo cur_s_left is $cur_s_left;

20

21 #get how many seconds we need to set alarm since last 00:00:00

22 wakeup_total_s=`expr $[wakeup_time_h * 3600 + wakeup_time_m * 60 + wakeup_time_s]`;

23 echo wakeup_time_total is $wakeup_total_s;

24 wakeup_time_s_left=`expr $[wakeup_total_s % day_sec]`;

25 echo wakeup_time_s_left is $wakeup_time_s_left;

26

27 if [ "$wakeup_time_s_left" -lt "$cur_s_left" ]; then

28         sec=`expr $[wakeup_time_s_left + day_sec - cur_s_left]`;

29 else

30         sec=`expr $[wakeup_time_s_left - cur_s_left]`;

31 fi

32

33 echo alarm time is $sec;

34 echo +$sec > /sys/class/rtc/rtc0/wakealarm;

35 echo mem > /sys/power/state;

0 Kudos
5,834 Views
sebimohan
Contributor III

Hello Yongcai Huang,

I have one more doubt regarding the RTC wake. I set some more wake up sources, so when I wake up, I need to know the wake up source. How to know if its is from RTC.

Thanks

0 Kudos
5,834 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, S M

     You can get the wakeup irq statue from GPC_ISRx, if the pending IRQs are not masked in GPC_IMRx, then it is the wake up source.

0 Kudos
5,834 Views
sebimohan
Contributor III

Hi Yongcai Huang,

Thank you for the replay.

But sorry, I don't get a good idea. I didn't find any IRQ related to RTC. In the software point of view, can you explain the steps I need to follow to know whether RTC is the wake up source.

Thanks in advance

0 Kudos
5,834 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, S M

     The RTC ALARM's irq is 51, so you need to read GPC_ISR1 bit 19's status, if it is 1 and GPC_IMR1 bit 19 is 0, then it is waked up by RTC alarm.

     u32 val = readl_relaxed(gpc_base + 0x18) & 0x80000;

     u32 mask = readl_relaxed(gpc_base + 0x8) & 0x80000;

     if (val == 0x80000 && mask == 0)

          wakeup source is RTC alarm.

0 Kudos
5,834 Views
sebimohan
Contributor III

Hi Yongcai Huang,

I was trying to identify the wake reason as RTC wake using the method you have suggested. I did the following steps.

1. Set RTC alarm to wake up after 20 seconds using command:  echo +20 > /sys/class/rtc/rtc0/wakealarm

2. gave command to go to suspend to ram : echo mem > /sys/power/state

3. After waking up, i read the GPC_ISR1 and GPC_IMR1 registers as you have suggested using a kernel module

     u32 val = readl_relaxed(gpc_base + 0x18) & 0x80000;

     u32 mask = readl_relaxed(gpc_base + 0x8) & 0x80000;

     if (val == 0x80000 && mask == 0)

          wakeup source is RTC alarm.

    (gps base address was io remaped and used)

But i did not get the wake source as RTC alarm. Is there any other thing to be done to get it correctly?

Thanks

0 Kudos
5,834 Views
raymondwang
Senior Contributor I

I think you add code in wrong place.

I add code to read all gpc isr state in pm.c function mx6_suspend_enter after below code snippet.

if(arg_pg) {

. ..

restore_gic_cpu_state(0,&gcs);

}

wake_irq_state[0] = __raw_readl(gpc_base+GPC_ISR1_OFFSET)&gpc_wake_irq[0];

...

//print these irq_state will indicator is your wakeup irq event or not. In my case SNVS event irq is 51,which means wake_irq_state[0]=0x80000

0 Kudos
5,834 Views
sebimohan
Contributor III

Hi Yongcai Huang,

    Thank you very much for the reply. Your explanations are perfect.

    In the i.mx6q application processor reference manual, irq51 is shown as SNVS consolidated interrupts. Is this the same for RTC alarm's?. If that is the case my problem is fixed.

Thanks

0 Kudos
5,834 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, S M

     Yes, it is the RTC alarm interrupt. You can try it on your board.

0 Kudos
5,834 Views
sebimohan
Contributor III

Hello Yongcai Huang,

I am in a difficult situation, I cannot identify the wake source as RTC alarm, even though the system comes from Suspend to RAM state by RTC alarm.

The log which i got when the above procedure is executed is given below.

>PM: Syncing filesystems ... done.

>Freezing user space processes ... (elapsed 0.01 seconds) done.

>Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.

>Suspending console(s) (use no_console_suspend to debug)

>add wake up source irq 101

>add wake up source irq 99

>add wake up source irq 103

>add wake up source irq 51

>PM: suspend of devices complete after 8.569 msecs

>PM: late suspend of devices complete after 0.739 msecs

>Disabling non-boot CPUs ...

>CPU1: shutdown

>CPU2: shutdown

>CPU3: shutdown

--------------------------------------

>Enabling non-boot CPUs ...

>CPU1: Booted secondary processor

>Calibrating delay loop (skipped) already calibrated this CPU

>i.MXC CPU frequency driver

>CPU1 is up

>CPU2: Booted secondary processor

>Calibrating delay loop (skipped) already calibrated this CPU

>i.MXC CPU frequency driver

>CPU2 is up

>CPU3: Booted secondary processor

>Calibrating delay loop (skipped) already calibrated this CPU

>i.MXC CPU frequency driver

>CPU3 is up

>PM: early resume of devices complete after 0.440 msecs

>imx-ipuv3 imx-ipuv3.0: IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)

>imx-ipuv3 imx-ipuv3.1: IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)

>remove wake up source irq 51

>remove wake up source irq 103

>remove wake up source irq 101

>remove wake up source irq 99

>PM: resume of devices complete after 294.708 msecs

>Restarting tasks ... done.

-----------------------------------------------

>rtc alarm reg val 0

>rtc alarm mask 0

>Wake source not rtc

As you can see, "remove wake up source irq 51" is logged, probably because the register gets cleared by some other module during the wakeup. Do you have any idea which module will be doing that and can the status be retained until my module read that by some tweak?

0 Kudos
5,834 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, S M

I think the RTC interrupt has been serviced by RTC driver, maybe you can dump the gpc status register in pm.c right after system resume, or add some debug message I'm RTC driver's IRQ handler to verify that?

Sent from Anson's iPhone

? 2014?2?7??18:43?"S M" <admin@community.freescale.com<mailto:admin@community.freescale.com>> ???

<https://community.freescale.com/>

<https://community.freescale.com/>

How the set RTC as wake up source and set a specific time on all the days using sys file system - imx6 sabresd

reply from S M<https://community.freescale.com/people/sebimohan?et=watches.email.thread> in i.MX Community - View the full discussion<https://community.freescale.com/message/378482?et=watches.email.thread#378482>

0 Kudos
5,834 Views
sebimohan
Contributor III

Hi Yongcai Huang,

Sorry for the late reply.

I have tried what you have suggested. I have put some debug prints in pm.c and found that the register bit corresponding to RTC wake is set and its mask bit is reset. I have got this just after mx6_suspend_restore. But if i try to do this after system coming back after restore, using a module, both the registers are 0.

For my use I need to be read using my module. So to get that I thought of a global variable in pm.c and exporting it from there and checking its value from my module.

Can you please suggest some better method.

Thanks,

Sebi

0 Kudos
5,834 Views
AnsonHuang
NXP Employee
NXP Employee

Using a global variable should be acceptable, as this interrupt must be serviced after GIC resume, otherwise, kernel will hang, so you must store the wakeup source in somewhere for your module to use.

0 Kudos
5,834 Views
sebimohan
Contributor III

Hi Yongcai Huang,

Thanks for your support. This would

Sebi

0 Kudos
5,834 Views
sebimohan
Contributor III

Hi Yongcai Huang,

Thank you for your response. Let me check in my board.

Thanks

0 Kudos
5,834 Views
sebimohan
Contributor III

Thank you

0 Kudos