text: /**
    ******************************************************************************
    * @file    bl702_pds.c
    * @version V1.0
    * @date
    * @brief   This file is the standard driver c file
    ******************************************************************************
    * @attention
    *
    * <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
    *
    * 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 Bouffalo Lab 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 "bl702.h"
  #include "bl702_pds.h"
  
  /** @addtogroup  BL702_Peripheral_Driver
   *  @{
   */
  
  /** @addtogroup  PDS
   *  @{
   */
  
  /** @defgroup  PDS_Private_Macros
   *  @{
   */
  
  /*@} end of group PDS_Private_Macros */
  
  /** @defgroup  PDS_Private_Types
   *  @{
   */
  
  /*@} end of group PDS_Private_Types */
  
  /** @defgroup  PDS_Private_Variables
   *  @{
   */
  static intCallback_Type *pdsIntCbfArra[PDS_INT_MAX][1] = { { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL }, { NULL } };
  
  /*@} end of group PDS_Private_Variables */
  
  /** @defgroup  PDS_Global_Variables
   *  @{
   */
  
  /*@} end of group PDS_Global_Variables */
  
  /** @defgroup  PDS_Private_Fun_Declaration
   *  @{
   */
  
  /*@} end of group PDS_Private_Fun_Declaration */
  
  /** @defgroup  PDS_Private_Functions
   *  @{
   */
  
  /*@} end of group PDS_Private_Functions */
  
  /** @defgroup  PDS_Public_Functions
   *  @{
   */
  
  /****************************************************************************/ /**
   * @brief  power down sleep ram configure
   *
   * @param  ramCfg: power down sleep force ram configuration
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type ATTR_TCM_SECTION PDS_RAM_Config(PDS_RAM_CFG_Type *ramCfg)
  {
      if (NULL == ramCfg) {
          return ERROR;
      }
  
      /* PDS_RAM1 config */
      BL_WR_REG(PDS_BASE, PDS_RAM1, *(uint32_t *)ramCfg);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  power down sleep set pad configure
   *
   * @param  pin: power down sleep pad num
   * @param  cfg: power down sleep pad type
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type ATTR_TCM_SECTION PDS_Set_Pad_Config(PDS_PAD_PIN_Type pin, PDS_PAD_CFG_Type cfg)
  {
      uint32_t tmpVal = 0;
      uint32_t tmpPu = 0;
      uint32_t tmpPd = 0;
  
      if (pin < PDS_PAD_PIN_GPIO_23) {
          /* GPIO17 - GPIO22 */
          tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_SET_PU_PD);
  
          switch (cfg) {
              case PDS_PAD_CFG_PULL_NONE:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PD) & ~(1 << pin);
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PU) & ~(1 << pin);
                  break;
  
              case PDS_PAD_CFG_PULL_DOWN:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PD) | (1 << pin);
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PU) & ~(1 << pin);
                  break;
  
              case PDS_PAD_CFG_PULL_UP:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PD) & ~(1 << pin);
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PU) | (1 << pin);
                  break;
  
              case PDS_PAD_CFG_ACTIVE_IE:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PD) | (1 << pin);
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PU) | (1 << pin);
                  break;
  
              default:
                  break;
          }
  
          tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PD, tmpPd);
          tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_22_17_PU, tmpPu);
          BL_WR_REG(PDS_BASE, PDS_GPIO_SET_PU_PD, tmpVal);
      } else {
          /* GPIO23 - GPIO28 */
          tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_SET_PU_PD);
  
          switch (cfg) {
              case PDS_PAD_CFG_PULL_NONE:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PD) & ~(1 << (pin - PDS_PAD_PIN_GPIO_23));
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PU) & ~(1 << (pin - PDS_PAD_PIN_GPIO_23));
                  break;
  
              case PDS_PAD_CFG_PULL_DOWN:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PD) | (1 << (pin - PDS_PAD_PIN_GPIO_23));
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PU) & ~(1 << (pin - PDS_PAD_PIN_GPIO_23));
                  break;
  
              case PDS_PAD_CFG_PULL_UP:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PD) & ~(1 << (pin - PDS_PAD_PIN_GPIO_23));
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PU) | (1 << (pin - PDS_PAD_PIN_GPIO_23));
                  break;
  
              case PDS_PAD_CFG_ACTIVE_IE:
                  tmpPd = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PD) | (1 << (pin - PDS_PAD_PIN_GPIO_23));
                  tmpPu = BL_GET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PU) | (1 << (pin - PDS_PAD_PIN_GPIO_23));
                  break;
  
              default:
                  break;
          }
  
          tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PD, tmpPd);
          tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CR_PDS_GPIO_28_23_PU, tmpPu);
          BL_WR_REG(PDS_BASE, PDS_GPIO_SET_PU_PD, tmpVal);
      }
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  Enable power down sleep
   *
   * @param  cfg: power down sleep configuration 1
   * @param  cfg4: power down sleep configuration 2
   * @param  pdsSleepCnt: power down sleep count cycle
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type ATTR_TCM_SECTION PDS_App_Enable(PDS_CTL_Type *cfg, PDS_CTL4_Type *cfg4, uint32_t pdsSleepCnt)
  {
      /* PDS sleep time 0 <=> sleep forever */
      /* PDS sleep time 1~PDS_WARMUP_LATENCY_CNT <=> error */
      /* PDS sleep time >PDS_WARMUP_LATENCY_CNT <=> correct */
      if (!pdsSleepCnt) {
          cfg->sleepForever = 0;
      } else if ((pdsSleepCnt) && (pdsSleepCnt <= PDS_WARMUP_LATENCY_CNT)) {
          return ERROR;
      } else {
          BL_WR_REG(PDS_BASE, PDS_TIME1, pdsSleepCnt - PDS_WARMUP_LATENCY_CNT);
      }
  
      /* PDS_CTL4 config */
      BL_WR_REG(PDS_BASE, PDS_CTL4, *(uint32_t *)cfg4);
  
      /* PDS_CTL config */
      if (cfg->pdsStart) {
          BL_WR_REG(PDS_BASE, PDS_CTL, (*(uint32_t *)cfg & ~(1 << 0)));
          BL_WR_REG(PDS_BASE, PDS_CTL, (*(uint32_t *)cfg | (1 << 0)));
      } else {
          BL_WR_REG(PDS_BASE, PDS_CTL, *(uint32_t *)cfg);
      }
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  power down sleep force configure
   *
   * @param  cfg2: power down sleep force configuration 1
   * @param  cfg3: power down sleep force configuration 2
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type ATTR_TCM_SECTION PDS_Force_Config(PDS_CTL2_Type *cfg2, PDS_CTL3_Type *cfg3)
  {
      /* PDS_CTL2 config */
      BL_WR_REG(PDS_BASE, PDS_CTL2, *(uint32_t *)cfg2);
  
      /* PDS_CTL3 config */
      BL_WR_REG(PDS_BASE, PDS_CTL3, *(uint32_t *)cfg3);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  power down sleep force configure
   *
   * @param  defaultLvCfg: power down sleep default level configuration
   * @param  pdsSleepCnt: power down sleep time count
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type ATTR_TCM_SECTION PDS_Default_Level_Config(PDS_DEFAULT_LV_CFG_Type *defaultLvCfg, uint32_t pdsSleepCnt)
  {
      PDS_Force_Config((PDS_CTL2_Type *)&(defaultLvCfg->pdsCtl2), (PDS_CTL3_Type *)&(defaultLvCfg->pdsCtl3));
      PDS_App_Enable((PDS_CTL_Type *)&(defaultLvCfg->pdsCtl), (PDS_CTL4_Type *)&(defaultLvCfg->pdsCtl4), pdsSleepCnt);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  power down sleep int enable
   *
   * @param  intType: PDS int type
   * @param  enable: ENABLE or DISABLE
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_IntEn(PDS_INT_Type intType, BL_Fun_Type enable)
  {
      uint32_t offset = 0;
      uint32_t tmpVal = 0;
  
      if ((intType < PDS_INT_PDS_SLEEP_CNT) || (intType > PDS_INT_KYS_QDEC)) {
          return ERROR;
      }
  
      switch (intType) {
          case PDS_INT_WAKEUP:
          case PDS_INT_RF_DONE:
          case PDS_INT_PLL_DONE:
              return ERROR;
  
          case PDS_INT_PDS_SLEEP_CNT:
              offset = 16;
              break;
  
          case PDS_INT_HBN_IRQ_OUT0:
              offset = 17;
              break;
  
          case PDS_INT_HBN_IRQ_OUT1:
              offset = 18;
              break;
  
          case PDS_INT_GPIO_IRQ:
              offset = 19;
              break;
  
          case PDS_INT_IRRX:
              offset = 20;
              break;
  
          case PDS_INT_BLE_SLP_IRQ:
              offset = 21;
              break;
  
          case PDS_INT_USB_WKUP:
              offset = 22;
              break;
  
          case PDS_INT_KYS_QDEC:
              offset = 23;
              break;
  
          case PDS_INT_MAX:
              break;
  
          default:
              break;
      }
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
  
      if (enable) {
          tmpVal = tmpVal | (1 << offset);
      } else {
          tmpVal = tmpVal & ~(1 << offset);
      }
  
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  power down sleep int mask
   *
   * @param  intType: PDS int type
   * @param  intMask: MASK or UNMASK
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_IntMask(PDS_INT_Type intType, BL_Mask_Type intMask)
  {
      uint32_t offset = 0;
      uint32_t tmpVal = 0;
  
      if (intType > PDS_INT_PLL_DONE) {
          return ERROR;
      }
  
      switch (intType) {
          case PDS_INT_WAKEUP:
              offset = 8;
              break;
  
          case PDS_INT_RF_DONE:
              offset = 10;
              break;
  
          case PDS_INT_PLL_DONE:
              offset = 11;
              break;
  
          case PDS_INT_PDS_SLEEP_CNT:
          case PDS_INT_HBN_IRQ_OUT0:
          case PDS_INT_HBN_IRQ_OUT1:
          case PDS_INT_GPIO_IRQ:
          case PDS_INT_IRRX:
          case PDS_INT_BLE_SLP_IRQ:
          case PDS_INT_USB_WKUP:
          case PDS_INT_KYS_QDEC:
          case PDS_INT_MAX:
          default:
              return ERROR;
      }
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
  
      if (intMask != UNMASK) {
          tmpVal = tmpVal | (1 << offset);
      } else {
          tmpVal = tmpVal & ~(1 << offset);
      }
  
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  get power down sleep int status
   *
   * @param  intType: PDS int type
   *
   * @return SET or RESET
   *
  *******************************************************************************/
  BL_Sts_Type PDS_Get_IntStatus(PDS_INT_Type intType)
  {
      uint32_t offset = 0;
  
      switch (intType) {
          case PDS_INT_WAKEUP:
              offset = 0;
              break;
  
          case PDS_INT_RF_DONE:
              offset = 2;
              break;
  
          case PDS_INT_PLL_DONE:
              offset = 3;
              break;
  
          case PDS_INT_PDS_SLEEP_CNT:
              offset = 24;
              break;
  
          case PDS_INT_HBN_IRQ_OUT0:
              offset = 25;
              break;
  
          case PDS_INT_HBN_IRQ_OUT1:
              offset = 26;
              break;
  
          case PDS_INT_GPIO_IRQ:
              offset = 27;
              break;
  
          case PDS_INT_IRRX:
              offset = 28;
              break;
  
          case PDS_INT_BLE_SLP_IRQ:
              offset = 29;
              break;
  
          case PDS_INT_USB_WKUP:
              offset = 30;
              break;
  
          case PDS_INT_KYS_QDEC:
              offset = 31;
              break;
  
          case PDS_INT_MAX:
              break;
  
          default:
              break;
      }
  
      return (BL_RD_REG(PDS_BASE, PDS_INT) & (1 << offset)) ? SET : RESET;
  }
  
  /****************************************************************************/ /**
   * @brief  clear power down sleep int status
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_IntClear(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR);
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR);
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR);
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  get power down sleep PLL status
   *
   * @param  None
   *
   * @return PDS PLL status
   *
  *******************************************************************************/
  PDS_PLL_STS_Type PDS_Get_PdsPllStstus(void)
  {
      return (PDS_PLL_STS_Type)BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_STAT), PDS_RO_PDS_PLL_STATE);
  }
  
  /****************************************************************************/ /**
   * @brief  get power down sleep RF status
   *
   * @param  None
   *
   * @return PDS RF status
   *
  *******************************************************************************/
  PDS_RF_STS_Type PDS_Get_PdsRfStstus(void)
  {
      return (PDS_RF_STS_Type)BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_STAT), PDS_RO_PDS_RF_STATE);
  }
  
  /****************************************************************************/ /**
   * @brief  get power down sleep status
   *
   * @param  None
   *
   * @return PDS status
   *
  *******************************************************************************/
  PDS_STS_Type PDS_Get_PdsStstus(void)
  {
      return (PDS_STS_Type)BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_STAT), PDS_RO_PDS_STATE);
  }
  
  /****************************************************************************/ /**
   * @brief  power down sleep clear reset event
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_Clear_Reset_Event(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLR_RESET_EVENT);
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLR_RESET_EVENT);
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLR_RESET_EVENT);
      BL_WR_REG(PDS_BASE, PDS_INT, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  get power down sleep reset event
   *
   * @param  event: power down sleep reset event
   *
   * @return SET or RESET
   *
  *******************************************************************************/
  BL_Sts_Type PDS_Get_Reset_Event(PDS_RST_EVENT_Type event)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_INT);
      tmpVal = BL_GET_REG_BITS_VAL(tmpVal, PDS_RESET_EVENT);
  
      return (tmpVal & (1 << event)) ? SET : RESET;
  }
  
  /****************************************************************************/ /**
   * @brief  set power down sleep VDDCORE gpio interrupt config
   *
   * @param  src: PDS VDDCORE src pin num
   * @param  mode: PDS VDDCORE src pin interrupt type
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_Set_Vddcore_GPIO_IntCfg(PDS_VDDCORE_GPIO_SRC_Type src, PDS_AON_GPIO_INT_Trigger_Type mode)
  {
      uint32_t tmpVal = 0;
  
      CHECK_PARAM(IS_PDS_VDDCORE_GPIO_SRC_TYPE(src));
      CHECK_PARAM(IS_PDS_AON_GPIO_INT_Trigger_TYPE(mode));
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_INT);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_GPIO_INT_SELECT, src);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_GPIO_INT_MODE, mode);
      BL_WR_REG(PDS_BASE, PDS_GPIO_INT, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  set power down sleep VDDCORE gpio interrupt mask
   *
   * @param  intMask: None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_Set_Vddcore_GPIO_IntMask(BL_Mask_Type intMask)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_INT);
  
      if (intMask != UNMASK) {
          tmpVal = BL_SET_REG_BIT(tmpVal, PDS_GPIO_INT_MASK);
      } else {
          tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_GPIO_INT_MASK);
      }
  
      BL_WR_REG(PDS_BASE, PDS_GPIO_INT, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  set power down sleep VDDCORE gpio interrupt mask
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  PDS_STS_Type PDS_Get_Vddcore_GPIO_IntStatus(void)
  {
      return BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_GPIO_INT), PDS_GPIO_INT_STAT) ? SET : RESET;
  }
  
  /****************************************************************************/ /**
   * @brief  set power down sleep VDDCORE gpio interrupt mask
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_Set_Vddcore_GPIO_IntClear(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_INT);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_GPIO_INT_CLR);
      BL_WR_REG(PDS_BASE, PDS_GPIO_INT, tmpVal);
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_INT);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_GPIO_INT_CLR);
      BL_WR_REG(PDS_BASE, PDS_GPIO_INT, tmpVal);
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_GPIO_INT);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_GPIO_INT_CLR);
      BL_WR_REG(PDS_BASE, PDS_GPIO_INT, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  Install PDS interrupt callback function
   *
   * @param  intType: PDS int type
   * @param  cbFun: cbFun: Pointer to interrupt callback function. The type should be void (*fn)(void)
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_Int_Callback_Install(PDS_INT_Type intType, intCallback_Type *cbFun)
  {
      pdsIntCbfArra[intType][0] = cbFun;
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  Trim RC32M
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Trim_RC32M(void)
  {
      Efuse_Ana_RC32M_Trim_Type trim;
      int32_t tmpVal = 0;
  
      EF_Ctrl_Read_RC32M_Trim(&trim);
  
      if (trim.trimRc32mExtCodeEn) {
          if (trim.trimRc32mCodeFrExtParity == EF_Ctrl_Get_Trim_Parity(trim.trimRc32mCodeFrExt, 8)) {
              tmpVal = BL_RD_REG(PDS_BASE, PDS_RC32M_CTRL0);
              tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_RC32M_CODE_FR_EXT, trim.trimRc32mCodeFrExt);
              tmpVal = BL_SET_REG_BIT(tmpVal, PDS_RC32M_EXT_CODE_EN);
              BL_WR_REG(PDS_BASE, PDS_RC32M_CTRL0, tmpVal);
              BL702_Delay_US(2);
              return SUCCESS;
          }
      }
  
      return ERROR;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Select RC32M as PLL ref source
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Select_RC32M_As_PLL_Ref(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_XTAL_RC32M_SEL);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal);
  
      return SUCCESS;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Select XTAL as PLL ref source
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Select_XTAL_As_PLL_Ref(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_XTAL_RC32M_SEL);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal);
  
      return SUCCESS;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Power on PLL
   *
   * @param  xtalType: xtal type
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Power_On_PLL(PDS_PLL_XTAL_Type xtalType)
  {
      uint32_t tmpVal = 0;
  
      /* Check parameter*/
      CHECK_PARAM(IS_PDS_PLL_XTAL_TYPE(xtalType));
  
      /**************************/
      /* select PLL XTAL source */
      /**************************/
  
      if ((xtalType == PDS_PLL_XTAL_RC32M) || (xtalType == PDS_PLL_XTAL_NONE)) {
          PDS_Trim_RC32M();
          PDS_Select_RC32M_As_PLL_Ref();
      } else {
          PDS_Select_XTAL_As_PLL_Ref();
      }
  
      /*******************************************/
      /* PLL power down first, not indispensable */
      /*******************************************/
      /* power off PLL first, this step is not indispensable */
      PDS_Power_Off_PLL();
  
      /********************/
      /* PLL param config */
      /********************/
  
      /* clkpll_icp_1u */
      /* clkpll_icp_5u */
      /* clkpll_int_frac_sw */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_CP);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_ICP_1U, 0);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_ICP_5U, 2);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_INT_FRAC_SW, 0);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_CP, tmpVal);
  
      /* clkpll_c3 */
      /* clkpll_cz */
      /* clkpll_rz */
      /* clkpll_r4 */
      /* clkpll_r4_short */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_RZ);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_C3, 3);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_CZ, 1);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_RZ, 1);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_R4_SHORT, 1);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_R4, 2);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_RZ, tmpVal);
  
      /* clkpll_refdiv_ratio */
      /* clkpll_postdiv */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_POSTDIV, 0x14);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_REFDIV_RATIO, 2);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal);
  
      /* clkpll_sdmin */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x3C0000);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_SDM, tmpVal);
  
      /* clkpll_sel_fb_clk */
      /* clkpll_sel_sample_clk can be 0/1, default is 1 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_FBDV);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SEL_FB_CLK, 1);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SEL_SAMPLE_CLK, 1);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_FBDV, tmpVal);
  
      /*************************/
      /* PLL power up sequence */
      /*************************/
  
      /* pu_clkpll_sfreg=1 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_PU_CLKPLL_SFREG);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      BL702_Delay_US(5);
  
      /* pu_clkpll=1 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_PU_CLKPLL);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      /* clkpll_pu_cp=1 */
      /* clkpll_pu_pfd=1 */
      /* clkpll_pu_fbdv=1 */
      /* clkpll_pu_postdiv=1 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_CP);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_PFD);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_FBDV);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_POSTDIV);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      BL702_Delay_US(5);
  
      /* clkpll_sdm_reset=1 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_SDM_RESET);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
      BL702_Delay_US(1);
      /* clkpll_reset_fbdv=1 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_RESET_FBDV);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
      BL702_Delay_US(2);
      /* clkpll_reset_fbdv=0 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_RESET_FBDV);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
      BL702_Delay_US(1);
      /* clkpll_sdm_reset=0 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_SDM_RESET);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      return SUCCESS;
  }
  #endif
  /** PLL output config **/
  /*
  [8]    1'h0    r/w    clkpll_en_32m
  [7]    1'h0    r/w    clkpll_en_48m
  [6]    1'h0    r/w    clkpll_en_80m
  [5]    1'h0    r/w    clkpll_en_96m
  [4]    1'h0    r/w    clkpll_en_120m
  [3]    1'h0    r/w    clkpll_en_160m
  [2]    1'h0    r/w    clkpll_en_192m
  [1]    1'h0    r/w    clkpll_en_240m
  [0]    1'h0    r/w    clkpll_en_480m
  */
  
  /****************************************************************************/ /**
   * @brief  Enable all PLL clock
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Enable_PLL_All_Clks(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN);
      tmpVal |= 0x1FF;
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal);
  
      return SUCCESS;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Disable all PLL clock
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Disable_PLL_All_Clks(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN);
      tmpVal &= (~0x1FF);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal);
  
      return SUCCESS;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Enable PLL clock
   *
   * @param  pllClk: PLL clock type
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Enable_PLL_Clk(PDS_PLL_CLK_Type pllClk)
  {
      uint32_t tmpVal = 0;
  
      /* Check parameter*/
      CHECK_PARAM(IS_PDS_PLL_CLK_TYPE(pllClk));
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN);
      tmpVal |= (1 << pllClk);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal);
  
      return SUCCESS;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Disable PLL clock
   *
   * @param  pllClk: PLL clock type
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Disable_PLL_Clk(PDS_PLL_CLK_Type pllClk)
  {
      uint32_t tmpVal = 0;
  
      /* Check parameter*/
      CHECK_PARAM(IS_PDS_PLL_CLK_TYPE(pllClk));
  
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN);
      tmpVal &= (~(1 << pllClk));
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal);
  
      return SUCCESS;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Power off PLL
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Power_Off_PLL(void)
  {
      uint32_t tmpVal = 0;
  
      /* pu_clkpll_sfreg=0 */
      /* pu_clkpll=0 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_PU_CLKPLL_SFREG);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_PU_CLKPLL);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      /* clkpll_pu_cp=0 */
      /* clkpll_pu_pfd=0 */
      /* clkpll_pu_fbdv=0 */
      /* clkpll_pu_postdiv=0 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_CP);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_PFD);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_FBDV);
      tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_POSTDIV);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      return SUCCESS;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Set Audio PLL clock
   *
   * @param  audioPLLFreq: Audio PLL sel frequency , have two vaild input 12.288 or 11.289 MHZ
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  __WEAK
  BL_Err_Type ATTR_CLOCK_SECTION PDS_Set_Audio_PLL_Freq(PDS_AUDIO_PLL_Type audioPLLFreq)
  {
      uint32_t sdmin_table[] = { 0x374BC6, 0x32CCED, 0x32CCED, 0x6E978D, 0x6C0000 };
      uint32_t tmpVal = 0;
  
      CHECK_PARAM(IS_PDS_AUDIO_PLL_TYPE(audioPLLFreq));
  
      /*set PDS_CLKPLL_REFDIV_RATIO as 0x2 */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_REFDIV_RATIO, 0x2);
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal);
  
      /*set clkpll_sdmin as sdmin*/
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, (uint32_t)sdmin_table[audioPLLFreq % (sizeof(sdmin_table) / sizeof(sdmin_table[0]))]);
  
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_SDM, tmpVal);
  
      /*reset pll */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL);
  
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_PU_CLKPLL_SFREG, 1);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      BL702_Delay_MS(10);
  
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_PU_CLKPLL, 1);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_RESET_FBDV, 1);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      BL702_Delay_MS(10);
  
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_RESET_FBDV, 0);
      BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal);
  
      /*set div for audio pll */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL);
  
      if (audioPLLFreq != AUDIO_PLL_5644800_HZ) {
          tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_POSTDIV, 36);
      } else {
          tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_POSTDIV, 72);
      }
  
      BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal);
  
      return SUCCESS;
  }
  
  /****************************************************************************/ /**
   * @brief  PDS software reset
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  void ATTR_TCM_SECTION PDS_Reset(void)
  {
      uint32_t tmpVal = 0;
  
      tmpVal = *(uint32_t *)0x40000010;
      tmpVal = tmpVal | (1 << 14);
      *(uint32_t *)0x40000010 = tmpVal;
  
      tmpVal = *(uint32_t *)0x40000010;
      tmpVal = tmpVal & ~(1 << 14);
      *(uint32_t *)0x40000010 = tmpVal;
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Enable power down sleep
   *
   * @param  cfg: power down sleep configuration 1
   * @param  pdsSleepCnt: power down sleep count cycle
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  void ATTR_TCM_SECTION PDS_Enable(PDS_CFG_Type *cfg, uint32_t pdsSleepCnt)
  {
      uint32_t *p = (uint32_t *)cfg;
  
      if (pdsSleepCnt - PDS_WARMUP_CNT <= 0) {
          return;
      }
  
      BL_WR_REG(PDS_BASE, PDS_TIME1, pdsSleepCnt - PDS_WARMUP_CNT);
  
      /* Set PDS control register  */
      BL_WR_REG(PDS_BASE, PDS_CTL, *p);
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  PDS Auto mode wake up counter config
   *
   * @param  sleepDuration: sleep time, total pds = sleep_duration + max_warmup_cnt (32K clock cycles),
   *                        recommend maxWarmCnt*N+2
   *
   * @return None
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  void ATTR_TCM_SECTION PDS_Auto_Time_Config(uint32_t sleepDuration)
  {
      /* PDS_TIME1 */
      BL_WR_REG(PDS_BASE, PDS_TIME1, sleepDuration);
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  PDS Auto mode config and enable
   *
   * @param  powerCfg: PDS Auto mode power domain config
   * @param  normalCfg: PDS Auto mode power normal config
   * @param  enable: PDS Auto mode Enable or Disable
   *
   * @return None
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  void ATTR_TCM_SECTION PDS_Auto_Enable(PDS_AUTO_POWER_DOWN_CFG_Type *powerCfg, PDS_AUTO_NORMAL_CFG_Type *normalCfg, BL_Fun_Type enable)
  {
      uint32_t pdsCtl = 0;
  
      CHECK_PARAM(IS_PDS_LDO_VOLTAGE_TYPE(normalCfg->vddcoreVol));
  
      /* power config */
      pdsCtl |= (powerCfg->mbgPower << 31) |
                (powerCfg->ldo18rfPower << 30) |
                (powerCfg->sfregPower << 29) |
                (powerCfg->pllPower << 28) |
                (powerCfg->cpu0Power << 19) |
                (powerCfg->rc32mPower << 17) |
                (powerCfg->xtalPower << 14) |
                (powerCfg->allPower << 13) |
                (powerCfg->isoPower << 11) |
                (powerCfg->bzPower << 10) |
                (powerCfg->sramDisStanby << 9) |
                (powerCfg->cgPower << 8) |
                (powerCfg->cpu1Power << 7) |
                (powerCfg->usbPower << 3);
      pdsCtl = BL_SET_REG_BITS_VAL(pdsCtl, PDS_CR_PDS_LDO_VOL, normalCfg->vddcoreVol);
      pdsCtl |= (normalCfg->vddcoreVolEn << 18) |
                (normalCfg->cpu0NotNeedWFI << 21) |
                (normalCfg->cpu1NotNeedWFI << 20) |
                (normalCfg->busReset << 16) |
                (normalCfg->disIrqWakeUp << 15) |
                (normalCfg->powerOffXtalForever << 2) |
                (normalCfg->sleepForever << 1);
      BL_WR_REG(PDS_BASE, PDS_CTL, pdsCtl);
  
      pdsCtl = BL_RD_REG(PDS_BASE, PDS_CTL);
  
      if (enable) {
          pdsCtl |= (1 << 0);
      } else {
          pdsCtl &= ~(1 << 0);
      }
  
      BL_WR_REG(PDS_BASE, PDS_CTL, pdsCtl);
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  PDS force turn off XXX domain
   *
   * @param  domain: PDS domain
   *
   * @return None
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  void ATTR_TCM_SECTION PDS_Manual_Force_Turn_Off(PDS_FORCE_Type domain)
  {
      uint32_t tmpVal = 0;
  
      /* memory sleep */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal |= 1 << (domain + PDS_FORCE_MEM_STBY_OFFSET);
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* gate clock */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal |= 1 << (domain + PDS_FORCE_GATE_CLK_OFFSET);
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* pds reset */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal |= 1 << (domain + PDS_FORCE_PDS_RST_OFFSET);
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* isolation on */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal |= 1 << (domain + PDS_FORCE_ISO_EN_OFFSET);
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* power off */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal |= 1 << (domain + PDS_FORCE_PWR_OFF_OFFSET);
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  PDS force turn on XXX domain
   *
   * @param  domain: PDS domain
   *
   * @return None
   *
  *******************************************************************************/
  #ifndef BFLB_USE_ROM_DRIVER
  __WEAK
  void ATTR_TCM_SECTION PDS_Manual_Force_Turn_On(PDS_FORCE_Type domain)
  {
      uint32_t tmpVal = 0;
  
      /* power on */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal &= ~(1 << (domain + PDS_FORCE_PWR_OFF_OFFSET));
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* isolation off */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal &= ~(1 << (domain + PDS_FORCE_ISO_EN_OFFSET));
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* pds de_reset */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal &= ~(1 << (domain + PDS_FORCE_PDS_RST_OFFSET));
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* memory active */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal &= ~(1 << (domain + PDS_FORCE_MEM_STBY_OFFSET));
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  
      /* clock on */
      tmpVal = BL_RD_REG(PDS_BASE, PDS_CTL2);
      tmpVal &= ~(1 << (domain + PDS_FORCE_GATE_CLK_OFFSET));
      BL_WR_REG(PDS_BASE, PDS_CTL2, tmpVal);
  }
  #endif
  
  /****************************************************************************/ /**
   * @brief  Power down sleep wake up interrupt handler
   *
   * @param  None
   *
   * @return None
   *
  *******************************************************************************/
  void PDS_WAKEUP_IRQHandler(void)
  {
      for (PDS_INT_Type intType = PDS_INT_WAKEUP; intType < PDS_INT_MAX; intType++) {
          if (PDS_Get_IntStatus(intType) && (pdsIntCbfArra[intType][0] != NULL)) {
              pdsIntCbfArra[intType][0]();
          }
      }
      PDS_Set_Vddcore_GPIO_IntClear();
      PDS_IntClear();
  }
  
  /****************************************************************************/ /**
   * @brief  PDS wakeup IRQHandler install
   *
   * @param  None
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type PDS_WAKEUP_IRQHandler_Install(void)
  {
      Interrupt_Handler_Register(PDS_WAKEUP_IRQn, PDS_WAKEUP_IRQHandler);
      return SUCCESS;
  }
  
  /*@} end of group PDS_Public_Functions */
  
  /*@} end of group PDS */
  
  /*@} end of group BL702_Peripheral_Driver */
  