Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu/samd21: implement low power modes #2309

Merged
merged 1 commit into from
Oct 17, 2016

Conversation

LudwigKnuepfer
Copy link
Member

TODO: needs testing

@LudwigKnuepfer LudwigKnuepfer added Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Jan 15, 2015
start_lpm();
break;
case LPM_OFF: /* Standby Mode - Potential Wake Up sources: Asynchronous */
current_mode = LPM_POWERDOWN;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake sorry! Should be

current_mode = LPM_OFF;

@LudwigKnuepfer
Copy link
Member Author

Just tried with the diff below and couldn't see any difference on our energy consumption test equipment.
We tried to measure the energy consumption over the external power pins which might be imprecise. The xpro has support for energy measurements on the jumper'd pins next to the buttons.. we didn't try that.
Maybe someone else can try this PR with their measurement tools?

diff --git a/core/kernel_init.c b/core/kernel_init.c
index a57f119..c18b6e6 100644
--- a/core/kernel_init.c
+++ b/core/kernel_init.c
@@ -64,8 +64,8 @@ static void *idle_thread(void *arg)
             lpm_set(LPM_IDLE);
         }
         else {
-            lpm_set(LPM_IDLE);
-            /* lpm_set(LPM_SLEEP); */
+            //lpm_set(LPM_IDLE);
+            lpm_set(LPM_SLEEP);
             /* lpm_set(LPM_POWERDOWN); */
         }

@saurabh984
Copy link

I'll have access to my lab again next week. I'll give it a go then. Thanks

@LudwigKnuepfer
Copy link
Member Author

@saurabh984 I addressed your comments.

@@ -14,40 +15,112 @@
* @brief Implementation of the kernels power management interface
*
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
* @author Saurabh Singh <email-missing@example.com>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saurabh984 your email is missing here ;)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LudwigOrtmann saurabh@cezy.co Haven't had a chance to try it yet :(

@PeterKietzmann
Copy link
Member

@LudwigOrtmann I tried to test this PR with:

static void button_handler(void *args)
{
    puts("Button Handler");
    lpm_arch_awake();
}

int main(void)
{
    puts("Test LPM modes\n");
    /* this is the user button on samr21-xpro */
    gpio_init_int(GPIO_1, GPIO_NOPULL, GPIO_BOTH, &button_handler, 0);

    puts("Init lpm");
    lpm_arch_init();

    puts("LPM_ON");
    lpm_arch_set(LPM_ON);

    puts("LPM_IDLE");
    lpm_arch_set(LPM_IDLE);

    puts("LPM_SLEEP");
    lpm_arch_set(LPM_SLEEP);

    puts("LPM_POWERDOWN");
    lpm_arch_set(LPM_POWERDOWN);

    puts("LPM_OFF");
    lpm_arch_set(LPM_OFF);
}

I couldn't awake the board after LPM_SLEEP. Can you tell how this is done?

@saurabh984
Copy link

@PeterKietzmann Try commenting out the cpu_init() (shown below) code from lpm_arch_awake(void) please?

if (current_mode == LPM_SLEEP) {
        /* Re-init */
        cpu_init();
    }

@PeterKietzmann
Copy link
Member

@saurabh984, I commented this line out. With this change I could also awake from LPM_SLEEP and enter LPM_POWERDOWN. But I did not came out of LPM_POWERDOWN (btw: I haven't looked into the boards documentation). Then I measured the current through the "current measurement header". My results:
LPM_ON/LPM_IDLE : 560 uA
LPM_SLEEP : 535 uA
LPM_POWERDOWN : 500 uA
I don't know if this are the expected values: In addition: First I tried to measure the current through a 10Ohm shunt-resistor and an Oscilloskop which "crashed" the board in any way. Then I took my multimeter (ammeter) and had the same problems. Once I switched the multimeter-range to MICROampere the internal resistance seemd to be small enough to fit the measurement.

@PeterKietzmann
Copy link
Member

@saurabh984 did you experience the same?

@OlegHahm OlegHahm force-pushed the master branch 3 times, most recently from 9f184dd to 45554bf Compare March 31, 2015 13:01
@biboc
Copy link
Member

biboc commented Apr 7, 2015

@PeterKietzmann, from p1048 to 1051/1138 (samr21 datasheet), you can find the power consumption of the samr21. There is also a schematic about how to use the measurement pin.
Will try it in the comings days hopefully

@biboc
Copy link
Member

biboc commented Apr 8, 2015

Here are my results with @PeterKietzmann source code (above):

(h:14 m:4 s:56) Init lpm
(h:14 m:4 s:56) LPM_ON
(h:14 m:4 s:56) LPM_IDLE

LPM_IDLE/LPM_ON: 1,62mA

(h:14 m:5 s:1) Button Handler
(h:14 m:5 s:1) LPM_SLEEP

LPM_SLEEP1,38mA

(h:14 m:5 s:5) Button Handler
(h:14 m:5 s:5) LPM_POWERDOWN

LPM_POWERDOWN : 1,08mA

(h:14 m:5 s:21) Button Handler

Here I've got 0,39mA but I can't wake up, Interruption doesn't work anymore.

If I keep cpu_init(), I'm not able to wake up from LPM_SLEEP as well.

By the way, @PeterKietzmann, you should use a GPIO_PULLUP and GPIO_RISING otherwise the interrupt doesn't work properly.
gpio_init_int(GPIO_1, GPIO_PULLUP, GPIO_RISING, &button_handler, 0);

@biboc
Copy link
Member

biboc commented Apr 8, 2015

@jnohlgard
Copy link
Member

@bapclenet what do you mean by the SCB is not mentioned for power management?
The SLEEPDEEP bit in the SCB SCR decides if the CPU should go to STOP mode or WAIT mode when wfi is executed.

edit: I am speaking from experience with CM3/4 CPUs, I did not look up CM0 docs on this.

@biboc
Copy link
Member

biboc commented Apr 8, 2015

Sorry, my bad, I didn't know that before, I've just seen it.

@PeterKietzmann
Copy link
Member

@bapclenet your results seem somehow reasonable even if they appear to be kind of small, comparing to the datasheet (worse are mine :-) ). But honestly I didn't compare the clock setup etc. . Now the question is: is there anybody out who has a deeper knowledge with this MCU and with (low) power modes? Otherwise I need to spend some time in going into detail.

@PeterKietzmann
Copy link
Member

@bapclenet can you explain in detail how you build your setup? Looking at the datasheet on page 1054 it feels like I can't directly access the needed pins or have to use an external power supply not from USB.
In the user guide on page 7 sec. 3.3.1 you can read that it's possible to measure the consumption through the pins on which the jumper is on. They have a different naming scheme to the pins mentioned in the datasheet. What are your doubts using these?

Sorry for all these questions. I don't want to spend too much time in this and you already did these steps.

@biboc
Copy link
Member

biboc commented Apr 10, 2015

@PeterKietzmann, I use a Multimeter from Agilent.

  • in VCC target
    Ground in VCC MCU

There are the same pins as in the datasheet. What I'm doing is removing the header (Datasheet p4 - CURRENT MEASUREMENT HEADER) and plug them to my multimeter.

I think (not sure about that), whatever the source is, there is a regulator which transforms 5V to 3.3V, and after the transformation, there are those two pins where you can measure the current before going to the MCU.

Does it make sens?

@biboc
Copy link
Member

biboc commented Apr 10, 2015

For more details:
20150410_155745

@PeterKietzmann
Copy link
Member

Yes and no. Measuring the current through the "current measurement header"-pins is reasonable and the way I already did (some time ago). What I don't understand is the hint you gave me with the schematic in the datasheet (p. 1054). Anyway, if I see it right and understand correctly you just power your board by the pins and not by an USB connector and you measure the current through the measurement extension header.

@kYc0o
Copy link
Contributor

kYc0o commented Jul 12, 2016

I think this PR will need a lot of attention so I don't think it will make it for the release. What's the status BTW?

@PeterKietzmann PeterKietzmann modified the milestones: Release 2016.10, Release 2016.07 Jul 12, 2016
@PeterKietzmann
Copy link
Member

@MichelRottleuthner did you already give it a try?

@MichelRottleuthner
Copy link
Contributor

@PeterKietzmann Nope. It's on my todo list but I think it will take a few weeks before I have time for that.

@kYc0o
Copy link
Contributor

kYc0o commented Jul 12, 2016

Maybe @aabadie wants to take a look ;)

@immesys
Copy link
Contributor

immesys commented Sep 23, 2016

Hey all. Can I help get this merged in for the upcoming release? I have used it, along with a few other changes, and have a SAMR21 running at 5.2uA idle and 15uA average sampling temperature at 1Hz

@biboc
Copy link
Member

biboc commented Sep 23, 2016

@immesys, you're welcome to help us merging this PR :-)
How did you measure the current (can you provide a schema) ?
Did you try all different modes?
I remember that we had some problem to wake up from LPM_OFF, have you tried?
If you don't have a lot of changes, you can create a PR on LudwigKnuepfer:samd21_lpm branch (with rebase) or if it is totally different, create a new one.

@immesys
Copy link
Contributor

immesys commented Sep 23, 2016

So, the good news is yes, it is waking up fine from lpm off, the bad news is that the code is a little messy (as things get when you are just trying to make it work). I am busy splitting things up into independent PRs, so things like adding radio sleep to netdev, switching the xtimer source to ULP OSC32.

I could really use a shepherd, as some of these changes are in core code and change default behavior (I use FLL instead of PLL saving a bit of energy, and I source it from the ULP instead of the 8mhz RC, which costs accuracy but saves energy). I am busy running experiments to quantify the benefit of each change individually so that the riot core devs can decide if each one is worth it.

@OlegHahm
Copy link
Member

@kaspar030, @gebart, would you be willing to act as a shepherd? I would also volunteer but have only time in about two weeks from now.

@PeterKietzmann
Copy link
Member

@immesys it's great to see your efforts improving the sam* support in RIOT! Would it help you to merge this PR "as is" (or with slight adoptions which you would need to propose ;-) )?

@immesys
Copy link
Contributor

immesys commented Sep 30, 2016

I use this file as-is, so it would definitely help to merge it. The slight changes elsewhere are too invasive to just merge, I will need to discuss them with the core maintainers to work out the best way to do them.

@PeterKietzmann
Copy link
Member

@LudwigKnuepfer would you rebase this PR once more? If not @immesys can you take it over (closing this one and opening an updated PR)

@immesys
Copy link
Contributor

immesys commented Oct 4, 2016

I would not mind rebasing, but it didn't actually have any changes, I merge it as-is with no conflicts. In fact at the moment the idle thread (in kernel_init.c) doesn't actually put anything to sleep so merging this file shouldn't even change the behavior of existing code (which is either a feature or a problem depending on how you look at things)

@PeterKietzmann
Copy link
Member

@immesys I do agree with you but regardless of that I'd like to see Murdock pass, so the PR should be updated. (It's still based on Travis, so kind of old :-) )

@LudwigKnuepfer
Copy link
Member Author

I will rebase.

@LudwigKnuepfer
Copy link
Member Author

Should I also squash and mark as ready for CI?

@PeterKietzmann
Copy link
Member

Yes please! But probably I'm just back on Monday.

@OlegHahm
Copy link
Member

@LudwigKnuepfer, squash?

@LudwigKnuepfer
Copy link
Member Author

@OlegHahm I did.

@PeterKietzmann PeterKietzmann added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Oct 17, 2016
Copy link
Member

@PeterKietzmann PeterKietzmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK and go

@PeterKietzmann PeterKietzmann merged commit 4668904 into RIOT-OS:master Oct 17, 2016
@biboc
Copy link
Member

biboc commented Oct 17, 2016

Congrats for this PR!

@LudwigKnuepfer LudwigKnuepfer deleted the samd21_lpm branch January 14, 2017 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: pm Area: (Low) power management CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.