cancel
Showing results for 
Search instead for 
Did you mean: 

External RAM access after leaving STOP mode

martinblaser9
Associate II
Posted on April 05, 2011 at 09:18

External RAM access after leaving STOP mode

4 REPLIES 4
Posted on May 17, 2011 at 14:30

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?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
martinblaser9
Associate II
Posted on May 17, 2011 at 14:30

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?

Martin

Posted on May 17, 2011 at 14:30

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.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
martinblaser9
Associate II
Posted on May 17, 2011 at 14:30

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