Compare commits

...

7 Commits

Author SHA1 Message Date
YiChin 6fae1f65a1 fix bug 2019-11-15 17:15:29 +08:00
YiChin 34355a1a4a fix bug 2019-11-15 17:01:03 +08:00
105042004 2e4a260e17 update PSCurve 2019-11-15 16:09:28 +08:00
105042004 c3f19359f1 temp save 2019-11-15 14:25:24 +08:00
105042004 bb28a594f3 temp save 2019-11-15 14:07:14 +08:00
105042004 8216bb7a70 temp save 2019-11-15 13:54:46 +08:00
105042004 ef920851db add PSCurve 2019-11-08 22:24:16 +08:00
7 changed files with 300 additions and 22 deletions
@@ -205,4 +205,5 @@ static void CCCurrent2IUC(CCMode *CC){
// return CurrentUserCode;
//}
#endif
@@ -37,6 +37,9 @@ static int32_t IT_Plot(WorkMode *WorkModeData) {
#define CURRENT_MODE WorkModeData->IT
break;
}
case POTENTIAL_STATE:{
#define CURRENT_MODE WorkModeData->PS
}
default: {
#define CURRENT_MODE WorkModeData->IV
break;
@@ -15,6 +15,8 @@ static uint16_t VoltScan(WorkMode *WorkModeData) {
Voltage = DPVCurve(WorkModeData);
} else if (INSTRUCTION.eliteFxn == CV_CURVE) {
Voltage = CVCurve(WorkModeData->CV);
} else if (INSTRUCTION.eliteFxn == POTENTIAL_STATE ) {
Voltage = PSCurve(WorkModeData->PS);
}
// IV plot mode
@@ -72,15 +74,69 @@ static uint16_t OneWayVoltScan(IVMode *IV) {
DACOutCode = Usercode_Correction_to_DAC(DACUserCode);
DAC_outputV(DACOutCode);
// end IV task if we reach INSTRUCTION.VoltFinal
if (DACUserCode <= IV->_VStop){
PeriodicEvent = false;
DACReset = true;
// reset();
}
// // end IV task if we reach INSTRUCTION.VoltFinal
// if (DACUserCode <= IV->_VStop){
// PeriodicEvent = false;
// DACReset = true;
// // reset();
}
}
return DACOutCode;
}
static void IV_Plot(IVMode *IV) {
static uint8_t VoltCurrentSwitch = 0;
uint16_t ADC_measure = 0;
if(VoltCurrentSwitch < 5){
ReadCurrent(spi_ADC_rxbuf);
VoltCurrentSwitch ++;
}
else if(VoltCurrentSwitch == 5){
// read current
ReadCurrent(spi_ADC_rxbuf);
ADC_measure = (uint16_t) (spi_ADC_rxbuf[0] << 8) | (uint16_t) (spi_ADC_rxbuf[1]);
IV->_MeasureData = DecodeADCCurrent(INSTRUCTION.ADCGainLevel, ADC_measure);
VoltCurrentSwitch ++;
}
else if(VoltCurrentSwitch <9){
// read volt
ReadVolt(spi_ADC_rxbuf);
VoltCurrentSwitch++;
}
else if(VoltCurrentSwitch == 9){
/** read battery voltage **/
ReadVolt(spi_ADC_rxbuf);
ADC_measure = (uint16_t) (spi_ADC_rxbuf[0] << 8) | (uint16_t) (spi_ADC_rxbuf[1]);
IV->MeasureVolt = DecodeADCVolt(ADC_measure);
VoltCurrentSwitch++;
}
else{
VoltCurrentSwitch = 0;
}
NotifyCurrent[0] = (uint8_t) (IV->_MeasureData >> 24);
NotifyCurrent[1] = (uint8_t) ((IV->_MeasureData & 0x00FF0000) >> 16);
NotifyCurrent[2] = (uint8_t) ((IV->_MeasureData & 0x0000FF00) >> 8);
NotifyCurrent[3] = (uint8_t) (IV->_MeasureData & 0x000000FF);
NotifyVolt[0] = (uint8_t) (IV->MeasureVolt >> 24);
NotifyVolt[1] = (uint8_t) ((IV->MeasureVolt & 0x00FF0000) >> 16);
NotifyVolt[2] = (uint8_t) ((IV->MeasureVolt & 0x0000FF00) >> 8);
NotifyVolt[3] = (uint8_t) (IV->MeasureVolt & 0x000000FF);
if (IV->_VOrigin < IV->_VStop) {
if(IV->MeasureVolt >= (IV->_VStop - DAC_ZERO)/5){
PeriodicEvent = false;
DACReset = true;
}
}
else{
if(IV->MeasureVolt <= (IV->_VStop - DAC_ZERO)/5){
PeriodicEvent = false;
DACReset = true;
}
}
}
#endif
@@ -0,0 +1,175 @@
#ifndef ELITEPS
#define ELITEPS
static uint16_t PSCurve(PSMode *PS) {
static uint16_t DACOutCode;
static uint16_t DAC_ControlVolt;
static bool direction_up; // direction_up = true, if Vfinal > Vorigin
static bool current_direction_up; // current_direction_up = true, Vstep => positive. vice versa
// reset origin volt at the begin
if (DACReset) {
PS->_ControlVolt = PS->_VOrigin;
if (INSTRUCTION.VoltFinal > PS->_VOrigin) {
direction_up = true;
current_direction_up = true;
} else {
direction_up = false;
current_direction_up = false;
}
DACOutCode = Usercode_Correction_to_DAC(PS->_ControlVolt);
DAC_outputV(DACOutCode); // output VOLT_ORIGIN
DACReset = false;
return DACOutCode;
}
if (CT.StepTimeCounter == PS->_StepTime) {
// Decide next direction
if (direction_up) {
if (PS->_ControlVolt >= PS->_VStop) {
current_direction_up = false; // problem occurs when origin == 0000 final == ffff!!!!!!
} else if (PS->_ControlVolt <= PS->_VOrigin) {
current_direction_up = true;
if (PS->_CycleNumber == 0) {
PeriodicEvent = false; // periodic event end
DACReset = true;
}
PS->_CycleNumber--;
}
} else {
if (PS->_ControlVolt <= PS->_VStop) {
current_direction_up = true; // problem occurs when origin == 0000 final == ffff!!!!!!
} else if (PS->_ControlVolt >= PS->_VOrigin) {
current_direction_up = false;
if (PS->_CycleNumber == 0) {
PeriodicEvent = false; // periodic event end
DACReset = true;
}
PS->_CycleNumber--;
}
}
// Next output voltage
if (direction_up) {
if (current_direction_up) {
// PS->_ControlVolt overflow ?
if (PS->_ControlVolt + PS->_Step < PS->_ControlVolt) {
PS->_ControlVolt = PS->_VStop;
}
else if (PS->_ControlVolt + PS->_Step > PS->_VStop) {
PS->_ControlVolt =PS->_VStop;
}
else {
PS->_ControlVolt = PS->_ControlVolt + PS->_Step;
}
}
else {
// PS->_ControlVolt underflow ?
if (PS->_ControlVolt - PS->_Step > PS->_ControlVolt || PS->_ControlVolt > 60000) {
PS->_ControlVolt = PS->_VOrigin;
}
// reach Vorigin ?
else if (PS->_ControlVolt - PS->_Step < PS->_VOrigin) {
PS->_ControlVolt = PS->_VOrigin;
}
else {
PS->_ControlVolt = PS->_ControlVolt - PS->_Step;
}
}
}
else {
if (current_direction_up) {
if (PS->_ControlVolt + PS->_Step < PS->_ControlVolt) {
PS->_ControlVolt = PS->_VOrigin;
}
else if (PS->_ControlVolt + PS->_Step > PS->_VOrigin) {
PS->_ControlVolt = PS->_VOrigin;
}
else {
PS->_ControlVolt = PS->_ControlVolt + PS->_Step;
}
}
else {
if (PS->_ControlVolt - PS->_Step > PS->_ControlVolt || PS->_ControlVolt > 60000) {
PS->_ControlVolt = PS->_VStop ;
}
else if (PS->_ControlVolt - PS->_Step < PS->_VStop) {
PS->_ControlVolt = PS->_VStop;
}
else {
PS->_ControlVolt = PS->_ControlVolt - PS->_Step;
}
}
}
DACOutCode = PS->_MeasureVolt - PS->_ControlVolt;
DACOutCode = Usercode_Correction_to_DAC(DACOutCode);
DAC_outputV(DACOutCode);
}
DAC_ControlVolt = Usercode_Correction_to_DAC(PS->_ControlVolt);
return DAC_ControlVolt;
}
static void PS_Plot(PSMode* PS){
static uint8_t VoltCurrentSwitch = 0;
uint16_t ADC_measure = 0;
if(VoltCurrentSwitch < 5){
ReadCurrent(spi_ADC_rxbuf);
VoltCurrentSwitch ++;
}
else if(VoltCurrentSwitch == 5){
// read current
ReadCurrent(spi_ADC_rxbuf);
ADC_measure = (uint16_t) (spi_ADC_rxbuf[0] << 8) | (uint16_t) (spi_ADC_rxbuf[1]);
PS->_MeasureData = DecodeADCCurrent(INSTRUCTION.ADCGainLevel, ADC_measure);
VoltCurrentSwitch ++;
}
else if(VoltCurrentSwitch <9){
// read volt
ReadVolt(spi_ADC_rxbuf);
VoltCurrentSwitch++;
}
else if(VoltCurrentSwitch == 9){
/** read battery voltage **/
ReadVolt(spi_ADC_rxbuf);
ADC_measure = (uint16_t) (spi_ADC_rxbuf[0] << 8) | (uint16_t) (spi_ADC_rxbuf[1]);
PS->_MeasureVolt = DecodeADCVolt(ADC_measure);
VoltCurrentSwitch++;
}
else{
VoltCurrentSwitch = 0;
}
NotifyCurrent[0] = (uint8_t) (PS->_MeasureData >> 24);
NotifyCurrent[1] = (uint8_t) ((PS->_MeasureData & 0x00FF0000) >> 16);
NotifyCurrent[2] = (uint8_t) ((PS->_MeasureData & 0x0000FF00) >> 8);
NotifyCurrent[3] = (uint8_t) (PS->_MeasureData & 0x000000FF);
// NotifyVolt[0] = (uint8_t) (PS->_MeasureVolt >> 24);
// NotifyVolt[1] = (uint8_t) ((PS->_MeasureVolt & 0x00FF0000) >> 16);
// NotifyVolt[2] = (uint8_t) ((PS->_MeasureVolt & 0x0000FF00) >> 8);
// NotifyVolt[3] = (uint8_t) (PS->_MeasureVolt & 0x000000FF);
// if (PS->_VOrigin < PS->_VStop) {
// if(PS->MeasureVolt >= (PS->_VStop - DAC_ZERO)/5){
// PeriodicEvent = false;
// DACReset = true;
// }
// }
// else{
// if(PS->MeasureVolt <= (PS->_VStop - DAC_ZERO)/5){
// PeriodicEvent = false;
// DACReset = true;
// }
// }
}
#endif
@@ -244,6 +244,8 @@ VoltOutMode *InitVoltOutMode(){
/* IV Mode Data */
typedef struct _IVMode{
MEASURE;
int32_t MeasureVolt;
VOUT_PARA;
LIMIT;
}IVMode;
@@ -253,6 +255,7 @@ IVMode *InitIVMode(){
ret->_MeasureData = 0;
ret->SetMeasureData = &_SetMeasureData;
ret->GetMeasureData = &_GetMeasureData;
ret->MeasureVolt = 0;
ret->_VoltOut = DAC_ZERO;
ret->_VOrigin = INSTRUCTION.VoltOrigin;
@@ -443,8 +446,8 @@ CCMode * InitCCMode(){
typedef struct _PS{
// measure
MEASURE; // circuit current
int32_t ReferenceVolt;
int16_t _ControlVolt;
int32_t _MeasureVolt;
VOUT_PARA;
}PSMode;
@@ -453,7 +456,8 @@ PSMode *InitPSMode(){
ret->_MeasureData = 0;
ret->SetMeasureData = &_SetMeasureData;
ret->GetMeasureData = &_GetMeasureData;
ret->ReferenceVolt = 0;
ret->_ControlVolt = INSTRUCTION.VoltOrigin;
ret->_MeasureVolt = INSTRUCTION.VoltOrigin;
ret->_VoltOut = DAC_ZERO; // 25000 is DAC_ZERO
ret->_VOrigin = INSTRUCTION.VoltOrigin;
@@ -510,7 +514,9 @@ void InitWorkMode(WorkMode *WM){
case CONSTANT_CURRENT:
WM->CC = InitCCMode();
break;
case POTENTIAL_STATE:
WM->PS = InitPSMode();
break;
default:
WM->VT = InitVTMode();
break;
@@ -561,6 +567,12 @@ void FreeWorkMode(WorkMode *WM){
WM->CC = NULL;
}
break;
case POTENTIAL_STATE:
if(WM->PS != NULL){
free(WM->PS);
WM->PS = NULL;
}
break;
default:
if(WM->IV != NULL){
free(WM->IV);
@@ -642,7 +642,10 @@ static void DACCode2Real2Notify(uint16_t DACcode); // send notify voltage a
//static void VOLT_OUTPUT();
static void ZT_Plot(RTMode *RT);
static void VT_Plot(VTMode *VT);
static int32_t IT_PlotIT_Plot(WorkMode *WorkModeData);
static void IV_Plot(IVMode *IV);
static void PS_Plot(PSMode *PS);
static int32_t IT_Plot(WorkMode *WorkModeData);
// the following fxn do the same thing
// IVCurve_T is called if Vorigin > Vfinal, vice versa
@@ -657,6 +660,7 @@ static void ramp_test();
static uint16_t DPVCurve(WorkMode *WorkModeData);
static uint16_t CVCurve(CVMode *CV);
static uint16_t SWVCurve(WorkMode *WorkModeData);
static uint16_t PSCurve(PSMode *PS);
static void reset();
static void Eliteinterrupt();
@@ -687,6 +691,7 @@ static void TurnOn10V();
#include "EliteCCMode.h"
#include "EliteIVCurve.h"
#include "EliteCVCurve.h"
#include "ElitePSCurve.h"
#include "EliteITCurve.h"
#include "EliteVTCurve.h"
#include "EliteZTCurve.h"
@@ -800,7 +805,6 @@ static void update_ZM_instruction(uint8 *ins) {
}
break;
}
case CV_CURVE: {
// CleanBuffer();
INSTRUCTION.eliteFxn = CV_CURVE;
@@ -867,13 +871,36 @@ static void update_ZM_instruction(uint8 *ins) {
}
case POTENTIAL_STATE: {
INSTRUCTION.eliteFxn = POTENTIAL_STATE;
DACReset = true;
INSTRUCTION.SampleRate = 1000;
// test
not_buf[0] = ins[3];
not_buf[1] = ins[4];
not_buf[2] = ins[5];
not_buf[3] = ins[6];
// SimpleProfile_SetParameter(BLE_DAT_BUFF_CHAR, BLE_DAT_BUFF_SIZE, not_buf);
if (ins[3] | ins[4]) {
INSTRUCTION.VoltOrigin = ((uint16_t)(ins[3]) << 8) | (uint16_t)(ins[4]);
// INSTRUCTION.VoltOrigin = Usercode_Correction_to_DAC(INSTRUCTION.VoltOrigin);
}
if (ins[5] | ins[6]) {
INSTRUCTION.VoltFinal = ((uint16_t)(ins[5]) << 8) | (uint16_t)(ins[6]);
// INSTRUCTION.VoltFinal = Usercode_Correction_to_DAC(INSTRUCTION.VoltFinal);
}
if (ins[7] | ins[8]) {
INSTRUCTION.Step = ((uint16_t)(ins[7]) << 8) | (uint16_t)(ins[8]);
INSTRUCTION.Step = StepCode2DACcode(INSTRUCTION.Step);
}
if (ins[9]) {
INSTRUCTION.StepTime = ins[9];
INSTRUCTION.StepTime = OldStep2NewStepTime(INSTRUCTION.StepTime);
}
if (ins[10]) {
INSTRUCTION.CycleNumber = ins[10];
}
// // test
// not_buf[0] = ins[3];
// not_buf[1] = ins[4];
// not_buf[2] = ins[5];
// not_buf[3] = ins[6];
// SimpleProfile_SetParameter(BLE_DAT_BUFF_CHAR, BLE_DAT_BUFF_SIZE, not_buf);
break;
}
@@ -78,6 +78,7 @@ static void DACCode2Real2Notify(uint16_t DACcode) {
(INSTRUCTION.eliteFxn == IT_CURVE) || \
(INSTRUCTION.eliteFxn == VT_CURVE) || \
(INSTRUCTION.eliteFxn == ZT_CURVE) || \
(INSTRUCTION.eliteFxn == POTENTIAL_STATE) || \
(INSTRUCTION.eliteFxn == CONSTANT_CURRENT) \
)
@@ -149,7 +150,7 @@ static void SimpleBLEPeripheral_performPeriodicTask(WorkMode *WorkModeData) {
}
static void EliteDACControl(WorkMode *WorkModeData) {
if ((INSTRUCTION.eliteFxn == IV_CURVE) || (INSTRUCTION.eliteFxn == CV_CURVE)) {
if ((INSTRUCTION.eliteFxn == IV_CURVE) || (INSTRUCTION.eliteFxn == CV_CURVE) || (INSTRUCTION.eliteFxn == POTENTIAL_STATE)) {
// output a certain voltage and put it into NotifyVolt
DACCode2Real2Notify(VoltScan(WorkModeData));
}
@@ -179,7 +180,6 @@ static void EliteDACControl(WorkMode *WorkModeData) {
}
CCModeVoltOut(WorkModeData->CC);
}
else{
// IT, VT need only ADC measure
return;
@@ -190,7 +190,7 @@ static void EliteADCControl(WorkMode *WorkModeData) {
if (CT.SampleRate_counter == INSTRUCTION.SampleRate - 1) {
switch (INSTRUCTION.eliteFxn) {
case IV_CURVE:{
IT_Plot(WorkModeData);
IV_Plot(WorkModeData->IV);
break;
}
case CV_CURVE:{
@@ -215,6 +215,10 @@ static void EliteADCControl(WorkMode *WorkModeData) {
CCModeReverseCurrent(WorkModeData->CC);
break;
}
case POTENTIAL_STATE:{
PS_Plot(WorkModeData->PS);
break;
}
default:{
IT_Plot(WorkModeData);
break;
@@ -233,7 +237,7 @@ static void EliteNotifyControl() {
SendNotify();
}
}
else if(INSTRUCTION.eliteFxn == CONSTANT_CURRENT){
else if((INSTRUCTION.eliteFxn == CONSTANT_CURRENT) || (INSTRUCTION.eliteFxn == POTENTIAL_STATE)){
if(CT.NotifyCounter == INSTRUCTION.NotifyRate){
SendNotify();
}