1290 lines
37 KiB
C
1290 lines
37 KiB
C
|
|
#include "app_calibration.h"
|
|||
|
|
#include "flash_port.h"
|
|||
|
|
|
|||
|
|
#include <stdio.h>
|
|||
|
|
#include <string.h>
|
|||
|
|
|
|||
|
|
#undef MX_LOGD
|
|||
|
|
#undef MX_LOGI
|
|||
|
|
#undef MX_LOGW
|
|||
|
|
#undef MX_LOGE
|
|||
|
|
#define MX_LOGD APP_CALI_LOGD
|
|||
|
|
#define MX_LOGI APP_CALI_LOGI
|
|||
|
|
#define MX_LOGW APP_CALI_LOGW
|
|||
|
|
#define MX_LOGE APP_CALI_LOGE
|
|||
|
|
|
|||
|
|
#define CALI_TAG "APP_CALIBRATION"
|
|||
|
|
|
|||
|
|
#include "app_mozen_handler.h"
|
|||
|
|
#include "lib_cal_creep_resistance.h"
|
|||
|
|
|
|||
|
|
/*************************** Public Parameters **********************/
|
|||
|
|
volatile bool g_check_cali = false;
|
|||
|
|
volatile bool g_reset_takeEffect = false;
|
|||
|
|
volatile bool g_is_active_reporting = true;
|
|||
|
|
volatile bool g_is_creep_enable = true;
|
|||
|
|
|
|||
|
|
pressure_params_t* pressure_params = NULL;
|
|||
|
|
/********************************************************************/
|
|||
|
|
|
|||
|
|
static app_device_status_t g_device_status = {0};
|
|||
|
|
static CALI_INFO_T cali_info = {0};
|
|||
|
|
static app_math_cali_t s_temp_cali = {0};
|
|||
|
|
static app_creep_params s_temp_creep = {5U, 20U};
|
|||
|
|
static uint16_t s_map_matrix[APP_MAP_MATRIX_WORDS] = {0};
|
|||
|
|
|
|||
|
|
static uint8_t sensor_data_payload[APP_SENSOR_FRAME_PAYLOAD_MAX_BYTES];
|
|||
|
|
static volatile bool s_is_payload_packing = false;
|
|||
|
|
|
|||
|
|
#define APP_CREEP_DEFAULT_STRENGTH 2U
|
|||
|
|
#define APP_CREEP_DEFAULT_LEVEL 10U
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Get legacy device status
|
|||
|
|
* @return Pointer to legacy status structure
|
|||
|
|
*/
|
|||
|
|
app_device_status_t* app_device_status_get(void)
|
|||
|
|
{
|
|||
|
|
return &g_device_status;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Set legacy device status
|
|||
|
|
* @param status Pointer to status data to apply
|
|||
|
|
*/
|
|||
|
|
void app_device_status_set(const app_device_status_t *status)
|
|||
|
|
{
|
|||
|
|
if (status != NULL) {
|
|||
|
|
g_device_status = *status;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void app_device_status_init(void)
|
|||
|
|
{
|
|||
|
|
memset(&g_device_status, 0x00, sizeof(g_device_status));
|
|||
|
|
g_device_status.sensor_tx_sw = 1;
|
|||
|
|
g_device_status.tx_stopping = 0;
|
|||
|
|
g_device_status.output_pick = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Parse math calibration parameters from payload
|
|||
|
|
* @param data Input byte buffer
|
|||
|
|
* @param len Length of data
|
|||
|
|
* @param out_params Output structure
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
static uint8_t app_math_parse_payload(const uint8_t *data, uint16_t len, app_math_cali_t *out_params)
|
|||
|
|
{
|
|||
|
|
if ((data == NULL) || (out_params == NULL) || (len < APP_MATH_PARAM_FRAME_SIZE)) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
out_params->max_trigger_res_value = (uint16_t)(((uint16_t)data[1] << 8) | data[0]);
|
|||
|
|
out_params->min_trigger_res_value = (uint16_t)(((uint16_t)data[3] << 8) | data[2]);
|
|||
|
|
out_params->div_trigger_res_value = (uint16_t)(((uint16_t)data[5] << 8) | data[4]);
|
|||
|
|
out_params->max_display_value = (uint16_t)(((uint16_t)data[7] << 8) | data[6]);
|
|||
|
|
|
|||
|
|
if (out_params->min_trigger_res_value >= out_params->max_trigger_res_value) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
uint16_t g_buf[5];
|
|||
|
|
/**
|
|||
|
|
* @brief Apply math calibration parameters to runtime algorithms
|
|||
|
|
* @param params Parameter structure
|
|||
|
|
*/
|
|||
|
|
static void app_math_apply_runtime(const app_math_cali_t *params)
|
|||
|
|
{
|
|||
|
|
if (params == NULL) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
MX_LOGI(CALI_TAG, "Math apply runtime: min=%u max=%u div=%u max_display=%u",
|
|||
|
|
(unsigned int)params->min_trigger_res_value,
|
|||
|
|
(unsigned int)params->max_trigger_res_value,
|
|||
|
|
(unsigned int)params->div_trigger_res_value,
|
|||
|
|
(unsigned int)params->max_display_value);
|
|||
|
|
g_buf[0] = params->max_trigger_res_value;
|
|||
|
|
g_buf[1] = params->min_trigger_res_value;
|
|||
|
|
g_buf[2] = params->div_trigger_res_value;
|
|||
|
|
g_buf[3] = MAX_DISPLAY_ADC_VALUE;
|
|||
|
|
g_buf[4] = params->max_display_value;
|
|||
|
|
math_resi_init(params->max_trigger_res_value,
|
|||
|
|
params->min_trigger_res_value,
|
|||
|
|
params->div_trigger_res_value,
|
|||
|
|
MAX_DISPLAY_ADC_VALUE,
|
|||
|
|
params->max_display_value);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Set default creep parameters
|
|||
|
|
* @param params Parameter structure
|
|||
|
|
*/
|
|||
|
|
static void app_creep_set_default(app_creep_params *params)
|
|||
|
|
{
|
|||
|
|
if (params == NULL) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
params->creep_strength = APP_CREEP_DEFAULT_STRENGTH;
|
|||
|
|
params->creep_level = APP_CREEP_DEFAULT_LEVEL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Apply creep parameters to runtime algorithms
|
|||
|
|
* @param params Parameter structure
|
|||
|
|
*/
|
|||
|
|
static void app_creep_apply_runtime(const app_creep_params *params)
|
|||
|
|
{
|
|||
|
|
if (params == NULL) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
MX_LOGI(CALI_TAG, "Creep apply runtime: strength=%u level=%u",
|
|||
|
|
(unsigned int)params->creep_strength,
|
|||
|
|
(unsigned int)params->creep_level);
|
|||
|
|
|
|||
|
|
cal_creep_resistance_init(params->creep_strength, params->creep_level);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Set default device info
|
|||
|
|
* @param dev_info Device info structure
|
|||
|
|
*/
|
|||
|
|
static void app_device_info_set_default(app_dev_info *dev_info)
|
|||
|
|
{
|
|||
|
|
char sensor_size_text[16] = {0};
|
|||
|
|
|
|||
|
|
if (dev_info == NULL) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
memset(dev_info, 0, sizeof(app_dev_info));
|
|||
|
|
memcpy(dev_info->pn, DEFAULT_PN, sizeof(DEFAULT_PN) - 1);
|
|||
|
|
memcpy(dev_info->sn, DEFAULT_SN, sizeof(DEFAULT_SN) - 1);
|
|||
|
|
memcpy(dev_info->sw_ver, DEFAULT_SW_VER, sizeof(DEFAULT_SW_VER) - 1);
|
|||
|
|
memcpy(dev_info->hw_ver, DEFAULT_HW_VER, sizeof(DEFAULT_HW_VER) - 1);
|
|||
|
|
|
|||
|
|
(void)snprintf(sensor_size_text,
|
|||
|
|
sizeof(sensor_size_text),
|
|||
|
|
"%u,%u",
|
|||
|
|
(unsigned int)MT_AX_NUM,
|
|||
|
|
(unsigned int)MT_AY_NUM);
|
|||
|
|
memcpy(dev_info->sensor_size, sensor_size_text, strlen(sensor_size_text));
|
|||
|
|
memcpy(dev_info->protocol_ver, APP_DEVICE_PROTOCOL_VER, strlen(APP_DEVICE_PROTOCOL_VER));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Ensure device info strings are properly null-terminated
|
|||
|
|
* @param dev_info Device info structure
|
|||
|
|
*/
|
|||
|
|
static void app_device_info_normalize(app_dev_info *dev_info)
|
|||
|
|
{
|
|||
|
|
if (dev_info == NULL) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dev_info->pn[sizeof(dev_info->pn) - 1U] = '\0';
|
|||
|
|
dev_info->sn[sizeof(dev_info->sn) - 1U] = '\0';
|
|||
|
|
dev_info->sw_ver[sizeof(dev_info->sw_ver) - 1U] = '\0';
|
|||
|
|
dev_info->hw_ver[sizeof(dev_info->hw_ver) - 1U] = '\0';
|
|||
|
|
dev_info->sensor_size[sizeof(dev_info->sensor_size) - 1U] = '\0';
|
|||
|
|
dev_info->protocol_ver[sizeof(dev_info->protocol_ver) - 1U] = '\0';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Validate device info structure fields
|
|||
|
|
* @param dev_info Device info structure
|
|||
|
|
* @return 1 if valid, 0 otherwise
|
|||
|
|
*/
|
|||
|
|
static uint8_t app_device_info_is_valid(const app_dev_info *dev_info)
|
|||
|
|
{
|
|||
|
|
if (dev_info == NULL) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ((dev_info->pn[0] == '\0') || (dev_info->sn[0] == '\0') ||
|
|||
|
|
(dev_info->sw_ver[0] == '\0') || (dev_info->hw_ver[0] == '\0')) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (((uint8_t)dev_info->pn[0] == 0xFFU) ||
|
|||
|
|
((uint8_t)dev_info->sn[0] == 0xFFU) ||
|
|||
|
|
((uint8_t)dev_info->sw_ver[0] == 0xFFU) ||
|
|||
|
|
((uint8_t)dev_info->hw_ver[0] == 0xFFU)) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ((memchr(dev_info->pn, '\0', sizeof(dev_info->pn)) == NULL) ||
|
|||
|
|
(memchr(dev_info->sn, '\0', sizeof(dev_info->sn)) == NULL) ||
|
|||
|
|
(memchr(dev_info->sw_ver, '\0', sizeof(dev_info->sw_ver)) == NULL) ||
|
|||
|
|
(memchr(dev_info->hw_ver, '\0', sizeof(dev_info->hw_ver)) == NULL)) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Build 8-bit sensor payload
|
|||
|
|
* @param sensor_data 2D array of sensor data
|
|||
|
|
* @param payload Output buffer
|
|||
|
|
* @param payload_size Output buffer size
|
|||
|
|
* @param payload_len Actual payload length
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_calibration_build_sensor8bit_payload(const uint8_t (*sensor_data)[MT_AY_NUM],
|
|||
|
|
uint8_t *payload,
|
|||
|
|
uint16_t payload_size,
|
|||
|
|
uint16_t *payload_len)
|
|||
|
|
{
|
|||
|
|
uint16_t matrix_count = (uint16_t)(MT_AX_NUM * MT_AY_NUM);
|
|||
|
|
uint16_t need_len;
|
|||
|
|
|
|||
|
|
if ((sensor_data == NULL) || (payload == NULL) || (payload_len == NULL)) {
|
|||
|
|
return 0U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
need_len = (uint16_t)(1U + matrix_count);
|
|||
|
|
if (payload_size < need_len) {
|
|||
|
|
return 0U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
payload[0] = 0x01U;
|
|||
|
|
memcpy(&payload[1], sensor_data, (size_t)(need_len - 1U));
|
|||
|
|
*payload_len = need_len;
|
|||
|
|
return 1U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Build 16-bit sensor payload
|
|||
|
|
* @param sensor_data 2D array of sensor data
|
|||
|
|
* @param payload Output buffer
|
|||
|
|
* @param payload_size Output buffer size
|
|||
|
|
* @param payload_len Actual payload length
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_calibration_build_sensor16bit_payload(const uint16_t (*sensor_data)[MT_AY_NUM],
|
|||
|
|
uint8_t *payload,
|
|||
|
|
uint16_t payload_size,
|
|||
|
|
uint16_t *payload_len)
|
|||
|
|
{
|
|||
|
|
uint16_t matrix_count = (uint16_t)(MT_AX_NUM * MT_AY_NUM);
|
|||
|
|
uint16_t need_len;
|
|||
|
|
|
|||
|
|
if ((sensor_data == NULL) || (payload == NULL) || (payload_len == NULL)) {
|
|||
|
|
return 0U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
need_len = (uint16_t)(1U + (matrix_count * (uint16_t)sizeof(uint16_t)));
|
|||
|
|
if (payload_size < need_len) {
|
|||
|
|
return 0U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
payload[0] = 0x02U;
|
|||
|
|
memcpy(&payload[1], sensor_data, (size_t)(need_len - 1U));
|
|||
|
|
*payload_len = need_len;
|
|||
|
|
return 1U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Initialize math parameters
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_init(uint16_t *min_trigger_res_value,
|
|||
|
|
uint16_t *max_trigger_res_value,
|
|||
|
|
uint16_t *div_trigger_res_value,
|
|||
|
|
uint16_t *max_display_value,
|
|||
|
|
uint16_t *sensor_data_type)
|
|||
|
|
{
|
|||
|
|
app_math_cali_t flash_params;
|
|||
|
|
|
|||
|
|
if ((min_trigger_res_value == NULL) ||
|
|||
|
|
(max_trigger_res_value == NULL) ||
|
|||
|
|
(div_trigger_res_value == NULL) ||
|
|||
|
|
(max_display_value == NULL) ||
|
|||
|
|
(sensor_data_type == NULL)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Math init bad output pointers");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_math_load(&flash_params)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Math init load flash params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (flash_params.check_cail != APP_CALI_STATUS_CALIBRATED) {
|
|||
|
|
MX_LOGW(CALI_TAG, "Math init skipped: not calibrated");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (flash_params.min_trigger_res_value >= flash_params.max_trigger_res_value) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Math init invalid range, min=%u max=%u",
|
|||
|
|
(unsigned int)flash_params.min_trigger_res_value,
|
|||
|
|
(unsigned int)flash_params.max_trigger_res_value);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
*min_trigger_res_value = flash_params.min_trigger_res_value;
|
|||
|
|
*max_trigger_res_value = flash_params.max_trigger_res_value;
|
|||
|
|
*div_trigger_res_value = flash_params.div_trigger_res_value;
|
|||
|
|
*max_display_value = flash_params.max_display_value;
|
|||
|
|
*sensor_data_type = flash_params.sensor_data_type;
|
|||
|
|
|
|||
|
|
app_math_apply_runtime(&flash_params);
|
|||
|
|
MX_LOGI(CALI_TAG, "Math init from calibration flash params");
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Get current temporary math parameters
|
|||
|
|
* @param out_params Output parameter structure pointer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_get_temp_params(app_math_cali_t *out_params)
|
|||
|
|
{
|
|||
|
|
if (out_params == NULL) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Math get temp bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
out_params->max_trigger_res_value = s_temp_cali.max_trigger_res_value;
|
|||
|
|
|
|||
|
|
out_params->min_trigger_res_value = s_temp_cali.min_trigger_res_value;
|
|||
|
|
out_params->div_trigger_res_value = s_temp_cali.div_trigger_res_value;
|
|||
|
|
out_params->max_display_value = s_temp_cali.max_display_value;
|
|||
|
|
out_params->sensor_data_type = s_temp_cali.sensor_data_type;
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Set current temporary math parameters
|
|||
|
|
* @param params Input parameter structure pointer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_set_temp_params(const app_math_cali_t *params)
|
|||
|
|
{
|
|||
|
|
if (params == NULL) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Math set temp bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
s_temp_cali.min_trigger_res_value = params->min_trigger_res_value;
|
|||
|
|
s_temp_cali.max_trigger_res_value = params->max_trigger_res_value;
|
|||
|
|
s_temp_cali.div_trigger_res_value = params->div_trigger_res_value;
|
|||
|
|
s_temp_cali.max_display_value = params->max_display_value;
|
|||
|
|
s_temp_cali.sensor_data_type = params->sensor_data_type;
|
|||
|
|
|
|||
|
|
app_math_apply_runtime(&s_temp_cali);
|
|||
|
|
|
|||
|
|
// Persist the effective sensor_data_type together with runtime params
|
|||
|
|
if (!flash_port_math_save(&s_temp_cali)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Save math params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Apply temporary math parameters immediately from a byte buffer
|
|||
|
|
* @param data Input data buffer pointer
|
|||
|
|
* @param len Length of the buffer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_write_temp_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
app_math_cali_t params;
|
|||
|
|
|
|||
|
|
if (!app_math_parse_payload(data, len, ¶ms)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Math temp parse failed, len=%u", (unsigned int)len);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
s_temp_cali.min_trigger_res_value = params.min_trigger_res_value;
|
|||
|
|
s_temp_cali.max_trigger_res_value = params.max_trigger_res_value;
|
|||
|
|
s_temp_cali.div_trigger_res_value = params.div_trigger_res_value;
|
|||
|
|
s_temp_cali.max_display_value = params.max_display_value;
|
|||
|
|
|
|||
|
|
app_math_apply_runtime(&s_temp_cali);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @param data Input data buffer pointer
|
|||
|
|
* @param len Length of the buffer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_save_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
app_math_cali_t flash_params;
|
|||
|
|
|
|||
|
|
if (!app_math_write_temp_params(data, len)) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (flash_port_math_load(&flash_params)) {
|
|||
|
|
s_temp_cali.check_cail = flash_params.check_cail;
|
|||
|
|
} else {
|
|||
|
|
s_temp_cali.check_cail = APP_CALI_STATUS_UNCALIBRATED;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_math_save(&s_temp_cali)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Save math params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_math_load(&flash_params)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Verify math params failed");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
app_math_apply_runtime(&flash_params);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Clear math parameters to default values
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_clear_params(void)
|
|||
|
|
{
|
|||
|
|
app_math_cali_t default_params = {0};
|
|||
|
|
|
|||
|
|
default_params.min_trigger_res_value = DEFAULT_MIN_TRIGGER_RES_VALUE;
|
|||
|
|
default_params.max_trigger_res_value = DEFAULT_MAX_TRIGGER_RES_VALUE;
|
|||
|
|
default_params.div_trigger_res_value = DEFAULT_DIV_TRIGGER_RES_VALUE;
|
|||
|
|
default_params.max_display_value = DEFAULT_MAX_DISPLAY_VALUE;
|
|||
|
|
default_params.check_cail = APP_CALI_STATUS_UNCALIBRATED;
|
|||
|
|
|
|||
|
|
app_math_apply_runtime(&default_params);
|
|||
|
|
|
|||
|
|
s_temp_cali.check_cail = APP_CALI_STATUS_UNCALIBRATED;
|
|||
|
|
s_temp_cali.min_trigger_res_value = default_params.min_trigger_res_value;
|
|||
|
|
s_temp_cali.max_trigger_res_value = default_params.max_trigger_res_value;
|
|||
|
|
s_temp_cali.div_trigger_res_value = default_params.div_trigger_res_value;
|
|||
|
|
s_temp_cali.max_display_value = default_params.max_display_value;
|
|||
|
|
|
|||
|
|
return flash_port_math_save(&s_temp_cali);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Read temporary math parameters into response buffer
|
|||
|
|
* @param response_buf Output buffer
|
|||
|
|
* @param response_len Output length pointer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_read_temp_params(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
if ((response_buf == NULL) || (response_len == NULL)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Read temp math params bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response_buf[0] = (uint8_t)(s_temp_cali.max_trigger_res_value & 0xFFU);
|
|||
|
|
response_buf[1] = (uint8_t)((s_temp_cali.max_trigger_res_value >> 8) & 0xFFU);
|
|||
|
|
response_buf[2] = (uint8_t)(s_temp_cali.min_trigger_res_value & 0xFFU);
|
|||
|
|
response_buf[3] = (uint8_t)((s_temp_cali.min_trigger_res_value >> 8) & 0xFFU);
|
|||
|
|
response_buf[4] = (uint8_t)(s_temp_cali.div_trigger_res_value & 0xFFU);
|
|||
|
|
response_buf[5] = (uint8_t)((s_temp_cali.div_trigger_res_value >> 8) & 0xFFU);
|
|||
|
|
response_buf[6] = (uint8_t)(s_temp_cali.max_display_value & 0xFFU);
|
|||
|
|
response_buf[7] = (uint8_t)((s_temp_cali.max_display_value >> 8) & 0xFFU);
|
|||
|
|
|
|||
|
|
*response_len = APP_MATH_PARAM_FRAME_SIZE;
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Read solidified math parameters from Flash
|
|||
|
|
* @param response_buf Output buffer
|
|||
|
|
* @param response_len Output length pointer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_math_read_solidified_params(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
app_math_cali_t flash_params;
|
|||
|
|
|
|||
|
|
if ((response_buf == NULL) || (response_len == NULL)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Read flash math params bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_math_load(&flash_params)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Load flash math params failed");
|
|||
|
|
memset(response_buf, 0xFF, APP_MATH_PARAM_FRAME_SIZE);
|
|||
|
|
*response_len = APP_MATH_PARAM_FRAME_SIZE;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response_buf[0] = (uint8_t)(flash_params.max_trigger_res_value & 0xFFU);
|
|||
|
|
response_buf[1] = (uint8_t)((flash_params.max_trigger_res_value >> 8) & 0xFFU);
|
|||
|
|
response_buf[2] = (uint8_t)(flash_params.min_trigger_res_value & 0xFFU);
|
|||
|
|
response_buf[3] = (uint8_t)((flash_params.min_trigger_res_value >> 8) & 0xFFU);
|
|||
|
|
response_buf[4] = (uint8_t)(flash_params.div_trigger_res_value & 0xFFU);
|
|||
|
|
response_buf[5] = (uint8_t)((flash_params.div_trigger_res_value >> 8) & 0xFFU);
|
|||
|
|
response_buf[6] = (uint8_t)(flash_params.max_display_value & 0xFFU);
|
|||
|
|
response_buf[7] = (uint8_t)((flash_params.max_display_value >> 8) & 0xFFU);
|
|||
|
|
|
|||
|
|
*response_len = APP_MATH_PARAM_FRAME_SIZE;
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Initialize pressure parameters from Flash
|
|||
|
|
* @return Pointer to pressure_params_t or NULL if failed
|
|||
|
|
*/
|
|||
|
|
pressure_params_t *app_pressure_init(void)
|
|||
|
|
{
|
|||
|
|
if (!flash_port_pressure_load(&s_temp_cali)) {
|
|||
|
|
s_temp_cali.check_cail = APP_CALI_STATUS_UNCALIBRATED;
|
|||
|
|
s_temp_cali.min_trigger_res_value = DEFAULT_MIN_TRIGGER_RES_VALUE;
|
|||
|
|
s_temp_cali.max_trigger_res_value = DEFAULT_MAX_TRIGGER_RES_VALUE;
|
|||
|
|
s_temp_cali.div_trigger_res_value = DEFAULT_DIV_TRIGGER_RES_VALUE;
|
|||
|
|
s_temp_cali.max_display_value = DEFAULT_MAX_DISPLAY_VALUE;
|
|||
|
|
s_temp_cali.num_points = 0;
|
|||
|
|
memset(s_temp_cali.pressure_points, 0, sizeof(s_temp_cali.pressure_points));
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return &s_temp_cali;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Write temporary pressure parameters from buffer
|
|||
|
|
* @param data Buffer pointer
|
|||
|
|
* @param len Length of the data
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_pressure_write_temp_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
uint16_t num_points;
|
|||
|
|
|
|||
|
|
if ((data == NULL) || (len < 2U)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Pressure temp write bad arg, len=%u", (unsigned int)len);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
// mx_log_hex_frame(CALI_TAG, data, len);
|
|||
|
|
|
|||
|
|
num_points = (uint16_t)data[0];
|
|||
|
|
MX_LOGD(CALI_TAG, "Pressure temp write num_points=%u len=%u", (unsigned int)num_points, (unsigned int)len);
|
|||
|
|
|
|||
|
|
if (num_points > MAX_PRESSURE_POINTS) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Pressure temp write invalid points=%u len=%u",
|
|||
|
|
(unsigned int)num_points, (unsigned int)len);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
s_temp_cali.num_points = num_points;
|
|||
|
|
memset(s_temp_cali.pressure_points, 0, sizeof(s_temp_cali.pressure_points));
|
|||
|
|
memcpy(s_temp_cali.pressure_points, &data[1], (size_t)num_points * sizeof(uint16_t));
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Read temporary pressure parameters
|
|||
|
|
* @param response_buf Output buffer
|
|||
|
|
* @param response_len Output length pointer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_pressure_read_temp_params(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
if ((response_buf == NULL) || (response_len == NULL)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Read temp pressure params bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response_buf[0] = (uint8_t)(s_temp_cali.num_points & 0xFFU);
|
|||
|
|
response_buf[1] = (uint8_t)((s_temp_cali.num_points >> 8) & 0xFFU);
|
|||
|
|
memcpy(&response_buf[2],
|
|||
|
|
s_temp_cali.pressure_points,
|
|||
|
|
(size_t)s_temp_cali.num_points * sizeof(uint16_t));
|
|||
|
|
|
|||
|
|
*response_len = (uint16_t)(2U + (s_temp_cali.num_points * 2U));
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Save pressure parameters to Flash
|
|||
|
|
* @param data Input byte buffer
|
|||
|
|
* @param len Length of the data
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_pressure_save_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
if (!app_pressure_write_temp_params(data, len)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Write temp pressure params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_pressure_save(&s_temp_cali)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Save pressure params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Read solidified pressure parameters from Flash
|
|||
|
|
* @param response_buf Output buffer
|
|||
|
|
* @param response_len Output length pointer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_pressure_read_solidified_params(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
app_math_cali_t flash_params;
|
|||
|
|
|
|||
|
|
if ((response_buf == NULL) || (response_len == NULL)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Read flash pressure params bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_pressure_load(&flash_params)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Load flash pressure params failed");
|
|||
|
|
*response_len = 0;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response_buf[0] = (uint8_t)(flash_params.num_points & 0xFFU);
|
|||
|
|
response_buf[1] = (uint8_t)((flash_params.num_points >> 8) & 0xFFU);
|
|||
|
|
memcpy(&response_buf[2],
|
|||
|
|
flash_params.pressure_points,
|
|||
|
|
(size_t)flash_params.num_points * sizeof(uint16_t));
|
|||
|
|
|
|||
|
|
*response_len = (uint16_t)(2U + (flash_params.num_points * 2U));
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Clear pressure parameters
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_pressure_clear_params(void)
|
|||
|
|
{
|
|||
|
|
s_temp_cali.num_points = 0;
|
|||
|
|
memset(s_temp_cali.pressure_points, 0, sizeof(s_temp_cali.pressure_points));
|
|||
|
|
|
|||
|
|
if (!flash_port_pressure_save(&s_temp_cali)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Clear pressure params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Initialize map matrix from Flash
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_map_init(void)
|
|||
|
|
{
|
|||
|
|
if (!flash_port_map_load(s_map_matrix, APP_MAP_MATRIX_WORDS)) {
|
|||
|
|
memset(s_map_matrix, 0, sizeof(s_map_matrix));
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Write temporary map parameters
|
|||
|
|
* @param data Input byte buffer
|
|||
|
|
* @param len Length of data
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_map_write_temp_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
if ((data == NULL) || (len != (uint16_t)APP_MAP_MATRIX_BYTES)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Map temp write bad arg, len=%u", (unsigned int)len);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
memcpy(s_map_matrix, data, APP_MAP_MATRIX_BYTES);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Save map parameters to Flash
|
|||
|
|
* @param data Input byte buffer
|
|||
|
|
* @param len Length of data
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_map_save_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
if (!app_map_write_temp_params(data, len)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Map param length invalid: %u", (unsigned int)len);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_map_save(s_map_matrix, APP_MAP_MATRIX_WORDS)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Save map params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_map_load(s_map_matrix, APP_MAP_MATRIX_WORDS)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Verify map params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!app_calibration_set(1U)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Set calibrated state failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Clear map parameters from Flash
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_map_clear_params(void)
|
|||
|
|
{
|
|||
|
|
memset(s_map_matrix, 0, sizeof(s_map_matrix));
|
|||
|
|
if (!flash_port_map_clear()) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Clear map params failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!app_calibration_set(0U)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Clear calibrated state failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Read temporary map parameters
|
|||
|
|
* @param response_buf Output buffer
|
|||
|
|
* @param response_len Output length pointer
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_map_read_temp_params(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
if ((response_buf == NULL) || (response_len == NULL)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Read temp map params bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
*response_len = (uint16_t)APP_MAP_MATRIX_BYTES;
|
|||
|
|
memcpy(response_buf, s_map_matrix, *response_len);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Get pointer to map data buffer
|
|||
|
|
* @return Pointer to map data
|
|||
|
|
*/
|
|||
|
|
uint8_t *app_map_data_ptr(void)
|
|||
|
|
{
|
|||
|
|
return (uint8_t *)s_map_matrix;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Get map data size
|
|||
|
|
* @return Size of map data in bytes
|
|||
|
|
*/
|
|||
|
|
uint32_t app_map_data_size(void)
|
|||
|
|
{
|
|||
|
|
return (uint32_t)APP_MAP_MATRIX_BYTES;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Write temporary creep parameters
|
|||
|
|
* @param creep_params Input parameter structure
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_creep_write_temp_params(app_creep_params *creep_params)
|
|||
|
|
{
|
|||
|
|
if (creep_params == NULL) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Creep temp write bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
s_temp_creep.creep_strength = creep_params->creep_strength;
|
|||
|
|
s_temp_creep.creep_level = creep_params->creep_level;
|
|||
|
|
app_creep_apply_runtime(&s_temp_creep);
|
|||
|
|
|
|||
|
|
MX_LOGI(CALI_TAG, "Creep temp updated: strength=%u level=%u",
|
|||
|
|
(unsigned int)s_temp_creep.creep_strength,
|
|||
|
|
(unsigned int)s_temp_creep.creep_level);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Save creep parameters to Flash
|
|||
|
|
* @param creep_params Input parameter structure
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_creep_save_params(app_creep_params *creep_params)
|
|||
|
|
{
|
|||
|
|
if (!app_creep_write_temp_params(creep_params)) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_creep_save(&s_temp_creep)) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Clear creep parameters
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_creep_clear_params(void)
|
|||
|
|
{
|
|||
|
|
app_creep_set_default(&s_temp_creep);
|
|||
|
|
app_creep_apply_runtime(&s_temp_creep);
|
|||
|
|
|
|||
|
|
if (!flash_port_creep_clear()) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Creep clear failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Read device information from Flash
|
|||
|
|
* @param dev_info Output structure
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_device_get_info(app_dev_info *dev_info)
|
|||
|
|
{
|
|||
|
|
if (dev_info == NULL) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Device info get bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_device_info_load(dev_info))
|
|||
|
|
{
|
|||
|
|
app_device_info_set_default(dev_info);
|
|||
|
|
if (!app_device_set_info(dev_info)) {
|
|||
|
|
MX_LOGW(CALI_TAG, "Device info load default save failed");
|
|||
|
|
}
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
app_device_info_normalize(dev_info);
|
|||
|
|
if (!app_device_info_is_valid(dev_info))
|
|||
|
|
{
|
|||
|
|
app_device_info_set_default(dev_info);
|
|||
|
|
if (!app_device_set_info(dev_info)) {
|
|||
|
|
MX_LOGW(CALI_TAG, "Device info repair save failed");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Write device information to Flash
|
|||
|
|
* @param dev_info Input structure
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_device_set_info(const app_dev_info *dev_info)
|
|||
|
|
{
|
|||
|
|
app_dev_info flash_info;
|
|||
|
|
|
|||
|
|
if (dev_info == NULL) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Device info set bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
memcpy(&flash_info, dev_info, sizeof(flash_info));
|
|||
|
|
app_device_info_normalize(&flash_info);
|
|||
|
|
if (!app_device_info_is_valid(&flash_info)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Device info set invalid data");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_device_info_save(&flash_info)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Device info save failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Read creep parameters from Flash, load defaults if invalid
|
|||
|
|
* @param creep_params Output structure
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_creep_read_params(app_creep_params *creep_params)
|
|||
|
|
{
|
|||
|
|
if (creep_params == NULL) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Creep read bad arg");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!flash_port_creep_load(creep_params)) {
|
|||
|
|
app_creep_set_default(creep_params);
|
|||
|
|
if (!flash_port_creep_save(creep_params)) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Creep read default save failed");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
s_temp_creep = *creep_params;
|
|||
|
|
app_creep_apply_runtime(&s_temp_creep);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Invalidate calibration runtime state
|
|||
|
|
*/
|
|||
|
|
void app_calibration_invalidate_runtime(void)
|
|||
|
|
{
|
|||
|
|
#if APP_CALI_USE_PROJECT_RUNTIME_FLAGS
|
|||
|
|
pressure_params = NULL;
|
|||
|
|
g_check_cali = false;
|
|||
|
|
g_is_creep_enable = false;
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Request reset of runtime calibration logic
|
|||
|
|
* This will be applied after the next pressure measurementis taken.
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
void app_calibration_request_reset_effect(void)
|
|||
|
|
{
|
|||
|
|
#if APP_CALI_USE_PROJECT_RUNTIME_FLAGS
|
|||
|
|
g_reset_takeEffect = true;
|
|||
|
|
g_is_creep_enable = false;
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Check if device is calibrated
|
|||
|
|
* @return 1 if calibrated, 0 otherwise
|
|||
|
|
*/
|
|||
|
|
uint8_t app_calibration_check(void)
|
|||
|
|
{
|
|||
|
|
app_math_cali_t flash_params;
|
|||
|
|
|
|||
|
|
if (!flash_port_math_load(&flash_params))
|
|||
|
|
{
|
|||
|
|
MX_LOGW(CALI_TAG, "Check calibration state failed, treat as uncalibrated");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (uint8_t)(flash_params.check_cail == APP_CALI_STATUS_CALIBRATED);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Get global calibration status
|
|||
|
|
* @return Value of g_check_cali
|
|||
|
|
*/
|
|||
|
|
uint8_t app_calibration_get_cail_status(void)
|
|||
|
|
{
|
|||
|
|
return g_check_cali;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Set calibration status
|
|||
|
|
* @param calibrated 1 to mark as calibrated, 0 otherwise
|
|||
|
|
* @return 1 on success, 0 on failure
|
|||
|
|
*/
|
|||
|
|
uint8_t app_calibration_set(uint8_t calibrated)
|
|||
|
|
{
|
|||
|
|
s_temp_cali.check_cail = calibrated ? APP_CALI_STATUS_CALIBRATED : APP_CALI_STATUS_UNCALIBRATED;
|
|||
|
|
if (!flash_port_math_save(&s_temp_cali)) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
g_check_cali = (calibrated != 0);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Initialize the calibration module and underlying flash port.
|
|||
|
|
* @param flash_ops Pointer to flash operations mapping.
|
|||
|
|
*/
|
|||
|
|
void app_calibration_init(const struct flash_port_ops_t *flash_ops)
|
|||
|
|
{
|
|||
|
|
if (flash_ops != NULL) {
|
|||
|
|
flash_port_init((const flash_port_ops_t *)flash_ops);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
app_calibration_reset_init();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Initialize all calibration components and states
|
|||
|
|
*/
|
|||
|
|
void app_calibration_reset_init(void)
|
|||
|
|
{
|
|||
|
|
uint16_t min_trig, max_trig, div_trig, max_disp, sensor_type;
|
|||
|
|
app_math_cali_t cali_param;
|
|||
|
|
|
|||
|
|
g_check_cali = (app_calibration_check() != 0);
|
|||
|
|
g_is_creep_enable = true;
|
|||
|
|
|
|||
|
|
if (g_check_cali) {
|
|||
|
|
if (!app_math_init(&min_trig, &max_trig, &div_trig, &max_disp, &sensor_type)) {
|
|||
|
|
MX_LOGW(CALI_TAG, "Math init failed, fallback to default");
|
|||
|
|
(void)app_math_clear_params();
|
|||
|
|
g_check_cali = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pressure_params = app_pressure_init();
|
|||
|
|
if (pressure_params == NULL || pressure_params->num_points < 2) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Pressure params invalid");
|
|||
|
|
g_check_cali = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!app_map_init()) {
|
|||
|
|
MX_LOGE(CALI_TAG, "Map init failed");
|
|||
|
|
g_check_cali = false;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
(void)app_math_clear_params();
|
|||
|
|
pressure_params = NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
(void)app_creep_read_params(&s_temp_creep);
|
|||
|
|
|
|||
|
|
app_math_get_temp_params(&cali_param);
|
|||
|
|
|
|||
|
|
if (g_check_cali) {
|
|||
|
|
g_sensor_data_type = cali_param.sensor_data_type;
|
|||
|
|
} else {
|
|||
|
|
g_sensor_data_type = SENSOR_BIT_8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Default override to 8bit (from original code)
|
|||
|
|
g_sensor_data_type = SENSOR_BIT_8;
|
|||
|
|
cali_param.max_display_value = 255;
|
|||
|
|
|
|||
|
|
g_buf[0] = cali_param.max_trigger_res_value;
|
|||
|
|
g_buf[1] = cali_param.min_trigger_res_value;
|
|||
|
|
g_buf[2] = cali_param.div_trigger_res_value;
|
|||
|
|
g_buf[3] = MAX_DISPLAY_ADC_VALUE;
|
|||
|
|
g_buf[4] = cali_param.max_display_value;
|
|||
|
|
|
|||
|
|
math_resi_init(cali_param.max_trigger_res_value,
|
|||
|
|
cali_param.min_trigger_res_value,
|
|||
|
|
cali_param.div_trigger_res_value,
|
|||
|
|
MAX_DISPLAY_ADC_VALUE,
|
|||
|
|
cali_param.max_display_value);
|
|||
|
|
|
|||
|
|
MX_LOGI(CALI_TAG, "Calibration params -> max_trig:%u, min_trig:%u, div_trig:%u, max_disp:%u, type:%u",
|
|||
|
|
(unsigned int)cali_param.max_trigger_res_value,
|
|||
|
|
(unsigned int)cali_param.min_trigger_res_value,
|
|||
|
|
(unsigned int)cali_param.div_trigger_res_value,
|
|||
|
|
(unsigned int)cali_param.max_display_value,
|
|||
|
|
(unsigned int)cali_param.sensor_data_type
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
MX_LOGI(CALI_TAG, "g_sensor_data_type : %u, g_is_creep_enable : %u",
|
|||
|
|
(unsigned int)g_sensor_data_type,
|
|||
|
|
(unsigned int)g_is_creep_enable);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Process raw 16-bit sensor data against calibration map
|
|||
|
|
* @param in_raw_data Input raw sensor data matrix (MT_AX_NUM x MT_AY_NUM)
|
|||
|
|
* @param out_cali_data Output buffer to store processed data
|
|||
|
|
* @return 1 on success, 0 on invalid parameters
|
|||
|
|
*/
|
|||
|
|
void process_calibration_frame(const uint16_t in_raw_data[MT_AX_NUM][MT_AY_NUM],
|
|||
|
|
uint16_t out_cali_data[MT_AX_NUM][MT_AY_NUM])
|
|||
|
|
{
|
|||
|
|
if (in_raw_data == NULL || out_cali_data == NULL) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (g_check_cali &&
|
|||
|
|
(pressure_params != NULL) &&
|
|||
|
|
(pressure_params->num_points >= 2U) &&
|
|||
|
|
(pressure_params->num_points <= MAX_PRESSURE_POINTS))
|
|||
|
|
{
|
|||
|
|
// ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µı궨<C4B1><EAB6A8><EFBFBD><EFBFBD>
|
|||
|
|
cali_info.real_pressure_value = pressure_params->pressure_points;
|
|||
|
|
cali_info.cali_params = (uint16_t *)app_map_data_ptr();
|
|||
|
|
cali_info.cali_pressure_num = (uint8_t)pressure_params->num_points;
|
|||
|
|
cali_info.cali_data_out_bit_size = UINT16_DOUBLE;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>һά<D2BB><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㷨
|
|||
|
|
math_resi_cali((uint16_t *)in_raw_data,
|
|||
|
|
&cali_info,
|
|||
|
|
(uint16_t *)out_cali_data,
|
|||
|
|
(uint32_t)(MT_AX_NUM * MT_AY_NUM));
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// δ<>궨<EFBFBD><EAB6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧЧʱ<D0A7><CAB1><EFBFBD><EFBFBD>ȫ<C8AB><CDB8>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>
|
|||
|
|
if ((const void *)in_raw_data != (const void *)out_cali_data) {
|
|||
|
|
memcpy((void *)out_cali_data, (const void *)in_raw_data, sizeof(uint16_t) * MT_AX_NUM * MT_AY_NUM);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õײ<C3B5><D7B2>궨<EFBFBD><EAB6A8><EFBFBD><EFBFBD>
|
|||
|
|
if (g_reset_takeEffect) {
|
|||
|
|
g_reset_takeEffect = false;
|
|||
|
|
app_calibration_reset_init();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* @brief Check if sensor frame can be sent
|
|||
|
|
* @return true if sensor frame can be sent, false otherwise
|
|||
|
|
*/
|
|||
|
|
static bool can_send_sensor_frame(void)
|
|||
|
|
{
|
|||
|
|
if (!g_is_active_reporting && (g_sensor_frames_to_send <= 0)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (g_sensor_frames_to_send > 0) {
|
|||
|
|
g_sensor_frames_to_send--;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Send 8-bit sensor frame through Mozen protocol
|
|||
|
|
* @param sensor_data 8-bit sensor matrix
|
|||
|
|
* @return 1 on success, 0 on failure or busy
|
|||
|
|
*/
|
|||
|
|
uint8_t send_sensor_frame_8bit(const uint8_t (*sensor_data)[MT_AY_NUM])
|
|||
|
|
{
|
|||
|
|
uint16_t payload_len = 0U;
|
|||
|
|
|
|||
|
|
if (sensor_data == NULL || !can_send_sensor_frame()) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>뻥<EFBFBD><EBBBA5><EFBFBD><EFBFBD>
|
|||
|
|
if (s_is_payload_packing) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
s_is_payload_packing = true;
|
|||
|
|
|
|||
|
|
if (!app_calibration_build_sensor8bit_payload(sensor_data, sensor_data_payload, (uint16_t)sizeof(sensor_data_payload), &payload_len)) {
|
|||
|
|
s_is_payload_packing = false;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
(void)mozen_protocol_send_frame(&g_mozen_prot, 0x01U, sensor_data_payload, payload_len, false);
|
|||
|
|
|
|||
|
|
s_is_payload_packing = false;
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Send 16-bit sensor frame through Mozen protocol
|
|||
|
|
* @param sensor_data 16-bit sensor matrix
|
|||
|
|
* @return 1 on success, 0 on failure or busy
|
|||
|
|
*/
|
|||
|
|
uint8_t send_sensor_frame_16bit(const uint16_t (*sensor_data)[MT_AY_NUM])
|
|||
|
|
{
|
|||
|
|
uint16_t payload_len = 0U;
|
|||
|
|
|
|||
|
|
if (sensor_data == NULL || !can_send_sensor_frame()) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>뻥<EFBFBD><EBBBA5><EFBFBD><EFBFBD>
|
|||
|
|
if (s_is_payload_packing) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
s_is_payload_packing = true;
|
|||
|
|
|
|||
|
|
if (!app_calibration_build_sensor16bit_payload(sensor_data, sensor_data_payload, (uint16_t)sizeof(sensor_data_payload), &payload_len)) {
|
|||
|
|
s_is_payload_packing = false;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
(void)mozen_protocol_send_frame(&g_mozen_prot, 0x01U, sensor_data_payload, payload_len, false);
|
|||
|
|
|
|||
|
|
s_is_payload_packing = false;
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Legacy compatibility wrappers */
|
|||
|
|
#if APP_CALI_ENABLE_LEGACY_API
|
|||
|
|
uint8_t array_resi_params_write(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
return app_math_write_temp_params(data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t array_resi_params_save(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
return app_math_save_params(data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t clear_array_init_info(void)
|
|||
|
|
{
|
|||
|
|
return app_math_clear_params();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t return_array_resi_init_info(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
return app_math_read_temp_params(response_buf, response_len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t return_flash_array_resi_init_info(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
return app_math_read_solidified_params(response_buf, response_len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pressure_params_t *init_pressure_params(void)
|
|||
|
|
{
|
|||
|
|
return app_pressure_init();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t write_temp_pressure_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
return app_pressure_write_temp_params(data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t read_temp_pressure_params(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
return app_pressure_read_temp_params(response_buf, response_len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t write_solidified_pressure_params(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
return app_pressure_save_params(data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t read_solidified_pressure_params(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
return app_pressure_read_solidified_params(response_buf, response_len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t clear_pressure_params_from_flash(void)
|
|||
|
|
{
|
|||
|
|
return app_pressure_clear_params();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void write_cali_params_to_ram(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
(void)app_map_write_temp_params(data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t save_cali_params_to_flash(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
return app_map_save_params(data, len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t clear_cali_params_from_flash(void)
|
|||
|
|
{
|
|||
|
|
return app_map_clear_params();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t read_cali_params_from_ram(uint8_t *response_buf, uint16_t *response_len)
|
|||
|
|
{
|
|||
|
|
return app_map_read_temp_params(response_buf, response_len);
|
|||
|
|
}
|
|||
|
|
#endif
|