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.
The DFLL on samd5x has a hardware bug that requires a special
re-enabling sequence when it is disabled and then re-enabled again.
When running the clock on-demand, the hardware handles the disabling
and re-enabling so that sequence does not get executed.
To reproduce, run `tests/periph_uart` on `same54-xpro`.
Without this patch the test will get seemingly stuck on `sleep_test()`.
(In fact it keeps running, but the DFLL has the wrong frequency so the
UART baudrate is wrong).
In this test, on `same54-xpro` only UART0 is sourced from DFLL.
So if the UART is disabled the DFLL will be turned off as well.
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.)
When a previously disabled DFLL gets enabled again, the frequency will
be incorrect. Follow the procedure outlined in the errata sheet, section 2.8.3
to work around the issue.
This fixes wake from standby.
When changing the clock configuration while the RTC is running, the
RTC may end up in an undefined state that leaves it unresponsive.
The RTC is not reset to stay persistent across reboots/hibernate, so
it will not be reset on init.
Instead, disable the RTC while configuring the clocks, rtc_init() will
take care of re-enabling it.
@dylad introduced this workaround for saml21, samd5x needs it too.
To reproduce, set the CLOCK_CORECLOCK of a samd5x board (e.g. same54-xpro)
to 48 MHz.
Run any RTC application. The CPU will be stuck in _wait_syncbusy() after
a reboot.
This patch will fix this. (You will need to power-cycle the board if the
RTC has entered the stuck state as it will never be reset.)
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.
Set the ONDEMAND bit so clocks are only run if they have a user configured.
This saves 390 µA on same54-xpro.
examples/default:
before: 3.88 mA
after : 3.49 mA
examples/gnrc_networking: (with REB215-XPRO EXT3)
before: 13.29 mA
after : 12.9 mA
Instead of hard-coding the peripheral clocks to CLOCK_CORECLOCK
introduce helper functions to return the frequency of the individual
GCLKs and use those for baud-rate calculations.
This requires the GCLK to be part of the peripheral's config struct.
While this is already the case for most peripherals, this also adds
it for those where it wasn't used before.
As it defaults to 0 (CLOCK_CORECLOCK) no change is to be expected.
`pm_set()` gets called by the idle thread whose stack is too small
for normal DEBUG()/printf().
Use DEBUG_PUTS() instead to print the static debug strings.
There are some constraints to the oscillators on the samd5x.
- DFLL is fixed to run at 48 MHz
- DPLL can run at 96 to 200 MHz
Always use DFLL for frequencies <= 48 MHz.
For frequencies >= 96 MHz, use DPLL directly.
For frequencies < 96 MHz, clock DPLL at twice the desired frequency
and use a divider.
- Removed stdio_init() from newlib's _init(), as this is too late in the boot
process to allow DEBUG()ing during periph_init()
- Added stdio_init() to the various cpu_init() routines of the ARM CPUs just
before periph_init()
There were still some things wrong with samd5x CPU init which only
showed up when used in conjunction with RIOTBOOT, that is cpu_init()
was called twice.
- gclk_connect() should block until the GCLK is ready.
- DPLL should be disabled dring configuration.
- make sure not to use DPLL for MCLK when re-configuring DPLL
- All APBxMASK bits should be in a defined state.
- always enable 1kHz oscilator output.
This adds supoprt for the Atmel SAMD51 & SAME54 SoC.
The SAME5x/SAMD5x is a line of Cortex-M4F MCUs that share peripherals
with the samd2x Cortex-M0+ and saml1x Cortex-M23 parts.