/**
  ******************************************************************************
  * @file    lcm32f06x_cordic.h 
  * @author  System R&D Team
  * @version V2.0.2
  * @date    10-April-2025
  * @brief   Header for cordic.c module
  ******************************************************************************
  * @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.
  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LCM32F06X_CORDIC_H__
#define __LCM32F06X_CORDIC_H__

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

#ifdef __cplusplus
  extern "C" {
#endif

/** 
  * @brief CORDIC Init structure definition
  */
typedef struct
{
  uint32_t Cordic_Function;           /*!< EN: Rotation system selection.
                                           CN: 旋转系统选择。
                                           @Register: CORDIC_CFG @Bits:[13:12]FUNC.
                                           @default: CORDIC_FUNC_LINEAR */

  uint32_t Cordic_Mode;               /*!< EN: CORDIC mode selection.
                                           CN: CORDIC 模式选择。
                                           @Register: CORDIC_CFG @Bits:[8]MODE.
                                           @default: CORDIC_MODE_ROTATE */

  uint32_t Cordic_Cycles;             /*!< EN: The number of iterations for CORDIC operations.
                                           CN: CORDIC 运算的迭代次数。
                                           @Register: CORDIC_CFG @Bits:[20:16]CYCLES.
                                           @default: CORDIC_CYCLES_32 */

  uint32_t Cordic_Xi;                 /*!< EN: X input value.
                                           CN: X 输入值。
                                           @Register: CORDIC_Xi @Bits:[31:0]CORDIC_Xi.
                                           @range: 0x0 - 0xFFFFFFFF 
                                           @default: 0x0 */
  
  uint32_t Cordic_Yi;                 /*!< EN: Y input value.
                                           CN: Y 输入值。
                                           @Register: CORDIC_Yi @Bits:[31:0]CORDIC_Yi.
                                           @range: 0x0 - 0xFFFFFFFF 
                                           @default: 0x0 */

  uint32_t Cordic_Zi;                 /*!< EN: Z input value.
                                           CN: Z 输入值。
                                           @Register: CORDIC_Zi @Bits:[31:0]CORDIC_Zi.
                                           @range: 0x0 - 0xFFFFFFFF 
                                           @default: 0x0 */

  FunctionalState Cordic_BypassPOST;  /*!< EN: Ignoring CORDIC post-processing.
                                           CN: 忽略 CORDIC 后处理。
                                           @Register: CORDIC_CFG @Bits:[5]BYPASS_POST.
                                           @default: DISABLE */

  FunctionalState Cordic_BypassPRE;   /*!< EN: Ignoring CORDIC preprocessing.
                                           CN: 忽略 CORDIC 预处理。
                                           @Register: CORDIC_CFG @Bits:[4]BYPASS_PRE.
                                           @default: DISABLE */
} CORDIC_InitTypeDef;

typedef struct
{
    uint32_t XO;
    uint32_t YO;
    uint32_t ZO;
} Cordic_Result_t;

/* @defgroup Cycles */
#define CORDIC_CYCLES_1            ((uint32_t)0x00000000) /*@EN: 1  iteration @CN: 1  次迭代 */
#define CORDIC_CYCLES_2            ((uint32_t)0x00010000) /*@EN: 2  iteration @CN: 2  次迭代 */
#define CORDIC_CYCLES_3            ((uint32_t)0x00020000) /*@EN: 3  iteration @CN: 3  次迭代 */
#define CORDIC_CYCLES_4            ((uint32_t)0x00030000) /*@EN: 4  iteration @CN: 4  次迭代 */
#define CORDIC_CYCLES_5            ((uint32_t)0x00040000) /*@EN: 5  iteration @CN: 5  次迭代 */
#define CORDIC_CYCLES_6            ((uint32_t)0x00050000) /*@EN: 6  iteration @CN: 6  次迭代 */
#define CORDIC_CYCLES_7            ((uint32_t)0x00060000) /*@EN: 7  iteration @CN: 7  次迭代 */
#define CORDIC_CYCLES_8            ((uint32_t)0x00070000) /*@EN: 8  iteration @CN: 8  次迭代 */
#define CORDIC_CYCLES_9            ((uint32_t)0x00080000) /*@EN: 9  iteration @CN: 9  次迭代 */
#define CORDIC_CYCLES_10           ((uint32_t)0x00090000) /*@EN: 10 iteration @CN: 10 次迭代 */
#define CORDIC_CYCLES_11           ((uint32_t)0x000A0000) /*@EN: 11 iteration @CN: 11 次迭代 */
#define CORDIC_CYCLES_12           ((uint32_t)0x000B0000) /*@EN: 12 iteration @CN: 12 次迭代 */
#define CORDIC_CYCLES_13           ((uint32_t)0x000C0000) /*@EN: 13 iteration @CN: 13 次迭代 */
#define CORDIC_CYCLES_14           ((uint32_t)0x000D0000) /*@EN: 14 iteration @CN: 14 次迭代 */
#define CORDIC_CYCLES_15           ((uint32_t)0x000E0000) /*@EN: 15 iteration @CN: 15 次迭代 */
#define CORDIC_CYCLES_16           ((uint32_t)0x000F0000) /*@EN: 16 iteration @CN: 16 次迭代 */
#define CORDIC_CYCLES_17           ((uint32_t)0x00100000) /*@EN: 17 iteration @CN: 17 次迭代 */
#define CORDIC_CYCLES_18           ((uint32_t)0x00110000) /*@EN: 18 iteration @CN: 18 次迭代 */
#define CORDIC_CYCLES_19           ((uint32_t)0x00120000) /*@EN: 19 iteration @CN: 19 次迭代 */
#define CORDIC_CYCLES_20           ((uint32_t)0x00130000) /*@EN: 20 iteration @CN: 20 次迭代 */
#define CORDIC_CYCLES_21           ((uint32_t)0x00140000) /*@EN: 21 iteration @CN: 21 次迭代 */
#define CORDIC_CYCLES_22           ((uint32_t)0x00150000) /*@EN: 22 iteration @CN: 22 次迭代 */
#define CORDIC_CYCLES_23           ((uint32_t)0x00160000) /*@EN: 23 iteration @CN: 23 次迭代 */
#define CORDIC_CYCLES_24           ((uint32_t)0x00170000) /*@EN: 24 iteration @CN: 24 次迭代 */
#define CORDIC_CYCLES_25           ((uint32_t)0x00180000) /*@EN: 25 iteration @CN: 25 次迭代 */
#define CORDIC_CYCLES_26           ((uint32_t)0x00190000) /*@EN: 26 iteration @CN: 26 次迭代 */
#define CORDIC_CYCLES_27           ((uint32_t)0x001A0000) /*@EN: 27 iteration @CN: 27 次迭代 */
#define CORDIC_CYCLES_28           ((uint32_t)0x001B0000) /*@EN: 28 iteration @CN: 28 次迭代 */
#define CORDIC_CYCLES_29           ((uint32_t)0x001C0000) /*@EN: 29 iteration @CN: 29 次迭代 */
#define CORDIC_CYCLES_30           ((uint32_t)0x001D0000) /*@EN: 30 iteration @CN: 30 次迭代 */
#define CORDIC_CYCLES_31           ((uint32_t)0x001E0000) /*@EN: 31 iteration @CN: 31 次迭代 */
#define CORDIC_CYCLES_32           ((uint32_t)0x001F0000) /*@EN: 32 iteration @CN: 32 次迭代 */
/* @end */

/* @defgroup CORDIC_FUNC */
#define CORDIC_FUNC_CIRCLE         ((uint32_t)0x00001000) /*@EN: Circle system @CN: 圆周系统 */
#define CORDIC_FUNC_HYPERBOLIC     ((uint32_t)0x00003000) /*@EN: hyperbolic system @CN: 双曲系统 */
/* @end */

/* @defgroup Mode */
#define CORDIC_MODE_ROTATE         ((uint32_t)0x00000000) /*@EN: rotate mode @CN: 旋转模式 */
#define CORDIC_MODE_VECTOR         ((uint32_t)0x00000100) /*@EN: vector mode @CN: 向量模式 */
/* @end */

/* @defgroup CORDIC_IT */
#define CORDIC_IT_OVF              ((uint32_t)0x00000020) /*@EN: Overflow interrupt @CN: 溢出中断 */
#define CORDIC_IT_DONE             ((uint32_t)0x00000010) /*@EN: End of operation interrupt @CN: 运算结束中断 */
#define IS_CORDIC_IT(IT)           ((IT == CORDIC_IT_OVF) || \
                                    (IT == CORDIC_IT_DONE))
/* @end */

/* @defgroup CORDIC_FLAG */
#define CORDIC_FLAG_OVF            ((uint32_t)0x00000002) /*@EN: Operation overflow flag @CN: 运算溢出标志位 */
#define CORDIC_FLAG_DONE           ((uint32_t)0x00000001) /*@EN: End of operation flag @CN: 运算结束标志位 */
#define IS_CORDIC_FLAG(FLAG)       ((FLAG == CORDIC_FLAG_OVF) || \
                                    (FLAG == CORDIC_FLAG_DONE))
/* @end */

/* ========================================================================== */
/* ================            CORDIC REGISTER BIT              ============= */
/* ========================================================================== */

/* =================================  CTRL  ================================= */
#define CORDIC_CTRL_START_Pos                     (8UL)                        /* START (Bits 8)                    */
#define CORDIC_CTRL_START_Msk                     (0x00000100UL)               /* START (Bitfield-Mask: 0x03)       */
#define CORDIC_CTRL_OVF_INTEN_Pos                 (5UL)                        /* OVF_INTEN (Bits 5)                */
#define CORDIC_CTRL_OVF_INTEN_Msk                 (0x00000020UL)               /* OVF_INTEN (Bitfield-Mask: 0x03)   */
#define CORDIC_CTRL_DONE_INTEN_Pos                (4UL)                        /* DONE_INTEN (Bits 4)               */
#define CORDIC_CTRL_DONE_INTEN_Msk                (0x00000010UL)               /* DONE_INTEN (Bitfield-Mask: 0x03)  */
#define CORDIC_CTRL_OVF_Pos                       (1UL)                        /* OVF (Bits 1)                      */
#define CORDIC_CTRL_OVF_Msk                       (0x00000002UL)               /* OVF (Bitfield-Mask: 0x01)         */
#define CORDIC_CTRL_DONE_Pos                      (0UL)                        /* DONE (Bits 0)                     */
#define CORDIC_CTRL_DONE_Msk                      (0x00000001UL)               /* DONE (Bitfield-Mask: 0x01)        */
/* ==================================  CFG  ================================= */
#define CORDIC_CFG_CYCLES_Pos                     (16UL)                       /* CYCLES (Bits 16)                  */
#define CORDIC_CFG_CYCLES_Msk                     (0x001F0000UL)               /* CYCLES (Bitfield-Mask: 0x01F)     */
#define CORDIC_CFG_FUN_Pos                        (12UL)                       /* FUN (Bits 12)                     */
#define CORDIC_CFG_FUN_Msk                        (0x00003000UL)               /* FUN (Bitfield-Mask: 0x03)         */
#define CORDIC_CFG_MODE_Pos                       (8UL)                        /* MODE (Bits 8)                     */
#define CORDIC_CFG_MODE_Msk                       (0x00000100UL)               /* MODE (Bitfield-Mask: 0x03)        */
#define CORDIC_CFG_BYPASS_POST_Pos                (5UL)                        /* BYPASS_POST (Bits 5)              */
#define CORDIC_CFG_BYPASS_POST_Msk                (0x00000020UL)               /* BYPASS_POST (Bitfield-Mask: 0x03) */
#define CORDIC_CFG_BYPASS_PRE_Pos                 (4UL)                        /* BYPASS_PRE (Bits 4)               */
#define CORDIC_CFG_BYPASS_PRE_Msk                 (0x00000010UL)               /* BYPASS_PRE (Bitfield-Mask: 0x03)  */
/* ==================================== XI  ================================= */
#define CORDIC_XI_Pos                             (0UL)                        /* XI (Bits 0)                       */
#define CORDIC_XI_Msk                             (0xFFFFFFFFUL)               /* XI (Bitfield-Mask: 0xFFFFFFFF)    */
/* ===================================  YI  ================================= */
#define CORDIC_YI_Pos                             (0UL)                        /* YI (Bits 0)                       */
#define CORDIC_YI_Msk                             (0xFFFFFFFFUL)               /* YI (Bitfield-Mask: 0xFFFFFFFF)    */
/* ===================================  ZI  ================================= */
#define CORDIC_ZI_Pos                             (0UL)                        /* ZI (Bits 0)                       */
#define CORDIC_ZI_Msk                             (0xFFFFFFFFUL)               /* ZI (Bitfield-Mask: 0xFFFFFFFF)    */
/* ===================================  XO  ================================= */
#define CORDIC_XO_Pos                             (0UL)                        /* XO (Bits 0)                       */
#define CORDIC_XO_Msk                             (0xFFFFFFFFUL)               /* XO (Bitfield-Mask: 0xFFFFFFFF)    */
/* ===================================  YO  ==================================*/
#define CORDIC_YO_Pos                             (0UL)                        /* YO (Bits 0)                       */
#define CORDIC_YO_Msk                             (0xFFFFFFFFUL)               /* YO (Bitfield-Mask: 0xFFFFFFFF)    */
/* ===================================  ZO  ================================= */
#define CORDIC_ZO_Pos                             (0UL)                        /* ZO (Bits 0)                       */
#define CORDIC_ZO_Msk                             (0xFFFFFFFFUL)               /* ZO (Bitfield-Mask: 0xFFFFFFFF)    */

/* ========================================================================== */
/* ================                  END                      =============== */
/* ========================================================================== */

void CORDIC_Init(CORDIC_InitTypeDef *CORDIC_InitStruct);
Cordic_Result_t CORDIC_Start(void);
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 CORDIC_Hyperbolic_System_Config(uint32_t Mode, uint32_t Cycles, uint32_t Xi, uint32_t Yi, uint32_t Zi);

void CORDIC_ITConfig(uint32_t CORDIC_IT, FunctionalState NewState);
FlagStatus CORDIC_GetFlagStatus(uint32_t CORDIC_FLAG);
void CORDIC_ClearITPendingBit(uint32_t CORDIC_FLAG);

uint32_t CORDIC_Sqrt(uint32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);

int32_t CORDIC_Sin(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);
int32_t CORDIC_Cos(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);
int32_t CORDIC_Tan(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);
void CORDIC_SinCos(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy, int32_t* pSin, int32_t* pCos);

int32_t CORDIC_Sinh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);
int32_t CORDIC_Cosh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);
int32_t CORDIC_Tanh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);
void CORDIC_SinhCosh(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy, int32_t* pSinh, int32_t* pCosh);

int32_t CORDIC_Exp(int32_t InputValue, uint8_t IQnIn, uint32_t Accuracy);
int32_t CORDIC_arcTan2(int32_t InputValueX, int32_t InputValueY, uint8_t IQnIn, uint32_t Accuracy);
uint32_t CORDIC_Mod(int32_t InputValueX, int32_t InputValueY, uint8_t IQnIn, uint32_t Accuracy);
#ifdef __cplusplus
}
#endif

#endif // __LCM32F06X_CORDIC_H__
