From 494bfa409e3bf073a70babfbe433fa74e4397180 Mon Sep 17 00:00:00 2001 From: Rob French Date: Tue, 28 Apr 2020 21:45:35 -0500 Subject: [PATCH 01/17] Made some changes to disable the keyer so it doesn't go into transmit mode when I start up. Doesn't seem to compile, however... --- ubitx_20/ubitx.h | 4 ++-- ubitx_20/ubitx_keyer.ino | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ubitx_20/ubitx.h b/ubitx_20/ubitx.h index 958e4c4..3dbb4fb 100644 --- a/ubitx_20/ubitx.h +++ b/ubitx_20/ubitx.h @@ -48,8 +48,8 @@ //#define USE_CUSTOM_LPF_FILTER //LPF FILTER MOD //#define ENABLE_FACTORYALIGN -#define FACTORY_RECOVERY_BOOTUP //Whether to enter Factory Recovery mode by pressing FKey and turning on power -#define ENABLE_ADCMONITOR //Starting with Version 1.07, you can read ADC values directly from uBITX Manager. So this function is not necessary. +//#define FACTORY_RECOVERY_BOOTUP //Whether to enter Factory Recovery mode by pressing FKey and turning on power +//#define ENABLE_ADCMONITOR //Starting with Version 1.07, you can read ADC values directly from uBITX Manager. So this function is not necessary. extern byte I2C_LCD_MASTER_ADDRESS; //0x27 //if Set I2C Address by uBITX Manager, read from EEProm extern byte I2C_LCD_SECOND_ADDRESS; //only using Dual LCD Mode diff --git a/ubitx_20/ubitx_keyer.ino b/ubitx_20/ubitx_keyer.ino index 1ac1c2f..e3477fb 100644 --- a/ubitx_20/ubitx_keyer.ino +++ b/ubitx_20/ubitx_keyer.ino @@ -98,7 +98,7 @@ unsigned char keyerState = IDLE; char update_PaddleLatch(byte isUpdateKeyState) { unsigned char tmpKeyerControl = 0; int paddle = analogRead(ANALOG_KEYER); - +/* KC4UPR: temporarily disabling keyer while doing ubitx_iop development. if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo) tmpKeyerControl |= DAH_L; else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo) @@ -120,7 +120,7 @@ char update_PaddleLatch(byte isUpdateKeyState) { return tmpKeyerControl; } - +*/ /***************************************************************************** // New logic, by RON // modified by KD8CEC @@ -365,5 +365,3 @@ void cwKeyer(){ } } */ - - From 913f1d078166c48b93701ddc5eeb05004a54f1e6 Mon Sep 17 00:00:00 2001 From: Rob French Date: Tue, 28 Apr 2020 21:56:47 -0500 Subject: [PATCH 02/17] Misc small changes. --- ubitx_20/ubitx_keyer.ino | 6 ++++-- ubitx_20/ubitx_lcd_nextion.ino | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ubitx_20/ubitx_keyer.ino b/ubitx_20/ubitx_keyer.ino index e3477fb..c38d2e3 100644 --- a/ubitx_20/ubitx_keyer.ino +++ b/ubitx_20/ubitx_keyer.ino @@ -98,7 +98,9 @@ unsigned char keyerState = IDLE; char update_PaddleLatch(byte isUpdateKeyState) { unsigned char tmpKeyerControl = 0; int paddle = analogRead(ANALOG_KEYER); -/* KC4UPR: temporarily disabling keyer while doing ubitx_iop development. + + return 0; // KC4UPR: temporarily disabling keyer while doing ubitx_iop development. + if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo) tmpKeyerControl |= DAH_L; else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo) @@ -120,7 +122,7 @@ char update_PaddleLatch(byte isUpdateKeyState) { return tmpKeyerControl; } -*/ + /***************************************************************************** // New logic, by RON // modified by KD8CEC diff --git a/ubitx_20/ubitx_lcd_nextion.ino b/ubitx_20/ubitx_lcd_nextion.ino index 4c0a91a..62667af 100644 --- a/ubitx_20/ubitx_lcd_nextion.ino +++ b/ubitx_20/ubitx_lcd_nextion.ino @@ -1041,7 +1041,7 @@ void SendUbitxData(void) EEPROM.get(EXTERNAL_DEVICE_OPT1, nextionDisplayOption); SendCommandUL(CMD_DISP_OPTION2, nextionDisplayOption); - SendCommandStr(CMD_VERSION, (char *)("+v1.122")); //Version + SendCommandStr(CMD_VERSION, (char *)("+v1.200")); //Version SendEEPromData(CMD_CALLSIGN, 0, userCallsignLength -1, 0); /* From 44c6c868380a33106cc482118189a5c4fb4316ff Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 3 May 2020 22:00:02 -0500 Subject: [PATCH 03/17] Updated CAT to support interoperability with uBITX I/O Processor (IOP). --- ubitx_20/cat_libs.ino | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 608af79..e467f1b 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -48,6 +48,11 @@ #define CAT_MODE_FMN 0x88 #define ACK 0 +// KC4UPR--uBITX IOP: prefixes to determine "mode" of serial transmission +#define CAT_PREFIX 0xC0 +#define IOP_PREFIX 0xD0 +#define EEPROM_READ_PREFIX 0xE0 +#define EEPROM_WRITE_PREFIX 0xF0 unsigned int skipTimeCount = 0; byte CAT_BUFF[5]; @@ -55,6 +60,14 @@ byte CAT_SNDBUFF[5]; void SendCatData(byte sendCount) { + // KC4UPR--uBITX IOP: Adding an additional byte at the beginning that + // indicates that this is a "CAT mode" transmission. Extra byte includes + // a prefix, as well as the number of bytes being sent. + // + // NOTE: Need to do some error checking at some point to ensure we don't + // try to send more than 15 bytes!!! + Serial.write(CAT_PREFIX | sendCount); + for (byte i = 0; i < sendCount; i++) Serial.write(CAT_BUFF[i]); //Serial.flush(); @@ -250,6 +263,15 @@ void ReadEEPRom() //for remove warnings. byte checkSum = 0; byte read1Byte = 0; + // KC4UPR--uBITX IOP: Adding an additional byte at the beginning that + // indicates that this is a "Memory Manager mode" transmission. + // Then we repeat some of the CAT_BUFF data. + Serial.write(EEPROM_READ_PREFIX); + Serial.write(CAT_BUFF[0]); + Serial.write(CAT_BUFF[1]); + Serial.write(CAT_BUFF[2]); + Serial.write(CAT_BUFF[3]); + Serial.write(0x02); //STX checkSum = 0x02; //I2C Scanner @@ -293,6 +315,12 @@ void WriteEEPRom(void) //for remove warning uint16_t eepromStartIndex = CAT_BUFF[0] + CAT_BUFF[1] * 256; byte write1Byte = CAT_BUFF[2]; + // KC4UPR--uBITX IOP: Adding an additional byte at the beginning that + // indicates that this is a "Memory Manager mode" transmission. + // + // Also indicates that we are going to be sending two bytes of data. + Serial.write(EEPROM_WRITE_PREFIX | 2); + //Check Checksum if (CAT_BUFF[3] != ((CAT_BUFF[0] + CAT_BUFF[1] + CAT_BUFF[2]) % 256)) { @@ -890,4 +918,3 @@ void Init_Cat(long baud, int portConfig) Serial.begin(baud, portConfig); Serial.flush(); } - From 1aa9ce1bd6c5e28515bac891a94f4871a283e13a Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 3 May 2020 23:04:02 -0500 Subject: [PATCH 04/17] In theory, the code has now been modified to allow CW transmission when used with the IOP. However, at the moment, there is no way to put the IOP into CW mode. Intended behavior: PTT/Key in SSB = transmit (PTT) PTT/Key in CW = key down --- ubitx_20/ubitx_20.ino | 48 ++++++-- ubitx_20/ubitx_keyer.ino | 240 ++++++++++++++++++++++----------------- 2 files changed, 178 insertions(+), 110 deletions(-) diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index 2066939..c78da97 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -316,6 +316,17 @@ unsigned long delayBeforeTime = 0; byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWKey -> Check Paddle delayBeforeTime = millis(); + /* + * KC4UPR - IOP review, 2020-05-03 + * + * I don't see anything in here that is either important to, or will adversely affect, IOP + * operation. I'm not planning on using the uBITX autokeyer (since all keying will be in the + * IOP), so neither getPaddle() nor autoSendPTTCheck() will be issues. I do need to look into + * overall CAT operation, in general. + * + * UPDATE: Fixed getPaddle() to be compatible. + */ + while (millis() - delayBeforeTime <= delayTime) { if (fromType == 4) @@ -678,6 +689,10 @@ void ritDisable(){ */ void checkPTT(){ + /* + * KC4UPR - note that some of this is superfluous now that checkPTT() is only executed + * in SSB mode, and cwKeyer is only executed in CW mode... + */ //we don't check for ptt when transmitting cw if (cwTimeout > 0) return; @@ -1459,15 +1474,34 @@ void checkAutoSaveFreqMode() } void loop(){ - if (isCWAutoMode == 0){ //when CW AutoKey Mode, disable this process - if (!txCAT) + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Getting rid of the autokeyer code... not planning on using, since any autokeying + * would actually be done by the IOP. We'll check the PTT, but only in SSB mode + * (same line as CW, so it would be caught by cwKeyer() in CW mode). + * + * Only check the CW keyer if we are in one of the CW modes. Why? Because we + * are using the same input for PTT and CW. + */ +// if (isCWAutoMode == 0){ //when CW AutoKey Mode, disable this process +// if (!txCAT) +// checkPTT(); +// checkButton(); +// } +// else +// controlAutoCW(); + // KC4UPR: Note, implementation below leaves no manual way to abort TX due to CAT. May + // want to add in a way to interrupt CAT transmission with a PTT/CW event. + if (!txCAT) { + if (cwMode == 0) checkPTT(); - checkButton(); + else + cwKeyer(); + checkButton(); } - else - controlAutoCW(); - - cwKeyer(); + +//cwKeyer(); //tune only when not tranmsitting if (!inTx){ diff --git a/ubitx_20/ubitx_keyer.ino b/ubitx_20/ubitx_keyer.ino index c38d2e3..691b1d0 100644 --- a/ubitx_20/ubitx_keyer.ino +++ b/ubitx_20/ubitx_keyer.ino @@ -39,6 +39,22 @@ char lastPaddle = 0; //reads the analog keyer pin and reports the paddle byte getPaddle(){ + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Modifying this for the uBITX IOP. Big picture: + * + * (1) It uses the PTT input line. + * + * (2) It's always "straight key" mode (the IOP provides the keyer). + */ + + if (digitalRead(PTT) == 1) // key/PTT is up + return 0; + else + return PADDLE_STRAIGHT; + +/* int paddle = analogRead(ANALOG_KEYER); if (paddle > 800) // above 4v is up @@ -52,6 +68,7 @@ byte getPaddle(){ return PADDLE_BOTH; //both are between 1 and 2v else return PADDLE_STRAIGHT; //less than 1v is the straight key +*/ } /** @@ -96,11 +113,20 @@ unsigned char keyerState = IDLE; //Below is a test to reduce the keying error. do not delete lines //create by KD8CEC for compatible with new CW Logic char update_PaddleLatch(byte isUpdateKeyState) { + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Modifying this for the uBITX IOP. Big picture: + * + * No iambic keyer. It's always "straight key" based on the IOP. + * + * It uses the PTT line. + */ + return (digitalRead(PTT) ? 0 : DIT_L); +/* unsigned char tmpKeyerControl = 0; int paddle = analogRead(ANALOG_KEYER); - return 0; // KC4UPR: temporarily disabling keyer while doing ubitx_iop development. - if (paddle >= cwAdcDashFrom && paddle <= cwAdcDashTo) tmpKeyerControl |= DAH_L; else if (paddle >= cwAdcDotFrom && paddle <= cwAdcDotTo) @@ -121,6 +147,7 @@ char update_PaddleLatch(byte isUpdateKeyState) { keyerControl |= tmpKeyerControl; return tmpKeyerControl; +*/ } /***************************************************************************** @@ -128,106 +155,113 @@ char update_PaddleLatch(byte isUpdateKeyState) { // modified by KD8CEC ******************************************************************************/ void cwKeyer(void){ - lastPaddle = 0; - bool continue_loop = true; - unsigned tmpKeyControl = 0; - - if( Iambic_Key ) { - while(continue_loop) { - switch (keyerState) { - case IDLE: - tmpKeyControl = update_PaddleLatch(0); - if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L || - tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) { - update_PaddleLatch(1); - keyerState = CHK_DIT; - }else{ - if (0 < cwTimeout && cwTimeout < millis()){ - cwTimeout = 0; - stopTx(); - } - continue_loop = false; - } - break; - - case CHK_DIT: - if (keyerControl & DIT_L) { - keyerControl |= DIT_PROC; - ktimer = cwSpeed; - keyerState = KEYED_PREP; - }else{ - keyerState = CHK_DAH; - } - break; - - case CHK_DAH: - if (keyerControl & DAH_L) { - ktimer = cwSpeed*3; - keyerState = KEYED_PREP; - }else{ - keyerState = IDLE; - } - break; - - case KEYED_PREP: - //modified KD8CEC - /* - ktimer += millis(); // set ktimer to interval end time - keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits - keyerState = KEYED; // next state - if (!inTx){ - //DelayTime Option - delay_background(delayBeforeCWStartTime * 2, 2); - - keyDown = 0; - cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; - startTx(TX_CW, 1); - } - */ - if (!inTx){ - //DelayTime Option - delay_background(delayBeforeCWStartTime * 2, 2); - - keyDown = 0; - cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; - startTx(TX_CW, 1); - } - ktimer += millis(); // set ktimer to interval end time - keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits - keyerState = KEYED; // next state - - cwKeydown(); - break; - - case KEYED: - if (millis() > ktimer) { // are we at end of key down ? - cwKeyUp(); - ktimer = millis() + cwSpeed; // inter-element time - keyerState = INTER_ELEMENT; // next state - }else if (keyerControl & IAMBICB) { - update_PaddleLatch(1); // early paddle latch in Iambic B mode - } - break; - - case INTER_ELEMENT: - // Insert time between dits/dahs - update_PaddleLatch(1); // latch paddle state - if (millis() > ktimer) { // are we at end of inter-space ? - if (keyerControl & DIT_PROC) { // was it a dit or dah ? - keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits - keyerState = CHK_DAH; // dit done, check for dah - }else{ - keyerControl &= ~(DAH_L); // clear dah latch - keyerState = IDLE; // go idle - } - } - break; - } - - Check_Cat(2); - } //end of while - } - else{ + /* + * KC4UPR - IOP update, 2020-05-03 + * + * Modifying this for the uBITX IOP. Big picture: + * + * No iambic keyer. It's always "straight key" based on the IOP. + */ +// lastPaddle = 0; +// bool continue_loop = true; +// unsigned tmpKeyControl = 0; +// +// if( Iambic_Key ) { +// while(continue_loop) { +// switch (keyerState) { +// case IDLE: +// tmpKeyControl = update_PaddleLatch(0); +// if ( tmpKeyControl == DAH_L || tmpKeyControl == DIT_L || +// tmpKeyControl == (DAH_L | DIT_L) || (keyerControl & 0x03)) { +// update_PaddleLatch(1); +// keyerState = CHK_DIT; +// }else{ +// if (0 < cwTimeout && cwTimeout < millis()){ +// cwTimeout = 0; +// stopTx(); +// } +// continue_loop = false; +// } +// break; +// +// case CHK_DIT: +// if (keyerControl & DIT_L) { +// keyerControl |= DIT_PROC; +// ktimer = cwSpeed; +// keyerState = KEYED_PREP; +// }else{ +// keyerState = CHK_DAH; +// } +// break; +// +// case CHK_DAH: +// if (keyerControl & DAH_L) { +// ktimer = cwSpeed*3; +// keyerState = KEYED_PREP; +// }else{ +// keyerState = IDLE; +// } +// break; +// +// case KEYED_PREP: +// //modified KD8CEC +// /* +// ktimer += millis(); // set ktimer to interval end time +// keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits +// keyerState = KEYED; // next state +// if (!inTx){ +// //DelayTime Option +// delay_background(delayBeforeCWStartTime * 2, 2); +// +// keyDown = 0; +// cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; +// startTx(TX_CW, 1); +// } +// */ +// if (!inTx){ +// //DelayTime Option +// delay_background(delayBeforeCWStartTime * 2, 2); +// +// keyDown = 0; +// cwTimeout = millis() + cwDelayTime * 10; //+ CW_TIMEOUT; +// startTx(TX_CW, 1); +// } +// ktimer += millis(); // set ktimer to interval end time +// keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits +// keyerState = KEYED; // next state +// +// cwKeydown(); +// break; +// +// case KEYED: +// if (millis() > ktimer) { // are we at end of key down ? +// cwKeyUp(); +// ktimer = millis() + cwSpeed; // inter-element time +// keyerState = INTER_ELEMENT; // next state +// }else if (keyerControl & IAMBICB) { +// update_PaddleLatch(1); // early paddle latch in Iambic B mode +// } +// break; +// +// case INTER_ELEMENT: +// // Insert time between dits/dahs +// update_PaddleLatch(1); // latch paddle state +// if (millis() > ktimer) { // are we at end of inter-space ? +// if (keyerControl & DIT_PROC) { // was it a dit or dah ? +// keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits +// keyerState = CHK_DAH; // dit done, check for dah +// }else{ +// keyerControl &= ~(DAH_L); // clear dah latch +// keyerState = IDLE; // go idle +// } +// } +// break; +// } +// +// Check_Cat(2); +// } //end of while +// } +// else{ while(1){ if (update_PaddleLatch(0) == DIT_L) { // if we are here, it is only because the key is pressed @@ -264,7 +298,7 @@ void cwKeyer(void){ Check_Cat(2); } //end of while - } //end of elese +// } //end of elese } From 7ba147b06dd918816ae3598fcba0a92d98d774ad Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 3 May 2020 23:30:44 -0500 Subject: [PATCH 05/17] Added ability to send a command to the IOP, specifically a mode change command (to SSB, DIGI, or CW; although DIGI is currently not actually possible). --- ubitx_20/cat_libs.ino | 26 ++++++++++++++++++++++++++ ubitx_20/ubitx_menu.ino | 2 ++ 2 files changed, 28 insertions(+) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index e467f1b..13b3ab4 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -54,6 +54,32 @@ #define EEPROM_READ_PREFIX 0xE0 #define EEPROM_WRITE_PREFIX 0xF0 +#define IOP_MODE_COMMAND 0x00 +#define IOP_MODE_SSB 0x01 +#define IOP_MODE_DIGI 0x02 +#define IOP_MODE_CW 0x03 + +/* + * KC4UPR - IOP update, 2020-05-03 + * + * Send the current mode to the I/O Processor. + * + * NOTE: This all needs to be expanded to include digital... + * + * NOTE: Not yet called from CAT, only from menu... + */ +void iopSendMode(char is_cw, char is_usb) +{ + byte mode; + + Serial.write(IOP_PREFIX | 2); + Serial.write(IOP_MODE_COMMAND); + if (is_cw) + mode = IOP_MODE_CW; + else + mode = IOP_MODE_SSB; +} + unsigned int skipTimeCount = 0; byte CAT_BUFF[5]; byte CAT_SNDBUFF[5]; diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index 502bd94..4bec378 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -960,6 +960,8 @@ void menuSelectMode(int btn){ else if (selectModeType == 3) { cwMode = 2; } + // KC4UPR: sending mode to IOP + iopSendMode(cwMode, isUSB); FrequencyToVFO(1); } From c8b2110052c00d79d4ec8f18fdd90ba82794c950 Mon Sep 17 00:00:00 2001 From: Rob French Date: Fri, 8 May 2020 00:16:59 -0500 Subject: [PATCH 06/17] Successful communication between Raduino and IOP. Digi modes working. Have a high-pitched whine in RX audio, however (IOP problem, not Raduino). --- ubitx_20/cat_libs.ino | 44 +++++++++++--- ubitx_20/ubitx.h | 4 +- ubitx_20/ubitx_20.ino | 7 ++- ubitx_20/ubitx_lcd_1602.ino | 17 ++++-- ubitx_20/ubitx_menu.ino | 112 +++++++++++++++++++++++++++--------- 5 files changed, 141 insertions(+), 43 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 13b3ab4..354f5e0 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -54,30 +54,49 @@ #define EEPROM_READ_PREFIX 0xE0 #define EEPROM_WRITE_PREFIX 0xF0 -#define IOP_MODE_COMMAND 0x00 -#define IOP_MODE_SSB 0x01 -#define IOP_MODE_DIGI 0x02 -#define IOP_MODE_CW 0x03 +#define IOP_MODE_COMMAND 0x00 +#define IOP_START_TX_COMMAND 0x01 +#define IOP_STOP_TX_COMMAND 0x02 +#define IOP_MODE_SSB 0x00 +#define IOP_MODE_DIGI 0x01 +#define IOP_MODE_CW 0x02 /* * KC4UPR - IOP update, 2020-05-03 * * Send the current mode to the I/O Processor. * - * NOTE: This all needs to be expanded to include digital... - * * NOTE: Not yet called from CAT, only from menu... */ -void iopSendMode(char is_cw, char is_usb) +void iopSendMode(char cw_mode, char is_usb, char digi_mode) { byte mode; Serial.write(IOP_PREFIX | 2); Serial.write(IOP_MODE_COMMAND); - if (is_cw) + if (cw_mode > 0) mode = IOP_MODE_CW; + else if (digi_mode > 0) + mode = IOP_MODE_DIGI; else mode = IOP_MODE_SSB; + Serial.write(mode); +} + +// Used to tell the IOP that we're transmitting, when it came via +// CAT (otherwise, IOP is the one who tells Raduino to start TX!). +void iopStartTx() +{ + Serial.write(IOP_PREFIX | 1); + Serial.write(IOP_START_TX_COMMAND); +} + +// Used to tell the IOP to stop transmitting, when it came via +// CAT (otherwise, IOP is the one who tells Raduino to stop TX!). +void iopStopTx() +{ + Serial.write(IOP_PREFIX | 1); + Serial.write(IOP_STOP_TX_COMMAND); } unsigned int skipTimeCount = 0; @@ -202,7 +221,8 @@ void CatSetSplit(boolean isSplit) //for remove warning messages void CatSetPTT(boolean isPTTOn, byte fromType) { - // + // KC4UPR - so I think this means, that if we're currently processing a CW keyer (auto/manual), + // not to accept a CAT command in the middle of it. if ((!inTx) && (fromType == 2 || fromType == 3)) { Serial.write(ACK); return; @@ -215,6 +235,9 @@ void CatSetPTT(boolean isPTTOn, byte fromType) { txCAT = true; + // KC4UPR - added the next line to tell the IOP we're transmitting + iopStartTx(); + startTx(TX_SSB, 1); //Exit menu, Memory Keyer... ETC if (isCWAutoMode > 0) { @@ -228,6 +251,9 @@ void CatSetPTT(boolean isPTTOn, byte fromType) { if (inTx) { + // KC4UPR - added the next line to tell the IOP we're not transmitting + iopStopTx(); + stopTx(); txCAT = false; } diff --git a/ubitx_20/ubitx.h b/ubitx_20/ubitx.h index 3dbb4fb..427a99e 100644 --- a/ubitx_20/ubitx.h +++ b/ubitx_20/ubitx.h @@ -310,8 +310,8 @@ extern void printLineF(char linenmbr, const __FlashStringHelper *c); extern void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetType); extern byte delay_background(unsigned delayTime, byte fromType); extern int btnDown(void); -extern char c[30]; -extern char b[30]; +extern char c[40]; +extern char b[40]; extern int enc_read(void); extern void si5351bx_init(void); extern void si5351bx_setfreq(uint8_t clknum, uint32_t fout); diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index c78da97..4fb2bcd 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -191,10 +191,15 @@ boolean txCAT = false; //turned on if the transmitting due to a CAT comma char inTx = 0; //it is set to 1 if in transmit mode (whatever the reason : cw, ptt or cat) char splitOn = 0; //working split, uses VFO B as the transmit frequency char keyDown = 0; //in cw mode, denotes the carrier is being transmitted -char isUSB = 0; //upper sideband was selected, this is reset to the default for the +char isUSB = 0; //upper sideband was selected, this is reset to the default for the char cwMode = 0; //compatible original source, and extend mode //if cwMode == 0, mode check : isUSB, cwMode > 0, mode Check : cwMode //iscwMode = 0 : ssbmode, 1 :cwl, 2 : cwu, 3 : cwn (none tx) +char digiMode = 0; // 0: normal uBITX behavior (transmit LSB/USB when PTT is depressed) + // 1: user-defined digital mode via USB audio input; DTU (default) USB if isUSB; DTL LSB if !isUSB + // Effect of non-zero digiMode on ubitx software: should disable the physical PTT inputs (front/back), + // but might need to consider physical PTT as a way to stop CAT-based transmission. Also affects the mode + // info sent to the IOP. //frequency when it crosses the frequency border of 10 MHz byte menuOn = 0; //set to 1 when the menu is being displayed, if a menu item sets it to zero, the menu is exited diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index 76f2e5b..1f669ad 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -282,7 +282,7 @@ void LCD_CreateChar(uint8_t location, uint8_t charmap[]) //SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA #define OPTION_SKINNYBARS -char c[30], b[30]; +char c[40], b[40]; char printBuff[2][17]; //mirrors what is showing on the two lines of the display @@ -438,10 +438,17 @@ void updateDisplay() { else { if (cwMode == 0) { - if (isUSB) - strcpy(c, "USB "); - else - strcpy(c, "LSB "); + if (digiMode == 1) { + if (isUSB) + strcpy(c, "DGU "); + else + strcpy(c, "DGL "); + } else { + if (isUSB) + strcpy(c, "USB "); + else + strcpy(c, "LSB "); + } } else if (cwMode == 1) { diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index 4bec378..dd5a4cb 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -131,9 +131,9 @@ byte modeToByte(){ if (cwMode == 0) { if (isUSB) - return 3; + return 3 + (digiMode > 0 ? 3 + digiMode : 0); else - return 2; + return 2 + (digiMode > 0 ? 3 + digiMode : 0); } else if (cwMode == 1) { @@ -149,20 +149,56 @@ byte modeToByte(){ //autoSetModebyFreq : 0 //autoSetModebyFreq : 1, if (modValue is not set, set mode by frequency) void byteToMode(byte modeValue, byte autoSetModebyFreq){ - if (modeValue == 4) - cwMode = 1; - else if (modeValue == 5) - cwMode = 2; - else - { + isUSB = false; + cwMode = 0; + digiMode = 0; + + if (autoSetModebyFreq == 1 && (modeValue == 0)) { + isUSB = (frequency > 10000000l) ? true : false; + } else { + switch(modeValue) { + // LSB by default, so we can skip this case + //case 2: // LSB + //break; + + case 3: // USB + isUSB = true; + break; + + case 4: // CWL + cwMode = 1; + break; + + case 5: // CWU + cwMode = 2; + break; + + case 6: // DGL + digiMode = 1; + break; + + case 7: // DGU + isUSB = true; + digiMode = 1; + break; + } + } +/* if (modeValue == 4) { + cwMode = 1; digiMode = 0; + } else if (modeValue == 5) { + cwMode = 2; digiMode = 0; + } else { cwMode = 0; - if (modeValue == 3) - isUSB = 1; + if (modeValue == 3) { + isUSB = 1; digiMode = 0; + } else if (modeValue == 6) { + isUSB = + } else if (autoSetModebyFreq == 1 && (modeValue == 0)) isUSB = (frequency > 10000000l) ? true : false; else isUSB = 0; - } + }*/ } @@ -651,12 +687,19 @@ int getValueByKnob(int valueType, int targetValue, int minKnobValue, int maxKnob moveDetectStep = 0; } - strcpy(b, displayTitle); - if (valueType == 11) //Mode Select { - b[targetValue * 4] = '>'; - } + int tmpCol = targetValue * 4; + if (tmpCol >= 16) { + tmpCol -= 16; + strcpy(b, &displayTitle[16]); + } else { + strcpy(b, displayTitle); + } + b[tmpCol] = '>'; + } else { + strcpy(b, displayTitle); + /* else if (valueType == 4) //CW Key Type Select { @@ -668,8 +711,6 @@ int getValueByKnob(int valueType, int targetValue, int minKnobValue, int maxKnob strcat(b, "IAMBICB"); } */ - else - { strcat(b, ":"); itoa(targetValue,c, 10); strcat(b, c); @@ -932,36 +973,55 @@ void menuSelectMode(int btn){ } else { - //LSB, USB, CWL, CWU - if (cwMode == 0 && isUSB == 0) + //LSB, USB, CWL, CWU, DGL, DGU + if (cwMode == 0) { + if (isUSB == 0) { + selectModeType = 0; // LSB + } else { + selectModeType = 1; // USB + } + // modify if digital mode is set + if (digiMode > 0) { + selectModeType += (3 + digiMode); + } + } else if (cwMode == 1) { + selectModeType = 2; // CWL + } else { + selectModeType = 3; // CWU + } + /*if (cwMode == 0 && isUSB == 0) selectModeType = 0; else if (cwMode == 0 && isUSB == 1) selectModeType = 1; else if (cwMode == 1) selectModeType = 2; else - selectModeType = 3; + selectModeType = 3;*/ beforeMode = selectModeType; - selectModeType = getValueByKnob(11, selectModeType, 0, 3, 1, " LSB USB CWL CWU", 4); //3 : Select Mode, targetValue, minKnobValue, maxKnobValue, stepSize + selectModeType = getValueByKnob(11, selectModeType, 0, 5, 1, " LSB USB CWL CWU DGL DGU ", 4); //3 : Select Mode, targetValue, minKnobValue, maxKnobValue, stepSize if (beforeMode != selectModeType) { //printLineF1(F("Changed Mode")); if (selectModeType == 0) { - cwMode = 0; isUSB = 0; + cwMode = 0; isUSB = 0; digiMode = 0; } else if (selectModeType == 1) { - cwMode = 0; isUSB = 1; + cwMode = 0; isUSB = 1; digiMode = 0; } else if (selectModeType == 2) { - cwMode = 1; + cwMode = 1; digiMode = 0; } else if (selectModeType == 3) { - cwMode = 2; + cwMode = 2; digiMode = 0; + } else if (selectModeType == 4) { + cwMode = 0; isUSB = 0; digiMode = 1; + } else if (selectModeType == 5) { + cwMode = 0; isUSB = 1; digiMode = 1; } // KC4UPR: sending mode to IOP - iopSendMode(cwMode, isUSB); + iopSendMode(cwMode, isUSB, digiMode); FrequencyToVFO(1); } From 681e01d019e7779fd046ff133b730bc20cdcd5c0 Mon Sep 17 00:00:00 2001 From: Rob French Date: Sat, 16 May 2020 23:51:46 -0500 Subject: [PATCH 07/17] Updates to be compatible with iopcomm.h/iopcomm.cpp, and with the new two-tone test mode. --- ubitx_20/cat_libs.ino | 100 ++++++++++++++++-------------------- ubitx_20/ubitx_20.ino | 3 +- ubitx_20/ubitx_lcd_1602.ino | 5 ++ ubitx_20/ubitx_menu.ino | 45 ++++++++++------ 4 files changed, 81 insertions(+), 72 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 354f5e0..eb39c43 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -32,6 +32,8 @@ **************************************************************************/ +#include + #include "ubitx.h" //for broken protocol @@ -48,55 +50,25 @@ #define CAT_MODE_FMN 0x88 #define ACK 0 -// KC4UPR--uBITX IOP: prefixes to determine "mode" of serial transmission -#define CAT_PREFIX 0xC0 -#define IOP_PREFIX 0xD0 -#define EEPROM_READ_PREFIX 0xE0 -#define EEPROM_WRITE_PREFIX 0xF0 - -#define IOP_MODE_COMMAND 0x00 -#define IOP_START_TX_COMMAND 0x01 -#define IOP_STOP_TX_COMMAND 0x02 -#define IOP_MODE_SSB 0x00 -#define IOP_MODE_DIGI 0x01 -#define IOP_MODE_CW 0x02 /* * KC4UPR - IOP update, 2020-05-03 * * Send the current mode to the I/O Processor. - * - * NOTE: Not yet called from CAT, only from menu... */ -void iopSendMode(char cw_mode, char is_usb, char digi_mode) +void iopSendMode(char cw_mode, char is_usb, char digi_mode, char is_test) { byte mode; - Serial.write(IOP_PREFIX | 2); - Serial.write(IOP_MODE_COMMAND); if (cw_mode > 0) - mode = IOP_MODE_CW; + mode = MODE_CW; else if (digi_mode > 0) - mode = IOP_MODE_DIGI; + mode = MODE_DIGI; + else if (is_test) + mode = MODE_TEST; else - mode = IOP_MODE_SSB; - Serial.write(mode); -} - -// Used to tell the IOP that we're transmitting, when it came via -// CAT (otherwise, IOP is the one who tells Raduino to start TX!). -void iopStartTx() -{ - Serial.write(IOP_PREFIX | 1); - Serial.write(IOP_START_TX_COMMAND); -} - -// Used to tell the IOP to stop transmitting, when it came via -// CAT (otherwise, IOP is the one who tells Raduino to stop TX!). -void iopStopTx() -{ - Serial.write(IOP_PREFIX | 1); - Serial.write(IOP_STOP_TX_COMMAND); + mode = MODE_SSB; + sendIOPModeCommand(mode); } unsigned int skipTimeCount = 0; @@ -111,7 +83,7 @@ void SendCatData(byte sendCount) // // NOTE: Need to do some error checking at some point to ensure we don't // try to send more than 15 bytes!!! - Serial.write(CAT_PREFIX | sendCount); + Serial.write(prefixAndLengthToByte(CAT_PREFIX, sendCount)); for (byte i = 0; i < sendCount; i++) Serial.write(CAT_BUFF[i]); @@ -236,7 +208,7 @@ void CatSetPTT(boolean isPTTOn, byte fromType) txCAT = true; // KC4UPR - added the next line to tell the IOP we're transmitting - iopStartTx(); + sendIOPStartTxCommand(); startTx(TX_SSB, 1); //Exit menu, Memory Keyer... ETC @@ -252,7 +224,7 @@ void CatSetPTT(boolean isPTTOn, byte fromType) if (inTx) { // KC4UPR - added the next line to tell the IOP we're not transmitting - iopStopTx(); + sendIOPStopTxCommand(); stopTx(); txCAT = false; @@ -281,21 +253,33 @@ void CatSetMode(byte tmpMode, byte fromType) if (!inTx) { - if (tmpMode == CAT_MODE_CW) - { - cwMode = 1; - } - else if (tmpMode == CAT_MODE_USB) - { - cwMode = 0; - isUSB = true; - } - else - { - cwMode = 0; - isUSB = false; - } + switch(tmpMode) { + case CAT_MODE_CW: + cwMode = 2; // should be CWU + break; + case CAT_MODE_CWR: + cwMode = 1; // should be CWL + break; + + case CAT_MODE_USB: + cwMode = 0; + digiMode = 0; + isUSB = true; + break; + + case CAT_MODE_LSB: + cwMode = 0; + digiMode = 0; + isUSB = false; + break; + + case CAT_MODE_DIG: + cwMode = 0; + digiMode = 1; + isUSB = true; // DGU - but need to eventually use the FT-817 customization + } + iopSendMode(cwMode, isUSB, digiMode, isTest); setFrequency(frequency); updateDisplay(); } @@ -318,7 +302,7 @@ void ReadEEPRom() //for remove warnings. // KC4UPR--uBITX IOP: Adding an additional byte at the beginning that // indicates that this is a "Memory Manager mode" transmission. // Then we repeat some of the CAT_BUFF data. - Serial.write(EEPROM_READ_PREFIX); + Serial.write(prefixAndLengthToByte(RAD_EEPROM_READ_PREFIX, 5)); Serial.write(CAT_BUFF[0]); Serial.write(CAT_BUFF[1]); Serial.write(CAT_BUFF[2]); @@ -371,7 +355,7 @@ void WriteEEPRom(void) //for remove warning // indicates that this is a "Memory Manager mode" transmission. // // Also indicates that we are going to be sending two bytes of data. - Serial.write(EEPROM_WRITE_PREFIX | 2); + Serial.write(prefixAndLengthToByte(RAD_EEPROM_WRITE_PREFIX, 2)); //Check Checksum if (CAT_BUFF[3] != ((CAT_BUFF[0] + CAT_BUFF[1] + CAT_BUFF[2]) % 256)) @@ -969,4 +953,8 @@ void Init_Cat(long baud, int portConfig) { Serial.begin(baud, portConfig); Serial.flush(); + + // At start, immediately send mode to IOP. Currently, IOP has no way to + // request the mode. + iopSendMode(cwMode, isUSB, digiMode, isTest); } diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index 4fb2bcd..fc9cfee 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -1,4 +1,4 @@ - //Firmware Version +//Firmware Version //+ : This symbol identifies the firmware. // It was originally called 'CEC V1.072' but it is too long to waste the LCD window. // I do not want to make this Firmware users's uBITX messy with my callsign. @@ -193,6 +193,7 @@ char splitOn = 0; //working split, uses VFO B as the transmit freque char keyDown = 0; //in cw mode, denotes the carrier is being transmitted char isUSB = 0; //upper sideband was selected, this is reset to the default for the +char isTest = 0; // two-tone test mode char cwMode = 0; //compatible original source, and extend mode //if cwMode == 0, mode check : isUSB, cwMode > 0, mode Check : cwMode //iscwMode = 0 : ssbmode, 1 :cwl, 2 : cwu, 3 : cwn (none tx) char digiMode = 0; // 0: normal uBITX behavior (transmit LSB/USB when PTT is depressed) diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index 1f669ad..f4fb70a 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -443,6 +443,11 @@ void updateDisplay() { strcpy(c, "DGU "); else strcpy(c, "DGL "); + } else if (isTest == 1) { + if (isUSB) + strcpy(c, "TTU "); + else + strcpy(c, "TTL "); } else { if (isUSB) strcpy(c, "USB "); diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index dd5a4cb..d177b61 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -149,6 +149,7 @@ byte modeToByte(){ //autoSetModebyFreq : 0 //autoSetModebyFreq : 1, if (modValue is not set, set mode by frequency) void byteToMode(byte modeValue, byte autoSetModebyFreq){ + isTest = false; // test never settable from EEPROM isUSB = false; cwMode = 0; digiMode = 0; @@ -181,6 +182,15 @@ void byteToMode(byte modeValue, byte autoSetModebyFreq){ isUSB = true; digiMode = 1; break; +/* + case 8: // TTL + isUSB = false; + break; + + case 9: // TTU + isUSB = true; + break; +*/ } } /* if (modeValue == 4) { @@ -973,7 +983,7 @@ void menuSelectMode(int btn){ } else { - //LSB, USB, CWL, CWU, DGL, DGU + //LSB, USB, CWL, CWU, DGL, DGU, TTL, TTU if (cwMode == 0) { if (isUSB == 0) { selectModeType = 0; // LSB @@ -983,6 +993,10 @@ void menuSelectMode(int btn){ // modify if digital mode is set if (digiMode > 0) { selectModeType += (3 + digiMode); + + // modify if two-tone test mode is set + } else if (isTest > 0) { + selectModeType += 5; } } else if (cwMode == 1) { selectModeType = 2; // CWL @@ -999,29 +1013,30 @@ void menuSelectMode(int btn){ selectModeType = 3;*/ beforeMode = selectModeType; - selectModeType = getValueByKnob(11, selectModeType, 0, 5, 1, " LSB USB CWL CWU DGL DGU ", 4); //3 : Select Mode, targetValue, minKnobValue, maxKnobValue, stepSize + selectModeType = getValueByKnob(11, selectModeType, 0, 7, 1, " LSB USB CWL CWU DGL DGU TTL TTU", 4); //3 : Select Mode, targetValue, minKnobValue, maxKnobValue, stepSize if (beforeMode != selectModeType) { //printLineF1(F("Changed Mode")); if (selectModeType == 0) { - cwMode = 0; isUSB = 0; digiMode = 0; - } - else if (selectModeType == 1) { - cwMode = 0; isUSB = 1; digiMode = 0; - } - else if (selectModeType == 2) { - cwMode = 1; digiMode = 0; - } - else if (selectModeType == 3) { - cwMode = 2; digiMode = 0; + cwMode = 0; isUSB = 0; digiMode = 0; isTest = 0; + } else if (selectModeType == 1) { + cwMode = 0; isUSB = 1; digiMode = 0; isTest = 0; + } else if (selectModeType == 2) { + cwMode = 1; digiMode = 0; isTest = 0; + } else if (selectModeType == 3) { + cwMode = 2; digiMode = 0; isTest = 0; } else if (selectModeType == 4) { - cwMode = 0; isUSB = 0; digiMode = 1; + cwMode = 0; isUSB = 0; digiMode = 1; isTest = 0; } else if (selectModeType == 5) { - cwMode = 0; isUSB = 1; digiMode = 1; + cwMode = 0; isUSB = 1; digiMode = 1; isTest = 0; + } else if (selectModeType == 6) { + cwMode = 0; isUSB = 0; digiMode = 0; isTest = 1; + } else if (selectModeType == 7) { + cwMode = 0; isUSB = 1; digiMode = 0; isTest = 1; } // KC4UPR: sending mode to IOP - iopSendMode(cwMode, isUSB, digiMode); + iopSendMode(cwMode, isUSB, digiMode, isTest); FrequencyToVFO(1); } From 2f8fe7fb4c8a44bbf1042e68109d5ee32162e112 Mon Sep 17 00:00:00 2001 From: Rob French Date: Mon, 18 May 2020 08:15:28 -0500 Subject: [PATCH 08/17] Got the 5 second "DSP status menu" working. Got comms between the IOP and the Raduino working again. Now implements a wrapper around all IOP<=>Raduino comms (IOP prefix, CAT prefix...) --- ubitx_20/cat_libs.ino | 237 +++++++++++++++++++++--------------- ubitx_20/ubitx_lcd_1602.ino | 27 ++-- ubitx_20/ubitx_menu.ino | 2 +- 3 files changed, 160 insertions(+), 106 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index eb39c43..08789ad 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -61,13 +61,13 @@ void iopSendMode(char cw_mode, char is_usb, char digi_mode, char is_test) byte mode; if (cw_mode > 0) - mode = MODE_CW; + mode = RIG_MODE_CW; else if (digi_mode > 0) - mode = MODE_DIGI; + mode = RIG_MODE_DIGI; else if (is_test) - mode = MODE_TEST; + mode = RIG_MODE_TEST; else - mode = MODE_SSB; + mode = RIG_MODE_SSB; sendIOPModeCommand(mode); } @@ -810,12 +810,25 @@ byte rxBufferCheckCount = 0; //Prevent Stack Overflow byte isProcessCheck_Cat = 0; +char iopStatusWindow[4] = " "; // may need to move this if it's not visible to ubitx_lcd_1602 + +// KC4UPR - these are used to delay the display of the Smeter, if the +// IOP status has recently been displayed, to give time to see it. +// Put these here because of how Arduino IDE puts .ino files together. +#define SMETER_DELAY_TIME 5000 +bool displaySmeter = true; +int delaySmeter; + //fromType normal : 0, TX : 1, CW_STRAIGHT : 2, CW_PADDLE : 3, CW_AUTOMODE : 4 //if cw mode, no delay void Check_Cat(byte fromType) { byte i; + static PrefixID readPrefix; + static uint8_t readLength; + static IOPMessage msg; + //Check Serial Port Buffer if (Serial.available() == 0) { @@ -823,7 +836,9 @@ void Check_Cat(byte fromType) rxBufferCheckCount = 0; return; } - else if (Serial.available() < 5) + // KC4UPR - IOP update: changed this to 6 characters, because we're going to have a + // first character which defines if this is CAT or IOP. + else if (Serial.available() < 6) //5) { //First Arrived if (rxBufferCheckCount == 0) @@ -837,7 +852,7 @@ void Check_Cat(byte fromType) for (i = 0; i < Serial.available(); i++) rxBufferCheckCount = Serial.read(); - rxBufferCheckCount = 0; + rxBufferCheckCount = 0; } else if (rxBufferCheckCount < Serial.available()) //increase buffer count, slow arrived { @@ -848,103 +863,133 @@ void Check_Cat(byte fromType) } //Arived CAT DATA - for (i = 0; i < 5; i++) - CAT_BUFF[i] = Serial.read(); + // KC4UPR - IOP update - 6 characters; first character determines mode (CAT or IOP) + for (i = 0; i < 6; i++) { //5; i++) + if (i == 0) { + byte first = Serial.read(); + readPrefix = byteToPrefix(first); + readLength = byteToLength(first); + } else { + CAT_BUFF[i-1] = Serial.read(); + } + } + + // KC4UPR: I don't understand why this is here or how/when it will ever get called, but I will leave + // it alone for now. if (isProcessCheck_Cat == 1) return; - isProcessCheck_Cat = 1; + isProcessCheck_Cat = 1; - //reference : http://www.ka7oei.com/ft817_meow.html - switch(CAT_BUFF[4]) - { - //The stability has not been verified and there seems to be no need. so i remarked codes, - //if you need, unmark lines - /* - case 0x00 : //Lock On - if (isDialLock == 1) //This command returns 00 if it was unlocked, and F0 if already locked. - CAT_BUFF[0] = 0xF0; - else { - CAT_BUFF[0] = 0x00; - setDialLock(1, fromType); - } - Serial.write(CAT_BUFF[0]); //Time + if (readPrefix == IOP_PREFIX) { + recvIOPMessage(msg, CAT_BUFF, 5); // not super robust... if IOP ever sends more than a 5 (6) byte message + // following assumes it's a status message, 4 chars (including trailing null, which I'm ignoring... + switch(msg.id) { + case IOP_SSB_STATUS_MSG: + case IOP_DIGI_STATUS_MSG: + case IOP_CW_STATUS_MSG: + case IOP_TEST_STATUS_MSG: + iopStatusWindow[0] = msg.data[0]; + iopStatusWindow[1] = msg.data[1]; + iopStatusWindow[2] = msg.data[2]; + displaySmeter = false; + delaySmeter = millis() + SMETER_DELAY_TIME; + break; + } + + } else if (readPrefix == CAT_PREFIX) { + + //reference : http://www.ka7oei.com/ft817_meow.html + switch(CAT_BUFF[4]) + { + //The stability has not been verified and there seems to be no need. so i remarked codes, + //if you need, unmark lines + /* + case 0x00 : //Lock On + if (isDialLock == 1) //This command returns 00 if it was unlocked, and F0 if already locked. + CAT_BUFF[0] = 0xF0; + else { + CAT_BUFF[0] = 0x00; + setDialLock(1, fromType); + } + Serial.write(CAT_BUFF[0]); //Time + break; + case 0x80 : //Lock Off + if (isDialLock == 0) //This command returns 00 if the '817 was already locked, and F0 (HEX) if already unlocked. + CAT_BUFF[0] = 0xF0; + else { + CAT_BUFF[0] = 0x00; + setDialLock(0, fromType); + } + Serial.write(CAT_BUFF[0]); //Time + break; + */ + + case 0x01 : //Set Frequency + CatSetFreq(fromType); break; - case 0x80 : //Lock Off - if (isDialLock == 0) //This command returns 00 if the '817 was already locked, and F0 (HEX) if already unlocked. - CAT_BUFF[0] = 0xF0; - else { - CAT_BUFF[0] = 0x00; - setDialLock(0, fromType); - } - Serial.write(CAT_BUFF[0]); //Time + + case 0x02 : //Split On + case 0x82: //Split Off + CatSetSplit(CAT_BUFF[4] == 0x02); break; - */ - - case 0x01 : //Set Frequency - CatSetFreq(fromType); - break; - - case 0x02 : //Split On - case 0x82: //Split Off - CatSetSplit(CAT_BUFF[4] == 0x02); - break; - - case 0x03 : //Read Frequency and mode - CatGetFreqMode(frequency); - break; - - case 0x07 : //Set Operating Mode - CatSetMode(CAT_BUFF[0], fromType); - break; - - case 0x08 : //Set PTT_ON - case 0x88: //Set PTT Off - CatSetPTT(CAT_BUFF[4] == 0x08, fromType); - break; - - case 0x81: //Toggle VFO - CatVFOToggle(true, fromType); - break; - - case 0xDB: //Read uBITX EEPROM Data - ReadEEPRom(); //Call by uBITX Manager Program - break; - case 0xBB: //Read FT-817 EEPROM Data (for comfirtable) - ReadEEPRom_FT817(); - break; - - case 0xDC: //Write uBITX EEPROM Data - WriteEEPRom(); //Call by uBITX Manager Program - break; - case 0xBC: //Write FT-817 EEPROM Data (for comfirtable) - WriteEEPRom_FT817(fromType); - break; - - case 0xDD: //Read uBITX ADC Data - ReadADCValue(); //Call by uBITX Manager Program - break; - - case 0xDE: //IF-Shift Control by CAT - SetIFSValue(); // - break; - - case 0xE7 : //Read RX Status - CatRxStatus(); - break; - case 0xF7: //Read TX Status - CatTxStatus(); - break; - default: - /* - char buff[16]; - sprintf(buff, "DEFAULT : %x", CAT_BUFF[4]); - printLine2(buff); - */ - Serial.write(ACK); - break; - } //end of switch + + case 0x03 : //Read Frequency and mode + CatGetFreqMode(frequency); + break; + + case 0x07 : //Set Operating Mode + CatSetMode(CAT_BUFF[0], fromType); + break; + + case 0x08 : //Set PTT_ON + case 0x88: //Set PTT Off + CatSetPTT(CAT_BUFF[4] == 0x08, fromType); + break; + + case 0x81: //Toggle VFO + CatVFOToggle(true, fromType); + break; + + case 0xDB: //Read uBITX EEPROM Data + ReadEEPRom(); //Call by uBITX Manager Program + break; + case 0xBB: //Read FT-817 EEPROM Data (for comfirtable) + ReadEEPRom_FT817(); + break; + + case 0xDC: //Write uBITX EEPROM Data + WriteEEPRom(); //Call by uBITX Manager Program + break; + case 0xBC: //Write FT-817 EEPROM Data (for comfirtable) + WriteEEPRom_FT817(fromType); + break; + + case 0xDD: //Read uBITX ADC Data + ReadADCValue(); //Call by uBITX Manager Program + break; + + case 0xDE: //IF-Shift Control by CAT + SetIFSValue(); // + break; + + case 0xE7 : //Read RX Status + CatRxStatus(); + break; + case 0xF7: //Read TX Status + CatTxStatus(); + break; + default: + /* + char buff[16]; + sprintf(buff, "DEFAULT : %x", CAT_BUFF[4]); + printLine2(buff); + */ + Serial.write(ACK); + break; + } //end of switch + } isProcessCheck_Cat = 0; } diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index f4fb70a..7d58293 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -518,8 +518,6 @@ void updateDisplay() { } } - - char line2Buffer[17]; //KD8CEC 200Hz ST //L14.150 200Hz ST @@ -674,13 +672,18 @@ void updateLine2Buffer(char displayType) if (isStepKhz == 0) { - line2Buffer[11] = 'H'; - line2Buffer[12] = 'z'; + // KC4UPR: Getting rid of the "Hz" to unclutter the top line. + line2Buffer[11] = ' '; //'H'; + line2Buffer[12] = ' '; //'z'; } - line2Buffer[13] = ' '; - - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb + //line2Buffer[13] = ' '; + + // KC4UPR: Replacing these all with IOP status + line2Buffer[13] = iopStatusWindow[0]; + line2Buffer[14] = iopStatusWindow[1]; + line2Buffer[15] = iopStatusWindow[2]; +/* //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb if (sdrModeOn == 1) { line2Buffer[13] = 'S'; @@ -701,7 +704,7 @@ void updateLine2Buffer(char displayType) { line2Buffer[14] = 'I'; line2Buffer[15] = 'B'; - } + } */ } } @@ -745,8 +748,14 @@ void idle_process() } } + if (!displaySmeter) { + if (delaySmeter < millis()) { + displaySmeter = true; + } + } + //S-Meter Display - if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) + if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency) && displaySmeter) { int newSMeter; diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index d177b61..8dda453 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -996,7 +996,7 @@ void menuSelectMode(int btn){ // modify if two-tone test mode is set } else if (isTest > 0) { - selectModeType += 5; + selectModeType += 6; } } else if (cwMode == 1) { selectModeType = 2; // CWL From cc78a9f9a1e5ced47716c85b5f673f680514f9c7 Mon Sep 17 00:00:00 2001 From: Rob French Date: Mon, 25 May 2020 23:09:37 -0500 Subject: [PATCH 09/17] Updates to be compatible with the refactored IOP code. Compiles, but untested. --- ubitx_20/cat_libs.ino | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 08789ad..d6455e3 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -60,14 +60,15 @@ void iopSendMode(char cw_mode, char is_usb, char digi_mode, char is_test) { byte mode; - if (cw_mode > 0) - mode = RIG_MODE_CW; - else if (digi_mode > 0) - mode = RIG_MODE_DIGI; - else if (is_test) - mode = RIG_MODE_TEST; - else - mode = RIG_MODE_SSB; + if (cw_mode > 0) { + mode = (cw_mode == 1 ? RIG_MODE_CWL : RIG_MODE_CWU); + } else if (digi_mode > 0) { + mode = (is_usb ? RIG_MODE_DGU : RIG_MODE_DGL); + } else if (is_test) { + mode = (is_usb ? RIG_MODE_TTU : RIG_MODE_TTL); + } else { + mode = (is_usb ? RIG_MODE_USB : RIG_MODE_LSB); + } sendIOPModeCommand(mode); } @@ -887,7 +888,7 @@ void Check_Cat(byte fromType) // following assumes it's a status message, 4 chars (including trailing null, which I'm ignoring... switch(msg.id) { case IOP_SSB_STATUS_MSG: - case IOP_DIGI_STATUS_MSG: + case IOP_DGT_STATUS_MSG: case IOP_CW_STATUS_MSG: case IOP_TEST_STATUS_MSG: iopStatusWindow[0] = msg.data[0]; From 5a6c8308d32ef4816cec5db48d96a94df015e6d1 Mon Sep 17 00:00:00 2001 From: Rob French Date: Tue, 26 May 2020 10:48:35 -0500 Subject: [PATCH 10/17] Quick update to support a mode request message from the IOP. Compiles, runs; not comprehensively tested. --- ubitx_20/cat_libs.ino | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index d6455e3..e59f31c 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -884,7 +884,7 @@ void Check_Cat(byte fromType) isProcessCheck_Cat = 1; if (readPrefix == IOP_PREFIX) { - recvIOPMessage(msg, CAT_BUFF, 5); // not super robust... if IOP ever sends more than a 5 (6) byte message + recvIOPMessage(msg, CAT_BUFF, 5); // not super robust... if IOP ever sends more (or less) than a 5 (6) byte message // following assumes it's a status message, 4 chars (including trailing null, which I'm ignoring... switch(msg.id) { case IOP_SSB_STATUS_MSG: @@ -897,6 +897,10 @@ void Check_Cat(byte fromType) displaySmeter = false; delaySmeter = millis() + SMETER_DELAY_TIME; break; + + case IOP_MODE_REQUEST: + iopSendMode(cwMode, isUSB, digiMode, isTest); + break; } } else if (readPrefix == CAT_PREFIX) { From bbf883d3c5e84c4d69099fd1a818e617d6ec137c Mon Sep 17 00:00:00 2001 From: Rob French Date: Sat, 6 Jun 2020 00:07:50 -0500 Subject: [PATCH 11/17] Added support for a 16-char display to be received from the IOP, with a selectable timeout. Verified the basics of it working. Subsequently updated with better timeout code. This compiles, but has not been tested. --- ubitx_20/cat_libs.ino | 38 +++++++++++++++++++++++++------------ ubitx_20/ubitx_lcd_1602.ino | 21 +++++++++++++++++++- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index e59f31c..c5fd8af 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -73,8 +73,8 @@ void iopSendMode(char cw_mode, char is_usb, char digi_mode, char is_test) } unsigned int skipTimeCount = 0; -byte CAT_BUFF[5]; -byte CAT_SNDBUFF[5]; +byte CAT_BUFF[34]; +byte CAT_SNDBUFF[34]; void SendCatData(byte sendCount) { @@ -812,6 +812,7 @@ byte rxBufferCheckCount = 0; byte isProcessCheck_Cat = 0; char iopStatusWindow[4] = " "; // may need to move this if it's not visible to ubitx_lcd_1602 +char iopMenuDisplay[17] = " "; // KC4UPR - these are used to delay the display of the Smeter, if the // IOP status has recently been displayed, to give time to see it. @@ -819,6 +820,8 @@ char iopStatusWindow[4] = " "; // may need to move this if it's not visible t #define SMETER_DELAY_TIME 5000 bool displaySmeter = true; int delaySmeter; +int delayTopLine = 0; +int stateTopLine = 0; //fromType normal : 0, TX : 1, CW_STRAIGHT : 2, CW_PADDLE : 3, CW_AUTOMODE : 4 //if cw mode, no delay @@ -865,16 +868,13 @@ void Check_Cat(byte fromType) //Arived CAT DATA // KC4UPR - IOP update - 6 characters; first character determines mode (CAT or IOP) - for (i = 0; i < 6; i++) { //5; i++) - if (i == 0) { - byte first = Serial.read(); - readPrefix = byteToPrefix(first); - readLength = byteToLength(first); - } else { - CAT_BUFF[i-1] = Serial.read(); - } + // Will adjust based on readlength + byte first = Serial.read(); + readPrefix = byteToPrefix(first); + readLength = byteToLength(first); + for (int i = 0; i < readLength; i++) { + CAT_BUFF[i] = Serial.read(); } - // KC4UPR: I don't understand why this is here or how/when it will ever get called, but I will leave // it alone for now. @@ -884,7 +884,7 @@ void Check_Cat(byte fromType) isProcessCheck_Cat = 1; if (readPrefix == IOP_PREFIX) { - recvIOPMessage(msg, CAT_BUFF, 5); // not super robust... if IOP ever sends more (or less) than a 5 (6) byte message + recvIOPMessage(msg, CAT_BUFF, readLength); // not super robust... if IOP ever sends more (or less) than a 5 (6) byte message // following assumes it's a status message, 4 chars (including trailing null, which I'm ignoring... switch(msg.id) { case IOP_SSB_STATUS_MSG: @@ -901,6 +901,20 @@ void Check_Cat(byte fromType) case IOP_MODE_REQUEST: iopSendMode(cwMode, isUSB, digiMode, isTest); break; + + case IOP_MENU_DISPLAY_MSG: + for (int i = 0; i < 16; i++) { + iopMenuDisplay[i] = msg.data[i+1]; + } + if (int8_t(msg.data[0]) == 0) { + stateTopLine = 4; + } else if (int8_t(msg.data[0]) < 0) { + stateTopLine = 0; + } else { // > 0 + delayTopLine = millis() + (int8_t(msg.data[0]) * 1000); + stateTopLine = 2; + } + break; } } else if (readPrefix == CAT_PREFIX) { diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index 7d58293..2fc2da5 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -530,6 +530,25 @@ int freqScrollPosition = 0; void updateLine2Buffer(char displayType) { unsigned long tmpFreq = 0; + + if ((stateTopLine == 2) || (stateTopLine == 4)) { + strcpy(line2Buffer, iopMenuDisplay); + if (stateTopLine == 4) { + stateTopLine = 3; + } else { + stateTopLine = 1; + } + } + if (stateTopLine == 3) { + return; + } else if (stateTopLine == 1) { + if (delayTopLine < millis()) { + stateTopLine = 0; + } else { + return; + } + } + if (ritOn) { strcpy(line2Buffer, "RitTX:"); @@ -738,7 +757,7 @@ void idle_process() return; //if line2DisplayStatus == 0 <-- this condition is clear Line, you can display any message - if (line2DisplayStatus == 0 || (((displayOption1 & 0x04) == 0x04) && line2DisplayStatus == 2)) { + if (line2DisplayStatus == 0 || (((displayOption1 & 0x04) == 0x04) && line2DisplayStatus == 2) || stateTopLine > 0) { if (checkCount++ > 1) { updateLine2Buffer(0); //call by scheduler From 10926b54ec1cd5cf9d275c7f5d92d2bf6af286b5 Mon Sep 17 00:00:00 2001 From: Rob French Date: Sat, 6 Jun 2020 22:25:11 -0500 Subject: [PATCH 12/17] Further functioning, but with bugs. Top line is working, but clear there is messed up interplay between between how IOP updates its menu and sends it to the Raduino, and how the Raduino updates its display. Needs to be worked on. Issues: - After deselecting the I/O menu (i.e. should go back to normal Raduino top line), it never does. But the I/O menu is frozen. So clearly the top line never gets updated again by the Raduino. Need to understand the logic it uses to actually refresh the display. - Random garbage (black boxes) on the top line--intermittently. --- ubitx_20/cat_libs.ino | 10 +++++----- ubitx_20/ubitx_lcd_1602.ino | 10 +++++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index c5fd8af..1ced1e3 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -817,9 +817,9 @@ char iopMenuDisplay[17] = " "; // KC4UPR - these are used to delay the display of the Smeter, if the // IOP status has recently been displayed, to give time to see it. // Put these here because of how Arduino IDE puts .ino files together. -#define SMETER_DELAY_TIME 5000 -bool displaySmeter = true; -int delaySmeter; +//#define SMETER_DELAY_TIME 5000 +//bool displaySmeter = true; +//int delaySmeter; int delayTopLine = 0; int stateTopLine = 0; @@ -887,7 +887,7 @@ void Check_Cat(byte fromType) recvIOPMessage(msg, CAT_BUFF, readLength); // not super robust... if IOP ever sends more (or less) than a 5 (6) byte message // following assumes it's a status message, 4 chars (including trailing null, which I'm ignoring... switch(msg.id) { - case IOP_SSB_STATUS_MSG: + /*case IOP_SSB_STATUS_MSG: case IOP_DGT_STATUS_MSG: case IOP_CW_STATUS_MSG: case IOP_TEST_STATUS_MSG: @@ -896,7 +896,7 @@ void Check_Cat(byte fromType) iopStatusWindow[2] = msg.data[2]; displaySmeter = false; delaySmeter = millis() + SMETER_DELAY_TIME; - break; + break;*/ case IOP_MODE_REQUEST: iopSendMode(cwMode, isUSB, digiMode, isTest); diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index 2fc2da5..afb0da5 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -767,14 +767,18 @@ void idle_process() } } - if (!displaySmeter) { + if (stateTopLine > 0) { + return; + } + + /*if (!displaySmeter) { if (delaySmeter < millis()) { displaySmeter = true; } - } + }*/ //S-Meter Display - if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency) && displaySmeter) + if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) { int newSMeter; From 20e1eda14064368c4ae6edba21a3c70644ade453 Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 7 Jun 2020 08:56:06 -0500 Subject: [PATCH 13/17] Removed a bunch of files that I am not maintaining to be compatible with my Raduino/IOP mods. Increaesd the update rate for the display (hopefully). --- ubitx_20/cat_libs.ino | 10 +- ubitx_20/cw_autokey.ino | 400 ----------- ubitx_20/softserial_tiny.cpp | 334 ---------- ubitx_20/ubitx.h | 2 +- ubitx_20/ubitx_20.ino | 31 +- ubitx_20/ubitx_lcd_1602.ino | 41 +- ubitx_20/ubitx_lcd_1602Dual.ino | 727 -------------------- ubitx_20/ubitx_lcd_2004.ino | 743 --------------------- ubitx_20/ubitx_lcd_nextion.ino | 1107 ------------------------------- ubitx_20/ubitx_menu.ino | 2 + 10 files changed, 44 insertions(+), 3353 deletions(-) delete mode 100644 ubitx_20/cw_autokey.ino delete mode 100644 ubitx_20/softserial_tiny.cpp delete mode 100644 ubitx_20/ubitx_lcd_1602Dual.ino delete mode 100644 ubitx_20/ubitx_lcd_2004.ino delete mode 100644 ubitx_20/ubitx_lcd_nextion.ino diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 1ced1e3..0be4e4b 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -213,11 +213,11 @@ void CatSetPTT(boolean isPTTOn, byte fromType) startTx(TX_SSB, 1); //Exit menu, Memory Keyer... ETC - if (isCWAutoMode > 0) { - isCWAutoMode = 0; - printLineF2(F("AutoKey Exit/CAT")); - //delay_background(1000, 0); - } + //if (isCWAutoMode > 0) { + // isCWAutoMode = 0; + // printLineF2(F("AutoKey Exit/CAT")); + // //delay_background(1000, 0); + //} } } else diff --git a/ubitx_20/cw_autokey.ino b/ubitx_20/cw_autokey.ino deleted file mode 100644 index 9bf838e..0000000 --- a/ubitx_20/cw_autokey.ino +++ /dev/null @@ -1,400 +0,0 @@ -/************************************************************************* - KD8CEC's Memory Keyer for HAM - - This source code is written for All amateur radio operator, - I have not had amateur radio communication for a long time. CW has been - around for a long time, and I do not know what kind of keyer and keying - software is fashionable. So I implemented the functions I need mainly. - - To minimize the use of memory space, we used bitwise operations. - For the alphabet, I put Morsecode in 1 byte. The front 4Bit is the length - and the 4Bit is the Morse code. Because the number is fixed in length, - there is no separate length information. The 5Bit on the right side is - the Morse code. - - I wrote this code myself, so there is no license restriction. - So this code allows anyone to write with confidence. - But keep it as long as the original author of the code. - DE Ian KD8CEC ------------------------------------------------------------------------------ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -**************************************************************************/ -#include - -//27 + 10 + 18 + 1(SPACE) = //56 -const PROGMEM uint8_t cwAZTable[27] = {0b00100100 , 0b01001000 , 0b01001010 , 0b00111000 , 0b00010000, 0b01000010, 0b00111100, 0b01000000 , //A ~ H -0b00100000, 0b01000111 ,0b00111010, 0b01000100, 0b00101100, 0b00101000 , 0b00111110, 0b01000110, 0b01001101, 0b00110100, //I ~ R -0b00110000, 0b00011000, 0b00110010, 0b01000001, 0b00110110, 0b01001001, 0b01001011, 0b01001100}; //S ~ Z -PGM_P pCwAZTable = reinterpret_cast(cwAZTable); - -const PROGMEM uint8_t cw09Table[27] = {0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001, 0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110}; -PGM_P pcw09Table = reinterpret_cast(cw09Table); - -//# : AR, ~:BT, [:AS, ]:SK, ^:KN -const PROGMEM uint8_t cwSymbolIndex[] = {'.', ',', '?', '"', '!', '/', '(', ')', '&', ':', ';', '=', '+', '-', '_', '\'', '@', '#', '~', '[', ']', '^' }; -PGM_P pCwSymbolIndex = reinterpret_cast(cwSymbolIndex); - -const PROGMEM uint8_t cwSymbolTable[] = {0b11010101, 0b11110011, 0b11001100, 0b11011110, 0b11101011, 0b10100100, 0b10101100, 0b11101101, 0b10010000, 0b11111000, 0b11101010, 0b10100010, 0b10010100, 0b11100001, 0b11001101, 0b11010010, 0b11011010, 0b10010100, 0b10100010, 0b10010000, 0b11000101, 0b10101100}; -PGM_P pCwSymbolTable = reinterpret_cast(cwSymbolTable); -////const PROGMEM uint8_t cwSymbolLength[] = {6, 6, 6, 6, 6, 5, 5, 6, 5, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 6, 5}; - -// ":(Start"), ':(End "), >: My callsign, <:QSO Callsign (Second Callsign), #:AR, ~:BT, [:AS, ]:SK - -byte knobPosition = 0; -//byte cwTextData[30]; //Maximum 30 Remarked by KD8CE -> Direct Read EEPROM -byte autoCWSendCharEndIndex = 0; -byte autoCWSendCharIndex = 0; -unsigned long autoCWbeforeTime = 0; //for interval time between chars -byte pttBeforeStatus = 1; //PTT : default high -byte isKeyStatusAfterCWStart = 0; //0 : Init, 1 : Keyup after auto CW Start, 2 : Keydown after -byte selectedCWTextIndex = 0; -unsigned long autoCWKeydownCheckTime = 0; //for interval time between chars -byte changeReserveStatus = 0; -byte isAutoCWHold = 0; //auto CW Pause => Manual Keying => auto - -void autoSendPTTCheck() -{ - if (isCWAutoMode == 2) { //Sending Mode - //check PTT Button - //short Press => reservation or cancel - //long Press => Hold - if (digitalRead(PTT) == LOW) - { - //if (isKeyStatusAfterCWStart == 0) //Yet Press PTT from start TX - //{ - //} - - if (isKeyStatusAfterCWStart == 1) //while auto cw send, ptt up and ptt down again - { - //Start Time - autoCWKeydownCheckTime = millis() + 200; //Long push time - isKeyStatusAfterCWStart = 2; //Change status => ptt down agian - } - else if (isKeyStatusAfterCWStart == 2 && autoCWKeydownCheckTime < millis()) - { - //Hold Mode - isAutoCWHold = 1; - isKeyStatusAfterCWStart = 3; - } - else if (isKeyStatusAfterCWStart == 3) - { - autoCWKeydownCheckTime = millis() + 200; - } - } - else - { - //PTT UP - if (isKeyStatusAfterCWStart == 2) //0 (down before cw start) -> 1 (up while cw sending) -> 2 (down while cw sending) - { - if (autoCWKeydownCheckTime > millis()) //Short : Reservation or cancel Next Text - { - if (autoCWSendReservCount == 0 || - (autoCWSendReservCount < AUTO_CW_RESERVE_MAX && - autoCWSendReserv[autoCWSendReservCount - 1] != selectedCWTextIndex)) - { - //Reserve - autoCWSendReserv[autoCWSendReservCount++] = selectedCWTextIndex; - changeReserveStatus = 1; - } - else if (autoCWSendReservCount > 0 && autoCWSendReserv[autoCWSendReservCount - 1] == selectedCWTextIndex) - { - autoCWSendReservCount--; - changeReserveStatus = 1; - } - } // end of Short Key up - } - else if (isKeyStatusAfterCWStart == 3) //play from Hold (pause Auto CW Send) - { - isAutoCWHold = 0; - } - - isKeyStatusAfterCWStart = 1; //Change status => ptt up (while cw send mode) - } //end of PTT UP - } -} - -//Send 1 char -void sendCWChar(char cwKeyChar) -{ - byte sendBuff[7]; - byte i, j, charLength; - byte tmpChar; - - //For Macrofunction - //replace > and < to My callsign, qso callsign, use recursive function call - if (cwKeyChar == '>' || cwKeyChar == '<') - { - uint16_t callsignStartIndex = 0; - uint16_t callsignEndIndex = 0; - - if (cwKeyChar == '>') //replace my callsign - { - if (userCallsignLength > 0) - { - callsignStartIndex = 0; - callsignEndIndex = userCallsignLength; - } - } - else if (cwKeyChar == '<') //replace qso callsign - { - //ReadLength - callsignEndIndex = EEPROM.read(CW_STATION_LEN); - if (callsignEndIndex > 0) - { - callsignStartIndex = CW_STATION_LEN - callsignEndIndex - USER_CALLSIGN_DAT; - callsignEndIndex = callsignStartIndex + callsignEndIndex; - } - } - - if (callsignStartIndex == 0 && callsignEndIndex == 0) - return; - - for (uint16_t i = callsignStartIndex; i <= callsignEndIndex; i++) - { - sendCWChar(EEPROM.read(USER_CALLSIGN_DAT + i)); - autoSendPTTCheck(); //for reserve and cancel next CW Text - if (changeReserveStatus == 1) - { - changeReserveStatus = 0; - updateDisplay(); - } - - if (i < callsignEndIndex) delay_background(cwSpeed * 3, 4); // - } - - return; - } - else if (cwKeyChar >= 'A' && cwKeyChar <= 'Z') //Encode Char by KD8CEC - { - tmpChar = pgm_read_byte(pCwAZTable + (cwKeyChar - 'A')); - charLength = (tmpChar >> 4) & 0x0F; - for (i = 0; i < charLength; i++) - sendBuff[i] = (tmpChar << i) & 0x08; - } - else if (cwKeyChar >= '0' && cwKeyChar <= '9') - { - charLength = 5; - for (i = 0; i < charLength; i++) - sendBuff[i] = (pgm_read_byte(pcw09Table + (cwKeyChar - '0')) << i) & 0x10; - } - else if (cwKeyChar == ' ') - { - charLength = 0; - delay_background(cwSpeed * 4, 4); //7 -> basic interval is 3 - } - else if (cwKeyChar == '$') //7 digit - { - charLength = 7; - for (i = 0; i < 7; i++) - sendBuff[i] = (0b00010010 << i) & 0x80; //...1..1 - } - else - { - //symbol - for (i = 0; i < 22; i++) - { - if (pgm_read_byte(pCwSymbolIndex + i) == cwKeyChar) - { - tmpChar = pgm_read_byte(pCwSymbolTable + i); - charLength = ((tmpChar >> 6) & 0x03) + 3; - - for (j = 0; j < charLength; j++) - sendBuff[j] = (tmpChar << (j + 2)) & 0x80; - - break; - } - else - { - charLength = 0; - } - } - } - - for (i = 0; i < charLength; i++) - { - cwKeydown(); - if (sendBuff[i] == 0) - delay_background(cwSpeed, 4); - else - delay_background(cwSpeed * 3, 4); - cwKeyUp(); - if (i != charLength -1) - delay_background(cwSpeed, 4); - } -} - -byte isNeedScroll = 0; -unsigned long scrollDispayTime = 0; -#define scrollSpeed 500 -byte displayScrolStep = 0; - -void controlAutoCW(){ - int knob = 0; - byte i; - - byte cwStartIndex, cwEndIndex; - - if (cwAutoDialType == 0) - knob = enc_read(); - - if (knob != 0 || beforeCWTextIndex == 255 || isNeedScroll == 1){ //start display - if (knobPosition > 0 && knob < 0) - knobPosition--; - if (knobPosition < cwAutoTextCount * 10 -1 && knob > 0) - knobPosition++; - - selectedCWTextIndex = knobPosition / 10; - - if ((beforeCWTextIndex != selectedCWTextIndex) || - (isNeedScroll == 1 && beforeCWTextIndex == selectedCWTextIndex && scrollDispayTime < millis())) { - //Read CW Text Data Position From EEProm - EEPROM.get(CW_AUTO_DATA + (selectedCWTextIndex * 2), cwStartIndex); - EEPROM.get(CW_AUTO_DATA + (selectedCWTextIndex * 2 + 1), cwEndIndex); - - if (beforeCWTextIndex == selectedCWTextIndex) - { - if (++displayScrolStep > cwEndIndex - cwStartIndex) - displayScrolStep = 0; - } - else - { - displayScrolStep = 0; - } - -#ifdef USE_SW_SERIAL - //Not need Scroll - //Display_AutoKeyTextIndex(selectedCWTextIndex); - SendCommand1Num('w', selectedCWTextIndex); //Index - SendEEPromData('a', cwStartIndex + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ, 0) ; //Data - SendCommand1Num('y', 1); //Send YN - isNeedScroll = 0; -#else - printLineFromEEPRom(0, 2, cwStartIndex + displayScrolStep + CW_DATA_OFSTADJ, cwEndIndex + CW_DATA_OFSTADJ, 0); - isNeedScroll = (cwEndIndex - cwStartIndex) > 14 ? 1 : 0; - Display_AutoKeyTextIndex(selectedCWTextIndex); -#endif - scrollDispayTime = millis() + scrollSpeed; - beforeCWTextIndex = selectedCWTextIndex; - } - } //end of check knob - - if (isCWAutoMode == 1) { //ready status - if (digitalRead(PTT) == LOW) //PTT Down : Start Auto CW or DialMode Change - { - if (pttBeforeStatus == 1) //High to Low Change - { - autoCWbeforeTime = millis() + 500; //Long push time - pttBeforeStatus = 0; - } - else if (autoCWbeforeTime < millis()) //while press PTT, OK Long push then Send Auto CW Text - { - sendingCWTextIndex = selectedCWTextIndex; - - //Information about Auto Send CW Text - autoCWSendCharEndIndex = cwEndIndex; //length of CW Text //ianlee - autoCWSendCharIndex = cwStartIndex; //position of Sending Char //ianlee - - isCWAutoMode = 2; //auto sending start - autoCWbeforeTime = 0; //interval between chars, 0 = always send - isKeyStatusAfterCWStart = 0; //Init PTT Key status - autoCWSendReservCount = 0; //Init Reserve Count - isAutoCWHold = 0; - if (!inTx){ //if not TX Status, change RX -> TX - keyDown = 0; - startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time - updateDisplay(); - - delay_background(delayBeforeCWStartTime * 2, 2); //for External AMP or personal situation - } - } - } - else if (pttBeforeStatus == 0 && autoCWbeforeTime > 0) //while reade status LOW -> HIGH (before Auto send Before) - { - pttBeforeStatus = 1; //HIGH - if (autoCWbeforeTime > millis()) //short Press -> ? DialModeChange - { - cwAutoDialType = (cwAutoDialType == 1 ? 0 : 1); //Invert DialMode between select CW Text and Frequency Tune - if (cwAutoDialType == 0) - printLineF1(F("Dial:Select Text")); - else - printLineF1(F("Dial:Freq Tune")); - - delay_background(1000, 0); - updateDisplay(); - } - } - } //end of isCWAutoMode == 1 condition - - if (isCWAutoMode == 2) { //Sending Mode - autoSendPTTCheck(); - - //check interval time, if you want adjust interval between chars, modify below - if (isAutoCWHold == 0 && (millis() - autoCWbeforeTime > cwSpeed * 3)) - { - if (!inTx){ //if not TX Status, change RX -> TX - keyDown = 0; - startTx(TX_CW, 0); //disable updateDisplay Command for reduce latency time - } - - sendCWChar(EEPROM.read(CW_AUTO_DATA + autoCWSendCharIndex++)); - - if (autoCWSendCharIndex > autoCWSendCharEndIndex) { //finish auto cw send - //check reserve status - if (autoCWSendReservCount > 0) - { - //prepare - sendingCWTextIndex = autoCWSendReserv[0]; - - for (i = 0; i < AUTO_CW_RESERVE_MAX -1; i++) - autoCWSendReserv[i] = autoCWSendReserv[i + 1]; - - EEPROM.get(CW_AUTO_DATA + (sendingCWTextIndex * 2), cwStartIndex); - EEPROM.get(CW_AUTO_DATA + (sendingCWTextIndex * 2 + 1), cwEndIndex); - - //Information about Auto Send CW Text - autoCWSendCharEndIndex = cwEndIndex; //length of CW Text //ianlee - autoCWSendCharIndex = cwStartIndex; //position of Sending Char //ianlee - autoCWSendReservCount--; //Decrease - - sendCWChar(' '); //APPLY SPACE between CW Texts - changeReserveStatus = 1; - } - else - { - isCWAutoMode = 1; //ready status - delay_background(cwDelayTime * 10, 2); - stopTx(); - } - } - - autoCWbeforeTime = millis(); - - if (changeReserveStatus == 1) - { - changeReserveStatus = 0; - updateDisplay(); - } - } - } - - //abort if this button is down - if (btnDown()) - { - isCWAutoMode = 0; //dsiable Auto CW Mode - printLine2ClearAndUpdate(); - delay_background(1000, 0); - } -} - diff --git a/ubitx_20/softserial_tiny.cpp b/ubitx_20/softserial_tiny.cpp deleted file mode 100644 index 6023c67..0000000 --- a/ubitx_20/softserial_tiny.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* -Softserial for Nextion LCD and Control MCU -KD8CEC, Ian Lee ------------------------------------------------------------------------ -It is a library rewritten in C format based on SoftwareSerial.c. -I tried to use as much as possible without modifying the SoftwareSerial. -But eventually I had to modify the code. - -I rewrote it in C for the following reasons. - - Problems occurred when increasing Program Size and Program Memory - - We had to reduce the program size. - Of course, Software Serial is limited to one. - - reduce the steps for transmitting and receiving - -useage -extern void SWSerial_Begin(long speedBaud); -extern void SWSerial_Write(uint8_t b); -extern int SWSerial_Available(void); -extern int SWSerial_Read(void); -extern void SWSerial_Print(uint8_t *b); - -If you use Softwreserial library instead of this library, you can modify the code as shown below. -I kept the function name of SoftwareSerial so you only need to modify a few lines of code. - -define top of source code -#include -SoftwareSerial sSerial(10, 11); // RX, TX - -replace source code -SWSerial_Begin to sSerial.begin -SWSerial_Write to sSerial.write -SWSerial_Available to sSerial.available -SWSerial_Read to sSerial.read - -KD8CEC, Ian Lee ------------------------------------------------------------------------ -License -All licenses for the source code are subject to the license of the original source SoftwareSerial Library. -However, if you use or modify this code, please keep the all comments in this source code. -KD8CEC ------------------------------------------------------------------------ -License from SoftwareSerial ------------------------------------------------------------------------ -SoftwareSerial.cpp (formerly NewSoftSerial.cpp) - -Multi-instance software serial library for Arduino/Wiring --- Interrupt-driven receive and other improvements by ladyada - (http://ladyada.net) --- Tuning, circular buffer, derivation from class Print/Stream, - multi-instance support, porting to 8MHz processors, - various optimizations, PROGMEM delay tables, inverse logic and - direct port writing by Mikal Hart (http://www.arduiniana.org) --- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) --- 20MHz processor support by Garrett Mace (http://www.macetech.com) --- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -The latest version of this library can always be found at -http://arduiniana.org. - */ -#include - -//================================================================ -//Public Variable -//================================================================ -#define TX_PIN 9 -#define RX_PIN 8 -#define _SS_MAX_RX_BUFF 35 // RX buffer size -#define PRINT_MAX_LENGTH 30 - -//================================================================ -//Internal Variable from SoftwareSerial.c and SoftwareSerial.h -//================================================================ -//variable from softwareserial.c and softwareserial.h -static uint8_t swr_receive_buffer[_SS_MAX_RX_BUFF]; - -volatile uint8_t *_transmitPortRegister; //Write Port Register -uint8_t transmit_RegMask; //use Mask bit 1 -uint8_t transmit_InvMask; //use mask bit 0 - -volatile uint8_t *_receivePortRegister; //Read Port Register -uint8_t _receiveBitMask; - -//delay value for Bit -uint16_t _tx_delay; - -//delay value for Receive -uint16_t _rx_delay_stopbit; -uint16_t _rx_delay_centering; -uint16_t _rx_delay_intrabit; - -//Customize for uBITX Protocol -int8_t receiveIndex = 0; -uint8_t receivedCommandLength = 0; -int8_t ffCount = 0; - -//Values for Receive Buffer -//uint16_t _buffer_overflow; -//static volatile uint8_t _receive_buffer_head; -//static volatile uint8_t _receive_buffer_tail; - -//Values for Interrupt (check Start Bit) -volatile uint8_t *_pcint_maskreg; -uint8_t _pcint_maskvalue; - -//================================================================ -//Internal Function from SoftwareSerial.c -//================================================================ -uint16_t subtract_cap(uint16_t num, uint16_t sub) -{ - if (num > sub) - return num - sub; - else - return 1; -} - -inline void tunedDelay(uint16_t delay) -{ - _delay_loop_2(delay); -} - -void setRxIntMsk(bool enable) -{ - if (enable) - *_pcint_maskreg |= _pcint_maskvalue; - else - *_pcint_maskreg &= ~_pcint_maskvalue; -} - -uint8_t rx_pin_read() -{ - return *_receivePortRegister & _receiveBitMask; -} - -// -// The receive routine called by the interrupt handler -// -void softSerail_Recv() -{ -#if GCC_VERSION < 40302 -// Work-around for avr-gcc 4.3.0 OSX version bug -// Preserve the registers that the compiler misses -// (courtesy of Arduino forum user *etracer*) - asm volatile( - "push r18 \n\t" - "push r19 \n\t" - "push r20 \n\t" - "push r21 \n\t" - "push r22 \n\t" - "push r23 \n\t" - "push r26 \n\t" - "push r27 \n\t" - ::); -#endif - - uint8_t d = 0; - - // If RX line is high, then we don't see any start bit - // so interrupt is probably not for us - if (!rx_pin_read()) //Start Bit - { - // Disable further interrupts during reception, this prevents - // triggering another interrupt directly after we return, which can - // cause problems at higher baudrates. - setRxIntMsk(false); - - // Wait approximately 1/2 of a bit width to "center" the sample - tunedDelay(_rx_delay_centering); - - // Read each of the 8 bits - for (uint8_t i=8; i > 0; --i) - { - tunedDelay(_rx_delay_intrabit); - d >>= 1; - - if (rx_pin_read()) - d |= 0x80; - } - - if (receivedCommandLength == 0) //check Already Command - { - //Set Received Data - swr_receive_buffer[receiveIndex++] = d; - - //Finded Command - if (d == 0x73 && ffCount > 1 && receiveIndex > 6) - { - receivedCommandLength = receiveIndex; - receiveIndex = 0; - ffCount = 0; - } - else if (receiveIndex > _SS_MAX_RX_BUFF) - { - //Buffer Overflow - receiveIndex = 0; - ffCount = 0; - } - else if (d == 0xFF) - { - ffCount++; - } - else - { - ffCount = 0; - } - } - - // skip the stop bit - tunedDelay(_rx_delay_stopbit); - - // Re-enable interrupts when we're sure to be inside the stop bit - setRxIntMsk(true); - } - -#if GCC_VERSION < 40302 -// Work-around for avr-gcc 4.3.0 OSX version bug -// Restore the registers that the compiler misses - asm volatile( - "pop r27 \n\t" - "pop r26 \n\t" - "pop r23 \n\t" - "pop r22 \n\t" - "pop r21 \n\t" - "pop r20 \n\t" - "pop r19 \n\t" - "pop r18 \n\t" - ::); -#endif -} - -ISR(PCINT0_vect) -{ - softSerail_Recv(); -} - -//================================================================ -//Public Function from SoftwareSerial.c and modified and create -//================================================================ -// Read data from buffer -void SWSerial_Read(uint8_t * receive_cmdBuffer) -{ - for (int i = 0; i < receivedCommandLength; i++) - receive_cmdBuffer[i] = swr_receive_buffer[i]; -} - -void SWSerial_Write(uint8_t b) -{ - volatile uint8_t *reg = _transmitPortRegister; - uint8_t oldSREG = SREG; - uint16_t delay = _tx_delay; - - cli(); // turn off interrupts for a clean txmit - - // Write the start bit - *reg &= transmit_InvMask; - - tunedDelay(delay); - - // Write each of the 8 bits - for (uint8_t i = 8; i > 0; --i) - { - if (b & 1) // choose bit - *reg |= transmit_RegMask; // send 1 - else - *reg &= transmit_InvMask; // send 0 - - tunedDelay(delay); - b >>= 1; - } - - // restore pin to natural state - *reg |= transmit_RegMask; - - SREG = oldSREG; // turn interrupts back on - tunedDelay(_tx_delay); -} - -void SWSerial_Print(uint8_t *b) -{ - for (int i = 0; i < PRINT_MAX_LENGTH; i++) - { - if (b[i] == 0x00) - break; - else - SWSerial_Write(b[i]); - } -} - -void SWSerial_Begin(long speedBaud) -{ - //INT TX_PIN - digitalWrite(TX_PIN, HIGH); - pinMode(TX_PIN, OUTPUT); - transmit_RegMask = digitalPinToBitMask(TX_PIN); //use Bit 1 - transmit_InvMask = ~digitalPinToBitMask(TX_PIN); //use Bit 0 - _transmitPortRegister = portOutputRegister(digitalPinToPort(TX_PIN)); - - //INIT RX_PIN - pinMode(RX_PIN, INPUT); - digitalWrite(RX_PIN, HIGH); // pullup for normal logic! - _receiveBitMask = digitalPinToBitMask(RX_PIN); - _receivePortRegister = portInputRegister(digitalPinToPort(RX_PIN)); - - //Set Values - uint16_t bit_delay = (F_CPU / speedBaud) / 4; - _tx_delay = subtract_cap(bit_delay, 15 / 4); - - if (digitalPinToPCICR(RX_PIN)) - { - _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4); - _rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4); - _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4); - *digitalPinToPCICR(RX_PIN) |= _BV(digitalPinToPCICRbit(RX_PIN)); - _pcint_maskreg = digitalPinToPCMSK(RX_PIN); - _pcint_maskvalue = _BV(digitalPinToPCMSKbit(RX_PIN)); - - tunedDelay(_tx_delay); // if we were low this establishes the end - } - - //Start Listen - setRxIntMsk(true); -} diff --git a/ubitx_20/ubitx.h b/ubitx_20/ubitx.h index 427a99e..f9d1d92 100644 --- a/ubitx_20/ubitx.h +++ b/ubitx_20/ubitx.h @@ -69,7 +69,7 @@ extern byte I2C_LCD_SECOND_ADDRESS; //only using Dual LCD Mode #define FN_CW_SPEED 1 //152 #define FN_VFOTOMEM 1 //254 #define FN_MEMTOVFO 1 //188 -#define FN_MEMORYKEYER 1 //156 +#define FN_MEMORYKEYER 0 //156 #define FN_WSPR 1 //1044 #define FN_SDRMODE 1 //68 #define FN_CALIBRATION 1 //666 diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index fc9cfee..deb97b8 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -172,15 +172,15 @@ byte isShiftDisplayCWFreq = 1; //Display Frequency int shiftDisplayAdjustVal = 0; // //Variables for auto cw mode -byte isCWAutoMode = 0; //0 : none, 1 : CW_AutoMode_Menu_Selection, 2 : CW_AutoMode Sending -byte cwAutoTextCount = 0; //cwAutoText Count -byte beforeCWTextIndex = 255; //when auto cw start, always beforeCWTextIndex = 255, (for first time check) -byte cwAutoDialType = 0; //0 : CW Text Change, 1 : Frequency Tune +//byte isCWAutoMode = 0; //0 : none, 1 : CW_AutoMode_Menu_Selection, 2 : CW_AutoMode Sending +//byte cwAutoTextCount = 0; //cwAutoText Count +//byte beforeCWTextIndex = 255; //when auto cw start, always beforeCWTextIndex = 255, (for first time check) +//byte cwAutoDialType = 0; //0 : CW Text Change, 1 : Frequency Tune -#define AUTO_CW_RESERVE_MAX 3 -byte autoCWSendReserv[AUTO_CW_RESERVE_MAX]; //Reserve CW Auto Send -byte autoCWSendReservCount = 0; //Reserve CW Text Cound -byte sendingCWTextIndex = 0; //cw auto seding Text Index +//#define AUTO_CW_RESERVE_MAX 3 +//byte autoCWSendReserv[AUTO_CW_RESERVE_MAX]; //Reserve CW Auto Send +//byte autoCWSendReservCount = 0; //Reserve CW Text Cound +//byte sendingCWTextIndex = 0; //cw auto seding Text Index byte userCallsignLength = 0; //7 : display callsign at system startup, 6~0 : callsign length (range : 1~18) @@ -342,7 +342,7 @@ byte delay_background(unsigned delayTime, byte fromType){ //fromType : 4 autoCWK return 1; //Check PTT while auto Sending - autoSendPTTCheck(); + //autoSendPTTCheck(); Check_Cat(3); } @@ -732,8 +732,8 @@ void checkButton(){ SetSWActivePage(1); doMenu(); - if (isCWAutoMode == 0) - SetSWActivePage(0); + //if (isCWAutoMode == 0) + SetSWActivePage(0); #else doMenu(); #endif @@ -1511,15 +1511,16 @@ void loop(){ //tune only when not tranmsitting if (!inTx){ - if (isCWAutoMode == 0 || cwAutoDialType == 1) - { + //if (isCWAutoMode == 0 || cwAutoDialType == 1) + //{ if (ritOn) doRIT(); else doTuningWithThresHold(); - } + //} - if (isCWAutoMode == 0 && beforeIdle_ProcessTime < millis() - 250) { + // KC4UPR: Updated to 100 msec (instead of 250 msec) for improved display responsiveness) + if (beforeIdle_ProcessTime < millis() - 100) { idle_process(); checkAutoSaveFreqMode(); //move here form out scope for reduce cpu use rate beforeIdle_ProcessTime = millis(); diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index afb0da5..dbe1e15 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -417,20 +417,20 @@ void updateDisplay() { memset(c, 0, sizeof(c)); if (inTx){ - if (isCWAutoMode == 2) { - for (i = 0; i < 4; i++) - c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); + //if (isCWAutoMode == 2) { + // for (i = 0; i < 4; i++) + // c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); //display Sending Index - c[4] = byteToChar(sendingCWTextIndex); - c[5] = '='; - } - else { + // c[4] = byteToChar(sendingCWTextIndex); + // c[5] = '='; + //} + //else { if (cwTimeout > 0) strcpy(c, " CW:"); else strcpy(c, " TX:"); - } + //} } else { if (ritOn) @@ -507,10 +507,10 @@ void updateDisplay() { LCD_SetCursor(5,diplayVFOLine); LCD_Write((uint8_t)0); } - else if (isCWAutoMode == 2){ - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(0x7E); - } + //else if (isCWAutoMode == 2){ + // LCD_SetCursor(5,diplayVFOLine); + // LCD_Write(0x7E); + //} else { LCD_SetCursor(5,diplayVFOLine); @@ -691,18 +691,17 @@ void updateLine2Buffer(char displayType) if (isStepKhz == 0) { - // KC4UPR: Getting rid of the "Hz" to unclutter the top line. - line2Buffer[11] = ' '; //'H'; - line2Buffer[12] = ' '; //'z'; + line2Buffer[11] = 'H'; + line2Buffer[12] = 'z'; } - //line2Buffer[13] = ' '; + line2Buffer[13] = ' '; // KC4UPR: Replacing these all with IOP status - line2Buffer[13] = iopStatusWindow[0]; - line2Buffer[14] = iopStatusWindow[1]; - line2Buffer[15] = iopStatusWindow[2]; -/* //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb + //line2Buffer[13] = iopStatusWindow[0]; + //line2Buffer[14] = iopStatusWindow[1]; + //line2Buffer[15] = iopStatusWindow[2]; + //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb if (sdrModeOn == 1) { line2Buffer[13] = 'S'; @@ -723,7 +722,7 @@ void updateLine2Buffer(char displayType) { line2Buffer[14] = 'I'; line2Buffer[15] = 'B'; - } */ + } } } diff --git a/ubitx_20/ubitx_lcd_1602Dual.ino b/ubitx_20/ubitx_lcd_1602Dual.ino deleted file mode 100644 index 48598cb..0000000 --- a/ubitx_20/ubitx_lcd_1602Dual.ino +++ /dev/null @@ -1,727 +0,0 @@ -/************************************************************************* - KD8CEC's uBITX Display Routine for LCD1602 Dual LCD - 1.This is the display code for the 16x02 Dual LCD - 2.Some functions moved from uBITX_Ui. ------------------------------------------------------------------------------ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -**************************************************************************/ -#include "ubitx.h" -#include "ubitx_lcd.h" - -//======================================================================== -//Begin of I2CTinyLCD Library for Dual LCD by KD8CEC -//======================================================================== -#ifdef UBITX_DISPLAY_LCD1602I_DUAL - -#include -/************************************************************************* - I2C Tiny LCD Library - Referecnce Source : LiquidCrystal_I2C.cpp // Based on the work by DFRobot - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal_I2C Library - - I wrote this code myself, so there is no license restriction. - So this code allows anyone to write with confidence. - But keep it as long as the original author of the code. - Ian KD8CEC -**************************************************************************/ -#define UBITX_DISPLAY_LCD1602_BASE - -#define En B00000100 // Enable bit -#define Rw B00000010 // Read/Write bit -#define Rs B00000001 // Register select bit - -#define LCD_Command(x) (LCD_Send(x, 0)) -#define LCD_Write(x) (LCD_Send(x, Rs)) - -uint8_t _Addr; -uint8_t _displayfunction; -uint8_t _displaycontrol; -uint8_t _displaymode; -uint8_t _numlines; -uint8_t _cols; -uint8_t _rows; -uint8_t _backlightval; - -#define printIIC(args) Wire.write(args) - -void expanderWrite(uint8_t _data) -{ - Wire.beginTransmission(_Addr); - printIIC((int)(_data) | _backlightval); - Wire.endTransmission(); -} - -void pulseEnable(uint8_t _data){ - expanderWrite(_data | En); // En high - delayMicroseconds(1); // enable pulse must be >450ns - - expanderWrite(_data & ~En); // En low - delayMicroseconds(50); // commands need > 37us to settle -} - -void write4bits(uint8_t value) -{ - expanderWrite(value); - pulseEnable(value); -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - uint8_t highnib=value&0xf0; - uint8_t lownib=(value<<4)&0xf0; - write4bits((highnib)|mode); - write4bits((lownib)|mode); -} - - -// Turn the (optional) backlight off/on -void noBacklight(void) { - _backlightval=LCD_NOBACKLIGHT; - expanderWrite(0); -} - -void backlight(void) { - _backlightval=LCD_BACKLIGHT; - expanderWrite(0); -} - -void LCD1602_Dual_Init() -{ - //I2C Init - _cols = 16; - _rows = 2; - _backlightval = LCD_NOBACKLIGHT; - Wire.begin(); - - delay(50); - - // Now we pull both RS and R/W low to begin commands - _Addr = I2C_LCD_MASTER_ADDRESS; - expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) - _Addr = I2C_LCD_SECOND_ADDRESS; - expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) - delay(1000); - //put the LCD into 4 bit mode - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - _Addr = I2C_LCD_MASTER_ADDRESS; - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - //delayMicroseconds(2000); // this command takes a long time! - delayMicroseconds(1000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); - - backlight(); - - - _Addr = I2C_LCD_SECOND_ADDRESS; - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - //delayMicroseconds(2000); // this command takes a long time! - delayMicroseconds(1000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); - - backlight(); - - //Change to Default LCD (Master) - _Addr = I2C_LCD_MASTER_ADDRESS; -} - - -//======================================================================== -// 16 X 02 LCD Routines -//Begin of Display Base Routines (Init, printLine..) -//======================================================================== - -void LCD_Print(const char *c) -{ - for (uint8_t i = 0; i < strlen(c); i++) - { - if (*(c + i) == 0x00) return; - LCD_Write(*(c + i)); - } -} - -const int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; -void LCD_SetCursor(uint8_t col, uint8_t row) -{ - LCD_Command(LCD_SETDDRAMADDR | (col + row_offsets[row])); //0 : 0x00, 1 : 0x40, only for 20 x 4 lcd -} - -void LCD_CreateChar(uint8_t location, uint8_t charmap[]) -{ - location &= 0x7; // we only have 8 locations 0-7 - LCD_Command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) - LCD_Write(charmap[i]); -} - -//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA -//#define OPTION_SKINNYBARS - -char c[30], b[30]; -char printBuff[4][20]; //mirrors what is showing on the two lines of the display - -void LCD_Init(void) -{ - LCD1602_Dual_Init(); - - _Addr = I2C_LCD_SECOND_ADDRESS; - initMeter(); //for Meter Display //when dual LCD, S.Meter on second LCD - _Addr = I2C_LCD_MASTER_ADDRESS; -} - - -// The generic routine to display one line on the LCD -void printLine(unsigned char linenmbr, const char *c) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - if (strcmp(c, printBuff[linenmbr])) { // only refresh the display when there was a change - LCD_SetCursor(0, linenmbr); // place the cursor at the beginning of the selected line - LCD_Print(c); - strcpy(printBuff[linenmbr], c); - - for (byte i = strlen(c); i < 20; i++) { // add white spaces until the end of the 20 characters line is reached - LCD_Write(' '); - } - } -} - -void printLineF(char linenmbr, const __FlashStringHelper *c) -{ - int i; - char tmpBuff[21]; - PGM_P p = reinterpret_cast(c); - - for (i = 0; i < 21; i++){ - unsigned char fChar = pgm_read_byte(p++); - tmpBuff[i] = fChar; - if (fChar == 0) - break; - } - - printLine(linenmbr, tmpBuff); -} - -#define LCD_MAX_COLUMN 20 -void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetTtype) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - - LCD_SetCursor(lcdColumn, linenmbr); - - for (byte i = eepromStartIndex; i <= eepromEndIndex; i++) - { - if (++lcdColumn <= LCD_MAX_COLUMN) - LCD_Write(EEPROM.read((offsetTtype == 0 ? USER_CALLSIGN_DAT : WSPR_MESSAGE1) + i)); - else - break; - } - - for (byte i = lcdColumn; i < 20; i++) //Right Padding by Space - LCD_Write(' '); -} - -// short cut to print to the first line -void printLine1(const char *c) -{ - printLine(1,c); -} -// short cut to print to the first line -void printLine2(const char *c) -{ - printLine(0,c); -} - -void clearLine2() -{ - printLine2(""); - line2DisplayStatus = 0; -} - -// short cut to print to the first line -void printLine1Clear(){ - printLine(1,""); -} -// short cut to print to the first line -void printLine2Clear(){ - printLine(0, ""); -} - -void printLine2ClearAndUpdate(){ - printLine(0, ""); - line2DisplayStatus = 0; - updateDisplay(); -} - -//================================================================================== -//End of Display Base Routines -//================================================================================== - - -//================================================================================== -//Begin of User Interface Routines -//================================================================================== - -//Main Display -// this builds up the top line of the display with frequency and mode -void updateDisplay() { - // tks Jack Purdum W8TEE - // replaced fsprint commmands by str commands for code size reduction - // replace code for Frequency numbering error (alignment, point...) by KD8CEC - // i also Very TNX Purdum for good source code - int i; - unsigned long tmpFreq = frequency; // - - memset(c, 0, sizeof(c)); - - if (inTx){ - if (isCWAutoMode == 2) { - for (i = 0; i < 4; i++) - c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); - - //display Sending Index - c[4] = byteToChar(sendingCWTextIndex); - c[5] = '='; - } - else { - if (cwTimeout > 0) - strcpy(c, " CW:"); - else - strcpy(c, " TX:"); - } - } - else { - if (ritOn) - strcpy(c, "RIT "); - else { - if (cwMode == 0) - { - if (isUSB) - strcpy(c, "USB "); - else - strcpy(c, "LSB "); - } - else if (cwMode == 1) - { - strcpy(c, "CWL "); - } - else - { - strcpy(c, "CWU "); - } - } - - if (vfoActive == VFO_A) // VFO A is active - strcat(c, "A:"); - else - strcat(c, "B:"); - } - - //Fixed by Mitani Massaru (JE4SMQ) - if (isShiftDisplayCWFreq == 1) - { - if (cwMode == 1) //CWL - tmpFreq = tmpFreq - sideTone + shiftDisplayAdjustVal; - else if (cwMode == 2) //CWU - tmpFreq = tmpFreq + sideTone + shiftDisplayAdjustVal; - } - - //display frequency - for (int i = 15; i >= 6; i--) { - if (tmpFreq > 0) { - if (i == 12 || i == 8) c[i] = '.'; - else { - c[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - c[i] = ' '; - } - - //remarked by KD8CEC - //already RX/TX status display, and over index (16 x 2 LCD) - printLine(1, c); - - byte diplayVFOLine = 1; - if ((displayOption1 & 0x01) == 0x01) - diplayVFOLine = 0; - - if ((vfoActive == VFO_A && ((isDialLock & 0x01) == 0x01)) || - (vfoActive == VFO_B && ((isDialLock & 0x02) == 0x02))) { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write((uint8_t)0); - } - else if (isCWAutoMode == 2){ - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(0x7E); - } - else - { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(':'); - } -} - - - -char line2Buffer[20]; -//KD8CEC 200Hz ST -//L14.150 200Hz ST -//U14.150 +150khz -int freqScrollPosition = 0; - -//Example Line2 Optinal Display -//immediate execution, not call by scheulder -//warning : unused parameter 'displayType' <-- ignore, this is reserve -void updateLine2Buffer(char displayType) -{ - unsigned long tmpFreq = 0; - if (ritOn) - { - strcpy(line2Buffer, "RitTX:"); - - //display frequency - tmpFreq = ritTxFrequency; - - //Fixed by Mitani Massaru (JE4SMQ) - if (isShiftDisplayCWFreq == 1) - { - if (cwMode == 1) //CWL - tmpFreq = tmpFreq - sideTone + shiftDisplayAdjustVal; - else if (cwMode == 2) //CWU - tmpFreq = tmpFreq + sideTone + shiftDisplayAdjustVal; - } - - for (int i = 15; i >= 6; i--) { - if (tmpFreq > 0) { - if (i == 12 || i == 8) line2Buffer[i] = '.'; - else { - line2Buffer[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - line2Buffer[i] = ' '; - } - - return; - } //end of ritOn display - - //other VFO display - if (vfoActive == VFO_B) - { - tmpFreq = vfoA; - } - else - { - tmpFreq = vfoB; - } - - // EXAMPLE 1 & 2 - //U14.150.100 - //display frequency - for (int i = 9; i >= 0; i--) { - if (tmpFreq > 0) { - if (i == 2 || i == 6) line2Buffer[i] = '.'; - else { - line2Buffer[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - line2Buffer[i] = ' '; - } - - memset(&line2Buffer[10], ' ', 10); - - if (isIFShift) - { - line2Buffer[6] = 'M'; - line2Buffer[7] = ' '; - //IFShift Offset Value - line2Buffer[8] = 'I'; - line2Buffer[9] = 'F'; - - line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0; - line2Buffer[11] = 0; - line2Buffer[12] = ' '; - - //11, 12, 13, 14, 15 - memset(b, 0, sizeof(b)); - ltoa(ifShiftValue, b, DEC); - strncat(line2Buffer, b, 5); - - for (int i = 12; i < 17; i++) - { - if (line2Buffer[i] == 0) - line2Buffer[i] = ' '; - } - } // end of display IF - else // step & Key Type display - { - //Step - long tmpStep = arTuneStep[tuneStepIndex -1]; - - byte isStepKhz = 0; - if (tmpStep >= 1000) - { - isStepKhz = 2; - } - - for (int i = 13; i >= 11 - isStepKhz; i--) { - if (tmpStep > 0) { - line2Buffer[i + isStepKhz] = tmpStep % 10 + 0x30; - tmpStep /= 10; - } - else - line2Buffer[i +isStepKhz] = ' '; - } - - if (isStepKhz == 0) - { - line2Buffer[14] = 'H'; - line2Buffer[15] = 'z'; - } - } - - //line2Buffer[17] = ' '; - /* ianlee - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (cwKeyType == 0) - { - line2Buffer[18] = 'S'; - line2Buffer[19] = 'T'; - } - else if (cwKeyType == 1) - { - line2Buffer[18] = 'I'; - line2Buffer[19] = 'A'; - } - else - { - line2Buffer[18] = 'I'; - line2Buffer[19] = 'B'; - } -*/ - -} - - -//meterType : 0 = S.Meter, 1 : P.Meter -void DisplayMeter(byte meterType, byte meterValue, char drawPosition) -{ - if (meterType == 0 || meterType == 1 || meterType == 2) - { - drawMeter(meterValue); - - LCD_SetCursor(drawPosition, 0); - LCD_Write('S'); - - LCD_Write(':'); - for (int i = 0; i < 7; i++) - LCD_Write(lcdMeter[i]); - } -} - - -char checkCount = 0; -char checkCountSMeter = 0; - -char beforeKeyType = -1; -char displaySDRON = 0; - -//execute interval : 0.25sec -void idle_process() -{ - //space for user graphic display - if (menuOn == 0) - { - if ((displayOption1 & 0x10) == 0x10) //always empty topline - return; - - //if line2DisplayStatus == 0 <-- this condition is clear Line, you can display any message - if (line2DisplayStatus == 0 || (((displayOption1 & 0x04) == 0x04) && line2DisplayStatus == 2)) { - if (checkCount++ > 1) - { - updateLine2Buffer(0); //call by scheduler - printLine2(line2Buffer); - line2DisplayStatus = 2; - checkCount = 0; - - //check change CW Key Type - if (beforeKeyType != cwKeyType) - { - _Addr = I2C_LCD_SECOND_ADDRESS; - LCD_SetCursor(10, 0); - LCD_Write('K'); - LCD_Write('E'); - LCD_Write('Y'); - LCD_Write(':'); - - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (cwKeyType == 0) - { - LCD_Write('S'); - LCD_Write('T'); - } - else if (cwKeyType == 1) - { - LCD_Write('I'); - LCD_Write('A'); - } - else - { - LCD_Write('I'); - LCD_Write('B'); - } - - beforeKeyType = cwKeyType; - _Addr = I2C_LCD_MASTER_ADDRESS; - } //Display Second Screen - - } - } - - //EX for Meters - - //S-Meter Display - _Addr = I2C_LCD_SECOND_ADDRESS; - if (sdrModeOn == 1) - { - if (displaySDRON == 0) //once display - { - displaySDRON = 1; - LCD_SetCursor(0, 0); - LCD_Write('S'); - LCD_Write('D'); - LCD_Write('R'); - LCD_Write(' '); - LCD_Write('M'); - LCD_Write('O'); - LCD_Write('D'); - LCD_Write('E'); - } - } - else if (((displayOption1 & 0x08) == 0x08) && (++checkCountSMeter > 3)) - { - int newSMeter; - displaySDRON = 0; - -#ifdef USE_I2CSMETER - scaledSMeter = GetI2CSmeterValue(I2CMETER_CALCS); -#else - //VK2ETA S-Meter from MAX9814 TC pin / divide 4 by KD8CEC for reduce EEPromSize - newSMeter = analogRead(ANALOG_SMETER) / 4; - - //Faster attack, Slower release - //currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10); - //currentSMeter = (currentSMeter * 3 + newSMeter * 7) / 10; //remarked becaused of have already Latency time - currentSMeter = newSMeter; - - scaledSMeter = 0; - for (byte s = 8; s >= 1; s--) { - if (currentSMeter > sMeterLevels[s]) { - scaledSMeter = s; - break; - } - } -#endif - - DisplayMeter(0, scaledSMeter, 0); - checkCountSMeter = 0; - } //end of S-Meter - _Addr = I2C_LCD_MASTER_ADDRESS; - - - } -} - -//AutoKey LCD Display Routine -void Display_AutoKeyTextIndex(byte textIndex) -{ - byte diplayAutoCWLine = 0; - - if ((displayOption1 & 0x01) == 0x01) - diplayAutoCWLine = 1; - LCD_SetCursor(0, diplayAutoCWLine); - LCD_Write(byteToChar(textIndex)); - LCD_Write(':'); -} - -void DisplayCallsign(byte callSignLength) -{ - _Addr = I2C_LCD_SECOND_ADDRESS; - printLineFromEEPRom(1, 16 - userCallsignLength, 0, userCallsignLength -1, 0); //eeprom to lcd use offset (USER_CALLSIGN_DAT) - _Addr = I2C_LCD_MASTER_ADDRESS; -} - -void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo) -{ - _Addr = I2C_LCD_SECOND_ADDRESS; - printLineF(1, fwVersionInfo); - _Addr = I2C_LCD_MASTER_ADDRESS; -} - -#endif diff --git a/ubitx_20/ubitx_lcd_2004.ino b/ubitx_20/ubitx_lcd_2004.ino deleted file mode 100644 index 06d44fa..0000000 --- a/ubitx_20/ubitx_lcd_2004.ino +++ /dev/null @@ -1,743 +0,0 @@ -/************************************************************************* - KD8CEC's uBITX Display Routine for LCD2004 Parrel & I2C - 1.This is the display code for the 20x04 LCD - 2.Some functions moved from uBITX_Ui. ------------------------------------------------------------------------------ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -**************************************************************************/ -#include "ubitx.h" -#include "ubitx_lcd.h" - -//======================================================================== -//Begin of TinyLCD Library by KD8CEC -//======================================================================== - -#ifdef UBITX_DISPLAY_LCD2004P -/************************************************************************* - LCD2004TINY Library for 20 x 4 LCD - Referecnce Source : LiquidCrystal.cpp - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal Library - - I wrote this code myself, so there is no license restriction. - So this code allows anyone to write with confidence. - But keep it as long as the original author of the code. - DE Ian KD8CEC -**************************************************************************/ -#define LCD_Command(x) (LCD_Send(x, LOW)) -#define LCD_Write(x) (LCD_Send(x, HIGH)) - -#define UBITX_DISPLAY_LCD2004_BASE - -//Define connected PIN -#define LCD_PIN_RS 8 -#define LCD_PIN_EN 9 -uint8_t LCD_PIN_DAT[4] = {10, 11, 12, 13}; - -void write4bits(uint8_t value) -{ - for (int i = 0; i < 4; i++) - digitalWrite(LCD_PIN_DAT[i], (value >> i) & 0x01); - - digitalWrite(LCD_PIN_EN, LOW); - delayMicroseconds(1); - digitalWrite(LCD_PIN_EN, HIGH); - delayMicroseconds(1); // enable pulse must be >450ns - digitalWrite(LCD_PIN_EN, LOW); - delayMicroseconds(100); // commands need > 37us to settle -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - digitalWrite(LCD_PIN_RS, mode); - write4bits(value>>4); - write4bits(value); -} - -void LCD2004_Init() -{ - pinMode(LCD_PIN_RS, OUTPUT); - pinMode(LCD_PIN_EN, OUTPUT); - for (int i = 0; i < 4; i++) - pinMode(LCD_PIN_DAT[i], OUTPUT); - - delayMicroseconds(50); - - // Now we pull both RS and R/W low to begin commands - digitalWrite(LCD_PIN_RS, LOW); - digitalWrite(LCD_PIN_EN, LOW); - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - delayMicroseconds(2000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); -} -#endif -//======================================================================== -//End of TinyLCD Library by KD8CEC -//======================================================================== - - - -//======================================================================== -//Begin of I2CTinyLCD Library by KD8CEC -//======================================================================== -#ifdef UBITX_DISPLAY_LCD2004I - -#include -/************************************************************************* - I2C Tiny LCD Library - Referecnce Source : LiquidCrystal_I2C.cpp // Based on the work by DFRobot - KD8CEC - - This source code is modified version for small program memory - from Arduino LiquidCrystal_I2C Library - - I wrote this code myself, so there is no license restriction. - So this code allows anyone to write with confidence. - But keep it as long as the original author of the code. - Ian KD8CEC -**************************************************************************/ -#define UBITX_DISPLAY_LCD2004_BASE - -#define En B00000100 // Enable bit -#define Rw B00000010 // Read/Write bit -#define Rs B00000001 // Register select bit - -#define LCD_Command(x) (LCD_Send(x, 0)) -#define LCD_Write(x) (LCD_Send(x, Rs)) - -uint8_t _Addr; -uint8_t _displayfunction; -uint8_t _displaycontrol; -uint8_t _displaymode; -uint8_t _numlines; -uint8_t _cols; -uint8_t _rows; -uint8_t _backlightval; - -#define printIIC(args) Wire.write(args) - -void expanderWrite(uint8_t _data) -{ - Wire.beginTransmission(_Addr); - printIIC((int)(_data) | _backlightval); - Wire.endTransmission(); -} - -void pulseEnable(uint8_t _data){ - expanderWrite(_data | En); // En high - delayMicroseconds(1); // enable pulse must be >450ns - - expanderWrite(_data & ~En); // En low - delayMicroseconds(50); // commands need > 37us to settle -} - -void write4bits(uint8_t value) -{ - expanderWrite(value); - pulseEnable(value); -} - -void LCD_Send(uint8_t value, uint8_t mode) -{ - uint8_t highnib=value&0xf0; - uint8_t lownib=(value<<4)&0xf0; - write4bits((highnib)|mode); - write4bits((lownib)|mode); -} - - -// Turn the (optional) backlight off/on -void noBacklight(void) { - _backlightval=LCD_NOBACKLIGHT; - expanderWrite(0); -} - -void backlight(void) { - _backlightval=LCD_BACKLIGHT; - expanderWrite(0); -} - -void LCD2004_Init() -{ - //I2C Init - _Addr = I2C_LCD_MASTER_ADDRESS; - _cols = 20; - _rows = 4; - _backlightval = LCD_NOBACKLIGHT; - Wire.begin(); - - delay(50); - - // Now we pull both RS and R/W low to begin commands - expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) - delay(1000); - //put the LCD into 4 bit mode - // this is according to the hitachi HD44780 datasheet - // figure 24, pg 46 - - // we start in 8bit mode, try to set 4 bit mode - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // second try - write4bits(0x03 << 4); - delayMicroseconds(4500); // wait min 4.1ms - - // third go! - write4bits(0x03 << 4); - delayMicroseconds(150); - - // finally, set to 4-bit interface - write4bits(0x02 << 4); - - // finally, set # lines, font size, etc. - LCD_Command(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS | LCD_2LINE); - - // turn the display on with no cursor or blinking default - LCD_Command(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF); - - // clear it off - LCD_Command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero - //delayMicroseconds(2000); // this command takes a long time! - delayMicroseconds(1000); // this command takes a long time! - - LCD_Command(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); - - backlight(); -} -#endif -//======================================================================== -//End of I2CTinyLCD Library by KD8CEC -//======================================================================== - - -//======================================================================== -// 20 X 04 LCD Routines -//Begin of Display Base Routines (Init, printLine..) -//======================================================================== -#ifdef UBITX_DISPLAY_LCD2004_BASE - -void LCD_Print(const char *c) -{ - for (uint8_t i = 0; i < strlen(c); i++) - { - if (*(c + i) == 0x00) return; - LCD_Write(*(c + i)); - } -} - -const int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; -void LCD_SetCursor(uint8_t col, uint8_t row) -{ - LCD_Command(LCD_SETDDRAMADDR | (col + row_offsets[row])); //0 : 0x00, 1 : 0x40, only for 20 x 4 lcd -} - -void LCD_CreateChar(uint8_t location, uint8_t charmap[]) -{ - location &= 0x7; // we only have 8 locations 0-7 - LCD_Command(LCD_SETCGRAMADDR | (location << 3)); - for (int i=0; i<8; i++) - LCD_Write(charmap[i]); -} - -//SWR GRAPH, DrawMeter and drawingMeter Logic function by VK2ETA -//#define OPTION_SKINNYBARS - -char c[30], b[30]; -char printBuff[4][21]; //mirrors what is showing on the two lines of the display - -void LCD_Init(void) -{ - LCD2004_Init(); - initMeter(); //for Meter Display -} - - -// The generic routine to display one line on the LCD -void printLine(unsigned char linenmbr, const char *c) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - if (strcmp(c, printBuff[linenmbr])) { // only refresh the display when there was a change - LCD_SetCursor(0, linenmbr); // place the cursor at the beginning of the selected line - LCD_Print(c); - strcpy(printBuff[linenmbr], c); - - for (byte i = strlen(c); i < 20; i++) { // add white spaces until the end of the 20 characters line is reached - LCD_Write(' '); - } - } -} - -void printLineF(char linenmbr, const __FlashStringHelper *c) -{ - int i; - char tmpBuff[21]; - PGM_P p = reinterpret_cast(c); - - for (i = 0; i < 21; i++){ - unsigned char fChar = pgm_read_byte(p++); - tmpBuff[i] = fChar; - if (fChar == 0) - break; - } - - printLine(linenmbr, tmpBuff); -} - -#define LCD_MAX_COLUMN 20 -void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetTtype) { - if ((displayOption1 & 0x01) == 0x01) - linenmbr = (linenmbr == 0 ? 1 : 0); //Line Toggle - - LCD_SetCursor(lcdColumn, linenmbr); - - for (byte i = eepromStartIndex; i <= eepromEndIndex; i++) - { - if (++lcdColumn <= LCD_MAX_COLUMN) - LCD_Write(EEPROM.read((offsetTtype == 0 ? USER_CALLSIGN_DAT : WSPR_MESSAGE1) + i)); - else - break; - } - - for (byte i = lcdColumn; i < 20; i++) //Right Padding by Space - LCD_Write(' '); -} - -// short cut to print to the first line -void printLine1(const char *c) -{ - printLine(1,c); -} -// short cut to print to the first line -void printLine2(const char *c) -{ - printLine(0,c); -} - -void clearLine2() -{ - printLine2(""); - line2DisplayStatus = 0; -} - -// short cut to print to the first line -void printLine1Clear(){ - printLine(1,""); -} -// short cut to print to the first line -void printLine2Clear(){ - printLine(0, ""); -} - -void printLine2ClearAndUpdate(){ - printLine(0, ""); - line2DisplayStatus = 0; - updateDisplay(); -} - -//================================================================================== -//End of Display Base Routines -//================================================================================== - - -//================================================================================== -//Begin of User Interface Routines -//================================================================================== - -//Main Display -// this builds up the top line of the display with frequency and mode -void updateDisplay() { - // tks Jack Purdum W8TEE - // replaced fsprint commmands by str commands for code size reduction - // replace code for Frequency numbering error (alignment, point...) by KD8CEC - // i also Very TNX Purdum for good source code - int i; - unsigned long tmpFreq = frequency; // - - memset(c, 0, sizeof(c)); - - if (inTx){ - if (isCWAutoMode == 2) { - for (i = 0; i < 4; i++) - c[3-i] = (i < autoCWSendReservCount ? byteToChar(autoCWSendReserv[i]) : ' '); - - //display Sending Index - c[4] = byteToChar(sendingCWTextIndex); - c[5] = '='; - } - else { - if (cwTimeout > 0) - strcpy(c, " CW:"); - else - strcpy(c, " TX:"); - } - } - else { - if (ritOn) - strcpy(c, "RIT "); - else { - if (cwMode == 0) - { - if (isUSB) - strcpy(c, "USB "); - else - strcpy(c, "LSB "); - } - else if (cwMode == 1) - { - strcpy(c, "CWL "); - } - else - { - strcpy(c, "CWU "); - } - } - - if (vfoActive == VFO_A) // VFO A is active - strcat(c, "A:"); - else - strcat(c, "B:"); - } - - //Fixed by Mitani Massaru (JE4SMQ) - if (isShiftDisplayCWFreq == 1) - { - if (cwMode == 1) //CWL - tmpFreq = tmpFreq - sideTone + shiftDisplayAdjustVal; - else if (cwMode == 2) //CWU - tmpFreq = tmpFreq + sideTone + shiftDisplayAdjustVal; - } - - //display frequency - for (int i = 15; i >= 6; i--) { - if (tmpFreq > 0) { - if (i == 12 || i == 8) c[i] = '.'; - else { - c[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - c[i] = ' '; - } - - if (sdrModeOn) - strcat(c, " SDR"); - else - strcat(c, " SPK"); - - //remarked by KD8CEC - //already RX/TX status display, and over index (20 x 4 LCD) - //if (inTx) - // strcat(c, " TX"); - printLine(1, c); - - byte diplayVFOLine = 1; - if ((displayOption1 & 0x01) == 0x01) - diplayVFOLine = 0; - - if ((vfoActive == VFO_A && ((isDialLock & 0x01) == 0x01)) || - (vfoActive == VFO_B && ((isDialLock & 0x02) == 0x02))) { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write((uint8_t)0); - } - else if (isCWAutoMode == 2){ - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(0x7E); - } - else - { - LCD_SetCursor(5,diplayVFOLine); - LCD_Write(':'); - } -} - - - -char line2Buffer[20]; -//KD8CEC 200Hz ST -//L14.150 200Hz ST -//U14.150 +150khz -int freqScrollPosition = 0; - -//Example Line2 Optinal Display -//immediate execution, not call by scheulder -//warning : unused parameter 'displayType' <-- ignore, this is reserve -void updateLine2Buffer(char displayType) -{ - unsigned long tmpFreq = 0; - if (ritOn) - { - strcpy(line2Buffer, "RitTX:"); - - //display frequency - tmpFreq = ritTxFrequency; - - //Fixed by Mitani Massaru (JE4SMQ) - if (isShiftDisplayCWFreq == 1) - { - if (cwMode == 1) //CWL - tmpFreq = tmpFreq - sideTone + shiftDisplayAdjustVal; - else if (cwMode == 2) //CWU - tmpFreq = tmpFreq + sideTone + shiftDisplayAdjustVal; - } - - for (int i = 15; i >= 6; i--) { - if (tmpFreq > 0) { - if (i == 12 || i == 8) line2Buffer[i] = '.'; - else { - line2Buffer[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - line2Buffer[i] = ' '; - } - - return; - } //end of ritOn display - - //other VFO display - if (vfoActive == VFO_B) - { - tmpFreq = vfoA; - } - else - { - tmpFreq = vfoB; - } - - // EXAMPLE 1 & 2 - //U14.150.100 - //display frequency - for (int i = 9; i >= 0; i--) { - if (tmpFreq > 0) { - if (i == 2 || i == 6) line2Buffer[i] = '.'; - else { - line2Buffer[i] = tmpFreq % 10 + 0x30; - tmpFreq /= 10; - } - } - else - line2Buffer[i] = ' '; - } - - memset(&line2Buffer[10], ' ', 10); - - if (isIFShift) - { - line2Buffer[6] = 'M'; - line2Buffer[7] = ' '; - //IFShift Offset Value - line2Buffer[8] = 'I'; - line2Buffer[9] = 'F'; - - line2Buffer[10] = ifShiftValue >= 0 ? '+' : 0; - line2Buffer[11] = 0; - line2Buffer[12] = ' '; - - //11, 12, 13, 14, 15 - memset(b, 0, sizeof(b)); - ltoa(ifShiftValue, b, DEC); - strncat(line2Buffer, b, 5); - - for (int i = 12; i < 17; i++) - { - if (line2Buffer[i] == 0) - line2Buffer[i] = ' '; - } - } // end of display IF - else // step & Key Type display - { - //Step - long tmpStep = arTuneStep[tuneStepIndex -1]; - - byte isStepKhz = 0; - if (tmpStep >= 1000) - { - isStepKhz = 2; - } - - for (int i = 14; i >= 12 - isStepKhz; i--) { - if (tmpStep > 0) { - line2Buffer[i + isStepKhz] = tmpStep % 10 + 0x30; - tmpStep /= 10; - } - else - line2Buffer[i +isStepKhz] = ' '; - } - - if (isStepKhz == 0) - { - line2Buffer[15] = 'H'; - line2Buffer[16] = 'z'; - } - } - - line2Buffer[17] = ' '; - - //Check CW Key cwKeyType = 0; //0: straight, 1 : iambica, 2: iambicb - if (cwKeyType == 0) - { - line2Buffer[18] = 'S'; - line2Buffer[19] = 'T'; - } - else if (cwKeyType == 1) - { - line2Buffer[18] = 'I'; - line2Buffer[19] = 'A'; - } - else - { - line2Buffer[18] = 'I'; - line2Buffer[19] = 'B'; - } - -} - -//meterType : 0 = S.Meter, 1 : P.Meter -void DisplayMeter(byte meterType, byte meterValue, char drawPosition) -{ - if (meterType == 0 || meterType == 1 || meterType == 2) - { - drawMeter(meterValue); - - LCD_SetCursor(drawPosition, 2); - LCD_Write('S'); - LCD_Write(':'); - for (int i = 0; i < 7; i++) //meter 5 + +db 1 = 6 - LCD_Write(lcdMeter[i]); - } -} - -char checkCount = 0; -char checkCountSMeter = 0; - -//execute interval : 0.25sec -void idle_process() -{ - //space for user graphic display - if (menuOn == 0) - { - if ((displayOption1 & 0x10) == 0x10) //always empty topline - return; - - //if line2DisplayStatus == 0 <-- this condition is clear Line, you can display any message - if (line2DisplayStatus == 0 || (((displayOption1 & 0x04) == 0x04) && line2DisplayStatus == 2)) { - if (checkCount++ > 1) - { - updateLine2Buffer(0); //call by scheduler - printLine2(line2Buffer); - line2DisplayStatus = 2; - checkCount = 0; - } - } - - //EX for Meters - /* - DisplayMeter(0, testValue++, 0); - if (testValue > 30) - testValue = 0; - */ - - //Sample - //DisplayMeter(0, analogRead(ANALOG_SMETER) / 30, 0); - //DisplayMeter(0, analogRead(ANALOG_SMETER) / 10, 0); - //delay_background(10, 0); - //DisplayMeter(0, analogRead(ANALOG_SMETER), 0); - //if (testValue > 30) - // testValue = 0; - - //S-Meter Display - if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) - { - int newSMeter; - -#ifdef USE_I2CSMETER - scaledSMeter = GetI2CSmeterValue(I2CMETER_CALCS); -#else - //VK2ETA S-Meter from MAX9814 TC pin - newSMeter = analogRead(ANALOG_SMETER) / 4; - - //Faster attack, Slower release - //currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10); - //currentSMeter = ((currentSMeter * 7 + newSMeter * 3) + 5) / 10; - currentSMeter = newSMeter; - - scaledSMeter = 0; - for (byte s = 8; s >= 1; s--) { - if (currentSMeter > sMeterLevels[s]) { - scaledSMeter = s; - break; - } - } -#endif - - DisplayMeter(0, scaledSMeter, 0); - checkCountSMeter = 0; //Reset Latency time - } //end of S-Meter - - } -} - -//AutoKey LCD Display Routine -void Display_AutoKeyTextIndex(byte textIndex) -{ - byte diplayAutoCWLine = 0; - - if ((displayOption1 & 0x01) == 0x01) - diplayAutoCWLine = 1; - LCD_SetCursor(0, diplayAutoCWLine); - LCD_Write(byteToChar(textIndex)); - LCD_Write(':'); -} - -void DisplayCallsign(byte callSignLength) -{ - printLineFromEEPRom(3, 20 - userCallsignLength, 0, userCallsignLength -1, 0); //eeprom to lcd use offset (USER_CALLSIGN_DAT) -} - -void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo) -{ - printLineF(3, fwVersionInfo); -} - -#endif diff --git a/ubitx_20/ubitx_lcd_nextion.ino b/ubitx_20/ubitx_lcd_nextion.ino deleted file mode 100644 index 62667af..0000000 --- a/ubitx_20/ubitx_lcd_nextion.ino +++ /dev/null @@ -1,1107 +0,0 @@ -/************************************************************************* - KD8CEC's uBITX Display Routine for Nextion LCD - - Uses the default protocol of Nextion LCD. - Do not assign a 2 byte address to Nextion LCD. ------------------------------------------------------------------------------ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -**************************************************************************/ -#include "ubitx.h" -#include "ubitx_lcd.h" - -//======================================================================== -//Begin of Nextion LCD Library by KD8CEC -//======================================================================== -#ifdef UBITX_DISPLAY_NEXTION -/************************************************************************* - Nextion Library for uBItX - KD8CEC -**************************************************************************/ -extern void SWSerial_Begin(long speedBaud); -extern void SWSerial_Write(uint8_t b); -extern int SWSerial_Available(void); -extern int SWSerial_Read(void); -extern void SWSerial_Print(uint8_t *b); - -#define TEXT_LINE_LENGTH 20 -char softBuffLines[2][TEXT_LINE_LENGTH + 1]; -char softBuffSended[2][TEXT_LINE_LENGTH + 1]; -char softBuffTemp[TEXT_LINE_LENGTH + 1]; //for STR Command - -char c[30], b[30]; -char softBuff[20]; -char softTemp[20]; - -void LCDNextion_Init() -{ - SWSerial_Begin(9600); - memset(softBuffLines[0], ' ', TEXT_LINE_LENGTH); - softBuffLines[0][TEXT_LINE_LENGTH + 1] = 0x00; - memset(softBuffLines[1], ' ', TEXT_LINE_LENGTH); - softBuffLines[1][TEXT_LINE_LENGTH + 1] = 0x00; -} - -void LCD_Init(void) -{ - LCDNextion_Init(); -} - -//=================================================================== -//Begin of Nextion LCD Protocol -// -// v0~v9, va~vz : Numeric (Transceiver -> Nextion LCD) -// s0~s9 : String (Text) (Transceiver -> Nextion LCD) -// vlSendxxx, vloxxx: Reserve for Nextion (Nextion LCD -> Transceiver) -// -//=================================================================== -#define CMD_NOW_DISP '0' //c0 -char L_nowdisp = -1; //Sended nowdisp - -#define CMD_VFO_TYPE 'v' //cv -char L_vfoActive; //vfoActive - -#define CMD_CURR_FREQ 'c' //vc -unsigned long L_vfoCurr; //vfoA -#define CMD_CURR_MODE 'c' //cc -byte L_vfoCurr_mode; //vfoA_mode - -#define CMD_VFOA_FREQ 'a' //va -unsigned long L_vfoA; //vfoA -#define CMD_VFOA_MODE 'a' //ca -byte L_vfoA_mode; //vfoA_mode - -#define CMD_VFOB_FREQ 'b' //vb -unsigned long L_vfoB; //vfoB -#define CMD_VFOB_MODE 'b' //cb -byte L_vfoB_mode; //vfoB_mode - -#define CMD_IS_RIT 'r' //cr -char L_ritOn; -#define CMD_RIT_FREQ 'r' //vr -unsigned long L_ritTxFrequency; //ritTxFrequency - -#define CMD_IS_TX 't' //ct -char L_inTx; - -#define CMD_IS_DIALLOCK 'l' //cl -byte L_isDialLock; //byte isDialLock - -#define CMD_IS_SPLIT 's' //cs -byte L_Split; //isTxType -#define CMD_IS_TXSTOP 'x' //cx -byte L_TXStop; //isTxType - -#define CMD_TUNEINDEX 'n' //cn -byte L_tuneStepIndex; //byte tuneStepIndex - -#define CMD_SMETER 'p' //cs -byte L_scaledSMeter; //scaledSMeter - -#define CMD_SIDE_TONE 't' //vt -unsigned long L_sideTone; //sideTone -#define CMD_KEY_TYPE 'k' //ck -byte L_cwKeyType = -1; //L_cwKeyType 0: straight, 1 : iambica, 2: iambicb - -#define CMD_CW_SPEED 's' //vs -unsigned int L_cwSpeed; //cwSpeed - -#define CMD_CW_DELAY 'y' //vy -byte L_cwDelayTime=-1; //cwDelayTime - -#define CMD_CW_STARTDELAY 'e' //ve -byte L_delayBeforeCWStartTime=-1; //byte delayBeforeCWStartTime - -#define CMD_ATT_LEVEL 'f' //vf -byte L_attLevel; - -byte L_isIFShift; //1 = ifShift, 2 extend -#define CMD_IS_IFSHIFT 'i' //ci - -int L_ifShiftValue; -#define CMD_IFSHIFT_VALUE 'i' //vi - -byte L_sdrModeOn; -#define CMD_SDR_MODE 'j' //cj - -#define CMD_UBITX_INFO 'm' //cm Complete Send uBITX Information - -//Once Send Data, When boot -//arTuneStep, When boot, once send -//long arTuneStep[5]; -#define CMD_AR_TUNE1 '1' //v1 -#define CMD_AR_TUNE2 '2' //v2 -#define CMD_AR_TUNE3 '3' //v3 -#define CMD_AR_TUNE4 '4' //v4 -#define CMD_AR_TUNE5 '5' //v5 - - -#define CMD_IS_CW_SHIFT_DISPLAY 'h' //ch -byte L_isShiftDisplayCWFreq; //byte isShiftDisplayCWFreq - -#define CMD_CW_SHIFT_ADJUST 'h' //vh -int L_shiftDisplayAdjustVal; //int shiftDisplayAdjustVal - -//0:CW Display Shift Confirm, 1 : IFshift save -#define CMD_COMM_OPTION 'o' //vo -byte L_commonOption0; //byte commonOption0 - -//0:Line Toggle, 1 : Always display Callsign, 2 : scroll display, 3 : s.meter -#define CMD_DISP_OPTION1 'p' //vp -byte L_displayOption1; //byte displayOption1 -#define CMD_DISP_OPTION2 'q' //vq -byte L_displayOption2; //byte displayOption2 (Reserve) - -#define CMD_TEXT_LINE0 '0' //s0 -#define CMD_TEXT_LINE1 '1' //s1 - -#define CMD_CW_TEXT 'a' //sa -#define CMD_CALLSIGN 'c' //sc -#define CMD_VERSION 'v' //sv - -#define TS_CMD_MODE 1 -#define TS_CMD_FREQ 2 -#define TS_CMD_BAND 3 -#define TS_CMD_VFO 4 -#define TS_CMD_SPLIT 5 -#define TS_CMD_RIT 6 -#define TS_CMD_TXSTOP 7 -#define TS_CMD_SDR 8 -#define TS_CMD_LOCK 9 //Dial Lock -#define TS_CMD_ATT 10 //ATT -#define TS_CMD_IFS 11 //IFS Enabled -#define TS_CMD_IFSVALUE 12 //IFS VALUE -#define TS_CMD_STARTADC 13 -#define TS_CMD_STOPADC 14 -#define TS_CMD_SPECTRUMOPT 15 //Option for Spectrum -#define TS_CMD_SPECTRUM 16 //Get Spectrum Value -#define TS_CMD_TUNESTEP 17 //Get Spectrum Value -#define TS_CMD_WPM 18 //Set WPM -#define TS_CMD_KEYTYPE 19 //Set KeyType - -#define TS_CMD_SWTRIG 21 //SW Action Trigger for WSPR and more -#define TS_CMD_READMEM 31 //Read EEProm -#define TS_CMD_WRITEMEM 32 //Write EEProm -#define TS_CMD_LOOPBACK0 74 //Loopback1 (Response to Loopback Channgel) -#define TS_CMD_LOOPBACK1 75 //Loopback2 (Response to Loopback Channgel) -#define TS_CMD_LOOPBACK2 76 //Loopback3 (Response to Loopback Channgel) -#define TS_CMD_LOOPBACK3 77 //Loopback4 (Response to Loopback Channgel) -#define TS_CMD_LOOPBACK4 78 //Loopback5 (Response to Loopback Channgel) -#define TS_CMD_LOOPBACK5 79 //Loopback6 (Response to Loopback Channgel) -#define TS_CMD_FACTORYRESET 85 //Factory Reset -#define TS_CMD_UBITX_REBOOT 95 //Reboot - -char nowdisp = 0; - -#define SWS_HEADER_CHAR_TYPE 'c' //1Byte Protocol Prefix -#define SWS_HEADER_INT_TYPE 'v' //Numeric Protocol Prefex -#define SWS_HEADER_STR_TYPE 's' //for TEXT Line compatiable Character LCD Control - -//Control must have prefix 'v' or 's' -char softSTRHeader[11] = {'p', 'm', '.', 's', '0', '.', 't', 'x', 't', '=', '\"'}; -char softINTHeader[10] = {'p', 'm', '.', 'v', '0', '.', 'v', 'a', 'l', '='}; -const byte ADCIndex[6] = {A0, A1, A2, A3, A6, A7}; - -//send data for Nextion LCD -void SendHeader(char varType, char varIndex) -{ - if (varType == SWS_HEADER_STR_TYPE) - { - softSTRHeader[4] = varIndex; - for (int i = 0; i < 11; i++) - SWSerial_Write(softSTRHeader[i]); - } - else - { - softINTHeader[4] = varIndex; - for (int i = 0; i < 10; i++) - SWSerial_Write(softINTHeader[i]); - } -} - -#define INT_ETX 0 -#define STR_ETX 1 -#define TMP_ETX 2 -//Send 0xFF, 0xFF, 0xFF -//etxType : INT_ETX = 0xFF, 0xFF, 0xFF -// STR_ETX = ", 0xFF, 0xFF, 0xFF -// TEMP_ETX = softTemp, 0xFF, 0xFF, 0xff - -void SendCommandETX(char etxType) -{ - if (etxType == 2) - { - SWSerial_Print(softTemp); - } - else if (etxType == 1) - { - SWSerial_Print("\""); - } - - SWSerial_Write(0xff); - SWSerial_Write(0xff); - SWSerial_Write(0xff); -} - -void SendCommandUL(char varIndex, unsigned long sendValue) -{ - SendHeader(SWS_HEADER_INT_TYPE, varIndex); - - memset(softTemp, 0, 20); - ultoa(sendValue, softTemp, DEC); - SendCommandETX(TMP_ETX); -} - -void SendCommandL(char varIndex, long sendValue) -{ - SendHeader(SWS_HEADER_INT_TYPE, varIndex); - - memset(softTemp, 0, 20); - ltoa(sendValue, softTemp, DEC); - SendCommandETX(TMP_ETX); -} - -void SendCommandStr(char varIndex, char* sendValue) -{ - SendHeader(SWS_HEADER_STR_TYPE, varIndex); - - SWSerial_Print(sendValue); - SendCommandETX(STR_ETX); -} - -//Send String data with duplicate check -void SendTextLineBuff(char lineNumber) -{ - //Check Duplicated data - if (strcmp(softBuffLines[lineNumber], softBuffSended[lineNumber])) - { - SendHeader(SWS_HEADER_STR_TYPE, lineNumber + 0x30); //s0.txt, s1.txt - - SWSerial_Print(softBuffLines[lineNumber]); - SendCommandETX(STR_ETX); - - strcpy(softBuffSended[lineNumber], softBuffLines[lineNumber]); - } -} - -void SendTextLineStr(char lineNumber, char* sendValue) -{ - int i = 0; - for (i = 0; i < 16; i++) - { - if (sendValue[i] == 0x00) - break; - else - softBuffLines[lineNumber][i] = sendValue[i]; - } - - for (;i < 20; i++) - { - softBuffLines[lineNumber][i] = ' '; - } - - softBuffLines[lineNumber][TEXT_LINE_LENGTH + 1] = 0x00; - SendTextLineBuff(lineNumber); -} - -void SendEEPromData(char varIndex, int eepromStartIndex, int eepromEndIndex, char offsetTtype) -{ - SendHeader(SWS_HEADER_STR_TYPE, varIndex); - - for (int i = eepromStartIndex; i <= eepromEndIndex; i++) - { - SWSerial_Write(EEPROM.read((offsetTtype == 0 ? USER_CALLSIGN_DAT : WSPR_MESSAGE1) + i)); - } - - SendCommandETX(STR_ETX); -} - -uint8_t softBuff1Num[14] = {'p', 'm', '.', 'c', '0', '.', 'v', 'a', 'l', '=', 0, 0xFF, 0xFF, 0xFF}; -void SendCommand1Num(char varType, char sendValue) //0~9 : Mode, nowDisp, ActiveVFO, IsDialLock, IsTxtType, IsSplitType -{ - softBuff1Num[4] = varType; - softBuff1Num[10] = sendValue + 0x30; - - for (int i = 0; i < 14; i++) - SWSerial_Write(softBuff1Num[i]); -} - -void SetSWActivePage(char newPageIndex) -{ - if (L_nowdisp != newPageIndex) - { - L_nowdisp = newPageIndex; - SendCommand1Num(CMD_NOW_DISP, L_nowdisp); - } -} -//=================================================================== -//End of Nextion LCD Protocol -//=================================================================== - -// The generic routine to display one line on the LCD -void printLine(unsigned char linenmbr, const char *c) { - SendTextLineStr(linenmbr, c); -} - -void printLineF(char linenmbr, const __FlashStringHelper *c) -{ - int i; - char tmpBuff[21]; - PGM_P p = reinterpret_cast(c); - - for (i = 0; i < 21; i++){ - unsigned char fChar = pgm_read_byte(p++); - tmpBuff[i] = fChar; - if (fChar == 0) - break; - } - - printLine(linenmbr, tmpBuff); -} - -#define LCD_MAX_COLUMN 20 -void printLineFromEEPRom(char linenmbr, char lcdColumn, byte eepromStartIndex, byte eepromEndIndex, char offsetTtype) -{ - int colIndex = lcdColumn; - for (byte i = eepromStartIndex; i <= eepromEndIndex; i++) - { - if (++lcdColumn <= LCD_MAX_COLUMN) - softBuffLines[linenmbr][colIndex++] = EEPROM.read((offsetTtype == 0 ? USER_CALLSIGN_DAT : WSPR_MESSAGE1) + i); - else - break; - } - - SendTextLineBuff(linenmbr); -} - -// short cut to print to the first line -void printLine1(const char *c) -{ - printLine(1,c); -} -// short cut to print to the first line -void printLine2(const char *c) -{ - printLine(0,c); -} - -void clearLine2() -{ - printLine2(""); - line2DisplayStatus = 0; -} - -// short cut to print to the first line -void printLine1Clear(){ - printLine(1,""); -} -// short cut to print to the first line -void printLine2Clear(){ - printLine(0, ""); -} - -void printLine2ClearAndUpdate(){ - printLine(0, ""); - line2DisplayStatus = 0; - updateDisplay(); -} - -//================================================================================== -//End of Display Base Routines -//================================================================================== - -//================================================================================== -//Begin of User Interface Routines -//================================================================================== -//Main Display for Nextion LCD -//unsigned long -byte nowPageIndex = 0; - -//sendType == 1 not check different -void sendUIData(int sendType) -{ - char nowActiveVFO = vfoActive == VFO_A ? 0 : 1; - - //#define CMD_VFO_TYPE 'v' //cv - if (L_vfoActive != nowActiveVFO) - { - L_vfoActive = nowActiveVFO; - SendCommand1Num(CMD_VFO_TYPE, L_vfoActive); - } - - //#define CMD_CURR_FREQ 'c' //vc - if (L_vfoCurr != frequency) - { - L_vfoCurr = frequency; - SendCommandUL(CMD_CURR_FREQ, frequency); - } - - //#define CMD_CURR_MODE 'c' //cc - byte vfoCurr_mode = modeToByte(); - if (L_vfoCurr_mode != vfoCurr_mode) - { - L_vfoCurr_mode = vfoCurr_mode; - SendCommand1Num(CMD_CURR_MODE, L_vfoCurr_mode); - } - - //if auto cw key mode, exit - //if (isCWAutoMode != 0 || menuOn != 0) - if (isCWAutoMode != 0) - return; - - //nowPageIndex = 0; - if (menuOn==0) - { - if (sendType == 0) - { - SetSWActivePage(0); - } - else - { - SetSWActivePage(0); - } - } - else - { - //Text Line Mode - SetSWActivePage(1); - } - - //#define CMD_VFOA_FREQ 'a' //va - //VFOA - if (L_vfoA != vfoA) - { - L_vfoA = vfoA; - SendCommandUL(CMD_VFOA_FREQ, L_vfoA); - } - - //#define CMD_VFOA_MODE 'a' //ca - if (L_vfoA_mode != vfoA_mode) - { - L_vfoA_mode = vfoA_mode; - SendCommand1Num(CMD_VFOA_MODE, L_vfoA_mode); - } - - //#define CMD_VFOB_FREQ 'b' //vb - //VFOB - if (L_vfoB != vfoB) - { - L_vfoB = vfoB; - SendCommandUL(CMD_VFOB_FREQ, L_vfoB); - } - - //#define CMD_VFOB_MODE 'b' //cb - if (L_vfoB_mode != vfoB_mode) - { - L_vfoB_mode = vfoB_mode; - SendCommand1Num(CMD_VFOB_MODE, L_vfoB_mode); - } - - //byte isDialLock = ((isTxType & 0x01) == 0x01) ? 1 : 0; - if (L_isDialLock != isDialLock) - { - L_isDialLock = isDialLock; - SendCommand1Num(CMD_IS_DIALLOCK, L_isDialLock); - } - - //#define CMD_IS_RIT 'r' //cr - if (L_ritOn != ritOn) - { - L_ritOn = ritOn; - SendCommand1Num(CMD_IS_RIT, L_ritOn); - } - - //#define CMD_RIT_FREQ 'r' //vr - //unsigned long L_ritTxFrequency; //ritTxFrequency - if (L_ritTxFrequency != ritTxFrequency) - { - L_ritTxFrequency = ritTxFrequency; - SendCommandUL(CMD_RIT_FREQ, L_ritTxFrequency); - } - - //#define CMD_IS_TX 't' //ct - //char L_inTx; - if (L_inTx != inTx) - { - L_inTx = inTx; - SendCommand1Num(CMD_IS_TX, L_inTx); - } - - //#define CMD_IS_DIALLOCK 'l' //cl - //byte L_isDialLock; //byte isDialLock - if (L_isDialLock != isDialLock) - { - L_isDialLock = isDialLock; - SendCommand1Num(CMD_IS_DIALLOCK, L_isDialLock); - } - - //#define CMD_IS_SPLIT 's' //cs - //byte L_Split; //isTxType - if (L_Split != splitOn) - { - L_Split = splitOn; - SendCommand1Num(CMD_IS_SPLIT, L_Split); - } - - - //#define CMD_IS_TXSTOP 'x' //cx - byte isTXStop = ((isTxType & 0x01) == 0x01); - if (L_TXStop != isTXStop) - { - L_TXStop = isTXStop; - SendCommand1Num(CMD_IS_TXSTOP, L_TXStop); - } - - //#define CMD_TUNEINDEX 'n' //cn - if (L_tuneStepIndex != tuneStepIndex) - { - L_tuneStepIndex = tuneStepIndex; - SendCommand1Num(CMD_TUNEINDEX, L_tuneStepIndex); - } - - //#define CMD_SMETER 'p' //cp - if (L_scaledSMeter != scaledSMeter) - { - L_scaledSMeter = scaledSMeter; - SendCommand1Num(CMD_SMETER, L_scaledSMeter); - } - - //#define CMD_SIDE_TONE 't' //vt - if (L_sideTone != sideTone) - { - L_sideTone = sideTone; - SendCommandL(CMD_SIDE_TONE, L_sideTone); - } - - //#define CMD_KEY_TYPE 'k' //ck - if (L_cwKeyType != cwKeyType) - { - L_cwKeyType = cwKeyType; - SendCommand1Num(CMD_KEY_TYPE, L_cwKeyType); - } - - //#define CMD_CW_SPEED 's' //vs - if (L_cwSpeed != cwSpeed) - { - L_cwSpeed = cwSpeed; - SendCommandL(CMD_CW_SPEED, L_cwSpeed); - } - - //#define CMD_CW_DELAY 'y' //vy - if (L_cwDelayTime != cwDelayTime) - { - L_cwDelayTime = cwDelayTime; - SendCommandL(CMD_CW_DELAY, L_cwDelayTime); - } - - //#define CMD_CW_STARTDELAY 'e' //ve - if (L_delayBeforeCWStartTime != delayBeforeCWStartTime) - { - L_delayBeforeCWStartTime = delayBeforeCWStartTime; - SendCommandL(CMD_CW_STARTDELAY, L_delayBeforeCWStartTime); - } - - //#define CMD_ATT_LEVEL 'f' //vf - if (L_attLevel != attLevel) - { - L_attLevel = attLevel; - SendCommandL(CMD_ATT_LEVEL, L_attLevel); - } - - //#define CMD_IS_IFSHIFT 'i' - if (L_isIFShift != isIFShift) - { - L_isIFShift = isIFShift; - SendCommand1Num(CMD_IS_IFSHIFT, L_isIFShift); - } - - //#define CMD_IFSHIFT_VALUE 'i' - if (L_ifShiftValue != ifShiftValue) - { - L_ifShiftValue = ifShiftValue; - SendCommandL(CMD_IFSHIFT_VALUE, L_ifShiftValue); - } - - //#define CMD_SDR_MODE 'j' //cj - if (L_sdrModeOn != sdrModeOn) - { - L_sdrModeOn = sdrModeOn; - SendCommand1Num(CMD_SDR_MODE, L_sdrModeOn); - } -} - -void updateDisplay() { - sendUIData(0); //UI -} - -//**************************************************************** -// Spectrum for Range scan and Band Scan -//**************************************************************** -#define RESPONSE_SPECTRUM 0 -#define RESPONSE_EEPROM 1 -#define RESPONSE_EEPROM_HEX_F 89 //C Language order -#define RESPONSE_EEPROM_HEX_R 72 //Nextion order (Reverse) -#define RESPONSE_EEPROM_STR 87 //String - -const uint8_t ResponseHeader[11]={'p', 'm', '.', 's', 'h', '.', 't', 'x', 't', '=', '"'}; -const char HexCodes[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', }; - -//void sendSpectrumData(unsigned long startFreq, unsigned long incStep, int scanCount, int delayTime, int sendCount) -//sendResponseData(RESPONSE_EEPROM, 0, eepromIndex, eepromReadLength, eepromDataType, 1); -//protocol Type : 0 - Spectrum, 1 : EEProm -//startFreq : Spectrum - Frequency, EEProm - 0 -//sendOption1 : Spectrum - 1 Step Frequency, EEProm - EEProm Start Address -//scanCount : Spectrum - 1 Set Length, EEProm - Read Length -//sendOption2 : Spectrum - Value offset (because support various S-Meter), EEProm - EEProm Response DataType (0:HEX, 1:String) -//sendCount : Spectrum - All scan set count, EEProm - always 1 -void sendResponseData(int protocolType, unsigned long startFreq, unsigned int sendOption1, int readCount, int sendOption2, int sendCount) //Spectrum and EEProm Data -{ - unsigned long beforFreq = frequency; - unsigned long k; - uint8_t adcBytes[200]; //Maximum 200 Step - - //Voltage drop - //scanResult[0] = analogRead(ANALOG_SMETER); - //adcBytes[0] = analogRead(ANALOG_SMETER); - //delay(10); - int readedValue = 0; - - for (int si = 0; si < sendCount; si++) - { - for (int i = 0; i < 11; i++) - SWSerial_Write(ResponseHeader[i]); - - for (k = 0; k < readCount; k ++) - { - if (protocolType == RESPONSE_SPECTRUM) - { - //Spectrum Data - //Sampling Range - setFrequency(startFreq + (k * sendOption1)); - //Wait time for charging - //delay(10); - -#ifdef USE_I2CSMETER - readedValue = GetI2CSmeterValue(I2CMETER_UNCALCS); -#else - - //ADC - readedValue = analogRead(ANALOG_SMETER); - readedValue -= (sendOption2 * 3); //0 ~ 765 - //Down Scale - readedValue /= 2; - if (readedValue < 0) - { - readedValue = 0; - } - else if (readedValue>255) - { - readedValue=255; - } -#endif - } - else - { - readedValue = EEPROM.read(((sendOption2 == RESPONSE_EEPROM_HEX_R) ? (readCount - k - 1) : k) + sendOption1); - } - - if (protocolType == RESPONSE_EEPROM && sendOption2 == RESPONSE_EEPROM_STR) //None HEX - { - SWSerial_Write(readedValue); - } - else - { - SWSerial_Write(HexCodes[readedValue >> 4]); - SWSerial_Write(HexCodes[readedValue & 0xf]); - } - } - - SendCommandETX(STR_ETX); - } //end of for -} - -//**************************************************************** -//Receive command and processing from External device (LCD or MCU) -//**************************************************************** -int spectrumSendCount = 10; //count of full scan and Send -int spectrumOffset = 0; //offset position -int spectrumScanCount = 100; //Maximum 200 -unsigned int spectrumIncStep = 1000; //Increaase Step -extern uint8_t receivedCommandLength; -extern void SWSerial_Read(uint8_t * receive_cmdBuffer); -uint8_t swr_buffer[20]; - -//SoftwareSerial_Process -void SWS_Process(void) -{ - //Received Command from touch screen - if (receivedCommandLength > 0) - { - SWSerial_Read(swr_buffer); - - int8_t comandLength = receivedCommandLength; - int8_t commandStartIndex = -1; - receivedCommandLength = 0; - - //Data Process - //comandLength //Find start Length - for (int i = 0; i < comandLength - 3; i++) - { - if (swr_buffer[i] == 0x59 && swr_buffer[i+ 1] == 0x58 && swr_buffer[i + 2] == 0x68) - { - commandStartIndex = i; - break; - } - } //end of for - - if (commandStartIndex != -1) - { - //Complete received command from touch screen - uint8_t commandType = swr_buffer[commandStartIndex + 3]; - - if (commandType == TS_CMD_MODE) - { - byteToMode(swr_buffer[commandStartIndex + 4], 1); - } - else if (commandType == TS_CMD_FREQ) - { - unsigned long *tempFreq; - tempFreq = (unsigned long *)(&swr_buffer[commandStartIndex + 4]); - //if (*tempFreq > 3000) //for loss protcol - //{ - frequency = *tempFreq; - //} - } - else if (commandType == TS_CMD_BAND) - { - char currentBandIndex = -1; - if (tuneTXType == 2 || tuneTXType == 3 || tuneTXType == 102 || tuneTXType == 103) - { //only ham band move - currentBandIndex = getIndexHambanBbyFreq(frequency); - - if (currentBandIndex >= 0) - { - saveBandFreqByIndex(frequency, modeToByte(), currentBandIndex); - } - } - setNextHamBandFreq(frequency, swr_buffer[commandStartIndex + 4] == 1 ? -1 : 1); //Prior Band - } - else if (commandType == TS_CMD_VFO) - { - menuVfoToggle(1); //Vfo Toggle - } - else if (commandType == TS_CMD_SPLIT) - { - menuSplitOnOff(10); - } - else if (commandType == TS_CMD_RIT) - { - menuRitToggle(1); - } - else if (commandType == TS_CMD_TXSTOP) - { - menuTxOnOff(1, 0x01); - } - else if (commandType == TS_CMD_SDR) - { - menuSDROnOff(1); - } - else if (commandType == TS_CMD_LOCK) - { - if (vfoActive == VFO_A) - setDialLock((isDialLock & 0x01) == 0x01 ? 0 : 1, 0); //Reverse Dial lock - else - setDialLock((isDialLock & 0x02) == 0x02 ? 0 : 1, 0); //Reverse Dial lock - } - else if (commandType == TS_CMD_ATT) - { - attLevel = swr_buffer[commandStartIndex + 4]; - } - else if (commandType == TS_CMD_IFS) - { - isIFShift = isIFShift ? 0 : 1; //Toggle - } - else if (commandType == TS_CMD_IFSVALUE) - { - ifShiftValue = *(long *)(&swr_buffer[commandStartIndex + 4]); - } - else if (commandType == TS_CMD_STARTADC) - { - int startIndex = swr_buffer[commandStartIndex + 4]; - int endIndex = swr_buffer[commandStartIndex + 5]; - int adcCheckInterval = swr_buffer[commandStartIndex + 6] * 10; - int nowCheckIndex = startIndex; - - while(1 == 1) - { - if (receivedCommandLength > 0) - { - break; - } - - SendCommandL('n', nowCheckIndex); //Index Input - SendCommandL('x', analogRead(ADCIndex[nowCheckIndex++])); - - if (nowCheckIndex > endIndex) - nowCheckIndex = startIndex; - - delay(adcCheckInterval); - } //end of while - } - else if (commandType == TS_CMD_STOPADC) - { - //None Action - return; - } - else if (commandType == TS_CMD_SPECTRUM) - { - //sendSpectrumData(unsigned long startFreq, unsigned int incStep, int scanCount, int delayTime, int sendCount) - //sendSpectrumData(frequency - (1000L * 50), 1000, 100, 0, 10); - //sendSpectrumData(*(long *)(&swr_buffer[commandStartIndex + 4]), spectrumIncStep, spectrumScanCount, spectrumDelayTime, spectrumSendCount); - unsigned long beforeFreq = frequency; - sendResponseData(RESPONSE_SPECTRUM, *(long *)(&swr_buffer[commandStartIndex + 4]), spectrumIncStep, spectrumScanCount, spectrumOffset, spectrumSendCount); - frequency = beforeFreq; - } - else if (commandType == TS_CMD_SPECTRUMOPT) - { - //sendSpectrumData(unsigned long startFreq, unsigned int incStep, int scanCount, int delayTime, int sendCount) - //sendSpectrumData(frequency - (1000L * 50), 1000, 100, 0, 10); - spectrumSendCount = swr_buffer[commandStartIndex + 4]; //count of full scan and Send - spectrumOffset = swr_buffer[commandStartIndex + 5]; //Scan interval time - spectrumScanCount = swr_buffer[commandStartIndex + 6]; //Maximum 120 - spectrumIncStep = swr_buffer[commandStartIndex + 7] * 20; //Increaase Step - } - else if (commandType == TS_CMD_TUNESTEP) //Set Tune Step - { - tuneStepIndex = swr_buffer[commandStartIndex + 4]; //Tune Step Index - } - else if (commandType == TS_CMD_WPM) //Set WPM - { - cwSpeed = swr_buffer[commandStartIndex + 4]; // - } - else if (commandType == TS_CMD_KEYTYPE) //Set Key Type - { - cwKeyType = swr_buffer[commandStartIndex + 4]; - - //for reduce program memory - Iambic_Key = cwKeyType != 0; - //if (cwKeyType == 0) - // Iambic_Key = false; - //else - //Iambic_Key = true; - if (cwKeyType == 1) - keyerControl &= ~IAMBICB; - else - keyerControl |= IAMBICB; - //} - } - else if (commandType == TS_CMD_SWTRIG) - { - TriggerBySW = 1; //Action Trigger by Software - } - else if (commandType == TS_CMD_READMEM ) //Read Mem - { - uint16_t eepromIndex = *(uint16_t *)(&swr_buffer[commandStartIndex + 4]); - byte eepromReadLength = swr_buffer[commandStartIndex + 6]; - byte eepromDataType = swr_buffer[commandStartIndex + 7]; //0 : Hex, 1 : String - - sendResponseData(RESPONSE_EEPROM, 0, eepromIndex, eepromReadLength, eepromDataType, 1); - } - else if (commandType == TS_CMD_WRITEMEM) //Write Mem - { - /* - Address : 2 byte int - Length : Data Length - Checksum : (Addr0+Addr1+Len) %256 - Data : Variable (Max 23) - */ - uint16_t eepromIndex = *(uint16_t *)(&swr_buffer[commandStartIndex + 4]); - byte writeLength = swr_buffer[commandStartIndex + 6]; - byte writeCheckSum = swr_buffer[commandStartIndex + 7]; - - //Check Checksum - if (writeCheckSum == (swr_buffer[commandStartIndex + 4] + swr_buffer[commandStartIndex + 5] + swr_buffer[commandStartIndex + 6])) - //if (writeCheckSum == (swr_buffer[commandStartIndex + 4] + swr_buffer[commandStartIndex + 5] + writeLength)) - { - //if (eepromIndex > 64) //Safe #1 -#ifdef UBITX_DISPLAY_NEXTION_SAFE - //Safe #2 - if (eepromIndex < 770 || eepromIndex > 775 ) - { - eepromIndex = -2; - } - else -#else - if (1 == 1) -#endif - { - for (int i = 0; i < writeLength; i++) - EEPROM.write(eepromIndex + i , swr_buffer[commandStartIndex + 8 + i]); - } - } - else - { - eepromIndex = -2; - } - SendCommandL('n', eepromIndex); //Index Input - } - //else if (TS_CMD_LOOPBACK0 <= commandType && commandType <= TS_CMD_LOOPBACK5) //Loop back Channel 0 ~ 5 Loop back Channel 1~5 : Reserve - else if (TS_CMD_LOOPBACK0 == commandType) //Loop back Channel 0 ~ 5 - { - SendCommandUL('v', *(unsigned long *)&swr_buffer[commandStartIndex + 4]); //Return data - SendCommandUL('g', commandType); //Index Input - //return; - } - else if (commandType == TS_CMD_FACTORYRESET || commandType == TS_CMD_UBITX_REBOOT) - { - if (*(unsigned long *)&swr_buffer[commandStartIndex + 4] == 1497712748) - { - if (commandType == TS_CMD_UBITX_REBOOT) - { - FrequencyToVFO(1); //Save current Frequency and Mode to eeprom - asm volatile (" jmp 0"); - } - else - { - for (unsigned int i = 0; i < 32; i++) //factory setting range - EEPROM.write(i, EEPROM.read(FACTORY_VALUES + i)); //65~96 => 0~31 - } - } - } - - setFrequency(frequency); - SetCarrierFreq(); - updateDisplay(); - } - } -} - -char checkCount = 0; -char checkCountSMeter = 0; - -//execute interval : 0.25sec -void idle_process() -{ - //S-Meter Display - if (((displayOption1 & 0x08) == 0x08 && (sdrModeOn == 0)) && (++checkCountSMeter > SMeterLatency)) - { -#ifdef USE_I2CSMETER - scaledSMeter = GetI2CSmeterValue(I2CMETER_CALCS); -#else - int newSMeter; - - newSMeter = analogRead(ANALOG_SMETER) / 4; - currentSMeter = newSMeter; - - scaledSMeter = 0; - for (byte s = 8; s >= 1; s--) { - if (currentSMeter > sMeterLevels[s]) { - scaledSMeter = s; - break; - } - } - -#endif - checkCountSMeter = 0; //Reset Latency time - } //end of S-Meter - - sendUIData(1); -} - -//When boot time, send data -void SendUbitxData(void) -{ - //Wait for ready other device (LCD, DSP and more) - //delay(500); - delay_background(500, 2); - - SendCommandL(CMD_AR_TUNE1, arTuneStep[0]); - SendCommandL(CMD_AR_TUNE2, arTuneStep[1]); - SendCommandL(CMD_AR_TUNE3, arTuneStep[2]); - SendCommandL(CMD_AR_TUNE4, arTuneStep[3]); - SendCommandL(CMD_AR_TUNE5, arTuneStep[4]); - - SendCommand1Num(CMD_IS_CW_SHIFT_DISPLAY, isShiftDisplayCWFreq); - SendCommandL(CMD_CW_SHIFT_ADJUST, shiftDisplayAdjustVal); - SendCommandL(CMD_COMM_OPTION, commonOption0); - SendCommandL(CMD_DISP_OPTION1, displayOption1); - - unsigned long nextionDisplayOption; - EEPROM.get(EXTERNAL_DEVICE_OPT1, nextionDisplayOption); - SendCommandUL(CMD_DISP_OPTION2, nextionDisplayOption); - - SendCommandStr(CMD_VERSION, (char *)("+v1.200")); //Version - SendEEPromData(CMD_CALLSIGN, 0, userCallsignLength -1, 0); - - /* - //Frequency of Bands - for (int i = 0; i < 11; i++) - SWSerial_Write(SpectrumHeader[i]); - - byte *tmpByte; - tmpByte = (byte *)hamBandRange; - for (byte i = 0; i < (useHamBandCount -1) * 4; i++) - { - SWSerial_Write(HexCodes[*tmpByte >> 4]); - SWSerial_Write(HexCodes[*tmpByte & 0xf]); - tmpByte++; - } - - for (int i = 0; i < 4; i++) - SWSerial_Write(SpectrumFooter[i]); - */ - - //Complte Send Info - SendCommand1Num(CMD_UBITX_INFO, 1); - - //Page Init - L_nowdisp = 0; - SendCommand1Num(CMD_NOW_DISP, L_nowdisp); -} - - -//AutoKey LCD Display Routine -void Display_AutoKeyTextIndex(byte textIndex) -{ - byte diplayAutoCWLine = 0; - - if ((displayOption1 & 0x01) == 0x01) - diplayAutoCWLine = 1; - //LCD_SetCursor(0, diplayAutoCWLine); - - softBuffLines[diplayAutoCWLine][0] = byteToChar(textIndex); - softBuffLines[diplayAutoCWLine][1] = ':'; - - SendTextLineBuff(diplayAutoCWLine); -} - -void LCD_CreateChar(uint8_t location, uint8_t charmap[]) -{ -} - -void updateLine2Buffer(char displayType) -{ -} - -//not use with Nextion LCD -void DisplayCallsign(byte callSignLength) -{ -} - -//Not use with Nextion LCD -void DisplayVersionInfo(const __FlashStringHelper * fwVersionInfo) -{ -} - -#endif diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index 8dda453..4e4020d 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -548,6 +548,7 @@ void displayEmptyData(void){ delay_background(2000, 0); } +/* //Builtin CW Keyer Logic by KD8CEC void menuCWAutoKey(int btn){ if (!btn){ @@ -570,6 +571,7 @@ void menuCWAutoKey(int btn){ updateDisplay(); menuOn = 0; } +*/ //Standalone WSPR Beacone void menuWSPRSend(int btn){ From f588a89ee78137bc4633bb48031f03fd9909c739 Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 7 Jun 2020 13:27:24 -0500 Subject: [PATCH 14/17] Working on the buffer issues. It looks like the issue is a failure (on the Raduino side) to check for availability of character in the Serial port, before reading the serial port. Note, need to see if this is a weakness on the Teensy (IOP) side as well. --- ubitx_20/cat_libs.ino | 29 ++++++++++++++++------------- ubitx_20/ubitx_20.ino | 2 ++ ubitx_20/ubitx_lcd_1602.ino | 18 ++++-------------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 0be4e4b..771bbe7 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -76,6 +76,8 @@ unsigned int skipTimeCount = 0; byte CAT_BUFF[34]; byte CAT_SNDBUFF[34]; +byte error_buf[17]; + void SendCatData(byte sendCount) { // KC4UPR--uBITX IOP: Adding an additional byte at the beginning that @@ -811,7 +813,7 @@ byte rxBufferCheckCount = 0; //Prevent Stack Overflow byte isProcessCheck_Cat = 0; -char iopStatusWindow[4] = " "; // may need to move this if it's not visible to ubitx_lcd_1602 +//char iopStatusWindow[4] = " "; // may need to move this if it's not visible to ubitx_lcd_1602 char iopMenuDisplay[17] = " "; // KC4UPR - these are used to delay the display of the Smeter, if the @@ -820,7 +822,6 @@ char iopMenuDisplay[17] = " "; //#define SMETER_DELAY_TIME 5000 //bool displaySmeter = true; //int delaySmeter; -int delayTopLine = 0; int stateTopLine = 0; //fromType normal : 0, TX : 1, CW_STRAIGHT : 2, CW_PADDLE : 3, CW_AUTOMODE : 4 @@ -871,7 +872,7 @@ void Check_Cat(byte fromType) // Will adjust based on readlength byte first = Serial.read(); readPrefix = byteToPrefix(first); - readLength = byteToLength(first); + readLength = byteToLength(first); for (int i = 0; i < readLength; i++) { CAT_BUFF[i] = Serial.read(); } @@ -904,17 +905,18 @@ void Check_Cat(byte fromType) case IOP_MENU_DISPLAY_MSG: for (int i = 0; i < 16; i++) { - iopMenuDisplay[i] = msg.data[i+1]; - } - if (int8_t(msg.data[0]) == 0) { - stateTopLine = 4; - } else if (int8_t(msg.data[0]) < 0) { - stateTopLine = 0; - } else { // > 0 - delayTopLine = millis() + (int8_t(msg.data[0]) * 1000); - stateTopLine = 2; + iopMenuDisplay[i] = msg.data[i]; } + stateTopLine = 2; + sprintf(error_buf, "# recv'd: %3d", readLength); + sendIOPDebugMessage(error_buf); + sendIOPDebugMessage(iopMenuDisplay); break; + + case IOP_MENU_INACTIVE_MSG: + stateTopLine = 0; + line2DisplayStatus = 0; // trying to force an update + break; } } else if (readPrefix == CAT_PREFIX) { @@ -1020,5 +1022,6 @@ void Init_Cat(long baud, int portConfig) // At start, immediately send mode to IOP. Currently, IOP has no way to // request the mode. - iopSendMode(cwMode, isUSB, digiMode, isTest); + // Moving this to main setup loop. Here, it may actually occur before the Raduino knows its mode! + //iopSendMode(cwMode, isUSB, digiMode, isTest); } diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index deb97b8..f7ef20d 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -1453,6 +1453,8 @@ void setup() factory_alignment(); #endif + iopSendMode(cwMode, isUSB, digiMode, isTest); + } //Auto save Frequency and Mode with Protected eeprom life by KD8CEC diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index dbe1e15..2676000 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -531,22 +531,12 @@ void updateLine2Buffer(char displayType) { unsigned long tmpFreq = 0; - if ((stateTopLine == 2) || (stateTopLine == 4)) { - strcpy(line2Buffer, iopMenuDisplay); - if (stateTopLine == 4) { - stateTopLine = 3; - } else { - stateTopLine = 1; - } + if (stateTopLine == 2) { + strncpy(line2Buffer, iopMenuDisplay, 16); + stateTopLine = 1; } - if (stateTopLine == 3) { + if (stateTopLine == 1) { return; - } else if (stateTopLine == 1) { - if (delayTopLine < millis()) { - stateTopLine = 0; - } else { - return; - } } if (ritOn) From 1a1e92a709bf5d2129dc77e31a9faccd86083b9a Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 7 Jun 2020 15:26:37 -0500 Subject: [PATCH 15/17] Working! Implemented a more reasonable serial reader. --- ubitx_20/cat_libs.ino | 65 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 771bbe7..0afb739 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -832,51 +832,53 @@ void Check_Cat(byte fromType) static PrefixID readPrefix; static uint8_t readLength; - static IOPMessage msg; + static IOPMessage msg; + static bool read_in_progress = false; //Check Serial Port Buffer - if (Serial.available() == 0) + if (Serial.available() == 0 && !read_in_progress) { //Set Buffer Clear status - rxBufferCheckCount = 0; + //rxBufferCheckCount = 0; return; } // KC4UPR - IOP update: changed this to 6 characters, because we're going to have a // first character which defines if this is CAT or IOP. - else if (Serial.available() < 6) //5) + else // if (Serial.available() < 6) //5) { - //First Arrived - if (rxBufferCheckCount == 0) - { + if (!read_in_progress) { + byte first = Serial.read(); + readPrefix = byteToPrefix(first); + readLength = byteToLength(first); + rxBufferCheckCount = Serial.available(); - rxBufferArriveTime = millis() + CAT_RECEIVE_TIMEOUT; //Set time for timeout - } - else if (rxBufferArriveTime < millis()) //timeout - { - //Clear Buffer - for (i = 0; i < Serial.available(); i++) - rxBufferCheckCount = Serial.read(); + rxBufferArriveTime = millis() + CAT_RECEIVE_TIMEOUT; - rxBufferCheckCount = 0; + read_in_progress = true; } - else if (rxBufferCheckCount < Serial.available()) //increase buffer count, slow arrived - { - rxBufferCheckCount = Serial.available(); - rxBufferArriveTime = millis() + CAT_RECEIVE_TIMEOUT; //Set time for timeout + + if (Serial.available() < readLength) { // not ready to read everything yet (not enough bytes) + + if (rxBufferCheckCount < Serial.available()) { // increase buffer count, slow arrival + rxBufferCheckCount = Serial.available(); + rxBufferArriveTime = millis() + CAT_RECEIVE_TIMEOUT; // update time for timeout + + } else if (rxBufferArriveTime < millis()) { // timeout, so clear buffer + for (i = 0; i < Serial.available(); i++) + rxBufferCheckCount = Serial.read(); + rxBufferCheckCount = 0; + read_in_progress = false; + + } + + return; + } + + for (int i = 0; i < readLength; i++) { + CAT_BUFF[i] = Serial.read(); } - return; } - - //Arived CAT DATA - // KC4UPR - IOP update - 6 characters; first character determines mode (CAT or IOP) - // Will adjust based on readlength - byte first = Serial.read(); - readPrefix = byteToPrefix(first); - readLength = byteToLength(first); - for (int i = 0; i < readLength; i++) { - CAT_BUFF[i] = Serial.read(); - } - + // KC4UPR: I don't understand why this is here or how/when it will ever get called, but I will leave // it alone for now. if (isProcessCheck_Cat == 1) @@ -1013,6 +1015,7 @@ void Check_Cat(byte fromType) } isProcessCheck_Cat = 0; + read_in_progress = false; } void Init_Cat(long baud, int portConfig) From 5e675107c1f0ea5617d5c043b42b1debd2154de0 Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 14 Jun 2020 00:12:29 -0500 Subject: [PATCH 16/17] Changes to work with updated modes and such from iopcomm.h --- ubitx_20/cat_libs.ino | 17 +++++----- ubitx_20/ubitx_20.ino | 4 +-- ubitx_20/ubitx_lcd_1602.ino | 22 ++++++------- ubitx_20/ubitx_menu.ino | 66 +++++++++++++++---------------------- 4 files changed, 49 insertions(+), 60 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index 0afb739..c5c1183 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -56,18 +56,19 @@ * * Send the current mode to the I/O Processor. */ -void iopSendMode(char cw_mode, char is_usb, char digi_mode, char is_test) +void iopSendMode(char cw_mode, char is_usb, char digi_mode) { byte mode; if (cw_mode > 0) { - mode = (cw_mode == 1 ? RIG_MODE_CWL : RIG_MODE_CWU); + mode = (cw_mode == 1 ? cwr : cw); } else if (digi_mode > 0) { - mode = (is_usb ? RIG_MODE_DGU : RIG_MODE_DGL); - } else if (is_test) { - mode = (is_usb ? RIG_MODE_TTU : RIG_MODE_TTL); + //mode = (is_usb ? RIG_MODE_DGU : RIG_MODE_DGL); + mode = dig; +// } else if (is_test) { +// mode = (is_usb ? RIG_MODE_TTU : RIG_MODE_TTL); } else { - mode = (is_usb ? RIG_MODE_USB : RIG_MODE_LSB); + mode = (is_usb ? usb : lsb); } sendIOPModeCommand(mode); } @@ -282,7 +283,7 @@ void CatSetMode(byte tmpMode, byte fromType) digiMode = 1; isUSB = true; // DGU - but need to eventually use the FT-817 customization } - iopSendMode(cwMode, isUSB, digiMode, isTest); + iopSendMode(cwMode, isUSB, digiMode); setFrequency(frequency); updateDisplay(); } @@ -902,7 +903,7 @@ void Check_Cat(byte fromType) break;*/ case IOP_MODE_REQUEST: - iopSendMode(cwMode, isUSB, digiMode, isTest); + iopSendMode(cwMode, isUSB, digiMode); break; case IOP_MENU_DISPLAY_MSG: diff --git a/ubitx_20/ubitx_20.ino b/ubitx_20/ubitx_20.ino index f7ef20d..dc39af8 100644 --- a/ubitx_20/ubitx_20.ino +++ b/ubitx_20/ubitx_20.ino @@ -193,7 +193,7 @@ char splitOn = 0; //working split, uses VFO B as the transmit freque char keyDown = 0; //in cw mode, denotes the carrier is being transmitted char isUSB = 0; //upper sideband was selected, this is reset to the default for the -char isTest = 0; // two-tone test mode +//char isTest = 0; // two-tone test mode char cwMode = 0; //compatible original source, and extend mode //if cwMode == 0, mode check : isUSB, cwMode > 0, mode Check : cwMode //iscwMode = 0 : ssbmode, 1 :cwl, 2 : cwu, 3 : cwn (none tx) char digiMode = 0; // 0: normal uBITX behavior (transmit LSB/USB when PTT is depressed) @@ -1453,7 +1453,7 @@ void setup() factory_alignment(); #endif - iopSendMode(cwMode, isUSB, digiMode, isTest); + iopSendMode(cwMode, isUSB, digiMode); } diff --git a/ubitx_20/ubitx_lcd_1602.ino b/ubitx_20/ubitx_lcd_1602.ino index 2676000..41c169b 100644 --- a/ubitx_20/ubitx_lcd_1602.ino +++ b/ubitx_20/ubitx_lcd_1602.ino @@ -439,15 +439,15 @@ void updateDisplay() { if (cwMode == 0) { if (digiMode == 1) { - if (isUSB) - strcpy(c, "DGU "); - else - strcpy(c, "DGL "); - } else if (isTest == 1) { - if (isUSB) - strcpy(c, "TTU "); - else - strcpy(c, "TTL "); +// if (isUSB) + strcpy(c, "DIG "); +// else +// strcpy(c, "DGL "); +// } else if (isTest == 1) { +// if (isUSB) +// strcpy(c, "TTU "); +// else +// strcpy(c, "TTL "); } else { if (isUSB) strcpy(c, "USB "); @@ -457,11 +457,11 @@ void updateDisplay() { } else if (cwMode == 1) { - strcpy(c, "CWL "); + strcpy(c, "CWR "); } else { - strcpy(c, "CWU "); + strcpy(c, "CW "); } } if (vfoActive == VFO_A) // VFO A is active diff --git a/ubitx_20/ubitx_menu.ino b/ubitx_20/ubitx_menu.ino index 4e4020d..53b0f98 100644 --- a/ubitx_20/ubitx_menu.ino +++ b/ubitx_20/ubitx_menu.ino @@ -127,13 +127,17 @@ void menuBand(int btn){ //Convert Mode, Number by KD8CEC //0: default, 1:not use, 2:LSB, 3:USB, 4:CWL, 5:CWU, 6:FM -byte modeToByte(){ +// Updated: KC4UPR - 6: DIG +byte modeToByte() { if (cwMode == 0) { + if (digiMode > 0) { + return 6; + } if (isUSB) - return 3 + (digiMode > 0 ? 3 + digiMode : 0); + return 3; else - return 2 + (digiMode > 0 ? 3 + digiMode : 0); + return 2; } else if (cwMode == 1) { @@ -149,7 +153,7 @@ byte modeToByte(){ //autoSetModebyFreq : 0 //autoSetModebyFreq : 1, if (modValue is not set, set mode by frequency) void byteToMode(byte modeValue, byte autoSetModebyFreq){ - isTest = false; // test never settable from EEPROM + //isTest = false; // test never settable from EEPROM isUSB = false; cwMode = 0; digiMode = 0; @@ -174,23 +178,10 @@ void byteToMode(byte modeValue, byte autoSetModebyFreq){ cwMode = 2; break; - case 6: // DGL + case 6: // DIG digiMode = 1; - break; - - case 7: // DGU - isUSB = true; - digiMode = 1; - break; -/* - case 8: // TTL - isUSB = false; - break; - - case 9: // TTU isUSB = true; break; -*/ } } /* if (modeValue == 4) { @@ -994,16 +985,13 @@ void menuSelectMode(int btn){ } // modify if digital mode is set if (digiMode > 0) { - selectModeType += (3 + digiMode); - - // modify if two-tone test mode is set - } else if (isTest > 0) { - selectModeType += 6; + + selectModeType = 4; } - } else if (cwMode == 1) { - selectModeType = 2; // CWL + } else if (cwMode == 2) { + selectModeType = 2; // CW } else { - selectModeType = 3; // CWU + selectModeType = 3; // CWR } /*if (cwMode == 0 && isUSB == 0) selectModeType = 0; @@ -1015,30 +1003,30 @@ void menuSelectMode(int btn){ selectModeType = 3;*/ beforeMode = selectModeType; - selectModeType = getValueByKnob(11, selectModeType, 0, 7, 1, " LSB USB CWL CWU DGL DGU TTL TTU", 4); //3 : Select Mode, targetValue, minKnobValue, maxKnobValue, stepSize + selectModeType = getValueByKnob(11, selectModeType, 0, 4, 1, " LSB USB CW CWR DIG", 4); //3 : Select Mode, targetValue, minKnobValue, maxKnobValue, stepSize if (beforeMode != selectModeType) { //printLineF1(F("Changed Mode")); if (selectModeType == 0) { - cwMode = 0; isUSB = 0; digiMode = 0; isTest = 0; + cwMode = 0; isUSB = 0; digiMode = 0; //isTest = 0; } else if (selectModeType == 1) { - cwMode = 0; isUSB = 1; digiMode = 0; isTest = 0; + cwMode = 0; isUSB = 1; digiMode = 0; //isTest = 0; } else if (selectModeType == 2) { - cwMode = 1; digiMode = 0; isTest = 0; + cwMode = 2; digiMode = 0; //isTest = 0; } else if (selectModeType == 3) { - cwMode = 2; digiMode = 0; isTest = 0; + cwMode = 1; digiMode = 0; //isTest = 0; } else if (selectModeType == 4) { - cwMode = 0; isUSB = 0; digiMode = 1; isTest = 0; - } else if (selectModeType == 5) { - cwMode = 0; isUSB = 1; digiMode = 1; isTest = 0; - } else if (selectModeType == 6) { - cwMode = 0; isUSB = 0; digiMode = 0; isTest = 1; - } else if (selectModeType == 7) { - cwMode = 0; isUSB = 1; digiMode = 0; isTest = 1; + cwMode = 0; isUSB = 1; digiMode = 1; //isTest = 0; +// } else if (selectModeType == 5) { +// cwMode = 0; isUSB = 1; digiMode = 1; isTest = 0; +// } else if (selectModeType == 6) { +// cwMode = 0; isUSB = 0; digiMode = 0; isTest = 1; +// } else if (selectModeType == 7) { +// cwMode = 0; isUSB = 1; digiMode = 0; isTest = 1; } // KC4UPR: sending mode to IOP - iopSendMode(cwMode, isUSB, digiMode, isTest); + iopSendMode(cwMode, isUSB, digiMode); FrequencyToVFO(1); } From cdf3871385429193c04f7504ae3c65181d029637 Mon Sep 17 00:00:00 2001 From: Rob French Date: Sun, 14 Jun 2020 22:54:40 -0500 Subject: [PATCH 17/17] Updated to be compatible with some iopcomm changes. --- ubitx_20/cat_libs.ino | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ubitx_20/cat_libs.ino b/ubitx_20/cat_libs.ino index c5c1183..70e2422 100644 --- a/ubitx_20/cat_libs.ino +++ b/ubitx_20/cat_libs.ino @@ -58,17 +58,18 @@ */ void iopSendMode(char cw_mode, char is_usb, char digi_mode) { - byte mode; - + rig_mode mode; + + // NOTE: eventually, add sideband (is_usb) to all of these. if (cw_mode > 0) { - mode = (cw_mode == 1 ? cwr : cw); + mode = rig_mode::cw; } else if (digi_mode > 0) { //mode = (is_usb ? RIG_MODE_DGU : RIG_MODE_DGL); - mode = dig; + mode = rig_mode::digi; // } else if (is_test) { // mode = (is_usb ? RIG_MODE_TTU : RIG_MODE_TTL); } else { - mode = (is_usb ? usb : lsb); + mode = rig_mode::ssb; //(is_usb ? usb : lsb); } sendIOPModeCommand(mode); }