300 lines
6.8 KiB
C
300 lines
6.8 KiB
C
/* Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* High Level description:
|
|
* http://www.ti.com/lit/ds/symlink/device.pdf
|
|
* Thechnical Reference:
|
|
* http://www.ti.com/lit/ug/sluu431/sluu431.pdf
|
|
*/
|
|
|
|
#include "includes.h"
|
|
#include "device_param.h"
|
|
#include "ff.h"
|
|
#include "ff_shell.h"
|
|
#include "flash_if.h"
|
|
#include "dflash_sf1.h"
|
|
#include "dflash_chg_ctrl.h"
|
|
#include "dflash_cal.h"
|
|
#include "dflash_sbs.h"
|
|
#include "temp.h"
|
|
#include "asutil.h"
|
|
|
|
#define PARAM_INIT_DATA 0xAAAA32F4
|
|
#define CAL_PARAM_BASE_ADDR mBMS_PARAM_BASE_ADDR + 0x2000
|
|
|
|
const char ParamFileName[] = "0:/param.bin";
|
|
FIL pFile; /* File objects */
|
|
|
|
TDEVICE_VALUE device_value, bakdevice_value, dis_device_value;
|
|
TDEVICE_STATUS device_status, dis_device_status;
|
|
TDEVICE_PARAM device_param, dis_device_param;
|
|
TDEVICE_INV device_inv, dis_device_inv;
|
|
|
|
void SetCellQuantity(u8 cQuantity)
|
|
{
|
|
if ((cQuantity > 0) && (cQuantity <= 16))
|
|
{
|
|
device_param.info.CellQuantity = cQuantity;
|
|
Save_Param();
|
|
}
|
|
}
|
|
|
|
void Param_Init(u8 flag, u8 factory)
|
|
{
|
|
if (factory)
|
|
Cal_InitData();
|
|
if (flag)
|
|
SBS_InitData();
|
|
SF1_InitData();
|
|
ChgCtrlCfg_InitData();
|
|
|
|
}
|
|
|
|
/*
|
|
Inventory Data Load and Save Function
|
|
*/
|
|
void Inv_Init(void)
|
|
{
|
|
device_inv.ManufactureDate = 0;
|
|
memset(device_inv.ModuleNo, 0x00, sizeof(device_inv.ModuleNo));
|
|
memset(device_inv.SerialNo, 0x00, sizeof(device_inv.SerialNo));
|
|
}
|
|
|
|
void Save_InvData(void)
|
|
{
|
|
uint32_t result = 0;
|
|
uint32_t sector_addr = mBMS_INV_BASE_ADDR;
|
|
|
|
/* init flash */
|
|
FLASH_If_Init();
|
|
result = FLASH_If_SingleSectorErase(sector_addr);
|
|
|
|
if (result == 0)
|
|
{
|
|
uint32_t base = (uint32_t)&device_inv;
|
|
uint32_t len = sizeof(TDEVICE_INV);
|
|
|
|
if ((len % 4) > 0)
|
|
len = len / 4 + 1;
|
|
else
|
|
len = len / 4;
|
|
|
|
result = FLASH_If_Write(§or_addr, (uint32_t *)base, len);
|
|
#ifdef CONSOLE_DEBUG
|
|
if (result != 0)
|
|
printf("\r\n Inventory save fail (%d)", result);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void Load_InvData(void)
|
|
{
|
|
memcpy(&device_inv, (uint8_t *)mBMS_INV_BASE_ADDR, sizeof(TDEVICE_INV));
|
|
if (device_inv.initdata != INV_INIT_DATA)
|
|
{
|
|
#ifdef CONSOLE_DEBUG
|
|
printf("\r\n Initialize Inventory Data");
|
|
#endif
|
|
device_inv.initdata = INV_INIT_DATA;
|
|
Inv_Init();
|
|
Save_InvData();
|
|
}
|
|
}
|
|
|
|
void Load_Param(void)
|
|
{
|
|
memcpy(&device_param, (uint8_t *)mBMS_PARAM_BASE_ADDR, sizeof(TDEVICE_PARAM));
|
|
|
|
if (device_param.initdata != PARAM_INIT_DATA)
|
|
{
|
|
device_param.initdata = PARAM_INIT_DATA;
|
|
// Parameter init
|
|
Param_Init(true, true);
|
|
|
|
Save_Param();
|
|
}
|
|
|
|
ADC_Param_Load();
|
|
|
|
/* KT Requirement: Cell deviation 200mV threshold (Warning/Time unused, CV_Diff_ProtectHoldTime 24h default) */
|
|
if ((device_param.safety.cv_diff.Cell_Voltage_Diff_Threshold == 0) ||
|
|
(device_param.safety.cv_diff.Cell_Voltage_Diff_Threshold > 200))
|
|
{
|
|
device_param.safety.cv_diff.Cell_Voltage_Diff_Threshold = 200;
|
|
}
|
|
|
|
/* Load Inventory Data */
|
|
Load_InvData();
|
|
|
|
/* KT Requirement: Cell balancing threshold set to 3350mV in RAM at boot */
|
|
device_param.chg_ctrl.cell_bal_cfg.Cell_Balance_Threshold = 3350;
|
|
}
|
|
|
|
void Save_Param(void)
|
|
{
|
|
uint32_t result = 0;
|
|
uint32_t sector_addr = mBMS_PARAM_BASE_ADDR;
|
|
|
|
result = FLASH_If_SingleSectorErase(sector_addr);
|
|
|
|
if (result == 0)
|
|
{
|
|
uint32_t base = (uint32_t)&device_param;
|
|
uint32_t len = sizeof(TDEVICE_PARAM);
|
|
|
|
if ((len % 4) > 0)
|
|
len = len / 4 + 1;
|
|
else
|
|
len = len / 4;
|
|
|
|
result = FLASH_If_Write(§or_addr, (uint32_t *)base, len);
|
|
|
|
#ifdef CONSOLE_DEBUG
|
|
if (result != 0)
|
|
printf("\r\n Param save fail (%d)", result);
|
|
#endif /* CONSOLE_DEBUG */
|
|
}
|
|
}
|
|
|
|
void LoadFwInfo(void)
|
|
{
|
|
memcpy(&fwinfo, (uint8_t *)mBMS_FW_INFO_BASE_ADDR, sizeof(FW_INFO));
|
|
}
|
|
|
|
uint32_t SaveFwInfo(void)
|
|
{
|
|
uint32_t result = 0;
|
|
uint32_t sector_addr = mBMS_FW_INFO_BASE_ADDR;
|
|
|
|
/* init flash */
|
|
FLASH_If_Init();
|
|
result = FLASH_If_SingleSectorErase(sector_addr);
|
|
|
|
if (result == 0)
|
|
{
|
|
uint32_t base = (uint32_t)&fwinfo;
|
|
uint32_t len = sizeof(FW_INFO);
|
|
|
|
if ((len % 4) > 0)
|
|
len = len / 4 + 1;
|
|
else
|
|
len = len / 4;
|
|
|
|
result = FLASH_If_Write(§or_addr, (uint32_t *)base, len);
|
|
if ((result == 0) &&
|
|
((sector_addr != (mBMS_FW_INFO_BASE_ADDR + len * 4)) ||
|
|
(memcmp((const void *)mBMS_FW_INFO_BASE_ADDR, &fwinfo, sizeof(FW_INFO)) != 0))) {
|
|
result = 3; /* Incomplete write or flash readback mismatch. */
|
|
}
|
|
|
|
#ifdef CONSOLE_DEBUG
|
|
if (result != 0)
|
|
printf("\r\n Fw information save fail (%d)", result);
|
|
#endif /* CONSOLE_DEBUG */
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void Load_Param_File(void)
|
|
{
|
|
FRESULT rc;
|
|
u32 wlen;
|
|
|
|
if (ReqUseFatfs())
|
|
{
|
|
rc = f_open(&pFile, ParamFileName, FA_READ);
|
|
if (rc == FR_NO_FILE)
|
|
{
|
|
rc = f_open(&pFile, ParamFileName, FA_CREATE_NEW | FA_WRITE);
|
|
if (rc == FR_OK)
|
|
{
|
|
// Parameter init
|
|
Param_Init(true, true);
|
|
|
|
f_lseek(&pFile, 0); // From start
|
|
rc = f_write(&pFile, (const char *)&device_param, sizeof(TDEVICE_PARAM), &wlen);
|
|
f_close(&pFile);
|
|
}
|
|
}
|
|
else if (rc == FR_OK)
|
|
{
|
|
if (pFile.obj.objsize != sizeof(TDEVICE_PARAM))
|
|
{
|
|
f_close(&pFile);
|
|
|
|
rc = f_unlink(ParamFileName);
|
|
if (rc != FR_OK) return;
|
|
|
|
rc = f_open(&pFile, ParamFileName, FA_CREATE_NEW | FA_WRITE);
|
|
|
|
if (rc == FR_OK)
|
|
{
|
|
// Parameter init
|
|
Param_Init(true, true);
|
|
|
|
f_lseek(&pFile, 0); // From start
|
|
rc = f_write(&pFile, (const char *)&device_param, sizeof(TDEVICE_PARAM), &wlen);
|
|
f_close(&pFile);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
f_lseek(&pFile, 0); // From start
|
|
f_read(&pFile, &device_param, sizeof(TDEVICE_PARAM), &wlen);
|
|
f_close(&pFile);
|
|
}
|
|
}
|
|
leaveFatfs();
|
|
}
|
|
|
|
ADC_Param_Load();
|
|
|
|
/* KT Requirement: Cell deviation 200mV threshold (Warning/Time unused, CV_Diff_ProtectHoldTime 24h default) */
|
|
if ((device_param.safety.cv_diff.Cell_Voltage_Diff_Threshold == 0) ||
|
|
(device_param.safety.cv_diff.Cell_Voltage_Diff_Threshold > 200))
|
|
{
|
|
device_param.safety.cv_diff.Cell_Voltage_Diff_Threshold = 200;
|
|
}
|
|
}
|
|
|
|
void Save_Param_File(void)
|
|
{
|
|
FRESULT rc;
|
|
u32 wlen;
|
|
|
|
if (ReqUseFatfs())
|
|
{
|
|
rc = f_open(&pFile, ParamFileName, FA_WRITE);
|
|
|
|
if (rc == FR_NO_FILE)
|
|
{
|
|
rc = f_open(&pFile, ParamFileName, FA_CREATE_NEW | FA_WRITE);
|
|
|
|
if (rc == FR_OK)
|
|
{
|
|
f_lseek(&pFile, 0); // From start
|
|
f_write(&pFile, (const char *)&device_param, sizeof(TDEVICE_PARAM), &wlen);
|
|
f_close(&pFile);
|
|
}
|
|
}
|
|
else if (rc == FR_OK)
|
|
{
|
|
f_lseek(&pFile, 0); // From start
|
|
f_write(&pFile, &device_param, sizeof(TDEVICE_PARAM), &wlen);
|
|
f_close(&pFile);
|
|
}
|
|
leaveFatfs();
|
|
}
|
|
}
|