From 7a8551574b4841bff91cde6d36dba76391e82f35 Mon Sep 17 00:00:00 2001 From: Dan Evans Date: Mon, 1 May 2017 12:04:31 -0600 Subject: [PATCH] samd21/cpu:waitstates for low voltage --- cpu/samd21/cpu.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/cpu/samd21/cpu.c b/cpu/samd21/cpu.c index da9e99cf9d..b4f2d379a9 100644 --- a/cpu/samd21/cpu.c +++ b/cpu/samd21/cpu.c @@ -22,6 +22,24 @@ #include "periph_conf.h" #include "periph/init.h" +#ifndef VDD +/** + * @brief Set system voltage level in mV (determines flash wait states) + * + * @note Override this value in your boards periph_conf.h file + * if a different system voltage is used. + */ +#define VDD (3300U) +#endif + +/* determine the needed flash wait states based on the system voltage (Vdd) + * see SAMD21 datasheet Rev A (2017) table 37-40 , page 816 */ +#if (VDD > 2700) +#define WAITSTATES ((CLOCK_CORECLOCK - 1) / 24000000) +#else +#define WAITSTATES ((CLOCK_CORECLOCK - 1) / 14000000) +#endif + /** * @brief Configure clock sources and the cpu frequency */ @@ -31,12 +49,10 @@ static void clk_init(void) PM->APBAMASK.reg = (PM_APBAMASK_PM | PM_APBAMASK_SYSCTRL | PM_APBAMASK_GCLK); - /* adjust NVM wait states, see table 42.30 (p. 1070) in the datasheet */ -#if (CLOCK_CORECLOCK > 24000000) + /* adjust NVM wait states */ PM->APBBMASK.reg |= PM_APBBMASK_NVMCTRL; - NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_RWS(1); + NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_RWS(WAITSTATES); PM->APBBMASK.reg &= ~PM_APBBMASK_NVMCTRL; -#endif /* configure internal 8MHz oscillator to run without prescaler */ SYSCTRL->OSC8M.bit.PRESC = 0;