/* * @Author: mypx * @Date: 2025-09-18 09:52:47 * @LastEditTime: 2025-09-26 13:22:46 * @LastEditors: mypx mypx_coder@163.com * @Description: */ #include "mb_interface.h" #include "et_log.h" #include "etk_byte_conv.h" #include "mb_command.h" #include "user_config.h" #include /** * @brief Initialize Modbus interface module * 初始化Modbus接口模块 */ void mb_interface_init(void) { mb_command_t *mb = get_command_instance(); if (mb) { // Clear history data in the protocol cache if (mb->input_lock != RT_NULL) rt_mutex_take(mb->input_lock, RT_WAITING_FOREVER); memset(&mb->input_regs[0], 0, sizeof(mb->input_regs)); /* set device model and firmware version * - Device model: pack up to 4 ASCII chars from PM_DEVICE_MODE into two 16-bit registers. * Each register stores two bytes: high byte = char[i], low byte = char[i+1]. * - Firmware version: pack major/minor into INPUT_REG_FW_VERSION_H (major in high byte, * minor in low byte). Pack rev/build into INPUT_REG_FW_VERSION_L similarly. */ { const char *m = PM_DEVICE_MODE; uint16_t dm_hi = 0, dm_lo = 0; uint8_t c0 = (m[0] != '\0') ? (uint8_t)m[0] : 0; uint8_t c1 = (m[1] != '\0') ? (uint8_t)m[1] : 0; uint8_t c2 = (m[2] != '\0') ? (uint8_t)m[2] : 0; uint8_t c3 = (m[3] != '\0') ? (uint8_t)m[3] : 0; dm_hi = (uint16_t)((c0 << 8) | c1); dm_lo = (uint16_t)((c2 << 8) | c3); mb->input_regs[INPUT_REG_DEVICE_MODEL_H] = dm_hi; mb->input_regs[INPUT_REG_DEVICE_MODEL_L] = dm_lo; uint16_t fw_hi = (uint16_t)(((uint16_t)(PM_DEVICE_VER_MAJOR & 0xFF) << 8) | (uint16_t)(PM_DEVICE_VER_MINOR & 0xFF)); uint16_t fw_lo = (uint16_t)(((uint16_t)(PM_DEVICE_VER_REV & 0xFF) << 8) | (uint16_t)(PM_DEVICE_VER_BUILD & 0xFF)); mb->input_regs[INPUT_REG_FW_VERSION_H] = fw_hi; mb->input_regs[INPUT_REG_FW_VERSION_L] = fw_lo; } if (mb->input_lock != RT_NULL) rt_mutex_release(mb->input_lock); } ET_INFO("Modbus interface initialized successfully"); } /** * @brief Write current temperature data * 写入当前温度数据 * * @param temp Temperature value to write (°C) */ void mb_write_current_temp(float temp) { // Check temperature alarm conditions if (temp > 100.0f || temp < -10.0f) { mb_sync_exception_reg(PM_EXCEPTION_TEMPERATURE, true); ET_WARN("Temperature out of range: %.2f°C", temp); } else { mb_sync_exception_reg(PM_EXCEPTION_TEMPERATURE, false); } mb_sync_realtime_temp(temp); } /** * @brief Write current rotation data * 写入当前旋光度数据 * * @param rotation Rotation value to write (°) */ void mb_write_current_rotation(float rotation) { // Update protocol cache via sync helper (which converts and writes under lock) mb_sync_realtime_rotation(rotation); } /** * @brief Write measurement result * 写入测量结果 * * @param mode Measurement mode (0-3) * @param value Measurement value * @param temp Temperature at measurement time (°C) */ void mb_write_measurement_result(uint8_t mode, float value, float temp) { // Update protocol cache via sync helper (atomic under lock) mb_sync_result(mode, value, temp); // mark measurement complete in running state //mb_sync_running_state(PM_READY_STATE); // Save to history (writes into protocol cache directly) mb_save_to_history(value, temp); ET_INFO("Measurement result updated: mode=%d, value=%.4f, temp=%.2f\u00b0C", mode, value, temp); } /** * @brief Get current target temperature * 获取当前目标温度设置 * * @return Target temperature value (°C) */ float mb_get_target_temp(void) { mb_command_t *mb = get_command_instance(); if (!mb) return 0.0f; // target temp is held in holding regs (regs array) at HOLD_REG_TARGET_TEMP_H/L uint16_t h = mb->regs[HOLD_REG_TARGET_TEMP_H]; uint16_t l = mb->regs[HOLD_REG_TARGET_TEMP_L]; return et_mb_to_float_abcd(h, l); } /** * @brief Get current tube length setting * 获取当前旋光管长度设置 * * @return Tube length value (mm) */ float mb_get_tube_length(void) { mb_command_t *mb = get_command_instance(); if (!mb) return 0.0f; uint16_t h = mb->regs[HOLD_REG_TUBE_LEN]; return h; } /** * @brief Get current measurement mode * 获取当前测量模式 * * @return Measurement mode code (0-3) */ uint8_t mb_get_measure_mode(void) { mb_command_t *mb = get_command_instance(); if (!mb) return 0; return (uint8_t)(mb->regs[HOLD_REG_MEAS_MODE] & 0xFF); } /** * @brief Get current auto measurement count * 获取当前自动测量次数设置 * * @return Auto measurement count (1-255) */ uint8_t mb_get_auto_measure_count(void) { mb_command_t *mb = get_command_instance(); if (!mb) return 0; return (uint8_t)(mb->regs[HOLD_REG_AUTO_MEAS_CNT] & 0xFF); } /** * @brief Get current running state * 获取当前运行状态 * * @return Running state code */ PmRunningState mb_get_running_state(void) { mb_command_t *mb = get_command_instance(); if (!mb) return PM_READY_STATE; return (PmRunningState)(mb->input_regs[INPUT_REG_DEV_RUNNING_STATE] & 0xFF); } /** * @brief Check if measurement is complete * 检查测量是否完成 * * @return 1 if complete, 0 otherwise */ uint8_t mb_is_measure_complete(void) { mb_command_t *mb = get_command_instance(); if (!mb) return 0; return (uint8_t)(mb->input_regs[INPUT_REG_MEAS_DONE_FLAG] & 0xFF); }