What I am trying to do now is to reduce power consumption in active mode. According to the datasheet (table 37-8 page 988), the SAMD21 chip should be able to run a while{1} algorithm at about 3mA while being clocked at 48MHz.
But with the bare chip I get 9mA running a blank sketch !
I don't understand why the consumption is so much higher than stated in the datasheet?
Looking at peripheral power consumption, the only thing that could use that much power is the USB peripheral. The core allow the option to disable USB , which I did to have 9mA. I also added in the setupUSBDevice.detach();
with no impact on power consumption.
I successfully reduced the main clock rate to 8MHz and get 2.3mA consumption but the datasheet state we should get 3mA at 48MHz.
So does anyone have a clue why the SAMD21 use so much power in ACTIVE mode?
Did you shut off power and clocks to all the peripherals?
I don’t think that’s normally done by any of the arduino code... (usb.detach does not disable the peripheral. It just tells it to detach. Nothing clears PM_APBBMASK_USB, anywhere.)
Hi westfw,
thanks for the tip.
Using the PM controller, I turned off some peripheral using AHBMASK and slowed down the clock APBA, APBB and APBC to 375kHZ. I also turned down peripheral on APBB and APBC.
I also diabled all the clocks and pointed the peripheral to dead clocks.
With these following code I get 3.5mA in active mode, which is in line with the datasheet!
void setup()
{
reset_gclks();
disconnect_periph();
PM->AHBMASK.reg = 0B000010111;
PM->APBASEL.reg = 0x7;
PM->APBBSEL.reg = 0x7;
PM->APBCSEL.reg = 0x7;
//PM->APBAMASK.reg = 0;
PM->APBBMASK.reg = 0;
PM->APBCMASK.reg = 0;
}
void reset_gclks(void) {
for (uint8_t i = 1; i < GCLK_GEN_NUM; i++) {
disable_gclk(i);
disable_clock_generator(i);
}
}
void disable_gclk(uint8_t gclk) {
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk);
while (GCLK->STATUS.bit.SYNCBUSY == 1) {}
}
void connect_gclk_to_peripheral(uint8_t gclk, uint8_t peripheral) {
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(peripheral) | GCLK_CLKCTRL_GEN(gclk) | GCLK_CLKCTRL_CLKEN;
}
void disable_clock_generator(uint8_t gclk) {
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(gclk);
while (GCLK->STATUS.bit.SYNCBUSY != 0) {}
}
void disconnect_periph() {//connect all periph to a dead clock
for (byte i = 1; i < 37; i++) {
connect_gclk_to_peripheral(4, i);
}
}
void loop() {}
What I don't get is why there is such a big difference? In the datasheet, the sum of all the peripheral consumption seems to be around 1mA.
Now I will try to turn on just the peripherals I need and see what current I get when I do useful things in active mode.
Thanks again for pointing me in the right direction!
Olivier,
Can you show us the code that gets you to 3uA in deep sleep so easily on the SAMD21 (Zero)? On my bare bones clone I'm unable to get below about 500uA.
Thanks,
Stephen