#include "lks32mc09x_clu.h"
#include "lks32mc09x_sys.h"

/**
 * @brief CLU计算初始化
 */

void CLU_Init(CLU_TypeDef *CLUx, uint8_t CLU_MODEL_CLUx, CLU_InitTypeDef *CLU_InitStruct)
{
    CLU_Enable(CLUx);
    if ((CLU_MODEL_CLUx & CLU_MODEL_CLU0) != 0)
    {
        REG_WRITE_BIT(CLUx->EN, BIT0, CLU_InitStruct->EN ? BIT0 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT0, CLU_InitStruct->FIE ? BIT0 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT1, CLU_InitStruct->RIE ? BIT1 : 0);
        REG_WRITE_BIT(CLUx->MX, 0x000f, (CLU_InitStruct->MXA << 4) | (CLU_InitStruct->MXB));
        REG_WRITE_BIT(CLUx->FN, 0x000f, CLU_InitStruct->FN);
        REG_WRITE_BIT(CLUx->CF, 0x000f, (CLU_InitStruct->OUTSEL << 7) | (CLU_InitStruct->OEN << 6) | (CLU_InitStruct->CLKINV << 2) | (CLU_InitStruct->CLKSEL));
        REG_SET(CLUx->CF, BIT3);
    }
    if ((CLU_MODEL_CLUx & CLU_MODEL_CLU1) != 0)
    {
        REG_WRITE_BIT(CLUx->EN, BIT1, CLU_InitStruct->EN ? BIT1 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT2, CLU_InitStruct->FIE ? BIT2 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT3, CLU_InitStruct->RIE ? BIT3 : 0);
        REG_WRITE_BIT(CLUx->MX, 0x00f0, (CLU_InitStruct->MXA << 12) | (CLU_InitStruct->MXB << 8));
        REG_WRITE_BIT(CLUx->FN, 0x00f0, CLU_InitStruct->FN << 8);
        REG_WRITE_BIT(CLUx->CF, 0x00f0, (CLU_InitStruct->OUTSEL << 15) | (CLU_InitStruct->OEN << 14) | (CLU_InitStruct->CLKINV << 10) | (CLU_InitStruct->CLKSEL << 8));
        REG_SET(CLUx->CF, BIT11);
    }
    if ((CLU_MODEL_CLUx & CLU_MODEL_CLU2) != 0)
    {
        REG_WRITE_BIT(CLUx->EN, BIT2, CLU_InitStruct->EN ? BIT2 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT4, CLU_InitStruct->FIE ? BIT4 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT5, CLU_InitStruct->RIE ? BIT5 : 0);
        REG_WRITE_BIT(CLUx->MX, 0x0f00, (CLU_InitStruct->MXA << 20) | (CLU_InitStruct->MXB << 16));
        REG_WRITE_BIT(CLUx->FN, 0x0f00, CLU_InitStruct->FN << 16);
        REG_WRITE_BIT(CLUx->CF, 0x0f00, (CLU_InitStruct->OUTSEL << 23) | (CLU_InitStruct->OEN << 22) | (CLU_InitStruct->CLKINV << 18) | (CLU_InitStruct->CLKSEL << 16));
        REG_SET(CLUx->CF, BIT19);
    }
    if ((CLU_MODEL_CLUx & CLU_MODEL_CLU3) != 0)
    {
        REG_WRITE_BIT(CLUx->EN, BIT3, CLU_InitStruct->EN ? BIT3 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT6, CLU_InitStruct->FIE ? BIT6 : 0);
        REG_WRITE_BIT(CLUx->IE, BIT7, CLU_InitStruct->RIE ? BIT7 : 0);
        REG_WRITE_BIT(CLUx->MX, 0xf000, (CLU_InitStruct->MXA << 28) | (CLU_InitStruct->MXB << 24));
        REG_WRITE_BIT(CLUx->FN, 0xf000, CLU_InitStruct->FN << 24);
        REG_WRITE_BIT(CLUx->CF, 0xf000, (CLU_InitStruct->OUTSEL << 31) | (CLU_InitStruct->OEN << 30) | (CLU_InitStruct->CLKINV << 26) | (CLU_InitStruct->CLKSEL << 24));
        REG_SET(CLUx->CF, BIT27);
    }
}

/**
 * @brief CLU初始化结构体初始化
 */
void CLU_StructInit(CLU_InitTypeDef *CLU_InitStruct)
{
    CLU_InitStruct->FIE    = 0; ///< 下降沿中断使能
    CLU_InitStruct->RIE    = 0; ///< 上升沿中断使能
    CLU_InitStruct->EN     = 0; ///< 模块使能 0关闭模块 1打开模块
    CLU_InitStruct->MXA    = 0; ///< A输入复用选择 格式 CLU_MXA_CLUa_b a取值范围为[0 1 2 3] 对应不同的CLU b表示选择不同的输入信号
    CLU_InitStruct->MXB    = 0; ///< B输入复用选择 格式 CLU_MXB_CLUa_b a取值范围为[0 1 2 3] 对应不同的CLU b表示选择不同的输入信号
    CLU_InitStruct->FN     = 0; ///< 真值表 格式 CLU_FN_x x取值范围为[A NOTA A_NOTB ...]对应为最简与或式下的最小相 例如 y=a+bc+!c 表示为 CLU_FN_A|CLU_FN_B_C|CLU_FN_NOTC
    CLU_InitStruct->OUTSEL = 0; ///< 输出选择 0: D 触发器输出 1: LUT 输出
    CLU_InitStruct->OEN    = 0; ///< 输出使能 0: 关闭 1: 使能
    CLU_InitStruct->CLKINV = 0; ///< D 触发器时钟电平 0: 同相 1: 反向
    CLU_InitStruct->CLKSEL = 0; ///< D 触发器时钟选择 0x0: 进位输入 0x1: MXA 输入 0x2: ALTCLK0 0x3: ALTCLK1
}

/**
 * @brief CLU模块时钟使能
 */
void CLU_Enable(CLU_TypeDef *CLUx)
{
    SYS_ModuleClockCmd(SYS_MODULE_CL0, ENABLE);
}

/**
 * @brief CLU模块时钟关闭
 */
void CLU_Disable(CLU_TypeDef *CLUx)
{
    SYS_ModuleClockCmd(SYS_MODULE_CL0, DISABLE);
}

/**
 * @brief 获取CLU的输出值
 */
uint8_t CLU_ReadOutVolue(CLU_TypeDef *CLUx, uint8_t CLU_MODEL_CLUx)
{
    return (REG_READ_BIT(CLUx->OUT, CLU_MODEL_CLUx) != 0) ? 1 : 0;
}
