optical/NxFuncs/norparas/norparas.c
2025-09-04 09:45:08 +08:00

712 lines
16 KiB
C

#define _IN_NORPARAS_C
#include "norparas.h"
#if (MAX_PARA_BLOCK > 0)
#include "norflash.h"
#include "inout.h"
#include "shell.h"
#include "delay.h"
//----------------------------------------------------
#define NORPARA_BEG_ADDR (SNF_PARAS_BEGIN) // 参数块起始地址,每个参数块占一个扇区,最大共16个参数块
#define NP_BLOCK_BYTES SNF_BYTES_PER_PAGE // 每个参数页大小(一页)
#define NP_SAVE_BYTES_PER_BLOCK SNF_BYTES_PER_SEC // 每个参数块大小(一个扇区)
#define NP_SAVE_BLOCKS_PER_SEC 16 // 每个参数块页数,第一页存储参数页有效标志,实际共15个页用于存储参数
#define GET_NORPARA_BLOCK_ADDR(bidx) (NORPARA_BEG_ADDR+(bidx)*NP_SAVE_BYTES_PER_BLOCK) // 获取参数块起始地址
//----------------------------------------------------
typedef struct
{
int paraEn; // 参数块有效标志
NorParaBlock norParaBlock; // 参数块数据
s32 * pParaList; // 参数列表(包含参数类型,最小最大值和默认值)
char * pParasName; // 参数名称列表
// 存储
u32 pageFlag[NP_SAVE_BLOCKS_PER_SEC]; // 参数页标志
}NorParaBlockCtrl;
NorParaBlockCtrl g_norParaBlockList[MAX_PARA_BLOCK];
//----------------------------------------------------
const char * SHOWP_STR =
"\t" " 显示或加载参数 " "\r\n"
"\t" " p1 p2" "\r\n"
"\t" " 0 0 显示全部参数 " "\r\n"
"\t" " b001 0 显示参数块b " "\r\n"
"\t" " b002 0 参数块b加载默认参数 " "\r\n"
"\t" " b003 0 参数块b重新加载参数 " "\r\n"
;
void ShowPara(char * para1, char * para2);
const char * SETP_STR =
"\t" "设置参数 " "\r\n"
"\t" " p1 p2" "\r\n"
"\t" " b00x val 设置参数块b, 参数ID x, 参数值 val " "\r\n"
"\t" " 10b000 0 保存参数块b " "\r\n"
;
void SetPara(char * para1, char * para2);
//----------------------------------------------------
void InitNorParas(void)
{
static int g_inited = 0;
if (g_inited == 0)
{
g_inited = 1;
InitNorSpi(); // 初始化 nor flash 访问 SPI
SNFlashInit(SetNorSpiNssOn, SetNorSpiNssOff, NorSpiReadByte, NorSpiWriteByte); // 初始化nor flash 并注册读写函数
// 参数块初始化
for(int i = 0; i < MAX_PARA_BLOCK; i++)
{
memset(&g_norParaBlockList[i], 0, sizeof(NorParaBlockCtrl));
LoadNorParas(i);
}
AddShellCmd("SHOWPARA", SHOWP_STR, ShowPara);
AddShellCmd("SETPARA", SETP_STR, SetPara);
}
}
// 获取参数块有效标志
int GetNorParaEn(int bIdx)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return -1;
}
return g_norParaBlockList[bIdx].paraEn;
}
// 加载参数页有效标志
int LoadParaPageFlag(int bIdx)
{
NorParaBlockCtrl * pCtrl;
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return -1;
}
pCtrl = &g_norParaBlockList[bIdx];
return DatFlashRdData(GET_NORPARA_BLOCK_ADDR(bIdx), (u8 *)(&pCtrl->pageFlag[0]), NP_SAVE_BLOCKS_PER_SEC*sizeof(u32));
}
// 保存参数页有效标志
int SaveParaPageFlag(int bIdx)
{
NorParaBlockCtrl * pCtrl;
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return -1;
}
pCtrl = &g_norParaBlockList[bIdx];
return DatFlashWrData(GET_NORPARA_BLOCK_ADDR(bIdx), (u8 *)(&pCtrl->pageFlag[0]), NP_SAVE_BLOCKS_PER_SEC*sizeof(u32));
}
// 设置参数页有效标志
int SetParaPageFlagValue(int bIdx, int pIdx, int enFlag)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || pIdx < 0 || pIdx >= NP_SAVE_BLOCKS_PER_SEC)
{
return -1;
}
if (enFlag == 0)
{
g_norParaBlockList[bIdx].pageFlag[pIdx] = 0; // 失效,0xffffffff未使用页
}
else
{
g_norParaBlockList[bIdx].pageFlag[pIdx] = PARA_VALID+pIdx; // 有效
}
return 0;
}
// 从参数页标志得到当前有效参数页
int GetSaveIdxFromPageFlag(int bIdx)
{
int i;
NorParaBlockCtrl * pCtrl;
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return -1;
}
pCtrl = &g_norParaBlockList[bIdx];
for(i = 1; i < NP_SAVE_BLOCKS_PER_SEC; i++)
{
if (pCtrl->pageFlag[i] == PARA_VALID+i)
{
return i;
}
}
return -2;
}
// 得到下一个未使用页
int GetNextSaveIdxFromPageFlag(int bIdx)
{
int i;
NorParaBlockCtrl * pCtrl;
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return -1;
}
pCtrl = &g_norParaBlockList[bIdx];
for (i = 1; i < NP_SAVE_BLOCKS_PER_SEC; i++)
{
if (pCtrl->pageFlag[i] == 0xffffffff)
{
return i;
}
}
return -2;
}
// 读取参数
// bIdx:参数块ID
// return: -1:参数加载错误,所有参数页都被废弃,未找到有效参数
// 0:正确返回值
int LoadNorParas(int bIdx)
{
u32 addr; //
NorParaBlockCtrl * pCtrl;
int idx, rslt;
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return -1;
}
pCtrl = &g_norParaBlockList[bIdx];
memset(pCtrl, 0, sizeof(NorParaBlockCtrl));
// 读入扇区存储参数有效标志
rslt = LoadParaPageFlag(bIdx);
if (rslt < 0)
{
return -1;
}
idx = GetSaveIdxFromPageFlag(bIdx); // 得到当前有效参数页id
if (idx < 0)
{
printf("load nor para error, code=%d\r\n", idx);
return -1;
}
printf("load nor para block %d, page is %d\r\n", bIdx, idx);
addr = GET_NORPARA_BLOCK_ADDR(bIdx) + (idx * NP_BLOCK_BYTES);
DatFlashRdData(addr, (u8*)&pCtrl->norParaBlock, sizeof(NorParaBlock));
g_norParaBlockList[bIdx].paraEn = PARA_VALID; // 参数有效
return 0;
}
// 保存参数
//bIdx 定义的参数块ID
int SaveNorParas(int bIdx)
{
u32 addr;
int cidx, nidx;
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return -1;
}
cidx = GetSaveIdxFromPageFlag(bIdx);
nidx = GetNextSaveIdxFromPageFlag(bIdx);
if (cidx < 0)
{
cidx = 0;
}
if (nidx < 0) // 超出扇区
{
printf("overflow, erase 4k\r\n");
DatFlash4kErase(GET_NORPARA_BLOCK_ADDR(bIdx), 1); // 擦除整个扇区
LoadParaPageFlag(bIdx);
cidx = 0;
nidx = GetNextSaveIdxFromPageFlag(bIdx);
}
if (nidx < 0) //
{
printf("SaveNorParas error\r\n");
return -2;
}
// 将参数存储在之后的页中
addr = GET_NORPARA_BLOCK_ADDR(bIdx) + ((nidx) * NP_BLOCK_BYTES);
DatFlashWrDataWithErase(addr, (u8 *)&g_norParaBlockList[bIdx].norParaBlock, sizeof(NorParaBlock));
SetParaPageFlagValue(bIdx, nidx, 1); // 设置新参数存储页有效
SetParaPageFlagValue(bIdx, cidx, 0); // 废弃旧的参数存储页
SaveParaPageFlag(bIdx); // 保存参数页标志
g_norParaBlockList[bIdx].paraEn = PARA_VALID; // 参数有效
printf("save nor para successful, page is %d \r\n", nidx);
return 0;
}
// 获取并返回参数块
NorParaBlock * GetNorParaBlock(int bIdx)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK)
{
return NULL;
}
return &g_norParaBlockList[bIdx].norParaBlock;
}
// 设置参数名称
void SetNorParaNameString(int bIdx, void * pName)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK )
{
return;
}
g_norParaBlockList[bIdx].pParasName = pName;
}
// 设置参数列表(参数类型,最小最大值默认值)
void SetNorParaList(int bIdx, void * pPara)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK )
{
return;
}
g_norParaBlockList[bIdx].pParaList = pPara;
}
// 加载默认参数
void LoadNorDefPara(int bIdx)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || g_norParaBlockList[bIdx].pParaList == NULL)
{
return;
}
for(int i = 0; i < PARA_NUM_PER_BLK; i++)
{
int offset = i * 4 + 3;
g_norParaBlockList[bIdx].norParaBlock.buff[i] = * ( g_norParaBlockList[bIdx].pParaList + offset );
}
}
// 参数范围检测(检测参数块内的全部参数)
void CheckParaRange(int bIdx)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || g_norParaBlockList[bIdx].pParaList == NULL)
{
return;
}
for(int i = 0; i < PARA_NUM_PER_BLK; i++)
{
int paratype, minOffset, maxOffset; // 参数类型,最小最大值指针偏移量
paratype = (i * 4);
minOffset = (i * 4 + 1);
maxOffset = (i * 4 + 2);
if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_S)
{
if (g_norParaBlockList[bIdx].norParaBlock.buff[i] < (*(g_norParaBlockList[bIdx].pParaList + minOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + minOffset));
printf("less than min, equal min, block %d, id is %d\r\n", bIdx, i+1);
}
else if (g_norParaBlockList[bIdx].norParaBlock.buff[i] > (*( g_norParaBlockList[bIdx].pParaList + maxOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset));
printf("more than max, equal max, block %d, id is %d\r\n", bIdx, i+1);
}
}
else if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_U)
{
if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[i] < (u32)(*(g_norParaBlockList[bIdx].pParaList + minOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + minOffset));
printf("less than min, equal min, block %d, id is %d\r\n", bIdx, i+1);
}
else if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[i] > (u32)(*( g_norParaBlockList[bIdx].pParaList + maxOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset));
printf("more than max, equal max, block %d, id is %d\r\n", bIdx, i+1);
}
}
}
}
// 参数范围检测(检测参数块内的某个参数)
void CheckAParaRange(int bIdx, int id)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || g_norParaBlockList[bIdx].pParaList == NULL)
{
return;
}
if (id >= 0 && id < PARA_NUM_PER_BLK)
{
int paratype, minOffset, maxOffset; // 参数类型,最小最大值指针偏移量
paratype = (id * 4);
minOffset = (id * 4 + 1);
maxOffset = (id * 4 + 2);
if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_S)
{
if (g_norParaBlockList[bIdx].norParaBlock.buff[id] < (*( g_norParaBlockList[bIdx].pParaList + minOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + minOffset));
printf("less than min, equal min\r\n");
}
else if (g_norParaBlockList[bIdx].norParaBlock.buff[id] > (*( g_norParaBlockList[bIdx].pParaList + maxOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset));
printf("more than max, equal max\r\n");
}
}
else if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_U)
{
if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[id] < (u32)(*( g_norParaBlockList[bIdx].pParaList + minOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + minOffset));
printf("less than min, equal min\r\n");
}
else if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[id] > (u32)(*( g_norParaBlockList[bIdx].pParaList + maxOffset)) )
{
g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset));
printf("more than max, equal max\r\n");
}
}
}
}
// 获取一个参数
s32 GetANorPara(int bIdx, int id)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK )
{
return -1;
}
if (GetNorParaEn(bIdx) == PARA_VALID)
{
int idx = id - 1;
if (idx >= 0 && idx < PARA_NUM_PER_BLK)
{
return g_norParaBlockList[bIdx].norParaBlock.buff[idx];
}
}
return 0;
}
// 设置一个参数
// 该函数不提供保存功能,需参数设置完成后手动保存
// 注:norflash不宜频繁写
void SetANorPara(int bIdx, int id, s32 val)
{
if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK )
{
return;
}
char * pInfo = NULL;
int idx = id - 1;
if (idx >= 0 && idx < PARA_NUM_PER_BLK)
{
if ((*(g_norParaBlockList[bIdx].pParaList + idx*4)) == PTYPE_S)
{
s32 old;
pInfo = (g_norParaBlockList[bIdx].pParasName+(idx)*PARA_STR_LEN);
printf("set para block %d\r\n", bIdx+1);
old = g_norParaBlockList[bIdx].norParaBlock.buff[idx];
g_norParaBlockList[bIdx].norParaBlock.buff[idx] = val;
CheckAParaRange(bIdx, idx);
if (pInfo == NULL)
{
pInfo = "";
}
printf("%d. (%s) = %d, oldvalue=%d\r\n", (id), pInfo, val, old);
}
else
{
u32 old;
pInfo = (g_norParaBlockList[bIdx].pParasName+(idx)*PARA_STR_LEN);
printf("set para block %d\r\n", bIdx+1);
old = (u32)g_norParaBlockList[bIdx].norParaBlock.buff[idx];
g_norParaBlockList[bIdx].norParaBlock.buff[idx] = val;
CheckAParaRange(bIdx, idx);
if (pInfo == NULL)
{
pInfo = "";
}
printf("%d. (%s) = %d, oldvalue=%d\r\n", (id), pInfo, (u32)val, old);
}
}
}
/*
* p1 p2
* 1001 val // 设置参数块1,参数ID 1,参数值val
* 1002 val // 设置参数块1,参数ID 2,参数值val
......
* 2001 val // 设置参数块2,参数ID 1,参数值val
* 2002 val // 设置参数块2,参数ID 2,参数值val //不提供保存功能
......
* 101000 // 保存参数块1
* 102000 // 保存参数块2
*/
void SetPara(char * para1, char * para2)
{
int p1, p2, p3;
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)
{
}
p3 = p1 / 1000; // 参数块id
p1 = p1 % 1000; // 参数id
// p2:参数值
if (p3 > 0 && p3 <= MAX_PARA_BLOCK)
{
SetANorPara(p3-1, p1, p2);
}
else if (p3 > 100 && p3 <= 116)
{
p3 -= 101;
printf("save block %d\r\n", p3+1);
SaveNorParas(p3);
}
}
/*
* p1 p2
* // 显示全部参数
* 1001 // 显示参数块1
* 2001 // 显示参数块2
* 1002 // 参数块1加载默认参数
* 2002 // 参数块2加载默认参数
* 1003 // 参数块1重新加载参数
* 2003 // 参数块2重新加载参数
*/
void ShowPara(char * para1, char * para2)
{
int p1, p2, p3;
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)
{
}
p3 = p1 / 1000; // 参数块id
p1 = p1 % 1000; // 功能码
// p2: 参数ID
if (p3 <= MAX_PARA_BLOCK)
{
switch(p1)
{
case 0:
{
// 显示全部块参数
for (int j = 0; j < MAX_PARA_BLOCK; j++)
{
printf("\r\npara block %d:\r\n", j+1);
if (g_norParaBlockList[j].pParasName == NULL)
{
continue;
}
for(int i = 0; i < PARA_NUM_PER_BLK; i++)
{
char * pStr;
pStr = g_norParaBlockList[j].pParasName + (i*PARA_STR_LEN);
if (pStr == NULL)
{
pStr = "";
}
if ( strcmp(pStr, "") != 0 )
{
if ((*(g_norParaBlockList[j].pParaList+i*4)) == PTYPE_S)
{
printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr,
GetANorPara(j, i+1),
*(g_norParaBlockList[j].pParaList+ i*4+1),
*(g_norParaBlockList[j].pParaList+ i*4+2),
*(g_norParaBlockList[j].pParaList+ i*4+3) );
}
else
{
printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr,
(u32)GetANorPara(j, i+1),
(u32)(*(g_norParaBlockList[j].pParaList+ i*4+1)),
(u32)(*(g_norParaBlockList[j].pParaList+ i*4+2)),
(u32)(*(g_norParaBlockList[j].pParaList+ i*4+3)) );
}
}
DelayMs(1);
}
}
break;
}
case 1:
{
// 显示某个参数块
printf("\r\npara block %d:\r\n", p3);
if (g_norParaBlockList[p3-1].pParasName != NULL)
{
for(int i = 0; i < PARA_NUM_PER_BLK; i++)
{
char * pStr;
pStr = g_norParaBlockList[p3-1].pParasName + (i*PARA_STR_LEN);
if (pStr == NULL)
{
pStr = "";
}
if ( strcmp(pStr, "") != 0 )
{
if ((*(g_norParaBlockList[j].pParaList+i*4)) == PTYPE_S)
{
printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr,
GetANorPara(p3-1, i+1),
*(g_norParaBlockList[p3-1].pParaList+ i*4+1),
*(g_norParaBlockList[p3-1].pParaList+ i*4+2),
*(g_norParaBlockList[p3-1].pParaList+ i*4+3) );
}
else
{
printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr,
(u32)GetANorPara(p3-1, i+1),
(u32)(*(g_norParaBlockList[p3-1].pParaList+ i*4+1)),
(u32)(*(g_norParaBlockList[p3-1].pParaList+ i*4+2)),
(u32)(*(g_norParaBlockList[p3-1].pParaList+ i*4+3)) );
}
}
DelayMs(1);
}
}
break;
}
case 2:
{
int bidx = p3 - 1;
// 加载默认参数
if (bidx >= 0)
{
printf("load def para block %d:\r\n", p3);
LoadNorDefPara(bidx);
}
break;
}
case 3:
{
int bidx = p3 - 1;
if (bidx >= 0)
{
printf("load para block %d:\r\n", p3);
// 重新加载参数
LoadNorParas(bidx);
}
break;
}
default:
break;
}
}
}
#endif