STOP2, ENBDM on MCF51

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

STOP2, ENBDM on MCF51

Jump to solution
3,805 Views
leopard86
Contributor II

Hello, I'm new here. I am porting and expanding a RTOS on MCF51JM128 on a Flexis DEMOJM board. Up to now everything went ok, but now I have a few questions on the STOP2 procedure, which is necessary to standby the MCU for several seconds.

 

1. How do I set the XCSR[ENBDM] bit? The Reference Manual say it as to be done with BDM commands, but... what are BDM commands? I can't understand. Are they commands issued by the debugger interface? I have P&E Multilink CyclonePro with Hiwave. Now how should I issue these commands? OR are this commands C commands to embed in the code? Please help me to set this XCSR[ENBDM].

(NOTE: I have to set this bit cause I believe this is the only thing preventing the MCU to go stop2 by now)

 

2. Do you have general guidelines on the wakeup procedure after stop2? Where should I place the code? Maybe in the __initialize_hardware() procedure or MCU_init()? (these names are given by the Device Initialization wizard, in MCUinit.c)

 

Thanks for the help.

Labels (1)
0 Kudos
Reply
1 Solution
1,515 Views
leopard86
Contributor II

People, I solved my problems by neglecting STOP2 and using STOP3 instead. What was keeping me from using STOP3 was the fact I couldn't go STOP3, because the STOP instruction cause a Reset. I inspected the SRS register after reset to figure out the cause for the reset and discovered it was a LOC reset, then reading the Ref Man I understood the CME bit in MCGC3 must be cleared if you want to go STOP3 or STOP4, otherwise you get a Loss of Clock Reset.

That's all, now STOP3 works fine and it has a fast recovery time.

 

View solution in original post

0 Kudos
Reply
9 Replies
1,515 Views
leopard86
Contributor II

Can anyone, at least, point me to a source code of any project on the mcf51 using low power modes and/or stop2?

Thanks

0 Kudos
Reply
1,515 Views
WayneZ
Contributor I

This is a common issue encountered. Some settings I have used for STOP2 mode. You may also want to set up Low Voltage detection and only enable peripheral clocks that are needed. Also use RTC to periodically kick out of stop/wait mode.

 

    // Watchdog disabled. Stop Mode Enable. Background Pin enable. RESET pin enable
    SOPT1 = SOPT1_BKGDPE_MASK | SOPT1_STOPE_MASK;
    SPMSC2 = SPMSC2_LPWUI_MASK | SPMSC2_PPDE_MASK ;
    INTC_WCR = 0x80; // needed to wake from stop mode
                                        // interrupt (not reset) with errors
    SPMSC1 = 0;

and depending on other needs you may want to set CPUCR

    // ISR vectors not in FLASH, moved to RAM
    asm ( move.l #0xD2000000, D0)
    asm ( movec D0, CPUCR)

 

Also deriviatives.h file:

 

/*
 * Note: This file is recreated by the project wizard whenever the MCU is
 *       changed and should not be edited by hand
 */

/* Include the derivative-specific header file */
#include <MCF51QE128.h>
#include <hidef.h>

#define _Stop asm ( mov3q #4,d0; bclr.b d0,SOPT1; stop #0x2000; )
  /*!< Macro to enter stop modes, STOPE bit in SOPT1 register must be set prior to executing this macro */

#define _Wait asm ( mov3q #4,d0; bset.b d0,SOPT1; nop; stop #0x2000; )
  /*!< Macro to enter wait mode */

 

We also use the RTC as a timer tic to exit STOP2 or WAIT modes:

 

void krnl_init_rtc(bool slow)
{
    SCGC2_RTC = 1;

    // use 1kHZ LPO
    // RTIF[7], RTCLKS[6:5], RTIE[4], RTCPS[3:0}
    // RTCLKS[6:5] = 01 = external 38.4KHz oscillator
    // RTCLKS[6:5] = 00 = internal 1KHz LPO
    // RTIE[4] = 1
    // RTCPS[3:0] = 1000 = Div 1 prescaler for internal LPO
    if (slow)
    {
        RTCSC = 0x1F;    // 1 kHZ LPO clock, interrupt enable, divide by 1000
    }
    else
    {
  #if RTC_TIC_RATE_MS == 1
        RTCSC = 0x18;    // 1 kHZ LPO clock, interrupt enable, divide by 1
  #elif RTC_TIC_RATE_MS == 2
        RTCSC = 0x19;    // 1 kHZ LPO clock, interrupt enable, divide by 2
  #elif RTC_TIC_RATE_MS == 4
        RTCSC = 0x1A;    // 1 kHZ LPO clock, interrupt enable, divide by 4
  #elif RTC_TIC_RATE_MS == 10
        RTCSC = 0x1B;    // 1 kHZ LPO clock, interrupt enable, divide by 10
  #else
    #error invalid RTC scale factor
  #endif
    }

    // Note: the mod register = 0 is correct for 1mSec timer.
    RTCMOD = 0x00;   // RTCMOD == 0 configures to interrupt every ~1ms
}

 

interrupt VectorNumber_Vrtc void Real_Time_ISR(void)
{
    RTCSC_RTIF = 1;         // Clear the RTC flag

    systemTimeMs += RTC_TIC_RATE_MS;

   //...

}

 

0 Kudos
Reply
1,515 Views
leopard86
Contributor II

Thank you very much,

actually it seems I was already doing things correct except for INTC_WCR which was set to 0x00. But changing enabling it seems not changing the behaviour of the stop mode.

 

A few questions:

- I'm measuring STOP2 current on the jumper J24 of the Flexis DEMOJM board, it's 580uA, instead of 1.35uA (data sheet). I assume I have 500uA of quiescent current of the USB module plus some more extra. Is that correct? Note that I make no use of USB so it should be defaulted to suspended state from the beginning. Is there any way to avoid USB from draining all that current?

 

- shouldn't I add a "saveRegistersToRAM()" function before entering stop and "restoreRegistersFromRAM()" after wakeup? Then I should set the SPMSC2_PPDACK = 1 to confirm completion of wakeup procedure. Right?

 

The save and restore procedures should be like:

 

Save:

 

  char PTAD_store, PTBD_store // etc...

 

  PTAD_store = PTAD;

  PTBD_store = PTBD; //etc...

 

Restore:

 

 

  PTAD = PTAD_store;
  PTBD = PTBD_store;

 

  PTAD = PTAD_store;  PTBD = PTBD_store; //etc...

 

Right?

0 Kudos
Reply
1,516 Views
leopard86
Contributor II

People, I solved my problems by neglecting STOP2 and using STOP3 instead. What was keeping me from using STOP3 was the fact I couldn't go STOP3, because the STOP instruction cause a Reset. I inspected the SRS register after reset to figure out the cause for the reset and discovered it was a LOC reset, then reading the Ref Man I understood the CME bit in MCGC3 must be cleared if you want to go STOP3 or STOP4, otherwise you get a Loss of Clock Reset.

That's all, now STOP3 works fine and it has a fast recovery time.

 

0 Kudos
Reply
1,515 Views
GABI86
Contributor I

Hello leopard86  , I work with MCF51JM128 , I'm trying to pass the MCU RUN to some STOP mode, but is reset by illegal code i wondered if you have any code to see that I am wrong or if you know what could be the SRS after POR is 0x10.
Thanks leopard86.


0 Kudos
Reply
1,515 Views
WayneZ
Contributor I

Also, to enter STOP2 or WAIT mode use:

 

from hidef.h:

#define EnableInterrupts   ...
#define DisableInterrupts ...

 

Then:

 

void Wait_or_PD(void)
{
    DisableInterrupts;
    if (don't enter wait/stop) // tasks pending
    {
        EnableInterrupts;
        return;
    }

    if (enter wait mode)
    {
        _Wait;
    }
    else
    {
        _Stop; // QE128 uses internal RTC
    }
}

0 Kudos
Reply
1,515 Views
carlospalma
Contributor I

Greetings, I have a question regarding the wake-up sequence of the microcontroller. So far I have been able to suspend the device's activity using the instruction _Stop; that required changing the initialization code to write the following registers:

SOPT1_STOPE=1, SOPT1_WAITE=0 SPMSC1_LVDE=1 SPMSC1_LVDSE=0 SPMSC2_PPDC=1. I have been trying to wake-up the microcontroller, take a few ADC samples, and then make it sleep again. The problem is that it wakes up, sends

me the old ADC value, and then sleeps again, it requires two RTC interruptions to change the ADC value, therefore  it is not reliable, I was wondering if there's a specific set of instructions that need to be executed to ensure the proper peripheral initialization , i have tried writing a logic 1 to SPMSC2_PPACK=1 but the behavior hasn't changed significantly.

Any help will be much appreciated

0 Kudos
Reply
1,515 Views
TomE
Specialist II

Which microcontroller are you using? They don't all have the same internal modules.

If you're using the MCF51JM128, then read "21.4.6 MCU Wait Mode Operation".

If you're using the MCF52259, then you should read up on the PUDELAY field.

Are you starting a new ADC conversion, or are you only just reading the ADC? That usually always reads the results of the previous conversion. So "read twice after a reset" is the right way to use an ADC.

Tom

0 Kudos
Reply
1,515 Views
carlospalma
Contributor I

First of all  thank you for the quick response. I am using mcf51jm128. Will be reading 21.4.6 for sure. I didn't know it was necessary to read twice the ADC value, you saved me a lot of time and effort. Best regards.

0 Kudos
Reply