1033 lines
33 KiB
C++
1033 lines
33 KiB
C++
#include "comms.h"
|
|
#include <EEPROM.h>
|
|
|
|
extern mem presets[];
|
|
|
|
void Communication() {
|
|
if(!menu) {
|
|
if(wifi) {
|
|
int packetSize = Udp.parsePacket();
|
|
if(packetSize > 0) {
|
|
char packetBuffer[packetSize + 1];
|
|
Udp.read(packetBuffer, packetSize);
|
|
packetBuffer[packetSize] = '\0';
|
|
Udp.endPacket();
|
|
|
|
String packet = String(packetBuffer);
|
|
|
|
if(packet.equals("from=StationList;freq=?;bandwidth=?")) {
|
|
ShowFreq(0);
|
|
return;
|
|
}
|
|
|
|
externaltune = true;
|
|
|
|
if(packet.charAt(0) == '*') {
|
|
if(afscreen) BuildAdvancedRDS();
|
|
char command = packet.charAt(1);
|
|
switch(command) {
|
|
case 'U':
|
|
case 'D': {
|
|
tunemode = TUNE_MAN;
|
|
ShowTuneMode();
|
|
if(command == 'U') TuneUp(); else TuneDown();
|
|
ShowFreq(0);
|
|
break;
|
|
}
|
|
|
|
case '>':
|
|
case '<': {
|
|
if(command == '>') direction = true; else direction = false;
|
|
Seek(direction);
|
|
ShowFreq(0);
|
|
break;
|
|
}
|
|
|
|
case 'T': {
|
|
uint16_t freqtemp = packet.substring(2).toInt();
|
|
if(BAND_FM) freqtemp -= ConverterSet * 1000;
|
|
if(seek) seek = false;
|
|
radio.clearRDS();
|
|
|
|
if(freqtemp >= LowEdgeOIRTSet && freqtemp <= HighEdgeOIRTSet) {
|
|
frequency_OIRT = freqtemp;
|
|
if(afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
if(band != BAND_OIRT) {
|
|
band = BAND_OIRT;
|
|
SelectBand();
|
|
}
|
|
radio.SetFreq(frequency_OIRT);
|
|
} else if(freqtemp >= (TEF == 205 ? 6400 : 6500) && freqtemp <= 10800) {
|
|
frequency = freqtemp;
|
|
if(afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
SelectBand();
|
|
}
|
|
radio.SetFreq(frequency);
|
|
}
|
|
ShowFreq(0);
|
|
break;
|
|
}
|
|
|
|
case 'S': {if (!scandxmode) startFMDXScan(); break;}
|
|
case 'E': {if (scandxmode) cancelDXScan(); break;}
|
|
case 'R': {radio.clearRDS(); break;}
|
|
}
|
|
return;
|
|
}
|
|
|
|
int symPos = packet.indexOf("freq=");
|
|
|
|
if (symPos != -1) {
|
|
String stlfreq = packet.substring(symPos + 5);
|
|
int freqValue = stlfreq.toInt();
|
|
|
|
if (afscreen) BuildAdvancedRDS();
|
|
|
|
unsigned int tempfreq;
|
|
if ((freqValue / 10000) > (TEF == 205 ? 6400 : 6500) && (freqValue / 10000) < 10800) {
|
|
tempfreq = freqValue / 10000;
|
|
if (scandxmode) cancelDXScan();
|
|
|
|
if (tempfreq >= FREQ_FM_OIRT_START && tempfreq <= FREQ_FM_OIRT_END) {
|
|
if (band != BAND_OIRT) {
|
|
band = BAND_OIRT;
|
|
frequency_OIRT = tempfreq;
|
|
SelectBand();
|
|
}
|
|
radio.SetFreq(frequency_OIRT);
|
|
} else {
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
frequency = tempfreq;
|
|
SelectBand();
|
|
}
|
|
radio.SetFreq(frequency);
|
|
}
|
|
}
|
|
|
|
if ((freqValue / 1000) > 144 && (freqValue / 1000) < 27000) {
|
|
tempfreq = freqValue / 1000;
|
|
if (scandxmode) cancelDXScan();
|
|
if (afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
|
|
if (tempfreq >= FREQ_LW_LOW_EDGE_MIN && tempfreq <= FREQ_LW_HIGH_EDGE_MAX) {
|
|
frequency_LW = tempfreq;
|
|
if (band != BAND_LW) {
|
|
band = BAND_LW;
|
|
SelectBand();
|
|
} else {
|
|
radio.SetFreqAM(frequency_LW);
|
|
frequency_AM = frequency_LW;
|
|
}
|
|
} else if (tempfreq >= FREQ_MW_LOW_EDGE_MIN_9K && tempfreq <= FREQ_MW_HIGH_EDGE_MAX_9K) {
|
|
frequency_MW = tempfreq;
|
|
if (band != BAND_MW) {
|
|
band = BAND_MW;
|
|
SelectBand();
|
|
} else {
|
|
radio.SetFreqAM(frequency_MW);
|
|
frequency_AM = frequency_MW;
|
|
}
|
|
} else {
|
|
frequency_SW = tempfreq;
|
|
if (band != BAND_SW) {
|
|
band = BAND_SW;
|
|
SelectBand();
|
|
} else {
|
|
radio.SetFreqAM(frequency_SW);
|
|
frequency_AM = frequency_SW;
|
|
}
|
|
}
|
|
}
|
|
|
|
radio.clearRDS();
|
|
ShowFreq(0);
|
|
store = true;
|
|
externaltune = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Server.hasClient()) {
|
|
if (RemoteClient.connected()) {
|
|
Server.available().stop();
|
|
} else {
|
|
wificonnected = true;
|
|
RemoteClient = Server.available();
|
|
passwordcrypt();
|
|
RemoteClient.print(saltkey + "\n");
|
|
}
|
|
}
|
|
|
|
if (wificonnected && !RemoteClient.connected()) {
|
|
wificonnected = false;
|
|
RDSSPYTCP = false;
|
|
XDRGTKTCP = false;
|
|
}
|
|
|
|
if (!RDSSPYTCP && !XDRGTKTCP && RemoteClient.available()) {
|
|
String data_str = RemoteClient.readStringUntil('\n');
|
|
if (data_str.indexOf("?F") != -1 || data_str.indexOf("*F") != -1) {
|
|
RDSSPYTCP = true;
|
|
RDSSPYUSB = false;
|
|
} else {
|
|
if (data_str.equals(cryptedpassword)) {
|
|
radio.setFMABandw();
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
SelectBand();
|
|
}
|
|
XDRGTKTCP = true;
|
|
if (XDRGTKMuteScreen) MuteScreen(1);
|
|
RemoteClient.print("o1,0\n");
|
|
RemoteClient.print("G" + String(!EQset) + String(!iMSset) + "\n");
|
|
store = true;
|
|
} else RemoteClient.print("a0\n");
|
|
}
|
|
}
|
|
|
|
if (RDSSPYTCP && RemoteClient.available()) {
|
|
String data_str = RemoteClient.readStringUntil('\n');
|
|
int symPos = data_str.indexOf("*F");
|
|
if (symPos >= 5) {
|
|
String freq = data_str.substring(0, symPos);
|
|
freq = freq.substring(0, freq.length() - 1);
|
|
frequency = freq.toInt();
|
|
if (scandxmode) cancelDXScan();
|
|
radio.SetFreq(frequency);
|
|
radio.clearRDS();
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
SelectBand();
|
|
}
|
|
ShowFreq(0);
|
|
store = true;
|
|
}
|
|
}
|
|
|
|
if (!RDSSPYUSB && !XDRGTKUSB && Serial.available()) {
|
|
String data_str = Serial.readStringUntil('\n');
|
|
if (data_str.indexOf("?F") != -1 || data_str.indexOf("*F") != -1) {
|
|
RDSSPYUSB = true;
|
|
RDSSPYTCP = false;
|
|
} else if (data_str.charAt(0) == 'x') {
|
|
radio.setFMABandw();
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
SelectBand();
|
|
}
|
|
Serial.print("OK\nT" + String(frequency * 10) + "\nG" + String(!EQset) + String(!iMSset) + "\n");
|
|
XDRGTKUSB = true;
|
|
if (XDRGTKMuteScreen) MuteScreen(1);
|
|
} else if (data_str.charAt(0) == 's') {
|
|
Serial.print("r:0\n");
|
|
Serial.print("v:" + String(VERSION) + "\n");
|
|
Serial.print("m:" + String(EE_PRESETS_CNT) + "\n");
|
|
Serial.print("s:" + String(EE_PRESETS_FREQUENCY) + "\n");
|
|
Serial.print("o:" + String(ConverterSet) + "\n");
|
|
Serial.print("a:" + String(FREQ_LW_LOW_EDGE_MIN) + "," + String(FREQ_SW_END) + "\n");
|
|
Serial.print("f:" + String((TEF == 205 ? 64000 : 65000)) + "," + String(108000) + "\n");
|
|
|
|
for (byte x = 0; x < EE_PRESETS_CNT; x++) {
|
|
Serial.print(x + 1);
|
|
Serial.print(",");
|
|
Serial.print(presets[x].frequency);
|
|
if (presets[x].band == BAND_FM || presets[x].band == BAND_OIRT) Serial.print("0");
|
|
Serial.print(",");
|
|
Serial.print(presets[x].bw);
|
|
Serial.print(",");
|
|
Serial.print(presets[x].ms);
|
|
Serial.print(",");
|
|
Serial.print(String(presets[x].RDSPI).substring(0, 4));
|
|
Serial.print(",");
|
|
Serial.print(String(presets[x].RDSPS).substring(0, 8));
|
|
Serial.print("\n");
|
|
}
|
|
} else if (data_str.startsWith("S")) {
|
|
byte mempos = 0;
|
|
byte memband = 0;
|
|
unsigned int memfreq = 0;
|
|
byte membw;
|
|
byte memms;
|
|
byte error = 0;
|
|
data_str.remove(0, 1);
|
|
int commaPos = data_str.indexOf(',');
|
|
|
|
if (commaPos != -1) {
|
|
mempos = data_str.substring(0, commaPos).toInt() - 1;
|
|
|
|
data_str.remove(0, commaPos + 1);
|
|
commaPos = data_str.indexOf(',');
|
|
|
|
if (commaPos != -1) {
|
|
memfreq = data_str.substring(0, commaPos).toInt();
|
|
data_str.remove(0, commaPos + 1);
|
|
commaPos = data_str.indexOf(',');
|
|
|
|
if (commaPos != -1) {
|
|
membw = data_str.substring(0, commaPos).toInt();
|
|
data_str.remove(0, commaPos + 1);
|
|
commaPos = data_str.indexOf(',');
|
|
|
|
if (commaPos != -1) {
|
|
memms = data_str.substring(0, commaPos).toInt();
|
|
data_str.remove(0, commaPos + 1);
|
|
commaPos = data_str.indexOf(',');
|
|
|
|
if (commaPos != -1) {
|
|
String rdsPiStr = data_str.substring(0, commaPos);
|
|
char rdsPi[5];
|
|
rdsPiStr.toCharArray(rdsPi, sizeof(rdsPi));
|
|
data_str.remove(0, commaPos + 1);
|
|
commaPos = data_str.indexOf(',');
|
|
|
|
String rdsPs = data_str;
|
|
|
|
|
|
if (memfreq >= FREQ_LW_LOW_EDGE_MIN && memfreq <= FREQ_LW_HIGH_EDGE_MAX) memband = BAND_LW;
|
|
else if (memfreq > FREQ_LW_HIGH_EDGE_MAX && memfreq <= FREQ_MW_HIGH_EDGE_MAX_10K) memband = BAND_MW;
|
|
else if (memfreq > FREQ_MW_HIGH_EDGE_MAX_10K && memfreq <= FREQ_SW_END) memband = BAND_SW;
|
|
else if (ConverterSet != 0 && memfreq >= FREQ_FM_OIRT_START * 10 && memfreq <= FREQ_FM_OIRT_END * 10) {
|
|
memband = BAND_OIRT;
|
|
memfreq /= 10;
|
|
} else if ((ConverterSet != 0 && memfreq > FREQ_FM_OIRT_START * 10) || ((ConverterSet == 0 && memfreq > FREQ_FM_OIRT_END * 10) && memfreq <= 108000 * 10)) {
|
|
memband = BAND_FM;
|
|
memfreq /= 10;
|
|
} else if (memfreq == EE_PRESETS_FREQUENCY) memband = BAND_FM;
|
|
else error |= (1 << 0);
|
|
|
|
if (mempos == 0 && memfreq == EE_PRESETS_FREQUENCY) error |= (1 << 4);
|
|
|
|
if (mempos >= EE_PRESETS_CNT) error |= (1 << 1);
|
|
|
|
if (memband != BAND_FM && memband != BAND_OIRT && (membw < 1 || membw > 4)) error |= (1 << 2);
|
|
else if (membw > 16) error |= (1 << 2);
|
|
|
|
if (memms > 1) error |= (1 << 3);
|
|
|
|
if (rdsPi[0] != '\0') {
|
|
for (int i = 0; i < 4; i++) {
|
|
char c = rdsPi[i];
|
|
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
|
|
error |= (1 << 5);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (error == 0) {
|
|
error |= (1 << 7);
|
|
memorypos = mempos;
|
|
presets[mempos].band = memband;
|
|
presets[mempos].frequency = memfreq;
|
|
presets[mempos].bw = membw;
|
|
presets[mempos].ms = memms;
|
|
|
|
EEPROM.writeByte(mempos + EE_PRESETS_BAND_START, memband);
|
|
EEPROM.writeByte(mempos + EE_PRESET_BW_START, membw);
|
|
EEPROM.writeByte(mempos + EE_PRESET_MS_START, memms);
|
|
EEPROM.writeUInt((mempos * 4) + EE_PRESETS_FREQUENCY_START, memfreq);
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
presets[mempos].RDSPI[i] = rdsPi[i];
|
|
EEPROM.writeByte((mempos * 5) + i + EE_PRESETS_RDSPI_START, rdsPi[i]);
|
|
}
|
|
|
|
for (int i = 0; i < 9; i++) {
|
|
if (i < rdsPs.length()) presets[mempos].RDSPS[i] = rdsPs.charAt(i);
|
|
else presets[mempos].RDSPS[i] = '\0';
|
|
EEPROM.writeByte((mempos * 9) + i + EE_PRESETS_RDSPS_START, presets[mempos].RDSPS[i]);
|
|
}
|
|
|
|
EEPROM.commit();
|
|
}
|
|
Serial.print("S:" + String(error, DEC) + "\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (data_str.startsWith("l") || data_str.startsWith("L")) printLogbookCSV();
|
|
else if(data_str.charAt(0) == '~' && data_str.charAt(1) == '/') {
|
|
MuteScreen(true);
|
|
i2c_pc_control = i2c_pc_control_init = true;
|
|
Serial.flush();
|
|
}
|
|
}
|
|
|
|
if (RDSSPYUSB && Serial.available()) {
|
|
String data_str = Serial.readStringUntil('\n');
|
|
int symPos = data_str.indexOf("*F");
|
|
if (symPos >= 5) {
|
|
String freq = data_str.substring(0, symPos);
|
|
frequency = freq.substring(0, freq.length() - 1).toInt();
|
|
if (scandxmode) cancelDXScan();
|
|
radio.SetFreq(frequency);
|
|
if (afscreen) BuildAdvancedRDS();
|
|
radio.clearRDS();
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
SelectBand();
|
|
}
|
|
ShowFreq(0);
|
|
store = true;
|
|
}
|
|
}
|
|
|
|
if (XDRGTKUSB || XDRGTKTCP) XDRGTKRoutine();
|
|
}
|
|
}
|
|
|
|
void XDRGTKRoutine() {
|
|
if (XDRGTKUSB) {
|
|
while (Serial.available() > 0) {
|
|
char c = Serial.read();
|
|
if (buff_pos < 16 && c != '\n') buff[buff_pos++] = c;
|
|
else {
|
|
buff[buff_pos] = '\0';
|
|
buff_pos = 0;
|
|
XDRGTKdata = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (XDRGTKTCP && RemoteClient.available() > 0) {
|
|
while (RemoteClient.available() > 0) {
|
|
char c = RemoteClient.read();
|
|
if (buff_pos < 16 && c != '\n') buff[buff_pos++] = c;
|
|
else {
|
|
buff[buff_pos] = '\0';
|
|
buff_pos = 0;
|
|
XDRGTKdata = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(XDRGTKdata) {
|
|
switch (buff[0])
|
|
{
|
|
case 'A': {
|
|
int AGC = atoi(buff + 1);
|
|
DataPrint("A" + String(AGC) + "\n");
|
|
switch (AGC) {
|
|
case 0:
|
|
if (band == BAND_FM || BAND_OIRT) {
|
|
radio.setAGC(92);
|
|
fmagc = 92;
|
|
} else {
|
|
radio.setAMAGC(100);
|
|
amagc = 100;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (band == BAND_FM || BAND_OIRT) {
|
|
radio.setAGC(90);
|
|
fmagc = 90;
|
|
} else {
|
|
radio.setAMAGC(99);
|
|
amagc = 99;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (band == BAND_FM || BAND_OIRT) {
|
|
radio.setAGC(87);
|
|
fmagc = 87;
|
|
} else {
|
|
radio.setAMAGC(96);
|
|
amagc = 96;
|
|
}
|
|
break;
|
|
case 3:
|
|
if (band == BAND_FM || BAND_OIRT) {
|
|
radio.setAGC(84);
|
|
fmagc = 84;
|
|
} else {
|
|
radio.setAMAGC(94);
|
|
amagc = 94;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
} case 'B': {
|
|
byte stmo = atoi(buff + 1);
|
|
DataPrint("B" + String(stmo) + "\n");
|
|
StereoToggle = (stmo == 1);
|
|
audiomode = (stmo != 0 && stmo != 1);
|
|
doStereoToggle();
|
|
break;
|
|
} case 'C': {
|
|
if (afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
byte scanmethod = atoi(buff + 1);
|
|
|
|
if (band < BAND_GAP) {
|
|
stepsize = 0;
|
|
ShowStepSize();
|
|
}
|
|
|
|
if (scanmethod == 1) {
|
|
DataPrint("C1\n");
|
|
direction = false;
|
|
Seek(direction);
|
|
ShowFreq(0);
|
|
}
|
|
if (scanmethod == 2) {
|
|
DataPrint("C2\n");
|
|
direction = true;
|
|
Seek(direction);
|
|
ShowFreq(0);
|
|
}
|
|
DataPrint("C0\n");
|
|
break;
|
|
} case 'D': {
|
|
byte demp = atoi(buff + 1);
|
|
DataPrint("D" + String(demp) + "\n");
|
|
switch (demp) {
|
|
case 0:
|
|
fmdeemphasis = DEEMPHASIS_50;
|
|
break;
|
|
case 1:
|
|
fmdeemphasis = DEEMPHASIS_75;
|
|
break;
|
|
case 2:
|
|
fmdeemphasis = DEEMPHASIS_NONE;
|
|
break;
|
|
}
|
|
radio.setDeemphasis(fmdeemphasis);
|
|
break;
|
|
} case 'F': {
|
|
XDRBWset = atoi(buff + 1);
|
|
DataPrint("F" + String(XDRBWset) + "\n");
|
|
if (XDRBWset < 0) BWset = 0;
|
|
else if (XDRBWset < 16) BWset = XDRBWset + 1;
|
|
doBW();
|
|
break;
|
|
} case 'G': {
|
|
uint8_t offsetg = strtoul(buff + 1, NULL, 2);
|
|
iMSset = (offsetg & 2) == 2;
|
|
EQset = (offsetg & 1) == 1;
|
|
if (offsetg == 0) DataPrint("G00\n");
|
|
else if (offsetg == 2) DataPrint("G10\n");
|
|
else if (offsetg == 1) DataPrint("G01\n");
|
|
else if (offsetg == 3) DataPrint("G11\n");
|
|
updateiMS();
|
|
updateEQ();
|
|
break;
|
|
} case 'H': {
|
|
byte autosq_read = atoi(buff + 1);
|
|
if (autosq_read == 0) {
|
|
autosquelch = false;
|
|
DataPrint("H0\n");
|
|
} else if (autosq_read == 1) {
|
|
autosquelch = true;
|
|
DataPrint("H1\n");
|
|
} else autosquelch = !autosquelch;
|
|
|
|
if (autosquelch) {
|
|
DataPrint("H1\n");
|
|
if (!screenmute) showAutoSquelch(1);
|
|
} else {
|
|
DataPrint("H0\n");
|
|
if (!screenmute) {
|
|
if (!usesquelch) showAutoSquelch(0);
|
|
else Squelch = -150;
|
|
}
|
|
}
|
|
break;
|
|
} case 'I': {
|
|
byte fmscansenstemp = atoi(buff + 1);
|
|
if (fmscansenstemp > 0 && fmscansenstemp < 31) {
|
|
fmscansens = fmscansenstemp;
|
|
EEPROM.writeByte(EE_BYTE_FMSCANSENS, fmscansens);
|
|
EEPROM.commit();
|
|
}
|
|
DataPrint("I" + String(fmscansens) + "\n");
|
|
break;
|
|
} case 'J': {
|
|
byte scandxtemp = atoi(buff + 1);
|
|
if (scandxtemp == 0 && scandxmode) cancelDXScan();
|
|
if (scandxtemp == 1 && !scandxmode) startFMDXScan();
|
|
DataPrint("J" + String(scandxtemp) + "\n");
|
|
break;
|
|
} case 'K': {
|
|
byte scanholdtemp = atoi(buff + 1);
|
|
if (scanholdtemp < 31) {
|
|
scanhold = scanholdtemp;
|
|
EEPROM.writeByte(EE_BYTE_SCANHOLD, scanhold);
|
|
EEPROM.commit();
|
|
}
|
|
DataPrint("K" + String(scanhold) + "\n");
|
|
break;
|
|
} case 'M': {
|
|
if (scandxmode) cancelDXScan();
|
|
byte XDRband = atoi(buff + 1);
|
|
if (XDRband == 1) {
|
|
if (frequency_AM >= LWLowEdgeSet && frequency_AM <= LWHighEdgeSet) {
|
|
if (band != BAND_LW) {
|
|
band = BAND_LW;
|
|
SelectBand();
|
|
}
|
|
}
|
|
if (frequency_AM >= MWLowEdgeSet && frequency_AM <= MWHighEdgeSet) {
|
|
if (band != BAND_MW) {
|
|
band = BAND_MW;
|
|
SelectBand();
|
|
}
|
|
}
|
|
if (frequency_AM >= SWLowEdgeSet && frequency_AM <= SWHighEdgeSet) {
|
|
if (band != BAND_SW) {
|
|
band = BAND_SW;
|
|
SelectBand();
|
|
}
|
|
}
|
|
radio.SetFreqAM(frequency_AM);
|
|
DataPrint("M1\n");
|
|
DataPrint("T" + String(frequency_AM) + "\n");
|
|
} else {
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
SelectBand();
|
|
}
|
|
DataPrint("M0\n");
|
|
DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n");
|
|
radio.SetFreq(frequency);
|
|
radio.clearRDS();
|
|
RDSstatus = false;
|
|
}
|
|
store = true;
|
|
break;
|
|
} case 'T': {
|
|
if (scandxmode) cancelDXScan();
|
|
unsigned int freqtemp = atoi(buff + 1);
|
|
|
|
if(BAND_FM) freqtemp -= ConverterSet * 1000;
|
|
if(seek) seek = false;
|
|
radio.clearRDS();
|
|
|
|
if (freqtemp >= LWLowEdgeSet && freqtemp <= LWHighEdgeSet) {
|
|
frequency_LW = freqtemp;
|
|
frequency_AM = freqtemp;
|
|
if (afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
if (band != BAND_LW) {
|
|
band = BAND_LW;
|
|
SelectBand();
|
|
DataPrint("M1\n");
|
|
}
|
|
radio.SetFreqAM(frequency_LW);
|
|
} else if (freqtemp >= MWLowEdgeSet && freqtemp <= MWHighEdgeSet) {
|
|
frequency_AM = freqtemp;
|
|
frequency_MW = freqtemp;
|
|
if (afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
if (band != BAND_MW) {
|
|
band = BAND_MW;
|
|
SelectBand();
|
|
DataPrint("M1\n");
|
|
}
|
|
radio.SetFreqAM(frequency_MW);
|
|
} else if (freqtemp >= SWLowEdgeSet && freqtemp <= SWHighEdgeSet) {
|
|
frequency_SW = freqtemp;
|
|
frequency_AM = freqtemp;
|
|
if (afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
if (band != BAND_SW) {
|
|
band = BAND_SW;
|
|
SelectBand();
|
|
DataPrint("M1\n");
|
|
}
|
|
radio.SetFreqAM(frequency_SW);
|
|
} else if (freqtemp >= LowEdgeOIRTSet * 10 && freqtemp <= HighEdgeOIRTSet * 10) {
|
|
frequency_OIRT = freqtemp / 10;
|
|
if (afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
if (band != BAND_OIRT) {
|
|
band = BAND_OIRT;
|
|
SelectBand();
|
|
DataPrint("M0\n");
|
|
}
|
|
radio.SetFreq(frequency_OIRT);
|
|
} else if (freqtemp >= (TEF == 205 ? 64000 : 65000) && freqtemp <= 108000) {
|
|
frequency = freqtemp / 10;
|
|
if (afscreen || advancedRDS) {
|
|
BuildDisplay();
|
|
SelectBand();
|
|
}
|
|
if (band != BAND_FM) {
|
|
band = BAND_FM;
|
|
SelectBand();
|
|
DataPrint("M0\n");
|
|
}
|
|
radio.SetFreq(frequency);
|
|
}
|
|
|
|
if (band == BAND_FM) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n");
|
|
else if (band == BAND_OIRT) DataPrint("T" + String(frequency_OIRT * 10) + "\n");
|
|
else DataPrint("T" + String(frequency_AM) + "\n");
|
|
ShowFreq(0);
|
|
RDSstatus = false;
|
|
store = true;
|
|
aftest = true;
|
|
aftimer = millis();
|
|
break;
|
|
} case 'Q': {
|
|
Squelch = atoi(buff + 1);
|
|
if (Squelch == -1) DataPrint("Q-1\n");
|
|
else {
|
|
DataPrint("Q");
|
|
DataPrint(String(Squelch));
|
|
DataPrint("\n");
|
|
Squelch *= 10;
|
|
}
|
|
break;
|
|
} case 'S': {
|
|
if (scandxmode) cancelDXScan();
|
|
if (!XDRScan) BWsetRecall = BWset;
|
|
XDRScan = true;
|
|
|
|
switch (buff[1]) {
|
|
case 'a': scanner_start = (atoi(buff + 2) + 5) / 10; break;
|
|
case 'b': scanner_end = (atoi(buff + 2) + 5) / 10; return;
|
|
case 'c': scanner_step = (atoi(buff + 2) + 5) / 10; break;
|
|
case 'f':
|
|
scanner_filter = atoi(buff + 2);
|
|
switch (scanner_filter) {
|
|
case 0: BWset = 1; break;
|
|
case 26: BWset = 2; break;
|
|
case 1: BWset = 3; break;
|
|
case 28: BWset = 4; break;
|
|
case 29: BWset = 5; break;
|
|
case 3: BWset = 6; break;
|
|
case 4: BWset = 7; break;
|
|
case 5: BWset = 8; break;
|
|
case 7: BWset = 9; break;
|
|
case 8: BWset = 10; break;
|
|
case 9: BWset = 11; break;
|
|
case 10: BWset = 12; break;
|
|
case 11: BWset = 13; break;
|
|
case 12: BWset = 14; break;
|
|
case 13: BWset = 15; break;
|
|
case 15: BWset = 16; break;
|
|
}
|
|
doBW();
|
|
break;
|
|
case 'w': {
|
|
uint32_t bwtemp = atoi(buff + 2);
|
|
switch (bwtemp) {
|
|
case 0: BWset = 0; break;
|
|
case 56000: BWset = 1; break;
|
|
case 64000: BWset = 2; break;
|
|
case 72000: BWset = 3; break;
|
|
case 84000: BWset = 4; break;
|
|
case 97000: BWset = 5; break;
|
|
case 114000: BWset = 6; break;
|
|
case 133000: BWset = 7; break;
|
|
case 151000: BWset = 8; break;
|
|
case 168000: BWset = 9; break;
|
|
case 184000: BWset = 10; break;
|
|
case 200000: BWset = 11; break;
|
|
case 217000: BWset = 12; break;
|
|
case 236000: BWset = 13; break;
|
|
case 254000: BWset = 14; break;
|
|
case 287000: BWset = 15; break;
|
|
case 311000: BWset = 16; break;
|
|
}
|
|
doBW();
|
|
break;
|
|
}
|
|
case '\0':
|
|
radio.setMute();
|
|
if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor);
|
|
if (!screenmute) {
|
|
tft.drawRoundRect(10, 30, 300, 170, 5, ActiveColor);
|
|
tft.fillRoundRect(12, 32, 296, 166, 5, BackgroundColor);
|
|
tftPrint(ACENTER, textUI(31), 160, 100, ActiveColor, ActiveColorSmooth, 28);
|
|
}
|
|
|
|
DataPrint("U");
|
|
|
|
for (freq_scan = scanner_start; freq_scan <= scanner_end; freq_scan += scanner_step) {
|
|
radio.SetFreq(freq_scan);
|
|
delay(5);
|
|
DataPrint(String(freq_scan * 10, DEC));
|
|
DataPrint(" = ");
|
|
if (band < BAND_GAP) radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); else radio.getStatusAM(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN);
|
|
DataPrint(String((SStatus / 10) + 10, DEC));
|
|
DataPrint(", ");
|
|
}
|
|
DataPrint("\n");
|
|
|
|
radio.SetFreq(frequency);
|
|
BuildDisplay();
|
|
SelectBand();
|
|
BWset = BWsetRecall;
|
|
doBW();
|
|
XDRScan = false;
|
|
if (VolSet != 0) {
|
|
radio.setUnMute();
|
|
if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor);
|
|
radio.setVolume(((VolSet * 10) - 40) / 10);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
} case 'W': {
|
|
uint32_t bwtemp = atoi(buff + 1);
|
|
switch (bwtemp) {
|
|
case 0: BWset = 0; break;
|
|
case 56000: BWset = 1; break;
|
|
case 64000: BWset = 2; break;
|
|
case 72000: BWset = 3; break;
|
|
case 84000: BWset = 4; break;
|
|
case 97000: BWset = 5; break;
|
|
case 114000: BWset = 6; break;
|
|
case 133000: BWset = 7; break;
|
|
case 151000: BWset = 8; break;
|
|
case 168000: BWset = 9; break;
|
|
case 184000: BWset = 10; break;
|
|
case 200000: BWset = 11; break;
|
|
case 217000: BWset = 12; break;
|
|
case 236000: BWset = 13; break;
|
|
case 254000: BWset = 14; break;
|
|
case 287000: BWset = 15; break;
|
|
case 311000: BWset = 16; break;
|
|
}
|
|
doBW();
|
|
DataPrint("W" + String(bwtemp) + "\n");
|
|
break;
|
|
} case 'Y': {
|
|
VolSet = atoi(buff + 1) * 0.1;
|
|
if (VolSet == 0) {
|
|
radio.setMute();
|
|
if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor);
|
|
XDRMute = true;
|
|
SQ = true;
|
|
} else {
|
|
radio.setUnMute();
|
|
if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor);
|
|
radio.setVolume(VolSet);
|
|
XDRMute = false;
|
|
}
|
|
DataPrint("Y" + String(VolSet) + "\n");
|
|
break;
|
|
} case 'x': {
|
|
DataPrint("OK\n");
|
|
if (BAND_FM) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n");
|
|
else if (BAND_OIRT) DataPrint("T" + String(frequency_OIRT * 10) + "\n");
|
|
else DataPrint("T" + String(frequency_AM) + "\n");
|
|
if(StereoToggle) DataPrint("B0\n"); else DataPrint("B1\n");
|
|
if(XDRGTKMuteScreen) MuteScreen(1);
|
|
break;
|
|
} case 'X': {
|
|
XDRGTKTCP = false;
|
|
XDRGTKUSB = false;
|
|
store = true;
|
|
XDRMute = false;
|
|
saveData();
|
|
radio.setUnMute();
|
|
MuteScreen(0);
|
|
break;
|
|
} case 'Z': {
|
|
// TEF does not do multiple antennas, just do a screen on/off, also more than 4 so no accidental switch
|
|
byte data = atoi(buff + 1);
|
|
DataPrint("Z" + String(data) + "\n");
|
|
MuteScreen((data > 4) ? true : false);
|
|
break;
|
|
}
|
|
}
|
|
XDRGTKdata = false;
|
|
}
|
|
|
|
if (millis() >= signalstatustimer + 66) {
|
|
if (band > BAND_GAP) DataPrint("Sm");
|
|
else {
|
|
if(!StereoToggle) DataPrint("SM");
|
|
else if(Stereostatus) DataPrint("Ss");
|
|
else DataPrint("Sm");
|
|
}
|
|
|
|
DataPrint(String(((SStatus * 100) + 10875) / 1000) + "." + String(((SStatus * 100) + 10875) / 100 % 10) + "," + String(WAM / 10) + "," + String(USN / 10) + "," + String(BW) + "\n\n");
|
|
signalstatustimer = millis();
|
|
}
|
|
}
|
|
|
|
void passwordcrypt() {
|
|
int generated = 0;
|
|
while(generated < 16) {
|
|
byte randomValue = random(0, 26);
|
|
char letter = randomValue + 'a';
|
|
if (randomValue > 26) letter = (randomValue - 26);
|
|
saltkey.setCharAt(generated, letter);
|
|
generated++;
|
|
}
|
|
salt = saltkey + XDRGTK_key;
|
|
cryptedpassword = String(sha1(salt));
|
|
}
|
|
|
|
void tryWiFi() {
|
|
if (!setupmode && wifi) {
|
|
tft.drawRoundRect(1, 20, 319, 180, 5, ActiveColor);
|
|
tft.fillRoundRect(3, 22, 315, 176, 5, BackgroundColor);
|
|
Infoboxprint(textUI(52));
|
|
}
|
|
if (wifi) {
|
|
if (wc.autoConnect()) {
|
|
Server.begin();
|
|
Udp.begin(9031);
|
|
webserver.on("/", handleRoot);
|
|
webserver.on("/downloadCSV", HTTP_GET, handleDownloadCSV);
|
|
webserver.on("/logo.png", handleLogo);
|
|
webserver.begin();
|
|
NTPupdate();
|
|
remoteip = IPAddress(WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], subnetclient);
|
|
if (!setupmode) tftPrint(ACENTER, textUI(54), 155, 128, InsignificantColor, InsignificantColorSmooth, 28);
|
|
} else {
|
|
if (!setupmode) tftPrint(ACENTER, textUI(53), 155, 128, SignificantColor, SignificantColorSmooth, 28);
|
|
Server.end();
|
|
webserver.stop();
|
|
Udp.stop();
|
|
WiFi.mode(WIFI_OFF);
|
|
wifi = false;
|
|
XDRGTKTCP = false;
|
|
RDSSPYTCP = false;
|
|
}
|
|
} else {
|
|
Server.end();
|
|
webserver.stop();
|
|
Udp.stop();
|
|
WiFi.mode(WIFI_OFF);
|
|
}
|
|
}
|
|
|
|
void total_pc_control() {
|
|
static uint8_t data[255];
|
|
if(i2c_pc_control_init) {
|
|
Serial.write(1);
|
|
Serial.write(0xff);
|
|
Serial.flush();
|
|
i2c_pc_control_init = false;
|
|
}
|
|
if(Serial.available()) {
|
|
uint8_t userlen = Serial.read();
|
|
if(userlen == '~' && Serial.read() == '/') {
|
|
Serial.write(1);
|
|
Serial.write(0xff);
|
|
Serial.flush(true);
|
|
return;
|
|
}
|
|
|
|
auto len = Serial.read(data, userlen);
|
|
if(len != userlen) return;
|
|
|
|
switch (data[0]) {
|
|
case 0: { // Set clock
|
|
if(len < 5) break;
|
|
uint32_t clock = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | ((uint32_t)data[4]);
|
|
Wire.setClock(clock);
|
|
Serial.write(1);
|
|
Serial.write(0);
|
|
} break;
|
|
case 1: { // Send data
|
|
if(len < 3) break;
|
|
Wire.beginTransmission(data[1]);
|
|
Wire.write(data + 2, len - 2);
|
|
auto out = Wire.endTransmission();
|
|
Serial.write(2);
|
|
Serial.write(1);
|
|
Serial.write(out);
|
|
} break;
|
|
case 2: { // Send and receive data
|
|
if(len < 4) break; // Need at least: cmd, addr, datalen, recvlen
|
|
uint8_t addr = data[1];
|
|
uint8_t datalen = data[2];
|
|
|
|
if(len < 3 + datalen + 1) break; // Validate buffer size
|
|
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(data + 3, datalen);
|
|
auto out = Wire.endTransmission(false);
|
|
|
|
uint8_t recvlen = Wire.requestFrom(addr, data[3+datalen]);
|
|
Serial.write(recvlen+2);
|
|
Serial.write(2);
|
|
Serial.write(out);
|
|
while(Wire.available()) Serial.write(Wire.read());
|
|
} break;
|
|
case 3: { // Quit
|
|
i2c_pc_control = false;
|
|
MuteScreen(false);
|
|
Serial.write(1);
|
|
Serial.write(3);
|
|
Serial.flush();
|
|
Serial.updateBaudRate(115200);
|
|
} break;
|
|
case 4: { // Version
|
|
Serial.write(2);
|
|
Serial.write(4);
|
|
Serial.write(2);
|
|
} break;
|
|
case 5: { // Reboot
|
|
Serial.write(1);
|
|
Serial.write(5);
|
|
Serial.flush();
|
|
esp_restart();
|
|
} break;
|
|
case 6: { // Change baud
|
|
if(len < 5) break;
|
|
uint32_t clock = ((uint32_t)data[1] << 24) |
|
|
((uint32_t)data[2] << 16) |
|
|
((uint32_t)data[3] << 8) |
|
|
((uint32_t)data[4]);
|
|
Serial.write(1);
|
|
Serial.write(6);
|
|
Serial.flush();
|
|
Serial.updateBaudRate(clock);
|
|
} break;
|
|
case 7: { // Write to EEPROM
|
|
if(len < 4) break;
|
|
EEPROM.writeBytes((data[1] << 8) | data[2], data + 3, len - 3);
|
|
EEPROM.commit();
|
|
Serial.write(1);
|
|
Serial.write(7);
|
|
} break;
|
|
case 8: { // Read from EEPROM
|
|
if(len < 4) break;
|
|
auto address = (data[1] << 8) | data[2];
|
|
Serial.write(data[3] + 1);
|
|
Serial.write(8);
|
|
for(uint16_t i = 0; i < data[3]; i++) Serial.write(EEPROM.read(address + i));
|
|
} break;
|
|
case 0xff: { // Another wake command
|
|
Serial.write(1);
|
|
Serial.write(0xff);
|
|
Serial.flush(true);
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
Serial.flush(true);
|
|
}
|
|
} |