/*
 * @Date: 2025-07-18 08:53:16
 * @Author: mypx
 * @LastEditors: mypx mypx_coder@163.com
 * @LastEditTime: 2025-10-14 13:56:58
 * @FilePath: pm_common.h
 * @Description: 
 * Copyright (c) 2025 by mypx, All Rights Reserved.
 */
#ifndef __PM_COMMON__
#define __PM_COMMON__
#include "bsp_encoder.h"
#include "bsp_misc.h"
#include <rtthread.h>
#include <stdint.h>

#define DATA_PROCESS_STACK_SIZE (3 * 1024)
#define DATA_PROCESS_PRIORITY   10
#define HMI_THREAD_STACK_SIZE 2048
#define HMI_THREAD_PRIORITY   9

#define TEC_CONTROL_THREAD_PRIORITY   25
#define TEC_CONTROL_THREAD_STACK_SIZE 2048
#define TEC_CONTROL_THREAD_TIMESLICE  5

#define TEMP_SAMPLE_THREAD_PRIORITY   5
#define TEMP_SAMPLE_THREAD_STACK_SIZE 2048
#define TEMP_SAMPLE_THREAD_TIMESLICE  5

#define PM_EVT_QUEUE_FULL        (1 << 0)
#define PM_EVT_ENCODER_TO_TARGET (1 << 1)


extern struct rt_event pm_event;
extern uint32_t        encoder_cpr;

// device exception code
#define PM_EXCEPTION_NONE          (0x00)
#define PM_EXCEPTION_TEMPERATURE   (1 << 0)


typedef enum
{
    PM_PREPARE_STATE = 0, // 初始化状态
    PM_IDLE_STATE,        // 空闲状态
    PM_CALI_STATE,        // 校准状态
    PM_READY_STATE,       // 准备就绪
    PM_MEAS_STATE,        // 测量中

    // TODO:删除下面的状态
    RUNNING_STATE_PROCESSING, // 数据处理
    RUNNING_STATE_FINISHED,   // 测量完成
    RUNNING_STATE_ERROR       // 错误状态
} PmRunningState;

typedef enum
{
    PM_MEAS_NORMAL_Mode = 0, // normal working state, should manual click start measure button
    PM_MEAS_AUTO_Mode,       // auto working state, not need click start measure button
    PM_MEAS_TEST_Mode,       // factory test state
} PmMeasMode;

typedef int32_t (*mb_read_t)(uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg);
typedef int32_t (*mb_write_t)(const uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg);

double get_real_time_angle_degree(void);

rt_uint32_t convert_encoder_angle_rpm_to_to_time(double angle, float m_rpm);

/**
 * @brief Correct specific rotation for temperature using linear coefficient
 * @param specific_rotation_ref Specific rotation at reference temperature (°)
 * @param tref Reference temperature (°C)
 * @param temp Target temperature (°C)
 * @param temp_coeff Temperature coefficient (° per °C)
 * @return Corrected specific rotation at target temperature (°)
 */
float pm_correct_specific_rotation_temperature(float specific_rotation_ref, float tref, float temp, float temp_coeff);

/**
 * @brief Convert concentration from g/100mL to g/mL
 * @param conc_g_per_100ml Concentration in g/100mL
 * @return Concentration in g/mL
 */
float pm_convert_g_per_100ml_to_g_per_ml(float conc_g_per_100ml);

/**
 * @brief Convert concentration from g/100mL to mol/L
 * @param conc_g_per_100ml Concentration in g/100mL
 * @param molar_mass_g_per_mol Molar mass of solute in g/mol
 * @return Concentration in mol/L
 */
float pm_convert_g_per_100ml_to_molar(float conc_g_per_100ml, float molar_mass_g_per_mol);

/**
 * @brief Angle conversion helpers
 */
float pm_deg_to_rad(float deg);
float pm_rad_to_deg(float rad);

#endif
