mirror of
https://github.com/drasko/open-ameba.git
synced 2024-12-04 20:20:34 +00:00
291 lines
10 KiB
C
291 lines
10 KiB
C
|
/* mbed Microcontroller Library
|
||
|
*******************************************************************************
|
||
|
* Copyright (c) 2014, STMicroelectronics
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
*
|
||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||
|
* this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||
|
* this list of conditions and the following disclaimer in the documentation
|
||
|
* and/or other materials provided with the distribution.
|
||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||
|
* may be used to endorse or promote products derived from this software
|
||
|
* without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*******************************************************************************
|
||
|
*/
|
||
|
#include "sleep_ex_api.h"
|
||
|
#include "cmsis.h"
|
||
|
|
||
|
extern VOID SleepCG(u8 Option, u32 SDuration, u8 ClkSourceEn, u8 SDREn);
|
||
|
extern VOID DeepStandby(u8 Option, u32 SDuration, u8 GpioOption);
|
||
|
extern VOID DeepSleep(u8 Option, u32 SDuration);
|
||
|
|
||
|
SLEEP_WAKEUP_EVENT DStandbyWakeupEvent={0};
|
||
|
|
||
|
/**
|
||
|
* @brief To make the system entering the Clock Gated power saving.
|
||
|
* This function just make the system to enter the clock gated
|
||
|
* power saving mode and pending on wake up event waitting.
|
||
|
* The user application need to configure the peripheral to
|
||
|
* generate system wake up event, like GPIO interrupt
|
||
|
* , G-Timer timeout, etc. befor entering power saving mode.
|
||
|
*
|
||
|
* @param wakeup_event: A bit map of wake up event. Available event:
|
||
|
* SLEEP_WAKEUP_BY_STIMER
|
||
|
* SLEEP_WAKEUP_BY_GTIMER
|
||
|
* SLEEP_WAKEUP_BY_GPIO_INT
|
||
|
* SLEEP_WAKEUP_BY_WLAN
|
||
|
* SLEEP_WAKEUP_BY_NFC
|
||
|
* SLEEP_WAKEUP_BY_SDIO
|
||
|
* SLEEP_WAKEUP_BY_USB
|
||
|
* sleep_duration: the system sleep duration in ms, only valid
|
||
|
* for SLEEP_WAKEUP_BY_STIMER wake up event.
|
||
|
*
|
||
|
* @retval None
|
||
|
*/
|
||
|
void sleep_ex(uint32_t wakeup_event, uint32_t sleep_duration)
|
||
|
{
|
||
|
u8 wake_ev=0;
|
||
|
|
||
|
wake_ev = wakeup_event & 0xff;
|
||
|
|
||
|
if (sleep_duration == 0) {
|
||
|
wake_ev &= ~SLP_STIMER;
|
||
|
}
|
||
|
|
||
|
if (wake_ev == 0) {
|
||
|
// error: No wakeup event, skip the entering sleep mode
|
||
|
return;
|
||
|
}
|
||
|
SleepCG(wake_ev, sleep_duration, 0, 0); // same as old configuration: SCLK off & SDR no power off
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief To make the system entering the Clock Gated power saving.
|
||
|
* This function just make the system to enter the clock gated
|
||
|
* power saving mode and pending on wake up event waitting.
|
||
|
* The user application need to configure the peripheral to
|
||
|
* generate system wake up event, like GPIO interrupt
|
||
|
* , G-Timer timeout, etc. befor entering power saving mode.
|
||
|
*
|
||
|
* @param wakeup_event: A bit map of wake up event. Available event:
|
||
|
* SLEEP_WAKEUP_BY_STIMER
|
||
|
* SLEEP_WAKEUP_BY_GTIMER
|
||
|
* SLEEP_WAKEUP_BY_GPIO_INT
|
||
|
* SLEEP_WAKEUP_BY_WLAN
|
||
|
* SLEEP_WAKEUP_BY_NFC
|
||
|
* SLEEP_WAKEUP_BY_SDIO
|
||
|
* SLEEP_WAKEUP_BY_USB
|
||
|
* sleep_duration: the system sleep duration in ms, only valid
|
||
|
* for SLEEP_WAKEUP_BY_STIMER wake up event.
|
||
|
* clk_sourec_enable: the option for SCLK on(1)/off(0)
|
||
|
* sdr_enable: the option for turn off the SDR controller (1:off, 0:on)
|
||
|
*
|
||
|
* @retval None
|
||
|
*/
|
||
|
void sleep_ex_selective(uint32_t wakeup_event, uint32_t sleep_duration, uint32_t clk_sourec_enable, uint32_t sdr_enable)
|
||
|
{
|
||
|
u8 wake_ev=0;
|
||
|
u8 sdr_en=0;
|
||
|
u8 clk_source_en=0;
|
||
|
|
||
|
wake_ev = wakeup_event & 0xff;
|
||
|
sdr_en = sdr_enable & 0xff;
|
||
|
clk_source_en = clk_sourec_enable & 0xff;
|
||
|
|
||
|
if (sleep_duration == 0) {
|
||
|
wake_ev &= ~SLP_STIMER;
|
||
|
}
|
||
|
|
||
|
if (wake_ev == 0) {
|
||
|
// error: No wakeup event, skip the entering sleep mode
|
||
|
return;
|
||
|
}
|
||
|
SleepCG(wake_ev, sleep_duration, clk_source_en, sdr_en);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief To add a wake up event to wake up the system from the
|
||
|
* deep standby power saving mode.
|
||
|
*
|
||
|
* @param wakeup_event: A bit map of wake up event. Available event:
|
||
|
* STANDBY_WAKEUP_BY_STIMER
|
||
|
* STANDBY_WAKEUP_BY_NFC
|
||
|
* STANDBY_WAKEUP_BY_PA5 (GPIO)
|
||
|
* STANDBY_WAKEUP_BY_PC7 (GPIO)
|
||
|
* STANDBY_WAKEUP_BY_PD5 (GPIO)
|
||
|
* STANDBY_WAKEUP_BY_PE3 (GPIO)
|
||
|
* sleep_duration_ms: the system sleep duration in ms, only valid
|
||
|
* for STANDBY_WAKEUP_BY_STIMER wake up event.
|
||
|
* gpio_active: for a GPIO pin to wake up the system by
|
||
|
* goes high(1) or low(0)
|
||
|
*
|
||
|
* @retval None
|
||
|
*/
|
||
|
void standby_wakeup_event_add(uint32_t wakeup_event, uint32_t sleep_duration_ms, uint32_t gpio_active)
|
||
|
{
|
||
|
u32 i;
|
||
|
u8 gpio_event;
|
||
|
u8 gpio_en;
|
||
|
u8 gpio_act;
|
||
|
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_STIMER) {
|
||
|
DStandbyWakeupEvent.wakeup_event |= DSTBY_STIMER;
|
||
|
DStandbyWakeupEvent.timer_duration = sleep_duration_ms;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_DS_TIMER) {
|
||
|
DStandbyWakeupEvent.wakeup_event |= DSTBY_TIMER33;
|
||
|
// TODO: Sleep Duration ?
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_NFC) {
|
||
|
DStandbyWakeupEvent.wakeup_event |= DSTBY_NFC;
|
||
|
}
|
||
|
|
||
|
gpio_event = STANDBY_WAKEUP_BY_PA5;
|
||
|
gpio_en = BIT0;
|
||
|
gpio_act = BIT4;
|
||
|
// Loop 4 to check 4 GPIO wake up event
|
||
|
for (i=0;i<4;i++) {
|
||
|
if (wakeup_event & gpio_event) {
|
||
|
DStandbyWakeupEvent.wakeup_event |= DSTBY_GPIO;
|
||
|
DStandbyWakeupEvent.gpio_option |= gpio_en;
|
||
|
if (gpio_active) {
|
||
|
// Active High
|
||
|
DStandbyWakeupEvent.gpio_option |= gpio_act;
|
||
|
}
|
||
|
else {
|
||
|
// Active Low
|
||
|
DStandbyWakeupEvent.gpio_option &= ~gpio_act;
|
||
|
}
|
||
|
}
|
||
|
gpio_event = gpio_event << 1;
|
||
|
gpio_en = gpio_en << 1;
|
||
|
gpio_act = gpio_act << 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief To delete a wake up event for wakeing up the system from the
|
||
|
* deep standby power saving mode.
|
||
|
*
|
||
|
* @param wakeup_event: A bit map of wake up event. Available event:
|
||
|
* STANDBY_WAKEUP_BY_STIMER
|
||
|
* STANDBY_WAKEUP_BY_NFC
|
||
|
* STANDBY_WAKEUP_BY_PA5 (GPIO)
|
||
|
* STANDBY_WAKEUP_BY_PC7 (GPIO)
|
||
|
* STANDBY_WAKEUP_BY_PD5 (GPIO)
|
||
|
* STANDBY_WAKEUP_BY_PE3 (GPIO)
|
||
|
* @retval None
|
||
|
*/
|
||
|
void standby_wakeup_event_del(uint32_t wakeup_event)
|
||
|
{
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_STIMER) {
|
||
|
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_STIMER;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_DS_TIMER) {
|
||
|
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_TIMER33;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_NFC) {
|
||
|
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_NFC;
|
||
|
}
|
||
|
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_PA5) {
|
||
|
DStandbyWakeupEvent.gpio_option &= ~BIT0;
|
||
|
}
|
||
|
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_PC7) {
|
||
|
DStandbyWakeupEvent.gpio_option &= ~BIT1;
|
||
|
}
|
||
|
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_PD5) {
|
||
|
DStandbyWakeupEvent.gpio_option &= ~BIT2;
|
||
|
}
|
||
|
|
||
|
if (wakeup_event & STANDBY_WAKEUP_BY_PE3) {
|
||
|
DStandbyWakeupEvent.gpio_option &= ~BIT3;
|
||
|
}
|
||
|
|
||
|
if ((DStandbyWakeupEvent.gpio_option & 0x0f) == 0) {
|
||
|
// All GPIO wake up pin are disabled
|
||
|
DStandbyWakeupEvent.wakeup_event &= ~DSTBY_GPIO;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief To make the system entering the Deep Standby power saving.
|
||
|
* The CPU, memory and part fo peripheral power is off when
|
||
|
* entering deep standby power saving mode. The program needs
|
||
|
* to be reload from the flash at system resume.
|
||
|
*
|
||
|
* @retval None
|
||
|
*/
|
||
|
void deepstandby_ex(void)
|
||
|
{
|
||
|
if ((DStandbyWakeupEvent.wakeup_event & (DSTBY_STIMER|DSTBY_NFC|DSTBY_GPIO)) == 0) {
|
||
|
// error: no wakeup event was added, so skip the entering standby power saving
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
DeepStandby(DStandbyWakeupEvent.wakeup_event,
|
||
|
DStandbyWakeupEvent.timer_duration, DStandbyWakeupEvent.gpio_option);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief To make the system entering the Deep Sleep power saving mode.
|
||
|
* The CPU, memory and peripheral power is off when entering
|
||
|
* deep sleep power saving mode. The program needs to be reload
|
||
|
* and all peripheral needs be re-configure when system resume.
|
||
|
*
|
||
|
* @param wakeup_event: A bit map of wake up event. Available event:
|
||
|
* DSLEEP_WAKEUP_BY_TIMER
|
||
|
* DSLEEP_WAKEUP_BY_GPIO
|
||
|
* sleep_duration: the system sleep duration in ms, only valid
|
||
|
* for DSLEEP_WAKEUP_BY_TIMER wake up event.
|
||
|
*
|
||
|
* @retval None
|
||
|
*/
|
||
|
void deepsleep_ex(uint32_t wakeup_event, uint32_t sleep_duration)
|
||
|
{
|
||
|
u8 wake_ev=0;
|
||
|
|
||
|
if ((wakeup_event & DSLEEP_WAKEUP_BY_TIMER) && (sleep_duration > 0)) {
|
||
|
// wake up by timeout
|
||
|
wake_ev |= DS_TIMER33;
|
||
|
}
|
||
|
|
||
|
if (wakeup_event & DSLEEP_WAKEUP_BY_GPIO) {
|
||
|
// wake up by GPIO pin goes high
|
||
|
wake_ev |= DS_GPIO;
|
||
|
}
|
||
|
|
||
|
if (wake_ev == 0) {
|
||
|
// error: No wake up event, skip entering deep sleep mode
|
||
|
return;
|
||
|
}
|
||
|
DeepSleep (wake_ev, sleep_duration);
|
||
|
}
|