cancel
Showing results for 
Search instead for 
Did you mean: 

STR912FA Sleep Mode - Hangs!

aled
Associate II
Posted on October 16, 2009 at 21:35

STR912FA Sleep Mode - Hangs!

11 REPLIES 11
ly_liuyang_ly
Associate
Posted on May 17, 2011 at 09:47

I face the same problem

in Rev H.

code like this: (used in uCOS2)

RTC_SetAlarm(alarm); /*set alarm*/

RTC_AlarmCmd(ENABLE); /* enable alarm */

/*The system clock source switched to the RTC clock */

OS_ENTER_CRITICAL(); // this disables interrupts globally before enter sleep mode

RTC_ITConfig(RTC_IT_Per | RTC_IT_Tamper, DISABLE);

RTC_ClearFlag(RTC_FLAG_Alarm | RTC_FLAG_Per | RTC_FLAG_Tamper); /* clear RTC flag*/

RTC_ITConfig(RTC_IT_Alarm, ENABLE); /*Enable RTC alarm interrupt*/

VIC_ITCmd(WIU_ITLine, DISABLE);

y = SCU_GetMCLKFreqValue() / 1000;

SCU_MCLKSourceConfig(SCU_MCLK_RTC);

SetLED(1); // show the system status, just GPIO operations

WIU->PR = 0xFFFFFFFF; // Clear pending WIU interrupts

/*Enter Sleep mode*/

SCU_EnterSleepMode();

WIU->PR = 0xFFFFFFFF;

/* Dummy instructions

Execution of N=12 dummy instructions. This number depends on

the ratio between CPU clock frequency and the oscillator input

frequency(Please refer to the STR91xFA reference manual).

For fcpuclk = 32.768Khz, N=3 */

__nop(); __nop(); __nop();

/*Switch to oscillator as clock source after wake up*/

if (y > 25)

{ // MCLK by PLL

while(!(SCU->SYSSTATUS&SCU_FLAG_LOCK)); /*Wait PLL to lock*/

SCU_MCLKSourceConfig(SCU_MCLK_PLL); // restore clock, if it woke up...

} else SCU_MCLKSourceConfig(SCU_MCLK_OSC);

SetLED(0);

// clear RTC alarm and enable WIU interrupt

RTC_ITConfig(RTC_IT_Alarm, DISABLE);

RTC_AlarmCmd(DISABLE);

RTC_ITConfig(RTC_IT_Per, ENABLE);

VIC_ITCmd(WIU_ITLine, ENABLE);

OS_EXIT_CRITICAL(); // enabled interrupts globally

XXX codes: following some codes here will sometimes not run?

the problem is: CPU cannot wakup up or after OS_EXIT_CRITICAL, the system hang.

PS:OS_EXIT_CRITICAL set CPSRE reg to enable int.:

OS_CPU_SR_Save

MRS R0, CPSR

ORR R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS ; Set IRQ and FIQ bits in CPSR to disable all interrupts.

MSR CPSR_c, R1

BX LR ; Disabled, return the original CPSR contents in R0.

OS_CPU_SR_Restore

MSR CPSR_c, R0

BX LR

any suggest? or what code can be used as common purpose?

:(

omniprintinc
Associate II
Posted on May 17, 2011 at 09:47

Hello ly_liuyang_ly

From what I read in the ST application note AN2633, there should be 3 ''dummy'' instructions after executing the command to enter a low power mode if the system is running from the 32 kHz clock as your appears to be. In your call to the ST library function SCU_EnterSleepMode(), after the sleep mode bit is set in the SCU_PWRMNG register, there is a BX LR instruction to return from the function call. Likewise, there are likely four instructions to clear the WIU Pending Register:

WIU->PR = 0xFFFFFFFF;

LDR R0,WIU_Addr

LDR R0,[R0, #+0]

MVN R1,#+0

STR R1,[R0, #+12]

That is five instruction right away before your CPU even gets to the NOPs. Shouldn't it already be in a low power state at this point. If it is, your CPU will never execute the remainder of the instructions

Quote:

/* Dummy instructions

Execution of N=12 dummy instructions. This number depends on

the ratio between CPU clock frequency and the oscillator input

frequency(Please refer to the STR91xFA reference manual).

For fcpuclk = 32.768Khz, N=3 */

__nop(); __nop(); __nop();

/*Switch to oscillator as clock source after wake up*/

if (y > 25)

{ // MCLK by PLL

while(!(SCU->SYSSTATUS&SCU_FLAG_LOCK)); /*Wait PLL to lock*/

SCU_MCLKSourceConfig(SCU_MCLK_PLL); // restore clock, if it woke up...

} else SCU_MCLKSourceConfig(SCU_MCLK_OSC);

SetLED(0);

// clear RTC alarm and enable WIU interrupt

RTC_ITConfig(RTC_IT_Alarm, DISABLE);

RTC_AlarmCmd(DISABLE);

RTC_ITConfig(RTC_IT_Per, ENABLE);

VIC_ITCmd(WIU_ITLine, ENABLE);

OS_EXIT_CRITICAL(); // enabled interrupts globally

before it enables the interrupts to allow the CPU to be woken up from the low power mode.

Please let me know if I am not understanding this correctly.

Also, can anyone from ST comment on the AN2633 section 1.4.5 where it says

Quote:

Once Idle mode or Sleep mode are entered by writing the PWR_MODE[2:0] bits in the Power management register (SCU_PWRMNG) it takes about 12 crystal oscillator cycles (X1_CPU input frequency) for the device before stopping the execution.

How does one code about 12 cycles worth of instructions?