
/*

当前速度current_speed取值范围为0至800， 目标速度target_speed为0、400、500、600、700、800这几种数值。这个函数的作用是下设速度（算出预定速度result_speed后，下设这个预定速度给speed_set_val）。外部的电机会根据speed_set_val来让current_speed达到speed_set_val的速度，但也有可能会因为自身过流等故障，current_speed会掉下去。有以下要求：
1. result_speed的初值设为此时的current_speed，然后每秒根据加速度acc_val的值往上加。如果加速度为acc_val，预定速度为result_speed，那么1秒后，预定速度为 result_speed = result_speed+acc_val，再过一秒后result_speed继续加acc_val，若result_speed超过了target_speed，则result_speed改为目标速度，然后result_speed一直保持在target_speed；
2. 若target_speed突然变小，如果current_speed大于新的target_speed，则需要获取当前速度，result_speed一直保持在当前速度不改变；否则若当前速度小于等于新的目标速度，那不用管，result_speed继续根据加速度a来加；
3. 若target_speed突然变大，则result_speed继续根据加速度acc_val来增加，直到到达target_speed。
4. 无论什么情况，如果target_speed为0，那么result_speed就要变成0.
5. 外部可以留个接口，初始化这个状态机。
6. 除非停机，否则result_speed不要下降，只能不变或者上升。
*/

typedef enum
{
    LOGIC_INIT = 0x5AA5,
    LOGIC_RUN = 0x1111
    // LOGIC_CLOSE = 0x2222
}LOGIC_STATE_ENUM_T;

/* 脱水速度设置 枚举变量 */
typedef enum
{
    DEHY_SPEEDSET_INIT,         // 初始化
    DEHY_SPEEDSET_SPEED_UP,     // 加速
    DEHY_SPEEDSET_SPEED_KEEP,   // 稳速
    DEHY_SPEEDSET_SPEED_STOP,   // 超震停机  

    DEHY_SPEEDSET_NUM
}SPEEDUP_ENUM_T;

/* 外部调用 速度设置值 */
static uint16_t speed_set_val = 0u;

/*************************************************************************************
 * @brief    下设速度
 * @param[in/out] val  
 * 
 * @warning  
 * @note     
  *************************************************************************************/
void motor_speed_set(uint16_t val)
{
    speed_set_val = val;
}


/*************************************************************************************
 * @brief    提速逻辑
 * @param[in/out] init_cmd
 * @param[in/out] acc_val
 * @param[in/out] current_speed
 * @param[in/out] target_speed
 * 
 * @warning  
 * @note     
  *************************************************************************************/
void dehy_speed_up(LOGIC_STATE_ENUM_T init_cmd, uint16_t acc_val, uint16_t current_speed, uint16_t target_speed)
{

    static uint32_t timetick = 0;   // 时间戳
    static SPEEDUP_ENUM_T add_speed_state = DEHY_SPEEDSET_INIT;    // 本函数的状态机
    static uint16_t result_speed = 0;   // 预设速度
    static uint16_t target_speed_cache = 0; // 缓存目标速度
    // static uint16_t current_speed_cache = 0; // 缓存当前速度
    if(init_cmd == LOGIC_INIT)
    {
        add_speed_state = DEHY_SPEEDSET_INIT;
    }
    else
    {
        ;
    }

    switch(add_speed_state)
    {
        // init
        case DEHY_SPEEDSET_INIT:
            // 时间戳 初始化
            timetick = get_systick_ms();
            // 预设速度 初始化
            result_speed = current_speed;
            // 目标速度缓存 初始化
            target_speed_cache = target_speed;
            // 进入下一阶段
            add_speed_state = DEHY_SPEEDSET_SPEED_UP;
            break;
        // 加速
        case DEHY_SPEEDSET_SPEED_UP:
            // 当前 触发超震
            if(target_speed == 0)
            {
                add_speed_state = DEHY_SPEEDSET_SPEED_STOP;
                result_speed = 0;
            }
            // 周期到
            else if(get_systick_ms() - timetick > 1000u)
            {

                timetick = get_systick_ms();

                // 若当前速度 小于 现在的目标速度 则没事 更新一下目标速度缓存 当前就不加速了
                // 当前速度 不小于 新的目标速度 则稳住当前速度 进入稳态
                if((target_speed < target_speed_cache) && (current_speed >= target_speed))
                {
                    // 记录当前速度
                    result_speed = current_speed;
                    // 切到速度保持
                    add_speed_state = DEHY_SPEEDSET_SPEED_KEEP;
                }
                else
                {
                    // 更新 预设速度
                    result_speed += acc_val;
                    // 进下一阶段判断
                    if(result_speed >= target_speed)
                    {
                        result_speed = target_speed;
                        add_speed_state = DEHY_SPEEDSET_SPEED_KEEP;
                    }

                }
                // 刷新 目标速度缓存
                target_speed_cache = target_speed;
            }
            break;
        // 速度保持
        case DEHY_SPEEDSET_SPEED_KEEP:
            // 超震停机
            if(target_speed == 0)
            {
                result_speed = 0;
                add_speed_state = DEHY_SPEEDSET_SPEED_STOP;
            }
            // 目标速度变好了 外面超震小了
            else if(target_speed > target_speed_cache)
            {
                // 若预定速度 小于 新的目标速度，则回去加速
                if(result_speed < target_speed)
                {
                    // 回加速
                    add_speed_state = DEHY_SPEEDSET_SPEED_UP;
                }
                
                target_speed_cache = target_speed;
            }
            break;
        // 超震停机
        case DEHY_SPEEDSET_SPEED_STOP:
            result_speed = 0;
            break;
        default:
            break;
    }
    /* 设置速度 */
    motor_speed_set(result_speed);
}
