Compare commits
189 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0259d3ec61 | |||
| 8bc43f1bb0 | |||
| 50acc23eb1 | |||
| a26bad68a6 | |||
| f5796e8ac5 | |||
| c862e6790f | |||
| fb43ec6ac3 | |||
| e1aa33e6cb | |||
| fb3060a220 | |||
| be40ac25dc | |||
| 5a29b161ac | |||
| caee6602a8 | |||
| 12c4908881 | |||
| cb0b0fafd0 | |||
| 633b3424e1 | |||
| c75a147392 | |||
| 1e71de284c | |||
| 3bfadb0ea5 | |||
| a22a1aa656 | |||
| ac8f1af1cc | |||
| 42b5edd2bf | |||
| cafa70e740 | |||
| 7ecc6063ac | |||
| 1c5e586bd9 | |||
| 9861067a17 | |||
| 295abacf7c | |||
| 6b5dfcc12a | |||
| 8aab5b5aab | |||
| 776e40b639 | |||
| a97909625d | |||
| 259170af20 | |||
| b929433eef | |||
| b166235c21 | |||
| 37ad0160d0 | |||
| d40891396d | |||
| 4f31028d1a | |||
| 8727b7d2eb | |||
| 39e012de64 | |||
| 48e566dea4 | |||
| 3f617786ef | |||
| 080ca80f2b | |||
| 4875bb271a | |||
| b0ac5bb6e6 | |||
| 8b6a402d47 | |||
| aefb2cffbb | |||
| 6934d858fe | |||
| bc28dedc64 | |||
| 92b81cb47f | |||
| e9b5414ab0 | |||
| d3f6a6521a | |||
| 13efb6c32a | |||
| 18e4cac845 | |||
| f6a474e537 | |||
| 311bbdd809 | |||
| e47cf7c3db | |||
| b27718a30f | |||
| be79bec5e0 | |||
| a551eb1143 | |||
| ddc51481b8 | |||
| d8a567c607 | |||
| 776d8074b1 | |||
| e0f937be45 | |||
| 2d7bbb74aa | |||
| 03367a76cf | |||
| 8fffec3116 | |||
| d7210e3b5a | |||
| 82834f30b0 | |||
| 50fbaa5bc7 | |||
| 696f6447dc | |||
| 60734c69b4 | |||
| ddf22de09b | |||
| e169ed1d44 | |||
| 55759938da | |||
| 45de2e6825 | |||
| 4c0e7e2149 | |||
| b63989ca78 | |||
| c2df81dd3b | |||
| 7d6a0ce845 | |||
| 2c9105eb0a | |||
| 0d705b7d28 | |||
| 266e597e19 | |||
| 92d49c1f93 | |||
| c40adb3b64 | |||
| 44e5f54c50 | |||
| c642325859 | |||
| c3adc55aec | |||
| 8700625d69 | |||
| bc4dcfbe7d | |||
| 43170a4282 | |||
| 3652e19a3d | |||
| 36e6a47472 | |||
| c71c55ecf1 | |||
| 57a5b2b4f5 | |||
| 0da311941b | |||
| 7965a4cc1d | |||
| 551f9de36b | |||
| fa8f0202e9 | |||
| ee35c54dec | |||
| 031b98a6d5 | |||
| 82ab990f0b | |||
| 38774d9201 | |||
| 6845963c8b | |||
| 4e4ce66318 | |||
| 6fe44a536f | |||
| 07272963bf | |||
| 80dbc64452 | |||
| 3a8c5d843a | |||
| bf4baa8200 | |||
| bf2b1b9d3e | |||
| 03391b4fb3 | |||
| 9040e85dbb | |||
| 85021a88b0 | |||
| a5df1c227e | |||
| 8213d9fb19 | |||
| 14c424571a | |||
| 8a94a57843 | |||
| a58f787253 | |||
| 6c839b22d9 | |||
| c086de7cf4 | |||
| 3c5f4d9bb4 | |||
| f3037c7959 | |||
| 5a519d5fb5 | |||
| a16543ee57 | |||
| 9d281ce999 | |||
| d97b3ad6b0 | |||
| cad1763981 | |||
| 092c02940d | |||
| 0a19abd0e8 | |||
| 284cfe6d05 | |||
| 3298b6226b | |||
| dfcaf2d908 | |||
| d517318a67 | |||
| d0aa520329 | |||
| 9a875b8459 | |||
| 73ac2f5c90 | |||
| efcb1132de | |||
| 7492ed161d | |||
| ae7ec2e5ce | |||
| 63fde4bdbc | |||
| 32ccb8838f | |||
| 5b6fd53830 | |||
| 86eef98b13 | |||
| 3fdbfcf39f | |||
| 847ea9f3c0 | |||
| 25bd5b5ebe | |||
| 335fe6a9a4 | |||
| 6a0480613c | |||
| 300fb9a44c | |||
| 4fac2aa380 | |||
| d2ab4c1fe8 | |||
| 6048e10ab7 | |||
| 6bd94e3f73 | |||
| fc302d4c75 | |||
| 26a35a1446 | |||
| 8f2eda7281 | |||
| e26a97a32f | |||
| 5bdb0b04da | |||
| 8f8407601e | |||
| 4c6dbcf98d | |||
| 20ccd5de56 | |||
| 3c3ad8ccc7 | |||
| 1030d6625b | |||
| 326f3eb6b6 | |||
| 9dd7228eb5 | |||
| 59ac6b9909 | |||
| e24ce8e5d5 | |||
| 8720300bfc | |||
| 23fc75a236 | |||
| 80c25267cb | |||
| 81d1aff615 | |||
| 3221fe6492 | |||
| 4ca7d5b681 | |||
| 49677aa5b1 | |||
| bbfef99a65 | |||
| 05f11fd147 | |||
| f0aedf786d | |||
| a12146a479 | |||
| 410bef2e23 | |||
| 17c6a506cb | |||
| 0b9c945aee | |||
| 53ef219d6e | |||
| a14b2480db | |||
| 89368d5352 | |||
| f7903a0a31 | |||
| 56f42d21c5 | |||
| 52a8baad08 | |||
| 7acdbf6e78 | |||
| 393394be6f | |||
| b7f305e378 |
BIN
Binary file not shown.
+103
@@ -76,6 +76,11 @@ static void ADCGainControl(uint8_t ADCLevel){
|
||||
PIN_setOutputValue(pin_handle, Turnon10K, 0);
|
||||
PIN_setOutputValue(pin_handle, Turnon100R, 1);
|
||||
}
|
||||
else if(ADCLevel == 3){
|
||||
// ADC gain level = 0, auto gain (using 200R resister)
|
||||
PIN_setOutputValue(pin_handle, Turnon10K, 0);
|
||||
PIN_setOutputValue(pin_handle, Turnon100R, 0);
|
||||
}
|
||||
else{
|
||||
// default using 200R resister
|
||||
PIN_setOutputValue(pin_handle, Turnon10K, 0);
|
||||
@@ -121,4 +126,102 @@ static void ADCChannelSelect(uint8_t ADCChannel){
|
||||
}
|
||||
}
|
||||
|
||||
static void ReadVolt(uint8_t *buf){
|
||||
// Read data twice since the first data we get is previous data
|
||||
ADCChannelSelect(ADC_CH_VOLT);
|
||||
CPUdelay(10);
|
||||
ADC_read(buf);
|
||||
|
||||
ADCChannelSelect(ADC_CH_VOLT);
|
||||
CPUdelay(10);
|
||||
ADC_read(buf);
|
||||
}
|
||||
|
||||
static void ReadCurrent(uint8_t *buf){
|
||||
// Read data twice since the first data we get is previous data
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
ADCChannelSelect(ADC_CH_CURRENT);
|
||||
CPUdelay(10);
|
||||
ADC_read(buf);
|
||||
|
||||
ADCChannelSelect(ADC_CH_CURRENT);
|
||||
CPUdelay(10);
|
||||
ADC_read(buf);
|
||||
}
|
||||
|
||||
// theoretical boundary <20, 10~500, >100 (uA)
|
||||
#define GAIN_SMALL_BOUNDARY 40000 // 40 uA = 40,000,000 pA
|
||||
#define GAIN_MID_BOUNDARY1 20000 // 20 uA = 20,000,000 pA
|
||||
#define GAIN_MID_BOUNDARY2 400000 // 400 uA = 400,000,000 pA
|
||||
#define GAIN_LARGE_BOUNDARY 200000 // 200 uA = 200,000 nA
|
||||
|
||||
static int32_t AutoGainReadCurrent(uint8_t *buf){
|
||||
int32_t Real_Current = 0;
|
||||
|
||||
if(INSTRUCTION.ADCGainLevel == GAIN_AUTO){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
// LED_color(DARKLED, 0x00, 0x00, 0xFF);
|
||||
}
|
||||
|
||||
if(INSTRUCTION.ADCGainLevel == GAIN_200R){
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
|
||||
// switch to mid range current
|
||||
if(Real_Current < GAIN_LARGE_BOUNDARY && Real_Current > -1*GAIN_LARGE_BOUNDARY){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_10K;
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
// LED_color(DARKLED, 0x00, 0xFF, 0x00);
|
||||
|
||||
// // switch to small range current
|
||||
// if (Real_Current < GAIN_MID_BOUNDARY1 && Real_Current > -1*GAIN_MID_BOUNDARY1){
|
||||
// INSTRUCTION.ADCGainLevel = GAIN_200K;
|
||||
// ReadCurrent(spi_ADC_rxbuf);
|
||||
// Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
// LED_color(DARKLED, 0xFF, 0x00, 0x00);
|
||||
// }
|
||||
}
|
||||
}
|
||||
else if(INSTRUCTION.ADCGainLevel == GAIN_10K){
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
|
||||
// switch to large range current
|
||||
if(Real_Current > GAIN_MID_BOUNDARY2 || Real_Current < -1*GAIN_MID_BOUNDARY2){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
// LED_color(DARKLED, 0x00, 0x00, 0xFF);
|
||||
}
|
||||
|
||||
// switch to small range current
|
||||
else if (Real_Current < GAIN_MID_BOUNDARY1 && Real_Current > -1*GAIN_MID_BOUNDARY1){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_200K;
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
// LED_color(DARKLED, 0xFF, 0x00, 0x00);
|
||||
}
|
||||
}
|
||||
else if(INSTRUCTION.ADCGainLevel == GAIN_200K){
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
|
||||
// switch to mid range current
|
||||
if(Real_Current > GAIN_SMALL_BOUNDARY || Real_Current < -1*GAIN_SMALL_BOUNDARY){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_10K;
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
// LED_color(DARKLED, 0x00, 0xFF, 0x00);
|
||||
// switch to large range current
|
||||
// if(Real_Current > GAIN_MID_BOUNDARY2 || Real_Current < -1*GAIN_MID_BOUNDARY2){
|
||||
// INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
// ReadCurrent(spi_ADC_rxbuf);
|
||||
// Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
// }
|
||||
}
|
||||
}
|
||||
return Real_Current;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+175
-280
@@ -2,242 +2,193 @@
|
||||
#ifndef ELITECCMODE
|
||||
#define ELITECCMODE
|
||||
|
||||
#define CURRENT_LV_FOUR 4
|
||||
#define CURRENT_LV_THREE 3
|
||||
#define CURRENT_LV_TWO 2
|
||||
#define CURRENT_LV_ONE 1
|
||||
#define CURRENT_LV_ZERO 0
|
||||
static void CCModeDACControl(int32_t IUC_Measure_Difference);
|
||||
|
||||
/*********************************************************************
|
||||
* @struct Constant Current Code
|
||||
*
|
||||
* @brief A struct to handle CC mode command
|
||||
*/
|
||||
typedef struct _CURRENT_USER_CODE {
|
||||
/** 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
|
||||
uint8_t lv;
|
||||
static int32_t CCModeReadCurrent(CCMode *CC){
|
||||
|
||||
/** current value **/
|
||||
// current value divide current level into 50000 pieces
|
||||
uint16_t value;
|
||||
static uint8_t VoltCurrentSwitch = 0;
|
||||
|
||||
/** transform a current user code (IUC) to real current in pA **/
|
||||
// handle current lv 0~2
|
||||
int32_t (*_Transform2RealpA)(struct _CURRENT_USER_CODE *);
|
||||
CCModeDACEnable = 1; // This flag will control DAC working
|
||||
|
||||
/** transform an IUC to real current in nA **/
|
||||
// handle current lv 3~4
|
||||
int32_t (*_Transform2RealnA)(struct _CURRENT_USER_CODE *);
|
||||
|
||||
/** Measure Current **/
|
||||
int32_t _MeasureCurrent;
|
||||
|
||||
/** MeasureCurrent operation **/
|
||||
void (*SetMeasureCurrent)(struct _CURRENT_USER_CODE *, int32_t);
|
||||
|
||||
int32_t (*GetMeasureCurrent)(struct _CURRENT_USER_CODE *);
|
||||
}CURRENT_USER_CODE;
|
||||
|
||||
//static CURRENT_USER_CODE CurrentUserCode;
|
||||
|
||||
static int32_t CCModeReadCurrent(CURRENT_USER_CODE *CurrentUserCode){
|
||||
int32_t Real_Current = 0;
|
||||
CCModeReset = 0; // This flag will control DAC working
|
||||
|
||||
CCCurrent2IUC(CurrentUserCode);
|
||||
|
||||
// if(CurrentUserCode->lv == CURRENT_LV_FOUR){
|
||||
// Real_Current = CurrentUserCode->_Transform2RealnA(CurrentUserCode);
|
||||
// }
|
||||
// else{
|
||||
// Real_Current = CurrentUserCode->_Transform2RealpA(CurrentUserCode);
|
||||
// }
|
||||
|
||||
// set ADC gain according to constant current value
|
||||
SetCCModeGain(CurrentUserCode);
|
||||
|
||||
// read ADC current
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
ADCChannelSelect(ADC_CH_CURRENT);
|
||||
CPUdelay(10);
|
||||
ADC_read(spi_ADC_rxbuf);
|
||||
// set current value and ADC gain level
|
||||
CCCurrent2IUC(CC);
|
||||
|
||||
// decode ADC value and put it into notify buffer
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
CurrentUserCode->SetMeasureCurrent(CurrentUserCode, Real_Current);
|
||||
|
||||
// Real_Current = CurrentUserCode->_Transform2RealpA(CurrentUserCode);
|
||||
// NotifyVolt[0] = (uint8_t) (Real_Current >> 24);
|
||||
// NotifyVolt[1] = (uint8_t) ((Real_Current & 0x00FF0000) >> 16);
|
||||
// NotifyVolt[2] = (uint8_t) ((Real_Current & 0x0000FF00) >> 8);
|
||||
// NotifyVolt[3] = (uint8_t) (Real_Current & 0x000000FF);
|
||||
// Use 9-th measure value as real-measure value
|
||||
// because some value in the begin are garbage
|
||||
if(VoltCurrentSwitch < 9){
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
VoltCurrentSwitch ++;
|
||||
}
|
||||
else if(VoltCurrentSwitch == 9){
|
||||
// read current
|
||||
if(INSTRUCTION.AutoGainEnable){
|
||||
CC->_MeasureData = AutoGainReadCurrent(spi_ADC_rxbuf);
|
||||
}
|
||||
else{
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
CC->_MeasureData = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
}
|
||||
VoltCurrentSwitch ++;
|
||||
}
|
||||
else if(VoltCurrentSwitch <18){
|
||||
// read volt
|
||||
ReadVolt(spi_ADC_rxbuf);
|
||||
VoltCurrentSwitch++;
|
||||
}
|
||||
else if(VoltCurrentSwitch == 18){
|
||||
// read volt
|
||||
ReadVolt(spi_ADC_rxbuf);
|
||||
CC->BatteryV = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_VOLT, spi_ADC_rxbuf);
|
||||
|
||||
// if Iin connect to battery +, Vout connect to battery -
|
||||
// CC->BatteryV = CC->BatteryV - (CC->value - CC_ZERO_POINT)*10/1e5; // I_set * 10R = V_Iin2GND (mA * ohm)
|
||||
|
||||
// if Iin connect to battery -, Vout connect to battery +
|
||||
CC->BatteryV = CC->BatteryV + (CC->value - CC_ZERO_POINT)*10/1e5; // I_set * 10R = V_Iin2GND (mA * ohm)
|
||||
|
||||
VoltCurrentSwitch++;
|
||||
}
|
||||
else{
|
||||
VoltCurrentSwitch = 0;
|
||||
}
|
||||
|
||||
|
||||
// /** read battery voltage **/
|
||||
// // read ADC volt
|
||||
// ReadVolt(spi_ADC_rxbuf);
|
||||
//
|
||||
// NotifyCurrent[0] = (uint8_t) (Real_Current >> 24);
|
||||
// NotifyCurrent[1] = (uint8_t) ((Real_Current & 0x00FF0000) >> 16);
|
||||
// NotifyCurrent[2] = (uint8_t) ((Real_Current & 0x0000FF00) >> 8);
|
||||
// NotifyCurrent[3] = (uint8_t) (Real_Current & 0x000000FF);
|
||||
return Real_Current;
|
||||
// // decode ADC value and put it into notify buffer
|
||||
// CC->BatteryV = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_VOLT, spi_ADC_rxbuf);
|
||||
//
|
||||
NotifyVolt[0] = (uint8_t) (CC->BatteryV >> 24);
|
||||
NotifyVolt[1] = (uint8_t) ((CC->BatteryV & 0x00FF0000) >> 16);
|
||||
NotifyVolt[2] = (uint8_t) ((CC->BatteryV & 0x0000FF00) >> 8);
|
||||
NotifyVolt[3] = (uint8_t) (CC->BatteryV & 0x000000FF);
|
||||
|
||||
return CC->_MeasureData;
|
||||
}
|
||||
|
||||
static int32_t CCModeVoltOut(CURRENT_USER_CODE *CurrentUserCode){
|
||||
int32_t MeasureCurrent = 0, IUCCurrent = 0;
|
||||
static int32_t CCModeVoltOut(CCMode *CC){
|
||||
int32_t MeasureCurrent = 0, IUCCurrent = 0, ADCRealVolt = 0;
|
||||
|
||||
if(CCModeReset){
|
||||
if(!CCModeDACEnable){
|
||||
// DAC should not work now
|
||||
return 0;
|
||||
}
|
||||
|
||||
IUCCurrent = CurrentUserCode->_Transform2RealpA(CurrentUserCode);
|
||||
MeasureCurrent = CurrentUserCode->GetMeasureCurrent(CurrentUserCode) * 1000;
|
||||
IUCCurrent = CC->_Transform2RealnA(CC);
|
||||
|
||||
if(CurrentUserCode->lv != CURRENT_LV_FOUR && CurrentUserCode->lv != CURRENT_LV_THREE ){
|
||||
// if( IUCCurrent > MeasureCurrent){
|
||||
// INSTRUCTION.VoltConstant = INSTRUCTION.VoltConstant + (IUCCurrent - MeasureCurrent)/1e5;
|
||||
// }
|
||||
// else{
|
||||
// INSTRUCTION.VoltConstant = INSTRUCTION.VoltConstant + (IUCCurrent - MeasureCurrent)/1e5;
|
||||
// }
|
||||
// CCModeDACControl(IUCCurrent - MeasureCurrent);
|
||||
}
|
||||
NotifyVolt[0] = (uint8_t) (IUCCurrent >> 24);
|
||||
NotifyVolt[1] = (uint8_t) ((IUCCurrent & 0x00FF0000) >> 16);
|
||||
NotifyVolt[2] = (uint8_t) ((IUCCurrent & 0x0000FF00) >> 8);
|
||||
NotifyVolt[3] = (uint8_t) (IUCCurrent & 0x000000FF);
|
||||
MeasureCurrent = CC->_MeasureData;
|
||||
CCModeDACControl(IUCCurrent - MeasureCurrent);
|
||||
|
||||
NotifyCurrent[0] = (uint8_t) (IUCCurrent >> 24);
|
||||
NotifyCurrent[1] = (uint8_t) ((IUCCurrent & 0x00FF0000) >> 16);
|
||||
NotifyCurrent[2] = (uint8_t) ((IUCCurrent & 0x0000FF00) >> 8);
|
||||
NotifyCurrent[3] = (uint8_t) (IUCCurrent & 0x000000FF);
|
||||
|
||||
NotifyImpedance[0] = (uint8_t) (MeasureCurrent >> 24);
|
||||
NotifyImpedance[1] = (uint8_t) ((MeasureCurrent & 0x00FF0000) >> 16);
|
||||
NotifyImpedance[2] = (uint8_t) ((MeasureCurrent & 0x0000FF00) >> 8);
|
||||
NotifyImpedance[3] = (uint8_t) (MeasureCurrent & 0x000000FF);
|
||||
|
||||
// DACCode2Real2Notify(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
// if(IUCCurrent > 1000){
|
||||
// ADCRealVolt = 2*(INSTRUCTION.VoltConstant - 25000)/10 - IUCCurrent*200/1e6;
|
||||
// }
|
||||
// else{
|
||||
// CC->BatteryV = 2*(INSTRUCTION.VoltConstant - 25000)/10 - IUCCurrent*200/1e7;
|
||||
// }
|
||||
|
||||
// NotifyVolt[0] = (uint8_t) (CC->BatteryV >> 24);
|
||||
// NotifyVolt[1] = (uint8_t) ((CC->BatteryV & 0x00FF0000) >> 16);
|
||||
// NotifyVolt[2] = (uint8_t) ((CC->BatteryV & 0x0000FF00) >> 8);
|
||||
// NotifyVolt[3] = (uint8_t) (CC->BatteryV & 0x000000FF);
|
||||
|
||||
CCModeDACEnable = 0;
|
||||
return MeasureCurrent;
|
||||
}
|
||||
|
||||
static void CCModeDACControl(int32_t IUC_Measure_Difference){
|
||||
INSTRUCTION.VoltConstant = INSTRUCTION.VoltConstant + IUC_Measure_Difference;
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
int32_t step;
|
||||
if(IUC_Measure_Difference < 100 && IUC_Measure_Difference > -100){
|
||||
step = (IUC_Measure_Difference > 0) ? 1:-1;
|
||||
}
|
||||
// if(INSTRUCTION.ADCGainLevel == GAIN_200R){
|
||||
// LED_color(DARKLED, 0x0F, 0x00, 0x00);
|
||||
// }
|
||||
// else if(INSTRUCTION.ADCGainLevel == GAIN_10K){
|
||||
// LED_color(DARKLED, 0x0F, 0x00, 0x0F);
|
||||
// }
|
||||
// else if(INSTRUCTION.ADCGainLevel == GAIN_200K){
|
||||
// LED_color(DARKLED, 0x0F, 0x02, 0xFF);
|
||||
// }
|
||||
}
|
||||
|
||||
static void CCCurrent2IUC(CURRENT_USER_CODE *CurrentUserCode){
|
||||
if (INSTRUCTION.CurrentLV == CURRENT_LV_MA){
|
||||
// largest current ( 0~500 mA)
|
||||
CurrentUserCode->lv = CURRENT_LV_FOUR;
|
||||
CurrentUserCode->value = (uint16_t) (INSTRUCTION.ConstantCurrent);
|
||||
else if(IUC_Measure_Difference < 1000 && IUC_Measure_Difference > -1000){
|
||||
step = IUC_Measure_Difference / 100;
|
||||
}
|
||||
else if (INSTRUCTION.CurrentLV == CURRENT_LV_UA){
|
||||
if(INSTRUCTION.ConstantCurrent >= 50000){
|
||||
// mid range current ( 500 uA ~ 999 uA)
|
||||
CurrentUserCode->lv = CURRENT_LV_THREE;
|
||||
CurrentUserCode->value = (uint16_t) (INSTRUCTION.ConstantCurrent - 50000);
|
||||
else if(IUC_Measure_Difference < 10000 && IUC_Measure_Difference > -10000){
|
||||
step = IUC_Measure_Difference / 1000;
|
||||
}
|
||||
else{
|
||||
step = IUC_Measure_Difference / 1e4;
|
||||
}
|
||||
|
||||
// over/under flow
|
||||
if( (INSTRUCTION.VoltConstant + step) > MAX_DAC_UC || (INSTRUCTION.VoltConstant + step) < MIN_DAC_UC ){
|
||||
if(step > 0){
|
||||
INSTRUCTION.VoltConstant = (INSTRUCTION.VoltConstant + MAX_DAC_UC)/2;
|
||||
}
|
||||
else{
|
||||
// mid range current ( 0 uA ~ 499 uA)
|
||||
CurrentUserCode->lv = CURRENT_LV_TWO;
|
||||
CurrentUserCode->value = (uint16_t) (INSTRUCTION.ConstantCurrent);
|
||||
INSTRUCTION.VoltConstant = (INSTRUCTION.VoltConstant + MIN_DAC_UC)/2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(INSTRUCTION.ConstantCurrent >= 50000){
|
||||
// mid range current ( 500 nA ~ 999 nA)
|
||||
CurrentUserCode->lv = CURRENT_LV_ONE;
|
||||
CurrentUserCode->value = (uint16_t) (INSTRUCTION.ConstantCurrent - 50000);
|
||||
INSTRUCTION.VoltConstant = INSTRUCTION.VoltConstant + step;
|
||||
}
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
}
|
||||
|
||||
// XXX : should we reset DAC output after STOP?
|
||||
static void CCModeReverseCurrent(CCMode *CC){
|
||||
if(CC->StandBy){
|
||||
if(CT.StandByCounter == CC->StandByTime){
|
||||
CC->StandBy = false;
|
||||
CT.StandByCounter = 0;
|
||||
}
|
||||
else{
|
||||
// mid range current ( 0 nA ~ 499 nA)
|
||||
CurrentUserCode->lv = CURRENT_LV_ZERO;
|
||||
CurrentUserCode->value = (uint16_t) (INSTRUCTION.ConstantCurrent);
|
||||
CT.StandByCounter ++;
|
||||
}
|
||||
}
|
||||
else{
|
||||
// reverse charge/discharge
|
||||
if(CC->BatteryV == CC->VMax){
|
||||
CC->StandBy = true;
|
||||
CC->value = CC->DischargeCurrent;
|
||||
}
|
||||
else if(CC->BatteryV == CC->VMin){
|
||||
CC->StandBy = true;
|
||||
CC->value = CC->ChargeCurrent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static int32_t IUC2RealnA(){
|
||||
//
|
||||
//}
|
||||
//
|
||||
//static int32_t IUC2RealpA{
|
||||
//
|
||||
//}
|
||||
/*********************************************************************
|
||||
* @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
|
||||
/* Transform setting CC into IUC
|
||||
*
|
||||
* User code in CC mode : 0 ~ 3000000
|
||||
* Real current value : -15.00000 ~ 15.00000 mA
|
||||
* => user code = 1500000 mapping to 0.00000 mA
|
||||
*/
|
||||
static void CCCurrent2IUC(CCMode *CC){
|
||||
int32_t CurrentValue = 0;
|
||||
|
||||
// Saturate if current > 500 uA
|
||||
if (self->lv == CURRENT_LV_FOUR){
|
||||
return 0xFFFFFFFF;
|
||||
CC->value = INSTRUCTION.ConstantCurrent;
|
||||
CurrentValue = CC->value - CC_ZERO_POINT;
|
||||
|
||||
/* set ADC level */
|
||||
// largest current
|
||||
if (CurrentValue > 10000 || CurrentValue < -10000){
|
||||
CC->lv = GAIN_200R;
|
||||
}
|
||||
|
||||
if (self->lv == CURRENT_LV_THREE){
|
||||
return 0xFFFFFFFF;
|
||||
// mid range current
|
||||
else if (CurrentValue > 1000 || CurrentValue < -1000){
|
||||
CC->lv = GAIN_10K;
|
||||
}
|
||||
|
||||
// 0-499 nA
|
||||
if (self->lv == CURRENT_LV_ZERO){
|
||||
IUCReal = (int32_t) (self->value) * 10;
|
||||
// least range current
|
||||
else{
|
||||
CC->lv = GAIN_200K;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@@ -249,89 +200,33 @@ static int32_t _Transform2RealpA(CURRENT_USER_CODE *self){
|
||||
*
|
||||
* @return an int32_t current value in nA
|
||||
*/
|
||||
static int32_t _Transform2RealnA(CURRENT_USER_CODE *self){
|
||||
int32_t IUCReal;
|
||||
|
||||
// Saturate if current < 500 uA
|
||||
if (self->lv == CURRENT_LV_ZERO | self->lv == CURRENT_LV_ONE | self->lv == CURRENT_LV_TWO){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 500-999 uA
|
||||
if (self->lv == CURRENT_LV_THREE){
|
||||
IUCReal = (int32_t) (self->value + 50000) * 10;
|
||||
}
|
||||
|
||||
// 0-499 mA
|
||||
else if (self->lv == 4){
|
||||
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 SetMeasureCurrent(CURRENT_USER_CODE *self, int32_t current){
|
||||
self->_MeasureCurrent = current;
|
||||
}
|
||||
|
||||
static int32_t GetMeasureCurrent(CURRENT_USER_CODE *self){
|
||||
int32_t ret;
|
||||
ret = self->_MeasureCurrent;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CURRENT_USER_CODE *InitCurrentUserCode(){
|
||||
CURRENT_USER_CODE *CurrentUserCode = malloc(sizeof(CURRENT_USER_CODE));
|
||||
CurrentUserCode->lv = 0;
|
||||
CurrentUserCode->value = 0;
|
||||
CurrentUserCode-> _MeasureCurrent = 0;
|
||||
CurrentUserCode->_Transform2RealnA = &_Transform2RealnA;
|
||||
CurrentUserCode->_Transform2RealpA = &_Transform2RealpA;
|
||||
CurrentUserCode->SetMeasureCurrent = &SetMeasureCurrent;
|
||||
CurrentUserCode->GetMeasureCurrent = &GetMeasureCurrent;
|
||||
return CurrentUserCode;
|
||||
}
|
||||
|
||||
//static int32_t _Transform2RealnA(CCMode *self){
|
||||
// int32_t IUCReal;
|
||||
//
|
||||
// // self->value : 0 ~ 3000000 (which is -1500000 ~ 1500000 (10nA) )
|
||||
// IUCReal = (self->value - CC_ZERO_POINT) * 10;
|
||||
// return IUCReal;
|
||||
//}
|
||||
//
|
||||
//static void SetMeasureCurrent(CCMode *self, int32_t current){
|
||||
// self->_MeasureCurrent = current;
|
||||
//}
|
||||
//
|
||||
//static int32_t GetMeasureCurrent(CCMode *self){
|
||||
// return self->_MeasureCurrent;
|
||||
//}
|
||||
|
||||
//static CURRENT_USER_CODE *InitCurrentUserCode(){
|
||||
// CCMode *CurrentUserCode = malloc(sizeof(CCMode));
|
||||
// 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-> _MeasureData = 0;
|
||||
// CurrentUserCode->_Transform2RealnA = &_Transform2RealnA;
|
||||
// CurrentUserCode->SetMeasureData = &SetMeasureCurrent;
|
||||
// CurrentUserCode->GetMeasureData = &GetMeasureCurrent;
|
||||
// return CurrentUserCode;
|
||||
//}
|
||||
|
||||
#endif
|
||||
|
||||
+41
-37
@@ -2,7 +2,7 @@
|
||||
#ifndef ELITECV
|
||||
#define ELITECV
|
||||
|
||||
static uint16_t SWVCurve() {
|
||||
static uint16_t SWVCurve(WorkMode *WorkModeData) {
|
||||
static uint8_t counter;
|
||||
static uint16_t outputV;
|
||||
static uint16_t Volt;
|
||||
@@ -57,7 +57,7 @@ static uint16_t SWVCurve() {
|
||||
return outputV;
|
||||
}
|
||||
|
||||
static uint16_t DPVCurve() {
|
||||
static uint16_t DPVCurve(WorkMode *WorkModeData) {
|
||||
static uint8_t counter;
|
||||
static uint16_t Volt1;
|
||||
static uint16_t Volt2;
|
||||
@@ -132,15 +132,15 @@ static uint16_t DPVCurve() {
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t CVCurve() {
|
||||
static uint16_t CVCurve(CVMode *CV) {
|
||||
static uint16_t DACOutCode;
|
||||
static bool direction_up;
|
||||
static bool current_direction_up;
|
||||
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 = INSTRUCTION.VoltOrigin;
|
||||
if (INSTRUCTION.VoltFinal > INSTRUCTION.VoltOrigin) {
|
||||
DACUserCode = CV->_VOrigin;
|
||||
if (INSTRUCTION.VoltFinal > CV->_VOrigin) {
|
||||
direction_up = true;
|
||||
current_direction_up = true;
|
||||
} else {
|
||||
@@ -155,79 +155,83 @@ static uint16_t CVCurve() {
|
||||
return DACOutCode;
|
||||
}
|
||||
|
||||
if (StepTimeCounter == INSTRUCTION.StepTime) {
|
||||
if (CT.StepTimeCounter == CV->_StepTime) {
|
||||
|
||||
//Decide next direction
|
||||
// Decide next direction
|
||||
if (direction_up) {
|
||||
if (DACUserCode >= INSTRUCTION.VoltFinal) {
|
||||
if (DACUserCode >= CV->_VStop) {
|
||||
current_direction_up = false; // problem occurs when origin == 0000 final == ffff!!!!!!
|
||||
} else if (DACUserCode <= INSTRUCTION.VoltOrigin) {
|
||||
} else if (DACUserCode <= CV->_VOrigin) {
|
||||
current_direction_up = true;
|
||||
if (INSTRUCTION.CycleNumber == 0) {
|
||||
if (CV->_CycleNumber == 0) {
|
||||
PeriodicEvent = false; // periodic event end
|
||||
DACReset = true;
|
||||
}
|
||||
INSTRUCTION.CycleNumber--;
|
||||
CV->_CycleNumber--;
|
||||
}
|
||||
} else {
|
||||
if (DACUserCode <= INSTRUCTION.VoltFinal) {
|
||||
if (DACUserCode <= CV->_VStop) {
|
||||
current_direction_up = true; // problem occurs when origin == 0000 final == ffff!!!!!!
|
||||
} else if (DACUserCode >= INSTRUCTION.VoltOrigin) {
|
||||
} else if (DACUserCode >= CV->_VOrigin) {
|
||||
current_direction_up = false;
|
||||
if (INSTRUCTION.CycleNumber == 0) {
|
||||
if (CV->_CycleNumber == 0) {
|
||||
PeriodicEvent = false; // periodic event end
|
||||
DACReset = true;
|
||||
}
|
||||
INSTRUCTION.CycleNumber--;
|
||||
CV->_CycleNumber--;
|
||||
}
|
||||
}
|
||||
|
||||
// Next output voltage
|
||||
if (direction_up) {
|
||||
if (current_direction_up) {
|
||||
if (DACUserCode + INSTRUCTION.Step < DACUserCode) {
|
||||
DACUserCode = 0xffff;
|
||||
// DACUserCode overflow ?
|
||||
if (DACUserCode + CV->_Step < DACUserCode) {
|
||||
DACUserCode = CV->_VStop;
|
||||
}
|
||||
else if (DACUserCode + INSTRUCTION.Step > INSTRUCTION.VoltFinal) {
|
||||
DACUserCode = INSTRUCTION.VoltFinal;
|
||||
else if (DACUserCode + CV->_Step > CV->_VStop) {
|
||||
DACUserCode =CV->_VStop;
|
||||
}
|
||||
else {
|
||||
DACUserCode = DACUserCode + INSTRUCTION.Step;
|
||||
DACUserCode = DACUserCode + CV->_Step;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (DACUserCode - INSTRUCTION.Step > DACUserCode) {
|
||||
DACUserCode = 0x0000;
|
||||
// DACUserCode underflow ?
|
||||
if (DACUserCode - CV->_Step > DACUserCode || DACUserCode > 60000) {
|
||||
DACUserCode = CV->_VOrigin;
|
||||
}
|
||||
else if (DACUserCode + INSTRUCTION.Step < INSTRUCTION.VoltOrigin) {
|
||||
DACUserCode = INSTRUCTION.VoltOrigin;
|
||||
|
||||
// reach Vorigin ?
|
||||
else if (DACUserCode - CV->_Step < CV->_VOrigin) {
|
||||
DACUserCode = CV->_VOrigin;
|
||||
}
|
||||
else {
|
||||
DACUserCode = DACUserCode - INSTRUCTION.Step;
|
||||
DACUserCode = DACUserCode - CV->_Step;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (current_direction_up) {
|
||||
if (DACUserCode + INSTRUCTION.Step < DACUserCode) {
|
||||
DACUserCode = 0xffff;
|
||||
if (DACUserCode + CV->_Step < DACUserCode) {
|
||||
DACUserCode = CV->_VOrigin;
|
||||
}
|
||||
else if (DACUserCode + INSTRUCTION.Step > INSTRUCTION.VoltOrigin) {
|
||||
DACUserCode = INSTRUCTION.VoltOrigin;
|
||||
else if (DACUserCode + CV->_Step > CV->_VOrigin) {
|
||||
DACUserCode = CV->_VOrigin;
|
||||
}
|
||||
else {
|
||||
DACUserCode = DACUserCode + INSTRUCTION.Step;
|
||||
DACUserCode = DACUserCode + CV->_Step;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (DACUserCode - INSTRUCTION.Step > DACUserCode) {
|
||||
DACUserCode = 0x0000; //
|
||||
if (DACUserCode - CV->_Step > DACUserCode || DACUserCode > 60000) {
|
||||
DACUserCode = CV->_VStop ;
|
||||
}
|
||||
else if (DACUserCode + INSTRUCTION.Step < INSTRUCTION.VoltFinal) {
|
||||
DACUserCode = INSTRUCTION.VoltFinal;
|
||||
else if (DACUserCode - CV->_Step < CV->_VStop) {
|
||||
DACUserCode = CV->_VStop;
|
||||
}
|
||||
else {
|
||||
DACUserCode = DACUserCode - INSTRUCTION.Step;
|
||||
DACUserCode = DACUserCode - CV->_Step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -57,4 +57,9 @@ static uint16_t DAC_outputV(uint16_t voltLV) {
|
||||
|
||||
#endif
|
||||
|
||||
static int32_t User2Real(uint16_t UserCode){
|
||||
/* transfer usercode to real voltage value (mV) */
|
||||
return (int32_t) ((UserCode - 25000)*2)/10;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+167
-42
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#define BOARD_KELLY
|
||||
#define BOARD_MERCURY
|
||||
|
||||
typedef struct _formula{
|
||||
|
||||
@@ -141,11 +141,11 @@ struct _correction{
|
||||
.ADC_current[0].coeff = 30022512,
|
||||
.ADC_current[0].offset = -729552647201,
|
||||
|
||||
.ADC_current[1].coeff = 658398533,
|
||||
.ADC_current[1].offset = -16001498741131,
|
||||
.ADC_current[1].coeff = 658398533000,
|
||||
.ADC_current[1].offset = -16001498741131000,
|
||||
|
||||
.ADC_current[2].coeff = 30908351,
|
||||
.ADC_current[2].offset = -746548614824,
|
||||
.ADC_current[2].coeff = 30908351000,
|
||||
.ADC_current[2].offset = -746548614824000,
|
||||
|
||||
.DAC2RealV.coeff = (-19007867),
|
||||
.DAC2RealV.offset = 646316924837,
|
||||
@@ -172,8 +172,8 @@ struct _correction{
|
||||
.ADC_current[1].coeff = 652738209,
|
||||
.ADC_current[1].offset = -15767733896990,
|
||||
|
||||
.ADC_current[2].coeff = 30959456,
|
||||
.ADC_current[2].offset = -748026885843,
|
||||
.ADC_current[2].coeff = 30959456000,
|
||||
.ADC_current[2].offset = -748026885843000,
|
||||
|
||||
.DAC2RealV.coeff = (-18880478),
|
||||
.DAC2RealV.offset = 629012735316,
|
||||
@@ -350,8 +350,8 @@ struct _correction{
|
||||
.ADC_current[1].coeff = 68760643,
|
||||
.ADC_current[1].offset = (-1123221851971),
|
||||
|
||||
.ADC_current[2].coeff = 61882330,
|
||||
.ADC_current[2].offset = (-1010385966159),
|
||||
.ADC_current[2].coeff = 61882330000,
|
||||
.ADC_current[2].offset = (-10103859661590),
|
||||
|
||||
.DAC2RealV.coeff = (-18690126),
|
||||
.DAC2RealV.offset = 564319610294,
|
||||
@@ -462,8 +462,8 @@ struct _correction{
|
||||
.ADC_current[1].coeff = 656423459,
|
||||
.ADC_current[1].offset = (-10660544072862),
|
||||
|
||||
.ADC_current[2].coeff = 31414514,
|
||||
.ADC_current[2].offset = (-510185549182),
|
||||
.ADC_current[2].coeff = 31414514000,
|
||||
.ADC_current[2].offset = (-510185549182000),
|
||||
|
||||
.DAC2RealV.coeff = (-18990774),
|
||||
.DAC2RealV.offset = 570886531263,
|
||||
@@ -479,6 +479,118 @@ struct _correction{
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_EARTH
|
||||
{
|
||||
.ADC_volt.coeff = (-6256660),
|
||||
.ADC_volt.offset = 101658275678,
|
||||
|
||||
.ADC_current[0].coeff = 31271240,
|
||||
.ADC_current[0].offset = (-508496329863),
|
||||
|
||||
.ADC_current[1].coeff = 659931818,
|
||||
.ADC_current[1].offset = (-10729666444387),
|
||||
|
||||
.ADC_current[2].coeff = 31485559000,
|
||||
.ADC_current[2].offset = (-511907957163000),
|
||||
|
||||
.DAC2RealV.coeff = (-19047143),
|
||||
.DAC2RealV.offset = 565935714286,
|
||||
|
||||
.Usercode2DAC.coeff = (-10500262),
|
||||
.Usercode2DAC.offset = 559630236100,
|
||||
|
||||
.Gain0Boundary[0] = 0x5D96,
|
||||
.Gain0Boundary[1] = 0x5DD9,
|
||||
|
||||
.Gain1Boundary[0] = 0x57CD,
|
||||
.Gain1Boundary[1] = 0x639F
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_MARS
|
||||
{
|
||||
.ADC_volt.coeff = (-6270623),
|
||||
.ADC_volt.offset = 102383421553,
|
||||
|
||||
.ADC_current[0].coeff = 31187022,
|
||||
.ADC_current[0].offset = (-509159321195),
|
||||
|
||||
.ADC_current[1].coeff = 655981611,
|
||||
.ADC_current[1].offset = (-10709717111320),
|
||||
|
||||
.ADC_current[2].coeff = 31256968,
|
||||
.ADC_current[2].offset = (-510275213115),
|
||||
|
||||
.DAC2RealV.coeff = (-18937347),
|
||||
.DAC2RealV.offset = 568558163265,
|
||||
|
||||
.Usercode2DAC.coeff = (-10561141),
|
||||
.Usercode2DAC.offset = 564249134291,
|
||||
|
||||
.Gain0Boundary[0] = 0x5D96,
|
||||
.Gain0Boundary[1] = 0x5DD9,
|
||||
|
||||
.Gain1Boundary[0] = 0x57CD,
|
||||
.Gain1Boundary[1] = 0x639F
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_VENUS
|
||||
{
|
||||
.ADC_volt.coeff = (-6268996),
|
||||
.ADC_volt.offset = 102204055818,
|
||||
|
||||
.ADC_current[0].coeff = 31131930,
|
||||
.ADC_current[0].offset = (-507382432547),
|
||||
|
||||
.ADC_current[1].coeff = 654620883,
|
||||
.ADC_current[1].offset = (-10668953588943),
|
||||
|
||||
.ADC_current[2].coeff = 31245260000,
|
||||
.ADC_current[2].offset = (-509181085054000),
|
||||
|
||||
.DAC2RealV.coeff = (-19009388),
|
||||
.DAC2RealV.offset = 567032653061,
|
||||
|
||||
.Usercode2DAC.coeff = (-10521117),
|
||||
.Usercode2DAC.offset = 561308254899,
|
||||
|
||||
.Gain0Boundary[0] = 0x5D96,
|
||||
.Gain0Boundary[1] = 0x5DD9,
|
||||
|
||||
.Gain1Boundary[0] = 0x57CD,
|
||||
.Gain1Boundary[1] = 0x639F
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_MERCURY
|
||||
{
|
||||
.ADC_volt.coeff = (-6259808),
|
||||
.ADC_volt.offset = 102009860128,
|
||||
|
||||
.ADC_current[0].coeff = 31335917,
|
||||
.ADC_current[0].offset = (-511426612252),
|
||||
|
||||
.ADC_current[1].coeff = 658172815,
|
||||
.ADC_current[1].offset = (-10738251896209),
|
||||
|
||||
.ADC_current[2].coeff = 31482687000,
|
||||
.ADC_current[2].offset = (-513650531545000),
|
||||
|
||||
.DAC2RealV.coeff = (-19009388),
|
||||
.DAC2RealV.offset = 567032653061,
|
||||
|
||||
.Usercode2DAC.coeff = (-10548297),
|
||||
.Usercode2DAC.offset = 562611756757,
|
||||
|
||||
.Gain0Boundary[0] = 0x5D96,
|
||||
.Gain0Boundary[1] = 0x5DD9,
|
||||
|
||||
.Gain1Boundary[0] = 0x57CD,
|
||||
.Gain1Boundary[1] = 0x639F
|
||||
};
|
||||
#endif
|
||||
|
||||
// this function turn ADC measure value (0xXXXX) into real voltage
|
||||
// unit should be mV
|
||||
static int32_t DecodeADCVolt(uint16_t ADC_measure){
|
||||
@@ -503,34 +615,35 @@ static int32_t DecodeADCCurrent(uint8_t ADCGain, uint16_t ADC_measure){
|
||||
}
|
||||
|
||||
static int32_t DecodeResister(uint8_t ADCGainLevel, uint16_t CurrentMeasure, uint16_t VoltMeasure){
|
||||
long long ADCRealResister = 0, ADCRealCurrent=0, ADCRealVolt=0;
|
||||
int32_t current_32, volt_32, resister_32;
|
||||
long long ADCRealCurrent=0, ADCRealVolt=0;
|
||||
int32_t resister_32;
|
||||
|
||||
// get measure current
|
||||
ADCRealCurrent = (Correction.ADC_current[ADCGainLevel].coeff * CurrentMeasure + Correction.ADC_current[ADCGainLevel].offset)/1e7;
|
||||
current_32 = (int32_t) (ADCRealCurrent);
|
||||
|
||||
// get measure volt
|
||||
// This step is necessary, if the measure resister !>> 10 ohm
|
||||
ADCRealVolt = (Correction.ADC_volt.coeff * VoltMeasure + Correction.ADC_volt.offset);
|
||||
ADCRealVolt = ADCRealVolt / 1e4;
|
||||
volt_32 = (int32_t) (ADCRealVolt);
|
||||
|
||||
if (INSTRUCTION.ADCGainLevel == GAIN_200R){
|
||||
resister_32 = (int32_t) ((ADCRealVolt) / (ADCRealCurrent/1e3)); // nV / uA = mV
|
||||
}
|
||||
else{
|
||||
resister_32 = (int32_t) ((ADCRealVolt) / (ADCRealCurrent/1e6)); // nV / uA = mV
|
||||
}
|
||||
// NotifyVolt[0] = (uint8_t) (volt_32 >> 24);
|
||||
// NotifyVolt[1] = (uint8_t) ((volt_32 & 0x00FF0000) >> 16);
|
||||
// NotifyVolt[2] = (uint8_t) ((volt_32 & 0x0000FF00) >> 8);
|
||||
// NotifyVolt[3] = (uint8_t) (volt_32 & 0x000000FF);
|
||||
//
|
||||
// NotifyCurrent[0] = (uint8_t) (current_32 >> 24);
|
||||
// NotifyCurrent[1] = (uint8_t) ((current_32 & 0x00FF0000) >> 16);
|
||||
// NotifyCurrent[2] = (uint8_t) ((current_32 & 0x0000FF00) >> 8);
|
||||
// NotifyCurrent[3] = (uint8_t) (current_32 & 0x000000FF);
|
||||
// if (INSTRUCTION.ADCGainLevel == GAIN_200R){
|
||||
resister_32 = (int32_t) ((ADCRealVolt) / (ADCRealCurrent/1e3)); // nV / uA = mV
|
||||
// }
|
||||
// else{
|
||||
// resister_32 = (int32_t) ((ADCRealVolt) / (ADCRealCurrent/1e6)); // nV / uA = mV
|
||||
// }
|
||||
int32_t volt_32 = (int32_t) (ADCRealVolt);
|
||||
int32_t current_32 = (int32_t) (ADCRealCurrent);
|
||||
|
||||
NotifyVolt[0] = (uint8_t) (volt_32 >> 24);
|
||||
NotifyVolt[1] = (uint8_t) ((volt_32 & 0x00FF0000) >> 16);
|
||||
NotifyVolt[2] = (uint8_t) ((volt_32 & 0x0000FF00) >> 8);
|
||||
NotifyVolt[3] = (uint8_t) (volt_32 & 0x000000FF);
|
||||
|
||||
NotifyCurrent[0] = (uint8_t) (current_32 >> 24);
|
||||
NotifyCurrent[1] = (uint8_t) ((current_32 & 0x00FF0000) >> 16);
|
||||
NotifyCurrent[2] = (uint8_t) ((current_32 & 0x0000FF00) >> 8);
|
||||
NotifyCurrent[3] = (uint8_t) (current_32 & 0x000000FF);
|
||||
|
||||
NotifyImpedance[0] = (uint8_t) (resister_32 >> 24);
|
||||
NotifyImpedance[1] = (uint8_t) ((resister_32 & 0x00FF0000) >> 16);
|
||||
@@ -544,15 +657,11 @@ static int32_t DecodeResister(uint8_t ADCGainLevel, uint16_t CurrentMeasure, uin
|
||||
static int32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC_raw){
|
||||
|
||||
uint16_t ADC_measure = (uint16_t) (ADC_raw[0] << 8) | (uint16_t) (ADC_raw[1]);
|
||||
int32_t ADCRealVolt = 0, ret = 0, ADCRealCurrent = 0, ADCRealResister = 0;
|
||||
int32_t ADCRealVolt = 0, ret = 0, ADCRealCurrent = 0;
|
||||
|
||||
// return real volt to controller
|
||||
if(ADCChannel == ADC_CH_VOLT){
|
||||
ADCRealVolt = DecodeADCVolt(ADC_measure);
|
||||
NotifyVolt[0] = (uint8_t) (ADCRealVolt >> 24);
|
||||
NotifyVolt[1] = (uint8_t) ((ADCRealVolt & 0x00FF0000) >> 16);
|
||||
NotifyVolt[2] = (uint8_t) ((ADCRealVolt & 0x0000FF00) >> 8);
|
||||
NotifyVolt[3] = (uint8_t) (ADCRealVolt & 0x000000FF);
|
||||
ret = ADCRealVolt;
|
||||
}
|
||||
|
||||
@@ -562,13 +671,24 @@ static int32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC_
|
||||
if ( (INSTRUCTION.eliteFxn == IV_CURVE) || (INSTRUCTION.eliteFxn == CV_CURVE)) {
|
||||
// wait 0.1 sec until circuit stable => discard first data means wait 0.1 sec
|
||||
if(DiscardIVFirstData){
|
||||
DiscardIVFirstData = 0;
|
||||
return 0;
|
||||
}
|
||||
ADCRealCurrent_long += DecodeADCCurrent(ADCGain, ADC_measure);
|
||||
avg_number++;
|
||||
DiscardIVFirstData ++;
|
||||
DecodeADCCurrent(ADCGain, ADC_measure);
|
||||
ret = DecodeADCCurrent(ADCGain, ADC_measure);
|
||||
|
||||
if (StepTimeCounter == INSTRUCTION.StepTime - 1) {
|
||||
// DiscardIVFirstData :1,2; discard two data
|
||||
// DiscardIVFirstData = 0; recording data
|
||||
if(DiscardIVFirstData == 3){
|
||||
DiscardIVFirstData = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return a real time current (used for deciding auto gain)
|
||||
ret = DecodeADCCurrent(ADCGain, ADC_measure);
|
||||
ADCRealCurrent_long = ADCRealCurrent_long + ret;
|
||||
avg_number ++;
|
||||
|
||||
if (CT.StepTimeCounter == INSTRUCTION.StepTime - 1) {
|
||||
DiscardIVFirstData = 1;
|
||||
ADCRealCurrent_long = ADCRealCurrent_long / avg_number;
|
||||
NotifyCurrent[0] = (uint8_t) (ADCRealCurrent_long >> 24);
|
||||
@@ -577,6 +697,12 @@ static int32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC_
|
||||
NotifyCurrent[3] = (uint8_t) (ADCRealCurrent_long & 0x000000FF);
|
||||
avg_number = 0;
|
||||
ADCRealCurrent_long = 0;
|
||||
|
||||
int32_t G = ADCGain;
|
||||
NotifyImpedance[0] = (uint8_t) (G >> 24);
|
||||
NotifyImpedance[1] = (uint8_t) ((G & 0x00FF0000) >> 16);
|
||||
NotifyImpedance[2] = (uint8_t) ((G & 0x0000FF00) >> 8);
|
||||
NotifyImpedance[3] = (uint8_t) (G & 0x000000FF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,7 +715,6 @@ static int32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC_
|
||||
NotifyCurrent[3] = (uint8_t) (ADCRealCurrent & 0x000000FF);
|
||||
ret = ADCRealCurrent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
#ifndef ELITE_FLAG_CT_INIT
|
||||
#define ELITE_FLAG_CT_INIT
|
||||
|
||||
static void InitCT(){
|
||||
CT.SampleRate_counter = 1;
|
||||
CT.StepTimeCounter = 1;
|
||||
CT.NotifyCounter = 1;
|
||||
CT.StandByCounter = 0;
|
||||
}
|
||||
|
||||
static void InitFlag(){
|
||||
PeriodicEvent = false; // is there an PeriodicEvent?
|
||||
InitPeriodicEvent = true; // need to create a WorkModeData?
|
||||
DACReset = true;
|
||||
CCModeDACEnable = 0; // to make sure DAC work after ADC
|
||||
Free_Work_Mode = true; // Free(WorkModeData)
|
||||
// DiscardIVFirstData = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
+62
-10
@@ -2,22 +2,74 @@
|
||||
#ifndef ELITEIT
|
||||
#define ELITEIT
|
||||
|
||||
static int32_t IT_Plot() {
|
||||
#define absolute(a) ((a<0)? -a:a)
|
||||
|
||||
//static int32_t IT_Plot() {
|
||||
// // read ADC current
|
||||
// int32_t Real_Current = 0;
|
||||
// ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
// ADCChannelSelect(ADC_CH_CURRENT);
|
||||
// CPUdelay(10);
|
||||
// ADC_read(spi_ADC_rxbuf);
|
||||
//
|
||||
// // check if ADC over/under flow
|
||||
// // let the output saturate if over/under flow
|
||||
//// ADC_overflow(INSTRUCTION.ADCGainLevel, spi_ADC_rxbuf);
|
||||
//
|
||||
// // decode ADC value and put it into notify buffer
|
||||
// Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
//
|
||||
// return Real_Current;
|
||||
//}
|
||||
|
||||
static int32_t IT_Plot(WorkMode *WorkModeData) {
|
||||
|
||||
switch (INSTRUCTION.eliteFxn) {
|
||||
case IV_CURVE:{
|
||||
#define CURRENT_MODE WorkModeData->IV
|
||||
break;
|
||||
}
|
||||
case CV_CURVE:{
|
||||
#define CURRENT_MODE WorkModeData->CV
|
||||
break;
|
||||
}
|
||||
case IT_CURVE:{
|
||||
#define CURRENT_MODE WorkModeData->IT
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
#define CURRENT_MODE WorkModeData->IV
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// read ADC current
|
||||
int32_t Real_Current = 0;
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
ADCChannelSelect(ADC_CH_CURRENT);
|
||||
CPUdelay(10);
|
||||
ADC_read(spi_ADC_rxbuf);
|
||||
|
||||
// check if ADC over/under flow
|
||||
// let the output saturate if over/under flow
|
||||
// ADC_overflow(INSTRUCTION.ADCGainLevel, spi_ADC_rxbuf);
|
||||
if(INSTRUCTION.AutoGainEnable){
|
||||
Real_Current = AutoGainReadCurrent(spi_ADC_rxbuf);
|
||||
}
|
||||
else{
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
}
|
||||
|
||||
// IT->SetMeasureData((struct Measure *) IT, Real_Current);
|
||||
// Real_Current = IT->GetMeasureData((struct Measure *) IT);
|
||||
CURRENT_MODE->_MeasureData = Real_Current;
|
||||
|
||||
|
||||
// if(INSTRUCTION.eliteFxn == IV_CURVE){
|
||||
// if(absolute(Real_Current) > CURRENT_MODE->_LimitValue){
|
||||
//// PeriodicEvent = false; //Real current exceed expected limit value, force stop
|
||||
//// DACReset = true;
|
||||
// reset();
|
||||
// }
|
||||
// }
|
||||
|
||||
// decode ADC value and put it into notify buffer
|
||||
Real_Current = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
|
||||
return Real_Current;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+29
-13
@@ -2,7 +2,7 @@
|
||||
#ifndef ELITEIV
|
||||
#define ELITEIV
|
||||
|
||||
static uint16_t VoltScan() {
|
||||
static uint16_t VoltScan(WorkMode *WorkModeData) {
|
||||
uint16_t Voltage;
|
||||
if (INSTRUCTION.VoltOrigin == INSTRUCTION.VoltFinal) {
|
||||
Voltage = Usercode_Correction_to_DAC(INSTRUCTION.VoltOrigin);
|
||||
@@ -10,27 +10,28 @@ static uint16_t VoltScan() {
|
||||
PeriodicEvent = false;
|
||||
return Voltage;
|
||||
} else if (INSTRUCTION.eliteFxn == SQUARE_WAVE_VOLTAMMETRY) {
|
||||
Voltage = SWVCurve();
|
||||
Voltage = SWVCurve(WorkModeData);
|
||||
} else if (INSTRUCTION.eliteFxn == DIFFERENTIAL_PULSE_VOLTAMMETRY) {
|
||||
Voltage = DPVCurve();
|
||||
Voltage = DPVCurve(WorkModeData);
|
||||
} else if (INSTRUCTION.eliteFxn == CV_CURVE) {
|
||||
Voltage = CVCurve();
|
||||
Voltage = CVCurve(WorkModeData->CV);
|
||||
}
|
||||
|
||||
// IV plot mode
|
||||
else {
|
||||
Voltage = OneWayVoltScan();
|
||||
Voltage = OneWayVoltScan(WorkModeData->IV);
|
||||
}
|
||||
|
||||
return Voltage;
|
||||
}
|
||||
|
||||
static uint16_t OneWayVoltScan() {
|
||||
static uint16_t OneWayVoltScan(IVMode *IV) {
|
||||
static uint16_t DACOutCode;
|
||||
|
||||
// reset origin volt at the begin
|
||||
if (DACReset) {
|
||||
DACUserCode = INSTRUCTION.VoltOrigin;
|
||||
// DACUserCode = IV->GetVOrigin((struct VoltOutPara *) IV);
|
||||
DACUserCode = IV->_VOrigin;
|
||||
DACOutCode = Usercode_Correction_to_DAC(DACUserCode);
|
||||
DACReset = false;
|
||||
|
||||
@@ -39,28 +40,43 @@ static uint16_t OneWayVoltScan() {
|
||||
return DACOutCode;
|
||||
}
|
||||
|
||||
if (StepTimeCounter == INSTRUCTION.StepTime) {
|
||||
if (INSTRUCTION.VoltOrigin < INSTRUCTION.VoltFinal) {
|
||||
if (CT.StepTimeCounter == IV->_StepTime){
|
||||
if (IV->_VOrigin < IV->_VStop) {
|
||||
// output the next output volt
|
||||
DACUserCode = DACUserCode + INSTRUCTION.Step;
|
||||
DACUserCode = DACUserCode + IV->_Step;
|
||||
DACOutCode = Usercode_Correction_to_DAC(DACUserCode);
|
||||
DAC_outputV(DACOutCode);
|
||||
|
||||
// end IV task if we reach INSTRUCTION.VoltFinal
|
||||
if (DACUserCode >= INSTRUCTION.VoltFinal) {
|
||||
if (DACUserCode >= IV->_VStop) {
|
||||
PeriodicEvent = false;
|
||||
DACReset = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
DACUserCode = DACUserCode - IV->_Step;
|
||||
|
||||
// check if DACUserCode underflow
|
||||
if(DACUserCode >= 60000){
|
||||
// LED_color(DARKLED, 0xFF, 0x00, 0x00);
|
||||
DACUserCode = IV->_VStop;
|
||||
}
|
||||
|
||||
// int32_t DACUC = DACUserCode;
|
||||
// NotifyImpedance[0] = (uint8_t) (DACUC >> 24);
|
||||
// NotifyImpedance[1] = (uint8_t) ((DACUC & 0x00FF0000) >> 16);
|
||||
// NotifyImpedance[2] = (uint8_t) ((DACUC & 0x0000FF00) >> 8);
|
||||
// NotifyImpedance[3] = (uint8_t) (DACUC & 0x000000FF);
|
||||
|
||||
// output the next output volt
|
||||
DACUserCode = DACUserCode - INSTRUCTION.Step;
|
||||
DACOutCode = Usercode_Correction_to_DAC(DACUserCode);
|
||||
DAC_outputV(DACOutCode);
|
||||
|
||||
// end IV task if we reach INSTRUCTION.VoltFinal
|
||||
if (DACUserCode <= INSTRUCTION.VoltFinal) {
|
||||
if (DACUserCode <= IV->_VStop){
|
||||
PeriodicEvent = false;
|
||||
DACReset = true;
|
||||
// reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-8
@@ -20,6 +20,16 @@
|
||||
#define CURRENT_LV_UA 0x01
|
||||
#define CURRENT_LV_MA 0x02
|
||||
|
||||
/* DAC reset parameter */
|
||||
#define DAC_ZERO 25000
|
||||
#define DAC_POS_MAX 0x0000
|
||||
#define DAC_NEG_MAX 0xFFFF
|
||||
|
||||
// Step time macro
|
||||
#define STEPTIME_HALF_SEC 5000
|
||||
#define STEPTIME_ONE_SEC 10000
|
||||
#define STEPTIME_TWO_SEC 20000
|
||||
|
||||
/*==============================
|
||||
==== headstage instruction ====
|
||||
=============================*/
|
||||
@@ -38,15 +48,20 @@ struct HEADSTAGE_INSTRUCTION {
|
||||
uint16_t VoltFinal;
|
||||
uint16_t Step;
|
||||
uint16_t StepTime;
|
||||
|
||||
// constant volt
|
||||
uint16_t VoltConstant;
|
||||
|
||||
/** ADC parameter **/
|
||||
uint8_t ADCGainLevel;
|
||||
|
||||
uint8_t AutoGainEnable;
|
||||
|
||||
/** Notify parameter **/
|
||||
uint16_t NotifyRate;
|
||||
|
||||
/** Constant Current Parameter **/
|
||||
uint8_t CurrentLV; // nA? uA? mA?
|
||||
uint32_t ConstantCurrent;
|
||||
int32_t ConstantCurrent;
|
||||
|
||||
/** Resister Measure **/
|
||||
uint8_t ResisterMeter;
|
||||
@@ -70,15 +85,16 @@ struct HEADSTAGE_INSTRUCTION {
|
||||
static void InitEliteInstruction(){
|
||||
INSTRUCTION.chip_id = 0;
|
||||
INSTRUCTION.SampleRateIndex = 1;
|
||||
INSTRUCTION.SampleRate = 10;
|
||||
INSTRUCTION.SampleRate = 100;
|
||||
INSTRUCTION.VoltOrigin = DAC_ZERO;
|
||||
INSTRUCTION.VoltFinal = DAC_POS_MAX;
|
||||
INSTRUCTION.VoltFinal = DAC_ZERO;
|
||||
INSTRUCTION.Step = 0x0005; // 0x0005 = 1mV
|
||||
INSTRUCTION.StepTime = STEPTIME_HALF_SEC; // about 0.5 sec
|
||||
INSTRUCTION.VoltConstant = 24999; // is about 0V
|
||||
INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
INSTRUCTION.VoltConstant = DAC_ZERO; // is about 0V
|
||||
INSTRUCTION.ADCGainLevel = GAIN_AUTO;
|
||||
INSTRUCTION.AutoGainEnable = 1;
|
||||
INSTRUCTION.NotifyRate = STEPTIME_ONE_SEC/10;
|
||||
INSTRUCTION.ResisterMeter = RESISTER_METER_LARGE;
|
||||
INSTRUCTION.CurrentLV = 0x00;
|
||||
INSTRUCTION.ConstantCurrent = 0x00000000;
|
||||
INSTRUCTION.eliteFxn = 0; // default is a null event
|
||||
INSTRUCTION.CycleNumber = 0;
|
||||
@@ -97,7 +113,7 @@ static void GetInstructionParameter(uint8 *ins){
|
||||
// CurrentLV=0 => unit is nA
|
||||
// CurrentLV=1 => unit is uA
|
||||
// CurrentLV=2 => unit is mA
|
||||
INSTRUCTION.CurrentLV = (*ins);
|
||||
// INSTRUCTION.CurrentLV = (*ins);
|
||||
|
||||
// ConstantCurrentRange=0 => current value is 0~499
|
||||
// ConstantCurrentRange=1 => current value is 500~999
|
||||
|
||||
+5
-2
@@ -50,14 +50,17 @@ static void WorkModeLED() {
|
||||
break;
|
||||
}
|
||||
case VT_CURVE: {
|
||||
// WORKLED();
|
||||
WORKLED();
|
||||
break;
|
||||
}
|
||||
case IT_CURVE: {
|
||||
WORKLED();
|
||||
break;
|
||||
}
|
||||
|
||||
case CONSTANT_CURRENT:{
|
||||
WORKLED();
|
||||
break;
|
||||
}
|
||||
case VIS_RST: {
|
||||
LEDPowerON();
|
||||
break;
|
||||
|
||||
+17
-23
@@ -3,15 +3,14 @@
|
||||
#define ELITERESET
|
||||
|
||||
static void reset() {
|
||||
PeriodicEvent = false;
|
||||
DACReset = true;
|
||||
CCModeReset = 1;
|
||||
InitEliteInstruction();
|
||||
SampleRate_counter = 1;
|
||||
StepTimeCounter = 1;
|
||||
DiscardIVFirstData = 1;
|
||||
InitFlag();
|
||||
InitCT();
|
||||
|
||||
// IV/CV mode reset
|
||||
DiscardIVFirstData = 0;
|
||||
avg_number = 0;
|
||||
ADCRealCurrent_long = 0;
|
||||
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
|
||||
@@ -50,17 +49,15 @@ static void reset() {
|
||||
}
|
||||
|
||||
static void Eliteinterrupt() {
|
||||
PeriodicEvent = false;
|
||||
DACReset = true;
|
||||
CCModeReset = 1;
|
||||
InitEliteInstruction();
|
||||
StepTimeCounter = 1;
|
||||
SampleRate_counter = 1;
|
||||
DiscardIVFirstData = 1;
|
||||
InitFlag();
|
||||
InitCT();
|
||||
|
||||
// IV/CV mode reset
|
||||
DiscardIVFirstData = 0;
|
||||
avg_number = 0;
|
||||
ADCRealCurrent_long = 0;
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
// ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
// DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
|
||||
LEDPowerON();
|
||||
for (int i = 0; i < BLE_INS_BUFF_SIZE; i++) {
|
||||
@@ -92,13 +89,10 @@ static void Eliteinterrupt() {
|
||||
}
|
||||
|
||||
static void CleanBuffer() {
|
||||
PeriodicEvent = false;
|
||||
DACReset = true;
|
||||
CCModeReset = 1;
|
||||
// InitEliteInstruction();
|
||||
SampleRate_counter = 1;
|
||||
StepTimeCounter = 1;
|
||||
DiscardIVFirstData = 1;
|
||||
InitFlag();
|
||||
InitEliteInstruction();
|
||||
InitCT();
|
||||
DiscardIVFirstData = 0;
|
||||
avg_number = 0;
|
||||
ADCRealCurrent_long = 0;
|
||||
|
||||
|
||||
+9
-5
@@ -2,17 +2,21 @@
|
||||
#ifndef ELITEVT
|
||||
#define ELITEVT
|
||||
|
||||
static void VT_Plot() {
|
||||
static void VT_Plot(VTMode *VT) {
|
||||
// ADC gain is don't care when measuring voltage
|
||||
uint8_t ADCGain = 0;
|
||||
|
||||
// read ADC volt
|
||||
ADCChannelSelect(ADC_CH_VOLT);
|
||||
CPUdelay(10);
|
||||
ADC_read(spi_ADC_rxbuf);
|
||||
ReadVolt(spi_ADC_rxbuf);
|
||||
|
||||
// decode ADC value and put it into notify buffer
|
||||
DecodeADCValue(ADCGain, ADC_CH_VOLT, spi_ADC_rxbuf);
|
||||
VT->SetMeasureData((struct Measure *) VT, DecodeADCValue(ADCGain, ADC_CH_VOLT, spi_ADC_rxbuf));
|
||||
|
||||
int32_t ADCRealVolt = VT->GetMeasureData((struct Measure *) VT);
|
||||
NotifyVolt[0] = (uint8_t) (ADCRealVolt >> 24);
|
||||
NotifyVolt[1] = (uint8_t) ((ADCRealVolt & 0x00FF0000) >> 16);
|
||||
NotifyVolt[2] = (uint8_t) ((ADCRealVolt & 0x0000FF00) >> 8);
|
||||
NotifyVolt[3] = (uint8_t) (ADCRealVolt & 0x000000FF);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+574
@@ -0,0 +1,574 @@
|
||||
/**
|
||||
*
|
||||
* struct WorkMode{
|
||||
* // Measure Only
|
||||
* ITMode;
|
||||
* VTMode;
|
||||
*
|
||||
* // Measure + VoltOut
|
||||
* RTMode;
|
||||
* IVMode;
|
||||
* CVMode;
|
||||
*
|
||||
* // Volt out only
|
||||
* VOutMode
|
||||
* }
|
||||
*
|
||||
* -------------------------------
|
||||
* // Measure Only
|
||||
* struct ITMode{
|
||||
* MeasureData
|
||||
* SetMeasureData()
|
||||
* GetMeasureData()
|
||||
* }
|
||||
*
|
||||
* -------------------------------
|
||||
* // VoltOut parameter
|
||||
* stuct VOutMode{
|
||||
* Vout_UC
|
||||
* VoltOrigin
|
||||
* Vstop;
|
||||
* Step;
|
||||
* StepTime;
|
||||
* CycleNumber;
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ELITE_WORK_DATA
|
||||
#define ELITE_WORK_DATA
|
||||
|
||||
#include "EliteInstruction.h"
|
||||
#define IV_CURVE 0b00010000
|
||||
#define CV_CURVE 0b00100000
|
||||
#define VOLT_OUTPUT 0b00110000
|
||||
#define ZT_CURVE 0b01000000
|
||||
#define VT_CURVE 0b01010000
|
||||
#define IT_CURVE 0b01100000
|
||||
#define SET_SAMPLE_RATE 0b01110000
|
||||
#define SET_ADC_GAIN 0b10000000
|
||||
#define DIFFERENTIAL_PULSE_VOLTAMMETRY 0b10100000
|
||||
#define SQUARE_WAVE_VOLTAMMETRY 0b10110000
|
||||
#define POTENTIAL_STATE 0b11000000
|
||||
#define CONSTANT_CURRENT 0b11010000
|
||||
#define SET_RESISTER_LEVEL 0b11100000
|
||||
|
||||
static bool Free_Work_Mode = false;
|
||||
typedef void (*InitWorkData) ();
|
||||
|
||||
/***** Template of Measure and VoltOut parameter *****/
|
||||
#define MEASURE \
|
||||
int32_t _MeasureData; \
|
||||
void (*SetMeasureData) (struct Measure *, int32_t); \
|
||||
int32_t (*GetMeasureData) (struct Measure *)
|
||||
|
||||
/* VoltOut is an UserCode */
|
||||
/* VOrigin, VStop, Step are all UserCode */
|
||||
#define VOUT_PARA \
|
||||
uint16_t _VoltOut; \
|
||||
uint16_t _VOrigin; \
|
||||
uint16_t _VStop; \
|
||||
uint16_t _Step; \
|
||||
uint16_t _StepTime; \
|
||||
uint16_t _CycleNumber
|
||||
// void (*SetVoltOut) (struct VoltOutPara *, uint16_t); \
|
||||
// uint16_t (*GetVoltOut) (struct VoltOutPara *); \
|
||||
// void (*SetVOrigin) (struct VoltOutPara *, uint16_t); \
|
||||
// uint16_t (*GetVOrigin) (struct VoltOutPara *); \
|
||||
// void (*SetVStop) (struct VoltOutPara *, uint16_t); \
|
||||
// uint16_t (*GetVStop) (struct VoltOutPara *); \
|
||||
// void (*SetStep) (struct VoltOutPara *, uint16_t); \
|
||||
// uint16_t (*GetStep) (struct VoltOutPara *); \
|
||||
// void (*SetStepTime) (struct VoltOutPara *, uint16_t); \
|
||||
// uint16_t (*GetStepTime) (struct VoltOutPara *); \
|
||||
// void (*SetCycleNumber) (struct VoltOutPara *, uint16_t); \
|
||||
// uint16_t (*GetCycleNumber) (struct VoltOutPara *)
|
||||
|
||||
#define LIMIT \
|
||||
uint32_t _LimitValue; \
|
||||
void (*SetLimitValue) (struct Limit *, uint32_t); \
|
||||
uint32_t (*GetLimitValue) (struct Limit*)
|
||||
|
||||
struct Measure{
|
||||
MEASURE;
|
||||
};
|
||||
|
||||
struct VoltOutPara{
|
||||
VOUT_PARA;
|
||||
};
|
||||
|
||||
struct Limit{
|
||||
LIMIT;
|
||||
};
|
||||
/***** End of Measure and VoltOut parameter *****/
|
||||
|
||||
|
||||
/***** Measure Only Mode *****/
|
||||
void _SetMeasureData(struct Measure *self, int32_t Data){
|
||||
self->_MeasureData = Data;
|
||||
}
|
||||
|
||||
int32_t _GetMeasureData(struct Measure *self){
|
||||
return self->_MeasureData;
|
||||
}
|
||||
|
||||
|
||||
/**** Limit Mode ****/
|
||||
//LimitValue
|
||||
void _SetLimitValue(struct Limit *self, uint32_t LimitValue){
|
||||
self->_LimitValue = LimitValue;
|
||||
}
|
||||
uint32_t _GetLimitValue(struct Limit *self){
|
||||
return self->_LimitValue;
|
||||
}
|
||||
|
||||
/* IT Mode Data */
|
||||
typedef struct _ITMode{
|
||||
MEASURE;
|
||||
LIMIT;
|
||||
}ITMode;
|
||||
|
||||
ITMode * InitITMode(){
|
||||
ITMode *ret = malloc(sizeof(ITMode));
|
||||
ret->_MeasureData = 0;
|
||||
ret->SetMeasureData = &_SetMeasureData;
|
||||
ret->GetMeasureData = &_GetMeasureData;
|
||||
|
||||
ret->_LimitValue = 0;
|
||||
|
||||
ret->SetLimitValue = &_SetLimitValue;
|
||||
ret->GetLimitValue = &_GetLimitValue;
|
||||
return ret;
|
||||
}
|
||||
/* End of IT Mode Data */
|
||||
|
||||
/* VT Mode Data */
|
||||
typedef struct _VTMode{
|
||||
MEASURE;
|
||||
}VTMode;
|
||||
|
||||
VTMode * InitVTMode(){
|
||||
VTMode *ret = malloc(sizeof(VTMode));
|
||||
ret->_MeasureData = 0;
|
||||
ret->SetMeasureData = &_SetMeasureData;
|
||||
ret->GetMeasureData = &_GetMeasureData;
|
||||
return ret;
|
||||
}
|
||||
/* End of VT Mode Data */
|
||||
/***** End of Measure Only Mode *****/
|
||||
|
||||
|
||||
/**** VoltOut Only Mode ****/
|
||||
// VoltOut
|
||||
void _SetVoltOut(struct VoltOutPara *self, uint16_t VoltOut){
|
||||
self->_VoltOut = VoltOut;
|
||||
}
|
||||
uint16_t _GetVoltOut(struct VoltOutPara *self){
|
||||
return self->_VoltOut;
|
||||
}
|
||||
|
||||
// VOrigin
|
||||
void _SetVOrigin(struct VoltOutPara *self, uint16_t VOrigin){
|
||||
self->_VOrigin = VOrigin;
|
||||
}
|
||||
uint16_t _GetVOrigin(struct VoltOutPara *self){
|
||||
return self->_VOrigin;
|
||||
}
|
||||
|
||||
// VStop
|
||||
void _SetVStop(struct VoltOutPara *self, uint16_t VStop){
|
||||
self->_VStop = VStop;
|
||||
}
|
||||
uint16_t _GetVStop(struct VoltOutPara *self){
|
||||
return self->_VStop;
|
||||
}
|
||||
|
||||
// Step
|
||||
void _SetStep(struct VoltOutPara *self, uint16_t Step){
|
||||
self->_Step = Step;
|
||||
}
|
||||
uint16_t _GetStep(struct VoltOutPara *self){
|
||||
return self->_Step;
|
||||
}
|
||||
|
||||
// StepTime
|
||||
void _SetStepTime(struct VoltOutPara *self, uint16_t StepTime){
|
||||
self->_StepTime = StepTime;
|
||||
}
|
||||
uint16_t _GetStepTime(struct VoltOutPara *self){
|
||||
return self->_StepTime;
|
||||
}
|
||||
|
||||
// CycleNumber
|
||||
void _SetCycleNumber(struct VoltOutPara *self, uint16_t CycleNumber){
|
||||
self->_CycleNumber = CycleNumber;
|
||||
}
|
||||
uint16_t _GetCycleNumber(struct VoltOutPara *self){
|
||||
return self->_CycleNumber;
|
||||
}
|
||||
|
||||
|
||||
/* VoltOut Mode Data */
|
||||
typedef struct _VoltOutMode{
|
||||
VOUT_PARA;
|
||||
}VoltOutMode;
|
||||
|
||||
VoltOutMode *InitVoltOutMode(){
|
||||
VoltOutMode *ret = malloc(sizeof(VoltOutMode));
|
||||
ret->_VoltOut = INSTRUCTION.VoltConstant; // 25000 is DAC_ZERO
|
||||
ret->_VOrigin = DAC_ZERO;
|
||||
ret->_VStop = DAC_ZERO;
|
||||
ret->_Step = 0;
|
||||
ret->_StepTime = 10000; // STEPTIME_ONE_SEC
|
||||
ret->_CycleNumber = 1;
|
||||
|
||||
// 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;
|
||||
return ret;
|
||||
}
|
||||
/* End of VoltOut Mode Data */
|
||||
/**** End of VoltOut Only Mode ****/
|
||||
|
||||
|
||||
/**** Measure + VoltOut Mode ****/
|
||||
/* IV Mode Data */
|
||||
typedef struct _IVMode{
|
||||
MEASURE;
|
||||
VOUT_PARA;
|
||||
LIMIT;
|
||||
}IVMode;
|
||||
|
||||
IVMode *InitIVMode(){
|
||||
IVMode *ret = malloc(sizeof(IVMode));
|
||||
ret->_MeasureData = 0;
|
||||
ret->SetMeasureData = &_SetMeasureData;
|
||||
ret->GetMeasureData = &_GetMeasureData;
|
||||
|
||||
ret->_VoltOut = DAC_ZERO;
|
||||
ret->_VOrigin = INSTRUCTION.VoltOrigin;
|
||||
ret->_VStop = INSTRUCTION.VoltFinal;
|
||||
ret->_Step = INSTRUCTION.Step;
|
||||
ret->_StepTime = INSTRUCTION.StepTime;
|
||||
ret->_CycleNumber = 1;
|
||||
|
||||
// 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 IV Mode Data */
|
||||
|
||||
/* RT Mode Data */
|
||||
typedef struct _RTMode{
|
||||
MEASURE;
|
||||
VOUT_PARA;
|
||||
}RTMode;
|
||||
|
||||
RTMode * InitRTMode(){
|
||||
RTMode *ret = malloc(sizeof(RTMode));
|
||||
ret->_MeasureData = 0;
|
||||
ret->SetMeasureData = &_SetMeasureData;
|
||||
ret->GetMeasureData = &_GetMeasureData;
|
||||
|
||||
ret->_VoltOut = DAC_ZERO; // 25000 is DAC_ZERO
|
||||
ret->_VOrigin = DAC_ZERO;
|
||||
ret->_VStop = DAC_ZERO;
|
||||
ret->_Step = 0;
|
||||
ret->_StepTime = 10000; // STEPTIME_ONE_SEC
|
||||
ret->_CycleNumber = 1;
|
||||
|
||||
// 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;
|
||||
return ret;
|
||||
}
|
||||
/* End of RT Mode Data */
|
||||
|
||||
/* CV Mode*/
|
||||
typedef struct _CVMode{
|
||||
MEASURE;
|
||||
VOUT_PARA;
|
||||
}CVMode;
|
||||
|
||||
CVMode * InitCVMode(){
|
||||
CVMode *ret = malloc(sizeof(CVMode));
|
||||
ret->_MeasureData = 0;
|
||||
ret->SetMeasureData = &_SetMeasureData;
|
||||
ret->GetMeasureData = &_GetMeasureData;
|
||||
|
||||
ret->_VoltOut = DAC_ZERO; // 25000 is DAC_ZERO
|
||||
ret->_VOrigin = INSTRUCTION.VoltOrigin;
|
||||
ret->_VStop = INSTRUCTION.VoltFinal;
|
||||
ret->_Step = INSTRUCTION.Step;
|
||||
ret->_StepTime = INSTRUCTION.StepTime; // STEPTIME_ONE_SEC
|
||||
ret->_CycleNumber = INSTRUCTION.CycleNumber;
|
||||
|
||||
// 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;
|
||||
return ret;
|
||||
}
|
||||
/*End of CV Mode*/
|
||||
|
||||
/* Const Current Mode */
|
||||
#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
|
||||
|
||||
/*********************************************************************
|
||||
* @struct Constant Current Code
|
||||
*
|
||||
* @brief A struct to handle CC mode command
|
||||
*/
|
||||
typedef struct _CCMode{
|
||||
// measure value
|
||||
MEASURE; // current
|
||||
int32_t BatteryV;
|
||||
|
||||
/** Experience Setting **/
|
||||
/** current value **/
|
||||
// current value divide current level into 3,000,001 pieces
|
||||
// 1,500,000 is zero point
|
||||
int32_t value;
|
||||
|
||||
/** ADC level range: 0-2 **/
|
||||
// constant current value will decide ADC gain level
|
||||
// if |1500000 - value| > 10000 (+-100 uA) => lv = GAIN_200R
|
||||
// else if |1500000 - valule| > 1000 (+-10 uA) => lv = GAIN_10K
|
||||
// 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;
|
||||
|
||||
/* Charge/Discharge Current */
|
||||
int32_t ChargeCurrent;
|
||||
int32_t DischargeCurrent;
|
||||
uint8_t CycleNumber;
|
||||
|
||||
bool StandBy;
|
||||
uint32_t StandByTime;
|
||||
|
||||
/** transform a current user code (IUC) to real current in nA **/
|
||||
int32_t (*_Transform2RealnA)(struct _CCMode *);
|
||||
}CCMode;
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Transform2RealnA
|
||||
*
|
||||
* @brief transform an IUC into real current value in nA.
|
||||
*
|
||||
* @param self, which is an IUC
|
||||
*
|
||||
* @return an int32_t current value in nA
|
||||
*/
|
||||
int32_t _Transform2RealnA(CCMode *self){
|
||||
int32_t IUCReal;
|
||||
|
||||
// self->value : 0 ~ 3000000 (which is -1500000 ~ 1500000 (10nA) )
|
||||
IUCReal = (self->value - CC_ZERO_POINT) * 10;
|
||||
return IUCReal;
|
||||
}
|
||||
|
||||
CCMode * InitCCMode(){
|
||||
CCMode *ret = malloc(sizeof(CCMode));
|
||||
ret->_MeasureData = 0;
|
||||
ret->SetMeasureData = &_SetMeasureData;
|
||||
ret->GetMeasureData = &_GetMeasureData;
|
||||
ret->BatteryV = 0;
|
||||
|
||||
ret->value = CC_ZERO_POINT;
|
||||
ret->lv = INSTRUCTION.ADCGainLevel;
|
||||
ret->VMax = MAX_DAC_UC; // max DAC UserCode
|
||||
ret->VMin = MIN_DAC_UC; // min DAC UserCode
|
||||
ret->ChargeCurrent = 0;
|
||||
ret->DischargeCurrent = 0;
|
||||
ret->CycleNumber = 0;
|
||||
ret->StandBy = false;
|
||||
ret->StandByTime = 0;
|
||||
ret->_Transform2RealnA = &_Transform2RealnA;
|
||||
return ret;
|
||||
}
|
||||
/*End of Const Current Mode Mode*/
|
||||
|
||||
/** Potential State Mode **/
|
||||
typedef struct _PS{
|
||||
// measure
|
||||
MEASURE; // circuit current
|
||||
int32_t ReferenceVolt;
|
||||
|
||||
VOUT_PARA;
|
||||
}PSMode;
|
||||
|
||||
PSMode *InitPSMode(){
|
||||
PSMode *ret = malloc(sizeof(PSMode));
|
||||
ret->_MeasureData = 0;
|
||||
ret->SetMeasureData = &_SetMeasureData;
|
||||
ret->GetMeasureData = &_GetMeasureData;
|
||||
ret->ReferenceVolt = 0;
|
||||
|
||||
ret->_VoltOut = DAC_ZERO; // 25000 is DAC_ZERO
|
||||
ret->_VOrigin = INSTRUCTION.VoltOrigin;
|
||||
ret->_VStop = INSTRUCTION.VoltFinal;
|
||||
ret->_Step = INSTRUCTION.Step;
|
||||
ret->_StepTime = INSTRUCTION.StepTime; // STEPTIME_ONE_SEC
|
||||
ret->_CycleNumber = INSTRUCTION.CycleNumber;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** End of Potential State Mode **/
|
||||
|
||||
typedef union _WorkMode{
|
||||
// Measure only
|
||||
ITMode *IT;
|
||||
VTMode *VT;
|
||||
|
||||
// Output Only
|
||||
VoltOutMode *VO;
|
||||
|
||||
// Measure + Output
|
||||
IVMode *IV;
|
||||
CVMode *CV;
|
||||
RTMode *RT;
|
||||
CCMode *CC;
|
||||
PSMode *PS;
|
||||
}WorkMode;
|
||||
|
||||
WorkMode *CreateWorkMode(){
|
||||
WorkMode *ret = malloc(sizeof(WorkMode));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InitWorkMode(WorkMode *WM){
|
||||
switch(INSTRUCTION.eliteFxn){
|
||||
case IV_CURVE:
|
||||
WM->IV = InitIVMode();
|
||||
break;
|
||||
case CV_CURVE:
|
||||
WM->CV = InitCVMode();
|
||||
break;
|
||||
case VOLT_OUTPUT:
|
||||
WM->VO = InitVoltOutMode();
|
||||
break;
|
||||
case ZT_CURVE:
|
||||
WM->RT = InitRTMode();
|
||||
break;
|
||||
case VT_CURVE:
|
||||
WM->VT = InitVTMode();
|
||||
break;
|
||||
case IT_CURVE:
|
||||
WM->IT = InitITMode();
|
||||
break;
|
||||
case CONSTANT_CURRENT:
|
||||
WM->CC = InitCCMode();
|
||||
break;
|
||||
|
||||
default:
|
||||
WM->VT = InitVTMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FreeWorkMode(WorkMode *WM){
|
||||
switch(INSTRUCTION.eliteFxn){
|
||||
case IV_CURVE:
|
||||
if(WM->IV != NULL){
|
||||
free(WM->IV);
|
||||
WM->IV = NULL;
|
||||
}
|
||||
break;
|
||||
case CV_CURVE:
|
||||
if(WM->CV != NULL){
|
||||
free(WM->CV);
|
||||
WM->CV = NULL;
|
||||
}
|
||||
break;
|
||||
case VOLT_OUTPUT:
|
||||
if(WM->VO != NULL){
|
||||
free(WM->VO);
|
||||
WM->VO = NULL;
|
||||
}
|
||||
break;
|
||||
case ZT_CURVE:
|
||||
if(WM->RT != NULL){
|
||||
free(WM->RT);
|
||||
WM->RT = NULL;
|
||||
}
|
||||
break;
|
||||
case VT_CURVE:
|
||||
if(WM->VT != NULL){
|
||||
free(WM->VT);
|
||||
WM->VT = NULL;
|
||||
}
|
||||
break;
|
||||
case IT_CURVE:
|
||||
if(WM->IT != NULL){
|
||||
free(WM->IT);
|
||||
WM->IT = NULL;
|
||||
}
|
||||
break;
|
||||
case CONSTANT_CURRENT:
|
||||
if(WM->CC != NULL){
|
||||
free(WM->CC);
|
||||
WM->CC = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(WM->IV != NULL){
|
||||
free(WM->IV);
|
||||
WM->IV = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// free(WM);
|
||||
}
|
||||
|
||||
#endif
|
||||
+80
-46
@@ -9,64 +9,98 @@ static void ZT_notify(int32_t impedance);
|
||||
// => calculate the resister
|
||||
// change the output voltage step
|
||||
// => get a R-T curve (with resolution = 1 sample/volt step )
|
||||
static void ZT_Plot() {
|
||||
int32_t Real_Resister = 0;
|
||||
static void ZT_Plot(RTMode *RT) {
|
||||
// int32_t Real_Resister = 0;
|
||||
static uint16_t CurrentMeasure=0, VoltMeasure=0;
|
||||
uint8_t SPICurrent[SPI_ADC_SIZE]={0}, SPIVolt[SPI_ADC_SIZE]={0};
|
||||
static uint8_t VoltCurrentSwitch = 0;
|
||||
|
||||
// set ADC GAIN
|
||||
if(INSTRUCTION.ResisterMeter == RESISTER_METER_LARGE){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
}
|
||||
else if(INSTRUCTION.ResisterMeter == RESISTER_METER_MIDDLE2){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
}
|
||||
else if(INSTRUCTION.ResisterMeter == RESISTER_METER_MIDDLE1){
|
||||
INSTRUCTION.ADCGainLevel = GAIN_10K;
|
||||
int32_t volt_32 = 0;
|
||||
int32_t current_32 = 0;
|
||||
int32_t resister_32 = 0;
|
||||
|
||||
if(INSTRUCTION.AutoGainEnable){
|
||||
current_32 = AutoGainReadCurrent(SPICurrent);
|
||||
}
|
||||
else{
|
||||
INSTRUCTION.ADCGainLevel = GAIN_200K;
|
||||
ReadCurrent(spi_ADC_rxbuf);
|
||||
current_32 = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
}
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
|
||||
|
||||
volt_32 = User2Real(INSTRUCTION.VoltConstant)*1e4;
|
||||
// ReadVolt(SPIVolt);
|
||||
// VoltMeasure = (uint16_t) (SPIVolt[0] << 8) | (uint16_t) (SPIVolt[1]);
|
||||
// volt_32 = DecodeADCVolt(VoltMeasure)*1e4;
|
||||
resister_32 = volt_32 / current_32;
|
||||
|
||||
NotifyVolt[0] = (uint8_t) (volt_32 >> 24);
|
||||
NotifyVolt[1] = (uint8_t) ((volt_32 & 0x00FF0000) >> 16);
|
||||
NotifyVolt[2] = (uint8_t) ((volt_32 & 0x0000FF00) >> 8);
|
||||
NotifyVolt[3] = (uint8_t) (volt_32 & 0x000000FF);
|
||||
|
||||
NotifyCurrent[0] = (uint8_t) (current_32 >> 24);
|
||||
NotifyCurrent[1] = (uint8_t) ((current_32 & 0x00FF0000) >> 16);
|
||||
NotifyCurrent[2] = (uint8_t) ((current_32 & 0x0000FF00) >> 8);
|
||||
NotifyCurrent[3] = (uint8_t) (current_32 & 0x000000FF);
|
||||
|
||||
NotifyImpedance[0] = (uint8_t) (resister_32 >> 24);
|
||||
NotifyImpedance[1] = (uint8_t) ((resister_32 & 0x00FF0000) >> 16);
|
||||
NotifyImpedance[2] = (uint8_t) ((resister_32 & 0x0000FF00) >> 8);
|
||||
NotifyImpedance[3] = (uint8_t) (resister_32 & 0x000000FF);
|
||||
|
||||
// set ADC GAIN
|
||||
// if(INSTRUCTION.ResisterMeter == RESISTER_METER_LARGE){
|
||||
// INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
// }
|
||||
// else if(INSTRUCTION.ResisterMeter == RESISTER_METER_MIDDLE2){
|
||||
// INSTRUCTION.ADCGainLevel = GAIN_200R;
|
||||
// }
|
||||
// else if(INSTRUCTION.ResisterMeter == RESISTER_METER_MIDDLE1){
|
||||
// INSTRUCTION.ADCGainLevel = GAIN_10K;
|
||||
// }
|
||||
// else{
|
||||
// INSTRUCTION.ADCGainLevel = GAIN_200K;
|
||||
// }
|
||||
// ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
|
||||
// Use 9-th measure value as real-measure value
|
||||
// because some value in the begin are garbage
|
||||
if(VoltCurrentSwitch < 9){
|
||||
ADCChannelSelect(ADC_CH_CURRENT);
|
||||
CPUdelay(10);
|
||||
ADC_read(SPICurrent);
|
||||
VoltCurrentSwitch ++;
|
||||
}
|
||||
else if(VoltCurrentSwitch == 9){
|
||||
// read current
|
||||
ADCChannelSelect(ADC_CH_CURRENT);
|
||||
CPUdelay(10);
|
||||
ADC_read(SPICurrent);
|
||||
CurrentMeasure = (uint16_t) (SPICurrent[0] << 8) | (uint16_t) (SPICurrent[1]);
|
||||
VoltCurrentSwitch ++;
|
||||
}
|
||||
else if(VoltCurrentSwitch <18){
|
||||
// read volt
|
||||
ADCChannelSelect(ADC_CH_VOLT);
|
||||
CPUdelay(10);
|
||||
ADC_read(SPIVolt);
|
||||
VoltCurrentSwitch++;
|
||||
}
|
||||
else if(VoltCurrentSwitch == 18){
|
||||
// read volt
|
||||
ADCChannelSelect(ADC_CH_VOLT);
|
||||
CPUdelay(10);
|
||||
ADC_read(SPIVolt);
|
||||
VoltMeasure = (uint16_t) (SPIVolt[0] << 8) | (uint16_t) (SPIVolt[1]);
|
||||
VoltCurrentSwitch++;
|
||||
}
|
||||
else{
|
||||
VoltCurrentSwitch = 0;
|
||||
}
|
||||
// if(VoltCurrentSwitch < 9){
|
||||
// ADCChannelSelect(ADC_CH_CURRENT);
|
||||
// CPUdelay(10);
|
||||
// ADC_read(SPICurrent);
|
||||
// VoltCurrentSwitch ++;
|
||||
// }
|
||||
// else if(VoltCurrentSwitch == 9){
|
||||
// // read current
|
||||
// ADCChannelSelect(ADC_CH_CURRENT);
|
||||
// CPUdelay(10);
|
||||
// ADC_read(SPICurrent);
|
||||
// CurrentMeasure = (uint16_t) (SPICurrent[0] << 8) | (uint16_t) (SPICurrent[1]);
|
||||
// VoltCurrentSwitch ++;
|
||||
// }
|
||||
// else if(VoltCurrentSwitch <18){
|
||||
// // read volt
|
||||
// ADCChannelSelect(ADC_CH_VOLT);
|
||||
// CPUdelay(10);
|
||||
// ADC_read(SPIVolt);
|
||||
// VoltCurrentSwitch++;
|
||||
// }
|
||||
// else if(VoltCurrentSwitch == 18){
|
||||
// // read volt
|
||||
// ADCChannelSelect(ADC_CH_VOLT);
|
||||
// CPUdelay(10);
|
||||
// ADC_read(SPIVolt);
|
||||
// VoltMeasure = (uint16_t) (SPIVolt[0] << 8) | (uint16_t) (SPIVolt[1]);
|
||||
// VoltCurrentSwitch++;
|
||||
// }
|
||||
// else{
|
||||
// VoltCurrentSwitch = 0;
|
||||
// }
|
||||
|
||||
// decode ADC value and put it into notify buffer
|
||||
DecodeResister(INSTRUCTION.ADCGainLevel, CurrentMeasure, VoltMeasure);
|
||||
// DecodeResister(INSTRUCTION.ADCGainLevel, CurrentMeasure, VoltMeasure);
|
||||
// Real_Resister = DecodeADCValue(INSTRUCTION.ADCGainLevel, ADC_CH_CURRENT, spi_ADC_rxbuf);
|
||||
}
|
||||
|
||||
|
||||
+37
-38
@@ -374,11 +374,11 @@ characteristic change event
|
||||
#define HEADSTAGE_H
|
||||
|
||||
// product information
|
||||
#define DEVICE_NAME "Elite-ZMS-v1.4-re"
|
||||
#define DEVICE_NAME "Elite-ZM-v1.4-re"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 2
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 3
|
||||
#define MINOR_VERSION_NUMBER 2
|
||||
|
||||
#define ELITE_VERSION_1_4
|
||||
//#define ELITE_VERSION_1_3
|
||||
@@ -431,6 +431,7 @@ static Clock_Struct periodicClock;
|
||||
#include "simple_gatt_profile.h"
|
||||
|
||||
static bool PeriodicEvent = false;
|
||||
static bool InitPeriodicEvent = true;
|
||||
static ICall_Semaphore semaphore;
|
||||
static uint16_t events;
|
||||
|
||||
@@ -601,33 +602,20 @@ static void set_update_instruction_callback(update_instruction_callback_type cal
|
||||
static uint16_t DAC_outputV(uint16_t voltLV);
|
||||
static int32_t DAC_to_realV(uint16_t DACcode);
|
||||
|
||||
/* DAC reset parameter */
|
||||
#define DAC_ZERO 0x85B2
|
||||
#define DAC_POS_MAX 0x0000
|
||||
#define DAC_NEG_MAX 0xFFFF
|
||||
static uint16_t DACUserCode = 0x0000;
|
||||
|
||||
static uint32_t SampleRateTable[6] = {100, 1000, 10000, 50000, 100000, 1000000}; // 1 =>100 Hz, 10000=>0.01 Hz
|
||||
static uint32_t SampleRate_counter = 1;
|
||||
|
||||
// record value for IV curve to calculate average current
|
||||
static uint8_t DiscardIVFirstData = 1;
|
||||
static uint16_t avg_number = 0;
|
||||
static long long ADCRealCurrent_long = 0;
|
||||
|
||||
// Step time macro
|
||||
#define STEPTIME_HALF_SEC 5000
|
||||
#define STEPTIME_ONE_SEC 10000
|
||||
#define STEPTIME_TWO_SEC 20000
|
||||
|
||||
// Constant Current Mode function
|
||||
static uint8_t CCModeReset = 1;
|
||||
static uint8_t CCModeDACEnable = 0;
|
||||
static int32_t CCModeReadCurrent();
|
||||
static int32_t CCModeVoltOut();
|
||||
static void SetCCModeGain();
|
||||
static void CCCurrent2IUC();
|
||||
static int32_t IUC2RealnA();
|
||||
static int32_t IUC2RealpA();
|
||||
|
||||
// for DPVCurve SWVCurve
|
||||
static uint16_t Amplitude;
|
||||
@@ -636,16 +624,25 @@ static uint16_t PulseWidth_16;
|
||||
static uint8_t PulsePeriod;
|
||||
static uint16_t PulsePeriod_16;
|
||||
|
||||
static uint16_t StepTimeCounter = 1;
|
||||
struct _CT{
|
||||
uint32_t SampleRate_counter;
|
||||
uint16_t StepTimeCounter;
|
||||
uint16_t NotifyCounter;
|
||||
uint32_t StandByCounter;
|
||||
}CT = {0};
|
||||
|
||||
static void InitFlag();
|
||||
static void InitCT();
|
||||
|
||||
#include "EliteWorkData.h"
|
||||
// real instruction fxn
|
||||
static uint16_t VoltScan(); // used in I-V and cyclic
|
||||
static uint16_t VoltScan(WorkMode *WorkModeData); // used in I-V and cyclic
|
||||
static void DACCode2Real2Notify(uint16_t DACcode); // send notify voltage after VoltScan()
|
||||
|
||||
//static void VOLT_OUTPUT();
|
||||
static void ZT_Plot();
|
||||
static void VT_Plot();
|
||||
static int32_t IT_Plot();
|
||||
static void ZT_Plot(RTMode *RT);
|
||||
static void VT_Plot(VTMode *VT);
|
||||
static int32_t IT_PlotIT_Plot(WorkMode *WorkModeData);
|
||||
|
||||
// the following fxn do the same thing
|
||||
// IVCurve_T is called if Vorigin > Vfinal, vice versa
|
||||
@@ -655,11 +652,11 @@ static uint8_t OldStep2NewStep(uint8_t OldStep);
|
||||
static uint16_t OldStep2NewStepTime(uint8_t StepTime);
|
||||
static uint8_t IVdone = 0;
|
||||
|
||||
static uint16_t OneWayVoltScan();
|
||||
static uint16_t OneWayVoltScan(IVMode *IV);
|
||||
static void ramp_test();
|
||||
static uint16_t DPVCurve();
|
||||
static uint16_t CVCurve();
|
||||
static uint16_t SWVCurve();
|
||||
static uint16_t DPVCurve(WorkMode *WorkModeData);
|
||||
static uint16_t CVCurve(CVMode *CV);
|
||||
static uint16_t SWVCurve(WorkMode *WorkModeData);
|
||||
|
||||
static void reset();
|
||||
static void Eliteinterrupt();
|
||||
@@ -670,6 +667,7 @@ static void SendNotify();
|
||||
static bool If10Von = false;
|
||||
static void TurnOn10V();
|
||||
|
||||
|
||||
#include "EliteInstruction.h"
|
||||
#include "EliteADC.h"
|
||||
#include "EliteDAC.h"
|
||||
@@ -682,6 +680,7 @@ static void TurnOn10V();
|
||||
|
||||
#include "EliteDeviceCorrection.h"
|
||||
#include "EliteNotify.h"
|
||||
#include "EliteFlagCTInit.h"
|
||||
#include "EliteReset.h"
|
||||
#include "EliteLED.h"
|
||||
#include "EliteKeyDetect.h"
|
||||
@@ -700,7 +699,7 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
INSTRUCTION.chip_id = chip_ID;
|
||||
|
||||
uint8_t oper = ins[1] & 0xF0; // this is don't care in RIS
|
||||
uint8_t data_length = ins[1] & 0x0F;
|
||||
// uint8_t data_length = ins[1] & 0x0F;
|
||||
|
||||
if (!If10Von) {
|
||||
// TurnOn10V();
|
||||
@@ -737,7 +736,7 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
}
|
||||
|
||||
case DIFFERENTIAL_PULSE_VOLTAMMETRY: {
|
||||
CleanBuffer();
|
||||
// CleanBuffer();
|
||||
INSTRUCTION.eliteFxn = DIFFERENTIAL_PULSE_VOLTAMMETRY;
|
||||
DACReset = true;
|
||||
|
||||
@@ -772,7 +771,7 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
}
|
||||
|
||||
case SQUARE_WAVE_VOLTAMMETRY: {
|
||||
CleanBuffer();
|
||||
// CleanBuffer();
|
||||
INSTRUCTION.eliteFxn = SQUARE_WAVE_VOLTAMMETRY;
|
||||
DACReset = true;
|
||||
|
||||
@@ -832,12 +831,9 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VOLT_OUTPUT: {
|
||||
INSTRUCTION.eliteFxn = VOLT_OUTPUT;
|
||||
INSTRUCTION.VoltConstant = ( ((uint16_t)(ins[3])) << 8) | (uint16_t)(ins[4]);
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
// DAC_outputV(INSTRUCTION.VoltConstant);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -866,7 +862,7 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
case SET_SAMPLE_RATE: {
|
||||
INSTRUCTION.SampleRateIndex = ins[3];
|
||||
INSTRUCTION.SampleRate = SampleRateTable[INSTRUCTION.SampleRateIndex];
|
||||
SampleRate_counter = 1;
|
||||
CT.SampleRate_counter = 1;
|
||||
break;
|
||||
}
|
||||
case POTENTIAL_STATE: {
|
||||
@@ -883,9 +879,9 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
|
||||
case CONSTANT_CURRENT:{
|
||||
INSTRUCTION.eliteFxn = CONSTANT_CURRENT;
|
||||
INSTRUCTION.SampleRate = 1000;
|
||||
INSTRUCTION.CurrentLV = ins[3];
|
||||
INSTRUCTION.ConstantCurrent = ( (uint32_t) (ins[4])<<24 | (uint32_t) (ins[5])<<16 | (uint32_t) (ins[6])<<8 | (uint32_t) (ins[7]) );
|
||||
INSTRUCTION.SampleRate = 6;
|
||||
INSTRUCTION.ConstantCurrent = ( (uint32_t) (ins[3])<<24 | (uint32_t) (ins[4])<<16 | (uint32_t) (ins[5])<<8 | (uint32_t) (ins[6]) );
|
||||
INSTRUCTION.NotifyRate = 1000;
|
||||
// GetInstructionParameter(ins+2);
|
||||
// CCCurrent2IUC();
|
||||
break;
|
||||
@@ -893,6 +889,12 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
|
||||
case SET_ADC_GAIN: {
|
||||
INSTRUCTION.ADCGainLevel = ins[3];
|
||||
if(INSTRUCTION.ADCGainLevel != GAIN_AUTO){
|
||||
INSTRUCTION.AutoGainEnable = 0;
|
||||
}
|
||||
else{
|
||||
INSTRUCTION.AutoGainEnable = 1;
|
||||
}
|
||||
// if(INSTRUCTION.ADCGainLevel == GAIN_200R){
|
||||
// LED_color(DARKLED, 0x0F, 0x00, 0x00);
|
||||
// }
|
||||
@@ -915,9 +917,6 @@ static void update_ZM_instruction(uint8 *ins) {
|
||||
int32_t ADCRealValue = 0;
|
||||
uint8_t CIS_buf[9] = {0};
|
||||
|
||||
uint16_t ADCValueTemp = 0;
|
||||
uint32_t ADCValueAVG = 0;
|
||||
|
||||
// for(int i=0 ; i<10 ; i++){
|
||||
ADCGainControl(ins[3]);
|
||||
ADCChannelSelect(ins[4]);
|
||||
|
||||
+63
-32
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* impedance_meter.h
|
||||
*
|
||||
* Created on: 2019�~1��15��
|
||||
* Created on: 2019/01/15
|
||||
* Author: benny
|
||||
*/
|
||||
#ifndef HEADSTAGE_H
|
||||
@@ -19,8 +19,9 @@
|
||||
// header
|
||||
#include <ti/drivers/PIN.h>
|
||||
#include "board.h"
|
||||
#include "EliteWorkData.h"
|
||||
|
||||
static void SimpleBLEPeripheral_performPeriodicTask(CURRENT_USER_CODE *CurrentUserCode);
|
||||
static void SimpleBLEPeripheral_performPeriodicTask(WorkMode *WorkModeData);
|
||||
|
||||
static void SimpleBLEPeripheral_clockHandler(UArg arg) {
|
||||
// Store the event.
|
||||
@@ -51,7 +52,7 @@ static void ZM_init() {
|
||||
PIN_setOutputValue(pin_handle, DAC_CS, 1); // DAC_CS HIGH
|
||||
|
||||
InitEliteInstruction();
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
ADCGainControl(GAIN_AUTO);
|
||||
elite_gptimer_open();
|
||||
|
||||
// PIN_registerIntCb(pin_handle, switch_on_callback);
|
||||
@@ -89,50 +90,75 @@ static void DACCode2Real2Notify(uint16_t DACcode) {
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static void SimpleBLEPeripheral_performPeriodicTask(CURRENT_USER_CODE *CurrentUserCode) {
|
||||
static void SimpleBLEPeripheral_performPeriodicTask(WorkMode *WorkModeData) {
|
||||
if ( IsPeriodicMode() ){
|
||||
|
||||
if (StepTimeCounter == INSTRUCTION.StepTime){
|
||||
StepTimeCounter = 1;
|
||||
// DAC counter
|
||||
if (CT.StepTimeCounter == INSTRUCTION.StepTime){
|
||||
CT.StepTimeCounter = 1;
|
||||
}
|
||||
else{
|
||||
StepTimeCounter++;
|
||||
CT.StepTimeCounter++;
|
||||
}
|
||||
|
||||
if (SampleRate_counter == INSTRUCTION.SampleRate){
|
||||
SampleRate_counter = 1;
|
||||
// ADC counter
|
||||
if (CT.SampleRate_counter == INSTRUCTION.SampleRate){
|
||||
CT.SampleRate_counter = 1;
|
||||
}
|
||||
else{
|
||||
SampleRate_counter++;
|
||||
CT.SampleRate_counter++;
|
||||
}
|
||||
|
||||
// notify counter
|
||||
if (CT.NotifyCounter == INSTRUCTION.NotifyRate){
|
||||
CT.NotifyCounter = 1;
|
||||
}
|
||||
else{
|
||||
CT.NotifyCounter ++;
|
||||
}
|
||||
|
||||
/** Periodic Event **/
|
||||
// Default working mode is DAC out -> ADC read -> send notify
|
||||
// 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
|
||||
// This flag can be named by FxnNameReset
|
||||
// This flag can be named by FxnNameDACReset
|
||||
|
||||
// In IV, CV, and func-gen mode, DAC will output voltage
|
||||
// else DAC do nothing.
|
||||
EliteDACControl(CurrentUserCode);
|
||||
EliteDACControl(WorkModeData);
|
||||
|
||||
// Control ADC to sample rate
|
||||
EliteADCControl(CurrentUserCode);
|
||||
EliteADCControl(WorkModeData);
|
||||
|
||||
// Notify control, check if we need to send notify
|
||||
EliteNotifyControl();
|
||||
}
|
||||
|
||||
else if(INSTRUCTION.eliteFxn == VOLT_OUTPUT){
|
||||
// assign WorkModeData->VO = INSTRUCTION.VoltConstant
|
||||
WorkModeData->VO->_VoltOut = INSTRUCTION.VoltConstant;
|
||||
|
||||
// UserCode -> DAC code -> DAC out
|
||||
DAC_outputV(Usercode_Correction_to_DAC(WorkModeData->VO->_VoltOut));
|
||||
FreeWorkMode(WorkModeData);
|
||||
PeriodicEvent = false;
|
||||
InitPeriodicEvent = true;
|
||||
}
|
||||
else{
|
||||
PeriodicEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void EliteDACControl(CURRENT_USER_CODE *CurrentUserCode) {
|
||||
static void EliteDACControl(WorkMode *WorkModeData) {
|
||||
if ((INSTRUCTION.eliteFxn == IV_CURVE) || (INSTRUCTION.eliteFxn == CV_CURVE)) {
|
||||
// output a certain voltage and put it into NotifyVolt
|
||||
DACCode2Real2Notify(VoltScan());
|
||||
DACCode2Real2Notify(VoltScan(WorkModeData));
|
||||
}
|
||||
|
||||
else if (INSTRUCTION.eliteFxn == ZT_CURVE){
|
||||
if(INSTRUCTION.ResisterMeter == RESISTER_METER_SMALL){
|
||||
// output 1V
|
||||
if (DACReset) {
|
||||
INSTRUCTION.VoltConstant = 24999 + 5000;
|
||||
INSTRUCTION.VoltConstant = 25000 + 5000;
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
DACReset = false;
|
||||
}
|
||||
@@ -140,7 +166,7 @@ static void EliteDACControl(CURRENT_USER_CODE *CurrentUserCode) {
|
||||
else{
|
||||
// output 1V
|
||||
if (DACReset) {
|
||||
INSTRUCTION.VoltConstant = 24999 + 5000;
|
||||
INSTRUCTION.VoltConstant = 25000 + 5000;
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
DACReset = false;
|
||||
}
|
||||
@@ -148,11 +174,10 @@ static void EliteDACControl(CURRENT_USER_CODE *CurrentUserCode) {
|
||||
}
|
||||
else if(INSTRUCTION.eliteFxn == CONSTANT_CURRENT){
|
||||
if (DACReset) {
|
||||
DAC_outputV(Usercode_Correction_to_DAC(CurrentUserCode->value));
|
||||
DAC_outputV(Usercode_Correction_to_DAC(25000));
|
||||
DACReset = false;
|
||||
}
|
||||
CCModeVoltOut(CurrentUserCode);
|
||||
// DAC_outputV(Usercode_Correction_to_DAC(CurrentUserCode->value));
|
||||
CCModeVoltOut(WorkModeData->CC);
|
||||
}
|
||||
|
||||
else{
|
||||
@@ -161,35 +186,37 @@ static void EliteDACControl(CURRENT_USER_CODE *CurrentUserCode) {
|
||||
}
|
||||
}
|
||||
|
||||
static void EliteADCControl(CURRENT_USER_CODE *CurrentUserCode) {
|
||||
if (SampleRate_counter == INSTRUCTION.SampleRate-1) {
|
||||
static void EliteADCControl(WorkMode *WorkModeData) {
|
||||
if (CT.SampleRate_counter == INSTRUCTION.SampleRate - 1) {
|
||||
switch (INSTRUCTION.eliteFxn) {
|
||||
case IV_CURVE:{
|
||||
IT_Plot();
|
||||
IT_Plot(WorkModeData);
|
||||
break;
|
||||
}
|
||||
case CV_CURVE:{
|
||||
IT_Plot();
|
||||
IT_Plot(WorkModeData);
|
||||
break;
|
||||
}
|
||||
case IT_CURVE:{
|
||||
IT_Plot();
|
||||
IT_Plot(WorkModeData);
|
||||
break;
|
||||
}
|
||||
case VT_CURVE:{
|
||||
// read volt through ADC and put it into notify buffer
|
||||
VT_Plot();
|
||||
VT_Plot(WorkModeData->VT);
|
||||
break;
|
||||
}
|
||||
case ZT_CURVE:{
|
||||
ZT_Plot();
|
||||
ZT_Plot(WorkModeData->RT);
|
||||
break;
|
||||
}
|
||||
case CONSTANT_CURRENT:{
|
||||
CCModeReadCurrent(CurrentUserCode);
|
||||
CCModeReadCurrent(WorkModeData->CC);
|
||||
CCModeReverseCurrent(WorkModeData->CC);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
IT_Plot(WorkModeData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -202,12 +229,16 @@ static void EliteNotifyControl() {
|
||||
if (!PeriodicEvent) {
|
||||
SendNotify();
|
||||
reset();
|
||||
} else if (StepTimeCounter == INSTRUCTION.StepTime - 1) {
|
||||
} else if (CT.StepTimeCounter == INSTRUCTION.StepTime - 1) {
|
||||
SendNotify();
|
||||
}
|
||||
}
|
||||
|
||||
else if (SampleRate_counter == INSTRUCTION.SampleRate) {
|
||||
else if(INSTRUCTION.eliteFxn == CONSTANT_CURRENT){
|
||||
if(CT.NotifyCounter == INSTRUCTION.NotifyRate){
|
||||
SendNotify();
|
||||
}
|
||||
}
|
||||
else if (CT.SampleRate_counter == INSTRUCTION.SampleRate) {
|
||||
SendNotify();
|
||||
}
|
||||
}
|
||||
|
||||
+16
-4
@@ -529,7 +529,7 @@ static void SimpleBLEPeripheral_init(void) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "EliteWorkData.h"
|
||||
/*********************************************************************
|
||||
* @fn SimpleBLEPeripheral_taskFxn
|
||||
*
|
||||
@@ -551,14 +551,14 @@ static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1) {
|
||||
|
||||
ZM_init();
|
||||
Elite_SPI_init();
|
||||
CURRENT_USER_CODE *CurrentUserCode = InitCurrentUserCode();
|
||||
WorkMode *WorkModeData = CreateWorkMode();
|
||||
|
||||
uint8_t key = 0;
|
||||
uint16_t counter6994 = 0;
|
||||
bool EliteOn = 0;
|
||||
|
||||
// init DAC, set output ~= 0 V
|
||||
DAC_outputV(Usercode_Correction_to_DAC(24999));
|
||||
DAC_outputV(Usercode_Correction_to_DAC(25000));
|
||||
elite_gptimer_start();
|
||||
|
||||
// Application main loops
|
||||
@@ -627,14 +627,26 @@ static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1) {
|
||||
counter6994++;
|
||||
}
|
||||
EliteKeyPress(key);
|
||||
if(Free_Work_Mode){
|
||||
FreeWorkMode(WorkModeData);
|
||||
InitEliteInstruction();
|
||||
ADCGainControl(INSTRUCTION.ADCGainLevel);
|
||||
DAC_outputV(Usercode_Correction_to_DAC(INSTRUCTION.VoltConstant));
|
||||
Free_Work_Mode = false;
|
||||
}
|
||||
} else {
|
||||
EliteOn = TurnOnElite(key);
|
||||
}
|
||||
}
|
||||
// if there is periodic event
|
||||
else {
|
||||
if(InitPeriodicEvent){
|
||||
InitWorkMode(WorkModeData);
|
||||
InitPeriodicEvent = false;
|
||||
}
|
||||
|
||||
// Perform periodic application task
|
||||
SimpleBLEPeripheral_performPeriodicTask(CurrentUserCode);
|
||||
SimpleBLEPeripheral_performPeriodicTask(WorkModeData);
|
||||
|
||||
key = PIN_getInputValue(switch_on);
|
||||
EliteKeyPress(key); // onPress=> key = 0; 1.lighten LED 2.long press shut down 2650
|
||||
|
||||
Reference in New Issue
Block a user