
#include "ComiEcatSdk_Def.h"

#define NETID			0
#define ECAT_CMC		0x50323766
#define PDO_INTERVAL	5

#pragma pack(push, 1)

typedef struct{
	t_ui16	StsWord;
	t_i32	ActPos;
	t_i32	ActVel;
	t_byte	OpMode;
}TCmc_AxisInPDO;

typedef struct{
	t_ui16	CtlWord;
	t_i32	TargPos;
	t_i32	TargVel;
	t_byte	OpMode;
}TCmc_AxisOutPDO;

typedef struct{
	t_ui16	DiValue;
}TCmc_DiInPDO;


class CComiCmc
{
private:
	int	m_nSlaveIndex;
	int	m_nSlaveAddress;
public:
	CComiCmc();

	LONG		GetNumAxis();
	USHORT		GetSlaveAddress(void);
	USHORT		GetSlaveIndex(void);
	BOOL		SetSvon(int nAxis, BOOL SvonState, int *pErrCode);
	BOOL		GetSvon(int nAxis, int *pErrCode);
	BOOL		MoveStart(int nAxis, int Distance, int *pErrCode);
	BOOL		MoveToStart(int nAxis, int Position, int *pErrCode);
	BOOL		VMoveStart(int nAxis, int *pErrCode);
	BOOL		HomeMoveStart(int nAxis, int *pErrCode);
	BOOL		Stop(int nAxis, int *pErrCode);
	BOOL		EmgStop(int nAxis, int *pErrCode);
	BOOL		SetSpeedEnv(int nAxis, int WorkSpeed, int Accel, int Decel, int *pErrCode);
	BOOL		GetSpeedEnv(int nAxis, int *pWorkSpeed, int *pAccel, int *pDecel, int *pErrCode);
	BOOL		SetMaxSpeed(int nAxis, int MaxSpeed, int *pErrCode);
	BOOL		GetMaxSpeed(int nAxis, int *pMaxSpeed, int *pErrCode);
	BOOL		SetTargetVelocity(int nAxis, int Velocity, int *pErrCode);
	BOOL		GetTargetVelocity(int nAxis, int *pVelocity, int *pErrCode);
	BOOL		SetHomeMode(int nAxis, int HomeMethod, int *pErrCode);
	BOOL		GetHomeMode(int nAxis, int *pHomeMethod, int *pErrCode);
	BOOL		SetHomeSpeedEnv(int nAxis, int WorkSpeed, int StopSpeed, int AccDec, int *pErrCode);
	BOOL		GetHomeSpeedEnv(int nAxis, int *pWorkSpeed, int *pStopSpeed, int *pAccDec, int *pErrCode);
	BOOL		StGetPosition(int nAxis, int TargCntr, int *pPosition, int *pErrCode);
	BOOL		StGetCurSpeed(int nAxis, int TargCntr, int *pCurSpeed, int *pErrCode);
	BOOL		StGetMotFlag(int nAxis, void *pMotFlag, int *pErrCode);
	BOOL		SetPolarity(int nAxis, int Polarity, int *pErrCode);
	BOOL		GetPolarity(int nAxis, int *pPolarity, int *pErrCode);
	BOOL		SetSoftLimit(int nAxis, int TargLimit, int PosLimit, int *pErrCode);
	BOOL		GetSoftLimit(int nAxis, int TargLimit, int *pPosLimit, int *pErrCode);
	BOOL		ReadMotState(int nAxis, int *pState, int *pErrCode);
	BOOL		SetWorkCurrent(int nAxis, int TargCurrent, int CurrValue, int *pErrCode);
	BOOL		GetWorkCurrent(int nAxis, int TargCurrent, int *pCurrValue, int *pErrCode);
	BOOL		SetStopCurrent(int nAxis, int CurrValue, int *pErrCode);
	BOOL		GetStopCurrent(int nAxis, int *pCurrValue, int *pErrCode);
	BOOL		SetStepDivision(int nAxis, int StepDiv, int *pErrCode);
	BOOL		GetStepDivision(int nAxis, int *pStepDiv, int *pErrCode);
	BOOL		SetSensorChan(int nSensor, int SelectChan, int *pErrCode);
	BOOL		GetSensorChan(int nSensor, int *pConnectChan, int *pErrCode);
	BOOL		SetSensorLogic(int nSensor, int Logic, int *pErrCode);
	BOOL		GetSensorLogic(int nSensor, int *pLogic, int *pErrCode);
	BOOL		ReadEncoderCnt(int nChannel, int TargCntr, int *pCountValue, int *pErrCode);
	BOOL		SetCntClear(int nChannel, int TargCntr, int *pErrCode);

	USHORT		DiGetNumChannel(void);
	USHORT		DoGetNumChannel(void);
	BOOL		DiGetOne(int DiChannel, int *pErrCode);
	USHORT		DiGetMulti(int IniChannel, int NumChannel, int *pErrCode);
	BOOL		DoGetOne(int DoChannel, int *pErrCode);
	USHORT		DoGetMulti(int IniChannel, int NumChannel, int *pErrCode);
	BOOL		DoPutOne(int DoChannel, BOOL OutState, int *pErrCode);
	BOOL		DoPutMulti(int IniChannel, int NumChannel, USHORT OutState, int *pErrCode);

	BOOL		ReadFwVersion(char *pVersion, int *pErrCode);
	BOOL		SetSettingSave(int *pErrCode);

	TCmc_AxisInPDO*		GetInPDO(int nAxis);
	TCmc_AxisOutPDO*	GetOutPDO(int nAxis);
	USHORT*				GetDiPDO(void);
	USHORT*				GetDoPDO(void);

};


typedef enum _DefCntr { 
	CNT_COMM, // Command Counter
	CNT_FEED, // Feedback Counter
}DefCntr;

// Flag: Bit 별로 Axis의 상태를 알리는 플래그들의 집합
typedef union{
	struct{
		t_ui16 RdyToSwOn: 		1; // Ready To Switch On/Off
		t_ui16 SwOn: 			1; // Switch On
		t_ui16 OperEnabled:		1; // Operation Enabled (Servo-on/off 에 해당함)
		t_ui16 Fault:			1; // driver의 Fault 발생 상태

		t_ui16 VoltEnabled:		1; // Voltage Enabled
		t_ui16 QuickStop: 		1; // Quick Stop
		t_ui16 SwOnDisabled:	1; // Switch On Disabled
		t_ui16 Warning:			1; // driver의 Warning 발생 상태

		t_ui16 CtlrFault:		1; // Controller의 Fault 발생 상태
		t_ui16 HomeError:		1; // Homing중에 에러가 발생했는지...
		t_ui16 OMS1:			1; // Operation Mode Specific 1
		t_ui16 IntLimit:		1; // Internal Limit Active (POT/NOT, Software Limit, Torque Limit, ...

		t_ui16 OMS2:			2; // Operation Mode Specific 2
		t_ui16 HomeBusy:		1; // Homing operation이 진행중인지
		t_ui16 HomeAttained:	1; // 1 - Homing 동작이 성공적으로 완료되었음을 나타냄.
	}bit;
	t_ui16 word;
}TSxSt_Flags;

typedef enum{
	DIR_P	= 0,
	DIR_N	= 1
}DefDir;

typedef enum{
	MIN_LIMIT	= 0,
	MAX_LIMIT	= 1
}DefSWLimit;

typedef enum{
	ST_STOP		= 0,
	ST_ACC		= 1,
	ST_DEC		= 2,
	ST_WORK		= 3
}DefMotStat;

typedef enum{
	RUN_CURR		= 0,
	ACC_CURR		= 1
}DefMotCurr;

typedef enum{
	STEP_FULL		= 0,
	STEP_HALF		= 1,
	STEP_1DIV4		= 2,
	STEP_1DIV8		= 3,
	STEP_1DIV16		= 4,
}DefStepDiv;

typedef enum{
	HOME_DEC		= 0,
	HOME_STOP		= 1,
	EL_NEG			= 2,
	EL_POS			= 3,
	SENSOR_POS		= 4,
}DefSensor;

typedef enum{
	LOGIC_A		= 0,
	LOGIC_B		= 1,
}DefLogic;

typedef enum{
	ENC_AB		= 0,
	ENC_Z		= 1,
}DefEncoder;

// 에러코드 정의 //
#define CMC_ERR_NONE						0
#define CMC_ERR_BASE						-700000
#define CMC_ERR_INVALID_SLAVE_ADDR			(CMC_ERR_BASE - 10) // Slave address setting이 되지 않은 경우
#define CMC_ERR_INVALID_AL_STATE			(CMC_ERR_BASE - 20) // 
#define CMC_ERR_INVALID_OUTPDO_PTR			(CMC_ERR_BASE - 30) // 
#define CMC_ERR_INVALID_INPDO_PTR			(CMC_ERR_BASE - 31) // 
#define CMC_ERR_INVALID_PARAMETER			(CMC_ERR_BASE - 40) // 함수에 잘못된 파라미터가 전달 되었을 경우
#define CMC_ERR_MASTER_INTERFACE_FAIL		(CMC_ERR_BASE - 200) // 이더캣 마스터 장치와 데이터교환 중에 에러가 발행한 경우.
#define CMC_ERR_OPMODE_TIMEOUT				(CMC_ERR_BASE - 300) // Operation Mode 전환에 실패한 경우.

#pragma pack(pop)