Compare commits

...

5 Commits

Author SHA1 Message Date
yichin a64d596e7f test 2020-01-10 18:10:35 +08:00
105042004 e98f387c82 change pulse period 2020-01-10 17:17:35 +08:00
105042004 c9bbc1aab1 test SCC 2020-01-10 17:02:10 +08:00
yichin 9e4bb038e8 testing SAC 2019-12-27 19:20:50 +08:00
105042004 ce5c87fcf7 create Square Current mode 2019-12-27 17:40:34 +08:00
8 changed files with 8004 additions and 7 deletions
@@ -156,7 +156,6 @@ static uint16_t CVCurve(CVMode *CV) {
}
if (CT.StepTimeCounter == CV->_StepTime) {
// Decide next direction
if (CV->_VoVi_Switch == 0x00){ //user see Vout
if (direction_up) {
@@ -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 == SQUARE_CURR) {
Voltage = SCCurve(WorkModeData->SC);
}
// IV plot mode
@@ -45,7 +47,7 @@ static uint16_t OneWayVoltScan(IVMode *IV) {
// output the next output volt
INSTRUCTION.VoltConstant = INSTRUCTION.VoltConstant + IV->_Step;
// Only used in two-wire IV
// if(INSTRUCTION.VoltConstant > IV->_VStop){
// if(INSTRUCTION.VosltConstant > IV->_VStop){
// INSTRUCTION.VoltConstant = IV->_VStop;
// }
@@ -22,6 +22,7 @@
/* DAC reset parameter */
#define DAC_ZERO 25000
#define DAC_ONEV 30000
#define DAC_POS_MAX 0x0000
#define DAC_NEG_MAX 0xFFFF
@@ -77,6 +78,10 @@ struct HEADSTAGE_INSTRUCTION {
uint8_t VoVi_Switch;
// Square current curve
uint16_t Pulse_Period;
uint16_t Pulse_Length;
} INSTRUCTION = {0};
/*********************************************************************
@@ -0,0 +1,167 @@
#ifndef ELITESC
#define ELITESC
static uint16_t SCCurve(SCMode *SC) {
static uint16_t DACOutCode;
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) {
DACUserCode = SC->_VOrigin;
DACOutCode = Usercode_Correction_to_DAC(DACUserCode);
DAC_outputV(DACOutCode); // output VOLT_ORIGIN
DACReset = false;
return DACOutCode;
}
if (CT.StepTimeCounter == SC->_StepTime) {
// if (CT.PulseLength_counter < SC->_pulsePeriod) {
// if (SC->_MeasureData < (1e8 - SC->_Step)){ // SC->_MeasureData == 1e8 => 0.1mA
// SC->_VStop += SC->_Step;
// }
// else if (SC->_MeasureData > (1e8 + SC->_Step)){
// SC->_VStop -= SC->_Step;
// }
//
// DACUserCode = SC->_VStop;
// }
// else if (CT.PulseLength_counter < SC->_pulseLength) {
// if (SC->_MeasureData < (0 - SC->_Step)){ // SC->_MeasureData == 0 => 0mA
// SC->_VOrigin += SC->_Step;
// }
// else if (SC->_MeasureData > (0 + SC->_Step)){
// SC->_VOrigin -= SC->_Step;
// }
//
// DACUserCode = SC->_VOrigin;
// }
//
//
// SC->_CycleNumber--;
// if (SC->_CycleNumber == 0){
// PeriodicEvent = false; // periodic event end
// DACReset = true;
// }
if (CT.PulseLength_counter < SC->_pulsePeriod) {
//if (SC->_MeasureData > 1e10){
//LED_color(DARKLED, 255, 0, 0); // red when _MeasureData is larger than 10mA
//}
DACUserCode = SC->_VOrigin;
}
else if (CT.PulseLength_counter < SC->_pulseLength) {
//if (SC->_MeasureData > 1e10){
//LED_color(DARKLED, 0, 0, 255); // blue when _MeasureData is larger than 10mA
//}
DACUserCode = SC->_VStop;
}
if (CT.PulseLength_counter == 1 ) SC->_CycleNumber--;
if (SC->_CycleNumber == 0){
PeriodicEvent = false; // periodic event end
DACReset = true;
}
DACOutCode = Usercode_Correction_to_DAC(DACUserCode);
DAC_outputV(DACOutCode);
}
return DACOutCode;
}
static void SC_Plot(SCMode *SC){
static uint8_t PreviousGain = GAIN_200R;
static uint8_t VoltCurrentSwitch = 0;
uint16_t ADC_measure = 0;
if(VoltCurrentSwitch < 5){
ReadCurrent(spi_ADC_rxbuf);
VoltCurrentSwitch ++;
}
else if(VoltCurrentSwitch == 5){
// read current
if(INSTRUCTION.AutoGainEnable){
SC->_MeasureData = AutoGainReadCurrent(spi_ADC_rxbuf);
if(PreviousGain != INSTRUCTION.ADCGainLevel){
PreviousGain = INSTRUCTION.ADCGainLevel;
SC->_MeasureData = AutoGainReadCurrent(spi_ADC_rxbuf);
SC->_MeasureData = AutoGainReadCurrent(spi_ADC_rxbuf);
}
if(PreviousGain != INSTRUCTION.ADCGainLevel){
PreviousGain = INSTRUCTION.ADCGainLevel;
SC->_MeasureData = AutoGainReadCurrent(spi_ADC_rxbuf);
SC->_MeasureData = AutoGainReadCurrent(spi_ADC_rxbuf);
}
}
else{
ReadCurrent(spi_ADC_rxbuf);
SC->_MeasureData = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
}
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]);
// //SC->MeasureVolt = 20000;
// SC->MeasureVolt = DecodeADSColt(ADC_measure);
// VoltCurrentSwitch++;
// }
else if(VoltCurrentSwitch < 9){
if(SC->_VoVi_Switch == 0x01){
// read volt
ReadVolt(spi_ADC_rxbuf);
}else if(SC->_VoVi_Switch == 0x00){
// read vout volt
ReadVoutVolt(spi_ADC_rxbuf);
}
VoltCurrentSwitch++;
}
else if(VoltCurrentSwitch == 9){
if(SC->_VoVi_Switch == 0x01){
/** read battery voltage **/
ReadVolt(spi_ADC_rxbuf);
ADC_measure = (uint16_t) (spi_ADC_rxbuf[0] << 8) | (uint16_t) (spi_ADC_rxbuf[1]);
//SC->MeasureVolt = 20000;
SC->MeasureVolt = DecodeADCVolt(ADC_measure);
}else if(SC->_VoVi_Switch == 0x00){
/** read vout voltage **/
ReadVoutVolt(spi_ADC_rxbuf);
ADC_measure = (uint16_t) (spi_ADC_rxbuf[0] << 8) | (uint16_t) (spi_ADC_rxbuf[1]);
SC->MeasureVolt = DecodeADCVoutVolt(ADC_measure);
}
VoltCurrentSwitch++;
}
else{
VoltCurrentSwitch = 0;
}
NotifyCurrent[0] = (uint8_t) (SC->_MeasureData >> 24);
NotifyCurrent[1] = (uint8_t) ((SC->_MeasureData & 0x00FF0000) >> 16);
NotifyCurrent[2] = (uint8_t) ((SC->_MeasureData & 0x0000FF00) >> 8);
NotifyCurrent[3] = (uint8_t) (SC->_MeasureData & 0x000000FF);
if ((SC->_VoVi_Switch == 0x01) || (SC->_VoVi_Switch == 0x00)){ //user see Vin || user see Vout
NotifyVolt[0] = (uint8_t) (SC->MeasureVolt >> 24);
NotifyVolt[1] = (uint8_t) ((SC->MeasureVolt & 0x00FF0000) >> 16);
NotifyVolt[2] = (uint8_t) ((SC->MeasureVolt & 0x0000FF00) >> 8);
NotifyVolt[3] = (uint8_t) (SC->MeasureVolt & 0x000000FF);
}
}
#endif
@@ -39,7 +39,7 @@
#define ELITE_WORK_DATA
#include "EliteInstruction.h"
#define IV_CURVE 0b00010000
#define IV_CURVE 0b11110001
#define CV_CURVE 0b00100000
#define VOLT_OUTPUT 0b00110000
#define ZT_CURVE 0b01000000
@@ -52,6 +52,7 @@
#define POTENTIAL_STATE 0b11000000
#define CONSTANT_CURRENT 0b11010000
#define READ_VOUT_VALUE 0b11100000
#define SQUARE_CURR 0b00010000
static bool Free_Work_Mode = false;
typedef void (*InitWorkData) ();
@@ -405,6 +406,67 @@ CVMode * InitCVMode(){
}
/*End of CV Mode*/
/* SC Mode Data */ // SC mode => Square Current Mode
typedef struct _SCMode{
MEASURE;
int32_t MeasureVolt;
VOUT_PARA;
LIMIT;
uint16_t _pulseLength;
uint16_t _pulsePeriod;
}SCMode;
SCMode *InitSCMode(){
SCMode *ret = malloc(sizeof(SCMode));
ret->_MeasureData = 0;
ret->MeasureVolt = (INSTRUCTION.VoltOrigin - DAC_ZERO)/5;
// ret->_VoltOut = DAC_ZERO;
// ret->_VOrigin = DAC_ZERO;
// ret->_VStop = DAC_ONEV;;
// ret->_Step = 500; // approximately 10mV
// ret->_CycleNumber = 10;
// // ret->_StepTime = INSTRUCTION.StepTime;
// // ret->_pulseLength = INSTRUCTION.Pulse_Length; // this is pulse length, should be STEPTIME_ONE_SEC/10 or STEPTIME_ONE_SEC
// // ret->_pulsePeriod = INSTRUCTION.Pulse_Period; // this is pulse period, should be STEPTIME_ONE_SEC/100 or STEPTIME_ONE_SEC/10
//
// ret->_pulseLength = STEPTIME_ONE_SEC / 10; // this is pulse length, should be STEPTIME_ONE_SEC/10 or STEPTIME_ONE_SEC
// ret->_pulsePeriod = STEPTIME_ONE_SEC / 100; // this is pulse period, should be STEPTIME_ONE_SEC/100 or STEPTIME_ONE_SEC/10
// ret->_StepTime = STEPTIME_ONE_SEC / 1000;
//
ret->_VOrigin = INSTRUCTION.VoltOrigin;
ret->_VStop = INSTRUCTION.VoltFinal;;
ret->_Step = INSTRUCTION.Step; // approximately 10mV
ret->_CycleNumber = 100;
ret->_StepTime = INSTRUCTION.StepTime;
ret->_pulsePeriod = INSTRUCTION.Pulse_Period; // this is pulse period, should be STEPTIME_ONE_SEC/100 or STEPTIME_ONE_SEC/10
ret->_pulseLength = INSTRUCTION.Pulse_Length; // this is pulse length, should be STEPTIME_ONE_SEC/10 or STEPTIME_ONE_SEC
// ret->SetVoltOut = &_SetVoltOut;
// ret->GetVoltOut = &_GetVoltOut;
// ret->SetVOrigin = &_SetVOrigin;
// ret->GetVOrigin = &_GetVOrigin;
// ret->SetVStop = &_SetVStop;
// ret->GetVStop = &_GetVStop;
// ret->SetStep = &_SetStep;
// ret->GetStep = &_GetStep;
// ret->SetStepTime = &_SetStepTime;
// ret->GetStepTime = &_GetStepTime;
// ret->SetCycleNumber = &_SetCycleNumber;
// ret->GetCycleNumber = &_GetCycleNumber;
ret->_LimitValue = 1e5;
ret->SetLimitValue = &_SetLimitValue;
ret->GetLimitValue = &_GetLimitValue;
return ret;
}
/* End of SC Mode Data */
/* Const Current Mode */
#define CC_ZERO_POINT 0
#define MAX_DAC_UC 50000
@@ -534,6 +596,7 @@ typedef union _WorkMode{
CVMode *CV;
RTMode *RT;
CCMode *CC;
SCMode *SC;
// CCCMode *CCC;
PSMode *PS;
@@ -574,6 +637,9 @@ void InitWorkMode(WorkMode *WM){
case READ_VOUT_VALUE:
WM->RVout = InitTVMode();
break;
case SQUARE_CURR:
WM->SC = InitSCMode();
break;
default:
WM->VT = InitVTMode();
break;
@@ -630,8 +696,12 @@ void FreeWorkMode(WorkMode *WM){
WM->RVout = NULL;
}
break;
case SQUARE_CURR:
if(WM->SC != NULL){
free(WM->SC);
WM->SC = NULL;
}
break;
// case CYCLE_CONSTANT_CURRENT:
// if(WM->CCC != NULL){
// free(WM->CCC);
@@ -580,7 +580,7 @@ static void set_update_instruction_callback(update_instruction_callback_type cal
#define VIS_SHIFT_200R 0b10000000
// real instruction
#define IV_CURVE 0b00010000
#define IV_CURVE 0b11110001
#define CV_CURVE 0b00100000
#define VOLT_OUTPUT 0b00110000
#define ZT_CURVE 0b01000000
@@ -594,6 +594,8 @@ static void set_update_instruction_callback(update_instruction_callback_type cal
#define CONSTANT_CURRENT 0b11010000
#define READ_VOUT_VALUE 0b11100000
#define CYCLE_CONSTANT_CURRENT 0b11110000
#define SQUARE_CURR 0b00010000
// CIS instruction
@@ -632,6 +634,7 @@ struct _CT{
uint16_t StepTimeCounter;
uint16_t NotifyCounter;
uint32_t StandByCounter;
uint32_t PulseLength_counter;
}CT = {0};
//static bool NotifyReady = false;
@@ -661,6 +664,7 @@ static uint16_t OneWayVoltScan(IVMode *IV);
static void ramp_test();
static uint16_t DPVCurve(WorkMode *WorkModeData);
static uint16_t CVCurve(CVMode *CV);
static uint16_t SCCurve(SCMode *SC);
static uint16_t SWVCurve(WorkMode *WorkModeData);
static void reset();
@@ -692,6 +696,7 @@ static void TurnOn10V();
#include "EliteCCMode.h"
#include "EliteIVCurve.h"
#include "EliteCVCurve.h"
#include "EliteSCCurve.h"
#include "EliteITCurve.h"
#include "EliteVTCurve.h"
#include "EliteZTCurve.h"
@@ -851,6 +856,45 @@ static void update_ZM_instruction(uint8 *ins) {
break;
}
case SQUARE_CURR: {
// CleanBuffer();
INSTRUCTION.eliteFxn = SQUARE_CURR;
DACReset = true;
INSTRUCTION.SampleRate = 100;
// if (ins[3] | ins[4]) {
INSTRUCTION.VoltOrigin = ((uint16_t)(ins[3]) << 8) | (uint16_t)(ins[4]); // don't care, set to DAC_ZERO as default
// INSTRUCTION.VoltOrigin = Usercode_Correction_to_DAC(INSTRUCTION.VoltOrigin);
// }
// if (ins[5] | ins[6]) {
INSTRUCTION.VoltFinal = ((uint16_t)(ins[5]) << 8) | (uint16_t)(ins[6]); // don't care, set to DAC_ONEV as default
// 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);
// }
INSTRUCTION.Pulse_Period = ins[9] * 2; // Pulse Period
INSTRUCTION.Pulse_Period = OldStep2NewStepTime(INSTRUCTION.Pulse_Period);
INSTRUCTION.Pulse_Length = ins[9] * 4; // Pulse Length
INSTRUCTION.Pulse_Length = OldStep2NewStepTime(INSTRUCTION.Pulse_Length);
// set for testing
// INSTRUCTION.VoltOrigin = DAC_ZERO;
// INSTRUCTION.VoltFinal = DAC_ONEV;
// INSTRUCTION.Step = 500;
// INSTRUCTION.StepTime = STEPTIME_ONE_SEC / 1000;
// INSTRUCTION.Pulse_Period = STEPTIME_ONE_SEC / 100;
// INSTRUCTION.Pulse_Length = STEPTIME_ONE_SEC / 10;
break;
}
case VOLT_OUTPUT: {
INSTRUCTION.eliteFxn = VOLT_OUTPUT;
@@ -78,6 +78,7 @@ static void DACCode2Real2Notify(uint16_t DACcode) {
(INSTRUCTION.eliteFxn == IT_CURVE) || \
(INSTRUCTION.eliteFxn == VT_CURVE) || \
(INSTRUCTION.eliteFxn == ZT_CURVE) || \
(INSTRUCTION.eliteFxn == SQUARE_CURR) || \
(INSTRUCTION.eliteFxn == CONSTANT_CURRENT) || \
(INSTRUCTION.eliteFxn == READ_VOUT_VALUE) \
)
@@ -118,6 +119,14 @@ static void SimpleBLEPeripheral_performPeriodicTask(WorkMode *WorkModeData) {
CT.NotifyCounter ++;
}
// Pulse Length counter (Square Current Curve)
if (CT.PulseLength_counter == INSTRUCTION.Pulse_Length){
CT.PulseLength_counter = 1;
}
else{
CT.PulseLength_counter ++;
}
/** Periodic Event **/
// Default working flow is DAC out -> ADC read -> send notify
// We will need a flag to control DAC, if we want to exchange to ADC -> DAC -> notify
@@ -171,6 +180,9 @@ static void EliteDACControl(WorkMode *WorkModeData) {
VoltScan(WorkModeData);
}
}
else if(INSTRUCTION.eliteFxn == SQUARE_CURR){
VoltScan(WorkModeData);
}
else if (INSTRUCTION.eliteFxn == ZT_CURVE){
if(INSTRUCTION.ResisterMeter == RESISTER_METER_SMALL){
// output 1V
@@ -215,6 +227,10 @@ static void EliteADCControl(WorkMode *WorkModeData) {
CV_Plot(WorkModeData->CV);
break;
}
case SQUARE_CURR:{
SC_Plot(WorkModeData->SC);
break;
}
case IT_CURVE:{
IT_Plot(WorkModeData);
// NotifyReady = true;
@@ -256,7 +272,7 @@ static void EliteADCControl(WorkMode *WorkModeData) {
}
static void EliteNotifyControl() {
if ((INSTRUCTION.eliteFxn == IV_CURVE) || (INSTRUCTION.eliteFxn == CV_CURVE)) {
if ((INSTRUCTION.eliteFxn == IV_CURVE) || (INSTRUCTION.eliteFxn == CV_CURVE) || (INSTRUCTION.eliteFxn == SQUARE_CURR)) {
// output the last notify, and reset Elite
if (!PeriodicEvent) {
SendNotify();
+7694
View File
File diff suppressed because it is too large Load Diff