/**
  ******************************************************************************
  * @file    lcm32f06x_gpio.c 
  * @author  System R&D Team
  * @version V2.0.2
  * @date    10-April-2025
  * @brief   This file provides all the GPIO firmware functions.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) Hangzhou Lingxin Microelectronics Co.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "lcm32f06x_gpio.h"

/* Private define ------------------------------------------------------------*/

/*
  ==============================================================================
                    ##### Initialization and Configuration #####
  ==============================================================================
*/

/**
  * @name   GPIO_DeInit
  * @brief  EN: Deinitializes GPIO peripheral registers to their default reset values.
  *         CN: 将 GPIO 外设寄存器初始化为其默认重置值。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @retval None
  */
void GPIO_DeInit(GPIO_TypeDef *GPIOx)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  if (GPIOx == GPIOA)
  {
    RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, DISABLE);
  }
  else 
  {
    if (GPIOx == GPIOB)
    {
      RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, ENABLE);
      RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, DISABLE);
    }
  }
}

/**
  * @name   GPIO_Init
  * @brief  EN: Initializes the GPIOx peripheral according to the specified 
  *             parameters in the GPIO_InitStruct.
  *         CN: 根据 GPIO_InitStruct 中指定的参数初始化 GPIOx。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_InitStruct: 
  *         EN: pointer to a GPIO_InitTypeDef structure that contains the 
  *             configuration information for the specified GPIO peripheral.
  *         CN: 指向 GPIO_InitTypeDef 结构的指针，该结构包含指定 GPIO 外设的配置信息。
  * @retval None
  */
void GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct)
{
  uint32_t pinpos = 0, pos = 0;
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
  assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));
  assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));
  
  /* 获取需要配置的引脚 */
  pinpos = GPIO_InitStruct->GPIO_Pin;

  for (pos = 0; pos < 16; pos++)
  {
    if ((pinpos >> pos) & 0x01)
    {
       /* 配置引脚模式 */
      tmpreg = GPIOx->MODER;
      tmpreg &= ~(0x03 << (pos * 2));
      tmpreg |= (GPIO_InitStruct->GPIO_Mode) << (pos * 2);
      GPIOx->MODER = tmpreg;

      /* 配置翻转速率 */
      if (GPIO_InitStruct->GPIO_Speed == GPIO_Speed_Level_2)
      {
        GPIOx->CS_BSRR = 1 << (pos + 16);
      }
      else
      {
        GPIOx->CS_BSRR = 1 << pos;
      }

      /* 配置上下拉（默认为浮空） */
      if ((GPIO_InitStruct->GPIO_PuPd) == GPIO_PuPd_UP)
      {
        GPIOx->PD_BSRR = 1 << (pos + 16);
        GPIOx->PU_BSRR = 1 << pos;
      }
      else if ((GPIO_InitStruct->GPIO_PuPd) == GPIO_PuPd_DOWN)
      {
        GPIOx->PU_BSRR = 1 << (pos + 16);
        GPIOx->PD_BSRR = 1 << pos;
      }
      else if ((GPIO_InitStruct->GPIO_PuPd) == GPIO_PuPd_UPDOWN)
      {
        GPIOx->PU_BSRR = 1 << pos;
        GPIOx->PD_BSRR = 1 << pos;
      }
      else
      {
        GPIOx->PU_BSRR = 1 << (pos + 16);
        GPIOx->PD_BSRR = 1 << (pos + 16);
      }

      /* 配置输出类型 */
      if (GPIO_InitStruct->GPIO_OType == GPIO_OType_OS)
      {
        GPIOx->OS_BSRR = (1 << pos);
      }
      else if (GPIO_InitStruct->GPIO_OType == GPIO_OType_OD)
      {
        GPIOx->OD_BSRR = (1 << pos);
      }
      else
      {
        GPIOx->OD_BSRR = (1 << (pos + 16));
        GPIOx->OS_BSRR = (1 << (pos + 16));
      }
    }
  }
}

/**
  * @name   GPIO_StructInit
  * @brief  EN: Fills each GPIO_InitStruct member with its default value.
  *         CN: 用默认值填充每个 GPIO_InitStruct 成员。
  * @param  GPIO_InitStruct: 
  *         EN: pointer to a GPIO_InitTypeDef structure that contains the 
  *             configuration information for the specified GPIO peripheral.
  *         CN: 指向 GPIO_InitTypeDef 结构的指针，该结构包含指定 GPIO 外设的配置信息。
  * @retval None
  */
void GPIO_StructInit(GPIO_InitTypeDef *GPIO_InitStruct)
{
  GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;

  GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;

  GPIO_InitStruct->GPIO_Speed = GPIO_Speed_Level_2;

  GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;

  GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL;
}

/**
  * @name   GPIO_PinLockConfig
  * @brief  EN: Locks GPIO Pins configuration registers.
  *         CN: 锁定 GPIO 引脚配置寄存器
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be written.
  *         CN: 指定要写入的端口
  * @retval None
  */
void GPIO_PinLockConfig(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  uint32_t tmp_1 = 0x00010000;
  uint32_t tmp_0 = 0x00000000;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  tmp_1 |= GPIO_Pin;
  tmp_0 |= GPIO_Pin;

  /* Set LCKK bit */
  GPIOx->LCKR = tmp_1;

  /* Reset LCKK bit */
  GPIOx->LCKR = tmp_0;

  /* Set LCKK bit */
  GPIOx->LCKR = tmp_1;

  /* Read LCKK bit */
  tmp_1 = GPIOx->LCKR;

  /* Read LCKK bit */
  if (!((GPIOx->LCKR >> 16) & 0x01))
  {
    /* 锁定失败 */
    while (1)
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
  }
}

/*
  ==============================================================================
                    ##### GPIO Read and Write #####
  ==============================================================================
*/

/**
  * @name   GPIO_ReadInputDataBit
  * @brief  EN: Read the specified input port pins bit by bit.
  *         CN: 按位读指定的输入端口引脚。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be read.
  *         CN: 指定要读的端口位。
  * @retval EN: The input port pin value.
  *         CN: 该输入端口引脚的值。
  */
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  uint8_t bitstatus = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GET_GPIO_PIN(GPIO_Pin));

  if (GPIOx->IDR & GPIO_Pin)
  {
    bitstatus = (uint8_t)Bit_SET;
  }
  else
  {
    bitstatus = (uint8_t)Bit_RESET;
  }
  return bitstatus;
}

/**
  * @name   GPIO_ReadInputData
  * @brief  EN: Reads the specified input port pin.
  *         CN: 读指定的输入端口引脚。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @retval EN: The input port pin value.
  *         CN: 该输入端口引脚的值。
  */
uint16_t GPIO_ReadInputData(GPIO_TypeDef *GPIOx)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  return ((uint16_t)GPIOx->IDR);
}

/**
  * @name   GPIO_ReadOutputDataBit
  * @brief  EN: Reads the specified output data port bit.
  *         CN: 读指定的输出数据端口位。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be read.
  *         CN: 指定要读的端口位。
  * @retval EN: The input port pin value.
  *         CN: 该输出端口引脚的值。
  */
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  uint8_t bitstatus = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GET_GPIO_PIN(GPIO_Pin));

  if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
  {
    bitstatus = (uint8_t)Bit_SET;
  }
  else
  {
    bitstatus = (uint8_t)Bit_RESET;
  }
  return bitstatus;
}

/**
  * @name   GPIO_ReadOutputData
  * @brief  EN: Reads the specified GPIO output data port.
  *         CN: 读指定的输出数据端口。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @retval EN: The input port pin value.
  *         CN: 该输出端口引脚的值。
  */
uint16_t GPIO_ReadOutputData(GPIO_TypeDef *GPIOx)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  return ((uint16_t)GPIOx->ODR);
}

/**
  * @name   GPIO_SetBits
  * @brief  EN: Sets the selected data port bits.
  *         CN: 设置选定的数据端口位。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be written.
  *         CN: 指定要写入的端口。
  * @retval None
  */
void GPIO_SetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->BSRR = GPIO_Pin;
}

/**
  * @name   GPIO_ResetBits
  * @brief  EN: Clears the selected data port bits.
  *         CN: 清除选定的数据端口位。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be written.
  *         CN: 指定要写入的端口。
  * @retval None
  */
void GPIO_ResetBits(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->BSRR = GPIO_Pin << 16;
}

/**
  * @name   GPIO_WriteBit
  * @brief  EN: Sets or clears the selected data port bit.
  *         CN: 设置或清除选定的数据端口位。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be written.
  *         CN: 指定要写入的端口。
  * @param  BitVal:
  *         EN: Specifies the value to be written to the selected bit.
  *         CN: 指定要写入选择位的值。
  *             @arg Bit_RESET: to clear the port pin
  *             @arg Bit_SET  : to set the port pin
  * @retval None
  */
void GPIO_WriteBit(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_BIT_ACTION(BitVal));

  if (BitVal != Bit_RESET)
  {
    GPIOx->BSRR = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRR = GPIO_Pin << 16;
  }
}

/**
  * @name   GPIO_Write
  * @brief  EN: Writes data to the specified GPIO data port.
  *         CN: 将数据写入指定的GPIO数据端口。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  PortVal:
  *         EN: Specifies the value to be written to the port output data register.
  *         CN: 指定要写入端口输出数据寄存器的值。
  * @retval None
  */
void GPIO_Write(GPIO_TypeDef *GPIOx, uint16_t PortVal)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

  GPIOx->ODR = PortVal;
}

/*
  ==============================================================================
          ##### GPIO Alternate functions configuration functions #####
  ==============================================================================
*/

/**
  * @name   GPIO_PinAFConfig
  * @brief  EN: Configure digital alternate function.
  *         CN: 配置数字复用功能。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_PinSource:
  *         EN: Specifies the pin for the alternate function.
  *         CN: 指定复用引脚。
  * @param  GPIO_AF:
  *         EN: Selects the pin to used as alternate function.
  *         CN: 选择要用作复用的功能。
  *             @arg GPIO_AF_0: TIM15, TIM16, TIM17, SPI0, MCO, SWDIO, SWCLK, EVENTOUT
  *             @arg GPIO_AF_1: USART0, USART1, TIM1, TIM2, TIM15, TIM16, TIM17, I2C0, 
  *                         IR
  *             @arg GPIO_AF_2: TIM1, TIM15, TIM16, TIM17, SPI0, I2C0, USART0
  *             @arg GPIO_AF_3: TIM1, TIM2, TIM15, TIM16, TIM17, USART0, USART1, ACMP0, 
  *                         ACMP1
  *             @arg GPIO_AF_4: USART0, USART1, TIM1, SPI0, I2C0, TIM15, TIM16, TIM17 
  *             @arg GPIO_AF_5: TIM1, TIM2, TIM15, TIM16, TI17, SPI0, I2C0, WT, USART0
  *             @arg GPIO_AF_6: ACMP0, ACMP1, TIM1, TIM2, TIM15, TIM16, TIM17, USART0, 
  *                         USART1, I2C0
  *             @arg GPIO_AF_7: I2C0, SPI0, USART0, USART1, TIM2, TIM17
  * @retval None
  */
void GPIO_PinAFConfig(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
{
  uint32_t tmp_1 = 0x00;
  uint32_t tmp_2 = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  assert_param(IS_GPIO_AF(GPIO_AF));

  tmp_1 = GPIOx->AFRL;
  tmp_2 = GPIOx->AFRH;

  if (GPIO_PinSource < 8)
  {
    tmp_1 &= ~(0x0F << (GPIO_PinSource * 4));
    tmp_1 |= (GPIO_AF << (GPIO_PinSource * 4));
  }
  else
  {
    tmp_2 &= ~(0x0F << ((GPIO_PinSource - 8) * 4));
    tmp_2 |= (GPIO_AF << ((GPIO_PinSource - 8) * 4));
  }

  GPIOx->AFRL = tmp_1;
  GPIOx->AFRH = tmp_2;
}

/**
  * @name   GPIO_DriveConfig
  * @brief  EN: GPIO drive capability configuration.
  *         CN: GPIO 驱动器功能配置。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be written.
  *         CN: 指定要写入的端口。
  * @param  GPIO_Drive:
  *         EN: Select the driver mode to be configured.
  *         CN: 选择要配置的驱动模式。
  *             @arg GPIO_Drive_Level_strong
  *             @arg GPIO_Drive_Level_weak
  * @retval None
  */
void GPIO_DriveConfig(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint16_t GPIO_Drive)
{
  uint32_t tmppreg = 0;

  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_LEVEL(GPIO_Drive));

  tmppreg = GPIOx->DR_BSRR;
  if (GPIO_Drive == GPIO_Drive_Level_strong)
  {
    tmppreg &= ~GPIO_Pin;
    tmppreg |= (GPIO_Pin << 16);
  }
  else
  {
    tmppreg |= (GPIO_Pin);
  }

  GPIOx->DR_BSRR = tmppreg;
}

/**
  * @name   GPIO_BitToggle
  * @brief  EN: GPIO flip configuration.
  *         CN: GPIO 翻转配置。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be written.
  *         CN: 指定要写入的端口。
  * @retval None
  */
void GPIO_BitToggle(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->BTGLR = GPIO_Pin;
}

/**
  * @name   GPIO_InputCMOSCmd
  * @brief  EN: Configure CMOS and Schmitt triggers.
  *         CN: 配置 CMOS 和 施密特触发器。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_Pin: 
  *         EN: Specifies the port bit to be written.
  *         CN: 指定要写入的端口。
  * @param  NewState: 
  *         EN: New state of the GPIOx peripheral.
  *         CN: GPIOx 外设的新状态。
  *             @arg ENABLE
  *             @arg DISABLE
  * @retval None
  */
void GPIO_InputCMOSCmd(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, FunctionalState NewState)
{
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  if (NewState != DISABLE)
  {
    /* The CMOS as input */
    GPIOx->CS_BSRR = GPIO_Pin;
  }
  else
  {
    /* The Schmitt trigger as default input */
    GPIOx->CS_BSRR = GPIO_Pin << 16;
  }
}

/**
  * @name   GPIO_AnaModeSet
  * @brief  EN: Configure analog alternate function.
  *         CN: 配置模拟复用功能。
  * @param  GPIOx:
  *         EN: where x can be A or B to select the GPIO peripheral.
  *         CN: x 可以是 A 或 B 以选择 GPIO 外设。
  * @param  GPIO_PinSource:
  *         EN: Specifies the pin for the alternate function.
  *         CN: 指定复用引脚。
  * @param  GPIO_AN1: 
  *         EN: Analog channel 0  enable/disable.
  *         CN: 模拟通道 0 使能/禁止。
  *             @arg GPIO_AN_ENABLE
  *             @arg GPIO_AN_DISABLE
  * @param  GPIO_AN2: 
  *         EN: Analog channel 1  enable/disable.
  *         CN: 模拟通道 1 使能/禁止。
  *             @arg GPIO_AN_ENABLE
  *             @arg GPIO_AN_DISABLE
  * @retval None
  */
void GPIO_AnaModeSet(GPIO_TypeDef *GPIOx, uint16_t GPIO_PinSource, uint32_t GPIO_AN1, uint32_t GPIO_AN2)
{
  uint32_t tmp_0 = 0x00000000;
  uint32_t tmp_1 = 0x00000000;

  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  assert_param(IS_GPIO_AN(GPIO_AN1));
  assert_param(IS_GPIO_AN(GPIO_AN2));

  /* Set the pin as analog alternate function AN */
  GPIOx->MODER |= (0x3 << (GPIO_PinSource << 1));
  
  /* Clear the bits to be set  */
  tmp_0 = GPIOx->AFRL & ~(0xF << (GPIO_PinSource << 2));
  tmp_1 = GPIOx->AFRH & ~(0xf << ((GPIO_PinSource - 8) << 2));

  if (GPIO_PinSource < 8)
  {
    GPIOx->AFRL = tmp_0 | ((GPIO_AN1 | (GPIO_AN2 << 1)) << (GPIO_PinSource << 2));
  }
  else
  {
    GPIOx->AFRH = tmp_1 | ((GPIO_AN1 | (GPIO_AN2 << 1)) << ((GPIO_PinSource - 8) << 2));
  }
}

/**
  * @name   GPIO_ResetPB2Config
  * @brief  EN: Reset pin PB2 is used as a regular GPIO.
  *         CN: reset引脚PB2作为普通GPIO使用。
  * @param  NewState: 
  *         EN: Enable/disable.
  *         CN: 使能/关闭。
  * @retval None
  */
void GPIO_ResetPB2Config(uint32_t NewState)
{
  if (NewState != DISABLE)
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.RST_CFG = 0; // PB2作为通用GPIO /PF2 acts as a universal GPIO
    __dekey();
  }
  else
  {
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    if((GPIOB->MODER & 0x20) && ((GPIOB->AFRL & (0xF << 8)) == 0) && (*(volatile uint16_t *)(0x1ffff71C) == 0x01FE)) 
    {
        GPIOB->MODER &= 0xFFFFFFCF;
        GPIOB->PU_BSRR |= 1 << 2;
        delay10us(1);
        chipctrl_access();
        CHIPCTRL->BDCR_b.RST_CFG = 1; // PB2作为复位引脚 /PF2 serves as the reset pin
        __dekey();
        GPIOB->PU_BSRR = 1 << 18;
        GPIOB->MODER |= 2 << 4;
    }
    else
    {
        chipctrl_access();
        CHIPCTRL->BDCR_b.RST_CFG = 1; // PB2作为复位引脚 /PF2 serves as the reset pin
        __dekey(); 
    }
  }
}

