/**
 * @file     FU6522_72_MDU.h
 * @version  V1.0.0
 * @author   FortiorTech Hardware Team
 * @date     2021-07-15 20:52:58
 * @brief    This file contains ...
 * 
 * @copyright Copyright(C) 2022, Fortior Technology Co., Ltd. All rights reserved.
 */

#ifndef __FU6522_72_MDU_H__
#define __FU6522_72_MDU_H__

// Include external header file.
#include <FU6522_72_MCU.h>

#ifdef __cplusplus
extern "C" {
#endif
	
/**
 * @brief SMDU的模式类型
 *
 * @note 使用@ref SMDU_RunNoBlock时, 其中的mode参数可以直接使用本枚举的内容
 * @note 使用@ref SMDU_RunBlock时, 其中的mode参数可以直接使用本枚举的内容
 */
typedef enum
{
    S1MUL   = 0, /**< 有符号乘法, 计算结果左移1位 */
    SMUL    = 1, /**< 有符号乘法 */
    UMUL    = 2, /**< 无符号乘法 */
    DIV     = 3, /**< 32/16无符号除法 */
    SIN_COS = 4, /**< Sin/Cos */
    ATAN    = 5, /**< ATan */
    LPF     = 6, /**< 低通滤波 */
    PI      = 7  /**< PI */
} ETypeSMDUMode;


/**
 * @brief 运行SMDU且不等待运行结束
 *
 * @param  stan (0-3) 要启动的计算单元编号
 * @param  mode (0-7) 指定计算单元的模式, 可使用@see ETypeSMDUMode 作为计算模式的设置\n
 * @ref S1MUL   有符号乘法, 计算结果左移1位 \n
 * @ref SMUL    有符号乘法 \n
 * @ref UMUL    无符号乘法 \n
 * @ref DIV     32/16无符号除法 \n
 * @ref SIN_COS Sin/Cos \n
 * @ref ATAN    ATan \n
 * @ref LPF     低通 \n
 * @ref PI      PI \n
 */
#define SMDU_RunNoBlock(stan, mode)   do                                                  \
                                      {                                                   \
                                          MDU_CR = MDUSTA0 << stan | (unsigned char)mode; \
                                      } while (0)

/**
 * @brief 运行SMDU且等待运行结束
 *
 * @param  stan (0-3) 要启动的计算单元编号
 * @param  mode (0-7) 指定计算单元的模式, 可使用@see ETypeSMDUMode 作为计算模式的设置\n
 * @ref S1MUL   有符号乘法, 计算结果左移1位 \n
 * @ref SMUL    有符号乘法 \n
 * @ref UMUL    无符号乘法 \n
 * @ref DIV     32/16无符号除法 \n
 * @ref SIN_COS Sin/Cos \n
 * @ref ATAN    ATan \n
 * @ref LPF     低通 \n
 * @ref PI      PI \n
 */
#define SMDU_RunBlock(stan, mode)   do                                       \
                                    {                                        \
                                        SMDU_RunNoBlock(stan, mode);         \
                                        while ((MDU_CR & MDUBSY) == MDUBSY); \
                                    } while (0);

// SMDU部分函数声明
void HW_Zero_PI_Init(void);
void HW_One_PI_Init(void);
void HW_Two_PI_Init(void);
void HW_Three_PI_Init(void);

int16_t HW_Zero_Calc(int16_t Xn0);
int16_t HW_One_Calc(int16_t Xn0);
int16_t HW_Two_Calc(int16_t Xn0);
int16_t HW_Three_Calc(int16_t Xn0);

int16_t LPF_Zero_Update(int16_t Xn1, int16_t Xn0, int16_t K);
int16_t LPF_One_Update(int16_t Xn1, int16_t Xn0, int16_t K);
int16_t LPF_Two_Update(int16_t Xn1, int16_t Xn0, int16_t K);
int16_t LPF_Three_Update(int16_t Xn1, int16_t Xn0, int16_t K);

int16 Atan_Us_MDU(int16 Xn1, int16 Xn0);
int16 DivQ_L_MDU(uint16 Xn1, uint16 Xn0,uint16 Yn);
int16 MULU_H_MDU(uint16 Xn0, uint16 Xn1);
uint16 Sqrt_alpbet(int16 i_alp, int16 i_bet);
int16 DivQ_L_MDU2(uint16 Xn1, uint16 Xn0, uint16 Yn);
void MULS_H_MDU(int16 Xn0, int16 Xn1,uint16 xdata *lusResult32);

#ifdef __cplusplus
}
#endif

#endif