mbed-os/targets/TARGET_TOSHIBA/TARGET_TMPM4KN/sleep.c

129 lines
3.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* mbed Microcontroller Library
* Copyright(C) Toshiba Electronic Device Solutions Corporation 2021
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sleep_api.h"
// Number of warm-up cycle in EHOSC = (warming up time (s) / clock period (s)) - 16
#define CG_WUODR_EXT_5MS ((uint16_t)0xC340)
// Number of warm-up cycle in IHOSC = ((warming up time (s) 63.3(μs) / clock period (s)) - 41
#define CG_WUODR_INT_67_4us ((uint16_t)0x0000)
#define CG_STBY_MODE_IDLE 0x0
#define CG_STBY_MODE_STOP1 0x1
#define EXTERNEL_OSC_MASK 0xFFFFFFF1
#define SIWDT_DISABLE 0xB1
#define WUPT_LOWER_MASK 0x000F
#define WUPT_UPPER_MASK 0xFFF0
static void external_hosc_enable(void);
void hal_sleep(void)
{
// Set low power consumption mode IDLE
TSB_CG->STBYCR = CG_STBY_MODE_IDLE;
// Enter idle mode
__DSB();
__WFI();
}
void hal_deepsleep(void)
{
uint32_t wupt_lower = 0;
uint32_t wupt_upper = 0;
uint32_t tmp = 0;
TSB_CG_FSYSMENB_IPMENB31 = TXZ_ENABLE;
TSB_SIWD0->EN = TXZ_DISABLE;
TSB_SIWD0->CR = SIWDT_DISABLE;
while ((TSB_FC->SR0 & TXZ_DONE) != TXZ_DONE) {
// Flash wait
}
while (TSB_CG_WUPHCR_WUEF) {
// Wait for end of Warming-up for IHOSC1
}
TSB_CG_WUPHCR_WUCLK = TXZ_DISABLE;
wupt_lower = ((CG_WUODR_INT_67_4us & WUPT_LOWER_MASK) << 16U);
wupt_upper = ((CG_WUODR_INT_67_4us & WUPT_UPPER_MASK) << 16U);
TSB_CG->WUPHCR |= (wupt_lower | wupt_upper);
TSB_CG->STBYCR = CG_STBY_MODE_STOP1;
TSB_CG_PLL0SEL_PLL0SEL = TXZ_DISABLE;
while (TSB_CG_PLL0SEL_PLL0ST) {
// Wait for PLL status of fsys until off state(fosc=0)
}
// Stop PLL of fsys
TSB_CG_PLL0SEL_PLL0ON = TXZ_DISABLE;
TSB_CG_OSCCR_IHOSC1EN = TXZ_ENABLE;
TSB_CG_OSCCR_OSCSEL = TXZ_DISABLE;
while (TSB_CG_OSCCR_OSCF) {
// Wait for fosc status until IHOSC1 = 0
}
tmp = TSB_CG->OSCCR;
tmp &= EXTERNEL_OSC_MASK;
TSB_CG->OSCCR = tmp;
// Enter stop1 mode
__DSB();
__WFI();
// Switch over from IHOSC to EHOSC
// After coming out off sleep mode, Restore the clock setting to EHOSC.
external_hosc_enable();
}
static void external_hosc_enable(void)
{
uint32_t wupt_lower = 0;
uint32_t wupt_upper = 0;
// Enable high-speed oscillator
TSB_CG->OSCCR |= (TXZ_ENABLE << 1);
// Select internal(fIHOSC) as warm-up clock
wupt_lower = ((CG_WUODR_EXT_5MS & WUPT_LOWER_MASK) << 16U);
wupt_upper = ((CG_WUODR_EXT_5MS & WUPT_UPPER_MASK) << 16U);
TSB_CG->WUPHCR |= (wupt_lower | wupt_upper);
// Start warm-up
TSB_CG->WUPHCR |= TXZ_ENABLE;
// Wait until EHOSC become stable
while ((TSB_CG->WUPHCR & 0x0002)) {
// Do nothing
}
// Set fosc source
TSB_CG->OSCCR |= (1 << 8);
// Wait for <OSCSEL> to become "1"
while (!((TSB_CG->OSCCR & 0x200) >> 9)) {
// Do nothing
}
// Stop IHOSC
TSB_CG->OSCCR &= ~TXZ_ENABLE;
}