#include "app_math_info.h"

uint8_t frame_state =0;//电阻阵列指令帧状态
uint8_t cali_frame_state =0;//单个电阻校准指令帧状态

// 全局变量：电阻初始化模式（默认状态模式）
ARRAY_RESI_INIT_MODE_TYPE_T resi_init_mode = STATE;

// 全局变量：电阻校准模式（默认初始状态）
ARRAY_RESI_CALI_MODE_TYPE_T resi_cali_mode = CALI_INIT;

uint8_t  array_resi_init_params_read_buf[MAX_BUF_SIZE] = {0};
uint8_t  array_resi_init_params_write_buf[MAX_BUF_SIZE] = {0};



// 校准参数缓冲区（3个点×X轴×Y轴）
uint8_t  cali_adc_params[CALI_POINT_NUM * AX_NUM * AY_NUM] = {0};

// 全局缓冲区：校准参数读写缓冲区
uint8_t  array_resi_cali_params_write_buf[MAX_BUF_SIZE] = {0};
uint8_t  array_resi_cali_params_read_buf[MAX_BUF_SIZE] = {0};

uint8_t success_protocal[ARRAY_RESI_INIT_PARAMS_LEN] = {0x6F,0x6F,0x6F,0x6B,0x6B,0x6B};
uint8_t fail_protocal[ARRAY_RESI_INIT_PARAMS_LEN] = {0x6E,0x6E,0x6E,0x6F,0x6F,0x6F};
//static uint8_t static_protocal[ARRAY_RESI_INIT_PARAMS_LEN] = {0};
//extern uint8_t adc_read_sw;
/**
 * 设置电阻阵列初始化模式
 * @param state：模式（STATE/DATA）
 */
void set_array_resi_init_mode_type(ARRAY_RESI_INIT_MODE_TYPE_T state)
{
	resi_init_mode = state;
}

/**
 * 获取电阻阵列初始化模式
 * @return 当前模式
 */
ARRAY_RESI_INIT_MODE_TYPE_T get_resi_array_init_mode_type(void)
{
	return resi_init_mode;
}


//////////////////////////////////////////////////////////////////////////

/**
 * 设置电阻阵列校准模式
 * @param state：模式（CALI_SUCCESS/CALI_FAIL等）
 */
void set_array_resi_cali_mode_type(ARRAY_RESI_CALI_MODE_TYPE_T state)
{
	resi_cali_mode = state;
}

/**
 * 获取电阻阵列校准模式
 * @return 当前模式
 */
ARRAY_RESI_CALI_MODE_TYPE_T get_resi_array_cali_mode_type(void)
{
	return resi_cali_mode;
}



uint8_t array_resi_params_write(mx_frame_struct *buf)
{
    mx_frame_struct frame;
		
    // 1. 解析协议数据
     uint16_t min_resi = (buf->data[1] << 8) | buf->data[0];
		 uint16_t max_resi = (buf->data[3] << 8) | buf->data[2];
	   uint16_t ref_resi = (buf->data[5] << 8) | buf->data[4];
		   
    //printf("min_resi is %d, %d  %d\n",min_resi,max_resi,ref_resi);
    // 2. 参数有效性检查
    if(min_resi >= max_resi) {
        frame.trantype = 0x04;
        set_array_resi_init_mode_type(STATE);
        frame.type = get_resi_array_init_mode_type();
        frame.data = fail_protocal;
        frame.datalen = ARRAY_RESI_INIT_PARAMS_LEN;
        mx_serial_tx_frame(USART_3_TR, &frame);
        return 0;  // 参数无效
    }
    
    // 3. ? 更新到全局配置（不保存）
    g_sys_config.min_trigger_res_value = min_resi;
    g_sys_config.max_trigger_res_value = max_resi;
    g_sys_config.div_trigger_res = ref_resi;
    
    // 4. 应用到数学库
//    math_resi_init(max_resi, min_resi, ref_resi, MAX_ADC_VALUE, DEFAULT_MAX_DISPLAY_VALUE);
//    min_trigger_res_value1
    math_resi_init(g_sys_config.max_trigger_res_value, g_sys_config.min_trigger_res_value, g_sys_config.div_trigger_res, 4096, 255);
    
	// 5. 发送成功应答
    frame.trantype = 0x04;
    set_array_resi_init_mode_type(DATA);
    frame.type = get_resi_array_init_mode_type();
    frame.data = success_protocal;
    frame.datalen = ARRAY_RESI_INIT_PARAMS_LEN;
    mx_serial_tx_frame(USART_3_TR, &frame);
    
    return 1;  // 成功
}

/**
 * 保存电阻参数到Flash
 * @brief 解析协议数据并持久化保存
 */
uint8_t array_resi_params_save(void *buf)
{
    mx_frame_struct *frame = (mx_frame_struct *)buf;
    // 1. 解析协议数据
    static uint16_t min_resi=0;
		static uint16_t max_resi=0;
	  static uint16_t ref_resi=0;
		min_resi = (frame->data[1] << 8) | frame->data[0];
    max_resi = (frame->data[3] << 8) | frame->data[2];
    ref_resi = (frame->data[5] << 8) | frame->data[4];
    //printf("%d, %d  %d\n",min_resi,max_resi,ref_resi);
    // 2. 参数有效性检查
    if(min_resi > max_resi) {
        frame->trantype = 0x04;
        set_array_resi_init_mode_type(STATE);
        frame->type = get_resi_array_init_mode_type();
        frame->data = fail_protocal;
        frame->datalen = ARRAY_RESI_INIT_PARAMS_LEN;
        mx_serial_tx_frame(USART_3_TR, frame);

    }
    
    // 3. ? 更新到全局配置
    g_sys_config.min_trigger_res_value = min_resi;
    g_sys_config.max_trigger_res_value = max_resi;
    g_sys_config.div_trigger_res = ref_resi;
    
    // 4. 保存到Flash（使用统一接口）
    if(save_sys_config(&g_sys_config) != 0) {
        frame->trantype = 0x04;
        set_array_resi_init_mode_type(STATE);
        frame->type = get_resi_array_init_mode_type();
        frame->data = fail_protocal;
        frame->datalen = ARRAY_RESI_INIT_PARAMS_LEN;
        mx_serial_tx_frame(USART_3_TR, frame);
    }
    
    delay_ms(5);  // 等待Flash写入完成
    
    // 5.验证：重新加载配置
    
    if(load_config_params(&g_flash_para) == 1) {
        // 验证成功：应用新参数
//        math_resi_init(max_resi, min_resi, ref_resi, MAX_ADC_VALUE, DEFAULT_MAX_DISPLAY_VALUE);
        math_resi_init(g_sys_config.max_trigger_res_value, g_sys_config.min_trigger_res_value, g_sys_config.div_trigger_res, 4096, 255);
    
        frame->trantype = 0x04;
        set_array_resi_init_mode_type(STATE);
        frame->type = get_resi_array_init_mode_type();
        frame->data = success_protocal;
        frame->datalen = ARRAY_RESI_INIT_PARAMS_LEN;
        mx_serial_tx_frame(USART_3_TR, frame);
        return 1;
    }
    else {
        frame->trantype = 0x04;
        set_array_resi_init_mode_type(STATE);
        frame->type = get_resi_array_init_mode_type();
        frame->data = fail_protocal;
        frame->datalen = ARRAY_RESI_INIT_PARAMS_LEN;
        mx_serial_tx_frame(USART_3_TR, frame);
        return 0;
    }
}

/**
 * 清除电阻参数（恢复默认值）
 * @brief 擦除Flash并恢复默认配置
 */
uint8_t clear_array_init_info(void *buf)
{
    mx_frame_struct *frame = (mx_frame_struct *)buf;
    
    // 1. ? 准备默认参数（从 default_config 获取）
    uint8_t temp_data[6];
    temp_data[0] = default_config.min_trigger_res_value & 0xFF;
    temp_data[1] = (default_config.min_trigger_res_value >> 8) & 0xFF;
    temp_data[2] = default_config.max_trigger_res_value & 0xFF;
    temp_data[3] = (default_config.max_trigger_res_value >> 8) & 0xFF;
    temp_data[4] = default_config.div_trigger_res & 0xFF;
    temp_data[5] = (default_config.div_trigger_res >> 8) & 0xFF;
    
    // 2. 临时设置 frame->data 用于调用 array_resi_params_write
    frame->data = temp_data;
    array_resi_params_write(frame);  // 应用默认参数
    
    // 3. ? 擦除Flash配置（使用底层接口）
    flash_erase(FMC_WRITE_START_ADDR);
    
    // 4. 验证擦除
    uint16_t verify_buf[3];
    flash_read(FMC_WRITE_START_ADDR, verify_buf, 3);
    
    frame->trantype = 0x04;
    set_array_resi_init_mode_type(STATE);
    frame->type = get_resi_array_init_mode_type();
    
    if(verify_buf[0] == 0xFFFF && verify_buf[1] == 0xFFFF && verify_buf[2] == 0xFFFF) {
        frame->data = success_protocal;
        frame->datalen = ARRAY_RESI_INIT_PARAMS_LEN;
        mx_serial_tx_frame(USART_3_TR, frame);
        return 1;  // 擦除成功
    }
    else {
				frame->data = fail_protocal;
        frame->datalen = ARRAY_RESI_INIT_PARAMS_LEN;
        mx_serial_tx_frame(USART_3_TR, frame);
        return 0;  // 擦除失败
    }
}

/**
 * 返回当前电阻参数
 * @brief 读取并发送当前配置
 */
uint8_t return_array_resi_init_info(void *buf)
{
    mx_frame_struct *frame = (mx_frame_struct *)buf;
    
    // 1. ? 准备返回数据（从 g_sys_config 读取）
    static uint8_t response_data[6];
    response_data[0] = g_sys_config.min_trigger_res_value & 0xFF;
    response_data[1] = (g_sys_config.min_trigger_res_value >> 8) & 0xFF;
    response_data[2] = g_sys_config.max_trigger_res_value & 0xFF;
    response_data[3] = (g_sys_config.max_trigger_res_value >> 8) & 0xFF;
    response_data[4] = g_sys_config.div_trigger_res & 0xFF;
    response_data[5] = (g_sys_config.div_trigger_res >> 8) & 0xFF;
    
    // 2. 发送数据
    set_array_resi_init_mode_type(DATA);
    frame->trantype = 0x04;
    frame->type = get_resi_array_init_mode_type();
    frame->data = response_data;
    frame->datalen = ARRAY_RESI_INIT_PARAMS_LEN;
    mx_serial_tx_frame(USART_3_TR,frame);
   
    return 1;
}





//	0x03  // 单个电阻校准传输类型
/**
 * @brief 写入校准参数（临时应用，不保存到Flash）
 * @param buf 协议帧指针
 */
void math_resi_array_cali_write(void *buf)
{
    mx_frame_struct *frame = (mx_frame_struct *)buf;
    uint8_t empty_data = 0;
    
    // 1. ? 直接复制到map_sys的映射矩阵
    if(frame->datalen == ((CALI_POINT_NUM * AX_NUM*AY_NUM)+ 6)){
        memcpy(map_sys.map_matrix, frame->data, CALI_POINT_NUM * AX_NUM*AY_NUM);
        set_array_resi_cali_mode_type(CALI_SUCCESS);
    }
    else {
        set_array_resi_cali_mode_type(CALI_FAIL);
    }
    
    // 2. 发送应答
    frame->trantype = 0x03;
    frame->type = get_resi_array_cali_mode_type();
    frame->data = &empty_data;
    frame->datalen = 1;
    
    mx_serial_tx_frame(USART_3_TR, frame);
}

/**
 * @brief 保存校准参数到Flash
 * @param buf 协议帧指针
 */
void math_resi_array_cali_save(void *buf)
{
    mx_frame_struct *frame = (mx_frame_struct *)buf;
    uint8_t empty_data = 0;
    flash_map_struct verify_map;
    
    // 1. ? 复制校准数据到map_sys
    if(frame->datalen != ((CALI_POINT_NUM * AX_NUM*AY_NUM)+6)) {
        set_array_resi_cali_mode_type(CALI_FAIL);
        goto send_response;
    }
    
    memcpy(map_sys.map_matrix, frame->data, CALI_POINT_NUM * AX_NUM*AY_NUM);
    
    // 2. 擦除Flash校准区域
    flash_erase(FMC_WRITE_MAP_ADDR);
    
    // 3. 使用统一接口保存到Flash
    if(save_config_maps(&map_sys) != 0) {
        set_array_resi_cali_mode_type(CALI_FAIL);
        goto send_response;
    }
    
    delay_ms(2);  // 等待Flash写入完成
   
    // 4. 验证：重新加载并比对
    if(load_config_maps(&verify_map) != 1) {
        set_array_resi_cali_mode_type(CALI_FAIL);
        goto send_response;
    }
    
    // 5. 验证关键校准点（前3个校准层的首个点）
    if(verify_map.map_matrix[0] != 0xFF && 
       verify_map.map_matrix[AX_NUM*AY_NUM] != 0xFF && 
       verify_map.map_matrix[2 * AX_NUM*AY_NUM] != 0xFF) {
        set_array_resi_cali_mode_type(CALI_SUCCESS);
    }
    else {
        set_array_resi_cali_mode_type(CALI_FAIL);
    }
    
send_response:
    // 6. 发送应答
		
    frame->trantype = 0x03;
    frame->type = get_resi_array_cali_mode_type();
    frame->data = &empty_data;
    frame->datalen = 1;
    
    mx_serial_tx_frame(USART_3_TR, frame);
}

/**
 * @brief 清除校准参数（恢复默认映射）
 * @param buf 协议帧指针
 * @return 1=成功, 0=失败
 */
uint8_t cali_params_clear(void *buf)
{
    mx_frame_struct *frame = (mx_frame_struct *)buf;
    uint8_t empty_data = 0;
    uint16_t verify_buf[3];
    
    frame->trantype = 0x03;
    frame->data = &empty_data;
    frame->datalen = 1;
    
    // 1. ? 擦除Flash校准区域
    flash_erase(FMC_WRITE_MAP_ADDR);
    memset(map_sys.map_matrix, 0, sizeof(map_sys.map_matrix));
    // 2. ? 验证擦除（读取前3个半字）
    flash_read(FMC_WRITE_MAP_ADDR, verify_buf, 3);
    
    if(verify_buf[0] == 0xFFFF && verify_buf[1] == 0xFFFF && verify_buf[2] == 0xFFFF) {
        // 3. ? 擦除成功：恢复默认映射表到RAM
				
        memcpy(map_matrix_init, map_sys.map_matrix, sizeof(map_matrix_init));
        
        set_array_resi_cali_mode_type(CALI_SUCCESS);
        frame->type = get_resi_array_cali_mode_type();
        mx_serial_tx_frame(USART_3_TR, frame);
        return 1;
    }
    else {
        set_array_resi_cali_mode_type(CALI_FAIL);
        frame->type = get_resi_array_cali_mode_type();
        mx_serial_tx_frame(USART_3_TR, frame);
        return 0;
    }
}

/**
 * @brief 返回当前校准参数
 * @param buf 协议帧指针
 */
void cali_params_return(void *buf)
{
    mx_frame_struct *frame = (mx_frame_struct *)buf;
    
    frame->trantype = 0x03;
    set_array_resi_cali_mode_type(CALI_RETURN);
    frame->type = get_resi_array_cali_mode_type();
    

    frame->data = map_sys.map_matrix;
    frame->datalen = CALI_POINT_NUM * AX_NUM * AY_NUM;
    
    mx_serial_tx_frame(USART_3_TR, frame);
}
