TODO: IV CV add Imax

This commit is contained in:
weiting2
2019-10-23 14:04:35 +08:00
parent 5b6fd53830
commit 63fde4bdbc
@@ -2,9 +2,9 @@
#ifndef ELITECCMODE
#define ELITECCMODE
#define CURRENT_LV_FOUR 4
#define CURRENT_LV_THREE 3
#define CURRENT_LV_TWO 2
#define CC_ZERO_POINT 1500000
#define MAX_DAC_UC 50000
#define MIN_DAC_UC 0
#define CURRENT_LV_ONE 1
#define CURRENT_LV_ZERO 0
@@ -19,7 +19,8 @@ static void CCModeDACControl(int32_t IUC_Measure_Difference);
typedef struct _CURRENT_USER_CODE {
/** current value **/
// current value divide current level into 3e6 pieces
// current value divide current level into 3,000,001 pieces
// 1,500,000 is zero point
int32_t value;
/** ADC level range: 0-2 **/
@@ -29,6 +30,13 @@ typedef struct _CURRENT_USER_CODE {
// else lv = GAIN_200K
uint8_t lv;
/* Vmax and Vmin */
// Vmax protect battery charge
// Vmin protect battery discharge
// uint = mV
uint16_t Vmax;
uint16_t Vmin;
/** transform a current user code (IUC) to real current in nA **/
int32_t (*_Transform2RealnA)(struct _CURRENT_USER_CODE *);
@@ -47,6 +55,7 @@ static int32_t CCModeReadCurrent(CURRENT_USER_CODE *CurrentUserCode){
int32_t Real_Current = 0;
CCModeDACEnable = 1; // This flag will control DAC working
// set current value and ADC gain level
CCCurrent2IUC(CurrentUserCode);
// set ADC gain according to constant current value
@@ -123,7 +132,7 @@ static void CCCurrent2IUC(CURRENT_USER_CODE *CurrentUserCode){
int32_t CurrentValue = 0;
CurrentUserCode->value = INSTRUCTION.ConstantCurrent;
CurrentValue = CurrentUserCode->value - 1500000;
CurrentValue = CurrentUserCode->value - CC_ZERO_POINT;
/* set ADC level */
// largest current
@@ -153,7 +162,7 @@ static int32_t _Transform2RealnA(CURRENT_USER_CODE *self){
int32_t IUCReal;
// self->value : 0 ~ 3000000 (which is -1500000 ~ 1500000 (10nA) )
IUCReal = (self->value - 1500000) * 10;
IUCReal = (self->value - CC_ZERO_POINT) * 10;
return IUCReal;
}
@@ -167,8 +176,10 @@ static int32_t GetMeasureCurrent(CURRENT_USER_CODE *self){
static CURRENT_USER_CODE *InitCurrentUserCode(){
CURRENT_USER_CODE *CurrentUserCode = malloc(sizeof(CURRENT_USER_CODE));
CurrentUserCode->lv = GAIN_200R;
CurrentUserCode->value = 1500000;
CurrentUserCode->value = CC_ZERO_POINT;
CurrentUserCode->lv = GAIN_AUTO;
CurrentUserCode->Vmax = MAX_DAC_UC; // max DAC UserCode
CurrentUserCode->Vmin = MIN_DAC_UC; // min DAC UserCode
CurrentUserCode-> _MeasureCurrent = 0;
CurrentUserCode->_Transform2RealnA = &_Transform2RealnA;
CurrentUserCode->SetMeasureCurrent = &SetMeasureCurrent;
@@ -176,119 +187,4 @@ static CURRENT_USER_CODE *InitCurrentUserCode(){
return CurrentUserCode;
}
/*********************************************************************
* @fn Transform2RealpA
*
* @brief transform an IUC into real current value in pA.
*
* @param self, which is an IUC
*
* @return an int32_t current value in pA
*/
static int32_t _Transform2RealpA(CURRENT_USER_CODE *self){
int32_t IUCReal;
/** current level range: 0-4 **/
// current level = 0 => 0-499 nA => ADCGainLevel = 200K
// current level = 1 => 500-999 nA => ADCGainLevel = 10K
// current level = 2 => 0-499 uA => ADCGainLevel = 10K
// current level = 3 => 500-999 uA => ADCGainLevel = 200R
// current level = 4 => 0-499 mA => ADCGainLevel = 200R
// Saturate if current > 500 uA
if (self->lv == CURRENT_LV_FOUR){
return 0xFFFFFFFF;
}
if (self->lv == CURRENT_LV_THREE){
return 0xFFFFFFFF;
}
// 0-499 nA
if (self->lv == CURRENT_LV_ZERO){
IUCReal = (int32_t) (self->value) * 10;
}
// 500-999 nA
else if (self->lv == CURRENT_LV_ONE){
IUCReal = ((int32_t) (self->value + 50000) * 10);
}
// 0-499 uA
else if (self->lv == CURRENT_LV_TWO){
IUCReal = (int32_t) (self->value) * 1e4;
}
return IUCReal;
}
/*********************************************************************
* @fn CompareCurrent
*
* @brief compare an int32 current with CURRENT_USER_CODE (IUC) type current.
*
* @param unit is current unit (0 = pA, 1 = nA)
* value is current value
*
* @return 0 if equal
* 1 if IUC is larger
* 2 if int32 current is larger.
*/
//static uint8_t CompareCurrent(CURRENT_USER_CODE *self, uint8_t unit, int32_t value){
// int32_t ErrorRangeIUCReal;
//
// // unit = pA
// if (unit == 0){
// if (self->_Transform2RealpA(self) > value){
// return 1;
// }
// else if (self->_Transform2RealpA(self) < value){
// return 2;
// }
// else{
// return 0;
// }
// }
//
// // unit = nA
// else if (unit == 1){
// if (self->_Transform2RealnA(self) > value){
// return 1;
// }
// else if (self->_Transform2RealnA(self) < value){
// return 2;
// }
// else{
// return 0;
// }
// }
//}
static void SetCCModeGain(CURRENT_USER_CODE *CurrentUserCode){
switch(CurrentUserCode->lv){
case CURRENT_LV_FOUR:{
INSTRUCTION.ADCGainLevel = GAIN_200R;
break;
}
case CURRENT_LV_THREE:{
INSTRUCTION.ADCGainLevel = GAIN_200R;
break;
}
case CURRENT_LV_TWO:{
INSTRUCTION.ADCGainLevel = GAIN_10K;
break;
}
case CURRENT_LV_ONE:{
INSTRUCTION.ADCGainLevel = GAIN_200K;
break;
}
case CURRENT_LV_ZERO:{
INSTRUCTION.ADCGainLevel = GAIN_200K;
break;
}
default :{
INSTRUCTION.ADCGainLevel = GAIN_200R;
break;
}
}
}
#endif