I have a program that enter in stop mode and wakes when KBI interrupt is set, after he has that enter again in stop mode and wait new interrupt of KBI.
When I starts the program, he enter in stop mode, when occurs KBI wakes but not enter in STOP mode again.
after of initialization
for(;;){
asm stop;
if (KBISC_KBF)
{
KBISC_KBACK = 1;
bReadKey = 1 ;
}
//do few things
}
what the happend?
I am using MC9RSKA1
Solved! Go to Solution.
Hi
Have you checked the MTIM interrupt?
You can also exclude the intit of MTIM to prove or disprove my previous assumption keeping only KBI interrupt enabled.
Pavel
I just noticed that I ever did an example of RTI project I just made. It is running on DEMO9RS08KA2, it will flash LED2 on the board at approximate 1 second.
Unlike other HC(S)08 MCUs which jumps to the vector address directly when interrupt event comes, the interrupt event of KA2 can only wake up the MCU, and it is the MCU's task to find the interrupt source and jump to the corresponding routine.
The program will enter stop mode again before each rti finished.
Hope this helps!
hi
I do not have a KA device populated on any board here to try. I have noticed you are looking into KBI register instead or System Interrupt Pending Register SIP1 while checking the presence of pending interrupt. This might not be a problem, the problem seems you have any other pending interrupts and that is why you are not able to enter low power again. The suspect to me is MTIM.
MTIM - Clearing TOF is a two-step process. The first step is to read the MTIMSC register while TOF is set. The
second step is to write a 0 to TOF. If another overflow occurs between the first and second steps, the
clearing process is reset and TOF will remain set after the second step is performed.
I would try something like this>
for(;;) {
__RESET_WATCHDOG();
if (SIP1_KBI == 1) { //KBI interrupt pending
KBISC_KBACK=1;
counterKBI++; //only increments in ISR
}
if (SIP1_MTIM == 1) {
(void)(MTIMSC == 0); /* Overflow int. flag clearing (first part) */
MTIMSC_TOF = 0; /* Int. flag clearing (2nd part) and timer control register setting */
counterMTIM++; //only increments in ISR
}
asm STOP;
}
Pavel
In the software the bReadKey is a flag that enable other function that change the state of PTAD3.
The KBI is enables for the PTAD0, PTAD1, PTAD4 and PTAD5.
When any pins equals the 0, the KBI flag set, after set bReadKey and do the changes, after bReadKey is clear and just set the flag again in when flag KBI is set.
When the software starts, the current supply is of 1.1uA, after of first interrupt, the current supply is approximately 2.8mA, when the KBI is not set the current is 2.6mA.
Hi
Have you checked the MTIM interrupt?
You can also exclude the intit of MTIM to prove or disprove my previous assumption keeping only KBI interrupt enabled.
Pavel
Really the MTIM is the trouble.
I just set up when KBI wakeup. And before enter in stop mode I cleaned the MTIMSC register. Works perfect.
Thanks.
But, why is happen?
Great
Commonly the mcu just does not enter thel STOP when any interrupt is pending..
Pavel
Hi
I would point you to LSB of ICSC1, /* ICSC1: IREFSTEN=0 */
ICS requires IREFSTEN=1 and LVDE and LVDSE must be set to allow operation in stop.
Pavel
i don't use the ICS to wakeup the stop mode, i just use the KBI. This software reads if the button was pressed, then he send a code. The power supply is a lithium battery, then i need low power consume. The /*few things*/ no "stops" the to enter in stop mode because i left this in this loop o just a timer run and the result is the same. I need that the microcontroller return to stopmode after the button pressed. But i cannot do it.
Hi Paulo,
ICS is clock module, IREFSSTEN = 1 means Internal reference clock remains enabled in stop mode. if this bit is cleared,Internal reference clock is disabled in stop, those periphrals clocked by internal clock can't work in stop mode. I believe that is the problem in your code. Pavel is right. Pleasy try ICSC1 = 0x01;
Best Regards
Weiping
still doesn't work. Enter in stop mode once only. when KBI wakeup the stop mode he dont enter again
Hello,
I cannot see any obvious problem within your code for the main loop. Maybe you have a secondary loop within your "// do few things" location, so that the stop instruction is never reached the second time. Or perhaps you are disabling the KBI input as part of a debounce process, and are then not re-enabling the input?
Also it would seem that you have disabled the COP timer, since this is not periodically being cleared within the main loop.
Regards,
Mac
Yes, I have disabled COP . my main loop is so ..
void main (void) {
MCU_init () / * call Device Initialization * /
/ * Include your code here * /
KBISC_KBACK = 0;
asm stop;
for (;;)
{
the function above
}
for (;;) {
/ * __ RESET_WATCHDOG (), by default, COP is disabled with device init. When enabling, also reset the watchdog. * /
} / * Loop forever * /
/ * Please make sure que you never leave main * /
}
Hi,
Sorry for my mistake, yes, RS08 doesn't include interrupt controller.
If you mark a breakpoint at asm stop in the loop, can it be executed once more?
B.R
Weiping
Hi Paulo, did you enable the interrupt of KBI, if did, the corresponding ISR is necessary, or else the CPU will run away.
B.R
Weiping
In mC9rs08ka1 datasheet
5.5 Interrupts
The MC9RS08KA2 Series does not include an interrupt controller with vector table lookup mechanism as
used on the HC08 and HCS08 devices. However, the interrupt sources from modules such as LVD, KBI,
and ACMP are still available to wake the CPU from wait or stop mode. It is the responsibility of the user
application to poll the corresponding m odule to determine the source of wakeup.
my mcu init function
void MCU_init(void)
{
/* ### MC9RS08KA2_8 "Cpu" init code ... */
/* PE initialization code after reset */
/* Common initialization of the write once registers */
/* SOPT: COPE=0,COPT=1,STOPE=1,BKGDPE=0,RSTPE=0 */
SOPT = 0x60;
/* SPMSC1: LVDF=0,LVDACK=0,LVDIE=0,LVDRE=1,LVDSE=1,LVDE=0,BGBE=0 */
SPMSC1 = 0x18;
/* System clock initialization */
if (*(unsigned char* __paged)CONVERT_TO_PAGED(0x3FFA) != 0xFF) { /* Test if the device trim value is stored on the specified address */
ICSTRM = *(unsigned char* __paged)CONVERT_TO_PAGED(0x3FFA); /* Initialize ICSTRM register from a non volatile memory */
ICSSC = *(unsigned char* __paged)CONVERT_TO_PAGED(0x3FFB); /* Initialize ICSSC register from a non volatile memory */
}
/* ICSC1: CLKS=0,IREFSTEN=0 */
ICSC1 = 0x00; /* Initialization of the ICS control register 1 */
/* ICSC2: BDIV=0,LP=0 */
ICSC2 = 0x00; /* Initialization of the ICS control register 2 */
/* Common initialization of the CPU registers */
/* PTAPE: PTAPE5=1,PTAPE4=1,PTAPE2=1,PTAPE1=1,PTAPE0=1 */
PTAPE |= (unsigned char)0x37;
/* PTAPUD: PTAPUD5=0,PTAPUD4=0,PTAPUD2=0,PTAPUD1=0,PTAPUD0=0 */
PTAPUD &= (unsigned char)~0x37;
/* PTASE: PTASE5=1,PTASE4=1,PTASE3=1,PTASE1=1,PTASE0=1 */
PTASE |= (unsigned char)0x3B;
/* ### Init_KBI init code */
/* KBISC: KBIE=0 */
KBISC &= (unsigned char)~0x02;
/* KBIES: KBEDG5=0,KBEDG4=0,KBEDG2=0,KBEDG1=0,KBEDG0=0 */
KBIES = 0x00;
/* KBISC: KBIMOD=0 */
KBISC &= (unsigned char)~0x01;
/* KBIPE: KBIPE5=1,KBIPE4=1,KBIPE2=1,KBIPE1=1,KBIPE0=1 */
KBIPE = 0x37;
/* KBISC: KBACK=1 */
KBISC |= (unsigned char)0x04;
/* KBISC: KBIE=1 */
KBISC |= (unsigned char)0x02;
/* ### Init_MTIM init code */
/* MTIMMOD: MOD7=0,MOD6=1,MOD5=1,MOD4=0,MOD3=1,MOD2=1,MOD1=0,MOD0=1 */
MTIMMOD = 0x6D;
/* MTIMCLK: CLKS1=0,CLKS0=0,PS3=0,PS2=1,PS1=0,PS0=1 */
MTIMCLK = 0x06;
(void)(MTIMSC == 0); /* Overflow int. flag clearing (first part) */
/* MTIMSC: TOF=0,TOIE=1,TRST=1,TSTP=0 */
MTIMSC = 0x60; /* Int. flag clearing (2nd part) and timer control register setting */
/* ### Init_GPIO init code */
/* PTAD: PTAD3=0 */
PTAD &= (unsigned char)~0x08;
/* ### */
} /*MCU_init*/
The mcu just enter in stop mode one time, but i want that he enter every time that the KBI ends.