2011-04-05 12:18 AM
External RAM access after leaving STOP mode
2011-05-17 05:30 AM
And if you store these variables in internal SRAM does the problem go away?
If you think the FSMC settings are wrong for the 8 MHz HSI, then you should review the data sheet for your external SRAM part, and also check the settings in the FSMC when you restart, and during the RTC Alarm. Are the variables being corrupted in a predictable manner?2011-05-17 05:30 AM
Thanks for your suggestions!
I moved the static state variables to the SRAM and nothing changed. So I think the FSMC is not the reason. To be sure I checked all FSMC register: They are the same at startup and during the RTC ISR. Yes it is possible to predict the corruption. With a delay placed after the ''wfi'' command, it seems to work fine. To show how it's basically working, here's some kind of pseudo code: // Static variable which holds flags static struct internal internal; // Sets the wakeup flags void set_wakup(bool wakeup) { if (wakeup) internal.wakeup_isr = true; else internal.iwdg_isr = true; } // Checks if a wakeup is required bool check_wakeup(void) { if (internal.iwdg_isr && !internal.wakeup_isr) return false; else if (!internal.iwdg_isr && !internal.wakeup_isr) // Error case return true; else return true; } // Changes the power mode change_power_mode() { // Initialize internal data internal.iwdg_isr = false; internal.wakeup_isr = false; ... // Set all register to enter power ... do { asm(''wfi'') // If 10us delay is placed here, everythings seems ok while(!check_wakeup()); // Set all register to leave power mode ... } // RTC alarm ISR rtc_alarm_isr() { if (watchdog_timeout) set_wakeup(false); else set_wakeup(true); } Without the delay, on every second interrupt the iwdg_isr variable is not set. But I'm sure it is set. I toggled and measured some IO pins: iwdg_isr is set in the set_wakeup function before it's read by the check wakeup function. Do you see any reason why this delay has an influence on the variable? Martin2011-05-17 05:30 AM
Well, I'd probably define anything changed under interrupt as volatile, so the compiler doesn't optimize them out of loops. I'd look at the assembler code generated by the compiler.
In your reset path, check the RCC flag status to see if it is a watchdog reset. If the CPU resets via the IWDG your C startup code is likely to zero out the static memory. Not sure I can tell much from the pseudo-code, how the RTC is initialized, the interrupts cleared, how the alarm and the watchdog is setup and kicked would be more enlightening. Suggest you try to strip the functionality into a simple demo harness, and use the serial port to provide instrumentation and telemetry.2011-05-17 05:30 AM
OK, I tried volatile and it looks like it does the trick. I'm going to take a look at the assembler code to find out where something went wrong.
Thanks a lot! Regards Martin