polarimeter_software/User/driver/sv630p/sv_device.c
2025-09-30 10:37:23 +08:00

172 lines
4.9 KiB
C

/*
* @Date: 2025-07-02 13:22:04
* @Author: mypx
* @LastEditors: mypx mypx_coder@163.com
* @LastEditTime: 2025-09-12 13:59:23
* @FilePath: sv_device.c
* @Description:
* Copyright (c) 2025 by mypx, All Rights Reserved.
*/
#include "sv_device.h"
#include "etk_utils.h"
#include "et_log.h"
#include "h02_basic_control.h"
#include "h03_di_do.h"
#include "h05_pos_control.h"
#include "h06_speed_control.h"
#include "h0d_af.h"
#include "h31_comm_related_var.h"
// FIXME: this function is not debug
int sv630p_position_mode_init(sv630p_handle_t *dev)
{
sv630p_h02_00_write_control_mode(dev, SV630P_CONTROL_MODE_POSITION);
sv630p_h05_00_write_command_source(dev, SV630P_POS_CMD_STEP);
// 关键DI配置
sv630p_h03_01_write_power_on_di_func_assign2(dev, SV630P_FunIN_1_S_ON);
sv630p_h03_01_write_power_on_di_func_assign2(dev, SV630P_FunIN_27_POSDirSel);
sv630p_h03_02_write_di1_function_selection(dev, DI_FUNC_CLEAR_POS_ERROR);
// 关键DO配置
return 0;
}
int sv630p_speed_mode_init(sv630p_handle_t *dev)
{
int ret = 0;
dev->rpm = 0;
dev->dir = SV630P_DIR_UNKNOWN;
ret = sv630p_h02_00_write_control_mode(dev, SV630P_CONTROL_MODE_SPEED);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
// ret = sv630p_h06_00_write_main_speed_cmd_a_src(dev, DIGITAL_VALUE_SPECIFIED_CMD_A);
// ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
ret = sv630p_h06_02_write_speed_cmd_select(dev, SV630P_SPEED_CMD_COMMUNICATION);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
return 0;
err:
dev->is_error = true;
ET_ERR("Failed to init speed mode: %d", ret);
return -1;
}
int sv630p_speed_mode_start(sv630p_handle_t *dev, double rpm)
{
int ret = 0;
//ET_INFO("Start speed mode, rpm:%d", (int)rpm);
ret = sv630p_h31_09_write_speed_command(dev, rpm);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
ret = sv630p_h0d_17_write_force_output_mode(dev, SV630P_DIDO_FORCE_DI_ENABLE);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
/* FIXME: The default function of DI5 is servo enabling. Please check the function selection
of the H03.10 - DI5 terminal and the logic selection of the H03.11 - DI5 terminal.*/
ret = sv630p_h0d_18_write_force_input_bits(dev, NOT_CONCERN_BIT, DI5_BIT);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
dev->last_rpm = rpm;
dev->rpm = rpm;
dev->dir = rpm > 0 ? SV630P_DIR_FORWARD : SV630P_DIR_BACKWARD;
return 0;
err:
ET_ERR("Failed to start speed mode: %d", ret);
dev->is_error = true;
return -1;
}
int sv630p_speed_mode_resume(sv630p_handle_t *dev)
{
return sv630p_speed_mode_start(dev, dev->last_rpm);
}
int sv630p_speed_update(sv630p_handle_t *dev, double rpm)
{
int ret = 0;
SV630P_Dir dir = rpm > 0 ? SV630P_DIR_FORWARD : SV630P_DIR_BACKWARD;
if (ETK_FLOAT_ALMOST_EQUAL(dev->rpm, rpm, 0.005))
{
//ET_DBG("rpm diff small %.2f", rpm);
return 0;
}
dev->last_rpm = rpm;
if (dev->dir != dir)
{
ret = sv630p_speed_mode_stop(dev);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
rt_thread_mdelay(50); // 等待停止完成
ret = sv630p_speed_mode_start(dev, rpm);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
}
else
{
ET_INFO("Update rpm: %.2f", rpm);
ret = sv630p_h31_09_write_speed_command(dev, rpm);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
dev->rpm = rpm;
dev->dir = dir;
}
return 0;
err:
dev->is_error = true;
ET_ERR("Failed to start speed mode: %d", ret);
return -1;
}
int sv630p_dir_change(sv630p_handle_t *dev)
{
int ret = 0;
double rpm = dev->last_rpm * -1.0;
ET_INFO("Change dir, rpm:%d", (int)rpm);
ret = sv630p_speed_mode_stop(dev);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
rt_thread_mdelay(50); // 等待停止完成
ret = sv630p_speed_mode_start(dev, rpm);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
return 0;
err:
dev->is_error = true;
ET_ERR("Failed to change direction: %d", ret);
return -1;
}
int sv630p_speed_mode_stop(sv630p_handle_t *dev)
{
int ret = 0;
ret = sv630p_h0d_17_write_force_output_mode(dev, SV630P_DIDO_FORCE_NONE);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
/* FIXME: The default function of DI5 is servo enabling. Please check the function selection
of the H03.10 - DI5 terminal and the logic selection of the H03.11 - DI5 terminal.*/
ret = sv630p_h0d_18_write_force_input_bits(dev, DI5_BIT, NOT_CONCERN_BIT);
ERR_CHECK_RET_NONZERO_ACT(ret, { goto err; });
//ET_DBG("Servo STOP from dir:%d", dev->dir);
dev->rpm = 0;
dev->dir = SV630P_DIR_STOP;
return 0;
err:
dev->is_error = true;
ET_ERR("Failed to stop speed mode: %d", ret);
return -1;
}
double sv630p_get_last_rpm(sv630p_handle_t *dev)
{
return dev->last_rpm;
}
SV630P_Dir sv630p_get_dir(sv630p_handle_t *dev)
{
return dev->dir;
}