/**
******************************************************************************
* @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.
*
*
© COPYRIGHT 2016 TMC
******************************************************************************
**/
#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;
}