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_cpuid
|
||||||
FEATURES_PROVIDED += periph_gpio
|
FEATURES_PROVIDED += periph_gpio
|
||||||
FEATURES_PROVIDED += periph_i2c
|
FEATURES_PROVIDED += periph_i2c
|
||||||
|
FEATURES_PROVIDED += periph_pm
|
||||||
FEATURES_PROVIDED += periph_pwm
|
FEATURES_PROVIDED += periph_pwm
|
||||||
FEATURES_PROVIDED += periph_rtc
|
FEATURES_PROVIDED += periph_rtc
|
||||||
FEATURES_PROVIDED += periph_rtt
|
FEATURES_PROVIDED += periph_rtt
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export CPU_ARCH = cortex-m0plus
|
export CPU_ARCH = cortex-m0plus
|
||||||
export CPU_FAM = samd21
|
export CPU_FAM = samd21
|
||||||
|
|
||||||
|
USEMODULE += pm_layered
|
||||||
|
|
||||||
include $(RIOTCPU)/sam0_common/Makefile.include
|
include $(RIOTCPU)/sam0_common/Makefile.include
|
||||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||||
|
|||||||
@ -39,7 +39,7 @@ static void clk_init(void)
|
|||||||
|
|
||||||
/* configure internal 8MHz oscillator to run without prescaler */
|
/* configure internal 8MHz oscillator to run without prescaler */
|
||||||
SYSCTRL->OSC8M.bit.PRESC = 0;
|
SYSCTRL->OSC8M.bit.PRESC = 0;
|
||||||
SYSCTRL->OSC8M.bit.ONDEMAND = 0;
|
SYSCTRL->OSC8M.bit.ONDEMAND = 1;
|
||||||
SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
|
SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
|
||||||
SYSCTRL->OSC8M.bit.ENABLE = 1;
|
SYSCTRL->OSC8M.bit.ENABLE = 1;
|
||||||
while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY)) {}
|
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 */
|
/* make sure we synchronize clock generator 0 before we go on */
|
||||||
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
|
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 */
|
/* redirect all peripherals to a disabled clock generator (7) by default */
|
||||||
for (int i = 0x3; i <= 0x22; i++) {
|
for (int i = 0x3; i <= 0x22; i++) {
|
||||||
GCLK->CLKCTRL.reg = ( GCLK_CLKCTRL_ID(i) | GCLK_CLKCTRL_GEN_GCLK7 );
|
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;
|
return ((((uint32_t)sercom) >> 10) & 0x7) - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PM_NUM_MODES (3)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
PM->APBAMASK.reg |= PM_APBAMASK_EIC;
|
||||||
GCLK->CLKCTRL.reg = (EIC_GCLK_ID |
|
GCLK->CLKCTRL.reg = (EIC_GCLK_ID |
|
||||||
GCLK_CLKCTRL_CLKEN |
|
GCLK_CLKCTRL_CLKEN |
|
||||||
GCLK_CLKCTRL_GEN_GCLK0);
|
GCLK_CLKCTRL_GEN_GCLK2);
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
||||||
/* configure the active flank */
|
/* configure the active flank */
|
||||||
EIC->CONFIG[exti >> 3].reg &= ~(0xf << ((exti & 0x7) * 4));
|
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