cpu: samd21: add periph/pm support
This commit is contained in:
parent
807a190e20
commit
f42e5381ee
@ -2,6 +2,7 @@
|
||||
FEATURES_PROVIDED += periph_cpuid
|
||||
FEATURES_PROVIDED += periph_gpio
|
||||
FEATURES_PROVIDED += periph_i2c
|
||||
FEATURES_PROVIDED += periph_pm
|
||||
FEATURES_PROVIDED += periph_pwm
|
||||
FEATURES_PROVIDED += periph_rtc
|
||||
FEATURES_PROVIDED += periph_rtt
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
export CPU_ARCH = cortex-m0plus
|
||||
export CPU_FAM = samd21
|
||||
|
||||
USEMODULE += pm_layered
|
||||
|
||||
include $(RIOTCPU)/sam0_common/Makefile.include
|
||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||
|
||||
@ -39,7 +39,7 @@ static void clk_init(void)
|
||||
|
||||
/* configure internal 8MHz oscillator to run without prescaler */
|
||||
SYSCTRL->OSC8M.bit.PRESC = 0;
|
||||
SYSCTRL->OSC8M.bit.ONDEMAND = 0;
|
||||
SYSCTRL->OSC8M.bit.ONDEMAND = 1;
|
||||
SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
|
||||
SYSCTRL->OSC8M.bit.ENABLE = 1;
|
||||
while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY)) {}
|
||||
@ -84,6 +84,14 @@ static void clk_init(void)
|
||||
/* make sure we synchronize clock generator 0 before we go on */
|
||||
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
|
||||
|
||||
/* Setup Clock generator 2 with divider 1 (32.768kHz) */
|
||||
GCLK->GENDIV.reg = (GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(0));
|
||||
GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_GENEN |
|
||||
GCLK_GENCTRL_RUNSTDBY |
|
||||
GCLK_GENCTRL_SRC_OSCULP32K);
|
||||
|
||||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
||||
|
||||
/* redirect all peripherals to a disabled clock generator (7) by default */
|
||||
for (int i = 0x3; i <= 0x22; i++) {
|
||||
GCLK->CLKCTRL.reg = ( GCLK_CLKCTRL_ID(i) | GCLK_CLKCTRL_GEN_GCLK7 );
|
||||
|
||||
@ -102,6 +102,8 @@ static inline int _sercom_id(SercomUsart *sercom)
|
||||
return ((((uint32_t)sercom) >> 10) & 0x7) - 2;
|
||||
}
|
||||
|
||||
#define PM_NUM_MODES (3)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -138,7 +138,7 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
|
||||
PM->APBAMASK.reg |= PM_APBAMASK_EIC;
|
||||
GCLK->CLKCTRL.reg = (EIC_GCLK_ID |
|
||||
GCLK_CLKCTRL_CLKEN |
|
||||
GCLK_CLKCTRL_GEN_GCLK0);
|
||||
GCLK_CLKCTRL_GEN_GCLK2);
|
||||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
||||
/* configure the active flank */
|
||||
EIC->CONFIG[exti >> 3].reg &= ~(0xf << ((exti & 0x7) * 4));
|
||||
|
||||
89
cpu/samd21/periph/pm.c
Normal file
89
cpu/samd21/periph/pm.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* Copyright (C) 2015 Saurabh Singh
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_samd21
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
* @author Saurabh Singh <saurabh@cezy.co>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "periph/pm.h"
|
||||
|
||||
#define ENABLE_DEBUG (1)
|
||||
#include "debug.h"
|
||||
|
||||
enum system_sleepmode {
|
||||
/**
|
||||
* Idle 0 mode.
|
||||
* Potential Wake Up sources: Synchronous(APB, AHB), asynchronous.
|
||||
*/
|
||||
SYSTEM_SLEEPMODE_IDLE_0,
|
||||
/**
|
||||
* Idle 1 mode.
|
||||
* Potential Wake Up sources: Synchronous (APB), asynchronous
|
||||
*/
|
||||
SYSTEM_SLEEPMODE_IDLE_1,
|
||||
/**
|
||||
* Idle 2 mode.
|
||||
* Potential Wake Up sources: Asynchronous
|
||||
*/
|
||||
SYSTEM_SLEEPMODE_IDLE_2,
|
||||
/**
|
||||
* Standby mode.
|
||||
* Potential Wake Up sources: Asynchronous
|
||||
*/
|
||||
SYSTEM_SLEEPMODE_STANDBY,
|
||||
};
|
||||
|
||||
void pm_set(unsigned mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0:
|
||||
/* Standby Mode
|
||||
* Potential Wake Up sources: asynchronous
|
||||
*/
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
break;
|
||||
case 1:
|
||||
/* Sleep mode Idle 2
|
||||
* Potential Wake Up sources: asynchronous
|
||||
*/
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_2;
|
||||
break;
|
||||
case 2:
|
||||
/* Sleep mode Idle 1
|
||||
* Potential Wake Up sources: Synchronous (APB), asynchronous
|
||||
*/
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_1;
|
||||
break;
|
||||
case 3:
|
||||
/* Sleep mode Idle 0
|
||||
* Potential Wake Up sources: Synchronous (APB, AHB), asynchronous
|
||||
*/
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Executes a device DSB (Data Synchronization Barrier) */
|
||||
__DSB();
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user