Miss delay function and auto change gain for EIS. fset in log scale and linear 99% done.

This commit is contained in:
Taylor Liao
2021-08-02 14:52:35 +08:00
parent 27ffda9adf
commit 9ea1f6e40d
9 changed files with 125 additions and 111 deletions
@@ -57,17 +57,18 @@ static uint16_t DAC_outputV(uint16_t voltLV) {
}
#endif
#define ELITE_VERSION_EIS
#ifdef ELITE_VERSION_EIS
#define AD5940_SYS_CLOCK 16000000
#define Cutoff_Freq 250000
static uint32_t DAC_outputV(uint32_t freq) {
select_REG(0x2030);
w32_REG(freq);
return freq;
}
#endif
#define AD5940_SYS_CLOCK 16000000
#define Cutoff_Freq 250000
static void VoutGainControl(uint8_t VOUTLevel){
if(VOUTLevel == 0){
@@ -89,27 +90,37 @@ static void VoutGainControl(uint8_t VOUTLevel){
record_flag = false;
}
static uint32_t Delay2SetRate(uint16_t delay, uint32_t freq){
uint32_t period;
if (freq == 0){
period = 10000;
} else {
period = 1000000 / freq; // [sec]
period = period * delay / 10;
}
if (period <= 2){
period = 2; //0.2ms
}
return period;
}
static uint32_t User2Freq(uint32_t UserCode){
return ((uint64_t)(UserCode * AD5940_SYS_CLOCK * 10 + 536870912) / 1073741824); //return [100mHz]
uint32_t freq;
if (UserCode == 1){
freq = 100;
} else {
freq = UserCode * 100 * 0.0149 + 0.5;
}
return freq; //[100mHz]
}
static uint32_t Freq2DAC(uint32_t freq){
return ((uint64_t)(freq * 107374182 + AD5940_SYS_CLOCK/2)/ AD5940_SYS_CLOCK); //return code
}
static uint32_t CalcPeriod(uint32_t freq){
uint32_t period;
if(freq > 50000){
freq = 50000;
}
period = 100000 / freq;
return period; // [0.1ms]
uint32_t code;
code = freq / 0.0149 / 100 + 0.5;
return code; //return code
}
@@ -5,66 +5,95 @@
static void eis_fscan(void)
{
struct wm_eis_ctx_t *eis = (struct wm_eis_ctx_t *)wm_get();
if (vscanReset) {
eis->_f1 = User2Freq(eis->_f1);
eis->_f2 = User2Freq(eis->_f2);
eis->_fmax = User2Freq(eis->_fmax);
eis->_fmin = User2Freq(eis->_fmin);
if (instru.directionInit == 1) {
eis->_direction_up = true;
} else if (instru.directionInit == 0) {
eis->_direction_up = false;
}
SetDACBias(instru.dcbias);
SetWGAmp(instru.acamp);
SetAVG(instru.avgnum);
HSTIAGainCtrl(instru.rtia); // 1k
eis->_decades = CalcDecade(instru.f1, instru.f2);
instru.fset = instru.f1;
instru.fset = eis->_f1;
}
if (!vscanReset) {
//stop condition
if(eis->_direction_up){
if (instru.fset >= eis->_fmax) {
PeriodicEvent = false;
}
} else {
if (instru.fset <= eis->_fmin) {
PeriodicEvent = false;
}
}
if(eis->_direction_up) {
if(eis->_decadeIndex < eis->_decades && eis->_sweepIndex == 0) {
eis->_fd1 = instru.f1 * pow(10, eis->_decadeIndex);
eis->_fd2 = instru.f1 * pow(10, eis->_decadeIndex + 1);
if(eis->_sweepIndex == 0){
if(eis->_decadeIndex < eis->_decades) {
eis->_fd1 = eis->_f1 * pow(10, eis->_decadeIndex);
eis->_fd2 = eis->_f1 * pow(10, eis->_decadeIndex + 1);
} else if (eis->_decadeIndex == eis->_decades) {
eis->_fd1 = eis->_f1 * pow(10, eis->_decadeIndex);
eis->_fd2 = eis->_fmax;
}
}
if(eis->_decadeIndex != 0 && eis->_sweepIndex == 0){
eis->_sweepIndex++;
}
if(instru.scale == 0) { // logarithm
instru.fset = eis->_fd1 * pow(10, eis->_sweepIndex * (1 / (eis->_ppd - 1)));
instru.fset = (eis->_fd1 * (pow(10, (eis->_sweepIndex / (eis->_ppd - 1)))) + 0.5));
}
else if (instru.scale == 1) { // linear
instru.fset = eis->_fd1 + eis->_sweepIndex * ((eis->_fd2 - eis->_fd1) / (eis->_ppd - 1));
instru.fset = eis->_fd1 + eis->_sweepIndex * ((eis->_fd2 - eis->_fd1) / (eis->_ppd - 1) + 0.5);
}
} else { //reverse
if(eis->_decadeIndex < eis->_decades && eis->_sweepIndex == 0) {
eis->_fd1 = instru.f1 * pow(10, -eis->_decadeIndex);
eis->_fd2 = instru.f1 * pow(10, -(eis->_decadeIndex + 1));
if(eis->_sweepIndex == 0){
if(eis->_decadeIndex < eis->_decades){
eis->_fd1 = eis->_f1 * pow(10, -eis->_decadeIndex);
eis->_fd2 = eis->_f1 * pow(10, -(eis->_decadeIndex + 1));
} else if (eis->_decadeIndex == eis->_decades){
eis->_fd1 = eis->_f1 * pow(10, -eis->_decadeIndex);
eis->_fd2 = eis->_fmin;
}
}
if(eis->_decadeIndex != 0 && eis->_sweepIndex == 0){
eis->_sweepIndex++;
}
if(instru.scale == 0) { // logarithm
instru.fset = eis->_fd1 * pow(10, - (eis->_sweepIndex * (1 / (eis->_ppd - 1))));
instru.fset = eis->_fd1 * (pow(10, - (eis->_sweepIndex / (eis->_ppd - 1))) + 0.5);
}
else if(instru.scale == 1) { // linear
instru.fset = eis->_fd1 + eis->_sweepIndex * ((eis->_fd2 - eis->_fd1) / (eis->_ppd - 1));
instru.fset = eis->_fd1 + eis->_sweepIndex * ((eis->_fd2 - eis->_fd1) / (eis->_ppd - 1) + 0.5);
}
}
if(++eis->_sweepIndex == eis->_ppd) {
eis->_sweepIndex = 0;
eis->_sweepIndex = 0.0;
eis->_decadeIndex ++;
}
//stop condition
if (instru.fset >= eis->_fmax || instru.fset <= eis->_fmin) {
PeriodicEvent = false;
instru.fset = 0;
}
}
InputNotify(NOTIFY_CURRENT, instru.fset);
InputNotify(NOTIFY_VOLT, eis->_fd1);
InputNotify(NOTIFY_IMPEDANCE, 100 * pow(10, (eis->_sweepIndex / (eis->_ppd - 1))) + 0.5);
}
#endif
@@ -156,6 +156,7 @@ static void checkFlafLED()
static void WorkModeLED()
{
switch (instru.eliteFxn) {
case CURVE_EIS:
case CURVE_IV:
case CURVE_VO:
case CURVE_RT:
@@ -13,6 +13,7 @@ static void reset() {
initINSBuf();
initDATBuf();
AD5940_sftreset();
AD5940_init();
// PIN_setOutputValue(pin_handle, HIGH_Z_MODE, 0); // HIGH Z MODE // 1: close; 0: open;
@@ -58,9 +58,9 @@ struct wm_eis_ctx_t {
uint32_t _fmin;
uint32_t _fset;
uint8_t _decades; //num of decades in whole
uint16_t _ppd;
double _ppd;
uint8_t _decadeIndex; //index of decade max is 8
uint16_t _sweepIndex; //index of smaller decade max is 10
double _sweepIndex; //index of smaller decade max is 10
bool _direction_up;
};
@@ -198,7 +198,7 @@ static int __eis_create(void)
p->_fset = 0;
p->_ppd = instru.ppd; //points per decade
p->_decades = 0;
p->_sweepIndex = 0;
p->_sweepIndex = 0.0;
p->_decadeIndex = 0;
p->_direction_up = true;
@@ -29,13 +29,13 @@ enum all_mode_e {
CURVE_IT = 0x06, // I-T Graph //0x60,
CURVE_CC = 0x07, // Constant Current (CC) //0xD0,
CURVE_OCP = 0x08, // Open Circuit Potential (OCP)
CURVE_CV = 0x09, // Cyclic Voltammetry (CV) //0xC0,
CURVE_CV = 0xD1,//0x09, // Cyclic Voltammetry (CV) //0xC0,
CURVE_LSV = 0x0A, // Linear Sweep Voltammetry (LSV) //0x02,
CURVE_CA = 0x0B, // Chronoamperometric Graph (CA) //0x03,
CURVE_PULSE = 0x0C, //0x94,
CURVE_EIS = 0xD1, //Should Change to 0xD1
CURVE_EIS = 0x09, //Should Change to 0xD1
CURVE_EIS_CV = 0xD2,
CURVE_CALI_DAC = 0xF0, //0x93,
@@ -35,22 +35,7 @@ static void volt_out()
static void freq_out()
{
/*
Usercode | Reality | DAC
0 ~ 50000 | 1.2kHz ~ 180kHz | 80000 ~ 12080000
*/
// static int32_t freqDAC; //Freq code send to DAC
// static int32_t freqUser; //Freq from set usercode
// static int32_t freqOut; //Freq in reality
// freqUser = fset;
// freqDAC = Usercode_Correction_to_Freq(freqUser);
// DAC_outputF(freqDAC);
DAC_outputV(instru.fset);
// freqOut = (int32_t)(freqUser * 3.58 + 1000);
// InputNotify(NOTIFY_IMPEDANCE, freqOut);
return;
}
@@ -478,10 +463,10 @@ static void CC_Plot(void) //real and imag impedance plot (incorrect values)
void *wm = wm_get();
static int32_t realZ;
static int32_t imagZ;
static uint32_t freq;
static uint32_t freq, period;
if (ADC_cnt == 0) {
DACenable(AFTER_READ_V); //freq_out
DAC_outputV(Freq2DAC(instru.fset));
ADC_cnt++;
} else if (ADC_cnt == 1) {
@@ -493,13 +478,13 @@ static void CC_Plot(void) //real and imag impedance plot (incorrect values)
ADC_cnt++;
} else if (ADC_cnt == 3) {
freq = ReadFreq();
period = Delay2SetRate(instru.delay, instru.fset);
ADC_cnt = 0;
}
InputNotify(NOTIFY_CURRENT, realZ);
InputNotify(NOTIFY_VOLT, imagZ);
InputNotify(NOTIFY_IMPEDANCE, freq);
// InputNotify(NOTIFY_CURRENT, realZ);
// InputNotify(NOTIFY_VOLT, imagZ);
// InputNotify(NOTIFY_VOLT, period);
return;
}
@@ -672,24 +672,16 @@ static void setEIS_EIS (void)
AD5940_init();
select_REG(LPDACCON0); //2128 //DC on
w32_REG(0b0000001);
w32_REG(0x00000001); //LPDAC enabled
select_REG(LPDACSW0); //2124 //operation
w32_REG(0b101011);
select_REG(LPDACDAT0); //2120 //output Vout
w32_REG(0x00000799); //bias
// select_REG(DE0RESCON); //20F8 //DE0's gain
// w32_REG(0x00000000);
// select_REG(HSRTIACON); //20F0 HSTIA GAIN
// w32_RET(0x);
select_REG(ADCCON); //21A8
w32_REG(0x00000101);
select_REG(DFTCON); //20D0
w32_REG(0x001000C1);
select_REG(SWCON); //200C
w32_REG(0x00026905); //0b0100110100100000101
select_REG(WGFCW); //2030
w32_REG(0x00333333); //SINEFCW/2^30 * 16 MHz
select_REG(AFECON); //2000
w32_REG(0x0030CFC0);
@@ -707,13 +699,6 @@ static void setEIS_EIS (void)
w32_REG(0x0000000E); //DAC gain = 2, > 80 kHz
select_REG(0x238C); //ADCBUFCON
w32_REG(0x005F3D0F); //recommended
select_REG(0x2014);
w32_REG(0x0);
select_REG(0x203C);
w32_REG(0x00000400);
select_REG(0x2014);
w32_REG(0x00000004);
}
static void setEIS_CV (void)
@@ -769,15 +754,13 @@ static void update_ZM_instruction(uint8 *ins) {
switch (ins[2]) {
case CURVE_EIS: { //0xD1
if (ins[3] == PARA_1) { //3000D1 01
instru.sampleRate = 15; //ms
instru.f1 = 100;//((uint32_t)(ins[4]) << 24) | ((uint32_t)(ins[5]) << 16) | ((uint32_t)(ins[6]) << 8) | (uint32_t)(ins[7]); //FREQ_START
instru.f2 = 100000;//((uint32_t)(ins[8]) << 24) | ((uint32_t)(ins[9]) << 16) | ((uint32_t)(ins[10]) << 8) | (uint32_t)(ins[11]); //FREQ_STOP
instru.sampleRate = 15;//15; //ms
instru.f1 = 67;//((uint32_t)(ins[4]) << 24) | ((uint32_t)(ins[5]) << 16) | ((uint32_t)(ins[6]) << 8) | (uint32_t)(ins[7]); //FREQ_START
instru.f2 = 1342282;//((uint32_t)(ins[8]) << 24) | ((uint32_t)(ins[9]) << 16) | ((uint32_t)(ins[10]) << 8) | (uint32_t)(ins[11]); //FREQ_STOP
instru.fmax = (uint32_t)VMAX(instru.f1, instru.f2);
instru.fmin = (uint32_t)VMIN(instru.f1, instru.f2);
instru.delay = 0;//((uint16_t)(ins[12]) << 8) | (uint16_t)(ins[13]); //DELAY how many periods
if(instru.delay == 0){
instru.VsetRate = 10000;
}
instru.delay = 1;//((uint16_t)(ins[12]) << 8) | (uint16_t)(ins[13]); //DELAY how many periods
instru.VsetRate = 10000;//Delay2SetRate(instru.delay, instru.fset);
if (instru.f1 > instru.f2){
instru.directionInit = 0; //0:reverse 1:forward
} else if (instru.f1 <= instru.f2){
@@ -785,7 +768,7 @@ static void update_ZM_instruction(uint8 *ins) {
}
} else if (ins[3] == PARA_2) { //3000D1 02
instru.eliteFxn = CURVE_EIS;
instru.dcbias = 0;//((uint16_t)(ins[4]) << 8) | (uint16_t)(ins[5]);
instru.dcbias = 1945;//((uint16_t)(ins[4]) << 8) | (uint16_t)(ins[5]);
instru.acamp = 1280;//((uint16_t)(ins[6]) << 8) | (uint16_t)(ins[7]);
instru.avgnum = 2;//(uint8_t)(ins[8]);
instru.rtia = 1;//(uint8_t)(ins[9]);
@@ -793,6 +776,10 @@ static void update_ZM_instruction(uint8 *ins) {
instru.scale = 0;//(uint8_t)(ins[12]);
setEIS_EIS();
SetDACBias(instru.dcbias);
SetWGAmp(instru.acamp);
SetAVG(instru.avgnum);
ModeLED(WORKING);
}
break;
@@ -161,15 +161,19 @@ static void SimpleBLEPeripheral_performPeriodicTask(void) {
*/
if (Ve1MatchVe2Mode()) {
if (instru.Ve1 == instru.Ve2) {
DAC_outputV(Usercode_Correction_to_DAC(instru.VoutGainLevel, instru.Ve1));
PeriodicEvent = false;
// PIN_setOutputValue(pin_handle, HIGH_Z_MODE, 0); // 0: open highz;
ModeLED(NO_EVENT);
} else if (instru.f1 == instru.f2) {
DAC_outputV(instru.f1);
PeriodicEvent = false;
ModeLED(NO_EVENT);
if (instru.eliteFxn == CURVE_EIS){
if (instru.f1 == instru.f2) {
DAC_outputV(instru.f1);
PeriodicEvent = false;
ModeLED(NO_EVENT);
}
} else {
if (instru.Ve1 == instru.Ve2) {
DAC_outputV(Usercode_Correction_to_DAC(instru.VoutGainLevel, instru.Ve1));
PeriodicEvent = false;
// PIN_setOutputValue(pin_handle, HIGH_Z_MODE, 0); // 0: open highz;
ModeLED(NO_EVENT);
}
}
}
}
@@ -205,7 +209,7 @@ static void SimpleBLEPeripheral_performPeriodicTask(void) {
GPT.VscanRateCounter -= instru.VsetRate * GPT.GptimerMultiple; //To get right time
vscan_flag = true;
if (vscan_flag) {
vscan_ctrl(); // vset
vscan_ctrl(); // vset, fset
vscan_flag = false;
}
}
@@ -231,10 +235,6 @@ static void SimpleBLEPeripheral_performPeriodicTask(void) {
ADC_flag = true;
if(ADC_flag){
EliteADCControl(); //send vset and read data
if(GPT.DelayTimeCounter >= (CalcPeriod(instru.fset) * instru.delay * 10)){
CC_Plot();
GPT.DelayTimeCounter = 0;
}
ADC_flag = false;
}
}
@@ -249,7 +249,7 @@ static void SimpleBLEPeripheral_performPeriodicTask(void) {
notify_flag = false;
}
if(notify_flag){
SendNotify(); //data from EliteADCControl <- CC_Plot
SendNotify(); //data from EliteADCControl
notify_flag = false;
}
}
@@ -388,11 +388,11 @@ static void EliteADCControl(void) //CURVE_IV => CC_Plot() | CURVE_CV => Iin_Vin_
void *wm = wm_get();
switch (instru.eliteFxn) {
// case CURVE_EIS:
// CC_Plot();
// //Bode_Plot();
// //Nyquist_Plot();
// break;
case CURVE_EIS:
CC_Plot();
//Bode_Plot();
//Nyquist_Plot();
break;
case CURVE_IV:
case CURVE_IV_CY: