Files
Frame-rate-optimization/App/app_math_info.c
2026-04-09 10:14:20 +08:00

399 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
}