380 lines
9.0 KiB
C
380 lines
9.0 KiB
C
/**
|
|
******************************************************************************
|
|
* File Name : vi.c
|
|
* Description : This file provides code for the measument of voltage
|
|
and current.
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
|
* All rights reserved.</center></h2>
|
|
*
|
|
* This software component is licensed by ST under Ultimate Liberty license
|
|
* SLA0044, the "License"; You may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at:
|
|
* www.st.com/SLA0044
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "vi.h"
|
|
#include "delay.h"
|
|
#include "adc.h"
|
|
#include "asutil.h"
|
|
#include "device_param.h"
|
|
#include "malloc.h"
|
|
#include <includes.h>
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* Private define ------------------------------------------------------------*/
|
|
#define VI_TASK_TIME 2 // 10ms Delay
|
|
#define VI_CH_TIME VI_TASK_TIME + (10) // 20ms Delay
|
|
|
|
#define CURR_AVG_BUF_MAX 100
|
|
// PU3921FKMP50R001L
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
// ADC Buffer
|
|
u16 VIAdData[VI_CH_MAX][VI_BUF_MAX];
|
|
s32 VIRealData[VI_CH_MAX][VI_BUF_MAX];
|
|
u16 VIAdCh = 0;
|
|
|
|
s32 VICurrentCalc[VI_BUF_MAX] = {0, };
|
|
|
|
u32 CurrentAvgBuff[CURR_AVG_BUF_MAX];
|
|
u16 CurrentAvgBuffCh = 0;
|
|
u16 CurrentAvgBuffTime = 0;
|
|
|
|
u32 relexation_chg_time = 60 * 1000;
|
|
u32 relexation_dsg_time = 60 * 1000;
|
|
|
|
u32 dis_radc[4];
|
|
s32 dis_tadc = 0;
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
void InitVIAD(u8 ch);
|
|
void VI_ADC_Data_Process(void);
|
|
u16 GetCurrentValue(u16 ch);
|
|
s32 GetCurrentAvgValue(void);
|
|
void CheckCurrentStatus(void);
|
|
|
|
s32 CalcDischargeCurrent(u32 adc, u32 ref);
|
|
s32 CalcChargeCurrent(u32 adc);
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* 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
|
|
|
|
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();
|
|
|
|
for (;;)
|
|
{
|
|
VI_ADC_Data_Process();
|
|
|
|
delay_os_ms(VI_TASK_TIME);
|
|
}
|
|
}
|
|
|
|
/*
|
|
*********************************************************************************************************
|
|
* VI_ADC_Data_Process
|
|
*
|
|
* Description : VI_ADC_Data_Process
|
|
*
|
|
*********************************************************************************************************
|
|
*/
|
|
void VI_ADC_Data_Process(void)
|
|
{
|
|
s32 sum, sum1;
|
|
// double tmp, bGain, bOffset;
|
|
|
|
if (GetDmaBufferFlag() == false) return;
|
|
|
|
for (int i = 0; i < VI_CH_MAX; i++)
|
|
{
|
|
sum = GetCurrentValue(i) / 10;
|
|
VIRealData[i][VIAdCh] = (u16)((sum * (ADC_VBASE * 10)) / 0xFFF);
|
|
|
|
switch (i)
|
|
{
|
|
case DSG_CURR_ID:
|
|
sum1 = GetCurrentValue(CHG_CURR_ID) / 10;
|
|
VIAdData[i][VIAdCh] = (s32)CalcDischargeCurrent(sum, sum1);
|
|
break;
|
|
case CHG_CURR_ID:
|
|
sum1 = GetCurrentValue(DSG_CURR_ID) / 10;
|
|
VIAdData[i][VIAdCh] = (s32)CalcChargeCurrent(sum);
|
|
break;
|
|
}
|
|
}
|
|
|
|
VICurrentCalc[VIAdCh] = VIRealData[CHG_CURR_ID][VIAdCh] - VIRealData[DSG_CURR_ID][VIAdCh];
|
|
|
|
VIAdCh++;
|
|
VIAdCh %= VI_BUF_MAX;
|
|
|
|
ResetDmaBufferFlag();
|
|
|
|
// Discharge current
|
|
sum = 0;
|
|
for (int i = 0; i < VI_BUF_MAX; i++)
|
|
{
|
|
sum += VIAdData[DSG_CURR_ID][i];
|
|
}
|
|
device_value.DCurrent = (s32)(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 = (s32)(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();
|
|
}
|
|
|
|
u16 GetCurrentValue(u16 ch)
|
|
{
|
|
u16 result = 0;
|
|
|
|
switch (ch)
|
|
{
|
|
case DSG_CURR_ID:
|
|
result = AvgAdc2DmaValue(ch);
|
|
break;
|
|
case CHG_CURR_ID:
|
|
result = AvgAdc2DmaValue(ch);
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
s32 CalcDischargeCurrent(u32 adc, u32 ref)
|
|
{
|
|
s32 result = 0;
|
|
double tmp, bGain, bOffset;
|
|
|
|
tmp = (double)((adc * ADC_VBASE) / 0xFFF) / 1000;
|
|
|
|
bGain = (float)device_param.cal.current.DC_Gain / 1000;
|
|
bOffset = (float)device_param.cal.current.DC_Offset / 10000;
|
|
|
|
tmp = (tmp + bOffset) * bGain;
|
|
|
|
result = tmp * 10;
|
|
|
|
return result;
|
|
}
|
|
|
|
s32 CalcChargeCurrent(u32 adc)
|
|
{
|
|
s32 result = 0;
|
|
double tmp, bGain, bOffset;
|
|
|
|
tmp = (double)((adc * ADC_VBASE) / 0xFFF) / 1000;
|
|
|
|
bGain = (float)device_param.cal.current.CC1_Gain / 1000;
|
|
bOffset = (float)device_param.cal.current.CC1_Offset / 10000;
|
|
|
|
tmp = (tmp + bOffset) * bGain;
|
|
|
|
result = tmp * 10;
|
|
|
|
return result;
|
|
}
|
|
|
|
u32 GetRealCurrentAdc(u8 id)
|
|
{
|
|
u16 i;
|
|
u32 result = 0;
|
|
|
|
for (i = 0; i < VI_BUF_MAX; i++)
|
|
result += VIRealData[id][i];
|
|
|
|
return (result / VI_BUF_MAX);
|
|
}
|
|
|
|
s32 GetRealCurrentSum(void)
|
|
{
|
|
s32 i, result = 0;
|
|
|
|
for (i = 0; i < VI_BUF_MAX; i++)
|
|
result += VICurrentCalc[i];
|
|
|
|
return (result / VI_BUF_MAX);
|
|
}
|
|
|
|
void dec_relexation_tick(u32 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(u8 p)
|
|
{
|
|
float aParam;
|
|
s32 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
|
|
|