/*
 * @Date: 2025-07-01 17:18:13
 * @Author: mypx
 * @LastEditors: mypx mypx_coder@163.com
 * @LastEditTime: 2025-07-22 10:24:02
 * @FilePath: h05_pos_control.h
 * @Description: 
 * Copyright (c) 2025 by mypx, All Rights Reserved.
 */
#ifndef __H05_POS_CONTROL_H__
#define __H05_POS_CONTROL_H__
#include "sv_common.h"
// H05.00 - H05.09
#define REG_H05_00_POSITION_CMD_SRC 0x0500 // Position Command Source
/**
 * @enum SV630P_PositionCommandSource
 * @brief Position command source enumeration
 * Defines available position command sources in position control mode
 */
typedef enum
{
    SV630P_POS_CMD_PULSE         = 0,      /**< Pulse command: external pulse input via hardware terminal (selected by H05.01) */
    SV630P_POS_CMD_STEP          = 1,      /**< Step amount: set by H05.05, triggered by DI function FunIN.20 */
    SV630P_POS_CMD_MULTI_SEGMENT = 2,      /**< Multi-segment position command: configured by H11 group, triggered by DI function FunIN.28 */
} SV630P_PositionCommandSource;
#define REG_H05_01_PULSE_INPUT_MODE 0x0501 // Pulse Input Terminal Mode
/**
 * @enum SV630P_PulseInputMode
 * @brief Pulse input mode enumeration
 * Defines available hardware input terminal modes when position command source is pulse command
 */
typedef enum
{
    SV630P_PULSE_INPUT_LOW_SPEED  = 0,  /**< Low speed mode: use low-speed terminal (max 200kpps) */
    SV630P_PULSE_INPUT_HIGH_SPEED = 1,  /**< High speed mode: use high-speed terminal (max 4Mpps) */
} SV630P_PulseInputMode;
#define REG_H05_02_POSITION_UNIT 0x0502 // Position Units per Motor Revolution
// 0P/Rev~1048576P/Rev
#define POSITION_UNIT_MIN                0
#define POSITION_UNIT_MAX                1048576
#define REG_H05_03_RESERVED              0x0503 // Reserved
#define REG_H05_04_FILTER_TIME_CONST     0x0504 // 1st Order Low Pass Filter Time Constant
#define REG_H05_05_STEP_AMOUNT           0x0505 // Step Amount
#define REG_H05_06_AVG_FILTER_TIME_CONST 0x0506 // Average Filter Time Constant
#define REG_H05_07_GEAR_NUMERATOR        0x0507 // Electronic Gear Numerator 1
#define REG_H05_08_RESERVED              0x0508 // Reserved
#define REG_H05_09_GEAR_DENOMINATOR      0x0509 // Electronic Gear Denominator 1

// H05.10 - H05.19
#define REG_H05_10_POSITION_LOOP_GAIN        0x050A // Position Loop Gain
#define REG_H05_11_POSITION_INTEGRAL_GAIN    0x050B // Position Integral Gain
#define REG_H05_12_POSITION_FEEDFORWARD_GAIN 0x050C // Position Feedforward Gain
#define REG_H05_13_VELOCITY_FEEDFORWARD_GAIN 0x050D // Velocity Feedforward Gain
#define REG_H05_14_POSITION_DEADBAND         0x050E // Position Deadband
#define REG_H05_15_PULSE_CMD_TYPE            0x050F // Pulse Command Type
/**
 * @enum SV630P_PulseCommandType
 * @brief Pulse command type enumeration (H05.15)
 */
typedef enum
{
    SV630P_PULSE_TYPE_DIR_PULSE_POS = 0,        /**< Direction + pulse (positive logic) */
    SV630P_PULSE_TYPE_DIR_PULSE_NEG = 1,        /**< Direction + pulse (negative logic) */
    SV630P_PULSE_TYPE_AB_QUADRATURE = 2,        /**< A phase + B phase quadrature pulse */
    SV630P_PULSE_TYPE_CW_CCW_PULSE  = 3,        /**< CW + CCW pulse */
} SV630P_PulseCommandType;
#define REG_H05_16_RESERVED              0x0510 // Reserved
#define REG_H05_17_PULSE_INPUT_LOGIC     0x0511 // Pulse Input Logic Selection
#define REG_H05_18_PULSE_OUTPUT_MODE     0x0512 // Pulse Output Mode
#define REG_H05_19_PULSE_OUTPUT_POLARITY 0x0513 // Pulse Output Polarity

// H05.20 - H05.29
#define REG_H05_20_POSITION_COMPLETE_COND  0x0514 // Position Complete Condition
#define REG_H05_21_POSITION_WINDOW         0x0515 // Position Complete Threshold
#define REG_H05_22_VELOCITY_WINDOW         0x0516 // Velocity Complete Threshold
#define REG_H05_23_TORQUE_WINDOW           0x0517 // Torque Complete Threshold
#define REG_H05_24_POSITION_LIMIT_POSITIVE 0x0518 // Positive Position Limit
#define REG_H05_25_POSITION_LIMIT_NEGATIVE 0x0519 // Negative Position Limit
#define REG_H05_26_SOFT_POSITION_LIMIT     0x051A // Soft Position Limit Enable
#define REG_H05_27_PULSE_OUTPUT_SCALE      0x051B // Pulse Output Scale Factor
#define REG_H05_28_RESERVED                0x051C // Reserved
#define REG_H05_29_POSITION_CMD_FILTER     0x051D // Position Command Filter

// H05.30 - H05.39
#define REG_H05_30_HOME_SEARCH_ENABLE 0x051E // Home Search Enable Control
#define REG_H05_31_HOME_SEARCH_MODE   0x051F // Home Search Mode
/**
 * @enum SV630P_HomeSearchMode
 * @brief Home search mode enumeration (H05.31)
 */
typedef enum
{
    SV630P_HOME_MODE_POS_SW_HOME_SW       = 0,  /**< Positive direction, deceleration and home are both home switch */
    SV630P_HOME_MODE_NEG_SW_HOME_SW       = 1,  /**< Negative direction, deceleration and home are both home switch */
    SV630P_HOME_MODE_POS_Z_HOME_Z         = 2,  /**< Positive direction, deceleration and home are both motor Z signal */
    SV630P_HOME_MODE_NEG_Z_HOME_Z         = 3,  /**< Negative direction, deceleration and home are both motor Z signal */
    SV630P_HOME_MODE_POS_SW_HOME_Z        = 4,  /**< Positive direction, deceleration is home switch, home is motor Z signal */
    SV630P_HOME_MODE_NEG_SW_HOME_Z        = 5,  /**< Negative direction, deceleration is home switch, home is motor Z signal */
    SV630P_HOME_MODE_POS_LIMIT_POS_LIMIT  = 6,  /**< Positive direction, deceleration and home are positive overtravel switch */
    SV630P_HOME_MODE_NEG_LIMIT_NEG_LIMIT  = 7,  /**< Negative direction, deceleration and home are negative overtravel switch */
    SV630P_HOME_MODE_POS_LIMIT_HOME_Z     = 8,  /**< Positive direction, deceleration is positive overtravel, home is motor Z */
    SV630P_HOME_MODE_NEG_LIMIT_HOME_Z     = 9,  /**< Negative direction, deceleration is negative overtravel, home is motor Z */
    SV630P_HOME_MODE_POS_LIMIT_POS_LIMIT2 = 10, /**< Positive direction, deceleration and home are mechanical limit */
    SV630P_HOME_MODE_NEG_LIMIT_NEG_LIMIT2 = 11, /**< Negative direction, deceleration and home are mechanical limit */
    SV630P_HOME_MODE_POS_LIMIT_HOME_Z2    = 12, /**< Positive direction, deceleration is mechanical limit, home is motor Z */
    SV630P_HOME_MODE_NEG_LIMIT_HOME_Z2    = 13, /**< Negative direction, deceleration is mechanical limit, home is motor Z */
    SV630P_HOME_MODE_POS_SINGLE_TURN      = 14, /**< Positive single-turn homing */
    SV630P_HOME_MODE_NEG_SINGLE_TURN      = 15, /**< Negative single-turn homing */
    SV630P_HOME_MODE_NEAREST_SINGLE_TURN  = 16, /**< Nearest single-turn homing */
} SV630P_HomeSearchMode;
#define REG_H05_32_HOME_SEARCH_SPEED1    0x0520 // Home Search Speed 1
#define REG_H05_33_HOME_SEARCH_SPEED2    0x0521 // Home Search Speed 2
#define REG_H05_34_HOME_SEARCH_ACCEL     0x0522 // Home Search Acceleration
#define REG_H05_35_HOME_SEARCH_DECEL     0x0523 // Home Search Deceleration
#define REG_H05_36_HOME_OFFSET           0x0524 // Home Position Offset
#define REG_H05_37_HOME_SEARCH_DIRECTION 0x0525 // Home Search Direction
#define REG_H05_38_PULSE_OUTPUT_SRC      0x0526 // Servo Pulse Output Source
/**
 * @enum SV630P_PulseOutputSource
 * @brief Pulse output source enumeration (H05.38)
 */
typedef enum
{
    SV630P_PULSE_OUTPUT_ENCODER  = 0,          /**< Encoder frequency division output */
    SV630P_PULSE_OUTPUT_COMMAND  = 1,          /**< Command pulse synchronous output */
    SV630P_PULSE_OUTPUT_DISABLED = 2,          /**< Output disabled */
} SV630P_PulseOutputSource;
#define REG_H05_39_PULSE_OUTPUT_DIVISOR 0x0527 // Pulse Output Divisor
/**
 * @enum SV630P_GearRatioSwitchCondition
 * @brief Electronic gear ratio switch condition enumeration (H05.39)
 */
typedef enum
{
    SV630P_GEAR_SWITCH_ZERO_COMMAND = 0, /**< Switch when position command is 0 for 2.5ms, DI function 24 required */
    SV630P_GEAR_SWITCH_REALTIME     = 1, /**< Real-time switch */
} SV630P_GearRatioSwitchCondition;

// H05.40 - H05.49
#define REG_H05_40_HOME_OFFSET_MODE 0x0527 /**< Mechanical home offset and limit handling mode */
/**
 * @enum SV630P_MechanicalHomeOffsetMode
 * @brief Mechanical home offset and limit handling mode enumeration
 * Defines the logic for mechanical home offset and limit handling during homing.
 */
typedef enum
{
    SV630P_HOME_OFFSET_ABS_RETRIGGER    = 0, //< Absolute coordinate mode, retrigger after limit for reverse homing */
    SV630P_HOME_OFFSET_REL_RETRIGGER    = 1, //< Relative offset mode, retrigger after limit for reverse homing */
    SV630P_HOME_OFFSET_ABS_AUTO_REVERSE = 2, //< Absolute coordinate mode, auto reverse after limit for homing */
    SV630P_HOME_OFFSET_REL_AUTO_REVERSE = 3, //< Relative offset mode, auto reverse after limit for homing */
} SV630P_MechanicalHomeOffsetMode;
#define REG_H05_41_Z_PULSE_POLARITY 0x0529   // Z Pulse Output Polarity
/**
 * @enum SV630P_ZPulsePolarity
 * @brief Z pulse output polarity enumeration (H05.41)
 */
typedef enum
{
    SV630P_Z_PULSE_NEGATIVE = 0,               /**< Negative polarity: Z pulse active low */
    SV630P_Z_PULSE_POSITIVE = 1,               /**< Positive polarity: Z pulse active high */
} SV630P_ZPulsePolarity;
#define REG_H05_42_MARK_PULSE_WIDTH     0x052A // Mark Pulse Width
#define REG_H05_43_MARK_PULSE_DIVISOR   0x052B // Mark Pulse Divisor
#define REG_H05_44_POSITION_ERROR_LIMIT 0x052C // Position Error Limit

// H05.46 Absolute position linear mode position offset (low 32 bits)
#define REG_H05_46_ABS_POS_LINEAR_OFFSET_LOW  0x052E
#define REG_H05_48_ABS_POS_LINEAR_OFFSET_HIGH 0x0530

// H05.50 Absolute position rotary mode mechanical gear ratio (numerator)
#define REG_H05_50_ABS_ROT_GEAR_NUMERATOR   0x0532
#define REG_H05_51_ABS_ROT_GEAR_DENOMINATOR 0x0533

// H05.52 Absolute position rotary mode load rotation 1 turn pulse count (low 32 bits)
#define REG_H05_52_ABS_ROT_LOAD_PULSE_LOW  0x0534
#define REG_H05_54_ABS_ROT_LOAD_PULSE_HIGH 0x0536
// H05.56 Mechanical touch zero speed threshold
#define REG_H05_56_MECH_TOUCH_ZERO_SPEED 0x0538
// H05.57 Mechanical limit judgment count
#define REG_H05_57_MECH_LIMIT_COUNT 0x0539
// H05.58 Mechanical touch zero torque threshold
#define REG_H05_58_MECH_TOUCH_ZERO_TORQUE 0x053A
// H05.59 Position window time
#define REG_H05_59_POSITION_WINDOW_TIME 0x053B
// H05.60 Position complete hold time
#define REG_H05_60_POSITION_HOLD_TIME 0x053C
// H05.61 Encoder frequency division pulse output (32 bits)
#define REG_H05_61_ENCODER_DIV_PULSE_OUTPUT 0x053D
// H05.63 Position command source real-time update enable
#define REG_H05_63_POS_CMD_SRC_REALTIME_EN 0x053F
// H05.66 Homing time unit selection
#define REG_H05_66_HOME_TIME_UNIT 0x0542
// H05.67 Zero and single-turn absolute position offset
#define REG_H05_67_ZERO_SINGLE_TURN_OFFSET 0x0543

// H05.69 Homing assist function
#define REG_H05_69_HOME_ASSIST_FUNC 0x0545

/**
 * @defgroup SV630P_Constants Common constant definitions
 * @{
 */
#define SV630P_MAX_POSITION_ERROR 65535   /**< Maximum position error value */
#define SV630P_MAX_VELOCITY       10000   /**< Maximum velocity value (rpm) */
#define SV630P_MAX_ACCELERATION   10000   /**< Maximum acceleration value (rpm/s) */
#define SV630P_MIN_FILTER_TIME    0.0f    /**< Minimum filter time (ms) */
#define SV630P_MAX_FILTER_TIME    6553.5f /**< Maximum filter time (ms) */

#if defined(__cplusplus)
extern "C"
{
#endif
/**
 * @brief Read main position command source
 * @param dev Pointer to servo handle
 * @param src Pointer to store the read command source
 * @return SV630P_OK on success, error code otherwise
 * @note In position control mode, used to select the position command source.
 *       Pulse command is external, step and multi-segment are internal.
 */
int sv630p_h05_00_read_command_source(sv630p_handle_t *dev, SV630P_PositionCommandSource *src);

/**
 * @brief Write main position command source
 * @param dev Pointer to servo handle
 * @param src Command source to write
 * @return SV630P_OK on success, error code otherwise
 */
int sv630p_h05_00_write_command_source(sv630p_handle_t *dev, SV630P_PositionCommandSource src);

/**
 * @brief Read pulse input mode
 * @param dev Pointer to servo handle
 * @param mode Pointer to store the read pulse input mode
 * @return SV630P_OK on success, error code otherwise
 */
int sv630p_h05_01_read_pulse_input_mode(sv630p_handle_t *dev, SV630P_PulseInputMode *mode);

int sv630p_h05_01_write_pulse_input_mode(sv630p_handle_t *dev, SV630P_PulseInputMode mode);

int sv630p_h05_02_read_position_unit(sv630p_handle_t *dev, uint16_t *unit);

int sv630p_h05_02_read_position_unit(sv630p_handle_t *dev, uint16_t *unit);

#if defined(__cplusplus)
}
#endif

#endif // __SV_POS_CONTROL_H__
