2007-08-23 08:14 PM
Idle mode doesn't seem to work, what am I doing wrong?
2011-05-17 12:45 AM
I can not get Idle mode to work on the STR912. I call the following function (in SRAM, not flash) from my idle thread. I have a variety of interrupts that should wake it. Also, for testing, I have all peripheral clocks enabled during Idle mode, ie:
// enable all idle clocks SCU->MGR0 = 0xFFFFFFFF; SCU->MGR1 = 0xFFFFFFFF; When I let the program run, a few cycles after entering Idle mode, I get: ''Bad JTAG communication: Write to IR: Expected 0x1, got 0x0 (TAP Command:15) @ OF 0xCF4'' and I can't get back into the program. If I disconnect the JTAG adapter and let it run, it appears to hang in the same spot. The NOPs I added to the Idle() function are more than enough as recommended in the Errata. Any ideas? -Mark __ramfunc void Idle(void) { SCU->PWRMNG =0x1; // 96/25*12 = 48 junk cycles are needed. I've put 50. asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); asm(''nop''); }2011-05-17 12:45 AM
Does anyone have sample code that implements Idle mode successfully?
2011-05-17 12:45 AM
Hi Mark
Which errata are you refering to? The one that I use for the STR912 is from 9.5.2007 and says that the RTC crystal must be connected to enter idle or sleep mode. I see nothing about the NOPS. Regards Mark Butcher2011-05-17 12:45 AM
I'm using rev 5 of the errata dated May 2007
2.17 says you need an RTC crystal, which I have. 2.23 ''Exit from Sleep and Idle Mode'' says you need to enter idle mode from a function in RAM, which pasted above. 2.24 ''Sleep and Idle Mode Timing Requirements/Code Execution after Setting the Sleep or Idle Mode Bit'' says that you need No_dummy_Instr = (fCPUCLK/fOSC)*12 dummy instructions after waking from idle mode. I have fCPUCLK = 96 MHz and fOSC = 25 MHz, so that is about 46 or 48 NOPS, depending on if they meant for round-off or not. I used 50 NOPS which should be plenty.2011-05-17 12:45 AM
Any update on this topic?
i.e. I'd like some sample code for an Idle routine that I can call. I was going to use (from the ST library):void SCU_EnterIdleMode(void)
{
SCU->PWRMNG |= 0x1;
}
Thanks. -J [ This message was edited by: jsarao on 17-08-2007 23:11 ]
2011-05-17 12:45 AM
Hello jsarao,
You find attached a low power (Idle mode) working example.The example works as follows: -After system power on, the system operates in Normal Run mode with the oscillator as clock source.To indicate this, a LED connected to P9.1 is switched on. When you push a button connected to pin P7.4, the system enters Idle mode and the LED connected to P9.1 is switched off. When a falling edge on EXINT2 line 16 is detected, an external wake up is generated. To indicate that the MCU wakes up from Idle mode, a LED connected to P9.0 is toggled. In the example, we need to put 12 dummy instruction while fCPU=25 MHz and fOSC=25Mhz in order to avoid executing any valid instructions after the Idle bit setting and before entering the mode. With best regards, mirou2011-05-17 12:45 AM
Hello all,
Jsarao, it's enough to enable all peripherals in idle mode only once in all the project. lakata, I tested your project also and it works fine for me (with rev D, rev G and rev H). May be there is a problem with buttons or in your board. Please find attached the tested project. With best regards, mirou2011-05-17 12:45 AM
Thank for the quick response, mirou!
Follow up questions: If I enable all peripherals in Idle mode, I should only have to do that once, say at the beginning of my application. Or do I need to enable all peripherals in Idle mode any time I want to make the call to SCU_EnterIdleMode() ? Is there any problem making a method:void DoIdle( void )
{
/*Enter Idle mode*/
SCU_EnterIdleMode();
/*Dummy instructions*/
__asm
{
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
}
}
I don't plan to ever change my input clock crystal, so the number of NOPs should never have to change. As always, thanks so much for your help. -J
2011-05-17 12:45 AM
Mirou,
I tried your demo (and reworked it so that it works on the STR912-SK demo board. It doesn't work. The demo now is supposed to: 1. wait for B1 to be pressed 2. goes to Idle mode and waits for B2 to be pressed Pressing B1 will make LED2 blink. Pressing B2 will make LED1 toggle. It doesn't work though correctly. 1. It works correctly if I don't go into Idle mode (if it is commented out) but that isn't very interesting. 2. If I do go into Idle mode, without the secondary LED blink in the main while loop (commented out), then sometimes it works, and sometimes it just hangs (no response to B2). It is flaky. I would estimate it fails to work about 25% of the time. 3. If I do go into Idle mode and enable the secondary LED blink in the main while loop, it never works. Mirou, can you please figure out what is wrong? I am using a stock STR912-SK board, date code 619 with STR912FW44. I've attached a full IAR project.