It turns out hooking up an unused peripheral to a disabled GCLK
leads to surprising power savings.
Name the GCLK to be more explicit (and since not all members of
the extended samd2x family have a GCLK7).
Turns out we can just use a non-existing GCLK ID for this, this
even saves us a real GCLK that we can use for something else.
Also make sure to disable *all* peripherals by using
`GCLK_CLKCTRL_ID_Msk` instead of relying on a magic value.
Looks like we previously missed some, since this leads to some
additional power savings:
master: 4.22 mA
this patch: 4.09 mA
The sam0 MCUs all have a DAC peripheral.
The DAC has a resulution of 10 or 12 bits and can have one or two
output channels.
The output pins are always hard-wired to PA2 for DAC0 and PA5 for DAC1
if it exists.
On the same54-xpro I would only get a max value of ~1V when using the
internal reference, so I configured it to use an external voltage reference.
The external reference pin is hard-wired to PA3, so you'll have to connect
that to 3.3V to get results.
Also adapt the defines to the documentation
- CPUs define up to 4 power modes (from zero, the lowest power mode,
to PM_NUM_MODES-1, the highest)
- >> there is an implicit extra idle mode (which has the number PM_NUM_MODES) <<
Previously on saml21 this would always generate pm_set(3) which is an illegal state.
Now pm_layered will correctly generate pm_set(2) for IDLE modes.
Idle power consumption dropped from 750µA to 368µA and wake-up from standby is also
possible. (Before it would just enter STANDBY again as the mode register was never
written with the illegal value.)
Creating an `exti_config` array for a new MCU manually is tedious and error prone.
Luckiely all information is already availiable in the vendor files.
Credit for this discovery & method goes to @Sizurka
The file was generated with
```C
int main(void) {
puts("static const int8_t exti_config[PORT_GROUPS][32] = {");
for (unsigned port = 1; port < 5; ++port) {
printf("#if PORT_GROUPS >= %d\n{\n", port);
for (unsigned pin = 0; pin < 32; ++pin) {
printf("#ifdef PIN_P%c%02uA_EIC_EXTINT_NUM\n", '@' + port, pin);
printf(" PIN_P%c%02uA_EIC_EXTINT_NUM,\n", '@' + port, pin);
printf("#else\n -1,\n#endif\n");
}
printf("},\n#endif\n\n");
}
puts("};");
return 0;
}
```
No changes in generated code are expected, but this makes adding new members
of the sam0 CPU families much easier.