1108 lines
31 KiB
C++
1108 lines
31 KiB
C++
/*************************************************************************
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
**************************************************************************/
|
|
#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<PGM_P>(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
|