View previous topic :: View next topic |
Author |
Message |
Triplett
Joined: 28 Feb 2010 Posts: 52 Location: Maryland
|
Posted: Sun Dec 03, 2017 12:26 pm Post subject: Extending the powersave interval for the XMega |
|
|
I am guessing why this happens. Please check my guess.
In the code sample below, when I read back the content of the RTC_COMP register it contains the value I originally placed into the RTC_PER register. Also, the RTC_PER register content is automagically changed into a maximum 16 bit value.
The system behaves as if the Config Clock = Soft option tells the compiler to set up the interrupt for Sectic to trigger on a match with RTC_COMP instead of triggering on RTC_PER overflow. Also, something notices my attempt to write a value into the RTC_PER register, and places my value (2047) into the RTC_COMP register instead.
If that is the case, then it would make sense for the compiler to set RTC_PER to maximum, because if the period was smaller than the compare value there would never be a match.
The purpose of the experiment was to keep the Xmega in powersave mode for longer than one second. The example below wakes up from powersave and toggles the LED once each four seconds. By increasing the value stored in the RTC_PER register above the default (1023) it should be possible to extend the power save time to a maximum of 64 seconds when RTC_PER = 65535 and RTC_CTRL = 1. It becomes 128 seconds with RTC_CTRL = 2. Very long power save intervals are possible by increasing both RTC_PER and the RTC_CTRL prescaler.
I see the example for how to use Config Clock = User. I will experiment with it next.
If I set up a user timer, is it possible to have the RTC wake up the processor from power save each 60 seconds by using RTC_PER overflow instead of compare match?
I know it is possible to have the Sectic ISR increment a counter sixty times, set a flag, and have the micro wake up each second but do a task each minute when the flag commands. I would prefer to keep the micro in powersave mode during the entire minute, or for longer intervals.
Code: |
$regfile = "xm32A4Udef.dat"
$crystal = 2000000
$hwstack = 64
$swstack = 40
$framesize = 40
Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Config PortE.1 = Output ' LED
Config Osc = Enabled, 32KHzosc = Enabled ' Default 2MHz, so Config Sysclock is not needed.
Config Clock = Soft , Rtc = 1KHZ_INT32KHZ_RCOSC , Gosub = Sectic
' Change the RTC period.
BITWAIT RTC_STATUS.0, RESET : RTC_PER = 2047
' Change the RTC compare.
BITWAIT RTC_STATUS.0, RESET : RTC_COMP = 1023
' Write to the RTC_CTRL register.
RTC_CTRL = 2
Config Priority = Static , Vector = Application , Lo = Enabled
Enable Interrupts
Print
Print "RTC_PER = "; BIN(RTC_PER)
Print "RTC_COMP = "; BIN(RTC_COMP)
Print "RTC_CTRL = "; BIN(RTC_CTRL)
Print "RTC_TEMP = "; BIN(RTC_TEMP)
' Allow print to complete before going into powersave.
Waitms 1
Do
Config Powermode = Powersave
Toggle Porte.1 ' Flash an LED.
Loop
End
Sectic:
Return
' Output is as follows:
' RTC_PER = 1111111111111111
' RTC_COMP = 0000011111111111
' RTC_CTRL = 00000010
' RTC_TEMP = 00000011
|
(BASCOM-AVR version : 2.0.7.8 ) |
|
Back to top |
|
|
Triplett
Joined: 28 Feb 2010 Posts: 52 Location: Maryland
|
Posted: Sun Dec 03, 2017 2:54 pm Post subject: Extending the powersave interval for the XMega |
|
|
Update.
When choosing Clock = User, the same thing happens. That surprised me. I do not see a way to put values into the RTC_PER register without it being overridden. I suspect this is possibly a feature of the hardware, not the compiler. Check out the example below, I didn't set up anything to wake the processor and call a timer ISR when the RTC overflows. The revised snippet below only shows how RTC_PER is changed for Clock = User.
One example I found explained how to configure Timer1 for the Mega when using Clock = User, but it does not show using Clock = User with one of the equivalent timers for the XMega, or specifically configuring the XMega RTC to serve that function. A separate example in the BASCOM documentation mentions that when using Clock = User for the XMega we need to configure a timer and set up our own ISR, but I don't see specifics for how to make the RTC overflow wake the processor and execute Timer_irq. The specifics given in the User example for the simulator seem to be built for the Mega, not the XMega.
I should try using Studio to directly store values into the RTC_PER register and then read them back to determine whether it behaves differently. The goal is to put the XMega into powersave during intervals longer than one second, and have the processor wake from powersave mode when the RTC overflow event happens. If upon waking the processor also executes an ISR, that would be good.
So, here below is a revised snippet that shows the RTC_PER register content is automatically moved into the RTC_COMP register. This seems to have nothing to do with selecting Clock = Soft:
Code: |
$regfile = "xm32A4Udef.dat"
$crystal = 2000000
$hwstack = 64
$swstack = 40
$framesize = 40
Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Config PortE.1 = Output ' LED
Config Osc = Enabled, 32KHzosc = Enabled
Config Clock = User
DIM Count as Long
' Change the RTC period.
BITWAIT RTC_STATUS.0, RESET : RTC_PER = 2047
' Change the RTC compare.
BITWAIT RTC_STATUS.0, RESET : RTC_COMP = 1023
' Write to the RTC_CTRL register.
RTC_CTRL = 2
Config Priority = Static , Vector = Application , Lo = Enabled
Enable Interrupts
Print
Print "RTC_PER = "; BIN(RTC_PER)
Print "RTC_COMP = "; BIN(RTC_COMP)
Print "RTC_CTRL = "; BIN(RTC_CTRL)
Print "RTC_TEMP = "; BIN(RTC_TEMP)
' Allow print to complete before going into powersave.
Waitms 1
Do
Config Powermode = Powersave
Toggle Porte.1 ' Flash an LED.
Loop
End
|
|
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Sun Dec 03, 2017 6:05 pm Post subject: |
|
|
Try this:
Code: | $regfile = "xm16e5def.dat"
$hwstack = 200
$swstack = 200
$framesize = 200
Dim I As Byte
'============================================
'Config SOFT Clock
'============================================
Config Clock = Soft , Rtc = 1khz_int32khz_ulp , Gosub = Sectic 'select internal 1 KHz clock from the 32KHz internal oscillator
Waitms 1100 'MUST wait one second before changing RTC_CTRL
Rtc_ctrl = 4 '1=clock interrupt/second - OR 2=2,3=8,4=16,5=64,6=256,7=1024
Enable Interrupts
'++++++++++++++++++++++++++ M A I N ++++++++++++++++++++++++++++++++++++++++++++++++++++++
Do
I = 0
Do
' Config Powermode = Idle
Config Powermode = Powersave
Loop Until I = 2 'with rtc_ctrl=4 this = 32 sec
Loop
End 'end program
Sectic:
Incr I
Return |
E |
|
Back to top |
|
|
Triplett
Joined: 28 Feb 2010 Posts: 52 Location: Maryland
|
Posted: Mon Dec 04, 2017 1:03 am Post subject: Extending the powersave interval for the XMega |
|
|
Enniom,
Thanks. That method works to increase the time before an action is performed, but the micro wakes up multiple times to advance the "I" counter for each time it breaks out of the wait loop in main to do tasks. I am hoping we can make the micro stay completely asleep during all of exactly one minute, and then only wake up from powersave one time in each minute to execute the code in the Sectic ISR. If no code is in the Sectic ISR, then simply resume activity in the main loop exactly one time after a minute of full sleep. I don't care whether Time$ and Date$ would advance sixty times too slowly (I've had days like that).
We can come back to how to keep the micro asleep during all of one minute. For now, I just noticed something odd in the XMega A manual.
Section 17.3.1 on page 190 doesn't explicitly say we need to wait for synchronization when writing a value into the RTC_CTRL register. It isn't a 16 bit register with the need to bank one byte into the RTC_TEMP before writing, so that sort of makes sense. However, if we look further down in section 17.3.2 it mentions that the system can be busy doing a synchronization when we attempt to write a value into the RTC_CTRL register. It's listed with the others.
I noticed by experimenting that we don't need to wait one second before writing into the RTC_CTRL register. If we do a BITWAIT for SYCBUSY to reset immediately before writing into the RTC_CTRL register, the micro seems to write values into the register with no problems. I tried it a few times and it seems to work reliably. We can use this so that when we press the reset button on the development board, the micro starts counting time immediately. I just realized the code example I uploaded didn't have a BITWAIT immediately before writing into the control register, but it should have. Live and learn.
I am sorry for having multiple related questions, but the thing that perplexes me the most is that when I fetch back the contents of the RTC_PER register, it doesn't match what I wrote into that register. Instead, it looks very weird sometimes, as if the upper eight bits of the RTC_PER register are moved into the upper eight bits of the RTC_COMP register, but the lower eight bits of the RTC_PER register stay in the lower eight bits of the RTC_PER register. I will cook a better example to show it.
OK, back to the other thing about staying asleep for 60 seconds. Perhaps we can try this: Put 61439 into the RTC_PER register, because 1024 * 60 = 61440. With RTC_CTRL = 1, the system should come out of powersave and call Sectic one time each minute. |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Mon Dec 04, 2017 1:26 am Post subject: |
|
|
I would likely take the easiest approach.
Code: | Rtc_ctrl = 1
Enable Interrupts
Do
I = 0
Do
Config Powermode = Powersave
Loop Until I = 60
' execute all code here
Loop
End 'end program
Sectic:
Incr I
Return |
If your concern is power consumption, my simple measurements show almost negligible increase by executing the ISR.
E |
|
Back to top |
|
|
Triplett
Joined: 28 Feb 2010 Posts: 52 Location: Maryland
|
Posted: Mon Dec 04, 2017 2:18 am Post subject: |
|
|
Either way is fine. This seems simple enough:
Code: |
$regfile = "xm32A4Udef.dat"
$crystal = 2000000
$hwstack = 64
$swstack = 40
$framesize = 40
Config Osc = Enabled, 32KHzosc = Enabled
Config Clock = Soft , Rtc = 1KHZ_INT32KHZ_RCOSC
Config PORTE.1 = Output ' LED
BITWAIT RTC_STATUS.0, RESET : RTC_PER = 61439
BITWAIT RTC_STATUS.0, RESET : RTC_CTRL = 1
Config Priority = Static , Vector = Application , Lo = Enabled
Enable Interrupts
Do
'
' Do actions here one time each minute.
'
Set PORTE.1
Waitms 10 ' Expend energy briefly.
Reset PORTE.1
Config Powermode = Powersave
Loop
End
|
By changing the PER and CTRL values, the range of possible sleep times is very wide. For devices running on a coin cell, something like this could stay completely asleep for long periods but wake up occasionally to perform a task. |
|
Back to top |
|
|
Triplett
Joined: 28 Feb 2010 Posts: 52 Location: Maryland
|
Posted: Mon Dec 04, 2017 2:48 am Post subject: Extending the powersave interval for the XMega |
|
|
We still have a mystery.
I just wrote this binary 16 bit number (decimal 61445) into the RTC_PER register: 11110000 00000101
I immediately read the value of RTC_PER. It came back: 00000101 00000101
Even stranger, when I read the value of RTC_COMP, it was: 11110000 00000000
This looks as if the lower eight bits of RTC_PER are duplicated into the high byte of RTC_PER.
It also looks as if Montgomery Scott beamed the high byte of the RTC_PER register into the high byte of the RTC_COMP register.
Could someone please explain why this happens ???
Please try this on other micros in case it is a DAT file thing:
Code: |
$regfile = "xm32A4Udef.dat"
$crystal = 2000000
$hwstack = 64
$swstack = 40
$framesize = 40
Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Config PortE.1 = Output ' LED
Config Osc = Enabled, 32KHzosc = Enabled
Config Clock = Soft , Rtc = 1KHZ_INT32KHZ_RCOSC
' Change the RTC period.
BITWAIT RTC_STATUS.0, RESET : RTC_PER = 61445
' Choose the prescaler.
BITWAIT RTC_STATUS.0, RESET : RTC_CTRL = 1
Config Priority = Static , Vector = Application , Lo = Enabled
Enable Interrupts
Print "RTC_PER = "; BIN(RTC_PER)
Print "RTC_COMP = "; BIN(RTC_COMP)
Print "RTC_CTRL = "; BIN(RTC_CTRL)
' Allow print to complete before going into powersave.
Waitms 1
Do
Config Powermode = Powersave
Toggle Porte.1 ' Waste energy for debugging.
Loop
End
' Output is as follows:
' RTC_PER = 0000010100000101
' RTC_COMP = 1111000000000000
' RTC_CTRL = 00000001
|
Note that the micro actually behaves as if the RTC_PER register contains 61445.
The LED changes state at one minute intervals.
I used 61445 instead of 61439 for the period so the 101 would be easy to see in binary.
... |
|
Back to top |
|
|
Triplett
Joined: 28 Feb 2010 Posts: 52 Location: Maryland
|
Posted: Mon Dec 04, 2017 1:19 pm Post subject: Extending the powersave interval for the XMega |
|
|
Fascinating.
The default value for RTC_CTRL is 1.
In the most recent example, the system blinks the LED at something very close to one minute intervals. If we change the example code, and simply comment out the line for writing a 1 value into the RTC_CTRL register, but keep with writing the same large number (61445) into the RTC_PER register, the result is that the micro blinks the LED at one second intervals and ignores the large value in the RTC_PER register, but the program output remains identical to the output we witnessed when we actually wrote the 1 value into the RTC_CTRL register.
You can try the experiment by running the same code with or without the line commented out. The micro goes back and forth between blinking at one minute or one second intervals. The text output of the program remains the same in either case.
...
Possibly, the compiler begins by setting up the one second interrupt so it will trigger a wake up from powersave on a compare match instead of RTC_PER overflow.
Later, if we then actually write a value into the RTC_CTRL register, even the default 1, then the system behaves as if it changes over to using RTC_PER overflow to trigger the wake up from powersave.
In any case, we still have a mystery when trying to read back the values that are stored in the two registers. I'm thinking it's a transporter accident.
Code: |
$regfile = "xm32A4Udef.dat"
$crystal = 2000000
$hwstack = 64
$swstack = 40
$framesize = 40
Config Com1 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Config PortE.1 = Output ' LED
Config Osc = Enabled, 32KHzosc = Enabled
Config Clock = Soft , Rtc = 1KHZ_INT32KHZ_RCOSC
' Change the RTC period.
BITWAIT RTC_STATUS.0, RESET : RTC_PER = 61445
' Choose the prescaler.
'BITWAIT RTC_STATUS.0, RESET : RTC_CTRL = 1
Config Priority = Static , Vector = Application , Lo = Enabled
Enable Interrupts
Print "RTC_PER = "; BIN(RTC_PER)
Print "RTC_COMP = "; BIN(RTC_COMP)
Print "RTC_CTRL = "; BIN(RTC_CTRL)
' Allow print to complete before going into powersave.
Waitms 1
Do
Config Powermode = Powersave
Toggle Porte.1 ' Waste energy for debugging.
Loop
End
' (Unchanged) output is as follows:
' RTC_PER = 0000010100000101
' RTC_COMP = 1111000000000000
' RTC_CTRL = 00000001
|
|
|
Back to top |
|
|
Triplett
Joined: 28 Feb 2010 Posts: 52 Location: Maryland
|
Posted: Mon Dec 04, 2017 6:50 pm Post subject: Extending the powersave interval for the XMega |
|
|
This original post was about figuring out how to extend the RTC interval for powersave mode. We have identified two good ways to do that. The original question has been answered, so we can close this discussion.
Along the way, we separately discussed what seems to be a problem with the "Print BIN(RTC_PER)" statement not providing correct values.
I would like to break that discussion of BIN(RTC_PER) into a separate topic, just to keep it less confusing. See next post on new topic "RTC_PER value question about XMega RTC period register." |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|