TMC32_QJB/App/configuration.c
2026-04-30 16:23:12 +08:00

329 lines
9.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
******************************************************************************
* @file configuration.c
* @author TMC Scan Team
* @version V1.0.0
* @date 09/07/2019
* @brief
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, TMC SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2016 TMC</center></h2>
******************************************************************************
**/
#include "global.h"
CfgSetting *gCurrentSysCfg;
__align(8) CfgSetting gConfgBuf;
extern uint32_t gFunTrace;
//定义AB备份区地址和用户默认配置区
const uint8_t A_CFGBUF[FLASHPAGESIZE] __attribute__((at(A_CFGBUF_ADDR))) = {0};
const uint8_t B_CFGBUF[FLASHPAGESIZE] __attribute__((at(B_CFGBUF_ADDR))) = {0};
const uint16_t crc_table[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};
/**
* @function CRCGenerate
* @brief 生成CRC校验码
* @param[in] pData 数据
* @param[in] dLen 数据的长度
* @return 16位CRC校验码
*/
uint16_t CRCGenerate(uint8_t *pData, uint16_t dLen)
{
uint16_t crc = 0;
uint16_t crcleft, crcright, crcinvert;
uint8_t crc_H4;
while(dLen--)
{
crc_H4 = (uint8_t)(crc >> 12);
crc = crc << 4;
crc = crc ^ crc_table[ crc_H4 ^ (*pData >> 4)];
crc_H4 = (uint8_t)(crc >> 12);
crc = crc << 4;
crc = crc ^ crc_table[ crc_H4 ^ (*pData & 0x0f)];
pData++;
}
crcleft = crc << 8;
crcright = crc >> 8;
crcinvert = crcleft | crcright;
return crcinvert;
}
/**
* @function AppCfgInit
* @brief 上电检查配置区,完成初始配置
* @param[in] 无
* @return 无
*/
void SystemCfgInit(void)
{
uint8_t snA, snB;
uint16_t crcA, crcB, oldcrcA, oldcrcB;
uint16_t cfgflagA, cfgflagB;
CfgSetting *right_cfg;
crcA = CRCGenerate((uint8_t *)(A_CFGBUF_ADDR + 2), sizeof(CfgSetting) - 2);
crcB = CRCGenerate((uint8_t *) (B_CFGBUF_ADDR + 2), sizeof(CfgSetting) - 2);
snA = ((CfgSetting *)A_CFGBUF_ADDR)->SN;
snB = ((CfgSetting *)B_CFGBUF_ADDR)->SN;
oldcrcA = ((CfgSetting *)A_CFGBUF_ADDR)->CRCData;
oldcrcB = ((CfgSetting *)B_CFGBUF_ADDR)->CRCData;
TMC_FLASH_Msp_Init();
if((crcA == oldcrcA) && (crcB == oldcrcB))
{
if(snA == (snB + 1))
{
gCurrentSysCfg = (CfgSetting *)A_CFGBUF_ADDR;
}
else if(snB == (snA + 1))
{
gCurrentSysCfg = (CfgSetting *)B_CFGBUF_ADDR;
}
else
{
RestoreCfg();
}
Memcpy((uint8_t *) &gConfgBuf, (uint8_t *) gCurrentSysCfg, sizeof(CfgSetting));
return;
}
if((crcA == oldcrcA) && (cfgflagA == CFG_EXIST_FLAG))
{
right_cfg = (CfgSetting *)A_CFGBUF_ADDR;
}
else if((crcB == oldcrcB) && (cfgflagB == CFG_EXIST_FLAG))
{
right_cfg = (CfgSetting *)B_CFGBUF_ADDR;
}
else
{
RestoreCfg();
return;
}
gCurrentSysCfg = right_cfg;
return;
}
void CopyCfg(CfgSetting *cfg)
{
gConfgBuf.CRCData = cfg->CRCData;
gConfgBuf.CfgExsitFlag = cfg->CfgExsitFlag;
gConfgBuf.SN = cfg->SN;
gConfgBuf.bSettingCodeFlag = cfg->bSettingCodeFlag;
gConfgBuf.comunitationType = cfg->comunitationType;
gConfgBuf.uartBaudRate = cfg->uartBaudRate;
gConfgBuf.voiceScanFinish = cfg->voiceScanFinish;
gConfgBuf.HIDPollRate = cfg->HIDPollRate;
gConfgBuf.HIDKBValToRelInterval = cfg->HIDKBValToRelInterval;
gConfgBuf.HIDKBRelToValInterval = cfg->HIDKBRelToValInterval;
gConfgBuf.buzzerStatus = cfg->buzzerStatus;
gConfgBuf.buzzerFrequency = cfg->buzzerFrequency;
gConfgBuf.buzzerTime = cfg->buzzerTime;
gConfgBuf.buzzerDuty = cfg->buzzerDuty;
gConfgBuf.voiceStatus = cfg->voiceStatus;
gConfgBuf.voiceVolume = cfg->voiceVolume;
gConfgBuf.ledStatus = cfg->ledStatus;
gConfgBuf.ledFlash = cfg->ledFlash;
gConfgBuf.OpenvoiceChangeFlag = cfg->OpenvoiceChangeFlag;
gConfgBuf.scanCodeMode = cfg->scanCodeMode;
gConfgBuf.cmdModeTime = cfg->cmdModeTime;
gConfgBuf.sameCodeInterval = cfg->sameCodeInterval;
gConfgBuf.differentCodeInterval = cfg->differentCodeInterval;
gConfgBuf.EAN13_ID = cfg->EAN13_ID;
gConfgBuf.EAN13 = cfg->EAN13;
gConfgBuf.EAN13_2 = cfg->EAN13_2;
gConfgBuf.EAN13_5 = cfg->EAN13_5;
gConfgBuf.EAN8_ID = cfg->EAN8_ID;
gConfgBuf.EAN8 = cfg->EAN8;
gConfgBuf.EAN8_2 = cfg->EAN8_2;
gConfgBuf.EAN8_5 = cfg->EAN8_5;
gConfgBuf.UPC_A_ID = cfg->UPC_A_ID;
gConfgBuf.UPCA = cfg->UPCA;
gConfgBuf.UPCA_2 = cfg->UPCA_2;
gConfgBuf.UPCA_5 = cfg->UPCA_5;
gConfgBuf.UPCE0_ID = cfg->UPCE0_ID;
gConfgBuf.UPCE0 = cfg->UPCE0;
gConfgBuf.UPCE1_ID = cfg->UPCE1_ID;
gConfgBuf.UPCE1 = cfg->UPCE1;
gConfgBuf.UPCE1_2 = cfg->UPCE1_2;
gConfgBuf.UPCE1_5 = cfg->UPCE1_5;
gConfgBuf.Code128_ID = cfg->Code128_ID;
gConfgBuf.Code128 = cfg->Code128;
gConfgBuf.Code128MinLen = cfg->Code128MinLen;
gConfgBuf.Code128MaxLen = cfg->Code128MaxLen;
gConfgBuf.Code39_ID = cfg->Code39_ID;
gConfgBuf.Code39 = cfg->Code39;
gConfgBuf.Code39_32 = cfg->Code39_32;
gConfgBuf.Code39_32_Full_ASCII = cfg->Code39_32_Full_ASCII;
gConfgBuf.Code39MinLen = cfg->Code39MinLen;
gConfgBuf.Code39MaxLen = cfg->Code39MaxLen;
gConfgBuf.Code93_ID = cfg->Code93_ID;
gConfgBuf.Code93 = cfg->Code93;
gConfgBuf.Code93MinLen = cfg->Code93MinLen;
gConfgBuf.Code93MaxLen = cfg->Code93MaxLen;
gConfgBuf.CodeBar_ID = cfg->CodeBar_ID;
gConfgBuf.CodeBar = cfg->CodeBar;
gConfgBuf.CodeBarMinLen = cfg->CodeBarMinLen;
gConfgBuf.CodeBarMaxLen = cfg->CodeBarMaxLen;
gConfgBuf.QR_ID = cfg->QR_ID;
gConfgBuf.QR = cfg->QR;
gConfgBuf.Interleaved25_ID = cfg->Interleaved25_ID;
gConfgBuf.Interleaved25 = cfg->Interleaved25;
gConfgBuf.Interleaved25MinLen = cfg->Interleaved25MinLen;
gConfgBuf.Interleaved25MaxLen = cfg->Interleaved25MaxLen;
gConfgBuf.Industrail25_ID = cfg->Industrail25_ID;
gConfgBuf.Industrial_25 = cfg->Industrial_25;
gConfgBuf.Industrial_25MinLen = cfg->Industrial_25MinLen;
gConfgBuf.Industrial_25MaxLen = cfg->Industrial_25MaxLen;
gConfgBuf.Matrix25_ID = cfg->Matrix25_ID;
gConfgBuf.Matrix25 = cfg->Matrix25;
gConfgBuf.Matrix25MinLen = cfg->Matrix25MinLen;
gConfgBuf.Matrix25MaxLen = cfg->Matrix25MaxLen;
gConfgBuf.IATA25_ID = cfg->IATA25_ID;
gConfgBuf.IATA25 = cfg->IATA25;
gConfgBuf.IATA25MinLen = cfg->IATA25MinLen;
gConfgBuf.IATA25MaxLen = cfg->IATA25MaxLen;
gConfgBuf.PDF417 = cfg->PDF417;
gConfgBuf.DM = cfg->DM;
gConfgBuf.inputCodeType = cfg->inputCodeType;
gConfgBuf.outputCodeType = cfg->outputCodeType;
gConfgBuf.billModeStatus = cfg->billModeStatus;
gConfgBuf.endCode = cfg->endCode;
gConfgBuf.prefixLen = cfg->prefixLen;
gConfgBuf.suffixLen = cfg->suffixLen;
for(int i=0;i<16;i++)gConfgBuf.prefix[i] = cfg->prefix[i];
for(int i=0;i<16;i++)gConfgBuf.suffix[i] = cfg->suffix[i];
gConfgBuf.uartOutputProtocal = cfg->uartOutputProtocal;
gConfgBuf.ECIMode = cfg->ECIMode;
gConfgBuf.sensitivity = cfg->sensitivity;
gConfgBuf.stableTime = cfg->stableTime;
gConfgBuf.statusKeyVoice = cfg->statusKeyVoice;
gConfgBuf.voiceGain = cfg->voiceGain;
gConfgBuf.statusKey = cfg->statusKey;
}
/**
* @function RestoreCfg
* @brief 将AB备份页都恢复为默认配置
* @param[in] 无
* @return 返回正确或错误
*/
uint8_t RestoreCfg(void)
{
//AB页都恢复为默认配置
uint8_t status;
gCurrentSysCfg = (CfgSetting *)&DefaultCfg;
//把默认配置页内容拷贝到缓存中
CopyCfg((CfgSetting *)&DefaultCfg);
gConfgBuf.CRCData = CRCGenerate((uint8_t *)&gConfgBuf + 2, sizeof(CfgSetting) - 2);
//对A页擦
status = FLASH_NormalErase((uint8_t *)A_CFGBUF_ADDR);
if(status != TMC_OK)
{
return TMC_ERROR;
}
//对A页写
status = FLASH_WriteDoubleWords((uint32_t)A_CFGBUF_ADDR, (uint32_t)&gConfgBuf, sizeof(CfgSetting));
if(status != TMC_OK)
{
return TMC_ERROR;
}
//对B页擦
status = FLASH_NormalErase((uint8_t *)B_CFGBUF_ADDR);
if(status != TMC_OK)
{
return TMC_ERROR;
}
//改SN对B页写
gConfgBuf.SN = DefaultCfg.SN + 1;
gConfgBuf.CRCData = CRCGenerate((uint8_t *)&gConfgBuf + 2, sizeof(CfgSetting) - 2);
status = FLASH_WriteDoubleWords(B_CFGBUF_ADDR, ((uint32_t)&gConfgBuf), sizeof(CfgSetting));
if(status != TMC_OK)
{
return TMC_ERROR;
}
//标记最新页
gCurrentSysCfg = (CfgSetting *)B_CFGBUF_ADDR;
return TMC_OK;
}
/**
* @function UpdateCfg
* @brief 更新配置区
* @param[in] 无
* @return 返回正确或错误
*/
uint8_t UpdateCfg(void)
{
uint32_t pre_cfg;
uint8_t status;
gFunTrace = 39;
//确定旧页的地址
if((uint32_t) gCurrentSysCfg == A_CFGBUF_ADDR)
{
pre_cfg = B_CFGBUF_ADDR;
}
else
{
pre_cfg = A_CFGBUF_ADDR;
}
gConfgBuf.SN = gConfgBuf.SN + 1;
gConfgBuf.CRCData = CRCGenerate((uint8_t *)&gConfgBuf + 2, sizeof(CfgSetting) - 2);
//对旧页页擦、页写
gFunTrace = 40;
status = FLASH_NormalErase((uint8_t *)pre_cfg);
gFunTrace = 41;
if(status != TMC_OK)
{
return TMC_ERROR;
}
gFunTrace = 42;
status = FLASH_WriteDoubleWords(pre_cfg, ((uint32_t)&gConfgBuf), sizeof(CfgSetting));
gFunTrace = 43;
if(status != TMC_OK)
{
return TMC_ERROR;
}
//标记最新页
gCurrentSysCfg = (CfgSetting *)pre_cfg;
return TMC_OK;
}