/** ****************************************************************************** * 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