1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #13764 from benpicco/cpu/saml11/use_buck_converter

cpu/saml1x: select buck voltage regulator when possible
This commit is contained in:
Dylan Laduranty 2020-04-01 14:47:47 +02:00 committed by GitHub
commit 6bba4188fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 121 additions and 0 deletions

View File

@ -31,6 +31,12 @@ extern "C" {
*/
#define CLOCK_CORECLOCK (16000000U)
/**
* @brief Enable the internal DC/DC converter
* The board is equipped with the necessary inductor.
*/
#define USE_VREG_BUCK (1)
/**
* @name Timer peripheral configuration
* @{

View File

@ -367,6 +367,20 @@ void gpio_pm_cb_enter(int deep);
*/
void gpio_pm_cb_leave(int deep);
/**
* @brief Called before the power management enters a power mode
*
* @param[in] deep
*/
void cpu_pm_cb_enter(int deep);
/**
* @brief Called after the power management left a power mode
*
* @param[in] deep
*/
void cpu_pm_cb_leave(int deep);
/**
* @brief Wrapper for cortexm_sleep calling power management callbacks
*
@ -378,8 +392,12 @@ static inline void sam0_cortexm_sleep(int deep)
gpio_pm_cb_enter(deep);
#endif
cpu_pm_cb_enter(deep);
cortexm_sleep(deep);
cpu_pm_cb_leave(deep);
#ifdef MODULE_PERIPH_GPIO
gpio_pm_cb_leave(deep);
#endif
@ -392,6 +410,39 @@ static inline void sam0_cortexm_sleep(int deep)
*/
void gpio_disable_mux(gpio_t pin);
/**
* @brief Available voltage regulators on the supply controller.
*/
typedef enum {
SAM0_VREG_LDO, /*< LDO, always available but not very power efficient */
SAM0_VREG_BUCK /*< Buck converter, efficient but may clash with internal
fast clock generators (see errata sheets) */
} sam0_supc_t;
/**
* @brief Switch the internal voltage regulator used for generating the
* internal MCU voltages.
* Available options are:
*
* - LDO: not very efficient, but will always work
* - BUCK converter: Most efficient, but incompatible with the
* use of DFLL or DPLL.
* Please refer to the errata sheet, further restrictions may
* apply depending on the MCU.
*
* @param[in] src
*/
static inline void sam0_set_voltage_regulator(sam0_supc_t src)
{
#ifdef REG_SUPC_VREG
SUPC->VREG.bit.SEL = src;
while (!SUPC->STATUS.bit.VREGRDY) {}
#else
(void) src;
assert(0);
#endif
}
/**
* @brief Returns the frequency of a GCLK provider.
*

View File

@ -90,6 +90,18 @@ uint32_t sam0_gclk_freq(uint8_t id)
}
}
void cpu_pm_cb_enter(int deep)
{
(void) deep;
/* will be called before entering sleep */
}
void cpu_pm_cb_leave(int deep)
{
(void) deep;
/* will be called after wake-up */
}
/**
* @brief Configure clock sources and the cpu frequency
*/

View File

@ -144,6 +144,18 @@ uint32_t sam0_gclk_freq(uint8_t id)
}
}
void cpu_pm_cb_enter(int deep)
{
(void) deep;
/* will be called before entering sleep */
}
void cpu_pm_cb_leave(int deep)
{
(void) deep;
/* will be called after wake-up */
}
/**
* @brief Initialize the CPU, set IRQ priorities, clocks
*/

View File

@ -30,6 +30,16 @@
#define _NVMCTRL NVMCTRL
#endif
/* As long as FDPLL is not used, we can default to
* always using the buck converter.
*
* An external inductor needs to be present on the board,
* so the feature can only be enabled by the board configuration.
*/
#ifndef USE_VREG_BUCK
#define USE_VREG_BUCK (0)
#endif
static void _gclk_setup(int gclk, uint32_t reg)
{
GCLK->GENCTRL[gclk].reg = reg;
@ -89,6 +99,18 @@ uint32_t sam0_gclk_freq(uint8_t id)
}
}
void cpu_pm_cb_enter(int deep)
{
(void) deep;
/* will be called before entering sleep */
}
void cpu_pm_cb_leave(int deep)
{
(void) deep;
/* will be called after wake-up */
}
/**
* @brief Initialize the CPU, set IRQ priorities, clocks
*/
@ -97,6 +119,11 @@ void cpu_init(void)
/* initialize the Cortex-M core */
cortexm_init();
/* not compatible with 96 MHz FDPLL */
if (USE_VREG_BUCK) {
sam0_set_voltage_regulator(SAM0_VREG_BUCK);
}
/* turn on only needed APB peripherals */
MCLK->APBAMASK.reg = MCLK_APBAMASK_MCLK
| MCLK_APBAMASK_OSCCTRL

View File

@ -126,6 +126,19 @@ static void _dfll_setup(void)
NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_RWS(3);
#endif
}
void cpu_pm_cb_enter(int deep)
{
(void) deep;
/* will be called before entering sleep */
}
void cpu_pm_cb_leave(int deep)
{
(void) deep;
/* will be called after wake-up */
}
/**
* @brief Initialize the CPU, set IRQ priorities, clocks
*/