353 lines
9.3 KiB
C
353 lines
9.3 KiB
C
/**
|
|
******************************************************************************
|
|
* @file vi.h
|
|
* @author AMG Energy Solution Team
|
|
* @version V1.0.0
|
|
* @date 07-Feb-2022
|
|
* @brief This file provides all the headers of voltage and current functions.
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* 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, STMICROELECTRONICS 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>© COPYRIGHT 2022 AMG</center></h2>
|
|
******************************************************************************
|
|
*/
|
|
|
|
/** @addtogroup mBMS2
|
|
* @{
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include <includes.h>
|
|
#include "vi.h"
|
|
#include "delay.h"
|
|
#include "adc.h"
|
|
#include "asutil.h"
|
|
#include "device_param.h"
|
|
#include "malloc.h"
|
|
#include "relay.h"
|
|
#include "alarm.h"
|
|
#include "brtc.h"
|
|
#include "os_cfg_app.h"
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* Private define ------------------------------------------------------------*/
|
|
#define VI_TASK_TIME 2 // 1ms Delay
|
|
|
|
#define CURR_AVG_BUF_MAX 100
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
// ADC Buffer
|
|
uint16_t VIAdData[VI_CH_MAX][VI_BUF_MAX];
|
|
int32_t VIRealData[VI_CH_MAX][VI_BUF_MAX];
|
|
uint16_t VIAdCh = 0;
|
|
|
|
int32_t VICurrentCalc[VI_BUF_MAX] = {0, };
|
|
|
|
uint32_t CurrentAvgBuff[CURR_AVG_BUF_MAX];
|
|
uint16_t CurrentAvgBuffCh = 0;
|
|
uint16_t CurrentAvgBuffTime = 0;
|
|
|
|
uint32_t relexation_chg_time = 60 * 1000;
|
|
uint32_t relexation_dsg_time = 60 * 1000;
|
|
|
|
uint32_t dis_radc[4];
|
|
int32_t dis_tadc = 0;
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
void InitVIAD(uint8_t ch);
|
|
void VI_ADC_Data_Process(void);
|
|
int32_t GetCurrentAvgValue(void);
|
|
void CheckCurrentStatus(void);
|
|
|
|
int32_t CalcDischargeCurrent(uint32_t adc);
|
|
int32_t CalcChargeCurrent(uint32_t adc);
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* VIAdcInit
|
|
*
|
|
* Description : ADC TASK INIT
|
|
*
|
|
*********************************************************************************************************
|
|
*/
|
|
void VIAdcInit(void)
|
|
{
|
|
// ADC initialization
|
|
// ADC Clock frequency: 115.200 kHz
|
|
// ADC Voltage Reference: Vref Pin
|
|
// ADC High Speed Mode: On
|
|
|
|
ADC_Port_Init();
|
|
|
|
memset(VIAdData, 0x00, sizeof(VIAdData));
|
|
|
|
relexation_chg_time = device_param.chg_ctrl.current_thr.Charge_Relax_Time * 1000;
|
|
relexation_dsg_time = device_param.chg_ctrl.current_thr.Discharge_Relax_Time * 1000;
|
|
}
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* AppTaskVIAdc
|
|
*
|
|
* Description : Voltage and current measurement task
|
|
*
|
|
*********************************************************************************************************
|
|
*/
|
|
void AppTaskVIAdc(void)
|
|
{
|
|
VIAdcInit();
|
|
ADC_StartConvert(M4_ADC2);
|
|
|
|
for (;;) {
|
|
if (GetAdcIrgFlag(1) == true) {
|
|
VI_ADC_Data_Process();
|
|
|
|
DmaReloadConfig(1);
|
|
// PORT_SetBits(PortE, Pin00);
|
|
ADC_StartConvert(M4_ADC2);
|
|
}
|
|
delay_os_ms(VI_TASK_TIME);
|
|
}
|
|
}
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* VI_ADC_Data_Process
|
|
*
|
|
* Description : VI_ADC_Data_Process
|
|
*
|
|
*********************************************************************************************************
|
|
*/
|
|
uint32_t bakODC = 0;
|
|
uint32_t bakODC1 = 0;
|
|
|
|
void VI_ADC_Data_Process(void)
|
|
{
|
|
int32_t sum, sum1;
|
|
|
|
for (int i = 0; i < VI_CH_MAX; i++) {
|
|
sum = AvgAdc2DmaValue(i);
|
|
VIRealData[i][VIAdCh] = (uint16_t)((sum * (ADC_VBASE * 10)) / 0xFFF);
|
|
|
|
switch (i) {
|
|
case DSG_CURR_ID:
|
|
sum1 = (int32_t)CalcDischargeCurrent(sum);
|
|
VIAdData[i][VIAdCh] = (int32_t)sum1;
|
|
break;
|
|
case CHG_CURR_ID:
|
|
sum1 = (int32_t)CalcChargeCurrent(sum);
|
|
VIAdData[i][VIAdCh] = (int32_t)sum1;
|
|
break;
|
|
}
|
|
}
|
|
VICurrentCalc[VIAdCh] = VIRealData[CHG_CURR_ID][VIAdCh] - VIRealData[DSG_CURR_ID][VIAdCh];
|
|
|
|
VIAdCh++;
|
|
VIAdCh %= VI_BUF_MAX;
|
|
|
|
// Discharge current
|
|
sum = 0;
|
|
for (int i = 0; i < VI_BUF_MAX; i++) {
|
|
sum += VIAdData[DSG_CURR_ID][i];
|
|
}
|
|
device_value.DCurrent = (int32_t)(sum / VI_BUF_MAX);
|
|
if (device_value.DCurrent < (device_param.chg_ctrl.term_cfg.Taper_Current / 100))
|
|
device_value.DCurrent = 0;
|
|
|
|
// Charge current
|
|
sum = 0;
|
|
for (int i = 0; i < VI_BUF_MAX; i++) {
|
|
sum += VIAdData[CHG_CURR_ID][i];
|
|
}
|
|
device_value.CCurrent = (int32_t)(sum / VI_BUF_MAX);
|
|
if (device_value.CCurrent < (device_param.chg_ctrl.term_cfg.Taper_Current / 100)) {
|
|
device_value.CCurrent = 0;
|
|
}
|
|
|
|
if (device_value.DCurrent > device_value.CCurrent) {
|
|
device_value.CCurrent = 0;
|
|
} else {
|
|
device_value.DCurrent = 0;
|
|
}
|
|
|
|
device_value.Current = device_value.CCurrent - device_value.DCurrent;
|
|
|
|
CheckCurrentStatus();
|
|
}
|
|
|
|
int32_t CalcDischargeCurrent(uint32_t adc)
|
|
{
|
|
int32_t result = 0;
|
|
double tmp, bGain, bOffset;
|
|
|
|
tmp = (double)((adc * ADC_VBASE) / 0xFFF) / 1000;
|
|
|
|
bGain = (float)device_calib_data.cal.current.DC_Gain / 1000;
|
|
bOffset = (float)device_calib_data.cal.current.DC_Offset / 10000;
|
|
|
|
tmp = (tmp + bOffset) * bGain;
|
|
|
|
result = tmp * 10;
|
|
|
|
return result;
|
|
}
|
|
|
|
int32_t CalcChargeCurrent(uint32_t adc)
|
|
{
|
|
int32_t result = 0;
|
|
double tmp, bGain, bOffset;
|
|
|
|
tmp = (double)((adc * ADC_VBASE) / 0xFFF) / 1000;
|
|
|
|
bGain = (float)device_calib_data.cal.current.CC1_Gain / 1000;
|
|
bOffset = (float)device_calib_data.cal.current.CC1_Offset / 10000;
|
|
|
|
tmp = (tmp + bOffset) * bGain;
|
|
|
|
result = tmp * 10;
|
|
|
|
return result;
|
|
}
|
|
|
|
uint32_t GetRealCurrentAdc(uint8_t id)
|
|
{
|
|
uint16_t i;
|
|
uint32_t result = 0;
|
|
|
|
for (i = 0; i < VI_BUF_MAX; i++) {
|
|
result += VIRealData[id][i];
|
|
}
|
|
return (result / VI_BUF_MAX);
|
|
}
|
|
|
|
int32_t GetRealCurrentSum(void)
|
|
{
|
|
int32_t i, result = 0;
|
|
|
|
for (i = 0; i < VI_BUF_MAX; i++) {
|
|
result += VICurrentCalc[i];
|
|
}
|
|
return (result / VI_BUF_MAX);
|
|
}
|
|
|
|
void dec_relexation_tick(uint32_t tick)
|
|
{
|
|
if (relexation_chg_time > 0) {
|
|
if (relexation_chg_time > tick) {
|
|
relexation_chg_time -= tick;
|
|
} else {
|
|
relexation_chg_time = 0;
|
|
}
|
|
}
|
|
|
|
if (relexation_dsg_time > 0) {
|
|
if (relexation_dsg_time > tick) {
|
|
relexation_dsg_time -= tick;
|
|
} else {
|
|
relexation_dsg_time = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CheckCurrentStatus(void)
|
|
{
|
|
PDEVICE_CHG_CTRL_CURRENT_THR_VALUE thr;
|
|
|
|
thr = (PDEVICE_CHG_CTRL_CURRENT_THR_VALUE)mymalloc(sizeof(TDEVICE_CHG_CTRL_CURRENT_THR_VALUE));
|
|
|
|
if (thr != NULL) {
|
|
memcpy(thr, &device_param.chg_ctrl.current_thr, sizeof(TDEVICE_CHG_CTRL_CURRENT_THR_VALUE));
|
|
|
|
if (device_status.battery_status.bit.RXM == false) {
|
|
// Charge or Discharge Mode
|
|
if (device_status.battery_status.bit.MD == true) {
|
|
// Discharge Mode
|
|
if (device_value.CCurrent > (thr->Charge_Detection_Threshold / 100)) {
|
|
device_status.battery_status.bit.MD = false;
|
|
} else if (device_value.DCurrent < (thr->Quit_Current / 100)) {
|
|
// Relexation time
|
|
if (relexation_dsg_time == 0) {
|
|
device_status.battery_status.bit.RXM = true;
|
|
}
|
|
} else {
|
|
// Discharge time
|
|
relexation_dsg_time = thr->Discharge_Relax_Time * 1000;
|
|
}
|
|
} else {
|
|
// Charge Mode
|
|
if (device_value.DCurrent > (thr->Discharge_Detection_Threshold / 100)) {
|
|
device_status.battery_status.bit.MD = true;
|
|
} else if (device_value.CCurrent < (thr->Quit_Current / 100)) {
|
|
// Relexation time
|
|
if (relexation_chg_time == 0) {
|
|
device_status.battery_status.bit.RXM = true;
|
|
}
|
|
} else {
|
|
// Charge time
|
|
relexation_chg_time = thr->Charge_Relax_Time * 1000;
|
|
}
|
|
}
|
|
} else {
|
|
// Relexation True Mode
|
|
if (device_value.CCurrent > (thr->Charge_Detection_Threshold / 100)) {
|
|
device_status.battery_status.bit.RXM = false;
|
|
relexation_chg_time = thr->Charge_Relax_Time * 1000;
|
|
} else if (device_value.DCurrent > (thr->Discharge_Detection_Threshold / 100)) {
|
|
device_status.battery_status.bit.RXM = false;
|
|
relexation_dsg_time = thr->Discharge_Relax_Time * 1000;
|
|
}
|
|
}
|
|
myfree(thr);
|
|
}
|
|
}
|
|
|
|
/*************************************** Display **********************************************/
|
|
#ifdef CONSOLE_DEBUG
|
|
|
|
void SDisplayCurrentAdcRealValue(uint8_t p)
|
|
{
|
|
float aParam;
|
|
int32_t radc, tadc;
|
|
static int dCount = 0;
|
|
|
|
if (p || (dCount == 0))
|
|
{
|
|
for (int i = 0; i < VI_CH_MAX; i++)
|
|
{
|
|
radc = GetRealCurrentAdc(i);
|
|
|
|
if (p ||(dis_radc[i] != radc))
|
|
{
|
|
aParam = (float)radc / 10000;
|
|
FloatNormalOutIntXY( 70, 3 + i, aParam, 6, 4);
|
|
dis_radc[i] = radc;
|
|
}
|
|
}
|
|
|
|
tadc = GetRealCurrentSum();
|
|
|
|
if (dis_tadc != tadc)
|
|
{
|
|
aParam = (float)tadc / 10000;
|
|
FloatNormalOutIntXY( 68, 3 + 3, aParam, 8, 4);
|
|
dis_tadc = tadc;
|
|
}
|
|
dCount = 100;
|
|
}
|
|
dCount--;
|
|
}
|
|
|
|
#endif // #ifdef CONSOLE_DEBUG
|
|
|
|
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/
|