Elite 1.4-re VT function test

This commit is contained in:
alan
2019-08-15 16:32:39 +08:00
parent 0290a178ee
commit 4ffbcba8cf
4 changed files with 47 additions and 231 deletions
@@ -5,6 +5,19 @@
#include "Elite_PIN.h"
#include "EliteSPI.h"
// Elite ADC macro
// ADC command, Elite will use these cmd to control ADC
#define CMD_CURRENT_MEASURE 0xC5
#define CMD_VOLT_MEASURE 0xD5
#define CMD_DAC_MEASURE 0xE5
#define CMD_BATTERY_MEASURE 0xF5
// controller command, these are command from control box
#define ADC_CH_CURRENT 0x00
#define ADC_CH_VOLT 0x01
#define ADC_CH_DAC 0x02
#define ADC_CH_BAT 0x03
static void ADC_write(uint8_t ADCin) {
/*
* This function can only define [15]~[8] through ADCin
@@ -46,32 +59,6 @@ static void ADC_read(uint8_t *ADCdata){
ADC_SPI(SPI_ADC_SIZE, spi_ADC_txbuf, ADCdata);
}
static void ADC_Test(){
uint8_t ADCin = 0;
int32_t AIN = 0;
ADCin = 0xC1;
ADC_write(ADCin);
CPUdelay(160);
ADC_read(spi_ADC_rxbuf);
float Vo;
int16_t decode = (int16_t)(spi_ADC_rxbuf[0] << 8) | (uint16_t)(spi_ADC_rxbuf[1]);
Vo = decode * (-176.91125719) + 1400190.030591624;
AIN = (int32_t) (Vo / 1);
// NotifyCurrent[0] = (uint8_t) (AIN >> 24) & (0xFF);
// NotifyCurrent[1] = (uint8_t) (AIN >> 16) & (0xFF);
// NotifyCurrent[2] = (uint8_t) (AIN >> 8) & (0xFF);
// NotifyCurrent[3] = (uint8_t) (AIN) & (0xFF);
//
// NotifyImpedance[1] = spi_ADC_rxbuf[0];
// NotifyImpedance[2] = spi_ADC_rxbuf[1];
// SimpleProfile_SetParameter(BLE_CIS_BUFF_CHAR, 4, spi_ADC_rxbuf);
// SendNotify();
}
static void ADCGainControl(uint8_t ADCLevel){
if(ADCLevel == 0){
// ADC gain level = 0, using 200R resister
@@ -100,46 +87,32 @@ static void ADCChannelSelect(uint8_t ADCChannel){
// set ADC parameter
// 0xC1~F1 = reading AIN0~AIN3. Using FSR+-6V, resolution = 187.5uV
// 0xC5~F5 = reading AIN0~AIN3. Using FSR+-6V, resolution = 62.5 uV
uint8_t ADCin = 0xC1;
// 0xC5~F5 = reading AIN0~AIN3. Using FSR+-2V, resolution = 62.5 uV
switch(ADCChannel){
// AINp is AIN0; AINn is GND
// measure AIN0, which is a current measure
case 0 :{
ADCin = 0xC1;
ADC_write(ADCin);
CPUdelay(16000);
ADC_read(spi_ADC_rxbuf);
case ADC_CH_CURRENT :{
ADC_write(CMD_CURRENT_MEASURE);
break;
}
// AINp is AIN1; AINn is GND
// AIN1, which is a volt measure
case 1 :{
ADCin = 0xD1;
ADC_write(ADCin);
CPUdelay(16000);
ADC_read(spi_ADC_rxbuf);
case ADC_CH_VOLT :{
ADC_write(CMD_VOLT_MEASURE);
break;
}
// AINp is AIN2; AINn is GND
// AIN2, measure DAC voltage (Note that this is NOT DAC real output value!!)
case 2 :{
ADCin = 0xE1;
ADC_write(ADCin);
CPUdelay(16000);
ADC_read(spi_ADC_rxbuf);
case ADC_CH_DAC :{
ADC_write(CMD_DAC_MEASURE);
break;
}
// measure battery volt
case 3 :{
ADCin = 0xF1;
ADC_write(ADCin);
CPUdelay(16000);
ADC_read(spi_ADC_rxbuf);
case ADC_CH_BAT :{
ADC_write(CMD_BATTERY_MEASURE);
break;
}
default :{
@@ -154,7 +127,7 @@ static uint32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC
uint16_t ADC_measure = (uint16_t) (ADC_raw[0] << 8) | (uint16_t) (ADC_raw[1]);
uint32_t ret = 0, ADCRealVolt = 0, ADCRealCurrent = 0;
// return real volt to controller
if(ADCChannel == 0x01){
if(ADCChannel == ADC_CH_VOLT){
ADCRealVolt = DecodeADCVolt(ADC_measure);
NotifyVolt[0] = (uint8_t) (ADCRealVolt >> 24);
NotifyVolt[1] = (uint8_t) ((ADCRealVolt & 0x00110000) >> 16);
@@ -164,7 +137,7 @@ static uint32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC
}
// return real current to controller
else if(ADCChannel == 0x00){
else if(ADCChannel == ADC_CH_CURRENT){
ADCRealCurrent = DecodeADCCurrent(ADCGain, ADC_measure);
NotifyCurrent[0] = (uint8_t) (ADCRealCurrent >> 24);
NotifyCurrent[1] = (uint8_t) ((ADCRealCurrent & 0x00110000) >> 16);
@@ -608,10 +608,10 @@ static bool update_ins_rec_buffer();
/**
* send instruction to Z meter
*/
// static void spi_DAC_transact_ins truction();
// ADC function
static void ADC_write(uint8_t ADCin);
static void ADC_read(uint8_t *ADCdata);
static uint16_t DACCorrectionDecode(uint16_t usercode);
static void ADCGainControl(uint8_t ADCLevel);
static void ADCChannelSelect(uint8_t ADCChannel);
@@ -619,9 +619,12 @@ static uint32_t DecodeADCValue(uint8_t ADCGain, uint8_t ADCChannel, uint8_t *ADC
static int32_t DecodeADCVolt(uint16_t ADC_measure);
static int32_t DecodeADCCurrent(uint8_t ADCGain, uint16_t ADC_measure);
// DAC function
static uint16_t DACCorrectionDecode(uint16_t usercode);
// Elite key detection & turn on/ shutdown function
static void EliteKeyPress(uint8_t key);
static bool TurnOnElite(uint8_t key);
static void WorkModeLED();
static void KeyWorkModeLED();
@@ -851,7 +854,7 @@ static void update_ZM_instruction(uint8 *ins) {
case VTCurve:{
INSTRUCTION.eliteFxn = VTCurve;
StepTime = 0x14;
StepTime = 0x01;
// SimpleProfile_SetParameter(BLE_DAT_BUFF_CHAR, BLE_DAT_BUFF_SIZE, not_buf);
// VT_Plot(); // enable 10v = 0
@@ -891,6 +894,8 @@ static void update_ZM_instruction(uint8 *ins) {
ADCGainControl(ins[3]);
ADCChannelSelect(ins[4]);
CPUdelay(16000);
ADC_read(spi_ADC_rxbuf);
// decode ADC measure value
ADCRealValue = DecodeADCValue(ins[3], ins[4], spi_ADC_rxbuf);
@@ -918,7 +923,7 @@ static void update_ZM_instruction(uint8 *ins) {
}
SimpleProfile_SetParameter(BLE_CIS_BUFF_CHAR, 9, CIS_buf);
// SendNotify()
// SendNotify();
break;
}
@@ -105,165 +105,6 @@ static void LED_color(uint8_t bright, uint8_t red, uint8_t green, uint8_t blue);
static void ZM_update_instruction_callback(uint8_t ins_type, uint8_t chip_ID, uint8_t *ins) {}
// get ADC LSB size (uV)
static float getLSB(uint8_t ADCin) {
switch (ADCin & 0b00001110) {
case 0x00:
return 187.5;
case 0x02:
return 125;
case 0x04:
return 62.5;
case 0x06:
return 31.25;
case 0x08:
return 15.625;
case 0x0A:
return 7.8125;
case 0x0C:
return 7.8125;
case 0x0E:
return 7.8125;
default:
return 187.5;
}
}
//
#define ADC_stage1_overflow() ((spi_ADC_rxbuf[0] >= 0xFE) && (spi_ADC_rxbuf[1] >= 0xBD))
#define ADC_stage1_underflow() ((spi_ADC_rxbuf[0] <= 0x02) && (spi_ADC_rxbuf[1] <= 0x85))
#define ADC_stage2_overflow() ((spi_ADC_rxbuf[0] >= 0x3B) && (spi_ADC_rxbuf[1] >= 0x3E))
#define ADC_stage2_underflow() ((spi_ADC_rxbuf[0] <= 0x01) && (spi_ADC_rxbuf[1] <= 0x43))
#define ADC_stage1full() (ADC_stage1_overflow() || ADC_stage1_underflow())
#define ADC_stage2full() (ADC_stage2_overflow() || ADC_stage2_underflow())
static uint8_t DecodeADCCurrent_level1(){
uint8_t AIN1[SPI_ADC_SIZE];
NotifyImpedance[3] = 0xFF;
ADC_write(0xC1);
CPUdelay(160);
ADC_read(AIN1);
for(int i=0 ; i<SPI_ADC_SIZE ; i++){
spi_ADC_rxbuf[i] = AIN1[i];
}
// if (ADC_stage1full()){
if ((AIN1[0] >= 0xFE) || (AIN1[0] <= 02)){
// blue
LED_color(DARKLED, 0x00, 0x00, 0x0E);
return 0;
} else {
// purple
LED_color(DARKLED, 0x0E, 0x00, 0x0E);
return 1;
}
}
static uint8_t DecodeADCCurrent_level2(){
uint8_t AIN2[SPI_ADC_SIZE];
NotifyImpedance[0] = 0x22;
ADC_write(0xD1);
CPUdelay(160);
ADC_read(AIN2);
// if (ADC_stage2full()){
if ((AIN2[0] >= 0x3B) || (AIN2[0] <= 01)){
return DecodeADCCurrent_level1();
} else {
// orange?
LED_color(DARKLED, 0x0E, 0x0E, 0x00);
for(int i=0 ; i<SPI_ADC_SIZE ; i++){
spi_ADC_rxbuf[i] = AIN2[i];
}
return 2;
}
}
static uint8_t DecodeADCCurrent_level3(){
uint8_t AIN3[SPI_ADC_SIZE];
NotifyVolt[0] = 0xEE;
ADC_write(0xE1);
CPUdelay(160);
ADC_read(AIN3);
if ((AIN3[0] >= 0x3B) || (AIN3[0] <= 01)){
return DecodeADCCurrent_level2();
} else {
// white
LED_color(DARKLED, 0x0E, 0x0E, 0x0E);
for(int i=0 ; i<SPI_ADC_SIZE ; i++){
spi_ADC_rxbuf[i] = AIN3[i];
}
// return DecodeADCCurrent_level2();
return 3;
}
}
static int32_t DecodeADCCurrent(uint8_t ADCin){
int32_t Iin = 0;
float Vo;
uint8_t stage = DecodeADCCurrent_level3();
// CPUdelay(8000);
int16_t decode;
// SendNotify();
// SimpleProfile_SetParameter(BLE_DAT_BUFF_CHAR, 4, spi_ADC_rxbuf);
NotifyImpedance[1] = spi_ADC_rxbuf[0];
NotifyImpedance[2] = spi_ADC_rxbuf[1];
switch(stage){
case 1:
// Vo = 101*1500000 - 100 * decode*LSBuV / 10e6;
// Vo = Vo * 1000;
// Iin = DecodeADC(0xD1) / 10e6; // mA
decode = (int16_t)(spi_ADC_rxbuf[0] << 8) | (uint16_t)(spi_ADC_rxbuf[1]);
Vo = decode * (-176.91125719) + 1400190.030591624;
Iin = (int32_t) (Vo / 1);
break;
case 2:
decode = (int16_t)(spi_ADC_rxbuf[0] << 8) | (uint16_t)(spi_ADC_rxbuf[1]);
Vo = decode * (-5855081.65485084) + 47350.844772584;
Iin = (int32_t) (Vo / 1);
// Iin = DecodeADC(0xE1) / (25*10e6); // mA
break;
case 3:
Iin = 0x76543210;
// Iin = DecodeADC(0xF1) / (625*10e6); // mA
break;
// stage 1 over/under flow
case 0:
decode = (int16_t)(spi_ADC_rxbuf[0] << 8) | (uint16_t)(spi_ADC_rxbuf[1]);
Vo = decode * (-176.91125719) + 1400190.030591624;
Iin = 0x7FFFFFFF + (int32_t) (Vo / 1);
break;
default:
// Iin = DecodeADC(0xD1) / 10e6; // mA
break;
}
return Iin;
}
// ADC rx = 0xDDDDXXXX
// Vo = DDDD * 187.5 uV
// Vo = GNDS - Vin/10
// Vin = 10*GNDS - 10Vo
// = 10*GNDS - 10*(0xDDDD*187.5 uV)
// = 10*1500000 - 10*(0xDDDD*187.5) (uV)
static int32_t DecodeADCVolt(uint8_t ADCin) {
int16_t decode = (int16_t)(spi_ADC_rxbuf[0] << 8) | (uint16_t)(spi_ADC_rxbuf[1]);
float LSBuV = getLSB(ADCin);
float Vo = (1500000 - decode * LSBuV) / 10e5;
return (int32_t)(Vo * 10000); // mV
}
/*
static void VoltScan(){
if(VoltOrigin == VoltFinal){
@@ -332,27 +173,21 @@ static void fxn_Gen() {}
static void ZT_plot(uint16_t outV, uint16_t inV) {}
static void VT_Plot() {
//
uint8_t ADCin = 0;
int32_t AIN = 0;
// ADC gain is don't care when measuring voltage
uint8_t ADCGain = 1;
ADCin = 0xF1;
// ADCin = 0xF6;
ADC_write(ADCin);
CPUdelay(160);
// read ADC volt
ADCChannelSelect(ADC_CH_VOLT);
CPUdelay(16000);
ADC_read(spi_ADC_rxbuf);
AIN = DecodeADCVolt(ADCin);
// return voltage (mV)
NotifyVolt[0] = (uint8_t) (AIN >> 24) & (0xFF);
NotifyVolt[1] = (uint8_t) (AIN >> 16) & (0xFF);
NotifyVolt[2] = (uint8_t) (AIN >> 8) & (0xFF);
NotifyVolt[3] = (uint8_t) (AIN) & (0xFF);
// decode ADC value and put it into notify buffer
ADCRealValue = DecodeADCValue(ADCGain, ADC_CH_VOLT, spi_ADC_rxbuf);
}
static void IT_Plot() {
int32_t AIN;
AIN = DecodeADCCurrent(0xC1);
int32_t AIN = 0;
// AIN = DecodeADCCurrent(0xC1);
// return current (0.001 nA)
NotifyCurrent[0] = (uint8_t) (AIN >> 24) & (0xFF);
@@ -469,7 +304,10 @@ static void SimpleBLEPeripheral_performPeriodicTask() {
break;
}
case VTCurve: {
// read volt through ADC and put it into notify buffer
VT_Plot();
// output notify
SendNotify();
break;
}
@@ -636,7 +636,7 @@ static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1) {
Util_startClock(&periodicClock); //manually restart the clock
if(PeriodicCounter >= StepTime){
SimpleBLEPeripheral_performPeriodicTask();
PeriodicCounter = 1;
PeriodicCounter = 0;
}
key = PIN_getInputValue(switch_on);
EliteKeyPress(key); //onPress=> key = 0; 1.lighten LED 2.long press shut down 2650