
#define	_IN_PARAS_C

#include "paras.h"

#include "shell.h"
#include "delay.h"
#include "fram.h"
#include "smec98sp.h"

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

u32 * g_pMcParaList = NULL;			// 参数列表(包含参数类型,最小最大值和默认值)
u32 * g_pWkParaList = NULL;
u32 * g_pdefAngParaList = NULL;		// 动框角度默认参数

char* * g_pMcParasName = NULL;
char* * g_pWkParasName = NULL;

void LoadMcPara(void);
void LoadWkPara(void);
void LoadAngPara(void);

void ShowMcPara(char * para1, char * para2);
void ShowWkPara(char * para1, char * para2);

void SetMcPara(char * para1, char * para2);
void SetWkPara(char * para1, char * para2);

void ShowAngPara(char * para1, char * para2);
void SetAngPara(char * para1, char * para2);

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

void InitParas(void)
{
	LoadMcPara();
	LoadWkPara();

	LoadAngPara();

	AddShellCmd("SHOWMCPARA", "show the mc para", ShowMcPara);
	AddShellCmd("SHOWWKPARA", "show the wk para", ShowWkPara);
	AddShellCmd("SETMCPARA", "set the mc para", SetMcPara);
	AddShellCmd("SETWKPARA", "set the wk para", SetWkPara);

	AddShellCmd("SHOWANG", "show the ang para", ShowAngPara);
	AddShellCmd("SETANG", "set the ang para", SetAngPara);
}

//-------------------------------------------
void LoadPara(u16 addr, u8 * pBuf, u16 len)
{
	if (len == 0 || pBuf == NULL)
	{
		return;
	}

	ReadFramData(addr, pBuf, len);

	if (USE_SMEC == 1)		// 1:使用加密芯片 (使用加密芯片每次读写参数会增加30ms)
	{
		int i,j,k;
		u8 dat[128] = {0};
		u8 rst = 0;
		int jump = len / 120 +1;

		for (i=0,j=0;i<len;i++)
		{
			if ((i % jump) == 0)
			{
				dat[j++] = *(pBuf+i);
			}
		}
		for (k=0;k<10;k++)
		{
			rst = SMEC_DecryptionData(0,dat,j);
			if (rst == 0)
			{
				for (i=0,j=0;i<len;i++)
				{
					if ((i % jump) == 0)
					{
						*(pBuf+i) = dat[j++];
					}
				}
			}
			else
			{
				printf("LoadPara Err: Encryption chip access failed!\r\n");
			}
		}
	}
}

void SavePara(u16 addr, u8 * pBuf, u16 len)
{
	if (len == 0 || pBuf == NULL)
	{
		return;
	}

	if (USE_SMEC == 1)		// 1:使用加密芯片 (使用加密芯片每次读写参数会增加30ms)
	{
		int i,j,k;
		u8 dat[128] = {0};
		u8 rst = 0;
		int jump = len / 120 +1;

		for (i=0,j=0;i<len;i++)
		{
			if ((i % jump) == 0)
			{
				dat[j++] = *(pBuf+i);
			}
		}
		for (k=0;k<10;k++)
		{
			rst = SMEC_EncryptionData(0,dat,j);
			if (rst == 0)
			{
				for (i=0,j=0;i<len;i++)
				{
					if ((i % jump) == 0)
					{
						*(pBuf+i) = dat[j++];
					}
				}
			}
			else
			{
				printf("SavePara Err: Encryption chip access failed!\r\n");
			}
		}
	}

	WriteFramData(addr, pBuf, len);
}

//-------------------------------------------
void LoadMcPara(void)
{
	LoadPara(MCPARA_ADDR, (u8*)(&g_mcPara), sizeof(ParaStruct));
}

void LoadWkPara(void)
{
	LoadPara(WKPARA_ADDR, (u8*)(&g_wkPara), sizeof(ParaStruct));
}

void LoadAngPara(void)
{
	LoadPara(ANGPARA_ADDR, (u8*)(&g_angPara), sizeof(ParaStruct));
}

//-------------------------------------------
void SaveMcPara(void)
{
	SavePara(MCPARA_ADDR, (u8*)(&g_mcPara), sizeof(ParaStruct));
}

void SaveWkPara(void)
{
	SavePara(WKPARA_ADDR, (u8*)(&g_wkPara), sizeof(ParaStruct));
}

void SaveAngPara(void)
{
	SavePara(ANGPARA_ADDR, (u8*)(&g_angPara), sizeof(ParaStruct));
}

void WriteDefMcPara(void)
{
	if (g_pMcParaList == NULL)
	{
		return;
	}
	int offset;
	for (int i = 0; i < PARA_NUM; i++)
	{
		offset = i * 4 + 3;
		g_mcPara.buf[i] = *(g_pMcParaList + offset);
	}
	SaveMcPara();
	printf("write def mc para\r\n");
}

void WriteDefWkPara(void)
{
	if (g_pWkParaList == NULL)
	{
		return;
	}
	int offset;
	for (int i = 0; i < PARA_NUM; i++)
	{
		offset = i * 4 + 3;
		g_wkPara.buf[i] = *(g_pWkParaList + offset);
	}
	SaveWkPara();
	printf("write def wk para\r\n");
}

void WriteDefMvAngPara(void)
{
	if (g_pdefAngParaList == NULL)
	{
		return;
	}
	memcpy(&g_angPara, g_pdefAngParaList, sizeof(ParaStruct));
	SaveAngPara();
	printf("write def angle para\r\n");
}

void CheckMcParaRange(void)
{
	if (g_pMcParaList == NULL)
	{
		return;
	}
	int paratype, minOffset, maxOffset;		// 参数类型,最小最大值指针偏移量
	for (int i = 0; i < PARA_NUM; i++)
	{
		paratype = (i * 4);
		minOffset = (i * 4 + 1);
		maxOffset = (i * 4 + 2);
		if (*(g_pMcParaList+paratype) == PTYPE_U)
		{
			if (g_mcPara.buf[i] < *(g_pMcParaList+minOffset))
			{
				printf("mc para id=%d, val=%d less than min=%d, set to min\r\n", i+1, g_mcPara.buf[i], *(g_pMcParaList+minOffset));
				g_mcPara.buf[i] = *(g_pMcParaList+minOffset);
			}
			else if (g_mcPara.buf[i] > *(g_pMcParaList+maxOffset))
			{
				printf("mc para id=%d, val=%d more than max=%d, set to max\r\n", i+1, g_mcPara.buf[i], *(g_pMcParaList+maxOffset));
				g_mcPara.buf[i] = *(g_pMcParaList+maxOffset);
			}
		}
		else if (*(g_pMcParaList+paratype) == PTYPE_S)
		{
			if ((s32)g_mcPara.buf[i] < (s32)*(g_pMcParaList+minOffset))
			{
				printf("mc para id=%d, val=%d less than min=%d, set to min\r\n", i+1, (s32)g_mcPara.buf[i], (s32)*(g_pMcParaList+minOffset));
				g_mcPara.buf[i] = *(g_pMcParaList+minOffset);
			}
			else if ((s32)g_mcPara.buf[i] > (s32)*(g_pMcParaList+maxOffset))
			{
				printf("mc para id=%d, val=%d more than max=%d, set to max\r\n", i+1, (s32)g_mcPara.buf[i], (s32)*(g_pMcParaList+maxOffset));
				g_mcPara.buf[i] = *(g_pMcParaList+maxOffset);
			}
		}
	}
}

void CheckAMcParaRange(int id)
{
	if (g_pMcParaList == NULL || id <= 0 || id > PARA_NUM)
	{
		return;
	}
	int paratype, minOffset, maxOffset;		// 参数类型,最小最大值指针偏移量
	int idx = id - 1;
	paratype = (idx * 4);
	minOffset = (idx * 4 + 1);
	maxOffset = (idx * 4 + 2);
	if (*(g_pMcParaList+paratype) == PTYPE_U)
	{
		if (g_mcPara.buf[idx] < *(g_pMcParaList+minOffset))
		{
			printf("mc para id=%d, val=%d less than min=%d, set to min\r\n", id, g_mcPara.buf[idx], *(g_pMcParaList+minOffset));
			g_mcPara.buf[idx] = *(g_pMcParaList+minOffset);
		}
		else if (g_mcPara.buf[idx] > *(g_pMcParaList+maxOffset))
		{
			printf("mc para id=%d, val=%d more than max=%d, set to max\r\n", id, g_mcPara.buf[idx], *(g_pMcParaList+maxOffset));
			g_mcPara.buf[idx] = *(g_pMcParaList+maxOffset);
		}
	}
	else if (*(g_pMcParaList+paratype) == PTYPE_S)
	{
		if ((s32)g_mcPara.buf[idx] < (s32)*(g_pMcParaList+minOffset))
		{
			printf("mc para id=%d, val=%d less than min=%d, set to min\r\n", id, (s32)g_mcPara.buf[idx], (s32)*(g_pMcParaList+minOffset));
			g_mcPara.buf[idx] = *(g_pMcParaList+minOffset);
		}
		else if ((s32)g_mcPara.buf[idx] > (s32)*(g_pMcParaList+maxOffset))
		{
			printf("mc para id=%d, val=%d more than max=%d, set to max\r\n", id, (s32)g_mcPara.buf[idx], (s32)*(g_pMcParaList+maxOffset));
			g_mcPara.buf[idx] = *(g_pMcParaList+maxOffset);
		}
	}
}

void CheckWkParaRange(void)
{
	if (g_pWkParaList == NULL)
	{
		return;
	}
	int paratype, minOffset, maxOffset;		// 参数类型,最小最大值指针偏移量
	for (int i = 0; i < PARA_NUM; i++)
	{
		paratype = (i * 4);
		minOffset = (i * 4 + 1);
		maxOffset = (i * 4 + 2);
		if (*(g_pWkParaList+paratype) == PTYPE_U)
		{
			if (g_wkPara.buf[i] < *(g_pWkParaList+minOffset))
			{
				printf("wk para id=%d, val=%d less than min=%d, set to min\r\n", i+1, g_wkPara.buf[i], *(g_pWkParaList+minOffset));
				g_wkPara.buf[i] = *(g_pWkParaList+minOffset);
			}
			else if (g_wkPara.buf[i] > *(g_pWkParaList+maxOffset))
			{
				printf("wk para id=%d, val=%d more than max=%d, set to max\r\n", i+1, g_wkPara.buf[i], *(g_pWkParaList+maxOffset));
				g_wkPara.buf[i] = *(g_pWkParaList+maxOffset);
			}
		}
		else if (*(g_pWkParaList+paratype) == PTYPE_S)
		{
			if ((s32)g_wkPara.buf[i] < (s32)*(g_pWkParaList+minOffset))
			{
				printf("wk para id=%d, val=%d less than min=%d, set to min\r\n", i+1, (s32)g_wkPara.buf[i], (s32)*(g_pWkParaList+minOffset));
				g_wkPara.buf[i] = *(g_pWkParaList+minOffset);
			}
			else if ((s32)g_wkPara.buf[i] > (s32)*(g_pWkParaList+maxOffset))
			{
				printf("wk para id=%d, val=%d more than max=%d, set to max\r\n", i+1, (s32)g_wkPara.buf[i], (s32)*(g_pWkParaList+maxOffset));
				g_wkPara.buf[i] = *(g_pWkParaList+maxOffset);
			}
		}
	}
}

void CheckAWkParaRange(int id)
{
	if (g_pWkParaList == NULL || id <= 0 || id > PARA_NUM)
	{
		return;
	}
	int paratype, minOffset, maxOffset;		// 参数类型,最小最大值指针偏移量
	int idx = id - 1;
	paratype = (idx * 4);
	minOffset = (idx * 4 + 1);
	maxOffset = (idx * 4 + 2);
	if (*(g_pWkParaList+paratype) == PTYPE_U)
	{
		if (g_wkPara.buf[idx] < *(g_pWkParaList+minOffset))
		{
			printf("wk para id=%d, val=%d less than min=%d, set to min\r\n", id, g_wkPara.buf[idx], *(g_pWkParaList+minOffset));
			g_wkPara.buf[idx] = *(g_pWkParaList+minOffset);
		}
		else if (g_wkPara.buf[idx] > *(g_pWkParaList+maxOffset))
		{
			printf("wk para id=%d, val=%d more than max=%d, set to max\r\n", id, g_wkPara.buf[idx], *(g_pWkParaList+maxOffset));
			g_wkPara.buf[idx] = *(g_pWkParaList+maxOffset);
		}
	}
	else if (*(g_pWkParaList+paratype) == PTYPE_S)
	{
		if ((s32)g_wkPara.buf[idx] < (s32)*(g_pWkParaList+minOffset))
		{
			printf("wk para id=%d, val=%d less than min=%d, set to min\r\n", id, (s32)g_wkPara.buf[idx], (s32)*(g_pWkParaList+minOffset));
			g_wkPara.buf[idx] = *(g_pWkParaList+minOffset);
		}
		else if ((s32)g_wkPara.buf[idx] > (s32)*(g_pWkParaList+maxOffset))
		{
			printf("wk para id=%d, val=%d more than max=%d, set to max\r\n", id, (s32)g_wkPara.buf[idx], (s32)*(g_pWkParaList+maxOffset));
			g_wkPara.buf[idx] = *(g_pWkParaList+maxOffset);
		}
	}
}

void SetMcParaNameString(void* pDat)
{
	g_pMcParasName = pDat;
}

void SetWkParaNameString(void* pDat)
{
	g_pWkParasName = pDat;
}

void SetMcParaList(void * pDat)
{
	g_pMcParaList = pDat;
}

void SetWkParaList(void * pDat)
{
	g_pWkParaList = pDat;
}

void SetDefAngParaList(void * pDat)
{
	g_pdefAngParaList = pDat;
}

u32 GetAMcPara(int id)
{
	int idx = id - 1;

	if (idx >= 0 && idx < PARA_NUM)
	{
		return g_mcPara.buf[idx];
	}
	return 0;
}

void SetAMcPara(int id, u32 val)
{
	u32 * pItem;
	char * pInfo = NULL;
	int idx = id - 1;

	if (idx >= 0 && idx < PARA_NUM)
	{
		pItem = &g_mcPara.buf[idx];
		pInfo = g_pMcParasName[idx];
		printf("set mc para ");

		if (*(g_pMcParaList + idx * 4) == PTYPE_S)
		{
			s32 old = (s32)(*pItem);
			*pItem = val;
			if (pInfo != NULL)
			{
				printf("%d. %s = %d, oldvalue=%d\r\n", id, pInfo, (s32)*pItem, old);
			}
			else
			{
				printf("%d. = %d, oldvalue=%d\r\n", id, (s32)*pItem, old);
			}
		}
		else
		{
			u32 old = *pItem;
			*pItem = val;
			if (pInfo != NULL)
			{
				printf("%d. %s = %d, oldvalue=%d\r\n", id, pInfo, *pItem, old);
			}
			else
			{
				printf("%d. = %d, oldvalue=%d\r\n", id, *pItem, old);
			}
		}
		CheckAMcParaRange(id);
	}
}

u32 GetAWkPara(int id)
{
	int idx = id - 1;

	if (idx >= 0 && idx < PARA_NUM)
	{
		return g_wkPara.buf[idx];
	}
	return 0;
}

void SetAWkPara(int id, u32 val)
{
	u32 * pItem;
	char * pInfo = NULL;
	int idx = id - 1;

	if (idx >= 0 && idx < PARA_NUM)
	{
		pItem = &g_wkPara.buf[idx];
		pInfo = g_pWkParasName[idx];
		printf("set wk para ");

		if (*(g_pWkParaList + idx * 4) == PTYPE_S)
		{
			s32 old = (s32)(*pItem);
			*pItem = val;
			if (pInfo != NULL)
			{
				printf("%d. %s = %d, oldvalue=%d\r\n", id, pInfo, (s32)*pItem, old);
			}
			else
			{
				printf("%d. = %d, oldvalue=%d\r\n", id, (s32)*pItem, old);
			}
		}
		else
		{
			u32 old = *pItem;
			*pItem = val;
			if (pInfo != NULL)
			{
				printf("%d. %s = %d, oldvalue=%d\r\n", id, pInfo, *pItem, old);
			}
			else
			{
				printf("%d. = %d, oldvalue=%d\r\n", id, *pItem, old);
			}
		}
		CheckAWkParaRange(id);
	}
}

void SetAAnglePara(int id, u16 val)
{
	int old;
	u16 * pItem;
	int idx = id - 1;

	if ( idx >= 0 && idx < (PARA_NUM*2) )
	{
		pItem = ((u16*)(&g_angPara)+idx);
		printf("set move start angle ");

		old = *pItem;
		*pItem = val;
		printf("%d. = %d, oldvalue=%d\r\n", id, *pItem, old);
	}
}

void ShowMcPara(char * para1, char * para2)
{
	printf("mc para:\r\n");

	for (int i = 0; i < PARA_NUM; i++)
	{
		if (g_pMcParasName[i] != NULL)
		{
			if (strlen(g_pMcParasName[i]) != 0)
			{
				if (*(g_pMcParaList + i * 4) == PTYPE_U)
				{
					printf("%d. %s = %d\r\n", i+1, g_pMcParasName[i], g_mcPara.buf[i]);
				}
				else if (*(g_pMcParaList + i * 4) == PTYPE_S)
				{
					printf("%d. %s = %d\r\n", i+1, g_pMcParasName[i], (s32)g_mcPara.buf[i]);
				}
				else
				{
					printf("%d. %s = 0x%x\r\n", i+1, g_pMcParasName[i], g_mcPara.buf[i]);
				}
				DelayMs(2);
			}
		}
	}
}

void ShowWkPara(char * para1, char * para2)
{
	printf("wk para:\r\n");

	for (int i = 0; i < PARA_NUM; i++)
	{
		if (g_pWkParasName[i] != NULL)
		{
			if (strlen(g_pWkParasName[i]) != 0)
			{
				if (*(g_pWkParaList + i * 4) == PTYPE_U)
				{
					printf("%d. %s = %d\r\n", i+1, g_pWkParasName[i], g_wkPara.buf[i]);
				}
				else if (*(g_pWkParaList + i * 4) == PTYPE_S)
				{
					printf("%d. %s = %d\r\n", i+1, g_pWkParasName[i], (s32)g_wkPara.buf[i]);
				}
				else
				{
					printf("%d. %s = 0x%x\r\n", i+1, g_pWkParasName[i], g_wkPara.buf[i]);
				}
				DelayMs(2);
			}
		}
	}
}

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

	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)
	{
	}

	if (p1 == 0 && p2 == 0)
	{
		WriteDefMcPara();				// 写默认参数
	}
	else if (p1 <= PARA_NUM && p1 >= 1)
	{
		SetAMcPara(p1, p2);
	}
	else if (p1 == 1000)
	{
		printf("save mc para\r\n");
		SaveMcPara();
	}
	else
	{
	}
}

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

	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)
	{
	}

	if (p1 == 0 && p2 == 0)
	{
		WriteDefWkPara();	// 写默认参数
	}
	else if (p1 <= PARA_NUM && p1 >= 1)
	{
		SetAWkPara(p1, p2);
	}
	else if (p1 == 1000)
	{
		printf("save wk para\r\n");
		SaveWkPara();
	}
	else
	{
	}
}

void ShowAngPara(char * para1, char * para2)
{
	int p1 = 1;

	if (para1 != NULL)
	{
		p1 = atoi(para1);
	}

	{
		int gid = p1;
		ParaStruct * pPara = NULL;
		int ofst, val, ofst2;
		ofst = val = 0;

		printf("ang para %d:\r\n", gid);

		if (gid == 1 || gid == 2)
		{
			pPara = (&g_angPara);
		}

		if (gid == 1)
		{
			ofst2 = 0;
		}
		else if (gid == 2)
		{
			ofst2 = MAX_HOR * MAX_VER;
		}

		if (pPara != NULL)
		{
			printf("\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\r\n");
			for (int i = 0; i < MAX_VER; i++)
			{
				printf("%d:\t", i+1);
				for (int j = 0; j < MAX_HOR; j++)
				{
					ofst = (i * MAX_HOR + j + ofst2);
					val = *((u16*)(pPara) + ofst);
					printf("%d\t", val);
					DelayMs(1);
				}
				printf("\r\n");
			}
		}
	}
}

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

	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)
	{
	}

	if (p1 == 0)
	{
		WriteDefMvAngPara();
	}
	else if (p1 == 1000)
	{
		SaveAngPara();
		printf("save angle para\r\n");
	}
	else
	{
		int gid, subscript1, subscript2;	// 下标1,下标2
		int id;

		gid = p1 / 10000;
		p1 %= 10000;
		subscript1 = p1 / 100;
		subscript2 = p1 % 100;
		if (subscript1 < 1 || subscript2 < 1 || subscript1 > MAX_VER || subscript2 > MAX_HOR)
		{
			printf("idx err\r\n");
			return;
		}

		id = (subscript1-1) * MAX_HOR + (subscript2-1) + 1;
		if (id < 1 || id > PARA_NUM)
		{
			printf("idx err\r\n");
			return;
		}
		printf("set ang table %d, at (%d, %d), value=%d\r\n", gid, subscript1, subscript2, p2);

		if (gid == 2)
		{
			id += MAX_HOR * MAX_VER;
		}

		SetAAnglePara(id, p2);
	}
}


