1

I'm posting here as a last resort as I've read through the SAMD20 and SAMD21 datasheets, searched forums and used different deep sleep examples as references. My problem seems very similiar to what Matt Thomas was experiencing here: ATSAMR21 sleep high current draw However his link to the Atmel forum comment doesn't work any more, so I can't actually see what specifically he did to achieve low current consumption.

I've tried many different things but I can never get below around 500 µA. For now I'm testing on an Adafruit Qt Py, supplying 3V3 directly to circumvent the regulator. I'm measuring using a Power Profiler Kit II.

Even turning off the OSC8M and running on the ULP OSC I see no fall in current. Didn't expect it to do anything as the OSC8M is set to ONDEMAND and won't run once generator 0 sources the ULP oscillator.

Is there something I'm missing completely?

#include "sam.h"

int main(void)
{   
    GCLK->GENCTRL.reg =
        GCLK_GENCTRL_ID(0) |
        GCLK_GENCTRL_SRC_OSCULP32K |
        GCLK_GENCTRL_IDC |
        GCLK_GENCTRL_GENEN;
    while(GCLK->STATUS.bit.SYNCBUSY);
    
    SYSCTRL->OSC8M.bit.ENABLE = 0;
    SYSCTRL->BOD33.bit.ENABLE = 0;
    
    PM->APBCMASK.bit.ADC_ = 0;
    PM->APBBMASK.bit.DMAC_ = 0;
    PM->APBBMASK.bit.PAC1_ = 0;
    PM->APBBMASK.bit.PORT_ = 0;
    PM->APBBMASK.bit.USB_ = 0;
    
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();
    
    while (1) 
    {
    }
}
```
  • Please add a schematic and links to the data sheet. – Andy aka Mar 23 '23 at 11:50
  • Shouldn't you be setting up `OSCCTRL` somewhere? – Lundin Mar 23 '23 at 12:10
  • `GCLK_GENCTRL_IDC` Is some "improved duty cycle" setting. Sounds like it could cause extra current consumption - try disabling it? – Lundin Mar 23 '23 at 12:12
  • Not a direct solution but in the past I've found this sort of issue to be caused by GPIO internal pull up/down settings being in conflict with the external state of the pins either due to external pulls or actively driven levels. – Andrew Mar 23 '23 at 12:39
  • @Andyaka https://ww1.microchip.com/downloads/aemDocuments/documents/MCU32/ProductDocuments/DataSheets/SAM-D21-DA1-Family-Data-Sheet-DS40001882H.pdf – Praktikanten Mar 23 '23 at 12:42
  • @Lundin according to the datasheet you don't need to set up anything in regards to the oscillators. The chip sets the OSC8M to 1 MHz (prescaled by 8), and feeds it to generator 0, which supplies the CPU clock. In my code I disable the use of the OSC8M in favour of the low power internal 32K osc. But the IDC shouldn't cause that much current draw. – Praktikanten Mar 23 '23 at 12:43
  • @Praktikanten I might be confusing things for the case where you have external quartz. You only run on internal oscillators though? – Lundin Mar 23 '23 at 12:57
  • @Lundin Yes, only internal ones. I have an external available as well (not on the Qt Py, but on the other device I'm working on). I'm wondering if there's something I need to turn off via the registers, but it doesn't seem like it. The PM stuff doesn't change the power draw by much either. There's some high speed bus stuff enabled in the PM, but they seem to be necessary for the mic to be able to wake up again. – Praktikanten Mar 23 '23 at 13:01
  • So post the schematic, since this code doesn't do much at all and the board is therefore likely the problem. – Lundin Mar 23 '23 at 13:04
  • https://cdn-learn.adafruit.com/assets/assets/000/095/390/original/adafruit_products_QTPy_sch.png?1602007604 This is the dev board from Adafruit. Keep in mind I'm powering directly to 3V3 to avoid the 5V->3V3 regulator. – Praktikanten Mar 23 '23 at 13:06
  • Also, the pins are by default set to the low power settings according to the datasheet, so I shouldn't have to change them. – Praktikanten Mar 23 '23 at 13:07
  • Ohm's law. 3.3 / 5100 = 647uA from that one pull-up alone. – Lundin Mar 23 '23 at 13:53
  • @Lundin I desoldered it despite of knowing it wouldn't change anything. It might be pulled high, but the default pin state should be high impedance (basically best low power setting), and as expcted it didn't change anything. I do appreciate the suggestions though. – Praktikanten Mar 23 '23 at 14:53
  • @Praktikanten, in standby, what is the state of all the digital IOs? There can be unwanted current consumption if a) Input buffer is enabled and the pin is floating b) pullup is enabled and the pin is driven low either by the output buffer or externally c) pulldown is enabled and the pin in driven high by the output buffer. For each pin we need to ensure that we are not having any of this happening. It is tedious. – sai Mar 23 '23 at 15:39
  • Doesn't the Qt Py have a Neopixel built in? Even without turning on any of the colors in the Neopixel, there's a resting current draw. Use your multimeter to check voltages on the Vdd pin of the Neopixel. Is it zero or not? – Mark Leavitt Mar 23 '23 at 18:58
  • @MarkLeavitt thanks for the response - the Neopixel is one of those extra tiny chips with the pads underneath, so I'm not sure if I'll be able to read the voltage. According to the schematics the VDD pin is connected to PA15, so by default pin state it shouldn't be supplied anything. As I have no use for it this project, I desoldered it instead. It changed nothing in my power measurements. – Praktikanten Mar 24 '23 at 11:28
  • @sai I've been looking into that actually. The section 40.7 of the datasheet shows a scenario where they achieve something like 13 µA deep sleep current. In this they state "I/Os are inactive with internal pull-up". To achieve this I do the following ```PORT->Group[0].PINCFG[i].reg = PORT_PINCFG_PULLEN; PORT->Group[0].OUT.reg |= (1 << i);``` Where i is the pins, 0 to 31 in my case. OUT = 1 and PULLEN gives a pulled high IO. – Praktikanten Mar 24 '23 at 11:31
  • Datasheet states that "During Reset, all PORT lines are configured as inputs with input buffers, output buffers and pull disabled". The above two lines above enables the pull up, and keeps output and input buffers disabled. – Praktikanten Mar 24 '23 at 11:36
  • @Praktikanten, I am not familiar with the code and hence the following questions: I assume PORT->Group[0].PINCFG[i].reg = PORT_PINCFG_PULLEN; means you are enabling pullup. What does PORT->Group[0].OUT.reg |= (1 << i); mean? are you setting the output buffer HiZ or are you driving 1? Where is the setting to disable the input buffer? – sai Mar 25 '23 at 04:39
  • @sai Thanks for getting back :) The input buffer is disabled by default, and since I'm not configuring anything in regards to this, they are still disabled (Section 23.6.3.1 in the datasheet shows DIR and INEN to be 0 and PULLEN and OUT to be 1 for pull up with input buffer disabled. No matter what I do I do not see a current below 620 µA. The development board now only consists of the microcontroller and it's necessary caps and an unused regulator and QWIIK connector. – Praktikanten Mar 27 '23 at 06:20
  • I was considering if I had maybe disabled the peripheral clocks incorrectly, however if I run the generic clock generator 0 using the OSC8M at 1 MHz instead of the ULP I see no difference in sleep currents. – Praktikanten Mar 27 '23 at 06:22
  • SOLVED. The circumvented LDO was drawing some current through its 3V3 pin. After desoldering it and a diode I'm seeing 3.2 µA of deep sleep current, which is quite acceptable (datasheet is 2.9 µA in this scenario). Thankfully the software was correct, so I understood everything correctly, just not the hardware. – Praktikanten Mar 27 '23 at 08:29

1 Answers1

2

The small LDO on the development board was being circumvented by feeding 3V3 directly to the 3V3 pin on the board. However the LDO has common ground on the input and output side, which allowed a leakage current to run through the LDO. After desoldering it the correct sleep current was achieved. See info here: Unable to lower current consumption below 500 µA in SAMD21 chip during deep sleep