
#define _IN_DEBUG_C

#include "debug.h"
#include "shell.h"
#include "inout.h"
#include "delay.h"
#include "trigger.h"
#include "operator.h"
#include "workctrl.h"

//--------------------------------------------------------------------
void TestInputs(char * para1, char * para2);
void TestOutputs(char * para1, char * para2);
void TestExInputs(char * para1, char * para2);
void TestExOutput(char * para1, char * para2);
//--------------------------------------------------------------------

void InitDebug(void)
{
#if (INPUT_NUM > 0)
	AddShellCmd("INPUT", "input detect", TestInputs);
#endif

#if (OUTPUT_NUM > 0)
	AddShellCmd("OUTPUT", "output control", TestOutputs);
#endif

#if (USE_IOEX > 0)
	AddShellCmd("EXINPUT", "ex input detect", TestExInputs);
	AddShellCmd("EXOUTPUT", "ex output control", TestExOutput);
#endif
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef char NameStr[INPUT_STR_LEN];

// 测试功能
#if (INPUT_NUM > 0)

NameStr * g_inputName = NULL;

#define	INPUT_CASE_OP(cs)	\
{\
	case cs:\
	{\
		char*str="";\
		if (g_inputName != NULL)\
		{\
			str = g_inputName[cs-1];\
		}\
		if ((temp&mod) != 0)\
		{\
			printf("%d. Input%d is off (%s) \r\n", inidx++, cs, str);\
		}\
		else\
		{\
			printf("%d. Input%d is on  (%s) \r\n", inidx++, cs, str);\
		}\
		break;\
	}\
}

#define	ALM_CASE_OP(cs)	\
{\
	case (cs):\
	{\
		if ((temp&mod) != 0)\
		{\
			printf("%d. M%d alarm is off \r\n", inidx++, cs);\
		}\
		else\
		{\
			printf("%d. M%d alarm is on \r\n", inidx++, cs);\
		}\
		break;\
	}\
}

void TestInputs(char * para1, char * para2)
{
	int p1, p2;

	if (para1 == NULL || para2 == NULL)
	{
		return;
	}

	printf("para1=%s, para2=%s\r\n", para1, para2);

	p1 = 0;
	p2 = 0;
	if (strcmp(para1, "") != 0)
	{
		p1 = atoi(para1);
	}
	if (strcmp(para2, "") != 0)
	{
		p2 = atoi(para2);
	}
	if (p1 == p2)
	{
	}

	//--------------------------------
	{
		int inidx = 0;
		u16 inputsta;
		u16 almsta;
		u8 zp1sta, zp2sta;
		s32 ecd1, ecd2, ecdtemp;
		u16 temp, mod;
		int delay = 0;		// 延时时间计数
		int i;

		inputsta = GetInputStatus();
		inputsta = ~inputsta;

		almsta = GetAlarmValue();
		almsta = ~almsta;

		zp1sta = GetZP1Status();
		zp1sta = ~zp1sta;

		zp2sta = GetZP2Status();
		zp2sta = ~zp2sta;

		ecd1 = GetEcdCounter(ECD_SEL1);
		ecd1 = ~ecd1;
		ecd2 = GetEcdCounter(ECD_SEL2);
		ecd2 = ~ecd2;

		do
		{
			temp = GetInputStatus();
			if (temp != inputsta)
			{
				mod = 0x01;
				for (i = 1; i <= 16; i++)
				{
					if ((inputsta&mod) != (temp&mod))
					{
						switch (i)
						{
							INPUT_CASE_OP(1);
							INPUT_CASE_OP(2);
							INPUT_CASE_OP(3);
							INPUT_CASE_OP(4);
							INPUT_CASE_OP(5);
							INPUT_CASE_OP(6);
							INPUT_CASE_OP(7);
							INPUT_CASE_OP(8);
							INPUT_CASE_OP(9);
							INPUT_CASE_OP(10);
							INPUT_CASE_OP(11);
							INPUT_CASE_OP(12);
							INPUT_CASE_OP(13);
							INPUT_CASE_OP(14);
							INPUT_CASE_OP(15);
							INPUT_CASE_OP(16);
							default:
								break;
						}
					}
					mod = mod << 1;
					DelayMs(1);
					delay++;
				}
				inputsta = temp;
			}

			temp = GetAlarmValue();
			if (temp != almsta)
			{
				mod = 0x01;
				for (i = 1; i <= 6; i++)
				{
					if ((almsta&mod) != (temp&mod))
					{
						switch (i)
						{
							ALM_CASE_OP(1);
							ALM_CASE_OP(2);
							ALM_CASE_OP(3);
							ALM_CASE_OP(4);
							ALM_CASE_OP(5);
							ALM_CASE_OP(6);
							default:
								break;
						}
					}

					mod = mod << 1;
					DelayMs(1);
					delay++;
				}
				almsta = temp;
			}

			temp = GetZP1Status();
			if (temp != zp1sta)
			{
				if (temp == SENSOR_ON)
				{
					printf("%d. ZP1 is on \r\n", inidx++);
				}
				else
				{
					printf("%d. ZP1 is off \r\n", inidx++);
				}
				DelayMs(1);
				delay++;
				zp1sta = temp;
			}

			temp = GetZP2Status();
			if (temp != zp2sta)
			{
				if (temp == SENSOR_ON)
				{
					printf("%d. ZP2 is on \r\n", inidx++);
				}
				else
				{
					printf("%d. ZP2 is off \r\n", inidx++);
				}
				DelayMs(1);
				delay++;
				zp2sta = temp;
			}

			ecdtemp = GetEcdCounter(ECD_SEL1);
			if (ecdtemp != ecd1)
			{
				ecd1 = ecdtemp;

				printf("%d. Ecd1 = %d \r\n", inidx++, ecd1);

				DelayMs(1);
				delay++;
			}

			ecdtemp = GetEcdCounter(ECD_SEL2);
			if (ecdtemp != ecd2)
			{
				ecd2 = ecdtemp;

				printf("%d. Ecd2 = %d \r\n", inidx++, ecd2);

				DelayMs(1);
				delay++;
			}

			DelayMs(10);
			delay += 10;

			if (delay >= 500)
			{
				delay = 0;
				ReportError(0);
			}

			TriggerTask();
			OperatorTaskWhenRun(0);

			if (IsConsoleCancel() != 0)		// 终端输入停止
			{
				break;
			}

		}while(p1 != 0);
	}
}

void SetInputNameString(void* pDat)
{
	g_inputName = pDat;
}

#endif

//----------------------------------------------------------------

#if (OUTPUT_NUM > 0)

NameStr * g_outputName = NULL;

#define	OUT_CASE_OP(cs)	\
{\
	case cs:	\
	{\
		char*str="";\
		if (g_outputName != NULL)\
		{\
			str = g_outputName[cs-1];\
		}\
		if (p2 == 0)\
		{\
			Output##cs##Off();\
			printf("Output%d is off (%s) \r\n", cs, str);\
		}\
		else if (p2 == 1)\
		{\
			Output##cs##On();\
			printf("Output%d is on (%s) \r\n", cs, str);\
		}\
		break;	\
	}\
}

#define	MOTO_CASE_DIR(cs)	\
{\
	case cs:	\
	{\
		if (p2 == 0)\
		{\
			SetMoto##cs##SignOff();\
			printf("moto%d dir is off \r\n", cs);\
		}\
		else if (p2 == 1)\
		{\
			SetMoto##cs##SignOn();\
			printf("moto%d dir is on \r\n", cs);\
		}\
		break;	\
	}\
}

#define	MOTO_CASE_PULSE(cs)	\
{\
	case cs:	\
	{\
		if (p2 == 0)\
		{\
			SetMoto##cs##PulseOff();\
			printf("moto%d pulse is off \r\n", cs);\
		}\
		else if (p2 == 1)\
		{\
			SetMoto##cs##PulseOn();\
			printf("moto%d pulse is on \r\n", cs);\
		}\
		break;	\
	}\
}

#define	MOTO_CASE_SEL1(cs)	\
{\
	case cs:	\
	{\
		if (p2 == 0)\
		{\
			SetMoto##cs##SelAOff();\
			printf("moto%d sel1 is off \r\n", cs);\
		}\
		else if (p2 == 1)\
		{\
			SetMoto##cs##SelAOn();\
			printf("moto%d sel1 is on \r\n", cs);\
		}\
		break;	\
	}\
}

#define	MOTO_CASE_SEL2(cs)	\
{\
	case cs:	\
	{\
		if (p2 == 0)\
		{\
			SetMoto##cs##SelBOff();\
			printf("moto%d sel2 is off \r\n", cs);\
		}\
		else if (p2 == 1)\
		{\
			SetMoto##cs##SelBOn();\
			printf("moto%d sel2 is on \r\n", cs);\
		}\
		break;	\
	}\
}

#define	MOTO_CASE_SERVO(cs)	\
{\
	case cs:	\
	{\
		if (p2 == 0)\
		{\
			MotoServoCtrl(cs-1, SERVO_OFF);\
			printf("moto%d servo is off \r\n", cs);\
		}\
		else if (p2 == 1)\
		{\
			MotoServoCtrl(cs-1, SERVO_ON);\
			printf("moto%d servo is on \r\n", cs);\
		}\
		break;	\
	}\
}

void TestOutputs(char * para1, char * para2)
{
	int p1, p2;

	if (para1 == NULL || para2 == NULL)
	{
		return;
	}

	printf("para1=%s, para2=%s\r\n", para1, para2);

	p1 = 0;
	p2 = 0;
	if (strcmp(para1, "") != 0)
	{
		p1 = atoi(para1);
	}
	if (strcmp(para2, "") != 0)
	{
		p2 = atoi(para2);
	}
	if (p1 == p2)
	{
	}

	//--------------------------------
	if (p1 == 0)
	{
		int p2, count, timeout;
		p2 = 1;
		count = 1;
		timeout = 0;
		do
		{
			if (timeout == 0)
			{
				Output1Off();
				Output2Off();
				Output3Off();
				Output4Off();
				Output5Off();
				Output6Off();
				Output7Off();
				Output8Off();
				switch (count)
				{
					OUT_CASE_OP(1);
					OUT_CASE_OP(2);
					OUT_CASE_OP(3);
					OUT_CASE_OP(4);
					OUT_CASE_OP(5);
					OUT_CASE_OP(6);
					OUT_CASE_OP(7);
					OUT_CASE_OP(8);
				default:
					break;
				}
				count++;
				if (count > 8)
				{
					count = 1;
				}
			}

			DelayRef(1);
			timeout++;
			if (timeout > 1000)
			{
				timeout = 0;
			}

			if (IsConsoleCancel() != 0)		// 终端输入停止
			{
				Output1Off();
				Output2Off();
				Output3Off();
				Output4Off();
				Output5Off();
				Output6Off();
				Output7Off();
				Output8Off();
				break;
			}

		}while(1);
	}
	else if (p1 >= 1 && p1 <= 8)
	{
		switch (p1)
		{
			OUT_CASE_OP(1);
			OUT_CASE_OP(2);
			OUT_CASE_OP(3);
			OUT_CASE_OP(4);
			OUT_CASE_OP(5);
			OUT_CASE_OP(6);
			OUT_CASE_OP(7);
			OUT_CASE_OP(8);
			default:
				break;
		}
	}
	else if (p1 == 10)
	{
		if (p2 == 0)
		{
			SerIdOutOff();
			printf("SerIdOutOff\r\n");
		}
		else if (p2 == 1)
		{
			SerIdOutOn();
			printf("SerIdOutOn\r\n");
		}
	}
	else if (p1 == 20)
	{
		if (p2 == 0)
		{
			SetMpOutOff();
			printf("SetMpOutOff\r\n");
		}
		else if (p2 == 1)
		{
			SetMpOutOn();
			printf("SetMpOutOn\r\n");
		}
	}
	else if (p1 == 21)
	{
		for (int i = 0; i < p2; i++)
		{
			SetMpOutOn();
			DelayUs(100);
			SetMpOutOff();
			DelayUs(100);
		}
		printf("mp signal end\r\n");
	}
	else if (p1 == 30)
	{
		if (p2 == 0)
		{
			SetEn485OutOff();
			printf("SetEn485OutOff\r\n");
		}
		else
		{
			SetEn485OutOn();
			printf("SetEn485OutOn\r\n");
		}
	}
	else if (p1 >= 41 && p1 <= 46)
	{// 测试电机方向
		p1 -= 40;
		switch (p1)
		{
			MOTO_CASE_DIR(1);
			MOTO_CASE_DIR(2);
			MOTO_CASE_DIR(3);
			MOTO_CASE_DIR(4);
			MOTO_CASE_DIR(5);
			MOTO_CASE_DIR(6);
			default:
				break;
		}
	}
	else if (p1 >= 51 && p1 <= 56)
	{// 测试电机脉冲
		p1 -= 50;
		switch (p1)
		{
			MOTO_CASE_PULSE(1);
			MOTO_CASE_PULSE(2);
			MOTO_CASE_PULSE(3);
			MOTO_CASE_PULSE(4);
			MOTO_CASE_PULSE(5);
			MOTO_CASE_PULSE(6);
			default:
				break;
		}
	}
	else if (p1 >= 61 && p1 <= 66)
	{// 测试电机指令脉冲禁止1
		p1 -= 60;
		switch (p1)
		{
			MOTO_CASE_SEL1(1);
			MOTO_CASE_SEL1(2);
			MOTO_CASE_SEL1(3);
			MOTO_CASE_SEL1(4);
			MOTO_CASE_SEL1(5);
			MOTO_CASE_SEL1(6);
			default:
				break;
		}
	}
	else if (p1 >= 71 && p1 <= 76)
	{// 测试电机指令脉冲禁止2
		p1 -= 70;
		switch (p1)
		{
			MOTO_CASE_SEL2(1);
			MOTO_CASE_SEL2(2);
			MOTO_CASE_SEL2(3);
			MOTO_CASE_SEL2(4);
			MOTO_CASE_SEL2(5);
			MOTO_CASE_SEL2(6);
			default:
				break;
		}
	}
	else if (p1 >= 81 && p1 <= 86)
	{// 测试电机使能
		p1 -= 80;
		switch (p1)
		{
			MOTO_CASE_SERVO(1);
			MOTO_CASE_SERVO(2);
			MOTO_CASE_SERVO(3);
			MOTO_CASE_SERVO(4);
			MOTO_CASE_SERVO(5);
			MOTO_CASE_SERVO(6);
			default:
				break;
		}
	}
}


void SetOutputNameString(void* pDat)
{
	g_outputName = pDat;
}

#endif

#if (USE_IOEX > 0)
NameStr * g_exInputName = NULL;
NameStr * g_exOutputName = NULL;
int g_exInputNum = 0;
int g_exOutputNum = 0;
NameStr * g_exidName = NULL;

void SetExInputNameString(void * pDat, int inum)
{
	g_exInputName = pDat;
	g_exInputNum = inum;
}
void SetExOutputNameString(void * pDat, int onum)
{
	g_exOutputName = pDat;
	g_exOutputNum = onum;
}

#define	EXID_CASE_OP(cs)	\
{\
	case (cs+1+20):\
	{\
		char*str="";\
		if (g_exidName != NULL)\
		{\
			str = g_exidName[cs];\
		}\
		if ((temp&mod) != 0)\
		{\
			printf("%d. Exid%d is off (%s) \r\n", inidx++, cs, str);\
		}\
		else\
		{\
			printf("%d. Exid%d is on  (%s) \r\n", inidx++, cs, str);\
		}\
	}\
	break;\
}

void TestExInputs(char * para1, char * para2)
{
	int p1, p2;
	int inidx = 0;

	if (para1 == NULL || para2 == NULL)
	{
		return;
	}

	printf("para1=%s, para2=%s\r\n", para1, para2);

	p1 = 0;
	p2 = 0;
	if (strcmp(para1, "") != 0)
	{
		p1 = atoi(para1);
		if (strcmp(para2, "") != 0)
		{
			p2 = atoi(para2);
		}
	}

	if (p1 == p2)
	{
	}

	//--------------------------------
	{
		u16 exinbuf[EXIO_PORT_NUM], oldexinbuf[EXIO_PORT_NUM];
		u16 temp, old, mod, i, j;
		int addr;
		int num;
		int init;
		int sdct = 0;

		num = (g_exInputNum + EXIO_PER_PORT-1) / EXIO_PER_PORT;
		if (num > EXIO_PORT_NUM)
		{
			num = EXIO_PORT_NUM;
		}
		GetExInputs(exinbuf);
		for (i = 0; i < num; i++)
		{
			temp = exinbuf[i];
			temp = ~temp;
			oldexinbuf[i] = temp;
		}

		do
		{
			for (i = 0; i < num; i++)
			{
				temp = exinbuf[i];
				old = oldexinbuf[i];
				mod = 0x01;
				for (j = 0; j < EXIO_PER_PORT; j++)
				{
					if ((temp&mod) != (old&mod))
					{
						char*str="";
						addr = i*EXIO_PER_PORT+j;
						if (g_exInputName != NULL)
						{
							str = g_exInputName[addr];
						}

						if ((temp&mod) != 0)
						{
							printf("%d. addr=%d, N7(%d) Input%d is off (%s) \r\n", inidx++, addr+1, i+1, j+1, str);
						}
						else
						{
							printf("%d. addr=%d, N7(%d) Input%d is on (%s) \r\n", inidx++, addr+1, i+1, j+1, str);
						}
					}
					mod *= 2;
					DelayMs(2);
					sdct += 2;
				}

				if (init == 0)
				{// 增加分割线
					printf("--------------------- \r\n");
					DelayMs(50);
					sdct += 50;
				}
			}
			memcpy(oldexinbuf, exinbuf, EXIO_PORT_NUM*sizeof(u16));

			DelayMs(1);

			sdct += 1;
			if (sdct > 500)
			{
				sdct = 0;
				ReportError(0);
			}
			TriggerTask();			// 定时触发任务执行，TCP 连接，缝纫任务
			OperatorTaskWhenRun(0);

			if (IsConsoleCancel() != 0)		// 终端输入停止
			{
				break;
			}

			init = 1;
			GetExInputs(exinbuf);

		}while(p1 != 0);
	}
}

void OutByAddrOn(int idx, int addr)
{
	char*str="";\
	if (g_exOutputName != NULL)
	{
		str = g_exOutputName[addr-1];
	}

	SetExOutput(addr, Bit_RESET);
	printf("%d. addr=%d, N7(%d) Output%d is on (%s) \r\n", idx++, addr, (addr-1)/EXIO_PORT_NUM+1, addr%EXIO_PORT_NUM, str);
	DelayMs(4);
}

void OutByAddrOff(int idx, int addr)
{
	char*str="";\
	if (g_exOutputName != NULL)
	{
		str = g_exOutputName[addr-1];
	}

	SetExOutput(addr, Bit_SET);
	printf("%d. addr=%d, N7(%d) Output%d is off (%s) \r\n", idx++, addr, (addr-1)/EXIO_PORT_NUM+1, addr%EXIO_PORT_NUM, str);
	DelayMs(4);
}

void TestExOutput(char * para1, char * para2)
{
	int p1, p2;
	int count, delay;
	int inidx = 0;
	int dl;
	int num;

	if (para1 == NULL || para2 == NULL)
	{
		return;
	}

	printf("para1=%s, para2=%s\r\n", para1, para2);

	if (strcmp(para1, "") == 0 || strcmp(para2, "") == 0)
	{
		return;
	}
	p1 = atoi(para1);
	p2 = atoi(para2);

	if (p1 == p2)
	{
	}

	//--------------------------------

	num = g_exOutputNum;
	if (num > MAX_EXIO_ADDR)
	{
		num = MAX_EXIO_ADDR;
	}

	if (p1 == 0)
	{
		if (p2 == 0 || p2 == 1)
		{
			int i;
			if (p2 == 0)
			{
				for (i = 1; i <= num; i++)
				{
					OutByAddrOff(inidx, i);
				}
				inidx++;
			}
			else if (p2 == 1)
			{
				for (i = 1; i <= num; i++)
				{
					OutByAddrOn(inidx, i);
				}
				inidx++;
			}
		}
		else
		{
			int rep, i;
			if (p2 == 2)
			{
				rep = 1;
			}
			else
			{
				rep = S32_MAX;
			}
			do
			{
				for (i = 1; i <= num; i++)
				{
					OutByAddrOn(inidx, i);
				}

				for (i = 1; i <= num; i++)
				{
					OutByAddrOn(inidx, i);
				}

				if (IsConsoleCancel() != 0)
				{
					break;
				}

				TriggerTask();			// 定时触发任务执行，TCP 连接，缝纫任务
				OperatorTaskWhenRun(0);

				DelayMs(100);
				rep--;
			}while(rep != 0);
		}
	}
	else if (p1 <= num)
	{
		dl = 1000;

		if (p2 == 0)
		{
			OutByAddrOff(inidx, p1);
			inidx++;
		}
		else if (p2 == 1)
		{
			OutByAddrOn(inidx, p1);
			inidx++;
		}
		else if (p2 == 2)
		{
			OutByAddrOn(inidx, p1);
			inidx++;
			DelayMs(dl);
			if (dl != 0)
			{
				OutByAddrOff(inidx, p1);
				inidx++;
			}
		}
		else if (p2 > 0)
		{
			count = S32_MAX;
			while(count > 0)
			{
				count--;
				OutByAddrOn(inidx, p1);
				inidx++;
				delay = (p2+9)/10;
				do
				{
					TriggerTask();			// 定时触发任务执行，TCP 连接，缝纫任务
					OperatorTaskWhenRun(0);

					DelayMs(10);
					if (IsConsoleCancel() != 0)
					{
						break;
					}
					delay--;
				}while(delay != 0);

				if (delay != 0)
				{
					break;
				}
				if (dl == 1)
				{
					break;
				}
				OutByAddrOff(inidx, p1);
				inidx++;

				delay = (p2+9)/10;
				delay *= 4;
				do
				{
					TriggerTask();			// 定时触发任务执行，TCP 连接，缝纫任务
					OperatorTaskWhenRun(0);

					DelayMs(10);
					if (IsConsoleCancel() != 0)
					{
						break;
					}
					delay--;
				}while(delay != 0);
				if (delay != 0)
				{
					break;
				}
				if (dl == 0)
				{
					break;
				}
			}

			{
				OutByAddrOff(inidx, p1);
				inidx++;
			}
		}
	}
}
#endif

//------------------------------------------------------------------------------------------------------------------------------------------------------------

