text: /**
    ******************************************************************************
    * @file    bl702_sf_cfg_ext.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_glb.h"
  #include "bl702_sf_cfg.h"
  #include "bl702_sf_cfg_ext.h"
  #include "bl702_xip_sflash.h"
  #include "bl702_romdriver.h"
  
  /** @addtogroup  BL702_Peripheral_Driver
   *  @{
   */
  
  /** @addtogroup  SF_CFG_EXT
   *  @{
   */
  
  /** @defgroup  SF_CFG_EXT_Private_Macros
   *  @{
   */
  #define BFLB_FLASH_CFG_MAGIC "FCFG"
  
  /*@} end of group SF_CFG_EXT_Private_Macros */
  
  /** @defgroup  SF_CFG_EXT_Private_Types
   *  @{
   */
  typedef struct
  {
      uint32_t jedecID;
      char *name;
      const SPI_Flash_Cfg_Type *cfg;
  } Flash_Info_t;
  
  /*@} end of group SF_CFG_EXT_Private_Types */
  
  /** @defgroup  SF_CFG_EXT_Private_Variables
   *  @{
   */
  static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_Md_40D = {
      .resetCreadCmd = 0xff,
      .resetCreadCmdSize = 3,
      .mid = 0x51,
  
      .deBurstWrapCmd = 0x77,
      .deBurstWrapCmdDmyClk = 0x3,
      .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES,
      .deBurstWrapData = 0xF0,
  
      /*reg*/
      .writeEnableCmd = 0x06,
      .wrEnableIndex = 0x00,
      .wrEnableBit = 0x01,
      .wrEnableReadRegLen = 0x01,
  
      .qeIndex = 1,
      .qeBit = 0x01,
      .qeWriteRegLen = 0x02,
      .qeReadRegLen = 0x1,
  
      .busyIndex = 0,
      .busyBit = 0x00,
      .busyReadRegLen = 0x1,
      .releasePowerDown = 0xab,
  
      .readRegCmd[0] = 0x05,
      .readRegCmd[1] = 0x35,
      .writeRegCmd[0] = 0x01,
      .writeRegCmd[1] = 0x01,
  
      .fastReadQioCmd = 0xeb,
      .frQioDmyClk = 16 / 8,
      .cReadSupport = 0,
      .cReadMode = 0xA0,
  
      .burstWrapCmd = 0x77,
      .burstWrapCmdDmyClk = 0x3,
      .burstWrapDataMode = SF_CTRL_DATA_4_LINES,
      .burstWrapData = 0x40,
      /*erase*/
      .chipEraseCmd = 0xc7,
      .sectorEraseCmd = 0x20,
      .blk32EraseCmd = 0x52,
      .blk64EraseCmd = 0xd8,
      /*write*/
      .pageProgramCmd = 0x02,
      .qpageProgramCmd = 0x32,
      .qppAddrMode = SF_CTRL_ADDR_1_LINE,
  
      .ioMode = SF_CTRL_DO_MODE,
      .clkDelay = 1,
      .clkInvert = 0x3f,
  
      .resetEnCmd = 0x66,
      .resetCmd = 0x99,
      .cRExit = 0xff,
      .wrEnableWriteRegLen = 0x00,
  
      /*id*/
      .jedecIdCmd = 0x9f,
      .jedecIdCmdDmyClk = 0,
      .qpiJedecIdCmd = 0x9f,
      .qpiJedecIdCmdDmyClk = 0x00,
      .sectorSize = 4,
      .pageSize = 256,
  
      /*read*/
      .fastReadCmd = 0x0b,
      .frDmyClk = 8 / 8,
      .qpiFastReadCmd = 0x0b,
      .qpiFrDmyClk = 8 / 8,
      .fastReadDoCmd = 0x3b,
      .frDoDmyClk = 8 / 8,
      .fastReadDioCmd = 0xbb,
      .frDioDmyClk = 0,
      .fastReadQoCmd = 0x6b,
      .frQoDmyClk = 8 / 8,
  
      .qpiFastReadQioCmd = 0xeb,
      .qpiFrQioDmyClk = 16 / 8,
      .qpiPageProgramCmd = 0x02,
      .writeVregEnableCmd = 0x50,
  
      /* qpi mode */
      .enterQpi = 0x38,
      .exitQpi = 0xff,
  
      /*AC*/
      .timeEsector = 300,
      .timeE32k = 1200,
      .timeE64k = 1200,
      .timePagePgm = 5,
      .timeCe = 20 * 1000,
      .pdDelay = 20,
      .qeData = 0,
  };
  
  static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_MX_KH25 = {
      .resetCreadCmd = 0xff,
      .resetCreadCmdSize = 3,
      .mid = 0xc2,
  
      .deBurstWrapCmd = 0x77,
      .deBurstWrapCmdDmyClk = 0x3,
      .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES,
      .deBurstWrapData = 0xF0,
  
      /*reg*/
      .writeEnableCmd = 0x06,
      .wrEnableIndex = 0x00,
      .wrEnableBit = 0x01,
      .wrEnableReadRegLen = 0x01,
  
      .qeIndex = 1,
      .qeBit = 0x01,
      .qeWriteRegLen = 0x01,
      .qeReadRegLen = 0x1,
  
      .busyIndex = 0,
      .busyBit = 0x00,
      .busyReadRegLen = 0x1,
      .releasePowerDown = 0xab,
  
      .readRegCmd[0] = 0x05,
      .readRegCmd[1] = 0x00,
      .writeRegCmd[0] = 0x01,
      .writeRegCmd[1] = 0x00,
  
      .fastReadQioCmd = 0xeb,
      .frQioDmyClk = 16 / 8,
      .cReadSupport = 0,
      .cReadMode = 0x20,
  
      .burstWrapCmd = 0x77,
      .burstWrapCmdDmyClk = 0x3,
      .burstWrapDataMode = SF_CTRL_DATA_4_LINES,
      .burstWrapData = 0x40,
      /*erase*/
      .chipEraseCmd = 0xc7,
      .sectorEraseCmd = 0x20,
      .blk32EraseCmd = 0x52,
      .blk64EraseCmd = 0xd8,
      /*write*/
      .pageProgramCmd = 0x02,
      .qpageProgramCmd = 0x32,
      .qppAddrMode = SF_CTRL_ADDR_1_LINE,
  
      .ioMode = 0x11,
      .clkDelay = 1,
      .clkInvert = 0x3f,
  
      .resetEnCmd = 0x66,
      .resetCmd = 0x99,
      .cRExit = 0xff,
      .wrEnableWriteRegLen = 0x00,
  
      /*id*/
      .jedecIdCmd = 0x9f,
      .jedecIdCmdDmyClk = 0,
      .qpiJedecIdCmd = 0x9f,
      .qpiJedecIdCmdDmyClk = 0x00,
      .sectorSize = 4,
      .pageSize = 256,
  
      /*read*/
      .fastReadCmd = 0x0b,
      .frDmyClk = 8 / 8,
      .qpiFastReadCmd = 0x0b,
      .qpiFrDmyClk = 8 / 8,
      .fastReadDoCmd = 0x3b,
      .frDoDmyClk = 8 / 8,
      .fastReadDioCmd = 0xbb,
      .frDioDmyClk = 0,
      .fastReadQoCmd = 0x6b,
      .frQoDmyClk = 8 / 8,
  
      .qpiFastReadQioCmd = 0xeb,
      .qpiFrQioDmyClk = 16 / 8,
      .qpiPageProgramCmd = 0x02,
      .writeVregEnableCmd = 0x50,
  
      /* qpi mode */
      .enterQpi = 0x38,
      .exitQpi = 0xff,
  
      /*AC*/
      .timeEsector = 300,
      .timeE32k = 1200,
      .timeE64k = 1200,
      .timePagePgm = 5,
      .timeCe = 20 * 1000,
      .pdDelay = 20,
      .qeData = 0,
  };
  
  static const ATTR_TCM_CONST_SECTION Flash_Info_t flashInfos[] = {
      {
          .jedecID = 0x134051,
          .name = "GD_MD04D_04_33",
          .cfg = &flashCfg_Gd_Md_40D,
      },
      {
          .jedecID = 0x1320c2,
          .name = "MX_KH40_04_33",
          .cfg = &flashCfg_MX_KH25,
      },
      {
          .jedecID = 0x1420c2,
          .name = "MX_KH80_08_33",
          .cfg = &flashCfg_MX_KH25,
      },
      {
          .jedecID = 0x1520c2,
          .name = "MX_KH16_16_33",
          .cfg = &flashCfg_MX_KH25,
      },
  };
  
  /*@} end of group SF_CFG_EXT_Private_Variables */
  
  /** @defgroup  SF_CFG_EXT_Global_Variables
   *  @{
   */
  
  /*@} end of group SF_CFG_EXT_Global_Variables */
  
  /** @defgroup  SF_CFG_EXT_Private_Fun_Declaration
   *  @{
   */
  
  /*@} end of group SF_CFG_EXT_Private_Fun_Declaration */
  
  /** @defgroup  SF_CFG_EXT_Public_Functions
   *  @{
   */
  
  /****************************************************************************/ /**
   * @brief  Init internal flash GPIO
   *
   * @param  None
   *
   * @return None
   *
  *******************************************************************************/
  void ATTR_TCM_SECTION SF_Cfg_Init_Internal_Flash_Gpio(void)
  {
      GLB_GPIO_Cfg_Type gpioCfg = {
          .gpioPin = GLB_GPIO_PIN_0,
          .gpioFun = GPIO_FUN_GPIO,
          .gpioMode = GPIO_MODE_INPUT,
          .pullType = GPIO_PULL_NONE,
          .drive = 0,
          .smtCtrl = 1,
      };
  
      /* Turn on Flash pad, GPIO23 - GPIO28 */
      for (uint32_t pin = 23; pin < 29; pin++) {
          gpioCfg.gpioPin = pin;
  
          if (pin == 25) {
              gpioCfg.pullType = GPIO_PULL_DOWN;
          } else {
              gpioCfg.pullType = GPIO_PULL_NONE;
          }
  
          GLB_GPIO_Init(&gpioCfg);
      }
  }
  
  /****************************************************************************/ /**
   * @brief  Get flash config according to flash ID
   *
   * @param  flashID: Flash ID
   * @param  pFlashCfg: Flash config pointer
   *
   * @return SUCCESS or ERROR
   *
  *******************************************************************************/
  BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg)
  {
      uint32_t i;
      uint8_t buf[sizeof(SPI_Flash_Cfg_Type) + 8];
      uint32_t crc, *pCrc;
  
      if (flashID == 0) {
          XIP_SFlash_Read_Via_Cache_Need_Lock(8 + BL702_FLASH_XIP_BASE, buf, sizeof(SPI_Flash_Cfg_Type) + 8);
  
          if (BL702_MemCmp(buf, BFLB_FLASH_CFG_MAGIC, 4) == 0) {
              crc = BFLB_Soft_CRC32((uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type));
              pCrc = (uint32_t *)(buf + 4 + sizeof(SPI_Flash_Cfg_Type));
  
              if (*pCrc == crc) {
                  BL702_MemCpy_Fast(pFlashCfg, (uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type));
                  return SUCCESS;
              }
          }
      } else {
          if (SF_Cfg_Get_Flash_Cfg_Need_Lock(flashID, pFlashCfg) == SUCCESS) {
              return SUCCESS;
          }
  
          for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) {
              if (flashInfos[i].jedecID == flashID) {
                  BL702_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type));
                  return SUCCESS;
              }
          }
      }
  
      return ERROR;
  }
  
  /****************************************************************************/ /**
   * @brief  Identify one flash
   *
   * @param  callFromFlash: code run at flash or ram
   * @param  autoScan: Auto scan all GPIO pin
   * @param  flashPinCfg: Specify flash GPIO config, not auto scan
   * @param  restoreDefault: Wether restore default flash GPIO config
   * @param  pFlashCfg: Flash config pointer
   *
   * @return Flash ID
   *
  *******************************************************************************/
  uint32_t ATTR_TCM_SECTION SF_Cfg_Flash_Identify_Ext(uint8_t callFromFlash,
                                                      uint32_t autoScan, uint32_t flashPinCfg, uint8_t restoreDefault, SPI_Flash_Cfg_Type *pFlashCfg)
  {
      uint32_t jdecId = 0;
      uint32_t i = 0;
      uint32_t ret = 0;
  
      ret = SF_Cfg_Flash_Identify(callFromFlash, autoScan, flashPinCfg, restoreDefault, pFlashCfg);
  
      if ((ret & BFLB_FLASH_ID_VALID_FLAG) != 0) {
          return ret;
      }
  
      jdecId = (ret & 0xffffff);
  
      for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) {
          if (flashInfos[i].jedecID == jdecId) {
              BL702_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type));
              break;
          }
      }
  
      if (i == sizeof(flashInfos) / sizeof(flashInfos[0])) {
          return jdecId;
      } else {
          return (jdecId | BFLB_FLASH_ID_VALID_FLAG);
      }
  }
  
  /*@} end of group SF_CFG_EXT_Public_Functions */
  
  /*@} end of group SF_CFG_EXT */
  
  /*@} end of group BL702_Peripheral_Driver */
  