/**
******************************************************************************
* File Name : vi.c
* Description : This file provides code for the measument of voltage
and current.
******************************************************************************
* @attention
*
*
© Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* 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
/* 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