Go Down

Topic: How can I waste power as much as possible on SAMD21? (Read 148 times) previous topic - next topic


Hi, I made a board based on SAMD21, which is basically a crystaless Zero.

It turns out that to power from a USB battery pack, I need to periodically increase the current consumption > 50mA. My goal is to find a safe way to do this without adding more components onto the board.

What I've done so far:
Baseline with 48MHz DFLL oscillator + I2S, I2C, USB peripheral = 22mA
+ Outputting max voltage to DAC pin (not connected to anything) = 35mA

I can't seem to increase the draw beyond this point. Anyone has other suggestions?


Hi tanvach,

You could try firing up the SAMD21's 96MHz Fractional Digital Phase Locked Loop (FDPLL96M), then route this clock source to any unused TCCx/TC3 timers, all of which are capable of running at this higher speed:

Code: [Select]
// SAMD21: Connect the 96MHz DPLL to the TCCx timers
void setup()
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |         // Enable the generic clock
                      //GCLK_CLKCTRL_GEN_GCLK1 |     // Select GCLK1 using the OSC32K internal 32k oscillator for CRYSTALLESS operation
                      GCLK_CLKCTRL_GEN_GCLK2 |     // Select GCLK2 using the OSCULP32K ultra low power 32k oscillator
                      GCLK_CLKCTRL_ID_FDPLL;       // Connect GCLK2 to GCLK_DPLL input
  SYSCTRL->DPLLRATIO.reg = SYSCTRL_DPLLRATIO_LDRFRAC(11) |    // Generate a 96MHz DPLL clock source from the external 32kHz crystal
                           SYSCTRL_DPLLRATIO_LDR(2928);       // Frequency = 32.768kHz * (2928 + 1 + 11/16) = 96MHz
  SYSCTRL->DPLLCTRLA.reg = SYSCTRL_DPLLCTRLA_ENABLE;          // Enable the Digital Phase Locked Loop (DPLL)
  while (!SYSCTRL->DPLLSTATUS.bit.LOCK);                      // Wait for the DPLL to achieve lock
  GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) |         // Divide the 96MHz clock source by divisor 1: 96MHz/1=96MHz
                     GCLK_GENDIV_ID(4);           // Select Generic Clock (GCLK) 4

  GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC |          // Set the duty cycle to 50/50 HIGH/LOW
                      GCLK_GENCTRL_GENEN |        // Enable the generic clock
                      GCLK_GENCTRL_SRC_FDPLL |    // Set the clock source to FDPLL96M at 96MHz
                      GCLK_GENCTRL_ID(4);         // Select GCLK4
  while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |         // Enable the generic clock
                      GCLK_CLKCTRL_GEN_GCLK4 |     // Select GCLK4
                      GCLK_CLKCTRL_ID_TCC0_TCC1;   // Connect GCLK4 to TCC0 and TCC1

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |         // Enable the generic clock
                      GCLK_CLKCTRL_GEN_GCLK4 |     // Select GCLK4
                      GCLK_CLKCTRL_ID_TCC2_TC3;    // Connect GCLK4 to TCC2 and TC3
  TCC0->PER.reg = 0xFFFF;                          // Set the frequency of the PWM on TCC0
  while(TCC0->SYNCBUSY.bit.PER);                   // Wait for synchronization
  TCC1->PER.reg = 0xFFFF;                          // Set the frequency of the PWM on TCC1
  while(TCC1->SYNCBUSY.bit.PER);                   // Wait for synchronization
  TCC2->PER.reg = 0xFFFF;                          // Set the frequency of the PWM on TCC2
  while(TCC2->SYNCBUSY.bit.PER);                   // Wait for synchronization

  TCC0->CTRLA.bit.ENABLE = 1;                      // Enable TCC0
  while (TCC0->SYNCBUSY.bit.ENABLE);               // Wait for synchronization
  TCC1->CTRLA.bit.ENABLE = 1;                      // Enable TCC1
  while (TCC1->SYNCBUSY.bit.ENABLE);               // Wait for synchronization
  TCC2->CTRLA.bit.ENABLE = 1;                      // Enable TCC2
  while (TCC2->SYNCBUSY.bit.ENABLE);               // Wait for synchronization

void loop() {}

Note that the generic clock divider should remain set to 1 at this higher frequency.


Thanks for your response, that did help get around 2mA more power.

Go Up