#ifndef BMS_DI_DO_H_
#define BMS_DI_DO_H_

#ifdef __cplusplus
extern "C" {
#endif 

#include "kit_macro.h"
#include "logic_ctrl.h"

#define MAX_DI_NUM  9
#define	RELAY_CTRL_NO_DLY		1


typedef enum
{
	kDoStatus_Off, 		
	kDoStatus_On,  		
    kDoStatus_ForceOff, 	
	kDoStatus_ForceOn,
    kDoStatus_Adhesion,
    kDoStatus_Open,
    kDoStatus_End,
} DoStatus;

typedef enum
{
    kDoCtrlStatus_Off,
    kDoCtrlStatus_On,
    kDoCtrlStatus_None,
    kDoCtrlStatus_End,
}DoCtrlStatus;

/*0-无；1-预充；2-总正；3-总负；4-充电；5-放电；6-加热；7-制冷；8-运行灯1；9-运行灯2；10-运行灯3；
11-告警灯1，12-告警灯2，13-告警灯3，14-分励1，15-分励2，16-分励3，17-分励4（支持配置扩展）*/
typedef enum
{
    kDoType_Start = 0,
	kDoType_Unused = kDoType_Start,
	kDoType_PreChg,	
    kDoType_Chg, 
    kDoType_Dis,//3
    kDoType_Positive,	//4
    kDoType_Negative,//5
	kDoType_Cool,
    kDoType_Heat,
	kDoType_RunLed1,
	kDoType_RunLed2,
	kDoType_RunLed3,
	kDoType_AlarmLed1,
	kDoType_AlarmLed2,
	kDoType_AlarmLed3,
	kDoType_Trip1,
	kDoType_Trip2,
	kDoType_Trip3,
	kDoType_Trip4,
	kDoType_End,	
}DoType;


typedef void (*DoLogic)(uint32_t base_time, uint8_t idx);

typedef enum
{
	kDoErrSrc_Start = 0,
	kDoErrSrc_None = kDoErrSrc_Start, //0
	kDoErrSrc_HV1, //1
	kDoErrSrc_HV2, //2
	kDoErrSrc_DI1,
	kDoErrSrc_DI2,
	kDoErrSrc_DI3,
	kDoErrSrc_DI4,
	kDoErrSrc_DI5,
	kDoErrSrc_DI6,
	kDoErrSrc_DI7,
	kDoErrSrc_DI8,
	kDoErrSrc_DI9,
	kDoErrSrc_End,
}DoErrSrc;


typedef enum
{
	kDiType_Start = 0,
	kDiType_Unused= kDiType_Start,
    kDiType_FireAlarm1,      //消防1
	kDiType_FireAlarm2, 
	kDiType_FireAlarm3, 
	kDiType_EmergStop1,      //急停
    kDiType_Do1Feedback,
	kDiType_Do2Feedback,
    kDiType_Do3Feedback,
    kDiType_Do4Feedback,  
	kDiType_Do5Feedback,
    kDiType_Do6Feedback,
    kDiType_Do7Feedback,  
	kDiType_Do8Feedback,
	kDiType_Door,//门禁
	kDiType_Water,//水浸
	kDiType_Fuse,//保险丝故障信号
	kDiType_Pcs,//PCS故障信号
	kDiType_AirCon,//空调故障信号
	kDiType_Trip,//隔离开关反馈信号
	kDiType_AirCheck,//气体检测故障信号
	kDiType_Ups,//UPS故障信号
	kDiType_Ems,//EMS故障信号  
    kDiType_End
}DiType;

typedef enum
{
	kDiStatus_None,
	kDiStatus_Trigger,
	kDiStatus_End,
}DiStatus;

typedef enum
{
	kDiPolarity_Start = 0,
	kDiPolarity_Open = kDiPolarity_Start,//常开
	kDiPolarity_Close,//常闭
	kDiPolarity_End,
}DiPolarity;//DI极性枚举


void bms_cut_all_relay(void);
bool bms_is_do_config(DoType type);
void bms_poll_di_do(uint32_t base_time);
void bms_set_do_fault(DoType type, DoStatus status);
void bms_force_crtl_do_status(uint8_t idx, DoCtrlStatus status);
typedef void (*DiFun)(uint32_t base_time, DiStatus di_st, DiType di);
void bms_crtl_do_status(DoType type, DoCtrlStatus status, uint16_t dly);
void bms_crtl_do_status_by_idx(uint8_t idx, DoCtrlStatus status, uint16_t dly);
void bms_init_di_do(const DoLogic *do_main_poll_array, uint8_t do_main_poll_len, const DoLogic *do_poll_array);

DiType   bms_get_di_type(uint8_t idx);
DiStatus bms_get_di_status(DiType type);
DiPolarity bms_get_di_polarity(uint8_t idx);

DoType   bms_get_do_type(uint8_t idx);
DoErrSrc bms_get_do_err_src(DoType type);
DoStatus bms_get_do_status_by_idx(uint8_t idx);
DoStatus bms_get_do_status_by_type(DoType type);
DoCtrlStrategy bms_get_main_ctrl_strategy(void);


#ifdef __cplusplus
}
#endif

#endif
