Go Down

Topic: Clock and Register Configuration (Read 2025 times) previous topic - next topic

mattb1969

Hi,

I am struggling with the MKRWAN 1310 at the moment, not writing the code, but configuring the SAMD device to have only the correct clocks running to minimise power consumption whilst still having the correct clocks running.

In my current project I want to use the edge triggering of external interrupts, but this requires a clock. I don't know which clock is configured in the default codebase. I also want to use the RTC functionality, I'd like it to use the same clock, saving power, but once again I am not able to do this currently.

My question is not how to do this specific example, but how do others do this type of activity? Looking at the code snippets that are posted, I find it hard to believe that this is manually typed in, so is there a toolset that people use for it?

If there is, what is it? Is there any way I can 'see' the configuration that has already been applied in files like MKRWAN.H and therefore try and figure how best to get what I want with lowest power consumption.

If there isn't how do people know the exact constants that are use, things like:- 
     SYSCTRL-SYSCTRL->VREG.bit.RUNSTDBY = 1
     SYSCTRL->DFLLCTRL.bit.RUNSTDBY = 1;
Once I know them I can search through all the files in the library, but that makes it very difficult to work out new ones, especially as the library files are for multiple variants and I first need to figure out the bits that are relevant to my variant.

Grateful for any views.

hzrnbgy

At a minimum, you'll need an external 32K crystal to generate the 48MHz CPU clock, and the RTC. This means at least two clock generators, one for the main clock, and one for the RTC. Now if you need some of the other peripherals (USART/SPI/etc), you'll need another clock generator, so that makes it three.

You can't use the RTC clock generator since it has to be at 1 Hz (in Calendar mode at least)

MartinL

Hi mattb1969,

The SAMD21 has a variety of clock sources: external 32.768kHz crystal (XOSC32K), high accuracy internal 32.768kHz oscillator (OSC32K), ultra low power internal 32.768kHz oscillator (OSCULP32K), internal 8MHz oscillator (OSC8M), 48MHz Digtial Frequency Locked Loop (DFLL48M) and finally a 96MHz Digital Phase Locked Loop (DPLL96M).

These clock sources are selected and routed to the various peripherals, such as the ADC, AC, DAC, TCC/TC timers, SERCOM modules, RTC, WTC, etc.. via generic its generic clock system.

The Arduino core code file "startup.c" already assigns the clock sources to certain generic clocks:

GCLK0 - DFLL48M (also acts as the main processor clock)
GCLK1 - XOSC32K if using external crystal, or OSC32K for crystalless operation
GCLK2 - OSCULP32K used by the Watchdog Timer Counter (WTC)
GCLK3 - OSC8M

However, neither the clock sources or the generic clocks are set to run on standby (RUNSTDBY) by default. To do this, it's necessary to set the RUNSTDBY bit for the clock source, possibly the generic clock and the peripheral itself.

It's possible to assign the remaining generic clocks 4 to 7 to any clock source and route them to any peripheral of your choice.

The RTC is active during sleep by default, here's some example code to get it running together with sleep mode: https://forum.arduino.cc/index.php?topic=620634.0.

The SAMD21'S CPU will wake up from an asynchronous interrupt by default, even without the main clock running. If you require the External Interrupt Controller (EIC) to edge detect this is also possible.

Finally, if you intend to run a number of peripherals during sleep mode then it's necessary to keep the SAMD21's internal voltage regulator in normal mode. By default it will enter low power mode, but this means it won't be able to power all the peripherals. This is detailed here: https://forum.arduino.cc/index.php?topic=691880.0.

westfw

Quote
My question is not how to do this specific example, but how do others do this type of activity? Looking at the code snippets that are posted, I find it hard to believe that this is manually typed in, so is there a toolset that people use for it?
AFAIK, it's manually typed in.  Usually copied from someone else who already typed it in.
Microchip/Atmel has some tools that do things in a more standardized way (ASF), or even based on GUI manipulations (http://start.atmel.com, but:
  • Everyone hates them.
  • they're not compatible with the rest of the Arduino environment.
  • they produce very bloated code.
  • the code they produce isn't very readable.
  • they aren't really much easier to use than typing things in manually.


I don't know if you can actually save much power by configuring fewer clocks.  The usual power-saving technique is to avoid routing clocks to the peripherals, rather than actually disabling the clocks.

Quote
I don't know which clock is configured in the default codebase.
You CAN look at that, you know.  It even has unusually good comments!
https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/startup.c#L24

mattb1969

thanks all for the responses, they are really helpful.

These clock sources are selected and routed to the various peripherals, such as the ADC, AC, DAC, TCC/TC timers, SERCOM modules, RTC, WTC, etc.. via generic its generic clock system.

The Arduino core code file "startup.c" already assigns the clock sources to certain generic clocks:

GCLK0 - DFLL48M (also acts as the main processor clock)
GCLK1 - XOSC32K if using external crystal, or OSC32K for crystalless operation
GCLK2 - OSCULP32K used by the Watchdog Timer Counter (WTC)
GCLK3 - OSC8M

However, neither the clock sources or the generic clocks are set to run on standby (RUNSTDBY) by default. To do this, it's necessary to set the RUNSTDBY bit for the clock source, possibly the generic clock and the peripheral itself.
Thanks for this, it is starting to make some sense.

Finally, if you intend to run a number of peripherals during sleep mode then it's necessary to keep the SAMD21's internal voltage regulator in normal mode. By default it will enter low power mode, but this means it won't be able to power all the peripherals. This is detailed here: https://forum.arduino.cc/index.php?topic=691880.0.
Maybe this is why it isn't working, I will give that a go.

I don't know if you can actually save much power by configuring fewer clocks.  The usual power-saving technique is to avoid routing clocks to the peripherals, rather than actually disabling the clocks.
You CAN look at that, you know.  It even has unusually good comments!
https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/startup.c#L24

Thanks for the pointer to the source code that controls the clocks, that is at least giving me a clue as to the default configuration.

I totally agree, the tool provided by Atmel is awful. the output is completely different from anything else I have seen, so other than using it as a nice visual tool to understand some of the language, it's output is pointless.

At a minimum, you'll need an external 32K crystal to generate the 48MHz CPU clock, and the RTC. This means at least two clock generators, one for the main clock, and one for the RTC. Now if you need some of the other peripherals (USART/SPI/etc), you'll need another clock generator, so that makes it three.

You can't use the RTC clock generator since it has to be at 1 Hz (in Calendar mode at least)
This explains why when I first implemented the RTC and then added WDT, it just appeared to fail completely, although it did send data very infrequently!

Looks like I need to build my knowledge to understand the configuration of the chip and how best to do it. Datasheets are difficult documents to read, does anyone any easier way of getting to grips with it?

I had understood that I can turn off clocks etc to lower power consumption, one of the threads I read talked about swapping clocks for the RTC to the ultra lower power one, but maybe I have got all that wrong too.

All of this simply because I wanted to have Lora, RTC and WDT running at the same time and still keep power to the lowest possible.





Go Up