#include "APPDEF.h"
#include "i2c.h"
uint16_t ACCtrl(uint16_t Percent) /*0-1000*/
{
    uint8_t Out = 0;
    if (Percent < 10) {
        Out = 0;
    } else if (Percent > 990) {
        Out = 1;
    } else {
        Out = 127u - (uint8_t)((float)Percent * 0.128f);
    }
    WS100T10_Ctrl(Out);
    return Percent;
}
void ACCMD(bool cmd)
{
    if (!cmd) {
        GPIO_ResetBits(GPIOA, GPIO_Pin_15);

    } else {
        GPIO_SetBits(GPIOA, GPIO_Pin_15);
    }
}
uint16_t Percent[4];
uint16_t GetPercent[4];
uint16_t PercentOld[4];
void _task_ACCtrl(const void *p_arg)
{
    WS100T10_Init();
    for (;;) {
        if (Percent[0] != PercentOld[0]) {
            GetPercent[0] = ACCtrl(Percent[0]);
            PercentOld[0] = Percent[0];
        }
        osDelay(300);
    }
}

osThreadDef(_task_ACCtrl, osPriorityNormal, 1u, 0u);

void AC_CTRL_Init(void)
{
    osThreadCreate(osThread(_task_ACCtrl), NULL);
}

//
//
//
extern float Temperature;
float Kp, Ki, Kd;
static enum enumHeatOp_State { //	采样泵操作状态
    eShut,
    eRunning,
    eShutReq
} volatile HeatOp_State;
float HeatOutValue;
float OutputMax = 1;
static void HeatPID_Task(void)
{
    float SetValue, RunValue, OutValue = 0.0f;
    float Ek_1, Ek = 0.0f;
    float Up = 0.0f, Ui = 0.0f, Ud = 0.0f;
    float Upid        = 0.0f;
    float Initout     = 0.0f;
    float UpidSetGain = 0.800f;
    uint32_t SaveTick;
    SetValue     = Set.TempSet;
    Kp           = 0.06;
    Ki           = 0.00029;
    Kd           = 1.0;
    HeatOutValue = 0.0f;
    Percent[0]   = 0;
    osDelay(500u);
    ACCMD(true);
    //	初始化延时
    osDelay(500u);
    SaveTick               = osKernelSysTick();
    const uint32_t oneTick = osKernelSysTickMicroSec(1000u);
    uint32_t now, lostTick, delayCount;
    while (eRunning == HeatOp_State) {

        RunValue = Temperature;
        //	PID计算
        Ek_1 = Ek;
        Ek   = (SetValue - RunValue);
        if (Ek > 20.0f) {
            HeatOutValue = OutValue = OutputMax;
            Percent[0]              = OutValue * 1000;
        } else {
            Up = Kp * Ek;
            Ui += Ki * Ek;

            if (Ui < -1.0f) { Ui = -1.0f; }
            if (Ui > +1.0f) { Ui = +1.0f; }
            Ud       = (Ud * 0.667f) + (Kd * (Ek - Ek_1) * (1.0f - 0.667f));
            Upid     = (Upid * UpidSetGain) + (Up + Ui + Ud) * (1.0f - UpidSetGain);
            OutValue = Upid + Initout;

            //	PID输出
            if (OutValue < 0.0f) { OutValue = 0.0f; }
            if (OutValue > OutputMax) { OutValue = OutputMax; }
            HeatOutValue = OutValue;
            Percent[0]   = OutValue * 1000;
        }
        //	定间隔延时
        now = osKernelSysTick();
        //	计算已经逝去的tick计时单位
        lostTick = (uint32_t)(now + oneTick - 1u - SaveTick) / oneTick;
        //	计算余下需要的延时周期(设定间隔时间：300ms)
        if (lostTick < 300u) {
            delayCount = 300u - lostTick;
        } else { //	已经逝去的时间超过设定的间隔，重新计算时间起点后少量延时。
            SaveTick   = now;
            delayCount = 30u;
        }
        osDelay(delayCount);
        SaveTick += delayCount * oneTick;
    }
    //	PID 停止
    HeatOutValue = 0.0f;
    Percent[0]   = 0;
    osDelay(500u);
    ACCMD(false);
    HeatOp_State = eShut;
}

/********************************** 功能说明 ***********************************
 *	套接调用电机控制程序
 *******************************************************************************/
static void HeatTask_Socket(void const *p_arg)
{ //	调用采样控制程序，然后结束任务
    HeatPID_Task();

    osThreadTerminate(osThreadGetId());
}

osThreadDef(HeatTask_Socket, osPriorityHigh, 1, 0);

static void HeatTask_Init()
{
    osThreadCreate(osThread(HeatTask_Socket), NULL);
}
/********************************** 功能说明 ***********************************
 *  电机任务的启停控制///	开关指定的采样泵
 *******************************************************************************/
//	#include "BIOS.H"

void Pump_OutCmd(bool NewState)
{
    if (!NewState) { //	发标志，任务会检测标志自行中止。	//	osThread_SetReady;
        HeatOp_State = eShutReq;
    } else if (eRunning == HeatOp_State) { //	请求开泵，但泵并没有关?!
        ;
    } else { //	请求开泵，且已知泵是关的
        HeatOp_State = eRunning;
        HeatTask_Init();
    }
    // 	if( HeatOp_State == eRunning)
    // 		lightopen();
    // 	else
    // 		lightclose();
}

///	读取指定的采样泵的调速输出[0.0 ~ 1.0]
float Pump_GetOutput(void)
{
    {
        if (eShutReq == HeatOp_State) {
            return 0.0f;
        } else {
            return HeatOutValue;
        }
    }
}
