Hi there,
Can anyone give me a general idea of how to implement the STOP3 mode on a MC9S08GT60 MCU. I'm trying to implement the STOP3 mode in wireless_uart and it doesn't seem to work. Has anyone used STOP3 in wireless UART who may be able to give me some pointers? I'm using a 1321x SRB board with a MC9S08GT60 MCU. Thanks.
Hi Mac,
Thanks for the reply. I took a look at that. It was definitely helpful. I'm trying to use STOP2 or STOP3 mode in the wireless_uart application to achieve as low power as possible when I am not transmitting data(using zigbee) from the DS1822. Right now i'm using an RTI interrupt to wake the MCU from STOP2 or STOP3. After setting all the registers at the beginning of main(for stop2 mode) in wireless_uart.c, I then call _asm stop 9 times successively so I have enough time to measure current to see if STOP2 is working properly. I believe this gives me approx. 10sec delay. I believe I am also correctly setting all unused port pins to output (instead of input state). I am doing this in the main as well right now. Is there a better place to do this? In terms of register settings for STOP2 here is what I'm using right now:
SOPT=0b01100000; //STOPE=1
//SPMSC2=0b00000011;
SPMSC2=0b00000111; //this should set to STOP2
SRTISC_RTICLKS = 0;
SRTISC_RTIE = 1;
SRTISC_RTIS0 = 1;
SRTISC_RTIS1 = 1;
SRTISC_RTIS2 = 1; //approx 1 sec delay for RTI
IRQSC_IRQPE = 1;
SPMSC1_LVDRE = 0; //was 1 //reset on low voltage detect
SPMSC1_LVDSE = 0;
void interrupt rti_isr(void)
{
rti_count++;
if(rti_count >= MAX_RTI_COUNT){
SRTISC_RTIACK = 1; // reset the RTIF
Sleep_Mode = 0;
rti_count = 0;
}
else {
Sleep_Mode=1;
}
}
Just after I transmit data each time, I try to go into STOP2 mode and use the RTI interrupt to time the successive _asm stops. I also put the radio into Hibernate as well to try to conserve power when I am not transmitting. I have read in other posts that there may be some additional peripherals or settings I can turn off to get even lower power. Right now, we are measuring about 1.2 mA at the lowest but we would like to get down to about 100 uA if possible.
I would greatly appreciate any suggestions you may have on how to minimize the power when I am not transmitting. I am not really using any ports except PTF4 and PTF6 at the moment for my DS1822 communications. I am not using the SCI module or ATD module etc but I am using the radio to transmit the DS1822 sensor information. At the moment I am using an MC9S08GT60 MCU on the 1321xSRB board. One of the things I am trying to do right now is disable LVD (LVDE=0). The trouble is, if I disable this I do not seem to be able to exit from STOP2 mode for some reason. If I enable (LVDE=1) then it exits from STOP2 mode just fine but consumes more power. With LVDE=0, we measure approx. 500 uA and with LVDE=1 we measure 1.2 mA. I'm also setting ICGC1_OSCSTEN = 0 which I understand is also needed to save power so that the oscillator is not on during STOP mode? I'm also reading in the post below that I should turn off the VREF1 and VREF2 modules to conserve power as well. (I'm not using ATD modules or anything). The post also mentions that the BDM must be disconnected, and the DBG module must be clock gated off but I am unsure of how to accomplish this. Can this be accomplished by simple register settings?
Here is the other post I was referring to:
UseMcuClock();
MLMEHibernateRequest();
_asm stop;
_asm stop;
_asm stop;
_asm stop;
_asm stop;
_asm stop
_asm stop
_asm stop
_asm stop
MLMEWakeRequest();
UseExternalClock();
LOW_POWER_WHILE();
Hello,
At least part of your problem is due to you not disabling the LVD during stop mode. You are attempting to successively alter the LVDRE bit, and then the LVDSE bit. This will not work because these are write-once bits - all write once bits need to be simultaneously written with their required values. Since LVD is not disabled, you will not be able to enter stop 2 mode.
The statement SPMSC1_LVDRE = 0; is actually a read-modify-write process, i.e. all bits of the register are read, the required LVDRE bit is changed, and then the modified value is written back to the register, including the other write-once bits.
I notice that you are also writing individual bits to the SRTISC register. While there are no write-once bits in this register, it will result in less efficient code than simultaneously writing all bits.
The correct invocation of inline assembly code is __asm (with two underscores). You appear to have used a single underscore.
For stop 2 mode entry, the current GPIO output state wil be latched, but the internal logic is not maintained. So the current state of the various registers must also be saved to RAM variables, prior to entering stop mode. On exit from stop 2 mode, the saved values need to be restored to the GPIO registers (or alternatively the registers re-initialised), prior to releasing the latched state by writing to the PPDACK bit. If this restoral is not done, the GPIO will resume its reset state.
Regards,
Mac
Hi Mac,
Thanks for the reply. I made the changes you suggested. I can get down to 1.1 mA now but was hoping to still be able to get down to 500 uA or 100 uA.
In the beginning of main() I set all the registers for STOP2:
SOPT=0b01100000;
SPMSC2=0b00000111;
SRTISC=0b00010111;
SPMSC1=0x00;
IRQSC=0x10;
Then later on in the application I use the __asm stop; with two underscores this time:
UseMcuClock();
MLMEHibernateRequest()
__asm stop;
__asm stop;
__asm stop;
__asm stop;
__asm stop;
__asm stop
__asm stop
__asm stop
__asm stop
MLMEWakeRequest();
UseExternalClock();
However, is the beginning of main() the right time to make these register assignments? I noticed that the register assignments for SOPT, SPMSC2, SRTISC, SPMSC1, and IRQSC are being made in MC9S08GB60.h. Should I change these register assignments from that file instead of assigning them in main()? Thanks for your help.
Hello,
It is necessary to initialise the system registers as soon as possible after a reset, because some of these contain write once registers. This is why it is done early in main().
MMG135 wrote:I noticed that the register assignments for SOPT, SPMSC2, SRTISC, SPMSC1, and IRQSC are being made in MC9S08GB60.h. Should I change these register assignments from that file instead of assigning them in main()?
I think that there is some misunderstanding about the device header file. This file defines the various hardware registers, and their bit usage, and under normal circumstances should never be altered. This file does not assign any value to the contents of a register - it does not genenerate any code.
With respect to the current draw, you might test stop 3 mode, rather than stop 2 mode, to see whether the current is any lower.
As I mentioned previoulsy, stop 2 mode gives partial power down, and so does not maintain the state of the internal hardware registers (but does latch the current GPIO output states). Your code does not address this issue, but neither does it clear the latched state by writing 1 to the PPDACK bit. It may be possible that you have floating inputs after wakeup from the first STOP, but I am not sure. With stop 3 mode, there is no partial power down, so the register states are continuously maintained.
If you wish to persist with stop 2, you will likely need something similar to the following function.
void stop_1sec( void){ RTI_init(); // Initialise RTI for wakeup save_state(); // Save current state of critical MCU I/O registers __asm stop; // Enter stop2 mode GPIO_init(); // Initialise GPIO registers - similar to startup restore_state(); // Restore state of critical MCU I/O registers SPMSC2_PPDACK = 1; // Release latched state}
// Part of main() function for ( ; ; ) { // Main loop __RESET_WATCHDOG(); for (i = 10; i; i--) { stop_1sec(); // Code for execution every second } // Code for execution every 10 seconds }
Regards,
Mac