2021-03-07 18:40:49 +08:00

112 lines
2.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
* @brief <20><><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>(power manager)
*
* Copyright (c) 2021, <morro_luo@163.com>
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-03-02 Morro Initial version.
******************************************************************************/
#include "pm.h"
#include <stddef.h>
/**
* @brief pm<70><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
typedef struct {
const pm_adapter_t *adt;
bool enable;
}pm_watch_t;
static pm_watch_t pm_watch;
static const pm_item_t pm_tbl_start SECTION("pm.item.0");
static const pm_item_t pm_tbl_end SECTION("pm.item.2");
/*
* @brief ϵͳ<CFB5><CDB3><EFBFBD>м<EFBFBD><D0BC><EFBFBD>
*/
static bool system_is_idle(void)
{
const pm_item_t *it;
for (it = &pm_tbl_start + 1; it < &pm_tbl_end; it++) {
if (it->idle != NULL && !it->idle())
return false;
}
return true;
}
/*
* @brief ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD><DFB4><EFBFBD>
*/
static void system_goto_sleep(void)
{
const pm_item_t *it;
const pm_adapter_t *adt;
unsigned int sleep_time;
unsigned int tmp;
adt = pm_watch.adt;
sleep_time = adt->max_sleep_time;
//<2F><><EFBFBD>ߴ<EFBFBD><DFB4><EFBFBD>
for (it = &pm_tbl_start + 1; it < &pm_tbl_end; it++) {
if (it->sleep_notify == NULL)
continue;
tmp = it->sleep_notify(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>ڴ<EFBFBD><DAB4>´λ<C2B4><CEBB><EFBFBD>ʱ<EFBFBD><CAB1>
if (tmp && tmp < sleep_time) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
sleep_time = tmp;
}
adt->goto_sleep(sleep_time);
//<2F><><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD>
for (it = &pm_tbl_start + 1; it < &pm_tbl_end; it++) {
if (it->wakeup_notify == NULL)
continue;
it->wakeup_notify();
}
}
/**
* @brief <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>
* @retval adt - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
*/
void pm_init(const pm_adapter_t *adt)
{
pm_watch.adt = adt;
}
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>
* @retval none
*/
void pm_enable(void)
{
pm_watch.enable = true;
}
/**
* @brief <20><><EFBFBD>ù<EFBFBD><C3B9>Ĺ<EFBFBD><C4B9><EFBFBD>
* @retval none
*/
void pm_disable(void)
{
pm_watch.enable = false;
}
/**
* @brief <20><><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>
* @retval none
*/
void pm_process(void)
{
if (!pm_watch.enable || !system_is_idle())
return;
system_goto_sleep();
}