Newer
Older
mbed-os / targets / TARGET_RENESAS / TARGET_RZ_A2XX / sleep.c
@RyoheiHagimoto RyoheiHagimoto on 17 Aug 2020 6 KB Added GR-MANGO to be a target.
/* mbed Microcontroller Library
 * Copyright (c) 2018-2020 ARM Limited
 * 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"
#include "cmsis.h"
#include "mbed_interface.h"
#include "mbed_critical.h"
#include "iodefine.h"

#if DEVICE_SLEEP
static volatile uint8_t wk_CPGSTBCR3;
static volatile uint8_t wk_CPGSTBCR4;
static volatile uint8_t wk_CPGSTBCR5;
static volatile uint8_t wk_CPGSTBCR6;
static volatile uint8_t wk_CPGSTBCR7;
static volatile uint8_t wk_CPGSTBCR8;
static volatile uint8_t wk_CPGSTBCR9;
static volatile uint8_t wk_CPGSTBCR10;

typedef struct {
    volatile uint8_t * p_wk_stbcr;
    volatile uint8_t * p_stbcr;
    volatile uint8_t * p_stbreq;
    volatile uint8_t * p_stback;
    uint8_t mstp;
    uint8_t stbrq;
} module_stanby_t;

static const module_stanby_t module_stanby[] = {
    {&wk_CPGSTBCR5,  &CPG.STBCR5.BYTE,  &CPG.STBREQ1.BYTE, &CPG.STBACK1.BYTE, 0x40,  0x01}, /* CEU */
    {&wk_CPGSTBCR5,  &CPG.STBCR5.BYTE,  &CPG.STBREQ1.BYTE, &CPG.STBACK1.BYTE, 0x02,  0x08}, /* JCU */
    {&wk_CPGSTBCR6,  &CPG.STBCR6.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x40,  0x80}, /* VIN */
    {&wk_CPGSTBCR6,  &CPG.STBCR6.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x20,  0x40}, /* ethernet0 */
    {&wk_CPGSTBCR6,  &CPG.STBCR6.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x10,  0x40}, /* ethernet1 */
    {&wk_CPGSTBCR6,  &CPG.STBCR6.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x08,  0x40}, /* ethernet PTP */
    {&wk_CPGSTBCR6,  &CPG.STBCR6.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x04,  0x40}, /* ethernet M */
    {&wk_CPGSTBCR6,  &CPG.STBCR6.BYTE,  &CPG.STBREQ3.BYTE, &CPG.STBACK3.BYTE, 0x02,  0x03}, /* USB host 0 */
    {&wk_CPGSTBCR6,  &CPG.STBCR6.BYTE,  &CPG.STBREQ3.BYTE, &CPG.STBACK3.BYTE, 0x01,  0x0C}, /* USB host 1 */
    {&wk_CPGSTBCR7,  &CPG.STBCR7.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x80,  0x08}, /* IMR */
    {&wk_CPGSTBCR7,  &CPG.STBCR7.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x40,  0x03}, /* DAVE-2D */
    {&wk_CPGSTBCR8,  &CPG.STBCR8.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x02,  0x20}, /* VDC-6 */
    {&wk_CPGSTBCR9,  &CPG.STBCR9.BYTE,  &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x01,  0x10}, /* DRP */
    {&wk_CPGSTBCR10, &CPG.STBCR10.BYTE, &CPG.STBREQ2.BYTE, &CPG.STBACK2.BYTE, 0x10,  0x04}, /* NAND */
    {&wk_CPGSTBCR10, &CPG.STBCR10.BYTE, &CPG.STBREQ3.BYTE, &CPG.STBACK3.BYTE, 0x08,  0x04}, /* SD host 0 */
    {&wk_CPGSTBCR10, &CPG.STBCR10.BYTE, &CPG.STBREQ3.BYTE, &CPG.STBACK3.BYTE, 0x02,  0x02}, /* SD host 1 */
    {0, 0, 0, 0, 0}  /* None */
};

static void module_standby_in(void) {
    volatile uint32_t cnt;
    volatile uint8_t dummy_8;
    const module_stanby_t * p_module = &module_stanby[0];

    while (p_module->p_wk_stbcr != 0) {
        if ((*p_module->p_wk_stbcr & p_module->mstp) == 0) {
            *p_module->p_stbreq |= p_module->stbrq;
            dummy_8             = *p_module->p_stbreq;
            for (cnt = 0; cnt < 1000; cnt++) {      // wait time
                if ((*p_module->p_stback & p_module->stbrq) == p_module->stbrq) {
                    break;
                }
            }
            *p_module->p_stbcr |= p_module->mstp;
            dummy_8            = *p_module->p_stbcr;
        }
        p_module++;
    }
    (void)dummy_8;
}

static void module_standby_out(void) {
    volatile uint32_t cnt;
    volatile uint8_t dummy_8;
    const module_stanby_t * p_module = &module_stanby[0];

    while (p_module->p_wk_stbcr != 0) {
        if ((*p_module->p_wk_stbcr & p_module->mstp) == 0) {
            *p_module->p_stbreq &= ~(p_module->stbrq);
            dummy_8             = *p_module->p_stbreq;
            for (cnt = 0; cnt < 1000; cnt++) {
                if ((*p_module->p_stback & p_module->stbrq) == 0) {
                    break;
                }
            }
        }
        p_module++;
    }
    (void)dummy_8;
}

void hal_sleep(void) {
    // Transition to Sleep Mode
    __WFI();
}

void hal_deepsleep(void) {
    volatile uint8_t dummy_8;

    core_util_critical_section_enter();
    /* For powerdown the peripheral module, save current standby control register values(just in case) */
    wk_CPGSTBCR3  = CPG.STBCR3.BYTE;
    wk_CPGSTBCR4  = CPG.STBCR4.BYTE;
    wk_CPGSTBCR5  = CPG.STBCR5.BYTE;
    wk_CPGSTBCR6  = CPG.STBCR6.BYTE;
    wk_CPGSTBCR7  = CPG.STBCR7.BYTE;
    wk_CPGSTBCR8  = CPG.STBCR8.BYTE;
    wk_CPGSTBCR9  = CPG.STBCR9.BYTE;
    wk_CPGSTBCR10 = CPG.STBCR10.BYTE;

    /* non */
    CPG.STBCR3.BYTE  = 0xFF;
    dummy_8 = CPG.STBCR3.BYTE;
    /* non */
    CPG.STBCR4.BYTE  = 0xFF;
    dummy_8 = CPG.STBCR4.BYTE;
    /* Realtime Clock, CEU, JCU */
    CPG.STBCR5.BYTE  |= ~(0x4A);
    dummy_8 = CPG.STBCR5.BYTE;
    /* VIN, ethernet0, ethernet1, ethernet PTP, ethernet M, USB host 0, USB host 1 */
    CPG.STBCR6.BYTE  |= ~(0x7F);
    dummy_8 = CPG.STBCR6.BYTE;
    /* IMR, DAVE-2D */
    CPG.STBCR7.BYTE  |= ~(0xC0);
    dummy_8 = CPG.STBCR7.BYTE;
    /* VDC-6 */
    CPG.STBCR8.BYTE  |= ~(0x02);
    dummy_8 = CPG.STBCR8.BYTE;
    /* DRP */
    CPG.STBCR9.BYTE  |= ~(0x01);
    dummy_8 = CPG.STBCR9.BYTE;
    /* NAND, SD host 0, SD host 1 */
    CPG.STBCR10.BYTE |= ~(0x1A);
    dummy_8 = CPG.STBCR10.BYTE;

    module_standby_in();

    // Transition to Sleep Mode
    __WFI();

    /* Revert standby control register values */
    CPG.STBCR3.BYTE  = wk_CPGSTBCR3;
    dummy_8 = CPG.STBCR3.BYTE;
    CPG.STBCR4.BYTE  = wk_CPGSTBCR4;
    dummy_8 = CPG.STBCR4.BYTE;
    CPG.STBCR5.BYTE  = wk_CPGSTBCR5;
    dummy_8 = CPG.STBCR5.BYTE;
    CPG.STBCR6.BYTE  = wk_CPGSTBCR6;
    dummy_8 = CPG.STBCR6.BYTE;
    CPG.STBCR7.BYTE  = wk_CPGSTBCR7;
    dummy_8 = CPG.STBCR7.BYTE;
    CPG.STBCR8.BYTE  = wk_CPGSTBCR8;
    dummy_8 = CPG.STBCR8.BYTE;
    CPG.STBCR9.BYTE  = wk_CPGSTBCR9;
    dummy_8 = CPG.STBCR9.BYTE;
    CPG.STBCR10.BYTE = wk_CPGSTBCR10;
    dummy_8 = CPG.STBCR10.BYTE;

    module_standby_out();
    core_util_critical_section_exit();

    (void)dummy_8;
}
#endif