/* 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/bq28400.pdf * Thechnical Reference: * http://www.ti.com/lit/ug/sluu431/sluu431.pdf */ #include "includes.h" #include "dflash_cal.h" #include "console.h" #include "asutil.h" #include "device_param.h" #include "vi.h" u8 SetCal_Param(u8 *text, u8 aDevice); u8 SetCal_Param1(u8 *text, u8 aDevice); s32 CalibrationVoltage(u16 voltage, u8 item) { s32 sum = 0; float a, b, result; switch (item) { case DSG_CURR_ID: sum = GetRealCurrentAdc(item) + device_param.cal.current.DC_Offset; break; case CHG_CURR_ID: sum = GetRealCurrentAdc(item) + device_param.cal.current.CC1_Offset; break; } a = (float)voltage / 100; b = (float)sum / 10000; result = a / b; return (s32)(result * 1000); } s32 CalibrationCurrentA(u16 current, u8 item) { s32 sum; float a, b, result; switch (item) { case DSG_CURR_ID: sum = GetRealCurrentSum() - device_param.cal.current.DC_Offset; break; case CHG_CURR_ID: sum = GetRealCurrentSum() - device_param.cal.current.CC1_Offset; break; } if (sum < 0) sum *= -1; a = (float)current / 100; b = (float)(sum) / 10000; result = a / b; return (s32)(result * 1000); } #ifdef CONSOLE_DEBUG /* Command processing in SETTING STATE */ s8 Process_DataCalSet(u8 *text, u16 size) { u16 i, ret; /* Invalid command if space is in first position */ if (size > 1) {if (text[1] != ' ') return(0);} text[size] = 0x00; ret = 1; switch (text[0]) { case 'o': /* Switch to operating mode */ screenmode = OP_MODE; ViewScreen(); break; case 's': /* Switch to setting status */ screenmode = SET_MODE; ViewScreen(); break; case 'd': /* Switch to diagnostic mode */ screenmode = DIAG_MODE; ViewScreen(); break; case '1': // OCV Alarm Parameter Setting case '2': // OCV Shutdown Parameter Setting case '3': // OCV Alarm Parameter Setting case '4': // OCV Shutdown Parameter Setting case '5': // OCV Shutdown Parameter Setting case '6': // OCV Shutdown Parameter Setting i = SetCal_Param(&text[2],text[0]); if (i == 0) UserMessage("COMMAND COMPLETE"); else if (i == 1) UserMessage("COMMAND FORMAT ERROR"); /* setting format error */ else UserMessage("COMMAND LIMIT ERROR"); /* setting limit error */ break; case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'K' : // Charge Current Calibration i = SetCal_Param1(&text[2], text[0]); if (i == 0) UserMessage("COMMAND COMPLETE"); else if (i == 1) UserMessage("COMMAND FORMAT ERROR"); /* setting format error */ else UserMessage("COMMAND LIMIT ERROR"); /* setting limit error */ break; case 'I': Cal_InitData(); Save_Param(); break; default : ret = 1; break; } return(ret); } u8 SetCal_Param(u8 *text, u8 aDevice) { u16 size, i, j; s16 aParam[4]; s32 bParam[4]; u8 temp[10]; u8 ret; u8 cmd; ret = 0; size = 0; while (text[size] != 0x00) size++; /* Measure total string length */ switch (aDevice) { case '1': // Cal_Voltage_Subclass i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; cmd = temp[0]; j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; aParam[0] = StrToInt(temp, j); /* Value */ switch (cmd) { case '1': device_param.cal.voltage.Cell_Scale_0 = aParam[0]; break; case '2': device_param.cal.voltage.Cell_Scale_1 = aParam[0]; break; case '3': device_param.cal.voltage.BAT_Gain = aParam[0]; break; case '4': device_param.cal.voltage.BAT_Offset = aParam[0]; break; default : return (1); } Save_Param(); break; case '2': // Cal_Discharge_Current_Subclass i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; cmd = temp[0]; j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; bParam[0] = StrToInt32(temp, j); /* Value */ switch (cmd) { case '1': device_param.cal.current.DC_Gain = bParam[0]; break; case '2': device_param.cal.current.DC_Offset = bParam[0]; break; default: return(1); } Save_Param(); break; case '3': // Cal_Charge_Current_Subclass i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; cmd = temp[0]; j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; bParam[0] = StrToInt32(temp, j); /* Value */ switch (cmd) { case '1': device_param.cal.current.CC1_Gain = bParam[0]; break; case '2': device_param.cal.current.CC1_Offset = bParam[0]; break; case '3': device_param.cal.current.CC2_Gain = bParam[0]; break; case '4': device_param.cal.current.CC2_Offset = bParam[0]; break; default: return(1); } Save_Param(); break; case '6': // Current Offset (Subclass 20) i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; cmd = temp[0]; j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; aParam[0] = StrToInt(temp, j); /* Value */ switch (cmd) { case '1': device_param.cal.current_offset.Int_Power = aParam[0]; break; case '2': device_param.cal.current_offset.Relay_Power = aParam[0]; break; default: return(1); } Save_Param(); break; default: ret = 1; break; } return(ret); /* Setting value OK */ } u8 SetCal_Param1(u8 *text, u8 aDevice) { u8 temp[20]; float fParam[2]; u16 i, j, size; u8 ret; ret = 0; size = 0; while (text[size] != 0x00) size++; /* Measure total string length */ switch (aDevice) { case '8' : // Discharge Current Calibration i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); temp[j] = 0x00; i = i + j + 1; fParam[0] = atof((char *)temp); /* IP a */ device_param.cal.current.DC_Gain = CalibrationVoltage((u16)(fParam[0] * 100), DSG_CURR_ID); Save_Param(); break; case '9' : // Charge Current Calibration i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); temp[j] = 0x00; i = i + j + 1; fParam[0] = atof((char *)temp); /* IP a */ device_param.cal.current.CC1_Gain = CalibrationVoltage((u16)(fParam[0] * 100), CHG_CURR_ID); Save_Param(); break; case 'K' : // Charge Current Calibration device_param.cal.current.DC_Offset = -GetRealCurrentAdc(DSG_CURR_ID); device_param.cal.current.CC1_Offset = -GetRealCurrentAdc(CHG_CURR_ID); device_param.cal.current.CC2_Offset = -GetRealCurrentAdc(CHG_CURR_ID); Save_Param(); break; case 'B' : // Discharge Current Calibration i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); temp[j] = 0x00; i = i + j + 1; fParam[0] = atof((char *)temp); /* IP a */ device_param.cal.current.DC_Gain = CalibrationCurrentA((u16)(fParam[0] * 100), DSG_CURR_ID); Save_Param(); break; case 'C' : // Charge Current Calibration i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); temp[j] = 0x00; i = i + j + 1; fParam[0] = atof((char *)temp); /* IP a */ device_param.cal.current.CC1_Gain = CalibrationCurrentA((u16)(fParam[0] * 100), CHG_CURR_ID); Save_Param(); break; default: ret = 1; break; } return(ret); /* Setting value OK */ } void CalDisplayVoltage(u8 p) { u8 text[20]; // Cell_Scale_0 (Offset 0) if (p || (dis_device_param.cal.voltage.Cell_Scale_0 != device_param.cal.voltage.Cell_Scale_0)) { sprintf((char *)text, "%5d", device_param.cal.voltage.Cell_Scale_0); GreenOutXY(19, 3, text); dis_device_param.cal.voltage.Cell_Scale_0 = device_param.cal.voltage.Cell_Scale_0; } // Cell_Scale_1 (Offset 2) if (p || (dis_device_param.cal.voltage.Cell_Scale_1 != device_param.cal.voltage.Cell_Scale_1)) { sprintf((char *)text, "%5d", device_param.cal.voltage.Cell_Scale_1); GreenOutXY(19, 4, text); dis_device_param.cal.voltage.Cell_Scale_1 = device_param.cal.voltage.Cell_Scale_1; } // Pack_Offset (Offset 8) if (p || (dis_device_param.cal.voltage.BAT_Gain != device_param.cal.voltage.BAT_Gain)) { sprintf((char *)text, "%5d", device_param.cal.voltage.BAT_Gain); GreenOutXY(19, 5, text); dis_device_param.cal.voltage.BAT_Gain = device_param.cal.voltage.BAT_Gain; } // BAT_Offset (Offset 10) if (p || (dis_device_param.cal.voltage.BAT_Offset != device_param.cal.voltage.BAT_Offset)) { sprintf((char *)text, "%5d", device_param.cal.voltage.BAT_Offset); GreenOutXY(19, 6, text); dis_device_param.cal.voltage.BAT_Offset = device_param.cal.voltage.BAT_Offset; } } void CalDisplayDischargeCurrent(u8 p) { u8 text[20]; u16 x; x = 18; // DC_Gain (Offset 0) if (p || (dis_device_param.cal.current.DC_Gain != device_param.cal.current.DC_Gain)) { sprintf((char *)text, "%8d", device_param.cal.current.DC_Gain); GreenOutXY(x, 8, text); dis_device_param.cal.current.DC_Gain = device_param.cal.current.DC_Gain; } // DC_Offset (Offset 4) if (p || (dis_device_param.cal.current.DC_Offset != device_param.cal.current.DC_Offset)) { sprintf((char *)text, "%8d", device_param.cal.current.DC_Offset); GreenOutXY(x, 9, text); dis_device_param.cal.current.DC_Offset = device_param.cal.current.DC_Offset; } } void CalDisplayChargeCurrent(u8 p) { u8 text[20]; u16 x; x = 18; // CC1_Gain (Offset 0) if (p || (dis_device_param.cal.current.CC1_Gain != device_param.cal.current.CC1_Gain)) { sprintf((char *)text, "%8d", device_param.cal.current.CC1_Gain); GreenOutXY(x, 11, text); dis_device_param.cal.current.CC1_Gain = device_param.cal.current.CC1_Gain; } // CC1_Offset (Offset 4) if (p || (dis_device_param.cal.current.CC1_Offset != device_param.cal.current.CC1_Offset)) { sprintf((char *)text, "%8d", device_param.cal.current.CC1_Offset); GreenOutXY(x, 12, text); dis_device_param.cal.current.CC1_Offset = device_param.cal.current.CC1_Offset; } x = 18; // CC2_Gain (Offset 0) if (p || (dis_device_param.cal.current.CC2_Gain != device_param.cal.current.CC2_Gain)) { sprintf((char *)text, "%8d", device_param.cal.current.CC2_Gain); GreenOutXY(x, 14, text); dis_device_param.cal.current.CC2_Gain = device_param.cal.current.CC2_Gain; } // CC2_Offset (Offset 4) if (p || (dis_device_param.cal.current.CC2_Offset != device_param.cal.current.CC2_Offset)) { sprintf((char *)text, "%8d", device_param.cal.current.CC2_Offset); GreenOutXY(x, 15, text); dis_device_param.cal.current.CC2_Offset = device_param.cal.current.CC2_Offset; } } void CalDisplayPwrConsumpt(u8 p) { u8 text[20]; u16 x; x = 46; // Internal Power Consumption (Offset 0) if (p || (dis_device_param.cal.current_offset.Int_Power != device_param.cal.current_offset.Int_Power)) { sprintf((char *)text, "%5d", device_param.cal.current_offset.Int_Power); GreenOutXY(x, 3, text); dis_device_param.cal.current_offset.Int_Power = device_param.cal.current_offset.Int_Power; } // Relay Power Consumption (Offset 0) if (p || (dis_device_param.cal.current_offset.Relay_Power != device_param.cal.current_offset.Relay_Power)) { sprintf((char *)text, "%5d", device_param.cal.current_offset.Relay_Power); GreenOutXY(x, 4, text); dis_device_param.cal.current_offset.Relay_Power = device_param.cal.current_offset.Relay_Power; } } void CalDisplay(u8 p) { CalDisplayVoltage(p); CalDisplayChargeCurrent(p); CalDisplayDischargeCurrent(p); CalDisplayPwrConsumpt(p); } #endif // #ifdef CONSOLE_DEBUG void Cal_InitData(void) { device_param.cal.voltage.Cell_Scale_0 = 0; device_param.cal.voltage.Cell_Scale_1 = 0; device_param.cal.voltage.BAT_Gain = 0; // (1/1000) device_param.cal.voltage.BAT_Offset = 0; // (1/10000) device_param.cal.current.CC1_Gain = 0; device_param.cal.current.CC1_Offset = 0; device_param.cal.current.CC2_Gain = 0; device_param.cal.current.CC2_Offset = 0; device_param.cal.current.DC_Gain = 0; device_param.cal.current.DC_Offset = 0; device_param.cal.current_offset.Int_Power = 500; device_param.cal.current_offset.Relay_Power = 0; }