
//-------------------------------------------------------------------------------
// File Name:	stparas.h
// Brief: 
// Version:		1.0.0
// Create Date: 2017/05/08
// Create by: 	Marshal Lee
// Copyright: 
//				Copyright (c)  2017, GetonAgain Co., LTD.
//				All rights reserved.
//
// Modify by:	Marshal Lee
// Modify Date:	2017/05/08

// Modify by:	ljs
// Modify Date:	2021/12/23
//-------------------------------------------------------------------------------

#ifndef __STPARAS_H__
#define	__STPARAS_H__

#include "config.h"
#include "stflash.h"

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

#ifndef MAX_PARA_NUM
#define	MAX_PARA_NUM	32
#endif

#define	PARA_NUM	(MAX_PARA_NUM-1)

#define	PARA_STR_LEN	20

#define PARA_VALID		0x55AA

// 参数类型
#define PTYPE_U		0	// 无符号数
#define PTYPE_S		1	// 有符号数
#define PTYPE_B		2	// 位图

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

typedef struct
{
	u32 paraEn;				// 20211223 增加参数有效标志,用于参数无效时自动写入默认参数
	u32 buf[PARA_NUM];
}  __attribute__ ((packed)) StParaStruct;

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

#define	STPARA_ADDR		(STM32_PARA_ADDR+0)

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

#define ST_PARAS_CODE(staddr, name)		\
\
StParaStruct g_##name##Para;\
u32 * g_p##name##ParaList = NULL;\
char * g_p##name##ParasName = NULL;\
\
int	Read##name##ParaData(void)\
{\
	int rslt;\
	u32 rdaddr = (u32)(&g_##name##Para);\
	rslt = STMFlashRead((u32)(staddr), (u16*)(rdaddr), (sizeof(StParaStruct))/2);\
	return rslt;\
}\
\
void Write##name##ParaData(void)\
{\
	u32 wraddr = (u32)(&g_##name##Para);\
	STMFlashWrite((u32)(staddr), (u16*)(wraddr), (sizeof(StParaStruct))/2, 3);\
}\
\
void Save##name##Para(void)\
{\
	printf("save %s para\r\n", #name);\
	Write##name##ParaData();\
}\
\
void Set##name##ParaList(void* pDat)\
{\
	g_p##name##ParaList = pDat;\
}\
\
void WriteDef##name##Para(void)\
{\
	printf("write def %s para\r\n", #name);\
	if (g_p##name##ParaList != NULL)\
	{\
		int offset;\
		for (int i = 0; i < PARA_NUM; i++)\
		{\
			offset = i * 4 + 3;\
			g_##name##Para.buf[i] = *(g_p##name##ParaList + offset);\
		}\
		g_##name##Para.paraEn = PARA_VALID+CUR_MACHINE;\
		Save##name##Para();\
	}\
	else\
	{\
		printf("%s para list is NULL\r\n", #name);\
	}\
}\
\
void Set##name##ParaNameString(void* pDat)\
{\
	g_p##name##ParasName = pDat;\
}\
\
void Load##name##Para(void)\
{\
	int rslt;\
	rslt = Read##name##ParaData();\
	if (rslt != 0 || g_##name##Para.paraEn != (PARA_VALID+CUR_MACHINE))\
	{\
		printf("%s para invalid, rslt=%d, paraEn=0x%x\r\n", #name, rslt, g_##name##Para.paraEn);\
		WriteDef##name##Para();\
	}\
	else\
	{\
		printf("load %s para successful\r\n", #name);\
	}\
}\
\
void CheckA##name##ParaRange(int id)\
{\
	if (id <= 0 || id > PARA_NUM || g_p##name##ParaList == NULL)\
	{\
		return;\
	}\
	int paratype, minOffset, maxOffset;\
	int idx = id - 1;\
	paratype = (idx * 4);\
	minOffset = (idx * 4 + 1);\
	maxOffset = (idx * 4 + 2);\
	if (*(g_p##name##ParaList+paratype) == PTYPE_U)\
	{\
		if (g_##name##Para.buf[idx] < *(g_p##name##ParaList+minOffset))\
		{\
			printf(#name " para id=%d, val=%d less than min=%d, set to min\r\n", id, g_##name##Para.buf[idx], *(g_p##name##ParaList+minOffset));\
			g_##name##Para.buf[idx] = *(g_p##name##ParaList+minOffset);\
		}\
		else if (g_##name##Para.buf[idx] > *(g_p##name##ParaList+maxOffset))\
		{\
			printf(#name " para id=%d, val=%d more than max=%d, set to max\r\n", id, g_##name##Para.buf[idx], *(g_p##name##ParaList+maxOffset));\
			g_##name##Para.buf[idx] = *(g_p##name##ParaList+maxOffset);\
		}\
	}\
	else if (*(g_p##name##ParaList+paratype) == PTYPE_S)\
	{\
		if ((s32)g_##name##Para.buf[idx] < (s32)*(g_p##name##ParaList+minOffset))\
		{\
			printf(#name " para id=%d, val=%d less than min=%d, set to min\r\n", id, (s32)g_##name##Para.buf[idx], (s32)*(g_p##name##ParaList+minOffset));\
			g_##name##Para.buf[idx] = *(g_p##name##ParaList+minOffset);\
		}\
		else if ((s32)g_##name##Para.buf[idx] > (s32)*(g_p##name##ParaList+maxOffset))\
		{\
			printf(#name " para id=%d, val=%d more than max=%d, set to max\r\n", id, (s32)g_##name##Para.buf[idx], (s32)*(g_p##name##ParaList+maxOffset));\
			g_##name##Para.buf[idx] = *(g_p##name##ParaList+maxOffset);\
		}\
	}\
}\
void Check##name##ParasRange(void)\
{\
	for(int i = 1; i <= PARA_NUM; i++)\
	{\
		CheckA##name##ParaRange(i);\
	}\
}\
void SetA##name##Para(int id, int val)\
{\
	if (id < 1 || id > PARA_NUM)\
	{\
		return;\
	}\
	int old;\
	old = (int)g_##name##Para.buf[id-1];\
	g_##name##Para.buf[id-1] = val;\
	if (g_p##name##ParasName != NULL)\
	{\
		printf("set a para %d. %s = %d, oldvalue=%d\r\n", id, (g_p##name##ParasName+(id-1)*PARA_STR_LEN), g_##name##Para.buf[id-1], old);\
	}\
	else\
	{\
		printf("set a para %d. = %d, oldvalue=%d\r\n", id, g_##name##Para.buf[id-1], old);\
	}\
	CheckA##name##ParaRange(id);\
}\
\
void Show##name##Para(char * para1, char * para2)\
{\
	int i;\
	int paratype;\
\
	printf(#name " para:\r\n");\
\
	if (g_p##name##ParasName != NULL)\
	{\
		for (i = 0; i < PARA_NUM; i++)\
		{\
			if (strlen(g_p##name##ParasName+i*PARA_STR_LEN) != 0)\
			{\
				paratype = (i * 4);\
				if (*(g_p##name##ParaList+paratype) == PTYPE_U)\
				{\
					printf("%d. %s = %d\r\n", i+1, (g_p##name##ParasName+i*PARA_STR_LEN), g_##name##Para.buf[i]);\
					DelayMs(2);\
				}\
				else if (*(g_p##name##ParaList+paratype) == PTYPE_S)\
				{\
					printf("%d. %s = %d\r\n", i+1, (g_p##name##ParasName+i*PARA_STR_LEN), (s32)g_##name##Para.buf[i]);\
					DelayMs(2);\
				}\
				else if (*(g_p##name##ParaList+paratype) == PTYPE_B)\
				{\
					printf("%d. %s = 0x%x\r\n", i+1, (g_p##name##ParasName+i*PARA_STR_LEN), g_##name##Para.buf[i]);\
					DelayMs(2);\
				}\
			}\
		}\
	}\
}\
\
void Set##name##Para(char * para1, char * para2)\
{\
	int p1, p2;\
\
	if (para1 == NULL || para2 == NULL)\
	{\
		return;\
	}\
\
	if (strcmp(para1, "") == 0 || strcmp(para2, "") == 0)\
	{\
		return;\
	}\
	p1 = atoi(para1);\
	p2 = atoi(para2);\
\
	if (p1 == 0 && p2 == 0)\
	{\
		WriteDef##name##Para();\
	}\
	else if (p1 <= PARA_NUM && p1 >= 1)\
	{\
		SetA##name##Para(p1, p2);\
	}\
	else if (p1 == 1000)\
	{\
		Save##name##Para();\
	}\
	else\
	{\
	}\
}\
void Init##name##Paras(void)\
{\
	Set##name##ParaList((void*)(&g_def##name##ParaList));\
\
	Load##name##Para();\
\
	Set##name##ParaNameString((void*)(&g_##name##ParaStrList[0][0]));\
\
	Check##name##ParasRange();\
\
	AddShellCmd("SHOW"#name"PARA", "show "#name" paras", Show##name##Para);\
	AddShellCmd("SET"#name"PARA", "set "#name" paras", Set##name##Para);\
}\
//----------------------





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



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


#endif


