/*
 * @Date: 2025-07-01 10:50:37
 * @Author: mypx
 * @LastEditors: mypx mypx_coder@163.com
 * @LastEditTime: 2025-07-02 16:35:55
 * @FilePath: h03_di_do.h
 * @Description: 
 * Copyright (c) 2025 by mypx, All Rights Reserved.
 */
#ifndef __H03_DI_DO_H__
#define __H03_DI_DO_H__
#include "sv_common.h"

typedef struct
{
    SV630P_DIDO_FunIN funin; // DI function enum
    uint16_t          mask;  // Corresponding bit mask
    const char       *desc;  // Function description string
} funin_map_entry_t;

#define FUNIN_MAP_SIZE(x) (sizeof(x) / sizeof(x[0]))

/* H03.00: Power-on DI function assignment 1 */
#define REG_H03_00_POWER_ON_DI1 0x0300

typedef enum
{
    SV630P_DIFUNC1_NONE     = 0x0000, /**< No defined function - value 0 */
    SV630P_DIFUNC1_FUNIN_1  = 0x0001, /**< FunIN.1 function - value 1 */
    SV630P_DIFUNC1_FUNIN_2  = 0x0002, /**< FunIN.2 function - value 2 */
    SV630P_DIFUNC1_FUNIN_3  = 0x0004, /**< FunIN.3 function - value 4 */
    SV630P_DIFUNC1_FUNIN_4  = 0x0008, /**< FunIN.4 function - value 8 */
    SV630P_DIFUNC1_FUNIN_5  = 0x0010, /**< FunIN.5 function - value 16 */
    SV630P_DIFUNC1_FUNIN_6  = 0x0020, /**< FunIN.6 function - value 32 */
    SV630P_DIFUNC1_FUNIN_7  = 0x0040, /**< FunIN.7 function - value 64 */
    SV630P_DIFUNC1_FUNIN_8  = 0x0080, /**< FunIN.8 function - value 128 */
    SV630P_DIFUNC1_FUNIN_9  = 0x0100, /**< FunIN.9 function - value 256 */
    SV630P_DIFUNC1_FUNIN_10 = 0x0200, /**< FunIN.10 function - value 512 */
    SV630P_DIFUNC1_FUNIN_11 = 0x0400, /**< FunIN.11 function - value 1024 */
    SV630P_DIFUNC1_FUNIN_12 = 0x0800, /**< FunIN.12 function - value 2048 */
    SV630P_DIFUNC1_FUNIN_13 = 0x1000, /**< FunIN.13 function - value 4096 */
    SV630P_DIFUNC1_FUNIN_14 = 0x2000, /**< FunIN.14 function - value 8192 */
    SV630P_DIFUNC1_FUNIN_15 = 0x4000, /**< FunIN.15 function - value 16384 */
} SV630P_FuncTypeMask1;

/* H03.01: Power-on DI function assignment 2 */
#define REG_H03_01_POWER_ON_DI2 0x0301

typedef enum
{
    SV630P_DIFUNC2_NONE     = 0x0000, /**< No defined function - value 0 */
    SV630P_DIFUNC2_FUNIN_17 = 0x0001, /**< FunIN.17 function - value 1 (bit 0 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_18 = 0x0002, /**< FunIN.18 function - value 2 (bit 1 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_19 = 0x0004, /**< FunIN.19 function - value 4 (bit 2 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_20 = 0x0008, /**< FunIN.20 function - value 8 (bit 3 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_21 = 0x0010, /**< FunIN.21 function - value 16 (bit 4 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_22 = 0x0020, /**< FunIN.22 function - value 32 (bit 5 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_23 = 0x0040, /**< FunIN.23 function - value 64 (bit 6 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_24 = 0x0080, /**< FunIN.24 function - value 128 (bit 7 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_25 = 0x0100, /**< FunIN.25 function - value 256 (bit 8 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_26 = 0x0200, /**< FunIN.26 function - value 512 (bit 9 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_27 = 0x0400, /**< FunIN.27 function - value 1024 (bit 10 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_28 = 0x0800, /**< FunIN.28 function - value 2048 (bit 11 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_29 = 0x1000, /**< FunIN.29 function - value 4096 (bit 12 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_30 = 0x2000, /**< FunIN.30 function - value 8192 (bit 13 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_31 = 0x4000, /**< FunIN.31 function - value 16384 (bit 14 of high 16 bits) */
    SV630P_DIFUNC2_FUNIN_32 = 0x8000  /**< FunIN.32 function - value 32768 (bit 15 of high 16 bits) */
} SV630P_FuncTypeMask2;

typedef enum
{
    DI_FUNC_NONE                   = 0,  // 0: No defined function
    DI_FUNC_SERVO_ENABLE           = 1,  // 1: Servo enable
    DI_FUNC_ALARM_RESET            = 2,  // 2: Alarm reset signal
    DI_FUNC_GAIN_SWITCH            = 3,  // 3: Gain switch
    DI_FUNC_MAIN_AUX_SWITCH        = 4,  // 4: Main/auxiliary command switch
    DI_FUNC_MULTI_SEG_DIR          = 5,  // 5: Multi-segment direction selection
    DI_FUNC_MULTI_SEG_CMD1         = 6,  // 6: Multi-segment command switch CMD1
    DI_FUNC_MULTI_SEG_CMD2         = 7,  // 7: Multi-segment command switch CMD2
    DI_FUNC_MULTI_SEG_CMD3         = 8,  // 8: Multi-segment command switch CMD3
    DI_FUNC_MULTI_SEG_CMD4         = 9,  // 9: Multi-segment command switch CMD4
    DI_FUNC_MODE_SWITCH_M1         = 10, // 10: Mode switch M1-SEL
    DI_FUNC_MODE_SWITCH_M2         = 11, // 11: Mode switch M2-SEL
    DI_FUNC_ZERO_POS_LOCK          = 12, // 12: Zero position lock enable
    DI_FUNC_POS_CMD_PROHIBIT       = 13, // 13: Position command prohibit
    DI_FUNC_OVERRUN_POSITIVE       = 14, // 14: Positive overtravel switch
    DI_FUNC_OVERRUN_NEGATIVE       = 15, // 15: Negative overtravel switch
    DI_FUNC_TORQUE_LIMIT_POSITIVE  = 16, // 16: Positive external torque limit
    DI_FUNC_TORQUE_LIMIT_NEGATIVE  = 17, // 17: Negative external torque limit
    DI_FUNC_JOG_POSITIVE           = 18, // 18: Jog command +
    DI_FUNC_JOG_NEGATIVE           = 19, // 19: Jog command -
    DI_FUNC_STEP_ENABLE            = 20, // 20: Step enable
    DI_FUNC_HANDWHEEL_RATIO1       = 21, // 21: Handwheel ratio signal 1
    DI_FUNC_HANDWHEEL_RATIO2       = 22, // 22: Handwheel ratio signal 2
    DI_FUNC_HANDWHEEL_ENABLE       = 23, // 23: Handwheel enable signal
    DI_FUNC_GEAR_SELECT            = 24, // 24: Electronic gear select
    DI_FUNC_TORQUE_DIR             = 25, // 25: Torque command direction select
    DI_FUNC_SPEED_DIR              = 26, // 26: Speed command direction select
    DI_FUNC_POS_DIR                = 27, // 27: Position command direction select
    DI_FUNC_MULTI_POS_ENABLE       = 28, // 28: Multi-position command enable
    DI_FUNC_INTERRUPT_FIX_LENGTH   = 29, // 29: Interrupt fixed length state release
    DI_FUNC_NO_FUNCTION            = 30, // 30: None
    DI_FUNC_HOME_SWITCH            = 31, // 31: Home switch
    DI_FUNC_HOME_ENABLE            = 32, // 32: Homing enable
    DI_FUNC_INTERRUPT_FIX_PROHIBIT = 33, // 33: Interrupt fixed length prohibit
    DI_FUNC_EMERGENCY_STOP         = 34, // 34: Emergency stop
    DI_FUNC_CLEAR_POS_ERROR        = 35, // 35: Clear position error
    DI_FUNC_INTERNAL_SPEED_LIMIT   = 36, // 36: Internal speed limit source
    DI_FUNC_PULSE_CMD_PROHIBIT     = 37, // 37: Pulse command prohibit
    DI_FUNC_WRITE_CMD_INTERRUPT    = 38, // 38: Write command generates interrupt
    DI_FUNC_WRITE_CMD_NO_INTERRUPT = 39, // 39: Write command does not generate interrupt
    DI_FUNC_POS_COMPLETE_CLEAR     = 40, // 40: Clear position and command complete signal
    DI_FUNC_SET_CURRENT_AS_HOME    = 41  // 41: Set current position as home
} DiFunctionType;

// 脉冲宽度必须大于3ms才有效
typedef enum
{
    LOW_LEVEL_EFFECTIVE  = 0, // Low level active
    HIGH_LEVEL_EFFECTIVE = 1, // High level active
    DEF_LEVEL_EFFECTIVE  = LOW_LEVEL_EFFECTIVE,
} DI_LogicType;

#define REG_H03_02_DI1_FUNC  0x0302    /* H03.02: DI1 terminal function selection */
#define REG_H03_03_DI1_LOGIC 0x0303    /* H03.03: DI1 terminal logic selection */
#define REG_H03_04_DI2_FUNC  0x0304    /* H03.04: DI2 terminal function selection */
#define REG_H03_05_DI2_LOGIC 0x0305    /* H03.05: DI2 terminal logic selection */
#define REG_H03_06_DI3_FUNC  0x0306    /* H03.06: DI3 terminal function selection */
#define REG_H03_07_DI3_LOGIC 0x0307    /* H03.07: DI3 terminal logic selection */
#define REG_H03_08_DI4_FUNC  0x0308    /* H03.08: DI4 terminal function selection */
#define REG_H03_09_DI4_LOGIC 0x0309    /* H03.09: DI4 terminal logic selection */
#define REG_H03_10_DI5_FUNC  0x030A    /* H03.10: DI5 terminal function selection */
#define REG_H03_11_DI5_LOGIC 0x030B    /* H03.11: DI5 terminal logic selection */
#define REG_H03_16_DI8_FUNC  0x0310    /* H03.16: DI8 terminal function selection */
#define REG_H03_17_DI8_LOGIC 0x0311    /* H03.17: DI8 terminal logic selection */
#define REG_H03_18_DI9_FUNC  0x0312    /* H03.18: DI9 terminal function selection */
#define REG_H03_19_DI9_LOGIC 0x0313    /* H03.19: DI9 terminal logic selection */

#define REG_H03_34_POWER_ON_DI3 0x0322 /* H03.34: Power-on DI function assignment 3 */

typedef enum
{
    SV630P_DIFUNC3_NONE     = 0x0000, /**< None */
    SV630P_DIFUNC3_FUNIN_33 = 0x0001, /**< FunIN.33 */
    SV630P_DIFUNC3_FUNIN_34 = 0x0002, /**< FunIN.34 */
    SV630P_DIFUNC3_FUNIN_35 = 0x0004, /**< FunIN.35 */
    SV630P_DIFUNC3_FUNIN_36 = 0x0008, /**< FunIN.36 */
    SV630P_DIFUNC3_FUNIN_37 = 0x0010, /**< FunIN.37 */
    SV630P_DIFUNC3_FUNIN_38 = 0x0020, /**< FunIN.38 */
    SV630P_DIFUNC3_FUNIN_39 = 0x0040, /**< FunIN.39 */
    SV630P_DIFUNC3_FUNIN_40 = 0x0080, /**< FunIN.40 */
    SV630P_DIFUNC3_FUNIN_41 = 0x0100, /**< FunIN.41 */
    SV630P_DIFUNC3_FUNIN_42 = 0x0200, /**< FunIN.42 */
    SV630P_DIFUNC3_FUNIN_43 = 0x0400, /**< FunIN.43 */
    SV630P_DIFUNC3_FUNIN_44 = 0x0800, /**< FunIN.44 */
    SV630P_DIFUNC3_FUNIN_45 = 0x1000, /**< FunIN.45 */
    SV630P_DIFUNC3_FUNIN_46 = 0x2000, /**< FunIN.46 */
    SV630P_DIFUNC3_FUNIN_47 = 0x4000  /**< FunIN.47 */
} SV630P_FuncTypeMask3;

/* H03.35: Power-on DI function assignment 4 */
#define REG_H03_35_POWER_ON_DI4 0x0323

typedef enum
{
    SV630P_DIFUNC4_NONE     = 0x0000, /**< None */
    SV630P_DIFUNC4_FUNIN_49 = 0x0001, /**< FunIN.49 */
    SV630P_DIFUNC4_FUNIN_50 = 0x0002, /**< FunIN.50 */
    SV630P_DIFUNC4_FUNIN_51 = 0x0004, /**< FunIN.51 */
    SV630P_DIFUNC4_FUNIN_52 = 0x0008, /**< FunIN.52 */
    SV630P_DIFUNC4_FUNIN_53 = 0x0010, /**< FunIN.53 */
    SV630P_DIFUNC4_FUNIN_54 = 0x0020, /**< FunIN.54 */
    SV630P_DIFUNC4_FUNIN_55 = 0x0040, /**< FunIN.55 */
    SV630P_DIFUNC4_FUNIN_56 = 0x0080, /**< FunIN.56 */
    SV630P_DIFUNC4_FUNIN_57 = 0x0100, /**< FunIN.57 */
    SV630P_DIFUNC4_FUNIN_58 = 0x0200, /**< FunIN.58 */
    SV630P_DIFUNC4_FUNIN_59 = 0x0400, /**< FunIN.59 */
    SV630P_DIFUNC4_FUNIN_60 = 0x0800, /**< FunIN.60 */
    SV630P_DIFUNC4_FUNIN_61 = 0x1000, /**< FunIN.61 */
    SV630P_DIFUNC4_FUNIN_62 = 0x2000, /**< FunIN.62 */
    SV630P_DIFUNC4_FUNIN_63 = 0x4000  /**< FunIN.63 */
} SV630P_FuncTypeMask4;

#define REG_H03_60_DI1_FILTER  0x033D /* H03.60: DI1 filter time constant */
#define REG_H03_61_DI2_FILTER  0x033E /* H03.61: DI2 filter time constant */
#define REG_H03_62_DI3_FILTER  0x033F /* H03.62: DI3 filter time constant */
#define REG_H03_63_DI4_FILTER  0x0340 /* H03.63: DI4 filter time constant */
#define REG_H03_64_DI5_FILTER  0x0341 /* H03.64: DI5 filter time constant */
#define REG_H03_65_DI8_FILTER1 0x0342 /* H03.65: DI8 filter time 1 */
#define REG_H03_66_DI9_FILTER1 0x0343 /* H03.66: DI9 filter time 1 */

#if defined(__cplusplus)
extern "C"
{
#endif
/**
 * @brief Write power-on DI function assignment 2, 设置某一DI功能(FunIN.17~FunIN.32)重新上电后立即有效
 * @param dev Pointer to servo handle
 * @param func DI function enum to write
 * @return SV630P_OK on success, error code otherwise
 * @description: 再上电生效, 实时更改
 */
int sv630p_h03_01_write_power_on_di_func_assign2(sv630p_handle_t *dev, SV630P_DIDO_FunIN func);

/**
 * @brief DI1端子功能选择
 * @param dev
 * @param type - 设置硬件DI1端子对应的DI功能
*/
int sv630p_h03_02_write_di1_function_selection(sv630p_handle_t *dev, DiFunctionType type);
#if defined(__cplusplus)
}
#endif


#endif
