2009-10-16 12:35 PM
2011-05-17 12:47 AM
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? :(2011-05-17 12:47 AM
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 instructionsQuote:
/* 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 saysQuote:
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?