Files

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>&copy; 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******/