/**
  ******************************************************************************
  * @file    lcm32f06x_cordic.c
  * @author  System R&D Team
  * @version V2.0.2
  * @date    10-April-2025
  * @brief   This file provides all the cordic 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_cordic.h"


/**
  * @name   CORDIC_Init
  * @brief  EN: Initializes the CORDIC peripheral according to the specified 
  *             parameters in the CORDIC_InitStruct.
  *         CN: 根据指定的参数初始化 CORDIC 外设在 CORDIC_InitStruct 中。
  * @param  CORDIC_InitStruct: 
  *         EN: Pointer to an CORDIC_InitTypeDef structure that contains the 
  *             configuration information for the specified CORDIC peripheral.
  *         CN: 指向 CORDIC_InitTypeDef 结构的指针，该结构包含指定 CORDIC 外设的配置信息。
  * @retval None
  */
void CORDIC_Init(CORDIC_InitTypeDef *CORDIC_InitStruct)
{
  CORDIC->CFG = (CORDIC_InitStruct->Cordic_Function | CORDIC_InitStruct->Cordic_Mode | \
                  CORDIC_InitStruct->Cordic_Cycles | (uint32_t)(CORDIC_InitStruct->Cordic_BypassPOST << CORDIC_CFG_BYPASS_POST_Pos) | \
                 (uint32_t)(CORDIC_InitStruct->Cordic_BypassPRE << CORDIC_CFG_BYPASS_PRE_Pos));

  CORDIC->XI = CORDIC_InitStruct->Cordic_Xi;
  CORDIC->YI = CORDIC_InitStruct->Cordic_Yi;
  CORDIC->ZI = CORDIC_InitStruct->Cordic_Zi;
}

/**
  * @name   CORDIC_Start
  * @brief  EN: CORDIC starts calculation.
  *         CN: CORDIC开始运算。
  * @retval Cordic_Result_t
  *         EN: Operation result.
  *         CN: 运算结果。
  */
Cordic_Result_t CORDIC_Start(void)
{
  Cordic_Result_t result;
  CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
  while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  };
  result.XO = CORDIC->XO;
  result.YO = CORDIC->YO;
  result.ZO = CORDIC->ZO;
  return result;
}

/**
  * @name   CORDIC_Circle_System_Config
  * @brief  EN: Circumferential system.
  *         CN: 圆周系统。
  * @param  Mode:
  *         EN: CORDIC mode selection.
  *         CN: CORDIC 模式选择
  * @param  Cycles:
  *         EN: The number of iterations for CORDIC operations.
  *         CN: CORDIC 运算的迭代次数。
  *             @arg CORDIC_CYCLES_1
  *             @arg ...
  *             @arg CORDIC_CYCLES_32
  * @param  Xi:
  *         EN: X input value.
  *         CN: X 输入值。
  * @param  Yi:
  *         EN: Y input value.
  *         CN: Y 输入值。
  * @param  Zi:
  *         EN: Z input value.
  *         CN: Z 输入值。
  * @retval Cordic_Result_t
  *         EN: Operation result.
  *         CN: 运算结果。
  */
Cordic_Result_t CORDIC_Circle_System_Config(uint32_t Mode, uint32_t Cycles, uint32_t Xi, uint32_t Yi, uint32_t Zi)
{

  Cordic_Result_t result;

  CORDIC->CFG = CORDIC_FUNC_CIRCLE | Mode | Cycles;

  if (Mode == CORDIC_MODE_ROTATE)
  {
    CORDIC->XI = (1/1.64676 * Xi);
    CORDIC->YI = 0;
    CORDIC->ZI = Zi;

    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    result.XO = CORDIC->XO;
    result.YO = CORDIC->YO;
    result.ZO = CORDIC->ZO;
  }
  else if (Mode == CORDIC_MODE_VECTOR)
  {
    CORDIC->XI = Xi;
    CORDIC->YI = Yi;
    CORDIC->ZI = 0;

    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    result.XO = CORDIC->XO;
    result.YO = CORDIC->YO;
    result.ZO = CORDIC->ZO;
  }
  return result;
}

/**
  * @name   CORDIC_Hyperbolic_System_Config
  * @brief  EN: Hyperbolic system
  *         CN: 双曲系统
  * @param  Mode:
  *         EN: CORDIC mode selection.
  *         CN: CORDIC 模式选择
  * @param  Cycles:
  *         EN: The number of iterations for CORDIC operations.
  *         CN: CORDIC 运算的迭代次数。
  *             @arg CORDIC_CYCLES_1
  *             @arg ...
  *             @arg CORDIC_CYCLES_32
  * @param  Xi:
  *         EN: X input value.
  *         CN: X 输入值。
  * @param  Yi:
  *         EN: Y input value.
  *         CN: Y 输入值。
  * @param  Zi:
  *         EN: Z input value.
  *         CN: Z 输入值。
  * @retval Cordic_Result_t
  *         EN: Operation result.
  *         CN: 运算结果。
  */
Cordic_Result_t CORDIC_Hyperbolic_System_Config(uint32_t Mode, uint32_t Cycles, uint32_t Xi, uint32_t Yi, uint32_t Zi)
{
  Cordic_Result_t result;

  CORDIC->CFG = CORDIC_FUNC_HYPERBOLIC | Mode | Cycles;

  if (Mode == CORDIC_MODE_ROTATE)
  {
    CORDIC->XI = (Xi/0.82815936);
    CORDIC->YI = 0;
    CORDIC->ZI = Zi;

    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    result.XO = CORDIC->XO;
    result.YO = CORDIC->YO;
    result.ZO = CORDIC->ZO;
  }
  else if (Mode == CORDIC_MODE_VECTOR)
  {
    CORDIC->XI = Xi;
    CORDIC->YI = Yi;
    CORDIC->ZI = 0;

    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    result.XO = CORDIC->XO;
    result.YO = CORDIC->YO;
    result.ZO = CORDIC->ZO;
  }
  return result;
}

/**
  * @name   CORDIC_ITConfig
  * @brief  EN: Enables or disables the specified Cordic interrupts.
  *         CN: 启用或禁用指定的Cordic中断。
  * @param  CORDIC_IT: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: 指定要启用或禁用的CORDIC中断源。
  *             @arg CORDIC_IT_OVF
  *             @arg CORDIC_IT_DONE
  * @param  NewState: 
  *         EN: new state of the specified CORDIC interrupts.
  *         CN: 指定CORDIC中断的新状态。
  *             @arg ENABLE
  *             @arg DISABLE
  * @retval None
  */
void CORDIC_ITConfig(uint32_t CORDIC_IT, FunctionalState NewState)
{
  assert_param(IS_CORDIC_IT(CORDIC_IT));
  /* Check the parameters */
  if (NewState != DISABLE)
  {
    /* Enable the selected CORDIC interrupts */
    CORDIC->CTRL |= CORDIC_IT;
  }
  else
  {
    /* Disable the selected CORDIC interrupts */
    CORDIC->CTRL &= (~(uint32_t)CORDIC_IT);
  }
}

/**
  * @name   CORDIC_GetFlagStatus
  * @brief  EN: Read Cordic status flags.
  *         CN: 读取Cordic状态标志。
  * @param  CORDIC_FLAG: 
  *         EN: Specify the Cordic flag to be read.
  *         CN: 指定Cordic要读取的标志。
  *             @arg CORDIC_FLAG_OVF
  *             @arg CORDIC_FLAG_DONE
  * @retval FlagStatus
  */
FlagStatus CORDIC_GetFlagStatus(uint32_t CORDIC_FLAG)
{
  FlagStatus bitstatus = RESET;

  /* Check the parameters */
  assert_param(IS_CORDIC_FLAG(CORDIC_FLAG));

  /* Check the status of the specified ADC flag */
  if ((CORDIC->CTRL & CORDIC_FLAG) != (uint32_t)RESET)
  {
    /* ADC_FLAG is set */
    bitstatus = SET;
  }
  else
  {
    /* ADC_FLAG is reset */
    bitstatus = RESET;
  }
  /* Return the ADC_FLAG status */
  return bitstatus;
}

/**
  * @name   CORDIC_ClearITPendingBit
  * @brief  EN: Clears the Cordic interrupt pending bits.
  *         CN: 清除Cordic的中断挂起位。
  * @param  CORDIC_FLAG: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: 指定要启用或禁用的CORDIC中断源。
  *             @arg CORDIC_FLAG_OVF
  *             @arg CORDIC_FLAG_DONE
  * @retval None
  */
void CORDIC_ClearITPendingBit(uint32_t CORDIC_FLAG)
{
  /* Check the parameters */
  assert_param(IS_CORDIC_FLAG(CORDIC_FLAG));

  /* Clear the selected ADC interrupt pending bits */
  CORDIC->CTRL = (uint32_t)CORDIC_FLAG; 
}


/**
  * @name   CORDIC_Sqrt
  * @brief  EN: Calculate the square root of input data.
  *         CN: 计算输入数据平方根。
  * @param  InputValue: 
  *         EN: input value(IQ format). （IQ13 - IQ31）。
  *         CN: 输入值（IQ格式）。 （IQ13 - IQ31）。
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the square root of the input value. (input in IQ format).
  *         CN: 返回输入值的平方根（输入IQ格式）。
  */
uint32_t CORDIC_Sqrt(uint32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    __disable_irq();
    uint8_t i = 0;
    uint32_t CordicHyperbolicAn = 1236;//  1/0.82815936 * (1 << 10);  1/0.82815936 = 1.20749707
    uint32_t temp = 0;
    CORDIC->CFG &= ~CORDIC_CFG_CYCLES_Msk; 
    CORDIC->CFG = 0x00003100 | Accuracy;

    while((InputValue >> IQnIn) > 9)
    {
      InputValue = InputValue >> 1;
      i ++;
    }
    if(i & 0x1)
    {
      InputValue = InputValue >> 1;
      i ++;
    }

    i = i >> 1;

    CORDIC->XI = InputValue + (1 << IQnIn);
    CORDIC->YI = InputValue - (1 << IQnIn);
    CORDIC->ZI = 0;

    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    temp = CORDIC->XO >> 11;
    temp = temp * CordicHyperbolicAn;
    __enable_irq();
    return temp << i ;
}

/**
  * @name   CORDIC_Sin
  * @brief  EN: Calculate the sine value of a given angle (in radians).
  *         CN: 计算给定角度（以弧度为单位）的正弦值。
  * @param  InputValue: 
  *         EN: input value.
  *         CN: 输入值。
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the sine value of a given angle (in radians). (input in IQ format).
  *         CN: 返回给定角度（以弧度为单位）的正弦值。（输入IQ格式）。
  */
int32_t CORDIC_Sin(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    __disable_irq();
    CORDIC->CFG = 0x00001000 | Accuracy;

    CORDIC->XI = 652032976; // 1/1.64676 * (1 << 30)
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;

    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    __enable_irq();
    return ((int32_t)CORDIC->YO) >> (30 - IQnIn);
}

/**
  * @name   CORDIC_Cos
  * @brief  EN: Calculate the cosine value of a given angle (in radians).
  *         CN: 计算给定角度（以弧度为单位）的余弦值。
  * @param  InputValue: 
  *         EN: input value.
  *         CN: 输入值。
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the cosine value of a given angle (in radians). (input in IQ format).
  *         CN: 返回给定角度（以弧度为单位）的余弦值。（输入IQ格式）。
  */
int32_t CORDIC_Cos(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    CORDIC->CFG = 0x00001000 | Accuracy;

    CORDIC->XI = 652032976; // 1/1.64676 * (1 << 30)
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    return ((int32_t)CORDIC->XO) >> (30 - IQnIn);
}

/**
  * @name   CORDIC_SinCos
  * @brief  EN: Calculate the sine and cosine value of a given angle (in radians).
  *         CN: 计算给定角度（以弧度为单位）的正弦和余弦值。
  * @param  InputValue: 
  *         EN: input value.
  *         CN: 输入值。
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @param  pSin: 
  *         EN: The sine value of a given angle (in radians). (Input IQ format).
  *         CN: 给定角度（以弧度为单位）的正弦值。（输入IQ格式）。
  * @param  pCos: 
  *         EN: The cosine value of a given angle (in radians). (Input IQ format).
  *         CN: 给定角度（以弧度为单位）的余弦值。（输入IQ格式）。
  * @retval None
  */
void CORDIC_SinCos(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy, int32_t* pSin, int32_t* pCos)
{
    CORDIC->CFG = 0x00001000 | Accuracy;

    CORDIC->XI = 652032976; // 1/1.64676 * (1 << 30)
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    *pCos = (int32_t)CORDIC->XO >> (30 - IQnIn);
    *pSin = (int32_t)CORDIC->YO >> (30 - IQnIn);
}
/**
  * @name   CORDIC_Tan
  * @brief  EN: Calculate the tangent value of a given angle (in radians).
  *         CN: 计算给定角度（以弧度为单位）的正切值。
  * @param  InputValue: 
  *         EN: input value.
  *         CN: 输入值。
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value (IQ6 - IQ26).
  *         CN: 指定输入数据的IQ格式 （IQ6 - IQ26）。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the tangent value of a given angle (in radians). (input in IQ format).
  *         CN: 返回给定角度（以弧度为单位）的正切值。
  */
int32_t CORDIC_Tan(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    int32_t sinx,cosx = 0;
    CORDIC->CFG = 0x00001000 | Accuracy;

    CORDIC->XI = 652032976; // 1/1.64676 * (1 << 30)
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    cosx = ((int32_t)CORDIC->XO) >> 6;
    sinx = ((int32_t)CORDIC->YO) ;
    DIV0->DIV_CTRL_b.DIV16 = 0; //被除数32位
    DIV0->DIV_ALO = sinx;
    DIV0->DIV_B = cosx;
    while (DIV0->DIV_CTRL_b.DIV_IN_PROCCEED == RESET)
    {
        __NOP(); __NOP(); __NOP();  __NOP(); __NOP();
    };
    DIV0->DIV_CTRL_b.DIV_IN_PROCCEED = SET; //写1清0

    return ((int32_t)DIV0->DIV_QUOT) << (IQnIn - 6);
}

/**
  * @name   CORDIC_Sinh
  * @brief  EN: Calculate the hyperbolic sine value of input data.
  *         CN: 计算输入数据的双曲正弦值。
  * @param  InputValue: 
  *         EN: input value.(The original value is limited to -1.1-1.1)
  *         CN: 输入值。（原值限制在-1.1 - 1.1）
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the the hyperbolic sine value of input data. (input in IQ format).
  *         CN: 返回输入数据的双曲正弦值。（输入IQ格式）。
  */
int32_t CORDIC_Sinh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    CORDIC->CFG = 0x00003000 | Accuracy;
    if(IQnIn < 23)
    {
        CORDIC->XI = 10129223;
    }
    else
    {
        CORDIC->XI = 10129223 << (IQnIn - 23); // 1/0.82815936 * (1 << 23)
    }
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    if(IQnIn < 23)
    {
        return  ((int32_t)CORDIC->YO >> (23 - IQnIn));
    }
    else
    {
        return  ((int32_t)CORDIC->YO);
    }
}

/**
  * @name   CORDIC_Cosh
  * @brief  EN: Calculate the hyperbolic cosine value of input data.
  *         CN: 计算输入数据的双曲余弦值。
  * @param  InputValue: 
  *         EN: input value.(The original value is limited to -1.1-1.1)
  *         CN: 输入值。（原值限制在-1.1 - 1.1）
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the the hyperbolic cosine value of input data. (input in IQ format).
  *         CN: 返回输入数据的双曲余弦值。（输入IQ格式）。
  */
int32_t CORDIC_Cosh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    CORDIC->CFG = 0x00003000 | Accuracy;

    if(IQnIn < 23)
    {
        CORDIC->XI = 10129223;
    }
    else
    {
        CORDIC->XI = 10129223 << (IQnIn - 23); // 1/0.82815936 * (1 << 23)
    }
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    if(IQnIn < 23)
    {
        return  ((int32_t)CORDIC->XO >> (23 - IQnIn));
    }
    else
    {
        return  ((int32_t)CORDIC->XO);
    }
}

/**
  * @name   CORDIC_SinhCosh
  * @brief  EN: Calculate the hyperbolic sine adn chyperbolic cosine value of input data.
  *         CN: 计算输入数据的双曲正弦和双曲余弦值。
  * @param  InputValue: 
  *         EN: input value.(The original value is limited to -1.1-1.1)
  *         CN: 输入值。（原值限制在-1.1 - 1.1）
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @param  pSinh: 
  *         EN: The the hyperbolic sine value of input data. (input in IQ format).
  *         CN: 输入数据的双曲正弦值。（输入IQ格式）。
  * @param  pCosh: 
  *         EN: The the hyperbolic cosine value of input data. (input in IQ format).
  *         CN: 输入数据的双曲余弦值。（输入IQ格式）。
  * @retval None
  */
void CORDIC_SinhCosh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy, int32_t* pSinh, int32_t* pCosh)
{
    CORDIC->CFG = 0x00003000 | Accuracy;

    if(IQnIn < 23)
    {
        CORDIC->XI = 10129223;
    }
    else
    {
        CORDIC->XI = 10129223 << (IQnIn - 23); // 1/0.82815936 * (1 << 23)
    }
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    if(IQnIn < 23)
    {
        *pCosh = ((int32_t)CORDIC->XO>> (23 - IQnIn));
        *pSinh = ((int32_t)CORDIC->YO>> (23 - IQnIn));
    }
    else
    {
        *pCosh = (int32_t)CORDIC->XO;
        *pSinh = (int32_t)CORDIC->YO;
    }

}
/**
  * @name   CORDIC_Tanh
  * @brief  EN: Calculate the hyperbolic tangent of input data.
  *         CN: 计算输入数据的双曲正切值。
  * @param  InputValue: 
  *         EN: input value.(The original value is limited to -1.1-1.1)
  *         CN: 输入值。（原值限制在-1.1 - 1.1）
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return Hyperbolic tangent value of input data. (input in IQ format).
  *         CN: 输入数据的双曲正切值。（输入IQ格式）。
  */
int32_t CORDIC_Tanh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    int32_t sinhx,coshx,tanhx = 0;
    CORDIC->CFG = 0x00003000 | Accuracy;

    if(IQnIn < 23)
    {
        CORDIC->XI = 10129223;
    }
    else
    {
        CORDIC->XI = 10129223 << (IQnIn - 23); // 1/0.82815936 * (1 << 23)
    }
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };

    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    coshx = CORDIC->XO >> 7;
    sinhx = CORDIC->YO;
    DIV0->DIV_CTRL_b.DIV16 = 0; //被除数32位
    DIV0->DIV_ALO = sinhx;
    DIV0->DIV_B = coshx;
    while (DIV0->DIV_CTRL_b.DIV_IN_PROCCEED == RESET)
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    DIV0->DIV_CTRL_b.DIV_IN_PROCCEED = SET; //写1清0
    tanhx = ((int32_t)DIV0->DIV_QUOT) << (IQnIn - 7);
    return  ((int32_t)tanhx);
}

/**
  * @name   CORDIC_Exp
  * @brief  EN: Calculate the x-power of e.
  *         CN: 计算e 的 x 次幂。
  * @param  InputValue: 
  *         EN: input value.(The original value is limited to -1.1-1.1)
  *         CN: 输入值。（原值限制在-1.1 - 1.1）
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the x-power of e. (input in IQ format).
  *         CN: 返回e 的 x 次幂。（输入IQ格式）。
  */
int32_t CORDIC_Exp(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy)
{
    CORDIC->CFG = 0x00003000 | Accuracy;

    if(IQnIn < 23)
    {
        CORDIC->XI = 10129223;
    }
    else
    {
        CORDIC->XI = 10129223 << (IQnIn - 23); // 1/0.82815936 * (1 << 23)
    }
    CORDIC->YI = 0;
    CORDIC->ZI = InputValue << (31 - IQnIn);
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    if(IQnIn < 23)
    {
        return  ((int32_t)((int32_t)CORDIC->XO + (int32_t)CORDIC->YO) >> (23 - IQnIn));
    }
    else
    {
        return  ((int32_t)CORDIC->XO + (int32_t)CORDIC->YO);
    }
}

/**
  * @name   CORDIC_arcTan2
  * @brief  EN: Calculate the arctangent of input data.
  *         CN: 计算输入数据的反正切值。
  * @param  InputValueX: 
  *         EN: input value x cos.
  *         CN: 输入值X cos。
  * @param  InputValueY: 
  *         EN: input value Y sin.
  *         CN: 输入值Y sin。
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the arctangent value of the input data. (input in IQ format).
  *         CN: 返回输入数据的反正切值。（输入IQ格式）。
  */
int32_t CORDIC_arcTan2(int32_t InputValueX, int32_t InputValueY, uint8_t IQnIn, uint32_t Accuracy)
{
    CORDIC->CFG = 0x00001100 | Accuracy;

    CORDIC->XI = InputValueX; 
    CORDIC->YI = InputValueY;
    CORDIC->ZI = 0;
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    return ((int32_t)CORDIC->ZO) >> (31 - IQnIn);
}

/**
  * @name   CORDIC_Mod
  * @brief  EN: Calculate the modulus of input data.
  *         CN: 计算输入数据的模值。
  * @param  InputValueX: 
  *         EN: input value x.
  *         CN: 输入值X。
  * @param  InputValueY: 
  *         EN: input value Y.
  *         CN: 输入值Y。
  * @param  IQnIn: 
  *         EN: Specifies the IQ format of the input value.
  *         CN: 指定输入数据的IQ格式。
  * @param  Accuracy: 
  *         EN: Specifies the CORDIC interrupt sources to be enabled or disabled.
  *         CN: CORDIC 运算的迭代次数，计算消耗的周期数。
  *             @arg CORDIC_CYCLES_1
  *             @arg CORDIC_CYCLES_2
  *             @arg ...
  *             @arg CORDIC_CYCLES_31
  *             @arg CORDIC_CYCLES_32
  * @retval uint32_t:
  *         EN: Return the modulus value of the input data. (input in IQ format).
  *         CN: 返回输入数据的模值。（输入IQ格式）。
  */
uint32_t CORDIC_Mod(int32_t InputValueX, int32_t InputValueY, uint8_t IQnIn, uint32_t Accuracy)
{
    uint32_t Mod = 0;
    CORDIC->CFG = 0x00001100 | Accuracy;

    CORDIC->XI = InputValueX; 
    CORDIC->YI = InputValueY;
    CORDIC->ZI = 0;
  
    CORDIC->CTRL |= CORDIC_CTRL_START_Msk;
    while(!(CORDIC->CTRL & CORDIC_CTRL_DONE_Msk))
    {
        __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    };
    Mod = 1304065952 >> (IQnIn);
    return (uint32_t)((CORDIC->XO) * Mod) >> (31 - IQnIn);
}
