
#include "storage.h"
#include "flash.h"
#include <stdlib.h>
#include "TaskLoop.h"


Loop_Balance_PlanB  g_loop_balance_planB;
Loop_Cng_Info       g_loop_cng_info = {0, {0}};
Loop_Sens_List      g_loop_sens_list;


uint8_t loop_cng_default[8] = {2,1,0,0,4,0,0,0};
uint8_t loops_cng_default[LOOP_CAPTURE_MAX][8] = {
    {2, 1, 0, 0, Freq_Low, 0, 0, 0 },
    {2, 1, 0, 0, Freq_Middle_High, 0, 0, 0},
    {2, 1, 0, 0, Freq_Middle_Low, 0, 0, 0 },
    {2, 1, 0, 0, Freq_Low, 0, 0, 0 }
};


void set_factory_param(void)
{
    uint8_t i;

    g_loop_cng_info.smart_mode = Smart_Mode_Disable;
    Loop_Cng_Unit *unit = g_loop_cng_info.loop_cng;
    for(i = 0; i < LOOP_CAPTURE_MAX; i++)
    {
        memcpy(unit, loops_cng_default[i], 8);
        unit++;
    }
    

    g_loop_sens_list.total = SENS_Default_Amount;
    for(i = 0; i < g_loop_sens_list.total && i < 4; i++)
    {
        g_loop_sens_list.sens[i].sens_in = SensTable[i];
        g_loop_sens_list.sens[i].sens_out = SensTable_1[i];
    }
    
}


void storage_dev(void)
{
    uint8_t i = 0, k = 0;

    uint8_t *rBuf = (uint8_t *)malloc(MAX_Store_Size);
    if(rBuf == NULL){
//        PRINT("Not enough memory!!");
        nvic_system_reset();
    }
    for(i = 0; i < MAX_Store_Size; i++){
        rBuf[i] = 0;
    }
    
    PRINT("Will_storage_dev\r\n");

    rBuf[0] = 0x33;
    rBuf[1] = 0xBB;
    rBuf[2] = 0xC3;
    rBuf[3] = 0x3C;

//    g_freq_sens = 1;
    rBuf[Addr_Sens_Amount_Offset] = g_loop_sens_list.total;
    rBuf[Addr_Smart_Mode_Offset] = g_loop_cng_info.smart_mode;
    i = Addr_Loop_Cng_Offset;
    memcpy(&rBuf[i], (uint8_t *)g_loop_cng_info.loop_cng, sizeof(Loop_Cng_Unit) * LOOP_CAPTURE_MAX );
    i += sizeof(Loop_Cng_Unit) * LOOP_CAPTURE_MAX;

//    i = Addr_Loop_PlanB_Cng_Offset;
//    rBuf[i++] = g_loop_balance_planB.sample_cng.flag;
//    rBuf[i++] = g_loop_balance_planB.sample_cng.max_amplitude;
//    rBuf[i++] = g_loop_balance_planB.sample_cng.max_amplitude >> 8;
//    rBuf[i++] = g_loop_balance_planB.balance_ori_cng.flag;
//    rBuf[i++] = g_loop_balance_planB.balance_ori_cng.max_cnt;
//    rBuf[i++] = g_loop_balance_planB.balance_ori_cng.max_cnt >> 8;
//    rBuf[i++] = g_loop_balance_planB.release_ori_planB.flag_weight;
//    rBuf[i++] = g_loop_balance_planB.release_ori_planB.max_amplitude;
//    rBuf[i++] = g_loop_balance_planB.release_ori_planB.max_amplitude >> 8;
//    rBuf[i++] = g_loop_balance_planB.release_ori_planB.timeout;
//
//    rBuf[i++] = g_loop_balance_planB.release_change_rate.flag_weight;
//    rBuf[i++] = g_loop_balance_planB.release_change_rate.rate_first;
//    rBuf[i++] = g_loop_balance_planB.release_change_rate.rate_second;
//    rBuf[i++] = g_loop_balance_planB.release_change_rate.mode;

    i = Addr_Loop_Sens_List_Offset;
    if(g_loop_sens_list.total > MAX_LOOP_SENS_AMOUNT)
    {
        g_loop_sens_list.total = MAX_LOOP_SENS_AMOUNT;
    }
    
    for(k = 0; k < MAX_LOOP_SENS_AMOUNT; k++)
    {
        rBuf[i++] = g_loop_sens_list.sens[k].sens_in;
        rBuf[i++] = g_loop_sens_list.sens[k].sens_in >> 8;
        rBuf[i++] = g_loop_sens_list.sens[k].sens_out;
        rBuf[i++] = g_loop_sens_list.sens[k].sens_out >> 8;
    }
    
//    PRINT("Will_write: \n");
//    for(i = 0; i < MAX_Store_Size; i++)
//    {
//        PRINT(" %02X", rBuf[i]);
//    }

    flash_write(Addr_Dev_Flag_Offset, (uint16_t *)rBuf, DLD_BUFEER_SIZE/2);

    free(rBuf);
    

}

// set frequent level
void set_flp_level(uint8_t loop_num, uint8_t freq_level)
{
    switch( freq_level)
    {
        case Freq_High: // 33nF
        {
            if(loop_num == 0)     { FLPA1_HIGH; FLPA2_HIGH; }
            else if(loop_num == 1){ FLPB1_HIGH; FLPB2_HIGH; }
            else if(loop_num == 2){ FLPC1_HIGH; FLPC2_HIGH; }
            else if(loop_num == 3){ FLPD1_HIGH; FLPD2_HIGH; }
        } break;
        case Freq_Middle_High: // 43nF
        {
            if(loop_num == 0)     { FLPA1_HIGH; FLPA2_LOW; }
            else if(loop_num == 1){ FLPB1_HIGH; FLPB2_LOW; }
            else if(loop_num == 2){ FLPC1_HIGH; FLPC2_LOW; }
            else if(loop_num == 3){ FLPD1_HIGH; FLPD2_LOW; }
        } break;
        case Freq_Middle_Low: // 66nF
        {
            if(loop_num == 0)     { FLPA1_LOW; FLPA2_HIGH; }
            else if(loop_num == 1){ FLPB1_LOW; FLPB2_HIGH; }
            else if(loop_num == 2){ FLPC1_LOW; FLPC2_HIGH; }
            else if(loop_num == 3){ FLPD1_LOW; FLPD2_HIGH; }
        } break;
        case Freq_Low: //76nF
        {
            if(loop_num == 0)     { FLPA1_LOW; FLPA2_LOW; }
            else if(loop_num == 1){ FLPB1_LOW; FLPB2_LOW; }
            else if(loop_num == 2){ FLPC1_LOW; FLPC2_LOW; }
            else if(loop_num == 3){ FLPD1_LOW; FLPD2_LOW; }
        } break;
    }
}


void para_store_init(void)
{
    uint8_t i;
    uint8_t *rBuf = (uint8_t *)malloc(MAX_Store_Size);

    if(rBuf == NULL){
//        PRINT("Not enough memory!!");
        nvic_system_reset();
    }
    memset(rBuf, 0, MAX_Store_Size);

    flash_read(DLD_FLASH_ADDRESS_START, (uint16_t *)rBuf, MAX_Store_Size/2);
    PRINT("Read_Cng_Store:\n");
    for(i = 0; i < MAX_Store_Size; i++){
        PRINT("%02X ", rBuf[i]);
    }
    PRINT("\n");

    if(rBuf[0] == 0x33 && rBuf[1] == 0xBB && rBuf[2] == 0xC3 && rBuf[3] == 0x3C){
        g_loop_sens_list.total = rBuf[Addr_Sens_Amount_Offset];
        g_loop_cng_info.smart_mode = rBuf[Addr_Smart_Mode_Offset];
        memcpy(g_loop_cng_info.loop_cng, &rBuf[Addr_Loop_Cng_Offset], sizeof(Loop_Cng_Unit) * LOOP_CAPTURE_MAX);
        memcpy(&g_loop_sens_list.sens, &rBuf[Addr_Loop_Sens_List_Offset], sizeof(g_loop_sens_list) - 1);

        Loop_Cng_Unit *unitout = g_loop_cng_info.loop_cng;
        for(i = 0; i < LOOP_CAPTURE_MAX; i++)
        {
            PRINT("loop_%d, sens:%d,delay:%d, exit_mode:%d, out_put:%d\n", i, unitout->sensitvity, unitout->delay_time, unitout->exist_mode, unitout->output_mode);
            set_flp_level(i, unitout->loopFreq_Level);
            
            // 同步灵敏度到检测单元
            g_loop_states.loop_unit[i].loop_SensLevel = unitout->sensitvity & 0x03;
            g_loop_states.loop_unit[i].SET_PLUS = unitout->output_mode & 0x01;
            g_loop_states.loop_unit[i].SET_DLY  = (unitout->output_mode >> 1) & 0x01;
            g_loop_states.loop_unit[i].hold_time = unitout->exist_mode * 20 * 5;
            g_loop_states.loop_unit[i].relay_delay = unitout->delay_time * 2;
            
            unitout++;
        }
        
//        g_loop_out_delay = g_loop_cng_unit.delay_time * 2;                  // 定时器以 50ms 为单位， 延时以100ms为单位

//        g_hold_time = g_loop_cng_unit.exist_mode * 30 * 20;  //50ms/per,  30s

        
//        g_safe_max_cnt = g_loop_cng_unit.loopSafe_Timeout * 10 * (1000 / 50);
//        g_freq_level = g_loop_cng_unit.loopFreq_Level - 1;

//        flt_mgr.max_cnt_flat_release = g_loop_cng_unit.delay_time * 20 /2;
//        if(flt_mgr.max_cnt_flat_release < 40){  // 至少检查400毫秒
//            flt_mgr.max_cnt_flat_release = 40;
//        }
        
        
        free(rBuf);
    }
    else{
        free(rBuf);
        //TODO: need to be normal
        set_factory_param();
        
        storage_dev();
//        
        delay_ms(10);
        nvic_system_reset();
    }

}




void test_factory(void)
{
    set_factory_param();
    
    storage_dev();
    
//    delay_ms(10);

}


