optimize auto gain changer

This commit is contained in:
Roy
2021-07-01 15:50:33 +08:00
parent cfa28f9d7d
commit 8d9d9a4955
10 changed files with 685 additions and 422 deletions
@@ -1,4 +1,6 @@
/*=============================================================================
= EliteADC.h =
=============================================================================*/
#ifndef EliteADC
#define EliteADC
@@ -6,7 +8,6 @@
#include "EliteSPI.h"
#include "EliteNotify.h"
// Elite ADC macro
// ADC command, Elite will use these cmd to control ADC
#define CMD_CURRENT_MEASURE 0xC5
#define CMD_VOLT_MEASURE 0xD5
@@ -14,12 +15,56 @@
#define CMD_BATTERY_MEASURE 0xF1
// controller command, these are command from control box
#define ADC_CH_CURRENT 0x00
#define ADC_CH_VOLT 0x01
#define ADC_CH_DAC 0x02
#define ADC_CH_CURR 0x00
#define ADC_CH_VIN 0x01
#define ADC_CH_VOUT 0x02
#define ADC_CH_BAT 0x03
static void ADC_write(uint8_t ADCin) {
/* for Elite1.5-re */
// Iin theoretical boundary <2.67, 1.89~80, 63~2600, >1900 (uA)
#define I_GAIN_SMALL_BOUNDARY 4000 // 4 uA = 4,000,000 pA
#define I_GAIN_MID1_BOUNDARY1 2500 // 2.5 uA = 2,500,000 pA
#define I_GAIN_MID1_BOUNDARY2 100000 // 100 uA = 100,000,000 pA
#define I_GAIN_MID2_BOUNDARY1 85000 // 85 uA = 85,000,000 pA
#define I_GAIN_MID2_BOUNDARY2 2050000 // 2050 uA = 2,050,000 nA
#define I_GAIN_LARGE_BOUNDARY 1800000 // 1800 uA = 1,800,000 nA
// Vin theoretical boundary <7, 5~200, >100 (mV)
#define VIN_GAIN_SMALL_BOUNDARY 7000 // 7 mV = 7,000,000 nV
#define VIN_GAIN_MID1_BOUNDARY1 5000 // 5 mV = 5,000,000 nV
#define VIN_GAIN_MID1_BOUNDARY2 300000 // 300 mV = 300,000,000 nV
#define VIN_GAIN_LARGE_BOUNDARY 250000 // 250 mV = 250,000,000 nV
/*
* skip damping times in Iin channel
* 0 switch to 1 level has 5ms damping
* higher switch to 0 level has 80ms damping
*/
#define CNT_H2L_IIN_VIN_VOUT_PLOT 9 // need skip 9 * 9ms = 81ms notify data
#define CNT_L2H_IIN_VIN_VOUT_PLOT 1 // need skip 1 * 9ms = 9ms notify data
#define CNT_H2L_IIN_VIN_PLOT 14 // 14 * 6ms = 84ms
#define CNT_L2H_IIN_VIN_PLOT 1 // 1 * 6ms = 6ms
#define CNT_H2L_IT_PLOT 27 // 27 * 3ms = 81ms
#define CNT_L2H_IT_PLOT 2 // 2 * 3ms = 6ms
void IinADCGainControl(uint8_t IinADCLevel);
void VinADCGainCtrl(uint8_t VinADCLevel);
void ReadADCIin(uint8_t *buf);
void ReadADCVin(uint8_t *buf);
void ReadADCVout(uint8_t *buf);
void ReadADCBat(uint8_t *buf);
int32_t read_cali_Iin(uint8_t *buf);
int32_t read_cali_Vin(uint8_t *buf);
int32_t read_cali_Vout(uint8_t *buf);
uint16_t AutoGainChangeIin(int32_t RealCurrent, uint16_t plot_type);
void AutoGainChangeVin(int32_t RealVin);
/*=============================================================================
= EliteADC.c =
=============================================================================*/
static void __ADC_write(uint8_t ADCin)
{
/*
* This function can only define [15]~[8] through ADCin
* [7]~[0] should always be 0b11101011
@@ -38,419 +83,515 @@ static void ADC_write(uint8_t ADCin) {
*/
// spi_ADC_txbuf[0] = 0b00000101;
for(int i=0 ; i<SPI_ADC_SIZE ; i++){
for (int i=0; i<SPI_ADC_SIZE; i++) {
spi_ADC_txbuf[i] = 0;
spi_ADC_rxbuf[i] = 0;
}
spi_ADC_txbuf[0] = ADCin;
spi_ADC_txbuf[1] = 0b11101011;
ADC_SPI(2, spi_ADC_txbuf, spi_ADC_rxbuf);
return;
}
static void ADC_read(uint8_t *ADCdata){
for(int i=0 ; i<SPI_ADC_SIZE ; i++){
static void __ADC_read(uint8_t *ADCdata)
{
for (int i=0; i<SPI_ADC_SIZE; i++) {
spi_ADC_txbuf[i] = 0;
spi_ADC_rxbuf[i] = 0;
}
ADC_SPI(2, spi_ADC_txbuf, spi_ADC_rxbuf);
return;
}
/* Elite1.5 Calibration Usage */
static void CAL_ADC_read(uint8_t *ADCdata){
for(int i=0 ; i<SPI_ADC_SIZE ; i++){
spi_ADC_txbuf[i] = 0;
spi_ADC_rxbuf[i] = 0;
}
static void __ADCChannelSelect(uint8_t ADCChannel)
{
/* set ADC parameter
* 0xC1~F1 = reading AIN0~AIN3. Using FSR+-6V, resolution = 187.5uV
* 0xC5~F5 = reading AIN0~AIN3. Using FSR+-2V, resolution = 62.5 uV
*
* ADCChannel == ADC_CH_CURR: - AINp is AIN0; AINn is GND
* - measure AIN0, which is a current measure
* == ADC_CH_VIN: - AINp is AIN1; AINn is GND
* - AIN1, which is a volt measure
* == ADC_CH_VOUT: - AINp is AIN2; AINn is GND
* - AIN2, measure DAC voltage (Note that this is NOT DAC real output value!!)
* == ADC_CH_BAT: - measure battery volt
*
*/
CAL_ADC_SPI(SPI_ADC_SIZE, spi_ADC_txbuf, ADCdata);
}
switch (ADCChannel) {
case ADC_CH_CURR:
__ADC_write(CMD_CURRENT_MEASURE);
break;
static void CAL_ADC_write(uint8_t ADCin) {
for(int i=0 ; i<SPI_ADC_SIZE ; i++){
spi_ADC_txbuf[i] = 0;
spi_ADC_rxbuf[i] = 0;
case ADC_CH_VIN:
__ADC_write(CMD_VOLT_MEASURE);
break;
case ADC_CH_VOUT:
__ADC_write(CMD_DAC_MEASURE);
break;
case ADC_CH_BAT:
__ADC_write(CMD_BATTERY_MEASURE);
break;
default:
break;
}
spi_ADC_txbuf[0] = ADCin;
spi_ADC_txbuf[1] = 0b11101011;
CAL_ADC_SPI(2, spi_ADC_txbuf, spi_ADC_rxbuf);
return;
}
/* Gain Control for Vin & Iin */
static void IinADCGainControl(uint8_t IinADCLevel){
if(IinADCLevel == 0){
static void __reset_i_gain_cnt(int16_t *I_100R_cnt, int16_t *I_3K_cnt, int16_t *I_100K_cnt, int16_t *I_3M_cnt)
{
*I_3M_cnt = 0;
*I_100K_cnt = 0;
*I_3K_cnt = 0;
*I_100R_cnt = 0;
return;
}
static void __switch_lv0(uint8_t gain0_en, uint16_t plot, int16_t *I_GAIN_3M_counter, uint16_t *no_rec_cnt)
{
int16_t *gain_cnt = I_GAIN_3M_counter;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain0_en;
uint16_t pt = plot;
if (gain_en) {
*gain_cnt += 1;
if (*gain_cnt > 2) {
instru.ADCGainLv = I_GAIN_3M;
IinADCGainControl(instru.ADCGainLv);
*gain_cnt = 0;
if (pt == IIN_VIN_VOUT_PLOT) {
*no_rec = CNT_H2L_IIN_VIN_VOUT_PLOT;
} else if (pt == IIN_VIN_PLOT) {
*no_rec = CNT_H2L_IIN_VIN_PLOT;
} else if (pt == IT_PLOT) {
*no_rec = CNT_H2L_IT_PLOT;
}
}
}
return;
}
static void __switch_lv3(uint8_t gain3_en, uint16_t plot, int16_t *I_GAIN_100R_counter, uint16_t *no_rec_cnt)
{
int16_t *gain_cnt = I_GAIN_100R_counter;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain3_en;
if (gain_en) {
*gain_cnt += 1;
if (*gain_cnt > 2) {
instru.ADCGainLv = I_GAIN_100R;
IinADCGainControl(instru.ADCGainLv);
*gain_cnt = 0;
*no_rec = 0;
}
}
return;
}
static void __large_switch_lv1(uint8_t gain1_en, uint16_t plot, int16_t *I_GAIN_100K_counter, uint16_t *no_rec_cnt)
{
int16_t *gain_cnt = I_GAIN_100K_counter;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain1_en;
if (gain_en) {
*gain_cnt += 1;
if (*gain_cnt > 2) {
instru.ADCGainLv = I_GAIN_100K;
IinADCGainControl(instru.ADCGainLv);
*gain_cnt = 0;
*no_rec = 0;
}
}
return;
}
static void __small_switch_lv1(uint8_t gain1_en, uint16_t plot, int16_t *I_GAIN_100K_counter, uint16_t *no_rec_cnt)
{
int16_t *gain_cnt = I_GAIN_100K_counter;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain1_en;
uint16_t pt = plot;
if (gain_en) {
*gain_cnt += 1;
if (*gain_cnt > 2) {
instru.ADCGainLv = I_GAIN_100K;
IinADCGainControl(instru.ADCGainLv);
*gain_cnt = 0;
if (pt == IIN_VIN_VOUT_PLOT) {
*no_rec = CNT_L2H_IIN_VIN_VOUT_PLOT;
} else if (pt == IIN_VIN_PLOT) {
*no_rec = CNT_L2H_IIN_VIN_PLOT;
} else if (pt == IT_PLOT) {
*no_rec = CNT_L2H_IT_PLOT;
}
}
}
return;
}
static void __large_switch_lv2(uint8_t gain2_en, uint16_t plot, int16_t *I_GAIN_3K_counter, uint16_t *no_rec_cnt)
{
int16_t *gain_cnt = I_GAIN_3K_counter;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain2_en;
if (gain_en) {
*gain_cnt += 1;
if (*gain_cnt > 2) {
instru.ADCGainLv = I_GAIN_3K;
IinADCGainControl(instru.ADCGainLv);
*gain_cnt = 0;
*no_rec = 0;
}
}
return;
}
static void __small_switch_lv2(uint8_t gain2_en, uint16_t plot, int16_t *I_GAIN_3K_counter, uint16_t *no_rec_cnt)
{
int16_t *gain_cnt = I_GAIN_3K_counter;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain2_en;
if (gain_en) {
*gain_cnt += 1;
if (*gain_cnt > 2) {
instru.ADCGainLv = I_GAIN_3K;
IinADCGainControl(instru.ADCGainLv);
*gain_cnt = 0;
*no_rec = 0;
}
}
return;
}
void IinADCGainControl(uint8_t IinADCLevel)
{
if (IinADCLevel == 0) {
// ADC gain level = 0, using 3M resister
PIN15_setOutputValue(Turnon_I_LARGE, 0);
PIN15_setOutputValue(Turnon_I_MID, 0);
PIN15_setOutputValue(Turnon_I_SMALL, 0);
}
else if(IinADCLevel == 1){
} else if (IinADCLevel == 1) {
// ADC gain level = 1, using 100K resister
PIN15_setOutputValue(Turnon_I_LARGE, 0);
PIN15_setOutputValue(Turnon_I_MID, 0);
PIN15_setOutputValue(Turnon_I_SMALL, 1);
}
else if(IinADCLevel == 2){
} else if (IinADCLevel == 2) {
// ADC gain level = 2, using 3K resister
PIN15_setOutputValue(Turnon_I_LARGE, 0);
PIN15_setOutputValue(Turnon_I_MID, 1);
PIN15_setOutputValue(Turnon_I_SMALL, 0);
}
else if(IinADCLevel == 3){
} else if (IinADCLevel == 3) {
// ADC gain level = 3, using 100R resistor
PIN15_setOutputValue(Turnon_I_LARGE, 1);
PIN15_setOutputValue(Turnon_I_MID, 0);
PIN15_setOutputValue(Turnon_I_SMALL, 0);
}
else if(IinADCLevel == 4){
} else if (IinADCLevel == 4) {
// ADC gain level = 3, auto gain (using 100R resister)
PIN15_setOutputValue(Turnon_I_LARGE, 1);
PIN15_setOutputValue(Turnon_I_MID, 0);
PIN15_setOutputValue(Turnon_I_SMALL, 0);
}
else{
} else {
// default using 100R resister
PIN15_setOutputValue(Turnon_I_LARGE, 1);
PIN15_setOutputValue(Turnon_I_MID, 0);
PIN15_setOutputValue(Turnon_I_SMALL, 0);
}
if(IinADCLevel == 0 || IinADCLevel == 1 || IinADCLevel == 2 || IinADCLevel == 3){
if (IinADCLevel == 0 || IinADCLevel == 1 || IinADCLevel == 2 || IinADCLevel == 3) {
lastIinADCGainLevel = IinADCLevel;
}else{
} else {
lastIinADCGainLevel = 3;
}
record_flag = false;
curr_rec_en = false;
return;
}
static void VinADCGainCtrl(uint8_t VinADCLevel){
if(VinADCLevel == 0){
void VinADCGainCtrl(uint8_t VinADCLevel)
{
if (VinADCLevel == 0) {
// Vin ADC gain level = 0, using 1M resister
PIN15_setOutputValue(Turnon_V_SMALL, 0);
PIN15_setOutputValue(Turnon_V_MID, 0);
}
else if(VinADCLevel == 1){
} else if (VinADCLevel == 1) {
// Vin ADC gain level = 1, using 30K resister
PIN15_setOutputValue(Turnon_V_SMALL, 0);
PIN15_setOutputValue(Turnon_V_MID, 1);
}
else if(VinADCLevel == 2){
} else if (VinADCLevel == 2) {
// Vin ADC gain level = 2, using 1K resister
PIN15_setOutputValue(Turnon_V_SMALL, 1);
PIN15_setOutputValue(Turnon_V_MID, 0);
}
else if(VinADCLevel == 3){
} else if (VinADCLevel == 3) {
// Vin ADC gain level = 3, auto gain (using 1K resister)
PIN15_setOutputValue(Turnon_V_SMALL, 1);
PIN15_setOutputValue(Turnon_V_MID, 0);
}
else{
} else {
// default using 1K resister
PIN15_setOutputValue(Turnon_V_SMALL, 1);
PIN15_setOutputValue(Turnon_V_MID, 0);
}
if(VinADCLevel == 0 || VinADCLevel == 1 || VinADCLevel == 2){
if (VinADCLevel == 0 || VinADCLevel == 1 || VinADCLevel == 2) {
lastVinADCGainLv = VinADCLevel;
}else{
} else {
lastVinADCGainLv = 2;
}
record_flag = false;
volt_rec_en = false;
return;
}
static void ADCChannelSelect(uint8_t ADCChannel){
// set ADC parameter
// 0xC1~F1 = reading AIN0~AIN3. Using FSR+-6V, resolution = 187.5uV
// 0xC5~F5 = reading AIN0~AIN3. Using FSR+-2V, resolution = 62.5 uV
switch(ADCChannel){
// AINp is AIN0; AINn is GND
// measure AIN0, which is a current measure
case ADC_CH_CURRENT :{
ADC_write(CMD_CURRENT_MEASURE);
break;
}
// AINp is AIN1; AINn is GND
// AIN1, which is a volt measure
case ADC_CH_VOLT :{
ADC_write(CMD_VOLT_MEASURE);
break;
}
// AINp is AIN2; AINn is GND
// AIN2, measure DAC voltage (Note that this is NOT DAC real output value!!)
case ADC_CH_DAC :{
ADC_write(CMD_DAC_MEASURE);
break;
}
// measure battery volt
case ADC_CH_BAT :{
ADC_write(CMD_BATTERY_MEASURE);
break;
}
default :{
break;
}
}
}
static void ReadADCIin(uint8_t *buf){
void ReadADCIin(uint8_t *buf)
{
// Read data twice since the first data we get is previous data
ADCChannelSelect(ADC_CH_CURRENT);
ADC_read(buf);
__ADCChannelSelect(ADC_CH_CURR);
__ADC_read(buf);
ADCChannelSelect(ADC_CH_CURRENT);
ADC_read(buf);
__ADCChannelSelect(ADC_CH_CURR);
__ADC_read(buf);
return;
}
static void ReadADCVin(uint8_t *buf){
void ReadADCVin(uint8_t *buf)
{
// Read data twice since the first data we get is previous data
__ADCChannelSelect(ADC_CH_VIN);
__ADC_read(buf);
ADCChannelSelect(ADC_CH_VOLT);
ADC_read(buf);
__ADCChannelSelect(ADC_CH_VIN);
__ADC_read(buf);
ADCChannelSelect(ADC_CH_VOLT);
ADC_read(buf);
return;
}
static void ReadADCVout(uint8_t *buf){
void ReadADCVout(uint8_t *buf)
{
// Read data twice since the first data we get is previous data
ADCChannelSelect(ADC_CH_DAC);
ADC_read(buf);
__ADCChannelSelect(ADC_CH_VOUT);
__ADC_read(buf);
ADCChannelSelect(ADC_CH_DAC);
ADC_read(buf);
__ADCChannelSelect(ADC_CH_VOUT);
__ADC_read(buf);
return;
}
static void ReadADCBat(uint8_t *buf){
void ReadADCBat(uint8_t *buf)
{
// Read data twice since the first data we get is previous data
ADCChannelSelect(ADC_CH_BAT);
ADC_read(buf);
__ADCChannelSelect(ADC_CH_BAT);
__ADC_read(buf);
ADCChannelSelect(ADC_CH_BAT);
ADC_read(buf);
__ADCChannelSelect(ADC_CH_BAT);
__ADC_read(buf);
return;
}
/* for Elite1.5-re */
// Iin theoretical boundary <2.67, 1.89~80, 63~2600, >1900 (uA)
#define I_GAIN_SMALL_BOUNDARY 4000 // 4 uA = 4,000,000 pA
#define I_GAIN_MID1_BOUNDARY1 2500 // 2.5 uA = 2,500,000 pA
#define I_GAIN_MID1_BOUNDARY2 100000 // 100 uA = 100,000,000 pA
#define I_GAIN_MID2_BOUNDARY1 85000 // 85 uA = 85,000,000 pA
#define I_GAIN_MID2_BOUNDARY2 2050000 // 2050 uA = 2,050,000 nA
#define I_GAIN_LARGE_BOUNDARY 1800000 // 1800 uA = 1,800,000 nA
// Vin theoretical boundary <7, 5~200, >100 (mV)
#define VIN_GAIN_SMALL_BOUNDARY 7000 // 7 mV = 7,000,000 nV
#define VIN_GAIN_MID1_BOUNDARY1 5000 // 5 mV = 5,000,000 nV
#define VIN_GAIN_MID1_BOUNDARY2 300000 // 300 mV = 300,000,000 nV
#define VIN_GAIN_LARGE_BOUNDARY 250000 // 250 mV = 250,000,000 nV
static int32_t read_cali_Iin(uint8_t *buf){
int32_t read_cali_Iin(uint8_t *buf)
{
int32_t RealCurrent = 0;
ReadADCIin(spi_ADC_rxbuf);
RealCurrent = DecodeADCValue(instru.ADCGainLv, ADC_CH_CURRENT, spi_ADC_rxbuf);
RealCurrent = DecodeADCValue(instru.ADCGainLv, ADC_CH_CURR, spi_ADC_rxbuf);
return RealCurrent;
}
static int32_t read_cali_Vin(uint8_t *buf){
int32_t read_cali_Vin(uint8_t *buf)
{
int32_t RealVolt = 0;
ReadADCVin(spi_ADC_rxbuf);
RealVolt = DecodeADCValue(instru.VinADCGainLv, ADC_CH_VOLT, spi_ADC_rxbuf);
RealVolt = DecodeADCValue(instru.VinADCGainLv, ADC_CH_VIN, spi_ADC_rxbuf);
return RealVolt;
}
static int32_t read_cali_Vout(uint8_t *buf){
int32_t read_cali_Vout(uint8_t *buf)
{
int32_t RealVolt = 0;
ReadADCVout(spi_ADC_rxbuf);
RealVolt = DecodeADCValue(0, ADC_CH_DAC, spi_ADC_rxbuf);
RealVolt = DecodeADCValue(0, ADC_CH_VOUT, spi_ADC_rxbuf);
return RealVolt;
}
static void AutoGainChangeIin(int32_t RealCurrent){
// switch to 1 level current(small) 3M
// switch to 2 level current 100K
// switch to 3 level current 3K
// switch to 4 level current(large) 100R
if(instru.ADCGainLv == I_GAIN_100R){
if(RealCurrent < I_GAIN_LARGE_BOUNDARY && RealCurrent > -1*I_GAIN_LARGE_BOUNDARY){
// switch to 1 level current(small)
if (RealCurrent < I_GAIN_MID1_BOUNDARY1 && RealCurrent > -1*I_GAIN_MID1_BOUNDARY1){
I_GAIN_3M_counter++;
if(I_GAIN_3M_counter > 2){
instru.ADCGainLv = I_GAIN_3M;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_3M_counter = 0;
}
}
// switch to 2 level current
else if (RealCurrent < I_GAIN_MID2_BOUNDARY1 && RealCurrent > -1*I_GAIN_MID2_BOUNDARY1){
I_GAIN_100K_counter++;
if(I_GAIN_100K_counter > 2){
instru.ADCGainLv = I_GAIN_100K;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_100K_counter = 0;
}
}
// switch to 3 level current
else{
I_GAIN_3K_counter++;
if(I_GAIN_3K_counter > 2){
instru.ADCGainLv = I_GAIN_3K;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_3K_counter = 0;
}
}
}else{
if(I_GAIN_3K_counter > 0){
I_GAIN_3K_counter--;
}
if(I_GAIN_100K_counter > 0){
I_GAIN_100K_counter--;
}
if(I_GAIN_3M_counter > 0){
I_GAIN_3M_counter--;
}
}
}
else if(instru.ADCGainLv == I_GAIN_3K){
// switch to 4 level current(large)
if(RealCurrent > I_GAIN_MID2_BOUNDARY2 || RealCurrent < -1*I_GAIN_MID2_BOUNDARY2){
I_GAIN_100R_counter++;
if(I_GAIN_100R_counter > 2){
instru.ADCGainLv = I_GAIN_100R;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_100R_counter = 0;
}
}
else if (RealCurrent < I_GAIN_MID2_BOUNDARY1 && RealCurrent > -1*I_GAIN_MID2_BOUNDARY1){
// switch to 1 level current(small)
if(RealCurrent < I_GAIN_MID1_BOUNDARY1 && RealCurrent > -1*I_GAIN_MID1_BOUNDARY1){
I_GAIN_3M_counter++;
if(I_GAIN_3M_counter > 2){
instru.ADCGainLv = I_GAIN_3M;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_3M_counter = 0;
}
}
// switch to 2 level current
else{
I_GAIN_100K_counter++;
if(I_GAIN_100K_counter > 2){
instru.ADCGainLv = I_GAIN_100K;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_100K_counter = 0;
}
}
}else{
if(I_GAIN_100R_counter > 0){
I_GAIN_100R_counter--;
}
if(I_GAIN_100K_counter > 0){
I_GAIN_100K_counter--;
}
if(I_GAIN_3M_counter > 0){
I_GAIN_3M_counter--;
}
}
}
else if(instru.ADCGainLv == I_GAIN_100K){
// switch to 1 level current(small)
if(RealCurrent < I_GAIN_MID1_BOUNDARY1 && RealCurrent > -1*I_GAIN_MID1_BOUNDARY1){
I_GAIN_3M_counter++;
if(I_GAIN_3M_counter > 2){
instru.ADCGainLv = I_GAIN_3M;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_3M_counter = 0;
}
}
else if (RealCurrent > I_GAIN_MID1_BOUNDARY2 || RealCurrent < -1*I_GAIN_MID1_BOUNDARY2){
// switch to 4 level current(large)
if(RealCurrent > I_GAIN_MID2_BOUNDARY2 || RealCurrent < -1*I_GAIN_MID2_BOUNDARY2){
I_GAIN_100R_counter++;
if(I_GAIN_100R_counter > 2){
instru.ADCGainLv = I_GAIN_100R;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_100R_counter = 0;
}
}
// switch to 3 level current
else{
I_GAIN_3K_counter++;
if(I_GAIN_3K_counter > 2){
instru.ADCGainLv = I_GAIN_3K;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_3K_counter = 0;
}
}
}else{
if(I_GAIN_100R_counter > 0){
I_GAIN_100R_counter--;
}
if(I_GAIN_3K_counter > 0){
I_GAIN_3K_counter--;
}
if(I_GAIN_3M_counter > 0){
I_GAIN_3M_counter--;
}
}
}
else if(instru.ADCGainLv == I_GAIN_3M){
if(RealCurrent > I_GAIN_SMALL_BOUNDARY || RealCurrent < -1*I_GAIN_SMALL_BOUNDARY){
// switch to 4 level current(large)
if(RealCurrent > I_GAIN_MID2_BOUNDARY2 || RealCurrent < -1*I_GAIN_MID2_BOUNDARY2){
I_GAIN_100R_counter++;
if(I_GAIN_100R_counter > 2){
instru.ADCGainLv = I_GAIN_100R;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_100R_counter = 0;
}
}
// switch to 3 level current
else if(RealCurrent > I_GAIN_MID1_BOUNDARY2 || RealCurrent < -1*I_GAIN_MID1_BOUNDARY2){
I_GAIN_3K_counter++;
if(I_GAIN_3K_counter > 2){
instru.ADCGainLv = I_GAIN_3K;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_3K_counter = 0;
}
}
// switch to 2 level current
else{
I_GAIN_100K_counter++;
if(I_GAIN_100K_counter > 2){
instru.ADCGainLv = I_GAIN_100K;
IinADCGainControl(instru.ADCGainLv);
I_GAIN_100K_counter = 0;
}
uint16_t AutoGainChangeIin(int32_t RealCurrent, uint16_t plot_type)
{
/*
* instru.ADCGainLv == I_GAIN_100R: 3 level current(large)
* == I_GAIN_3K: 2 level current
* == I_GAIN_100K: 1 level current
* == I_GAIN_3M: 0 level current(small)
*/
int32_t curr = RealCurrent;
uint16_t plot = plot_type;
static uint16_t no_rec_cnt = 0;
static int16_t I_100R_cnt = 0;
static int16_t I_3K_cnt = 0;
static int16_t I_100K_cnt = 0;
static int16_t I_3M_cnt = 0;
int64_t small_gain = I_GAIN_SMALL_BOUNDARY;
int64_t mid1_gain1 = I_GAIN_MID1_BOUNDARY1;
int64_t mid1_gain2 = I_GAIN_MID1_BOUNDARY2;
int64_t mid2_gain1 = I_GAIN_MID2_BOUNDARY1;
int64_t mid2_gain2 = I_GAIN_MID2_BOUNDARY2;
int64_t large_gain = I_GAIN_LARGE_BOUNDARY;
uint8_t gain0_en = (instru.gain_switch_on & 0b10000000) >> 7;
uint8_t gain1_en = (instru.gain_switch_on & 0b01000000) >> 6;
uint8_t gain2_en = (instru.gain_switch_on & 0b00100000) >> 5;
uint8_t gain3_en = (instru.gain_switch_on & 0b00010000) >> 4;
if (instru.ADCGainLv == I_GAIN_100R) {
if (curr < large_gain && curr > -1 * large_gain) {
if (curr < mid1_gain1 && curr > -1 * mid1_gain1) {
__switch_lv0(gain0_en, plot, &I_3M_cnt, &no_rec_cnt);
} else if (curr < mid2_gain1 && curr > -1 * mid2_gain1) {
__large_switch_lv1(gain1_en, plot, &I_100K_cnt, &no_rec_cnt);
} else {
__large_switch_lv2(gain2_en, plot, &I_3K_cnt, &no_rec_cnt);
}
}else{
if(I_GAIN_100R_counter > 0){
I_GAIN_100R_counter--;
}
if(I_GAIN_3K_counter > 0){
I_GAIN_3K_counter--;
}
if(I_GAIN_100K_counter > 0){
I_GAIN_100K_counter--;
}
} else {
__reset_i_gain_cnt(&I_100R_cnt, &I_3K_cnt, &I_100K_cnt, &I_3M_cnt);
}
return no_rec_cnt;
}
if (instru.ADCGainLv == I_GAIN_3K) {
if (curr > mid2_gain2 || curr < -1 * mid2_gain2) {
__switch_lv3(gain3_en, plot, &I_100R_cnt, &no_rec_cnt);
} else if (curr < mid2_gain1 && curr > -1 * mid2_gain1) {
if (curr < mid1_gain1 && curr > -1 * mid1_gain1) {
__switch_lv0(gain0_en, plot, &I_3M_cnt, &no_rec_cnt);
} else {
__large_switch_lv1(gain1_en, plot, &I_100K_cnt, &no_rec_cnt);
}
} else {
__reset_i_gain_cnt(&I_100R_cnt, &I_3K_cnt, &I_100K_cnt, &I_3M_cnt);
}
return no_rec_cnt;
}
if (instru.ADCGainLv == I_GAIN_100K) {
if (curr < mid1_gain1 && curr > -1 * mid1_gain1) {
__switch_lv0(gain0_en, plot, &I_3M_cnt, &no_rec_cnt);
} else if (curr > mid1_gain2 || curr < -1 * mid1_gain2) {
if (curr > mid2_gain2 || curr < -1 * mid2_gain2) {
__switch_lv3(gain3_en, plot, &I_100R_cnt, &no_rec_cnt);
} else {
__large_switch_lv2(gain2_en, plot, &I_3K_cnt, &no_rec_cnt);
}
} else {
__reset_i_gain_cnt(&I_100R_cnt, &I_3K_cnt, &I_100K_cnt, &I_3M_cnt);
}
return no_rec_cnt;
}
if (instru.ADCGainLv == I_GAIN_3M) {
if (curr > small_gain || curr < -1 * small_gain) {
if (curr > mid2_gain2 || curr < -1 * mid2_gain2) {
__switch_lv3(gain3_en, plot, &I_100R_cnt, &no_rec_cnt);
} else if (curr > mid1_gain2 || curr < -1 * mid1_gain2) {
__small_switch_lv2(gain2_en, plot, &I_3K_cnt, &no_rec_cnt);
} else {
__small_switch_lv1(gain1_en, plot, &I_100K_cnt, &no_rec_cnt);
}
} else {
__reset_i_gain_cnt(&I_100R_cnt, &I_3K_cnt, &I_100K_cnt, &I_3M_cnt);
}
return no_rec_cnt;
}
return no_rec_cnt;
}
static void AutoGainChangeVin(int32_t RealVin){
void AutoGainChangeVin(int32_t RealVin){
// switch to 1 level volt(small) 1M
// switch to 2 level volt 30K
// switch to 3 level volt(large) 1K
@@ -73,7 +73,7 @@ static void VoutGainControl(uint8_t VOUTLevel){
// default using 15K resister
PIN15_setOutputValue(Turon_VOUT_SMALL, 1);
}
record_flag = false;
volt_rec_en = false;
}
#endif
@@ -1049,19 +1049,19 @@ static int32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC_
// InputNotify(NOTIFY_VOLT, (uint32_t)(ADC_measure));//
// return real volt to controller
if(ADCChannel == ADC_CH_VOLT){
if(ADCChannel == ADC_CH_VIN){
ADCRealVolt = DecodeADCVolt(ADCGain, ADC_measure);
ret = ADCRealVolt;
}
// return real current to controller
else if(ADCChannel == ADC_CH_CURRENT){
else if(ADCChannel == ADC_CH_CURR){
ADCRealCurrent = DecodeADCCurrent(ADCGain, ADC_measure);
ret = ADCRealCurrent;
}
// return real VoutVolt to controller
else if(ADCChannel == ADC_CH_DAC){
else if(ADCChannel == ADC_CH_VOUT){
ADCVoutVolt = DecodeADCVoutVolt(ADC_measure);
ret = ADCVoutVolt;
}
@@ -1081,6 +1081,7 @@ static int32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC_
// #0 board, (0x5f75 <= rawdata) && (rawdata <= 0x5fb2)
// ((0x5f97 < rawdata) && (rawdata < 0x6589)) || ((0x5999 < rawdata) && (rawdata < 0x5f93))
#if 0
static void ADC_overflow(uint8_t gain, uint8_t *rawdata){
// Gain boundary defines different ADC gain level working area
@@ -1110,6 +1111,7 @@ static void ADC_overflow(uint8_t gain, uint8_t *rawdata){
}
}
}
#endif
// User will enter -5V~+5V in UI.
// websever and controler use 0~50000 represent -5~+5V
@@ -26,7 +26,6 @@ struct HEADSTAGE_INSTRUCTION {
int32_t Vmin;
/** ADC parameter **/
uint8_t notifyRateIndex;
uint32_t sampleRate;
uint8_t VoViSwitch;
uint8_t AutoGainEnable;
@@ -65,30 +64,30 @@ struct HEADSTAGE_INSTRUCTION {
uint16_t StepTime;
uint8_t AdcChannel;
uint8_t gain_switch_on;
} instru = {0};
/** Iin, Vin, Vout **/
#define IIN_ADC 0x00
#define VIN_ADC 0x01
#define VOUT_DAC 0x02
#define HIGH_Z 0x03
#define VOUT_VIN_ADC 0x04
#define RIS_ADC_IIN 0x00
#define RIS_ADC_VIN 0x01
#define RIS_DAC_VOUT 0x02
#define RIS_HIGH_Z 0x03
/** ADC Iin gain level **/
#define I_GAIN_3M 0x00 // largest gain
#define I_GAIN_100K 0x01
#define I_GAIN_3K 0x02
#define I_GAIN_100R 0x03 // the least gain
// ADC Iin gain level !!! move to ADC.h in future
#define I_GAIN_3M 0x00 // lv0,largest gain
#define I_GAIN_100K 0x01 // lv1
#define I_GAIN_3K 0x02 // lv2
#define I_GAIN_100R 0x03 // lv3,the least gain
#define I_GAIN_AUTO 0x04
/** ADC Vin gain level **/
// ADC Vin gain level !!! move to ADC.h in future
#define VIN_GAIN_1M 0x00
#define VIN_GAIN_30K 0x01
#define VIN_GAIN_1K 0x02
#define VIN_GAIN_AUTO 0x03
/** Vout gain level **/
// DAC Vout gain level !!! move to DAC.h in future
#define VOUT_GAIN_240K 0x00
#define VOUT_GAIN_15K 0x01
#define VOUT_GAIN_AUTO 0x02
@@ -124,22 +123,22 @@ static void InitEliteInstruction(){
instru.Vinit = 0;
instru.Vmax = 0;
instru.Vmin = 0;
instru.notifyRateIndex = 100;
instru.sampleRate = 15;
instru.VoViSwitch = 0x01; //0:user see Vo 1: user see Vi
instru.AutoGainEnable = 1;
instru.VinAutoGainEnable = 1;
instru.VoutAutoGainEnable = 1;
instru.ADCGainLv = I_GAIN_AUTO;
instru.ADCGainLv = I_GAIN_AUTO;
instru.VoutGainLevel = VOUT_GAIN_AUTO;
instru.VinADCGainLv = VIN_GAIN_AUTO;
instru.VinADCGainLv = VIN_GAIN_AUTO;
instru.notifyRate = STEPTIME_ONE_SEC;
instru.cycleNumber = 1;
instru.charge = 1; //0:discharge 1:charge
instru.constantCurrent = 0;
instru.Currentmax = 0;
instru.StepTime = STEPTIME_ONE_SEC;
instru.AdcChannel = 0;
instru.AdcChannel = 0; // RIS_ADC_IIN: 0x00, RIS_ADC_VIN: 0x01, RIS_DAC_VOUT: 0x02, RIS_HIGH_Z: 0x03
instru.gain_switch_on = 0b11110000; // cur auto gain switch, |lv0|lv1|lv2|lv3|none|none|none|none|
//pulse mode
instru.sti_t1 = 0;
@@ -172,11 +172,11 @@ static void WorkModeLED()
break;
case CURVE_CALI_ADC:
if (instru.AdcChannel == IIN_ADC) {
if (instru.AdcChannel == RIS_ADC_IIN) {
Elite_led_color(COLOR_RED);
} else if (instru.AdcChannel == VIN_ADC) {
} else if (instru.AdcChannel == RIS_ADC_VIN) {
Elite_led_color(COLOR_ORANGE);
} else if (instru.AdcChannel == VOUT_DAC) {
} else if (instru.AdcChannel == RIS_DAC_VOUT) {
Elite_led_color(COLOR_BLUE);
}
break;
@@ -4,8 +4,6 @@
#ifndef ELITE_WORK_DATA
#define ELITE_WORK_DATA
#define CLOCK_ONE_SECOND 10000
#include "EliteInstruction.h"
/***** Template of Measure and VoltOut parameter *****/
@@ -129,7 +127,7 @@ struct wm_ocp_ctx_t {
struct wm_meas_t measure;
};
int wm_init(void); //(void *instr_ctx);
int wm_init(void);
int wm_deinit(void);
void *wm_get(void);
@@ -526,7 +524,7 @@ int wm_init(void)
default:
// printf("DO NOT support!!");
return -3;
};
}
return 0;
}
@@ -552,20 +550,4 @@ void *wm_get(void)
return wm;
}
/* CC Mode parameter
* @ Measure : measure current value (nA)
* @ Charge : Charge or Discharge
* @ BatteryV : Vin measure battery voltage (mV)
* @ value : constant current setting.
* Current value divide current level into 3,000,001 pieces
* 1,500,000 is zero point; 3,000,000 is 15mA
* Current = (value - 1,500,000)/100,000 mA
* @ Done : Done = false => Ignore Vmin condition;
* Done will be true, if BatteryV <= Vmin last for about 12sec in discharge mode
* @ VMax : voltage upper bound in charge mode
* CC->value will set to zero if BatteryV >= VMax in charge mode
* @ VMin : voltage lower bound in charge mode
* CC->value will set to zero if BatteryV <=> VMin in charge mode
* Note that VMax and VMin are always larger or equal to zero
*/
#endif
@@ -104,4 +104,14 @@ enum all_mode_e {
#define POST_WORK 0x05
#define VALUE_ZERO_TO_ONE(_v) (_v == 0) ? 1 : _v
//plot_type
#define IT_PLOT 1
#define VT_PLOT 2
#define VOUT_PLOT 3
#define IIN_VIN_PLOT 4
#define IIN_VIN_VOUT_PLOT 5
#define CLOCK_ONE_SECOND 10000
#endif
@@ -111,10 +111,12 @@ static void DACenable(uint8_t afterRead){
}
}
static void read_Iin_change_gain(void)
static void read_Iin_change_gain(uint16_t plot_type)
{
uint16_t plot = plot_type;
static uint8_t rec_cnt = 0;
void *wm = wm_get();
uint16_t no_rec_cnt;
if (instru.AutoGainEnable > 1)
return;
@@ -122,19 +124,19 @@ static void read_Iin_change_gain(void)
/* read Iin and do NOT record the Iin after changing gain twice */
MEAS_CURR(wm) = read_cali_Iin(spi_ADC_rxbuf);
if (instru.AutoGainEnable) {
AutoGainChangeIin(MEAS_CURR(wm));
no_rec_cnt = AutoGainChangeIin(MEAS_CURR(wm), plot);
} else {
if (lastIinADCGainLevel != instru.ADCGainLv) {
IinADCGainControl(instru.ADCGainLv);
}
}
if (record_flag == false) {
if (curr_rec_en == false) {
rec_cnt++;
}
if (rec_cnt == 2) {
record_flag = true;
if (rec_cnt >= no_rec_cnt) {
curr_rec_en = true;
rec_cnt = 0;
}
@@ -159,12 +161,12 @@ static void read_Vin_change_gain(void)
}
}
if (record_flag == false) {
if (volt_rec_en == false) {
rec_cnt++;
}
if (rec_cnt == 2) {
record_flag = true;
volt_rec_en = true;
rec_cnt = 0;
}
@@ -179,12 +181,12 @@ static void read_Vout_change_gain(void)
/* read Vout and do NOT record the Vout after changing gain twice */
MEAS_VOUT(wm) = read_cali_Vout(spi_ADC_rxbuf);
if (record_flag == false) {
if (volt_rec_en == false) {
rec_cnt++;
}
if (rec_cnt == 2) {
record_flag = true;
volt_rec_en = true;
rec_cnt = 0;
}
@@ -216,7 +218,7 @@ static void Iin_Vin_Vout_Plot(void)
* 3 - read Iin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
read_Iin_change_gain();
read_Iin_change_gain(IIN_VIN_VOUT_PLOT);
DACenable(AFTER_READ_I);
ReadADCVin(spi_ADC_rxbuf);
ADC_cnt++;
@@ -249,7 +251,7 @@ static void Iin_Vin_Vout_Plot(void)
return;
}
static void CC_Plot(void)
static void Iin_Vin_Plot(void)
{
static uint8_t ADC_cnt = 0;
void *wm = wm_get();
@@ -274,7 +276,7 @@ static void CC_Plot(void)
* 3 - read Iin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
read_Iin_change_gain();
read_Iin_change_gain(IIN_VIN_PLOT);
DACenable(AFTER_READ_I);
ReadADCVin(spi_ADC_rxbuf);
ADC_cnt++;
@@ -318,7 +320,7 @@ static void IT_Plot(void)
* 2 - read Iin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
read_Iin_change_gain();
read_Iin_change_gain(IT_PLOT);
DACenable(AFTER_READ_I);
ReadADCIin(spi_ADC_rxbuf);
ADC_cnt++;
@@ -446,7 +448,7 @@ static void cali_IT_plot(void) {
cali_count_max = 1000;
}
if (record_flag == false) {
if (curr_rec_en == false) {
rec_cnt++;
} else {
if (cali_count >= cali_count_max) {
@@ -477,7 +479,7 @@ static void cali_IT_plot(void) {
}
if (rec_cnt == 2) {
record_flag = true;
curr_rec_en = true;
rec_cnt = 0;
}
ADC_cnt++;
@@ -531,7 +533,7 @@ static void cali_VT_plot(void) {
cali_count_max = 1000;
}
if (record_flag == false) {
if (volt_rec_en == false) {
rec_cnt++;
} else {
if (cali_count >= cali_count_max) {
@@ -562,7 +564,7 @@ static void cali_VT_plot(void) {
}
if (rec_cnt == 2) {
record_flag = true;
volt_rec_en = true;
rec_cnt = 0;
}
ADC_cnt++;
@@ -605,7 +607,7 @@ static void cali_Vout_plot(void) {
ReadADCVout(spi_ADC_rxbuf);
MEAS_VOUT(wm) = (int32_t) (spi_ADC_rxbuf[0] << 8) | (int32_t) (spi_ADC_rxbuf[1]);
if (record_flag == false) {
if (volt_rec_en == false) {
rec_cnt++;
} else {
if (cali_count >= cali_count_max) {
@@ -636,7 +638,7 @@ static void cali_Vout_plot(void) {
}
if (rec_cnt == 2) {
record_flag = true;
volt_rec_en = true;
rec_cnt = 0;
}
ADC_cnt++;
@@ -560,17 +560,14 @@ static bool ADC_flag;
static bool vscan_flag;
static bool notify_flag;
static bool notifyFirst_flag;
static bool record_flag;
static bool volt_rec_en;
static bool curr_rec_en;
static bool vscanReset;
static bool mode_init;
static bool leadTimeReset;
static bool firstTimeReset;
//pulse mode variable
static bool stiFirstTime;
static int16_t I_GAIN_100R_counter;
static int16_t I_GAIN_3K_counter;
static int16_t I_GAIN_100K_counter;
static int16_t I_GAIN_3M_counter;
static int16_t VIN_GAIN_1M_counter;
static int16_t VIN_GAIN_30K_counter;
static int16_t VIN_GAIN_1K_counter;
@@ -624,8 +621,8 @@ static void initDATBuf();
//init parameter
static void InitEliteFlag();
#include "EliteInstruction.h"
#include "EliteADC.h"
#include "EliteInstruction.h"
#include "EliteDAC.h"
#include "EliteSPI.h"
#include "Elite_PIN.h"
@@ -684,13 +681,24 @@ static void update_ZM_instruction(uint8 *ins) {
instru.VsetRate = VsetRateTable[instru.VsetRateIndex];//N
instru.cycleNumber = 1;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
if((instru.Ve1 < DAC_VOUT_GAIN_LARGE_BOUNDARY_USERCODE && instru.Ve1 > DAC_VOUT_GAIN_LARGE_BOUNDARY1_USERCODE)
&& (instru.Ve2 < DAC_VOUT_GAIN_LARGE_BOUNDARY_USERCODE && instru.Ve2 > DAC_VOUT_GAIN_LARGE_BOUNDARY1_USERCODE)){
instru.VoutGainLevel = VOUT_GAIN_15K;
} else {
instru.VoutGainLevel = VOUT_GAIN_240K;
}
ModeLED(WORKING);
break;
}
@@ -711,13 +719,24 @@ static void update_ZM_instruction(uint8 *ins) {
instru.VsetRate = VsetRateTable[instru.VsetRateIndex];//N
instru.cycleNumber = ((uint16_t)(ins[10]) << 8) | (uint16_t)(ins[11]);
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
if((instru.Ve1 < DAC_VOUT_GAIN_LARGE_BOUNDARY_USERCODE && instru.Ve1 > DAC_VOUT_GAIN_LARGE_BOUNDARY1_USERCODE)
&& (instru.Ve2 < DAC_VOUT_GAIN_LARGE_BOUNDARY_USERCODE && instru.Ve2 > DAC_VOUT_GAIN_LARGE_BOUNDARY1_USERCODE)){
instru.VoutGainLevel = VOUT_GAIN_15K;
}else{
instru.VoutGainLevel = VOUT_GAIN_240K;
}
ModeLED(WORKING);
break;
}
@@ -736,6 +755,15 @@ static void update_ZM_instruction(uint8 *ins) {
instru.notifyRate = 10000 / instru.notifyRate * 10;
instru.sampleRate = 15;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
// TODO: input to json
instru.AutoGainEnable = 1;
instru.ADCGainLv = I_GAIN_100R;
@@ -746,7 +774,6 @@ static void update_ZM_instruction(uint8 *ins) {
// end
ModeLED(WORKING);
break;
}
@@ -759,6 +786,15 @@ static void update_ZM_instruction(uint8 *ins) {
instru.Ve1 = 25000 + 5000;
instru.Vinit = (int32_t)instru.Ve1;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
// TODO: input to json
instru.AutoGainEnable = 1;
instru.ADCGainLv = I_GAIN_100R;
@@ -768,13 +804,14 @@ static void update_ZM_instruction(uint8 *ins) {
VinADCGainCtrl(instru.VinADCGainLv);
// end
if(instru.Ve1 < DAC_VOUT_GAIN_LARGE_BOUNDARY_USERCODE && instru.Ve1 > DAC_VOUT_GAIN_LARGE_BOUNDARY1_USERCODE){
instru.VoutGainLevel = VOUT_GAIN_15K;
} else {
instru.VoutGainLevel = VOUT_GAIN_240K;
}
ModeLED(WORKING);
break;
}
@@ -783,6 +820,16 @@ static void update_ZM_instruction(uint8 *ins) {
instru.notifyRate = ((uint32_t)ins[3] << 8) | (uint32_t)ins[4];
instru.notifyRate = 10000 / instru.notifyRate * 10;
instru.sampleRate = 15;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
ModeLED(WORKING);
break;
@@ -793,6 +840,16 @@ static void update_ZM_instruction(uint8 *ins) {
instru.notifyRate = ((uint32_t)ins[3] << 8) | (uint32_t)ins[4];
instru.notifyRate = 10000 / instru.notifyRate * 10;
instru.sampleRate = 15;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
ModeLED(WORKING);
break;
@@ -803,7 +860,18 @@ static void update_ZM_instruction(uint8 *ins) {
instru.notifyRate = ((uint32_t)ins[3] << 8) | (uint32_t)ins[4];
instru.notifyRate = 10000 / instru.notifyRate * 10;
instru.sampleRate = 15;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
ModeLED(WORKING);
break;
}
@@ -818,12 +886,23 @@ static void update_ZM_instruction(uint8 *ins) {
instru.Vmin = (uint32_t)(ins[10]) << 8 | (uint32_t)(ins[11]);
instru.VoutGainLevel = VOUT_GAIN_240K;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
ModeLED(WORKING);
/*******************************************************
controller instruction
ins[3] -> Charge, 0:discharge 1:charge
ins[6:9] -> ConstantCurrent, 0 ~ 15000uA : 0 ~ 1500000
********************************************************/
break;
}
@@ -845,6 +924,15 @@ static void update_ZM_instruction(uint8 *ins) {
instru.Currentmax = (int32_t)(ins[10]) << 24 | (int32_t)(ins[11]) << 16 | (int32_t)(ins[12]) << 8 | (int32_t)(ins[13]);
instru.notifyRate = (uint32_t)(ins[8]) << 8 | (uint32_t)(ins[9]);
instru.notifyRate = 10000 / instru.notifyRate * 10;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
//controller UI 0.01~1000mv send to Elite 1~100000
instru.step = (uint32_t)(ins[4]) << 24 | (uint32_t)(ins[5]) << 16 | (uint32_t)(ins[6]) << 8 | (uint32_t)(ins[7]);
STEP_TO_VSETRATE(instru.step);
@@ -854,6 +942,7 @@ static void update_ZM_instruction(uint8 *ins) {
instru.VoutGainLevel = VOUT_GAIN_240K;
ModeLED(WORKING);
}
break;
}
@@ -876,7 +965,18 @@ static void update_ZM_instruction(uint8 *ins) {
instru.cycleNumber = 1;//ins[17];
instru.VoutGainLevel = VOUT_GAIN_240K;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
ModeLED(WORKING);
break;
}
@@ -889,6 +989,16 @@ static void update_ZM_instruction(uint8 *ins) {
instru.VsetRate = VsetRateTable[0];
instru.VoutGainLevel = VOUT_GAIN_240K;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
ModeLED(WORKING);
break;
}
@@ -896,12 +1006,26 @@ static void update_ZM_instruction(uint8 *ins) {
case SET_SAMPLE_RATE: {
instru.notifyRate = (uint32_t)(ins[3]) << 8 | (uint32_t)(ins[4]);
instru.notifyRate = 10000 / instru.notifyRate * 10;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
// gain_switch_on: [1:4]: none
// [5]: ADC gain level = 4, if value = 1, gain 4 switch on
// [6]: ADC gain level = 3, if value = 1, gain 3 switch on
// [7]: ADC gain level = 2, if value = 1, gain 2 switch on
// [8]: ADC gain level = 1, if value = 1, gain 1 switch on
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
break;
}
case SET_ADC_DAC_GAIN: {
switch(ins[3]){
case IIN_ADC : {
case RIS_ADC_IIN : {
instru.ADCGainLv = ins[4];
if (instru.ADCGainLv != I_GAIN_AUTO) {
instru.AutoGainEnable = 0;
@@ -912,7 +1036,7 @@ static void update_ZM_instruction(uint8 *ins) {
}
break;
}
case VIN_ADC : {
case RIS_ADC_VIN : {
instru.VinADCGainLv = ins[4];
if (instru.VinADCGainLv != VIN_GAIN_AUTO) {
instru.VinAutoGainEnable = 0;
@@ -923,7 +1047,7 @@ static void update_ZM_instruction(uint8 *ins) {
}
break;
}
case VOUT_DAC : {
case RIS_DAC_VOUT : {
// instru.VoutGainLevel = ins[4];
// if(instru.VoutGainLevel == VOUT_GAIN_AUTO){
// instru.VoutGainLevel = VOUT_GAIN_15K;
@@ -932,7 +1056,7 @@ static void update_ZM_instruction(uint8 *ins) {
VoutGainControl(instru.VoutGainLevel);
break;
}
case HIGH_Z : {
case RIS_HIGH_Z : {
switch(ins[4]) {
case 0x00 : {
PIN15_setOutputValue(HIGH_Z_MODE, 0); // 0 => open high_z mode
@@ -955,38 +1079,29 @@ static void update_ZM_instruction(uint8 *ins) {
break;
}
case CURVE_CALI_DAC: {
instru.eliteFxn = CURVE_CALI_DAC;
ModeLED(WORKING);
instru.sampleRate = 15;
PIN15_setOutputValue(HIGH_Z_MODE, 1); // 1 => close high_z mode
instru.VoltConstant = ( ((uint16_t)(ins[3])) << 8) | (uint16_t)(ins[4]);
break;
}
case CURVE_CALI_ADC: {
switch(ins[3]) {
case IIN_ADC : { // 0x00
case RIS_ADC_IIN : { // 0x00
instru.eliteFxn = CURVE_CALI_ADC;
instru.AdcChannel = IIN_ADC;
instru.AdcChannel = RIS_ADC_IIN;
instru.notifyRate = 1000;
instru.sampleRate = 15;
instru.VoViSwitch = 0x01;
ModeLED(WORKING);
break;
}
case VIN_ADC : { // 0x01
case RIS_ADC_VIN : { // 0x01
instru.eliteFxn = CURVE_CALI_ADC;
instru.AdcChannel = VIN_ADC;
instru.AdcChannel = RIS_ADC_VIN;
instru.notifyRate = 1000;
instru.sampleRate = 15;
instru.VoViSwitch = 0x01;
ModeLED(WORKING);
break;
}
case VOUT_DAC : { // 0x02
case RIS_DAC_VOUT : { // 0x02
instru.eliteFxn = CURVE_CALI_ADC;
instru.AdcChannel = VOUT_DAC;
instru.AdcChannel = RIS_DAC_VOUT;
instru.notifyRate = 1000;
instru.sampleRate = 15;
instru.VoViSwitch = 0x00; // 0: read Vout voltage
@@ -1058,21 +1173,6 @@ static void update_ZM_instruction(uint8 *ins) {
break;
}
case 0x02: {
instru.VinADCGainLv = ins[4]; //0:VIN_GAIN_1M, 1:VIN_GAIN_30K, 2:VIN_GAIN_1K, 3:VIN_GAIN_AUTO
if (instru.VinADCGainLv != VIN_GAIN_AUTO) {
instru.VinAutoGainEnable = 0;
VinADCGainCtrl(instru.VinADCGainLv);
} else {
instru.VinAutoGainEnable = 1;
instru.VinADCGainLv = VIN_GAIN_1K;
VinADCGainCtrl(instru.VinADCGainLv);
}
break;
}
}
break;
}
@@ -1153,6 +1253,16 @@ static void update_ZM_instruction(uint8 *ins) {
instru.eliteFxn = CURVE_OCP;
instru.notifyRate = 500;
instru.sampleRate = 15;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
ModeLED(PRE_WORK);
break;
}
@@ -130,14 +130,11 @@ static void SimpleBLEPeripheral_performPeriodicTask(void) {
GPT.VscanRateCounter = instru.VsetRate - 1;
mode_init = false;
batteryADC_flag = false;
record_flag = true;
volt_rec_en = true;
curr_rec_en = true;
firstTimeReset = true;
notifyFirst_flag = true;
first_highz_flag = true;
I_GAIN_100R_counter = 0;
I_GAIN_3K_counter = 0;
I_GAIN_100K_counter = 0;
I_GAIN_3M_counter = 0;
VIN_GAIN_1M_counter = 0;
VIN_GAIN_30K_counter = 0;
VIN_GAIN_1K_counter = 0;
@@ -250,7 +247,8 @@ static void SimpleBLEPeripheral_performPeriodicTask(void) {
GPT.VscanRateCounter = instru.VsetRate - 1;
mode_init = false;
batteryADC_flag = false;
record_flag = true;
volt_rec_en = true;
curr_rec_en = true;
firstTimeReset = true;
notifyFirst_flag = true;
//pulsemode variable
@@ -373,24 +371,33 @@ static void EliteADCControl(void)
case CURVE_IV:
case CURVE_IV_CY:
Iin_Vin_Vout_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VOUT(wm));
}
break;
case CURVE_RT:
Iin_Vin_Vout_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VOUT(wm));
}
break;
case CURVE_CC:
Iin_Vin_Vout_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VIN(wm));
InputNotify(NOTIFY_IMPEDANCE, MEAS_VOUT(wm));
}
@@ -400,8 +407,11 @@ static void EliteADCControl(void)
case CURVE_CA:
case CURVE_LSV:
Iin_Vin_Vout_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VOUT(wm) - MEAS_VIN(wm));
InputNotify(NOTIFY_IMPEDANCE, MEAS_VOUT(wm));
}
@@ -409,8 +419,11 @@ static void EliteADCControl(void)
case CURVE_PULSE:
Iin_Vin_Vout_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VIN(wm));
InputNotify(NOTIFY_IMPEDANCE, MEAS_VOUT(wm));
}
@@ -418,40 +431,44 @@ static void EliteADCControl(void)
case CURVE_IT:
IT_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
break;
case CURVE_VT:
VT_Plot();
if (record_flag) {
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VIN(wm));
}
break;
case CURVE_VO:
Iin_Vin_Vout_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VOUT(wm));
}
break;
case CURVE_OCP:
Iin_Vin_Vout_Plot();
if (record_flag) {
if (curr_rec_en) {
InputNotify(NOTIFY_CURRENT, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_VOLT, MEAS_VOUT(wm) - MEAS_VIN(wm));
}
break;
case CURVE_CALI_ADC:
if (instru.AdcChannel == IIN_ADC) {
if (instru.AdcChannel == RIS_ADC_IIN) {
cali_IT_plot();
} else if (instru.AdcChannel == VIN_ADC) {
} else if (instru.AdcChannel == RIS_ADC_VIN) {
cali_VT_plot();
} else if (instru.AdcChannel == VOUT_DAC) {
} else if (instru.AdcChannel == RIS_DAC_VOUT) {
cali_Vout_plot();
}
break;