/*
 * Copyright (c) 2017, NXP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o Neither the name of copyright holder 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.
 */
#ifndef _FSL_POWER_H_
#define _FSL_POWER_H_

#include "fsl_common.h"

/** @defgroup LPC5588 CHIP: LPC5588 LOWPOWER Driver
 * @ingroup CHIP_LPC5588_DRIVERS
 * @{
 */

/*******************
 * EXPORTED MACROS  *
 ********************/

/** @brief	Low Power main structure */
typedef struct {             /*     */
    __IO uint32_t CFG          ;  /*!< Low Power Mode Configuration, and miscallenous options  */
    __IO uint32_t PDCTRL0      ;  /*!< Power Down control : controls power of various modules 
                                      in the different Low power modes, including ROM */
    __IO uint32_t SRAMRETCTRL  ;  /*!< Power Down control : controls power SRAM instances 
                                         in the different Low power modes */
    __IO uint32_t CPURETCTRL   ;  /*!< CPU0 retention control : controls CPU retention parameters in POWER DOWN modes */
    __IO uint64_t VOLTAGE      ;  /*!< Voltage control in Low Power Modes */
    __IO uint64_t WAKEUPSRC    ;  /*!< Wake up sources control for sleepcon */
    __IO uint64_t WAKEUPINT    ;  /*!< Wake up sources control for ARM */
    __IO uint32_t HWWAKE       ;  /*!< Interrupt that can postpone power down modes 
                                     in case an interrupt is pending when the processor request deepsleep */
    __IO uint32_t WAKEUPIOSRC  ;  /*!< Wake up I/O sources in DEEP POWER DOWN mode */
    __IO uint32_t TIMERCFG     ;  /*!< Wake up timers configuration */
    __IO uint32_t TIMERCOUNT   ;  /*!< Wake up Timer count*/
    __IO uint32_t POWERCYCLE   ;  /*!< Cancels entry in Low Power mode if set with 0xDEADABBA (might be used by some interrupt handlers)*/
} LPC_LOWPOWER_T;

/*   */
#define LOWPOWER_POWERCYCLE_CANCELLED               0xDEADABBA /*!<    */

/* Low Power modes  */
#define LOWPOWER_CFG_LPMODE_INDEX                   0
#define LOWPOWER_CFG_LPMODE_MASK                    (0x3UL << LOWPOWER_CFG_LPMODE_INDEX)
#define LOWPOWER_CFG_SELCLOCK_INDEX                 2
#define LOWPOWER_CFG_SELCLOCK_MASK                  (0x1UL << LOWPOWER_CFG_SELCLOCK_INDEX)
#define LOWPOWER_CFG_SELMEMSUPPLY_INDEX             3
#define LOWPOWER_CFG_SELMEMSUPPLY_MASK              (0x1UL << LOWPOWER_CFG_SELMEMSUPPLY_INDEX)
#define LOWPOWER_CFG_MEMLOWPOWERMODE_INDEX          4
#define LOWPOWER_CFG_MEMLOWPOWERMODE_MASK           (0x1UL << LOWPOWER_CFG_MEMLOWPOWERMODE_INDEX)
#define LOWPOWER_CFG_LDODEEPSLEEPREF_INDEX          5
#define LOWPOWER_CFG_LDODEEPSLEEPREF_MASK           (0x1UL << LOWPOWER_CFG_LDODEEPSLEEPREF_INDEX)

#define LOWPOWER_CFG_LPMODE_ACTIVE                  0 /*!< ACTIVE mode */
#define LOWPOWER_CFG_LPMODE_DEEPSLEEP               1 /*!< DEEP SLEEP mode */
#define LOWPOWER_CFG_LPMODE_POWERDOWN               2 /*!< POWER DOWN mode */
#define LOWPOWER_CFG_LPMODE_DEEPPOWERDOWN           3 /*!< DEEP POWER DOWN mode */
#define LOWPOWER_CFG_LPMODE_SLEEP                   4 /*!< SLEEP mode */

#define LOWPOWER_CFG_SELCLOCK_1MHZ                  0 /*!< The 1 MHz clock is used during the configuration of the PMC */
#define LOWPOWER_CFG_SELCLOCK_12MHZ                 1 /*!< The 12 MHz clock is used during the configuration
                                                        of the PMC (to speed up PMC configuration process)*/

#define LOWPOWER_CFG_SELMEMSUPPLY_LDOMEM            0 /*!< In DEEP SLEEP power mode, the Memories are supplied 
                                                        by the LDO_MEM */
#define LOWPOWER_CFG_SELMEMSUPPLY_LDODEEPSLEEP      1 /*!< In DEEP SLEEP power mode, the Memories are supplied 
                                                        by the LDO_DEEP_SLEEP (or DCDC)  */
#define LOWPOWER_CFG_MEMLOWPOWERMODE_SOURCEBIASING  0 /*!< All SRAM instances use "Source Biasing" as low power mode technic 
                          (it is recommended to set LDO_MEM as high as possible -- 1.1V typical -- during low power mode) */
#define LOWPOWER_CFG_MEMLOWPOWERMODE_VOLTAGESCALING 1 /*!< All SRAM instances use "Voltage Scaling" as low power mode technic 
                           (it is recommended to set LDO_MEM as low as possible -- down to 0.7V -- during low power mode) */

#define LOWPOWER_CFG_LDODEEPSLEEPREF_FLASHBUFFER    0 /*!< LDO DEEP SLEEP uses Flash Buffer as reference  */
#define LOWPOWER_CFG_LDODEEPSLEEPREF_BANDGAG0P8V    1 /*!< LDO DEEP SLEEP uses Band Gap 0.8V as reference */

/* CPU Retention Control*/
#define LOWPOWER_CPURETCTRL_ENA_INDEX               0
#define LOWPOWER_CPURETCTRL_ENA_MASK                (0x1UL << LOWPOWER_CPURETCTRL_ENA_INDEX)
#define LOWPOWER_CPURETCTRL_MEMBASE_INDEX           1
#define LOWPOWER_CPURETCTRL_MEMBASE_MASK            (0x1FFF << LOWPOWER_CPURETCTRL_MEMBASE_INDEX)
#define LOWPOWER_CPURETCTRL_RETDATALENGTH_INDEX     14
#define LOWPOWER_CPURETCTRL_RETDATALENGTH_MASK      (0x3FFUL << LOWPOWER_CPURETCTRL_RETDATALENGTH_INDEX)

#define LOWPOWER_CPURETCTRL_ENA_DISABLE             0 /*!< In POWER DOWN mode, CPU Retention is disabled */
#define LOWPOWER_CPURETCTRL_ENA_ENABLE              1 /*!< In POWER DOWN mode, CPU Retention is enabled  */

/**
 * @brief Analog components power modes control during low power modes
 */
typedef enum pd_bits
{
    kPDRUNCFG_PD_DCDC           =    (1UL <<  0), 
    kPDRUNCFG_PD_BIAS           =    (1UL <<  1), 
    kPDRUNCFG_PD_BODCORE        =    (1UL <<  2), 
    kPDRUNCFG_PD_BODVBAT        =    (1UL <<  3), 
    kPDRUNCFG_PD_FRO1M          =    (1UL <<  4), 
    kPDRUNCFG_PD_FRO192M        =    (1UL <<  5), 
    kPDRUNCFG_PD_FRO32K         =    (1UL <<  6), 
    kPDRUNCFG_PD_XTAL32K        =    (1UL <<  7), 
    kPDRUNCFG_PD_XTAL32M        =    (1UL <<  8), 
    kPDRUNCFG_PD_PLL0           =    (1UL <<  9), 
    kPDRUNCFG_PD_PLL1           =    (1UL << 10), 
    kPDRUNCFG_PD_USB0_PHY       =    (1UL << 11), 
    kPDRUNCFG_PD_USB1_PHY       =    (1UL << 12), 
    kPDRUNCFG_PD_COMP           =    (1UL << 13), 
    kPDRUNCFG_PD_TEMPSENS       =    (1UL << 14),
    kPDRUNCFG_PD_GPADC          =    (1UL << 15),
    kPDRUNCFG_PD_LDOMEM         =    (1UL << 16), 
    kPDRUNCFG_PD_LDODEEPSLEEP   =    (1UL << 17), 
    kPDRUNCFG_PD_LDOUSBHS       =    (1UL << 18),
    kPDRUNCFG_PD_LDOGPADC       =    (1UL << 19),
    kPDRUNCFG_PD_LDOXO32M       =    (1UL << 20),
    kPDRUNCFG_PD_LDOFLASHNV     =    (1UL << 21),
    kPDRUNCFG_PD_RNG            =    (1UL << 22),
    kPDRUNCFG_PD_PLL0_SSCG      =    (1UL << 23), 
    kPDRUNCFG_PD_ROM            =    (1UL << 24),

    /*
    This enum member has no practical meaning,it is used to avoid MISRA issue,
    user should not trying to use it.
    */
    kPDRUNCFG_ForceUnsigned = 0x80000000U,
} pd_bit_t;

   
/**
 * @brief SRAM instances retention control during low power modes
 */
/*!< Enable SRAMX_0 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX0            (1UL <<  0)  
/*!< Enable SRAMX_1 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX1            (1UL <<  1)  
/*!< Enable SRAMX_2 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX2            (1UL <<  2)  
/*!< Enable SRAMX_3 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAMX3            (1UL <<  3)  
/*!< Enable SRAM0_0 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM00            (1UL <<  4)  
/*!< Enable SRAM0_1 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM01            (1UL <<  5)  
/*!< Enable SRAM1_0 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM10            (1UL <<  6)  
/*!< Enable SRAM2_0 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM20            (1UL <<  7)  
/*!< Enable SRAM3_0 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM30            (1UL <<  8)  
/*!< Enable SRAM3_1 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM31            (1UL <<  9)  
/*!< Enable SRAM4_0 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM40            (1UL << 10) 
/*!< Enable SRAM4_1 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM41            (1UL << 11)  
/*!< Enable SRAM4_2 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM42            (1UL << 12)  
/*!< Enable SRAM4_3 retention when entering in Low power modes       */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM43            (1UL << 13)  
/*!< Enable SRAM USB HS retention when entering in Low power modes   */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM_USB_HS       (1UL << 14)  
/*!< Enable SRAM PUFF retention when entering in Low power modes     */
#define LOWPOWER_SRAMRETCTRL_RETEN_RAM_PUF          (1UL << 15)  

/**
 * @brief SRAM Low Power Modes
 */

#define LOWPOWER_SRAM_LPMODE_MASK                   (0xFUL)
/*!< SRAM functional mode                                */
#define LOWPOWER_SRAM_LPMODE_ACTIVE                 (0x6UL) 
/*!< SRAM Sleep mode (Data retention, fast wake up)      */
#define LOWPOWER_SRAM_LPMODE_SLEEP                  (0xFUL) 
/*!< SRAM Deep Sleep mode (Data retention, slow wake up) */
#define LOWPOWER_SRAM_LPMODE_DEEPSLEEP              (0x8UL) 
/*!< SRAM Shut Down mode (no data retention)             */
#define LOWPOWER_SRAM_LPMODE_SHUTDOWN               (0x9UL)
/*!< SRAM is powering up                                 */ 
#define LOWPOWER_SRAM_LPMODE_POWERUP                (0xAUL) 


/**
 * @brief LDO Voltage control in Low Power Modes
 */
#define LOWPOWER_VOLTAGE_LDO_PMU_INDEX              0
#define LOWPOWER_VOLTAGE_LDO_PMU_MASK               (0x1FULL << LOWPOWER_VOLTAGE_LDO_PMU_INDEX)
#define LOWPOWER_VOLTAGE_LDO_MEM_INDEX              5
#define LOWPOWER_VOLTAGE_LDO_MEM_MASK               (0x1FULL << LOWPOWER_VOLTAGE_LDO_MEM_INDEX)
#define LOWPOWER_VOLTAGE_LDO_DEEP_SLEEP_INDEX       10
#define LOWPOWER_VOLTAGE_LDO_DEEP_SLEEP_MASK        (0x7ULL  << LOWPOWER_VOLTAGE_LDO_DEEP_SLEEP_INDEX)
#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX        19
#define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_MASK         (0x1FULL << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX)
#define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX        24
#define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_MASK         (0x1FULL << LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX)
#define LOWPOWER_VOLTAGE_DCDC_INDEX                 29
#define LOWPOWER_VOLTAGE_DCDC_MASK                  (0x7ULL << LOWPOWER_VOLTAGE_DCDC_INDEX)

/**
 * @brief Low Power Modes Wake up sources
 */
#define WAKEUP_SYS                                  (1ULL <<  0) /*!< [SLEEP, DEEP SLEEP  ] */ /* WWDT0_IRQ and BOD_IRQ*/
#define WAKEUP_SDMA0                                (1ULL <<  1) /*!< [SLEEP,                                        ] */
#define WAKEUP_GPIO_GLOBALINT0                      (1ULL <<  2) /*!< [SLEEP, DEEP SLEEP, POWER DOWN                 ] */
#define WAKEUP_GPIO_GLOBALINT1                      (1ULL <<  3) /*!< [SLEEP, DEEP SLEEP, POWER DOWN                 ] */
#define WAKEUP_GPIO_INT0_0                          (1ULL <<  4) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_GPIO_INT0_1                          (1ULL <<  5) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_GPIO_INT0_2                          (1ULL <<  6) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_GPIO_INT0_3                          (1ULL <<  7) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_UTICK                                (1ULL <<  8) /*!< [SLEEP,                                        ] */
#define WAKEUP_MRT                                  (1ULL <<  9) /*!< [SLEEP,                                        ] */
#define WAKEUP_CTIMER0                              (1ULL << 10) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_CTIMER1                              (1ULL << 11) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_SCT                                  (1ULL << 12) /*!< [SLEEP,                                        ] */
#define WAKEUP_CTIMER3                              (1ULL << 13) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_FLEXCOMM0                            (1ULL << 14) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_FLEXCOMM1                            (1ULL << 15) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_FLEXCOMM2                            (1ULL << 16) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_FLEXCOMM3                            (1ULL << 17) /*!< [SLEEP, DEEP SLEEP, POWER DOWN                 ] */
#define WAKEUP_FLEXCOMM4                            (1ULL << 18) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_FLEXCOMM5                            (1ULL << 19) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_FLEXCOMM6                            (1ULL << 20) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_FLEXCOMM7                            (1ULL << 21) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_ADC                                  (1ULL << 22) /*!< [SLEEP,                                        ] */
// reserved                                         (1ULL << 23) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_ACMP_CAPT                            (1ULL << 24) /*!< [SLEEP, DEEP SLEEP, POWER DOWN                 ] */
// reserved                                         (1ULL << 25)
// reserved                                         (1ULL << 26)
#define WAKEUP_USB0_NEEDCLK                         (1ULL << 27) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_USB0                                 (1ULL << 28) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_RTC_LITE_ALARM_WAKEUP                (1ULL << 29) /*!< [SLEEP, DEEP SLEEP, POWER DOWN, DEEP POWER DOWN] */
#define WAKEUP_EZH_ARCH_B                           (1ULL << 30) /*!< [SLEEP,                                        ] */
#define WAKEUP_WAKEUP_MAILBOX                       (1ULL << 31) /*!< [SLEEP, DEEP SLEEP, POWER DOWN                 ] */
#define WAKEUP_GPIO_INT0_4                          (1ULL << 32) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_GPIO_INT0_5                          (1ULL << 33) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_GPIO_INT0_6                          (1ULL << 34) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_GPIO_INT0_7                          (1ULL << 35) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_CTIMER2                              (1ULL << 36) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_CTIMER4                              (1ULL << 37) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_OS_EVENT_TIMER                       (1ULL << 38) /*!< [SLEEP, DEEP SLEEP, POWER DOWN, DEEP POWER DOWN] */
// reserved                                         (1ULL << 39)
// reserved                                         (1ULL << 40)
// reserved                                         (1ULL << 41)
#define WAKEUP_SDIO                                 (1ULL << 42) /*!< [SLEEP,                                        ] */
// reserved                                         (1ULL << 43)
// reserved                                         (1ULL << 44)
// reserved                                         (1ULL << 45)
// reserved                                         (1ULL << 46)
#define WAKEUP_USB1                                 (1ULL << 47) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_USB1_NEEDCLK                         (1ULL << 48) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_SEC_HYPERVISOR_CALL                  (1ULL << 49) /*!< [SLEEP,                                        ] */
#define WAKEUP_SEC_GPIO_INT0_0                      (1ULL << 50) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_SEC_GPIO_INT0_1                      (1ULL << 51) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_PLU                                  (1ULL << 52) /*!< [SLEEP, DEEP SLEEP                             ] */
#define WAKEUP_SEC_VIO                              (1ULL << 53)
#define WAKEUP_SHA                                  (1ULL << 54) /*!< [SLEEP,                                        ] */
#define WAKEUP_CASPER                               (1ULL << 55) /*!< [SLEEP,                                        ] */
#define WAKEUP_PUFF                                 (1ULL << 56) /*!< [SLEEP,                                        ] */
#define WAKEUP_PQ                                   (1ULL << 57) /*!< [SLEEP,                                        ] */
#define WAKEUP_SDMA1                                (1ULL << 58) /*!< [SLEEP,                                        ] */
#define WAKEUP_LSPI_HS                              (1ULL << 59) /*!< [SLEEP, DEEP SLEEP                             ] */
// reserved WAKEUP_PVTVF0_AMBER                     (1ULL << 60)
// reserved WAKEUP_PVTVF0_RED                       (1ULL << 61)
// reserved WAKEUP_PVTVF1_AMBER                     (1ULL << 62)
#define WAKEUP_ALLWAKEUPIOS                         (1ULL << 63) /*!< [                             , DEEP POWER DOWN] */


/**
 * @brief Sleep Postpone
 */
/*!< Force peripheral clocking to stay on during deep-sleep mode. */
#define LOWPOWER_HWWAKE_FORCED                      (1UL <<  0)  
/*!< Wake for Flexcomms. Any Flexcomm FIFO reaching the level specified by its own TXLVL 
 *will cause peripheral clocking to wake up temporarily while the related status is asserted */
#define LOWPOWER_HWWAKE_PERIPHERALS                 (1UL <<  1)  
/*!< Wake for DMA0. DMA0 being busy will cause peripheral clocking to remain running until DMA completes. 
 * Used in conjonction with LOWPOWER_HWWAKE_PERIPHERALS */
#define LOWPOWER_HWWAKE_SDMA0                       (1UL <<  3)  
/*!< Wake for DMA1. DMA0 being busy will cause peripheral clocking to remain running until DMA completes.
 * Used in conjonction with LOWPOWER_HWWAKE_PERIPHERALS */
#define LOWPOWER_HWWAKE_SDMA1                       (1UL <<  5)  
/*!< Need to be set if FRO192M is disable - via PDCTRL0 - in Deep Sleep mode and any of LOWPOWER_HWWAKE_PERIPHERALS, 
 * LOWPOWER_HWWAKE_SDMA0 or LOWPOWER_HWWAKE_SDMA1 is set */
#define LOWPOWER_HWWAKE_ENABLE_FRO192M              (1UL << 31)  

/**
 * @brief Wake up I/O sources
 */
#define LOWPOWER_WAKEUPIOSRC_PIO0_INDEX             0  /*!< Pin P1( 1) */
#define LOWPOWER_WAKEUPIOSRC_PIO1_INDEX             2  /*!< Pin P0(28) */
#define LOWPOWER_WAKEUPIOSRC_PIO2_INDEX             4  /*!< Pin P1(18) */
#define LOWPOWER_WAKEUPIOSRC_PIO3_INDEX             6  /*!< Pin P1(30) */

#define LOWPOWER_WAKEUPIOSRC_DISABLE                0  /*!< Wake up is disable                      */
#define LOWPOWER_WAKEUPIOSRC_RISING                 1  /*!< Wake up on rising edge                  */
#define LOWPOWER_WAKEUPIOSRC_FALLING                2  /*!< Wake up on falling edge                 */
#define LOWPOWER_WAKEUPIOSRC_RISING_FALLING         3  /*!< Wake up on both rising or falling edges */

/**
 * @brief Wake up timers configuration in Low Power Modes
 */
#define LOWPOWER_TIMERCFG_CTRL_INDEX                0
#define LOWPOWER_TIMERCFG_CTRL_MASK                 (0x1UL << LOWPOWER_TIMERCFG_CTRL_INDEX)
#define LOWPOWER_TIMERCFG_TIMER_INDEX               1
#define LOWPOWER_TIMERCFG_TIMER_MASK                (0x7UL << LOWPOWER_TIMERCFG_TIMER_INDEX)
#define LOWPOWER_TIMERCFG_OSC32K_INDEX              4
#define LOWPOWER_TIMERCFG_OSC32K_MASK               (0x1UL << LOWPOWER_TIMERCFG_OSC32K_INDEX)

#define LOWPOWER_TIMERCFG_CTRL_DISABLE              0 /*!< Wake Timer Disable */
#define LOWPOWER_TIMERCFG_CTRL_ENABLE               1 /*!< Wake Timer Enable */

/**
 * @brief Primary Wake up timers configuration in Low Power Modes
 */
#define LOWPOWER_TIMERCFG_TIMER_RTC1KHZ             0 /*!< 1 KHz Real Time Counter (RTC) used as wake up source */
#define LOWPOWER_TIMERCFG_TIMER_RTC1HZ              1 /*!< 1 Hz Real Time Counter (RTC) used as wake up source  */
#define LOWPOWER_TIMERCFG_TIMER_OSTIMER             2 /*!< OS Event Timer used as wake up source                */

#define LOWPOWER_TIMERCFG_OSC32K_FRO32KHZ           0 /*!< Wake up Timers uses FRO 32 KHz as clock source      */
#define LOWPOWER_TIMERCFG_OSC32K_XTAL32KHZ          1 /*!< Wake up Timers uses Chrystal 32 KHz as clock source */

/* Power mode configuration API parameter */
typedef enum _power_mode_config
{
    kPmu_Sleep = 0U,
    kPmu_Deep_Sleep = 1U,
    kPmu_Deep_PowerDown = 2U,
} power_mode_cfg_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif

/*!
 * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
 *
 * @param en    peripheral for which to enable the PDRUNCFG bit
 * @return none
 */
static inline void POWER_EnablePD(pd_bit_t en)
{
    /* PDRUNCFGSET */
    PMC->PDRUNCFGSET0 = en;
}

/*!
 * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
 *
 * @param en    peripheral for which to disable the PDRUNCFG bit
 * @return none
 */
static inline void POWER_DisablePD(pd_bit_t en)
{
    /* PDRUNCFGCLR */
    PMC->PDRUNCFGCLR0 = en;
}

/*!
 * @brief API to enable deep sleep bit in the ARM Core.
 *
 * @param none
 * @return none
 */
static inline void POWER_EnableDeepSleep(void)
{
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
}

/*!
 * @brief API to disable deep sleep bit in the ARM Core.
 *
 * @param none
 * @return none
 */
static inline void POWER_DisableDeepSleep(void)
{
    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
}

/*!
 * @brief API to power down flash controller.
 *
 * @param none
 * @return none
 */
static inline void POWER_PowerDownFlash(void)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* TURN OFF clock ip_2113 (only needed for FLASH programming, will be turned on by ROM API) */
    CLOCK_DisableClock(kCLOCK_Flash);

    /* TURN OFF clock ip_2113 (only needed for FLASH programming, will be turned on by ROM API) */
    CLOCK_DisableClock(kCLOCK_Fmc);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/*!
 * @brief API to power up flash controller.
 *
 * @param none
 * @return none
 */
static inline void POWER_PowerUpFlash(void)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* TURN OFF clock ip_2113 (only needed for FLASH programming, will be turned on by ROM API) */
    CLOCK_EnableClock(kCLOCK_Fmc);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/**
 * @brief    PMC Sleep function call
 * @return   nothing
 */
void POWER_EnterSleep(void);
/**
 * @brief    PMC Deep Sleep function call
 * @return   nothing
 */
void POWER_EnterDeepSleep(uint64_t exclude_from_pd);

/**
 * @brief    PMC power Down function call
 * @return   nothing
 */
void POWER_EnterPowerDown(uint64_t exclude_from_pd);

/**
 * @brief    PMC Deep Sleep Power Down function call
 * @return   nothing
 */
void POWER_EnterDeepPowerDown(uint64_t exclude_from_pd);

/*!
 * @brief Power Library API to enter different power mode.
 *
 * @param exclude_from_pd  Bit mask of the PDRUNCFG0(low 32bits) and PDRUNCFG1(high 32bits) that needs to be powered on
 * during power mode selected.
 * @return none
 */
void POWER_EnterPowerMode(power_mode_cfg_t mode, uint64_t exclude_from_pd);

/*!
 * @brief Power Library API to return the library version.
 *
 * @param none
 * @return version number of the power library
 */
uint32_t POWER_GetLibVersion(void);
/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* _FSL_POWER_H_ */
