MCU specific sleep feature is now defined in MCU specific file.
This commit is contained in:
5
mcu/chx-gnu-linux.c
Normal file
5
mcu/chx-gnu-linux.c
Normal file
@@ -0,0 +1,5 @@
|
||||
void
|
||||
chx_sleep_mode (int enable_sleep)
|
||||
{
|
||||
(void)enable_sleep;
|
||||
}
|
||||
23
mcu/chx-mkl27z.c
Normal file
23
mcu/chx-mkl27z.c
Normal file
@@ -0,0 +1,23 @@
|
||||
extern int chx_allow_sleep;
|
||||
|
||||
void
|
||||
chx_sleep_mode (int enable_sleep)
|
||||
{
|
||||
(void)enable_sleep;
|
||||
}
|
||||
|
||||
void __attribute__((naked))
|
||||
chx_idle (void)
|
||||
{
|
||||
int sleep_enabled;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
|
||||
if (sleep_enabled)
|
||||
{
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
/* NOTE: it never comes here. Don't add lines after this. */
|
||||
}
|
||||
}
|
||||
}
|
||||
41
mcu/chx-stm32f0.c
Normal file
41
mcu/chx-stm32f0.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <stdint.h>
|
||||
#include <mcu/cortex-m.h>
|
||||
#include <mcu/stm32.h>
|
||||
|
||||
extern int chx_allow_sleep;
|
||||
|
||||
void
|
||||
chx_sleep_mode (int how)
|
||||
{
|
||||
PWR->CR |= PWR_CR_CWUF;
|
||||
PWR->CR &= ~(PWR_CR_PDDS|PWR_CR_LPDS);
|
||||
|
||||
if (how == 0 || how == 1 /* Sleep only (not deepsleep) */)
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP;
|
||||
else
|
||||
{ /* Deepsleep */
|
||||
/* how == 2: deepsleep but regulator ON */
|
||||
if (how == 3)
|
||||
PWR->CR |= PWR_CR_LPDS; /* regulator low-power mode */
|
||||
else if (how == 4)
|
||||
PWR->CR |= PWR_CR_PDDS; /* Power down: All OFF */
|
||||
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP;
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((naked))
|
||||
chx_idle (void)
|
||||
{
|
||||
int sleep_enabled;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
|
||||
if (sleep_enabled)
|
||||
{
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
/* NOTE: it never comes here. Don't add lines after this. */
|
||||
}
|
||||
}
|
||||
}
|
||||
60
mcu/chx-stm32f103.c
Normal file
60
mcu/chx-stm32f103.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <stdint.h>
|
||||
#include <mcu/stm32f103.h>
|
||||
|
||||
extern int chx_allow_sleep;
|
||||
|
||||
static void
|
||||
configure_clock (uint32_t cfg_sw)
|
||||
{
|
||||
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_MASK) | cfg_sw;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != (cfg_sw << 2))
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
* When HOW=0 or HOW=1, clock is PLL (72MHz).
|
||||
* When HOW=2, clock will be HSI (8MHz) on sleep.
|
||||
*
|
||||
* With HSI clock, it can achieve lower power consumption.
|
||||
*
|
||||
* Implementation note: Deepsleep is only useful with RTC, Watch Dog,
|
||||
* or WKUP pin. We can't use deepsleep for USB, it never wakes up.
|
||||
*
|
||||
*/
|
||||
void
|
||||
chx_sleep_mode (int how)
|
||||
{
|
||||
if (how == 0 || how == 1)
|
||||
configure_clock (RCC_CFGR_SW_PLL);
|
||||
|
||||
/* how == 2: Defer setting to 8MHz clock to the idle function */
|
||||
}
|
||||
|
||||
void __attribute__((naked))
|
||||
chx_idle (void)
|
||||
{
|
||||
int sleep_enabled;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
asm ("ldr %0, %1" : "=r" (sleep_enabled): "m" (chx_allow_sleep));
|
||||
if (sleep_enabled)
|
||||
{
|
||||
asm volatile ("cpsid i" : : : "memory");
|
||||
if (sleep_enabled == 1)
|
||||
{
|
||||
/* Allow JTAG/SWD access on sleep. */
|
||||
DBGMCU->CR |= DBG_SLEEP;
|
||||
}
|
||||
else if (sleep_enabled == 2)
|
||||
{
|
||||
DBGMCU->CR &= ~DBG_SLEEP; /* Disable HCLK on sleep */
|
||||
configure_clock (RCC_CFGR_SW_HCI);
|
||||
}
|
||||
asm volatile ("cpsie i" : : : "memory");
|
||||
|
||||
asm volatile ("wfi" : : : "memory");
|
||||
/* NOTE: it never comes here. Don't add lines after this. */
|
||||
}
|
||||
}
|
||||
}
|
||||
9
mcu/stm32.h
Normal file
9
mcu/stm32.h
Normal file
@@ -0,0 +1,9 @@
|
||||
struct PWR
|
||||
{
|
||||
volatile uint32_t CR;
|
||||
volatile uint32_t CSR;
|
||||
};
|
||||
static struct PWR *const PWR = ((struct PWR *)0x40007000);
|
||||
#define PWR_CR_LPDS 0x0001 /* Low-power deepsleep */
|
||||
#define PWR_CR_PDDS 0x0002 /* Power down deepsleep */
|
||||
#define PWR_CR_CWUF 0x0004 /* Clear wakeup flag */
|
||||
Reference in New Issue
Block a user