Optimized from Version1.03

This commit is contained in:
phdlee 2018-03-05 12:51:14 +09:00
parent bf68dd6c26
commit fb2c9d2cc3
5 changed files with 79 additions and 153 deletions

View File

@ -408,7 +408,6 @@ void saveBandFreqByIndex(unsigned long f, unsigned long mode, char bandIndex) {
When the delay is used, the program will generate an error because it is not communicating, When the delay is used, the program will generate an error because it is not communicating,
so Create a new delay function that can do background processing. so Create a new delay function that can do background processing.
*/ */
unsigned long delayBeforeTime = 0; unsigned long delayBeforeTime = 0;
byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWKey -> Check Paddle byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWKey -> Check Paddle
delayBeforeTime = millis(); delayBeforeTime = millis();
@ -526,7 +525,6 @@ void setFrequency(unsigned long f){
* put the uBitx in tx mode. It takes care of rit settings, sideband settings * put the uBitx in tx mode. It takes care of rit settings, sideband settings
* Note: In cw mode, doesnt key the radio, only puts it in tx mode * Note: In cw mode, doesnt key the radio, only puts it in tx mode
*/ */
void startTx(byte txMode, byte isDisplayUpdate){ void startTx(byte txMode, byte isDisplayUpdate){
//Check Hamband only TX //Not found Hamband index by now frequency //Check Hamband only TX //Not found Hamband index by now frequency
if (tuneTXType >= 100 && getIndexHambanBbyFreq(ritOn ? ritTxFrequency : frequency) == -1) { if (tuneTXType >= 100 && getIndexHambanBbyFreq(ritOn ? ritTxFrequency : frequency) == -1) {
@ -682,7 +680,7 @@ void checkButton(){
delay(10); delay(10);
Check_Cat(0); Check_Cat(0);
} }
delay(50);//debounce //delay(50);//debounce
} }
@ -697,7 +695,7 @@ int encodedSumValue = 0;
unsigned long lastTunetime = 0; //if continous moving, skip threshold processing unsigned long lastTunetime = 0; //if continous moving, skip threshold processing
byte lastMovedirection = 0; //0 : stop, 1 : cw, 2 : ccw byte lastMovedirection = 0; //0 : stop, 1 : cw, 2 : ccw
#define skipThresholdTime 100 //#define skipThresholdTime 70
#define encodeTimeOut 1000 #define encodeTimeOut 1000
void doTuningWithThresHold(){ void doTuningWithThresHold(){
@ -726,7 +724,9 @@ void doTuningWithThresHold(){
encodedSumValue += (s > 0 ? 1 : -1); encodedSumValue += (s > 0 ? 1 : -1);
//check threshold and operator actions (hold dial speed = continous moving, skip threshold check) //check threshold and operator actions (hold dial speed = continous moving, skip threshold check)
if ((lastTunetime < millis() - skipThresholdTime) && ((encodedSumValue * encodedSumValue) <= (threshold * threshold))) //not use continues changing by Threshold
//if ((lastTunetime < (millis() - skipThresholdTime)) && ((encodedSumValue * encodedSumValue) <= (threshold * threshold)))
if (((encodedSumValue * encodedSumValue) <= (threshold * threshold)))
return; return;
lastTunetime = millis(); lastTunetime = millis();
@ -736,7 +736,8 @@ void doTuningWithThresHold(){
prev_freq = frequency; prev_freq = frequency;
//incdecValue = tuningStep * s; //incdecValue = tuningStep * s;
frequency += (arTuneStep[tuneStepIndex -1] * s * (s * s < 10 ? 1 : 3)); //appield weight (s is speed) //frequency += (arTuneStep[tuneStepIndex -1] * s * (s * s < 10 ? 1 : 3)); //appield weight (s is speed)
frequency += (arTuneStep[tuneStepIndex -1] * s); //appield weight (s is speed) //if want need more increase size, change step size
if (prev_freq < 10000000l && frequency > 10000000l) if (prev_freq < 10000000l && frequency > 10000000l)
isUSB = true; isUSB = true;
@ -757,16 +758,15 @@ void doRIT(){
if (knob < 0) if (knob < 0)
frequency -= (arTuneStep[tuneStepIndex -1]); // frequency -= (arTuneStep[tuneStepIndex -1]); //
//frequency -= 100l;
else if (knob > 0) else if (knob > 0)
frequency += (arTuneStep[tuneStepIndex -1]); // frequency += (arTuneStep[tuneStepIndex -1]); //
//frequency += 100;
if (old_freq != frequency){ if (old_freq != frequency){
setFrequency(frequency); setFrequency(frequency);
updateDisplay(); updateDisplay();
} }
} }
/* /*
save Frequency and mode to eeprom for Auto Save with protected eeprom cycle, by kd8cec save Frequency and mode to eeprom for Auto Save with protected eeprom cycle, by kd8cec
*/ */
@ -1060,7 +1060,6 @@ void initSettings(){
} }
void initPorts(){ void initPorts(){
analogReference(DEFAULT); analogReference(DEFAULT);
//?? //??
@ -1110,7 +1109,7 @@ void setup()
//Serial.begin(9600); //Serial.begin(9600);
lcd.begin(16, 2); lcd.begin(16, 2);
printLineF(1, F("CECBT v1.03")); printLineF(1, F("CECBT v1.04"));
Init_Cat(38400, SERIAL_8N1); Init_Cat(38400, SERIAL_8N1);
initMeter(); //not used in this build initMeter(); //not used in this build

View File

@ -31,12 +31,15 @@ void updateLine2Buffer(char isDirectCall)
{ {
if (ritOn) if (ritOn)
{ {
strcpy(line2Buffer, "RitTX:");
/*
line2Buffer[0] = 'R'; line2Buffer[0] = 'R';
line2Buffer[1] = 'i'; line2Buffer[1] = 'i';
line2Buffer[2] = 't'; line2Buffer[2] = 't';
line2Buffer[3] = 'T'; line2Buffer[3] = 'T';
line2Buffer[4] = 'X'; line2Buffer[4] = 'X';
line2Buffer[5] = ':'; line2Buffer[5] = ':';
*/
//display frequency //display frequency
tmpFreq = ritTxFrequency; tmpFreq = ritTxFrequency;
@ -61,12 +64,10 @@ void updateLine2Buffer(char isDirectCall)
if (vfoActive == VFO_B) if (vfoActive == VFO_B)
{ {
tmpFreq = vfoA; tmpFreq = vfoA;
//line2Buffer[0] = 'A';
} }
else else
{ {
tmpFreq = vfoB; tmpFreq = vfoB;
//line2Buffer[0] = 'B';
} }
// EXAMPLE 1 & 2 // EXAMPLE 1 & 2
@ -133,16 +134,18 @@ void updateLine2Buffer(char isDirectCall)
line2Buffer[8] = 'I'; line2Buffer[8] = 'I';
line2Buffer[9] = 'F'; line2Buffer[9] = 'F';
if (ifShiftValue == 0) //if (ifShiftValue == 0)
{ //{
/*
line2Buffer[10] = 'S'; line2Buffer[10] = 'S';
line2Buffer[11] = ':'; line2Buffer[11] = ':';
line2Buffer[12] = 'O'; line2Buffer[12] = 'O';
line2Buffer[13] = 'F'; line2Buffer[13] = 'F';
line2Buffer[14] = 'F'; line2Buffer[14] = 'F';
} */
else //}
{ //else
//{
line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0; line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0;
line2Buffer[11] = 0; line2Buffer[11] = 0;
line2Buffer[12] = ' '; line2Buffer[12] = ' ';
@ -151,7 +154,7 @@ void updateLine2Buffer(char isDirectCall)
memset(b, 0, sizeof(b)); memset(b, 0, sizeof(b));
ltoa(ifShiftValue, b, DEC); ltoa(ifShiftValue, b, DEC);
strncat(line2Buffer, b, 5); strncat(line2Buffer, b, 5);
} //}
if (isDirectCall == 1) //if call by encoder (not scheduler), immediate print value if (isDirectCall == 1) //if call by encoder (not scheduler), immediate print value
printLine2(line2Buffer); printLine2(line2Buffer);

View File

@ -56,7 +56,7 @@ void menuBand(int btn){
return; return;
} }
printLineF2(F("Press to confirm")); //printLineF2(F("Press to confirm"));
//wait for the button menu select button to be lifted) //wait for the button menu select button to be lifted)
while (btnDown()) { while (btnDown()) {
delay_background(50, 0); delay_background(50, 0);
@ -72,9 +72,9 @@ void menuBand(int btn){
} }
delay_background(1000, 0); delay_background(1000, 0);
printLine2ClearAndUpdate(); printLine2ClearAndUpdate();
printLineF2(F("Press to confirm"));
} }
} }
printLineF2(F("Press to confirm"));
char currentBandIndex = -1; char currentBandIndex = -1;
//Save Band Information //Save Band Information
@ -92,7 +92,6 @@ void menuBand(int btn){
ritDisable(); ritDisable();
while(!btnDown()){ while(!btnDown()){
knob = enc_read(); knob = enc_read();
if (knob != 0){ if (knob != 0){
if (tuneTXType == 2 || tuneTXType == 3 || tuneTXType == 102 || tuneTXType == 103) { //only ham band move if (tuneTXType == 2 || tuneTXType == 3 || tuneTXType == 102 || tuneTXType == 103) { //only ham band move
@ -127,17 +126,7 @@ void menuBand(int btn){
delay_background(20, 0); delay_background(20, 0);
} }
/*
while(btnDown()) {
delay(50);
Check_Cat(0); //To prevent disconnections
}
*/
FrequencyToVFO(1); FrequencyToVFO(1);
//printLine2ClearAndUpdate();
//delay_background(500, 0);
//menuOn = 0;
menuClearExit(500); menuClearExit(500);
} }
@ -181,25 +170,6 @@ void byteToMode(byte modeValue, byte autoSetModebyFreq){
} }
} }
/*
//Convert Number to Mode by KD8CEC
void byteWithFreqToMode(byte modeValue){
if (modeValue == 4)
cwMode = 1;
else if (modeValue == 5)
cwMode = 2;
else {
cwMode = 0;
if (modeValue == 3)
isUSB = 1;
else if (modeValue == 0) //Not Set
isUSB = (frequency > 10000000l) ? true : false;
else
isUSB = 0;
}
}
*/
//IF Shift function, BFO Change like RIT, by KD8CEC //IF Shift function, BFO Change like RIT, by KD8CEC
void menuIFSSetup(int btn){ void menuIFSSetup(int btn){
int knob = 0; int knob = 0;
@ -212,11 +182,7 @@ void menuIFSSetup(int btn){
printLineF2(F("IF Shift:Off, On?")); printLineF2(F("IF Shift:Off, On?"));
} }
else { else {
//if (isIFShift == 0){
//printLineF2(F("IF Shift is ON"));
//delay_background(500, 0);
isIFShift = 1; isIFShift = 1;
//}
delay_background(500, 0); delay_background(500, 0);
updateLine2Buffer(1); updateLine2Buffer(1);
@ -255,7 +221,7 @@ void menuIFSSetup(int btn){
isIFShift = 0; isIFShift = 0;
printLineF2(F("IF Shift is OFF")); printLineF2(F("IF Shift is OFF"));
setFrequency(frequency); setFrequency(frequency);
delay_background(500, 0); delay_background(1500, 0);
} }
//menuOn = 0; //menuOn = 0;
@ -343,17 +309,12 @@ void menuSelectMode(int btn){
si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off si5351bx_setfreq(0, cwmCarrier + (isIFShift ? ifShiftValue : 0)); //set back the carrier oscillator anyway, cw tx switches it off
setFrequency(frequency); setFrequency(frequency);
//delay_background(500, 0);
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(500); menuClearExit(500);
} }
} }
//Memory to VFO, VFO to Memory by KD8CEC //Memory to VFO, VFO to Memory by KD8CEC
//select between MtoV and VtoM by isMemoryToVfo
void menuCHMemory(int btn, byte isMemoryToVfo){ void menuCHMemory(int btn, byte isMemoryToVfo){
int knob = 0; int knob = 0;
int selectChannel = 0; int selectChannel = 0;
@ -407,10 +368,6 @@ void menuCHMemory(int btn, byte isMemoryToVfo){
strcat(c, b); //append channel Number; strcat(c, b); //append channel Number;
strcat(c, " :"); //append channel Number; strcat(c, " :"); //append channel Number;
} }
/*
if (selectChannel < 10)
printLineFromEEPRom(0, 4, 0, userCallsignLength -1); //eeprom to lcd use offset (USER_CALLSIGN_DAT)
*/
//display frequency //display frequency
tmpFreq = resultFreq; tmpFreq = resultFreq;
@ -624,25 +581,16 @@ void menuVfoToggle(int btn)
FrequencyToVFO(1); FrequencyToVFO(1);
if (vfoActive == VFO_B){ if (vfoActive == VFO_B){
//vfoB = frequency;
//vfoB_mode = modeToByte();
//storeFrequencyAndMode(2); //vfoB -> eeprom
vfoActive = VFO_A; vfoActive = VFO_A;
frequency = vfoA; frequency = vfoA;
saveCheckFreq = frequency; saveCheckFreq = frequency;
byteToMode(vfoA_mode, 0); byteToMode(vfoA_mode, 0);
} }
else { else {
//vfoA = frequency;
//vfoA_mode = modeToByte();
//storeFrequencyAndMode(1); //vfoA -> eeprom
vfoActive = VFO_B; vfoActive = VFO_B;
frequency = vfoB; frequency = vfoB;
saveCheckFreq = frequency; saveCheckFreq = frequency;
byteToMode(vfoB_mode, 0); byteToMode(vfoB_mode, 0);
//printLineF2(F("Selected VFO B"));
} }
ritDisable(); ritDisable();
@ -661,12 +609,12 @@ void menuRitToggle(int btn){
} }
else { else {
if (ritOn == 0){ if (ritOn == 0){
printLineF2(F("RIT is ON")); //printLineF2(F("RIT is ON"));
//enable RIT so the current frequency is used at transmit //enable RIT so the current frequency is used at transmit
ritEnable(frequency); ritEnable(frequency);
} }
else{ else{
printLineF2(F("RIT is OFF")); //printLineF2(F("RIT is OFF"));
ritDisable(); ritDisable();
} }
@ -694,9 +642,6 @@ void menuSplitOnOff(int btn){
printLineF2(F("Split On!")); printLineF2(F("Split On!"));
} }
//delay_background(500, 0);
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(500); menuClearExit(500);
} }
} }
@ -721,9 +666,6 @@ void menuTxOnOff(int btn, byte optionType){
printLineF2(F("TX ON!")); printLineF2(F("TX ON!"));
} }
//delay_background(500, 0);
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(500); menuClearExit(500);
} }
} }
@ -751,9 +693,6 @@ void menuSetup(int btn){
} }
*/ */
//delay_background(2000, 0);
//printLine2Clear();
//menuOn = 0;
menuClearExit(1000); menuClearExit(1000);
} }
} }
@ -803,23 +742,18 @@ void menuCWSpeed(int btn){
printLine2(b); printLine2(b);
} }
//abort if this button is down //abort if this button is down
if (btnDown()) //if (btnDown())
//re-enable the clock1 and clock 2 //re-enable the clock1 and clock 2
break; // break;
Check_Cat(0); //To prevent disconnections Check_Cat(0); //To prevent disconnections
} }
//save the setting //save the setting
//if (digitalRead(PTT) == LOW){ //printLineF2(F("CW Speed set!"));
printLineF2(F("CW Speed set!")); cwSpeed = 1200 / wpm;
cwSpeed = 1200/wpm; EEPROM.put(CW_SPEED, cwSpeed);
EEPROM.put(CW_SPEED, cwSpeed); menuClearExit(1000);
//}
//delay_background(2000, 0);
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(1000);
} }
//Builtin CW Keyer Logic by KD8CEC //Builtin CW Keyer Logic by KD8CEC
@ -884,14 +818,9 @@ void menuSetupCwDelay(int btn){
} }
//save the setting //save the setting
//if (digitalRead(PTT) == LOW){ //printLineF2(F("CW Delay set!"));
printLineF2(F("CW Delay set!")); cwDelayTime = tmpCWDelay / 10;
cwDelayTime = tmpCWDelay / 10; EEPROM.put(CW_DELAY, cwDelayTime);
EEPROM.put(CW_DELAY, cwDelayTime);
//delay_background(2000, 0);
//}
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(1000); menuClearExit(1000);
} }
@ -940,21 +869,17 @@ void menuSetupTXCWInterval(int btn){
needDisplayInformation = 1; needDisplayInformation = 1;
} }
//abort if this button is down //abort if this button is down
if (btnDown()) //if (btnDown())
break; // break;
Check_Cat(0); //To prevent disconnections Check_Cat(0); //To prevent disconnections
} }
//save the setting //save the setting
//if (digitalRead(PTT) == LOW){ //printLineF2(F("CW Start set!"));
printLineF2(F("CW Start set!")); delayBeforeCWStartTime = tmpTXCWInterval / 2;
delayBeforeCWStartTime = tmpTXCWInterval / 2; EEPROM.put(CW_START, delayBeforeCWStartTime);
EEPROM.put(CW_START, delayBeforeCWStartTime);
//delay_background(2000, 0);
//}
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(1000); menuClearExit(1000);
} }
@ -1215,8 +1140,6 @@ void menuSetupCWCarrier(int btn){
si5351bx_setfreq(0, cwmCarrier); si5351bx_setfreq(0, cwmCarrier);
printCarrierFreq(cwmCarrier); printCarrierFreq(cwmCarrier);
//Check_Cat(0); //To prevent disconnections
//delay(100);
delay_background(100, 0); delay_background(100, 0);
} }
@ -1235,8 +1158,6 @@ void menuSetupCWCarrier(int btn){
si5351bx_setfreq(0, cwmCarrier); //set back the carrier oscillator anyway, cw tx switches it off si5351bx_setfreq(0, cwmCarrier); //set back the carrier oscillator anyway, cw tx switches it off
setFrequency(frequency); setFrequency(frequency);
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(0); menuClearExit(0);
} }
@ -1284,8 +1205,6 @@ void menuSetupCwTone(int btn){
else else
sideTone = prev_sideTone; sideTone = prev_sideTone;
//printLine2ClearAndUpdate();
//menuOn = 0;
menuClearExit(0); menuClearExit(0);
} }
@ -1298,15 +1217,7 @@ void setDialLock(byte tmpLock, byte fromMode) {
if (fromMode == 2 || fromMode == 3) return; if (fromMode == 2 || fromMode == 3) return;
//for reduce using flash memory //delay_background(1000, 0);
/*
if (tmpLock == 1)
printLineF2(F("Dial Lock ON"));
else
printLineF2(F("Dial Lock OFF"));
*/
delay_background(1000, 0);
printLine2ClearAndUpdate(); printLine2ClearAndUpdate();
} }
@ -1382,8 +1293,6 @@ void doMenu(){
} }
} //end of while } //end of while
//printLineF2(F("Changed Step!")); //remarked for reduce program memory by KD8CEC
//SAVE EEPROM
EEPROM.put(TUNING_STEP, tuneStepIndex); EEPROM.put(TUNING_STEP, tuneStepIndex);
delay_background(500, 0); delay_background(500, 0);
printLine2ClearAndUpdate(); printLine2ClearAndUpdate();
@ -1433,6 +1342,8 @@ void doMenu(){
menuSetup(btnState); menuSetup(btnState);
else if (select < 120) else if (select < 120)
menuExit(btnState); menuExit(btnState);
/*
else if (select < 130 && modeCalibrate) else if (select < 130 && modeCalibrate)
menuSetupCalibration(btnState); //crystal menuSetupCalibration(btnState); //crystal
else if (select < 140 && modeCalibrate) else if (select < 140 && modeCalibrate)
@ -1453,14 +1364,40 @@ void doMenu(){
menuTxOnOff(btnState, 0x01); //TX OFF / ON menuTxOnOff(btnState, 0x01); //TX OFF / ON
else if (select < 220 && modeCalibrate) else if (select < 220 && modeCalibrate)
menuExit(btnState); menuExit(btnState);
*/
else if (modeCalibrate)
{
if (select < 130)
menuSetupCalibration(btnState); //crystal
else if (select < 140)
menuSetupCarrier(btnState); //lsb
else if (select < 150)
menuSetupCWCarrier(btnState); //lsb
else if (select < 160)
menuSetupCwTone(btnState);
else if (select < 170)
menuSetupCwDelay(btnState);
else if (select < 180)
menuSetupTXCWInterval(btnState);
else if (select < 190)
menuSetupKeyType(btnState);
else if (select < 200)
menuADCMonitor(btnState);
else if (select < 210)
menuTxOnOff(btnState, 0x01); //TX OFF / ON
else if (select < 220)
menuExit(btnState);
}
Check_Cat(0); //To prevent disconnections Check_Cat(0); //To prevent disconnections
} }
/*
//debounce the button //debounce the button
while(btnDown()){ while(btnDown()){
delay_background(50, 0); //To prevent disconnections delay_background(50, 0); //To prevent disconnections
} }
//delay(50); */
} }

View File

@ -60,6 +60,7 @@ void i2cWriten(uint8_t reg, uint8_t *vals, uint8_t vcnt) { // write array
Wire.endTransmission(); Wire.endTransmission();
} }
uint8_t si5351Val[8] = {0, 1, 0, 0, 0, 0, 0, 0}; //for reduce program memory size
void si5351bx_init() { // Call once at power-up, start PLLA void si5351bx_init() { // Call once at power-up, start PLLA
uint32_t msxp1; uint32_t msxp1;
@ -68,11 +69,13 @@ void si5351bx_init() { // Call once at power-up, start PLLA
i2cWrite(3, si5351bx_clken); // Disable all CLK output drivers i2cWrite(3, si5351bx_clken); // Disable all CLK output drivers
i2cWrite(183, SI5351BX_XTALPF << 6); // Set 25mhz crystal load capacitance i2cWrite(183, SI5351BX_XTALPF << 6); // Set 25mhz crystal load capacitance
msxp1 = 128 * SI5351BX_MSA - 512; // and msxp2=0, msxp3=1, not fractional msxp1 = 128 * SI5351BX_MSA - 512; // and msxp2=0, msxp3=1, not fractional
uint8_t vals[8] = {0, 1, BB2(msxp1), BB1(msxp1), BB0(msxp1), 0, 0, 0}; //uint8_t vals[8] = {0, 1, BB2(msxp1), BB1(msxp1), BB0(msxp1), 0, 0, 0};
i2cWriten(26, vals, 8); // Write to 8 PLLA msynth regs si5351Val[2] = BB2(msxp1);
si5351Val[3] = BB1(msxp1);
si5351Val[4] = BB0(msxp1);
i2cWriten(26, si5351Val, 8); // Write to 8 PLLA msynth regs
i2cWrite(177, 0x20); // Reset PLLA (0x80 resets PLLB) i2cWrite(177, 0x20); // Reset PLLA (0x80 resets PLLB)
// for (reg=16; reg<=23; reg++) i2cWrite(reg, 0x80); // Powerdown CLK's
// i2cWrite(187, 0); // No fannout of clkin, xtal, ms0, ms4
} }
void si5351bx_setfreq(uint8_t clknum, uint32_t fout) { // Set a CLK to fout Hz void si5351bx_setfreq(uint8_t clknum, uint32_t fout) { // Set a CLK to fout Hz

View File

@ -327,22 +327,6 @@ void updateDisplay() {
lcd.setCursor(5,diplayVFOLine); lcd.setCursor(5,diplayVFOLine);
lcd.write(":"); lcd.write(":");
} }
/*
//now, the second line
memset(c, 0, sizeof(c));
memset(b, 0, sizeof(b));
if (inTx)
strcat(c, "TX ");
else if (ritOn)
strcpy(c, "RIT");
strcpy(c, " \xff");
drawMeter(meter_reading);
strcat(c, meter);
strcat(c, "\xff");
printLine2(c);*/
} }
int enc_prev_state = 3; int enc_prev_state = 3;